Pesquisa Semântica em OpenSearch

O OCI Search com OpenSearch suporta pesquisa semântica começando com o OpenSearch versão 2.11.

Com a pesquisa semântica, os mecanismos de pesquisa usam o contexto e o conteúdo das consultas de pesquisa para entender melhor o significado de uma consulta, em comparação com a pesquisa por palavras-chave, em que os resultados da pesquisa são baseados em palavras-chave de correspondência de conteúdo em uma consulta. O OpenSearch implementa a pesquisa semântica usando a pesquisa neural, que é uma técnica que usa grandes modelos de linguagem para entender as relações entre termos. Para obter mais informações sobre pesquisa neural em OpenSearch, consulte Tutorial de pesquisa neural.

Usando o Neural Search no OCI Search com o OpenSearch

Para usar a pesquisa neural para pesquisa semântica no OCI Search com o OpenSearch, você precisa:
  1. Registre e implante sua escolha de modelo no cluster.
  2. Crie um índice e configure um pipeline de ingestão usando o modelo implantado. Use o pipeline de ingestão para ingerir documentos no índice.
  3. Execute consultas de pesquisa semântica no índice usando pesquisa híbrida ou neural.

Pré-requisitos

Para usar a pesquisa semântica, a versão do OpenSearch do cluster deve ser 2.11 ou mais recente. Por padrão, os novos clusters usam a versão 2.11. Consulte Creating an OpenSearch Cluster.

Para clusters existentes configurados para a versão 2.3, você pode executar um upgrade em linha para a versão 2.11. Para obter mais informações, consulte OpenSearch Upgrades de Software do Cluster.

Para fazer upgrade de clusters existentes configurados para a versão 1.2.3 para 2.11, use o processo de upgrade descrito em OpenSearch Upgrades de Software do Cluster.

Antes de começar a configurar o modelo para pesquisa semântica, você precisa concluir os pré-requisitos, que incluem especificar a política aplicável do IAM, se necessário, e configurar as definições de cluster recomendadas.

Política do IAM para Modelos Personalizados e Conectores de IA Generativa

Se você estiver usando um dos modelos pré-treinados hospedados no OCI Search com o OpenSearch que não precisa configurar permissões, poderá ignorar o próximo pré-requisito, Definições de Cluster para Pesquisa Semântica. Consulte também Passo a Passo da Pesquisa Semântica.

Caso contrário, você precisará criar uma política para conceder o acesso necessário.

Você precisa criar uma política para conceder o acesso necessário.

Se você não conhece as políticas, consulte Conceitos Básicos de Políticas e Políticas Comuns.

Política do IAM para Modelos Personalizados

Se você estiver usando um modelo personalizado, precisará conceder acesso para o OCI Search com OpenSearch para acessar o bucket do Object Storage que contém o modelo.

O exemplo de política a seguir inclui a permissão necessária:

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

Política do IAM para Conectores de IA Generativa

Se você estiver usando um conector de IA generativa, precisará conceder acesso para o OCI Search com OpenSearch para acessar recursos do serviço Generative AI.

O exemplo de política a seguir inclui a permissão necessária:

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

Regiões para Conectores de IA Generativa

Para usar o OCI Generative AI, sua tenancy deve estar inscrita na região Centro-Oeste dos EUA (Chicago) ou na região Central da Alemanha (Frankfurt). Você não precisa criar o cluster em nenhuma dessas regiões, apenas certifique-se de que sua tenancy esteja inscrita em uma das regiões.

Definições de Cluster para Pesquisa Semântica

Use a operação configurações das APIs do Cluster para configurar as definições de cluster recomendadas para pesquisa semântica. O exemplo a seguir inclui as configurações recomendadas:

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

Configurando um Modelo

A primeira etapa ao configurar a pesquisa neural é configurar o modelo de linguagem grande que você deseja usar. O modelo é usado para gerar incorporações vetoriais a partir de campos de texto.

Registrar um Grupo de Modelos

Os grupos de modelos permitem que você gerencie o acesso a modelos específicos. O registro de um grupo de modelos é opcional. No entanto, se você não registrar um grupo de modelos, o ML Commons criará registros de um novo grupo de modelos para você. Por isso, recomendamos que você registre o grupo de modelos.

Registre um grupo de modelos usando a operação registrar nas APIs do Grupo de Modelos, conforme mostrado no seguinte exemplo:

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

Anote o model_group_id retornado na resposta:

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

Registrar o Modelo no Grupo de Modelos

