チュートリアル: セマンティックテキストを用いたセマンティック検索

この機能はベータ版であり、変更される可能性があります。設計とコードは公式GA機能よりも成熟しておらず、保証なしでそのまま提供されています。ベータ機能は公式GA機能のサポートSLAの対象外です。

このチュートリアルでは、セマンティックテキスト機能を使用してデータに対してセマンティック検索を実行する方法を示します。

セマンティックテキストは、取り込み時に推論を提供し、自動的に合理的なデフォルト値を提供することで推論ワークフローを簡素化します。モデル関連の設定やパラメータを定義したり、推論取り込みパイプラインを作成したりする必要はありません。

Elastic Stackでセマンティック検索を使用する推奨方法は、semantic_textワークフローに従うことです。インデックス作成やクエリ設定に対してより多くの制御が必要な場合は、完全な推論ワークフローを使用することもできます(プロセスを確認するにはこのチュートリアルを参照してください)。

このチュートリアルでは、デモンストレーションのためにelserサービスを使用しますが、Inference APIが提供する任意のサービスとそのサポートされているモデルを使用できます。

要件

semantic_textフィールドタイプを使用するには、Create inference APIを使用してクラスターに推論エンドポイントをデプロイする必要があります。

推論エンドポイントの作成

Create inference APIを使用して推論エンドポイントを作成します:

Python

  1. resp = client.inference.put(
  2. task_type="sparse_embedding",
  3. inference_id="my-elser-endpoint",
  4. inference_config={
  5. "service": "elser",
  6. "service_settings": {
  7. "num_allocations": 1,
  8. "num_threads": 1
  9. }
  10. },
  11. )
  12. print(resp)

コンソール

  1. PUT _inference/sparse_embedding/my-elser-endpoint
  2. {
  3. "service": "elser",
  4. "service_settings": {
  5. "num_allocations": 1,
  6. "num_threads": 1
  7. }
  8. }
タスクタイプはsparse_embeddingで、elserサービスが使用され、ELSERがスパースベクトルを作成します。inference_idmy-elser-endpointです。
この例ではelserサービスが使用されています。

Kibanaコンソールを使用しているときに502 Bad Gatewayエラーが応答に表示されることがあります。このエラーは通常、モデルがバックグラウンドでダウンロードされている間のタイムアウトを反映しています。ダウンロードの進行状況はMachine Learning UIで確認できます。Pythonクライアントを使用している場合は、timeoutパラメータをより高い値に設定できます。

インデックスマッピングの作成

推論エンドポイントが入力テキストに基づいて生成する埋め込みを含む宛先インデックスのマッピングを作成する必要があります。宛先インデックスには、使用される推論エンドポイントの出力をインデックスするために、semantic_textフィールドタイプのフィールドが必要です。

Python

  1. resp = client.indices.create(
  2. index="semantic-embeddings",
  3. mappings={
  4. "properties": {
  5. "content": {
  6. "type": "semantic_text",
  7. "inference_id": "my-elser-endpoint"
  8. }
  9. }
  10. },
  11. )
  12. print(resp)

Js

  1. const response = await client.indices.create({
  2. index: "semantic-embeddings",
  3. mappings: {
  4. properties: {
  5. content: {
  6. type: "semantic_text",
  7. inference_id: "my-elser-endpoint",
  8. },
  9. },
  10. },
  11. });
  12. console.log(response);

コンソール

  1. PUT semantic-embeddings
  2. {
  3. "mappings": {
  4. "properties": {
  5. "content": {
  6. "type": "semantic_text",
  7. "inference_id": "my-elser-endpoint"
  8. }
  9. }
  10. }
  11. }
生成された埋め込みを含むフィールドの名前。
埋め込みを含むフィールドはsemantic_textフィールドです。
inference_idは前のステップで作成した推論エンドポイントです。
それは入力テキストに基づいて埋め込みを生成するために使用されます。
データを関連するsemantic_textフィールドに取り込むたびに、このエンドポイントがテキストのベクトル表現を作成するために使用されます。

データのロード

このステップでは、後で埋め込みを作成するために使用するデータをロードします。

msmarco-passagetest2019-top1000データセットを使用します。これはMS MARCO Passage Rankingデータセットのサブセットです。200のクエリが含まれており、それぞれに関連するテキストパッセージのリストが付随しています。すべてのユニークなパッセージとそのIDは、そのデータセットから抽出され、tsvファイルにまとめられています。

ファイルをダウンロードし、Machine Learning UIのData Visualizerを使用してクラスターにアップロードします。データが分析された後、Override settingsをクリックします。Edit field namesの下で、最初の列にidを、2番目の列にcontentを割り当てます。Applyをクリックし、次にImportをクリックします。インデックスにtest-dataという名前を付け、Importをクリックします。アップロードが完了すると、182,469ドキュメントを持つtest-dataという名前のインデックスが表示されます。

