このチュートリアルでは、 slm_embeddings_fl() ユーザー定義関数 (UDF) を使用して、イベント ハウスでテキスト埋め込みを生成し、セマンティック検索を実行する方法について説明します。 外部の Azure OpenAI エンドポイントを必要とする ai_embeddings プラグインとは異なり、slm_embeddings_fl()は Kusto Python サンドボックス内で Small Language Models (SLB) をローカルで実行します。 外部の依存関係や要求ごとのコストなしで、イベントハウス内にデータを完全に埋め込んで検索できます。
このシナリオでは、一連のテクノロジ記事の説明に対するセマンティック検索を示します。 ローカル SLM を使用して記事の説明を埋め込み、結果のベクターを eventhouse テーブルに格納した後、自然言語検索クエリを実行して、最も意味的に似た記事を見つけます。
具体的には、このチュートリアルでは次の操作を行います。
- Python プラグインを有効にし、SLM モデル成果物をホストする lakehouse を準備します。
- イベントハウスに、ベクター列の
Vector16エンコードを使用してテーブルを作成します。 -
slm_embeddings_fl()UDF をデータベースに格納されている関数としてインストールします。 - UDF を使用して一連のドキュメントを埋め込み、ベクターを eventhouse に取り込みます。
- 同じ UDF を使用して自然言語検索クエリを埋め込みます。
- series_cosine_similarity KQL 関数を使用して、最も意味的に似たドキュメントを検索します。
前提条件
- Microsoft Fabric 対応の 容量を持つ ワークスペース。
- ワークスペース内の イベントハウス 。
- eventhouse データベースで有効になっているPython プラグイン。
3.11.7または3.11.7 DLの Python サンドボックス イメージを使用します。 - SLM モデル成果物ファイルをホストするための、イベント ハウスと同じワークスペース内の レイクハウス 。
レイクハウスのアーティファクトを準備する
slm_embeddings_fl()関数は、KQL クエリで参照する前に、Fabric lakehouse にダウンロードして格納する必要があるモデル成果物ファイルを使用します。
一覧表示されている URL から次の成果物ファイルをダウンロードします。
[embedding_engine.zip](https://artifactswestus.z22.web.core.windows.net/models/SLM/embedding_engine.zip)[harrier-v1-270m.zip](https://artifactswestus.z22.web.core.windows.net/models/SLM/harrier-v1-270m.zip)[jina-v2-small.zip](https://artifactswestus.z22.web.core.windows.net/models/SLM/jina-v2-small.zip)[e5-small-v2.zip](https://artifactswestus.z22.web.core.windows.net/models/SLM/e5-small-v2.zip)
ダウンロードしたファイルをレイクハウス内のフォルダーにアップロードします。 たとえば、lakehouse の
models/SLM/] セクション内の という名前のフォルダーにアップロードします。フォルダーの OneLake パスをメモします。 パスは次の形式を使用します。
https://onelake.dfs.fabric.microsoft.com/<WorkspaceName>/<LakehouseName>.Lakehouse/Files/models/SLM/この基本パスは、次のセクションで UDF をインストールするときに使用します。
イベントハウス環境を準備する
この手順では、埋め込みベクター データを格納するために必要な列とエンコード ポリシーを含むテーブルをイベントハウスに作成します。
Real Time Analytics でワークスペースのホーム ページを参照します。
前提条件で作成したイベントハウスを選択します。
ターゲット データベースを選択します。 データベースがない場合は、[データベースの 追加] を選択してデータベースを作成します。
データベース ツリーを展開し、埋め込みクエリセットを選択し、次の KQL コマンドを実行して Articles というテーブルを作成します。
.create table Articles (id:string, article_title:string, description:string, content_vector:dynamic)次のコマンドを実行して、ベクター列に
Vector16エンコード ポリシーを設定します。.alter column Articles.content_vector policy encoding type='Vector16'
slm_embeddings_fl() 関数をインストールする
slm_embeddings_fl() UDF をデータベースに格納されている関数としてインストールします。
<OneLakePath>は、前のセクションで説明した基本の OneLake パスに置き換えます。 使用する予定のないモデルの外部成果物を参照する行をコメント アウトまたは削除できます。 (これらの行は、この UDF の下部にあります)。このチュートリアルでは、 harrier-v1-270m モデルを使用するため、 embedding_engine.zip と harrier-v1-270m.zipのみが必要です。
slm_embeddings_fl() UDF をデータベースに格納されている関数としてインストールします。
<OneLakePath>は、前のセクションで説明した基本の OneLake パスに置き換えます。 使用する予定のないモデルの外部成果物を参照する行をコメント アウトまたは削除できます。 (これらの行は、この UDF の下部にあります)。このチュートリアルでは、 harrier-v1-270m モデルを使用するため、 embedding_engine.zip と harrier-v1-270m.zipのみが必要です。
.create-or-alter function with (folder = "Packages\\AI", docstring = "Embedding using local SLM")
slm_embeddings_fl(tbl:(*), text_col:string, embeddings_col:string, batch_size:int=32, model_name:string='harrier-v1-270m', prefix:string='query:')
{
let kwargs = bag_pack('text_col', text_col, 'embeddings_col', embeddings_col, 'batch_size', batch_size, 'model_name', model_name, 'prefix', prefix);
let code = ```if 1:
from sandbox_utils import Zipackage
Zipackage.install('embedding_engine.zip')
from embedding_factory import create_embedding_engine
text_col = kargs["text_col"]
embeddings_col = kargs["embeddings_col"]
batch_size = kargs["batch_size"]
model_name = kargs["model_name"]
prefix = kargs["prefix"]
Zipackage.install(f'{model_name}.zip')
engine = create_embedding_engine(model_name, cache_dir="C:\\Temp")
work_dir = os.environ.get("UPLOAD_PATH")
embeddings = engine.encode(df[text_col].tolist(), batch_size=batch_size, prefix=prefix) # prefix is used only for E5
result = df
result[embeddings_col] = list(embeddings)```;
tbl
| evaluate hint.distribution=per_node python(typeof(*), code, kwargs,
external_artifacts = bag_pack(
'embedding_engine.zip', '<OneLakePath>embedding_engine.zip;impersonate',
'harrier-v1-270m.zip', '<OneLakePath>harrier-v1-270m.zip;impersonate',
'jina-v2-small.zip', '<OneLakePath>jina-v2-small.zip;impersonate',
'e5-small-v2.zip', '<OneLakePath>e5-small-v2.zip;impersonate'))
}
関数パラメーターとサポートされているモデルの詳細については、 slm_embeddings_fl()を参照してください。
ドキュメントの埋め込みと取り込み
UDF がインストールされたので、それを使用してドキュメントの埋め込みを生成し、 Articles テーブルに格納できます。
次の KQL クエリを実行して、一連のサンプル テクノロジ記事の説明を埋め込み、テーブルに書き込みます。
.set-or-append Articles <|
datatable(id:string, article_title:string, description:string)
"1", "Introduction to machine learning", "Machine learning enables computers to learn from data and improve over time without being explicitly programmed.",
"2", "Getting started with Python", "Python is a versatile, high-level programming language popular for data science, automation, and web development.",
"3", "Real-time analytics with Eventhouse", "eventhouse provides fast, scalable analytics on large volumes of streaming and historical data using KQL.",
"4", "Understanding vector embeddings", "Embeddings convert text and other data into dense numerical vector representations that capture semantic meaning.",
"5", "Neural networks explained", "Neural networks are computational models inspired by the brain, capable of learning complex patterns from large datasets.",
"6", "Building RAG pipelines", "Retrieval-Augmented Generation combines vector search with language model generation to produce grounded, accurate responses.",
"7", "Semantic search techniques", "Semantic search goes beyond keyword matching to find results that are conceptually similar to the user's query.",
"8", "Data ingestion best practices", "Efficient data ingestion requires choosing the right format, batch size, and compression strategy for your workload."
]
| extend content_vector=dynamic(null)
| invoke slm_embeddings_fl('description', 'content_vector', model_name='harrier-v1-270m', prefix='passage:')
注
passage: プレフィックスは、取得のためにドキュメントを埋め込むときに使用されます。 次の手順で検索クエリを埋め込む場合は、 query: プレフィックスを使用します。 Harrier モデルでは、これらのプレフィックスを使用して、クエリ表現と通路表現を区別します。
検索語句の埋め込みを生成する
埋め込み記事をイベントハウスに格納した後は、同じモデルを使用して自然言語検索クエリを埋め込み、最も似た記事を見つけることができます。
次のクエリを実行して検索語句を埋め込み、そのベクトルを取得します。
let searchTerm = "How do I find similar text using vectors?";
print query=searchTerm
let searchTerm = "How do I find similar text using embedding vectors?";
| invoke slm_embeddings_fl('query', 'query_vector', model_name='harrier-v1-270m', prefix='query:')
| project query_vector
類似性クエリを実行する
次の KQL クエリを実行して、検索用語と Articles テーブル内の各アーティクルの間のコサインの類似性を計算し、上位の一致を返します。
let searchTerm = "How do I find similar text using vectors?";
let searchVector = toscalar(
print query=searchTerm
| extend query_vector=dynamic(null)
| invoke slm_embeddings_fl('query', 'query_vector', model_name='harrier-v1-270m', prefix='query:')
| project query_vector
);
Articles
| extend similarity = series_cosine_similarity(searchVector, content_vector, 1.0, 1.0)
| project title, description, similarity
| top 3 by similarity desc
| project article_title, description, similarity
このクエリは、検索用語に最も意味的に似た 3 つの記事を返します。コサインの類似性スコアによってランク付けされます。
| article_title | description | 類似性 |
|---|---|---|
| ベクター埋め込みについて | 埋め込みでは、テキストやその他のデータを、セマンティックな意味をキャプチャする密な数値ベクトル表現に変換します。 | 0.600029468536377 |
| RAG パイプラインの構築 | Retrieval-Augmented 生成では、ベクター検索と言語モデルの生成を組み合わせて、根拠のある正確な応答を生成します。 | 0.573046445846558 |
| セマンティック検索手法 | セマンティック検索は、キーワード マッチングを超えて、概念的にはユーザーのクエリに似た結果を見つけます。 | 0.469195783138275 |
検索語句を変更し、クエリを再実行してさまざまな結果を調べることができます。
リソースをクリーンアップする
チュートリアルを完了したら、追加コストが発生しないように、作成したリソースを削除します。 リソースを削除するには、次の手順を実行します。
- ワークスペースのホームページを参照します。
- Eventhouse データベースから Articles テーブルを削除するか、このチュートリアルで使用する データベース または eventhouse を削除します。
- モデル成果物ファイルが不要になった場合は、レイクハウスから削除します。