Búsqueda semántica en OpenSearch

OCI Search con OpenSearch soporta la búsqueda semántica a partir de la versión 2.11 de OpenSearch.

Con la búsqueda semántica, los motores de búsqueda utilizan el contexto y el contenido de las consultas de búsqueda para comprender mejor el significado de una consulta, en comparación con la búsqueda por palabras clave, donde los resultados de búsqueda se basan en el contenido que coincide con las palabras clave en una consulta. OpenSearch implementa la búsqueda semántica mediante la búsqueda neuronal, que es una técnica que utiliza grandes modelos de lenguaje para comprender las relaciones entre términos. Para obtener más información sobre la búsqueda neuronal en OpenSearch, consulte Tutorial de búsqueda neuronal.

Uso de la búsqueda neuronal en OCI Search con OpenSearch

Para utilizar la búsqueda neuronal para la búsqueda semántica en OCI Search con OpenSearch, debe:
  1. Registre y despliegue el modelo que elija en el cluster.
  2. Cree un índice y configure un pipeline de ingesta mediante el modelo desplegado. Utilice el pipeline de ingesta para introducir documentos en el índice.
  3. Ejecute consultas de búsqueda semántica en el índice mediante la búsqueda híbrida o la búsqueda neuronal.

Requisitos

Para utilizar la búsqueda semántica, la versión OpenSearch para el cluster debe ser 2.11 o posterior. Por defecto, los nuevos clusters utilizan la versión 2.11. Consulte Creación de un cluster OpenSearch.

Para los clusters existentes configurados para la versión 2.3, puede realizar una actualización en línea a la versión 2.11. Para obtener más información, consulte OpenSearch Cluster Software Upgrades.

Para actualizar los clusters existentes configurados para la versión 1.2.3 a 2.11, debe utilizar el proceso de actualización que se describe en OpenSearch Cluster Software Upgrades.

Antes de empezar a configurar el modelo para la búsqueda semántica, debe completar los requisitos, que incluyen la especificación de la política de IAM aplicable si es necesario y la configuración de los valores de cluster recomendados.

Política de IAM para modelos personalizados y conectores de IA generativa

Si utiliza uno de los modelos previamente entrenados que se alojan en OCI Search con OpenSearch, no necesita configurar permisos, puede pasar al siguiente requisito previo, Configuración de cluster para búsqueda semántica. Consulte también Tutorial de búsqueda semántica.

De lo contrario, deberá crear una política para otorgar el acceso necesario.

Debe crear una política para otorgar el acceso necesario.

Si no está familiarizado con las políticas, consulte Introducción a las políticas y Políticas comunes.

Política de IAM para modelos personalizados

Si utiliza un modelo personalizado, debe otorgar acceso a OCI Search con OpenSearch para acceder al cubo de Object Storage que contiene el modelo.

El siguiente ejemplo de política incluye el permiso necesario:

ALLOW ANY-USER to manage object-family in tenancy WHERE ALL {request.principal.type='opensearchcluster', request.resource.compartment.id='<cluster_compartment_id>'}

Política de IAM para conectores de IA generativa

Si utiliza un conector de IA generativa, debe otorgar acceso a OCI Search con OpenSearch para acceder a los recursos de IA generativa.

El siguiente ejemplo de política incluye el permiso necesario:

ALLOW ANY-USER to manage generative-ai-family in tenancy WHERE ALL {request.principal.type='opensearchcluster', request.resource.compartment.id='<cluster_compartment_id>'}

Regiones para conectores de IA generativa

Para utilizar OCI Generative AI, su arrendamiento debe estar suscrito a la región del Medio Oeste de EE. UU. (Chicago) o a la región del Centro de Alemania (Fráncfort). No es necesario que cree el cluster en ninguna de esas regiones, solo asegúrese de que su arrendamiento esté suscrito a una de las regiones.

Configuración de cluster para búsqueda semántica

