OpenSearchのセマンティック検索

OpenSearchを使用したOCI検索では、OpenSearchバージョン2.11以降のセマンティック検索がサポートされます。

セマンティック検索では、検索エンジンは検索問合せのコンテキストおよびコンテンツを使用して、問合せの意味をより深く理解します。キーワード検索では、検索結果は問合せ内のキーワードに一致するコンテンツに基づきます。OpenSearchは、ニューラル検索を使用してセマンティック検索を実装します。これは、大規模な言語モデルを使用して用語間の関係を理解する手法です。OpenSearchのニューラル検索の詳細は、ニューラル検索のチュートリアルを参照してください。

OpenSearchを使用したOCI検索でのニューラル検索の使用

OpenSearchを使用してOCI検索でセマンティック検索にニューラル検索を使用するには、次を実行する必要があります:
  1. 選択したモデルを登録し、クラスタにデプロイします。
  2. 索引を作成し、デプロイされたモデルを使用して取込みパイプラインを設定します。取込みパイプラインを使用して、ドキュメントを索引に取り込みます。
  3. ハイブリッド検索またはニューラル検索を使用して、索引に対してセマンティク検索問合せを実行します。

前提条件

セマンティック検索を使用するには、クラスタのOpenSearchバージョンが2.11以上である必要があります。デフォルトでは、新しいクラスタはバージョン2.11を使用します。「OpenSearchクラスタの作成」を参照してください。

バージョン2.3用に構成された既存のクラスタでは、バージョン2.11へのインライン・アップグレードを実行できます。詳細は、OpenSearchクラスタ・ソフトウェアのアップグレードを参照してください。

バージョン1.2.3用に構成された既存のクラスタを2.11にアップグレードするには、OpenSearchクラスタ・ソフトウェアのアップグレードで説明されているアップグレード・プロセスを使用する必要があります。

セマンティック検索のモデルの設定を開始する前に、前提条件を完了する必要があります。前提条件には、必要に応じて適用可能なIAMポリシーを指定し、推奨されるクラスタ設定を構成することが含まれます。

カスタム・モデルおよび生成AIコネクタのIAMポリシー

OpenSearchでOCI Search内でホストされている事前トレーニング済モデルのいずれかを使用している場合は、権限を構成する必要はありません。次の前提条件であるセマンティック検索のクラスタ設定にスキップできます。セマンティック検索ウォークスルーも参照してください。

それ以外の場合は、必要なアクセス権を付与するポリシーを作成する必要があります。

必要なアクセス権を付与するには、ポリシーを作成する必要があります。

ポリシーを初めて使用する場合は、ポリシーの開始および共通ポリシーを参照してください。

カスタム・モデルのIAMポリシー

カスタム・モデルを使用している場合は、モデルを含むオブジェクト・ストレージ・バケットにアクセスするために、OpenSearchを使用してOCI検索へのアクセス権を付与する必要があります。

次のポリシーの例には、必要な権限が含まれています。

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

生成AIコネクタのIAMポリシー

生成AIコネクタを使用している場合は、生成AIリソースにアクセスするには、OpenSearchを使用してOCI検索へのアクセス権を付与する必要があります。

次のポリシーの例には、必要な権限が含まれています。

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

生成AIコネクタのリージョン

OCI生成AIを使用するには、テナンシが米国中西部(シカゴ)リージョンまたはドイツ中央部(フランクフルト)リージョンにサブスクライブされている必要があります。これらのリージョンのいずれかにクラスタを作成する必要はありません。テナンシがいずれかのリージョンにサブスクライブされていることを確認してください。

セマンティック検索のクラスタ設定

クラスタAPI設定操作を使用して、セマンティク検索の推奨クラスタ設定を構成します。次の例は、推奨される設定を示しています。

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

モデルの設定

ニューラル検索を構成する際の最初のステップは、使用する大規模言語モデルを設定することです。モデルは、テキスト・フィールドからベクトル埋込みを生成するために使用されます。

モデル・グループの登録

モデル・グループを使用すると、特定のモデルへのアクセスを管理できます。モデル・グループの登録はオプションです。ただし、モデル・グループを登録しない場合、ML Commonsは新しいモデル・グループを登録するため、モデル・グループを登録することをお薦めします。

次の例に示すように、モデル・グループAPI登録操作を使用してモデル・グループを登録します。

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

レスポンスで返されたmodel_group_idを書き留めます。

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

モデル・グループへのモデルの登録

