第6部 どうやって軽くするのか第10章

量子化(Quantization)

16GBのモデルが5GBに縮む——その正体は、数字の目盛りを粗くすること。FP16・BF16・FP8・INT4・MXFP4といった数値形式から、GPTQ・AWQ・GGUFのk-quantsまで、量子化の地図を描きます。

約16分で読めます2026年10月改訂

このページの内容(9項目)
  1. 量子化とは「目盛りを粗くする」こと
  2. 数値形式の図鑑:FP16からNVFP4まで
  3. どれだけ小さくなる? 計算してみよう
  4. どうやって量子化する? PTQとQAT
  5. 重みだけじゃない:活性化とKVキャッシュの量子化
  6. なぜ速くなるのか、いつ速くならないのか
  7. どれを選べばいい?
  8. さらに深く学ぶ
  9. 出典・参考

80億パラメータのモデルが、16GBから5GBに縮む。何を捨てたのでしょう?

Llama 3.1 8B をそのまま16bitで持つと重みだけで約16GB。ところが llama.cpp で「Q4_K_M」に変換すると約4.9GBになり、ノートPCでも動くようになります。中身の数字を3分の1以下に削ったのに、会話の質は思ったほど落ちません。

この魔法の正体が量子化(quantization)です。この章では「数字の目盛りを粗くする」という一つのアイデアから、FP8、INT4、MXFP4、GPTQ、AWQ、GGUF といった呪文のような名前を一つずつほどいていきます。

量子化とは「目盛りを粗くする」こと

ひとことで言うと

量子化は、モデルの重み(や途中の計算値)を少ないビット数で近似して表すことです。メモリが減り、多くの場合は生成も速くなりますが、少しだけ誤差が入ります。

LLMの中身は、数十億〜数千億個の小数(重み、weights)の集まりです。学習するときは1個あたり16bitや32bitで細かく持っていますが、推論で使うだけなら、そこまで細かい目盛りは要らないことが多いのです。

身長を「172.38cm」と記録する代わりに「172cm」と書いても、服のサイズ選びには困りません。さらに「170cm台」まで粗くすると困る場面も出てきます。量子化は、この「どこまで丸めても困らないか」を、何十億個の数字について工夫しながら決める作業です。

具体的には、重みをいくつかのまとまり(ブロック)に分け、ブロックごとに「ものさしの長さ」にあたるスケール(scale)を1つ決めます。各重みは「スケール × 小さな整数」で表すので、整数の部分だけを少ないビットで保存すれば済みます。

もう一歩深く: 4bitで丸めてみる

重みのブロック [0.12, −0.50, 0.33, 0.07] を、−7〜7 の整数(4bitに収まる)で表してみます。絶対値の最大 0.50 を 7 に対応させると、スケールは 0.50 ÷ 7 ≒ 0.0714。各値をスケールで割って四捨五入すると [2, −7, 5, 1] になり、戻すと [0.143, −0.50, 0.357, 0.071] です。少しずつずれていますが、だいたい元の形を保っています。

ブロックを小さくするほど、外れ値に引っ張られずに精度が上がります。そのかわりスケールを保存する分の「おまけ」が増えます。量子化の種類がたくさんあるのは、この精度とサイズの綱引きのバランスが方式ごとに違うからです。

数値形式の図鑑:FP16からNVFP4まで

まずは「1個の数字を何ビットでどう表すか」という数値形式を整理します。浮動小数点(FP)は「符号・指数・仮数」の3つに分けてビットを割り振ります。指数が多いほど大きな数・小さな数を扱え(範囲が広い)、仮数が多いほど細かく表せます(精度が高い)。

形式ビット構成特徴
FP32符号1・指数8・仮数23学習の基準。推論には贅沢
FP16符号1・指数5・仮数10最大値は約6.5万。範囲が狭く、学習ではあふれに注意
BF16符号1・指数8・仮数7FP32と同じ範囲で精度を削った形。いまの学習・配布の標準
FP8 E4M3符号1・指数4・仮数3最大448。精度寄りで、推論の重み・活性化向き
FP8 E5M2符号1・指数5・仮数2最大57344。範囲寄りで、学習時の勾配向き
INT8 / INT4整数8bit / 4bitスケールと組み合わせて使う。INT4は16段階しかない
MXFP4FP4(E2M1)×32個+共有スケール8bit実質約4.25bit。OCPの業界標準
NVFP4FP4(E2M1)×16個+FP8スケール実質約4.5bit。NVIDIA Blackwell世代向け

