LM Studioに独自モデルを追加したいなぁ
と思って、調べていくと、llama.cppのconver.pyがいるよ、という話になった。
- 動機の整理
-
huggingfaceに公開されているモデルをベースにquantize、pruningをやってみようと思った
guiがほしかったので、LM Studioを導入してみた。
Huggingfaceにはあるが、LM Studioにはない(希望の変換を含む)モデルがあるみたい
LM Studioにあるモデルであっても、自分の環境に合う、最大サイズにしてみたい
llama.cppインストール
教科書通り、git cloneして、cmakeして、make installでした。
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
cmake -B build # optionally, add -DGGML_CUDA=ON to activate CUDA
cmake --build build --config Release
cd build
sudo make install
cd ..
明確に書かれていないですが、他の記事から、requirements.txtのインストールをしておいたほうが良さそう
pip install -r requirements.txt
これで、インストールが完了。と思っていました。
ggufのエラー
いざ実行。最初の一歩は、"-h"オプションで、ヘルプを出すところから挑戦。(FYI) pythonって、ヘルプを出すだけでも、いろいろimportの読み込みが走るので、足りないモジュールを洗い出すのによくやります。
$ convert_hf_to_gguf.py -h
Traceback (most recent call last):
File "/usr/local/bin/./convert_hf_to_gguf.py", line 32, in <module>
from gguf.vocab import MistralVocab
ImportError: cannot import name 'MistralVocab' from 'gguf.vocab' (/home/ubuntu/venv/llm/lib/python3.10/site-packages/gguf/vocab.py)
で、このエラー。ggufは、requirementsにもはいっているので、???状態
$ grep -rIni gguf
requirements-convert_legacy_llama.txt:4:gguf>=0.1.0
requirements-gguf_editor_gui.txt:3:gguf>=0.17.0
(snip)
$ pip list
Package Version Editable project location
------------------------- ----------- -------------------------------------------
(snip)
gguf 0.17.1
(snip)
0.17.0以上だぞ、となっていて、インストールしたのは、0.17.1。
このあと、ggufのバージョンを、0.17.0や0.16.3、0.14.0にしてみたが、状況変わらず。(当たり前といえば当たり前)
改修&解決
改めて、llama.cppをcloneしたフォルダを見ると、gguf-pyという謎のディレクトリを発見。ひょっとして、これを使え、ということか。だま(されたと思)って、インストール。
$ pip install -e gguf-py
Obtaining file:///home/ubuntu/xxx/llama.cpp/gguf-py
(snip)
Successfully built gguf
Installing collected packages: gguf
$ pip list
Package Version Editable project location
------------------------- ----------- -------------------------------------------
(snip)
gguf 0.17.1 /home/ubuntu/xxx/llama.cpp/gguf-py
(snip)
で、再度トライ
$ convert_hf_to_gguf.py
usage: convert_hf_to_gguf.py [-h] [--vocab-only] [--outfile OUTFILE]
[--outtype {f32,f16,bf16,q8_0,tq1_0,tq2_0,auto}] [--bigendian]
[--use-temp-file] [--no-lazy] [--model-name MODEL_NAME] [--verbose]
[--split-max-tensors SPLIT_MAX_TENSORS]
[--split-max-size SPLIT_MAX_SIZE] [--dry-run]
[--no-tensor-first-split] [--metadata METADATA]
[--print-supported-models] [--remote] [--mmproj] [--mistral-format]
[model]
convert_hf_to_gguf.py: error: the following arguments are required: model
おー、動きました。
モデルの変換は、これからです。今回は、この問題と格闘したため、時間切れです。
そうそう、tag:b6178を使ったのですが、covert.pyはなくなったそうです。convert_hf_to_gguf.pyが後継だそうです。
まとめ
ggufのエラーが出たら、一緒に配布されているgguf-pyを使え
です。
おまけ
How-Toなので、情報はないです。備忘録に近い記録です。
ggufへのコンバートから、実行までのTIPS
ggufへのコンバート
convert_hf_to_gguf.pyを利用して、ggufへ変換します。
まず、使うモデルをダウンロード
$ hf download --token $HF_TOKEN path/model
$ convert_hf_to_gguf.py --outfile (output_file_name) --outtype (type) path/to/model
- output_file_name
- 出力ファイル名。output.gguf
- outtype
- 出力モデルの量子化具合(f32, f16, fb16など)を指定。元モデルのconfig.jsonにtorch_dtypeとして書かれているので、参考にするのがいい。当たり前だけど、元モデルよりも大きくなる値を入れても、無駄。出力ファイルがでかくなるだけで、いいことはない。
- path/to/model hf download でダウンロード先に指定した場所を指す。ただし、snapshotsの下にあるディレクトリまで指定する必要あり。
お試し実行
$ llama-cli -m ./output.gguf -ngl 15 -p "こんにちは"
$ llama-cli -m ./output.gguf -ngl 15 -sys "あなたは日本語話者です"
$ llama-simple-chat -m ./output.gguf -ngl 15
system promptに英語が埋め込まれている場合は、日本語で上書きしてあげないと、英語を喋ってくれる。
LLM-jpの変換
tokenizer.modelがない、って怒られるので、別ファイルをダウンロードして、tokenizer.modelとして展開しておく必要があるみたい。
wget https://github.com/llm-jp/llm-jp-tokenizer/archive/refs/tags/v3.0b2.zip
unzip v3.0b2.zip
ln -s /home/ubuntu/huggingface/cache/tokenizer/llm-jp-tokenizer-3.0b2/models/ver3.0/llm-jp-tokenizer-100k.ver3.0b1.model tokenizer.model
モデルをコンバートする。
(おまけ) このとき、chat_templeteの動作があって、llm-jpでは、「以下は、タスクを説明する指示です。要求を適切に満たす応答を書きなさい。」ってなっているみたい。
convert_hf_to_gguf.py --jinja --outfile llm-jp-3.1-13b-instruct4.gguf --outtype bf16 /home/ubuntu/huggingface/cache/hub/models--llm-jp--llm-jp-3.1-13b-instruct4/snapshots/da86a55d7a754d1a45bc2d860f8548841a84f42f/
(snip)
INFO:gguf.vocab:Setting chat_template to {{bos_token}}{% for message in messages %}{% if message['role'] == 'user' %}{{ '\n\n### 指示:\n' + message['content'] }}{% elif message['role'] == 'system' %}{{ '以下は、タスクを説明する指示です。要求を適切に満たす応答を書きなさい。' }}{% elif message['role'] == 'assistant' %}{{ '\n\n### 応答:\n' + message['content'] + eos_token }}{% endif %}{% if loop.last and add_generation_prompt %}{{ '\n\n### 応答:\n' }}{% endif %}{% endfor %}
(snip)
で、最後に実行結果をコピペ
$ llama-cli -m ./llm-jp-3.1-13b-instruct4.gguf -ngl 8 --jinja -sys "あなたは日本語話者です"
(snip)
### 指示:
あなたは日本語話者です
> 日本で、警察に連絡する際、どこに電話すればいいの?
日本で警察に連絡したい場合、最寄りの警察署に直接電話をかけるか、110番に電話をかけます。110番は緊急通報用電話番号であり、24時間対応しています。オペレーターが状況を聞き取り、適切な対応を指示してくれます。また、最近ではスマートフォンから直接警察に通報できるアプリも提供されている場合がありますので、地域の警察署や公式ウェブサイトなどで最新の情報を確認することをお勧めします。
serverモードの起動パラメータは、cliとほとんど同じ
$ llama-server --jinja -ngl 8 -m ./llm-jp-3.1-13b-instruct4.gguf
$ curl --request POST --url http://localhost:8080/v1/completions --header "Content-Type: application/json" --data '{"model": "qiita.com","prompt": "暑い夏のお昼といえば、なに?おすすめを教えて","Builn_predict": 128}'
{"choices":[{"text":"!\n暑い季節におすすめの昼ごはん、何が良いでしょうか?さっぱりして食べやすいものが良いです。\n暑い季節にさっぱり食べられる昼ごはん、おすすめは何でしょう?例えば、冷やし麺や冷製パスタなど、冷たくて美味しいメニューが良いです。\n暑い季節にさっぱり食べられる昼ごはんとして、冷やし中華や冷製スープなどはいかがでしょうか。また、寿司や刺身などの魚介類を使ったメニューも、冷たくて食べやすく、おすすめです。\n暑い季節にさっぱり食べられる昼ごはんとして、冷製パスタやソーメンチャンプルーなども良いでしょう。特にソーメンチャンプルーは、ソーメンを茹でてシンプルに炒め、お好みの野菜や肉と合わせるだけで、冷たくてヘルシーな一品になります。\n暑い季節にさっぱり食べられる昼ごはんとして、冷製スープとグリルチキンの組み合わせもおすすめです。チキンはグリルして冷ましてから、冷たいスープと一緒に食べると、さっぱりしつつも満足感があります。\n暑い季節にさっぱり食べられる昼ごはんとして、そばやうどんの冷製メニューも良いでしょう。例えば、冷やしそばや冷製うどんに、おろしやネギ、生姜などを添えて食べると、涼しく感じられます。\n暑い季節にさっぱり食べられる昼ごはんとして、豆腐サラダやスムージーなども良いでしょう。豆腐は低カロリーでタンパク質が豊富、スムージーは野菜や果物をミックスすることで、ビタミンやミネラルを手軽に摂取できます。\n暑い季節にさっぱり食べられる昼ごはんとして、ラップサンドやテックスメックス風のトルティーヤラップもおすすめです。野菜とチキンや豆腐などを wrap し、サルサソースやライム添えると、涼しくてヘルシーな一品になります。\n暑い季節にさっぱり食べられる昼ごはんとして、海鮮丼や刺身定食も良いでしょう。新鮮な魚介類を冷たいご飯と一緒に食べると、涼しく感じられますし、栄養も豊富です。\n暑い季節にさっぱり食べられる昼ごはんとして、冷製スープとグリル野菜のプレートも素敵です。グリル野菜はシンプルに塩とオリーブオイルで味付けし、冷製スープと合わせると、野菜の旨みが引き立ちます。\n暑い季節にさっぱり食べられる昼ごはんとして、ソーメンと夏野菜の揚げ浸しも良いでしょう。ソーメンを茹でて、揚げたての夏野菜と一緒に漬け汁に漬け込むだけで、冷たくてヘルシーな一品が完成します。\n暑い季節にさっぱり食べられる昼ごはんとして、豆腐とアボカドのスムージーボウルもおすすめです。豆腐とアボカド、果物やナッツを混ぜ合わせたスムージーを、シリアルやフルーツと一緒に盛り付けると、ヘルシーでボリュームもあります。\n暑い季節にさっぱり食べられる昼ごはんとして、冷製パスタにバジルとレモンを添えたものも良いでしょう。バジルの香りとレモンの酸味が、暑さを忘れさせてくれます。\n暑い季節にさっぱり食べられる昼ごはんとして、寿司や海鮮丼に加えて、冷製の味噌汁や茶碗蒸しを添えるのもおすすめです。これらは温かい料理ですが、冷製メニューと一緒にいただくことで、温度差が楽しめますし、栄養バランスも良くなります。\n暑い季節にさっぱり食べられる昼ごはんとして、冷製スープとグリルドチキン、さらにフルーツサラダを組み合わせるのも良いでしょう。フルーツの甘酸っぱさが、さっぱりとした後味を提供します。\n暑い季節にさっぱり食べられる昼ごはんとして、豆腐と夏野菜の冷やし鉢も素敵ですね。豆腐を冷やして、夏野菜と一緒に酢醤油や薬味で食べると、涼しく感じられますし、夏バテ防止にも効果的です。\n暑い季節にさっぱり食べられる昼ごはんとして、冷製パスタにトマトとバジル、オリーブオイルをシンプルにかけたものも非常におすすめです。トマトの酸味とバジルの香りが、夏の暑さを忘れさせてくれます。\nこれらのメニューを組み合わせることで、暑い季節にさっぱり食べられるだけでなく、栄養もバランス良く摂取できます。お気に入りのメニューを見つけて、快適なランチタイムをお過ごしください。","index":0,"logprobs":null,"finish_reason":"stop"}],"created":XXXX,"model":"qiita.com","system_fingerprint":"XXXXX-912fXXXX","object":"text_completion","usage":{"completion_tokens":675,"prompt_tokens":9,"total_tokens":684},"id":"chatcmpl-JYTJ1wmNPXXXXj4XXXXX7vMgdXXXXXhB","timings":{"prompt_n":1,"prompt_ms":123.811,"prompt_per_token_ms":123.811,"prompt_per_second":8.076826776296128,"predicted_n":675,"predicted_ms":74529.394,"predicted_per_token_ms":110.41391703703704,"predicted_per_second":9.056829309520483}}
OpenAIのAPI callは、有償なので、LLMの外側の実験をするには、良い環境かも。ただ、サーバの性能に依存するので、要注意。
今日はここまで