`_tp_plan` / `_cp_plan`: allow entries for modules that are not always present

当模型的 _tp_plan / _cp_plan 中写入了只会在部分配置或部分 checkpoint 下才存在的模块(例如 fuse_projections() 后才生成的 attn.to_qkv ,或 add_k_proj / add_v_proj 这类可选层)时,计划解析失败。优先排查计划里是否

快速结论:当模型的 _tp_plan / _cp_plan 中写入了只会在部分配置或部分 checkpoint 下才存在的模块(例如 fuse_projections() 后才生成的 attn.to_qkv,或 add_k_proj/add_v_proj 这类可选层)时,计划解析失败。优先排查计划里是否包含实例上不存在的键。

适用环境:diffusers 的 tensor_parallel / context_parallel 钩子;相关代码位于 src/diffusers/hooks/tensor_parallel.py 与 src/diffusers/hooks/context_parallel.py。Issue 讨论中未给出已确认的操作系统、Python、CUDA、PyTorch 或显卡版本。

最快修复方案:暂无确认的一步修复方案。Issue 中倾向采用 Option 1(用 Optional(...) 包装可选条目)并对未匹配模块告警,但该设计在 Issue 关闭时仍处于讨论阶段,没有已验证的代码路径。

注意事项:直接删除可选条目可以绕过解析失败,但后续调用 fuse_projections() 时被融合出的 nn.Linear 没有 TP 钩子和计划条目,在已分片模型上无法正常工作;Issue 建议在此场景直接报错。另外,在已用 TP 分片且已调用 fuse_qkv_projections() 的模型上,to_q/to_k/to_v 权重是 DTensor,融合会得到无 TP 钩子的普通层。

问题场景

使用 diffusers 对扩散模型配置张量并行(TP)或上下文并行(CP)计划时触发。典型情况包括:

  • 为融合投影(fused projections)编写计划,但 attn.to_qkv 只有在调用 fuse_projections() 之后才存在;
  • 模型根据 config 启用可选层(如 guidance embedder、由开关控制的额外投影、按 checkpoint 选择的 block 变体),同一个类下的不同 checkpoint 布局略有差异(例如某些 checkpoint 中 add_k_proj/add_v_proj 不为 None,另一些为 None);
  • 在已分片的模型上再调用 fuse_qkv_projections()。

问题源自 #14609 的后续讨论。

报错原文

_tp_plan / _cp_plan: allow entries for modules that are not always present

Issue 正文中给出的具体失败机制是:_find_submodule_by_name 对不属于子模块的原子条目抛出 ValueError;当存在可选条目时,计划在真正开始分片之前就会解析失败。

原因分析

_tp_plan 与 _cp_plan 是类属性,按属性查找解析:tensor_parallel.py 中的 resolve_tp_shard_specs / _resolve_tp_plan 对每个键执行 getattr,context_parallel.py 中的 _find_submodule_by_name 对不存在的子模块直接抛 ValueError。因此计划中的每个键都必须在实例上存在,计划只能覆盖该类每个实例都具备的模块。

可能的规避方式(均未在该 Issue 中验证):

  • 用 Optional(...) 显式标记可选条目,缺失时跳过,必填条目拼写错误仍报错;
  • 仿照 transformers,把计划键与实际存在的模块匹配,对未匹配键发出告警;
  • 暴露模型级 _get_tp_plan() 供子类按条件覆盖(关联 PR #15197),但讨论中认为这会把同一份计划拆到两处、可读性较差。

环境排查

  • 确认所使用的 diffusers 版本是否包含 resolve_tp_shard_specs / _resolve_tp_plan / _find_submodule_by_name 相关代码。
  • 确认模型类中 _tp_plan 或 _cp_plan 的每个键在目标实例上都能通过 getattr 解析到。
  • 确认模型 config:可选层(如 add_k_proj/add_v_proj、依赖 hidden_act 的 MLP 层)在当前 checkpoint 下是否存在。
  • 确认是否在已应用 TP 分片的模型上调用了 fuse_qkv_projections() / fuse_projections()。
  • Issue 讨论未提供已确认的 Python、CUDA、PyTorch、显卡或依赖版本信息,排查时请以本机实际环境为准。

解决步骤

  1. 定位触发失败的模型类,打印其 _tp_plan / _cp_plan 中的全部键。
  2. 逐个键在实例上做 getattr(或 hasattr)检查,找出在目标实例上不存在的条目。
  3. 若这些条目属于融合投影或 config 依赖的可选层,不要直接删除后依赖后续融合:Issue 指出融合出的普通 nn.Linear 没有 TP 钩子与计划条目,无法在分片模型上工作。可优先尝试在可选条目缺失时跳过该条目,并对未匹配键记录告警,仅作为临时规避。
  4. 若要在已分片模型上做融合,应先在应用 TP 之前完成融合,或等待 Issue 讨论落地的方案;对已分片模型直接调用融合,Issue 建议像 offloading、保存和 LoRA 那样直接报错。
  5. 关注关联 PR #15197 与后续修复 PR 的进展;其中提议的 _get_tp_plan() 与 Optional(...) 方案在 Issue 关闭时均未被确认为最终实现。
  6. 若模型存在多种 checkpoint 布局,需切换 checkpoint 后重新检查计划中的键与实例模块的匹配情况。

验证方法

应用计划时不再因可选条目抛 ValueError,即计划解析通过并进入分片阶段;同时确认必填条目拼写错误仍会报错,可选条目缺失时有明确告警。若要验证融合场景,还需确认分片后的模型上没有缺失 TP 钩子的融合层。

参考来源

huggingface/diffusers #15218

huggingface/diffusers #14609(前序 Issue,首次遇到融合投影缺失条目问题)

huggingface/diffusers PR #15197(提议模型级 _get_tp_plan(),讨论中提及)

huggingface/diffusers PR #15137(Cosmos 可选层相关,讨论中提及)

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 34867

发表回复

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