Docs Menu
Docs Home
/

柔軟な次元と数量化

投票AI埋め込みモデルは、柔軟な次元と数量化をサポートし、ベクトルベースのアプリケーションのストレージと検索コストを最適化します。このページでは、これらの機能を使用して高い検索品質を維持しつつコストを削減する方法について説明します。

Google Colas のインタラクティブ チュートリアルで、柔軟な次元と数量化について学びます。

大規模なリポジトリにわたるコード取得など、大規模なベクトル検索アプリケーションを扱う場合、ストレージと計算のコストが重要になる可能性があります。これらのコストは、次の要因に応じて直線的に増やす。

  • 埋め込み次元: 各ベクトルの次元数

  • 精度:ベクトル内の各数値をエンコードするのに使用されるビット数

これらの要因のいずれかを削減することで、取得品質に大きな影響を与えずにコストを大幅に削減できます。投票AIモデルは、これを実現するための 2 つの補完的な手法をサポートしています。

  • マトロール埋め込み: 埋め込みをより少ない次元に切り捨てることで、より小さいバージョンの埋め込みを使用できます

  • 量子化: 埋め込み内の各数値の精度を32 ビットの浮動小数点数から低精度形式に縮小します

これらの手法は、次元や量子化された値が削減されても品質を維持するようにモデルを訓練する、Matrishka 学習と量子化対応の訓練によって有効になっています。

マトロール埋め込みは、単一のベクトル内にネストされた異なるサイズの複数の有効な埋め込みを含む特殊なタイプのベクトル埋め込みです。これにより、パフォーマンスとコスト要件の最もバランスが取れた次元を柔軟に選択できます。

最新のステージの埋め込みモデルは、Matryshka 埋め込みを生成し、output_dimension パラメーターを直接サポートします。詳しくは、「 モデルの概要 」を参照してください。

マテリアライズド学習では、1 つの埋め込みにさまざまな長さの埋め込みのネストされたファミリーが含まれます。例、2048 次元の Vyage 埋め込みには、複数の短い長さの有効な埋め込みが含まれています。

  • 最初の 256 次元は有効な 256 次元埋め込みを形成します

  • 最初の 512 次元は有効な 512 次元埋め込みを形成します

  • 最初の 1024 次元は有効な 1024 次元埋め込みを形成します

  • すべての 2048 次元はフル忠実度埋め込みを形成します

短いバージョンごとに、完全な埋め込みよりも取得の品質は若干低下しますが、必要なストレージと計算リソースは少なくなります。

先頭の次元サブセットを保持して、MongoDB Atlas 埋め込みを切り捨てます。次の例では、1024 次元ベクトルを 256 次元に切り捨てる方法を示しています。

import voyageai
import numpy as np
def embd_normalize(v: np.ndarray) -> np.ndarray:
# Normalize rows of a 2D array to unit vectors
row_norms = np.linalg.norm(v, axis=1, keepdims=True)
if np.any(row_norms == 0):
raise ValueError("Cannot normalize rows with a norm of zero.")
return v / row_norms
vo = voyageai.Client()
# Generate 1024-dimensional embeddings
embd = vo.embed(['Sample text 1', 'Sample text 2'], model='voyage-4-large').embeddings
# Truncate to 256 dimensions and normalize
short_dim = 256
resized_embd = embd_normalize(np.array(embd)[:, :short_dim]).tolist()

量子化により、高精度の浮動小数点数が低精度の形式に変換されるため、埋め込みの精度が低下します。このプロセスにより、ストレージとコンピューティングのコストを大幅に削減できると同時に、強力な検索品質を維持できます。

最新の 使用量の埋め込みモデルは、量子化対応の訓練を使用して訓練されているため、量子化されても高い取得品質が維持されます。詳細については、「 モデルの概要 」を参照してください。

注意

ベクトルストレージと検索をサポートする多くのデータベースは、 MongoDBを含む量子化された埋め込みもサポートしています。 MongoDB ベクトル検索での量子化の詳細については、「 ベクトル量子化 」を参照してください。

量子化により、各次元を標準の 32 ビット浮動小数点形式よりも少ないビットで表現することで、埋め込みの精度が低下します。次元ごとに 4 バイトを使用する代わりに、量子化された埋め込みは次の値を使用します。

  • 8ビット整数(次元ごとに1 バイト):ストレージを4 x ずつ削減します

  • バイナリ(次元ごとに1 ビット):ストレージを32 x ずつ削減します

サイズは大幅に縮小されているにもかかわらず、Valage のような量子化対応の訓練されたモデルは高い検索品質を維持します。サポートされている投票モデルでは、output_dtype パラメーターで出力データ型を指定することで量子化が可能になります。