FP8の2種類は2022年の論文「FP8 Formats for Deep Learning」で提案され、NVIDIAのHopper世代(H100など)以降のGPUが計算に対応しています。4bitの浮動小数点 E2M1 は、表せる値が 0, 0.5, 1, 1.5, 2, 3, 4, 6 とその負の数だけ。これを単独で使うのは無理があるので、小さなブロックごとにスケールを掛ける「マイクロスケーリング」と組み合わせます。

MXFP4は32個ごとに2のべき乗のスケールを1つ共有し、NVFP4は16個ごとにFP8(E4M3)のスケールと、テンソル全体用のFP32スケールの2段構えで誤差を減らします。NVIDIAはNVFP4の実質サイズを「1値あたり4.5bit」、FP16比で約3.5分の1と説明しています。OpenAIの gpt-oss は、MoE層の重みをMXFP4で量子化した状態で公開され、gpt-oss-120b が80GBのGPU 1枚に収まるとされています。

どれだけ小さくなる? 計算してみよう

重みのサイズはざっくり「パラメータ数 × 1個あたりのビット数 ÷ 8」バイトです。8B(80億)モデルなら、16bitで 8 × 16 ÷ 8 = 16GB、4bitなら約4GB。ただし実際の量子化ファイルはスケールなどの「おまけ」を含むので、4bit系でも1個あたり4.5〜5bit程度になります。

上のウィジェットは、パラメータ数とビット幅から重みだけのおおよそのサイズを計算し、8GB〜128GBのメモリに対して何%を占めるかをバーで示します。初期状態の「8B・Q4_K_M(約4.9bit)」では約4.9GBと表示され、llama.cpp のドキュメントにある Llama 3.1 8B の Q4_K_M サイズ(4.9GB)とほぼ一致します。選択肢のビット数(Q8_0 は約8.5bit、Q6_K は約6.6bit など)も、同じドキュメントにある Llama-3.1-8B での実測値です。

試しにプリセットを70Bにして、FP16とQ4_K_Mを切り替えてみてください。FP16では約140GBで、80GBのGPUにも入りません。Q4_K_Mにすると約43GBまで縮み、48GBクラスなら収まる計算になります。ただしバーが90%を超えると赤くなるのは、実際には第15章で扱うKVキャッシュや作業用メモリの余裕も必要だからです。

ためしてみよう

「三値 1.58bit(理論値)」を選ぶと、8Bモデルでも約1.6GBになります。これが第11章のBitNetが目指す世界です。ただし後から1.58bitに丸めるのではなく、最初からその形で学習するところがミソです。

どうやって量子化する? PTQとQAT

量子化のやり方は、大きく2つに分かれます。

  • PTQ(Post-Training Quantization、学習後量子化): 学習済みのモデルを、あとから丸める。手軽で、配布されている量子化モデルのほとんどはこちら。
  • QAT(Quantization-Aware Training、量子化を考慮した学習): 学習中から「丸められること」を前提に重みを調整する。手間はかかるが、低ビットでも劣化しにくい。

QATの例として、Googleは2025年4月に Gemma 3 のQAT版を公開し、BF16で54GBあった27Bモデルをint4で約14.1GBにして、RTX 3090のような家庭用GPUで動かせるとしました。Googleによると、約5,000ステップのQATで、Q4_0に量子化したときのパープレキシティの悪化を54%減らせたそうです。前述の gpt-oss も、MXFP4にした状態で学習の後半(post-training)を行っています。

いちばん単純なPTQは、ブロックごとに最大値でスケールを決めて四捨五入するだけの方法(RTN: round-to-nearest)です。8bitならこれでも十分なことが多いのですが、4bit以下では工夫が必要になります。代表的な方式を見ていきましょう。

GPTQ ジーピーティーキュー

2022年の論文の方式。少量の入力データ(キャリブレーションデータ)を流し、重みを1列ずつ丸めながら、その誤差を残りの列で補正していきます。二次の情報(ヘッセ行列の近似)を使うのが特徴で、論文では175Bモデルを約4GPU時間で3〜4bitにでき、精度の劣化はわずかと報告しています。

AWQ Activation-aware Weight Quantization

