Knihovna FAISS a embedding: základ jazykových modelů (2. část)

5. 8. 2025
Doba čtení: 34 minut

Sdílet

Autor: Root.cz s využitím DALL-E
Dnes si vyzkoušíme, jak se knihovny FAISS a Sentence-transformers chovají v situacích, v nichž je použita datová sada s velkým počtem vět, konkrétně s cca jedním milionem anglických vět.

Obsah

1. Knihovna FAISS a embedding: základ jazykových modelů (2. část)

2. Úprava projektu – přidání nových závislostí

3. Datová sada s jedním milionem anglických vět

4. Získání vybrané datové sady polygraf-ai/human-sentences-1M-sample-v2

5. Slovník s datovými sadami vs. jedna datová sada

6. Konstrukce běžného Pythonovského seznamu s větami

7. Hledání nejpodobnějších vět v celé datové sadě

8. Krátké připomenutí: vyhledávání na základě výrazů s využitím sémantické podobnosti

9. Využití celé datové sady pro sémantické vyhledávání

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

11. Refaktoring pro lepší čitelnost a další rozšiřování funkcionality

12. Výsledky získané demonstračním příkladem

13. Rychlost sémantického vyhledávání

14. Rychlost embeddingu i konstrukce indexu

15. Výsledky benchmarku

16. Vektory s prvky typu float16 nebo bfloat16

17. Výsledky benchmarku

18. Velikost sady vektorů i indexu při použití prvků typu float32, float16 a bfloat16

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

20. Odkazy na Internetu

1. Knihovna FAISS a embedding: základ jazykových modelů (2. část)

V předchozím článku jsme si ukázali jeden dosti typický způsob využití knihovny FAISS. S využitím FAISSu a vhodným způsobem „vektorizovaného“ textu je totiž možné zajistit takzvané sémantické vyhledávání, které není založeno na (většinou dosti triviální) textové podobě či podobě tokenizovaného textu, ale na významu, které věty či delší texty obsahují. Základem je přitom převod původních textů s využitím vhodného modelu do podoby vektorů pevné délky (typicky se jedná o délky 256, 384, 512, 768), přičemž do hodnot konkrétních prvků je nějakým způsobem promítnuta sémantika (jak konkrétně či naopak obecně je to provedeno, do značné míry záleží na použitém modelu, kterých dnes existuje minimálně několik desítek, spíše však několik set).

Minule obsahovala naše „textová databáze“ pouze přibližně deset vět. Dnes si vyzkoušíme, jak se FAISS a taktéž knihovna Sentence-Transformers chová v situaci, když použijeme datovou sadu s mnohem větším počtem vět. Konkrétně využijeme sadu s přibližně milionem anglických vět. Při takovém rozsahu dat již bude zajímavé sledovat výkonnost obou zmíněných knihoven. A taktéž bude zajímavé zjistit, jak se vlastně změní velikost modelu v případě, že prvky vektorů (po vektorizaci textu) budou typu float16 nebo bfloat16 a nikoli float32 (což je výchozí typ).

Poznámka: typy float16 a bfloat16 jsme se zabývali v článku Brain Floating Point – nový formát uložení čísel pro strojové učení a chytrá čidla .

2. Úprava projektu – přidání nových závislostí

Ještě před tím, než si ukážeme další vlastnosti knihoven Faisssentence-transformers, je nutné provést úpravu projektu. Přidáme do něj další závislosti, konkrétně knihovny nazvané datasets a matplotlib. To se provede snadno. Buď příkazy:

uv add datasets
uv add matplotlib

Nebo lze alternativně použít správce balíčků PDM:

uv add datasets
uv add matplotlib

Projektový soubor pyproject.toml by nyní měl vypadat následovně:

[project]
name = "sentence-transformer"
version = "0.1.0"
description = "Sentence transformer demos"
authors = [
    {name = "Pavel Tisnovsky", email = "ptisnovs@redhat.com"},
]
dependencies = [
    "datasets&=4.0.0",
    "faiss-cpu&=1.11.0.post1",
    "matplotlib&=3.10.5",
    "sentence-transformers&=5.0.0",
]
requires-python = "==3.12.*"
readme = "README.md"
license = {text = "MIT"}
 
 
[tool.pdm]
distribution = false
Poznámka: nástroj uv ve skutečnosti všechny závislosti zapisuje na jediném řádku – neprovádí formátování projektového souboru.

3. Datová sada s jedním milionem anglických vět

V demonstračních příkladech, které jsme si ukázali v předchozím článku, se pracovalo pouze s minimalistickou „databází“ textů, která se skládala pouze z osmi vět, což skutečně při práci s reálným mluveným jazykem není mnoho:

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"
]

Dnes již budeme pracovat s mnohem větší databází. Konkrétně se bude jednat o datovou sadu polygraf-ai/human-sentences-1M-sample-v2 obsahující jeden milion anglických vět. Na tomto místě je vhodné poznamenat, že se stále jedná o relativně malou datovou sadu (například pro trénink LLM je naprosto nedostačující), ovšem pro otestování základních vlastností knihoven Faiss a sentence-transformers bude její velikost dostačující. Navíc je práce s touto datovou sadou relativně rychlá.

4. Získání vybrané datové sady polygraf-ai/human-sentences-1M-sample-v2

Datovou sadu polygraf-ai/human-sentences-1M-sample-v2 není nutné stahovat ručně, protože tuto funkci zajišťuje přímo knihovna dataset. Postačuje pouze zavolat funkci load_dataset a předat jí jednoznačný identifikátor datové sady. Knihovna automaticky zjistí, zda je datová sada dostupná na lokálním úložišti a pokud tomu tak není, provede její stažení:

from datasets import load_dataset
 
dataset_id = "polygraf-ai/human-sentences-1M-sample-v2"
 
