# BFL (fp8r / nvfp4)

[Black Forest Labs](https://huggingface.co/black-forest-labs)は、[Flux3](../api/pipelines/flux3) transformersの量子化版を2つのスキームで提供しています。これらは、元のbf16重みの隣に単一ファイルのチェックポイントとして保存されています。

- `fp8r`: rowwise FP8。各量子化線形層は、E4M3 の `weight` と、行ごとの fp32 の `weight_scale` を保存します。アクティベーションは、実行時に E4M3 へ行ごとに量子化されます。
- `nvfp4`: [ModelOpt](https://github.com/NVIDIA/Model-Optimizer) レイアウトの NVFP4。各量子化線形層は、パックされた E2M1 `weight`（1 バイトあたり 2 値）、16 個の E4M3 ブロックスケール（`weight_scale`）、グローバルな fp32 `weight_scale_2`、およびキャリブレーション済みの fp32 アクティベーションスケール `input_scale` を保存します。

Diffusers は、[BFLQuantizationConfig](/docs/diffusers/v0.43.0/ja/api/quantization#diffusers.BFLQuantizationConfig) を使用して `~FromSingleFileMixin.from_single_file` 経由で両方をロードします。スキームはチェックポイントから読み取られるため、どちらのファイルに対しても同じ設定が適用できます。プリクオンタイズ済みチェックポイントのロードのみがサポートされており、パイプラインレベルでのロードはサポートされていません。

以下の例では、モデルリポジトリ内の `variants/fp8r/model.safetensors` にある [FLUX 3 Image Klein Base](https://huggingface.co/black-forest-labs/flux-3-image-klein-base) の `fp8r` チェックポイントをロードします。`config` を渡すことで、そのリポジトリの Diffusers フォルダからモデル設定を読み込み、その後、他のコンポーネントを名前指定でロードします（[Single-file loading](../api/pipelines/flux3#single-file-loading) を参照）。

```python
import torch

from diffusers import BFLQuantizationConfig, Flux3Transformer2DModel, ModularPipeline

ckpt_path = "https://huggingface.co/black-forest-labs/flux-3-image-klein-base/blob/main/variants/fp8r/model.safetensors"
transformer = Flux3Transformer2DModel.from_single_file(
    ckpt_path,
    config="black-forest-labs/flux-3-image-klein-base",
    subfolder="transformer",
    quantization_config=BFLQuantizationConfig(compute_dtype=torch.bfloat16),
    dtype=torch.bfloat16,
)
pipe = ModularPipeline.from_pretrained("black-forest-labs/flux-3-image-klein-base")
pipe.load_components(dtype=torch.bfloat16)
pipe.update_components(transformer=transformer)
pipe.to("cuda")

prompt = "A wide-angle wildlife photograph of a red fox standing alert in a snow-covered forest clearing at golden hour."
image = pipe(prompt=prompt, generator=torch.Generator().manual_seed(0), output="images")[0]
image.save("flux3-klein-base-fp8r.png")
```

`variants/fp8r` を `variants/nvfp4` に置き換えて、`nvfp4` バリアントを読み込みます。ステップ蒸留済みの [FLUX 3 Image Klein](https://huggingface.co/black-forest-labs/flux-3-image-klein) には同じ 2 つのバリアントが同梱されており、リポジトリ ID を `config` およびパイプラインとして指定して読み込みます。

## カーネル

量子化された重みは、低精度のストレージ dtype のまま保持されます。どの GEMM が実行されるかは、デバイスによって異なります。

| スキーム | Fused kernel | 要件 |
|---|---|---|
| `fp8r` | rowwise スケール付きの`torch._scaled_mm` | 計算能力 8.9 以上の CUDA GPU |
| `nvfp4` | `flashinfer.mm_fp4` (CUTLASS) と、アクティベーション用の `flashinfer.nvfp4_quantize` | Blackwell GPU（compute capability 10.0 以上）、`nvcc` を備えた CUDA toolkit、および同じバージョンの `flashinfer-python` と `flashinfer-cubin` |

FlashInfer の 2 つのパッケージを同じバージョンでインストールしてください。例えば `pip install flashinfer-python==0.6.13 flashinfer-cubin==0.6.13` のようにします。`flashinfer-cubin` のリリースは `flashinfer-python` より遅れることがあり、バージョンが一致しない場合、FlashInfer はインポートを拒否します。

FlashInfer は、初回使用時に環境の CUDA ツールキットで NVFP4 カーネルをコンパイルし、ターゲットアーキテクチャは表示されている GPU から選択します（`FLASHINFER_CUDA_ARCH_LIST` が設定されている場合は、そこから選択します）。コンシューマーおよびワークステーション向けの Blackwell GPU（compute capability 12.0）には、CUDA ツールキット 12.9 以降が必要です。古いツールキットを使用している場合、FlashInfer は対象となるアーキテクチャを見つけられず、最初の NVFP4 呼び出しが `FlashInfer requires GPUs with sm75 or higher` というエラーで失敗します。

その他のデバイスでは、各フォワードパスにおいて重みが`compute_dtype`にデクォンタイズされ、そのレイヤーは通常の線形レイヤーとして実行されます。その場合、アクティベーションはクォンタイズされないため、出力はフュージョンカーネルの結果とわずかに異なります。

