The way DataParallel works is that at each iteration, it creates a replica of the input model on each device. So each device has it’s own replica of the model, a different python object than the input model. So your original approach of directly assigning doesn’t work, as it is assigning as an attribute on a replica, which is freed after the iteration.
The weights & buffers of these replicas are linked to the original weights & buffers in input model by autograd graph, so backward still works. Moreover, weights & buffers of the replica on device[0] share storage with those of the input model! So the inplace version “works” in the sense that changes done on the first replica (on device[0]) will propagate through. However, changes from other replicas are lost.