Revue de processus de recherche sémantique
Découvrez comment effectuer une recherche sémantique des données à l'aide d'OCI Search avec OpenSearch.
Prérequis
Avant de commencer, vous devez effectuer les opérations suivantes :
-
Sélectionnez l'un des modèles préentraînés pris en charge par OCI Search avec OpenSearch
-
Vérifiez que le cluster OpenSearch est version 2.11.
-
Mettez à jour les paramètres du cluster pour effectuer une recherche sémantique. L'exemple de commande suivant met à jour les paramètres applicables :
PUT _cluster/settings { "persistent": { "plugins": { "ml_commons": { "only_run_on_ml_node": "false", "model_access_control_enabled": "true", "native_memory_threshold": "99", "rag_pipeline_feature_enabled": "true", "memory_feature_enabled": "true", "allow_registering_model_via_local_file": "true", "allow_registering_model_via_url": "true", "model_auto_redeploy.enable":"true", "model_auto_redeploy.lifetime_retry_times": 10 } } } }
Enregistrer le groupe de modèles
Utilisez des groupes de modèles pour regrouper logiquement les modèles et contrôler qui y a accès. Enregistrez un groupe de modèles à l'aide de l'opération Enregistrer dans les API de groupe de modèles, comme indiqué dans l'exemple suivant :
POST /_plugins/_ml/model_groups/_register
{
"name": "general pretrained models",
"description": "A model group for pretrained models hosted by OCI Search with OpenSearch"
}
Notez le message model_group_id
renvoyé dans la réponse :
{
"model_group_id": "<model_group_ID>",
"status": "CREATED"
}
Inscrire et déployer le modèle
Vous disposez des trois options suivantes pour la recherche sémantique :
- Option 1 : inscrivez et déployez un modèle préentraîné hébergé dans OCI Search avec OpenSearch en suivant les étapes décrites dans Utilisation d'un modèle préentraîné OpenSearch. Cette option est la plus simple à utiliser, vous n'avez pas besoin de configurer de stratégies IAM supplémentaires et la charge utile n'est pas aussi complexe que la charge utile pour l'option suivante.
- Option 2 : importez, enregistrez et déployez un modèle préentraîné OpenSearch à l'aide des étapes décrites dans Modèles personnalisés. Vous pouvez ainsi télécharger le fichier de modèle vers un bucket Object Storage, puis indiquer l'URL Object Storage du fichier de modèle lors de l'inscription du modèle.
- Option 3 : vous pouvez également inscrire et déployer un modèle d'intégration GenAI distant tel que cohere.embed-english-v3.0 dans votre cluster à l'aide de notre connecteur GenAI. Vous devez d'abord créer un connecteur, puis enregistrer et déployer le modèle à l'aide de l'ID de connecteur, comme décrit dans les étapes suivantes.Remarque
Si vous utilisez le modèle ON-DEMAND, restez à jour avec les notifications d'abandon de modèle du service GenAI et mettez à jour votre connecteur si nécessaire pour éviter d'éventuelles interruptions de service. Reportez-vous à Modèles de base préentraînés dans l'IA générative pour connaître les modèles d'intégration pris en charge afin de sélectionner un modèle d'intégration dans la liste des modèles pris en charge.Si vous utilisez le modèle DEDICATED, remplacez le paramètre
servingType
de l'exemple de charge utile suivant de ON-DEMAND à DEDICATED.
model_group_id
: si vous avez terminé l'étape 1, il s'agit de la valeur de model_group_id pour la demande _register.name
: nom du modèle à utiliser pour le modèle préentraîné.version
: numéro de version du modèle préentraîné à utiliser.model_format
: format du modèle,TORCH_SCRIPT
ouONNX
.
Enregistrez le modèle à l'aide de l'opération d'enregistrement à partir des API de modèle, comme indiqué dans l'exemple suivant :
POST /_plugins/_ml/models/_register
{
"name": "huggingface/sentence-transformers/msmarco-distilbert-base-tas-b",
"version": "1.0.2",
"model_group_id": "<model_group_ID>",
"model_format": "TORCH_SCRIPT"
}
Notez la valeur task_id
renvoyée dans la réponse. Vous pouvez utiliser task_id
pour vérifier le statut de l'opération.
Par exemple, à partir de la réponse suivante :
{
"task_id": "<task_ID>",
"status": "CREATED"
}
pour vérifier le statut de l'opération d'inscription, utilisez task_id
avec l'opération Get des API de tâche, comme indiqué dans l'exemple suivant :
GET /_plugins/_ml/tasks/<task_ID>
Une fois l'opération d'inscription terminée, la valeur state
dans la réponse à l'opération Get est COMPLETED
, comme indiqué dans l'exemple suivant :
{
"model_id": "<embedding_model_ID>",
"task_type": "REGISTER_MODEL",
"function_name": "TEXT_EMBEDDING",
"state": "COMPLETED",
"worker_node": [
"f2b_8-mVRVyVqeKqsA7dcQ"
],
"create_time": 1706831015570,
"last_update_time": 1706831070740,
"is_async": true
}
Notez la valeur model_ID
renvoyée dans la réponse à utiliser lors du déploiement du modèle.
Déploiement du modèle
Une fois l'opération d'inscription terminée pour le modèle, vous pouvez déployer le modèle vers le cluster à l'aide de l'opération de déploiement des API de modèle, en transmettant model_ID
à partir de la réponse de l'opération Get à l'étape précédente, comme indiqué dans l'exemple suivant :
POST /_plugins/_ml/models/<embedding_model_ID>/_deploy
Notez la valeur task_id
renvoyée dans la réponse. Vous pouvez utiliser task_id
pour vérifier le statut de l'opération.
Par exemple, à partir de la réponse suivante :
{
"task_id": "<task_ID>",
"task_type": "DEPLOY_MODEL",
"status": "CREATED"
}
pour vérifier le statut de l'opération d'inscription, utilisez task_ID
avec l'opération Get des API des tâches, comme indiqué dans l'exemple suivant :
GET /_plugins/_ml/tasks/<task_ID>
Une fois l'opération de déploiement terminée, la valeur status
dans la réponse à l'opération Get est COMPLETED
.
Création d'un pipeline d'ingestion k-NN
Une fois l'opération de déploiement terminée, créez un pipeline d'inclusion à l'aide du modèle déployé. Le pipeline d'inclusion utilise le modèle déployé pour générer automatiquement les vecteurs d'intégration pour chaque document au moment de l'inclusion. Le processeur gère tout pour l'intégration, vous n'avez donc qu'à mapper correctement le champ de texte attendu dans le document en cours de conversion en intégration. L'exemple suivant illustre la création d'un pipeline d'inclusion :
PUT _ingest/pipeline/<pipeline_name>
{
"description": "An example neural search pipeline",
"processors" : [
{
"text_embedding": {
"model_id": "<embedding_model_ID>",
"field_map": {
"<text_field_name>": "<embedding_field_name>"
}
}
}
]
}
Si le pipeline d'inclusion a été créé, la réponse suivante est renvoyée :
{
"acknowledged": true
}
Créer un indice
Créez un index à l'aide du pipeline d'inclusion créé à l'étape précédente. Vous pouvez utiliser n'importe quel moteur ANN disponible dans l'index. L'exemple suivant utilise le moteur Lucene :
PUT /lucene-index
{
"settings": {
"index.knn": true,
"default_pipeline": "<pipeline_name>"
},
"mappings": {
"properties": {
"<embedding_field_name>": {
"type": "knn_vector",
"dimension": <model_dimension>,
"method": {
"name":"hnsw",
"engine":"lucene",
"space_type": "l2",
"parameters":{
"m":512,
"ef_construction": 245
}
}
},
"<text_field_name>": {
"type": "text"
}
}
}
}
Le champ passage_text
de l'index de création correspond au champ passage_text
dans le pipeline d'inclusion, ce qui permet au pipeline de savoir comment créer des intégrations, puis de les mettre en correspondance avec des documents au moment de l'inclusion.
Pour vous aider à choisir le moteur à utiliser et les paramètres de configuration disponibles pour ces moteurs, reportez-vous à index k-NN et à recherche approximative k-NN.
Voici un exemple de réponse pour une création d'index réussie :
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "lucene-index"
}
Inclusion de documents dans l'index
Incluez des données dans votre index, comme indiqué dans l'exemple suivant :
POST /lucene-index/_doc/1
{
"<text_field_name>": "there are many sharks in the ocean"
}
POST /lucene-index/_doc/2
{
"<text_field_name>": "fishes must love swimming"
}
POST /lucene-index/_doc/3
{
"<text_field_name>": "summers are usually very hot"
}
POST /lucene-index/_doc/4
{
"<text_field_name>": "florida has a nice weather all year round"
}
Réponse :
# POST /lucene-index/_doc/1
{
"_index": "lucene-index",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
# POST /lucene-index/_doc/2
{
"_index": "lucene-index",
"_id": "2",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 1,
"_primary_term": 1
}
# POST /lucene-index/_doc/3
{
"_index": "lucene-index",
"_id": "3",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 2,
"_primary_term": 1
}
# POST /lucene-index/_doc/4
{
"_index": "lucene-index",
"_id": "4",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 3,
"_primary_term": 1
}
Exécutez la commande suivante pour vérifier l'un des documents afin de vous assurer que les incorporations sont générées correctement :
GET /lucene-index/_doc/3
Réponse :
{
"_index": "lucene-index",
"_id": "3",
"_version": 1,
"_seq_no": 2,
"_primary_term": 1,
"found": true,
"_source": {
"<embedding_field_list>": [
-0.1254959,
-0.3151774,
0.03526799,
0.39322096,
-0.0475556,
-0.12378334,
-0.032554347,
0.4033895,
0.050718695,
-0.3587931,
0.097042784,
0.11742551,
-0.06573639,
0.14252506,
-0.466573,
0.56093556,
-0.2815812,
-0.00016521096,
-0.2858566,
Effectuer une recherche sémantique
Cette section contient des exemples de différents types de recherches sémantiques que vous pouvez effectuer.
Recherche sémantique avec recherche hybride
A l'aide de l'ID de modèle de Inscription et déploiement du modèle, effectuez une recherche sémantique avec la recherche hybride comme suit :
GET lucene-index/_search
{
"query": {
"bool" : {
"should" : [
{
"script_score": {
"query": {
"neural": {
"<embedding_field_name>": {
"query_text": "what are temperatures in miami like",
"model_id": "<embedding_model_ID>",
"k": 2
}
}
},
"script": {
"source": "_score * 1.5"
}
}
}
]
}
},
"fields": [
"<text_field_name>"
],
"_source": false
}
Réponse :
{
"took": 343,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 0.032253794,
"hits": [
{
"_index": "lucene-index",
"_id": "4",
"_score": 0.032253794,
"fields": {
"<text_field_name>": [
"florida has a nice weather all year round"
]
}
},
{
"_index": "lucene-index",
"_id": "3",
"_score": 0.031487543,
"fields": {
"<text_field_name>": [
"summers are usually very hot"
]
}
}
]
}
}
Vous pouvez constater que la question de requête ne mentionne ni Floride, ni mété, ni été, mais que le modèle infère la signification sémantique des températures et miami pour renvoyer les réponses les plus pertinentes.
Recherche sémantique avec recherche neuronale
A l'aide de l'ID de modèle de Inscription et déploiement du modèle, effectuez une recherche sémantique avec la recherche neuronale comme suit :
GET /lucene-index/_search
{
"_source": {
"excludes": [
"<embedding_field_name>"
]
},
"query": {
"neural": {
"<embedding_field_name>": {
"query_text": "good climate",
"model_id": "<embedding_model_ID>",
"k": 5
}
}
}
}
Réponse :
{
"took": 36,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 4,
"relation": "eq"
},
"max_score": 0.012060728,
"hits": [
{
"_index": "lucene-index",
"_id": "4",
"_score": 0.012060728,
"_source": {
"passage_text": "florida has a nice weather all year round"
}
},
{
"_index": "lucene-index",
"_id": "1",
"_score": 0.010120423,
"_source": {
"passage_text": "there are many sharks in the ocean"
}
},
{
"_index": "lucene-index",
"_id": "3",
"_score": 0.00985171,
"_source": {
"passage_text": "summers are usually very hot"
}
},
{
"_index": "lucene-index",
"_id": "2",
"_score": 0.009575767,
"_source": {
"passage_text": "fishes must love swimming"
}
}
]
}
}