Práctica de búsqueda híbrida basada en la búsqueda en la nube del motor Volcano

En las aplicaciones de búsqueda, la búsqueda de palabras clave tradicional siempre ha sido el método de búsqueda principal. Es adecuada para escenarios de consultas de coincidencia exacta y puede proporcionar una latencia baja y una buena interpretabilidad de los resultados. Sin embargo, la búsqueda de palabras clave no considera información contextual y puede producir resultados irrelevantes. En los últimos años, la búsqueda semántica, una tecnología de mejora de búsqueda basada en tecnología de recuperación de vectores, se ha vuelto cada vez más popular. Utiliza modelos de aprendizaje automático para convertir objetos de datos (texto, imágenes, audio y video, etc.) en vectores. la similitud entre objetos si el modelo utilizado es muy relevante para el dominio del problema, a menudo puede comprender mejor el contexto y la intención de la búsqueda, mejorando así la relevancia de los resultados de la búsqueda. el dominio del problema, el efecto se reducirá considerablemente.
Tanto la búsqueda por palabras clave como la búsqueda semántica tienen ventajas y desventajas obvias, entonces, ¿se puede mejorar la relevancia general de la búsqueda combinando sus ventajas? La respuesta es que las combinaciones aritméticas simples no pueden lograr los resultados esperados por dos razones principales:
  • En primer lugar, las puntuaciones de diferentes tipos de consultas no se encuentran en la misma dimensión comparable, por lo que no se pueden realizar cálculos aritméticos simples directamente.
  • En segundo lugar, en un sistema de recuperación distribuido, las puntuaciones suelen estar en el nivel de fragmentos y las puntuaciones de todos los fragmentos deben normalizarse globalmente.
En resumen, necesitamos encontrar un tipo de consulta ideal para resolver estos problemas. Puede ejecutar cada cláusula de consulta individualmente, recopilar los resultados de la consulta a nivel de fragmento y finalmente normalizar y fusionar las puntuaciones de todas las consultas para devolver el resultado final. es la solución de búsqueda híbrida.
Por lo general, una consulta de búsqueda híbrida se puede dividir en los siguientes pasos:
  1. Fase de consulta: utilice cláusulas de consulta mixtas para la búsqueda por palabras clave y la búsqueda semántica.
  2. Etapa de normalización y fusión de puntuaciones, que sigue a la etapa de consulta.
    1. Dado que cada tipo de consulta proporcionará un rango diferente de puntuaciones, esta etapa realiza una operación de normalización en los resultados de puntuación de cada cláusula de consulta. Los métodos de normalización admitidos son min_max, l2 y rrf.
    2. Para combinar las puntuaciones normalizadas, los métodos de combinación incluyen media_aritmética, media_geométrica y media_armónica.
  3. Los documentos se reordenan según las calificaciones combinadas y se devuelven al usuario.

Ideas de implementación

De la introducción de los principios anteriores, podemos ver que para implementar una aplicación de recuperación híbrida, se requieren al menos estas instalaciones técnicas básicas.
  • Buscador de texto completo
  • motor de búsqueda vectorial
  • Modelo de aprendizaje automático para incrustación de vectores
  • Canalización de datos que convierte texto, audio, video y otros datos en vectores
  • Clasificación por fusión
La búsqueda en la nube de Volcano Engine se basa en los proyectos de código abierto Elasticsearch y OpenSearch. Ha admitido capacidades completas y maduras de recuperación de texto y recuperación de vectores desde el primer día de su lanzamiento. Al mismo tiempo, también ha llevado a cabo una serie de iteraciones funcionales. y evoluciones para escenarios de búsqueda híbrida, proporcionando una solución de búsqueda híbrida que funciona de forma inmediata. Este artículo tomará una aplicación de búsqueda de imágenes como ejemplo para presentar cómo desarrollar rápidamente una aplicación de búsqueda híbrida con la ayuda de la solución de servicio de búsqueda en la nube Volcano Engine.
Su proceso de principio a fin se resume a continuación:
  1. Configurar y crear objetos relacionados.
    1. Canalización de ingesta: admite llamar automáticamente al modelo para almacenar vectores de conversión de imágenes en el índice.
    2. Canal de búsqueda: admite la conversión automática de declaraciones de consulta de texto en vectores para el cálculo de similitud
    3. Índice k-NN: el índice donde se almacena el vector
  2. Escriba los datos del conjunto de datos de imágenes en la instancia de OpenSearch y OpenSearch llamará automáticamente al modelo de aprendizaje automático para convertir el texto en un vector de incrustación.
  3. Cuando el cliente inicia una consulta de búsqueda híbrida, OpenSearch llama al modelo de aprendizaje automático para convertir la consulta entrante en un vector de incrustación.
  4. OpenSearch realiza un procesamiento de solicitudes de búsqueda híbrida, combina puntuaciones de búsqueda de palabras clave y búsqueda semántica y devuelve resultados de búsqueda.

