快速结论:使用 DiffusionGemma 做批量推理时,如果逻辑输入完全相同,只是物理 batch size 不同,却得到不同输出文本,这通常属于批次形状变化引起的数值差异,不是采样参数问题。优先确认差异是否首先出现在 MoE router projection(F.linear)和 self-conditioning matmul,再判断能否接受或规避。
适用环境:transformers 5.15.0;Python 3.12.10;PyTorch 2.13.0+cu130;CUDA 13.0,cuDNN 92000,NVIDIA 驱动 610.57.04;NVIDIA H100 80GB HBM3(另有 A100-SXM4-80GB sm_80 复现);bfloat16、eval + inference_mode、关闭 torch.compile、TF32 关闭、attn_implementation=sdpa、experts=grouped_mm。
最快修复方案:暂无确认的一步修复方案。Issue 中用户自行验证的“逐行计算 30 层 decoder router projection,并对 self-conditioning 的 FP32 softmax→BF16→matmul 也逐行计算”可以做到逐字节对齐,但维护者明确表示不会接受只把输入串行化计算的 PR。
注意事项:该逐行方案是绕过批处理,不能作为通用修复。维护者指出批量与非批量输入使用不同 kernel,数值差异属于预期;若确认存在真正的 bug,才值得提交 PR。Issue 已关闭。
问题场景
在 Linux + 单张 H100 上,用 transformers 加载 google/diffusiongemma-26B-A4B-it(revision f7f5b7f5fa82ffc52addd066915886d497f5517b)做 DiffusionGemma 块扩散推理。用户构造受控实验:逻辑输入固定,B1 是一行,B2–B4 是 2–4 份按位完全相同的副本,并复制 batch-1 的 prompt cache。结果是仅改变 batch size 就会改变最终生成文本和停止位置:24 次生成中有 22 次文本变化、19 次停止点变化。
报错原文
DiffusionGemma: generated text changes with batch size (MoE router projection and self-conditioning matmul)
原因分析
可能原因:batch size 变化后,底层 kernel 选择或计算路径发生变化,导致浮点结果出现批次形状相关差异。在 H100 上,首个差异出现在 MoE router projection(decoder.layer.*.moe.router.proj 的 F.linear 调用);约 0.051% 的 router score 发生变化,两层内影响所有 canvas 位置,最终 98.82% 的 token score 不同。后续去噪轮次还会在 self-conditioning 中继续分叉,即上轮概率经 FP32 softmax 转 BF16 后再做 matmul 的步骤。在 A100 上,每个 batch size 都不同,且首个差异出现在第一层 attention。
环境排查
- 确认 transformers 版本是否为 5.15.0。
- 确认 Python 3.12.10、PyTorch 2.13.0+cu130、CUDA 13.0、cuDNN 92000、驱动 610.57.04。
- 确认 GPU 型号(H100 与 A100 表现不同)。
- 确认 dtype=bfloat16、eval + inference_mode、torch.compile 已关闭。
- 确认 TF32 已关闭,且未开启
torch.use_deterministic_algorithms。 - 确认 attn_implementation=sdpa、experts=grouped_mm。
- 确认模型 revision 与 prompt cache 是否按要求复制。
解决步骤
- 先用 Issue 中的最小复现脚本,固定同一 prompt 和同一 canvas,比较 batch size 1 与 2–4 时 row 0 的 logits;同时重复运行 batch size 1,排除运行间噪声。
- 若确认 batch size 1 重跑按位一致,而不同 batch size 下出现差异,则问题与批次形状相关,而非采样随机性。
- 可优先尝试用户验证的 H100 规避方案:将 30 层 decoder router projection 逐行计算,使首次去噪输出对齐。
- 若后续去噪轮次仍有差异,可继续对 self-conditioning 步骤逐行计算(FP32 softmax 转 BF16 后再 matmul)。
- Issue 中该方法在 batch-of-four 与单行运行间,跨全部 293 次去噪轮次实现逐字节一致,包括采样决策、停止点和最终文本。
- 不要将其作为上游补丁提交:维护者已明确表示,仅串行化输入、导致 batch 不可用的 PR 会被关闭。
验证方法
在同一 prompt、同一 canvas、同一模型 revision 下,比较 batch size 1 与 batch size 4(四份逻辑相同输入)的 row 0 logits;若逐字节一致,并连续多轮去噪后最终文本、停止点、采样决策均一致,说明复现层面的差异已消除。仅 batch size 1 重跑一致,不足以说明批量结果一致。
参考来源
huggingface/transformers #49876
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。
![[Bug] Starred Apps API returns empty permission_keys](https://www.chat-gpts.plus/wp-content/uploads/2026/10/42807-9b211237-768x403.jpg)
![[Bug]: Abnormally bad performance on AMD ROCM gfx1030 (W6800, V620, 6900XT 6800XT)](https://www.chat-gpts.plus/wp-content/uploads/2026/10/38107-c0716f30-768x403.jpg)
![[Bug]: persistent_topk silently drops top-k candidates when many values share a coarse histogram bin](https://www.chat-gpts.plus/wp-content/uploads/2026/10/51782-b37011fe-768x403.jpg)