[OpenAI] 埋め込み(Embeddings)を理解する

LLM

埋め込み(Embeddings)

埋め込み(Embeddings)とは?

「埋め込み(Embeddings)」とは、テキストや他の種類のデータを数値のベクトルに変換するプロセスを指し、この変換により、高次元から低次元へデータをコンピュータがより容易に処理できる形式にすることです。「埋め込みベクトル」は、元のテキストやデータの意味的な情報を保持し、その情報を数値データとして表現します。

意味的な情報の保持

埋め込みベクトルは、単にテキストを数値に変換するだけでなく、単語や文の持つ「意味」を数値的に表現します。例えば、意味的に類似した単語はベクトル空間上で近い位置にマッピングされ、類似していない意味を持つ単語はベクトル空間上で遠くなるように設計されています。

ベクトルの位置付けに関しては下記の公式ドキュメントを参照してください。

埋め込み(Embeddings) | OpenAIドキュメント - 日本語版
埋め込みとは?

応用範囲

埋め込みは、テキスト分類、自然言語理解、情報検索など、多岐にわたる機械学習および自然言語処理(NLP)のタスクに利用されます。

OpenAI APIの利用料金

埋め込み(Embeddings)はテキスト生成や画像生成と同様に利用料金がかかります。

Pricing
Simple and flexible. Only pay for what you use.

OpenAIのAPIの取得

埋め込み(Embeddings)を利用する際はOpenAIのAPIキーが必要ですので予め、取得しておいてください。APIキーの取得の仕方については下記を参照してください。

[OpenAI]GPT-4の魅力とAPIの使い方
GPT-4とは? 進化した言語理解 多岐にわたる知識への対応 問題解決とクリエイティビティ OpenAIが開発した大規模言語モデルでGPT-3.5に続くモデル。上記を踏まえあらゆる意味合いでGPT-3.5を凌駕したモデルです。 GPT−4と...

埋め込み生成

環境構築

今回はGoogleColaboratoryを使って説明します。

まずはパッケージのインストールを行います。

# パッケージのインストール
!pip install openai

OpenAIで取得したAPIキーを入力します。

# 環境変数の準備
import os
os.environ["OPENAI_API_KEY"] = "<YOUR_API_KEY>"

環境構築は以上です。

テキストから埋め込みの生成

テキストから埋め込みの生成を行います。modelについては3種類から選ぶことができますので、公式ドキュメントを参考にしてください。今回は text-embedding-3-large を使います。

Just a moment...
from openai import OpenAI
client = OpenAI()

response = client.embeddings.create(
    model = "text-embedding-3-large",
    input = ["僕は高校生探偵の中村です。"]
)

# 確認
print(len(response.data[0].embedding))
print(response.data[0].embedding)
3072
[0.04623928666114807, -0.00828608963638544, ......]

入力テキストが長さ「3072」のベクトルに変換されていますが、3072次元のベクトル表現という意味です。

近傍探索

入力テキストから意味の近いものを探すタスクです。

Faiss

今回はFaissを用いて近傍探索を行ってみたいと思います。Fasisとは効率的な類似探索に特化したライブラリで、10億規模のデータセットに対しても高速な最近傍検索を行うことができます。faissの詳細は以下のリンクから参照できます。

Faiss: A library for efficient similarity search
Visit the post for more.
Home
A library for efficient similarity search and clustering of dense vectors. - facebookresearch/faiss

まずはパッケージのインストールを行います。

# Faissパッケージのインストール
!pip install faiss-gpu

入力テキストと対象テキストの埋め込み生成

入力テキストと対象テキストのテキスト変換を行います。対象テキストは複数の埋め込みを同時生成します。

from openai import OpenAI
client = OpenAI()

# 入力テキスト埋め込み生成
in_text = "今日は温泉街を観光した"
response = client.embeddings.create(
    input= in_text,
    model = "text-embedding-3-large"
)
in_embeds = [record.embedding for record in response.data]
in_embeds = np.array(in_embeds).astype("float32")

# 対象テキスト埋め込み生成
target_texts = [
    "夕食は何にしますか?",
    "外は雨が降っていますか?",
    "朝は何時に起きますか?",
    "お風呂上がりは牛乳を飲みますか?",
    "お風呂上がりはビールですよね"
]

# 対象テキスト埋め込み生成
response = client.embeddings.create(
    input=target_texts,
    model = "text-embedding-3-large"
)

target_embeds = [record.embedding for record in response.data]
target_embeds = np.array(target_embeds).astype("float32")
print(response.data[0].embedding)
[-0.0035304203629493713, -0.01681499183177948,.....]

次にtarget_embedsの次元数を確認します。

print(target_embeds.shape)
(5, 3072)

(5, 3072)という形状は、target_embedsが5行3072列の2次元配列(具体的には、5つの3072次元ベクトル)であることを示しています。

ここでの「5」は、target_embedsに含まれるベクトル(またはデータポイント、サンプル)の数を示しています。つまり、target_embedsは5つの異なるテキストの埋め込みを含んでいるということです。

一方、「3072」は各ベクトルの次元数(または特徴量の数)を示しています。つまり、各テキストの埋め込みは3072次元のベクトルとして表現されているということです。

インデックス生成(Faiss)

Faissを使ったインデックスの生成を行います。今回インデックスのアルゴリズムはfaiss.IndexFlatL2を使いますが、faiss.IndexFlatL2の引数には「3072」を入れます。

