事情本身不复杂,线索都在日志里。推理脚本里模型已经 model.to(‘cuda’),但新构造的 attention mask 还在 CPU 上,报 Expected all tensors to be on the same device, but found cuda:0 and cpu。
第一反应是「多卡场景下张量分布在不同卡上」,验证下来不成立。
把日志和配置对完,能解释这个现象的基本就这几处。手工构造的张量没有跟随模型搬到显存。另一种情况是tokenizer 返回的 batch 只搬了 input_ids。
另外,数据加载器把张量固定在了 CPU。
第一件事是把整个 batch 一次性搬到模型所在设备
batch = {k: v.to(device) for k, v in batch.items()}
随后确认模型参数所在设备
python -c "import torch;print(next(model.parameters()).device)"
多卡时把输入送到对应 rank 的设备
local_device = torch.device('cuda', rank)
等前面都确认过,再在 forward 前加一次断言,尽早暴露问题
assert mask.device == input_ids.device
那几天正好在做别的变更,先把时间线对齐才敢动手。
改完先别撤,确认这几项。前向计算正常完成,输出张量在 cuda:0 上,断言不再触发设备不一致,多卡时也能落到各自对应的显卡。
补一句。只搬 input_ids 是最常见的漏项,attention_mask、position_ids、labels 都要一起搬,少一个就会在特定分支才报错。这类问题最好一次改到位,反复小改反而容易把原因搅混。