Transformers 中的细粒度 FP8 量化:配置、DeepGEMM 加速路径与 UE8M0 缩放格式完全指南
【免费下载链接】transformers🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers
Fine-grained FP8 是 🤗 Transformers 提供的一种面向 DeepSeek-V3 / R1 及后续 V4 风格权重的高性能 8-bit 量化方案:权重按 2D 块、激活按 token 分组量化到 FP8,并在 Hopper/Blackwell GPU 上自动切换到 DeepGEMM 快速路径。读完本文你将掌握如何用FineGrainedFP8Config完成加载时量化、保存与重载,理解 DeepGEMM 与 Triton 两条后端的调度规则、nvcc工具链要求、TRANSFORMERS_DISABLE_DEEPGEMM_LINEAR调试开关,以及 UE8M0 压缩缩放格式的来龙去脉。
一、什么是细粒度 FP8 量化
细粒度(fine-grained)FP8 量化把权重(weights)和激活(activations)同时量化到 FP8,从而在保证精度的前提下显著压缩显存占用与访存带宽:
- 权重按 2D 块(block)量化,每块大小为
weight_block_size=(128, 128),即每个 128×128 的权重子矩阵共享一个缩放因子; - 激活按“每个 token 一组”量化,其分组宽度与权重在输入通道维度上的分块一致(默认 128),两者对齐后可以高效完成逐块的矩阵乘。
从源码实现看,权重张量以torch.float8_e4m3fn存储,块级缩放因子weight_scale_inv的形状为(ceil(out/128), ceil(in/128)),见 finegrained_fp8.py 中FP8Linear的参数分配逻辑。
这一方案最初正是为 FP8 推理场景下的 DeepSeek-V3 与 DeepSeek-R1 设计的(FineGrainedFP8Config的类注释也写明“used mainly for deepseek models”,见 quantization_config.py),同时兼容标准稠密模型与 MoE 模型:前者替换为FP8Linear/FP8Embedding,后者使用专门的FP8Experts专家容器,并可进一步支持 V4 风格的 FP4 打包专家权重。
[!TIP] 需要一块 Compute Capability ≥ 9 的 GPU(如 H100 / B200),并安装与你 GPU CUDA 版本兼容的 PyTorch。需要注意,量化器的环境校验实际上对 Compute Capability ≥ 8.9(如 RTX 4090)也会放行;低于该门槛或缺少 GPU/XPU 时,加载预量化 checkpoint 会告警并默认反量化回 bf16,而“边加载边量化”(on-the-fly)模式则会直接抛错。
二、环境准备与安装
首先升级 Accelerate 与 PyTorch 到最新版本:
pip install --upgrade accelerate torch其中accelerate是必须依赖——量化器在validate_environment中会显式检查is_accelerate_available(),缺失时直接抛出ImportError(见 quantizer_finegrained_fp8.py)。
如果你想启用后续的 DeepGEMM 快速路径,还需额外安装kernels包(见下文第三节):
pip install -U kernels三、5 分钟上手:加载时量化
构造一个FineGrainedFP8Config实例并传给from_pretrained即可在加载时把模型量化到 FP8。默认情况下权重会以全精度(torch.float32)加载;设置dtype="auto"可让权重按模型config.json中声明的数据类型加载,自动采用最省内存的数据类型。
from transformers import FineGrainedFP8Config, AutoModelForCausalLM, AutoTokenizer model_name = "meta-llama/Meta-Llama-3-8B" quantization_config = FineGrainedFP8Config() quantized_model = AutoModelForCausalLM.from_pretrained( model_name, dtype="auto", device_map="auto", quantization_config=quantization_config, ) tokenizer = AutoTokenizer.from_pretrained(model_name) input_text = "What are we having for dinner?" input_ids = tokenizer(input_text, return_tensors="pt").to(quantized_model.device.type) output = quantized_model.generate(**input_ids, max_new_tokens=10) print(tokenizer.decode(output[0], skip_special_tokens=True))整个加载流程由FineGrainedFP8HfQuantizer驱动(注册于 quantizer_finegrained_fp8.py):在权重加载前,通过replace_with_fp8_linear把目标nn.Linear替换成FP8Linear(必要时替换 embedding 为FP8Embedding),并在param_needs_quantization中识别FP8Linear/FP8Experts上的待量化参数(bias 不量化)。该量化器requires_calibration=False、is_trainable=False,即纯推理场景,同时is_compileable=True,可与torch.compile配合使用。
几点来自源码的加载约束,值得提前知晓:
- 不要在 on-the-fly 量化的 device_map 中混入
"cpu"/"disk"设备——若pre_quantized=False且device_map含多个设备且包含 cpu/disk,会直接抛ValueError(见 validate_environment)。预量化 checkpoint 不受此限制。 - 加载 FP8 模型后如果没有显式设置
device_map,量化器会提示你把它放到 GPU/XPU 上运行。
四、FineGrainedFP8Config 参数详解
FineGrainedFP8Config的全部可配置项及其默认值如下表(依据 配置类实现 整理):
| 参数 | 类型 | 默认值 | 含义 |
|---|---|---|---|
activation_scheme | str | "dynamic" | 激活量化方案。目前默认且最常用的是"dynamic"(逐 token 动态量化);也接受"static",但静态激活量化永远走 Triton 路径(DeepGEMM 仅支持 dynamic),且需要额外的逐张量激活缩放参数activation_scale |
weight_block_size | tuple[int, int] | (128, 128) | 权重 2D 分块大小,即 (块的行数, 块的列数),必须为两个正整数 |
dequantize | bool | False | 加载时是否反量化模型。置True时会把权重按块级缩放还原为 bf16(常用于无 FP8 硬件环境) |
modules_to_not_convert | list | None | 量化时跳过、不转换的模块名列表;MiniMax 系列 checkpoint 以ignored_layers命名该字段,配置类将其作为别名兼容接收 |
modules_to_convert | list | None | 额外指定需要转换的模块名(如 embedding 表),仅在pre_quantized时生效 |
scale_fmt | str | "float" | 逐块权重缩放因子的存储格式:"float"表示 fp32(V3 风格),"ue8m0"表示 1 字节的torch.float8_e8m0fnu(V4 风格,见第五节) |
post_init()会对这些参数做合法性校验(见 quantization_config.py):
activation_scheme会被小写化,仅允许"dynamic"或"static",否则抛ValueError;weight_block_size必须是长度为 2、且两个元素都为正整数的元组;scale_fmt仅允许"float"或"ue8m0"。
另外该配置类也提供了from_dict/to_dict等序列化能力,便于你从config.json中的quantization_config字段读取预量化 checkpoint 的配置。
五、保存与重新加载量化模型
用save_pretrained保存量化后的模型,之后随时可用from_pretrained直接重载(checkpoint 自带 FP8 权重与量化配置,无需再次传quantization_config):
quant_path = "/path/to/save/quantized/model" quantized_model.save_pretrained(quant_path) model = AutoModelForCausalLM.from_pretrained(quant_path, device_map="auto")预量化 checkpoint 反量化(dequantize=True)时,量化器会通过WeightConverter+Fp8Dequantize把逐块缩放折叠进权重:它会把weight$/weight_scale_inv收进同一个转换桶并前置反量化算子,同时兼容部分 checkpoint 把逐块缩放存放在.scale键下的命名差异(统一重命名为.weight_scale_inv),详见 get_weight_conversions / update_weight_conversions。
六、DeepGEMM 快速路径
6.1 触发条件与性能
在 Hopper(SM90+)与 Blackwell(SM100+)GPU 上,当满足以下条件时,每个 FP8 线性层都会自动分发到 DeepGEMM kernel(来自 kernels-community 的 DeepGEMM 内核,由kernels包提供):
weight_block_size=(128, 128),且activation_scheme="dynamic"。
根据文档说明,DeepGEMM 比 Triton 回退路径快3–6 倍。从 fp8_linear 的分发逻辑 可以看到完整的deepgemm_preferred判定还包含:DeepGEMM 可加载、未显式传入静态激活缩放、Blackwell 上不能是 fp32 缩放与 FP8 块权的组合,以及未设置禁用环境变量。若 DeepGEMM 对该次调用不可用或拒绝(例如架构/输入组合没有对应 kernel),会自动回退到 Triton 的 finegrained-fp8 kernel 并只打印一次告警。整个 FP8 后端的入口实现在 finegrained_fp8.py,而 DeepGEMM 侧的封装(deepgemm_fp8_fp4_linear、分组/批处理专家 GEMM 等)在 deepgemm.py。
启用方式:
pip install -U kernels6.2 nvcc 工具链要求
DeepGEMM 会使用系统的nvcc对 kernel 做 JIT 编译,因此必须安装完整 CUDA 工具包——仅有运行时的 CUDA 库(没有nvcc)无法工作。工具包最低版本取决于硬件:
- Hopper(SM90):CUDA Toolkit 12.3 或更高;
- Blackwell(SM100):CUDA Toolkit 12.9 或更高。
Transformers 按以下顺序定位工具包:检查CUDA_HOME→CUDA_PATH→PATH中的nvcc→/usr/local/cuda。如果nvcc未被自动发现,请把CUDA_HOME显式设置为工具包根目录,例如:
export CUDA_HOME=/usr/local/cuda6.3 加载失败时的行为与强制回退
如果 kernel 无法加载(缺少kernels包、GPU 架构不支持、没有 CUDA 工具包,或nvcc版本低于要求),Transformers 会记录一次告警并回退到 Triton 的 finegrained-fp8 kernel,不会中断加载。静态(static)激活量化则始终留在 Triton 路径上。
即使 DeepGEMM 可用,你也可以强制走 Triton 回退:
TRANSFORMERS_DISABLE_DEEPGEMM_LINEAR=1 python your_script.py该环境变量只影响 FP8 线性层的分发,不会触碰"deepgemm"专家后端——后者的切换请使用PreTrainedModel.set_experts_implementation。
6.4 与 MoE 专家后端的配合
对 MoE 模型,DeepGEMM 路径是可选项(opt-in):加载时传入experts_implementation="deepgemm"(Blackwell 上还可选"deepgemm_megamoe")即可把专家矩阵乘路由到 DeepGEMM。FP8Experts容器在源码中维护着一张_impl_tp_layer_overrides映射,用于按实现重写 TP/EP 并行计划中的层级类型(见 finegrained_fp8.py),量化器在update_tp_plan中会把专家缩放与权重一并切分。更多后端选项参见 专家后端指南。
内部实现注意:若单个进程内模型跨多个 CUDA 设备,DeepGEMM 的 kernel 因绑定单一 CUDA context 会产生错误结果,加载器会通过
_disable_deepgemm_on_multi_device自动把这类模型改走 Triton / grouped_mm(见 quantizer_finegrained_fp8.py)。
七、UE8M0 缩放格式(V4 风格 checkpoint)
DeepSeek-V4 风格的 checkpoint 把 FP8 权重缩放以打包的float8_e8m0fnu格式存储,而不再是float32。这类 checkpoint 是预量化的,并在其quantization_config中声明scale_fmt="ue8m0"。由于 DeepGEMM 与 Triton 两种 kernel 都能原生读取 UE8M0 缩放,这类 checkpoint 在任一路径上都可以运行。
源码侧的关键实现点:
_get_ue8m0_dtype()返回torch.float8_e8m0fnu,该 dtype 需要PyTorch ≥ 2.7,否则会抛出明确错误(见 finegrained_fp8.py);- 以 UE8M0 存储时,
FP8Linear的weight_scale_inv参数会以该 dtype 分配且不可训练(非浮点,requires_grad=False),见 FP8Linear.init; - 部分 checkpoint 把幂次风格的 UE8M0 缩放以 float32 容器存放(键名
.scale),权重加载后量化器会把它们精确转换为 kernel 期望的 UE8M0 dtype(见 quantizer_finegrained_fp8.py)。
一个需要注意的硬件差异:在 **Blackwell(SM100+)**上,DeepGEMM 专家 kernel只支持 UE8M0 缩放。使用普通float32缩放(scale_fmt="float")的 checkpoint 会直接抛出ValueError。此时你有两种选择:
- 换用
scale_fmt="ue8m0"的 checkpoint; - 用
grouped_mm或batched_mm来运行专家,这两种实现可直接支持 fp32 缩放。
而在Hopper(SM90+)上,DeepGEMM 路径无需转换即可直接支持 fp32 缩放。专家后端选项的完整说明同样见 专家后端指南。
补充:源码对 FP8 线性层在 Blackwell + fp32 缩放 + 128 块权重的组合做了前置拦截——DeepGEMM 会把 fp32 缩放向上取整成 UE8M0 而不重新量化,静默损坏输出,因此会直接跳过 DeepGEMM 走 Triton,而不是尝试后再回退(见 fp8_linear 注释)。
八、源码级工作流与验证
把整个 FP8 加载链路串起来看,一次from_pretrained大致经历:
AutoHfQuantizer依据quantization_config的quant_method(FP8)选择FineGrainedFP8HfQuantizer;validate_environment检查 accelerate、硬件与 device_map 合法性;_process_model_before_weight_loading:处理modules_to_not_convert的命名归一(通过conversion_mapping的权重重命名把发布版模型的 skip-list 映射到本仓库实际层名),再执行replace_with_fp8_linear(必要时replace_with_fp8_embedding);- 权重流经
get_quantize_ops()返回的Fp8Quantize(on-the-fly 量化)或模型自带的WeightConverter加载链路;预量化 +dequantize=True时插入Fp8Dequantize将权重还原; _process_model_after_weight_loading:处理 UE8M0 dtype 转换与多设备 DeepGEMM 禁用;- 前向时
FP8Linear.forward判断权重若仍为高精度则走普通F.linear,否则进入fp8_linear完成 DeepGEMM/Triton 分发。
仓库的量化测试覆盖了上述大部分行为,包括配置合法性、dequantize反量化、weight_block_size=(32, 32)等非默认分块、无 GPU 环境下的降级路径以及 DeepGEMM 多设备禁用开关,见 tests/quantization/finegrained_fp8/test_fp8.py。
九、常见问题速查
- 加载时提示缺少 accelerate→
pip install --upgrade accelerate。 ValueError: Activation scheme xxx not supported→activation_scheme只能取"dynamic"或"static"。- 提示 nvcc / CUDA toolkit 找不到→ 确认安装了完整 CUDA 工具包(含
nvcc),并把CUDA_HOME指向工具包根目录;Hopper 需 ≥ 12.3,Blackwell 需 ≥ 12.9。 - 没有走 DeepGEMM 而打了回退告警→ 检查是否满足
weight_block_size=(128, 128)+activation_scheme="dynamic"、GPU 是否为 SM90+,以及TRANSFORMERS_DISABLE_DEEPGEMM_LINEAR是否被误设为 1。 - Blackwell 上 UE8M0 checkpoint 报错→ 确认 checkpoint 的
scale_fmt为"ue8m0",或将专家实现切换为grouped_mm/batched_mm。 - 加载 FP8 模型很慢或报 FP8 dtype 错误→ 确认 PyTorch 版本 ≥ 2.7(UE8M0 需要
torch.float8_e8m0fnu),并与 GPU 的 CUDA 驱动匹配。
【免费下载链接】transformers🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考