2023年の方式。「重みはどれも同じくらい大事」ではなく、活性化(入力側の値)が大きいチャンネルの重みが特に効く、という観察に基づきます。論文では、重要な重みの約1%を守るだけで誤差が大きく減ると述べ、それらを丸める前にスケールアップして保護します。逆伝播を使わないので速く、キャリブレーションデータに過学習しにくいとされます。

bitsandbytes ビッツアンドバイツ

PyTorch用の量子化ライブラリ。8bit推論の LLM.int8()(外れ値の次元だけ16bitで計算し、99.9%以上の値は8bitで掛け算する)と、QLoRAで提案された4bit形式 NF4 を提供します。Hugging Face Transformers からモデル読み込み時に指定するだけで使えるので、「事前に変換したファイル」が要らないのが手軽な点です。QLoRAについては第13章で扱います。

GGUFのk-quantsとimatrix llama.cpp

llama.cpp 系で使うGGUF(第5章)の量子化方式です。Q4_K_M の「K」はk-quants(256個のスーパーブロックの中に小ブロックを入れ子にし、スケールまで量子化する方式)、「M」はMedium で、テンソルによってビット幅を混ぜる構成の大きさを表します。さらにimatrix(重要度行列)を使うと、サンプル文章を流して「どの重みがよく効くか」を測り、その重みの誤差を優先して小さくできます。IQ系(IQ2_XXSなど)の2〜3bit台の方式は、imatrixと組み合わせて使うのが基本です。

どれも「誤差をゼロにする」のではなく、「出力に効くところの誤差を優先して減らす」工夫だと考えると整理しやすくなります。

重みだけじゃない:活性化とKVキャッシュの量子化

量子化の対象は重みだけではありません。表記として「W4A16」のような書き方がよく使われます。Wは重み(weights)、Aは活性化(activations、計算途中の値)のビット数です。

  • W4A16: 重みだけ4bit、計算は16bit。GPTQ・AWQ・GGUFの多くはこれ。メモリと読み込み量が減る。
  • W8A8(FP8やINT8): 重みも活性化も8bitで、掛け算そのものを8bit演算器で行う。サーバーでの大量処理(スループット)に効く。
  • KVキャッシュの量子化: 会話の文脈を覚えておくKVキャッシュを8bitなどにする。vLLMは kv_cache_dtype="fp8"、llama.cpp は --cache-type-k q8_0 のような指定ができます。

長い文脈や多人数の同時処理では、重みよりKVキャッシュのほうが大きくなることもあります。その計算は第15章のウィジェットで確かめられます。

なぜ速くなるのか、いつ速くならないのか

文章を1トークンずつ生成する段階(デコード)では、GPUやCPUは「計算」より「重みをメモリから読み出すこと」に時間を取られています。重みが3分の1になれば、読み出す量も3分の1。だから量子化すると生成が速くなりやすいのです。

llama.cpp のドキュメントに載っている Llama-3.1-8B の計測例では、同じ環境で F16 の生成速度が毎秒約29トークン、Q4_K_M が約72トークンでした。一方、プロンプトを一気に読む処理(プロンプト処理)は F16 が約923、Q4_K_M が約822トークン毎秒と、むしろ F16 のほうが速くなっています。こちらは計算量が支配的で、丸めた値を戻す手間が効いてくるためです。

また、FP8やFP4の「計算」を速くするには、それに対応した演算器を持つハードウェアが必要です。対応していないGPUでは、読み込み時に16bitへ戻して計算するため、メモリは減っても計算は速くなりません。ハードウェアの違いは第17章で扱います。

どれを選べばいい?