データ型
説明

float

返される各埋め込みは、32 ビット(4 バイト)の単精度浮動小数点数のリストです。これはデフォルトで、精度と検索精度が最も高くなります。

int8 および uint8

返される各埋め込みは、それぞれ -128 から 127 まで、および 0 から 255 までの 8 ビット(1 バイト)整数のリストです。

binary および ubinary

8返される各埋め込みは、ビット圧縮され、量化された単一ビット埋め込み値を表すint8 binaryuint8ubinaryビット整数のリストです。 は 、 は です。返される整数のリストの長さは、埋め込みの実際の次元の1 /8 です。binary 型は、以下で説明するオフセット バイナリ メソッドを使用します。

バイナリ量子化の理解

  1. 次の埋め込み値について考えてみましょう。

    -0.0396, 0.0062, -0.0745, -0.0390, 0.0046, 0.0003, -0.0850, 0.0399
  2. バイナリ量子化では、次のルールを使用して各値を単一のビットに変換します。

    • 0 未満の値は 0 に変換されます

    • 0 以上の値は 1 に変換されます

    0, 1, 0, 0, 1, 1, 0, 1
  3. 8 ビットを 1 つの 8 ビット整数、01001101 に圧縮します。この整数は 10 進数では 77 に変換されます。

  4. 最終出力型に変換するには、次の変換を適用します。

    出力タイプ
    変換方法
    結果

    ubinary

    uint8: 値を符号なし整数として直接使用します。

    77

    binary

    int8: を減算してオフセット バイナリ 128メソッドを適用します。

    -5177 - 128 に等しい)

オフセット バイナリは、符号付き整数をバイナリ形式で表現する方法です。投票AI は、 出力タイプにこのメソッドを使用して、ビット圧縮されたバイナリ埋め込みを符号付き整数(binary int8)としてエンコードします。

オフセット バイナリ メソッドは、オフセット値を追加または減算することで機能します。

  • バイナリに変換する場合:128 エンコードする前に、符号付き整数に を追加します

  • バイナリから変換する場合:128 デコード後に整数から を減算

8 ビット符号付き整数(範囲 -128 から 127)の場合、オフセットは常に 128 になります。

符号付き整数からバイナリへ

-32 を 8 ビットのバイナリ数として表すには、次のようにします。

  1. オフセット(128)を -32 に追加すると、96 が得られます。

  2. 96 をバイナリに変換します: 01100000

バイナリから符号付き整数へ

8 ビットのバイナリ数 01010101 から符号付き整数を決定するには、次の手順に従います。

  1. 整数に直接変換します: 85

  2. 85 からオフセット(128)を減算すると、-43 が得られます。

浮動小数埋め込みをバイナリ形式に手動で変換することも、バイナリ埋め込みを個々のビットに解凍して戻すこともできます。次の例は、両方の操作を示しています。

import numpy as np
import voyageai
vo = voyageai.Client()
# Generate float embeddings
embd_float = vo.embed('Sample text 1', model='voyage-4-large', output_dimension=2048).embeddings[0]
# Compute 512-dimensional bit-packed binary and ubinary embeddings from 2048-dimensional float embeddings
embd_binary_calc = (np.packbits(np.array(embd_float) > 0, axis=0) - 128).astype(np.int8).tolist() # Quantize, binary offset
embd_binary_512_calc = embd_binary_calc[0:64] # Truncate. Binary is 1/8 length of embedding dimension.
embd_ubinary_calc = (np.packbits(np.array(embd_float) > 0, axis=0)).astype(np.uint8).tolist() # Quantize, binary offset
embd_ubinary_512_calc = embd_ubinary_calc[0:64] # Truncate. Binary is 1/8 length of embedding dimension.
import numpy as np
import voyageai
vo = voyageai.Client()
# Generate binary embeddings
embd_binary = vo.embed('Sample text 1', model='voyage-4-large', output_dtype='binary', output_dimension=2048).embeddings[0]
embd_ubinary = vo.embed('Sample text 1', model='voyage-4-large', output_dtype='ubinary', output_dimension=2048).embeddings[0]
# Unpack bits
embd_binary_bits = [format(x, f'08b') for x in np.array(embd_binary) + 128] # List of (bits) strings
embd_binary_unpacked = [bit == '1' for bit in ''.join(embd_binary_bits)] # List of booleans
embd_ubinary_bits = [format(x, f'08b') for x in np.array(embd_ubinary)] # List of (bits) strings
embd_ubinary_unpacked = [bit == '1' for bit in ''.join(embd_ubinary_bits)] # List of booleans

戻る

トークン化

項目一覧