Facebook AI類似検索(FAISS)の設定

技術ファンの皆さん、こんにちは!今日は、人工知能界を騒がせているツールを探る旅に出ます:フェイスブックのAI 類似検索(FAISS)だ。Spotifyがどうやって自分のお気に入りと不気味なほど似ている曲を見つけるのか、あるいはGoogleフォトがどうやって同じ人物の写真をグループ分けするのか、不思議に思ったことがあるとしよう。その場合、あなたはその謎を解き明かそうとしている。
類似検索、または最近傍検索は、多くのAIや機械学習アプリケーションの重要な側面である。これは、与えられたクエリーポイントに最も類似したデータポイントを見つけることである。例えば、Spotifyで曲を検索する場合、システムは検索クエリに最も「似ている」曲を見つける必要がある。
この効率的な類似性検索が印象的なように聞こえるが、キャッチがある。従来の類似性検索方法は、大量のデータを扱うと恐ろしく時間がかかる。そこでFAISSが登場し、従来のクエリー検索エンジンの限界を解決します。これはFacebook AIが開発した効率的な類似検索のためのライブラリで、特に大規模なデータを扱う場合に、類似検索の問題に信頼性の高いソリューションを提供する。
しかし、世間話はもう十分だ!このブログポストでは、FAISSのセットアップ、起動、そしてサンプルの類似検索プログラムによるそのパワーのデモンストレーションをご案内します。シートベルトを締めて、FAISSを使った効率的な類似検索の魅力的な世界に深く飛び込んでいきましょう。お楽しみに!
FAISS(フェイスブックAI類似検索)を理解する
さて、簡単な紹介で食欲をそそったところで、FAISSについて深く掘り下げていきましょう。FAISS(Facebook AI Similarity Search)とは、ベクトル類似度検索(https://zilliz.com/blog/similarity-metrics-for-vector-search)と密なベクトルのクラスタリングのためのアルゴリズムのライブラリである。フェイスブックのAIチームが考案したもので、大規模なデータベースを効率的に処理できるように設計されている。
FAISSは主に "ベクトルの類似性 "という概念で機能する。平たく言えば、ベクトルとは基本的に数字のリストであり、類似性とは2つのベクトルがどれだけ似ているかということだ。今お気に入りの曲の雰囲気に合う曲を探そうとしているとしよう。ベクトルは両方の曲を表すことができ、似たベクトルの異なる要素は異なる曲の特徴を表す。高次元空間におけるベクトルの距離を比較することで、これらの曲の「類似性」を比較することができます。ユークリッド距離は、このベクトル間の類似性を測定する上で重要な役割を果たします。
ここでFAISSが威力を発揮する。FAISSは、数百万、あるいは数十億のこれらのベクトルを素早く正確に比較する方法を提供する。それはまるで、膨大な音楽ライブラリを瞬きする間にスキャンし、お気に入りの曲に最も似ている曲をピンポイントで見つけることができる、超強力な検索エンジンを手に入れたようなものだ。インデックス化されたベクトルは、システムが与えられたクエリ・ベクトルに最も近いものを効率的に検索できるようにするため、このプロセスには不可欠である。
しかし、FAISSの魔法は音楽推薦だけにとどまらない。画像認識やテキスト検索からクラスタリングやデータ分析まで、多くのアプリケーションでFAISSが使われている。大量のデータがあり、似たようなアイテムを素早く見つける必要があるとき、FAISSはいつでもあなたの頼れるツールとなるでしょう。
FAISS のセットアップ
このセクションでは、FAISSをLinuxシステムにセットアップする方法を説明します。
Conda のインストール
FAISSをインストールする前に、システムにCondaをインストールしておく必要があります。Conda は Windows、macOS、Linux 上で動作するオープンソースのパッケージおよび環境管理システムです。
以下の手順に従って、LinuxシステムにCondaをインストールしてください:
公式ウェブサイト](https://docs.conda.io/projects/conda/en/latest/user-guide/install/linux.html)からLinux用のMinicondaインストーラーをダウンロードする。
インストーラーのハッシュを確認する。
ターミナルウィンドウを開き、以下のコマンドを実行してインストールを開始する:
bash Miniconda3-latest-Linux-x86_64.sh
インストーラーが起動すると、いくつかの質問をします。わからないことがあれば、デフォルトのオプションのままにしておいてください。後でいつでも変更できます。
インストールが終わったら、ターミナル・ウィンドウを閉じて、もう一度開いてください。こうすることで、変更した内容が確実に有効になります。
ここで、すべてが正しくインストールされているかどうかをチェックしたくなるでしょう。これを行うには、ターミナルウィンドウか Anaconda Prompt に conda list と入力して Enter キーを押します。全てが正しく動作していれば、インストールされたパッケージのリストが表示されます。
FAISS のインストール
Conda経由でFAISSをインストールできます。FAISSパッケージには2つのバージョンがあります: CPUのみのバージョン(faiss-cpu)とCPUとGPU両方のインデックスを含むバージョン(faiss-gpu)です。必要に応じて、これらのバージョンのどちらかをインストールしてください。
FAISSをインストールする推奨の方法は、PyTorchのCondaチャンネルからインストールすることです。以下はFAISSの最新の安定版をインストールするためのコマンドです。
CPU版
conda install -c pytorch faiss-cpu
GPU版の場合:
conda install -c pytorch faiss-gpu
さらに、FAISSはconda-forgeによってパッケージ化されています。conda-forgeはCondaのためのコミュニティ主導のパッケージングエコシステムです。conda-forgeからFAISSをインストールするには以下のコマンドを使います。CPUのみのバージョンの場合
conda install -c conda-forge faiss-cpu
GPUバージョンの場合:
conda install -c conda-forge faiss-gpu
SQuAD を使ったサンプルコードのウォークスルー
Conda listコマンドを使うことで、Condaパッケージがどのチャンネルから来たかを確認できます。
今回はStanford Question Answering Dataset (SQuAD)を使ってみましょう。SQuADは自然言語処理(NLP)でよく使われるデータセットで、FAISSがどのように動作するかを説明するのに適しています。このデータセットには質問と答えのペアが含まれており、各質問に対する答えは、対応するリーディングパッセージのテキストセグメント、つまり「スパン」である。検索プロセスでは、クエリーベクターが使用され、データセットと比較することで、最も関連性の高い答えを見つけることができる。
コードに入る前に、まずSQuADデータセットをダウンロードして準備しましょう:
SQuADデータセットをダウンロードする:SQuADデータセットのダウンロード:SQuADウェブサイトからデータセットをダウンロードできる。簡単のため、ここでは SQuAD 1.1 を使用する。データセットは次のリンクからダウンロードできる:SQuAD 1.1 Train.JSONファイル(train-v1.1.json)をダウンロードし、作業ディレクトリに保存します。
JSONファイルを読み込みます:これで、Python JSONライブラリを使用してデータをロードすることができます:
with open('train-v1.1.json', 'r') as file: squad_data = json.load(ファイル)
数値ベクトルは、効率的な距離測定とIndexFlatL2内でのクエリを可能にするため、FAISSインデックスには不可欠です。
必要なライブラリのインポート
最初のステップは、必要なライブラリをインポートすることです。数値演算にはnumpy、ベクトルの類似性検索にはFaiss、データセットの読み込みにはJSON、テキストのトークン化にはnltkが必要です。
npとしてnumpyをインポートする。
インポート faiss
import json
from nltk.tokenize import word_tokenize
データの読み込みと前処理
SQuADデータセットをロードしてみよう。JSONファイルなので、JSONモジュールのload関数が使える。
with open('train-v1.1.json', 'r') as file:
squad_data = json.load(ファイル)
JSONオブジェクトは、データキーと辞書のリストを含む辞書であると仮定します。リスト内の各ディクショナリは、段落のリストを持つ段落キーを含む記事を表しています。
では、データを前処理しましょう。nltkのword_tokenize関数を使用して各段落をトークン化します。そして、各単語をワンホットエンコーディングされたベクトルとして表現します。
vocabulary = set(word for article in squad_data['data'] for paragraph in article['paragraphs'] for word_tokenize(paragraph['context']))
word_to_index = {word: index for index, word in enumerate(vocabulary)}.
def convert_text_to_vector(text):
words = word_tokenize(text)
bow_vector = np.zeros(len(vocabulary))
for word in words:
word_to_index 内の word:
bow_vector[word_to_index[word]] = 1
return bow_vector
paragraph_vectors = [convert_text_to_vector(paragraph['context']) for article in squad_data['data'] for paragraph in article['paragraphs']].
インデックスの構築
データが正しいフォーマットになったので、FAISSインデックスを作成します。ここでは、基本的なL2距離インデックスであるIndexFlatL2インデックスタイプを使用します。
dimension = len(vocabulary)
index = faiss.IndexFlatL2(dimension)
# NumPy配列のリストを1つの2次元配列に変換する
paragraph_vectors = np.stack(paragraph_vectors).astype('float32')
index.add(paragraph_vectors)
IndexFlatL2 型では、データの次元を指定する必要があります。各ベクトルはワンホットエンコーディングされているので、次元は語彙のサイズになります。
次に、2次元のNumPy配列を必要とするaddメソッドを使ってインデックスにデータを追加します。
FAISSベクトル探索の実行
インデックスがすべてセットアップされたので、次は探偵ごっこをして、データセットから検索クエリに最も近い段落を探します。
これが検索関数です:
def search_for_paragraphs(search_term, num_results):
search_vector = convert_text_to_vector(search_term)
search_vector = np.array([search_vector]).astype('float32')
距離、インデックス = index.search(search_vector, num_results)
for i, (distance, index) in enumerate(zip(distances[0], indexes[0]):
print(f "Result {i+1}, Distance: {distance}")
print(squad_data['data'][index]['paragraphs'][0]['context'])
print()
検索語は "What is the capital of France? "で、5つの結果を見つけたい:
search_term = "フランスの首都は?"
search_for_paragraphs(search_term, 5)
search_for_paragraphs()は、まず検索語を符号化されたベクトルに変換します。そして、このベクトル表現をインデックスの検索メソッドとして使用します。これには2次元配列が必要なので、検索ベクトルに次元を追加します。
また、類似検索メソッドでは、いくつの検索結果が欲しいかを指定する必要がある(これがnum_resultsの目的だ)。1つは最も近い結果の距離、もう1つはそのインデックスです。これらのインデックスを使って、データセット内の実際の段落を見つけることができる。そして、各結果の順位、類似距離、段落テキストを出力します。
これで完成だ!これがFAISSを使って類似テキストデータを見つける基本的な例です。もちろん、FAISSは高次元ベクトル空間での検索など、もっと複雑なことができる。しかし、この例はFAISSを使うための良い出発点になるはずです。
ベストプラクティスとヒント
データを手に入れましたか?データを知りましょう:データを知る: FAISSを使う前に、自分のデータについてよく知りましょう。以下のような質問をしてみましょう:それは高い数字で埋め尽くされているか?データは多くの数字で埋め尽くされているか、隙間だらけか、情報がぎっしり詰まっているか?自分のデータを知ることで、FAISSインデックスの正しいタイプを選び、データを準備する最善の方法を判断することができます。
前処理が鍵:データをどのように前処理するかは、FAISSの効果に大きく影響します。テキストデータの場合、単なるワンホットエンコーディングではなく、TF-IDFやWord2Vecのような、単語を数値に変換するスマートな方法を使うことを考える。写真の場合は、畳み込みニューラルネットワーク(CNN)からの特徴を使ってみよう。
最適なインデックスを選ぶFAISSには様々なタイプのインデックスがあり、それぞれが特別な強みを持っています。次元の多いデータを扱うのに最適なもの、バイナリベクトルに最適なもの、大きなビッグデータを扱うためのものなどがあります。あなたのニーズに最適なものをお選びください。
クエリーをバッチ化する:インデックスに対して実行するクエリが多すぎる場合は、バッチ処理をして一度に実行する方が効率的です。FAISSはバッチ処理に最適化されています。
パラメーターの調整FAISSには、インデックス作成段階でのクラスタ数や、ベクトル類似性検索段階でのプローブ数など、調整可能なパラメータがいくつかあります。デフォルトの設定にこだわらず、様々な設定を試して、あなたのデータに最適なものを見つけてください。
ベクターデータベース vs FAISS
FAISSはANN検索のための素晴らしいソリューションです。さらにFAISSは、類似性検索や密なベクトルのクラスタリングに関する評価やパラメータチューニングのための追加機能を提供するサポートコードを提供しています。しかし、何千万ものベクトルを保存・検索し、同時にリアルタイム応答や高度なクエリ・ベクトル関連機能を必要とする場合には、いくつかの制限があります。
FAISSと比較すると、MilvusやZilliz Cloudのような専用に構築されたベクトルデータベースは、上記の課題に対処でき、より高度な機能を備えています:
CRUDサポート、データ一貫性、フィルター検索などの基本機能
強力なデータ永続性と優れたディザスタリカバリによるシステムの可用性
ロードバランシングのサポート、コンピューティングとストレージを分離した分散アーキテクチャー、より良いユーザビリティによるシステムのスケーラビリティ
マルチテナントをサポートするRBAC、様々なプログラミング言語のSDK、restful API、監視システム。
Milvusは、億規模の類似検索とAIアプリケーションのための世界初で最も人気のあるオープンソース・ベクターデータベースです。Milvusは、ディープニューラルネットワークやその他の機械学習(ML)モデルによって生成された10億以上のベクトルの埋め込みを保存、インデックス付け、管理することができます。ベクトルデータベース](https://zilliz.com/learn/what-is-vector-database)をあらゆる開発者や組織が利用できるようにするため、Zillizはインキュベーション段階のプロジェクトとしてMilvusをLF AI & Data Foundationに寄付し、2021年6月に卒業した。
Milvus Liteは、Pythonアプリケーション内でローカルに動作するMilvusの軽量版です。オープンソースで人気の高いMilvusベクトルデータベースをベースにしたMilvus Liteは、ベクトルインデックス作成とクエリ解析のコアコンポーネントを再利用する一方で、分散システムにおける高いスケーラビリティのために設計された要素を削除しています。この設計により、ラップトップ、Jupyter Notebooks、モバイルデバイスやエッジデバイスなど、コンピューティングリソースが限られている環境に理想的なコンパクトで効率的なソリューションを実現します。
Zilliz Cloudは、Milvus上に構築されたフルマネージドベクトルデータベースサービスです。Zilliz Cloudを使えば、ベクトル検索は10倍速くなり、ベクトル検索アプリケーションのデプロイとスケーリングはかつてないほど簡単になります。Zilliz Cloudには無料ティアもあり、すべての開発者は金銭的な負担をすることなく、この最先端技術にアクセスすることができます。
結論
以上です!我々は、Facebook AI類似検索(FAISS)のエキサイティングな世界を横断してきた。FAISSとは何か、どのように機能するのかを理解し、システムにセットアップするところから、SQuADデータセットを使ったサンプルコードや、専用のベクターデータベースとの違いまで、多くの分野をカバーしてきました。
FAISSは、膨大な量のデータを効率的に検索できるように設計された、非常に強力なツールであることを忘れないでください。さまざまなデータタイプやサイズに対応できる汎用性は、その設計の証です。
このような知識を身につけながら、ベストプラクティスとヒントを思い出してください。データを理解し、適切なインデックスを選択し、データを効果的に前処理し、クエリをバッチ処理し、パラメータをチューニングする。
しかし、ここで立ち止まってはいけない。探求、実験、学習を続けてください。FAISSが提供する様々なインデックスタイプを深く掘り下げたり、より複雑なデータ前処理テクニックを探求したり、より洗練されたユースケースを試してみたりと、学ぶべきことは常にあります。
この投稿は、非常に熟練した熱心なセキュリティ・エンジニアであるKeshav Malikによって書かれました。Keshavは、自動化、ハッキング、さまざまなツールやテクノロジーの探求に情熱を注いでいる。複雑な問題に対する革新的な解決策を見つけることが大好きで、プロフェッショナルとして成長し向上するための新しい機会を常に求めている。常に時代の最先端を行くことに専心し、最新かつ最高のツールやテクノロジーを求めている。
読み続けて

8 Latest RAG Advancements Every Developer Should Know
Explore eight advanced RAG variants that can solve real problems you might be facing: slow retrieval, poor context understanding, multimodal data handling, and resource optimization.

How to Build RAG with Milvus, QwQ-32B and Ollama
Hands-on tutorial on how to create a streamlined, powerful RAG pipeline that balances efficiency, accuracy, and scalability using the QwQ-32B model and Milvus.

Building Secure RAG Workflows with Chunk-Level Data Partitioning
Rob Quiros shared how integrating permissions and authorization into partitions can secure data at the chunk level, addressing privacy concerns.