dataset = load_dataset(dataset_id)
 
print(dataset)

Při prvním spuštění tohoto skriptu je patrné, že stažení opravdu proběhlo (cca 100 MB!):

README.md: 100%|███████████████████████████████████████████████████████████████████████████████████████| 317/317 [00:00<00:00, 1.31MB/s]
train-00000-of-00001.parquet: 100%|██████████████████████████████████████████████████████████████████| 100M/100M [00:09<00:00, 10.1MB/s]
Generating train split: 100%|████████████████████████████████████████████████████████| 997593/997593 [00:01<00:00, 926163.87 examples/s]
DatasetDict({
    train: Dataset({
        features: ['text', 'source'],
        num_rows: 997593
    })
})

Po každém dalším spuštění skriptu se pouze zobrazí informace o datové sadě:

DatasetDict({
    train: Dataset({
        features: ['text', 'source'],
        num_rows: 997593
    })
})
Poznámka: datová sada se uloží do adresáře .cache/huggingface/datasets/. Nalezneme zde i soubor se všemi anglickými větami ve formátu Arrow:
$ ls -lah human-sentences-1_m-sample-v2-train.arrow
 
-rw-r--r--. 1 ptisnovs ptisnovs 145M Jul 31 18:46 human-sentences-1_m-sample-v2-train.arrow

5. Slovník s datovými sadami vs. jedna datová sada

Předchozí skript by měl po svém spuštění vypsat informaci o tom, že ve skutečnosti nenačetl a nevrátil pouze jedinou datovou sadu, ale celý slovník datových sad s jediným prvkem:

DatasetDict({
    train: Dataset({
        features: ['text', 'source'],
        num_rows: 997593
    })
})

Sadu nazvanou train získáme snadno – předáním pojmenovaného parametru split=„train“ funkci load_dataset:

from datasets import load_dataset
 
dataset_id = "polygraf-ai/human-sentences-1M-sample-v2"
 
dataset = load_dataset(dataset_id, split="train")
 
print(dataset.features)

Po spuštění tohoto skriptu by se měly vypsat informace o sloupcích v tabulce, ve které je datová sada uložena:

{'text': Value('string'), 'source': Value('string')}

6. Konstrukce běžného Pythonovského seznamu s větami

Ukažme si ještě jeden mezikrok, který vlastně v praxi není nezbytně nutné provádět, protože je výpočetně i paměťově náročný. Nicméně je vhodné vědět, že stažená datová sada není nějakým „magickým objektem“, ale skutečným zdrojem dat. Konkrétně si necháme z datové sady vygenerovat běžný Pythonovský seznam se všemi větami (v čisté textové podobě):

from datasets import load_dataset
 
dataset_id = "polygraf-ai/human-sentences-1M-sample-v2"
 
dataset = load_dataset(dataset_id, split="train")
 
print("Building sentences")
sentences = [sentence for sentence in dataset["text"]]
 
print(f"{len(sentences)} sentences created")

Výsledek získaný po určité době (jednotky až desítky sekund):

Building sentences
997593 sentences created
Poznámka: jméno datové sady tedy není zcela přesné, protože počet vět je menší, než jeden milion.

Počet vět transformovaných do seznamu lze řídit s využitím operace řezu (slice), a to ještě před vytvořením seznamu:

from datasets import load_dataset
 
dataset_id = "polygraf-ai/human-sentences-1M-sample-v2"
 
dataset = load_dataset(dataset_id, split="train")
 
print("Building sentences")
sentences = [sentence for sentence in dataset["text"][0:100]]
 
print(f"{len(sentences)} sentences created")

Nyní získáme výsledky prakticky okamžitě:

Building sentences
100 sentences created

7. Hledání nejpodobnějších vět v celé datové sadě

V navazujících kapitolách si ukážeme, jakým způsobem je možné provádět vyhledávání vět na základě podobnosti v rámci celé datové sady s přibližně jedním milionem vět. Opět je však nutné zdůraznit, že 1000000 vět sice může vypadat jako velmi vysoká hodnota, ovšem v praxi se mnohdy pracuje i s (mnohem) většími datovými sadami. Typickým příkladem je trénink velkých jazykových modelů, což je však téma na samostatné články.

Na druhou stranu je ovšem tato hodnota již dostatečně vysoká na to, aby byly jednotlivé kroky zpracování časově náročné. Z tohoto důvodu si otestujeme rychlost (nebo spíše pomalost) vektorizace textů (embedding), rychlost konstrukce indexu knihovnou FAISS a samozřejmě i rychlost vyhledávání s využitím tohoto indexu.

8. Krátké připomenutí: vyhledávání na základě výrazů s využitím sémantické podobnosti

Jen pro připomenutí si ukažme demonstrační příklad z předchozího článku. V tomto příkladu jsme si nechali zvoleným embedding modelem „vektorizovat“ sedm vět, poté jsme knihovnou FAISS z těchto vektorů zkonstruovali index a následně jsme tento index použili při vyhledávání výrazů či celých vět na základě jejich sémantické podobnosti s původními větami:

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)

Příklad výsledků získaných po spuštění tohoto demonstračního příkladu:

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: Shakespeare
Most 3 similar sentences:
1: To be or not to be, that is the question (Distance: 83.53305053710938)
2: The tesselated polygon is a special type of polygon (Distance: 112.60221862792969)
3: The rain in Spain falls mainly on the plain (Distance: 114.61812591552734)
----------------------------------------
Query: animal
Most 3 similar sentences:
1: The goat ran down the hill (Distance: 67.3703384399414)
2: The quick brown fox jumps over the lazy dog (Distance: 68.25883483886719)
3: To be or not to be, that is the question (Distance: 82.82962036132812)
----------------------------------------
Query: geometry
Most 3 similar sentences:
1: The tesselated polygon is a special type of polygon (Distance: 51.57851791381836)
2: To be or not to be, that is the question (Distance: 91.08709716796875)
3: The goat ran down the hill (Distance: 109.95413208007812)
----------------------------------------
Query: weather
Most 3 similar sentences:
1: The rain in Spain falls mainly on the plain (Distance: 73.53900146484375)
2: To be or not to be, that is the question (Distance: 86.14794921875)
3: How old are you? (Distance: 101.28636169433594)

