FAISS: Vektorsuche von Meta für Forschung
Was dieser Artikel behandelt
- Was FAISS ist und warum es eine Bibliothek und keine Datenbank ist.
- Welche Index-Typen FAISS bietet und wie Du den richtigen wählst.
- Wie Du FAISS mit Python installierst und nutzt.
- Wie GPU-Support die Vektorsuche beschleunigt.
- Wo FAISS im Vergleich zu Chroma und Qdrant steht.
Einleitung
FAISS steht für Facebook AI Similarity Search und ist eine Bibliothek von Meta für effiziente Vektorsuche. Im Gegensatz zu Chroma oder Qdrant ist FAISS keine Datenbank, sondern eine C++-Bibliothek mit Python-Bindings. Sie speichert keine Metadaten, bietet keine REST-API und verwaltet keine Persistenz automatisch. Dafür ist FAISS extrem schnell und skaliert auf Milliarden von Vektoren. Dieser Artikel zeigt Dir, wie Du FAISS installierst, Index-Typen wählst und es für RAG nutzt.
Warum brauche ich FAISS?
Wenn Du sehr viele Vektoren durchsuchen musst und maximale Performance brauchst, ist FAISS eine der schnellsten verfügbaren Lösungen. Meta entwickelt FAISS für den Einsatz in eigenen Produkten und optimiert es kontinuierlich. Besonders beim GPU-Support ist FAISS führend: Es kann Vektoren auf der GPU indizieren und durchsuchen, was die Suchzeiten dramatisch verkürzt.
FAISS eignet sich für Forschung, Prototypen und Anwendungen, bei denen Du die Infrastruktur selbst verwalten willst. Wenn Du eine fertige Datenbank mit Persistenz, Filterung und API suchst, bist Du mit Chroma oder Qdrant besser bedient. Wenn Du aber maximale Kontrolle und Geschwindigkeit brauchst, ist FAISS die richtige Wahl.
FAISS kurz erklärt
FAISS arbeitet mit Indizes, die Vektoren speichern und durchsuchen. Ein Index ist ein Objekt, das Du mit Vektoren füllst und danach abfragst. FAISS bietet verschiedene Index-Typen, die unterschiedliche Kompromisse zwischen Geschwindigkeit, Genauigkeit und Speicher eingehen. Die wichtigsten sind:
- IndexFlatL2: Brute-Force-Suche mit L2-Distanz. Exakt, aber langsam bei grossen Datenmengen.
- IndexFlatIP: Brute-Force-Suche mit Inner Product. Exakt, ebenfalls langsam bei grossen Datenmengen.
- IndexIVFFlat: Cluster-basierte Suche. Schneller als Flat, leichter Genauigkeitsverlust.
- IndexIVFPQ: Cluster-basiert mit Product Quantization. Sehr speichereffizient, grösserer Genauigkeitsverlust.
- IndexHNSWFlat: Graph-basierte Suche. Sehr schnell und genau, höherer Speicherbedarf.
Du kannst Indizes auch kombinieren, etwa IVF mit PQ für speichereffiziente approximative Suche.
Für wen ist dieser Artikel gedacht?
Dieser Artikel richtet sich an Entwickler und Forscher, die maximale Performance bei der Vektorsuche brauchen und bereit sind, mehr manuelle Arbeit in Kauf zu nehmen. Du solltest Python-Kenntnisse haben und verstehen, was Embeddings sind. Wenn Du neu bei Vektordatenbanken bist, beginne mit dem Überblicksartikel zu Vektordatenbanken und dem Artikel zu Embedding-Modellen.
Wichtige Begriffe
| Begriff | Bedeutung |
|---|---|
| Index | FAISS-Objekt, das Vektoren speichert und durchsucht |
| Flat | Brute-Force-Suche ohne Approximation |
| IVF | Inverted File, Cluster-basierte approximative Suche |
| PQ | Product Quantization, Komprimierung von Vektoren zur Speicherersparnis |
| HNSW | Hierarchical Navigable Small World, graph-basierte approximative Suche |
| GPU Index | Index, der auf der Grafikkarte läuft |
| Recall | Anteil der korrekt gefundenen Nachbarn an allen tatsächlichen Nachbarn |
| nlist | Anzahl der Cluster bei IVF |
| nprobe | Anzahl der Cluster, die bei der Suche durchsucht werden |
Installation
FAISS für CPU
pip install faiss-cpu
FAISS für GPU
Für GPU-Support brauchst Du eine NVIDIA-Grafikkarte mit CUDA:
pip install faiss-gpu
Wenn Du FAISS aus dem Quellcode kompilieren willst, findest Du die Anleitung im FAISS GitHub Repository. Für die meisten Anwendungen reicht die pip-Installation.
Erste Schritte
Einen einfachen Index erstellen
import faiss
import numpy as np
dimension = 768
# Zufällige Vektoren für das Beispiel
vectors = np.random.rand(1000, dimension).astype('float32')
# Flat-Index mit L2-Distanz
index = faiss.IndexFlatL2(dimension)
index.add(vectors)
print(f"Vektoren im Index: {index.ntotal}")
# Suchanfrage
query = np.random.rand(1, dimension).astype('float32')
distanzen, indizes = index.search(query, k=5)
print("Gefundene Indizes:", indizes)
print("Distanzen:", distanzen)
FAISS erwartet Vektoren als numpy-Arrays vom Typ float32. Achte darauf, dass Deine Embeddings dieses Format haben.
IVF-Index mit Training
IVF-Indizes müssen trainiert werden, bevor Du Vektoren hinzufügst. Das Training bestimmt die Cluster-Zentren.
import faiss
import numpy as np
dimension = 768
nlist = 100 # Anzahl Cluster
vectors = np.random.rand(10000, dimension).astype('float32')
# Quantizer als Basis für IVF
quantizer = faiss.IndexFlatL2(dimension)
# IVF-Index erstellen
index = faiss.IndexIVFFlat(quantizer, dimension, nlist)
# Training mit den Vektoren
index.train(vectors)
# Vektoren hinzufügen
index.add(vectors)
# Suchparameter setzen
index.nprobe = 10 # Anzahl zu durchsuchender Cluster
# Suchanfrage
query = np.random.rand(1, dimension).astype('float32')
distanzen, indizes = index.search(query, k=5)
print("Gefundene Indizes:", indizes)
Der Parameter nprobe steuert den Kompromiss zwischen Geschwindigkeit und Genauigkeit. Mehr nprobe bedeutet genauere Ergebnisse, aber langsamere Suche.
HNSW-Index
import faiss
import numpy as np
dimension = 768
vectors = np.random.rand(10000, dimension).astype('float32')
# HNSW-Index
index = faiss.IndexHNSWFlat(dimension, 32)
index.hnsw.efConstruction = 40
index.hnsw.efSearch = 16
index.add(vectors)
query = np.random.rand(1, dimension).astype('float32')
distanzen, indizes = index.search(query, k=5)
print("Gefundene Indizes:", indizes)
HNSW braucht kein Training. Der Parameter M (hier 32) steuert die Graph-Verbindungen, efConstruction die Build-Qualität und efSearch die Suchgenauigkeit.
GPU-Nutzung
import faiss
import numpy as np
dimension = 768
vectors = np.random.rand(100000, dimension).astype('float32')
# GPU-Ressource holen
res = faiss.StandardGpuResources()
# CPU-Index erstellen und auf GPU verschieben
cpu_index = faiss.IndexFlatL2(dimension)
gpu_index = faiss.index_cpu_to_gpu(res, 0, cpu_index)
gpu_index.add(vectors)
query = np.random.rand(1, dimension).astype('float32')
distanzen, indizes = gpu_index.search(query, k=5)
print("Gefundene Indizes:", indizes)
Die Zahl 0 in index_cpu_to_gpu ist die GPU-ID. Bei mehreren Grafikkarten kannst Du so wählen, welche genutzt wird.
Index speichern und laden
# Speichern
faiss.write_index(index, "mein_index.faiss")
# Laden
index = faiss.read_index("mein_index.faiss")
FAISS speichert nur die Vektoren und Index-Struktur. Metadaten wie Texte oder Quellen musst Du separat verwalten, etwa in einer JSON-Datei oder einer SQLite-Datenbank.
Index-Typen im Vergleich
| Index-Typ | Training | Genauigkeit | Geschwindigkeit | Speicher | GPU |
|---|---|---|---|---|---|
| IndexFlatL2 | Nein | Exakt | Langsam | Hoch | Ja |
| IndexFlatIP | Nein | Exakt | Langsam | Hoch | Ja |
| IndexIVFFlat | Ja | Hoch | Mittel | Mittel | Ja |
| IndexIVFPQ | Ja | Mittel | Schnell | Niedrig | Ja |
| IndexHNSWFlat | Nein | Hoch | Schnell | Hoch | Nein |
Für kleine Datenmengen bis etwa 10.000 Vektoren reicht IndexFlatL2. Für mittlere Datenmengen ist IVFFlat ein guter Kompromiss. Bei grossen Datenmengen mit Speicherlimits hilft IVFPQ. HNSW ist die beste Wahl für schnelle und genaue Suche, wenn genug Speicher vorhanden ist.
Vergleich mit Chroma und Qdrant
| Eigenschaft | FAISS | Chroma | Qdrant |
|---|---|---|---|
| Typ | Bibliothek | Vektordatenbank | Vektordatenbank |
| Persistenz | Manuell (write_index) | Automatisch | Automatisch |
| Metadaten | Nein | Ja | Ja |
| API | Python/C++ | Python | REST, gRPC, Python |
| Filterung | Nein | Einfach | Erweitert |
| GPU-Support | Ja | Nein | Nein |
| Skalierbarkeit | Sehr hoch | Klein bis mittel | Hoch |
| Einstiegshürde | Hoch | Niedrig | Mittel |
FAISS ist die schnellste Lösung für reine Vektorsuche, besonders mit GPU. Dafür fehlen Features, die dedizierte Datenbanken bieten: Persistenz, Metadaten, Filterung und API. In der Praxis nutzt Du FAISS oft als Engine unter einer eigenen Schicht, die diese Features ergänzt. Wenn Du diese Schicht nicht bauen willst, sind Chroma und Qdrant die bessere Wahl. Mehr zur Kombination verschiedener Suchmethoden findest Du im Artikel zu Hybrid Search.
Typische Stolpersteine
- Falscher Datentyp: FAISS erwartet
float32-Arrays. Wenn Dufloat64oderintübergibst, kommt es zu Fehlern oder stillen Problemen. Wandle mit.astype('float32')um. - Kein Training bei IVF: IVF-Indizes müssen vor dem Hinzufügen von Vektoren trainiert werden. Vergisst Du das, schlägt
add()fehl. - Zu wenig Trainingsdaten: IVF braucht ausreichend Vektoren für das Training. Ein Richtwert ist mindestens 39-mal so viele Vektoren wie
nlist. - nprobe zu niedrig: Ein zu niedriges
nprobemacht die Suche schnell, aber ungenau. Teste verschiedene Werte und messe den Recall. - Keine Persistenz: FAISS speichert Indizes nicht automatisch. Wenn Dein Prozess beendet wird, sind die Daten weg, ausser Du rufst
write_indexauf. - Metadaten separat verwalten: FAISS gibt Dir nur Index-Positionen zurück. Du musst selbst eine Mapping-Tabelle pflegen, die Positionen auf Texte oder Quellen abbildet.
- GPU-Speicher überschritten: Bei sehr grossen Indizes reicht der GPU-Speicher nicht aus. Teile den Index oder nutze IVFPQ zur Komprimierung.
- Index nach Datenänderung nicht aktualisiert: Wenn Du neue Vektoren hinzufügst, werden sie bei HNSW automatisch integriert. Bei IVF kann die Qualität leiden, wenn Du sehr viele neue Vektoren hinzufügst, ohne neu zu trainieren.
- Dimensionen stimmen nicht: Der Index wird mit einer festen Dimension erstellt. Vektoren mit anderer Dimension führen zu Fehlern.
Hardware, Kosten und Sicherheit
FAISS läuft auf jedem Rechner mit CPU. Für kleine bis mittlere Datenmengen reicht ein normaler Desktop. Für grosse Datenmengen und GPU-Support brauchst Du eine NVIDIA-Grafikkarte mit ausreichend VRAM, mindestens 8 GB, besser 24 GB oder mehr. Der GPU-Speedup kann 10- bis 100-fach sein, je nach Index-Typ und Datenmenge.
Kosten: FAISS ist Open Source unter der MIT-Lizenz und kostenlos. Die Hauptkosten entstehen durch die Hardware, insbesondere durch GPUs.
Sicherheit: FAISS selbst hat keine Netzwerkschnittstelle und keine Authentifizierung. Es läuft als Bibliothek in Deinem Prozess. Die Sicherheit hängt davon ab, wie Du die Umgebung absicherst, in der FAISS läuft. Da alle Daten lokal bleiben, gibt es kein Risiko der Datenweitergabe an externe Dienste. Wenn Du FAISS in einen Service einbindest, sichere diesen Service wie jede andere Anwendung ab.
Weiterführende Links
- FAISS GitHub Repository
- FAISS Dokumentation
- FAISS Tutorial
- Übersicht Vektordatenbanken
- RAG Grundlagen
- Lokales RAG
- Embedding-Modelle
- Chroma einrichten
- Qdrant einrichten
- Hybrid Search
- Docker Grundlagen
FAQ
Ist FAISS eine Datenbank?
Nein. FAISS ist eine Bibliothek für Vektorsuche. Es gibt keine Persistenz, keine Metadaten und keine API. Du musst diese Features selbst ergänzen.
Brauche ich eine GPU für FAISS?
Nein. FAISS funktioniert auch auf der CPU. Eine GPU beschleunigt die Suche bei grossen Datenmengen erheblich, ist aber nicht zwingend erforderlich.
Welche Grafikkarten werden unterstützt?
FAISS unterstützt NVIDIA-Grafikkarten mit CUDA. AMD-Grafikkarten werden nicht offiziell unterstützt.
Wie speichere ich einen FAISS-Index dauerhaft?
Mit faiss.write_index(index, dateipfad) speicherst Du den Index in eine Datei. Mit faiss.read_index(dateipfad) lädst Du ihn wieder.
Kann ich Metadaten in FAISS speichern?
Nein. FAISS speichert nur Vektoren. Du musst Metadaten in einer separaten Datenbank oder Datei verwalten und über die Index-Positionen verknüpfen.
Welcher Index-Typ ist der beste?
Das hängt von Deinen Anforderungen ab. Für kleine Datenmengen reicht IndexFlatL2. Für grosse Datenmengen mit Geschwindigkeitsanforderungen ist HNSW oder IVFFlat empfehlenswert. Bei Speicherlimits hilft IVFPQ.
Wie wähle ich nlist und nprobe bei IVF?
Ein guter Richtwert für nlist ist die Quadratwurzel aus der Anzahl der Vektoren. nprobe steuert den Kompromiss zwischen Geschwindigkeit und Genauigkeit. Starte mit nprobe gleich nlist geteilt durch 10 und experimentiere.
Kann ich FAISS mit Ollama kombinieren?
Ja. Ollama liefert das Sprachmodell, FAISS die Vektorsuche. Dein Python-Skript verbindet beide und verwaltet die Metadaten selbst.
Ist FAISS kostenlos?
Ja, FAISS ist Open Source unter der MIT-Lizenz und kostenlos. Du zahlst nur für die Hardware.
Wie messe ich die Genauigkeit eines Index?
Du vergleichst die Ergebnisse des approximativen Index mit denen eines exakten Index wie IndexFlatL2. Der Anteil übereinstimmender Ergebnisse ist der Recall.
Kann ich FAISS in Docker nutzen?
Ja. Es gibt offizielle Docker-Images mit GPU-Support. Du musst Docker mit NVIDIA-Container-Toolkit einrichten. Mehr dazu im Artikel Docker Grundlagen.
Was ist der Unterschied zwischen FAISS und Chroma?
Chroma ist eine vollständige Vektordatenbank mit Persistenz und Metadaten. FAISS ist eine reine Such-Bibliothek, die schneller ist, aber mehr manuelle Arbeit erfordert.
Quellen
- FAISS GitHub Repository
- FAISS Dokumentation
- FAISS Wiki mit Tutorials
- HNSW Paper von Malkov und Yashunin
- Product Quantization Paper von Jegou et al.


