MCPcopy Create free account
hub / github.com/Francis-Rings/MotionFollower / DDIMInversion

Class DDIMInversion

src/utils/inversion.py:7–56  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

5
6
7class 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

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected