Zum Inhalt springen
Kurzer Hinweis: flozi00 TechHub ist ein Solo-Nebenprojekt neben einem Vollzeitjob — persönliche Lernnotizen, keine offiziellen Aussagen. Kritische Schritte selbst prüfen.

RAG-Retrieval-Mathematik: Embedding-Speicher, Vektorindex-Größe und das Latenzbudget, das niemand rechnet

Die Arithmetik von selbst gehostetem RAG: fp16-Footprints von bge-base, bge-m3 und e5-mistral-7b, Bytes pro Vektor und Korpus-Indexgrößen von 1 Mio. bis 100 Mio. Chunks, Flat- vs. HNSW-Vergleichszahlen, warum Embedding prefill-gebundene Rechenleistung ist, Cross-Encoder-Reranker-FLOPs und die Break-even-Rechnung API gegen GPU — jede Zahl aus Primärquellen berechnet.

10 Min. Lesezeitflozi00
aimachine-learninggpuragretrievalvector-searchgpu-memory

Jede Entscheidung „wir bauen einfach RAG dazu" ist eine Reihe von Rechenaufgaben im Trenchcoat: wie viel VRAM das Embedding-Modell braucht, wie viele Bytes der Vektorindex frisst, wie viele Distanzberechnungen eine Query kostet und ob die ganze Pipeline in Ihr Latenzbudget passt. Dieser Guide rechnet das mit Zahlen aus Primärquellen durch — Hugging-Face-Model-Karten, NVIDIA-Datenblätter, Qdrants offizielle Dokumentation und aktuelle API-Preise — damit Sie die Infrastruktur dimensionieren, bevor Sie der Demo glauben.

Das Embedding-Modell ist der günstige Teil — bis es das nicht ist

Drei offene Embedding-Modelle über klein, mittel und groß verteilt; die Parameterzahlen direkt aus den Hugging-Face-Repositories gelesen (fp16 = 2 Bytes pro Parameter, dieselbe Konvention wie in unserem Quantisierungs-Guide):

ModellParameter (HF)fp16-GewichteEmbedding-DimOutput-Tokens?
BAAI/bge-base-en-v1.5109.482.75210,22 GB768—
BAAI/bge-m3567.755.77721,14 GB1024 (+ sparse)—
intfloat/e5-mistral-7b-instruct7.110.660.096314,22 GB4096—

Die Parameterzahl von bge-m3 lässt sich prüfen, ohne irgendeinem Blog-Post zu vertrauen: Die pytorch_model.bin ist 2.271.145.830 Bytes groß (fp32) — durch 4 geteilt ergeben sich 567,8 Mio. Parameter4. Das e5-mistral-Checkpoint liefert fp16-Safetensors mit zusammen 14,2 GB — die Gewichte sind also die Standard-Deployments-Größe3.

Die GPU-Klassen-Folgen bei fp16:

  • bge-base (0,22 GB) läuft überall — Laptop-GPU, CPU, Jetson. Speicher ist nicht die Grenze; Durchsatz ist es.
  • bge-m3 (1,14 GB) passt auf jede Datacenter-GPU mit reichlich Reserve; selbst 8-GB-Karten tragen das Modell plus große Batches.
  • e5-mistral-7b (14,22 GB) will eine 24-GB-Karte (L40S, RTX 4090, A30) oder eine A100 40/80 GB, damit Platz für Aktivierungen bleibt. Eine 16-GB-Karte trägt die Gewichte technisch, lässt aber fast nichts für Batch-Attention über 512-Token-Inputs.

Die teure Klasse entscheidet nicht über Qualität pro Euro im Betrieb — sondern über die Vektorbreite, die sie erzeugt. Ein 4096-Dim-Modell vervierfacht jede nachgelagerte Speicherrechnung gegenüber 1024-Dim-bge-m3, bei Benchmark-Scores, die sich um einstellige Punkte verbessern5.

Bytes pro Vektor: wo die echte Speicherrechnung lebt

Rohe Embedding-Speicherung ist peinlich simple Arithmetik: Bytes pro Vektor = Dimensionalität × Bytes pro Komponente. Stand 2026 speichert Qdrant Vektoren intern standardmäßig als 32-Bit-Floats6.

Dim (Modellklasse)fp32 (4 B)fp16 (2 B)int8 (1 B)
768 (bge-base, MiniLM-Klasse)3,0 KiB1,5 KiB0,75 KiB
1024 (bge-m3, e5-large-Klasse)4,0 KiB2,0 KiB1,0 KiB
1536 (OpenAI text-embedding-3-small)6,0 KiB3,0 KiB1,5 KiB
3072 (text-embedding-3-large)12,0 KiB6,0 KiB3,0 KiB
3584 (gte-Qwen2-7B)14,0 KiB7,0 KiB3,5 KiB
4096 (e5-mistral-7b)16,0 KiB8,0 KiB4,0 KiB

