快速结论:该问题通常出现在 InvokeAI 加载一个尚未进入模型缓存的 SDXL 模型、并且该 CLIP 文本编码器的首次前向就带 CLIP skip 执行时。此后这个缓存实例的每一步前向都会少一层 hidden_states,SDXL 条件向量静默取到错误的层,图像照常生成但不报错。优先排查的是“首次前向时是否被 ModelPatcher.apply_clip_skip 弹出过编码器层”,而不是先怀疑模型文件或采样参数。
适用环境:Issue 已在 InvokeAI main 分支、transformers 5.5.4 与 5.10.4、SDXL 模型路径下复现。评论区的验证环境为 Windows、Python 3.12.14、Torch 2.13 CPU/float32,使用随机初始化的四层小模型(未下载权重)。未确认其他操作系统、CUDA、显卡或加速器环境的结论。
最快修复方案:暂无已合并的一步修复方案。Issue 的评论区给出一个已验证提案:在 invokeai/backend/model_patcher.py 中,于移除层之前,在完整的内层 CLIP capture owner 上初始化已有的 capture helper,使被恢复的层同样带 capture wrapper。该提案仅改动 model_patcher.py 和一个新增行为测试文件,尚未成为上游 PR 或被采纳。
注意事项:上述提案依赖 transformers 的内部 API,未来版本可能失效;它只修复新加载的编码器,不能修复已经处于损坏状态的缓存实例。评论明确说明未验证加速器、编译执行和端到端 SDXL 生成。若无法打补丁,可优先尝试 Issue 提出的规避方式:首次前向不要带 CLIP skip,或改用不修改 encoder.layers 的 CLIP skip 实现;两者均属推测性建议,未在 Issue 中单独验证。
问题场景
在 InvokeAI 中用 SDXL 模型出图,且该模型的 CLIP 文本编码器是首次载入(不在模型缓存中)。如果第一次生成时设置了 CLIP skip = 1,那么之后即使把 CLIP skip 改回 0、使用固定种子,生成结果也会和“重启后首跑就用 CLIP skip = 0”的结果不一致。整个过程没有异常抛出。Issue 中的最小复现脚本直接组合使用 transformers 的 CLIPTextModel / CLIPTextModelWithProjection 与 invokeai.backend.model_patcher.ModelPatcher,通过 uv run --no-sync python 运行。
报错原文
bug: CLIP skip on a fresh text encoder's first run corrupts later SDXL conditioning
CLIPTextModel expected 5 got 4 penultimate matches: False
CLIPTextModelWithProjection expected 5 got 4 penultimate matches: False
原因分析
transformers 通过前向钩子(forward hooks)记录 output_hidden_states,而这些钩子是惰性安装的:只在模型首次前向时,针对当时存在于编码器中的层安装。InvokeAI 的 ModelPatcher.apply_clip_skip(invokeai/backend/model_patcher.py)实现 CLIP skip 的方式是把 encoder.layers 末尾的层弹出,之后再追加回去。
如果钩子恰好在该层被弹出的期间安装,那么被恢复的层就拿不到钩子,其输出不会出现在 hidden_states 里。结果就是 hidden_states 少一项,[-2] 指向了更早的一层。SDXL 路径(invokeai/app/invocations/text_encoder/compel.py)使用 PENULTIMATE_HIDDEN_STATES_NON_NORMALIZED,即读取 hidden_states[-2],因此取到错误层且不报错。SD1/SD2 使用 last_hidden_state,是直接计算得到的,不受影响。
环境排查
- 确认 InvokeAI 版本:Issue 报告在 main 分支上存在,并已包含 #9723。
- 确认 transformers 版本:已复现于 5.5.4 和 5.10.4。
- 确认触发路径为 SDXL 模型,而非 SD1/SD2 模型。
- 确认模型是否已在本进程的模型缓存中:仅当编码器为“首次前向”时触发。
- 评论中的验证环境为 Windows、Python 3.12.14、Torch 2.13 CPU/float32;其他平台与 CUDA/GPU 组合尚未确认。
- 若自行跑测试,评论使用的命令为
python -m pytest -o addopts= -p no:cov -p xdist.plugin -n 0 -q tests/backend/test_clip_skip_first_forward.py tests/backend/test_clip_text_model_wrapper.py,配合 Ruff 0.11.2 检查。
解决步骤
- 先按 Issue 的复现步骤确认问题:重启 InvokeAI,使用未缓存的 SDXL 模型,第一次生成设置 CLIP skip = 1。
- 再用固定种子、CLIP skip = 0 生成一次;随后重启并直接以 CLIP skip = 0 作为首次生成再跑一次,对比两次输出。若不一致,即符合本 Issue 的症状。
- 可优先尝试的规避方式:在新加载编码器的首次前向之前,避免带 CLIP skip 执行(例如先跑一次 skip 为 0 的生成再调高),或改用不修改
encoder.layers的 CLIP skip 实现(请求 hidden states 后取hidden_states[-(clip_skip + 1)])。这两条来自 Issue 的 Possible fixes,未单独验证。 - 若要采用评论区提案:在
model_patcher.py中,于移除层之前先对内层 CLIP capture owner 初始化已有 capture helper。评论指出,对外层投影包装器调用会导致已预热编码器出现重复 capture,同权重数值对照测试发现了这一点,所以补丁必须指向内层 owner。 - 该提案需配套新增回归测试:加载全新编码器,先带 CLIP skip 跑首次前向,再验证不带 skip 的前向与参考模型一致。
- 对已经损坏的缓存编码器,补丁无效,需要重新加载模型(如重启进程)后再使用修复后的代码。
验证方法
运行 Issue 中的最小脚本,确认 expected 5 got 4 变为层数一致且 penultimate matches: True。在应用提案补丁的情况下,评论区报告的验证结果包括:在真实 transformers 5.5.4/5.10.4 上的上游方法复现为每次 16 失败、10 对照通过;补丁后 5.5.4 上 26 项通过;固定 5.10.4 下新测试文件单独 26 项通过,与既有 CLIP wrapper/LoRA/SDNQ 覆盖合跑 34 项通过。测试比较的是恢复后的 hidden states、最终输出以及 pooled/projected 输出与独立同权重编码器是否一致,覆盖首次/无 capture/已预热/重复上下文及层前向抛异常等情况。最终出图层面,Issue 未提供端到端 SDXL 的验证结论。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。

![[Feature Request]: Support Multiple Output Variables for Code Component](https://www.chat-gpts.plus/wp-content/uploads/2026/11/15098-4731e120-768x403.jpg)
