ニュース
モデル
製品
keyboard_arrow_down
ディープサーチ
最善の答えが見つかるまで、検索し、読み、推論してください。
読者
URL を読み取ったり検索したりすると、大規模なモデルのサポートが向上します。
ベクトルモデル
世界クラスのマルチモーダル、多言語埋め込み。
並べ替え者
検索の関連性を最大化する世界クラスのニューラルレトリーバー。
もっと
keyboard_arrow_down
分類子
画像とテキストのゼロショットおよび少数ショットの分類。
スライサー
長いテキストをチャンクまたはトークンに分割します。

APIドキュメント
AIプログラミングアシスタントIDEまたは大規模モデル用のコードを自動生成
open_in_new


会社
keyboard_arrow_down
私たちについて
営業担当者に問い合わせる
インターンプログラム
参加しませんか
open_in_new
ロゴをダウンロード
open_in_new
利用規約


ログイン
login
バイナリ埋め込みとは?
バイナリ埋め込みはどのように機能するのか?
Jina AI のバイナリ埋め込みでどれだけ節約できるか?
はじめに
例
技術記事
5月 15, 2024

バイナリ Embeddings:AI をすべて、容量はわずか 3.125%

AI モデルのような堅牢で不正確なものに対して、32 ビットの精度は大きすぎます。そこで私たちは 31 ビットを削減しました!バイナリ埋め込みはより小さく、より高速で、高性能です。
Futuristic digital 3D model of a coffee grinder with blue neon lights on a black background, featuring numerical data.
Sofia Vasileva
Scott Martens
Sofia Vasileva, Scott Martens • 11 読む時間

埋め込み(Embeddings)は、様々な AI や自然言語処理アプリケーションの基盤となり、テキストの意味を高次元ベクトルとして表現する方法を提供しています。しかし、モデルのサイズが大きくなり、AI モデルが処理するデータ量が増加するにつれて、従来の埋め込みの計算とストレージの要件は急激に増加しています。バイナリ埋め込みは、高性能を維持しながらリソース要件を大幅に削減する、コンパクトで効率的な代替手段として導入されました。

バイナリ埋め込みは、埋め込みベクトルのサイズを最大 96%(Jina Embeddings の場合は 96.875%)削減することで、これらのリソース要件を軽減する一つの方法です。ユーザーは、精度をほとんど損なうことなく、コンパクトなバイナリ埋め込みの力を AI アプリケーションで活用できます。

tagバイナリ埋め込みとは?

バイナリ埋め込みは、従来の高次元浮動小数点ベクトルをバイナリベクトルに変換する特殊なデータ表現形式です。これは埋め込みを圧縮するだけでなく、ベクトルの完全性と有用性をほぼ完全に保持します。この技術の本質は、変換後もデータポイント間の意味論的関係と距離を維持できることにあります。

バイナリ埋め込みの魔法は量子化にあります。これは高精度の数値を低精度の数値に変換する方法です。AI モデリングでは、通常、埋め込みの 32 ビット浮動小数点数を 8 ビット整数などの少ないビット数の表現に変換することを意味します。

Comparison of Hokusai's Great Wave print in color and black & white, highlighting the wave's dynamism and detail.
2値化はすべてのスカラー値を 0 または 1 に変換することです。カラー画像を白黒のピクセルだけの画像に変換するようなものです。画像:神奈川沖浪裏(1831)葛飾北斎

バイナリ埋め込みは、これを究極まで推し進め、各値を 0 または 1 に縮小します。32 ビット浮動小数点数をバイナリ桁に変換することで、埋め込みベクトルのサイズを 32 分の 1、つまり 96.875% 削減します。結果として、得られる埋め込みのベクトル演算が大幅に高速化されます。一部のマイクロチップで利用可能なハードウェアの高速化を使用すると、ベクトルが 2 値化された場合、ベクトル比較の速度は 32 倍以上に向上する可能性があります。

このプロセスでは必然的に一部の情報が失われますが、モデルの性能が非常に高い場合、この損失は最小限に抑えられます。非量子化された埋め込みが異なるものの間で最大限に異なる場合、2 値化はその違いをうまく保持する可能性が高くなります。そうでない場合、埋め込みを正しく解釈することが困難になる可能性があります。

Jina Embeddings のモデルは、まさにそのような頑健性を持つように訓練されており、2 値化に適しています。

このようなコンパクトな埋め込みにより、特にモバイルや時間に敏感な用途など、リソースに制約のある環境で新しい AI アプリケーションが可能になります。

以下のグラフが示すように、これらのコストと計算時間の利点は、比較的小さな性能コストで得られます。

image
NDCG@10:正規化割引累積利得を使用してトップ 10 の結果について計算されたスコア。

