Hi,
In this case, you should not save it on ctx at all and only with save_for_backward:
I couldn’t run the code so there might be typos. But this is the idea:
class CustomStd(torch.autograd.Function):
    @staticmethod
    def forward(ctx, input, dim=None, keepdim=False, eps=1e-5, unbiased=True):
        if dim is None:
            dim = tuple([i for i in range(input.dim())])
        dev = input - input.mean(dim=dim, keepdim=True)
        ctx.eps=eps
        ctx.dev = dev
        ctx.numdim = input.dim()
        ctx.numel = functools.reduce(lambda x, y: x * y, [input.size(d) for d in dim])
        if unbiased:
            ctx.numel -= 1
        std = torch.sqrt(torch.sum(dev * dev, dim=dim, keepdim=True) / ctx.numel)
        ctx.std_shape = std.shape
        res = std if keepdim else std.squeeze()
        ctx.save_for_backward(input, res)
        return res

    @staticmethod
    def backward(ctx, grad_output):
        input, res = ctx.saved_tensors
        std = res.view(std_shape)
        grad_input = grad_output
        for i in range(grad_output.dim(), ctx.numdim):
            grad_input = grad_input.unsqueeze(i)
        grad_input = ctx.dev * (ctx.numel - 1) / (ctx.numel**2) / (std + ctx.eps) * grad_input
        return grad_input, None, None, None, None