Pratique de recherche hybride basée sur la recherche cloud du moteur Volcano

Dans les applications de recherche, la recherche par mot-clé traditionnelle a toujours été la méthode de recherche principale. Elle convient aux scénarios de requêtes avec correspondance exacte et peut fournir une faible latence et une bonne interprétabilité des résultats. Cependant, la recherche par mot-clé ne prend pas en compte les informations contextuelles et peut produire des résultats non pertinents. Ces dernières années, la recherche sémantique, une technologie d'amélioration de la recherche basée sur la technologie de récupération de vecteurs, est devenue de plus en plus populaire. Elle utilise des modèles d'apprentissage automatique pour convertir des objets de données (texte, images, audio et vidéo, etc.) en vecteurs. la similarité entre les objets. Si le modèle utilisé est très pertinent pour le domaine du problème, il peut souvent mieux comprendre le contexte et l'intention de recherche, améliorant ainsi la pertinence des résultats de la recherche. Au contraire, si le modèle n'est pas très pertinent pour le domaine problématique. le domaine problématique, l’effet sera considérablement réduit.
La recherche par mots clés et la recherche sémantique présentent toutes deux des avantages et des inconvénients évidents. La pertinence globale de la recherche peut-elle donc être améliorée en combinant leurs avantages ? La réponse est que de simples combinaisons arithmétiques ne peuvent pas donner les résultats escomptés pour deux raisons principales :
  • Premièrement, les scores des différents types de requêtes ne se situent pas dans la même dimension comparable, de sorte que de simples calculs arithmétiques ne peuvent pas être effectués directement.
  • Deuxièmement, dans un système de récupération distribué, les scores sont généralement au niveau des fragments et les scores de tous les fragments doivent être globalement normalisés.
En résumé, nous devons trouver un type de requête idéal pour résoudre ces problèmes. Il peut exécuter chaque clause de requête individuellement, collecter les résultats de la requête au niveau du fragment, et enfin normaliser et fusionner les scores de toutes les requêtes pour renvoyer le résultat final. est la solution de recherche hybride.
Habituellement, une requête de recherche hybride peut être divisée en les étapes suivantes :
  1. Phase de requête : utilisez des clauses de requête mixtes pour la recherche par mot clé et la recherche sémantique.
  2. Étape de normalisation et de fusion des scores, qui suit l’étape de requête.
    1. Étant donné que chaque type de requête fournit une plage de scores différente, cette étape effectue une opération de normalisation sur les résultats de score de chaque clause de requête. Les méthodes de normalisation prises en charge sont min_max, l2 et rrf.
    2. Pour combiner les scores normalisés, les méthodes de combinaison incluent arithmetic_mean,ometric_mean et harmonic_mean.
  3. Les documents sont réorganisés en fonction des notes combinées et renvoyés à l'utilisateur.

Idées de mise en œuvre

De l’introduction des principes précédents, nous pouvons voir que pour mettre en œuvre une application de récupération hybride, au moins ces installations techniques de base sont nécessaires.
  • Moteur de recherche en texte intégral
  • moteur de recherche de vecteurs
  • Modèle d'apprentissage automatique pour l'intégration de vecteurs
  • Pipeline de données qui convertit le texte, l'audio, la vidéo et d'autres données en vecteurs
  • Tri par fusion
La recherche cloud Volcano Engine est construite sur les projets open source Elasticsearch et OpenSearch. Elle a pris en charge des capacités complètes et matures de récupération de texte et de récupération de vecteurs dès le premier jour de son lancement, et a également réalisé une série d'itérations fonctionnelles. et des évolutions pour les scénarios de recherche hybride, fournissant une solution de recherche hybride qui fonctionne immédiatement. Cet article prendra comme exemple une application de recherche d'images pour présenter comment développer rapidement une application de recherche hybride à l'aide de la solution de service de recherche cloud Volcano Engine.
Son processus de bout en bout se résume comme suit :
  1. Configurer et créer des objets associés
    1. Pipeline d'ingestion : prend en charge l'appel automatique du modèle pour stocker les vecteurs de conversion d'image dans l'index
    2. Pipeline de recherche : prend en charge la conversion automatique des instructions de requête textuelle en vecteurs pour le calcul de similarité.
    3. Indice k-NN : l'index où le vecteur est stocké
  2. Écrivez les données de l'ensemble de données d'image dans l'instance OpenSearch et OpenSearch appellera automatiquement le modèle d'apprentissage automatique pour convertir le texte en vecteur d'intégration.
  3. Lorsque le client lance une requête de recherche hybride, OpenSearch appelle le modèle d'apprentissage automatique pour convertir la requête entrante en un vecteur d'intégration.
  4. OpenSearch effectue un traitement des demandes de recherche hybride, combine les scores de recherche par mot-clé et de recherche sémantique et renvoie les résultats de la recherche.

Planifier un combat réel

