Hi,
The problem is that M is the same during process 1 and 2. You won’t be able to get 2 different behaviors here.
If would suggest doing two steps (add the corresponding optimizer zero grad and step of course):
# Process 1 as usual:
P = M(A)
C = some_func(P)

# Now break the graph and get a new C
C_2 = C.detach().requires_grad_()

# Process 2
Q = M(C_2)
loss = criterion(Q, label)

# Compute grads for C_2 (but don't change .grads in M)
C_2_grad = autograd.grad(loss, C_2)[0]

# Not do a regular backward for process 1 to populate the .grad in M
C.backward(C_2_grad)