Download models/kandinsky5/kandinsky/generation_utils.py from 1ripon1/ColabWan: direct link, hf CLI and curl.
- Browser
- Download file 20.4 kB
-
https://huggingface.co/spaces/1ripon1/ColabWan/resolve/main/models/kandinsky5/kandinsky/generation_utils.py
- Command line
-
hf download hf://spaces/1ripon1/ColabWan/models/kandinsky5/kandinsky/generation_utils.py
-
curl -L -o generation_utils.py https://huggingface.co/spaces/1ripon1/ColabWan/resolve/main/models/kandinsky5/kandinsky/generation_utils.py
20.4 kB
| import os | |
| os.environ["TOKENIZERS_PARALLELISM"] = "False" | |
| import torch | |
| from tqdm import tqdm | |
| from .models.utils import fast_sta_nabla | |
| import torchvision.transforms.functional as F | |
| def get_sparse_params(conf, batch_embeds, device): | |
| assert conf.model.dit_params.patch_size[0] == 1 | |
| T, H, W, _ = batch_embeds["visual"].shape | |
| T, H, W = ( | |
| T // conf.model.dit_params.patch_size[0], | |
| H // conf.model.dit_params.patch_size[1], | |
| W // conf.model.dit_params.patch_size[2], | |
| ) | |
| if conf.model.attention.type == "nabla": | |
| sta_mask = fast_sta_nabla(T, H // 8, W // 8, conf.model.attention.wT, | |
| conf.model.attention.wH, conf.model.attention.wW, device=device) | |
| sparse_params = { | |
| "sta_mask": sta_mask.unsqueeze_(0).unsqueeze_(0), | |
| "attention_type": conf.model.attention.type, | |
| "to_fractal": True, | |
| "P": conf.model.attention.P, | |
| "wT": conf.model.attention.wT, | |
| "wW": conf.model.attention.wW, | |
| "wH": conf.model.attention.wH, | |
| "add_sta": conf.model.attention.add_sta, | |
| "visual_shape": (T, H, W), | |
| "method": getattr(conf.model.attention, "method", "topcdf"), | |
| } | |
| else: | |
| sparse_params = None | |
| return sparse_params | |
| def adaptive_mean_std_normalization(source, reference): | |
| source_mean = source.mean(dim=(1,2,3),keepdim=True) | |
| source_std = source.std(dim=(1,2,3),keepdim=True) | |
| #magic constants - limit changes in latents | |
| clump_mean_low = 0.05 | |
| clump_mean_high = 0.1 | |
| clump_std_low = 0.1 | |
| clump_std_high = 0.25 | |
| reference_mean = torch.clamp(reference.mean(), source_mean - clump_mean_low, source_mean + clump_mean_high) | |
| reference_std = torch.clamp(reference.std(), source_std - clump_std_low, source_std + clump_std_high) | |
| # normalization | |
| normalized = (source - source_mean) / source_std | |
| normalized = normalized * reference_std + reference_mean | |
| return normalized | |
| def normalize_first_frame(latents, reference_frames=5, clump_values=False): | |
| latents_copy = latents.clone() | |
| samples = latents_copy | |
| if samples.shape[0] <= 1: | |
| return (latents, "Only one frame, no normalization needed") | |
| nFr = 4 | |
| first_frames = samples[:nFr] | |
| reference_frames_data = samples[nFr:nFr+min(reference_frames, samples.shape[0]-1)] | |
| # print("First frame stats - Mean:", first_frames.mean(dim=(1,2,3)), "Std: ", first_frames.std(dim=(1,2,3))) | |
| # print(f"Reference frames stats - Mean: {reference_frames_data.mean().item():.4f}, Std: {reference_frames_data.std().item():.4f}") | |
| normalized_first = adaptive_mean_std_normalization(first_frames, reference_frames_data) | |
| if clump_values: | |
| min_val = reference_frames_data.min() | |
| max_val = reference_frames_data.max() | |
| normalized_first = torch.clamp(normalized_first, min_val, max_val) | |
| samples[:nFr] = normalized_first | |
| return samples | |
| def get_velocity( | |
| dit, | |
| x, | |
| t, | |
| text_embeds, | |
| null_text_embeds, | |
| visual_rope_pos, | |
| text_rope_pos, | |
| null_text_rope_pos, | |
| guidance_weight, | |
| conf, | |
| sparse_params=None, | |
| attention_mask=None, | |
| null_attention_mask=None, | |
| joint_pass=False, | |
| ): | |
| with torch._dynamo.utils.disable_cache_limit(): | |
| if joint_pass and abs(guidance_weight - 1.0) > 1e-6: | |
| outputs = dit( | |
| [x, x], | |
| [text_embeds["text_embeds"], null_text_embeds["text_embeds"]], | |
| [text_embeds["pooled_embed"], null_text_embeds["pooled_embed"]], | |
| t * 1000, | |
| [visual_rope_pos, visual_rope_pos], | |
| [text_rope_pos, null_text_rope_pos], | |
| scale_factor=[conf.metrics.scale_factor, conf.metrics.scale_factor], | |
| sparse_params=[sparse_params, sparse_params], | |
| attention_mask=[attention_mask, null_attention_mask], | |
| ) | |
| if outputs is None: | |
| return None | |
| pred_velocity, uncond_pred_velocity = outputs | |
| pred_velocity = uncond_pred_velocity + guidance_weight * ( | |
| pred_velocity - uncond_pred_velocity | |
| ) | |
| else: | |
| pred_velocity = dit( | |
| x, | |
| text_embeds["text_embeds"], | |
| text_embeds["pooled_embed"], | |
| t * 1000, | |
| visual_rope_pos, | |
| text_rope_pos, | |
| scale_factor=conf.metrics.scale_factor, | |
| sparse_params=sparse_params, | |
| attention_mask=attention_mask, | |
| ) | |
| if pred_velocity is None: | |
| return None | |
| if abs(guidance_weight - 1.0) > 1e-6: | |
| uncond_pred_velocity = dit( | |
| x, | |
| null_text_embeds["text_embeds"], | |
| null_text_embeds["pooled_embed"], | |
| t * 1000, | |
| visual_rope_pos, | |
| null_text_rope_pos, | |
| scale_factor=conf.metrics.scale_factor, | |
| sparse_params=sparse_params, | |
| attention_mask=null_attention_mask, | |
| ) | |
| if uncond_pred_velocity is None: | |
| return None | |
| pred_velocity = uncond_pred_velocity + guidance_weight * ( | |
| pred_velocity - uncond_pred_velocity | |
| ) | |
| return pred_velocity | |
| def generate( | |
| model, | |
| device, | |
| img, | |
| num_steps, | |
| text_embeds, | |
| null_text_embeds, | |
| visual_rope_pos, | |
| text_rope_pos, | |
| null_text_rope_pos, | |
| guidance_weight, | |
| scheduler_scale, | |
| first_frames, | |
| conf, | |
| progress=False, | |
| seed=6554, | |
| attention_mask=None, | |
| null_attention_mask=None, | |
| callback=None, | |
| interrupt_check=None, | |
| joint_pass=False, | |
| ): | |
| sparse_params = get_sparse_params(conf, {"visual": img}, device) | |
| timesteps = torch.linspace(1, 0, num_steps + 1, device=device) | |
| timesteps = scheduler_scale * timesteps / (1 + (scheduler_scale - 1) * timesteps) | |
| if callback is not None: | |
| callback(-1, None, True, override_num_inference_steps=num_steps) | |
| step_iter = zip(timesteps[:-1], torch.diff(timesteps)) | |
| if progress: | |
| step_iter = tqdm(step_iter, total=num_steps) | |
| for step_idx, (timestep, timestep_diff) in enumerate(step_iter): | |
| if interrupt_check is not None and interrupt_check(): | |
| return None | |
| time = timestep.unsqueeze(0) | |
| if model.visual_cond: | |
| visual_cond = torch.zeros_like(img) | |
| visual_cond_mask = torch.zeros( | |
| [*img.shape[:-1], 1], dtype=img.dtype, device=img.device | |
| ) | |
| if first_frames is not None: | |
| first_frames = first_frames.to(device=visual_cond.device, dtype=visual_cond.dtype) | |
| img[:1] = first_frames | |
| visual_cond_mask[:1] = 1 | |
| model_input = torch.cat([img, visual_cond, visual_cond_mask], dim=-1) | |
| else: | |
| model_input = img | |
| pred_velocity = get_velocity( | |
| model, | |
| model_input, | |
| time, | |
| text_embeds, | |
| null_text_embeds, | |
| visual_rope_pos, | |
| text_rope_pos, | |
| null_text_rope_pos, | |
| guidance_weight, | |
| conf, | |
| sparse_params=sparse_params, | |
| attention_mask=attention_mask, | |
| null_attention_mask=null_attention_mask, | |
| joint_pass=joint_pass, | |
| ) | |
| if pred_velocity is None: | |
| return None | |
| img[..., :pred_velocity.shape[-1]] += timestep_diff * pred_velocity | |
| if callback is not None: | |
| latents_preview = None | |
| if visual_rope_pos is not None and len(visual_rope_pos) > 0: | |
| duration = int(visual_rope_pos[0].numel()) | |
| if duration > 0 and img.shape[0] % duration == 0: | |
| batch = img.shape[0] // duration | |
| latents_preview = ( | |
| img.reshape(batch, duration, img.shape[1], img.shape[2], img.shape[3]) | |
| .permute(0, 4, 1, 2, 3) | |
| .detach() | |
| )[0] | |
| callback(step_idx, latents_preview, False) | |
| # NOTE: remove extra channels that can be added in Image Editing (I2I) | |
| return img[..., :pred_velocity.shape[-1]] | |
| def resize_video(video, visual_size): | |
| height, width = video.shape[-2:] | |
| nearest_height, nearest_width = visual_size | |
| scale_factor = min(height / nearest_height, width / nearest_width) | |
| video = F.resize(video, (int(height / scale_factor), int(width / scale_factor))) | |
| height, width = video.shape[-2:] | |
| video = F.crop( | |
| video, | |
| (height - nearest_height) // 2, | |
| (width - nearest_width) // 2, | |
| nearest_height, | |
| nearest_width, | |
| ) | |
| return video | |
| def encode_video(data, vae, image_vae): # batch, channels, time, h, w | |
| if image_vae: | |
| assert data.shape[2] == 1 | |
| data = vae.encode(data[:, :, 0]).latent_dist.sample()[:, :, None] | |
| else: | |
| data = vae.encode(data)[0] | |
| data *= vae.config.scaling_factor | |
| return data.permute(0, 2, 3, 4, 1) # batch, time, h, w, channels | |
| def generate_sample( | |
| shape, | |
| caption, | |
| dit, | |
| vae, | |
| conf, | |
| text_embedder, | |
| num_steps=25, | |
| guidance_weight=5.0, | |
| scheduler_scale=1, | |
| negative_caption="", | |
| seed=6554, | |
| device="cuda", | |
| vae_device="cuda", | |
| text_embedder_device="cuda", | |
| progress=True, | |
| joint_pass=False, | |
| callback=None, | |
| interrupt_check=None, | |
| ): | |
| bs, duration, height, width, dim = shape | |
| g = torch.Generator(device="cuda") | |
| g.manual_seed(seed) | |
| img = torch.randn(bs * duration, height, width, dim, device=device, generator=g, dtype=torch.bfloat16) | |
| if duration == 1: | |
| type_of_content = "image" | |
| else: | |
| type_of_content = "video" | |
| with torch.no_grad(): | |
| bs_text_embed, text_cu_seqlens, attention_mask = text_embedder.encode( | |
| [caption], type_of_content=type_of_content | |
| ) | |
| bs_null_text_embed, null_text_cu_seqlens, null_attention_mask = text_embedder.encode( | |
| [negative_caption], type_of_content=type_of_content | |
| ) | |
| for key in bs_text_embed: | |
| bs_text_embed[key] = bs_text_embed[key].to(device=device) | |
| bs_null_text_embed[key] = bs_null_text_embed[key].to(device=device) | |
| if attention_mask is not None: | |
| attention_mask = attention_mask.to(device=device) | |
| if null_attention_mask is not None: | |
| null_attention_mask = null_attention_mask.to(device=device) | |
| text_cu_seqlens = text_cu_seqlens.to(device=device)[-1].item() | |
| null_text_cu_seqlens = null_text_cu_seqlens.to(device=device)[-1].item() | |
| visual_rope_pos = [ | |
| torch.arange(duration), | |
| torch.arange(shape[-3] // conf.model.dit_params.patch_size[1]), | |
| torch.arange(shape[-2] // conf.model.dit_params.patch_size[2]), | |
| ] | |
| text_rope_pos = torch.arange(text_cu_seqlens) | |
| null_text_rope_pos = torch.arange(null_text_cu_seqlens) | |
| with torch.no_grad(): | |
| with torch.autocast(device_type="cuda", dtype=torch.bfloat16): | |
| latent_visual = generate( | |
| dit, | |
| device, | |
| img, | |
| num_steps, | |
| bs_text_embed, | |
| bs_null_text_embed, | |
| visual_rope_pos, | |
| text_rope_pos, | |
| null_text_rope_pos, | |
| guidance_weight, | |
| scheduler_scale, | |
| None, | |
| conf, | |
| seed=seed, | |
| progress=progress, | |
| attention_mask=attention_mask, | |
| null_attention_mask=null_attention_mask, | |
| callback=callback, | |
| interrupt_check=interrupt_check, | |
| joint_pass=joint_pass, | |
| ) | |
| if latent_visual is None: | |
| return None | |
| with torch.no_grad(): | |
| with torch.autocast(device_type="cuda", dtype=torch.bfloat16): | |
| images = latent_visual.reshape( | |
| bs, | |
| -1, | |
| latent_visual.shape[-3], | |
| latent_visual.shape[-2], | |
| latent_visual.shape[-1], | |
| ) | |
| images = images.to(device=vae_device) | |
| images = (images / vae.config.scaling_factor).permute(0, 4, 1, 2, 3) | |
| images = vae.decode(images).sample | |
| images = ((images.clamp(-1.0, 1.0) + 1.0) * 127.5).to(torch.uint8) | |
| return images | |
| def generate_sample_ti2i( | |
| shape, | |
| caption, | |
| dit, | |
| vae, | |
| conf, | |
| text_embedder, | |
| num_steps=25, | |
| guidance_weight=5.0, | |
| scheduler_scale=1, | |
| negative_caption="", | |
| seed=6554, | |
| device="cuda", | |
| vae_device="cuda", | |
| text_embedder_device="cuda", | |
| progress=True, | |
| image_vae=False, | |
| image=None, | |
| joint_pass=False, | |
| callback=None, | |
| interrupt_check=None | |
| ): | |
| bs, duration, height, width, dim = shape | |
| g = torch.Generator(device="cuda") | |
| g.manual_seed(seed) | |
| img = torch.randn(bs * duration, height, width, dim, device=device, generator=g, dtype=torch.bfloat16) | |
| if duration == 1: | |
| if image is None: | |
| type_of_content = "image" | |
| else: | |
| type_of_content = 'image_edit' | |
| else: | |
| type_of_content = "video" | |
| if image is not None: | |
| image = [resize_video(image, (height * 8, width * 8))] | |
| if dit.instruct_type == 'channel': | |
| if image is not None: | |
| edit_latent = [(i.to(device=vae_device, dtype=torch.bfloat16) / 127.5 - 1.0) for i in image] | |
| edit_latent = torch.cat([encode_video(i[:,:,None], vae, image_vae).squeeze(0) for i in edit_latent], 0) | |
| edit_latent = torch.cat([edit_latent, torch.ones_like(img[...,:1])],-1) | |
| else: | |
| edit_latent = torch.cat([torch.zeros_like(img), torch.zeros_like(img[...,:1])],-1) | |
| img = torch.cat([img, edit_latent],dim=-1) | |
| with torch.no_grad(): | |
| bs_text_embed, text_cu_seqlens, attention_mask = text_embedder.encode( | |
| [caption], type_of_content=type_of_content, images=image | |
| ) | |
| bs_null_text_embed, null_text_cu_seqlens, null_attention_mask = text_embedder.encode( | |
| [negative_caption], type_of_content=type_of_content, images=image | |
| ) | |
| for key in bs_text_embed: | |
| bs_text_embed[key] = bs_text_embed[key].to(device=device,dtype=torch.bfloat16) | |
| bs_null_text_embed[key] = bs_null_text_embed[key].to(device=device,dtype=torch.bfloat16) | |
| if attention_mask is not None: | |
| attention_mask = attention_mask.to(device=device) | |
| if null_attention_mask is not None: | |
| null_attention_mask = null_attention_mask.to(device=device) | |
| text_cu_seqlens = text_cu_seqlens.to(device=device)[-1].item() | |
| null_text_cu_seqlens = null_text_cu_seqlens.to(device=device)[-1].item() | |
| visual_rope_pos = [ | |
| torch.arange(duration), | |
| torch.arange(shape[-3] // conf.model.dit_params.patch_size[1]), | |
| torch.arange(shape[-2] // conf.model.dit_params.patch_size[2]), | |
| ] | |
| text_rope_pos = torch.arange(text_cu_seqlens) | |
| null_text_rope_pos = torch.arange(null_text_cu_seqlens) | |
| with torch.no_grad(): | |
| with torch.autocast(device_type="cuda", dtype=torch.bfloat16): | |
| latent_visual = generate( | |
| dit, | |
| device, | |
| img, | |
| num_steps, | |
| bs_text_embed, | |
| bs_null_text_embed, | |
| visual_rope_pos, | |
| text_rope_pos, | |
| null_text_rope_pos, | |
| guidance_weight, | |
| scheduler_scale, | |
| None, | |
| conf, | |
| seed=seed, | |
| progress=progress, | |
| attention_mask=attention_mask, | |
| null_attention_mask=null_attention_mask, | |
| callback=callback, | |
| interrupt_check=interrupt_check, | |
| joint_pass=joint_pass, | |
| ) | |
| if latent_visual is None: | |
| return None | |
| with torch.no_grad(): | |
| with torch.autocast(device_type="cuda", dtype=torch.bfloat16): | |
| images = latent_visual.reshape( | |
| bs, | |
| -1, | |
| latent_visual.shape[-3], | |
| latent_visual.shape[-2], | |
| latent_visual.shape[-1], | |
| ) | |
| images = images.to(device=vae_device) | |
| images = (images / vae.config.scaling_factor).permute(0, 4, 1, 2, 3) | |
| if image_vae: | |
| images = images[:,:,0] | |
| images = vae.decode(images).sample | |
| images = ((images.clamp(-1.0, 1.0) + 1.0) * 127.5).to(torch.uint8) | |
| return images | |
| def generate_sample_i2v( | |
| shape, | |
| caption, | |
| dit, | |
| vae, | |
| conf, | |
| text_embedder, | |
| images, | |
| num_steps=50, | |
| guidance_weight=5.0, | |
| scheduler_scale=1, | |
| negative_caption="", | |
| seed=6554, | |
| device="cuda", | |
| vae_device="cuda", | |
| progress=True, | |
| callback=None, | |
| joint_pass=False, | |
| interrupt_check=None | |
| ): | |
| text_embedder.embedder.mode = "i2v" | |
| bs, duration, height, width, dim = shape | |
| g = torch.Generator(device="cuda") | |
| g.manual_seed(seed) | |
| img = torch.randn(bs * duration, height, width, dim, device=device, generator=g, dtype=torch.bfloat16) | |
| if duration == 1: | |
| type_of_content = "image" | |
| else: | |
| type_of_content = "video" | |
| with torch.no_grad(): | |
| bs_text_embed, text_cu_seqlens, attention_mask = text_embedder.encode( | |
| [caption], type_of_content=type_of_content | |
| ) | |
| bs_null_text_embed, null_text_cu_seqlens, null_attention_mask = text_embedder.encode( | |
| [negative_caption], type_of_content=type_of_content | |
| ) | |
| for key in bs_text_embed: | |
| bs_text_embed[key] = bs_text_embed[key].to(device=device) | |
| bs_null_text_embed[key] = bs_null_text_embed[key].to(device=device) | |
| if attention_mask is not None: | |
| attention_mask = attention_mask.to(device=device) | |
| if null_attention_mask is not None: | |
| null_attention_mask = null_attention_mask.to(device=device) | |
| text_cu_seqlens = text_cu_seqlens.to(device=device)[-1].item() | |
| null_text_cu_seqlens = null_text_cu_seqlens.to(device=device)[-1].item() | |
| visual_rope_pos = [ | |
| torch.arange(duration), | |
| torch.arange(shape[-3] // conf.model.dit_params.patch_size[1]), | |
| torch.arange(shape[-2] // conf.model.dit_params.patch_size[2]), | |
| ] | |
| text_rope_pos = torch.arange(text_cu_seqlens) | |
| null_text_rope_pos = torch.arange(null_text_cu_seqlens) | |
| first_frames = images | |
| with torch.no_grad(): | |
| with torch.autocast(device_type="cuda", dtype=torch.bfloat16): | |
| latent_visual = generate( | |
| dit, | |
| device, | |
| img, | |
| num_steps, | |
| bs_text_embed, | |
| bs_null_text_embed, | |
| visual_rope_pos, | |
| text_rope_pos, | |
| null_text_rope_pos, | |
| guidance_weight, | |
| scheduler_scale, | |
| first_frames, | |
| conf, | |
| seed=seed, | |
| progress=progress, | |
| attention_mask=attention_mask, | |
| null_attention_mask=null_attention_mask, | |
| callback=callback, | |
| interrupt_check=interrupt_check, | |
| joint_pass=joint_pass, | |
| ) | |
| if latent_visual is None: | |
| return None | |
| if images is not None: | |
| images = images.to(device=latent_visual.device, dtype=latent_visual.dtype) | |
| latent_visual[:1] = images | |
| latent_visual = normalize_first_frame(latent_visual) | |
| with torch.no_grad(): | |
| with torch.autocast(device_type="cuda", dtype=torch.bfloat16): | |
| images = latent_visual.reshape( | |
| bs, | |
| -1, | |
| latent_visual.shape[-3], | |
| latent_visual.shape[-2], | |
| latent_visual.shape[-1], | |
| ) | |
| images = images.to(device=vae_device) | |
| images = (images / vae.config.scaling_factor).permute(0, 4, 1, 2, 3) | |
| images = vae.decode(images).sample | |
| images = ((images.clamp(-1.0, 1.0) + 1.0) * 127.5).to(torch.uint8) | |
| return images | |