9. Využití celé datové sady pro sémantické vyhledávání

Podívejme se nyní, jak se datová sada polygraf-ai/human-sentences-1M-sample-v2 využije v praxi pro embedding i pro tvorbu indexu pro knihovnu FAISS. Celý skript je rozdělen do několika samostatných kroků.

V prvním kroku inicializujeme model, jenž bude využitý pro embedding, tedy pro vektorizaci celé datové sady:

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

V dalším kroku načteme, stejně jako v předchozích kapitolách, datovou sadu s cca jedním milionem vět:

from datasets import load_dataset
 
dataset = load_dataset("polygraf-ai/human-sentences-1M-sample-v2", split="train")
print(dataset)

Převedeme věty do formy běžného seznamu (můžeme i odstranit řez a převést všechny věty):

sentences = [sentence for sentence in dataset["text"][0:1000]]
print(f"{len(sentences)} sentences created")

Dále si necháme knihovnou Sentence-transformers vytvořit vektorizovanou formu vět (embedding):

embeddings = model.encode(sentences)
print(f"Embeddings shape: {embeddings.shape}")

Zbývá předposlední krok – tvorba FAISS indexu:

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

Ve chvíli, kdy je index vytvořen, již můžeme v celé databázi jednoho milionu vět provádět sémantické vyhledávání:

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("city", 3)
find_similar_sentences("animal", 3)
find_similar_sentences("geometry", 3)
find_similar_sentences("weather", 3)
find_similar_sentences("game", 3)
find_similar_sentences("school", 3)

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

Úplný zdrojový kód demonstračního příkladu popsaného v předchozí kapitole vypadá následovně:

from sentence_transformers import SentenceTransformer
import faiss
from datasets import load_dataset
 
 
model = SentenceTransformer("paraphrase-MiniLM-L6-v2")
print(model)
 
dataset = load_dataset("polygraf-ai/human-sentences-1M-sample-v2", split="train")
print(dataset)
 
sentences = [sentence for sentence in dataset["text"][0:1000]]
print(f"{len(sentences)} sentences created")
 
embeddings = model.encode(sentences)
print(f"Embeddings shape: {embeddings.shape}")
 
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("city", 3)
find_similar_sentences("animal", 3)
find_similar_sentences("geometry", 3)
find_similar_sentences("weather", 3)
find_similar_sentences("game", 3)
find_similar_sentences("school", 3)

11. Refaktoring pro lepší čitelnost a další rozšiřování funkcionality

Demonstrační příklad z předchozí kapitoly je sice funkční, ale není příliš čitelný ani rozšiřitelný. Z těchto důvodů ho nepatrně přepíšeme takovým způsobem, že každý krok bude realizován ve zvláštní funkci. Takto upravený zdrojový kód bude použitelný i pro další účely – měření času, benchmarky, zjištění velikosti vektorizovaného textu i FAISS indexu atd.:

from sentence_transformers import SentenceTransformer
import faiss
from datasets import load_dataset
 
MODEL_NAME = "paraphrase-MiniLM-L6-v2"
DATASET_ID = "polygraf-ai/human-sentences-1M-sample-v2"
 
 
def initialize_model(model_name):
    print("Model initialization started")
    model = SentenceTransformer(model_name)
    print(model)
    print("Model initialization finished")
    return model
 
 
def load_dataset_by_id(dataset_id):
    print("Loading dataset started")
    dataset = load_dataset(dataset_id, split="train")
    print("Loading dataset finished")
    return dataset
 
 
def build_sentences(dataset, from_, to_):
    print("Building sentences")
    sentences = [sentence for sentence in dataset["text"][from_:to_]]
    print(f"{len(sentences)} sentences created")
    return sentences
 
 
def create_embeddings(model, sentences):
    print("Embedding started")
    embeddings = model.encode(sentences)
    print(f"Embeddings shape: {embeddings.shape}")
    print("Embedding finished")
    return embeddings
 
 
def create_faiss_index(embeddings):
    print("FAISS index construction started")
    DIMENSIONS = embeddings.shape[1]
    index = faiss.IndexFlatL2(DIMENSIONS)
    index.add(embeddings)
    print(f"Index: {index.ntotal}")
    print("FAISS index construction finished")
    return index
 
 
def find_similar_sentences(model, index, 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]})")
 
 
model = initialize_model(MODEL_NAME)
dataset = load_dataset_by_id(DATASET_ID)
sentences = build_sentences(dataset, 0, 1000)
embeddings = create_embeddings(model, sentences)
index = create_faiss_index(embeddings)
 
find_similar_sentences(model, index, "city", 3)
find_similar_sentences(model, index, "animal", 3)
find_similar_sentences(model, index, "geometry", 3)
find_similar_sentences(model, index, "weather", 3)
find_similar_sentences(model, index, "game", 3)
find_similar_sentences(model, index, "school", 3)

12. Výsledky získané demonstračním příkladem

Podívejme se nyní na výsledky, které byly získány demonstračním příkladem popsaným v předchozí kapitole. Nejprve jsou vypsány informace o tvorbě modelu, embeddingu, indexu atd:

Model initialization started
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})
)
Model initialization finished
Loading dataset started
Loading dataset finished
Building sentences
1000 sentences created
Embedding started
Embeddings shape: (1000, 384)
Embedding finished
FAISS index construction started
Index: 1000
FAISS index construction finished

