I made a function to compute the IoU loss of 2 spans
def iou_loss(pred_start, pred_end, target_start, target_end):
    """
    pred_start, pred_end, target_start, target_end: b, *
    """

    num_common = (
        torch.minimum(pred_end, target_end)
        - torch.maximum(pred_start, target_start) + 1
    ).clamp_min_(0)

    num_pred = (pred_end - pred_start + 1).clamp_min_(0)
    num_target = target_end - target_start + 1

    iou = num_common / (num_pred + num_target - num_common)

    return 1 - iou

However the gradients are not zero when the loss is at its global minimum.
pred_start = torch.tensor([5, 2], dtype=torch.float, requires_grad=True)
pred_end = torch.tensor([5, 4], dtype=torch.float, requires_grad=True)
target_start = torch.tensor([5, 2])
target_end = torch.tensor([5, 4])

l = iou_loss(pred_start, pred_end, target_start, target_end)
print(l)
# tensor([0., 0.], grad_fn=<RsubBackward1>)

l = l.mean()
l.backward()

print(pred_start.grad)
# tensor([-0.5000, -0.1667])

print(pred_end.grad)
# tensor([0.5000, 0.1667])

Can anyone help me to understand why? Any help would be appreciated.