(self, batch, batch_idx)
| 178 | ) |
| 179 | |
| 180 | def training_step(self, batch, batch_idx): |
| 181 | # get input |
| 182 | cond_imgs, target_imgs = self.prepare_batch_data(batch) |
| 183 | |
| 184 | # sample random timestep |
| 185 | B = cond_imgs.shape[0] |
| 186 | |
| 187 | t = torch.randint(0, self.num_timesteps, size=(B,)).long().to(self.device) |
| 188 | |
| 189 | # classifier-free guidance |
| 190 | if np.random.rand() < self.drop_cond_prob: |
| 191 | prompt_embeds = self.pipeline._encode_prompt([""]*B, self.device, 1, False) |
| 192 | cond_latents = self.encode_condition_image(torch.zeros_like(cond_imgs)) |
| 193 | else: |
| 194 | prompt_embeds = self.forward_vision_encoder(cond_imgs) |
| 195 | cond_latents = self.encode_condition_image(cond_imgs) |
| 196 | |
| 197 | latents = self.encode_target_images(target_imgs) |
| 198 | noise = torch.randn_like(latents) |
| 199 | latents_noisy = self.train_scheduler.add_noise(latents, noise, t) |
| 200 | |
| 201 | v_pred = self.forward_unet(latents_noisy, t, prompt_embeds, cond_latents) |
| 202 | v_target = self.get_v(latents, noise, t) |
| 203 | |
| 204 | loss, loss_dict = self.compute_loss(v_pred, v_target) |
| 205 | |
| 206 | # logging |
| 207 | self.log_dict(loss_dict, prog_bar=True, logger=True, on_step=True, on_epoch=True) |
| 208 | self.log("global_step", self.global_step, prog_bar=True, logger=True, on_step=True, on_epoch=False) |
| 209 | lr = self.optimizers().param_groups[0]['lr'] |
| 210 | self.log('lr_abs', lr, prog_bar=True, logger=True, on_step=True, on_epoch=False) |
| 211 | |
| 212 | if self.global_step % 500 == 0 and self.global_rank == 0: |
| 213 | with torch.no_grad(): |
| 214 | latents_pred = self.predict_start_from_z_and_v(latents_noisy, t, v_pred) |
| 215 | |
| 216 | latents = unscale_latents(latents_pred) |
| 217 | images = unscale_image(self.pipeline.vae.decode(latents / self.pipeline.vae.config.scaling_factor, return_dict=False)[0]) # [-1, 1] |
| 218 | images = (images * 0.5 + 0.5).clamp(0, 1) |
| 219 | images = torch.cat([target_imgs, images], dim=-2) |
| 220 | |
| 221 | grid = make_grid(images, nrow=images.shape[0], normalize=True, value_range=(0, 1)) |
| 222 | save_image(grid, os.path.join(self.logdir, 'images', f'train_{self.global_step:07d}.png')) |
| 223 | |
| 224 | return loss |
| 225 | |
| 226 | def compute_loss(self, noise_pred, noise_gt): |
| 227 | loss = F.mse_loss(noise_pred, noise_gt) |
nothing calls this directly
no test coverage detected