| 5 | |
| 6 | |
| 7 | class DDIMInversion: |
| 8 | def __init__(self, model, scheduler, NUM_DDIM_STEPS): |
| 9 | self.model = model |
| 10 | self.scheduler = scheduler |
| 11 | self.scheduler.set_timesteps(NUM_DDIM_STEPS) |
| 12 | self.NUM_DDIM_STEPS = NUM_DDIM_STEPS |
| 13 | |
| 14 | def next_step(self, model_output: Union[torch.FloatTensor, np.ndarray], timestep: int, |
| 15 | sample: Union[torch.FloatTensor, np.ndarray]): |
| 16 | timestep, next_timestep = min( |
| 17 | timestep - self.scheduler.config.num_train_timesteps // self.scheduler.num_inference_steps, 999), timestep |
| 18 | alpha_prod_t = self.scheduler.alphas_cumprod[timestep] if timestep >= 0 else self.scheduler.final_alpha_cumprod |
| 19 | alpha_prod_t_next = self.scheduler.alphas_cumprod[next_timestep] |
| 20 | beta_prod_t = 1 - alpha_prod_t |
| 21 | next_original_sample = (sample - beta_prod_t ** 0.5 * model_output) / alpha_prod_t ** 0.5 |
| 22 | next_sample_direction = (1 - alpha_prod_t_next) ** 0.5 * model_output |
| 23 | next_sample = alpha_prod_t_next ** 0.5 * next_original_sample + next_sample_direction |
| 24 | return next_sample |
| 25 | |
| 26 | def get_noise_pred_single(self, latents, t, context, ref_images_pil=None, pose_cond_fea=None): |
| 27 | noise_pred = self.model( |
| 28 | latents, |
| 29 | t, |
| 30 | pose_cond_fea=pose_cond_fea, |
| 31 | encoder_hidden_states=context, |
| 32 | ref_images=ref_images_pil)["sample"] |
| 33 | return noise_pred |
| 34 | |
| 35 | @torch.no_grad() |
| 36 | def init_emb_img(self, clip_emb_im=None): |
| 37 | self.emb_im = clip_emb_im.to(self.model.device) |
| 38 | |
| 39 | @torch.no_grad() |
| 40 | def ddim_loop(self, latent, ref_images_pil=None, pose_cond_fea=None): |
| 41 | cond_embeddings = self.emb_im |
| 42 | all_latent = [latent] |
| 43 | latent = latent.clone().detach() |
| 44 | print('DDIM Inversion:') |
| 45 | for i in tqdm(range(self.NUM_DDIM_STEPS)): |
| 46 | t = self.scheduler.timesteps[len(self.scheduler.timesteps) - i - 1] |
| 47 | noise_pred = self.get_noise_pred_single(latent, t, cond_embeddings, ref_images_pil=ref_images_pil, pose_cond_fea=pose_cond_fea) |
| 48 | latent = self.next_step(noise_pred, t, latent) |
| 49 | all_latent.append(latent) |
| 50 | |
| 51 | return all_latent |
| 52 | |
| 53 | def invert(self, ddim_latents, clip_emb_im=None, ref_images_pil=None, pose_cond_fea=None): |
| 54 | self.init_emb_img(clip_emb_im=clip_emb_im) |
| 55 | ddim_latents = self.ddim_loop(ddim_latents, ref_images_pil=ref_images_pil, pose_cond_fea=pose_cond_fea) |
| 56 | return ddim_latents |
nothing calls this directly
no outgoing calls
no test coverage detected