The Decoder can consist of multiple Unets (e.g., for cascading diffusion). Training them manually is complex because each Unet requires its own optimizer and exponential moving average (EMA). DecoderTrainer simplifies this by managing multiple optimizers and EMAs automatically.
To train, iterate through the unet_numbers (the index of the Unet in the Decoder.unet tuple) and call the trainer. Use max_batch_size to implement gradient accumulation.
Key steps:
- Instantiate
CLIP, Unets, and the Decoder. - Wrap the
Decoder in a DecoderTrainer. - In a training loop, call
decoder_trainer(images, text=text, unet_number=i, max_batch_size=N). - Call
decoder_trainer.update(unet_number=i) to update the specific Unet and its EMA. - Use
decoder_trainer.sample(...) to generate images from the EMA weights.
import torch
from dalle2_pytorch import Unet, Decoder, CLIP, DecoderTrainer
clip = CLIP(...).cuda()
unet1 = Unet(dim=128, image_embed_dim=512, text_embed_dim=512, cond_dim=128, channels=3, dim_mults=(1, 2, 4, 8), cond_on_text_encodings=True).cuda()
unet2 = Unet(dim=16, image_embed_dim=512, cond_dim=128, channels=3, dim_mults=(1, 2, 4, 8, 16)).cuda()
decoder = Decoder(
unet = (unet1, unet2),
image_sizes = (128, 256),
clip = clip,
timesteps = 1000
).cuda()
decoder_trainer = DecoderTrainer(
decoder,
lr = 3e-4,
wd = 1e-2,
ema_beta = 0.99,
ema_update_after_step = 1000,
ema_update_every = 10,
)
# Training loop
for unet_number in (1, 2):
loss = decoder_trainer(
images,
text = text,
unet_number = unet_number,
max_batch_size = 4
)
decoder_trainer.update(unet_number)
# Sampling
images = decoder_trainer.sample(image_embed = mock_image_embed, text = text)