Následují výsledky sémantického vyhledávání v prvních tisících větách:

----------------------------------------
Query: city
Most 3 similar sentences:
1: Do you gamble that the city will stay quiet for a few hours, or do you risk sending an undermanned team into a dangerous situation? (Distance: 59.321781158447266)
2: "Please respond" said: "Sam - do yourself a favor and contact Pleasanton city management and they will confirm that personnel costs have increased from the 65% range to 77% due to the significant increase of personnel costs in and of themselves." (Distance: 59.33335876464844)
3: Mayor of Hartford and subsequent career Upon the death of John A. Pilgard—who died only nine days after being elected and before he could take office—Spellacy was elected mayor of Hartford in 1935 by the Board of Aldermen. (Distance: 59.40525817871094)
----------------------------------------
Query: animal
Most 3 similar sentences:
1: Prolific fly tyer Blane Chocklett of the TFO Advisory Staff, was integral in the design of the “Esox” rod and brings forth a wealth of knowledge from years of chasing toothy, carnivorous fish. (Distance: 55.286163330078125)
2: In contrast to tunicates and echinoderms, the MRCA of vertebrates is thought to have resembled a lancelet, which is pelagic and which has a more advanced nervous system than adult tunicates or echinoderms. (Distance: 56.6212158203125)
3: Rare Alnskan Bird’s Nest and Eggs Found Ornithologists have just succeeded in finding the nest and eggs of the rare surf bird of Alaska, though the bird itself has been known to science for a century and a half. (Distance: 58.14012145996094)
----------------------------------------
Query: geometry
Most 3 similar sentences:
1: In the present work we show that this is indeed the case and that for spherically symmetric spacetimes there are several inequivalent representations possible. (Distance: 53.43998718261719)
2: Geometric intuition plays an important role in many aspects of Hilbert space theory. (Distance: 54.873863220214844)
3: To further confirm these projection pulses are able to correctly construct a robust density matrix, a tomographic Rabi Chevron map is performed in Figure 2c,d, combined with the calibration technique described above. (Distance: 56.672767639160156)
----------------------------------------
Query: weather
Most 3 similar sentences:
1: In late fall and early winter, they’ve given that heat up, back into the atmosphere. (Distance: 48.415863037109375)
2: Traffic patterns are flown at one specific altitude, usually 800 or 1,000 ft (244 or 305 m) above ground level (AGL). (Distance: 58.13227081298828)
3: Considered an exploratory species Arabian oryx exhibit highly flexible home ranges with large distance migration being observed after rainfall (mostly during spring in Saudi Arabia) while it will contract again during hot and dry periods (e.g. (Distance: 65.33474731445312)
----------------------------------------
Query: game
Most 3 similar sentences:
1: But also to give my players a chance to continue playing with the character they are invested in. (Distance: 45.21950912475586)
2: In contrast, Go is ancient board game that consists of simple elements (a line and circle, black and white colors, and stone and wood materials) combined with simple rules that generate subtleties that have enthralled players for millennia \[[@CR5]\]. (Distance: 49.22539138793945)
3: Differing skill levels of players made it work. (Distance: 51.900543212890625)
----------------------------------------
Query: school
Most 3 similar sentences:
1: Three of my children have progressed through the PPS (soon my youngest will finish at Allderdice) and I was happy with their middle schools being separate from high school. (Distance: 44.28334045410156)
2: When afternoon school began Mr. Porson placed on the desk before him a packet done up in brown paper. (Distance: 54.15468978881836)
3: In response to these considerations, we propose to conduct an innovative multi-measure longitudinal study of a national sample of medical students in order to examine the impact of medical school factors, independent of individual medical student characteristics, on implicit and explicit racial bias in medical students' judgments and decisions. (Distance: 54.777183532714844)

13. Rychlost sémantického vyhledávání

V praxi je velmi často důležité zajistit, aby samotné sémantické vyhledávání bylo co nejrychlejší, k čemuž v knihovně FAISS slouží několik speciálních datových struktur a algoritmů (blíže se s nimi seznámíme příště). Nepatrnou úpravou demonstračního příkladu můžeme zjistit časy vyhledávání a ty následně vypsat:

from sentence_transformers import SentenceTransformer
import faiss
from datasets import load_dataset
from time import time
 
MODEL_NAME = "paraphrase-MiniLM-L6-v2"
DATASET_ID = "polygraf-ai/human-sentences-1M-sample-v2"
 
 
def initialize_model(model_name):
    print("Model initialization started")
    model = SentenceTransformer(model_name)
    print(model)
    print("Model initialization finished")
    return model
 
 
def load_dataset_by_id(dataset_id):
    print("Loading dataset started")
    dataset = load_dataset(dataset_id, split="train")
    print("Loading dataset finished")
    return dataset
 
 
def build_sentences(dataset, from_, to_):
    print("Building sentences")
    sentences = [sentence for sentence in dataset["text"][from_:to_]]
    print(f"{len(sentences)} sentences created")
    return sentences
 
 
def create_embeddings(model, sentences):
    print("Embedding started")
    embeddings = model.encode(sentences)
    print(f"Embeddings shape: {embeddings.shape}")
    print("Embedding finished")
    return embeddings
 
 
def create_faiss_index(embeddings):
    print("FAISS index construction started")
    DIMENSIONS = embeddings.shape[1]
    index = faiss.IndexFlatL2(DIMENSIONS)
    index.add(embeddings)
    print(f"Index: {index.ntotal}")
    print("FAISS index construction finished")
    return index
 
 
def find_similar_sentences(model, index, query_sentence, k):
    t1 = time()
    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]})")
    t2 = time()
    print(f"Finished in {t2-t1:3.2} seconds")
 
 
