基于NeMo实体链接模型训练时Loss key缺失报错求助
问题:训练NeMo实体链接模型时出现loss键缺失报错
问题背景
- 使用NVIDIA NeMo实体链接模块,已切换至r1.10.0分支
- 在完整UMLS数据集上训练模型时触发报错
报错信息
In automatic_optimization, when `training_step` returns a dict, the 'loss' key needs to be present
涉及的training_step代码
def training_step(self, batch, batch_idx): """ Lightning calls this inside the training loop with the data from the training dataloader passed in as `batch`. """ input_ids, token_type_ids, attention_mask, concept_ids = batch logits = self.forward(input_ids=input_ids, token_type_ids=token_type_ids, attention_mask=attention_mask) train_loss = self.loss(logits=logits, labels=concept_ids) # No hard examples found in batch, # shouldn't use this batch to update model weights if train_loss == 0: train_loss = None lr = None else: lr = self._optimizer.param_groups[0]["lr"] self.log("train_loss", train_loss) self.log("lr", lr, prog_bar=True) return {"loss": train_loss, "lr": lr}
完整堆栈跟踪
[NeMo I 2022-07-29 18:29:27 multi_similarity_loss:91] Encountered zero loss in multisimloss, loss = 0.0. No hard examples found in the batch Error executing job with overrides: ['project_dir=.'] Traceback (most recent call last): File "self_alignment_pretraining.py", line 38, in main trainer.fit(model) File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/trainer/trainer.py", line 769, in fit self._fit_impl, model, train_dataloaders, val_dataloaders, datamodule, ckpt_path File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/trainer/trainer.py", line 719, in _call_and_handle_interrupt return self.strategy.launcher.launch(trainer_fn, *args, trainer=self, **kwargs) File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/strategies/launchers/subprocess_script.py", line 93, in launch return function(*args, **kwargs) File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/trainer/trainer.py", line 809, in _fit_impl results = self._run(model, ckpt_path=self.ckpt_path) File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/trainer/trainer.py", line 1234, in _run results = self._run_stage() File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/trainer/trainer.py", line 1321, in _run_stage return self._run_train() File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/trainer/trainer.py", line 1351, in _run_train self.fit_loop.run() File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/loops/base.py", line 204, in run self.advance(*args, **kwargs) File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/loops/fit_loop.py", line 268, in advance self._outputs = self.epoch_loop.run(self._data_fetcher) File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/loops/base.py", line 204, in run self.advance(*args, **kwargs) File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/loops/epoch/training_epoch_loop.py", line 208, in advance batch_output = self.batch_loop.run(batch, batch_idx) File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/loops/base.py", line 204, in run self.advance(*args, **kwargs) File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/loops/batch/training_batch_loop.py", line 88, in advance outputs = self.optimizer_loop.run(split_batch, optimizers, batch_idx) File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/loops/base.py", line 204, in run self.advance(*args, **kwargs) File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/loops/optimization/optimizer_loop.py", line 207, in advance self.optimizer_idx, File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/loops/optimization/optimizer_loop.py", line 256, in _run_optimization self._optimizer_step(optimizer, opt_idx, batch_idx, closure) File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/loops/optimization/optimizer_loop.py", line 378, in _optimizer_step using_lbfgs=is_lbfgs, File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/trainer/trainer.py", line 1593, in _call_lightning_module_hook output = fn(*args, **kwargs) File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/core/lightning.py", line 1644, in optimizer_step optimizer.step(closure=optimizer_closure) File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/core/optimizer.py", line 168, in step step_output = self._strategy.optimizer_step(self._optimizer, self._optimizer_idx, closure, **kwargs) File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/strategies/ddp.py", line 278, in optimizer_step optimizer_output = super().optimizer_step(optimizer, opt_idx, closure, model, **kwargs) File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/strategies/strategy.py", line 193, in optimizer_step return self.precision_plugin.optimizer_step(model, optimizer, opt_idx, closure, **kwargs) File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/plugins/precision/native_amp.py", line 85, in optimizer_step closure_result = closure() File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/loops/optimization/optimizer_loop.py", line 148, in __call__ self._result = self.closure(*args, **kwargs) File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/loops/optimization/optimizer_loop.py", line 134, in closure step_output = self._step_fn() File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/loops/optimization/optimizer_loop.py", line 437, in _training_step training_step_output, self.trainer.accumulate_grad_batches File "/home/umair/miniconda3/envs/aemap/lib/python3.7/site-packages/pytorch_lightning/loops/optimization/optimizer_loop.py", line 75, in from_training_step_output "In automatic_optimization, when `training_step` returns a dict, the 'loss' key needs to be present" pytorch_lightning.utilities.exceptions.MisconfigurationException: In automatic_optimization, when `training_step` returns a dict, the 'loss' key needs to be present Set the environment variable HYDRA_FULL_ERROR=1 for a complete stack trace.
解决方案
问题根源:当train_loss为0时,代码将其设为None,但PyTorch Lightning自动优化模式要求返回的字典中必须包含有效loss值。以下是两种可行修复方案:
方案一:返回None跳过批次优化(推荐)
当无需更新模型时,直接返回None,PyTorch Lightning会自动跳过该批次的梯度计算与参数更新:
def training_step(self, batch, batch_idx): input_ids, token_type_ids, attention_mask, concept_ids = batch logits = self.forward(input_ids=input_ids, token_type_ids=token_type_ids, attention_mask=attention_mask) train_loss = self.loss(logits=logits, labels=concept_ids) # 无有效样本,跳过当前批次 if train_loss == 0: return None lr = self._optimizer.param_groups[0]["lr"] self.log("train_loss", train_loss) self.log("lr", lr, prog_bar=True) return {"loss": train_loss, "lr": lr}
方案二:构造无梯度占位损失
若必须返回字典,可创建一个不需要梯度的零损失,避免报错同时不影响模型更新:
def training_step(self, batch, batch_idx): input_ids, token_type_ids, attention_mask, concept_ids = batch logits = self.forward(input_ids=input_ids, token_type_ids=token_type_ids, attention_mask=attention_mask) train_loss = self.loss(logits=logits, labels=concept_ids) if train_loss == 0: # 生成无梯度的零损失,不参与梯度更新 train_loss = torch.tensor(0.0, device=train_loss.device, requires_grad=False) lr = None else: lr = self._optimizer.param_groups[0]["lr"] self.log("train_loss", train_loss) self.log("lr", lr, prog_bar=True) return {"loss": train_loss, "lr": lr}
额外提示
- 方案一更贴合PyTorch Lightning设计逻辑,优先选择
- 考虑浮点精度问题,可将
train_loss == 0替换为torch.allclose(train_loss, torch.tensor(0.0)),避免误判接近零的有效损失
内容的提问来源于stack exchange,提问作者Gladiator
相关产品推荐
相关产品推荐

