If I’m not missing something obvious, do you really need to explicitly pass the embedding.parameters() to the opt, since you already gave it encoder.parameters() which includes embedding.parameters()?
The code for nn.Module.__setattr__() suggests that it will remove duplicate parameters passed to it, so it seems to me that

opt = optim.Adam(list(encoder.parameters()) + list(decoder.parameters()))

should be fine.