Korpus-Dimensionierung — angenommen 512-Token-Chunks, also entsprechen 500 Mio. Tokens Quelltext ≈ 1 Mio. Chunks, 50 Mrd. Tokens ≈ 98 Mio. Chunks. Die Indexspeicher-Tabelle für bge-Klasse, 1024-Dim:

Chunksfp32 rohint8 (4×)PQ, 0,5 B/Komp. (8×)
1 Mio.4,10 GB1,02 GB0,51 GB
10 Mio.40,96 GB10,24 GB5,12 GB
100 Mio.409,60 GB102,40 GB51,20 GB

Und bei 4096-Dim (7B-Klasse-Embedder) erreicht dieselbe Tabelle 1,64 TB roh bei 100 Mio. Chunks — alles mal 4. Oben auf die Vektoren kommt der HNSW-Graph selbst in RAM: Qdrant dokumentiert die exakte Formel — jeder Knoten hält rund m Verbindungen auf oberen Ebenen und 2 × m auf Ebene 0, jede eine 4-Byte-Integer, also kostet M=16 2 × 16 × 4 = 128 B pro Vektor — 12,8 GB bei 100 Mio. Vektoren7.

Kompressionsraten aus den Dokumentationen der Anbieter, nicht aus Marketing-Rekapitulierungen: Qdrants Skalarquantisierung ist float32 → uint8, hartes 4× mit „Fehler meist unter 1 %"; Binärquantisierung bis 32×; Produktquantisierung bis 64×, wenn Speicher die oberste Priorität hat6. Weaviate dokumentiert PQ zur Speicherreduktion bei Skalierung8, und Milvus unterstützt Skalar-, Produkt- und Binär-/RaBitQ-Quantisierung für denselben Zweck9. Die ehrliche Lesart: 4× ist praktisch gratis, 32× kostet echte Recall-Qualität ohne Oversampling und Rescoring, und Raten darüber sind Panikmodus.

Latenz-Zerlegung: Flat Brute Force vs. HNSW

Flat-Suche ist exakt und O(n). HNSW ist approximativ und theoretisch grob logarithmisch — aber was logarithmisch in Vergleichen bedeutet, lohnt sich auszuschreiben.

Distanzvergleiche pro Query, ef = 100 als realistische Suchbreite:

KorpusgrößeFlat (exakt)HNSW (approx., ~ef·log₂n)
1 Mio. Vektoren1.000.000~2.000
10 Mio. Vektoren10.000.000~2.300
100 Mio. Vektoren100.000.000~2.700

Das ist die Kernzahl: Ein 100× größerer Korpus verteuert die Flat-Suche um 100×, die HNSW-Suche um ~35 %. Eine Flat-Suche über 1 Mio. 1024-Dim-float32-Vektoren sind nur 1 Mio. × 2 × 1024 ≈ 2 GFLOP plus der Speichertransport, um 4 GB zu lesen — Millisekundenbereich auf einer modernen CPU mit SIMD. Genau deshalb definiert Qdrants eigene Doku eine full_scan_threshold_kb, unterhalb deren Brute Force den Graph schlägt7. Flat-Suche verliert irgendwo zwischen 1 und 10 Mio. Vektoren im RAM; danach akzeptiert man approximativen Recall.

Absolute QPS-Zahlen zitieren wir nur herstellerseitig und als solche gekennzeichnet: Qdrant veröffentlicht ein eigenes HNSW-Benchmark-Repository genau für diesen Zweck10, und ihr Large-Scale-Tutorial — 400 Mio. CLIP-Vektoren, Binärquantisierung, M=6 — liefert eine konkrete, reproduzierbare Ressourcenaufstellung (23,8 GB quantisierte Vektoren + 17,9 GB HNSW-Graph im RAM für alle 400 Mio.)11. Jede „einstellige Millisekunden pro Query"-Zahl aus einem ungebremsten Benchmark verdient Skepsis, solange Hardware, ef und Recall nicht mit angegeben sind.

Embedding ist Prefill, nicht Decode — und das ändert die Rechnung

Die KV-Cache-Intuition aus unserem KV-Cache-Guide führt hier in die Irre, also präzise formuliert: Ein Embedding-Forward-Pass über einen 512-Token-Chunk ist reiner Prefill. Ein Durchgang, alle Positionen gleichzeitig, keine Decode-Schritte, kein gespeicherter KV-Cache, keine speicherbandbreiten-gebundene Token-für-Token-Schleife. Embedding-Durchsatz ist in einer Weise compute-gebunden, wie es Generierung nie ist.

