Both approaches work identical as seen here:
def get_optimizerA(model):
    lr = 1.
    params = []
    for key, value in model.named_parameters():
        if value.requires_grad:
            params += [{'params': [value], 'lr': lr, 'weight_decay': 0}]
    optimizer = torch.optim.SGD(params, momentum=0.9)
    return optimizer

def get_optimizerB(model):
    lr = 1.
    optimizer = torch.optim.SGD(model.parameters(), lr=lr, momentum=0.9)
    return optimizer

# setup
modelA = models.resnet18().eval()
modelB = models.resnet18().eval()
modelB.load_state_dict(modelA.state_dict())
x = torch.randn(2, 3, 224, 224)

optimizerA = get_optimizerA(modelA)
optimizerB = get_optimizerB(modelB)

outA = modelA(x)
outB = modelB(x)

lossA = outA.mean()
lossB = outB.mean()
print((lossA - lossB).abs())

lossA.backward()
lossB.backward()

optimizerA.step()
optimizerB.step()

for (nameA, paramA), (nameB, paramB) in zip(modelA.named_parameters(), modelB.named_parameters()):
    if not nameA == nameB:
        print("Error in iterating param dicts")
        break
    print('{}: abs.max error {}'.format(nameA, (paramA - paramB).abs().max()))

Could you post an executable code snippet, which would reproduce the issue you are seeing?