Planificar el combate real

Preparación ambiental

  1. Inicie sesión en el servicio de búsqueda en la nube de Volcano Engine (https://console.volcengine.com/es), cree un clúster de instancias y seleccione OpenSearch 2.9.0 como versión.
  1. Una vez creada la instancia, habilite el nodo AI.
  1. En términos de selección de modelo, puedes crear tu propio modelo o elegir un modelo público. Aquí seleccionamos el modelo público . Después de completar la configuración, hacemos clic en Iniciar ahora .
En este punto, la instancia de OpenSearch y el servicio de aprendizaje automático en el que se basa la búsqueda híbrida están listos.

Preparación del conjunto de datos

Utilice el conjunto de datos de objetos de Amazon Berkeley (https://registry.opendata.aws/amazon-berkeley-objects/) como conjunto de datos. No es necesario descargar el conjunto de datos localmente y se carga directamente en OpenSearch a través de la lógica del código. Codifique el contenido a continuación para obtener más detalles.

Pasos

Instalar dependencias de Python

pip install -U elasticsearch7==7.10.1
pip install -U pandas
pip install -U jupyter
pip install -U requests
pip install -U s3fs
pip install -U alive_progress
pip install -U pillow
pip install -U ipython

Conéctese a OpenSearch

# Prepare opensearch info
from elasticsearch7 import Elasticsearch as CloudSearch
from ssl import create_default_context
# opensearch info
opensearch_domain = '{{ OPENSEARCH_DOMAIN }}'
opensearch_port = '9200'
opensearch_user = 'admin'
opensearch_pwd = '{{ OPENSEARCH_PWD }}'
# remote config for model server
model_remote_config = {
    "method": "POST",
    "url": "{{ REMOTE_MODEL_URL }}",
    "params": {},
    "headers": {
        "Content-Type": "application/json"
    },
    "advance_request_body": {
        "model": "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
    }
}
# dimension for knn vector
knn_dimension = 384
# load cer and create ssl context
ssl_context = create_default_context(cafile='./ca.cer')
# create CloudSearch client
cloud_search_cli = CloudSearch([opensearch_domain, opensearch_port],
                               ssl_context=ssl_context,
                               scheme="https",
                               http_auth=(opensearch_user, opensearch_pwd)
                               )
# index name
index_name = 'index-test'

# pipeline id
pipeline_id = 'remote_text_embedding_test'
# search pipeline id
search_pipeline_id = 'rrf_search_pipeline_test'
  1. Complete la dirección del enlace de OpenSearch y la información de nombre de usuario y contraseña. model_remote_config es la configuración de conexión del modelo de aprendizaje automático remoto, que se puede ver en la información de llamada del modelo. Copie todas las configuraciones de remote_config en la información de llamada a model_remote_config .
  1. En la sección Información de instancia- > Acceso al servicio , descargue el certificado en el directorio actual.
  2. Se le da un nombre de índice, un ID de canalización y un ID de canalización de búsqueda.

Crear canalización de ingesta

Cree una canalización de ingesta, especifique el modelo de aprendizaje automático que se utilizará, convierta los campos especificados en vectores y vuelva a incrustarlos. De la siguiente manera, convierta el campo de título en un vector y guárdelo en caption_embedding .  
# Create ingest pipeline
pipeline_body = {
    "description": "text embedding pipeline for remote inference",
    "processors": [{
        "remote_text_embedding": {
            "remote_config": model_remote_config,
            "field_map": {
                "caption": "caption_embedding"
            }
        }
    }]
}
# create request
resp = cloud_search_cli.ingest.put_pipeline(id=pipeline_id, body=pipeline_body)
print(resp)

Crear canal de búsqueda

Cree el Pipeline necesario para consultar y configurar el modelo remoto.
Métodos de normalización admitidos y métodos de suma ponderada:
  • Método de normalización: min_max , l2 , rrf
  • Método de suma ponderada: arithmetic_mean , geometric_mean , harmonic_mean
Aquí se selecciona el método de normalización rrf.
# Create search pipeline
import requests
search_pipeline_body = {
    "description": "post processor for hybrid search",
    "request_processors": [{
        "remote_embedding": {
            "remote_config": model_remote_config
        }
    }],
    "phase_results_processors": [  # normalization and combination
        {
            "normalization-processor": {
                "normalization": {
                    "technique": "rrf",  # the normalization technique in the processor is set to rrf
                    "parameters": {
                        "rank_constant": 60  # param
                    }
                },
                "combination": {
                    "technique": "arithmetic_mean",  # the combination technique is set to arithmetic mean
                    "parameters": {
                        "weights": [
                            0.4,
                            0.6
                        ]
                    }
                }
            }
        }
    ]
}
headers = {
    'Content-Type': 'application/json',
}
# create request
resp = requests.put(
    url="https://" + opensearch_domain + ':' + opensearch_port + '/_search/pipeline/' + search_pipeline_id,
    auth=(opensearch_user, opensearch_pwd),
    json=search_pipeline_body,
    headers=headers,
    verify='./ca.cer')
print(resp.text)

Crear índice k-NN

  1. Configure la canalización de ingesta creada previamente en el campo index.default_pipeline ;
  2. Al mismo tiempo, configure las propiedades y establezca caption_embedding en knn_vector. Aquí usamos hnsw en faiss.
# Create k-NN index
# create index and set settings, mappings, and properties as needed.
index_body = {
    "settings": {
        "index.knn": True,
        "number_of_shards": 1,
        "number_of_replicas": 0,
        "default_pipeline": pipeline_id  # ingest pipeline
    },
    "mappings": {
        "properties": {
            "image_url": {
                "type": "text"
            },
            "caption_embedding": {
                "type": "knn_vector",
                "dimension": knn_dimension,
                "method": {
                    "engine": "faiss",
                    "space_type": "l2",
                    "name": "hnsw",
                    "parameters": {}
                }
            },
            "caption": {
                "type": "text"
            }
        }
    }
}
# create index
resp = cloud_search_cli.indices.create(index=index_name, body=index_body)
print(resp)

Cargar conjunto de datos

Lea los datos establecidos en la memoria y filtre algunos de los datos que deben usarse.
# Prepare dataset
import pandas as pd
import string
appended_data = []
for character in string.digits[0:] + string.ascii_lowercase:
    if character == '1':
        break
    try:
        meta = pd.read_json("s3://amazon-berkeley-objects/listings/metadata/listings_" + character + ".json.gz",
                            lines=True)
    except FileNotFoundError:
        continue
    appended_data.append(meta)
appended_data_frame = pd.concat(appended_data)
appended_data_frame.shape
meta = appended_data_frame
def func_(x):
    us_texts = [item["value"] for item in x if item["language_tag"] == "en_US"]
    return us_texts[0] if us_texts else None
meta = meta.assign(item_name_in_en_us=meta.item_name.apply(func_))
meta = meta[~meta.item_name_in_en_us.isna()][["item_id", "item_name_in_en_us", "main_image_id"]]
print(f"#products with US English title: {len(meta)}")
meta.head()
image_meta = pd.read_csv("s3://amazon-berkeley-objects/images/metadata/images.csv.gz")
dataset = meta.merge(image_meta, left_on="main_image_id", right_on="image_id")
dataset.head()

Cargar conjunto de datos

Cargue el conjunto de datos en Opensearch y pase image_url y título para cada dato. No es necesario pasar caption_embedding , se generará automáticamente a través del modelo de aprendizaje automático remoto.
# Upload dataset
import json
from alive_progress import alive_bar
cnt = 0
batch = 0
action = json.dumps({"index": {"_index": index_name}})
body_ = ''

with alive_bar(len(dataset), force_tty=True) as bar:
    for index, row in (dataset.iterrows()):
        if row['path'] == '87/874f86c4.jpg':
            continue
        payload = {}
        payload['image_url'] = "https://amazon-berkeley-objects.s3.amazonaws.com/images/small/" + row['path']
        payload['caption'] = row['item_name_in_en_us']
        body_ = body_ + action + "\n" + json.dumps(payload) + "\n"
        cnt = cnt + 1

        if cnt == 100:
            resp = cloud_search_cli.bulk(
                request_timeout=1000,
                index=index_name,
                body=body_)
            cnt = 0
            batch = batch + 1
            body_ = ''

        bar()
print("Total Bulk batches completed: " + str(batch))

Consulta de búsqueda híbrida

Tomemos como ejemplo la consulta de zapatos match . La consulta contiene dos cláusulas de consulta, una es consulta y la otra es remote_neural consulta. Al realizar la consulta, especifique el canal de búsqueda creado previamente como parámetro de consulta. El canal de búsqueda convertirá el texto entrante en un vector y lo almacenará en el campo caption_embedding para consultas posteriores.
# Search with search pipeline
from urllib import request
from PIL import Image
import IPython.display as display
def search(text, size):
    resp = cloud_search_cli.search(
        index=index_name,
        body={
            "_source": ["image_url", "caption"],
            "query": {
                "hybrid": {
                    "queries": [
                        {
                            "match": {
                                "caption": {
                                    "query": text
                                }
                            }
                        },
                        {
                            "remote_neural": {
                                "caption_embedding": {
                                    "query_text": text,
                                    "k": size
                                }
                            }
                        }
                    ]
                }
            }
        },
        params={"search_pipeline": search_pipeline_id},
    )
    return resp
k = 10
ret = search('shoes', k)
for item in ret['hits']['hits']:
    display.display(Image.open(request.urlopen(item['_source']['image_url'])))
    print(item['_source']['caption'])

Pantalla de búsqueda híbrida

Lo anterior toma la aplicación de búsqueda de imágenes como ejemplo para presentar el proceso práctico de cómo desarrollar rápidamente una aplicación de búsqueda híbrida con la ayuda de la solución de servicio de búsqueda en la nube Volcano Engine. ¡Bienvenidos a todos a iniciar sesión en la consola Volcano Engine para operar!


El servicio de búsqueda en la nube Volcano Engine es compatible con Elasticsearch, Kibana y otros software y complementos de código abierto de uso común. Proporciona recuperación de múltiples condiciones, estadísticas e informes de texto estructurado y no estructurado. Puede lograr una implementación elástica con un solo clic. escalado, operación y mantenimiento simplificados y creación rápida de registros, análisis de recuperación de información y otras capacidades comerciales.

¿Cuántos ingresos puede generar un proyecto desconocido de código abierto? El equipo chino de inteligencia artificial de Microsoft empacó colectivamente y se fue a los Estados Unidos, involucrando a cientos de personas. Huawei anunció oficialmente que los cambios de trabajo de Yu Chengdong estaban clavados en el "Pilar de la vergüenza de FFmpeg" durante 15 años. Hace, pero hoy tiene que agradecernos—— ¿Tencent QQ Video venga su humillación pasada? El sitio espejo de código abierto de la Universidad de Ciencia y Tecnología de Huazhong está oficialmente abierto para acceso externo : Django sigue siendo la primera opción para el 74% de los desarrolladores. El editor Zed ha logrado avances en el soporte de Linux. Un ex empleado de una conocida empresa de código abierto . dio la noticia: después de ser desafiada por un subordinado, la líder técnica se puso furiosa y grosera, fue despedida y quedó embarazada. La empleada Alibaba Cloud lanza oficialmente Tongyi Qianwen 2.5 Microsoft dona 1 millón de dólares a la Fundación Rust.
{{o.nombre}}
{{m.nombre}}

Supongo que te gusta

Origin my.oschina.net/u/5941630/blog/11124964
Recomendado
Clasificación