# モジュールをフル精度で保持する

量子化により精度が低下するモジュールは、モジュールによって異なります。一部のモジュールを元の精度のままにしておくと、メモリをわずかに消費するだけで、精度の大部分を回復できます。これは、モデルの読み込み時に量子化を行う場合に適用されます。事前量子化済みのチェックポイントには、どのモジュールをスキップしたかが既に記録されています。

## デフォルトでスキップされるモジュール

スキップリストを渡さない場合、ほとんどのメソッドはこれらのモジュールを量子化せずに保持します。

- 出力埋め込み、通常は`lm_head`です。
- `lm_head`と重みを共有する入力埋め込みなど、他の重みに紐付けられた重み。
- モデルの最後のモジュール。
- モデルが`_keep_in_fp32_modules`に列挙するモジュール。

いくつかのメソッドは独自のデフォルトを設定します。[HQQ](./hqq)、[FP-Quant](./fp_quant)、[Four Over Six](./fouroversix)は`lm_head`のみをスキップします。[SINQ](./sinq)は`_keep_in_fp32_modules`内のモジュールのみをスキップします。

## スキップリストを渡す

メソッドのconfigのskip-list引数にモジュール名を渡します。以下の例では、[bitsandbytes](./bitsandbytes)を使用して、`lm_head`とMLPのdown projectionsをbf16で保持します。

```py
from transformers import AutoModelForCausalLM, BitsAndBytesConfig

quantization_config = BitsAndBytesConfig(
    load_in_4bit=True,
    llm_int8_skip_modules=["lm_head", "mlp.down_proj"],
)
model = AutoModelForCausalLM.from_pretrained(
    "Qwen/Qwen3-0.6B",
    quantization_config=quantization_config,
    device_map="auto",
)
```

> [!WARNING]
> スキップリストは、デフォルトのスキップ対象モジュールに追加するのではなく、それらを置き換えます。ただし、`_keep_in_fp32_modules`内のモジュールはスキップされたままです。`lm_head`を量子化しないままにしたい場合は、リストに含めてください。[AWQ](./awq)は例外で、デフォルトにあなたのリストを追加します。

引数の名前はメソッドによって異なります。

| 引数 | メソッド |
|---|---|
| `modules_to_not_convert` | AWQ、EETQ、FBGEMM FP8、Fine-grained FP8、Four Over Six、FP-Quant、HIGGS、Metal、MXFP4、NVFP4、Quanto、SINQ、torchao を含むほとんどの手法 |
| `llm_int8_skip_modules` | 4ビットモードおよび8ビットモードの両方で、bitsandbytes |
| `skip_modules` | HQQ |

[GPTQ](./gptq)は逆のアプローチを採用します。`modules_in_block_to_quantize`は量子化対象のモジュールを列挙し、ブロック内のそれ以外の部分は量子化されません。

## モジュール名を一致させる

ほとんどのメソッドは、`model.named_modules()` からの完全なモジュール名（`model.layers.3.mlp.down_proj` など）とスキップリストの各エントリを照合します。[HQQ](./hqq) は例外で、レイヤー名を正確に照合します。エントリの照合には3つの方法があります。

- サフィックスとして。`mlp.down_proj` は、すべてのレイヤーのダウンプロジェクションに一致します。
- モジュール境界で終わるプレフィックスとして。`model.layers.1` は `model.layers.1.mlp` にマッチしますが、`model.layers.11.mlp` にはマッチしません。
- 同じ境界を持つ正規表現として。`model\.layers\.(0|1)` は最初の2つのレイヤーに一致します。

モジュール名を出力して、適切なエントリを見つけます。

```py
for name, _ in model.named_modules():
    print(name)
```

## スキップするモジュールを選択

丸め誤差が精度に最も影響を与え、かつメモリ削減効果が最も小さいモジュールはスキップします。まずデフォルト設定から始め、タスクでの精度を測定し、精度が低下した場合にのみモジュールを追加してください。

- `lm_head` は語彙内のすべてのトークンに対する logits を生成するため、ここでの誤差は選択されるトークンに直接影響します。デフォルトではスキップされます。大規模な語彙を持つモデルでは、`lm_head` は単一の層として最も大きいものの一つでもあるため、精度が維持される場合、これを量子化することで実際のメモリを節約できます。
- Qwen3-MoEの`mlp.gate`やgpt-ossの`mlp.router`のようなMoEのルーターまたはゲート層は、各トークンをどのエキスパートにルーティングするかを決定します。これらの層は非常に小さく、丸め誤差によってトークンが誤ったエキスパートに送られる可能性があるため、ほぼ常にスキップする価値があります。
- ビジョン言語モデルにおけるビジョンエンコーダーとマルチモーダルプロジェクターは、言語モデルと比較すると規模が小さく、これらのエラーはすべての画像トークンを歪めます。画像理解の性能が低下する場合は、これらをスキップしてください。
- 最初の数層と最後の数層のデコーダー層は、中間の層よりも活性化のアウトライアが多い傾向があります。量子化モデルの精度がbf16と比べて明らかに劣っている場合は、これらの層をスキップしてください。

スキップした各モジュールは元の精度のままメモリを消費します。スキップリストに追加した後に、モデルがまだ収まるか確認してください。

