def METHOD_NAME(self, batch_id, data, outputs):
    """update metrics during each iter
    """
    hit_at_one = paddle.to_tensor(outputs['hit_at_one'])
    perr = paddle.to_tensor(outputs['perr'])
    gap = paddle.to_tensor(outputs['gap'])
    # NOTE(shipping): deal with multi cards validate
    if self.world_size > 1:
        hit_at_one = paddle.distributed.all_reduce(
            hit_at_one,
            op=paddle.distributed.ReduceOp.SUM) / self.world_size
        perr = paddle.distributed.all_reduce(
            perr, op=paddle.distributed.ReduceOp.SUM) / self.world_size
        gap = paddle.distributed.all_reduce(
            gap, op=paddle.distributed.ReduceOp.SUM) / self.world_size
    self.hit_at_one.append(hit_at_one.numpy())
    self.perr.append(perr.numpy())
    self.gap.append(gap.numpy())
    # preds ensemble
    if batch_id % self.log_interval == 0:
        logger.info("[TEST] Processing batch {}/{}...".format(
            batch_id,
            self.data_size // (self.batch_size * self.world_size),
        ))