LLM Mistral 7B系のMoEを作って遊ぶ


成果物

ツール

mergekit

Installationに従って環境を構築しましょう
私はvenvを利用しています

git clone https://github.com/arcee-ai/mergekit.git
cd mergekit

python -m venv venv
.\venv\Scripts\activate

pip install -e .  # install the package and make scripts available

記憶ではいざ使おうとするとNumpyのバージョンで怒られたはずなのでその時はダウングレードしておきましょう

pip uninstall numpy
pip install numpy==1.26.4

llama.cpp (convert_hf_to_gguf.py)

convert_hf_to_gguf.pyを使うためだけなのでビルドはしません
mergekitと同様にvenvとか使って環境構築します

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

python -m venv venv
.\venv\Scripts\activate

pip install .

llama.cpp (llama-imatrix.exe, llama-quantize.exe)

https://github.com/ggerganov/llama.cpp/releases

Releaseから環境にあったバイナリを取得しましょう
私はllama-b3578-bin-win-cuda-cu12.2.0-x64.zip を使用しました

手順

1. mergekitでMoE

モデルとMoE用のconfigを用意します

mkdir models
cd models

git clone https://huggingface.co/Local-Novel-LLM-project/Ninja-V3
git clone https://huggingface.co/Local-Novel-LLM-project/Vecteus-v1

実際には取得後モデルのconfig.jsonを編集しているのですがそれについては後述します

base_model: models/Ninja-V3
gate_mode: random
dtype: bfloat16
experts:
- source_model: models/Ninja-V3
- source_model: models/Vecteus-v1

mergekit_moe_config.yml

MoE用のconfigはmergekit_moe_config.ymlという名前としました
パラメーターの詳細はmergekitのドキュメントを参照しましょう

MoE作成
gate_modeにhiddenを設定する場合などは、vramに合わせて--load-in-4bit等を使用する必要があるかもしれません

.\venv\scripts\activate
mergekit-moe --trust-remote-code .\mergekit_moe_config.yml .\output

mergekit\outputにモデルが吐き出されます

2. convert_hf_to_gguf.pyでggufに変換

outputディレクトリをllama.cpp直下に移動するとかしましょう

.\venv\scripts\activate

python convert_hf_to_gguf.py output --outtype bf16

ここで--outtype q8_0を指定することもできますが再量子化には不適です
処理が終わったらllama.cpp\outputにggufファイルがあります

3. llama-imatrix.exeでimatrixを計算&llama-quantize.exeで量子化

・imatrix

imatrixの計算用データセットを準備
今回は下記の「c4_en_ja_imatrix.txt」を使用させていただきました
https://huggingface.co/datasets/TFMC/imatrix-dataset-for-japanese-llm

.\llama-imatrix.exe -m models\Ninja-v3-Vecteus-v1.gguf -f models\c4_en_ja_imatrix.txt -o models\Ninja-v3-Vecteus-v1.imatrix

標準設定では恐らくかなりの時間がかかるので、引数でchunksを指定するか、あるいは10chanksごとに自動的に保存されるので途中で打ち切るとかもあり
適切な設定は不明ですがchunksが少なくてもそんなに影響はないらしい?
また、VRAMが十分ある場合-ngl 99を指定してあげると少し速くなります

・量子化

.\llama-quantize.exe --imatrix models\Ninja-v3-Vecteus-v1.imatrix models\Ninja-v3-Vecteus-v1-BF16.gguf models\Ninja-v3-Vecteus-v1-Q8_0.gguf Q8_0
.\llama-quantize.exe --imatrix models\Ninja-v3-Vecteus-v1.imatrix models\Ninja-v3-Vecteus-v1-BF16.gguf models\Ninja-v3-Vecteus-v1-Q6_K.gguf Q6_K
.\llama-quantize.exe --imatrix models\Ninja-v3-Vecteus-v1.imatrix models\Ninja-v3-Vecteus-v1-BF16.gguf models\Ninja-v3-Vecteus-v1-Q5_K.gguf Q5_K

以上

余談

コンテキスト長とモデルのconfig.json

初めに上記の手順でMoE作成を行ったところ、コンテキスト長8kあたりで出力がおかしくなる症状が確認されました
そこでモデルに付属するconfig.jsonを弄った結果、とある設定により改善が見られました

"attention_dropout": 0.0,
"bos_token_id": 1,
"eos_token_id": 2,
"hidden_act": "silu",
"hidden_size": 4096,
"initializer_range": 0.02,
"intermediate_size": 14336,
"max_position_embeddings": 32768,
"model_type": "mistral",
"num_attention_heads": 32,
"num_hidden_layers": 32,
"num_key_value_heads": 8,
"rms_norm_eps": 1e-05,
"rope_theta": 100000.0,
"sliding_window": 32768,
"tie_word_embeddings": false,
"torch_dtype": "bfloat16",
"transformers_version": "4.41.2",
"use_cache": true,
"vocab_size": 32000

config.json

具体的にはNinja v3・Vecteus v1のconfig.jsonについてこのように
"max_position_embeddings": 32768,
"rope_theta": 100000.0,
"sliding_window": 32768,
としただけなのですが、果たしてこれは適切なのか…自分には調べられませんでした
有識者の方がおられましたら、情報をご提供いただけると幸いです


この記事が気に入ったらサポートをしてみませんか?