Utilice la operación settings (Configuración) de las API del cluster para configurar los valores de cluster recomendados para la búsqueda semántica. El siguiente ejemplo incluye la configuración recomendada:

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
      }
    }
  }
}

Configuración de un modelo

El primer paso al configurar la búsqueda neuronal es configurar el modelo de lenguaje grande que desea utilizar. El modelo se utiliza para generar incrustaciones vectoriales a partir de campos de texto.

Registro de un grupo de modelos

Los grupos de modelos permiten gestionar el acceso a modelos específicos. El registro de un grupo de modelos es opcional, pero si no registra un grupo de modelos, ML Commons crea un nuevo grupo de modelos para usted, por lo que le recomendamos que registre el grupo de modelos.

Registre un grupo de modelos mediante la operación register en las API de grupo de modelos, como se muestra en el siguiente ejemplo:

POST /_plugins/_ml/model_groups/_register
{
  "name": "new_model_group",
  "description": "A model group for local models"
}

Anote el valor model_group_id devuelto en la respuesta:

{
  "model_group_id": "<model_group_ID>",
  "status": "CREATED"
}

Registrar el modelo en el grupo de modelos

Registre el modelo mediante la operación register desde las API de modelo. El contenido de la solicitud POST para la operación de registro depende del tipo de modelo que esté utilizando.

  • Opción 1: Modelos incorporados OpenSearch preentrenados

    Hay disponibles varios modelos de transformador de frases previamente entrenados para que pueda registrar y desplegar directamente en un cluster sin necesidad de descargarlos y, a continuación, cargarlos manualmente en un cubo de almacenamiento privado, a diferencia del proceso necesario para la opción de modelos personalizados. Con esta opción, al registrar un modelo previamente entrenado, solo necesita los valores model_group_id, name, version y model_format del modelo. Consulte Uso de un modelo previamente entrenado OpenSearch para obtener información sobre cómo utilizar un modelo previamente entrenado.

  • Opción 2: Modelos personalizados

    Debe transferir la URL de Object Storage en la sección actions de la operación de registro, por ejemplo:

    POST /_plugins/_ml/models/_register
    {
    .....
            "actions": [
                {
                    "method": "GET",
                    "action_type": "DOWNLOAD",
                    "url": "<object_storage_URL_path>"
                }
            ]
        }
    }

    Para ver un ejemplo completo de una operación de registro, consulte Custom Models - 2: Register the Model.

  • Opción 3: conector de IA generativa

    También puede registrar e implementar un modelo de incrustación remoto GenAI, como cohere.embed-english-v3.0, en el cluster mediante nuestro conector GenAI. Primero debe crear un conector y, a continuación, registrar y desplegar el modelo con el ID de conector, como se describe en los siguientes pasos.

    Nota

    Si utiliza el modelo ON-DEMAND, manténgase al día con las notificaciones de desuso del modelo del servicio GenAI y actualice el conector cuando sea necesario para evitar posibles interrupciones del servicio. Consulte Modelos fundamentales previamente entrenados en IA generativa para conocer los modelos de incrustación soportados a fin de seleccionar un modelo de incrustación de la lista de modelos soportados.

    Si utiliza el modelo DEDICATED, cambie el parámetro servingType en el siguiente ejemplo de carga útil de ON-DEMAND a DEDICATED.

    Cree un conector para el modelo de incrustación de Cohere:

    POST /_plugins/_ml/connectors/_create
    {
      "name": "<connector_name>",
      "description": "<connector_description>",
      "version": "2",
      "protocol": "oci_sigv1",
      
        "parameters": {
          "endpoint": "inference.generativeai.us-chicago-1.oci.oraclecloud.com",
          "auth_type": "resource_principal",
          "model": "<embedding_model>",
          "input_type":"search_document",
          "truncate": "END"
        },
      
         "credential": {
         },
         "actions": [
             {
                 "action_type": "predict",
                 "method":"POST",
                 "url": "https://${parameters.endpoint}/20231130/actions/embedText",
                 "request_body": "{ \"inputs\":[\"${parameters.passage_text}\"], \"truncate\": \"${parameters.truncate}\" ,\"compartmentId\": \"<compartment_ocid>\", \"servingMode\": { \"modelId\": \"${parameters.model}\", \"servingType\": \"ON_DEMAND\" } }",
                 "pre_process_function": "return '{\"parameters\": {\"passage_text\": \"' + params.text_docs[0] + '\"}}';",
                  "post_process_function": "connector.post_process.cohere.embedding"
             }
         ]
     }

    En el siguiente ejemplo se muestra una carga útil para crear un conector para el modelo cohere.embed-english-v3.0:

    POST /_plugins/_ml/connectors/_create
    {
      "name": "OCI GenAI Chat Connector to cohere.embed-english-v3 model",
      "description": "The connector to public Cohere model service for embed",
      "version": "2",
      "protocol": "oci_sigv1",
      
        "parameters": {
          "endpoint": "inference.generativeai.us-chicago-1.oci.oraclecloud.com",
          "auth_type": "resource_principal",
          "model": "cohere.embed-english-v3.0",
          "input_type":"search_document",
          "truncate": "END"
        },
      
         "credential": {
         },
         "actions": [
             {
                 "action_type": "predict",
                 "method":"POST",
                 "url": "https://${parameters.endpoint}/20231130/actions/embedText",
                 "request_body": "{ \"inputs\":[\"${parameters.passage_text}\"], \"truncate\": \"${parameters.truncate}\" ,\"compartmentId\": \"ocid1.compartment.oc1..aaaaaaaa..........5bynxlkea\", \"servingMode\": { \"modelId\": \"${parameters.model}\", \"servingType\": \"ON_DEMAND\" } }",
                 "pre_process_function": "return '{\"parameters\": {\"passage_text\": \"' + params.text_docs[0] + '\"}}';",
                  "post_process_function": "connector.post_process.cohere.embedding"
             }
         ]
     }

