def METHOD_NAME(model_outputs, loss_img, loss_txt, loss_cfg):
    image_features = model_outputs[OutputKeys.IMG_EMBEDDING]
    text_features = model_outputs[OutputKeys.TEXT_EMBEDDING]
    logit_scale = model_outputs['logit_scale']
    logit_scale = logit_scale.mean()
    if loss_cfg.aggregate and int(os.environ.get('WORLD_SIZE', 1)) > 1:
        world_size = dist.get_world_size()
        rank = dist.get_rank()
        # We gather tensors from all gpus to get more negatives to contrast with.
        gathered_image_features = [
            torch.zeros_like(image_features) for _ in range(world_size)
        ]
        gathered_text_features = [
            torch.zeros_like(text_features) for _ in range(world_size)
        ]
        dist.all_gather(gathered_image_features, image_features)
        dist.all_gather(gathered_text_features, text_features)
        all_image_features = torch.cat([image_features]
                                       + gathered_image_features[:rank]
                                       + gathered_image_features[rank + 1:])
        all_text_features = torch.cat([text_features]
                                      + gathered_text_features[:rank]
                                      + gathered_text_features[rank + 1:])
        # this is needed to send gradients back everywhere.
        logits_per_image = logit_scale * all_image_features @ all_text_features.t(
        )
        logits_per_text = logits_per_image.t()
    else:
        logits_per_image = logit_scale * image_features @ text_features.t()
        logits_per_text = logit_scale * text_features @ image_features.t()
    ground_truth = torch.arange(len(logits_per_image)).long()
    ground_truth = ground_truth.cuda(
        int(os.environ.get('LOCAL_RANK', 0)), non_blocking=True)
    total_loss = (loss_img(logits_per_image, ground_truth)
                  + loss_txt(logits_per_text, ground_truth)) / 2
    return total_loss