モデルAPI登録操作を使用してモデルを登録します。レジスタ操作に対するPOSTリクエストの内容は、使用しているモデルのタイプによって異なります。

  • オプション1: 組込みのOpenSearch事前トレーニング済モデル

    いくつかの事前トレーニング済センテンス・トランスフォーマ・モデルは、カスタム・モデル・オプションに必要なプロセスとは異なり、ダウンロードして手動でプライベート・ストレージ・バケットにアップロードすることなく、クラスタに直接登録およびデプロイできます。このオプションでは、事前トレーニング済モデルを登録する場合、モデルのmodel_group_idnameversionおよびmodel_formatのみが必要です。事前トレーニング済モデルの使用方法は、OpenSearch事前トレーニング済モデルの使用を参照してください。

  • オプション2: カスタムモデル

    登録操作のactionsセクションでオブジェクト・ストレージURLを渡す必要があります。たとえば:

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

    レジスタ操作の完全な例は、カスタム・モデル- 2: モデルの登録を参照してください。

  • オプション3: 生成AIコネクタ

    GenAIコネクタを使用して、cohere.embed-english-v3.0などのリモートGenAI埋込みモデルをクラスタに登録およびデプロイすることもできます。最初にコネクタを作成し、次のステップの説明に従ってコネクタIDを使用してモデルを登録およびデプロイする必要があります。

    ノート

    ON-DEMANDモデルを使用している場合は、GenAIサービスからのモデル非推奨通知を最新の状態に保ち、サービスの中断の可能性を回避するために、必要に応じてコネクタを更新します。サポートされている埋込みモデルで、サポートされているモデルのリストから埋込みモデルを選択するには、生成AIの事前トレーニング済基本モデルを参照してください。

    DEDICATEDモデルを使用している場合は、次のペイロード例のservingTypeパラメータをON-DEMANDからDEDICATEDに変更します。

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

    次の例は、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"
             }
         ]
     }

レジスタ・リクエストを行った後、操作のステータスを確認し、次の例に示すように、タスクAPI取得操作でtask_idを使用できます:

GET /_plugins/_ml/tasks/<task_ID>

登録操作が完了すると、次の例に示すように、Get操作に対するレスポンスのstatus値はCOMPLETEDになります。

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

モデルのデプロイ時に使用するレスポンスで返されるmodel_id値をノートにとります。

モデルのデプロイ

モデルの登録操作が完了したら、次の例に示すように、モデルAPIのdeploy操作を使用して、前のステップでGet操作レスポンスからmodel_idを渡して、モデルをクラスタにデプロイできます。

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

レスポンスで返されたtask_idを書き留めます。task_idを使用して、操作のステータスを確認できます。

たとえば、次のレスポンスから:

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

レジスタ操作のステータスを確認するには、次の例に示すように、タスクAPIGet操作でtask_idを使用します。

GET /_plugins/_ml/tasks/<task_ID>

デプロイ操作が完了すると、Get操作に対するレスポンスのstatus値はCOMPLETEDになります。

データの収集

ニューラル検索を構成する際の最初のステップは、使用する大規模言語モデルを設定することです。モデルは、テキスト・フィールドからベクトル埋込みを生成するために使用されます。

索引へのデータの取込み

索引を正常に作成した後、次の例に示すように、索引にデータを取り込むことができます。

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"
}
GETを使用して、ドキュメントが正しく収集され、収集中に埋込みが自動生成されていることを確認します:
GET /test-index/_doc/3

取込みパイプラインの作成

デプロイされたモデルのモデルIDを使用して、次の例に示すように取込みパイプラインを作成します。

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

取込みパイプラインは、プロセッサとフィールド・マッピング(この場合は「passage_text」 → 「passage_embedding」)を定義します。つまり、このパイプラインを特定の索引で使用してデータを取り込む場合、パイプラインは自動的に「passage_text」フィールドを検出し、パイプライン・モデルを使用して対応する埋込み「passage_embedding」を生成し、索引付けの前にマップします。

「passage_text」 → 「passage_embedding」はユーザー定義であり、任意のものにできることに注意してください。パイプラインを使用する予定の索引を作成する際に、ネーミングに一貫性があることを確認してください。パイプライン・プロセッサは、説明に従ってフィールドをマップできる必要があります。

索引を作成します。

索引の作成時に、索引へのドキュメントの取込みに使用するパイプラインを指定できます。

次のAPI呼び出しの例は、前の手順で作成した test-nlp-pipelineパイプラインを使用してインデックスを作成する方法を示しています。

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

索引を作成する場合は、使用する近接近傍(ANN)のライブラリ実装も指定する必要があります。OCI Search with OpenSearchでは、NMSLIB、FaissおよびLuceneライブラリがサポートされます。詳細は、検索エンジンを参照してください。

次の例では、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
}

索引へのデータの取込み

索引を正常に作成した後、次の例に示すように、索引にデータを取り込むことができます。

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

GETを使用して、ドキュメントが正しく収集され、収集中に埋込みが自動生成されていることを確認します:

GET /test-index/_doc/3