Cómo los modelos de embeddings mantienen las respuestas de Instant Search por debajo de 10 ms

En 2016, nuestro equipo creó una herramienta de búsqueda de dominios prémium diseñada para encontrar al instante dominios similares del mercado secundario mientras escribes. Usamos embeddings de fastText con el índice Annoy de Spotify para ofrecer búsquedas semánticas en menos de 10 ms.

A diferencia de las herramientas tradicionales que solo comprueban la disponibilidad, la nuestra intentaba entender la intención del usuario. Cuando alguien busca «instantdomainsearch.com», nuestro índice encuentra dominios semánticamente similares:

  • domaininstant.com
  • fastdomainsearch.com
  • searchdomain.com

Los inconvenientes de fastText: el contexto específico del dominio

fastText aprendió su comprensión semántica de miles de millones de palabras de Common Crawl y Wikipedia. Pero los dominios representan empresas y marcas, que a menudo utilizan las palabras de forma distinta al texto general de la web.

Tomemos «mint» como ejemplo. Aunque fastText reconoce ambos significados, asigna puntuaciones de similitud mucho mayores a los términos de plantas y hierbas. En el mundo de los dominios y las empresas, «mint» se asocia con más frecuencia al dinero (por ejemplo, Mint.com). Este patrón se repetía con muchos términos, como Cloud o Spark.

Palabra relacionadaSimilitud de fastText con «mint»Contexto
peppermint0.64 (alta)Planta/hierba
herb0.49Planta/hierba
money0.37Dinero/finanzas
finance0.29Dinero/finanzas
budget0.27 (baja)Dinero/finanzas

Nos dimos cuenta de que no era una limitación de fastText, sino que los nombres de dominio habían desarrollado su propio significado semántico.

Esto planteó un reto: ¿cómo podíamos dar a nuestro modelo un contexto específico de dominios?

¿Por qué no usar simplemente IA?

Los LLM modernos entienden el contexto de forma excelente. Cuando probamos GPT-4 para sugerir dominios similares, captó claramente los significados que esperaban los usuarios.

Con una breve instrucción que aportaba contexto de dominios, entendía que «cloud» también significa computación en la nube, «mint» se refiere a finanzas y «spark» a análisis de datos. Sugería dominios que coincidían con lo que realmente quieren los compradores, no solo variantes textuales.

Pero había un impedimento fundamental: la latencia. Nuestro sistema fastText devuelve resultados en menos de 10 ms. GPT-4 promedió 1,7 segundos, 85 veces más lento. En una herramienta donde los usuarios esperan resultados mientras escriben, esperar más de un segundo por pulsación destruiría la experiencia.

Entran los modelos de embeddings: de las palabras a los conceptos

Esto nos llevó a una idea: en lugar de ejecutar LLM en tiempo real, podíamos usarlos sin conexión para entrenar nuestro propio modelo rápido de embeddings. Así tendría un contexto específico de nuestro caso de uso —los dominios— en lugar del contexto general de la web.

Estas son las diferencias prácticas:

Enfoque de fastText (comprensión semántica general):

  • Usa 2 millones de vectores de palabras entrenados con Common Crawl (2017)
  • Entiende la relación entre palabras según su uso en textos web
  • «searchengine» = significado semántico de millones de frases
  • Excelente comprensión del lenguaje general

Nuestro enfoque mejorado (semántica específica de dominios):

  • Trata cada palabra y frase como un concepto empresarial
  • «searchengine» = «Una plataforma de búsqueda y descubrimiento en la web»
  • Añade un contexto de dominios que fastText nunca vio
  • Amplía la base de fastText con técnicas modernas

Para crearlo usamos sentence-transformers, una biblioteca de Python compatible con modelos de embeddings más modernos, diseñados para búsquedas semánticas, que podíamos ajustar a nuestro caso. El panorama de la IA ha evolucionado considerablemente desde 2017 y ahora es mucho más fácil crear modelos especializados. Usamos GPT-4 para generar por lotes millones de ejemplos de entrenamiento específicos de dominios. Después ajustamos estos modelos más recientes para que entendieran los dominios como los profesionales del sector.

La implementación requirió cinco pasos: generar datos, calcular similitudes, estructurarlos para el entrenamiento, ajustar el modelo y optimizar su velocidad en producción.

Paso 1: generar descripciones de dominios con GPT-4

Descubrimos que GPT-4 destaca al ampliar palabras individuales en descripciones con abundante contexto. Con solo un dominio, podía inferir posibles usos, sectores relacionados y conexiones semánticas.

DominioDescripción generada por GPT-4Palabras clave extraídas
torontopancakes.comUn nombre encantador que combina el atractivo de Toronto con la afición a las tortitas, perfecto para amantes del desayuno y exploradores urbanos.food, breakfast, pancakes, maple syrup, Canada, Toronto, brunch, treats, sweet, delicious, local, community
matchupitchutours.comUn nombre adecuado para viajes, inspirado en Machu Picchu, que ofrece visitas guiadas y aventuras inolvidables en los Andes.travel, tours, adventure, Peru, Machu Picchu, history, culture, nature, explore, hiking, mountains, guide
frankenbergerschokolade.comUn nombre rico y tentador que mezcla el encanto de la tradición alemana con la dulzura del chocolate, perfecto para delicias y dulces gourmet.chocolate, gourmet, sweets, German, heritage, desserts, artisan, cocoa, indulgence, handmade, treats, premium

