☰
ComfyUI 量化完全指南:从量化原理到 FP8/INT8 量化检查点制作与加载
2026/9/30 12:57:52 网站建设 项目流程
  • 人工智能
  • 大模型
  • 媒体生成
  • 本地部署

【免费下载链接】ComfyUI

The most powerful and modular diffusion model GUI, api and backend with a graph/nodes interface. The fastest local inference engine in the world.

项目地址:https://gitcode.com/GitHub_Trending/co/ComfyUI
点击查看免费下载

本篇技术指南以仓库 QUANTIZATION.md 为核心骨架,围绕 ComfyUI 的量化体系展开:先讲清量化的数学原理(per-tensor 绝对最大缩放),再深入到QuantizedTensor派生子类与双级注册表的分发机制,继而剖析MixedPrecisionOps的逐层混合精度策略、量化检查点的 safetensors 存储格式与_quantization_metadata元数据规范,最后给出权重量化与激活量化(PTQ 校准)的完整制作流程。读完你不仅能读懂 ComfyUI 中的量化代码与检查点结构,还能依据本指南制作出兼容 ComfyUI 加载规范的量化检查点。

量化的基本原理:为什么要引入缩放因子

量化(Quantization)的目标是把高精度数值x_f映射到低精度格式,同时把精度损失控制到最小。更小的数据格式一方面显著降低模型的内存占用,另一方面可以借助专用的硬件指令(如 NVIDIA 的 FP8 Tensor Core)提升推理吞吐。

直接使用 round-nearest(四舍五入)把 FP16 数值转成 FP8 会遇到两个典型问题:

  • 动态范围不匹配导致截断(clipping):FP16 的动态范围约为 (-65,504, 65,504),而 FP8 的 E4M3 格式只有 (-448, 448),E5M2 格式为 (-57,344, 57,344)。超出低精度格式表示范围的数值会被直接截断,引入大误差。
  • 有效位浪费:如果原始数值集中在很小的范围(例如 -1 到 1),直接转换后 FP8 的大部分编码位处于"闲置"状态,精度带宽被浪费。

解决思路是引入缩放因子(scaling factor),把原始数值先缩放进量化 dtype 的完整动态范围,用满整个编码空间。最常用且最简单的方案是per-tensor 绝对最大值(absolute-maximum)缩放:

absmax = max(abs(tensor)) scale = absmax / max_dynamic_range_low_precision # 量化 tensor_q = (tensor / scale).to(low_precision_dtype) # 反量化 tensor_dq = tensor_q.to(fp16) * scale # tensor_dq ≈ tensor

由于量化后的数值必须结合缩放因子才能"还原"含义,这类带附加元数据的数据类型在 ComfyUI 中被称作派生数据类型(derived datatypes)。

ComfyUI 中的量化架构总览

ComfyUI 的量化运行时是一条清晰的分发流水线,见 comfy/quant_ops.py 与 comfy/ops.py:

QuantizedTensor (torch.Tensor subclass) ↓ __torch_dispatch__ Two-Level Registry (generic + layout handlers) ↓ MixedPrecisionOps + Metadata Detection

整体流程是:QuantizedTensor作为torch.Tensor的派生子类承载量化数据,通过__torch_dispatch__拦截算子调用;两级注册表(通用注册表 + 布局专属注册表)决定每个算子走哪条实现路径;最终由MixedPrecisionOps与量化元数据检测驱动逐层混合精度的加载与执行。

表示层:QuantizedTensor 与 Layout

为了表示派生数据类型,ComfyUI 使用torch.Tensor的子类QuantizedTensor。从源码结构看,comfy/quant_ops.py在成功导入comfy_kitchen时直接复用其后端实现,导入失败时则提供占位类并输出日志fp8 and fp4 support will not be available(comfy/quant_ops.py),说明 FP8/FP4 支持是可选依赖。

Layout 类定义了某种量化格式的完整行为契约(QUANTIZATION.md):

  • 必需参数(Required parameters)
  • 量化方法(Quantize)
  • 反量化方法(De-Quantize)

