Técnico

Cómo implementar rápidamente un sistema de búsqueda de texto con pyvespa

Share

Introducción

En los sistemas modernos de recuperación de información, se aprovechan los modelos de aprendizaje automático. Estos modelos son mucho más pesados y presentan diversos desafíos de implementación, lo que significa que las soluciones personalizadas son casi imposibles de escalar y distribuir. Las soluciones existentes, como Elastic Search, carecen de funcionalidad, ya que no están diseñadas para modelos de aprendizaje profundo. Aquí es donde Vespa viene a facilitar las cosas. Este blog es para aquellos que tengan curiosidad por encontrar soluciones innovadoras a los problemas que surgen al implementar un sistema de recuperación de información. Aquí veremos una forma rápida y sencilla de implementar un sistema de búsqueda de texto utilizando la API de Python de Vespa, pyvespa.

Qué es Vespa

Vespa es una plataforma para aplicaciones que necesitan computación de baja latencia en bases de datos de gran tamaño. Almacena e indexa los datos estructurados, textuales y vectoriales para que las consultas, la selección y el procesamiento y la inferencia de modelos aprendidos por máquina sobre los datos se puedan realizar rápidamente, en tiempo de entrega y a cualquier escala. Le permite escribir y conservar cualquier cantidad de datos y ejecutar grandes volúmenes de consultas sobre los datos, que normalmente se completan en decenas de milisegundos. Las consultas pueden utilizar condiciones de búsqueda vectorial, texto y filtro del vecino más cercano para seleccionar los datos. Luego, todos los datos coincidentes se clasifican según funciones de clasificación (normalmente aprendidas automáticamente) para implementar casos de uso como la relevancia de las búsquedas, la recomendación, la segmentación y la personalización. Todos los datos coincidentes también se pueden agrupar en grupos y subgrupos, donde se agregan los datos de cada grupo para implementar funciones como gráficos, nubes de etiquetas, herramientas de navegación, diversidad de resultados, etc.

Trabajando con python

Vespa es el motor de servicio escalable de código abierto para almacenar, calcular y clasificar macrodatos en el momento en que los usuarios atienden. pyvespa proporciona una API de Python a Vespa: úsala para crear, modificar, implementar e interactuar con instancias de Vespa en ejecución. El objetivo principal de la biblioteca es permitir una creación más rápida de prototipos y facilitar los experimentos de aprendizaje automático para las aplicaciones de Vespa. pyvespa proporciona una API de Python para Vespa. El objetivo principal de la biblioteca es permitir creación de prototipos más rápida y facilitar los experimentos de aprendizaje automático para aplicaciones de Vespa:

  1. Construir y desplegar una aplicación Vespa que usa la API pyvespa.
  2. Conectar a una aplicación Vespa existente y ejecuta consultas desde python.
  3. Importar un paquete de aplicaciones Vespa a partir de archivos y usa pyvespa para acceder a él.

¿Para qué se usa Vespa?

Con la computación de baja latencia en grandes bases de datos, se abre un nuevo mundo de posibilidades para nuevas aplicaciones y funciones. Estos son algunos de los problemas más conocidos para los que la gente usa la Vespa:

  • Búsqueda de texto: Vespa tiene un motor de búsqueda de texto con todas las funciones que admite la recuperación de información tradicional, así como las técnicas modernas basadas en la incrustación.
  • Recomendación y personalización: La recomendación, la personalización del contenido y la segmentación de los anuncios son lo mismo en lo que respecta a la implementación: para un usuario o contexto determinado, evalúa los modelos de recomendación de contenido aprendidos automáticamente para encontrar los mejores elementos y mostrárselos al usuario.
  • Respuesta a la pregunta: La respuesta a las preguntas proporciona respuestas directas a la pregunta del usuario.
  • Navegación semiestructurada: Las aplicaciones que utilizan datos semiestructurados (es decir, una combinación de bases de datos como datos y texto sin formato) suelen beneficiarse al permitir a los usuarios navegar por los datos mediante la navegación estructurada y la búsqueda de texto.
  • Búsqueda personal: La búsqueda personal permite buscar en colecciones personales de datos donde nunca es necesario buscar en muchas colecciones en una sola consulta.
  • Escriba las sugerencias con antelación: cualquier aplicación que utilice la entrada de texto utiliza sugerencias de escritura anticipada, en las que se presentan una serie de sugerencias para completar mientras el usuario escribe. Por lo general, esto implica buscar y clasificar las finalizaciones de los candidatos con una latencia muy baja, un trabajo adecuado para Vespa.

