diff --git a/README.md b/README.md index 612e193..39c45ed 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,10 @@ Get the model from here, put it in ComfyUI/models/checkpoints and name it `dynamicrafter_1024_v1.ckpt` https://huggingface.co/Doubiiu/DynamiCrafter_1024 -With fp16 1024x576 uses bit under 12GB VRAM +Interpolation model should be named `dynamicrafter_512_interp_v1.ckpt` +https://huggingface.co/Doubiiu/DynamiCrafter_512_Interp/ + +With fp16 1024x576 uses bit under 12GB VRAM, and interpolation at 512p can be done with 8GB # ORIGINAL REPO: diff --git a/configs/dynamicrafter_256_v1.yaml b/configs/dynamicrafter_256_v1.yaml index 3f09879..88ebc82 100644 --- a/configs/dynamicrafter_256_v1.yaml +++ b/configs/dynamicrafter_256_v1.yaml @@ -1,5 +1,5 @@ model: - target: lvdm.models.ddpm3d.LatentVisualDiffusion + target: .lvdm.models.ddpm3d.LatentVisualDiffusion params: linear_start: 0.00085 linear_end: 0.012 @@ -16,7 +16,7 @@ model: use_ema: False uncond_type: 'empty_seq' unet_config: - target: lvdm.modules.networks.openaimodel3d.UNetModel + target: .lvdm.modules.networks.openaimodel3d.UNetModel params: in_channels: 8 out_channels: 4 @@ -50,7 +50,7 @@ model: fs_condition: true first_stage_config: - target: lvdm.models.autoencoder.AutoencoderKL + target: .lvdm.models.autoencoder.AutoencoderKL params: embed_dim: 4 monitor: val/rec_loss @@ -73,18 +73,18 @@ model: target: torch.nn.Identity cond_stage_config: - target: lvdm.modules.encoders.condition.FrozenOpenCLIPEmbedder + target: .lvdm.modules.encoders.condition.FrozenOpenCLIPEmbedder params: freeze: true layer: "penultimate" img_cond_stage_config: - target: lvdm.modules.encoders.condition.FrozenOpenCLIPImageEmbedderV2 + target: .lvdm.modules.encoders.condition.FrozenOpenCLIPImageEmbedderV2 params: freeze: true image_proj_stage_config: - target: lvdm.modules.encoders.resampler.Resampler + target: .lvdm.modules.encoders.resampler.Resampler params: dim: 1024 depth: 4 diff --git a/configs/dynamicrafter_512_interp_v1.yaml b/configs/dynamicrafter_512_interp_v1.yaml new file mode 100644 index 0000000..581e274 --- /dev/null +++ b/configs/dynamicrafter_512_interp_v1.yaml @@ -0,0 +1,103 @@ +model: + target: .lvdm.models.ddpm3d.LatentVisualDiffusion + params: + rescale_betas_zero_snr: True + parameterization: "v" + linear_start: 0.00085 + linear_end: 0.012 + num_timesteps_cond: 1 + timesteps: 1000 + first_stage_key: video + cond_stage_key: caption + cond_stage_trainable: False + conditioning_key: hybrid + image_size: [40, 64] + channels: 4 + scale_by_std: False + scale_factor: 0.18215 + use_ema: False + uncond_type: 'empty_seq' + use_dynamic_rescale: true + base_scale: 0.7 + fps_condition_type: 'fps' + perframe_ae: True + unet_config: + target: .lvdm.modules.networks.openaimodel3d.UNetModel + params: + in_channels: 8 + out_channels: 4 + model_channels: 320 + attention_resolutions: + - 4 + - 2 + - 1 + num_res_blocks: 2 + channel_mult: + - 1 + - 2 + - 4 + - 4 + dropout: 0.1 + num_head_channels: 64 + transformer_depth: 1 + context_dim: 1024 + use_linear: true + use_checkpoint: True + temporal_conv: True + temporal_attention: True + temporal_selfatt_only: true + use_relative_position: false + use_causal_attention: False + temporal_length: 16 + addition_attention: true + image_cross_attention: true + default_fs: 24 + fs_condition: true + + first_stage_config: + target: .lvdm.models.autoencoder.AutoencoderKL + params: + embed_dim: 4 + monitor: val/rec_loss + ddconfig: + double_z: True + z_channels: 4 + resolution: 256 + in_channels: 3 + out_ch: 3 + ch: 128 + ch_mult: + - 1 + - 2 + - 4 + - 4 + num_res_blocks: 2 + attn_resolutions: [] + dropout: 0.0 + lossconfig: + target: torch.nn.Identity + + cond_stage_config: + target: .lvdm.modules.encoders.condition.FrozenOpenCLIPEmbedder + params: + freeze: true + layer: "penultimate" + + img_cond_stage_config: + target: .lvdm.modules.encoders.condition.FrozenOpenCLIPImageEmbedderV2 + params: + freeze: true + + image_proj_stage_config: + target: .lvdm.modules.encoders.resampler.Resampler + params: + dim: 1024 + depth: 4 + dim_head: 64 + heads: 12 + num_queries: 16 + embedding_dim: 1280 + output_dim: 1024 + ff_mult: 4 + video_length: 16 + diff --git a/nodes.py b/nodes.py index 77e9f68..1289fab 100644 --- a/nodes.py +++ b/nodes.py @@ -50,6 +50,10 @@ class DynamiCrafterI2V: "default": 'fp16' }), "keep_model_loaded": ("BOOLEAN", {"default": True}), + + }, + "optional": { + "optional_image2": ("IMAGE",), } } @@ -58,7 +62,7 @@ class DynamiCrafterI2V: FUNCTION = "process" CATEGORY = "DynamiCrafter" - def process(self, image, dtype, ckpt_name, prompt, cfg, steps, eta, seed, fs, keep_model_loaded): + def process(self, image, dtype, ckpt_name, prompt, cfg, steps, eta, seed, fs, keep_model_loaded, optional_image2=None): device = mm.get_torch_device() mm.unload_all_models() mm.soft_empty_cache() @@ -84,18 +88,31 @@ class DynamiCrafterI2V: channels = self.model.model.diffusion_model.out_channels frames = self.model.temporal_length B, H, W, C = image.shape - + image2 = optional_image2 noise_shape = [B, channels, frames, H // 8, W // 8] - - image = image * 2 - 1 - image = image.permute(0, 3, 1, 2).to(dtype).to(device) + autocast_condition = (dtype != torch.float32) and not comfy.model_management.is_device_mps(device) with torch.autocast(comfy.model_management.get_autocast_device(device), dtype=dtype) if autocast_condition else nullcontext(): text_emb = self.model.get_learned_conditioning([prompt]) + image = image * 2 - 1 + image = image.permute(0, 3, 1, 2).to(dtype).to(device) z = get_latent_z(self.model, image.unsqueeze(2)) #bc,1,hw - image + + if image2 is not None: + image2 = image2 * 2 - 1 + image2 = image2.permute(0, 3, 1, 2).to(dtype).to(device) + z2 = get_latent_z(self.model, image2.unsqueeze(2)) #bc,1,hw + img_tensor_repeat = repeat(z, 'b c t h w -> b c (repeat t) h w', repeat=frames) + img_tensor_repeat = torch.zeros_like(img_tensor_repeat) + + img_tensor_repeat[:,:,:1,:,:] = z + if image2 is not None: + img_tensor_repeat[:,:,-1:,:,:] = z2 + else: + img_tensor_repeat[:,:,-1:,:,:] = z + cond_images = self.model.embedder(image) img_emb = self.model.image_proj_model(cond_images) imtext_cond = torch.cat([text_emb, img_emb], dim=1) @@ -103,6 +120,9 @@ class DynamiCrafterI2V: cond = {"c_crossattn": [imtext_cond], "fs": fs, "c_concat": [img_tensor_repeat]} ## inference batch_samples = batch_ddim_sampling(self.model, cond, noise_shape, n_samples=1, ddim_steps=steps, ddim_eta=eta, cfg_scale=cfg) + ## remove the last frame + if image2 is None: + batch_samples = batch_samples[:,:,:,:-1,...] ## b,samples,c,t,h,w prompt_str = prompt.replace("/", "_slash_") if "/" in prompt else prompt prompt_str = prompt_str.replace(" ", "_") if " " in prompt else prompt_str