自定义一个布局的模板如下:

from comfy.quant_ops import QuantizedLayout class MyLayout(QuantizedLayout): @classmethod def quantize(cls, tensor, **kwargs): # Convert to quantized format qdata = ... params = {'scale': ..., 'orig_dtype': tensor.dtype} return qdata, params @staticmethod def dequantize(qdata, scale, orig_dtype, **kwargs): return qdata.to(orig_dtype) * scale

在 comfy/quant_ops.py 中可以找到几个真实布局类:

  • TensorCoreFP8E4M3Layout/TensorCoreFP8E5M2Layout:继承_TensorCoreFP8LayoutBase,分别以torch.float8_e4m3fn/torch.float8_e5m2存储,支持scale="recalculate"动态重算缩放、随机舍入(stochastic rounding)与就地操作;其中 E4M3 布局通过TensorCoreFP8Layout = TensorCoreFP8E4M3Layout保留向后兼容别名。
  • TensorCoreNVFP4Layout:以uint8容器存储 NVFP4 数据,要求 2D 张量,内部还会做 16 的倍数维度 padding,并额外携带block_scale。
  • TensorCoreMXFP8Layout:MXFP8 块级缩放格式(需要较新版本的comfy_kitchen,且仅支持 2D 张量,按 32 对齐 padding)。
  • TensorWiseINT8Layout、TensorCoreConvRotW4A4Layout、AsymW4A8Int8Layout:INT8 系列布局,分别对应逐张量 INT8、W4A4 旋转、非对称 W4A8 等量化方案。

分发层:双级注册表与torch_dispatch

要让这些QuantizedTensor真正参与运算,ComfyUI 使用了两级注册表来定义支持的操作(QUANTIZATION.md):

  1. 通用注册表(generic registry):处理所有量化格式共有的操作,例如.to()、.clone()、.reshape()。
  2. 布局专属注册表(layout-specific registry):允许为特定布局注册快速路径,例如nn.Linear的专用核。
from comfy.quant_ops import register_layout_op @register_layout_op(torch.ops.aten.linear.default, MyLayout) def my_linear(func, args, kwargs): # Extract tensors, call optimized kernel ...

当torch.nn.functional.linear()收到QuantizedTensor参数时,__torch_dispatch__会自动路由到已注册的实现。对于任何未注册的操作,QuantizedTensor会回退到先dequantize、再以高精度实现分发——这正是"正确性兜底"的设计:没有快速路径的算子永远不会算错,只会慢一些。

此外,comfy/quant_ops.py底部维护了一张QUANT_ALGOS注册表(comfy/quant_ops.py),它把检查点元数据中的人类可读格式字符串映射到具体布局类、存储 dtype 和所需参数:

格式字符串存储 dtype所需参数布局类
float8_e4m3fntorch.float8_e4m3fnweight_scale,input_scaleTensorCoreFP8E4M3Layout
float8_e5m2torch.float8_e5m2weight_scale,input_scaleTensorCoreFP8E5M2Layout
nvfp4torch.uint8weight_scale,weight_scale_2,input_scale,pre_quant_scale(group_size=16)TensorCoreNVFP4Layout
mxfp8(需 comfy_kitchen 支持)torch.float8_e4m3fnweight_scale,input_scale(group_size=32)TensorCoreMXFP8Layout
int8_tensorwisetorch.int8weight_scale(不量化输入)TensorWiseINT8Layout
convrot_w4a4torch.int8weight_scale(不量化输入)TensorCoreConvRotW4A4Layout
asym_w4a8_int8torch.int8weight_scale(不量化输入)AsymW4A8Int8Layout

创建兼容检查点时,格式字符串必须能在QUANT_ALGOS中找到对应定义。

混合精度:MixedPrecisionOps 逐层量化决策

