# 量化感知训练（QAT）

我们与 PyTorch 合作，在 Unsloth 中引入了 QAT（感知量化训练），以启用 **可训练量化** 以尽可能恢复准确性。这比标准的 4 位简单量化在模型质量上有显著提升。QAT 可以恢复多达 **70% 的损失准确度** 并实现 **1–3%** 在 GPQA 和 MMLU Pro 等基准上的模型性能提升。

> **使用我们的免费** [**Qwen3 (4B) 笔记本尝试 QAT**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen3_\(4B\)_Instruct-QAT.ipynb)

### :books:量化

{% columns %}
{% column width="50%" %}
对模型进行简单量化称为 **训练后量化** （PTQ）。例如，假设我们想量化为 8 位整数：

1. 找到 `max(abs(W))`
2. 找到 `a = 127/max(abs(W))` 其中 a 是 int8 的最大范围，即 127
3. 通过以下方式量化 `qW = int8(round(W * a))`
   {% endcolumn %}

{% column width="50%" %}

<figure><img src="/files/7b5351403250a3f4cca10cfae43ea54cb986626e" alt=""><figcaption></figcaption></figure>
{% endcolumn %}
{% endcolumns %}

反量化回 16 位只是通过执行相反操作来实现，即 `float16(qW) / a` 。训练后量化（PTQ）可以大幅减少存储和推理成本，但在用更少位数表示高精度值时常常会降低准确性——尤其是在 4 位或更低时。解决方法之一是使用我们的 [**动态 GGUF 量化**](/docs/zh/ji-chu/unsloth-dynamic-2.0-ggufs.md)，它使用校准数据集来调整量化过程以对重要权重分配更多重要性。另一种方法是使 **量化更智能，通过使其可训练或可学习**!

### :fire:更智能的量化

<div><figure><img src="/files/8a535d43563b43ff27c099c1ecb5d252a1323112" alt=""><figcaption></figcaption></figure> <figure><img src="/files/c9efd8a89af2480dfcf0150ad56727e42d925aee" alt=""><figcaption></figcaption></figure></div>