Die FLOPs pro Chunk folgen der Standard-Forward-Pass-Schätzung 2 × Parameter × Tokens:

  • bge-m3 (568 Mio. Parameter), 512-Token-Chunk: 2 × 567.755.777 × 512 ≈ 581 GFLOP
  • e5-mistral-7b (7,11 Mrd. Parameter), 512-Token-Chunk: 2 × 7.110.660.096 × 512 ≈ 7.281 GFLOP

Obergrenzen bei Spezifikations-TFLOPS aus NVIDIA-Datenblättern — dichtes fp16, mit ehrlich angenommenen 50 % der Spitzenleistung (Model-Kernel-MFU auf gut gebatchten Encoder-Inputs):

GPUfp16 dense (Datenblatt)bge-m3 Tok/se5-mistral-7b Tok/s
L40S362 TFLOPS12~159.400~12.700
A100 80 GB312 TFLOPS13~137.400~11.000

Die L40S-Zahl verdient ihre Skepsis: 362 TFLOPS ist die dense-fp16-Figur hinter der 1.466-TFLOPS-Sparse-Schlagzeile12. Selbst bei halber Auslastung embeddet eine L40S einen 1-Mio.-Chunk-Korpus (500 Mio. Tokens) mit bge-m3 in unter einer Stunde reiner Rechenzeit (500 × 10⁶ / 159.400 ≈ 52 Minuten). Speicher ist nicht der Flaschenhals; die Datenzuführung in die Batches ist es.

Reranker: die zweite Stufe, die still Ihr Budget besitzt

Hybrides Sparse-plus-Dense-Retrieval ist 2026 der Standard, weil es funktioniert — dense Vektoren verpassen exakte Keywords, BM25-artiges Sparse verpassen Paraphrasen, bge-m3 liefert beides aus einem Forward-Pass2. Aber der Qualitätshebel, den Leute tatsächlich spüren, ist der Cross-Encoder-Reranker — und er ist die am schlechtesten budgetierte Komponente in RAG.

Ein Cross-Encoder bewertet jedes Paar einzeln: voller Forward-Pass über konkatenierte Query plus Kandidat. Pro Kandidatenpaar mit einem Reranker der 280-Mio.-Klasse (bge-reranker-base, 278.044.931 Parameter14) über 32 Query-Tokens + 512 Dokument-Tokens:

2 × 278 Mio. × 544 ≈ 302 GFLOP pro Paar

Die Top-100-Kandidaten aus dem Retrieval zu bewerten kostet 100 × 302 GFLOP ≈ 30,3 TFLOP — auf einer L40S bei 50 % MFU sind das ~167 ms pro Query, bevor der Generierungsaufruf begonnen hat. Dieselbe 100-Paar-Last auf einem reinen CPU-Pfad dauert Minuten. Deshalb reranken Produktionspipelines 20–50 Kandidaten, nicht 100, und deshalb ist die Reranker-Wahl eine Latenzentscheidung, nicht nur eine Qualitätsentscheidung.

Das zweistufige Latenzbudget pro Query bei realistischer Skalierung:

  • Query-Embedding (bge-m3 über 32 Tokens): sub-Millisekunden-Klasse auf GPU, ~ms-Klasse auf CPU
  • HNSW-Retrieval über 10 Mio. Vektoren: einstellige ms (Recall unter 1,0; Sie haben das so gewählt)
  • Reranken von 100 Kandidaten @ 280 Mio. Parameter: ~100–170 ms GPU
  • Generierung über 8k Kontext: Sekunden — und wie der KV-Cache-Guide zeigt, zweistellige GB bei Misswirtschaft

Die unbequeme Beobachtung: Der Reranker, nicht die Vektorsuche, dominiert die Retrieval-Latenz, und der Generator dominiert die ganze Pipeline. Vektorsuche bei 10 Mio. Skala ist nicht Ihr Problem. Alles drumherum ist es.

API vs. Self-Hosting: Der Break-even liegt nicht, wo Sie denken

Aktuelle Preise pro 1 Mio. Input-Tokens: OpenAI text-embedding-3-small bei 0,02 USD, text-embedding-3-large bei 0,13 USD15. Die Batch API halbiert beide15. Embeddings berechnen nur Input — keine Output-Tokens, weil es keine gibt.