import faiss
import numpy as np

# インデックスの生成
index = faiss.IndexFlatL2(3072)
print(index.is_trained)

# 対象テキストの追加
index.add(np.array(target_embeds).astype('float32'))
print(index.ntotal)
True
5

Faissのインデックスは、一部のタイプでは訓練が必要です。しかし、IndexFlatL2は訓練不要なタイプなので、is_trainedプロパティは常にTrueを返します。

対象テキストの埋め込み(target_embeds)をFaissのインデックスに追加します。

ここで、np.array(target_embeds).astype('float32')は、埋め込みをNumPy配列に変換し、データ型をfloat32に変換しています。Faissはfloat32型のデータしか扱えないため、この変換が必要です。

Faissのインデックスの検索アルゴリズム

Faissのインデックスの検索アルゴリズムは下記の通りです。

検索アルゴリズム種類内容
IndexFlatL2L2ノルムユークリッド距離を使用してベクトル距離を計算する
IndexFlatIPコサイン類似度内積を使用してベクトルの類似度を計算する
IndexIVFFlat高速化アルゴリズム高次元ベクトルをクラスタリングすることで検索を高速化する

インデックスの検索アルゴリズムの詳細は下記を参考にしてください。

Faissの概要 | Hakky Handbook
このページはFaissの概要ついて説明したページです。

近傍探索の実行

近傍探索を実行します。ここでの1は、検索する最近傍の数を指定しています。Dは検索結果の距離(類似度)を、Iは検索結果のインデックス(対象テキストのリスト内の位置)をそれぞれ格納します。

# 近傍探索の実行
D, I = index.search(in_embeds, 1)

# 確認
print(D)
print(I)
print(target_texts[I[0][0]])
[[1.4947984]]
[[4]]
お風呂上がりはビールですよね

まとめ

OpenAIの埋め込み技術は、テキストやデータを高密度のベクトル表現に変換することで、自然言語処理のタスクにおいて深い意味理解と処理を可能にします。この技術は、単語、文、あるいは文書全体の複雑な意味内容を、コンピュータが解釈しやすい形式に変換することにより、テキストベースのアプリケーションの精度と効率を飛躍的に向上させます。

おまけ / 研究コーナー

ChatGPT PlusのDALL-E 3

OpenAIのDALL-E 3の可能性を見出すべく、ChatGPT PlusのDALL-E 3を使って生成画像を作る上で有効的なプロンプトを生成してみたいと思います。

プロンプトの役割・条件・キーワード

<役割>
あなたは世界的に有名な画家で趣味は写真を撮ることです。最近は描いてきた絵の見識美を活かして小説も書き始めました。

<プロンプト>
下記の条件を踏まえながら、条件とキーワードを踏まえてDALL-E3を使った画像生成に有効なプロンプトを作ってください。

<条件>
・表現手法
・色彩
・画像のイメージ(モノクロ、アニメ風など)

<キーワード>
・埋め込み
・コード
・コンピューティング

ChatGPT Plusの返答

「未来的なコンピューティングラボの中で、壁一面に埋め込まれた複雑なコードが浮かび上がるシーンを描いた画像。このアニメ風のシーンでは、先端技術に囲まれた研究者が大型の透明なタッチスクリーンを通じて、空中に表示されたコードとインタラクションしている様子が捉えられている。背景はモノクロで描かれており、冷たい科学技術の世界を表現しているが、コードの部分だけが鮮やかな青と緑の色彩で強調され、デジタル世界の美しさと複雑さを際立たせている。この画像は、コンピューティングの未来と、それが私たちの生活にどのように埋め込まれていくかというテーマを探求している。」

生成されたプロンプトを使って画像生成

プロンプトの補足説明

画像のテーマ

「未来的なコンピューティングラボでの複雑なコードとのインタラクション」

科学技術が進歩し、コンピューティングが日常生活に深く組み込まれていく未来を探求しています。技術と人間の関係、特にデジタル世界との対話の方法に焦点を当てていると言えます。

表現手法

「透明なタッチスクリーンの使用」

研究者が空中に表示されたコードとインタラクションしているシーンは、大型の透明なタッチスクリーンを介して描かれています。これは、最新技術を駆使した未来的なコミュニケーションの形を象徴しています。

色彩

「モノクロの背景」

背景はモノクロで描かれており、科学技術の冷たく硬質な世界を表現しています。これにより、視覚的なコントラストが生まれ、テーマの重要性が強調されます。

「コードの鮮やかな青と緑」

複雑なコードの部分だけが鮮やかな青と緑で強調されています。これはデジタル世界の美しさと複雑さを際立たせると同時に、技術の中に存在する生命力や創造性を象徴しています。

画像のイメージ

「コンピューティングの未来が単なる冷たい技術の進歩ではなく、人間との深い意味での対話を通じて、より豊かな世界を創造していくこと」

テクノロジーと人間の相互作用の未来を表現しています。コードとの直接的なインタラクションを通じて、人間がテクノロジーをどのように理解し、操作するかを示しています。同時に、科学技術の進歩がもたらす冷たさや無機質さの中にも、人間の創造性や温かみを見出すことができる希望のメッセージを含んでいます。

まとめ

このプロンプトを使用することで、DALL-E 3は、「未来の対話と希望」を表現した画像を生成することができたと言えます。

コメント

タイトルとURLをコピーしました