DiffusionGemma: generated text changes with batch size (MoE router projection and self-conditioning matmul)

使用 DiffusionGemma 做批量推理时,如果逻辑输入完全相同,只是物理 batch size 不同,却得到不同输出文本,这通常属于批次形状变化引起的数值差异,不是采样参数问题。优先确认差异是否首先出现在 MoE router projection(F.linear)和 self-condi

快速结论:使用 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 是否按要求复制。

解决步骤

  1. 先用 Issue 中的最小复现脚本,固定同一 prompt 和同一 canvas,比较 batch size 1 与 2–4 时 row 0 的 logits;同时重复运行 batch size 1,排除运行间噪声。
  2. 若确认 batch size 1 重跑按位一致,而不同 batch size 下出现差异,则问题与批次形状相关,而非采样随机性。
  3. 可优先尝试用户验证的 H100 规避方案:将 30 层 decoder router projection 逐行计算,使首次去噪输出对齐。
  4. 若后续去噪轮次仍有差异,可继续对 self-conditioning 步骤逐行计算(FP32 softmax 转 BF16 后再 matmul)。
  5. Issue 中该方法在 batch-of-four 与单行运行间,跨全部 293 次去噪轮次实现逐字节一致,包括采样决策、停止点和最终文本。
  6. 不要将其作为上游补丁提交:维护者已明确表示,仅串行化输入、导致 batch 不可用的 PR 会被关闭。

验证方法

在同一 prompt、同一 canvas、同一模型 revision 下,比较 batch size 1 与 batch size 4(四份逻辑相同输入)的 row 0 logits;若逐字节一致,并连续多轮去噪后最终文本、停止点、采样决策均一致,说明复现层面的差异已消除。仅 batch size 1 重跑一致,不足以说明批量结果一致。

参考来源

huggingface/transformers #49876

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 30146

发表回复

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