量子化(Quantization、連続的な数値を少ない表現段階へ写す処理)は、LLMのweightやactivationを低bitで表し、保存容量とメモリ転送量を減らす技術です。FP16のweightをINT8へ変えれば生のweight payloadは概ね半分、INT4なら概ね4分の1になります。
ただし、モデル全体のVRAMが同じ比率で減るとは限りません。scaleなどのmetadata、量子化しない層、KV Cache、一時bufferが残るためです。速度もhardwareと推論runtimeが対象formatのkernelを持つ場合に限って改善しやすくなります。

3文要約
- 量子化ではweightやactivationの実数値をscaleとzero pointで有限個の値へ写し、丸めとclippingによる誤差と引き換えに容量・転送量を減らします。
- INT8とINT4の違いはbit数だけではなく、weight-onlyかweight-activationか、scaleの粒度、calibration、packing、計算dtypeまで確認する必要があります。
- 採用判断ではmodel fileの大きさだけでなく、実測VRAM、prefill・decode速度、対象taskの品質を同じ条件で比較します。
代表的な論文
LLM量子化には一つの標準手法があるわけではありません。代表例は、それぞれ異なる問題を扱います。
| 手法 | 主な対象 | bit構成の代表例 | 中心となる考え方 |
|---|---|---|---|
| LLM.int8() | weightとactivation | 8-bit中心のmixed precision | activationの外れ値次元を高精度計算へ分離 |
| SmoothQuant | weightとactivation | W8A8 | activationの量子化困難性をweight側へ移す |
| GPTQ | weight | W4A16など | 近似的な2次情報でweight量子化誤差を補償 |
| AWQ | weight | W4A16など | activation統計から重要なweight channelを保護 |
個人ブログのシリーズ計画ではQLoRA論文を量子化の代表資料として挙げています。QLoRAのNF4は重要な4-bit表現ですが、主題は凍結した量子化base modelを通してLoRAを学習することです。本記事では推論時の量子化全体を扱い、QLoRAによる追加学習はQLoRAとは?量子化で省メモリFine-tuningする方法へ分けます。
量子化する対象を先に分ける
LLM推論でメモリを使う数値はweightだけではありません。
| 対象 | 役割 | 生存期間 | 量子化したときの主効果 |
|---|---|---|---|
| Weight | 学習済みparameter | modelを載せている間 | model fileとweight読出し量を減らす |
| Activation | 層の入出力・中間値 | forward中 | 演算入力と中間転送を減らす |
| KV Cache | 過去tokenのK/V | requestの生成中 | 長いcontextや多数requestのcache量を減らす |
| Optimizer state | 学習時の更新状態 | training中 | 推論には通常存在しない |
「4-bit model」と書かれていても、すべての値が4-bitとは限りません。weightだけ4-bitで、activationと計算はFP16/BF16という構成も一般的です。LayerNormや出力headなど、一部moduleを高精度のまま残す実装もあります。
KV Cacheの量は系列長とrequest数で増えます。weight量子化後にKV Cacheが支配的になることもあるため、KV Cacheとは?LLMの生成を高速化する仕組みと分けて見積もります。

実数を整数へ写す基本式
affine quantization(scaleとzero pointを使う線形な量子化)では、実数 \(x\) を整数 \(q\) へ次のように写します。
- \(S\): scale。整数1段階が実数のどれだけに相当するか
- \(Z\): zero point。実数0に対応する整数値
- \(q_{min},q_{max}\): 量子化後の表現範囲
利用時には、整数から近似的な実数へ戻します。
\(\hat{x}\) は元の \(x\) と完全には一致しません。有限個の格子点へ丸めるquantization error(量子化誤差)と、範囲外を端へ寄せるclipping errorが生じます。
具体値を代入する
値域 \([-1.0,1.0]\) をsigned INT4のうち対称な \([-7,7]\) へ写す例を考えます。zero pointは0、scaleは次です。
\(x=0.68\)を量子化すると、
逆量子化値は、
元の値との差は約0.034です。同じscaleを使う値が外れ値を含み、たとえば最大絶対値が7へ広がれば、scaleは1になります。すると0.2、0.4、0.68のような値を細かく区別できず、量子化後の解像度が粗くなります。これがscaleを決める範囲と粒度が重要な理由です。