Registre o modelo usando a operação registrar nas APIs do Modelo. O conteúdo da solicitação POST para a operação de registro depende do tipo de modelo que você está usando.

  • Opção 1: Modelos pré-treinados integrados do OpenSearch

    Vários modelos de transformador de frase pré-treinados estão disponíveis para você se registrar e implantar diretamente em um cluster sem precisar fazer download e, em seguida, fazer upload deles manualmente em um bucket de armazenamento privado, ao contrário do processo necessário para a opção de modelos personalizados. Com essa opção, quando você registra um modelo pré-treinado, só precisa dos modelos model_group_id, name, version e model_format. Consulte Usando um Modelo Pré-treinado OpenSearch para saber como usar um modelo pré-treinado.

  • Opção 2: Modelos personalizados

    Você precisa informar o URL do Object Storage na seção actions na operação de registro, por exemplo:

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

    Para obter um exemplo completo de uma operação de registro, consulte Modelos Personalizados - 2: Registrar o Modelo.

  • Opção 3: Conector de IA generativa

    Você também pode registrar e implantar um modelo de incorporação GenAI remoto, como o cohere.embed-english-v3.0, no seu cluster usando nosso Conector GenAI. Você deve criar um conector primeiro e, em seguida, registrar e implantar o modelo usando o ID do conector, conforme descrito nas etapas a seguir.

    Observação

    Se você estiver usando o modelo ON-DEMAND, mantenha-se atualizado com as notificações de descontinuação do modelo do serviço GenAI e atualize seu conector quando necessário para evitar possíveis interrupções de serviço. Consulte Modelos Básicos Pré-treinados no Serviço Generative AI para obter os modelos de incorporação suportados e selecionar um modelo de incorporação na lista de modelos suportados.

    Se você estiver usando o modelo DEDICATED, altere o parâmetro servingType no exemplo de payload a seguir de ON-DEMAND para DEDICATED.

    Crie um conector para o modelo de Incorporação 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"
             }
         ]
     }

    O exemplo a seguir mostra um payload para criar um conector para o 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"
             }
         ]
     }

Depois de fazer a solicitação de registro, você poderá verificar o status da operação, usar task_id com a operação Obter das APIs de Tarefas, conforme mostrado no seguinte exemplo:

GET /_plugins/_ml/tasks/<task_ID>

Quando a operação de registro estiver concluída, o valor status na resposta à operação Obter será COMPLETED, conforme mostrado o seguinte exemplo:

{
  "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 o valor model_id retornado na resposta a ser usada quando você implantar o modelo.

Implantar o Modelo

Depois que a operação de registro for concluída para o modelo, você poderá implantar o modelo no cluster usando a operação de implantação das APIs de Modelo, informando o model_id da resposta da operação Obter na etapa anterior, conforme mostrado no seguinte exemplo:

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

Anote o task_id retornado na resposta. Você pode usar o task_id para verificar o status da operação.

Por exemplo, a partir da seguinte resposta:

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

para verificar o status da operação de registro, use o task_id com a operação Get das APIs de Tarefas, conforme mostrado no seguinte exemplo:

GET /_plugins/_ml/tasks/<task_ID>

Quando a operação de implantação estiver concluída, o valor status na resposta à operação Obter será COMPLETED.

Ingestão de Dados

A primeira etapa ao configurar a pesquisa neural é configurar o modelo de linguagem grande que você deseja usar. O modelo é usado para gerar incorporações vetoriais a partir de campos de texto.

Ingerir Dados no Índice

Depois de criar um índice com sucesso, agora você pode ingerir dados no índice, conforme mostrado no seguinte exemplo:

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"
}
Use uma opção GET para verificar se os documentos estão sendo ingeridos corretamente e se as incorporações estão sendo geradas automaticamente durante a ingestão:
GET /test-index/_doc/3

Criar Pipeline de Ingestão

Usando o ID do modelo implantado, crie um pipeline de ingestão, conforme mostrado no seguinte exemplo:

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

O pipeline de ingestão define um processador e os mapeamentos de campo (neste caso, "passage_text" → "passage_embedding" ) Isso significa que, se você usar esse pipeline em um índice específico para ingerir dados, o pipeline localizará automaticamente o campo "passage_text" e usará o modelo de pipeline para gerar as incorporações correspondentes, "passage_embedding", e depois os mapeará antes da indexação.

Lembre-se de que "passage_text" → "passage_embedding" são definidos pelo usuário e podem ser qualquer coisa que você quiser. Certifique-se de que você esteja consistente com a nomenclatura ao criar o índice no qual planeja usar o pipeline. O processador de pipeline precisa ser capaz de mapear os campos conforme descrito.

Criar um Índice

Durante a criação do índice, você pode especificar o pipeline que deseja usar para ingerir documentos no índice.

O exemplo de chamada de API a seguir mostra como criar um índice usando o pipeline test-nlp-pipeline criado na etapa 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"
            }
        }
    }
}

Ao criar o índice, você também precisa especificar qual implementação de biblioteca do vizinho mais próximo aproximado (ANN) você deseja usar. O OCI Search with OpenSearch suporta bibliotecas NMSLIB, Faiss e Lucene. Para obter mais informações, consulte Mecanismos de Pesquisa.

O exemplo a seguir usa o mecanismo 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
}

Ingerir Dados no Índice

Depois de criar um índice com sucesso, agora você pode ingerir dados no índice, conforme mostrado no seguinte exemplo:

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

Use uma GET para verificar se os documentos estão sendo ingeridos corretamente e se as incorporações estão sendo geradas automaticamente durante a ingestão:

GET /test-index/_doc/3