为实现更智能的量化，我们与 [TorchAO](https://github.com/pytorch/ao) 团队合作，添加了 **感知量化训练（QAT）** 直接集成到 Unsloth 中——现在你可以在 Unsloth 中微调模型，然后直接导出为 4 位 QAT 格式并获得准确性提升！

事实上， **QAT 恢复了 66.9%** 在 GPQA 上的 Gemma3-4B，并将原始准确率提高了 +1.0%。Gemma3-12B 在 BBH 上恢复了 45.5%，并 **将原始准确率提高了 +2.1%**。QAT 在推理期间没有额外开销，并且在磁盘和内存使用上与普通的简单量化相同！因此你可以获得低位量化的所有好处，同时大幅提高准确性！

### :mag:感知量化训练

QAT 通过在训练期间“**伪量化**”权重（可选地也对激活进行伪量化）来模拟真实的量化过程，通常是将高精度值四舍五入为量化值（同时保持高精度数据类型，例如 bfloat16），然后立即对其反量化。

TorchAO 通过首先（1）在线性层中插入伪量化操作，然后（2）在训练后将伪量化操作转换为实际的量化和反量化操作来使 QAT 成为可能，从而使其可用于推理。步骤 1 使我们能够训练出更准确的量化表示。

<figure><img src="/files/45d18f1717a411164ca9be88b4a19e229b4f1e54" alt=""><figcaption></figcaption></figure>

### :sparkles:QAT + LoRA 微调

Unsloth 中的 QAT 还可以与 LoRA 微调结合使用，以同时实现两方面的优势：在训练期间显著减少存储和计算需求，同时缓解量化带来的退化！我们通过 `qat_scheme` 支持多种方法，包含 `fp8-int4`, `fp8-fp8`, `int8-int4`, `int4` 。我们也计划在后续发布中添加 QAT 的自定义定义！

{% code overflow="wrap" %}

```python
from unsloth import FastLanguageModel
model, tokenizer = FastLanguageModel.from_pretrained(
    model_name = "unsloth/Qwen3-4B-Instruct-2507",
    max_seq_length = 2048,
    load_in_16bit = True,
)
model = FastLanguageModel.get_peft_model(
    model,
    r = 16,
    target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",
                      "gate_proj", "up_proj", "down_proj",],
    lora_alpha = 32,
    
    # 我们支持 fp8-int4、fp8-fp8、int8-int4、int4
    qat_scheme = "int4",
)
```

{% endcode %}

### :teapot:导出 QAT 模型

在 Unsloth 中微调后，你可以调用 `model.save_pretrained_torchao` 使用 TorchAO 的 PTQ 格式保存你训练好的模型。你也可以将这些上传到 HuggingFace hub！我们支持任何配置，并计划提供基于文本的方法，使流程对所有人更简单！但首先，我们必须通过以下方式准备 QAT 模型以进行最终转换步骤：

{% code overflow="wrap" %}

```python
from torchao.quantization import quantize_
from torchao.quantization.qat import QATConfig
quantize_(model, QATConfig(step = "convert"))
```

{% endcode %}

现在我们可以选择你想要的 QAT 风格：

{% code overflow="wrap" %}

```python
# 使用与 QAT 完全相同的配置（便捷函数）
model.save_pretrained_torchao(
    model, "tokenizer", 
    torchao_config = model._torchao_config.base_config,
)

# Int4 QAT
from torchao.quantization import Int4WeightOnlyConfig
model.save_pretrained_torchao(
    model, "tokenizer",
    torchao_config = Int4WeightOnlyConfig(),
)

# Int8 QAT
from torchao.quantization import Int8DynamicActivationInt8WeightConfig
model.save_pretrained_torchao(
    model, "tokenizer",
    torchao_config = Int8DynamicActivationInt8WeightConfig(),
)
```

{% endcode %}

然后你可以在 vLLM、Unsloth 及其他系统中运行合并后的 QAT 低精度模型进行推理！这些都在我们提供的 [Qwen3-4B QAT Colab 笔记本](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen3_\(4B\)_Instruct-QAT.ipynb) 中！

### :teapot:在不训练的情况下量化模型

你也可以直接调用 `model.save_pretrained_torchao` 而无需进行任何 QAT！这就是简单的 PTQ 或原生量化。例如，保存为动态 float8 格式如下：

{% code overflow="wrap" %}

```python
# Float8
from torchao.quantization import PerRow
from torchao.quantization import Float8DynamicActivationFloat8WeightConfig
torchao_config = Float8DynamicActivationFloat8WeightConfig(granularity = PerRow())
model.save_pretrained_torchao(torchao_config = torchao_config)
```

{% endcode %}

### :mobile\_phone:ExecuTorch - 面向移动部署的 QAT

{% columns %}
{% column %}
借助 Unsloth 和 TorchAO 的 QAT 支持，你还可以在 Unsloth 中微调模型并无缝导出到 [ExecuTorch](https://github.com/pytorch/executorch) （PyTorch 的设备端推理解决方案）并直接部署到移动设备。请在此处查看一个实际示例 [这里](https://huggingface.co/metascroy/Qwen3-4B-int8-int4-unsloth) ，更多详细的工作流程正在规划中！

**公告即将发布！**
{% endcolumn %}

{% column %}

<figure><img src="/files/e8d5007ecf63bc31e4b15c71ab6ffc04d506d03e" alt=""><figcaption></figcaption></figure>
{% endcolumn %}
{% endcolumns %}

### :sunflower:如何启用 QAT

将 Unsloth 更新到最新版本，并同时安装最新的 TorchAO！

然后 **使用我们的免费试用 QAT** [**Qwen3 (4B) 笔记本尝试 QAT**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen3_\(4B\)_Instruct-QAT.ipynb)

{% code overflow="wrap" %}

```bash
pip install --upgrade --no-cache-dir --force-reinstall unsloth unsloth_zoo
pip install torchao==0.14.0 fbgemm-gpu-genai==1.3.0
```

{% endcode %}

### :person\_tipping\_hand:致谢

非常感谢整个 PyTorch 和 TorchAO 团队的帮助与合作！特别感谢 Andrew Or、Jerry Zhang、Supriya Rao、Scott Roy 和 Mergen Nachin 在 QAT 的许多讨论中提供帮助，并协助将其集成到 Unsloth 中！也感谢 Executorch 团队的贡献！


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://unsloth.ai/docs/zh/bo-ke/quantization-aware-training-qat.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