En este post nos centraremos en búsqueda de texto con vespa, así que vamos a ver lo que vespa puede hacer por nosotros.

Búsqueda de texto con Vespa

«Vespa es un motor de búsqueda de texto con todas las funciones que admite la recuperación de información tradicional, así como las técnicas modernas basadas en la incrustación... estos enfoques se pueden combinar de manera eficiente en el mismo modelo de consulta y clasificación...» Las aplicaciones de búsqueda suelen utilizar estas funciones de Vespa:

  • Búsqueda de texto completo con soporte para la posición de las palabras a juego y pertinencia, y operadores avanzados como VARITA sobre términos de texto.
  • Rápido búsqueda aproximada del vecino más cercano (ANN)) en espacios vectoriales, basados en el algoritmo HNSW.
  • Coincidencia por metadatos estructurados.
  • Combinar libremente varios de los operadores coincidentes anteriores en la misma consulta mediante Y y O.
  • Un amplio conjunto de características relevantes que incluyen BM25 y funciones de texto más avanzadas que utilizan información posicional, funciones geográficas y tiempo y así sucesivamente.
  • Clasificación por arbitrario expresiones matemáticas sobre escalar y tensor características, así como por modelos creados en LightGBM, XGBoost, TensorFlow o cualquier herramienta compatible con ONNX. Esto incluye la compatibilidad con modelos de lenguaje modernos basados en transformadores, que se evalúan en los nodos de contenido como otras expresiones de clasificación para garantizar su escalabilidad.
  • Soporte para Clasificación en 2 fases.
  • Mostrar los datos de cualquier documento en los resultados, con soporte opcional para fragmentos estáticos o dinámicos con resaltado.
  • Implemente aplicaciones específicas consulta, resultado y procesadores de documentos en Java desplegado como parte de la aplicación.
  • Agrupación, deduplicación y agregación en todos los partidos.

En este tutorial nos centraremos en la mayoría de estas funciones de Vespa, dejando la importación de modelos a Vespa fuera del alcance. Ahora que sabemos qué es la vespa y para qué sirve, vamos a profundizar en cómo implementar rápidamente un sistema de búsqueda de texto usando pyvespa.

Lo primero es lo primero: los datos