Self-Hosting auf einer L40S zu einem typischen On-Demand-Cloud-Preis von 1,20 USD/Stunde: bge-m3 bei ~159.400 Tok/s (50 % MFU) embeddet 574 Mio. Tokens pro Stunde. Kosten pro 1 Mio. Tokens:

1,20 USD / 574 ≈ 0,0021 USD

Das ist ~10× günstiger als text-embedding-3-small und ~60× günstiger als 3-large — pro Token, solange die GPU unter Last läuft. Der Haken: Eine GPU, die nach Stunde abgerechnet wird und Ihren Korpus an einem Nachmittag embeddet, um dann rumzusitzt, ist nicht günstiger als irgendetwas — sie ist die teuerste Option auf dem Tisch.

Der ehrliche Break-even-Rahmen ist daher Auslastung, nicht Korpusgröße:

Embedding-VolumenGPU-Stunden/Monat (bge-m3)GPU-Kosten @1,20 USD/hAPI 3-smallAPI 3-large
10 Mio. Tok/Monat0,02 h0,02 USD0,20 USD1,30 USD
1.000 Mio. Tok/Monat1,74 h2,09 USD20,00 USD130,00 USD
10.000 Mio. Tok/Monat17,4 h20,91 USD200,00 USD1.300,00 USD

Die Tabelle ohne Wunschdenken gelesen:

  • Self-Hosting gewinnt, wenn Ihre Pipeline kontinuierlich neu embeddet (Crawls, Churn, Re-Indexierung bei Modellwechseln), wenn Daten die Grenze nicht verlassen dürfen (unsere EU-KI-rechtsnahen Guides erklären, warum europäische Deployments das ernst nehmen) oder wenn das Volumen eine dedizierte Karte heiß laufen lässt: ab mehreren Milliarden Tokens pro Monat Re-Embedding zahlt sich eine L40S monatlich selbst, selbst gegen die günstigste API.
  • Die API gewinnt beim Einmal-Indexieren: 500 Mio. Tokens einmal einzubetten kostet mit 3-small Batch 5 USD (halber Standardpreis von 10 USD) — ein Zehntel eines einzigen Monats selbst eines günstigen GPU-Leasings. Niemand sollte für einen einzigen Korpusdurchlauf eine GPU kaufen.
  • Kontinuierliche Konsequenz: Bei 10 Mio. Tok/Monat ist die „GPU-Kosten"-Spalte 1 Minute Rechnung. Mieten Sie sekundengenau (Serverless-GPU) oder nutzen die API; eine Dauernote ist der einzige Weg, diesen Vergleich zu verlieren.

Und der Qualitätsvorbehalt: Qualitätsparität ist modellabhängig. Wer bge-base self-hostet, weil es gratis ist, und als Baseline 3-large vergleicht, frisst jeden Infra-Sparkauf durch die Retrieval-Qualitätseinbuße. Erst Modelle angleichen, dann Preise vergleichen.

Fazit, mit ausbuchstabierten Fallstricken

Selbst gehostete RAG-Infrastruktur-Mathematik schlägt eine API unter drei Bedingungen: anhaltendes Embedding-Volumen (≥ einstellig Milliarden Tokens/Monat neu verarbeitet), harte Datengrenzen-Anforderungen oder die Qualitätsklasse der 7B-Embedder, für die keine API ein gleichwertiges Modell anbietet, das Sie verarbeiten dürfen. Unter einer Milliarde Tokens Embedding-Arbeit pro Monat und ohne Datengrenze ist die API arithmetisch unschlagbar — 2–20 USD/Monat gegen jeden GPU-Vertrag.

Die ehrlichen Fallstricken:

  • „RAG behebt Halluzinationen" ist ein Kategorienfehler. Retrieval erdet die Generierung in dem, was indexiert ist; wird der korrekte Chunk nicht gefunden, halluziniert das Modell trotzdem — nur selbstbewusster. RAG verschiebt das Fehlerbild von „das Modell weiß es nicht" zu „das Retrieval hat es verpasst" — gebunden durch Recall auf Ihrem Korpus, nicht durch MTEB-Benchmark-Scores.
  • Recall-Verlust wird doppelt bezahlt: Approximatives HNSW (ef zu niedrig) senkt Recall, Quantisierung senkt ihn weiter, und jeder Verlust summiert sich lautlos, weil die Fehleroberfläche exakt so aussieht wie „das Modell hat es erfunden".
  • Die Chunking-Strategie dominiert die Modellwahl, bevor irgendeines benchmarked ist — 512-Token-Chunks ohne Überlappung verlieren gegen naives BM25 mit besserem Chunking.
  • Die 4096-Dim-Vektoren des 7B-Embedders kosten für immer 4× Speicher und 4× Flat-Suchzeit. Qualität wird gemietet; die Vektorbreite wird gekauft.

