なぜ今、4bit 推論が注目されているのか
拡散トランスフォーマー(Diffusion Transformer)をローカルで動かした経験のある方ならご存じかと思いますが、モデルのロードだけで VRAM を 20〜30GB 消費し、1024x1024 の画像生成に 3 秒以上かかるケースが珍しくありません。特に FLUX や ERNIE-Image といった最新アーキテクチャは、コンシューマー向け GPU では負担が大きいのが現状です。
従来の量子化バックエンドの多くは weight-only 方式です。重みを低精度で保存し、演算時に高精度へ復元(dequantize)するため、メモリは削減できますが推論速度は向上せず、逆量子化のオーバーヘッドでわずかに遅くなることもあります。
そこで登場するのが SVDQuant です。重みと活性値の両方を 4bit(W4A4) で扱い、メモリと速度を同時に改善します。これまでは専用の推論エンジン(Nunchaku)が必要でしたが、現在は Diffusers の from_pretrained() 一行でネイティブロードが可能になり、ローカルでの CUDA コンパイルも不要です。
本記事は Hugging Face 公式ブログ(根拠資料: Nunchaku Diffusers 統合発表)を基に、日本の開発環境に合わせて再構成した実践ガイドです。
![]()
まずは動かす: インストールと初回推論
1. パッケージのインストール
最新の Diffusers と kernels パッケージが必要です。kernels は NVFP4/INT4 の CUDA カーネルを Hub から自動取得する役割を担います。
pip install -U diffusers transformers accelerate kernels bitsandbytes
2. 事前量子化済みパイプラインのロード
カスタムパイプラインクラスも専用推論エンジンも不要です。通常の Diffusers モデルと同様にロードできます。
import torch
from diffusers import ErnieImagePipeline
# 4bit 量子化済みチェックポイントを通常の Diffusers モデルとしてロード
pipe = ErnieImagePipeline.from_pretrained(
"lite-infer/ERNIE-Image-Turbo-nunchaku-lite-nvfp4_r32-bnb4-text-encoder",
torch_dtype=torch.bfloat16,
).to("cuda")
image = pipe(
prompt="A cinematic portrait of a red fox in a misty forest at sunrise, "
"detailed fur, volumetric light",
height=1024,
width=1024,
num_inference_steps=8,
guidance_scale=1.0,
generator=torch.Generator("cuda").manual_seed(42),
).images[0]
image.save("output.png")
RTX 5090 環境で 1024x1024 の画像が約 1.7 秒、ピークメモリは約 12GB です。BF16 パイプラインが 24GB を消費することを考えると、効果は明確です。
3. ハードウェアに関する注意点
ここで重要な落とし穴があります。NVFP4 チェックポイントは Blackwell GPU(RTX 50 シリーズ、RTX PRO 6000、B200)専用です。 RTX 30/40 シリーズや A100、L40S を使用する場合は、必ず INT4 版を選択してください。
| スキーム | 精度 | 対応 GPU |
|---|---|---|
svdq_w4a4 | nvfp4 | Blackwell (RTX 50 シリーズ, RTX PRO 6000, B200) |
svdq_w4a4 | int4 | Turing / Ampere / Ada (RTX 30・40 シリーズ, A100, L40S) |
awq_w4a16 | int4 | Turing / Ampere / Ada (RTX 30・40 シリーズ, A100, L40S) |
Volta および Hopper は現在 4bit カーネルが未対応です。ロード時に CUDA capability を検証し、明確なエラーを返すため、不正な出力が生成される前に検知できます。

速度とメモリをどこまで引き出せるか
torch.compile との併用
Nunchaku Lite は既存の Diffusers 最適化と自由に組み合わせられます。特に torch.compile を適用すると、エンドツーエンドの高速化が 1.35 倍 → 1.8 倍 に向上します。
# トランスフォーマーをコンパイルしてカーネル起動オーバーヘッドを削減
pipe.transformer.compile(fullgraph=True)
# コンパイル時間を短縮したい場合:
# pipe.transformer.compile_repeated_blocks(fullgraph=True)
テキストエンコーダも量子化する
メモリを消費するのはトランスフォーマーだけではありません。T5 や Qwen3 などのテキストエンコーダは単体で数 GB を占有します。bitsandbytes NF4 でテキストエンコーダも量子化すると、ピーク VRAM が約 22% 追加削減されます。
ベンチマーク(RTX PRO 6000、1024x1024、ERNIE-Image-Turbo)
| 構成 | パイプライン全体 | デノイズループ | ピーク VRAM | 高速化 |
|---|---|---|---|---|
| BF16 ベースライン | 3.00 s | 2.86 s | 31.1 GB | 1.0x |
| Nunchaku Lite NVFP4 | 2.27 s | 2.13 s | 20.6 GB | 1.35x |
NVFP4 + torch.compile | 1.68 s | 1.53 s | 20.6 GB | 1.8x |
| NVFP4 + NF4 テキストエンコーダ | 2.29 s | 2.13 s | 16.0 GB | 1.35x |
まとめると、VRAM は最大 50% 削減、レイテンシは約 30% 改善されます。残存するオーバーヘッドの多くはカーネル起動に起因し、torch.compile がこれを大幅に緩和します。
日本国内の開発環境における注意点
国内のスタートアップや受託開発では、RTX 30/40 シリーズの比率が依然として高いため、NVFP4 チェックポイントをそのまま使用するとロード時にエラーになります。まずは INT4 版 + awq_w4a16 の組み合わせから始め、Blackwell ワークステーション(RTX PRO 6000 など)が確保できているチームは NVFP4 へ移行するのが現実的です。また、運用サーバーが Hopper(H100)ベースの場合、現時点で 4bit カーネルは未対応のため、学習は H100、推論は Ada/Blackwell に分離する戦略を推奨します。

