def METHOD_NAME(
    compressed_model_outputs: Any,
    orig_model_outputs: Any,
    kd_loss_fn: Callable[[torch.Tensor, torch.Tensor], torch.Tensor],
) -> Optional[torch.Tensor]:
    """
    Calculates knowledge distillation loss value from compressed_model_outputs and orig_model_outputs. First uses
    nested_object_paths_generator to unpack input containers and numerate contents inside them.
    Than checks compressed_model_outputs unpacked container for loss tensors (requires_grad=True)
    and maps extracted structure of loss tensors to orig_model_outputs.
    Finally computes knowledge distillation loss with extracted loss tensors.
    :param compressed_model_outputs: Output tensors of compressed model can be any type of container with
        deterministic traversal.
    :param orig_model_outputs: Output tensors of original model (used for distillation) can be any type of
        container with deterministic traversal.
    :return: knowledge distillation loss value
    """
    compressed_model_outputs_nested_obj_indexing = NestedObjectIndex([compressed_model_outputs])
    orig_model_outputs_nested_obj_indexing = NestedObjectIndex([orig_model_outputs])
    compressed_model_loss_outputs_nested_obj_indexing = list(
        filter(
            lambda x: KnowledgeDistillationLoss._is_loss(x.getter()),
            compressed_model_outputs_nested_obj_indexing.get_flat_nested_obj_indexing(),
        )
    )
    compressed_model_loss_outputs = list(
        map(lambda x: x.getter(), compressed_model_loss_outputs_nested_obj_indexing)
    )
    def match_fn(obj):
        for x in compressed_model_loss_outputs_nested_obj_indexing:
            if x.path == obj.path:
                return True
        return False
    orig_model_loss_outputs = list(
        map(
            lambda x: x.getter(),
            filter(match_fn, orig_model_outputs_nested_obj_indexing.get_flat_nested_obj_indexing()),
        )
    )
    if len(orig_model_loss_outputs) != len(compressed_model_loss_outputs):
        nncf_logger.warning(
            f"KD: mismatch in the number of detected loss tensors in return value between original "
            f"and compressed models;\n"
            f"original has {len(orig_model_loss_outputs)} loss tensors,\n"
            f"compressed has {len(compressed_model_loss_outputs)}"
        )
    if not orig_model_loss_outputs:
        nncf_logger.warning("KD: no loss outputs detected in original model, knowledge distillation not possible")
        return None
    if not compressed_model_loss_outputs:
        nncf_logger.warning("KD: no loss outputs detected in compressed model, knowledge distillation not possible")
        return None
    return reduce(
        lambda kd_loss, loss_tensors: kd_loss + kd_loss_fn(loss_tensors[0], loss_tensors[1]),
        zip(orig_model_loss_outputs, compressed_model_loss_outputs),
        torch.zeros([], device=orig_model_loss_outputs[0].device),
    )