Die Mathematik hier ist der einfache Teil. Jede Zahl oben ist ein Boden, keine Prognose — echte Pipelines verlieren an Netzwerk-Hops, Serialisierung und Leerlauf. Rechnen Sie die Böden zuerst, und messen Sie dann die Realität gegen sie.

Fußnoten

Footnotes

  1. BAAI/bge-base-en-v1.5 — Hugging-Face-Modellrepository, Safetensors gesamt 109.482.752 Parameter (fp32-Checkpoint, 437.955.512 Bytes): https://huggingface.co/BAAI/bge-base-en-v1.5 ↩

  2. BAAI/bge-m3 — Hugging-Face-Model-Karte: 1024 Dim, 8192-Token-Kontext, Dense- + Sparse- + Multi-Vector-Ausgaben aus einem Forward-Pass: https://huggingface.co/BAAI/bge-m3 ↩ ↩2

  3. intfloat/e5-mistral-7b-instruct — Hugging-Face-Modellrepository, fp16-Safetensors gesamt 7.110.660.096 Parameter auf zwei Shards: https://huggingface.co/intfloat/e5-mistral-7b-instruct ↩ ↩2

  4. bge-m3 pytorch_model.bin = 2.271.145.830 Bytes fp32 ⇒ ~567,8 Mio. Parameter, über die Dateiliste des Hugging-Face-Modells: https://huggingface.co/BAAI/bge-m3/tree/main ↩

  5. Alibaba-NLP/gte-Qwen2-7B-instruct — Hugging-Face-Model-Karte: 3584 Dim, 32k Max-Input, fp32-Gewichte 26,45 GB gelistet, MTEB(56) 70,24 vs. bge-base-en-1.5 64,23: https://huggingface.co/Alibaba-NLP/gte-Qwen2-7B-instruct ↩

  6. Qdrant-Dokumentation, „Quantization" — Skalarquantisierung float32 → uint8 = 4× mit „Fehler meist unter 1 %"; Binär bis 32×; Produktquantisierung bis 64×: https://qdrant.tech/documentation/manage-data/quantization/ ↩ ↩2

  7. Qdrant-Dokumentation, „Indexing" — HNSW-Verbindungsformel (m Kanten auf oberen Ebenen, 2×m auf Ebene 0, 4-Byte-Links), full_scan_threshold_kb sowie Defaults m=16, ef_construct=100: https://qdrant.tech/documentation/concepts/indexing/ ↩ ↩2

  8. Weaviate-Dokumentation, Produktquantisierung zur Reduktion des Speicherbedarfs für Vektoren: https://weaviate.io/developers/weaviate/concepts/vector-quantization ↩

  9. Milvus-Dokumentation, Indextypen inkl. Skalar- (IVF_SQ8), Produkt- (IVF_PQ) und Binär-/RaBitQ-Quantisierung (IVF_RABITQ): https://milvus.io/docs/index.md ↩

  10. Qdrants offizielles HNSW-Benchmark-Repository (search_benchmark, memory_benchmark, filter_speed_benchmark): https://github.com/qdrant/benchmark ↩

  11. Qdrant-Tutorial, „Large-Scale Search" — 400 Mio. 512-Dim-Vektoren: 23,84 GB quantisierte Vektoren + ~17,9 GB HNSW-Graph (M=6) im RAM, mit vollständiger Speicheraufstellung: https://qdrant.tech/documentation/tutorials-operations/large-scale-search ↩

  12. NVIDIA-L40S-Produktseite und Datenblatt — FP16 Tensor Core 362,05 TFLOPS dense (direkt gelistet), 733 TFLOPS mit 2:4-Sparsity; FP8 733 dense | 1.466 sparse; 91,6 TFLOPS FP32: https://www.nvidia.com/en-us/data-center/l40s/ ↩ ↩2

  13. NVIDIA A100 Datenblatt — 312 TFLOPS fp16 dense Tensor Core, 80 GB HBM2e bei >2 TB/s: https://www.nvidia.com/en-us/data-center/a100/ ↩

  14. BAAI/bge-reranker-base — Hugging-Face-Modellrepository, 278.044.931 Parameter: https://huggingface.co/BAAI/bge-reranker-base ↩

  15. OpenAI-Plattformpreise — text-embedding-3-small 0,02 USD/1 Mio. Input-Tokens, text-embedding-3-large 0,13 USD/1 Mio., Batch API 50 % (live abgerufen September 2026): https://platform.openai.com/docs/pricing ↩ ↩2