Cómo construir desde cero en 2 meses un motor de búsqueda web con 300 millones de embeddings neuronales
(blog.wilsonl.in)- A partir del deterioro en la calidad de los motores de búsqueda y de los avances en modelos de embeddings basados en Transformer, se presenta la experiencia de desarrollar durante 2 meses un motor de búsqueda web basado en 300 millones de embeddings
- Mediante un total de 200 clústeres de GPU, rastreadores distribuidos a gran escala, RocksDB, HNSW y otra infraestructura y algoritmos de alto rendimiento, se implementó una búsqueda con comprensión de lenguaje natural en tiempo real
- Con el objetivo de ofrecer preguntas y respuestas centradas en la intención en lugar de coincidencias por palabras clave, se aplicaron diversas técnicas de NLP/ML como normalización, chunking y encadenamiento de enunciados para el parsing de documentos y la preservación del contexto
- Se presentan el diseño de sistemas distribuidos a gran escala en cada capa —pipeline, almacenamiento, service mesh, índice vectorial, etc.— así como estrategias para optimizar cuellos de botella y costos
- Finalmente, se describe la creación de un motor de búsqueda personalizado con latencia ultrabaja, gran distribución y alta precisión
Panorama general y motivación
- El autor decidió construir recientemente un motor de búsqueda desde cero, motivado por la preocupación ante la caída en la calidad de los buscadores, el spam SEO y el aumento de contenido irrelevante, así como por el hecho de que los modelos de embeddings basados en Transformer han mejorado notablemente su comprensión del lenguaje natural
- Las limitaciones de los motores de búsqueda existentes provienen de su falta de comprensión de preguntas a nivel humano y de su simple coincidencia basada en palabras clave
- El objetivo es lograr un ranking centrado en la intención que permita que el contenido de buena calidad siempre aparezca en los primeros resultados y que explore de manera equilibrada incluso la cola larga
- El proceso de construir un motor de búsqueda web abarca múltiples áreas, entre ellas ciencias de la computación, lingüística, ontología, NLP, ML, sistemas distribuidos e ingeniería de rendimiento
- Este proyecto fue el desafío de implementar un motor de búsqueda completamente nuevo en 2 meses, partiendo en solitario y sin infraestructura ni experiencia previa
Arquitectura general del sistema
- Se generaron 300 millones de embeddings de texto basados en SBERT en 200 clústeres de GPU
- Cientos de rastreadores concurrentes recopilaron 50,000 páginas por segundo y construyeron un índice total de 280 millones de páginas
- RocksDB y HNSW se almacenaron e indexaron con sharding sobre 200 núcleos, 4 TB de RAM y 82 TB de SSD
- La latencia total de respuesta a consultas se fijó en alrededor de 500 ms
- La estructura y el flujo completos se dividieron en rastreadores, pipeline, almacenamiento, índice de vectores de embeddings, service mesh y áreas de frontend/backend
Experimentos y mejoras en búsqueda basada en embeddings
Neural Embedding Playground
- Los experimentos confirmaron que la búsqueda con modelos de embeddings como SBERT ofrece una comprensión de consultas más natural y mayor precisión que la búsqueda tradicional centrada en palabras clave
- Es posible entender la intención de la consulta de entrada a nivel de contexto y oración, y extraer respuestas realmente relevantes
Ejemplo de búsqueda tradicional vs. búsqueda neuronal
- Búsqueda tradicional: resultados aleatorios, centrados en coincidencia de palabras clave
- Búsqueda por embeddings: entiende el contexto y la intención de la pregunta, y ofrece resultados precisos centrados en oraciones clave o conceptos
- Para combinaciones de conceptos complejos, preguntas implícitas/compuestas y consultas con señales de calidad, permite encontrar respuestas basadas en significado
Parsing y normalización de páginas web
-
El objetivo de la normalización es extraer del HTML solo los elementos de texto con significado, eliminando ruido como diseño visual y elementos de control
-
Siguiendo estándares como WHATWG y MDN, se preservan estructuras como p, table, pre, blockquote, ul, ol y dl
-
Se eliminan por completo elementos de chrome del sitio como menús, navegación, comentarios e interfaces
-
Se aplican reglas especiales por sitio (por ejemplo, en.wikipedia.org) para resolver problemas de extracción excesiva o insuficiente
-
También es posible aprovechar datos estructurados basados en significado (meta, OpenGraph, schema.org, etc.) para construir un grafo de conocimiento y mejorar el ranking
Chunking y preservación del contexto
Chunking a nivel de oración
- Para superar las limitaciones de los modelos de embeddings, se aplicó chunking por oraciones en lugar de usar la página completa
- Durante el chunking, se distinguen correctamente con spaCy sentencizer diversos casos como límites naturales entre oraciones, gramática, abreviaciones, URL y expresiones informales
Preservación y conexión del contexto
- Se identifican relaciones de dependencia entre oraciones, encabezados, párrafos, tablas, etc., y se generan embeddings junto con esa información contextual
- Por ejemplo, incluso la estructura de tablas se inserta encadenando encabezados o cláusulas superiores para no perder el significado de cada fila
Encadenamiento de enunciados (Statement Chaining)
- Con un clasificador DistilBERT se analiza una oración junto con la anterior para automatizar la verificación de dependencia contextual y la extracción de cadenas
- Al generar embeddings, se incluyen conjuntamente todas las oraciones dependientes superiores para mejorar la conservación del contexto
Resultados del uso del prototipo
- En un entorno sandbox, pruebas con diversas consultas reales confirmaron preguntas y respuestas mucho más precisas y ajustadas al contexto que los métodos existentes
- Incluso con discrepancias de palabras clave, omisiones, metáforas o preguntas compuestas, la aplicación reconoce la intención y empareja correctamente las oraciones contextuales, descubriendo también de forma efectiva conocimiento y relaciones ocultas
Rastreador web a gran escala (basado en nodos)
- Se consideraron diversos factores de estabilidad y eficiencia, como work stealing para distribuir la carga, control de concurrencia y tráfico por dominio, y validación de DNS/URL/headers
- El rastreador aplica Promise con I/O asíncrona, mecanismos resistentes a DDoS, gestión de recursos (memoria, delay, backoff) y detección de dominios ruidosos
- Se reforzó el filtrado de URL duplicadas o anómalas mediante normalización de URL, restricciones sobre protocolo, puerto e información de usuario, y canonicalization
Pipeline (cola de tareas distribuida)
- El estado de cada página se gestionó en PostgreSQL y, al inicio, se usaron directamente polling y transacciones
- En un entorno distribuido a gran escala (miles de rastreadores), surgieron problemas de escalabilidad y cuellos de botella de colas/bloqueos, por lo que se pasó a un coordinador en memoria basado en Rust para gestionar el estado de la cola
- Estructura de tareas: índice basado en hash map, binary heap, grupos por dominio, polling aleatorio, intercambio con
swap_removey otros métodos de indexación - La memoria por tarea ronda los 100 B, por lo que incluso 1B de tareas pueden manejarse en un servidor de 128 GB
- Después se desarrolló una cola open source basada en RocksDB como reemplazo de SQS, con soporte de 300 mil ops/seg en un solo nodo
Diseño de almacenamiento (Oracle → PostgreSQL → RocksDB)
- Al inicio se usó Oracle Cloud (egress y almacenamiento de bajo costo) y luego PostgreSQL (TOAST), pero se llegó a los límites de escalado de escritura y rendimiento
- Debido a características de PostgreSQL como MVCC, write amplification y WAL, aparecieron cuellos de botella con INSERT paralelos a gran escala, por lo que finalmente se migró a RocksDB como almacén KV
- Con almacenamiento separado de blobs (BlobDB), archivos SST, multihilo e indexación hash de RocksDB, se aprovechó al máximo el rendimiento de los SSD NVMe
- Se escaló a 64 shards de RocksDB; cada shard se enruta con xxHash(key) y usa serialización con Serde + MessagePack
- Finalmente, miles de clientes (rastreadores/parsers/vectorizadores) procesaban 200 mil ops/seg, con metadatos y blobs almacenados de forma separada y comprimida
Service mesh y networking
- Al escalar la infraestructura, se adoptó un diseño basado en mTLS + HTTP2 para descubrimiento automático de instancias de servicio y seguridad en la comunicación
- En cada nodo se aplicaron certificados basados en una CA raíz, se usó serialización directa con MessagePack y se desarrollaron DNS interno, CoreDNS y un SDK cliente personalizado
- Aunque existía experiencia previa con VPN como ZeroTier y Tailscale, por problemas de red, rendimiento y operación se eligió directamente HTTP + mTLS
- La administración se unificó mediante control de servicios del sistema (
systemd + cgroup + journald), logrando mayor ligereza y estandarización
Pipeline de generación de embeddings con GPU a gran escala
- Al principio se usó la API de OpenAI, pero por costos se migró a entornos de GPU de alto rendimiento como Runpod
- El pipeline separó de forma asíncrona cada etapa, logró más de 90% de eficiencia de GPU y generó 100 mil embeddings por segundo con 250 GPU
- Pipeline en Rust, inferencia en Python → IPC mediante named pipe, y ajuste automático de recursos con backpressure estructurado
Indexación vectorial (HNSW/sharding)
- Se utilizó el algoritmo HNSW para búsqueda vectorial en memoria, con ANN (Approximate Nearest Neighbor) para latencia ultrabaja
- Al alcanzar el límite de RAM, se aplicó sharding uniforme por nodo (64 nodos), y cada shard se buscó en paralelo con su propio índice HNSW
- Debido a que HNSW requiere gran cantidad de RAM y tiene limitaciones para actualizaciones en vivo, finalmente se migró a CoreNN, una vector DB open source basada en disco
- CoreNN puede consultar con alta precisión hasta 3B embeddings incluso en un solo nodo con 128 GB de RAM
UX del motor de búsqueda y optimización de latencia
- En la UX de un motor de búsqueda, la inmediatez de la respuesta es clave (sin indicador de carga, SSR tradicional)
- Con Cloudflare Argo y otros, se acercó el servicio a los edge PoP y se adoptó HTTP/3 para minimizar la latencia de transporte
- Todos los datos se preparan a nivel de servidor de aplicación, se minimizan los round trips de API individuales y se responde de inmediato con páginas minificadas y comprimidas
Este resumen explica de forma concreta cómo un motor de búsqueda web a gran escala que aplica las tecnologías más recientes de procesamiento de lenguaje natural y ML puede construirse end-to-end en solo 2 meses, guiando al lector a través de las principales decisiones de diseño y optimización en sistemas, algoritmos e infraestructura.
Aún no hay comentarios.