ELSERモデル
前の章では、機械学習モデルによって生成された埋め込みが設定されたdense_vectorフィールドを使用して Elasticsearch インデックスを拡張する方法を説明しました。モデルはコンピューターにローカルにインストールされ、埋め込みは Python コードから生成され、インデックスに挿入される前にドキュメントに追加されました。
この章では 、Elastic Learned Sparse EncodeR モデル (ELSER) からの推論を格納するために設計された別のベクトル型 sparse_vector について学習します。このモデルによって返される埋め込みは、それぞれに 重み が割り当てられたタグ (より適切には 機能 と呼ばれます) のコレクションです。
この章では、Elasticsearch サービス自体がモデルを実行し、結果の埋め込みをパイプラインを通じてインデックスに追加するという、機械学習モデルを操作するための別の方法も使用します。
sparse_vectorフィールド
前の章で使用したdense_vectorフィールド タイプと同様に、 sparse_vectorタイプには機械学習モデルによって返された推論を保存できます。密ベクトルはソーステキストを記述する数値の固定長配列を保持しますが、疎ベクトルは特徴と重みのマッピングを格納します。
インデックスにsparse_vectorフィールドを追加しましょう。これは、インデックス マッピングで明示的に定義する必要があるタイプです。以下に、このタイプのelser_embeddingという新しいフィールドを持つcreate_index()メソッドの更新バージョンを示します。
class Search:
# ...
def create_index(self):
self.es.indices.delete(index='my_documents', ignore_unavailable=True)
self.es.indices.create(index='my_documents', mappings={
'properties': {
'embedding': {
'type': 'dense_vector',
},
'elser_embedding': {
'type': 'sparse_vector',
},
}
})
# ...ELSERモデルの展開
前述のように、この例では、Elasticsearch がモデルの所有権を取得し、ドキュメントの挿入時と検索時の両方で自動的にモデルを実行して埋め込みを生成します。
Elasticsearch クライアントは、機械学習モデルとそのパイプラインを管理するための一連の API エンドポイントを公開します。search.py の次のdeploy_elser()メソッドは、ELSER v2 モデルをダウンロードしてインストールし、それを使用して上記で定義したelser_embeddingフィールドに入力するパイプラインを作成するためのいくつかの手順に従います。
class Search:
# ...
def deploy_elser(self):
# download ELSER v2
self.es.ml.put_trained_model(model_id='.elser_model_2',
input={'field_names': ['text_field']})
# wait until ready
while True:
status = self.es.ml.get_trained_models(model_id='.elser_model_2',
include='definition_status')
if status['trained_model_configs'][0]['fully_defined']:
# model is ready
break
time.sleep(1)
# deploy the model
self.es.ml.start_trained_model_deployment(model_id='.elser_model_2')
# define a pipeline
self.es.ingest.put_pipeline(
id='elser-ingest-pipeline',
processors=[
{
'inference': {
'model_id': '.elser_model_2',
'input_output': [
{
'input_field': 'summary',
'output_field': 'elser_embedding',
}
]
}
}
]
)ELSER を設定するには、いくつかの手順が必要です。まず、Elasticsearch のml.put_trained_model()メソッドを使用して ELSER をダウンロードします。model_id引数は、ダウンロードするモデルとバージョンを識別します (ELSER v2 は Elasticsearch 8.11 以降で使用できます)。inputフィールドはこのモデルに必要な構成です。
モデルをダウンロードしたら、デプロイする必要があります。このため、デプロイするモデルの識別子のみを指定してml.start_trained_model_deployment()メソッドを使用します。これは非同期操作であるため、モデルはしばらくすると使用できるようになることに注意してください。
ELSER の使用を構成する最後の手順は、ELSER 用のパイプラインを定義することです。パイプラインは、Elasticsearch にモデルの使用方法を伝えるために使用されます。パイプラインには、識別子と、実行する 1 つ以上の処理タスクが指定されます。上記で作成されたパイプラインはelser-ingest-pipelineと呼ばれ、単一の推論タスクを持ちます。つまり、ドキュメントが追加されるたびに、モデルはinput_fieldで実行され、出力はoutput_fieldのドキュメントに追加されます。この例では、前の章の稠密ベクトル埋め込みと同様に、 summaryフィールドを使用して埋め込みを生成します。結果の埋め込みは、前のセクションで作成されたelser_embeddingスパース ベクトル フィールドに書き込まれます。
このメソッドを簡単に呼び出せるようにするには、 app.pyの Flask アプリケーションにdeploy-elserコマンドを追加します。
@app.cli.command()
def deploy_elser():
"""Deploy the ELSER v2 model to Elasticsearch."""
try:
es.deploy_elser()
except Exception as exc:
print(f'Error: {exc}')
else:
print(f'ELSER model deployed.')次のコマンドを使用して、Elasticsearch サービスに ELSER をデプロイできるようになりました。
flask deploy-elser最後の構成タスクでは、インデックスをパイプラインにリンクして、このインデックスにドキュメントが挿入されたときにモデルが自動的に実行されるようにします。これは、 settingsオプションを使用してインデックス構成で実行されます。このリンクを作成するためのcreate_index()メソッドのもう 1 つの更新を次に示します。
class Search:
# ...
def create_index(self):
self.es.indices.delete(index='my_documents', ignore_unavailable=True)
self.es.indices.create(
index='my_documents',
mappings={
'properties': {
'embedding': {
'type': 'dense_vector',
},
'elser_embedding': {
'type': 'sparse_vector',
},
}
},
settings={
'index': {
'default_pipeline': 'elser-ingest-pipeline'
}
}
)この変更により、ELSER 推論を完全にサポートしたインデックスを再生成できるようになりました。
flask reindex