Elasticsearch: agregue búsqueda de vector de párrafo a Lucene

Por Benjamín Trent

La búsqueda de vectores es una herramienta poderosa en la caja de herramientas de recuperación de información. El uso de vectores con búsquedas léxicas como BM25 rápidamente se convirtió en algo común. Pero todavía hay algunos puntos débiles en la búsqueda de vectores que deben resolverse. El principal son los modelos de incrustación de texto y el manejo de entradas de texto más grandes.

Las búsquedas léxicas como BM25 ya están diseñadas para documentos largos, mientras que los modelos de incrustación de texto no. Todos los modelos de incrustación tienen un límite en la cantidad de tokens que pueden incrustar. Por lo tanto, para entradas de texto más largas, se debe dividir en párrafos más cortos que el límite del modelo. Ahora, en lugar de tener un documento con todos los metadatos, tiene varios párrafos e incrustaciones. Si desea conservar los metadatos, debe agregarlos a cada documento nuevo.

Figura 1: En lugar de utilizar una sola pieza de metadatos que indique el primer capítulo de Mujercitas, ahora debe indexar estos datos informativos para cada oración.

Una forma de resolver este problema es utilizar la función de unión de Lucene. Esta es una parte integral del tipo de campo anidado ( nested ) de Elasticsearch. Permite documentos de nivel superior con múltiples documentos anidados, le permite buscar documentos anidados y conectarse nuevamente a sus documentos principales. ¡Esto suena genial para múltiples párrafos y vectores que pertenecen a un único documento de nivel superior! ¡Esto es genial! Pero espera, Elasticsearch® no admite vectores en campos anidados. ¿por qué no? ¿Qué necesita ser cambiado?

Relación padre-hijo en problemas kNN

La pregunta clave es cómo Lucene se conecta nuevamente con el documento principal cuando busca pasajes de vectores secundarios. Al igual que
el filtrado previo y posterior de kNN , el momento de la unión determina la calidad y cantidad de los resultados. Si un usuario busca los primeros cuatro documentos principales (no párrafos) más cercanos al vector de consulta, normalmente espera cuatro documentos. Pero, ¿qué pasa si están buscando pasajes de subvectores y los cuatro vectores más cercanos provienen del mismo documento principal? Esto terminaría devolviendo solo una copia del documento principal, lo cual sería sorprendente. El mismo problema ocurre con el posfiltrado.

Figura 2: Los documentos 3, 5, 10 son los documentos principales. 1, 2 pertenece al 3; 4 pertenece al 5; 6, 7, 8, 9 pertenece al 10.

Busquemos usando el vector de consulta A, los cuatro vectores de párrafo más cercanos son 6, 7, 8, 9. Con "publicar unión", solo terminarás recuperando el documento principal 10.

Figura 3: El vector "A" es el más cercano a todos los niños de 10 años.

¿Qué podemos hacer ante este problema? Una respuesta podría ser: "¡Simplemente aumente el número de vectores de retorno!" Sin embargo, a escala, esto es insostenible. ¿Qué pasa si cada padre tiene al menos 100 hijos y usted quiere los 1.000 vecinos más cercanos? ¡Esto significa que tienes que encontrar al menos 100.000 niños! Esto puede salirse de control rápidamente. Entonces, ¿cuál es la solución?

Pre-uniéndose al rescate

La solución al problema de la "unión posterior" es la "unión previa". ¡Un cambio agregado recientemente a Lucene permite incluir documentos principales al buscar gráficos HNSW! Al igual que con el filtrado previo de kNN , esto garantiza que cuando se nos solicite encontrar los k vecinos más cercanos de un vector de consulta, en lugar de los k párrafos más cercanos representados por un vector denso, podamos devolver los k documentos más cercanos, representados por sus subpárrafos que representan los más similares a el vector de consulta. ¿Cómo se ve esto realmente en la práctica?

Digamos que estamos buscando los mismos documentos anidados que antes:

Figura 4: Los documentos 3, 5, 10 son los documentos principales. 1, 2 pertenece al 3; 4 pertenece al 5; 6, 7, 8, 9 pertenece al 10.

Cuando buscamos documentos y los calificamos, en lugar de realizar un seguimiento de los documentos secundarios, realizamos un seguimiento de los documentos principales y actualizamos sus puntuaciones. La Figura 5 muestra un flujo simple. Para cada documento secundario visitado, obtenemos su puntuación y luego lo rastreamos según su ID del documento principal. De esta manera, cuando buscamos y puntuamos vectores, solo recopilamos las identificaciones de los padres. Esto garantiza una variedad de resultados y no aumenta la complejidad del algoritmo HNSW utilizando las potentes herramientas que ya están disponibles en Lucene. Todo esto requiere sólo un bit extra de memoria para almacenar cada vector.

Figura 5: Cuando buscamos vectores, calificamos y recopilamos documentos principales relevantes. Las puntuaciones sólo se actualizan si son más competitivas que las puntuaciones anteriores.

Pero, ¿cómo funciona esto? ¡Me alegra que hayas preguntado! Existen algunas restricciones que proporcionan atajos realmente agradables. Como puede ver en los ejemplos anteriores, todos los ID de los documentos principales son mayores que los ID de los documentos secundarios. Además, los documentos principales en sí no contienen vectores, lo que significa que los documentos secundarios y principales son conjuntos puramente disjuntos  . Esto proporciona algunas optimizaciones interesantes mediante conjuntos de bits . Los conjuntos de bits proporcionan una estructura excepcionalmente rápida para "dime qué bit configurar a continuación". Para cualquier documento secundario, podemos preguntarle al conjunto de bits: "Oye, ¿cuál es el número en el conjunto que es mayor que yo?" Dado que los conjuntos son separados, sabemos que el siguiente bit a configurar es el ID del documento principal.

en conclusión

En esta publicación, exploramos los desafíos de admitir la recuperación de documentos densos a gran escala y nuestra solución propuesta utilizando campos anidados y uniones en Lucene. Este trabajo en Lucene allana el camino para un almacenamiento y búsqueda más naturales de vectores densos de pasajes de texto largos en documentos y mejoras generales en el modelado de documentos para búsquedas vectoriales en Elasticsearch . ¡Este es un paso adelante muy interesante para la búsqueda de vectores en Elasticsearch!

Si desea discutir esto o cualquier otra cosa relacionada con la búsqueda de vectores en Elasticsearch, únase a nuestro foro de discusión .

Supongo que te gusta

Origin blog.csdn.net/UbuntuTouch/article/details/132600403
Recomendado
Clasificación