Préparation environnementale

  1. Connectez-vous au service de recherche cloud Volcano Engine (https://console.volcengine.com/es), créez un cluster d'instances et sélectionnez OpenSearch 2.9.0 comme version.
  1. Une fois l'instance créée, activez le nœud AI.
  1. En termes de sélection de modèle, vous pouvez créer votre propre modèle ou choisir un modèle public. Ici, nous sélectionnons le modèle public . Après avoir terminé la configuration, cliquez sur Démarrer maintenant .
À ce stade, l’instance OpenSearch et le service d’apprentissage automatique sur lequel s’appuie la recherche hybride sont prêts.

Préparation du jeu de données

Utilisez l'ensemble de données d'objets Amazon Berkeley (https://registry.opendata.aws/amazon-berkeley-objects/) comme ensemble de données. L'ensemble de données n'a pas besoin d'être téléchargé localement et est directement téléchargé sur OpenSearch via la logique de code. contenu du code ci-dessous pour plus de détails.

Pas

Installer les dépendances 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

Connectez-vous à 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. Remplissez l’adresse du lien OpenSearch ainsi que les informations de nom d’utilisateur et de mot de passe. model_remote_config est la configuration de connexion du modèle d'apprentissage automatique à distance, qui peut être consultée dans les informations d'appel du modèle . Copiez toutes les configurations remote_config dans les informations d'appel vers model_remote_config .
  1. Dans la section Informations sur l'instance- > Accès au service , téléchargez le certificat dans le répertoire actuel.
  2. Compte tenu d'un nom d'index, d'un ID de pipeline et d'un ID de pipeline de recherche.

Créer un pipeline d'ingestion

Créez un pipeline d'ingestion, spécifiez le modèle d'apprentissage automatique à utiliser, convertissez les champs spécifiés en vecteurs et réintégrez-les. Comme suit, convertissez le champ de légende en vecteur et stockez-le dans 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)

Créer un pipeline de recherche

Créez le pipeline requis pour l'interrogation et configurez le modèle distant.
Méthodes de normalisation et méthodes de somme pondérée prises en charge :
  • Méthode de normalisation : min_max , l2 , rrf
  • Méthode de sommation pondérée : arithmetic_mean , geometric_mean , harmonic_mean
La méthode de normalisation rrf est sélectionnée ici.
# 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)

Créer un index k-NN

  1. Configurez le pipeline d'ingestion pré-créé dans le champ index.default_pipeline ;
  2. En même temps, configurez les propriétés et définissez caption_embedding sur knn_vector. Ici, nous utilisons hnsw dans 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)

Charger l'ensemble de données

Lisez l'ensemble de données en mémoire et filtrez certaines des données qui doivent être utilisées.
# 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()

Télécharger l'ensemble de données

Téléchargez l'ensemble de données sur Opensearch et transmettez image_url et la légende pour chaque élément de données. Il n'est pas nécessaire de transmettre caption_embedding , il sera automatiquement généré via le modèle d'apprentissage automatique à distance.
# 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))

Requête de recherche hybride

Prenons l'exemple de l'interrogation des chaussures match . La requête contient deux clauses de requête, l'une est une requête et l'autre est remote_neural une requête. Lors de l'interrogation, spécifiez le pipeline de recherche précédemment créé comme paramètre de requête. Le pipeline de recherche convertira le texte entrant en vecteur et le stockera dans le champ caption_embedding pour les requêtes ultérieures.
# 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'])

Affichage de recherche hybride

Ce qui précède prend l'application de recherche d'images comme exemple pour présenter le processus pratique permettant de développer rapidement une application de recherche hybride à l'aide de la solution de service de recherche cloud Volcano Engine. Invitez tout le monde à se connecter à la console Volcano Engine pour fonctionner !


Le service de recherche cloud Volcano Engine est compatible avec Elasticsearch, Kibana et d'autres logiciels et plug-ins open source couramment utilisés. Il fournit une récupération multi-conditions, des statistiques et des rapports de texte structuré et non structuré. Il peut réaliser un déploiement élastique en un clic. mise à l'échelle, opération et maintenance simplifiées et création rapide de journaux d'analyse, d'analyse de récupération d'informations et d'autres fonctionnalités commerciales.

Combien de revenus un projet open source inconnu peut-il rapporter ? L'équipe chinoise d'IA de Microsoft a fait ses valises et s'est rendue aux États-Unis, impliquant des centaines de personnes. Huawei a officiellement annoncé que les changements d'emploi de Yu Chengdong étaient cloués au « pilier de la honte FFmpeg » 15 ans. il y a, mais aujourd'hui il doit nous remercier—— Tencent QQ Video venge son humiliation passée ? Le site miroir open source de l'Université des sciences et technologies de Huazhong est officiellement ouvert à l'accès externe : Django est toujours le premier choix pour 74 % des développeurs. L'éditeur Zed a progressé dans la prise en charge de Linux. Un ancien employé d'une société open source bien connue . a annoncé la nouvelle : après avoir été interpellé par un subordonné, le responsable technique est devenu furieux et impoli, et a été licencié et enceinte. Une employée d'Alibaba Cloud publie officiellement Tongyi Qianwen 2.5 Microsoft fait un don d'un million de dollars à la Fondation Rust.
{{o.name}}
{{m.nom}}

Je suppose que tu aimes

Origine my.oschina.net/u/5941630/blog/11124964
conseillé
Classement