Prhub

#22293 [fix] [whisper] ensure inputs are moved to the correct device before processing.

sgl-project/sglang · 作者 AgainstEntropy · 合并时间 2026-04-08 23:45

分析状态 已生成
文件变更 1提交数 3 · 评论 4
代码增减 +4 / -0
bugfix run-ci multimodal

执行摘要

修复 Whisper 模型输入特征未正确转移到 GPU 设备导致的运行时错误。

根据PR body描述,Whisper模型未覆盖#22038引入的延迟设备转移机制,导致输入特征可能未转移到正确设备。这在使用CUDA图时会导致运行时错误:"RuntimeError: Expected all tensors to be on the same device, but got weight is on cuda:0, different from other tensors on cpu"。手动测试test_whisper_cuda_graph.py可复现此问题。

该PR值得快速浏览以了解设备同步问题的典型修复模式。重点关注:1)如何确定正确的目标设备;2)review中提到的更稳健设备获取方案为何未被采纳;3)可结合#22038理解延迟设备转移机制的背景。

讨论亮点

review中只有一条来自mickqian的评论,建议使用device=next(self()).device替代self.conv1.weight.device以获得更稳健的设备获取方式。但作者未采纳此建议,最终代码仍使用原方案。没有其他设计争议或未解决疑虑。

实现拆解

仅修改了python/sglang/srt/models/whisper.py文件的forward方法,在卷积操作前添加4行代码:1)获取self.conv1.weight.device作为目标设备;2)将input_features移动到该设备;3)将position_ids移动到该设备;4)然后执行原有的卷积和激活操作。这是一个最小化的设备同步修复。

文件 模块 状态 重要度
python/sglang/srt/models/whisper.py models/whisper modified 8.0

分析完成后,这里会展示 LLM 生成的相对完整源码片段和详细注释。

关键符号

forward

评论区精华

设备获取方式的稳健性讨论 设计

mickqian 建议使用 `device=next(self()).device` 替代 `self.conv1.weight.device` 以获得更稳健的设备获取方式

结论:作者未采纳建议,保持使用 conv1.weight.device 的方案 · 已解决

风险与影响

风险较低:1)变更范围极小,仅添加设备转移逻辑;2)可能引入微小性能开销(额外的to()调用),但在CUDA图捕获场景下这是必要的;3)如果模型有其他未考虑的设备依赖,可能存在遗漏,但当前修复针对具体错误点;4)缺少单元测试覆盖此修复场景。

影响范围有限但关键:1)仅影响Whisper模型用户,特别是使用CUDA图优化的场景;2)解决了设备不匹配导致的运行时崩溃,提升模型稳定性;3)对系统其他部分无影响;4)团队需要关注类似模型是否也存在相同设备转移问题。

缺少测试覆盖 设备同步逻辑

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

执行摘要

本次PR修复了Whisper模型因未覆盖#22038引入的延迟设备转移机制而导致的设备不匹配错误。通过在forward方法中显式将输入张量移动到模型权重所在设备,解决了CUDA图捕获时出现的"Expected all tensors to be on the same device"运行时异常。这是一个针对特定模型的关键bugfix,影响范围有限但解决了稳定性问题。

功能与动机

问题根源:Whisper模型未覆盖#22038引入的延迟设备转移机制,导致输入特征input_features和位置IDposition_ids可能停留在CPU,而模型权重已在GPU上。

具体表现:执行手动测试test/manual/test_whisper_cuda_graph.py时出现运行时错误:

RuntimeError: Expected all tensors to be on the same device, but got weight is on cuda:0, different from other tensors on cpu

修复目标:确保在卷积操作self.conv1(input_features)执行前,所有张量都在同一设备上。

实现拆解

仅修改python/sglang/srt/models/whisper.py文件的forward方法,在原有逻辑前插入设备同步代码:

device = self.conv1.weight.device
input_features = input_features.to(device=device)
position_ids = position_ids.to(device=device)

关键设计点

  1. 使用self.conv1.weight.device作为目标设备参考点
  2. 同时移动input_featuresposition_ids两个张量
  3. 在第一个卷积操作前完成设备转移

评论区精华

review中只有一条实质性技术讨论:

mickqian: "nit: device=next(self()).device is more robust"

讨论要点

  • mickqian建议使用迭代器方式获取设备,认为比直接引用特定层权重更稳健
  • 作者最终未采纳此建议,保持原方案
  • 可能原因:conv1作为模型第一个卷积层,其设备位置具有代表性,且代码更直观

风险与影响

技术风险

  1. 性能开销:增加两次to()调用,但在CUDA图场景下这是必要成本
  2. 覆盖不全:如果模型其他部分也有类似设备依赖,可能遗漏
  3. 测试缺失:缺少针对此修复的单元测试

影响评估

  • 用户影响:仅影响使用Whisper模型且启用CUDA图的用户,解决崩溃问题
  • 系统影响:无架构或接口变更,不影响其他模型
  • 团队影响:提醒需要检查其他模型是否也存在#22038覆盖不全问题

关联脉络

与历史PR的关联

  1. #22038:引入了延迟设备转移机制,是本bug的根本原因
  2. #21817:类似的多模态设备同步修复,解决warmup图像初始化并发问题
  3. #22266:NPU上Qwen3.5视频处理器的设备相关修复

演进趋势

  • 随着#22038机制的推广,需要确保所有模型都正确覆盖设备转移逻辑
  • 多模态模型(Whisper、扩散模型等)在设备同步方面有特殊需求
  • CI标签run-cimultimodal频繁出现,显示团队对多模态测试的重视

参与讨论