LLM の量子化モデルには Q4_K_M、Q5_K_M などの表記があります。しかし、4 bit という表記だけでは、モデルファイルの容量、推論時に必要なメモリ、実際の推論速度までは判断できません[1]。
量子化モデルを選ぶときは、少なくとも次の値を分けて確認します。
| 確認対象 | 確認する値 | 判断できること |
|---|---|---|
| 重みの理論容量 | パラメータ数と量子化ビット数 | 重みコード本体のおおよその下限 |
| モデルファイル | GGUF ファイルの実サイズ | 保存・配布に必要な容量 |
| 実行時メモリ | 推論中の最大メモリ使用量 | 対象マシンで安定して動くか |
| KV キャッシュ | キャッシュ形式と文脈長 | 長い文脈で追加されるメモリ |
| 入力処理速度 |
pp の token/s |
プロンプト処理の速度 |
| 生成速度 |
tg の token/s |
継続生成の速度 |
この記事では、同じモデルの量子化違いを llama.cpp で比較する場合を例に、これらを順番に確認します。
前提:同じモデルを同じ条件で比較する
量子化形式の差を見るには、モデルと実行条件をそろえる必要があります。別のモデル、別の llama.cpp、異なる GPU オフロード設定を混ぜると、速度差の原因を量子化形式へ帰属できません。
比較時には、少なくとも次の条件を固定して記録します。
- 元モデルとパラメータ数
- 比較する GGUF ファイル
-
llama.cppの commit - CPU、GPU、RAM または VRAM
- GPU へオフロードする層数
- KV キャッシュ形式
- 文脈長
- batch size
llama.cpp の commit は、リポジトリ内で次のように確認できます。
$ git rev-parse HEAD
以下では、同じ元モデルから作られた model-Q4_K_M.gguf と model-Q5_K_M.gguf を比較するものとします。
4 bit から計算できるのは重みコード本体の理論容量
最初に、量子化ビット数から重みコード本体のおおよその容量を計算します。
重み容量 [byte] = パラメータ数 × 1 重み当たりの bit 数 ÷ 8
たとえば、70 億パラメータをすべて 4 bit で保存すると仮定すると、次の値になります。
7,000,000,000 × 4 ÷ 8
= 3,500,000,000 byte
= 3.5 GB
≈ 3.26 GiB
これは実際の GGUF ファイル容量ではありません。量子化に必要な尺度や、量子化されない部分などを含まないためです。
尺度を保存すると 4 bit/weight を超える
グループ量子化では、複数の重みを 1 グループとして扱い、グループごとに尺度を保存する方式があります。尺度は、量子化された整数値を元の値域へ対応させるための情報です。
重みを b_w bit、グループサイズを G、グループごとの尺度を b_s bit とすると、尺度だけを加えた 1 重み当たりの保存量は次のように見積もれます[1]。
b_effective = b_w + b_s / G
4 bit の重みと 16 bit の尺度を使う単純な例では、グループサイズ 128 なら次の値です。
4 + 16 / 128 = 4.125 bit/weight
グループサイズ 64 なら次の値になります。
4 + 16 / 64 = 4.25 bit/weight
さらにゼロ点、アラインメント、テンソル情報、量子化されない重みなどがあれば、実際の保存量は増えます。したがって、モデル名に 4 bit と書かれていても、ファイル全体が正確に 4 bit/weight になるわけではありません。
Q4_K_M を「すべての重みが一律 4 bit」と読まない
llama.cpp の量子化ツールには --pure があり、これを指定すると K-quant の混合を無効にして同じ型へ量子化します。また、出力テンソルや token embedding だけ別の量子化型へ変更するオプションもあります[2]。
たとえば、公式 README には次のような指定があります。
./llama-quantize \
--imatrix imatrix.gguf \
--output-tensor-type q5_k \
--token-embedding-type q3_k \
--keep-split \
input-model-f32.gguf \
q4_k_m \
8
このため、Q4_K_M の文字列だけから全テンソルの実際の保存形式を単純化して扱うより、最終的な GGUF ファイルを測る方が確実です。
GGUF ファイルの容量を実測する
保存や配布に必要な容量は、生成済み GGUF ファイルそのものを確認します。
人が読みやすい概算は ls -lh で確認できます。
$ ls -lh model-Q4_K_M.gguf model-Q5_K_M.gguf
正確な byte 数を比較する場合は wc -c を使えます。
$ wc -c model-Q4_K_M.gguf model-Q5_K_M.gguf
結果は次のように記録します。
| 量子化形式 | 理論上の重み容量 | GGUF 実サイズ |
|---|---|---|
| Q4_K_M | 計算値 | 実測値 |
| Q5_K_M | 計算値 | 実測値 |
ここで比較するのはストレージ上のファイル容量です。次に確認する実行時メモリとは分けて扱います。
モデルファイルが収まっても推論時のメモリが足りるとは限らない
推論時には、モデル重み以外にも活性値、作業領域、KV キャッシュ、推論エンジン自体の管理領域が必要です[1]。
概念的には、必要メモリを次のように分けられます。
M_total =
M_weights
+ M_activations
+ M_KV
+ M_workspace
+ M_runtime
+ M_other
GGUF ファイルが RAM や VRAM より小さいというだけでは、目的の文脈長で安定して推論できるとは判断できません。
実行時メモリを比較するときは、モデル読み込み直後だけでなく、実際に使う文脈長まで入力した状態で最大使用量を確認します。OS のメモリ監視機能や GPU の監視ツールを使い、Q4_K_M と Q5_K_M を同じ条件で測定します。
KV キャッシュは重みとは別に増える
KV キャッシュは、Attention で過去の token の key と value を再利用するために保持する領域です。文脈長や batch size が大きくなるとメモリ消費が増え、重みを量子化しただけでは自動的に減りません。長文脈や大きな batch では KV キャッシュ自体がメモリと速度のボトルネックになり得ることも報告されています[3]。
現在の llama-bench では、KV キャッシュの既定形式は key、value ともに f16 です[4]。重みが Q4_K_M でも、既定の KV キャッシュまで 4 bit になるわけではありません。
比較条件を明示する場合は、たとえば次のように KV キャッシュ形式を固定できます。
./build/bin/llama-bench \
-m model-Q4_K_M.gguf \
-m model-Q5_K_M.gguf \
-ctk f16 \
-ctv f16 \
-p 512 \
-n 128 \
-r 5
推論速度は bit 数ではなく実測する
低ビット化すると重みの読み出し量を減らせますが、保存量の削減率と推論速度の向上率は一致しません。量子化形式を演算器がどう扱うか、復号処理が必要か、処理がメモリ帯域と演算性能のどちらに制約されているかで結果が変わります。
NVIDIA が Llama 3 を H100 上で比較した例でも、INT4 AWQ の FP16 比速度向上は batch size 32 の Llama 3 8B で 1.08 倍、batch size 1 では 1.56 倍となっており、同じ量子化方式でも実行条件によって異なります[5]。
llama-bench で入力処理と生成速度を分けて測る
llama-bench は、prompt processing を pp、text generation を tg として別々に測定できます。また、各テストは -r で指定した回数だけ実行され、平均 token/s と標準偏差が出力されます[4]。
Q4_K_M と Q5_K_M を同じ条件で比較する例です。
./build/bin/llama-bench \
-m model-Q4_K_M.gguf \
-m model-Q5_K_M.gguf \
-ctk f16 \
-ctv f16 \
-p 512 \
-n 128 \
-r 5
結果では、少なくとも次の 2 行を分けて見ます。
pp 512
tg 128
pp が速くても tg の差が小さい場合や、その逆もあります。用途が長い文書の一括処理なのか、対話形式で token を継続生成するのかによって、重視する値も変わります。
なお、llama-bench の測定には tokenization と sampling の時間は含まれません[4]。アプリケーション全体の応答時間ではなく、モデル処理部分の比較として扱います。
長い文脈でも同じ条件で測る
llama-bench の -d は、指定した token 数まで KV キャッシュを事前に埋めた状態でテストします[4]。
通常状態と 4096 token の深さを一度に比較する例です。
./build/bin/llama-bench \
-m model-Q4_K_M.gguf \
-m model-Q5_K_M.gguf \
-ctk f16 \
-ctv f16 \
-p 512 \
-n 128 \
-d 0,4096 \
-r 5
d=0 と d=4096 で pp と tg がどう変わるかを確認します。長い文脈で使うモデルなら、ファイルサイズだけでなく、この状態でのメモリ使用量と token/s を選定材料にします。
量子化モデルは 6 項目を分けて選ぶ
量子化モデルを選ぶときは、Q4 や Q5 の名前だけで決めず、次の順で確認すると判断しやすくなります。
- パラメータ数と bit 数から、重みコード本体の理論容量を計算する。
- 実際の GGUF ファイル容量を測る。
- 目的の文脈長で実行時メモリを測る。
- KV キャッシュの形式を記録する。
-
llama-benchでppとtgを別々に測る。 - 必要な品質を満たしているか、実際の用途で生成結果を確認する。
たとえば Q4_K_M のファイルが Q5_K_M より小さくても、対象ハードウェアで tg にほとんど差がなく、メモリにも十分な余裕があるなら、容量だけを理由に Q4_K_M を選ぶ必要はありません。逆に、モデル読み込みがメモリ上限に近い環境では、数 GB の差が実行可否を決める場合があります。
「ファイルが小さい」「実行時メモリが少ない」「推論が速い」は、それぞれ別の測定結果です[1]。量子化形式の名称は比較の入口として使い、最終判断は対象環境での実測値に置きます。
留意事項
llama.cpp は継続的に更新されています。量子化形式、既定値、利用できる backend、演算カーネルが変われば、同じ GGUF ファイルでも結果が変わる可能性があります。比較結果を残す場合は、llama.cpp の commit と実行条件を一緒に記録します。
GPU オフロード層数、Flash Attention、KV キャッシュ形式、batch size、文脈長のいずれかを変更した測定値は、量子化形式だけを変えた比較にはなりません。速度差を確認するときは、比較対象以外の条件を固定します。
また、低ビット化は品質との交換条件を持ちます。ファイル容量や token/s が良くても、必要な生成品質を満たさなければ採用できません。最終的には、容量、実行時メモリ、速度、品質を同じ利用条件で確認します。
参考文献
- id774, 量子化について詳しく解説する(2026-08-07). https://blog.id774.net/entry/2026/08/07/5472/
- ggml-org, llama.cpp/tools/quantize(2026-06-05). https://github.com/ggml-org/llama.cpp/blob/ad1b88ca0d37a2171efba1c04f1a3531c78f1b52/tools/quantize/README.md
- Zirui Liu, Jiayi Yuan, Hongye Jin, Shaochen Zhong, Zhaozhuo Xu, Vladimir Braverman, Beidi Chen, Xia Hu, KIVI: A Tuning-Free Asymmetric 2bit Quantization for KV Cache(2024-02-05). https://arxiv.org/abs/2402.02750
- ggml-org, llama.cpp/tools/llama-bench(2026-05-30). https://github.com/ggml-org/llama.cpp/blob/aa46bda89b9a8378ae76bb15fc2ce2f571f0983c/tools/llama-bench/README.md
- Jan Lasek, Onur Yilmaz, Chenjie Luo, Chenhan Yu, Post-Training Quantization of LLMs with NVIDIA NeMo and NVIDIA TensorRT Model Optimizer(2024-09-10). https://developer.nvidia.com/blog/post-training-quantization-of-llms-with-nvidia-nemo-and-nvidia-tensorrt-model-optimizer/