jina-embeddings-v2-base-enでは、バイナリ量子化により検索精度が 47.13% から 42.05% に低下し、約 10% の損失となります。jina-embeddings-v2-base-deでは、この損失は 44.39% から 42.65% とわずか 4% です。

Jina Embeddings のモデルがバイナリベクトルの生成で優れた性能を発揮するのは、より均一な埋め込みの分布を作成するように訓練されているためです。これは、2 つの異なる埋め込みが、他のモデルの埋め込みよりも多くの次元でより離れている可能性が高いことを意味します。この特性により、それらの距離がバイナリ形式でより適切に表現されることが保証されます。

tagバイナリ埋め込みはどのように機能するのか?

これがどのように機能するかを理解するために、3 つの埋め込み:A、B、C を考えてみましょう。これらはすべて完全な浮動小数点ベクトルで、2 値化されたものではありません。ここで、A から B までの距離が B から C までの距離よりも大きいとします。埋め込みでは、通常コサイン距離を使用します:

cos⁡(A,B)>cos⁡(B,C)\cos(A,B) > \cos(B,C)cos(A,B)>cos(B,C)

A、B、C を 2 値化すると、ハミング距離でより効率的に距離を測定できます。

Geometric diagrams with labeled circles A, B, and C connected by lines against a contrasting background.
立方体上のハミング距離。左:A から B までの距離は 1。右:B から C までの距離は 2。

A、B、C の 2 値化されたバージョンをそれぞれ Abin、Bbin、Cbin と呼びましょう。

バイナリベクトルの場合、Abin と Bbin 間のコサイン距離が Bbin と Cbin 間よりも大きい場合、Abin と Bbin 間のハミング距離は Bbin と Cbin 間のハミング距離以上になります。

したがって:

cos⁡(A,B)>cos⁡(B,C)\cos(A,B) > \cos(B,C)cos(A,B)>cos(B,C)

の場合、ハミング距離については:

hamm(Abin,Bbin)≥hamm(Bbin,Cbin)hamm(A{bin}, B{bin}) \geq hamm(B{bin}, C{bin})hamm(Abin,Bbin)≥hamm(Bbin,Cbin)

理想的には、埋め込みを 2 値化する際、完全な埋め込みと同じ関係が 2 値化された埋め込みでも成り立つことが望ましいです。つまり、浮動小数点コサインで一方の距離が他方より大きい場合、それらの 2 値化された等価物間のハミング距離でも同様になるべきです:

cos⁡(A,B)>cos⁡(B,C)⇒hamm(Abin,Bbin)≥hamm(Bbin,Cbin)\cos(A,B) > \cos(B,C) \Rightarrow hamm(A{bin}, B{bin}) \geq hamm(B{bin}, C{bin})cos(A,B)>cos(B,C)⇒hamm(Abin,Bbin)≥hamm(Bbin,Cbin)

すべての埋め込みの三つ組についてこれを真にすることはできませんが、ほとんどの場合について真にすることは可能です。

Graph with labeled points A and B, connected by lines marked as 'hamm AB' and 'cos AB', on a black background.
青い点は完全な浮動小数点ベクトルを、赤い点はその 2 値化された等価物を表しています。

バイナリベクトルでは、各次元を存在する(1)か存在しない(0)かのいずれかとして扱うことができます。2 つのベクトルが非バイナリ形式で互いに離れているほど、任意の次元で一方が正の値を持ち、他方が負の値を持つ確率が高くなります。これは、バイナリ形式では、一方が 0 で他方が 1 である次元がより多くなる可能性が高いことを意味します。これによりハミング距離でより離れた位置にあることになります。

逆に、より近いベクトルについては:非バイナリベクトルが近いほど、任意の次元で両方とも 0 または両方とも 1 を持つ確率が高くなります。これによりハミング距離でより近い位置にあることになります。

Jina Embeddings のモデルが 2 値化に非常に適しているのは、ネガティブマイニングやその他の微調整の実践を使用して、特に異なるものの間の距離を増加させ、似ているものの間の距離を減少させるように訓練されているためです。これにより、埋め込みはより頑健になり、類似性と違いにより敏感になり、バイナリ埋め込み間のハミング距離が非バイナリ埋め込み間のコサイン距離により比例するようになります。

tagJina AI のバイナリ埋め込みでどれだけ節約できるか?

Jina AI のバイナリ埋め込みモデルを採用することで、時間に敏感なアプリケーションのレイテンシーを低減するだけでなく、以下の表が示すように、かなりのコスト削減効果も得られます:

モデル 2億5000万の
埋め込みあたりの
メモリ
検索
ベンチマーク
平均
AWS での推定価格
(x2gb インスタンスで
月額 $3.8/GB)
32 ビット浮動小数点埋め込み 715 GB 47.13 $35,021
バイナリ埋め込み 22.3 GB 42.05 $1,095

