🎀

Rinna-3.6B を llama.cpp で CPU 動作のメモ

2023/06/01に公開

https://twitter.com/npaka123/status/1663874748387061761?s=20

ふえぇ... Rinna-3.6B-Instruction-PPO しゅごいね...

Google Colab で Rinna-3.6B を試す
https://note.com/npaka/n/ne4a38239f420

npaka 先生(LLM 神)ありがとうございます.

llama.cpp で CPU やスマホで動かしたい...!

量子化なし(素の fp16 weight)だと CPU mem 10 GB くらいで動きました.

情報

rinna 3Bをcppで動かす
https://note.com/if001/n/n6da85d0077d7

ありがとうございます!

環境

  • Ryzen9 3900 + WSL
  • 128 GB CPU mem
    • 32 GB くらいあれば十分と思われます.
  • python 3.10 + pytorch 2.0.1(CPU 版でよい)

再現コード

redpajama.cpp https://github.com/togethercomputer/redpajama.cpp だとちょっと古かったので, llama.cpp に redpajama.cpp をマージして使うようにしました.

https://github.com/syoyo/llama.cpp/tree/redpajama

redpajama branch になります.

データ変換

今回は. sft(Supervised Fine-Tuning)より, より自然な会話ができる japanese-gpt-neox-3.6b-instruction-ppo を使います.

https://huggingface.co/rinna/japanese-gpt-neox-3.6b-instruction-ppo

元モデルは fp16 で, 7.4 GB あります.

converter は huggingface の repo を自動で取得します.

$ python convert_gptneox_to_ggml.py 'rinna/japanese-gpt-neox-3.6b-instruction-ppo' ./output_dir

huggingface 使う場合は,

$ python -m pip install transformers sentencepiece protobuf

で依存 moudle 入れておきます. Linux の場合は

PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python

環境変数設定しておく必要があるかもです(特に Python 実装使うことによる速度低下はありません)

スクリプトちょっといじれば, huggigface 経由(transformers 経由)ではなく, ファイル直指定で変換もできるでしょう.

model 構造自体変わりませんので, sft なども同様に変換できます.

llama.cpp で CPU で LLM のメモ(2023/05/15 時点日本語もいけるよ)
https://zenn.dev/syoyo/articles/f869a3fda15f45

にあるように, tokenizer のモデル(sentencepiece model)も変換されて .bin に取り込まれますので, 動作させるときは .bin が一個あれば OK です. 執筆時点(2023/06/01)では日本語も特に文字化けすることなく扱えました.

また, 量子化もしたら 8bit なら 4~5 GB, 4bit 量子化なら 2~3 GB 程度で動くと予想されます. 4bit ならスマホで余裕でうごきますネ.

redpajama ビルド

cmake にターゲット追加しました. 普通に cmake ビルドで redpajama, redpajama-chat がビルドされます. quantize-gptneox もビルドされます.

makefile でもビルドできます.

$ make redpajama

動かす.

とりま動かします.

prompt="Q:小津安二郎監督作品を教えてください。"

./redpajama -m examples/redpajama/scripts/output_dir/ggml-japanese-gpt-neox-3.6b-instruction-ppo-f16.bin -t 10 -p "$prompt"
gptneox_model_load_internal: model size = 12B
gptneox_model_load_internal: ggml ctx size = 7048095.00 KiB
gptneox_model_load_internal: mem required  = 8930.91 MiB (+ 1608.00 MiB per state)
..................................................................................................
.
.
gptneox_init_from_file: kv self size  =  198.00 MiB

system_info: n_threads = 10 / 24 | AVX = 1 | AVX2 = 1 | AVX512 = 0 | AVX512_VBMI = 0 | AVX512_VNNI = 0 | FMA = 1 | NEON = 0 | ARM_FMA = 0 | F16C = 1 | FP16_VA = 0 | WASM_SIMD = 0 | BLAS = 0 | SSE3 = 1 | VSX = 0 |
sampling: repeat_last_n = 64, repeat_penalty = 1.100000, presence_penalty = 0.000000, frequency_penalty = 0.000000, top_k = 40, tfs_z = 1.000000, top_p = 0.950000, typical_p = 1.000000, temp = 0.800000, mirostat = 0, mirostat_lr = 0.100000, mirostat_ent = 5.000000
generate: n_ctx = 512, n_batch = 512, n_predict = 128, n_keep = 0


