RuntimeError: Tensor.item() cannot be called on meta tensors

使用 transformers 库加载 DiffusionGemmaForBlockDiffusion 模型( google/diffusiongemma-26B-A4B-it ),并传入 device_map="auto" 参数时,在后续调用 model.generate() 阶段触发此错误。用户

RuntimeError: Tensor.item() cannot be called on meta tensors

RuntimeError: Tensor.item() cannot be called on meta tensors

快速结论:此报错发生在使用 device_map="auto" 加载 DiffusionGemma 模型时,部分权重被错误地遗留在 meta 设备上,导致前向传播时无法调用 .item()。优先排查:检查 model.hf_device_map 是否存在,并尝试使用硬编码的 device_map 字典手动分配设备。

问题场景

使用 transformers 库加载 DiffusionGemmaForBlockDiffusion 模型(google/diffusiongemma-26B-A4B-it),并传入 device_map="auto" 参数时,在后续调用 model.generate() 阶段触发此错误。用户在 2 张 L40S GPU 上复现,而单张 H100 GPU 未能重现。

报错原文

File "transformers/models/diffusion_gemma/generation_diffusion_gemma.py", line 645, in generate
    and input_ids is not None
File "torch/_meta_registrations.py", line 8086, in meta_local_scalar_dense
    raise RuntimeError("Tensor.item() cannot be called on meta tensors")
RuntimeError: Tensor.item() cannot be called on meta tensors

原因分析

可能原因:DiffusionGemma 模型在 _tied_weights_keys 中使用了正则表达式(如 r"encoder.language_model.layers\.(?:[^.]+\.)*weight")来定义权重的绑定关系。然而 accelerate 在进行设备映射时不完全支持此类正则表达式的匹配,导致 tied weights 无法正确链接。在内存受限的多 GPU 环境(如 2×L40S)下,accelerate 会跳过这些模块的设备分配,使它们留在 meta 设备上,最终触发 RuntimeError

用户通过 model.named_parameters() 确认了多个子模块(如 model.encoder.language_model.embed_tokens.weight 以及 model.decoder.self_conditioning 下的参数)设备为 meta。此外,model.hf_device_map 在该架构下抛出 AttributeError(对象不存在该属性),进一步印证了设备映射过程未完成。

环境排查

  • transformers:5.11.0
  • accelerate:1.13.0
  • torch:2.11.0+cu126
  • GPU:2× L40S(用户复现);单张 H100(未复现)
  • flash_attn:2.8.3

注意:标准 GEMMA-4 模型(gemma-4-26B-A4B-it)在同一环境下运行正常,表明问题仅出现在 DiffusionGemma 特定架构。

解决步骤

  1. 绕过 device_map="auto":避免使用自动设备映射,改为传递硬编码的 device_map 字典。以下示例将前 6 层语言模型和解码器层分配到 GPU 0,其余层分配到 CPU,同时固定关键模块(Embeddings、Vision Tower、Self-Conditioning、LM Head)到 GPU 0:
device_map = {}
device_map["model.encoder.language_model.embed_tokens"] = 0
device_map["model.decoder.embed_tokens"] = 0
device_map["model.encoder.vision_tower"] = 0
device_map["model.encoder.embed_vision"] = 0
device_map["model.decoder.self_conditioning"] = 0
device_map["lm_head"] = 0

# 将 layers 0-5 保留在 GPU 0,layers 6-29 分配到 CPU
for i in range(6):
    device_map[f"model.encoder.language_model.layers.{i}"] = 0
    device_map[f"model.decoder.layers.{i}"] = 0

for i in range(6, 30):
    device_map[f"model.encoder.language_model.layers.{i}"] = "cpu"
    device_map[f"model.decoder.layers.{i}"] = "cpu"

device_map["model.encoder.language_model.norm"] = "cpu"
device_map["model.decoder.norm"] = "cpu"

model = DiffusionGemmaForBlockDiffusion.from_pretrained(
    MODEL_ID,
    dtype="auto",
    device_map=device_map,
    local_files_only=True
)
  1. 确认 model.hf_device_map 属性是否存在:加载模型后打印 model.hf_device_map,若抛出 AttributeError 说明设备映射失败,应转用步骤 1 的硬编码方案。
  2. 使用 model.named_parameters() 逐一检查设备:循环打印所有参数所在的设备,确认是否有任何模块仍留在 meta。如果发现,调整 device_map 将这些模块显式分配到 GPU 或 CPU。
  3. 考虑单 GPU 或更高的内存预算(可优先尝试):如果条件允许,尝试在单张高显存 GPU(如 H100 80GB)上运行,用户报告此配置下未触发错误。

验证方法

修改 device_map 后再次调用 model.generate(**input_ids, max_new_tokens=512),确保不再抛出 RuntimeError: Tensor.item() cannot be called on meta tensors。可以通过 model.named_parameters() 确认所有参数的 device 不再为 meta 来辅证修复成功。

参考来源

huggingface/transformers #46566

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

celebrityanime
celebrityanime
文章: 8341

发表回复

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