MCPcopy Create free account
hub / github.com/SpatialVLA/SpatialVLA / compute_loss

Function compute_loss

train/monkey_patch.py:222–326  ·  view source on GitHub ↗

How the loss is computed by Trainer. By default, all models return the loss in the first element. Subclass and override for custom behavior.

(self, model, inputs, return_outputs=False, num_items_in_batch=None)

Source from the content-addressed store, hash-verified

220 print("Replace train dataloader!!")
221
222def compute_loss(self, model, inputs, return_outputs=False, num_items_in_batch=None):
223 """
224 How the loss is computed by Trainer. By default, all models return the loss in the first element.
225
226 Subclass and override for custom behavior.
227 """
228 if (self.label_smoother is not None or self.compute_loss_func is not None) and "labels" in inputs:
229 labels = inputs.pop("labels")
230 else:
231 labels = None
232 if self.model_accepts_loss_kwargs:
233 loss_kwargs = {}
234 if num_items_in_batch is not None:
235 loss_kwargs["num_items_in_batch"] = num_items_in_batch
236 inputs = {**inputs, **loss_kwargs}
237 outputs = model(**inputs)
238 # Save past state if it exists
239 if self.args.past_index >= 0:
240 self._past = outputs[self.args.past_index]
241
242 if labels is not None:
243 unwrapped_model = self.accelerator.unwrap_model(model)
244 if _is_peft_model(unwrapped_model):
245 model_name = unwrapped_model.base_model.model._get_name()
246 else:
247 model_name = unwrapped_model._get_name()
248 # User-defined compute_loss function
249 if self.compute_loss_func is not None:
250 loss = self.compute_loss_func(outputs, labels, num_items_in_batch=num_items_in_batch)
251 elif model_name in MODEL_FOR_CAUSAL_LM_MAPPING_NAMES.values():
252 loss = self.label_smoother(outputs, labels, shift_labels=True)
253 else:
254 loss = self.label_smoother(outputs, labels)
255 else:
256 if isinstance(outputs, dict) and "loss" not in outputs:
257 raise ValueError(
258 "The model did not return a loss from the inputs, only the following keys: "
259 f"{','.join(outputs.keys())}. For reference, the inputs it received are {','.join(inputs.keys())}."
260 )
261 # We don't use .loss here since the model may return tuples instead of ModelOutput.
262 loss = outputs["loss"] if isinstance(outputs, dict) else outputs[0]
263
264 if self.args.average_tokens_across_devices and self.model_accepts_loss_kwargs:
265 loss *= self.accelerator.num_processes
266
267 with torch.no_grad():
268 logits = outputs["logits"] # (bs, seq, voc)
269 labels = inputs["labels"] # (bs, seq)
270 shift_logits = logits[..., :-1, :].argmax(-1).contiguous()
271 shift_labels = labels[..., 1:].contiguous()
272
273 mask = (shift_labels >= model.action_tokenizer.translation_tokenizer.token_start_idx) & (
274 shift_labels <= model.action_tokenizer.gripper_tokenizer.token_end_idx
275 )
276 gt_action_ids, pred_action_ids = shift_labels[mask], shift_logits[mask]
277 correct_preds = gt_action_ids == pred_action_ids
278 action_accuracy = correct_preds.sum().float() / mask.sum().float()
279

Callers

nothing calls this directly

Calls 1

Tested by

no test coverage detected