RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:7 and cpu! (when checking argument for argument index in method wrapper_CUDA__index_select)`

该报错通常发生在旧版 Transformers 中对小型 GPT-2 模型使用 device_map="auto" 且模型被切分到多张 GPU 时,原因是旧的 balanced device-map 算法没有将 tied weights( transformer.wte.weight 与 lm_he

快速结论:该报错通常发生在旧版 Transformers 中对小型 GPT-2 模型使用 device_map="auto" 且模型被切分到多张 GPU 时,原因是旧的 balanced device-map 算法没有将 tied weights(transformer.wte.weightlm_head.weight)始终放置在同一设备上。请优先升级 Transformers 与 Accelerate 到最新版本。

适用环境:Transformers 4.36.2、Accelerate 0.26.1、PyTorch 2.1.2+cu118、Python 3.9.18、Linux、多卡 CUDA 环境(报错中出现 cuda:7)。

最快修复方案:暂无确认的一步修复方案。官方维护者确认该问题已被修复,建议升级到修复后的 Transformers 版本(2024 年 12 月后的 release 均可,维护者曾在 2025 年 2 月的新版本上复现失败)。

注意事项:升级后若仍复现,需要提供完整的 transformers env 输出并重新打开 Issue。此问题与模型大小无关,小型模型在多卡环境下更容易触发 tied weights 被分配到不同设备的情况。该修复逻辑在后续版本已重写为显式将 tied parameter groups 分配在同一设备上。

问题场景

用户在旧版 Transformers(4.36.2)中使用 GPT2LMHeadModel.from_pretrained(..., device_map="auto") 加载 GPT-2 系列模型并计算 loss。gpt2-large 可以正常工作,但较小的 gpt2 模型报错,说明问题并非由显存不足或模型过大引起,而是设备映射算法在处理不同大小的模型时,对 tied weights 的处理策略产生了差异。

报错原文

RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:7 and cpu! (when checking argument for argument index in method wrapper_CUDA__index_select)

原因分析

可能原因:GPT-2 的 transformer.wte.weight(输入嵌入)和 lm_head.weight(输出投影)是 tied weights,必须始终位于同一设备。旧的 balanced device-map 算法在将小型模型切分到多张 GPU 时,偶尔会把这对 tied weights 分配到不同的设备(例如一个在 cuda:7,另一个在 CPU),导致 index_select 操作出现设备不一致错误。官方维护者确认该算法后来已被重写,专门将 tied parameter groups 的大小与放置位置一起显式处理。

环境排查

  • 确认 Transformers 版本是否为 4.36.2 或附近的旧版本;
  • 确认 Accelerate 版本(Issue 中为 0.26.1,且 Accelerate config 未找到);
  • 确认 PyTorch 版本与 CUDA 版本(Issue 中为 2.1.2+cu118);
  • 确认是否使用多卡环境,且设备映射是否正确(报错中涉及 cuda:7cpu 两个设备);
  • 检查 Python 版本是否为 3.9.x(Issue 中为 3.9.18)。

解决步骤

  1. 升级 Transformers 到当前最新稳定版(该问题已在后续版本中修复,重写逻辑位于 src/transformers/integrations/accelerate.py);
  2. 同步升级 Accelerate 以确保新版 device_map 算法正常工作;
  3. 若无法立即升级,可优先尝试将 device_map="auto" 改为不切分模型的方案,例如指定单卡 device_map={"": 0},确认是否仍会触发 tied weights 跨设备问题;
  4. 若升级后问题依旧存在,请提供完整的 transformers env 输出,并反馈到官方 Issue 以便进一步排查。

验证方法

在升级后重新运行同一段复现脚本,确认 GPT-2(非 large 版本)可以正常计算 loss 且不再抛出 RuntimeError: Expected all tensors to be on the same device 错误。同时建议对比打印模型各层 weight 所在设备,确认 transformer.wte.weightlm_head.weight 位于同一设备。

参考来源

huggingface/transformers #28672

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 21581

发表回复

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