このような 95% 以上の削減は、検索精度の低下が約 10% に抑えられています。

これは、OpenAI の Ada 2 モデルやCohere の Embed v3 の 2 値化ベクトルを使用する場合よりもさらに大きな削減効果です。これらのモデルは 1024 次元以上の出力埋め込みを生成します。Jina AI の埋め込みは 768 次元しかなく、量子化する前の段階で同じ精度でも他のモデルよりもサイズが小さくなっています。

💡
2 値ベクトルはメモリ、計算時間、通信帯域幅、ディスク容量を節約し、複数の面でコスト面でのメリットをもたらします。

これらの節約は環境面でも効果があり、希少材料やエネルギーの使用を抑えることができます。

tagはじめに

Jina Embeddings API を使用して 2 値埋め込みを取得するには、API 呼び出しに encoding_type パラメータを追加し、符号付き整数としてエンコードされた 2 値化埋め込みを取得する場合は binary、符号なし整数の場合は ubinary を値として指定するだけです。

tagJina Embedding API に直接アクセス

curl を使用する場合:

curl https://api.jina.ai/v1/embeddings \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <YOUR API KEY>" \
  -d '{
    "input": ["Your text string goes here", "You can send multiple texts"],
    "model": "jina-embeddings-v2-base-en",
    "encoding_type": "binary"
  }'

または Python の requests API を使用する場合:

import requests

headers = {
  "Content-Type": "application/json",
  "Authorization": "Bearer <YOUR API KEY>"
}

data = {
  "input": ["Your text string goes here", "You can send multiple texts"],
  "model": "jina-embeddings-v2-base-en",
  "encoding_type": "binary",
}

response = requests.post(
    "https://api.jina.ai/v1/embeddings", 
    headers=headers, 
    json=data,
)

上記の Python request を使用すると、response.json() を確認することで以下のようなレスポンスが得られます:

{
  "model": "jina-embeddings-v2-base-en",
  "object": "list",
  "usage": {
    "total_tokens": 14,
    "prompt_tokens": 14
  },
  "data": [
    {
      "object": "embedding",
      "index": 0,
      "embedding": [
        -0.14528547,
        -1.0152762,
        ...
      ]
    },
    {
      "object": "embedding",
      "index": 1,
      "embedding": [
        -0.109809875,
        -0.76077706,
        ...
      ]
    }
  ]
}

これらは 96 個の 8 ビット符号付き整数として保存された 2 つの 2 値埋め込みベクトルです。これらを 768 個の 0 と 1 に展開するには、numpy ライブラリを使用する必要があります:

import numpy as np

# assign the first vector to embedding0
embedding0 = response.json()['data'][0]['embedding']

# convert embedding0 to a numpy array of unsigned 8-bit ints
uint8_embedding = np.array(embedding0).astype(numpy.uint8) 

# unpack to binary
np.unpackbits(uint8_embedding)

結果として、0 と 1 のみからなる 768 次元のベクトルが得られます:

array([0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0,
       0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1,
       0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1,
       0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1,
       1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0,
       0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0,
       1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1,
       1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1,
       1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1,
       0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1,
       1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0,
       0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0,
       1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1,
       0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1,
       1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0,
       0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1,
       1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1,
       1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1,
       0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0,
       1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0,
       0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0,
       0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1,
       0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0,
       0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0,
       1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0,
       0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0,
       0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1,
       1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0,
       1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0,
       1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1,
       1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0,
       1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1,
       1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0,
       1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1,
       0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0],
      dtype=uint8)

tagQdrant での 2 値量子化の使用

Qdrant の統合ライブラリを使用して、2 値埋め込みを Qdrant ベクトルストアに直接格納することもできます。Qdrant は内部的に BinaryQuantization を実装しているため、ベクトルコレクション全体のプリセット設定として使用でき、コードを変更することなく 2 値ベクトルの検索と保存が可能です。

使用方法は以下のコード例を参照してください:

import qdrant_client
import requests

from qdrant_client.models import Distance, VectorParams, Batch, BinaryQuantization, BinaryQuantizationConfig

# Jina API キーを提供し、利用可能なモデルの1つを選択します。
# 無料トライアルキーはこちらで取得できます:https://jina.ai/embeddings/
JINA_API_KEY = "jina_xxx"
MODEL = "jina-embeddings-v2-base-en"  # または "jina-embeddings-v2-base-en"
EMBEDDING_SIZE = 768  # small バリアントの場合は 512

# API からエンベディングを取得
url = "https://api.jina.ai/v1/embeddings"

