Knihovna FAISS a embedding: základ jazykových modelů

29. 7. 2025
Doba čtení: 31 minut

Sdílet

Autor: Root.cz s využitím DALL-E
Ukážeme si praktické použití knihovny FAISS, společně s embedding modely, které mj. umožňují vyhledávání v textech na základě sémantické podobnosti. S touto technologií se setkáme při zpracování přirozeného jazyka atd.

Obsah

1. Knihovna FAISS a embedding: základ jazykových modelů

2. Příprava projektu

3. Instalace balíčku sentence-transformers i jeho závislostí do virtuálního prostředí

4. Načtení modelu

5. Načtení odlišných modelů

6. Velikost stažených modelů

7. Převod vět do vektorizované podoby (embeddings)

8. Podoba výsledné matice

9. Podrobnější informace o vypočtené matici

10. Výpočet míry podobnosti jednotlivých vět

11. Využití knihovny Faiss pro získání původní věty na základě předaného vzorku

12. Instalace knihovny Faiss do virtuálního prostředí

13. Získání vět z původního seznamu na základě dotazu

14. Úplný zdrojový kód demonstračního příkladu

15. Výsledky dotazů

16. Jsou věty vybírány na základě textové podobnosti nebo jejich významu?

17. Věty s podobným významem, ovšem zapsané naprosto odlišným způsobem

18. Vyhledávání na základě kontextu (zobecnění provedené modelem)

19. Repositář s demonstračními příklady

20. Odkazy na Internetu

1. Knihovna FAISS a embedding: základ jazykových modelů

V úvodních dvou článcích o knihovně Faiss [1] [2] jsme si ukázali základní a vlastně i nejdůležitější funkci nabízenou touto knihovnou. Konkrétně se jedná o schopnost vyhledávání vektorů (o libovolném počtu dimenzí) na základě jejich podobnosti, přičemž pro stanovení podobnosti je možné využít různé metriky, typicky Eukleidovskou metriku L2 nebo výsledek výpočtu skalárního součinu. Prozatím však nemusí být zcela zřejmé, k jakým účelům je možné tuto knihovnu využít v praxi.

Dnes si ukážeme jeden poměrně typický způsob využití této knihovny. Použijeme ji pro vyhledávání vět (či delších popř. kratších textů) na základě sémantické podobnosti. Co to konkrétně znamená si můžeme ukázat na jednoduchém příkladu. Mějme databázi s následujícími větami:

The rain in Spain falls mainly on the plain
The tesselated polygon is a special type of polygon
The quick brown fox jumps over the lazy dog
To be or not to be, that is the question
It is a truth universally acknowledged...
How old are you?
The goat ran down the hill

S využitím vhodném embedding modelu a knihovny Faiss můžeme dosáhnout toho, že systém bude tyto věty prohledávat „inteligentně“, tedy například takto:

Dotaz (vzor) Vyhledaná věta
rainy weather in Spain, especially on plains The rain in Spain falls mainly on the plain
What is your age? How old are you?
Shakespeare To be or not to be, that is the question
animal The goat ran down the hill
geometry The tesselated polygon is a special type of polygon
weather The rain in Spain falls mainly on the plain

2. Příprava projektu

V prvním kroku si, naprosto stejným způsobem, jako jsme to provedli u demonstračních příkladů využívajících knihovnu FAISS, připravíme projekt v Pythonu a následně do něj nainstalujeme všechny potřebné knihovny. Pro vytvoření projektu použijeme buď nástroj PDM – viz též PDM: moderní správce balíčků a virtuálních prostředí Pythonu nebo (což je v současnosti výhodnější) nástroj uv. Projekt bude vytvořen v novém (původně prázdném) adresáři a jeho projektový soubor pyproject.toml může vypadat následovně:

[project]
name = "sentence-transformer"
version = "0.1.0"
description = "Sentence transformer demos"
authors = [
    {name = "Pavel Tisnovsky", email = "tisnik@nikdo.nikde.cz"},
]
dependencies = [
]
requires-python = "==3.12.*"
readme = "README.md"
license = {text = "MIT"}
 
 
[tool.pdm]
distribution = false

3. Instalace balíčku sentence-transformers i jeho závislostí do virtuálního prostředí

Ve druhém kroku do virtuálního prostředí vytvořeného pro nový projekt přidáme balíček nazvaný sentence-transformers. Později do projektu přidáme i knihovnu faiss-cpu, to ovšem prozatím nebude nutné:

uv add sentence_transformers

Tato knihovna má poměrně velké množství závislostí, včetně cca 6GB balíčků on NVidie. To je ostatně patrné i z průběhu instalace:

Installed 46 packages in 2.73s
 + certifi==2025.7.14
 + charset-normalizer==3.4.2
 + filelock==3.18.0
 + fsspec==2025.7.0
 + hf-xet==1.1.5
 + huggingface-hub==0.34.1
 + idna==3.10
 + jinja2==3.1.6
 + joblib==1.5.1
 + markupsafe==3.0.2
 + mpmath==1.3.0
 + networkx==3.5
 + numpy==2.3.2
 + nvidia-cublas-cu12==12.6.4.1
 + nvidia-cuda-cupti-cu12==12.6.80
 + nvidia-cuda-nvrtc-cu12==12.6.77
 + nvidia-cuda-runtime-cu12==12.6.77
 + nvidia-cudnn-cu12==9.5.1.17
 + nvidia-cufft-cu12==11.3.0.4
 + nvidia-cufile-cu12==1.11.1.6
 + nvidia-curand-cu12==10.3.7.77
 + nvidia-cusolver-cu12==11.7.1.2
 + nvidia-cusparse-cu12==12.5.4.2
 + nvidia-cusparselt-cu12==0.6.3
 + nvidia-nccl-cu12==2.26.2
 + nvidia-nvjitlink-cu12==12.6.85
 + nvidia-nvtx-cu12==12.6.77
 + packaging==25.0
 + pillow==11.3.0
 + pyyaml==6.0.2
 + regex==2024.11.6
 + requests==2.32.4
 + safetensors==0.5.3
 + scikit-learn==1.7.1
 + scipy==1.16.0
 + sentence-transformers==5.0.0
 + setuptools==80.9.0
 + sympy==1.14.0
 + threadpoolctl==3.6.0
 + tokenizers==0.21.2
 + torch==2.7.1
 + tqdm==4.67.1
 + transformers==4.53.3
 + triton==3.3.1
 + typing-extensions==4.14.1
 + urllib3==2.5.0

Projektový soubor by se měl změnit do následující podoby:

[project]
name = "sentence-transformer"
version = "0.1.0"
description = "Sentence transformer demos"
authors = [
    {name = "Pavel Tisnovsky", email = "tisnik@nikdo.nikde.cz"},
]
dependencies = [
    "sentence-transformers>=5.0.0",
]
requires-python = "==3.12.*"
readme = "README.md"
license = {text = "MIT"}
 
 
[tool.pdm]
distribution = false

Otestujeme, zda je možné právě nainstalovaný balíček naimportovat:

$ uv run python
 
Python 3.12.10 (main, Apr 22 2025, 00:00:00) [GCC 14.2.1 20240912 (Red Hat 14.2.1-3)] on linux
Type "help", "copyright", "credits" or "license" for more information.
 
