HuggingFace ブログ : 埋め込み (Embeddings) を始める (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 11/21/2022
* 本ページは、HuggingFace Blog の以下のドキュメントを翻訳した上で適宜、補足説明したものです:
- Getting Started With Embeddings (Authors : Omar Espejel ; Published : 06/23/2022)
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
- 人工知能研究開発支援
- 人工知能研修サービス(経営者層向けオンサイト研修)
- テクニカルコンサルティングサービス
- 実証実験(プロトタイプ構築)
- アプリケーションへの実装
- 人工知能研修サービス
- PoC(概念実証)を失敗させないための支援
- お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
◆ お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。
- 株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
- sales-info@classcat.com ; Web: www.classcat.com ; ClassCatJP
HuggingFace ブログ : 埋め込み (Embeddings) を始める
埋め込みを理解する
埋め込みは例えば、テキスト, 文書, 画像, 音声等のような、情報のピースの数値表現です。表現は埋め込まれたものの意味論的意味 (= semantic meaning) を捉え、多くの産業利用に対して堅牢にします。
テキスト “What is the main benefit of voting?” が与えられたとき、センテンスの埋め込みはベクトル空間内で表すことができます、例えば、384 個の数字のリスト (例えば, [0.84, 0.42, …, 0.02]) によってです。このリストは意味を捉えていますので、2 つのセンテンスの意味がどのくらい上手く一致するかを決定するために異なる埋め込み間の距離を計算するような、エキサイティングなことができます。
埋め込みはテキストに制限されません!画像の埋め込み (例えば、384 数値のリスト) を作成して、センテンスがその画像を說明しているか決定するためにそれをテキスト埋め込みと比較することもできます。このコンセプトは画像検索, 分類, 說明等のためのパワフルなシステムのもとにあります。
埋め込みはどのように生成されるのでしょう?Sentence Transformers と呼ばれるオープンソース・ライブラリは画像とテキストから最先端の埋め込みを無料で作成することを可能にします。このブログはこのライブラリを使用した例を示します。
埋め込みは何のためにあるのでしょう?
“[…] この ML マルチツール (埋め込み) 理解すれば、検索エンジンからレコメンデーション・システム, チャットボットまで多くのこと、すべてを構築することができます。それらを使用するために ML の専門技術を持つデータサイエンティストである必要はありませんし、膨大なラベル付けされたデータセットも必要としません。” – Dale Markowitz, Google Cloud.
情報 (センテンス, 文書, 画像) のピースがひとたび埋め込まれたら、創造力 (creativity) が始まります ; 幾つかの興味深い産業的なアプリケーションは埋め込みを使用しています。E.g., Google 検索は テキスト-to-テキストとテキスト-to-画像のマッチング に埋め込みを使用しています ; Snapchat は “serve the right ad to the right user at the right time” のためにそれらを使用し、そして Meta (Facebook) は ソーシャル検索 にそれらを使用しています。
埋め込みから知性を得られる前に、これらの会社は情報のピースを埋め込む必要がありました。埋め込まれたデータセットはアルゴリズムが素早く検索し、ソートし、グループ化する等のことを可能にします。けれども、それは高価で技術的に複雑である可能性があります。この投稿では、データセットを埋め込み分析することがどれほど簡単にできるかを示すために単純なオープンソースのツールを使用します。
埋め込みを始める
小さい「よくある質問 (Frequently Asked Questions (FAQs))」エンジンを作成します : ユーザから質問を受け取りどの FAQ が最も類似しているかを識別します。US ソーシャル・セキュリティ・メディケア FAQ を使用します。
しかし最初に、データセットを埋め込む必要があります (他のテキストは用語エンコードと埋め込みを同じ意味で使用しています)。Hugging Face Inference API は素早い POST 呼び出しを使用してデータセットを簡単に埋め込むことを可能にしています。
埋め込みは質問の意味論的意味を捉えますので、異なる埋め込みを比較してそれらがどのくらい異なるか類似しているかを見ることができます。これのおかげで、ある質問に最も類似した埋め込みを取得することができます、これは最も類似した FAQ を見つけることに等しいです。このメカニズムがどのように動作するかの詳細な說明は私たちの セマンティック検索チュートリアル を確認してください。
簡単に言えば、以下を行ないます :
- 推論 API を使用してメディケアの FAQ を埋め込みます (埋め込みを作成します)。
- 埋め込まれた質問をハブにアップロードし、フリーでホスティングします。
- 顧客の質問を埋め込みデータセットと比較して、最も類似した FAQ を識別します。
1. データセットを埋め込む
最初のステップは埋め込みを作成するために既存の事前訓練済みモデルを選択することです。Sentence Transformers ライブラリ からモデルを選択することができます。このケースでは、”sentence-transformers/all-MiniLM-L6-v2” を使用しましょう、それは小さいですが強力なモデルであるからです。今後の記事では、他のモデルとそれらのトレードオフを調べる予定です。
ハブにログインします。貴方の アカウント設定 で書き込みトークンを作成する必要があります。書き込みトークンを hf_token にストアします。
model_id = "sentence-transformers/all-MiniLM-L6-v2"
hf_token = "get your token in http://hf.co/settings/tokens"
埋め込みを生成するために、ヘッダ {“Authorization”: f”Bearer {hf_token}”} と共に https://api-inference.huggingface.co/pipeline/feature-extraction/{model_id} エンドポイントを利用できます。
ここにテキストを伴う辞書を受け取り、埋め込みのリストを返す関数があります。
import requests
api_url = f"https://api-inference.huggingface.co/pipeline/feature-extraction/{model_id}"
headers = {"Authorization": f"Bearer {hf_token}"}
最初に埋め込みを生成するとき、API がそれらを返すのにしばらく (およそ 20 秒) かかるかもしれません。retry デコレータ (“pip install retry” にインストール) を使用し、その結果最初の試行で output = query(dict(inputs = texts)) が動作しない場合、10 秒間待って 3 回リトライします。これは、最初のリクエストで、モデルがダウンロードされてサーバ上でインストールされる必要があるためですが、続く呼び出しは遥かに高速になります。
def query(texts):
response = requests.post(api_url, headers=headers, json={"inputs": texts, "options":{"wait_for_model":True}})
return response.json()
現在の API は厳密なレート制限を強制していません。代わりに、Hugging Face はすべての利用可能なリソース間の負荷のバランスを均等に取り、リクエストの堅固なフローを優先します。幾つかのテキストや画像を埋め込む必要がある場合、Hugging Face Accelerated Inference API は推論を高速化して CPU か GPU 間の使用の間で貴方に選択させます。
texts = ["How do I get a replacement Medicare card?",
"What is the monthly premium for Medicare Part B?",
"How do I terminate my Medicare Part B (medical insurance)?",
"How do I sign up for Medicare?",
"Can I sign up for Medicare Part B if I am working and have health insurance through an employer?",
"How do I sign up for Medicare Part B if I already have Part A?",
"What are Medicare late enrollment penalties?",
"What is Medicare and who can get it?",
"How can I get help with my Medicare Part A and Part B premiums?",
"What are the different parts of Medicare?",
"Will my Medicare premiums be higher because of my higher income?",
"What is TRICARE ?",
"Should I sign up for Medicare Part B if I have Veterans' Benefits?"]
output = query(texts)
レスポンスとして、リストのリストを取得します。各リストは FAQ の埋め込みを含みます。モデル “sentence-transformers/all-MiniLM-L6-v2” は入力の質問を各々サイズ 384 の 13 個の埋め込みにエンコードしています。リストを shape (13×384) の Pandas DataFrame に変換しましょう。
import pandas as pd
embeddings = pd.DataFrame(output)
It looks similar to this matrix:
[[-0.02388945 0.05525852 -0.01165488 ... 0.00577787 0.03409787 -0.0068891 ] [-0.0126876 0.04687412 -0.01050217 ... -0.02310316 -0.00278466 0.01047371] [ 0.00049438 0.11941205 0.00522949 ... 0.01687654 -0.02386115 0.00526433] ... [-0.03900796 -0.01060951 -0.00738271 ... -0.08390449 0.03768405 0.00231361] [-0.09598278 -0.06301168 -0.11690582 ... 0.00549841 0.1528919 0.02472013] [-0.01162949 0.05961934 0.01650903 ... -0.02821241 -0.00116556 0.0010672 ]]
2. Hugging Face ハブ上で埋め込みを無料でホスティングする
🤗 Datasets はデータセットに素早くアクセスして共有するためのライブラリです。ユーザーインターフェース (UI) を使用してハブに埋め込みデータセットをホスティングしましょう。すると、誰でもコードの単一行でそれをロードできます。データセットを共有するために端末を使用することもできます ; 手順については ドキュメント をご覧ください。このエントリーの ノートブック・コンパニオン では、データセットを共有するために端末が使用できます。このセクションをスキップしたい場合には、埋め込まれた FAQ を持つ ITESM/embedded_faqs_medicare レポジトリ を確認してください。
最初に、Pandas DataFrame から CSV に埋め込みをエクスポートします。データセットは貴方が好むどのような方法でもセーブできます、e.g., zip or pickle ; Pandas or CSV を使用する必要はありません。私たちの埋め込みファイルは大きくありませんので、それを CSV にストアできます、これは次のセクション (Datasets ドキュメント 参照) で採用する datasets.load_dataset() 関数により容易に推論されます、i.e., ロード用スクリプトを作成する必要はありません。埋め込みを embeddings.csv という名前でセーブします。
embeddings.to_csv("embeddings.csv", index=False)
ハブで embeddings.csv をホストするためには次のステップに従ってください :
- Hub UI の右上隅のユーザをクリックします。
- “New dataset” でデータセットを作成します。
- データセットの所有者 (組織 or 個人), 名前とライセンスを選択します。それにプライベートかパブリックを望むかを選択します。データセットを作成します。
- “Files” タブに進んで (下のスクリーンショット) “Add file” と “Upload file” をクリックします。
- 最後に、データセットをドラッグかアップロードして、変更をコミットします。
今ではデータセットはハブに無料でホストされています。貴方は (or 貴方が埋め込みを共有したい人は誰でも) それらを素早くロードできます。Let’s see how.
3. 質問に対して最も類似した FAQ を取得する
メディケアの顧客が “How can Medicare help me?” と尋ねたと仮定します。どの FAQ がユーザの質問に最善に答えることができるかを見つけます。その意味論的意味を表現できる質問の埋め込みを作成します。それから、ベクトル空間內でどれが質問に最も近いかを特定するためにそれを FAQ データセットの各埋め込みと比較します。
🤗 Datasets ライブラリを “pip install datasets” でインストールします。それから、ハブから埋め込まれたデータセットをロードしてそれを PyTorch FloatTensor に変換します。これがデータセット上で演算する唯一の方法ではないことに注意してください ; 例えば、NumPy, Tensorflow, or SciPy を使用できるでしょう (ドキュメント 参照)。実データセットで実践したい場合、ITESM/embedded_faqs_medicare レポジトリが埋め込まれた FAQ を含みます、またはこのブログの コンパニオン・ノートブック を使用することもできます。
import torch
from datasets import load_dataset
faqs_embeddings = load_dataset('namespace/repo_name')
dataset_embeddings = torch.from_numpy(faqs_embeddings["train"].to_pandas().to_numpy()).to(torch.float)
前に定義した query 関数を使用して顧客の質問を埋め込み、そしてそれで効率的に演算するために PyTorch FloatTensor に変換します。埋め込まれたデータセットがロードされた後、Dataset の add_faiss_index と search メソッドを使用して、埋め込まれた質問に最も近い FAQ を faiss ライブラリ を使用して特定できることに注意してください。ここに 別の方法の良いチュートリアル があります。
question = ["How can Medicare help me?"]
output = query(question)
query_embeddings = torch.FloatTensor(output)
Sentence Transformers ライブラリの util.semantic_search 関数を使用してどの FAQ がユーザの質問に最も近いか (最も類似しているか) 特定することができます。この関数は、埋め込みの近さ (proximity) を決定するためにデフォルト関数としてコサイン類似度を使用しています。けれども、ベクトル空間の 2 つのポイント間の距離を測る他の関数もまた利用できるでしょう、例えば、ドット積です。
sentence-transformers を “pip install -U sentence-transformers” でインストールして、質問に対して 5 つの最も類似した FAQ を探し求めます。
from sentence_transformers.util import semantic_search
hits = semantic_search(query_embeddings, dataset_embeddings, top_k=5)
util.semantic_search は 13 FAQ の各々が顧客の質問にどれくらい近いかを識別して上位の top_k FAQ を含む辞書のリストを返します。hits はこのようなものです :
[{'corpus_id': 8, 'score': 0.75653076171875}, {'corpus_id': 7, 'score': 0.7418993711471558}, {'corpus_id': 3, 'score': 0.7252674102783203}, {'corpus_id': 9, 'score': 0.6735571622848511}, {'corpus_id': 10, 'score': 0.6505177617073059}]
corpus_id の値は最初のセクションで定義したテキストのリストにインデックスして、5 つの最も類似した FAQ を取得することを可能にします。
print([texts[hits[0][i]['corpus_id']] for i in range(len(hits[0]))])
ここに、顧客の質問に最も近い 5 つの FAQ があります :
['How can I get help with my Medicare Part A and Part B premiums?', 'What is Medicare and who can get it?', 'How do I sign up for Medicare?', 'What are the different parts of Medicare?', 'Will my Medicare premiums be higher because of my higher income?']
このリストは顧客の質問に最も近い 5 つの FAQ を表しています。Nice! 主要な数値ツールとしてここでは PyTorch と Sentence Transformers を使用しました。けれども、NumPy と SciPy のようなツールを私たち自身で使用して、コサイン類似度とランキング関数を定義することもできたでしょう。
学習し続けるための追加リソース
Sentence Transformers ライブラリについて更に知りたい場合 :
- すべての新しいモデルとモデルをダウンロードする手順に対する ハブ Organization。
- Nils Reimers は Sentence Transformer モデルを GPT-3 埋め込みと比較したツイートをしています。ネタバレ注意 : the Sentence Transformers are awesome!
- Sentence Transformers ドキュメント,
- Nima の最近の研究についてのスレッド
Thanks for reading!
以上