データの再インデックス化

  1. #### Python
  2. ``````python
  3. resp = client.reindex(
  4. wait_for_completion=False,
  5. source={
  6. "index": "test-data",
  7. "size": 10
  8. },
  9. dest={
  10. "index": "semantic-embeddings"
  11. },
  12. )
  13. print(resp)
  14. `

Js

  1. const response = await client.reindex({
  2. wait_for_completion: "false",
  3. source: {
  4. index: "test-data",
  5. size: 10,
  6. },
  7. dest: {
  8. index: "semantic-embeddings",
  9. },
  10. });
  11. console.log(response);

コンソール

  1. POST _reindex?wait_for_completion=false
  2. {
  3. "source": {
  4. "index": "test-data",
  5. "size": 10
  6. },
  7. "dest": {
  8. "index": "semantic-embeddings"
  9. }
  10. }
再インデックス化のデフォルトバッチサイズは1000です。サイズを小さくすると、再インデックス化プロセスの更新が迅速になり、進行状況を密接に追跡し、エラーを早期に検出できます。

呼び出しは進行状況を監視するためのタスクIDを返します:

Python

  1. resp = client.tasks.get(
  2. task_id="<task_id>",
  3. )
  4. print(resp)

Js

  1. const response = await client.tasks.get({
  2. task_id: "<task_id>",
  3. });
  4. console.log(response);

コンソール

  1. GET _tasks/<task_id>

大規模なデータセットの再インデックス化には時間がかかることがあります。このワークフローをデータセットのサブセットのみを使用してテストできます。再インデックス化プロセスをキャンセルし、再インデックス化されたサブセットの埋め込みのみを生成することでこれを行います。次のAPIリクエストは再インデックス化タスクをキャンセルします:

Python

  1. resp = client.tasks.cancel(
  2. task_id="<task_id>",
  3. )
  4. print(resp)

Js

  1. const response = await client.tasks.cancel({
  2. task_id: "<task_id>",
  3. });
  4. console.log(response);

コンソール

  1. POST _tasks/<task_id>/_cancel

セマンティック検索

データセットが埋め込みで強化された後、セマンティック検索を使用してデータをクエリできます。semantic_textフィールド名とsemanticクエリタイプでクエリテキストを提供します。semantic_textフィールドの埋め込みを生成するために使用された推論エンドポイントがクエリテキストを処理するために使用されます。

Python

  1. resp = client.search(
  2. index="semantic-embeddings",
  3. query={
  4. "semantic": {
  5. "field": "content",
  6. "query": "How to avoid muscle soreness while running?"
  7. }
  8. },
  9. )
  10. print(resp)

Js

  1. const response = await client.search({
  2. index: "semantic-embeddings",
  3. query: {
  4. semantic: {
  5. field: "content",
  6. query: "How to avoid muscle soreness while running?",
  7. },
  8. },
  9. });
  10. console.log(response);

コンソール

  1. GET semantic-embeddings/_search
  2. {
  3. "query": {
  4. "semantic": {
  5. "field": "content",
  6. "query": "How to avoid muscle soreness while running?"
  7. }
  8. }
  9. }
検索を実行したいsemantic_textフィールド。
クエリテキスト。

その結果、semantic-embeddingインデックスからクエリに最も近い意味を持つ上位10件のドキュメントが返されます:

コンソール-結果

  1. "hits": [
  2. {
  3. "_index": "semantic-embeddings",
  4. "_id": "Jy5065EBBFPLbFsdh_f9",
  5. "_score": 21.487484,
  6. "_source": {
  7. "id": 8836652,
  8. "content": {
  9. "text": "There are a few foods and food groups that will help to fight inflammation and delayed onset muscle soreness (both things that are inevitable after a long, hard workout) when you incorporate them into your postworkout eats, whether immediately after your run or at a meal later in the day. Advertisement. Advertisement.",
  10. "inference": {
  11. "inference_id": "my-elser-endpoint",
  12. "model_settings": {
  13. "task_type": "sparse_embedding"
  14. },
  15. "chunks": [
  16. {
  17. "text": "There are a few foods and food groups that will help to fight inflammation and delayed onset muscle soreness (both things that are inevitable after a long, hard workout) when you incorporate them into your postworkout eats, whether immediately after your run or at a meal later in the day. Advertisement. Advertisement.",
  18. "embeddings": {
  19. (...)
  20. }
  21. }
  22. ]
  23. }
  24. }
  25. }
  26. },
  27. {
  28. "_index": "semantic-embeddings",
  29. "_id": "Ji5065EBBFPLbFsdh_f9",
  30. "_score": 18.211695,
  31. "_source": {
  32. "id": 8836651,
  33. "content": {
  34. "text": "During Your Workout. There are a few things you can do during your workout to help prevent muscle injury and soreness. According to personal trainer and writer for Iron Magazine, Marc David, doing warm-ups and cool-downs between sets can help keep muscle soreness to a minimum.",
  35. "inference": {
  36. "inference_id": "my-elser-endpoint",
  37. "model_settings": {
  38. "task_type": "sparse_embedding"
  39. },
  40. "chunks": [
  41. {
  42. "text": "During Your Workout. There are a few things you can do during your workout to help prevent muscle injury and soreness. According to personal trainer and writer for Iron Magazine, Marc David, doing warm-ups and cool-downs between sets can help keep muscle soreness to a minimum.",
  43. "embeddings": {
  44. (...)
  45. }
  46. }
  47. ]
  48. }
  49. }
  50. }
  51. },
  52. {
  53. "_index": "semantic-embeddings",
  54. "_id": "Wi5065EBBFPLbFsdh_b9",
  55. "_score": 13.089405,
  56. "_source": {
  57. "id": 8800197,
  58. "content": {
  59. "text": "This is especially important if the soreness is due to a weightlifting routine. For this time period, do not exert more than around 50% of the level of effort (weight, distance and speed) that caused the muscle groups to be sore.",
  60. "inference": {
  61. "inference_id": "my-elser-endpoint",
  62. "model_settings": {
  63. "task_type": "sparse_embedding"
  64. },
  65. "chunks": [
  66. {
  67. "text": "This is especially important if the soreness is due to a weightlifting routine. For this time period, do not exert more than around 50% of the level of effort (weight, distance and speed) that caused the muscle groups to be sore.",
  68. "embeddings": {
  69. (...)
  70. }
  71. }
  72. ]
  73. }
  74. }
  75. }
  76. }
  77. ]

さらなる例

semantic_textをハイブリッド検索で使用したい場合は、このノートブックを参照してステップバイステップのガイドを確認してください。