>>> import sentence_transformers
 
>>> help(sentence_transformers)
 
Help on package sentence_transformers:
 
NAME
    sentence_transformers
 
PACKAGE CONTENTS
    LoggingHandler
    SentenceTransformer
    backend
    cross_encoder (package)
    data_collator
    datasets (package)
    evaluation (package)
    fit_mixin
    losses (package)
    model_card
    model_card_templates
    models (package)
    peft_mixin
    quantization
    readers (package)
    sampler
    similarity_functions
    sparse_encoder (package)
    trainer
    training_args
    util
 
    ...
    ...
    ...

4. Načtení modelu

Jedinou funkcí, kterou v dnešním článku budeme od balíčku sentence-transformers vyžadovat, je transformace textů (v našem případě jednoduchých vět) do formy vektorů pevné délky. Hodnoty prvků těchto vektorů nějakým způsobem popisují význam původních vět. To znamená, že, pokud situaci značně zjednodušíme, může jeden z prvků (v závislosti na modelu) určovat, jestli se v původní větě mluví o zvířatech (popř. o jakých zvířatech), další prvek určuje, že ve větě je zmínka o počasí atd. Prvky vektorů jsou přitom typicky reálnými čísly určujícími váhy příslušných kategorií a v závislosti na modelu mohou být vektory normalizovány či nikoli (normalizované vektory lze přímo použít při hledání podobných vektorů s využitím skalárního součinu).

Jedním z modelů, které je možné pro tvorbu vektorové databáze použít, je model nazvaný paraphrase-MiniLM-L6-v2. Můžeme se pokusit tento model načíst a vypsat si jeho základní vlastnosti:

from sentence_transformers import SentenceTransformer
 
model = SentenceTransformer("paraphrase-MiniLM-L6-v2")
 
print(model)

Po první spuštění tohoto skriptu se model načte z Internetu (což může nějakou dobu trvat) a posléze by se měly vypsat jeho základní vlastnosti:

SentenceTransformer(
  (0): Transformer({'max_seq_length': 128, 'do_lower_case': False, 'architecture': 'BertModel'})
  (1): Pooling({'word_embedding_dimension': 384, 'pooling_mode_cls_token': False, 'pooling_mode_mean_tokens': True, 'pooling_mode_max_tokens': False, 'pooling_mode_mean_sqrt_len_tokens': False, 'pooling_mode_weightedmean_tokens': False, 'pooling_mode_lasttoken': False, 'include_prompt': True})
)

Důležitá je pro nás především informace o délce vektorů, tedy o počtu dimenzí. Ta je v tomto modelu rovna hodnotě 384. S touto hodnotou se setkáme později. Zajímavá je taktéž informace o použité architektuře BERT (což by bylo téma na samostatný článek).

Poznámka: na jednu stranu modely s vektory s větším počtem dimenzí dokážou popsat původní věty přesněji, na stranu druhou mají tyto modely větší paměťové i výpočetní nároky. Z tohoto důvodu se velmi často setkáme s modely, jejichž vektory mají právě 384 dimenzí, ovšem pochopitelně existují i modely menší (typicky specializované na jednu oblast) nebo naopak větší. U takových modelů je již velmi složité určit, co která dimenze reprezentuje (už se nebude jednat o slova, ale spíše o ucelené a zobecněné významy).

5. Načtení odlišných modelů

Na stránkách projektu Hugging Face můžeme nalézt velké množství dalších modelů, které je možné použít pro vektorizaci textů. Některé z těchto modelů se snaží být univerzální (a to včetně podpory mnoha jazyků), další jsou specializované, atd. Modely se taktéž liší délkou (počtem dimenzí) výsledných vektorů.

Poměrně často se setkáme s modelem nazvaným all-mpnet-base-v2, který lze inicializovat tímto způsobem:

from sentence_transformers import SentenceTransformer
 
model = SentenceTransformer("all-mpnet-base-v2")
 
print(model)

Po prvním spuštění tohoto skriptu se celý model stáhne a následně se vypíšou jeho základní charakteristiky:

SentenceTransformer(
  (0): Transformer({'max_seq_length': 384, 'do_lower_case': False, 'architecture': 'MPNetModel'})
  (1): Pooling({'word_embedding_dimension': 768, 'pooling_mode_cls_token': False, 'pooling_mode_mean_tokens': True, 'pooling_mode_max_tokens': False, 'pooling_mode_mean_sqrt_len_tokens': False, 'pooling_mode_weightedmean_tokens': False, 'pooling_mode_lasttoken': False, 'include_prompt': True})
  (2): Normalize()
)
Poznámka: povšimněte si, že dimenzionalita výsledných vektorů je nyní rovna hodnotě 768, což znamená, že model bude kvalitnější (zaznamená více kontextu ze zpracovávaných textů), ovšem bude vyžadovat více paměti i více strojového času při práci s ním.

K dispozici jsou ovšem i modely určené pro konkrétní jazyky, tedy nikoli primárně pro angličtinu. Příkladem může být model od Seznamu, který si opět můžeme stáhnout a vypsat jeho základní vlastnosti:

from sentence_transformers import SentenceTransformer
 
model = SentenceTransformer("Seznam/small-e-czech")
 
print(model)

Opět se bude lišit dimezinonalita výsledných vektorů:

SentenceTransformer(
  (0): Transformer({'max_seq_length': 512, 'do_lower_case': False, 'architecture': 'ElectraModel'})
  (1): Pooling({'word_embedding_dimension': 256, 'pooling_mode_cls_token': False, 'pooling_mode_mean_tokens': True, 'pooling_mode_max_tokens': False, 'pooling_mode_mean_sqrt_len_tokens': False, 'pooling_mode_weightedmean_tokens': False, 'pooling_mode_lasttoken': False, 'include_prompt': True})
)

6. Velikost stažených modelů

V rámci předchozích kapitol bylo staženo několik modelů, ke kterým jsem ještě přidal model all-MiniLM-L6-v2. Tyto modely jsou, včetně jejich metadat, uloženy v podadresáři ~/.cache/huggingface/hug, takže bude snadné zjistit, kolik místa na disku vlastně vyžadují:

