bounty将在2天后过期。回答此问题可获得+50声望奖励。MichiganMagician希望引起更多人关注此问题。
我的训练在这条线上失败了:outputs = model(**{key: torch.squeeze(value.to(self.training_device), 1) for key, value in inputs.items()})
我尝试用torch.nn.DataParallel()训练https://huggingface.co/docs/transformers/model_doc/layoutlmv2模型。我在AWS Sagemaker中使用了一个4 GPU的节点示例。但是,当代码到达上面一行时,它失败了,并在标题中显示了指定的错误。
我试着在网上看了一下,建议似乎是把模型和输入都移到GPU上,但我想我已经这样做了。另外,我不能调用inputs = inputs.to(self.training_device)
,因为输入是一个字典:dict_keys(['input_ids', 'token_type_ids', 'attention_mask', 'bbox', 'labels', 'image'])
这是我的培训师课程:
class LanguageModelTrainer(Trainer):
def __init__(self, *args, class_weights=None, l1_coef=0, **kwargs):
self.class_weights = class_weights
self.l1_coef = l1_coef
self.training_device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
super().__init__(*args, **kwargs)
def compute_loss(self, model, inputs, return_outputs=False):
model = torch.nn.DataParallel(model)
model.to(self.training_device)
loss_fn = torch.nn.CrossEntropyLoss(weight=self.class_weights)
outputs = model(**{key: torch.squeeze(value.to(self.training_device),
1) for key, value in inputs.items()})
loss = loss_fn(outputs.logits.view(-1, model.config.num_labels), inputs["labels"].view(-1))
if self.l1_coef:
l1_norm = sum(torch.linalg.norm(p.flatten(), 1) for n, p in model.named_parameters() if 'bias' not in n)
loss += self.l1_coef * l1_norm
return (loss, outputs) if return_outputs else loss
对于DataParallel部分,我只是按照这个教程:https://pytorch.org/tutorials/beginner/blitz/data_parallel_tutorial.html
2条答案
按热度按时间a64a0gku1#
你的输入字典有“bbox”和“image”,我认为这是一个Tensor和非Tensor。“torch.squeeze”函数不能应用于非Tensor输入。这可能是问题所在。如果我误解了信息,请忽略以下内容。
要解决上述问题,请应用
torch.squeeze
使用验证后,仅对Tensor输入起作用
是示例(v, Torch ,Tensor)
检查一个值是否是Tensor。非Tensor输入应保持不变。
然后将修改后的输入传递给模型以训练/生成输出。
将输入移动到GPU并挤压Tensor的修改代码可能类似于以下代码:
此修改应允许您将Tensor输入移动到GPU并对其应用挤压函数,而不会影响非Tensor输入。
vs3odd8k2#
在
compute_loss()
方法中,在使用DataParallel
Package 模型之前,应将其移动到self.training_device
:然后将输入移动到与模型相同的设备:
然后将输入传递给模型,而不调用
torch.squeeze
:并保持其余代码不变。