Después de realizar la solicitud de registro, puede comprobar el estado de la operación, utilice task_id con la operación Get de las API de tareas, como se muestra en el siguiente ejemplo:

GET /_plugins/_ml/tasks/<task_ID>

Cuando se completa la operación de registro, el valor status en la respuesta a la operación Get es COMPLETED, como se muestra en el siguiente ejemplo:

{
  "model_id": "<embedding_model_ID>",
  "task_type": "REGISTER_MODEL",
  "function_name": "TEXT_EMBEDDING",
  "state": "COMPLETED",
  "worker_node": [
    "3qSqVfK2RvGJv1URKfS1bw"
  ],
  "create_time": 1706829732915,
  "last_update_time": 1706829780094,
  "is_async": true
}

Anote el valor model_id devuelto en la respuesta para utilizarlo al desplegar el modelo.

Despliegue del modelo

Una vez finalizada la operación de registro para el modelo, puede desplegar el modelo en el cluster mediante la operación desplegar de las API de modelo, transfiriendo model_id de la respuesta de la operación Get del paso anterior, como se muestra en el siguiente ejemplo:

POST /_plugins/_ml/models/<embedding_model_ID>/_deploy

Anote el valor task_id devuelto en la respuesta, puede utilizar task_id para comprobar el estado de la operación.

Por ejemplo, de la siguiente respuesta:

{
  "task_id": "<task_ID>",
  "task_type": "DEPLOY_MODEL",
  "status": "CREATED"
}

Para comprobar el estado de la operación de registro, utilice task_id con la operación Get de las API de tareas, como se muestra en el siguiente ejemplo:

GET /_plugins/_ml/tasks/<task_ID>

Cuando se completa la operación de despliegue, el valor status de la respuesta a la operación Get es COMPLETED.

Ingestión de datos

El primer paso al configurar la búsqueda neuronal es configurar el modelo de lenguaje grande que desea utilizar. El modelo se utiliza para generar incrustaciones vectoriales a partir de campos de texto.

Ingestión de datos en índice

