はじめに
愛衣ちゃん大勝利〜!! nikkieです。
世はまさに大規模言語モデル1時代!
ollamaを使ってLLMをもふもふ手元のPC(CPUのみ)でも動かしています2が、その秘密は量子化。
今回は、今まで利用するだけだった量子化を自分でもやってみます
目次
- はじめに
- 目次
- 「非力なパソコンでもLLMを動かしたい!? llama.cppの紹介」
- cyberagent/calm2-7b-chatをq5_k_mに量子化
- 量子化したモデルをollamaでも動かす
- 終わりに
- 積ん読リスト
「非力なパソコンでもLLMを動かしたい!? llama.cppの紹介」
こちらの記事を全力でパクッていきます!!
cyberagent/calm2-7b-chat3をq5_k_mに量子化します。
ちなみにこのモデルのライセンスは、Apache-2.0です。
M1 Mac(メモリ32GB・macOS 14.5)でllama.cppを使って量子化をしていきます。
(元記事ではUbuntu(Google CloudのVM)です)
手順
cyberagent/calm2-7b-chatをq5_k_mに量子化
環境構築
llama.cppのリポジトリをcloneします。
コミット 059031b8c40e1f4ba60586842c5b1ed3ddf61842 の時点のコードを動かしています。
(1) llama.cppをビルドします4
cd llama.cpp make # https://github.com/ggerganov/llama.cpp のルートでビルド
「Metal Build」は無効にせずに進めました
On MacOS, Metal is enabled by default.
元記事にならってmake test
したところ、1ケース通りませんでしたが、(私に解決できる技量はないので祈りを捧げて)先に進みました
(2) Pythonの環境構築
- Python 3.11.8
仮想環境を作って有効化して
% pip install -r requirements/requirements-convert-hf-to-gguf-update.txt
※requirements-convert-hf-to-gguf.txtと今は同内容でした
certifi==2024.2.2 charset-normalizer==3.3.2 filelock==3.14.0 fsspec==2024.5.0 gguf==0.6.0 huggingface-hub==0.23.0 idna==3.7 Jinja2==3.1.4 MarkupSafe==2.1.5 mpmath==1.3.0 networkx==3.3 numpy==1.24.4 packaging==24.0 protobuf==4.25.3 PyYAML==6.0.1 regex==2024.5.15 requests==2.31.0 safetensors==0.4.3 sentencepiece==0.2.0 sympy==1.12 tokenizers==0.19.1 torch==2.1.2 tqdm==4.66.4 transformers==4.41.0 typing_extensions==4.11.0 urllib3==2.2.1
1. Hugging Faceに置いてあるモデルをGGUF形式に変換
今回のディレクトリ構成
llama.cpp/ # リポジトリのルート ├── .venv/ # すでに作ったPython環境 └── work/ # 作業ディレクトリ └── models/ ├── hf/ # Hugging Faceからダウンロードしたモデルを置く └── gguf/ # llama.cppで量子化したモデルを置く
(1) Hugging Faceからモデルのダウンロード
Python環境を使います
% python -c 'import huggingface_hub; huggingface_hub.snapshot_download(repo_id="cyberagent/calm2-7b-chat", cache_dir="./work/models/hf")'
ここのダウンロードが一番時間がかかりました
% ls work/models/hf/models--cyberagent--calm2-7b-chat/snapshots/3e110c7624ff7a940badebfd5f9a91569f98cc56/ README.md model.safetensors.index.json special_tokens_map.json config.json pytorch_model-00001-of-00002.bin tokenizer.json generation_config.json pytorch_model-00002-of-00002.bin tokenizer_config.json model-00001-of-00002.safetensors pytorch_model.bin.index.json model-00002-of-00002.safetensors
(2) vocab.jsonを作る
元記事より
このモデルのトークナイザ(GPTNeoXTokenizerFast)の設定をそのままの形でGGUF形式に変換することはできないからです。
そのため、トークンとIDの対応関係のみ抽出してGGUF形式に変換できるように、語彙のファイル(vocab.json)を追加します。
まずディレクトリを移動
% cd work/models/hf/models--cyberagent--calm2-7b-chat/snapshots/3e110c7624ff7a940badebfd5f9a91569f98cc56/
元記事中のコードをscript.py
として置いて実行。
vocab.jsonができました!
(3) llama.cppが用意したconvert.pyでGGUF形式に変換
% cd - # llama.cppのルートディレクトリに戻った % python convert.py --vocab-type bpe --outfile work/models/gguf/calm2-7b-chat.gguf work/models/hf/models--cyberagent--calm2-7b-chat/snapshots/3e110c7624ff7a940badebfd5f9a91569f98cc56
元記事は--vocabtype
引数ですが、llama.cpp側のアップデートで--vocab-type
とハイフンが入っていました
できたwork/models/gguf/calm2-7b-chat.gguf
は26GBでした。
Hugging Faceではtokenizerが別ファイルだったり、モデル(の重み)が複数のファイルに分かれていたりしますが、これが1つにまとまったということですかね。
2. GGUF形式から量子化
ビルドしたllama.cppを使って量子化します
./quantize work/models/gguf/calm2-7b-chat.gguf work/models/gguf/calm2-7b-chat-q5_k_m.gguf
体感1分くらいでした。
できたwork/models/gguf/calm2-7b-chat-q5_k_m.gguf
は4.6GBです(5分の1!)。
(小数の精度を劣後したことで)軽量化している!!
3. 量子化したモデルをllama.cppで動かす
% ./main -m work/models/gguf/calm2-7b-chat-q5_k_m.gguf -n 500 -p "USER: AIによって私達の暮らしはどのように変わりますか? ASSISTANT: " <|endoftext|>USER: AIによって私達の暮らしはどのように変わりますか? ASSISTANT: 人工知能(AI)は、私たちの生活に多大な変化をもたらします。以下は、AIが私たちの生活にもたらす可能性のある変化の一例です。 1. 生産性の向上: AIは、データの分析、タスクの自動化、および予測分析などの機能を通じて、生産性を向上させます。 (省略しますが、箇条書きが5点出てきました)
流れるように文章が出てきます。
このスピードはすごい!
量子化したモデルをollamaでも動かす
以前Phi-3をollamaで動かした後、同じモデルをllama.cppでも動かしました5。
この経験から、llama.cppで量子化したモデルはollamaでも動かせるのではないかと考えました。
結論を言うと、動かせています。
ollamaのリポジトリを覗いたところ、
https://github.com/ollama/ollama/tree/v0.1.38?tab=readme-ov-file#import-from-gguf
ローカルにあるGGUF形式のモデルを動かす場合は、まずModelfileを作るそうです。
% cat work/Modelfile FROM ./models/gguf/calm2-7b-chat-q5_k_m.gguf
このModelfileからollama create
% ollama create calm2:7b-chat-q5_k_m -f work/Modelfile
successすると、ollama list
に出てきます
これで、もふもふ(ollama run
)できるぜ!
% ollama run calm2:7b-chat-q5_k_m >>> AIによって私達の暮らしはどのように変わりますか? A: AI技術の進歩によって、私たちの生活は大きく変化します。例えば、医療やヘルスケアの分野では、医師の診断を助けるAI診断システムが開発され、より正確な診断が可能になることが期待されています。 (省略します)
流れるようにテキストが出てきます!
ollamaでも動かせました🙌
終わりに
cyberagent/calm2-7b-chatを例に、llama.cppで量子化して動かし、さらにollamaでも動かしました。
この手順を使えば、Hugging Faceに置いてあるどんなモデルも量子化して、ollamaで動かせるんじゃ!?6
勝ったな!
変化の激しいLLM時代ですが、この手順を掴んだことで「いいのか? こちらは量子化していつでもollamaでもふもふできるんだぞ」と余裕を持って臨んでいけそうに思います。
CyberAgentの山本さん、素晴らしい記事をありがとうございました
この記事の元ネタです
量子化すげ〜
— nikkie / にっきー 技書博 け-04 Python型ヒント本 (@ftnext) 2024年5月18日
cyberagent/calm2-7b-chat、ファイルサイズは25GBくらいあるんですが、q5_k_mで5GBくらいになり、llama.cppやollamaを使ってCPUでもサクサク動くhttps://t.co/53MbnqzAU2
メモリ32GBのM1 Macで加工から動かすまでできるんだな〜
積ん読リスト
llm-courseに量子化の記事を見つけました。
仕組みや理論面は理解を深めたいですね。
- Maxime Labonne - Introduction to Weight Quantization
- Maxime Labonne - Quantize Llama models with GGUF and llama.cpp
GGUFも謎のアルファベットなので、理解していきたいところ
https://github.com/ggerganov/ggml/blob/master/docs/gguf.md:enbed
- 同等性能の小規模言語モデルとか出てきて、largeとかsmallの言葉選びがアホだったと思ってます(バベルの塔を立てちゃったぞ...)↩
- Phi-3をもふもふしたいなー ↩
- ↩
- https://github.com/ggerganov/llama.cpp/tree/059031b8c40e1f4ba60586842c5b1ed3ddf61842?tab=readme-ov-file#build↩
- この記事では既出の Apple Silicon・CPUでphi-3(Phi-3-mini-4k-instruct-gguf)を動かす - nikkie-ftnextの日記↩
- 完全に理解した段階(馬鹿の山)なので、やろうとすると色々ハマると思います↩