llama.cppを試す

llama.cppはLlamaモデルの推論を実行するC/C++の実装です。量子化もできたり、簡単に動かして試すときに便利なツールだと思います。

実際にllama.cppを用いてなんか作るようなときは、Pythonバインディングなどを使って、作ったりするほうが良いと思いますが、今回はllama.cppをビルドして試す方法を書いておきます。

まず、git cloneします。今回利用している環境はUbuntu 22.04を使っています。makeとかが実行できるように開発に必要なツールは事前にインストールある想定です。

git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp

あとは、

make

を実行すれば、mainコマンドなどが生成されます。libllama.soを作成したいときには、

 make libllama.so 

を実行すれば生成できます。libllama.soはPythonバインディングとかで差し替えて使いたいときとかにあると便利かもしれません。

MKLやBLASなど用にビルドしたいときには、makeのときに環境変数で指定してあげれば、良いです。

次に、Llama 2をMetaのサイト経由で入手すると、pthのファイルですが、これをggmlなファイルに変換します。llama.cppに必要なコマンドが用意されているのでそれを利用します。以下のような感じで、ダウンロードしたtokenizerやpthファイルをmodelsディレクトリに置いて、convert.pyを実行します。

$ ls models                                                                                                                                    ggml-vocab.bin  llama-2-7b-chat  tokenizer.model  tokenizer_checklist.chk
$ ls models/llama-2-7b-chat/                                                                                                                   checklist.chk  consolidated.00.pth  params.json

という感じで、

python convert.py models/llama-2-7b-chat/

で変換処理を実行すると、models/llama-2-7b-chat/ggml-model-f32.bin が生成されます。

量子化するコマンドも提供されています。ggmlのファイルができたら、quantizeコマンドを実行すれば、量子化してサイズを減らすこともできます。オプションについては、–helpで確認できます。

./quantize models/llama-2-7b-chat/ggml-model-f32.bin models/llama-2-7b-chat/ggml-model-f32-q4km.bin Q4_K_M 

を実行するだけで、変換処理が実行できます。

あとは、

./main -m ./models/llama-2-7b-chat/ggml-model-f32-q4km.bin -n 128

という感じで実行すれば、動作確認することができます。

実際に利用するときには、llama-cpp-pythonなどのバインディング経由で、生成したbinファイルを指定して利用すると良いと思います。

GGMLって?

LLM関連の話題は新しいものが次々出てくるので、キャッチアップしていくのも大変なのだが、llama.cppを試していて、GGMLを使っているけど、これってなんだろう、みたいな…。

GGML自体は機械学習向けCライブラリという感じ。とはいえ、llama.cppとか見ていると、モデルのファイル名に書いていたりもするから、ファイルフォーマット的な雰囲気も感じる。もう少し直感的にわかりやすい説明がないかなと思っていたら、わかりやすい感じでまとめてあった。ChatGPTにまとめてもらうと、

GGMLは、大規模な言語モデルを扱うためのCライブラリで、その名前は開発者Georgi Gerganovのイニシャルから取られています。このライブラリは、低レベルの機械学習プリミティブ(テンソル型など)を定義するとともに、大規模言語モデル(LLM)を配布するためのバイナリ形式も定義しています。このバイナリ形式は、消費者ハードウェア上で大規模言語モデルを実行可能にする「量子化」という技術を利用しています。

GGMLファイルは、指定された形式に従ってレイアウトされたバイナリエンコードデータで構成されています。この形式は、ファイル内に存在するデータの種類、その表現方法、およびその出現順序を指定します。有効なGGMLファイルには最初にGGMLのバージョン番号が存在し、その後に大規模言語モデルを定義する三つのコンポーネント、すなわちモデルのハイパーパラメータ、語彙、および重みが続きます。

GGMLは最先端の技術であり、頻繁に変更が行われます。後方互換性を犠牲にすることなく迅速な開発を支援するため、GGMLはエンコーディングの形式を変更する可能性のある改善を導入するためにバージョニングを使用します。

ハイパーパラメータは、大規模言語モデルの振る舞いを設定するために使用される値を指します。これは、モデルを作成するために使用された訓練プロセスで導出された重みであるモデルのパラメータとは対照的です。各モデルは、そのモデルが受け入れるハイパーパラメータ値を定義する独自のハイパーパラメータ構造を定義します。

モデルの語彙は、モデルが言語(テキスト)を生成するために使用するコンポーネントを含みます。しかし、人間の語彙が単語で構成されているのとは異なり、大規模言語モデルの語彙は「トークン」で構成されています。トークンは一つの単語全体であることもありますが、多くの場合、それらは単語の断片です。

最後に、GGMLファイルの最大のコンポーネントは、ファイルが表現するLLMの重みです。大規模言語モデルは、言語を生成するために使用されるソフトウェアであり、画像を生成するために使用されるソフトウェアがレンダリングできる色の数を増やすことで改善できるのと同様に、大規模言語モデルはモデル内の重みの数を増やすことで改善できます。

量子化とは、モデルを使用するために必要なリソースを減らすために、重みが表現される精度を減らすプロセスを指します。GGMLは、効率とパフォーマンスの間のトレードオフを提供するいくつかの異なる量子化戦略(例えば、4ビット、5ビット、8ビットの量子化)をサポートしています。

GGML – Large Language Models for Everyone の要約

という感じで、GGは人の名前で、Cのライブラリなのだが、このライブラリがハイバーパラメーター、辞書、ウェイトを保持していて、量子化もできる、という感じみたい。

Fessでセマンティックサーチ

Fess 14.9.1にfess-webapp-semantic-searchプラグインを入れることで、通常のキーワードベースの検索に加えて、ベクトルで検索した結果をマージして利用することができます。以前のプラグインでは、上位X件しか、ベクトル検索の結果を表示できなかったのですが、Fess 14.9.1以降ではReciprocal Rank Fusion(RRF)によって、ベクトル検索の結果をマージすることができるので、キーワード検索の結果でページングすることができ、通常の検索システムとしても利用できます。

利用方法は、fess-webapp-semantic-searchのREADME.mdに書いてあるとおりですが、Dockerであれば、簡単に試すことができると思います。まず、docker-fessをcloneして取得します。

git clone --branch v14.9.1 --single-branch https://github.com/codelibs/docker-fess.git
cd docker-fess/compose

compose.yamlを編集して、プラグインがインストールされるようにします。以下のように環境変数に設定されるようにします。

      - "FESS_PLUGINS=fess-webapp-semantic-search:14.9.0"

Fessを起動します。

docker compose -f compose.yaml -f compose-opensearch2.yaml up -d

OpenSearchにモデルをロードさせるために以下のスクリプトを取得してセットアップします。一応、多言語対応のモデルを利用して、ベクトルを生成していますが、必要に応じて、モデルを変更するなどしてください。

curl -o setup.sh https://github.com/codelibs/fess-webapp-semantic-search/blob/fess-webapp-semantic-search-14.9.0/tools/setup.sh
/bin/bash setup.sh

setup.shを実行すると、fess.semantic_search.〜が表示されるので、これは、Fessにログインして、全般のシステムプロパティの入力欄にコピペしてください。

あとは、管理画面のメンテンナンスページにいき、再インデクシングを実行してください。この状態では、何もインデクシングされていないと思いますが、再インデクシングすると、ベクトル検索が可能なインデックスに更新する処理が走ります。

あとは、普通にクロールして、検索するだけです。何かあれば、フォーラムとかで気軽に聞いてください。