MixedPrecisionOps类(源码中位于 comfy/ops.py,文档描述的行号 542-648 对应旧版本)实现了逐层量化决策:同一个模型的不同层可以使用不同精度。它由模型配置中的layer_quant_config(实际源码中为quant_config)字典激活——该字典指定哪些层需要量化、用什么格式量化。

架构骨架:

class MixedPrecisionOps(disable_weight_init): _layer_quant_config = {} # Maps layer names to quantization configs _compute_dtype = torch.bfloat16 # Default compute / dequantize precision

核心机制:

自定义的Linear._load_from_state_dict()在模型加载阶段逐层检查(comfy/ops.py):

  • 若层名不在量化配置中:以普通张量按_compute_dtype加载权重;
  • 若层名在量化配置中:把权重加载为QuantizedTensor,使用指定布局(如TensorCoreFP8Layout),同时加载对应的量化参数(scales、block_size 等)。

与之配套,forward()在推理时还会根据pre_quant_scale对输入做 AWQ 风格平滑(smoothing),把高维输入 reshape 成 2D 再量化,并在输出后恢复原始维度;对于input_scale场景,输入激活也会被量化为QuantizedTensor(comfy/ops.py)。

为什么需要它:

并非所有层都能承受同等程度的量化。最终投影等敏感操作可以保持高精度,而计算密集的 matmul 层则量化到 FP8/INT8。这样既拿到大部分性能收益,又守住生成质量。

选择时机:

该模式在pick_operations()中被选中:当model_config.quant_config存在时,它作为最高优先级的操作模式启用(comfy/ops.py)。quant_config的来源是模型加载时的自动检测——comfy/model_detection.py 调用comfy.utils.detect_layer_quantization(state_dict, unet_key_prefix)扫描 state_dict,一旦发现量化层就把结果写入model_config.quant_config。文本编码器与音频模型也复用同一机制,例如 comfy/sd1_clip.py 从model_options["quantization_metadata"]取出配置后调用mixed_precision_ops(quant_config, dtype, full_precision_mm=True)。

量化检查点格式

量化检查点与普通模型一样存储为标准 safetensors 文件,但包含量化权重张量、关联的缩放参数,以及一段描述量化方案的_quantization_metadataJSON 元数据。

与原始检查点相比,量化检查点具有以下特点:

  • 权重以量化值存储,有时使用不同的存储 dtype——例如 FP8 用uint8容器承载(nvfp4即torch.uint8,见QUANT_ALGOS);
  • 每个量化权重旁边会按配方(recipe)存储若干额外的缩放参数;
  • 最终 safetensors 的元数据中写入_quantization_metadata,说明哪些层被量化、使用了什么布局。

缩放参数细节

标准定义了 4 种缩放参数,覆盖近期绝大多数配方(QUANTIZATION.md):

  • weight_scale:权重的量化缩放因子
  • weight_scale_2:双重缩放(double scaling)语境下的全局缩放因子
  • pre_quant_scale:用于平滑突出权重(salient weights)的缩放因子
  • input_scale:激活值的量化缩放因子

对应关系如下:

格式存储 dtypeweight_scaleweight_scale_2pre_quant_scaleinput_scale
float8_e4m3fnfloat32float32(标量)--float32(标量)

所有已定义格式的完整参数集合可在 comfy/quant_ops.py 的QUANT_ALGOS中查到。

量化元数据(_quantization_metadata)

与检查点一同存储的元数据包含:

  • format_version:字符串,定义该标准规范的版本;
  • layers:字典,把层名映射到其量化格式。格式字符串与QUANT_ALGOS中的定义一一对应。

示例:

{ "_quantization_metadata": { "format_version": "1.0", "layers": { "model.layers.0.mlp.up_proj": {"format": "float8_e4m3fn"}, "model.layers.0.mlp.down_proj": {"format": "float8_e4m3fn"}, "model.layers.1.mlp.up_proj": {"format": "float8_e4m3fn"} } } }

创建量化检查点

