量子化とは?AIモデルを軽くする仕組みを整理

量子化とは?AIモデルを軽くする仕組みを整理

「量子化されたモデルなら手元のPCでも動く」——ローカルLLMの話題になると、この量子化という言葉が必ず顔を出します。

ただ、実際に何をどう削っているのかまでは、私もぼんやりとしか説明できませんでした。

量子化が何をする処理なのかを順に追っていくと、なぜモデルが軽くなるのかも見えてきます。

量子化とは何か

量子化とは、モデルの重みをより少ないビット数のデータ型で表現し直す処理です。

学習を終えた直後のモデルは、ひとつの重みを32ビットの浮動小数点数(float32)で持っています。

これを8ビット整数(int8)や4ビット整数(int4)に置き換えるのが、量子化の中身です。

数値の刻みが粗くなるぶん情報は落ちますが、そのかわりに容量と計算コストが下がるという取引になっています。

なぜモデルが軽くなるのか

効き方は単純で、重み1つが占めるバイト数がそのまま減ります。

float32 は1つあたり4バイト、int8 は1バイト、int4 は0.5バイトです。

Hugging Face のドキュメントでも、int8 のモデルは float32 のおよそ4分の1のサイズになると説明されています(Quantization concepts)。

70億パラメータ(7B)のモデルに当てはめると、こういう計算になります。

# 重み1つあたりのバイト数 x パラメータ数
float32 : 4.0 byte x 7,000,000,000 = 28.0 GB
int8    : 1.0 byte x 7,000,000,000 =  7.0 GB
int4    : 0.5 byte x 7,000,000,000 =  3.5 GB

# ※実際には KV キャッシュなどの作業領域が別途必要

手元の16GBのマシンに載るかどうかが、この一段の差で決まるわけです。

そもそも手元に重みをダウンロードして量子化できるのは、学習済みの重みが配られているオープンウェイトモデルに限られます。

重みの配られ方と、ライセンスで確かめておきたい条件は、オープンウェイトモデルの記事で整理しました。

オープンウェイトモデルとは?オープンソースとの違いと利用条件

int8 と int4 では性質が変わる

int8 は float32 の値域を256段階に、int4 は16段階に押し込めます。

段階が16しかない int4 では丸め誤差が大きくなるので、int8 より精度の落ち方がはっきり出ます。

そのため int4 では、誤差を抑える工夫を組み込んだ GPTQ や AWQ といった手法が併用されるのが一般的です。

もうひとつ知っておくと納得しやすいのが、weight packing という仕組みです。

ほとんどのハードウェアは4ビット単位のデータを直接扱えないため、int4 の値を2つ並べて1バイトに詰め込んで保存しています。

メモリから読み出す量が int8 の半分で済むので、計算そのものより「データを運ぶ時間」の短縮が効いてくるのです。

精度はどこまで落ちるのか

ここは「落ちる」とだけ覚えるより、どこで落ちるかを知っておくほうが役に立つでしょう。

量子化の誤差は、値のばらつきが大きいテンソルほど大きくなります。

そこでテンソル全体で1組の変換パラメータを共有する per-tensor ではなく、チャネルやブロック単位に分ける per-channel のほうが精度を保てます。

また、学習後に変換する PTQ(Post-Training Quantization)と、学習中から量子化の影響を織り込む QAT(Quantization-Aware Training)という2つの流派があります。

配布済みモデルをダウンロードして使う場面で目にするのは、ほぼ PTQ のほうです。

触ってみるときの入り口

Transformers なら、読み込み時に設定を渡すだけで4ビット量子化が有効になります(bitsandbytes のドキュメント)。

from transformers import BitsAndBytesConfig
import torch

quantization_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_compute_dtype=torch.bfloat16,
)

# from_pretrained() に quantization_config を渡して読み込む
# ...

重みは4ビットで保持されますが、計算自体は16ビットや32ビットで行われる点に注意してください。

Ollama のようにローカル実行を前提としたツールでは、q4_K_M のような名前で量子化済みファイルが配布されています。

q のあとの数字がビット数を表すので、モデル名を見るだけでどれくらい削られているかは読み取れます。

OllamaをAPIで使う|curlとPythonでローカルLLMを呼び出す

最後に

量子化はモデルを小さくする魔法ではなく、精度とメモリのどちらを取るかを自分で選ぶ操作でした。

まず int4 で動かしてみて、出力が怪しいと感じたら int8 に上げてみてください。

この順番で試すと、手元のマシンで扱えるモデルの上限が見えてきます。

モデルを小さくする方向としては、知識を小さなモデルへ移す蒸留という手もあります。

蒸留とは?大きなAIモデルの知識を小さなモデルへ移す仕組み
トークンとは?AIが文章を「かたまり」で数える仕組みを整理
コンテキストウィンドウとは?AIが指示を忘れる仕組みを整理

ビット数を削るのではなく、動かす部分を絞って計算量を落とすMoEという構造もあります。

MoEとは|47Bのモデルを13B分の計算で動かす

以上です。

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

CAPTCHA