自前のモデルを量子化したい場合
diffuse-compressor ツールキットを使用すると、Diffusers モデルのキャリブレーション → 量子化 → パッケージング → Hub へのプッシュまでを一貫して実行できます。FLUX.2 Klein 4B を例に流れを整理します。
1. 量子化対象のスキャン
python examples/text_to_image/quantize_hf.py black-forest-labs/FLUX.2-klein-4B \
--precision int4 --rank 32 --inspect-config
FLUX.2 Klein 4B の場合、SVDQ 100 件、AWQ 3 件、dense 6 件が正常な結果です。必ずこのレポートを先に確認してください。
2. SVDQuant の実行
python examples/text_to_image/quantize_hf.py black-forest-labs/FLUX.2-klein-4B \
--precision int4 \
--output outputs/checkpoints/svdq-int4_r32-flux-2-klein-4b.safetensors
Blackwell ネイティブで構築したい場合は --precision nvfp4 に変更します。
3. Diffusers パイプラインへのパッケージング
python examples/convert_nunchaku_lite_diffusers.py \
--checkpoint outputs/checkpoints/svdq-int4_r32-flux-2-klein-4b.safetensors \
--model-id black-forest-labs/FLUX.2-klein-4B \
--bnb4-text-encoder text_encoder \
--compute-dtype bfloat16 \
--output-dir outputs/diffusers/FLUX.2-klein-4B-nunchaku-lite-int4-bnb4-text-encoder
4. 検証と Hub へのプッシュ
import torch
from diffusers import DiffusionPipeline
pipe = DiffusionPipeline.from_pretrained(
"outputs/diffusers/FLUX.2-klein-4B-nunchaku-lite-int4-bnb4-text-encoder",
device_map="cuda",
)
image = pipe(
"A glass robot in a greenhouse, cinematic lighting",
num_inference_steps=4, guidance_scale=1.0,
generator=torch.Generator("cuda").manual_seed(12345),
).images[0]
pipe.push_to_hub("your-name/your-model-nunchaku-lite-int4")
構造的書き換えが必要なモデルについて
一点、制約を明記しておきます。汎用パスは 構造的書き換えなしで量子化可能なアーキテクチャを前提としています。オリジナルの Nunchaku エンジンは Q/K/V プロジェクションを単一の to_qkv モジュールに統合し、Q/K 正規化と rotary embedding までを一つの fused operator として処理します。こうした fused パスは汎用パスが自動推論できません。
# Diffusers 標準パス: Q, K, V を個別に実行
query = attn.to_q(hidden_states)
key = attn.to_k(hidden_states)
value = attn.to_v(hidden_states)
query = attn.norm_q(query.unflatten(-1, (attn.heads, -1)))
key = attn.norm_k(key.unflatten(-1, (attn.heads, -1)))
query = apply_rotary_emb(query, image_rotary_emb, sequence_dim=1)
key = apply_rotary_emb(key, image_rotary_emb, sequence_dim=1)
# Nunchaku パス: 単一の fused operator に統合
qkv = fused_qkv_norm_rottary(
hidden_states, attn.to_qkv, attn.norm_q, attn.norm_k, image_rotary_emb
)
このようなモデルでは、量子化時に モデル固有の target config で書き換え方式を指定し、ランタイムでは小型のアダプタがロード時に処理します。FLUX.2 Klein 4B のスクリプトと rootonchair/nunchaku-lite リポジトリが良い参考例です。
次のステップ学習の方向性
- ステップ 1: 事前量子化済みチェックポイント(
lite-infer,rootonchair)で感覚を掴む - ステップ 2:
torch.compile+ NF4 テキストエンコーダの組み合わせで VRAM をプロファイリング - ステップ 3:
diffuse-compressorで自前モデルを量子化し Hub へ配布 - ステップ 4: QKV fusion などの構造的書き換えアダプタを自作
あわせて読みたい記事
- Google ADK for Kotlin/Android — AI エージェントをアプリ内に直接組み込む方法
- Netflix の AI 進化 — 複雑な Graph Search を自然言語で検索する技術
まとめ
Nunchaku Lite は「4bit 推論 = 専用エンジン」という常識を覆しました。from_pretrained() 一行、ローカルコンパイル不要、既存の Diffusers エコシステム(scheduler、LoRA、offloading、torch.compile)と完全互換。コンシューマー向け GPU で FLUX 級のモデルを動かすことが、現実的な選択肢になったと言えます。
自前で量子化したモデルがあれば、ぜひ Hub で共有してください。同じ試行錯誤を繰り返している開発者が少なくありません。