Q:小津安二郎監督作品を教えてください。彼は監督だけでなく、脚本や演出も手掛けています。代表的な作品には『東京物語』や『秋刀魚の味』があります。これらは小津安二郎の最高傑作と言われています。これらの作品は日本だけでなく、世界中の人々に愛されています。彼の最も重要な作品のいくつかは、『秋刀魚の味』と『東京物語』です。彼の他の人気のある作品としては、監督作としては『麦秋』や『故郷』が挙げられます。これらの作品で彼の芸術性は高く評価されています。彼の芸術的な業績は、日本映画全体に影響を与えました。</s>・このプロジェクトは、世界で最高の品質基準


gptneox_print_timings:        load time =  2690.32 ms
gptneox_print_timings:      sample time =    78.40 ms /   128 runs   (    0.61 ms per run)
gptneox_print_timings: prompt eval time =   852.95 ms /    13 tokens (   65.61 ms per token)
gptneox_print_timings:        eval time = 33365.11 ms /   127 runs   (  262.72 ms per run)
gptneox_print_timings:       total time = 36164.72 ms

Voila!

13 tokens/sec と速度も申し分ありません!

https://twitter.com/syoyo/status/1663983234001297408?s=20

ただこれだと text generation mode 的なので, あんまり会話っぽくないです.

https://note.com/npaka/n/ne4a38239f420#66d04aa9-fe52-4390-ba4c-0207f1cfac67

https://github.com/ggerganov/llama.cpp/blob/master/examples/chat-13B.sh

あたりを参考に, chat 設定うまくやるとより応答が改善されるでしょう.

あと, 実際に production 利用する場合は, </s> の bullet item 指示 token? など, スッペシャルな token 対応もいるでしょう.

量子化

たぶん普通にいけると思いますが, redpajama.cpp の最終コミットあたりで, ggml の量子化フォーマットが変わったので何か注意いるかもしれません.

T.B.W.

https://zenn.dev/syoyo/articles/3bde98e9972dea

Rinna 3.6B はどうなるか要検証ですが, LLM の場合は量子化したほうが性能いいことが多いことが知られています(推論時)

BLAS, BLIS 有効ビルド

BLAS(数値演算ライブラリ)で, 推論処理の高速化が期待できます.

最近では BLAS 的でよりポータブルで性能もよい BLIS(BLAS-like Library Instantiation Software) がはやってきています.

https://exa.phys.s.u-tokyo.ac.jp/ja/projects/highlight/2020/shqind

基本 LLM 推論では BLAS の行列演算関数(gemm)しか使わないので, BLIS 使うのがよいでしょうか.
Ubuntu ならどちらも apt で入るので, とくにこだわりがなければお好みで...

さらなる高みへ...

https://twitter.com/natfriedman/status/1665402680376987648?s=20

M2 Max で Metal で llama 7B が 40 tokens/sec!!!

Rinna 3.6B だと 60 tokens/sec くらい出そう(爆速)

Ryzen もノート用だと AI engine(まあ中身は RDNA3(w/ Matrix Core) ですけど)搭載の RyzenAI も出てきているので, M2 Max + Metal と同等のが AMD/Intel CPU でもできるようになってきそうです!

Tokenizer について

spiece.model を dump すると以下のようなのが得られました.

trainer_spec {
  input: "/home/tianyuz/data/ja_tokenizer_training/cirrussearch20220711.txt"
  model_prefix: "japanese_unigram_20220823"
  model_type: UNIGRAM
  vocab_size: 32000,
  ...

wikipedia jp(cirrussearch = wikipedia のダンプと思われる)から, Unigram(BPE ではない)で, 32,000 語彙で学習していました.

https://analytics-note.xyz/machine-learning/sentencepiece-usage/

BPE かとおもってましたが違いましたね. ただどちらの形式だとしても LLM モデルには大きくは影響は与えないかと思います.

TODO

  • Chat 設定プロンプトをしっかりやる.
  • 3bit or 4bit 量子化し, スマホ(iOS/Android)で動かす
    • whisper.cpp と合わせて日本語音声入力 + 日本語 Chat LLM する
  • QLoRA や llama.cpp でファインチューンを極める

Discussion