model = initialize_model(MODEL_NAME)
dataset = load_dataset_by_id(DATASET_ID)
sentences = build_sentences(dataset, 0, 100000)
embeddings = create_embeddings(model, sentences)
index = create_faiss_index(embeddings)
 
find_similar_sentences(model, index, "city", 3)
find_similar_sentences(model, index, "animal", 3)
find_similar_sentences(model, index, "geometry", 3)
find_similar_sentences(model, index, "weather", 3)
find_similar_sentences(model, index, "game", 3)
find_similar_sentences(model, index, "school", 3)
Poznámka: nyní je datová sada větší – 100000 vět.

Výsledky:

Model initialization started
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})
)
Model initialization finished
Loading dataset started
Loading dataset finished
Building sentences
100000 sentences created
Embedding started
Embeddings shape: (100000, 384)
Embedding finished
FAISS index construction started
Index: 100000
FAISS index construction finished
----------------------------------------
Query: city
Most 3 similar sentences:
1: Which is the best city in the world? (Distance: 34.68456268310547)
2: Which city do you come from? (Distance: 36.576637268066406)
3: That’s more than the population of the city. (Distance: 39.577919006347656)
Finished in 0.025 seconds
----------------------------------------
Query: animal
Most 3 similar sentences:
1: The animal comes from an early branch of the mammal family, and like mammals it is covered in fur and produces milk. (Distance: 36.88507843017578)
2: If an animal determines that you are indeed a human its game over. (Distance: 38.494911193847656)
3: State the animal mentioned in the sentence above." (Distance: 39.17326354980469)
Finished in 0.027 seconds
----------------------------------------
Query: geometry
Most 3 similar sentences:
1: One obtains a physical geometry as a deformation of some standard geometry, which is axiomatizable and physical simultaneously. (Distance: 36.97258377075195)
2: Later published in Discrete and Computational Geometry. (Distance: 40.11151123046875)
3: of Lagrange, Euler and collision points on a geometrically unfaithful depiction of the shape sphere S 2 . (Distance: 43.62152862548828)
Finished in 0.025 seconds
----------------------------------------
Query: weather
Most 3 similar sentences:
1: Daytime highs in the winter range between 64 and 75 °F (18 and 24 °C), with overnight lows between 30 and 44 °F (−1 and 7 °C). (Distance: 40.27581787109375)
2: Winters are cool and wet, with summers mild and also wet. (Distance: 40.89495086669922)
3: He sends rain in summer, snow in winter, and all the changes of weather in their season. (Distance: 42.138771057128906)
Finished in 0.031 seconds
----------------------------------------
Query: game
Most 3 similar sentences:
1: What would be the point of continuing the game? (Distance: 36.408992767333984)
2: The game has a lot of varieties that is either a curse or a blessing to the game. (Distance: 39.20246124267578)
3: Great games, but do not underestimate player frustrations. (Distance: 39.954978942871094)
Finished in 0.038 seconds
----------------------------------------
Query: school
Most 3 similar sentences:
1: But nonetheless, school is beginning or already under way for fully one in four American youngsters and adults enrolled in the nation’s more than 95,000 public elementary and secondary schools, 3,200 charter schools and nearly 4,300 degree-granting colleges, as well as for the 1.1 million who are home-schooled. (Distance: 36.799034118652344)
2: A great thing about this school is all of the clubs and activities available. (Distance: 37.57196044921875)
3: It now houses students in grades Year 1 to Year 11 and Kindergarten. (Distance: 38.36991500854492)
Finished in 0.029 seconds
Poznámka: prozatím tedy časy vyhledávání nepřesahují jednu desetinu sekundy, ovšem společně s rostoucím počtem vektorů bude i tento čas narůstat.

14. Rychlost embeddingu i konstrukce indexu

Časy sémantického vyhledávání, které jsme zjišťovali v předchozím textu, jsou velmi důležité v praxi, ovšem při tvorbě modelů a indexů (což není tak častá operace) je důležité vědět i to, jak dlouho tyto dvě operace trvají. Opět si pro tyto účely vytvoříme jednoduchý benchmark. Tentokrát budeme zjišťovat, kolik času trvá vektorizace n vět i tvorba FAISS indexu z výsledné sady vektorů. Výsledky budou zobrazeny knihovnou Matplotlib pomocí dvojice grafů (každý totiž bude mít zcela odlišné časové měřítko na vertikální ose, proto nemá velký význam vše zobrazit v grafu jediném). Implementace benchmarku vypadá následovně:

from sentence_transformers import SentenceTransformer
import faiss
from datasets import load_dataset
from time import time
import numpy as np
 
import matplotlib.pyplot as plt
 
MODEL_NAME = "paraphrase-MiniLM-L6-v2"
DATASET_ID = "polygraf-ai/human-sentences-1M-sample-v2"
 
 
def initialize_model(model_name):
    print("Model initialization started")
    model = SentenceTransformer(model_name)
    print(model)
    print("Model initialization finished")
    return model
 
 
def load_dataset_by_id(dataset_id):
    print("Loading dataset started")
    dataset = load_dataset(dataset_id, split="train")
    print("Loading dataset finished")
    return dataset
 
 
def build_sentences(dataset, from_, to_):
    print("Building sentences")
    sentences = [sentence for sentence in dataset["text"][from_:to_]]
    print(f"{len(sentences)} sentences created")
    return sentences
 
 
def create_embeddings(model, sentences):
    t1 = time()
    print("Embedding started")
    embeddings = model.encode(sentences)
    print(f"Embeddings shape: {embeddings.shape}")
    print("Embedding finished")
    t2 = time()
    return embeddings, t2-t1
 
 
