OpenAI互換APIも使えるllama-cpp-python

OpenAIのAPIは有料なので気軽に使うにはちょっと厳しいので、気軽に使う方法がないかなと言うときに良さそうなのが、llama-cpp-pythonというのがあります。Llama2とか、いい感じのものも増えてきていますし、これと合わせて使うと、気軽に試したりすることができます。

llama.cppで、量子化してたりして、利用する環境に合わせたサイズのモデルを事前に準備しておくと良いです。事前に準備しておいたら、llama-cpp-pythonは

pip install llama-cpp-python

でインストールすることができます。GPU環境とかであれば、ドキュメントを参考にして、cuBlasなどを有効にして、インストールしてください。

あとは、

python3 -m llama_cpp.server --model models/7B/ggml-model.bin

みたいな感じで、モデルを指定すれば起動できます。–portとか、オプションもいろいろとあるので、指定すれば、一部の層をGPUに置いたりとか、できたりで便利です。

OpenAIのライブラリ経由とかで使う場合は、OPENAI_API_BASE環境変数とかで、http://localhost:8000/v1とか指定すれば、差し替えて使えることもできると思います。

補足:llama.cppにもserverコマンドでAPI化できるのですが、これはllama-cpp-pythonほど、実装されていなかったので、まだ使えなかった…。

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のライブラリなのだが、このライブラリがハイバーパラメーター、辞書、ウェイトを保持していて、量子化もできる、という感じみたい。