headers = {
    "Content-Type": "application/json",
    "Authorization": f"Bearer {JINA_API_KEY}",
}

text_to_encode = ["Your text string goes here", "You can send multiple texts"]
data = {
    "input": text_to_encode,
    "model": MODEL,
}

response = requests.post(url, headers=headers, json=data)
embeddings = [d["embedding"] for d in response.json()["data"]]


# エンベディングを Qdrant にインデックス化
client = qdrant_client.QdrantClient(":memory:")
client.create_collection(
    collection_name="MyCollection",
    vectors_config=VectorParams(size=EMBEDDING_SIZE, distance=Distance.DOT, on_disk=True),
    quantization_config=BinaryQuantization(binary=BinaryQuantizationConfig(always_ram=True)),
)

client.upload_collection(
    collection_name="MyCollection",
    ids=list(range(len(embeddings))),
    vectors=embeddings,
    payload=[
            {"text": x} for x in text_to_encode
    ],
)

検索を設定するには、oversampling と rescore パラメータを使用する必要があります:

from qdrant_client.models import SearchParams, QuantizationSearchParams

results = client.search(
    collection_name="MyCollection",
    query_vector=embeddings[0],
    search_params=SearchParams(
        quantization=QuantizationSearchParams(
            ignore=False,
            rescore=True,
            oversampling=2.0,
        )
    )
)

tagLlamaIndex を使用する

Jina バイナリエンベディングを LlamaIndex で使用するには、JinaEmbedding オブジェクトをインスタンス化する際に encoding_queries パラメータを binary に設定します:

from llama_index.embeddings.jinaai import JinaEmbedding

# 無料トライアルキーはこちらで取得できます:https://jina.ai/embeddings/
JINA_API_KEY = "<YOUR API KEY>"

jina_embedding_model = JinaEmbedding(
    api_key=jina_ai_api_key,
    model="jina-embeddings-v2-base-en",
    encoding_queries='binary',
    encoding_documents='float'
)

jina_embedding_model.get_query_embedding('Query text here')
jina_embedding_model.get_text_embedding_batch(['X', 'Y', 'Z'])

tagバイナリエンベディングをサポートする他のベクトルデータベース

以下のベクトルデータベースはバイナリベクトルをネイティブにサポートしています:

  • DataStax の AstraDB
  • FAISS
  • Milvus
  • Vespa.ai
  • Weaviate

tag例

バイナリエンベディングの実際の動作を示すために、arXiv.org から選んだアブストラクトに対して、jina-embeddings-v2-base-en を使用して 32 ビット浮動小数点とバイナリベクトルの両方を取得しました。そして、サンプルクエリ「3D segmentation」に対するエンベディングと比較しました。

下の表から分かるように、上位3件は同じで、上位5件中4件が一致しています。バイナリベクトルを使用しても、ほぼ同じトップマッチが得られています。

バイナリ 32ビット浮動小数点
ランク ハミング
距離
マッチしたテキスト コサイン マッチしたテキスト
1 0.1862 SEGMENT3D: A Web-based
Application for Collaboration...
0.2340 SEGMENT3D: A Web-based
Application for Collaboration...
2 0.2148 Segmentation-by-Detection:
A Cascade Network for...
0.2857 Segmentation-by-Detection:
A Cascade Network for...
3 0.2174 Vox2Vox: 3D-GAN for Brain
Tumour Segmentation...
0.2973 Vox2Vox: 3D-GAN for Brain
Tumour Segmentation...
4 0.2318 DiNTS: Differentiable Neural
Network Topology Search...
0.2983 Anisotropic Mesh Adaptation for
Image Segmentation...
5 0.2331 Data-Driven Segmentation of
Post-mortem Iris Image...
0.3019 DiNTS: Differentiable Neural
Network Topology...

カテゴリー:
技術記事
rss_feed
オフィス
location_on
カリフォルニア州サニーベール
710 Lakeway Dr、Ste 200、サニーベール、CA 94085、アメリカ合衆国
location_on
ドイツ、ベルリン(本社)
Prinzessinnenstraße 19-20、10969 ベルリン、ドイツ
location_on
中国、北京
中国北京市海淀区西街48号ビル6号5階
location_on
深セン、中国
ルーム 402、4 階、福安テクノロジービル、深セン、中国
検索ベース
ディープサーチ
読者
ベクトルモデル
並べ替え者
分類子
スライサー
APIドキュメント
Jina APIキーを取得する
レート制限
APIステータス
会社
私たちについて
営業担当者に問い合わせる
ニュース
インターンプログラム
参加しませんか
open_in_new
ロゴをダウンロード
open_in_new
条項
安全性
利用規約
プライバシー
Cookieを管理する
email
Jina AI © 2020-2025.