The error was due to the use of .data attribute. But it runs perfectly fine if i just given output directly to backpropogate.
%%time
import copy
#loss_arr = []
loss_epoch_arr = []
max_epochs = 30
train_loss =[]
valid_loss = []
min_loss = 100
for epoch in range(max_epochs):
for i, data in enumerate(trainloader, 0):

    inputs, labels = data
    inputs, labels = inputs.to(cuda0), labels.to(cuda0)
    
    opt.zero_grad()

    outputs = model(inputs)
    # _,labels = torch.max(labels.data, 1)
    # _,pred = torch.max(outputs.data, 1)
    loss = soft_dice_loss(labels, outputs)
    loss.backward()
    opt.step()

    if min_loss > loss.item():
        min_loss = loss.item()
        best_model = copy.deepcopy(model.state_dict())
        #print('Min loss %0.2f' % min_loss)

    del inputs, labels, outputs
    torch.cuda.empty_cache()
    
    
    #loss_arr.append(loss.item())
    
loss_epoch_arr.append(loss.item())
train_loss.append(evaluation(trainloader, model))
valid_loss.append(evaluation(validloader, model))
print('Epoch: %d/%d, Train DLoss: %0.2f, valid Dloss: %0.2f' % (epoch, max_epochs, evaluation(trainloader, model), evaluation(validloader, model)))

plt.plot(loss_epoch_arr, ‘r’)
plt.plot(train_loss, ‘b’)
plt.plot(valid_loss, ‘g’)
plt.show()
I am not understanding why there is problem with using torch.max? Does using output directly for backpropogation has any effects on accuracy?