def next_token_metrics_epoch_end(self, outputs, stage):
    '\n        Logic for validation & testing epoch end:\n        1) Calculate accuracy@1, accuracy@5, MRR@5\n        2) (in val stage only) Aggregate loss and log metric(s) for ModelCheckpoint\n        3) Log everything to wandb\n        '
    loss = torch.stack([x['loss'] for x in outputs]).mean()
    metrics = {f'{stage}_loss_epoch': loss}
    if (stage == 'val'):
        self.log('val_loss_epoch', metrics['val_loss_epoch'], on_step=False, on_epoch=True, prog_bar=True, logger=False)
    self.logger.experiment.log(metrics, step=self.examples_count)
Logic for validation & testing epoch end:
1) Calculate accuracy@1, accuracy@5, MRR@5
2) (in val stage only) Aggregate loss and log metric(s) for ModelCheckpoint
3) Log everything to wandb
def next_token_metrics_epoch_end(self, outputs, stage):
    '\n        Logic for validation & testing epoch end:\n        1) Calculate accuracy@1, accuracy@5, MRR@5\n        2) (in val stage only) Aggregate loss and log metric(s) for ModelCheckpoint\n        3) Log everything to wandb\n        '
    loss = torch.stack([x['loss'] for x in outputs]).mean()
    metrics = {f'{stage}_loss_epoch': loss}
    if (stage == 'val'):
        self.log('val_loss_epoch', metrics['val_loss_epoch'], on_step=False, on_epoch=True, prog_bar=True, logger=False)
    self.logger.experiment.log(metrics, step=self.examples_count)