创建兼容检查点的通用要求:使用任何量化工具均可,但输出必须符合上述检查点格式规范,且布局必须定义在QUANT_ALGOS中。

扩散模型注意力偏好(Attention Preferences)

扩散注意力模块可以携带一个<module path>.comfy_attention.config条目,其内容为 uint8 张量包裹的 UTF-8 JSON:

{"attention": "comfy_kitchen_int8"}

应用在真正执行注意力的模块上,例如 Qwen Image 2.1 的transformer_blocks.0.attn,或 MiniMax H3 的blocks.0.attn。需要注意的边界行为:

  • 目前仅支持comfy_kitchen_int8;无效目标与其他方法名在加载时会被忽略并给出警告,退回正常的注意力选择;
  • Kitchen INT8 支持度在每条偏好加载时按主设备检查,不支持的设备保持正常注意力选择;
  • 显式的注意力覆盖(explicit attention overrides)优先级更高;
  • ComfyAttention子模块通过常规的 state-dict 加载/保存机制自行读写元数据;
  • 注意力偏好不启用权重量化;文本编码器与 VAE 加载器不应用这些偏好。

权重量化(Weight Quantization)

权重量化比较直接——用前文提到的绝对最大值方法,直接从权重张量计算缩放因子。每个层的权重独立量化,并与对应的weight_scale参数一同存储。

校准:激活量化(Calibration for Activation Quantization)

激活量化(例如 FP8 Tensor Core 运算所需的input_scale)无法只凭静态权重确定,因为激活值取决于真实输入。因此需要训练后量化校准(post-training calibration,PTQ):

  1. 收集统计量:在 N 个代表性样本上运行推理;
  2. 追踪激活:记录每个被量化层输入的绝对最大值(amax);
  3. 计算缩放:由收集的统计量推导input_scale;
  4. 写入检查点:把input_scale参数与权重一同保存。

校准数据集必须能代表目标使用场景——对扩散模型而言,通常意味着覆盖多样的提示词与生成参数组合。

运行前提与限制

  • FP8/FP4 快速路径依赖可选依赖comfy_kitchen;未安装时 ComfyUI 会降级处理并提示fp8 and fp4 support will not be available(comfy/quant_ops.py)。
  • CUDA 优化算子要求 PyTorch cu130 及以上;低于该版本时ck.registry.disable("cuda")会被调用并输出升级警告(comfy/quant_ops.py)。AMD(HIP)与 NVIDIA(CUDA)后端在导入时自动选择,Triton 后端默认关闭、可用--enable-triton-backend等命令行参数显式启用。
  • pick_operations()的完整选择顺序是:存在quant_config时优先使用混合精度 ops → 支持 FP8 计算且开启 FP8 优化时使用fp8_ops→ 满足条件时使用cublas_ops→ 权重 dtype 与计算 dtype 一致时使用disable_weight_init→ 否则回退manual_cast(comfy/ops.py)。

小结

ComfyUI 的量化体系由三层构成:原理层(per-tensor 绝对最大缩放)、表示与分发层(QuantizedTensor+ Layout + 双级注册表 +__torch_dispatch__)、以及加载决策层(MixedPrecisionOps+_quantization_metadata自动检测)。量化检查点以标准 safetensors 承载量化权重与 4 类缩放参数,通过_quantization_metadata描述逐层格式。制作兼容检查点时,权重量化简单直接,而涉及激活量化的方案必须走 PTQ 校准流程;运行侧则要满足comfy_kitchen与 PyTorch 版本等前提条件。这套设计让"大部分层量化、敏感层保精度"的混合精度策略成为可能,是 ComfyUI 在保持出图质量的同时压榨推理性能的关键机制。

  • 人工智能
  • 大模型
  • 媒体生成
  • 本地部署

【免费下载链接】ComfyUI

The most powerful and modular diffusion model GUI, api and backend with a graph/nodes interface. The fastest local inference engine in the world.

项目地址:https://gitcode.com/GitHub_Trending/co/ComfyUI
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询