Azure AI Visionのマルチモーダル埋め込みを試す
はじめに
こちらの記事は Azure PoC 部 Advent Calendar 2024 の 19 日目の記事です。
あまり知られていないのですが、Azure AI Vision では、マルチモーダル埋め込み生成に対応しています。
マルチモーダル埋め込みでは、テキストと画像を同じベクトル空間にベクトル化する手法です。
マルチモーダル埋め込みの代表的な手法としては CLIP ( Contrastive Language–Image Pre-training )などがあります。
Azure AI Vision でのマルチモーダル埋め込みの実装詳細は公開されていませんが、多言語に対応した形で画像、テキストとも 1,024 次元のベクトルが取得できます。
Azure AI Vision のマルチモーダル埋め込み機能(画像 → ベクトル化)
まずは画像をベクトル化する関数を用意します。
Image Retrieval
のVectorize Stream
エンドポイントを呼び出す形で実装しています。
import requests
def get_image_embedding(
image_data: bytes,
endpoint: str,
key: str,
api_version: str = "2023-04-01-preview",
model_version: str = "2023-04-15",
) -> list[float] | None:
"""画像の埋め込みベクトルを取得する関数
Args:
image_data (bytes): 画像データ
endpoint (str): Azure AI Visionのエンドポイント
key (str): Azure AI Visionのキー
api_version (str, optional): API バージョン Defaults to "2023-04-01-preview".
model_version (str, optional): モデルバージョン Defaults to "2023-04-15".
Returns:
list[float] | None: 1024次元のベクトル。エラーが発生した場合はNoneを返す
"""
url = f"{endpoint}/computervision/retrieval:vectorizeImage?api-version={api_version}&{model_version}"
headers = {
"Content-type": "application/octet-stream",
"Ocp-Apim-Subscription-Key": key,
}
try:
resp = requests.post(url, data=image_data, headers=headers)
if resp.ok:
return resp.json()["vector"]
else:
print(f"An error occurred while processing {resp.status_code}")
return None
except Exception as e:
print(f"An error occurred while processing {e}")
return None
Azure AI Vision の API バージョンは最新は2024-02-01
ですが、マルチモーダル埋め込み系の API は2023-04-01-preview
でしか呼び出すことができませんでした。
Azure AI Vision のマルチモーダル埋め込み機能(テキスト → ベクトル化)
同様にテキストをベクトル化する関数を用意します。
こちらもImage Retrieval
のVectorize Text
エンドポイントを呼び出す形で実装します。
import requests
import json
def get_text_embedding(
text: str,
endpoint: str,
key: str,
api_version: str = "2023-04-01-preview",
model_version: str = "2023-04-15",
) -> list[float] | None:
"""テキストの埋め込みベクトルを取得する関数
Args:
text (str): テキスト
endpoint (str): Azure AI Visionのエンドポイント
key (str): Azure AI Visionのキー
api_version (str, optional): API バージョン Defaults to "2023-04-01-preview".
model_version (str, optional): モデルバージョン Defaults to "2023-04-15".
Returns:
list[float] | None: 1024次元のベクトル。エラーが発生した場合はNoneを返す
"""
url = f"{endpoint}/computervision/retrieval:vectorizeText?api-version={api_version}&{model_version}"
headers = {
"Content-type": "application/json",
"Ocp-Apim-Subscription-Key": key,
}
try:
resp = requests.post(url, data=json.dumps({"text": text}), headers=headers)
if resp.ok:
return resp.json()["vector"]
else:
print(f"An error occurred while processing {resp.status_code}")
return None
except Exception as e:
print(f"An error occurred while processing {e}")
return None
画像とテキストの類似度を計算してみる
2 つのベクトルをコサイン類似度を計算する関数を用意しておきます。
import numpy as np
def calc_cosine_similarity(vector1: list[float], vector2: list[float]) -> float:
"""コサイン類似度を計算する関数
Args:
vector1 (list[float]): べクトル1
vector2 (list[float]): ベクトル2
Returns:
float: コサイン類似度
"""
return np.dot(vector1, vector2) / (
np.linalg.norm(vector1) * np.linalg.norm(vector2)
)
それでは実際に画像とテキストをそれぞれベクトル化してコサイン類似度を計算してみます。
今回はいらすとやの以下の画像を使って試してみます。
画像のベクトル化
先ほどのget_image_embedding
関数を使って画像のベクトル値を取得します。
endpoint = "<Azure AI Visionのエンドポイント>"
key = "<Azure AI Visionのキー>"
# ベクトル化対象ファイル
file_path = "./pet_robot_soujiki_cat.png"
with open(file_path, "rb") as f:
image_data = f.read()
image_vector = get_image_embedding(
image_data=image_data,
endpoint=endpoint,
key=key,
)
if image_vector:
print("Vector is successfully generated")
print(image_vector)
Vector is successfully generated
[1.2333984, -1.7792969, -1.9472656, ..., -2.2128906, -2.1328125] # ベクトル値は省略
テキストのベクトル化
同様にget_text_embedding
関数を使ってテキストのベクトル値を取得します。
text_vector = get_text_embedding(
text="灰色の猫",
endpoint=endpoint,
key=key,
)
if text_vector:
print("Vector is successfully generated")
print(text_vector)
Vector is successfully generated
[-0.00023115672, -0.041656945, -0.026567545, ..., -0.030063469, -0.0257012] # ベクトル値は省略
コサイン類似度の計算
calc_cosine_similarity
関数を使って取得した画像のベクトル値とテキストのベクトル値のコサイン類似度を計算します。
similarity = calc_cosine_similarity(vector1=image_vector, vector2=text_vector)
print(similarity)
0.3607935767576095s
今回の結果だとコサイン類似度が 0.36 なのであまり類似度が高いとは言えない形になりましたが、テキストと画像を同じベクトル空間で比較できること自体は確認できました。
まとめ
本記事では Azure AI Vision のマルチモーダル埋め込み機能を試してみました。
API バージョンが2023-04-01-preview
版でないと使えないのは地味にハマりポイントでした。
今後はよりプロダクション向けに Azure AI Search にベクトル値を保存して、検索でマルチモーダル埋め込みを活用していく部分を紹介できればと思います。
参考
Discussion