If I’m understanding the issue correctly, the first approach (using the optimizer) doesn’t update w1 while the second one (using the manual parameter updates) works?
If so, then this would be expected, as you haven’t passed w1 to torch.optim.Adam, but model.parameters() only.
Use
optim = torch.optim.Adam(list(model.parameters()) + [w1], lr=1e-4, eps=1e-8)

and it should work.