Hugging Face TransformersのQuantization conceptsでは、affine/symmetric quantization、scale、zero point、粒度、PTQ/QATが整理されています。
symmetricとasymmetricの違い
| 比較軸 | Symmetric | Asymmetric |
|---|---|---|
| 実数範囲 | 0を中心に対称な範囲として扱う | 観測した最小・最大へ合わせる |
| zero point | 通常0へ固定 | 計算して保持 |
| 長所 | 表現と演算を単純化しやすい | 0を中心としない分布の範囲を使いやすい |
| 弱点 | 非対称な分布では段階を無駄にする | metadataと補正処理が増える |
どちらが常に高精度という関係ではありません。weightやactivationの分布、kernelが対応するscheme、量子化単位から決めます。
scaleを共有する粒度
同じINT4でも、どの範囲でscaleを共有するかにより誤差と容量が変わります。
| 粒度 | scaleを共有する範囲 | 長所 | 代償 |
|---|---|---|---|
| Per-tensor | tensor全体 | metadataが少なく単純 | 外れ値の影響が全体へ広がる |
| Per-channel | 出力channelなど | channelごとの値域へ合わせやすい | scale数と処理が増える |
| Group-wise | 連続するweightのgroup | 誤差とmetadataの折衷 | group sizeとpackingがformat依存 |
group sizeを小さくすると局所的な分布へ合わせやすい一方、scaleやzero pointの数は増えます。そのため「4-bitだから0.5 byte/parameter」と計算した値は、生weight payloadの下限に近い概算です。

INT8とINT4を比較する
signed integerの代表的な表現段階は、INT8が256、INT4が16です。INT4は多くの環境で2値を1 byteへpackして保存します。
| 比較軸 | FP16/BF16 | INT8 | INT4 |
|---|---|---|---|
| 1要素の生bit数 | 16 | 8 | 4 |
| 生weight payload | 基準 | 約1/2 | 約1/4 |
| 表現段階 | 浮動小数点形式に依存 | 256 | 16 |
| 量子化誤差 | 量子化なし | 比較的小さい傾向 | 大きくなりやすい |
| 追加処理 | 不要 | scale適用など | packing/unpackingとscale適用など |
| 実測速度 | 基準 | 対応kernel次第 | 対応kernelとmemory-bound度次第 |
FP16とBF16も同じ16-bitですが、指数部と仮数部の割り当てが異なります。INT8・INT4は整数の固定格子へ写す方式であり、「bit数が同じなら数値特性も同じ」とは限りません。
W4A16とW8A8は何を表すのか
量子化構成は、W(weight)とA(activation)を分けると読みやすくなります。
| 表記 | Weight | Activation | 典型的な狙い |
|---|---|---|---|
| W8A16 | 8-bit | 16-bit | weight容量と転送量を抑える |
| W4A16 | 4-bit | 16-bit | weight-onlyでさらに圧縮する |
| W8A8 | 8-bit | 8-bit | weightとactivationの転送・演算を低精度化する |
表記だけでは不十分です。たとえばW4A16でも、weightを4-bitで保存してkernel内で16-bitへdequantizeするのか、専用の低bit matrix kernelを使うのかで速度は変わります。積のaccumulationをINT32やFP32で行う場合もあり、保存dtype、入力dtype、計算dtype、accumulation dtypeを分けて確認します。
PTQとQATの違い
| 比較軸 | PTQ | QAT |
|---|---|---|
| 実施時期 | 学習済みmodelへ適用 | 学習中に量子化誤差を模擬 |
| parameter更新 | 通常は追加trainingなし | 量子化を考慮して更新 |
| 必要データ | calibration dataを使う場合がある | training dataと学習環境 |
| 導入cost | 小さい | 大きい |
| 低bitでの適応 | 限定的 | modelが誤差へ適応できる |
PTQ(Post-Training Quantization、学習後量子化)は、既存modelを短時間で圧縮したい場合に向きます。calibration(代表入力で値の分布や重要度を測る処理)を必要とする方式では、dataの選び方が結果へ影響します。
QAT(Quantization-Aware Training、量子化を考慮した学習)は、forward中に丸めやclippingを模擬し、modelを誤差へ適応させます。精度を保ちやすい可能性がある一方、学習cost、data、実装検証が必要です。
代表的なLLM量子化手法
LLM.int8()は外れ値次元を分離する
LLM.int8()論文は、大規模Transformerのactivationに現れる外れ値featureを扱います。大部分の値を8-bit matrix multiplicationへ送り、外れ値次元を16-bitで計算するmixed-precision decompositionを採用しました。
単純に全要素を同じINT8 scaleへ押し込むのではなく、量子化しにくい部分だけ高精度へ逃がす設計です。したがって「LLM.int8()では全演算が純粋なINT8になる」と理解するとずれます。
SmoothQuantはactivationの難しさをweight側へ移す
SmoothQuant論文は、activation outlierのためにW8A8が難しい問題へ取り組みます。channelごとの等価なscale変換により、activationの大きさを抑える代わりにweight側を調整し、量子化の難しさを移します。
これはactivationを削除する方法ではありません。weightとactivationの両方をINT8化しやすい分布へ変換するPTQです。論文の速度・精度結果は対象modelとhardware、実装条件に基づくため、任意の環境へ固定倍率として当てはめません。
GPTQは量子化誤差を後続weightで補償する
GPTQ論文は、approximate second-order information(入力に対する誤差感度を近似する2次情報)を使うone-shot weight quantizationです。weightを順に量子化し、そこで生じた誤差をまだ量子化していないweightへ反映します。
単純なround-to-nearestより出力誤差を抑えることを狙い、3-bit・4-bitのweight-only量子化を大規模modelへ適用しました。実行にはcalibration input、group size、dampeningなどの設定が関わります。
AWQはactivationから重要なweightを見つける
AWQ論文は、すべてのweightが同じ重要度ではない点に着目します。activation統計を使ってsalient weight channelを特定し、等価なscalingにより重要channelの量子化誤差を抑えます。
Activation-awareという名前ですが、AWQはlow-bit weight-only quantizationです。activationをINT4で保存する方式という意味ではありません。
4方式を同じ軸で比べる
| 手法 | Weight | Activation | calibration | 主に扱う問題 |
|---|---|---|---|---|
| LLM.int8() | INT8中心 | INT8+外れ値を高精度 | 実行時の外れ値処理 | 大規模LLMのactivation outlier |
| SmoothQuant | INT8 | INT8 | activation統計 | W8A8でのactivation量子化 |
| GPTQ | 低bit | 高精度 | layer input | weight量子化の出力誤差 |
| AWQ | 低bit | 高精度 | activation統計 | salient weight channelの保護 |
この表はalgorithmの役割を比較したものです。実際に利用できるformat、GPU、CPU、kernel、model architectureは各runtimeの対応表で確認します。

