Einen Websuchmaschine von Grund auf in 2 Monaten mit 300 Millionen neuronalen Embeddings aufbauen
(blog.wilsonl.in)- Vor dem Hintergrund der Qualitätsverschlechterung von Suchmaschinen und der Fortschritte bei Transformer-basierten Embedding-Modellen wird die Erfahrung beschrieben, in zwei Monaten eine Websuchmaschine auf Basis von 300 Millionen Embeddings entwickelt zu haben
- Mit insgesamt 200 GPU-Clustern, einem groß angelegten verteilten Crawler, RocksDB, HNSW und weiterer Hochleistungsinfrastruktur sowie Algorithmen wurde eine Suche mit Echtzeit-Natural-Language-Understanding umgesetzt
- Statt Keyword-Matching war das Ziel ein intentionszentriertes Frage-Antwort-System; dafür kamen verschiedene NLP/ML-Techniken wie Normalisierung, Chunking und Statement-Chaining zur Dokumentenverarbeitung und Kontexterhaltung zum Einsatz
- Vorgestellt werden Entwurf großer verteilter Systeme für jede Schicht – Pipeline, Storage, Service Mesh, Vektorindex usw. – sowie Ansätze zur Engpass- und Kostenoptimierung
- Abschließend wird geschildert, wie eine personalisierte Suchmaschine mit extrem niedriger Latenz, großer Verteilung und hoher Genauigkeit entstand
Überblick und Motivation
- Der Autor entschied sich, vor dem Hintergrund sinkender Suchmaschinenqualität, SEO-Spam und der Zunahme irrelevanter Inhalte sowie angesichts der gewachsenen Sprachverständnisfähigkeiten Transformer-basierter Embedding-Modelle dazu, eine Suchmaschine von Grund auf neu zu bauen
- Die Grenzen bestehender Suchmaschinen ergeben sich aus mangelndem Frageverständnis auf menschlichem Niveau und einfachem keywordbasiertem Matching
- Ziel ist ein intentionsbasiertes Ranking, bei dem hochwertige Inhalte zuverlässig weit oben erscheinen und auch der lange Tail gleichmäßig erschlossen wird
- Der Aufbau einer Websuchmaschine umfasst viele Bereiche wie Informatik, Linguistik, Ontologien, NLP, ML, verteilte Systeme und Performance Engineering
- Dieses Projekt ist die Herausforderung, innerhalb von zwei Monaten ohne Infrastruktur oder Vorerfahrung allein eine vollständig neue Suchmaschine zu realisieren
Gesamtsystemaufbau
- Auf 200 GPU-Clustern wurden 300 Millionen SBERT-basierte Text-Embeddings erzeugt
- Hunderte Crawler sammelten parallel 50.000 Seiten pro Sekunde und bauten insgesamt einen Index mit 280 Millionen Einträgen auf
- RocksDB und HNSW wurden über Sharding auf 200 CPU-Kerne, 4 TB RAM und 82 TB SSD für Speicherung und Indexierung verteilt
- Die gesamte Query-Latenz wurde auf etwa 500 ms ausgelegt
- Die Gesamtarchitektur und der Datenfluss sind in Crawler, Pipeline, Storage, Embedding-Vektorindex, Service Mesh sowie Frontend-/Backend-Bereiche gegliedert
Experimente und Verbesserungen bei Embedding-basierter Suche
Neural Embedding Playground
- Experimente bestätigten, dass Suche mit Embedding-Modellen wie SBERT gegenüber klassischer keywordzentrierter Suche ein natürlicheres Query-Verständnis und höhere Genauigkeit bietet
- Es ist möglich, die Absicht einer Eingabe-Query auf Kontext- und Satzebene zu erfassen und tatsächlich stark relevante Antworten zu extrahieren
Beispiele: traditionelle Suche vs. neuronale Suche
- Klassische Suche: zufällige Ergebnisse, Fokus auf Keyword-Übereinstimmung
- Embedding-Suche: Erkennen von Kontext und Intention der Frage, Bereitstellung präziser Ergebnisse rund um Kernsätze oder Konzepte
- Auch bei komplexen Konzeptkombinationen, impliziten/zusammengesetzten Fragen und Queries mit Qualitätssignalen ist eine bedeutungsbasierte Suche nach den richtigen Antworten möglich
Parsen und Normalisieren von Webseiten
-
Ziel der Normalisierung ist es, aus HTML nur semantisch relevante Textelemente zu extrahieren und Rauschen wie Layout- oder Steuerelemente zu entfernen
-
In Anlehnung an Standards wie WHATWG und MDN bleiben Tabellenstrukturen für p, table, pre, blockquote, ul, ol, dl usw. erhalten
-
Chrome-Elemente wie Menüs, Navigation, Kommentare und Interface-Bestandteile werden vollständig entfernt
-
Es werden spezielle Regeln pro Website angewandt, etwa für en.wikipedia.org, um Probleme mit Über- oder Unterextraktion zu beheben
-
Auch semantisch strukturierte Daten wie meta, OpenGraph und schema.org lassen sich nutzen, um Knowledge Graphs aufzubauen und das Ranking zu verbessern
Chunking und Kontexterhaltung
Chunking auf Satzebene
- Um die Grenzen von Embedding-Modellen zu überwinden, wird nicht die gesamte Seite, sondern satzbasiertes Chunking verwendet
- Beim Chunking werden natürliche Satzgrenzen, Grammatik, Abkürzungen, URLs und informelle Ausdrücke mit dem spaCy-Sentencizer präzise unterschieden
Kontexterhaltung und Verknüpfung
- Durch die Erkennung von Abhängigkeiten zwischen Sätzen, Überschriften, Absätzen, Tabellen usw. werden auch Kontextinformationen gemeinsam in die Embeddings eingebunden
- So werden etwa Tabellenstrukturen zusammen mit übergeordneten Überschriften oder Klauseln verkettet eingefügt, damit die Bedeutung jeder Zeile erhalten bleibt
Statement Chaining
- Mit einem DistilBERT-Klassifikator werden ein Satz und der vorherige Satz gemeinsam analysiert, um Kontextabhängigkeit zu prüfen und Chains zu extrahieren
- Beim Embedding werden alle übergeordneten abhängigen Sätze gemeinsam einbezogen, um die Kontexterhaltung zu verbessern
Ergebnisse des Prototypen
- In einer Sandbox-Umgebung zeigten vielfältige praxisnahe Queries im Vergleich zu bestehenden Ansätzen deutlich präzisere, kontextangepasste Frage-Antwort-Ergebnisse
- Auch bei Keyword-Mismatch, Auslassungen, Metaphern oder zusammengesetzten Fragen erkennt die App die Intention und findet die richtigen Kontextsätze – verborgene Wissensbestände und Beziehungen werden effektiv aufgedeckt
Großer Webcrawler auf Node-Basis
- Berücksichtigt wurden verschiedene Stabilitäts- und Effizienzaspekte wie Work Stealing zur Lastverteilung, domänenspezifische Parallelitäts-/Traffic-Kontrolle sowie DNS-/URL-/Header-Validierung
- Der Crawler nutzt asynchrones I/O auf Promise-Basis, DDoS-resistente Mechanismen, Ressourcenmanagement (Speicher, Delay, Backoff) und Erkennung verrauschter Domains
- Durch URL-Normalisierung, Einschränkungen bei Protokollen, Ports und Benutzerinformationen sowie Canonicalization wurde die Filterung doppelter oder fehlerhafter URLs verstärkt
Pipeline (verteilte Task-Queue)
- Der Status jeder Seite wurde in PostgreSQL verwaltet; anfangs kamen direkt Polling und Transaktionen zum Einsatz
- In einer großen verteilten Umgebung mit Tausenden Crawlern traten Skalierungsprobleme sowie Queue-/Lock-Engpässe auf → Verwaltung des Queue-Zustands mit einem In-Memory-Koordinator auf Rust-Basis
- Task-Struktur: HashMap-basierte Indizes, Binary Heap, Domain-Gruppen, zufälliges Polling,
swap_removeund weitere Indexierungsverfahren - Der Speicherbedarf pro Task liegt bei etwa 100 B; auf einem 128-GB-Server lassen sich auch 1B Tasks verarbeiten
- Später wurde als Ersatz für SQS eine Open-Source-Queue auf RocksDB-Basis entwickelt, die auf einem einzelnen Node 300.000 Ops/s unterstützt
Storage-Design (Oracle → PostgreSQL → RocksDB)
- Zunächst wurden Oracle Cloud (günstiger Egress/Storage) und später PostgreSQL (TOAST) genutzt, stießen aber an Grenzen bei Write-Scaling und Performance
- Aufgrund von Eigenschaften wie MVCC, Write Amplification und WAL wurde PostgreSQL bei massiv parallelen INSERTs zum Engpass; schließlich erfolgte der Wechsel zum KV-Store RocksDB
- Mit separater Blob-Speicherung (BlobDB), SST-Dateien, Multithreading und Hash-Indizierung nutzt RocksDB die maximale Leistung von NVMe-SSDs aus
- Skalierung auf 64 RocksDB-Shards – jedes Shard wird per xxHash(key)-basiertem Routing angesprochen, mit Serde+MessagePack-Serialisierung
- Am Ende wurden 200.000 Ops/s aus Tausenden Clients (Crawler/Parser/Vectorizer) verarbeitet; Metadaten und Blobs werden getrennt und komprimiert gespeichert
Service Mesh und Networking
- Für automatische Service-Discovery und abgesicherte Kommunikation beim Ausbau der Infrastruktur wurde ein Design auf Basis von mTLS+HTTP2 gewählt
- Auf jedem Node kommen Zertifikate mit Root-CA-Basis zum Einsatz; zusätzlich wurden direkte MessagePack-Serialisierung, internes DNS und CoreDNS sowie ein eigenes Client-SDK entwickelt
- Zwar gab es Erfahrungen mit bestehenden VPNs (ZeroTier, Tailscale), wegen Problemen bei Netzwerk, Performance und Betrieb fiel die Wahl aber auf eigenes HTTP+mTLS
- Mit System-Service-Steuerung (
systemd + cgroup + journald) wurde das Management vereinheitlicht sowie eine schlanke und standardisierte Betriebsumgebung erreicht
Pipeline zur Erzeugung von Embeddings im großen GPU-Maßstab
- Anfangs wurde die OpenAI API verwendet, wegen der Kosten erfolgte später der Wechsel in Hochleistungs-GPU-Umgebungen wie Runpod
- Die Pipeline trennt die einzelnen Stufen asynchron, erreicht über 90 % GPU-Auslastung und erzeugt auf 250 GPUs 100.000 embeddings pro Sekunde
- Rust-Pipeline, Python-Inference → IPC über named pipe, automatische Ressourcentuning durch strukturierten Backpressure
Vektorindizierung (HNSW/Sharding)
- Mit dem HNSW-Algorithmus wird eine speicherbasierte Vektorsuche als ANN (Approximate Nearest Neighbor) für extrem niedrige Latenzen realisiert
- Bei Erreichen der RAM-Grenzen wurde gleichmäßiges Sharding über Nodes hinweg (64 Nodes) eingesetzt; jedes Shard wird mit einem eigenen HNSW-Index parallel durchsucht
- Aufgrund der hohen RAM-Anforderungen und begrenzter Live-Update-Fähigkeiten von HNSW erfolgte schließlich der Wechsel zu CoreNN, einer diskbasierten Open-Source-Vektor-DB
- CoreNN ermöglicht auch auf einem einzelnen Node mit 128 GB RAM hochpräzise Abfragen über 3B Embeddings
Suchmaschinen-UX und Latenzoptimierung
- Für die UX einer Suchmaschine ist Unmittelbarkeit der Antwort entscheidend (kein Ladeindikator, traditionelles SSR)
- Mit Cloudflare Argo u. a. wird die Nähe zu Edge-PoPs erhöht; durch HTTP/3 wird die Übertragungslatenz minimiert
- Auf Ebene des App-Servers werden alle Daten vollständig vorbereitet, einzelne API-Roundtrips minimiert und minifizierte sowie komprimierte Seiten sofort ausgeliefert
Diese Zusammenfassung zeigt konkret die wichtigsten Entwurfs- und Optimierungspunkte über System, Algorithmen und Infrastruktur hinweg, wie eine groß angelegte Websuchmaschine mit aktueller Natural-Language-Processing- und ML-Technologie in nur zwei Monaten end-to-end aufgebaut werden kann.
Noch keine Kommentare.