1 points par GN⁺ 2025-08-13 | Aucun commentaire pour le moment. | Partager sur WhatsApp
  • Face à la baisse de qualité des moteurs de recherche et aux progrès des modèles d’embedding basés sur les Transformers, l’auteur raconte son expérience de développement, en 2 mois, d’un moteur de recherche web reposant sur 300 millions d’embeddings
  • Grâce à une infrastructure et à des algorithmes haute performance — 200 clusters GPU au total, un crawler distribué à grande échelle, RocksDB, HNSW, etc. — il met en œuvre une recherche en compréhension du langage naturel en temps réel
  • Avec pour objectif une réponse aux requêtes centrée sur l’intention plutôt que sur la simple correspondance de mots-clés, il applique diverses techniques de NLP/ML comme la normalisation, le chunking et le chaînage d’énoncés afin de préserver le parsing documentaire et le contexte
  • Il présente, couche par couche, la conception d’un système distribué à grande échelle ainsi que des méthodes d’optimisation des goulets d’étranglement et des coûts, sur le pipeline, le stockage, le service mesh, l’index vectoriel, etc.
  • Au final, il décrit la naissance d’un moteur de recherche personnalisé combinant latence ultra-faible, distribution massive et grande précision

Vue d’ensemble et motivation

  • L’auteur explique avoir décidé de construire un moteur de recherche from scratch, motivé par la dégradation récente de la qualité des moteurs, le spam SEO, la hausse des contenus non pertinents, et par les progrès de compréhension du langage naturel des modèles d’embedding basés sur les Transformers
  • Les limites des moteurs existants viennent d’un manque de compréhension des questions au niveau humain et d’une simple correspondance fondée sur les mots-clés
  • L’objectif est un ranking centré sur l’intention, qui permette à des contenus de bonne qualité d’apparaître systématiquement en haut des résultats tout en explorant aussi correctement la longue traîne
  • Le processus de construction d’un moteur de recherche web couvre de nombreux domaines : informatique, linguistique, ontologie, NLP, ML, systèmes distribués, ingénierie des performances, etc.
  • Ce projet représente le défi de partir totalement de zéro, seul, sans infrastructure ni expérience préalable, pour réaliser un moteur de recherche entièrement nouveau en 2 mois

Architecture générale du système

  • 300 millions d’embeddings de texte basés sur SBERT sont générés sur 200 clusters GPU
  • Des centaines de crawlers collectent simultanément 50 000 pages par seconde, pour construire un index total de 280 millions d’éléments
  • RocksDB et HNSW sont shardés pour le stockage et l’indexation sur 200 cœurs, 4 To de RAM et 82 To de SSD
  • La latence totale de réponse aux requêtes est fixée à environ 500 ms
  • L’architecture globale et les flux sont séparés entre crawler, pipeline, stockage, index vectoriel d’embeddings, service mesh et couches front/back-end

Expérimentations et améliorations autour de la recherche par embeddings

Neural Embedding Playground

  • Les expériences montrent qu’une recherche utilisant des modèles d’embedding comme SBERT offre une meilleure compréhension naturelle des requêtes et une précision supérieure à la recherche traditionnelle centrée sur les mots-clés
  • Il devient possible d’identifier l’intention de la requête au niveau du contexte et de la phrase, puis d’extraire des réponses réellement pertinentes

Exemples : recherche traditionnelle vs recherche neuronale

  • Recherche classique : résultats aléatoires, centrés sur la correspondance de mots-clés
  • Recherche par embeddings : compréhension du contexte et de l’intention de la question, avec des résultats ciblant précisément la phrase clé ou le concept pertinent
  • Pour les combinaisons de concepts complexes, les questions implicites/composites ou les requêtes contenant des signaux de qualité, il devient possible de trouver des réponses fondées sur le sens

Parsing et normalisation des pages web

  • L’objectif de la normalisation est d’extraire depuis le HTML uniquement les éléments textuels sémantiques et d’éliminer le bruit comme la mise en page ou les éléments de contrôle

  • En s’appuyant sur les standards WHATWG, MDN, etc., il conserve les structures de tableaux et d’éléments comme p, table, pre, blockquote, ul, ol, dl

  • Les éléments chrome du site — menus, navigation, commentaires, interface, etc. — sont entièrement supprimés

  • Des règles spécifiques par site (par ex. en.wikipedia.org) sont appliquées pour résoudre les problèmes d’extraction excessive ou insuffisante

  • Les données structurées sémantiques (meta, OpenGraph, schema.org, etc.) peuvent aussi être exploitées pour construire un graphe de connaissances et améliorer le ranking

Chunking et préservation du contexte

Chunking au niveau de la phrase

  • Pour contourner les limites des modèles d’embedding, l’auteur applique un chunking par phrases plutôt que d’encoder la page entière
  • Lors du chunking, il distingue précisément, avec le sentencizer de spaCy, les frontières naturelles des phrases, la grammaire, les abréviations, les URL et les formulations informelles

Préservation et chaînage du contexte

  • Les dépendances entre phrases, titres, paragraphes, tableaux, etc. sont identifiées afin d’embarquer également les informations de contexte avec les embeddings
  • Par exemple, la structure d’un tableau est conservée en reliant en chaîne les titres ou clauses supérieures pour ne pas perdre le sens de chaque ligne

Chaînage d’énoncés (Statement Chaining)

  • Un classifieur DistilBERT analyse une phrase avec la phrase précédente afin d’automatiser la détection de dépendance contextuelle et l’extraction des chaînes
  • Lors de la génération des embeddings, toutes les phrases dépendantes de niveau supérieur sont incluses pour mieux préserver le contexte