7B modelのweight容量を計算する
parameter数を \(N\)、weightの平均bit数を \(b\) とすると、生のweight payloadは次の概算です。
7B parameterを単純計算すると次の値になります。
| 形式 | 計算 | 生weight payload |
|---|---|---|
| FP16/BF16 | \(7\times10^9\times2\) bytes | 約14 GB |
| INT8 | \(7\times10^9\times1\) byte | 約7 GB |
| INT4 | \(7\times10^9\times0.5\) byte | 約3.5 GB |
これは全parameterを一度ずつ数えた10進GBの理論値です。実際のmodel fileにはscale、zero point、header、alignmentが入り、embeddingやnormalizationなど一部tensorを16-bitや32-bitで保持する場合もあります。
実行時VRAMはさらに次のように考えます。
そのため、14 GBのweightが3.5 GB相当になっても、総VRAMが14 GBから3.5 GBへ下がるとは限りません。contextを長くしたときにKV Cacheが増える点も別に見積もります。

量子化しても速くならない理由
weightを低bit化すると、GPU memoryやRAMから読むbyte数を減らせます。decodeのようにweight読出しがbottleneckになりやすい場面では、これは速度向上につながる可能性があります。
一方、次のcostが加わります。
- packed INT4をunpackする
- scaleとzero pointを読み、dequantizeする
- 対応しない演算を高精度へfallbackする
- 量子化できないmoduleとの間でdtypeを変換する
- 小さいbatchではkernel launchや変換のoverheadが相対的に大きくなる
| 条件 | 速度が上がりやすい | 上がりにくい・下がり得る |
|---|---|---|
| Hardware | 対象bit幅の命令・Tensor Core等へ対応 | native対応がない |
| Kernel | format専用のfused kernelがある | 汎用演算へ毎回展開する |
| Bottleneck | memory bandwidthが支配的 | 別の演算やCPU転送が支配的 |
| Workload | 大きいmodelを繰り返し読む | modelが小さくoverheadが目立つ |
| Format | runtimeの期待するpackingと一致 | 変換やfallbackが必要 |
INT4自体は互換format名ではありません。NVIDIA TensorRTのQuantization Schemesでも、INT4の対象、block size、scale dtypeにはbackend固有の条件があります。使用するruntimeのversionとhardwareで実測します。

