我正在使用 Pytorch-lightning 2.4.0。在以下代码片段中,lmm
是一个继承自nn.Module
的类,它是一个huggingface模型和处理器的包装类。
class ICVModel(pl.LightningModule): def __init__(self, lmm, icv_encoder: torch.nn.Module) -> None: super().__init__() self.lmm = lmm self.lmm.requires_grad_(False) self.icv_encoder = icv_encoder self.eos_token = self.lmm.processor.tokenizer.eos_token def forward(self, ice_texts, query_texts, answers, images): query_answer = [ query + answer + self.eos_token for query, answer in zip(query_texts, answers) ] query_images = [img[-setting.num_image_in_query :] for img in images] query_inputs = self.lmm.process_input(query_answer, query_images) query_outputs = self.lmm.model( **query_inputs, labels=query_inputs["input_ids"], )
然而,在以下位置引发了设备不匹配错误
query_outputs = self.lmm.model( **query_inputs, labels=query_inputs["input_ids"],)
我在lmm.model.forward
之外打印了inputs.pixel_values.device
、self.device
、self.lmm.device
的设备信息,然后我得到了
rank[0]: cpu cuda:0 cuda:0rank[1]: cpu cuda:1 cuda:1
在Idefics(self.lmm.model
)的前向过程中,当我打印inputs.pixel_values.device
和self.device
时,我得到了
rank[0]: cuda:0 cuda:0rank[1]: cuda:0 cuda:1
此外,我还尝试将pixel_values
移动到正确的设备上,但在后续的前向传递中,它仍然被移动到错误的设备上。
错误信息:
RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cuda:1! (when checking argument for argument weight in method wrapper_CUDA__cudnn_convolution)
回答:
我已经解决了这个问题。
问题的关键是我在提问时没有展示出来,因为当时我没有意识到bitsandbytes
和accelerate
库会自动注册pre_forward_hook
。
它在每个前向方法中注册了一个AlignDeviceHook
(可能是),这与pytorch lightning的设备控制相冲突。当我移除bitsandbytes
后,一切正常工作。