En este ejemplo de uso pyvespa utilizaremos datos de los productos de Amazon. Nuestro conjunto de datos tiene el siguiente formato: como titledescriptionbrandmain_catpriceembedings Cinturón de aspiradora B00002N62Y Eureka 54312-12 Cinturón de aspiradora de repuesto Eureka Amazon Home $4.36 {'valores': [1.3838, 0.5255, -1.0725, -1.1171,... Aspiradora con cable B00002N8CX Eureka Mighty Mite 3670 G... La aspiradora de bote Mighty Mite está equipada con... Eureka Amazon Home 12,97$ {'valores': [1.79, 0.4431, -0.3274, -1.2027, 1... Un par de cosas a tener en cuenta al intentar subir datos a la aplicación vespa: necesitamos un identificador único para cada fila (en este caso será «ASIN», que es el identificador del producto) y los datos de incrustación deben ser un diccionario con una clave llamada «valores» y el valor debe ser el tensor. Antes de importar los datos, deben estar en formato json, como este: [{'asin': 'B00002N62Y', 'title': 'Cinturón de aspiradora Eureka 54312-12', 'category': 'Aspiradoras y cuidado del suelo para el hogar y la cocina', 'description': 'Correa de repuesto para aspiradora Eureka', 'feature': 'Límite de 1 devolución por pedido en este cierre out item', 'rank': '> #1 ,098,930 en Hogar y cocina (consulte los 100 mejores en Hogar y cocina) > #17 ,327 en Hogar y cocina > Aspiradoras y cuidado del suelo', 'marca': 'Eureka', 'main_cat': 'Amazon Home', 'price': '$4.36', 'incrustaciones': {'values': [1.3838, 0.5255, -1,0725,..., 0. 456, 0.8432, 0.3859]}}] Ahora estamos listos para crear nuestro sistema de búsqueda de texto con vespa.

Cómo implementar rápidamente un sistema de búsqueda de texto con pyvespa:

  1. Crear un paquete de aplicaciones
  2. Añadir campos del esquema
  3. Búsqueda varios campos al consultar y definir cómo rango los documentos coinciden
  4. Construir el paquete de solicitud
  5. Despliegue la aplicación vespa
  6. Alimentar y actualización los datos
  7. Consulta la aplicación de búsqueda de texto con el lenguaje Vespa Query

1. Crear un paquete de aplicaciones

Crea un paquete de solicitud , no utilice un - en el nombre: from vespa.package import ApplicationPackage app_package = applicationPackage (name="completePipeline»)

2. Agregar campos al esquema

Añadir campos a la aplicación esquema: En términos de datos, Vespa opera con la noción de documentos. Un documento representa un único elemento del sistema en el que se pueden realizar búsquedas, por ejemplo, un artículo de noticias, una foto o un usuario. Cada tipo de documento debe definirse en la configuración de Vespa mediante un esquema. Los datos introducidos en Vespa deben coincidir con la estructura del esquema, y los resultados que arroje la búsqueda también estarán en este formato. No hay soporte para la creación dinámica de campos en Vespa, se puede decir que los esquemas de documentos de Vespa están fuertemente tipados. Desde vespa.package import Document, Field, HNSW products_document = Document (fields= [Field (name = «id», type = «string», indexing = ["attribute», «summary"]), Field (name = «asin», type = «string», indexing = ["atributo», «resumen"], atributo = ['búsqueda rápida', 'acceso rápido']), campo (nombre = «título», tipo = «cadena», indexación = ["índice», «resumen"], índice = «enable-bm25"), campo (nombre = «descripción», tipo = «cadena», indexación = ["índice», «resumen"], índice = «enable-bm25"), campo (nombre = «marca», tipo = «cadena», indexación = ["atributo», «resumen"]), campo (nombre = «main_cat», tipo = «cadena», indexación = ["atributo», «resumen"]), campo (nombre = «precio», tipo = «cadena», indexación = ["atributo», «resumen"]), Field (name="embeddings», type="tensor <float>(x [512])», indexing= ["attribute», «index"], ann=HNSW (distance_metric="euclidean», max_links_per_node=16, neighbors_to_explore_at_insert=500),)]) El documento está envuelto dentro de otro elemento llamado schema. Este documento contiene varios campos. Cada campo tiene un tipo, como cadena, int o tensor. Los campos también tienen propiedades. Por ejemplo, la indexación de propiedades configura el proceso de indexación de un campo, que define cómo tratará Vespa la entrada durante la indexación.

  • índice: Cree un índice de búsqueda para este campo.
  • atributo: Almacene este campo en la memoria como un atributo: para clasificación, consulta, clasificación y agrupación.
  • resumen: Permite que este campo forme parte del resumen del documento en el conjunto de resultados.

Aquí, también utilizamos la propiedad index, que establece los parámetros de cómo Vespa debe indexar el campo. Para algunos campos, configuramos Vespa para configurar un índice compatible con la clasificación bm25 para la búsqueda de texto. Añadimos el incrustaciones campo definido para contener un tensor unidimensional de flotadores de tamaño 512. Almacenaremos el campo como un atributo en la memoria y crearemos una ANN índice utilizando el HNSW algoritmo (mundo pequeño navegable jerárquico).

Algunos datos útiles a la hora de definir un documento:

Coincidencia Considera el campo del título de nuestro esquema y el documento del producto titulado «Cinturón para aspiradora Eureka 54312-12». En la entrada original, el valor del título es una cadena compuesta por un máximo de 5 palabras, con un solo carácter de espacio en blanco entre ellas. ¿Cómo deberíamos poder buscar en este campo? ¿Para campos de cadenas con índice que por defecto es coincidencia: texto, Vespa actúa procesamiento lingüístico de la cadena. Esto incluye tokenización, normalización y depende del idioma derivando de la cadena. En nuestro ejemplo, esto significa que la cadena anterior está dividida en 5 fichas, lo que permite a Vespa coincidir con este documento para:

  • las consultas de un solo término, como «Eureka», «Vacuum» y «Cleaner»,
  • la frase exacta consulta «Cinturón de aspiradora Eureka 54312-12»,
  • una consulta con dos o más fichas en cualquier orden (por ejemplo, «Eureka Vacuum»).

Así es como todos esperamos que funcione la búsqueda normal de texto libre. Sin embargo, los campos de cadena con indexación:atributos no apoyan coincidencia: texto, únicamente coincidencia exacta o coincidencia de prefijos. La coincidencia exacta es la opción predeterminada y, como su nombre indica, es necesario buscar el contenido exacto del campo para obtener una coincidencia. Consulta los modos de coincidencia compatibles y las diferencias de compatibilidad entre el atributo y el índice. Uso de memoria Los atributos se almacenan en la memoria, a diferencia de los campos con índice, donde los datos se guardan principalmente en el disco, pero se paginan bajo demanda y se almacenan en caché en la caché del búfer del sistema operativo. Incluso con tipos de tipos grandes, se observará que no es práctico definir todos los campos de los tipos de documentos como atributos, ya que esto restringiría considerablemente el número de documentos por nodo de búsqueda. Cuándo usar los atributos El uso de atributos tiene ventajas e inconvenientes: permite ordenar, clasificar y agrupar, pero requiere más memoria y no admite las capacidades de match:text. Cuándo usar los atributos depende de la aplicación; en general, usa los atributos para:

  1. campos utilizados para clasificación, por ejemplo, una marca de tiempo de la última actualización,
  2. campos utilizados para agrupación, por ejemplo, categoría, y
  3. campos a los que se accede en clasificación expresiones

Por último, todos los campos numéricos y tensores utilizados en la clasificación deben definirse como atributos. Combinación de índice y atributo Se admite la combinación de índices y atributos para el mismo campo. En este caso, podemos ordenar y agrupar por categoría, mientras que para buscar o buscar coincidencias se utilizará la coincidencia de índices con match:text, lo que tokenizará y resumirá el contenido del campo.

3. Busque en varios campos al realizar consultas y defina cómo clasificar los documentos coincidentes

UN Conjunto de campos agrupa los campos para la búsqueda: configura las consultas para buscar coincidencias tanto en los títulos como en el cuerpo de los documentos: especifique cómo clasificar los documentos coincidentes definiendo un Perfil de rango. Aquí, el BM25 El perfil de rango combina las puntuaciones de BM25 de título y descripción: desde vespa.package import Schema, fieldSet, RankProfile products_schema = Schema (name="products», document=products_document, fieldsets= [fieldSet (name="default», fields= ["title», «description"])], rank_profiles= [rankProfile (name="bm25", herits="default», first_phase="bm25 (title) + bm25 (descripción)»), rankProfile (name="nativerank», herits="default», first_phase="nativerank (título, descripción)»), rankProfile (name="embedding_similarity», herits="default», first_phase="closeness (embeddings)»), rankProfile (name="bm25_embedddded ing_similarity», herits="predeterminado», first_phase="bm25 (título) + bm25 (descripción) + cercanía (incrustaciones)»)]) Para el productos esquema, definimos cuatro perfiles de rango. El incrustación_similitud usa la Vespa cercanía función de clasificación, que se define como 1/ (1 + distancia) de modo que los productos con incrustaciones más cercanas a la incrustación de la consulta obtendrán una clasificación más alta que los productos que están muy separados. El BM25 es un ejemplo de un perfil de rango basado en términos, y bm25_incrustación_similitud combina señales semánticas y semánticas como ejemplo de enfoque híbrido.

4. Cree el paquete de la aplicación

El tensores las utilizadas en las consultas deben tener su tipo declarado en un perfil de consulta del paquete de la aplicación. El siguiente código indica la incrustación de texto que se enviará a través de la consulta de Vespa. <float>Tiene el mismo tamaño y tipo que el producto incrustado. De vespa.package import ApplicationPackage, QueryProfile, QueryProfileType, QueryTypeField app_package = ApplicationPackage (name="myapp», schema= [products_schema], query_profile=queryProfile (), query_profile_type=queryProfileType (fields= [queryTypeField () name="ranking.features.query (embedding_text)», type="tensor (x [512])»,)]) Aquí definimos el esquema que se cargará en la aplicación. En este ejemplo, agregamos solo el esquema de productos, pero puede ser más de uno. Una vez creado el paquete de la aplicación, podemos visualizar los componentes del paquete, como el esquema: print (app_package.get_schema ('products') .schema_to_text) schema products {document products {field id type string {indexing: attribute | summary} field ASIN type string {indexing: attribute | summary attribute {fast-search fast-access} field title type string {indexing: summary index: summary attribute {fast-search fast-access} field title type string {indexing: index | summary attribute {fast-search fast-access} 25} descripción del campo tipo cadena {indexing: index | summary index: enable-bm25} campo tipo marca string {indexing: attribute | summary} campo main_cat type string {indexing: attribute | summary} field price type string {indexing: attribute | summary} incrustaciones de campo type tensor <float>(x [512]) {indexing: attribute | index attribute {distancia-métrica: euclidiana} index {hnsw {max-links-per-node: 16 vecinos para explorar en insertar: 500}}} fieldset default {fields: title, description} rank-profile bm25 hereda el predeterminado {first-phase {expression: bm25 (title) + bm25 (description)}} rank-profile NativeRank hereda el predeterminado {first phase {expression: nativeRank (title, description)}} rank- profile embedding_similarity hereda el predeterminado {first-phase {expression: closeness (embeddings)}} rank-profile bm25_embedding_similarity hereda el predeterminado {first-phase {expression: bm25 (title) + bm25 (description) + closeness (embeddings)}}} Si decides crear la aplicación más básica directamente utilizando los archivos de configuración de Vespa, terminarás con algo como esto: myapp/ ├── schemas │ ── schema_file.sd ── services.xml La visualización de estos datos puede ayudarte a crear la aplicación vespa fuera de pysvespa más rápido. Esto se debe a que en el ejemplo anterior, para crear el archivo_esquema bajo el esquemas carpeta, solo necesitarás copiar y pegar los datos que obtuviste del get_schema () y esquema_a_texto () funciones.

5. Implemente la aplicación vespa

La aplicación de búsqueda de texto con campos, un conjunto de campos para agrupar campos y un perfil de clasificación para clasificar los documentos coincidentes ya está definida y lista para su implementación. Implemente paquete de aplicaciones en la máquina local mediante Docker, sin salir del bloc de notas, creando una instancia de Vespa Docker: importar sistema operativo desde vespa.deployment importar VespaDocker vespa_docker = vespaDocker () app = vespa_docker.deploy (application_package=app_package) app ahora tiene un Vespa instancia, que se utilizará para interactuar con la aplicación. pyvespa proporciona una API para definir paquetes de aplicaciones Vespa desde python. vespa_docker.deploy exporta los archivos de configuración de Vespa a carpeta_disco - revisarlos es una buena forma de aprender sobre la configuración de Vespa.

6. Alimentar y actualizar los datos

Podemos alimentar a un lote de datos para mayor comodidad o alimentación individual puntos de datos para un mayor control. En este post nos alimentaremos con un lote de datos.

Lote

Datos de alimentación Necesitamos preparar los datos como una lista de dictados que tengan el identificación clave que contiene una identificación única del punto de datos y el campos clave que contiene un diccionario con los campos de datos. batch_feed = [{«id»: product ['asin'], «fields»: product} para idx, product in enumerate (merged_data_json)] A continuación, alimentamos el lote al esquema deseado mediante lote de alimentación método. response = app.feed_batch (schema="products», batch=batch_feed) Actualizar datos Al igual que en los ejemplos sobre la alimentación, podemos actualizar un lote de datos para mayor comodidad o actualizar puntos de datos individuales para aumentar el control. Tenemos que preparar los datos como una lista de dictados que contengan identificación clave que contiene una identificación única del punto de datos, la campos clave que contiene un diccionario con los campos que se van a actualizar y un campo opcional crear clave con un valor booleano para indicar si se debe crear un punto de datos en caso de que no exista (predeterminado para Falso). batch_update = [{«id»: product ['asin'], # data_id «fields»: product, # campos a actualizar «create»: True # Opcional. Crea un punto de datos si no existe; el valor predeterminado es False.} para idx, product in enumerate (merged_data_json)] A continuación, actualizamos el lote según el esquema deseado mediante el update_batch método. response = app.update_batch (schema="products», batch=batch_update)

7. Consulta la aplicación de búsqueda de texto utilizando el lenguaje Vespa Query

Consulta

Consulta la aplicación de búsqueda de texto mediante el Lenguaje de consulta Vespa enviando los parámetros al argumento corporal de app.query: query = {'yql': 'selecciona * de los productos de origen donde userQuery (); ',' query ': 'mejor aspiradora',' ranking ':' nativeRank ',' type ':' all ',' hits ': 5} El tipo de consulta predeterminado es usar todo, exigiendo que todos los términos coincidan con el documento. results = app.query (body=query) print ('Número de documentos recuperados: '+ str (results.number_documents_retrieved)) print ('Número de documentos devueltos: '+ str (len (results.hits))) Número de documentos recuperados: 104 Número de documentos devueltos: 5 A continuación, podemos recuperar información específica de la lista de resultados a través de results.hits o acceder a toda la Vespa respuesta. [hit ["fields"] ["documenid"] para obtener resultados. hits] ['id:products:products: :B00LUQEWMK', 'id:products:products: :B00HL0L8FS', 'id:products:products: :B00D6CNEQQ', 'id:products:products: :B00J3031B8', 'id:products:products: :B00LERGLR4'] results.hits [1] {'id': 'id:products:products: :B00HL0L8FS', 'relevancia': 0.21797787435902613, 'source': 'myapp_content', 'fields': {'sddocname': 'products', 'documenid': 'id:products:products: :B00HL0L8FS', 'asin': 'B00HL0L8FS', 'title': 'Aspirador sin bolsa Dyson Dc40 Animal Upright mejor valorado', 'description': 'The Dyson DC40 La aspiradora vertical Animal está diseñada para todo tipo de suelos, incluyendo alfombras, baldosas, vinilos y madera. La DC40 Animal viene con una miniherramienta con cabezal de turbina para limpiar el pelo y la suciedad de las mascotas en lugares estrechos y de difícil acceso. Si te han gustado las series DC24, DC25, DC28, DC33, DC35 y DC44, seguro que te encantará esta tecnología Radial Root Cyclone de Dyson, con flujos de aire remodelados para maximizar la potencia de succión. La mayoría de los comentarios de los clientes afirman que es el aspirador portátil sin bolsa mejor valorado, incluso mejor que los limpiadores verticales, Bosch, Sharp, Riccar y Hepa comerciales. Su cabezal de limpieza autoajustable mantiene un contacto óptimo, incluso en suelos duros y en el interior del coche. La tecnología Ball All Floors facilita el manejo hasta los bordes y lugares estrechos. La varilla de liberación instantánea se estira hasta 5 veces para limpiar escaleras y superficies de gran alcance. Los controles con la punta de los dedos te permiten apagar al instante la barra de cepillado motorizada para pisos y alfombras duros o delicados. El filtro lavable de por vida captura los alérgenos y expulsa el aire más limpio. Incluye una herramienta combinada con cerdas suaves para quitar el polvo con suavidad. Herramienta para eliminar la suciedad y el polvo de las esquinas y los bordes verticales de las escaleras. Materiales: plástico ABS, metal, componentes electrónicos. Dimensiones: 12,2 pulgadas de ancho x 13,8 pulgadas de profundidad x 42,1 pulgadas de alto, peso: 14,51 libras. Piezas incluidas: herramienta combinada, herramienta para escaleras, miniherramienta con cabezal de turbina. Motor: 200 W de potencia de succión, capacidad: 0,42 galones, alcance del cable: 24 pies, alcance de la manguera: 15,3 pies, modelo: 22913-02, piezas, accesorios y bolsas Dyson. ',' marca ':' Dyson ',' main_cat ': 'Amazon Home',' precio ':' 339,99 '}} Podemos cambiar el modo de recuperación de todos a ninguna: query = {'yql': 'selección* de los productos de origen donde userQuery (); ',' query ': 'mejor aspirador',' ranking ':' nativeRank ',' type ':' any ',' hits ': 5} results = app.query (body=query) print ('Número de documentos recuperados: '+ str (results.number_documents_retrieved)) print ('Número de documentos recuperados: '+ str (results.number_documents_returned)) print ('Número de documentos recuperados: '+ str (results.number_documents_returned)) print ('Número de documentos recuperados: '+ str (results.number_documents_returned)) print ('Número de documentos recuperados: '+ str (results.number_documents_returned)) print ('Número de documentos recuperados: returned: '+ str (len (results.hits))) [hit ["fields"] ["documentid"] for hit in results.hits] Número de documentos recuperados: 1938 Número de documentos devueltos: 5 ['id:products:products: :B00LUQEWMK', 'id:products:products: :B00HL0L8FS', 'id:products:B0000L8FS' ATSRQXW», «identificación: products:products: :B0042X5RBI', 'id:products:products: :B007IX0OGC'] Que recuperará y clasificará todos los documentos que coincidan con alguno de los términos de consulta. Como puede verse en el resultado, casi todos los documentos coincidían con la consulta. Este tipo de consultas se puede optimizar el rendimiento con la Vespa Débil y operador de consulta: query = {'yql': 'seleccione * de los productos de origen donde userQuery (); ',' query ': 'mejor aspirador',' ranking ':' nativeRank ',' type ':' WeakAnd ',' hits ': 5} results = app.query (body=query) print ('Número de documentos recuperados: '+ str (results.number_documents_retrieved)) print ('Número de documentos recuperados: '+ str (results.number_documents_retrieved)) print ('Número de documentos recuperados: '+ str (results.number_documents_retrieved)) print ('Número de documentos recuperados: '+ str (results.number_documents_retrieved)) print ('Número de documentos recuperados: '+ str (results.number_documents_retrieved)) print ('Número de documentos Número de documentos devueltos: '+ str (len (results.hits))) [hit ["fields"] ["documentid"] for hit in results.hits] Número de documentos recuperados: 1835 Número de documentos devueltos: 5 ['id:products:products: :B00LUQEWMK', 'id:products:products: :B00HL0L8FS', 'id:products:products:: B00ATSRQXW', 'id:products:products: :B0042X5RBI', 'id:products:products: :B007IX0OGC'] En este caso, se clasificó completamente un conjunto de documentos mucho más pequeño debido al uso de WeakAnd en lugar de ninguno, y obtuvimos los mismos 5 productos mejor clasificados. En cualquier caso, los documentos recuperados se clasifican según la puntuación de relevancia, que en este caso se obtiene mediante la función de clasificación de NativeRanking que definimos como el perfil de clasificación predeterminado en nuestro archivo de definición de esquemas.

Consulta para incrustar y ANN

Para crear incrustaciones a partir de las consultas, emplearemos un Clasificador de frases basado en Bert de la Transformadores HuggingFace biblioteca: from transformers import BertTokenizer, BertModel tokenizer = BertTokenizer.from_pretrained ('bert-base-uncased') model = bertmodel.from_pretrained ('google/bert_uncased_l-8_h-512_a-8') def query_to_embedding (query): tokens = tokenizer (query, return _tensors="pt», max_length=100, truncation=true, padding=true) outputs = model (**tokens) embedding_query = outputs [0] .tolist () [0] [0] return embedding_query Aquí utilizamos un modelo BERT de tamaño mediano con 8 capas y un tamaño de dimensión oculta de 512. Esto significa que la incrustación será un vector de tamaño 512. Vespa te permite cargar modelos creados en LightGBM, XGBoost, TensorFlow o cualquier herramienta compatible con ONNX. Para simplificar, decidimos usar nuestro modelo bert fuera de vespa para este tutorial.

Recuperación a nivel de consulta

La consulta siguiente envía la incrustación del texto de la consulta (query_to_embedding (query_text)) a través del ranking.features.query (embedding_text) parámetro y utilice el Vecino más cercano operador de búsqueda para recuperar las 100 frases más cercanas en el espacio de incrustación utilizando la distancia euclidiana configurada en el HNSW ajustes. Los productos devueltos se clasificarán según incrustación_similitud perfil de rango definido en productos schema. query_text = 'Aspiradora vertical sin bolsa Eureka Light Speed 200 sin contacto - Rojo' query = {'yql': 'selección* de la frase del producto donde ({targetHits:100} NearestNeighbor (embeddings, embedding_text)); ',' hits ': 5,' query ': query_text, 'ranking.features.query (dding_text)': query_to_embedding (query_text), 'ranking.profile': 'embedding_similarity'} results = app.query (body=query) print ('Número de documentos recuperados: '+ str (results.number_documents_retrieved)) print ('Número de documentos devueltos: '+ str (len (results.hits))) [hit ["fields"] ["ID del documento"] for hit in results.hits] Número de documentos recuperados: 100 Número de documentos devueltos: 5 ['id:products:products: :B003RL86FU', 'id:products:products: :B00D41LZFQ', 'id:products:products: :B003JKH5MY', 'id:products:products: :B00GAWPRUA', 'id:products:products: :B00008OIG 6']

Recuperación híbrida a nivel de consulta

Además de enviar la incrustación de la consulta, podemos enviar la cadena de consulta (texto_consulta) a través del consulta parámetro y utilice el ooperador para recuperar documentos que cumplan con el operador semántico nearestNeighbor o con el operador basado en términos Consulta de usuario. Eligiendo tipo igual ninguna significa que el operador basado en términos recuperará todos los documentos que coincidan con al menos un token de consulta. Los documentos recuperados se clasificarán según el perfil de rango híbrido bm25_incrustación_similitud. query_text = 'Aspiradora vertical sin bolsa Eureka Light Speed 200 sin contacto - Rojo' query = {'yql': 'selecciona * en la frase del producto donde ({TargetHits:100} nearestNeighbor (embeddings, embedding_text)) o userQuery (); ',' hits ': 5,' query ': query_text,' type ':' any ', 'ranking.features.query (embedding_text)': query_to_embedding (query_text), 'ranking.profile': 'bm25_embedding_similarity'} results = app.query (body=query) print ('Número de documentos recuperados: '+ str (results.number_documents_retrieved)) print ('Número de documentos devueltos: '+ str (len (resultados.hits))) [hit ["fields"] ["documentid"] for hit in results.hits] Número de documentos recuperados: 1938 Número de documentos devueltos: 5 ['id:products:products: :B003RL86FU', 'id:products:products: :B00IE3OC1I', 'id:products:products: :B00CTQ8RTY', 'id:products:products:: B00B34TW4M», «identificación: productos: productos:: B008MM5LRA»]

8. Limpieza

vespa_docker.container.stop (tiempo de espera = 600) vespa_docker.container.remove ()

Reflexiones finales

Hoy has aprendido los conceptos básicos de Vespa, desde configurar un documento hasta realizar consultas híbridas utilizando la consulta como texto y la consulta como tensor. Ten en cuenta que pyvespa está pensada para usarse como una herramienta de experimentación para la recuperación de información (IR) y no para crear aplicaciones listas para la producción. Por lo tanto, si tu aplicación requiere funciones o ajustes que no están disponibles en pyvespa, simplemente créala directamente utilizando los archivos de configuración de Vespa, como se muestra en muchos ejemplos de los documentos de Vespa. En Marvik siempre buscamos aplicar este tipo de soluciones innovadoras. Si quieres obtener más información sobre cómo implementar Vespa en tu proyecto, ponte en contacto con [email protected] y podemos ayudarte.

Cada viaje de IA comienza con una conversación

Hablemos
Hablemos