品質はperplexityだけで決めない
量子化誤差の影響は、model size、layer、task、prompt、生成設定で変わります。perplexity(次token予測の不確実さを表す指標)が元modelに近くても、利用taskで同じ出力品質になる保証はありません。
評価では少なくとも次を固定します。
- 同じbase model revisionとtokenizerを使う
- 同じprompt setとchat templateを使う
- temperature、top-p、seedなど生成条件を揃える
- perplexityやbenchmarkに加え、実際のtask成功率を見る
- code、math、長文、instruction followingなど重要なsliceを分ける
- 失敗例を保存し、丸め誤差以外の原因と切り分ける
PTQでcalibration dataを使う場合は、dataset名、件数、sequence length、前処理も記録します。評価dataと同じものを調整へ使えば、汎化性能を過大評価する可能性があります。
方式を選ぶ手順
1. 何が収まらないかを測る
model weight、KV Cache、activation、runtime予約領域を分けます。weightが支配的ならweight-only量子化が直接効きます。長いcontextのKV Cacheが支配的なら、weightをさらに下げるだけでは解決しません。
2. hardwareとruntimeの対応formatを絞る
同じ量子化modelでも、対応kernelがない環境では読み込めないか、高精度へ展開されます。GPU architecture、CPU instruction、runtime version、推奨packingを先に確認します。
3. INT8を基準にINT4を比較する
容量に余裕があり品質を優先するなら、まず8-bitまたは高精度をbaselineにします。4-bitが必要なら、GPTQやAWQなどmodelとruntimeが対応する方式を候補にし、group sizeとcalibration条件も固定します。
4. 容量・速度・品質を同時に記録する
| 軸 | 記録する例 |
|---|---|
| 容量 | model file、peak allocated VRAM、peak reserved VRAM、RAM |
| 速度 | prefill tokens/s、decode tokens/s、time to first token、inter-token latency |
| 品質 | task成功率、perplexity、長文・code・mathなどのslice |
一つの軸だけで結論を出しません。たとえば容量が半分でもdecodeが遅くなるformatは、単一GPUへ載せる目的には有効でもlatency要件には合わない場合があります。
よくある誤解
INT4なら必ずFP16の4分の1か
生weight payloadは概ね4分の1ですが、scale、zero point、alignment、非量子化tensorが加わります。実行時にはKV Cacheやworkspaceも必要です。
AWQはactivationも量子化するのか
AWQはactivation統計を使って重要なweight channelを見つけるweight-only方式です。名称のActivation-awareは、activation自体を低bit化するという意味ではありません。
量子化modelを読み込めれば専用kernelで動いているか
読み込み成功だけでは判断できません。実際のmodule型、kernel、profiler、throughputを確認します。backendが一部演算を高精度へfallbackする場合があります。
INT4と4-bit NF4は同じか
同じではありません。INT4は整数格子、NF4はQLoRAで導入されたnormally distributed weight向けの4-bit data typeです。bit数が同じでも表現値と用途が異なります。
量子化はtrainingでもそのまま使えるか
推論専用の量子化weightを通常の方法で全parameter更新できるとは限りません。QLoRAは4-bit base weightを凍結し、別のLoRA parameterを学習します。推論量子化と学習方式を分けて確認します。
まとめ
LLMの量子化は、weightやactivationを少ないbit数で表し、容量とメモリ転送量を減らす技術です。scale、zero point、粒度、calibrationにより量子化誤差を制御し、GPTQやAWQなどは単純な丸めよりweight-only低bit化の誤差を抑えることを狙います。
重要なのは、bit幅だけで判断しないことです。何を量子化するか、計算時に何bitへ戻すか、対応kernelがあるか、どのtaskで品質を測るかまでが量子化構成です。model file、実測VRAM、prefill・decode速度、task品質を同じ条件で比較してください。
次回は、数値のbit幅ではなくGPUメモリ階層間の読み書きを減らしてAttentionを高速化するFlashAttentionを扱います。
関連記事
参考資料
- Hugging Face Transformers: Quantization concepts
- LLM.int8(): 8-bit Matrix Multiplication for Transformers at Scale
- SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models
- GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers
- AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration
- QLoRA: Efficient Finetuning of Quantized LLMs
- Hugging Face Transformers: bitsandbytes
- NVIDIA TensorRT: Quantization Schemes



コメント