def create_faiss_index(embeddings):
    t1 = time()
    print("FAISS index construction started")
    DIMENSIONS = embeddings.shape[1]
    index = faiss.IndexFlatL2(DIMENSIONS)
    index.add(embeddings)
    print(f"Index: {index.ntotal}")
    print("FAISS index construction finished")
    t2 = time()
    return index, t2-t1
 
 
model = initialize_model(MODEL_NAME)
dataset = load_dataset_by_id(DATASET_ID)
 
ns = []
ts_embeddings = []
ts_index = []
 
for n in np.linspace(1000, 10000, 20):
    ns.append(n)
    sentences = build_sentences(dataset, 0, int(n))
    embeddings, t_embeddings = create_embeddings(model, sentences)
    index, t_index = create_faiss_index(embeddings)
    ts_embeddings.append(t_embeddings)
    ts_index.append(t_index)
 
fig = plt.figure(figsize=(10, 10))
 
plt.subplot(2, 1, 1)
plt.plot(ns, ts_embeddings, "b-")
plt.title("Embeddings creation")
 
plt.subplot(2, 1, 2)
plt.plot(ns, ts_index, "m-", label="index creation")
plt.title("Index creation")
 
# povolení zobrazení mřížky
plt.grid(True)
 
fig.savefig("embeddings.png")
 
# zobrazení grafu
fig.show()

15. Výsledky benchmarku

Výsledky benchmarku z předchozí kapitoly (pro 1000 až 10000 vět, tedy pro relativně malé množství dat) jsou zobrazeny na následující dvojici grafů:

Benchmark: tvorba vektorizovaného textu do podoby vektorů s prvky typu float32

Obrázek 1: Výsledek benchmarku – tvorba vektorizovaného textu do podoby vektorů s prvky typu float32

Autor: tisnik, podle licence: Rights Managed

16. Vektory s prvky typu float16 nebo bfloat16

Prozatím jsme při vektorizaci textů vůbec nespecifikovali, jakého typu budou prvky vektorů (na druhou stranu počet prvků určuje model, v našem případě to je 384 prvků). Při výchozím nastavení je pro reprezentaci prvků vektorů použit datový typ float32 neboli IEEE 754 single precision. Alternativně je ovšem možné namísto tohoto typu použít float16 (IEEE 754 half precision) nebo bfloat16 (brain floating point). Tyto datové typy využívají pro uložení numerické hodnoty pouze šestnáct bitů a vektorizovaný text by tak měl být teoreticky poloviční. Ovšem důležitější je, že výpočty s těmito datovými typy budou při použití GPU rychlejší (do jaké míry rychlejší – k tomu se ještě vrátíme). Na druhou stranu při SW výpočtech (Torch CPU) bude pravděpodobně naopak docházet ke zpomalení, zejména pokud nejsou k dispozici příslušná rozšíření instrukční sady (starší mikroprocesory).

Ostatně se o tom můžeme snadno přesvědčit specifikací datového typu float16:

model = SentenceTransformer(model_name, model_kwargs={"torch_dtype": "float16"})

Celý benchmark je upraven do této podoby:

from sentence_transformers import SentenceTransformer
import faiss
from datasets import load_dataset
from time import time
import numpy as np
 
import matplotlib.pyplot as plt
 
MODEL_NAME = "paraphrase-MiniLM-L6-v2"
DATASET_ID = "polygraf-ai/human-sentences-1M-sample-v2"
 
 
def initialize_model(model_name):
    print("Model initialization started")
    model = SentenceTransformer(model_name, model_kwargs={"torch_dtype": "float16"})
    print(model)
    print("Model initialization finished")
    return model
 
 
def load_dataset_by_id(dataset_id):
    print("Loading dataset started")
    dataset = load_dataset(dataset_id, split="train")
    print("Loading dataset finished")
    return dataset
 
 
def build_sentences(dataset, from_, to_):
    print("Building sentences")
    sentences = [sentence for sentence in dataset["text"][from_:to_]]
    print(f"{len(sentences)} sentences created")
    return sentences
 
 
def create_embeddings(model, sentences):
    t1 = time()
    print("Embedding started")
    embeddings = model.encode(sentences)
    print(f"Embeddings shape: {embeddings.shape}")
    print("Embedding finished")
    t2 = time()
    return embeddings, t2-t1
 
 
def create_faiss_index(embeddings):
    t1 = time()
    print("FAISS index construction started")
    DIMENSIONS = embeddings.shape[1]
    index = faiss.IndexFlatL2(DIMENSIONS)
    index.add(embeddings)
    print(f"Index: {index.ntotal}")
    print("FAISS index construction finished")
    t2 = time()
    return index, t2-t1
 
 
model = initialize_model(MODEL_NAME)
dataset = load_dataset_by_id(DATASET_ID)
 
ns = []
ts_embeddings = []
ts_index = []
 
for n in np.linspace(1000, 10000, 20):
    ns.append(n)
    sentences = build_sentences(dataset, 0, int(n))
    embeddings, t_embeddings = create_embeddings(model, sentences)
    index, t_index = create_faiss_index(embeddings)
    ts_embeddings.append(t_embeddings)
    ts_index.append(t_index)
 
fig = plt.figure(figsize=(10, 10))
 
plt.subplot(2, 1, 1)
plt.plot(ns, ts_embeddings, "b-")
plt.title("Embeddings creation")
 
plt.subplot(2, 1, 2)
plt.plot(ns, ts_index, "m-", label="index creation")
plt.title("Index creation")
 
# povolení zobrazení mřížky
plt.grid(True)
 
fig.savefig("embeddings.png")
 
# zobrazení grafu
fig.show()

17. Výsledky benchmarku

Výsledky benchmarku z předchozí kapitoly jsou zobrazeny na následující dvojici grafů:

Benchmark: tvorba vektorizovaného textu do podoby vektorů s prvky typu float32

