Construindo do zero, em 2 meses, um mecanismo de busca na web com 300 milhões de embeddings neurais
(blog.wilsonl.in)- Em meio à queda na qualidade dos mecanismos de busca e ao avanço dos modelos de embedding baseados em Transformer, o autor relata a experiência de desenvolver, em 2 meses, um mecanismo de busca web baseado em 300 milhões de embeddings
- Com um total de 200 clusters de GPU, um crawler distribuído em larga escala, RocksDB, HNSW e outras infraestruturas e algoritmos de alto desempenho, foi implementada uma busca com compreensão de linguagem natural em tempo real
- Em vez de correspondência por palavras-chave, o objetivo é resposta a consultas centrada na intenção, aplicando várias técnicas de NLP/ML como normalização, chunking e encadeamento de sentenças para parsing de documentos e preservação de contexto
- O texto apresenta o projeto de sistemas distribuídos em larga escala em cada camada, como pipeline, armazenamento, service mesh e índice vetorial, além de estratégias de otimização de gargalos e custos
- Por fim, descreve o surgimento de um mecanismo de busca personalizado com latência ultrabaixa, grande escala distribuída e alta precisão
Visão geral e motivação
- Diante da percepção recente de piora na qualidade dos mecanismos de busca, spam de SEO e aumento de conteúdo irrelevante, e em um contexto em que os modelos de embedding baseados em Transformer passaram a compreender melhor a linguagem natural, o autor decidiu construir do zero um mecanismo de busca
- As limitações dos mecanismos de busca existentes decorrem da falta de capacidade de entender perguntas em nível humano e da simples correspondência baseada em palavras-chave
- O objetivo é um ranking centrado na intenção, que faça com que conteúdo de boa qualidade apareça sempre no topo e explore de forma equilibrada até a cauda longa
- O processo de construção de um mecanismo de busca web abrange várias áreas, como ciência da computação, linguística, ontologia, NLP, ML, sistemas distribuídos e engenharia de performance
- Este projeto é o desafio de começar sozinho, sem infraestrutura prévia nem experiência anterior, e implementar um mecanismo de busca totalmente novo em 2 meses
Arquitetura geral do sistema
- Foram gerados 300 milhões de embeddings de texto baseados em SBERT em 200 clusters de GPU
- Centenas de crawlers simultâneos coletaram 50.000 páginas por segundo, construindo ao todo um índice de 280 milhões de itens
- RocksDB e HNSW foram armazenados e indexados com sharding em 200 núcleos, 4 TB de RAM e 82 TB de SSD
- A latência total de resposta a consultas foi definida em cerca de 500 ms
- A arquitetura e o fluxo gerais foram divididos em crawler, pipeline, armazenamento, índice vetorial de embeddings, service mesh e áreas de front-end/back-end
Experimentos e melhorias em busca baseada em embeddings
Neural Embedding Playground
- Experimentos confirmaram que a busca com modelos de embedding como SBERT oferece entendimento de consulta mais natural e maior precisão do que a busca tradicional focada em palavras-chave
- Tornou-se possível captar a intenção da consulta em nível de contexto e frase, extraindo respostas realmente relevantes
Exemplo de busca tradicional vs. busca neural
- Busca tradicional: resultados aleatórios, focados em correspondência de palavras-chave
- Busca por embeddings: entende o contexto e a intenção da pergunta, fornecendo resultados centrados em frases-chave ou conceitos corretos
- Para combinações complexas de conceitos, perguntas implícitas/compostas e consultas com sinais de qualidade, torna-se possível buscar respostas com base em significado
Parsing e normalização de páginas web
-
O objetivo da normalização é extrair do HTML apenas elementos de texto semanticamente relevantes, removendo ruído como layout e elementos de controle
-
Seguindo padrões como WHATWG e MDN, preserva estruturas como p, table, pre, blockquote, ul, ol e dl
-
Elementos de interface como menus, navegação, comentários e outros componentes de chrome são removidos por completo
-
Regras especiais por site (por exemplo, en.wikipedia.org) são aplicadas para resolver problemas de extração excessiva ou insuficiente
-
Dados estruturados baseados em significado (meta, OpenGraph, schema.org etc.) também podem ser usados para construir um grafo de conhecimento e melhorar o ranking
Chunking e preservação de contexto
Chunking em nível de sentença
- Para superar as limitações dos modelos de embedding, foi adotado chunking baseado em sentenças, em vez de usar a página inteira
- Durante o chunking, o spaCy sentencizer distingue com precisão vários casos, como fronteiras naturais de frases, gramática, abreviações, URLs e expressões informais
Preservação e conexão de contexto
- As relações de dependência entre sentenças, headings, parágrafos, tabelas etc. são identificadas, e essas informações de contexto são incorporadas junto com os embeddings
- Por exemplo, mesmo a estrutura de tabelas é inserida de forma encadeada com headings/cláusulas superiores para que o significado de cada linha não se perca
Encadeamento de sentenças (Statement Chaining)
- Com um classificador DistilBERT, uma frase e a frase anterior são analisadas em conjunto, automatizando a verificação de dependência contextual e a extração de cadeias
- No momento do embedding, todas as sentenças superiores dependentes são incluídas juntas para aumentar a preservação do contexto
Resultados do uso do protótipo
- Em um ambiente sandbox, experimentos com várias consultas reais confirmaram perguntas e respostas muito mais precisas (ajustadas ao contexto) em comparação com métodos anteriores
- Mesmo com divergência de palavras-chave, omissões/metáforas/perguntas compostas, o app reconhece a intenção e faz correspondência com as frases corretas no contexto, revelando de forma eficaz conhecimento e relações ocultas
Crawler web em larga escala (baseado em nós)
- Foram considerados diversos aspectos de estabilidade e eficiência, como work stealing para distribuição de trabalho, controle de concorrência/tráfego por domínio e validação de DNS/URL/headers
- O crawler aplica Promise com I/O assíncrono, mecanismos resistentes a DDoS, gerenciamento de recursos (memória, delay, backoff) e detecção de domínios ruidosos
- Também houve reforço da filtragem de URLs duplicadas/anormais por meio de normalização de URL, restrições de protocolo, porta e informações de usuário, além de canonicalization
Pipeline (fila de tarefas distribuída)
- O estado de cada página foi gerenciado no PostgreSQL; no início, foram usados polling e transações diretamente
- Em ambiente distribuído de grande escala (milhares de crawlers), surgiram problemas de escala e gargalos de filas/locks → o estado da fila passou a ser gerenciado por um coordenador em memória baseado em Rust
- Estrutura das tarefas: índice baseado em hash map, binary heap, grupos por domínio, polling aleatório, swap_remove e outras formas de indexação
- Cada tarefa usa cerca de 100 B de memória, permitindo processar até 1 bilhão de tarefas em um servidor com 128 GB
- Depois, foi desenvolvido um substituto open source do SQS, baseado em RocksDB, com suporte a 300 mil ops/seg em um único nó
Projeto de armazenamento (Oracle → PostgreSQL → RocksDB)
- No início foram usados Oracle Cloud (egress/armazenamento de baixo custo) e depois PostgreSQL (TOAST), mas o sistema encontrou limites de escalabilidade de escrita e performance
- Devido a características do PostgreSQL como MVCC, write amplification e WAL, houve gargalos em INSERTs paralelos em grande escala, levando à migração para o KV store RocksDB
- Com armazenamento separado de blobs no RocksDB (BlobDB), arquivos SST, multithreading e indexação por hash, foi possível aproveitar o desempenho máximo de SSDs NVMe
- Houve expansão para 64 shards de RocksDB — cada shard faz roteamento com base em xxHash(key) e usa serialização Serde + MessagePack
- No fim, milhares de clientes (crawlers/parsers/vectorizers) processavam 200 mil ops/seg, com armazenamento separado e comprimido de metadados e blobs
Service mesh e rede
- Para descoberta automática de instâncias de serviço e segurança na comunicação à medida que a infraestrutura crescia, foi adotado um projeto baseado em mTLS + HTTP2
- Cada nó recebeu certificados com base em uma root CA, usando serialização MessagePack diretamente, além de DNS interno, CoreDNS e um SDK de cliente customizado
- Embora houvesse experiência prévia com VPNs existentes (ZeroTier, Tailscale), por problemas de rede, performance e operação, a escolha final foi por HTTP + mTLS próprios
- O controle dos serviços do sistema (systemd + cgroup + journald) unificou a administração, trazendo leveza e padronização
Pipeline de geração de embeddings em GPU em larga escala
- Inicialmente foi usada a API da OpenAI, mas por questões de custo a operação migrou para ambientes de GPU de alto desempenho como Runpod
- O pipeline separa cada estágio de forma assíncrona, alcança mais de 90% de eficiência das GPUs e gera 100 mil embeddings por segundo em 250 GPUs
- Pipeline em Rust, inferência em Python → IPC por named pipe, com backpressure estruturado para ajuste automático de recursos
Indexação vetorial (HNSW/sharding)
- Foi usada a algoritmo HNSW para busca vetorial em memória, com ANN (Approximate Nearest Neighbor) para latência ultrabaixa
- Ao atingir o limite de RAM, aplicou-se sharding uniforme por nó (64 nós), e cada shard foi pesquisado em paralelo com seu próprio índice HNSW
- Como o HNSW exige muita RAM e tem limitações para atualizações em produção, houve migração posterior para o CoreNN, um vector DB open source baseado em disco
- O CoreNN permite consultas de alta precisão sobre 3 bilhões de embeddings mesmo em um único nó com 128 GB de RAM
UX do mecanismo de busca e otimização de latência
- Na UX de mecanismo de busca, a resposta imediata é o ponto central (sem indicador de carregamento, SSR tradicional)
- Com Cloudflare Argo e afins, o sistema se aproxima de edge PoPs e adota HTTP/3 para minimizar a latência de transmissão
- Todos os dados são preparados no nível do servidor da aplicação, minimizando round trips de API individuais e devolvendo imediatamente páginas minificadas e comprimidas
Este resumo mostra em detalhes como um mecanismo de busca web em larga escala, com as mais recentes tecnologias de processamento de linguagem natural e ML, pode ser construído end-to-end em apenas 2 meses, cobrindo de forma concreta os principais pontos de projeto e otimização em sistemas, algoritmos e infraestrutura.
Ainda não há comentários.