ValueError: Custom filter_fn and FqnToConfig were both specified. Only filter_fn=None is supported when FqnToConfig is specified.

这个报错通常出现在用 TorchAoConfig 包裹 FqnToConfig 并对 Diffusers 模型(例如 Flux2Transformer2DModel)做量化加载时。根本原因是 Diffusers 在调用 torchao 的 quantize_ 时同时传入了自定义 filter_fn

快速结论:这个报错通常出现在用 TorchAoConfig 包裹 FqnToConfig 并对 Diffusers 模型(例如 Flux2Transformer2DModel)做量化加载时。根本原因是 Diffusers 在调用 torchao 的 quantize_ 时同时传入了自定义 filter_fnFqnToConfig,而 torchao 只允许在 FqnToConfig 模式下将 filter_fn 设为 None。优先排查 Diffusers 的 torchao 量化调用路径,而不是量化配置本身的写法。

适用环境:Issue 中确认的环境:Diffusers 0.40.0.dev0,Python 3.12.13,PyTorch 2.13.0+rocm7.2,torchao 0.17.0+rocm7.2,Transformers 5.5.4,Huggingface_hub 1.24.0,Accelerate 1.12.0,PEFT 0.18.1,bitsandbytes 0.49.2,optimum-quanto 0.2.7,Safetensors 0.8.0,xFormers 未安装;平台为 Linux x86_64,非 Colab,未使用分布式/并行。

最快修复方案:暂无确认的一步修复方案。Issue 中维护者提供了 PR #14686 作为候选修复,报告者确认该 PR 的改动方向看起来有希望,但讨论链中没有明确写出已验证通过的最终结论。可优先尝试升级到包含 PR #14686 的 Diffusers 版本,或按该 PR 调整 Diffusers 的 torchao 调用逻辑,使使用 FqnToConfig 时不再传入自定义 filter_fn

注意事项:不要只在业务代码中把 filter_fn 改成 None 来绕过,因为报错发生在 Diffusers 内部调用 quantize_ 的位置,用户代码通常无法直接控制那个参数。Issue 中提到 Transformers 已有更完善的处理方式,但 Diffusers 侧的具体实现需要以合入的 PR 为准;在修复合并并验证前,建议先确认该 PR 是否已进入你使用的 Diffusers 版本。

问题场景

用户在 Diffusers 中加载 FLUX.2-klein-4B 的 transformer(Flux2Transformer2DModel),并通过 from_pretrainedquantization_config=TorchAoConfig(FqnToConfig(...)) 指定按模块名正则匹配不同量化策略(FF 层用 Int8WeightOnlyConfig + PerTensor,attention 层用 Int8WeightOnlyConfig + PerGroup(64))。加载过程中触发报错,量化流程中断。同一用户在 issue 中确认:直接用 torchao 的 quantize_ 对该模型量化可以正常完成,说明问题出在 Diffusers 对 quantize_ 的调用方式上。

报错原文

Traceback (most recent call last):
  File "/tmp/reproduce.py", line 9, in <module>
    _t = Flux2Transformer2DModel.from_pretrained(
  ...
  File ".../diffusers/quantizers/torchao/torchao_quantizer.py", line 366, in create_quantized_param
    quantize_(module, self.quantization_config.get_apply_tensor_subclass())
  File ".../torchao/quantization/quant_api.py", line 422, in quantize_
    raise ValueError(
ValueError: Custom filter_fn and FqnToConfig were both specified. Only filter_fn=None is supported when FqnToConfig is specified.

原因分析

最可能的原因是 Diffusers 的 torchao quantizer 在 create_quantized_param 中调用 quantize_ 时,除了传入 TorchAoConfig 内的 FqnToConfig,还额外传入了一个自定义 filter_fn。torchao 的 quantize_ 在检测到 FqnToConfig 时,只支持 filter_fn=None,因为 FqnToConfig 自身已经通过 FQN 映射决定哪些模块用什么配置,再给一个自定义 filter 会产生语义冲突,于是直接抛出这个 ValueError

Issue 中的补充证据是:用户绕过 Diffusers,直接对同一个模型调用 quantize_(t, FqnToConfig(...), filter_fn=None) 可以正常完成量化。因此问题不在 FqnToConfig 的配置内容或正则写法,而在 Diffusers 的调用点。报告者还指出,Transformers 已经处理了这种情况,所以把 FqnToConfig 传给 ModularPipeline.load_components 时只有 text encoders 能正常工作。

环境排查

  • 确认 Diffusers 版本:Issue 中为 0.40.0.dev0,需检查所用版本是否包含 PR #14686 的改动。
  • 确认 torchao 版本:Issue 中为 0.17.0+rocm7.2;不同版本对 FqnToConfigfilter_fn 的校验行为可能不同。
  • 确认 PyTorch 版本:Issue 中为 2.13.0+rocm7.2。
  • 确认 Python 版本:Issue 中为 3.12.13。
  • 确认 Transformers 版本:Issue 中为 5.5.4;报告中提到 Transformers 侧已有较完善的处理。
  • 确认量化配置:是否使用 TorchAoConfig(FqnToConfig(...)),而不是直接使用 Int8WeightOnlyConfig 等单一配置。
  • 确认调用入口:是 Flux2Transformer2DModel.from_pretrained(..., quantization_config=...),还是通过 pipeline 的 load_components 等上层接口触发。

解决步骤

  1. 先按 issue 中的方式做对照验证:在不使用 Diffusers 的 quantization_config 时,直接对已加载的模型调用 torchao 的 quantize_(model, FqnToConfig(...), filter_fn=None),确认量化配置本身可用。Issue 中该路径已确认可以成功。
  2. 检查你使用的 Diffusers 版本是否已包含 PR #14686。若没有,可优先尝试升级到包含该 PR 的版本,或从 PR #14686 的改动出发查看 Diffusers torchao quantizer 的调用逻辑。
  3. 若无法升级,可优先尝试的临时方案是:在 Diffusers 的 torchao 量化调用路径中,当检测到 FqnToConfig 时不再传入自定义 filter_fn,即按 torchao 的要求使用 filter_fn=None。Issue 报告者提到自己在 fork 中写过类似特殊处理的 hacky patch,但这属于绕过方案,不是官方修复。
  4. 如果暂时无法修改 Diffusers 内部代码,可考虑绕过 Diffusers 的量化加载入口:先以非量化方式加载模型,再用 torchao 的 quantize_ 直接量化,即 issue 中已验证可用的 direct quantization 方式。
  5. 关注 PR #14686 的合入状态和后续评论;在确认修复已合入并发布后,回退临时方案。

验证方法

用 issue 中的最小复现脚本重新执行 Flux2Transformer2DModel.from_pretrained(..., quantization_config=TorchAoConfig(FqnToConfig(...))),确认不再抛出 ValueError: Custom filter_fn and FqnToConfig were both specified. Only filter_fn=None is supported when FqnToConfig is specified.,并且模型能够正常完成加载。进一步可检查目标层是否真的被量化:例如确认 transformer_blocks.*.ff.*transformer_blocks.*.attn.* 的权重类型符合预期,且 _defaultNone 的层未被量化。若走的是临时 direct quantization 方案,则确认量化后模型能正常前向推理。

参考来源

huggingface/diffusers #14667

相关 PR:huggingface/diffusers #14686

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 23777

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注