flowchart TD
  A["どこで動かす?"] --> B["手元のPC・Mac"]
  A --> C["GPUサーバー"]
  B --> D["GGUF
Q4_K_M から試す"] D --> E["余裕があれば
Q5_K_M・Q6_K"] C --> F["対応GPUなら
FP8 W8A8"] C --> G["メモリ重視なら
AWQ・GPTQ 4bit"] C --> H["最新GPUなら
NVFP4・MXFP4"]
図: 量子化形式選びのおおまかな目安

ローカルで試すなら、まずは GGUF の Q4_K_M が定番の出発点です。Q8_0 はほぼ劣化なし、Q2 台は小さいけれど劣化がはっきり出やすい、と覚えておくとよいでしょう。llama.cpp の llama-quantize の一覧では、Llama-3-8B で Q8_0 のパープレキシティ(予測の当たらなさ)の悪化は +0.0026、Q4_K_M は +0.1754、Q2_K は +3.5199 と示されています。

同じ「4bit」でも、モデルの大きさで影響は変わります。大きなモデルほど量子化に強い傾向があるので、「小さいモデルを高精度で」より「大きいモデルを4bitで」のほうが賢いことも珍しくありません。最後は、自分の用途で実際に答えを比べるのがいちばん確かです。

よくある誤解

4bit量子化したモデルは、ファイルサイズがちょうど4分の1になる

スケールなどの付加情報や、高ビットのまま残すテンソルがあるため、16bitの約3割(4.5〜5bit相当)になるのが普通です

量子化すれば、どんな処理も必ず速くなる

速くなりやすいのはメモリ読み出しが支配的な生成(デコード)。プロンプト処理や非対応ハードウェアでは速くならないこともあります

GGUFは量子化の方式の名前だ

GGUFはファイル形式。Q4_K_M や IQ3_M などが、その中に入っている量子化方式です

確認クイズ

Q1. BF16とFP16はどちらも16bit。何が違う?

ビットの割り振りです。BF16は指数8bit・仮数7bitでFP32と同じ広い範囲を持ち、FP16は指数5bit・仮数10bitで範囲が狭いかわりに細かく表せます。学習であふれにくいBF16が今の標準です。

Q2. 70BモデルをQ4_K_M(約4.9bit)にすると、重みはおよそ何GB?

  • 約9GB
  • 約43GB
  • 約140GB

700億 × 4.9bit ÷ 8 ≒ 43GB。140GBはFP16のときのサイズです。

Q3. PTQとQATの違いは?

PTQは学習済みモデルをあとから丸める方法、QATは丸められることを前提に学習(または追加学習)する方法です。QATのほうが手間はかかりますが、低ビットでの劣化を抑えやすくなります。

Q4. 「重要な重みを見分けるのに、活性化の大きさを見る」のはどの方式?

  • GPTQ
  • AWQ
  • MXFP4

AWQ(Activation-aware Weight Quantization)です。GPTQは丸め誤差を残りの重みで補正する方式、MXFP4は数値形式の名前です。

この章のまとめ

  • 量子化は、ブロックごとのスケールと小さな整数(や小さな浮動小数点)で重みを近似し、メモリを減らす技術
  • BF16が学習と配布の標準。FP8(E4M3/E5M2)、MXFP4・NVFP4といった低ビット形式は、対応ハードウェアで計算まで速くなる
  • PTQの代表がGPTQ・AWQ・GGUFのk-quants(imatrix併用)・bitsandbytes。QATは学習段階から低ビットに備える
  • 生成が速くなるのは、メモリ読み出し量が減るから。重みの外にKVキャッシュの量子化もある

さらに深く学ぶ

この章の内容をもう一歩掘り下げるための原典です。

第10章の論文・資料をすべて見る →

出典・参考

  1. llama.cpp tools/quantize README — Llama 3.1 のQ4_K_Mサイズ、Llama-3.1-8Bでのbits/weightと速度の計測表(2026年10月時点で確認)
  2. llama.cpp quantize.cpp — 量子化タイプ一覧とLlama-3-8Bでのパープレキシティ悪化値(2026年10月確認)
  3. llama.cpp PR #1684(k-quants)、PR #4861(importance matrix)
  4. Micikevicius ほか「FP8 Formats for Deep Learning」(arXiv:2209.05433)
  5. NVIDIA Technical Blog「Introducing NVFP4 for Efficient and Accurate Low-precision Inference」 — 16値ごとのFP8スケールとFP32テンソルスケール、4.5bit/値
  6. openai/gpt-oss(GitHub) — MoE重みのMXFP4量子化、80GB GPU 1枚での実行
  7. Frantar ほか「GPTQ」(arXiv:2210.17323)
  8. Lin ほか「AWQ」(arXiv:2306.00978)
  9. Dettmers ほか「LLM.int8()」(arXiv:2208.07339)、「QLoRA」(arXiv:2305.14314)、Transformers の bitsandbytes ドキュメント
  10. Google Developers Blog「Gemma 3 QAT Models」(2025年4月)
  11. vLLM ドキュメント「Quantized KV Cache」、llama.cpp server README(--cache-type-k)