Después de crear correctamente un índice, ahora puede ingerir datos en el índice como se muestra en el siguiente ejemplo:

POST /test-index/_doc/1
{
  "passage_text": "there are many sharks in the ocean"
}
 
POST /test-index/_doc/2
{
  "passage_text": "fishes must love swimming"
}
 
POST /test-index/_doc/3
{
  "passage_text": "summers are usually very hot"
}
 
POST /test-index/_doc/4
{
  "passage_text": "florida has a nice weather all year round"
}
Utilice un GET para verificar que los documentos se están ingiriendo correctamente y que las incrustaciones se están generando automáticamente durante la ingestión:
GET /test-index/_doc/3

Crear pipeline de ingesta

Mediante el ID de modelo del modelo desplegado, cree un pipeline de ingestión, como se muestra en el siguiente ejemplo:

PUT _ingest/pipeline/test-nlp-pipeline
{
  "description": "An example neural search pipeline",
  "processors" : [
    {
      "text_embedding": {
        "model_id": "<model_ID>",
        "field_map": {
           "passage_text": "passage_embedding"
        }
      }
    }
  ]
}

El pipeline de ingestión define un procesador y las asignaciones de campos (en este caso "passage_text" → "passage_embedding" ) Esto significa que si utiliza este pipeline en un índice específico para ingerir datos, el pipeline busca automáticamente el campo "passage_text" y utiliza el modelo de pipeline para generar las incrustaciones correspondientes, "passage_embedding" y, a continuación, las asigna antes de la indexación.

Recuerde que "passage_text" → "passage_embedding" están definidos por el usuario y pueden ser lo que desee. Asegúrese de que es consistente con la nomenclatura al crear el índice en el que desea utilizar el pipeline. El procesador de pipeline debe poder asignar los campos como se describe.

Crear un índice

Durante la creación del índice, puede especificar el pipeline que desea utilizar para ingerir documentos en el índice.

En el siguiente ejemplo de llamada de API se muestra cómo crear un índice mediante el pipeline test-nlp-pipeline creado en el paso anterior.

PUT /test-index
{
    "settings": {
        "index.knn": true,
        "default_pipeline": "test-nlp-pipeline"
    },
    "mappings": {
        "properties": {
            "passage_embedding": {
                "type": "knn_vector",
                "dimension": <model_dimension>,
                "method": {
                    "name":"hnsw",
                    "engine":"lucene",
                    "space_type": "l2",
                    "parameters":{
                        "m":512,
                        "ef_construction": 245
                    }
                }
            },
            "passage_text": {
                "type": "text"
            }
        }
    }
}

Al crear el índice, también debe especificar qué implementación de biblioteca del vecino más cercano (ANN) aproximado desea utilizar. OCI Search con OpenSearch soporta las bibliotecas NMSLIB, Faiss y Lucene. Para obtener más información, consulte Motores de búsqueda.

En el siguiente ejemplo se utiliza el motor Lucene:

{
  "model_id": "<model_ID>",
  "task_type": "REGISTER_MODEL",
  "function_name": "TEXT_EMBEDDING",
  "state": "COMPLETED",
  "worker_node": [
    "3qSqVfK2RvGJv1URKfS1bw"
  ],
  "create_time": 1706829732915,
  "last_update_time": 1706829780094,
  "is_async": true
}

Ingestión de datos en índice

Después de crear correctamente un índice, ahora puede ingerir datos en el índice como se muestra en el siguiente ejemplo:

POST /test-index/_doc/1
{
  "passage_text": "there are many sharks in the ocean"
}
 
POST /test-index/_doc/2
{
  "passage_text": "fishes must love swimming"
}
 
POST /test-index/_doc/3
{
  "passage_text": "summers are usually very hot"
}
 
POST /test-index/_doc/4
{
  "passage_text": "florida has a nice weather all year round"
}

Utilice un GET para verificar que los documentos se ingieren correctamente y que las incrustaciones se generan automáticamente durante la ingestión:

GET /test-index/_doc/3