Generar descripciones para una parte de nuestro inventario nos proporcionó datos de entrenamiento etiquetados que captaban la semántica de los dominios.

Paso 2: convertir las descripciones en puntuaciones de similitud

Con una descripción de cada dominio, podíamos medir la similitud semántica mediante modelos de embeddings existentes. Así obtuvimos datos de referencia sobre qué dominios debían considerarse relacionados:

Par de dominiosPuntuación de similitudTipo de relación
google.com ↔ searchengine.com0.68588746Misma categoría
cloudeous.com ↔ cloudivio.com0.82812774Concepto similar
omnigenics.com ↔ omniparent.com0.66224474Solo comparten prefijo
xaute.com ↔ paveup.com0.50881153Sin relación

Estas puntuaciones se convirtieron en nuestros objetivos de entrenamiento. Indicaban al modelo qué dominios debían estar cerca o lejos en el espacio de embeddings.

Paso 3: crear tripletas de entrenamiento para el ajuste fino

El entrenamiento con pérdida de tripletes requiere conjuntos de tres: un dominio de referencia, una coincidencia positiva (similar) y una negativa (distinta). Generamos miles de tripletes a partir de los cálculos de similitud:

Dominio de referenciaCoincidencia positiva (similar)Coincidencia negativa (distinta)
google.comsearchengine.com (0.6858)flowershop.com (0.2754)
uber.comrideshare.com (0.7139)cookbook.net (0.2201)
shopify.comecommerce.com (0.6064)weatherapp.org (0.2656)

Esta estructura obliga al modelo a aprender similitudes relativas en lugar de clasificaciones absolutas.

Paso 4: entrenar nuestro modelo de embeddings específico

Elegimos all-MiniLM-L6-v2 como modelo base y usamos all-mpnet-base-v2 como proveedor inicial de embeddings. Equilibra rendimiento y tamaño. Mediante pérdida de tripletes, lo entrenamos para imitar la comprensión semántica de GPT-4:

Métrica de entrenamientoValor
Modelo baseall-MiniLM-L6-v2
Muestras de entrenamiento500,000
Épocas25
Correlación final con GPT-4~0.87

La correlación de 0,87 significaba que nuestro modelo ligero captaba la mayor parte de la comprensión semántica de GPT-4 mientras se ejecutaba varios órdenes de magnitud más rápido.

Paso 5: optimizar de unos 500 ms a 10 ms

Implementamos la primera versión de esta nueva tecnología en Python para probar algunas hipótesis. Usamos bibliotecas habituales como usearch para HNSW y SQLite para recuperar el dominio correspondiente. Los resultados prometedores, en su mayoría de unos 500 ms, mostraron que íbamos en la dirección correcta. Entrenar un buen modelo resolvía la mitad del problema. ¡Todavía necesitábamos una latencia inferior a 50 ms!

La mayor parte de nuestra tecnología ya está escrita en Rust, así que decidimos trasladar también estos modelos a Rust. Para evitar dependencias pesadas y porque Torch no es lo más rápido para inferencia, elegimos ONNX Runtime.

  • Formato del modelo: ONNX, 3 veces más rápido que PyTorch
  • Entorno de ejecución: Rust + ort, con sobrecarga mínima y excelente rendimiento en CPU
  • Índice: HNSW para un conjunto limitado de unos 25 millones de dominios del mercado secundario
  • Hardware: solo CPU, sin sobrecarga de coordinación de GPU
  • Optimizaciones: salida optimizada y cuantizada (optimum)

Resultado: una latencia de 10 ms en el percentil 95, dentro de nuestro objetivo de 25 ms. Esta velocidad es esencial para mantener la experiencia instantánea que hemos optimizado con nuestra infraestructura CDN.

La IA en desarrollo frente a producción

«Con IA» suele entenderse como integrar un LLM en cada petición, pero su ubicación es una decisión de diseño con distintas ventajas y costes.

  • En desarrollo: menos contexto, más velocidad
  • En producción: más contexto, menos velocidad

Nuestra búsqueda instantánea demuestra hasta dónde puede llegar el primer enfoque: destilamos el conocimiento de los billones de parámetros de GPT-4 en un modelo de embeddings de 22,7 millones de parámetros, que devuelve resultados semánticos en menos de 10 ms, sin contar la distancia entre el usuario y nuestros servidores.

Por otro lado, nuestro generador de nombres de empresas muestra dónde destaca un LLM en directo: idear marcas requiere un razonamiento nuevo y amplio, así que intercambiamos velocidad por profundidad y ofrecemos sugerencias que realmente necesitan un contexto de más de un billón de parámetros.

No significa que los LLM en desarrollo sean mejores que en producción. Se trata de ajustar la profundidad del contexto al coste de latencia.

Tenemos previsto desplegar nuestro nuevo modelo durante el próximo mes.