def METHOD_NAME(self, split, records, logger, global_step, **kwargs):
    loss = torch.FloatTensor(records["loss"]).mean().item()
    results = {"loss": loss}
    for metric in self.metrics:
        results[metric] = eval(metric)(
            hypothesis=records["hypothesis"],
            groundtruth=records["groundtruth"],
        )
    save_names = []
    for key, value in results.items():
        print(f"{split} {key}: {value}")
        logger.add_scalar(
            f"{self._get_task_name()}/{split}-{key}", value, global_step=global_step
        )
        if key == self.metrics[0]:
            save_criterion = (
                value > self.best_score
                if self.metric_higher_better
                else value < self.best_score
            )
            if split in self.save_best_on and save_criterion:
                self.best_score = torch.ones(1) * value
                save_names.append(f"{split}-best.ckpt")
    if "test" in split or "dev" in split:
        hyp_ark = open(os.path.join(self.expdir, f"{split}-hyp.ark"), "w")
        ref_ark = open(os.path.join(self.expdir, f"{split}-ref.ark"), "w")
        for filename, hyp, ref in zip(
            records["filename"], records["hypothesis"], records["groundtruth"]
        ):
            hyp_ark.write(f"{filename} {hyp}\n")
            ref_ark.write(f"{filename} {ref}\n")
        hyp_ark.close()
        ref_ark.close()
    return save_names