Azure AI Search でより小さなベクトル用にベクトル量子化とストレージの削減を構成する
重要
これらの機能はパブリック プレビュー段階にあり、追加使用条件の下で提供されます。 2024-03-01-Preview REST API 以降のプレビュー API では、新しいデータ型、ベクター圧縮プロパティ、および stored
プロパティが提供されます。
この記事では、Azure AI Search でベクトル インデックスを圧縮するためのベクトル量子化やその他の手法について説明します。
オプションを評価する
最初の手順として、ベクトル フィールドが使用するストレージの量を減らすための 3 つのオプションを確認します。 これらのオプションを同時に使用することはできません。
スカラー量子化をお勧めします。これは、メモリおよびディスク上のベクトル サイズを最小限の労力で圧縮し、ほとんどのシナリオで最大のメリットが得られる傾向があるためです。 一方、ナロー型 (Float16
以外) では作成に労力を要し、stored
で節約できるのは、メモリよりも安価なディスク ストレージです。
アプローチ | このオプションを使用する理由 |
---|---|
スカラー量子化を追加する | 組み込みのスカラー量子化を使用すると、ネイティブの Float32 埋め込みを Int8 に圧縮できます。 このオプションを使用すると、クエリのパフォーマンスを悪化させずにメモリとディスク上のストレージを削減できます。 Int8 のようなより小さなデータ型を使用すると、Float32 埋め込みよりもコンテンツが豊富ではないベクトル インデックスが生成されます。 情報の損失を緩和するために、組み込みの圧縮機能には、非圧縮の埋め込みとオーバーサンプリングを使用してより関連性の高い結果を返すクエリ後の処理オプションが含まれます。 再ランク付けとオーバーサンプリングは、Float32 フィールドまたは Float16 フィールドの組み込みのスカラー量子化の特定の機能で、カスタム量子化の対象となる埋め込みでは使用できません。 |
ベクトル フィールドにより小さいプリミティブ データ型を割り当てる | Float16 、Int16 、Int8 、byte (バイナリ) などのナロー データ型では、メモリとディスクの使用量が少なくなりますが、ベクトルをナロー データ形式で出力する埋め込みモデルが必要です。 または、小さなデータを出力するカスタム量子化ロジックが必要です。 3 番目のユース ケースでは、必要な労力が少なく、ほとんどのモデルによって生成されたネイティブ Float32 埋め込みが Float16 に再キャストされます。 バイナリ ベクトルの詳細については、バイナリ ベクトルのインデックスに関する記事をご覧ください。 |
取得可能なベクトルのオプションのストレージを排除する | クエリの応答で返されるベクトルは、クエリの実行中に使用されるベクトルとは別に保存されます。 ベクトルを返す必要がない場合は、取得可能なストレージをオフにすることで、フィールドごとの全体的なストレージを最大 50% 削減できます。 |
これらのオプションはすべて空のインデックス上で定義します。 いずれかを実装するには、Azure portal、2024-03-01-preview REST API、またはベータ版の Azure SDK パッケージを使用します。
インデックスが定義されると、別の手順としてドキュメントを読み込み、インデックスを作成できます。
オプション 1: スカラー量子化を構成する
メモリとディスク ストレージの要件を減らし、より小さなインデックスの効果を緩和するために再ランク付けとオーバーサンプリングを追加できるため、組み込みのスカラー量子化を推奨します。 組み込みのスカラー量子化は、Float32
または Float16
データを含むベクトル フィールドに適用できます。
組み込みのベクトル圧縮を使用するには以下を実施します。
- 検索インデックスに
vectorSearch.compressions
を追加します。 このプレビューでサポートされている圧縮アルゴリズムは "スカラー量子化" です。 - オプションのプロパティを設定して、損失のあるインデックス作成の影響を軽減します。
rerankWithOriginalVectors
とdefaultOversampling
の両方がクエリの実行中に最適化を提供します。 - 新しいベクトル プロファイルに
vectorSearch.profiles.compression
を追加します。 - 新しいベクトル フィールドに新しいベクトル プロファイルを割り当てます。
圧縮設定を追加し、オプションのプロパティを設定する
2024-03-01-preview REST API を使用して作成されたインデックス定義に compressions
セクションを追加します。 テンプレートとして次の JSON を使用します。
"compressions": [
{
"name": "my-scalar-quantization",
"kind": "scalarQuantization",
"rerankWithOriginalVectors": true, (optional)
"defaultOversampling": 10.0, (optional)
"scalarQuantizationParameters": { (optional)
"quantizedDataType": "int8", (optional)
}
}
]
重要なポイント:
kind
がscalarQuantization
に設定されていること。 これは現時点でサポートされている唯一の量子化方法です。rerankWithOriginalVectors
は元の非圧縮ベクトルを使用して類似性を再計算し、最初の検索クエリによって返される上位の結果を再ランク付けします。stored
が false の場合でも、非圧縮ベクトルが検索インデックスに存在します。 このプロパティは省略可能です。 既定値は True です。量子化による情報の減少を緩和するために、
defaultOversampling
は潜在的な結果のより広範なセットを考慮します。 潜在的な結果の数式は、クエリ内のk
とオーバーサンプリング乗数で構成されます。 たとえば、クエリがk
を 5 に指定し、オーバーサンプリングが 20 の場合、クエリはその目的のために元の非圧縮ベクトルを使用して、再ランク付けに使用する 100 個のドキュメントを効果的に要求します。 上位のk
個の再ランク付けの結果のみが返されます。 このプロパティは省略可能です。 既定値は 4 です。quantizedDataType
がint8
に設定されていること。 これは現時点でサポートされている唯一のプリミティブ データ型です。 このプロパティは省略可能です。 既定値はint8
です。
ベクトル プロファイルに圧縮設定を追加する
スカラー量子化は、"新しい" ベクトル プロファイルでプロパティとして指定されます。 メモリ内に圧縮インデックスを構築するには、新しいベクトル プロファイルを作成する必要があります。
プロファイル内で Hierarchical Navigable Small Worlds (HNSW) アルゴリズムを使用する必要があります。 組み込みの量子化は、完全な KNN ではサポートされていません。
新しいベクトル プロファイルを作成し、圧縮プロパティを追加します。
"profiles": [ { "name": "my-vector-profile", "compression": "my-scalar-quantization", "algorithm": "my-hnsw-vector-config-1", "vectorizer": null } ]
"新しい" ベクトル フィールドにベクトル プロファイルを割り当てます。 スカラー量子化によってコンテンツが
Int8
になるため、コンテンツがFloat32
またはFloat16
であることを確認します。Azure AI Search では、
Float32
型とFloat16
型のエンティティ データ モデル (EDM) に相当するものはそれぞれCollection(Edm.Single)
とCollection(Edm.Half)
になります。{ "name": "DescriptionVector", "type": "Collection(Edm.Single)", "searchable": true, "retrievable": true, "dimensions": 1536, "vectorSearchProfile": "my-vector-profile" }
インデックスを読み込むには、プル モデルのインデックス作成の場合はインデクサーを使用し、プッシュ モデルのインデックス作成の場合は API を使用します。
Azure AI Search でのスカラー量子化のしくみ
スカラー量子化により、各ベクトル埋め込み内の各数値の解像度が低下します。 各数値を 32 ビット浮動小数点数として記述する代わりに、8 ビット整数を使用します。 数値の範囲 (通常は 99 パーセンタイルの最小値と最大値) を識別し、それらを有限数のレベルまたはビンに分割することで、各ビンに識別子を割り当てます。 8 ビットスカラー量子化では、2^8 すなわち 256 のビンが存在する可能性があります。
実数を最も近い整数に四捨五入するのに似たプロセスで、ベクトルの各コンポーネントは量子化レベルのこのセット内で最も近い代表値にマッピングされます。 量子化された 8 ビット ベクトルでは、識別子番号が元の値の代わりに表示されます。 量子化後、各ベクトルはそのコンポーネントが属するビンの識別子の配列によって表されます。 これらの量子化されたベクトルでは、元のベクトルと比較して保存すべきビット数がはるかに小さいため、ストレージ要件とメモリ占有領域を削減できます。
オプション 2: ベクトル フィールドに狭いデータ型を割り当てる
ベクトル フィールドは、数値の配列として表されるベクトル埋め込みを保存します。 フィールド型を指定する場合、これらの配列内の各数値を保持するために使用される基になるプリミティブ データ型を指定します。 データ型は各数値が占める領域の量に影響します。
プレビュー API を使用すると、狭いプリミティブ データ型を割り当てることで、ベクトル フィールドのストレージ要件を減らすことができます。
ベクトル フィールドのデータ型を確認します。
Collection(Edm.Single)
32 ビット浮動小数点 (既定値)Collection(Edm.Half)
16 ビット浮動小数点Collection(Edm.Int16)
16 ビット符号付き整数Collection(Edm.SByte)
8 ビット符号付き整数
Note
バイナリ データ型は現時点ではサポートされていません。
埋め込みモデルの出力、またはカスタム量子化の対象となるベクトルに対して有効なデータ型を選択します。
ほとんどの埋め込みモデルでは 32 ビット浮動小数点数が出力されますが、カスタム量子化を適用すると、出力が
Int16
またはInt8
になることがあります。 これで、より小さい形式を受け入れるベクトル フィールドを定義できます。テキスト埋め込みモデルには、Azure AI Search の
Collection(Edm.Single)
にマッピングされるFloat32
のネイティブ出力形式があります。float
からint
へのキャストは禁止されているため、その出力をInt8
にマッピングすることはできません。 ただし、Float32
からFloat16
(またはCollection(Edm.Half)
) にキャストできます。これは追加の作業なしで狭いデータ型を使用する簡単な方法です。次の表は、狭いデータ型を使用するいくつかの埋め込みモデルへのリンクを示しています。
埋め込みモデル ネイティブ出力 Azure AI Search で有効な型 text-embedding-ada-002 Float32
Collection(Edm.Single)
またはCollection(Edm.Half)
text-embedding-3-small Float32
Collection(Edm.Single)
またはCollection(Edm.Half)
text-embedding-3-large Float32
Collection(Edm.Single)
またはCollection(Edm.Half)
int8 embedding_type を使用した Cohere V3 埋め込みモデル Int8
Collection(Edm.SByte)
狭いデータ型のトレードオフを理解していることを確認します。
Collection(Edm.Half)
には含まれる情報が少ないため、解像度が低くなります。 データが同種または高密度の場合、追加の詳細情報や微妙な差異が失われると、近くのベクトルを区別するために使用できる詳細情報が少なくなるため、クエリ時に許容できない結果になることがあります。インデックスを定義してビルドします。 この手順では、Azure portal、2024-03-01-preview、またはベータ版の Azure SDK パッケージを使用できます。
結果を確認する。 ベクトル フィールドが取得可能としてマークされている場合は、Search エクスプローラーまたは REST API を使用して、フィールドのコンテンツがデータ型と一致することを確認します。 クエリには正しい
2024-03-01-preview
API バージョンを使用してください。そうでない場合、新しいプロパティは表示されません。
ベクトル インデックスのサイズを確認するには、Azure portal または 2024-03-01-preview を使用します。
Note
フィールドのデータ型は、物理データ構造を作成するために使用されます。 後でデータ型を変更する場合は、インデックスを削除して再構築するか、新しい定義で 2 つ目のフィールドを作成します。
オプション 3: stored
プロパティを設定して、取得可能なストレージを削除する
stored
プロパティはベクトル フィールド定義の新しいブール値で、取得可能なベクトル フィールドのコンテンツにストレージが割り当てられているかどうかを決定します。 クエリ応答にベクトルのコンテンツが必要ない場合は、stored
を false に設定することで、フィールドごとに最大 50% のストレージ削減できます。
ベクトルは人間が判読できないため、検索ページに表示されるクエリ応答では通常省略されます。 ただし、ベクトルのコンテンツを使用するモデルやプロセスにクエリ結果を渡すなどのダウンストリーム処理でベクトルを使用している場合は、stored
を true に設定し、ベクトル サイズを最小限に抑えるための別の手法を選ぶ必要があります。
次の例は、検索インデックスのフィールド コレクションを示しています。 ベクトル フィールドの取得可能なストレージを完全に削除するには、stored
を false に設定します。
PUT https://[service-name].search.windows.net/indexes/[index-name]?api-version=2024-03-01-preview
Content-Type: application/json
api-key: [admin key]
{
"name": "myindex",
"fields": [
{
"name": "myvector",
"type": "Collection(Edm.Single)",
"retrievable": false,
"stored": false,
"dimensions": 1536,
"vectorSearchProfile": "vectorProfile"
}
]
}
重要なポイント:
ベクトル フィールドにのみ適用されます。
メモリではなくディスク上のストレージに影響し、クエリにはまったく影響しません。 クエリ実行では、
stored
プロパティの影響を受けない別のベクトル インデックスが使用されます。stored
プロパティはベクトル フィールドのインデックス作成時に設定され、元に戻すことはできません。 後で取得可能なコンテンツが必要になった場合は、インデックスを削除して再構築するか、新しい属性を持つ新しいフィールドを作成して読み込む必要があります。既定値は、true に設定された
stored
と false に設定されたretrievable
です。 既定の構成では、取得可能なコピーが保存されますが、結果では自動的に返されません。stored
が true の場合、インデックスを再構築しなくても、いつでもretrievable
を true と false の間で切り替えられます。stored
が false の場合、retrievable
は false である必要があり、変更できません。
vectorCompression、データ型、および保存されたプロパティを含むインデックスの例
ナロー データ型、削減されたストレージ、ベクトル圧縮を指定する検索インデックスの複合例を次に示します。
- "HotelNameVector" はナロー データ型の例を指定しており、元の
Float32
値を検索インデックスでCollection(Edm.Half)
と表されているFloat16
に再キャストします。 - "HotelNameVector" では、
stored
も false に設定されています。 クエリ応答で使用される追加の埋め込みは格納されません。stored
が false の場合、retrievable
も false にする必要があります。 - "DescriptionVector" は、ベクトル圧縮の例を示します。 ベクトル圧縮はインデックスで定義され、プロファイルで参照された後、ベクトル フィールドに割り当てられます。 "DescriptionVector" では、
stored
も false に設定されています。
### Create a new index
POST {{baseUrl}}/indexes?api-version=2024-03-01-preview HTTP/1.1
Content-Type: application/json
api-key: {{apiKey}}
{
"name": "hotels-vector-quickstart",
"fields": [
{
"name": "HotelId",
"type": "Edm.String",
"searchable": false,
"filterable": true,
"retrievable": true,
"sortable": false,
"facetable": false,
"key": true
},
{
"name": "HotelName",
"type": "Edm.String",
"searchable": true,
"filterable": false,
"retrievable": true,
"sortable": true,
"facetable": false
},
{
"name": "HotelNameVector",
"type": "Collection(Edm.Half)",
"searchable": true,
"retrievable": false,
"dimensions": 1536,
"stored": false,
"vectorSearchProfile": "my-vector-profile-no-compression"
},
{
"name": "Description",
"type": "Edm.String",
"searchable": true,
"filterable": false,
"retrievable": false,
"sortable": false,
"facetable": false
},
{
"name": "DescriptionVector",
"type": "Collection(Edm.Single)",
"searchable": true,
"retrievable": false,
"dimensions": 1536,
"stored": false,
"vectorSearchProfile": "my-vector-profile-with-compression"
},
{
"name": "Category",
"type": "Edm.String",
"searchable": true,
"filterable": true,
"retrievable": true,
"sortable": true,
"facetable": true
},
{
"name": "Tags",
"type": "Collection(Edm.String)",
"searchable": true,
"filterable": true,
"retrievable": true,
"sortable": false,
"facetable": true
},
{
"name": "Address",
"type": "Edm.ComplexType",
"fields": [
{
"name": "City", "type": "Edm.String",
"searchable": true, "filterable": true, "retrievable": true, "sortable": true, "facetable": true
},
{
"name": "StateProvince", "type": "Edm.String",
"searchable": true, "filterable": true, "retrievable": true, "sortable": true, "facetable": true
}
]
},
{
"name": "Location",
"type": "Edm.GeographyPoint",
"searchable": false,
"filterable": true,
"retrievable": true,
"sortable": true,
"facetable": false
}
],
"vectorSearch": {
"compressions": [
{
"name": "my-scalar-quantization",
"kind": "scalarQuantization",
"rerankWithOriginalVectors": true,
"defaultOversampling": 10.0,
"scalarQuantizationParameters": {
"quantizedDataType": "int8"
}
}
],
"algorithms": [
{
"name": "my-hnsw-vector-config-1",
"kind": "hnsw",
"hnswParameters":
{
"m": 4,
"efConstruction": 400,
"efSearch": 500,
"metric": "cosine"
}
},
{
"name": "my-hnsw-vector-config-2",
"kind": "hnsw",
"hnswParameters":
{
"m": 4,
"metric": "euclidean"
}
},
{
"name": "my-eknn-vector-config",
"kind": "exhaustiveKnn",
"exhaustiveKnnParameters":
{
"metric": "cosine"
}
}
],
"profiles": [
{
"name": "my-vector-profile-with-compression",
"compression": "my-scalar-quantization",
"algorithm": "my-hnsw-vector-config-1",
"vectorizer": null
},
{
"name": "my-vector-profile-no-compression",
"compression": null,
"algorithm": "my-eknn-vector-config",
"vectorizer": null
}
]
},
"semantic": {
"configurations": [
{
"name": "my-semantic-config",
"prioritizedFields": {
"titleField": {
"fieldName": "HotelName"
},
"prioritizedContentFields": [
{ "fieldName": "Description" }
],
"prioritizedKeywordsFields": [
{ "fieldName": "Tags" }
]
}
}
]
}
}
オーバーサンプリングを使用して量子化されたベクトル フィールドのクエリを実行する
この例のクエリ構文は、組み込みのスカラー量子化を使用するベクトル フィールドに適用されます。 既定では、スカラー量子化を使用するベクトル フィールドは rerankWithOriginalVectors
と defaultOversampling
も使用することで、より小さいベクトル インデックスの影響を緩和できます。 これらの設定は、検索インデックスで指定されます。
クエリでは、オーバーサンプリングの既定値をオーバーライドできます。 たとえば、defaultOversampling
が 10.0 の場合は、クエリ要求で別のものに変更できます。
インデックスに明示的に rerankWithOriginalVectors
または defaultOversampling
の定義がない場合でも、オーバーサンプリング パラメータを設定できます。 クエリ時に oversampling
を指定すると、そのクエリのインデックス設定をオーバーライドし、有効な rerankWithOriginalVectors
を true としてクエリを実行できます。
POST https://[service-name].search.windows.net/indexes/[index-name]/docs/search?api-version=2024-03-01-Preview
Content-Type: application/json
api-key: [admin key]
{
"vectorQueries": [
{
"kind": "vector",
"vector": [8, 2, 3, 4, 3, 5, 2, 1],
"fields": "myvector",
"oversampling": 12.0,
"k": 5
}
]
}
重要なポイント:
ベクトル プロファイルの割り当てに従い、ベクトル圧縮の対象となるベクトル フィールドに適用されます。
インデックスの圧縮構成でオーバーサンプリングまたは再ランク付けオプションが指定されていない場合でも、
defaultOversampling
値をオーバーライドするか、クエリ時にオーバーサンプリングを実施します。
関連項目
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示