Obrázek 2: Výsledek benchmarku – tvorba vektorizovaného textu do podoby vektorů s prvky typu float16. Povšimněte si velkého zpomalení při implementaci na CPU.

Autor: tisnik, podle licence: Rights Managed
Poznámka: je vhodné si porovnat tento graf s grafem ze čtrnácté kapitoly. Nyní jsou časy mnohem delší, protože veškeré výpočty jsou prováděny na CPU (viz měřítko na vertikálních osách). Počet vstupných dat zůstává pochopitelně zachován.

18. Velikost sady vektorů i indexu při použití prvků typu float32, float16 a bfloat16

Pro zjištění velikostí vektorizovaného textu i indexu při použití prvků různých typů si upravíme původní skript do následující podoby, v níž se provádí uložení modelu i indexu do souboru, pochopitelně pro každý datový typ zvlášť (embeddings.dump vs. faiss.write_index):

for dtype in ["float32", "float16", "bfloat16"]:
    model = initialize_model(MODEL_NAME, dtype)
    dataset = load_dataset_by_id(DATASET_ID)
 
    sentences = build_sentences(dataset, 0, 10)
    embeddings = create_embeddings(model, sentences)
    index = create_faiss_index(embeddings)
 
    embeddings.dump(f"embeddings.{dtype}")
    faiss.write_index(index, f"index.{dtype}")

Z výsledků je patrné, že vektorizovaná datová sada je (podle očekávání) zhruba poloviční při použití float16 namísto float32 (23225/11668=1.987080767, tedy přibližně 2.0). Zajímavé je, že pro typ bfloat16 dosahuje velikost 19454 bajtů, což si vyžádá hlubší prozkoumání. Ovšem FAISS indexy jsou stejně velké: 15405 bajtů. Proč tomu tak je? Při výpočtech podobnosti pomocí L2 metriky je vyžadováno 4×d×n bajtů, kde d je dimenze vektoru a n je počet vektorů. V našem konkrétním případě tedy 4×384×10=15360, což po doplnění hlavičky vychází na 15405 bajtů:

Typ prvků vektorů Embeggings FAISS index
bfloat16 19454 15405
float16 11668 15405
float32 23225 15405

Celý skript vypadá následovně:

from sentence_transformers import SentenceTransformer
import faiss
from datasets import load_dataset
 
MODEL_NAME = "paraphrase-MiniLM-L6-v2"
DATASET_ID = "polygraf-ai/human-sentences-1M-sample-v2"
 
 
def initialize_model(model_name, dtype):
    print("Model initialization started")
    model = SentenceTransformer(model_name, model_kwargs={"torch_dtype": dtype})
    print(model)
    print("Model initialization finished")
    return model
 
 
def load_dataset_by_id(dataset_id):
    print("Loading dataset started")
    dataset = load_dataset(dataset_id, split="train")
    print("Loading dataset finished")
    return dataset
 
 
def build_sentences(dataset, from_, to_):
    print("Building sentences")
    sentences = [sentence for sentence in dataset["text"][from_:to_]]
    print(f"{len(sentences)} sentences created")
    return sentences
 
 
def create_embeddings(model, sentences):
    print("Embedding started")
    embeddings = model.encode(sentences)
    print(f"Embeddings shape: {embeddings.shape}")
    print("Embedding finished")
    return embeddings
 
 
def create_faiss_index(embeddings):
    print("FAISS index construction started")
    DIMENSIONS = embeddings.shape[1]
    index = faiss.IndexFlatL2(DIMENSIONS)
    index.add(embeddings)
    print(f"Index: {index.ntotal}")
    print("FAISS index construction finished")
    return index
 
 
for dtype in ["float32", "float16", "bfloat16"]:
    model = initialize_model(MODEL_NAME, dtype)
    dataset = load_dataset_by_id(DATASET_ID)
 
    sentences = build_sentences(dataset, 0, 1000)
    embeddings = create_embeddings(model, sentences)
    index = create_faiss_index(embeddings)
 
    embeddings.dump(f"embeddings.{dtype}")
    faiss.write_index(index, f"index.{dtype}")

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

Demonstrační příklady z předchozího i 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 dataset1.py získání datové sady s milionem anglických vět https://github.com/tisnik/most-popular-python-libs/blob/master/faiss-transfomers/dataset1.py
12 dataset2.py získání tréninkových dat s milionem anglických vět https://github.com/tisnik/most-popular-python-libs/blob/master/faiss-transfomers/dataset2.py
13 dataset3.py konstrukce Pythonovského seznamu s větami https://github.com/tisnik/most-popular-python-libs/blob/master/faiss-transfomers/dataset3.py
14 dataset4.py konstrukce Pythonovského seznamu s větami, omezení počtu vět https://github.com/tisnik/most-popular-python-libs/blob/master/faiss-transfomers/dataset4.py
       
15 transformerB.py vytvoření indexu z datové sady s milionem anglických vět https://github.com/tisnik/most-popular-python-libs/blob/master/faiss-transfomers/transformerB.py
16 transformerC.py refaktoring předchozího demonstračního příkladu https://github.com/tisnik/most-popular-python-libs/blob/master/faiss-transfomers/transformerC.py
17 transformerD.py zjištění rychlosti nalezení nejpodobnějších vět https://github.com/tisnik/most-popular-python-libs/blob/master/faiss-transfomers/transformerD.py
18 transformerE.py benchmark: rychlost embeddingu a konstrukce indexu (využití typu float32) https://github.com/tisnik/most-popular-python-libs/blob/master/faiss-transfomers/transformerE.py
19 transformerF.py benchmark: rychlost embeddingu a konstrukce indexu (využití typu float16) https://github.com/tisnik/most-popular-python-libs/blob/master/faiss-transfomers/transformerF.py
20 transformerG.py uložení modelu i indexu do souboru pro porovnání velikostí https://github.com/tisnik/most-popular-python-libs/blob/master/faiss-transfomers/transformerG.py
       