Résultats d’utilisation du prototype

  • Dans un environnement sandbox, divers tests de requêtes réelles montrent une question-réponse bien plus précise et adaptée au contexte que les approches existantes
  • Même en cas de divergence de mots-clés, d’omissions, de métaphores ou de questions composites, l’application reconnaît l’intention et associe les bonnes phrases de contexte, mettant aussi efficacement au jour des connaissances et relations cachées

Crawler web à grande échelle (basé sur Node)

  • Pour répartir la charge, de nombreux aspects de stabilité et d’efficacité sont pris en compte : work stealing, contrôle de la concurrence et du trafic par domaine, validation DNS/URL/en-têtes, etc.
  • Le crawler s’appuie sur des Promises et des E/S asynchrones, des mécanismes résistants au DDoS, la gestion des ressources (mémoire, délais, backoff), ainsi que la détection des domaines bruités
  • La normalisation des URL, les restrictions de protocole, de port et d’informations utilisateur, ainsi que la canonicalization renforcent le filtrage des URL dupliquées ou anormales

Pipeline (file de tâches distribuée)

  • L’état de chaque page est géré dans PostgreSQL ; au départ, l’auteur utilise directement du polling et des transactions
  • Dans un environnement distribué de grande taille (des milliers de crawlers), des problèmes de passage à l’échelle et de contention sur les files/verrous apparaissent ; la gestion de l’état de la file est donc déplacée vers un coordinateur en mémoire écrit en Rust
  • Structure des tâches : indexation par hash map, tas binaire, groupes de domaines, polling aléatoire, permutation avec swap_remove, etc.
  • Chaque tâche n’occupe qu’environ 100 B en mémoire, ce qui permet de traiter 1 milliard de tâches sur un serveur de 128 Go
  • Par la suite, l’auteur développe une file d’attente open source basée sur RocksDB pour remplacer SQS, avec 300 000 ops/s sur un seul nœud

Conception du stockage (Oracle → PostgreSQL → RocksDB)

  • Au début, l’auteur utilise Oracle Cloud (egress et stockage peu coûteux), puis PostgreSQL (TOAST), mais se heurte à des limites de performances et de montée en charge à l’écriture
  • En raison des caractéristiques de PostgreSQL comme MVCC, la write amplification ou le WAL, les INSERT parallèles à grande échelle créent des goulets d’étranglement ; il migre donc finalement vers le KV store RocksDB
  • Avec le stockage séparé des blobs (BlobDB), les fichiers SST, le multithreading et l’indexation par hachage, RocksDB exploite au maximum les performances des SSD NVMe
  • L’architecture est étendue à 64 shards RocksDB, chaque shard étant routé via xxHash(key) avec sérialisation Serde + MessagePack
  • Au final, des milliers de clients (crawlers/parsers/vectoriseurs) traitent 200 000 ops/s, avec séparation et compression du stockage des métadonnées et des blobs

Service mesh et réseau

  • Pour faciliter la montée en charge de l’infrastructure, avec découverte automatique des instances de service et sécurité des communications, la conception repose sur mTLS + HTTP2
  • Chaque nœud reçoit un certificat basé sur une CA racine ; l’auteur développe aussi une sérialisation directe en MessagePack, un DNS interne avec CoreDNS et un SDK client personnalisé
  • Il avait déjà utilisé des VPN comme ZeroTier ou Tailscale, mais a finalement choisi directement HTTP + mTLS en raison de problèmes de réseau, de performances et d’exploitation
  • La gestion est unifiée via le contrôle des services système (systemd + cgroup + journald), pour plus de légèreté et de standardisation

Pipeline de génération d’embeddings GPU à grande échelle

  • Au départ, l’auteur s’appuie sur l’API OpenAI, puis migre vers des environnements GPU haute performance comme Runpod pour des raisons de coût
  • Le pipeline sépare chaque étape de manière asynchrone, atteint plus de 90 % d’efficacité GPU, et génère 100 000 embeddings par seconde sur 250 GPU
  • Le pipeline en Rust et l’inférence en Python communiquent par named pipe pour l’IPC, avec une backpressure structurée qui ajuste automatiquement les ressources

Indexation vectorielle (HNSW/sharding)

  • L’algorithme HNSW est utilisé pour une recherche vectorielle en mémoire, avec ANN (Approximate Nearest Neighbor) pour une latence ultra-faible
  • Une fois la limite de RAM atteinte, l’index est réparti uniformément entre les nœuds (64 nœuds), chaque shard effectuant sa recherche en parallèle dans son propre index HNSW
  • HNSW exigeant beaucoup de RAM et présentant des limites pour les mises à jour en direct, l’auteur migre finalement vers CoreNN, une base de données vectorielle open source sur disque
  • CoreNN permet des recherches très précises sur 3 milliards d’embeddings avec 128 Go de RAM, même sur un seul nœud

UX du moteur de recherche et optimisation de la latence

  • Pour l’UX d’un moteur de recherche, la réponse immédiate est essentielle (pas d’indicateur de chargement, SSR traditionnel)
  • Avec Cloudflare Argo, etc., le service est rapproché des edge PoP, et HTTP/3 est adopté pour minimiser la latence de transport
  • Toutes les données sont préparées côté serveur applicatif, les allers-retours API individuels sont minimisés, et des pages minifiées et compressées sont renvoyées immédiatement

Ce résumé détaille concrètement comment un moteur de recherche web à grande échelle, intégrant les dernières techniques de traitement du langage naturel et de ML, peut être construit de bout en bout en 2 mois, en couvrant les principaux choix de conception et d’optimisation côté système, algorithmes et infrastructure.

Aucun commentaire pour le moment.

Aucun commentaire pour le moment.