$ du --summarize --human-readable ~/.cache/huggingface/hub/*
 
88M     /home/ptisnovs/.cache/huggingface/hub/models--sentence-transformers--all-MiniLM-L6-v2
419M    /home/ptisnovs/.cache/huggingface/hub/models--sentence-transformers--all-mpnet-base-v2
88M     /home/ptisnovs/.cache/huggingface/hub/models--sentence-transformers--paraphrase-MiniLM-L6-v2
105M    /home/ptisnovs/.cache/huggingface/hub/models--Seznam--small-e-czech

Povšimněte si, že obsazené místo na disku do určité míry záleží na dimenzionalitě výsledných vektorů (což je pochopitelné), ovšem nejedná se o jedinou veličinu, protože záleží i na interní složitosti modelu atd. Ovšem je patrné, že modely nazvané „mini“ nebo v případě českého modelu „small“ jsou skutečně menší, než všeobjímající model all-mpnet-base-v2.

Poznámka: pokud vám zdánlivě „mizí“ místo na disku, podívejte se i na adresář ~/.cache/huggingface/xet, ve kterém se mohou nacházet částečně stažené soubory. Pokud například při stahování modelu o velikosti 500MB dojde před koncem stahování k přerušení připojení (stránky Hugging Face bývají přetíženy), může se ve výše zmíněném podadresáři nacházet částečně stažený soubor.

7. Převod vět do vektorizované podoby (embeddings)

Balíček sentence-transformers i modely z Hugging Face jsme instalovali z jediného důvodu – aby bylo možné převádět věty (pro jednoduchost prozatím řekněme anglické věty) do vektorizované podoby. V případě, že použijeme model paraphrase-MiniLM-L6-v2, měla by být každá věta převedena do vektoru s 384 prvky, jejichž hodnoty by měly ve více či méně dokonalé podobě vyjadřovat význam věty.

Podívejme se nyní, jak tato vektorizace probíhá. Je to vlastně velmi jednoduché:

  1. Načteme vybraný model, v našem konkrétním případě výše zmíněný modelparaphrase-MiniLM-L6-v2
  2. Zavoláme metodu modelu nazvanou encode a předáme jí seznam (nebo sekvenci) vět v textové podobě. Tato metoda má velké množství doplňujících parametrů, ty ovšem prozatím nebudeme používat a ponecháme explicitní hodnoty.
  3. Výsledkem bude matice (reálných hodnot) o n řádcích a m sloupcích, kde n odpovídá počtu předaných vět a m dimenzionalitě vektorů (takže například 256, 384, 512, 768 atd. – závisí na použitém modelu)

V Pythonu celý postup vypadá následovně:

from sentence_transformers import SentenceTransformer
 
model = SentenceTransformer("paraphrase-MiniLM-L6-v2")
 
print(model)
 
sentences = [
    "The rain in Spain falls mainly on the plain",
    "The tesselated polygon is a special type of polygon",
    "The quick brown fox jumps over the lazy dog",
    "To be or not to be, that is the question",
    "It is a truth universally acknowledged...",
    "The goat ran down the hill"
]
 
embeddings = model.encode(sentences)
print(f"Embeddings shape: {embeddings.shape}")
 
print(f"Data type: {type(embeddings)}")
 
print(embeddings)

8. Podoba výsledné matice

Skript popsaný v předchozí kapitole spustíme. Přitom musíme myslet na to, že balíček sentence-transformers byl nainstalován do virtuálního prostředí a proto pro spuštění skriptu použijeme nástroj pdm nebo uv:

$ uv run transformer4.py 

Nejprve se vypíšou vlastnosti vybraného modelu. Ten se již nemusí stahovat, takže by tento výpis měl proběhnout relativně rychle:

SentenceTransformer(
  (0): Transformer({'max_seq_length': 128, 'do_lower_case': False, 'architecture': 'BertModel'})
  (1): Pooling({'word_embedding_dimension': 384, 'pooling_mode_cls_token': False, 'pooling_mode_mean_tokens': True, 'pooling_mode_max_tokens': False, 'pooling_mode_mean_sqrt_len_tokens': False, 'pooling_mode_weightedmean_tokens': False, 'pooling_mode_lasttoken': False, 'include_prompt': True})
)

Dále se vypíšou informace o výsledné matici, tj. počet řádků a počet sloupců. Vypíšeme (pro jistotu) i typ výsledné hodnoty a následně i celou matici (výpis bude automaticky zkrácený tak, aby se vlezl na terminál):

Embeddings shape: (6, 384)
Data type: <class 'numpy.ndarray'>
 
[[ 0.3478464   0.16516833  0.80891246 ...  0.30405566 -0.03139801
   0.01735949]
 [ 0.1602744  -0.4778426   0.14267132 ...  0.35347039  0.0946853
   0.16065337]
 [ 0.6181423  -0.24776645 -0.23564643 ...  0.17215663  1.1165967
   0.63950485]
 [ 0.6088223   0.5830838   0.4046087  ...  0.08260182  0.8130692
   0.16788083]
 [ 0.11015981  0.10045841 -0.24472675 ... -0.06199175  0.46151286
  -0.12090196]
 [ 0.15316609 -0.05734093 -0.27605703 ...  0.01458593  0.24355106
  -0.44814658]]

9. Podrobnější informace o vypočtené matici

Další informace o matici lze získat zavoláním funkce numpy.info():

from sentence_transformers import SentenceTransformer
import numpy as np
 
model = SentenceTransformer("paraphrase-MiniLM-L6-v2")
 
print(model)
 
sentences = [
    "The rain in Spain falls mainly on the plain",
    "The tesselated polygon is a special type of polygon",
    "The quick brown fox jumps over the lazy dog",
    "To be or not to be, that is the question",
    "It is a truth universally acknowledged...",
    "The goat ran down the hill"
]
 
# Generate embeddings for the sentences
embeddings = model.encode(sentences)
 
np.info(embeddings)

Vypíšou se spíše interní informace o matici, které však mohou být v některých případech užitečné:

class:  ndarray
shape:  (6, 384)
strides:  (1536, 4)
itemsize:  4
aligned:  True
contiguous:  True
fortran:  False
data pointer: 0x55a259b4e060
byteorder:  little
byteswap:  False
type: float32

10. Výpočet míry podobnosti jednotlivých vět

Ve chvíli, kdy máme připravenu matici s „vektorizovanými“ větami, můžeme se pokusit o provedení dalších výpočtů. S využitím metody nazvané model.similarity lze vypočítat (de facto) matici, která bude obsahovat míry podobnosti jednotlivých vět. Pro původních šest vět bude mít tato matice velikost 6×6 prvků, bude (logicky) symetrická okolo hlavní diagonály a současně bude mít na hlavní diagonále jedničky (což je opět pochopitelné – věta je nejvíce podobná sobě samé).

from sentence_transformers import SentenceTransformer
 
model = SentenceTransformer("paraphrase-MiniLM-L6-v2")
 
print(model)
 
sentences = [
    "The rain in Spain falls mainly on the plain",
    "The tesselated polygon is a special type of polygon",
    "The quick brown fox jumps over the lazy dog",
    "To be or not to be, that is the question",
    "It is a truth universally acknowledged...",
    "The goat ran down the hill"
]
 
embeddings = model.encode(sentences)
print(f"Embeddings shape: {embeddings.shape}")
 
print(embeddings)
similarities = model.similarity(embeddings, embeddings)
print(similarities)

Po spuštění tohoto skriptu se nejdříve opět vypíše informace o modelu:

SentenceTransformer(
  (0): Transformer({'max_seq_length': 128, 'do_lower_case': False, 'architecture': 'BertModel'})
  (1): Pooling({'word_embedding_dimension': 384, 'pooling_mode_cls_token': False, 'pooling_mode_mean_tokens': True, 'pooling_mode_max_tokens': False, 'pooling_mode_mean_sqrt_len_tokens': False, 'pooling_mode_weightedmean_tokens': False, 'pooling_mode_lasttoken': False, 'include_prompt': True})
)

Následně se vypíše informace o vytvořené matici (vektorizovaný text):

Embeddings shape: (6, 384)
[[ 0.3478464   0.16516833  0.80891246 ...  0.30405566 -0.03139801
   0.01735949]
 [ 0.1602744  -0.4778426   0.14267132 ...  0.35347039  0.0946853
   0.16065337]
 [ 0.6181423  -0.24776645 -0.23564643 ...  0.17215663  1.1165967
   0.63950485]
 [ 0.6088223   0.5830838   0.4046087  ...  0.08260182  0.8130692
   0.16788083]
 [ 0.11015981  0.10045841 -0.24472675 ... -0.06199175  0.46151286
  -0.12090196]
 [ 0.15316609 -0.05734093 -0.27605703 ...  0.01458593  0.24355106
  -0.44814658]]

A nakonec výpočtem získáme matici s podobnostmi jednotlivých vět (nenechte se zmást, že typem je tenzor, tento tenzor druhého řádu je maticí):

tensor([[ 1.0000,  0.0134, -0.0661,  0.0697,  0.0171,  0.0515],
        [ 0.0134,  1.0000, -0.0014, -0.0654, -0.0510,  0.0028],
        [-0.0661, -0.0014,  1.0000, -0.1279, -0.0577,  0.3191],
        [ 0.0697, -0.0654, -0.1279,  1.0000,  0.1503, -0.0457],
        [ 0.0171, -0.0510, -0.0577,  0.1503,  1.0000, -0.0364],
        [ 0.0515,  0.0028,  0.3191, -0.0457, -0.0364,  1.0000]])

11. Využití knihovny Faiss pro získání původní věty na základě předaného vzorku

Připomeňme si, že model volaný z knihovny sentence-transformers vytvořil z původních vět reprezentovaných v textové podobě matici vektorů pevné délky (například se jedná o 384 prvků typu float atd.). A knihovna Faiss (resp. přesněji řečeno její varianta faiss-cpu) dokáže efektivně vyhledávat podobné vektory, přičemž je možné volit, jaký algoritmus bude při vyhodnocování podobnosti použit. To ovšem znamená, že tyto dvě knihovny je možné s výhodou použít společně a realizovat tak vyhledávání vět z původního seznamu na základě položeného dotazu (textový vstup). Bude se přitom provádět vyhledávání na základě sémantiky (smyslu) věty, nikoli na základě „primitivnějších“ metrik typu Levenštejnovy vzdálenosti nebo podobné metriky založené na zpracování jednotlivých znaků popř. tokenů.

Možnosti, které nám takto pojaté řešení přináší, jsou překvapivě široké, což ostatně uvidíme z následujících demonstračních příkladů.

12. Instalace knihovny Faiss do virtuálního prostředí

Demonstrační příklady ukázané v navazujících kapitolách budou používat jak výše zmíněnou knihovnu sentence-transformers, tak i knihovnu Fass resp. přesněji řečeno její „CPU“ variantu nazvanou faiss-cpu. Budeme tedy muset upravit projektový soubor a Faiss nainstalovat do virtuálního prostředí. To je snadné. Příkazem uv add faiss-cpu doinstalujeme do našeho projektu knihovnu Faiss:

$ uv add faiss-cpu

Projektový soubor pyproject.toml by se měl změnit do této podoby (viz podtržený řádek):

[project]
name = "sentence-transformer"
version = "0.1.0"
description = "Sentence transformer demos"
authors = [
    {name = "Pavel Tisnovsky", email = "ptisnovs@redhat.com"},
]
dependencies = [
    "faiss-cpu>=1.11.0.post1",
    "sentence-transformers>=5.0.0",
]
requires-python = "==3.12.*"
readme = "README.md"
license = {text = "MIT"}
 
 
[tool.pdm]
distribution = false
Poznámka: pochopitelně se změní i obsah souboru uv.lock, nyní však nemusíme řešit konkrétní verze knihoven, takže se jím nebudeme zabývat.

13. Získání vět z původního seznamu na základě dotazu

Nyní si konečně ukážeme, jakým způsobem je možné provést vyhledávání, přesněji řečeno sémantické vyhledávání, na základě položeného dotazu. Vstupem pro vyhledávání bude věta nebo nějaký termín v textové podobě a výsledkem pak k nejpodobnějších vět získaných z původního seznamu. A pochopitelně platí, že pokud dosadíme za k hodnotu 1, dostaneme zcela nejbližší větu. To, o jakou větu se bude konkrétně jednat, závisí na použitém modelu a taktéž na zvolené metrice při vyhledávání (L2, skalární součin či cosine similarity, což je zobecnění skalárního součinu).

Nejdříve vytvoříme z matice vypočtené modelem knihovny sentence-transformers index zpracovatelný a prohledávatelný knihovnou Faiss:

DIMENSIONS = embeddings.shape[1]
 
index = faiss.IndexFlatL2(DIMENSIONS)
index.add(embeddings)
 
print(f"Index: {index.ntotal}")

Základem vyhledávání bude funkce nazvaná find_similar_sentences, která přes knihovnu Faiss nalezne k nejpodobnějších vektorů a následně na základě indexů těchto vektorů vytiskne původní věty uložené v seznamu sentencec. Využíváme zde faktu, že pořadí řádků v matici vypočtené knihovnou sentence-transformers odpovídá pořadí původních vět (jinak by nebylo možné dohledat původní věty – ty totiž není možné z embedded vektoru zrekonstruovat!):

def find_similar_sentences(query_sentence, k):
    query_embedding = model.encode([query_sentence])
    distances, indices = index.search(query_embedding, k)
    print("-"*40)
    print(f"Query: {query_sentence}")
    print(f"Most {k} similar sentences:")
    for i, idx in enumerate(indices[0]):
        print(f"{i + 1}: {sentences[idx]} (Distance: {distances[0][i]})")

14. Úplný zdrojový kód demonstračního příkladu

Úplný zdrojový kód demonstračního příkladu, který po svém spuštění dokáže z původní sady vět vyhledat větu (či větší množství vět) sémanticky nejpodobnějších zadanému vzorku, vypadá následovně. Pro spuštění je nutné použít nástroj uv nebo pdm, popř. jakýkoli jiný nástroj umožňující využití virtuálního prostředí Pythonu:

from sentence_transformers import SentenceTransformer
import faiss
 
model = SentenceTransformer("paraphrase-MiniLM-L6-v2")
 
print(model)
 
sentences = [
    "The rain in Spain falls mainly on the plain",
    "The tesselated polygon is a special type of polygon",
    "The quick brown fox jumps over the lazy dog",
    "To be or not to be, that is the question",
    "It is a truth universally acknowledged...",
    "The goat ran down the hill"
]
 
embeddings = model.encode(sentences)
print(f"Embeddings shape: {embeddings.shape}")
 
similarities = model.similarity(embeddings, embeddings)
 
DIMENSIONS = embeddings.shape[1]
 
index = faiss.IndexFlatL2(DIMENSIONS)
index.add(embeddings)
 
print(f"Index: {index.ntotal}")
 
 
def find_similar_sentences(query_sentence, k):
    query_embedding = model.encode([query_sentence])
    distances, indices = index.search(query_embedding, k)
    print("-"*40)
    print(f"Query: {query_sentence}")
    print(f"Most {k} similar sentences:")
    for i, idx in enumerate(indices[0]):
        print(f"{i + 1}: {sentences[idx]} (Distance: {distances[0][i]})")
 
 
find_similar_sentences("The quick brown fox jumps over the lazy dog", 3)
find_similar_sentences("quick brown fox jumps over lazy dog", 3)
find_similar_sentences("The quick brown fox jumps over the angry dog", 3)
find_similar_sentences("The quick brown cat jumps over the lazy dog", 3)
Poznámka: úplný zdrojový kód tohoto příkladu naleznete na adrese https://github.com/tisnik/most-popular-python-libs/blob/master/faiss_tran­sformers/transformer7.py.

15. Výsledky dotazů

Skript z předchozí kapitoly nyní spustíme a otestujeme jeho výsledky. Nejdříve se opět vypíše informace o použitém modelu (mimochodem – model můžete snadno změnit):

SentenceTransformer(
  (0): Transformer({'max_seq_length': 128, 'do_lower_case': False, 'architecture': 'BertModel'})
  (1): Pooling({'word_embedding_dimension': 384, 'pooling_mode_cls_token': False, 'pooling_mode_mean_tokens': True, 'pooling_mode_max_tokens': False, 'pooling_mode_mean_sqrt_len_tokens': False, 'pooling_mode_weightedmean_tokens': False, 'pooling_mode_lasttoken': False, 'include_prompt': True})
)

Následně se, což již taktéž známe, vypíše výsledek tvorby vektorové podoby textů (embeddingu):

Embeddings shape: (6, 384)

Z matice vygenerované modelem vytvoříme index použitelný knihovnou FAISS. Po konstrukci indexu se vypíše počet vektorů, které jsou zde zaindexovány/uloženy. Tento počet pochopitelně musí odpovídat počtu vstupních vět:

Index: 6

Nyní nastává nejzajímavější část, a to vyhledání tří nejbližších vět, které odpovídají zadanému vzorku (dotazu). Nejdříve uvedu výsledek činnosti skriptu, až poté ho okomentuji:

----------------------------------------
Query: The quick brown fox jumps over the lazy dog
Most 3 similar sentences:
1: The quick brown fox jumps over the lazy dog (Distance: 1.1586743717262316e-11)
2: The goat ran down the hill (Distance: 82.36725616455078)
3: The tesselated polygon is a special type of polygon (Distance: 95.39698791503906)
----------------------------------------
Query: quick brown fox jumps over lazy dog
Most 3 similar sentences:
1: The quick brown fox jumps over the lazy dog (Distance: 4.309008598327637)
2: The goat ran down the hill (Distance: 84.6357650756836)
3: The tesselated polygon is a special type of polygon (Distance: 98.03498840332031)
----------------------------------------
Query: The quick brown fox jumps over the angry dog
Most 3 similar sentences:
1: The quick brown fox jumps over the lazy dog (Distance: 12.856956481933594)
2: The goat ran down the hill (Distance: 80.267822265625)
3: To be or not to be, that is the question (Distance: 94.48042297363281)
----------------------------------------
Query: The quick brown cat jumps over the lazy dog
Most 3 similar sentences:
1: The quick brown fox jumps over the lazy dog (Distance: 23.47003173828125)
2: To be or not to be, that is the question (Distance: 93.37678527832031)
3: The tesselated polygon is a special type of polygon (Distance: 96.07341003417969)

Tyto výsledky je vhodné nějakým způsobem okomentovat. První výsledek je snadno pochopitelný, protože vstupní vzorek/dotaz přesně odpovídá jedné z vět uložených do vektorizované podoby. I když se to nezdá, je vzdálenost těchto vět prakticky nulová (resp. rovna 1e-11, což je velmi malá hodnota). Další věty z databáze jsou vzdáleny mnohem více, takže „vítěz“ je v tomto případě zřejmý:

Query: The quick brown fox jumps over the lazy dog
Most 3 similar sentences:
1: The quick brown fox jumps over the lazy dog (Distance: 1.1586743717262316e-11)
2: The goat ran down the hill (Distance: 82.36725616455078)
3: The tesselated polygon is a special type of polygon (Distance: 95.39698791503906)

Další příklad je zajímavý – vynechal jsem totiž všechny členy, v tomto případě dvě slova the. V textové podobě se tedy věty relativně značně liší, ovšem z pohledu modelu jsou velmi blízké – vzdálenost nepřesahuje pět jednotek. Členy tudíž v tomto případě význam věty pozměnily jen minimálně:

Query: quick brown fox jumps over lazy dog
Most 3 similar sentences:
1: The quick brown fox jumps over the lazy dog (Distance: 4.309008598327637)
2: The goat ran down the hill (Distance: 84.6357650756836)
3: The tesselated polygon is a special type of polygon (Distance: 98.03498840332031)

Další věta obsahuje namísto slova lazy slovo angry, což evidentně význam věty pozmění více, než chybějící členy (to je logické a model se chová korektně). Vzdálenost je rovna cca 13 jednotkám:

Query: The quick brown fox jumps over the angry dog
Most 3 similar sentences:
1: The quick brown fox jumps over the lazy dog (Distance: 12.856956481933594)
2: The goat ran down the hill (Distance: 80.267822265625)
3: To be or not to be, that is the question (Distance: 94.48042297363281)

Mnohem vzdálenější (cca dvakrát) je věta, ve které zaměníme fox za cat. Z pohledu modelu má tedy jiné zvíře (kočka namísto lišky) větší váhu, než vlastnost stejného zvířete (naštvaný vs líný pes):

Query: The quick brown cat jumps over the lazy dog
Most 3 similar sentences:
1: The quick brown fox jumps over the lazy dog (Distance: 23.47003173828125)
2: To be or not to be, that is the question (Distance: 93.37678527832031)
3: The tesselated polygon is a special type of polygon (Distance: 96.07341003417969)

16. Jsou věty vybírány na základě textové podobnosti nebo jejich významu?

Z předchozího demonstračního příkladu je do jisté míry zřejmé, že věty nejsou vybírány čistě na základě textové podobnosti, ale spíše opravdu sémanticky. Ještě lépe to bude patrné z příkladu, ve kterém se vždy vybere původní věta „The rain in Spain falls mainly on the plain“ jako výsledek na dotazy/vzory:

The rain in Spain falls mainly on the plain
The rain in Czechia falls mainly on the plain
rainy weather in Spain, especially on plains

To by nemuselo být překvapující, protože všechny vzory obsahují podobná slova. Ovšem zajímavější je výpočet vzdáleností:

Odpověď Vzdálenost
The rain in Spain falls mainly on the plain 0
The rain in Czechia falls mainly on the plain 25
rainy weather in Spain, especially on plains 20

Co to znamená? Druhá věta se sice liší jediným slovem, ale je více odlišná od originálu, než věta třetí, která je (co se týče slovosledu), naopak naprosto odlišná. Ono rozdílové slovo (Spain/Czechia) přitom sémanticky opravdu znamená významnou změnu.

Jen pro úplnost si uveďme celý zdrojový kód tohoto příkladu:

from sentence_transformers import SentenceTransformer
import faiss
 
model = SentenceTransformer("paraphrase-MiniLM-L6-v2")
 
print(model)
 
sentences = [
    "The rain in Spain falls mainly on the plain",
    "The tesselated polygon is a special type of polygon",
    "The quick brown fox jumps over the lazy dog",
    "To be or not to be, that is the question",
    "It is a truth universally acknowledged...",
    "The goat ran down the hill"
]
 
embeddings = model.encode(sentences)
print(f"Embeddings shape: {embeddings.shape}")
 
similarities = model.similarity(embeddings, embeddings)
 
DIMENSIONS = embeddings.shape[1]
 
index = faiss.IndexFlatL2(DIMENSIONS)
index.add(embeddings)
 
print(f"Index: {index.ntotal}")
 
 
def find_similar_sentences(query_sentence, k):
    query_embedding = model.encode([query_sentence])
    distances, indices = index.search(query_embedding, k)
    print("-"*40)
    print(f"Query: {query_sentence}")
    print(f"Most {k} similar sentences:")
    for i, idx in enumerate(indices[0]):
        print(f"{i + 1}: {sentences[idx]} (Distance: {distances[0][i]})")
 
 
find_similar_sentences("The rain in Spain falls mainly on the plain", 3)
find_similar_sentences("The rain in Czechia falls mainly on the plain", 3)
find_similar_sentences("rainy weather in Spain, especially on plains", 3)
Poznámka: úplný zdrojový kód tohoto příkladu naleznete na adrese https://github.com/tisnik/most-popular-python-libs/blob/master/faiss_tran­sformers/transformer8.py.

Vypsané výsledky:

SentenceTransformer(
  (0): Transformer({'max_seq_length': 128, 'do_lower_case': False, 'architecture': 'BertModel'})
  (1): Pooling({'word_embedding_dimension': 384, 'pooling_mode_cls_token': False, 'pooling_mode_mean_tokens': True, 'pooling_mode_max_tokens': False, 'pooling_mode_mean_sqrt_len_tokens': False, 'pooling_mode_weightedmean_tokens': False, 'pooling_mode_lasttoken': False, 'include_prompt': True})
)
Embeddings shape: (6, 384)
Index: 6
----------------------------------------
Query: The rain in Spain falls mainly on the plain
Most 3 similar sentences:
1: The rain in Spain falls mainly on the plain (Distance: 9.972630360399748e-12)
2: To be or not to be, that is the question (Distance: 76.49514770507812)
3: The tesselated polygon is a special type of polygon (Distance: 86.21101379394531)
----------------------------------------
Query: The rain in Czechia falls mainly on the plain
Most 3 similar sentences:
1: The rain in Spain falls mainly on the plain (Distance: 25.665851593017578)
2: To be or not to be, that is the question (Distance: 77.630126953125)
3: The tesselated polygon is a special type of polygon (Distance: 78.29695129394531)
----------------------------------------
Query: rainy weather in Spain, especially on plains
Most 3 similar sentences:
1: The rain in Spain falls mainly on the plain (Distance: 20.314910888671875)
2: To be or not to be, that is the question (Distance: 80.71918487548828)
3: The tesselated polygon is a special type of polygon (Distance: 95.1287841796875)

17. Věty s podobným významem, ovšem zapsané naprosto odlišným způsobem

Ještě více jsou vlastnosti modelu (a částečně i knihovny FAISS) patrné při hledání, která věta z původního souboru nejlépe odpovídá větě „What is your age?“. Výsledek bude znít – nejpodobnější je věta „How old are you?“ a dokonce i (sémantická) vzdálenost mezi těmito dvěma větami je relativně malá – necelých 14 jednotek.

Poznámka: za povšimnutí stojí, že tyto věty nemají společné ani jedno slovo a veškerá práce tedy byla vykonána modelem a nikoli nějakou interní formou textového porovnávání.

Opět si pro úplnost uveďme celý zdrojový kód tohoto demonstračního příkladu:

from sentence_transformers import SentenceTransformer
import faiss
 
model = SentenceTransformer("paraphrase-MiniLM-L6-v2")
 
print(model)
 
sentences = [
    "The rain in Spain falls mainly on the plain",
    "The tesselated polygon is a special type of polygon",
    "The quick brown fox jumps over the lazy dog",
    "To be or not to be, that is the question",
    "It is a truth universally acknowledged...",
    "How old are you?",
    "The goat ran down the hill"
]
 
embeddings = model.encode(sentences)
print(f"Embeddings shape: {embeddings.shape}")
 
similarities = model.similarity(embeddings, embeddings)
 
DIMENSIONS = embeddings.shape[1]
 
index = faiss.IndexFlatL2(DIMENSIONS)
index.add(embeddings)
 
print(f"Index: {index.ntotal}")
 
 
def find_similar_sentences(query_sentence, k):
    query_embedding = model.encode([query_sentence])
    distances, indices = index.search(query_embedding, k)
    print("-"*40)
    print(f"Query: {query_sentence}")
    print(f"Most {k} similar sentences:")
    for i, idx in enumerate(indices[0]):
        print(f"{i + 1}: {sentences[idx]} (Distance: {distances[0][i]})")
 
 
find_similar_sentences("What is your age?", 3)
Poznámka: úplný zdrojový kód tohoto příkladu naleznete na adrese https://github.com/tisnik/most-popular-python-libs/blob/master/faiss_tran­sformers/transformer9.py.

Po spuštění dostaneme zprávy:

SentenceTransformer(
  (0): Transformer({'max_seq_length': 128, 'do_lower_case': False, 'architecture': 'BertModel'})
  (1): Pooling({'word_embedding_dimension': 384, 'pooling_mode_cls_token': False, 'pooling_mode_mean_tokens': True, 'pooling_mode_max_tokens': False, 'pooling_mode_mean_sqrt_len_tokens': False, 'pooling_mode_weightedmean_tokens': False, 'pooling_mode_lasttoken': False, 'include_prompt': True})
)
Embeddings shape: (7, 384)
Index: 7
----------------------------------------
Query: What is your age?
Most 3 similar sentences:
1: How old are you? (Distance: 13.968358993530273)
2: To be or not to be, that is the question (Distance: 69.80447387695312)
3: The tesselated polygon is a special type of polygon (Distance: 92.14169311523438)

18. Vyhledávání na základě kontextu (zobecnění provedené modelem)

Poslední příklad, který si dnes uvedeme, bude ještě zajímavější. Provedeme totiž vyhledávání na základě jediného slova. Tato slova i odpovědi skriptu (tedy nejbližší věty) jsou uvedeny v tabulce:

Slovo Model našel
Shakespeare To be or not to be, that is the question
animal The goat ran down the hill popř. se stejnou vzdáleností The quick brown fox jumps over the lazy dog
geometry The tesselated polygon is a special type of polygon
weather The rain in Spain falls mainly on the plain
Poznámka: to je skutečně zajímavé – model musí ve svých vektorech s pouze 384 prvky mít nějakým způsobem zakódován odkaz na Shakespeara, zobecnění pojmů zvíře, počasí, geometrie atd.

Celý příklad vypadá takto:

from sentence_transformers import SentenceTransformer
import faiss
 
model = SentenceTransformer("paraphrase-MiniLM-L6-v2")
 
print(model)
 
sentences = [
    "The rain in Spain falls mainly on the plain",
    "The tesselated polygon is a special type of polygon",
    "The quick brown fox jumps over the lazy dog",
    "To be or not to be, that is the question",
    "It is a truth universally acknowledged...",
    "How old are you?",
    "The goat ran down the hill"
]
 
embeddings = model.encode(sentences)
print(f"Embeddings shape: {embeddings.shape}")
 
similarities = model.similarity(embeddings, embeddings)
 
DIMENSIONS = embeddings.shape[1]
 
index = faiss.IndexFlatL2(DIMENSIONS)
index.add(embeddings)
 
print(f"Index: {index.ntotal}")
 
 
def find_similar_sentences(query_sentence, k):
    query_embedding = model.encode([query_sentence])
    distances, indices = index.search(query_embedding, k)
    print("-"*40)
    print(f"Query: {query_sentence}")
    print(f"Most {k} similar sentences:")
    for i, idx in enumerate(indices[0]):
        print(f"{i + 1}: {sentences[idx]} (Distance: {distances[0][i]})")
 
 
find_similar_sentences("Shakespeare", 3)
find_similar_sentences("animal", 3)
find_similar_sentences("geometry", 3)
find_similar_sentences("weather", 3)
Poznámka: úplný zdrojový kód tohoto příkladu naleznete na adrese https://github.com/tisnik/most-popular-python-libs/blob/master/faiss_tran­sformers/transformerA.py.

19. Repositář s demonstračními příklady

Demonstrační příklady z dnešního článku lze nalézt na následujících odkazech:

# Příklad Stručný popis Adresa
1 transformer1.py inicializace modelu paraphrase-MiniLM-L6-v2 přes knihovnu sentence-transformers s výpisem základních informací o něm https://github.com/tisnik/most-popular-python-libs/blob/master/faiss-transfomers/transformer1.py
2 transformer2.py inicializace modelu all-mpnet-base-v2 přes knihovnu sentence-transformers s výpisem základních informací o něm https://github.com/tisnik/most-popular-python-libs/blob/master/faiss-transfomers/transformer2.py
3 transformer3.py inicializace modelu Seznam/small-e-czech přes knihovnu sentence-transformers s výpisem základních informací o něm https://github.com/tisnik/most-popular-python-libs/blob/master/faiss-transfomers/transformer3.py
4 transformer4.py vektorizace textů (vět) přes knihovnu sentence-transformers s využitím zvoleného modelu https://github.com/tisnik/most-popular-python-libs/blob/master/faiss-transfomers/transformer4.py
5 transformer5.py informace o vypočtené matici s vektorizovaným textem (embedding) https://github.com/tisnik/most-popular-python-libs/blob/master/faiss-transfomers/transformer5.py
6 transformer6.py výpočet a zobrazení vypočtené tabulky podobností https://github.com/tisnik/most-popular-python-libs/blob/master/faiss-transfomers/transformer6.py
7 transformer7.py nalezení významově nejpodobnějších vět s využitím vektorizované databáze textů https://github.com/tisnik/most-popular-python-libs/blob/master/faiss-transfomers/transformer7.py
8 transformer8.py nalezení významově nejpodobnějších vět s využitím vektorizované databáze textů https://github.com/tisnik/most-popular-python-libs/blob/master/faiss-transfomers/transformer8.py
9 transformer9.py nalezení vět nejbližších k zadanému termínu https://github.com/tisnik/most-popular-python-libs/blob/master/faiss-transfomers/transformer9.py
10 transformerA.py podpora pro hledání na základě sémantické podobnosti https://github.com/tisnik/most-popular-python-libs/blob/master/faiss-transfomers/transformerA.py
       
11 pyproject.toml soubor s projektem a definicí všech potřebných závislostí https://github.com/tisnik/most-popular-python-libs/blob/master/faiss-transfomers/pyproject.toml

Demonstrační příklady vytvořené v Pythonu a popsané v předchozím i v článku FAISS: knihovna pro rychlé a efektivní vyhledávání podobných vektorů (2. část) https://github.com/tisnik/most-popular-python-libs/. Následují odkazy na jednotlivé příklady:

# Příklad Stručný popis Adresa
1 faiss-1.py seznamy souřadnic bodů v rovině https://github.com/tisnik/most-popular-python-libs/blob/master/faiss/faiss-1.py
2 faiss-2.py konstrukce matice se souřadnicemi bodů https://github.com/tisnik/most-popular-python-libs/blob/master/faiss/faiss-2.py
3 faiss-3.py konstrukce indexu pro vyhledávání na základě vzdálenosti https://github.com/tisnik/most-popular-python-libs/blob/master/faiss/faiss-3.py
4 faiss-4.py nalezení nejbližších bodů k zadaným souřadnicím – výpis indexů nalezených bodů https://github.com/tisnik/most-popular-python-libs/blob/master/faiss/faiss-4.py
5 faiss-5.py nalezení nejbližších bodů k zadaným souřadnicím – výpis souřadnic nalezených bodů https://github.com/tisnik/most-popular-python-libs/blob/master/faiss/faiss-5.py
6 faiss-6.py vyhledávání bodů na základě skalárního součinu bez normalizace vektorů https://github.com/tisnik/most-popular-python-libs/blob/master/faiss/faiss-6.py
7 faiss-7.py vyhledávání bodů na základě skalárního součinu s normalizací vektorů https://github.com/tisnik/most-popular-python-libs/blob/master/faiss/faiss-7.py
8 faiss-8.py jednoduchý benchmark rychlosti vyhledávání knihovnou FAISS https://github.com/tisnik/most-popular-python-libs/blob/master/faiss/faiss-8.py
     
9 faiss-9.py vizualizace koncových bodů vektorů v rovině https://github.com/tisnik/most-popular-python-libs/blob/master/faiss/faiss-9.py
10 faiss-A.py vykreslení nejpodobnějších vektorů získaných na základě L2 metriky https://github.com/tisnik/most-popular-python-libs/blob/master/faiss/faiss-A.py
11 faiss-B.py nalezení nejpodobnějších vektorů získaných na základě skalárního součinu: varianta s nenormovanými vektory https://github.com/tisnik/most-popular-python-libs/blob/master/faiss/faiss-B.py
12 faiss-C.py nalezení nejpodobnějších vektorů získaných na základě skalárního součinu: varianta s normovanými vektory https://github.com/tisnik/most-popular-python-libs/blob/master/faiss/faiss-C.py
13 faiss-D.py vykreslení nejpodobnějších vektorů před jejich normalizací https://github.com/tisnik/most-popular-python-libs/blob/master/faiss/faiss-D.py
14 faiss-E.py vykreslení vektorů formou orientovaných šipek https://github.com/tisnik/most-popular-python-libs/blob/master/faiss/faiss-E.py
15 faiss-F.py vykreslení vektorů po jejich normalizaci formou orientovaných šipek https://github.com/tisnik/most-popular-python-libs/blob/master/faiss/faiss-F.py
16 faiss-G.py vyhledání a vykreslení nejvíce NEpodobných vektorů https://github.com/tisnik/most-popular-python-libs/blob/master/faiss/faiss-G.py
17 faiss-H.py vyhledání podobných vektorů se složkami typu float16 https://github.com/tisnik/most-popular-python-libs/blob/master/faiss/faiss-H.py
18 faiss-I.py jednoduchý benchmark rychlosti vyhledávání knihovnou FAISS: rozdíly mezi float16 a float32 https://github.com/tisnik/most-popular-python-libs/blob/master/faiss/faiss-I.py
     
19 pyproject.toml soubor s projektem a definicí závislostí https://github.com/tisnik/most-popular-python-libs/blob/master/faiss/pyproject.toml

20. Odkazy na Internetu

  1. FAISS: knihovna pro rychlé a efektivní vyhledávání podobných vektorů
    https://www.root.cz/clanky/faiss-knihovna-pro-rychle-a-efektivni-vyhledavani-podobnych-vektoru/
  2. FAISS: knihovna pro rychlé a efektivní vyhledávání podobných vektorů (2. část)
    https://www.root.cz/clanky/faiss-knihovna-pro-rychle-a-efektivni-vyhledavani-podobnych-vektoru-2-cast/
  3. FAISS (Facebook AI Similarity Search)
    https://en.wikipedia.org/wiki/FAISS
  4. FAISS documentation
    https://faiss.ai/
  5. Introduction to Facebook AI Similarity Search (Faiss)
    https://www.pinecone.io/le­arn/series/faiss/faiss-tutorial/
  6. Faiss: Efficient Similarity Search and Clustering of Dense Vectors
    https://medium.com/@pankaj_pan­dey/faiss-efficient-similarity-search-and-clustering-of-dense-vectors-dace1df1e235
  7. Cosine Distance vs Dot Product vs Euclidean in vector similarity search
    https://medium.com/data-science-collective/cosine-distance-vs-dot-product-vs-euclidean-in-vector-similarity-search-227a6db32edb
  8. F16C
    https://en.wikipedia.org/wiki/F16C
  9. FP16 (AVX-512)
    https://en.wikipedia.org/wiki/AVX-512#FP16
  10. Top 8 Vector Databases in 2025: Features, Use Cases, and Comparisons
    https://synapsefabric.com/top-8-vector-databases-in-2025-features-use-cases-and-comparisons/
  11. Is FAISS a Vector Database? Complete Guide
    https://mljourney.com/is-faiss-a-vector-database-complete-guide/
  12. Vector database
    https://en.wikipedia.org/wi­ki/Vector_database
  13. Similarity search
    https://en.wikipedia.org/wi­ki/Similarity_search
  14. Nearest neighbor search
    https://en.wikipedia.org/wi­ki/Nearest_neighbor_search#Ap­proximation_methods
  15. Decoding Similarity Search with FAISS: A Practical Approach
    https://www.luminis.eu/blog/decoding-similarity-search-with-faiss-a-practical-approach/
  16. MetricType and distances
    https://github.com/facebo­okresearch/faiss/wiki/Metric­Type-and-distances
  17. RAG – Retrieval-augmented generation
    https://en.wikipedia.org/wi­ki/Retrieval-augmented_generation
  18. pgvector na GitHubu
    https://github.com/pgvector/pgvector
  19. Why we replaced Pinecone with PGVector
    https://www.confident-ai.com/blog/why-we-replaced-pinecone-with-pgvector
  20. PostgreSQL as VectorDB – Beginner Tutorial
    https://www.youtube.com/wat­ch?v=Ff3tJ4pJEa4
  21. What is a Vector Database? (neobsahuje odpověď na otázku v titulku :-)
    https://www.youtube.com/wat­ch?v=t9IDoenf-lo
  22. PGVector: Turn PostgreSQL Into A Vector Database
    https://www.youtube.com/wat­ch?v=j1QcPSLj7u0
  23. Milvus
    https://milvus.io/
  24. Vector Databases simply explained! (Embeddings & Indexes)
    https://www.youtube.com/wat­ch?v=dN0lsF2cvm4
  25. Vector databases are so hot right now. WTF are they?
    https://www.youtube.com/wat­ch?v=klTvEwg3oJ4
  26. Step-by-Step Guide to Installing “pgvector” and Loading Data in PostgreSQL
    https://medium.com/@besttechreads/step-by-step-guide-to-installing-pgvector-and-loading-data-in-postgresql-f2cffb5dec43
  27. Best 17 Vector Databases for 2025
    https://lakefs.io/blog/12-vector-databases-2023/
  28. Top 15 Vector Databases that You Must Try in 2025
    https://www.geeksforgeeks.org/top-vector-databases/
  29. Picking a vector database: a comparison and guide for 2023
    https://benchmark.vectorvi­ew.ai/vectordbs.html
  30. Top 9 Vector Databases as of Feburary 2025
    https://www.shakudo.io/blog/top-9-vector-databases
  31. What is a vector database?
    https://www.ibm.com/think/to­pics/vector-database
  32. SQL injection
    https://en.wikipedia.org/wi­ki/SQL_injection
  33. Cosine similarity
    https://en.wikipedia.org/wi­ki/Cosine_similarity
  34. Euclidean distance
    https://en.wikipedia.org/wi­ki/Euclidean_distance
  35. Dot product
    https://en.wikipedia.org/wi­ki/Dot_product
  36. Hammingova vzdálenost
    https://cs.wikipedia.org/wi­ki/Hammingova_vzd%C3%A1le­nost
  37. Jaccard index
    https://en.wikipedia.org/wi­ki/Jaccard_index
  38. Manhattanská metrika
    https://cs.wikipedia.org/wi­ki/Manhattansk%C3%A1_metri­ka
  39. pgvector: vektorová databáze postavená na Postgresu
    https://www.root.cz/clanky/pgvector-vektorova-databaze-postavena-na-postgresu/
  40. Matplotlib Home Page
    http://matplotlib.org/
  41. matplotlib (Wikipedia)
    https://en.wikipedia.org/wi­ki/Matplotlib
  42. Dot Product
    https://mathworld.wolfram­.com/DotProduct.html
  43. FAISS and sentence-transformers in 5 Minutes
    https://www.stephendiehl.com/pos­ts/faiss/
  44. Sentence Transformer: Quickstart
    https://sbert.net/docs/qu­ickstart.html#sentence-transformer
  45. Sentence Transformers: Embeddings, Retrieval, and Reranking
    https://pypi.org/project/sentence-transformers/
  46. uv
    https://docs.astral.sh/uv/
  47. A Gentle Introduction to Retrieval Augmented Generation (RAG)
    https://wandb.ai/cosmo3769/RAG/re­ports/A-Gentle-Introduction-to-Retrieval-Augmented-Generation-RAG---Vmlldzo1MjM4Mjk1
  48. The Beginner’s Guide to Text Embeddings
    https://www.deepset.ai/blog/the-beginners-guide-to-text-embeddings
  49. What are Word Embeddings?
    https://www.youtube.com/wat­ch?v=wgfSDrqYMJ4
  50. How to choose an embedding model
    https://www.youtube.com/wat­ch?v=djp4205tHGU
  51. What is a Vector Database? Powering Semantic Search & AI Applications
    https://www.youtube.com/wat­ch?v=gl1r1XV0SLw
  52. How do Sentence Transformers differ from traditional word embedding models like Word2Vec or GloVe?
    https://zilliz.com/ai-faq/how-do-sentence-transformers-differ-from-traditional-word-embedding-models-like-word2vec-or-glove
  53. BERT (language model)
    https://en.wikipedia.org/wi­ki/BERT_(language_model)
  54. Levenštejnova vzdálenost
    https://cs.wikipedia.org/wi­ki/Leven%C5%A1tejnova_vzd%C3%A1le­nost
Neutrální ikona do widgetu na odběr článků ze seriálů

Zajímá vás toto téma? Chcete se o něm dozvědět víc?

Objednejte si upozornění na nově vydané články do vašeho mailu. Žádný článek vám tak neuteče.


Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.