21 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. Knihovna FAISS a embedding: základ jazykových modelů
    https://www.root.cz/clanky/knihovna-faiss-a-embedding-zaklad-jazykovych-modelu/
  4. FAISS (Facebook AI Similarity Search)
    https://en.wikipedia.org/wiki/FAISS
  5. FAISS documentation
    https://faiss.ai/
  6. Introduction to Facebook AI Similarity Search (Faiss)
    https://www.pinecone.io/le­arn/series/faiss/faiss-tutorial/
  7. 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
  8. 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
  9. F16C
    https://en.wikipedia.org/wiki/F16C
  10. FP16 (AVX-512)
    https://en.wikipedia.org/wiki/AVX-512#FP16
  11. 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/
  12. Is FAISS a Vector Database? Complete Guide
    https://mljourney.com/is-faiss-a-vector-database-complete-guide/
  13. Vector database
    https://en.wikipedia.org/wi­ki/Vector_database
  14. Similarity search
    https://en.wikipedia.org/wi­ki/Similarity_search
  15. Nearest neighbor search
    https://en.wikipedia.org/wi­ki/Nearest_neighbor_search#Ap­proximation_methods
  16. Decoding Similarity Search with FAISS: A Practical Approach
    https://www.luminis.eu/blog/decoding-similarity-search-with-faiss-a-practical-approach/
  17. MetricType and distances
    https://github.com/facebo­okresearch/faiss/wiki/Metric­Type-and-distances
  18. RAG – Retrieval-augmented generation
    https://en.wikipedia.org/wi­ki/Retrieval-augmented_generation
  19. pgvector na GitHubu
    https://github.com/pgvector/pgvector
  20. Why we replaced Pinecone with PGVector
    https://www.confident-ai.com/blog/why-we-replaced-pinecone-with-pgvector
  21. PostgreSQL as VectorDB – Beginner Tutorial
    https://www.youtube.com/wat­ch?v=Ff3tJ4pJEa4
  22. What is a Vector Database? (neobsahuje odpověď na otázku v titulku :-)
    https://www.youtube.com/wat­ch?v=t9IDoenf-lo
  23. PGVector: Turn PostgreSQL Into A Vector Database
    https://www.youtube.com/wat­ch?v=j1QcPSLj7u0
  24. Milvus
    https://milvus.io/
  25. Vector Databases simply explained! (Embeddings & Indexes)
    https://www.youtube.com/wat­ch?v=dN0lsF2cvm4
  26. Vector databases are so hot right now. WTF are they?
    https://www.youtube.com/wat­ch?v=klTvEwg3oJ4
  27. 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
  28. Best 17 Vector Databases for 2025
    https://lakefs.io/blog/12-vector-databases-2023/
  29. Top 15 Vector Databases that You Must Try in 2025
    https://www.geeksforgeeks.org/top-vector-databases/
  30. Picking a vector database: a comparison and guide for 2023
    https://benchmark.vectorvi­ew.ai/vectordbs.html
  31. Top 9 Vector Databases as of Feburary 2025
    https://www.shakudo.io/blog/top-9-vector-databases
  32. What is a vector database?
    https://www.ibm.com/think/to­pics/vector-database
  33. SQL injection
    https://en.wikipedia.org/wi­ki/SQL_injection
  34. Cosine similarity
    https://en.wikipedia.org/wi­ki/Cosine_similarity
  35. Euclidean distance
    https://en.wikipedia.org/wi­ki/Euclidean_distance
  36. Dot product
    https://en.wikipedia.org/wi­ki/Dot_product
  37. Hammingova vzdálenost
    https://cs.wikipedia.org/wi­ki/Hammingova_vzd%C3%A1le­nost
  38. Jaccard index
    https://en.wikipedia.org/wi­ki/Jaccard_index
  39. Manhattanská metrika
    https://cs.wikipedia.org/wi­ki/Manhattansk%C3%A1_metri­ka
  40. pgvector: vektorová databáze postavená na Postgresu
    https://www.root.cz/clanky/pgvector-vektorova-databaze-postavena-na-postgresu/
  41. Matplotlib Home Page
    http://matplotlib.org/
  42. matplotlib (Wikipedia)
    https://en.wikipedia.org/wi­ki/Matplotlib
  43. Dot Product
    https://mathworld.wolfram­.com/DotProduct.html
  44. FAISS and sentence-transformers in 5 Minutes
    https://www.stephendiehl.com/pos­ts/faiss/
  45. Sentence Transformer: Quickstart
    https://sbert.net/docs/qu­ickstart.html#sentence-transformer
  46. Sentence Transformers: Embeddings, Retrieval, and Reranking
    https://pypi.org/project/sentence-transformers/
  47. uv
    https://docs.astral.sh/uv/
  48. A Gentle Introduction to Retrieval Augmented Generation (RAG)
    https://wandb.ai/cosmo3769/RAG/re­ports/A-Gentle-Introduction-to-Retrieval-Augmented-Generation-RAG---Vmlldzo1MjM4Mjk1
  49. The Beginner’s Guide to Text Embeddings
    https://www.deepset.ai/blog/the-beginners-guide-to-text-embeddings
  50. What are Word Embeddings?
    https://www.youtube.com/wat­ch?v=wgfSDrqYMJ4
  51. How to choose an embedding model
    https://www.youtube.com/wat­ch?v=djp4205tHGU
  52. What is a Vector Database? Powering Semantic Search & AI Applications
    https://www.youtube.com/wat­ch?v=gl1r1XV0SLw
  53. 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
  54. BERT (language model)
    https://en.wikipedia.org/wi­ki/BERT_(language_model)
  55. 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.