Spaces:
Running on Zero
Running on Zero
| import torch | |
| import torch.nn as nn | |
| import torch.nn.functional as F | |
| import math | |
| from typing import Literal, Tuple, Optional | |
| from einops import rearrange | |
| from .utils import hash_state_dict_keys | |
| from .wan_video_camera_controller import SimpleAdapter | |
| from .wan_video_dit import DiTBlock | |
| def modulate(x: torch.Tensor, shift: torch.Tensor, scale: torch.Tensor): | |
| # x is fp32 after layer norm | |
| # print(f"{shift.dtype = }") | |
| return (x * (1 + scale) + shift).to(shift.dtype) | |
| def sinusoidal_embedding_1d(dim, position): | |
| sinusoid = torch.outer(position.type(torch.float64), torch.pow( | |
| 10000, -torch.arange(dim//2, dtype=torch.float64, device=position.device).div(dim//2))) | |
| x = torch.cat([torch.cos(sinusoid), torch.sin(sinusoid)], dim=1) | |
| return x.to(position.dtype) | |
| def precompute_freqs_cis_3d(dim: int, end: int = 1024, theta: float = 10000.0): | |
| # 3d rope precompute | |
| f_freqs_cis = precompute_freqs_cis(dim - 2 * (dim // 3), end, theta) | |
| h_freqs_cis = precompute_freqs_cis(dim // 3, end, theta) | |
| w_freqs_cis = precompute_freqs_cis(dim // 3, end, theta) | |
| return f_freqs_cis, h_freqs_cis, w_freqs_cis | |
| def legacy_precompute_freqs_cis_1d(dim: int, end: int = 16384, theta: float = 10000.0, base_tps=4.0, target_tps=44100/2048): | |
| s = float(base_tps) / float(target_tps) | |
| # 1d rope precompute | |
| f_freqs_cis = precompute_freqs_cis(dim - 2 * (dim // 3), end, theta, s) | |
| # No positional encoding applied to the remaining dimensions. | |
| no_freqs_cis = precompute_freqs_cis(dim // 3, end, theta, s) | |
| no_freqs_cis = torch.ones_like(no_freqs_cis) | |
| return f_freqs_cis, no_freqs_cis, no_freqs_cis | |
| def precompute_freqs_cis_1d(dim: int, end: int = 16384, theta: float = 10000.0): | |
| f_freqs_cis = precompute_freqs_cis(dim, end, theta) | |
| return f_freqs_cis.chunk(3, dim=-1) | |
| def precompute_freqs_cis(dim: int, end: int = 16384, theta: float = 10000.0, s: float = 1.0): | |
| # 1d rope precompute | |
| freqs = 1.0 / (theta ** (torch.arange(0, dim, 2) | |
| [: (dim // 2)].double() / dim)) | |
| pos = torch.arange(end, dtype=torch.float64, device=freqs.device) * s | |
| freqs = torch.outer(pos, freqs) | |
| freqs_cis = torch.polar(torch.ones_like(freqs), freqs) # complex64 | |
| return freqs_cis | |
| class MLP(torch.nn.Module): | |
| def __init__(self, in_dim, out_dim, has_pos_emb=False): | |
| super().__init__() | |
| self.proj = torch.nn.Sequential( | |
| nn.LayerNorm(in_dim), | |
| nn.Linear(in_dim, in_dim), | |
| nn.GELU(), | |
| nn.Linear(in_dim, out_dim), | |
| nn.LayerNorm(out_dim) | |
| ) | |
| self.has_pos_emb = has_pos_emb | |
| if has_pos_emb: | |
| self.emb_pos = torch.nn.Parameter(torch.zeros((1, 514, 1280))) | |
| def forward(self, x): | |
| if self.has_pos_emb: | |
| x = x + self.emb_pos.to(dtype=x.dtype, device=x.device) | |
| return self.proj(x) | |
| class Head(nn.Module): | |
| def __init__(self, dim: int, out_dim: int, patch_size: Tuple[int, int, int], eps: float): | |
| super().__init__() | |
| self.dim = dim | |
| self.patch_size = patch_size | |
| self.norm = nn.LayerNorm(dim, eps=eps, elementwise_affine=False) | |
| self.head = nn.Linear(dim, out_dim * math.prod(patch_size)) | |
| self.modulation = nn.Parameter(torch.randn(1, 2, dim) / dim**0.5) | |
| def forward(self, x, t_mod): | |
| # print(f"{t_mod.shape = }") | |
| if len(t_mod.shape) == 3: | |
| shift, scale = (self.modulation.unsqueeze(0).to(dtype=t_mod.dtype, device=t_mod.device) + t_mod.unsqueeze(2)).chunk(2, dim=2) | |
| x = (self.head(self.norm(x) * (1 + scale.squeeze(2)) + shift.squeeze(2))) | |
| else: | |
| # t_mod is originally [B, C]; broadcasting works for B=1 but not for | |
| # B>1 against [1, 2, C], so reshape explicitly here. | |
| shift, scale = (self.modulation.to(dtype=t_mod.dtype, device=t_mod.device) + t_mod.unsqueeze(1)).chunk(2, dim=1) | |
| x = (self.head(self.norm(x) * (1 + scale) + shift)) | |
| return x | |
| from diffusers.configuration_utils import ConfigMixin, register_to_config | |
| from diffusers.models.modeling_utils import ModelMixin | |
| class WanAudioModel(ModelMixin, ConfigMixin): | |
| def __init__( | |
| self, | |
| dim: int, | |
| in_dim: int, | |
| ffn_dim: int, | |
| out_dim: int, | |
| text_dim: int, | |
| freq_dim: int, | |
| eps: float, | |
| patch_size: Tuple[int, int, int], | |
| num_heads: int, | |
| num_layers: int, | |
| has_image_input: bool, | |
| has_image_pos_emb: bool = False, | |
| has_ref_conv: bool = False, | |
| add_control_adapter: bool = False, | |
| in_dim_control_adapter: int = 24, | |
| seperated_timestep: bool = False, | |
| require_vae_embedding: bool = True, | |
| require_clip_embedding: bool = True, | |
| fuse_vae_embedding_in_latents: bool = False, | |
| vae_type: Literal["oobleck", "dac"] = "oobleck", | |
| ): | |
| super().__init__() | |
| self.dim = dim | |
| self.freq_dim = freq_dim | |
| self.has_image_input = has_image_input | |
| self.patch_size = patch_size | |
| self.seperated_timestep = seperated_timestep | |
| self.require_vae_embedding = require_vae_embedding | |
| self.require_clip_embedding = require_clip_embedding | |
| self.fuse_vae_embedding_in_latents = fuse_vae_embedding_in_latents | |
| self.vae_type = vae_type | |
| # self.patch_embedding = nn.Conv3d( | |
| # in_dim, dim, kernel_size=patch_size, stride=patch_size) | |
| self.patch_embedding = nn.Conv1d( | |
| in_dim, dim, kernel_size=patch_size, stride=patch_size | |
| ) | |
| self.text_embedding = nn.Sequential( | |
| nn.Linear(text_dim, dim), | |
| nn.GELU(approximate='tanh'), | |
| nn.Linear(dim, dim) | |
| ) | |
| self.time_embedding = nn.Sequential( | |
| nn.Linear(freq_dim, dim), | |
| nn.SiLU(), | |
| nn.Linear(dim, dim) | |
| ) | |
| self.time_projection = nn.Sequential( | |
| nn.SiLU(), nn.Linear(dim, dim * 6)) | |
| self.blocks = nn.ModuleList([ | |
| DiTBlock(has_image_input, dim, num_heads, ffn_dim, eps) | |
| for _ in range(num_layers) | |
| ]) | |
| self.head = Head(dim, out_dim, patch_size, eps) | |
| head_dim = dim // num_heads | |
| if vae_type == "oobleck": | |
| freqs = legacy_precompute_freqs_cis_1d(head_dim, base_tps=4.0, target_tps=44100/2048) | |
| elif vae_type == "dac": | |
| freqs = precompute_freqs_cis_1d(head_dim) | |
| else: | |
| raise ValueError(f"Invalid VAE type: {vae_type}") | |
| # Register RoPE freqs as buffers so model.to(device) / accelerate move | |
| # them with the model, and so forward / torch.compile graphs do not | |
| # mutate Python attributes mid-trace. | |
| self.register_buffer("freqs_cis_0", freqs[0], persistent=False) | |
| self.register_buffer("freqs_cis_1", freqs[1], persistent=False) | |
| self.register_buffer("freqs_cis_2", freqs[2], persistent=False) | |
| if has_image_input: | |
| self.img_emb = MLP(1280, dim, has_pos_emb=has_image_pos_emb) # clip_feature_dim = 1280 | |
| if has_ref_conv: | |
| self.ref_conv = nn.Conv2d(16, dim, kernel_size=(2, 2), stride=(2, 2)) | |
| self.has_image_pos_emb = has_image_pos_emb | |
| self.has_ref_conv = has_ref_conv | |
| if add_control_adapter: | |
| self.control_adapter = SimpleAdapter(in_dim_control_adapter, dim, kernel_size=patch_size[1:], stride=patch_size[1:]) | |
| else: | |
| self.control_adapter = None | |
| def freqs(self): | |
| # Backwards-compatible accessor: external code can still use self.freqs[i]. | |
| return (self.freqs_cis_0, self.freqs_cis_1, self.freqs_cis_2) | |
| def patchify(self, x: torch.Tensor, control_camera_latents_input: Optional[torch.Tensor] = None): | |
| x = self.patch_embedding(x) | |
| if self.control_adapter is not None and control_camera_latents_input is not None: | |
| y_camera = self.control_adapter(control_camera_latents_input) | |
| x = [u + v for u, v in zip(x, y_camera)] | |
| x = x[0].unsqueeze(0) | |
| grid_size = x.shape[2:] | |
| x = rearrange(x, 'b c f -> b f c').contiguous() | |
| return x, grid_size # x, grid_size: (f) | |
| def unpatchify(self, x: torch.Tensor, grid_size: torch.Tensor): | |
| return rearrange( | |
| x, 'b f (p c) -> b c (f p)', | |
| f=grid_size[0], | |
| p=self.patch_size[0] | |
| ) | |
| def forward(self, | |
| x: torch.Tensor, | |
| timestep: torch.Tensor, | |
| context: torch.Tensor, | |
| clip_feature: Optional[torch.Tensor] = None, | |
| y: Optional[torch.Tensor] = None, | |
| use_gradient_checkpointing: bool = False, | |
| use_gradient_checkpointing_offload: bool = False, | |
| **kwargs, | |
| ): | |
| t = self.time_embedding( | |
| sinusoidal_embedding_1d(self.freq_dim, timestep)) | |
| t_mod = self.time_projection(t).unflatten(1, (6, self.dim)) | |
| context = self.text_embedding(context) | |
| if self.has_image_input: | |
| x = torch.cat([x, y], dim=1) # (b, c_x + c_y, f, h, w) | |
| clip_embdding = self.img_emb(clip_feature) | |
| context = torch.cat([clip_embdding, context], dim=1) | |
| x, (f, ) = self.patchify(x) | |
| freqs = torch.cat([ | |
| self.freqs[0][:f].view(f, -1).expand(f, -1), | |
| self.freqs[1][:f].view(f, -1).expand(f, -1), | |
| self.freqs[2][:f].view(f, -1).expand(f, -1), | |
| ], dim=-1).reshape(f, 1, -1) | |
| def create_custom_forward(module): | |
| def custom_forward(*inputs): | |
| return module(*inputs) | |
| return custom_forward | |
| for block in self.blocks: | |
| if self.training and use_gradient_checkpointing: | |
| if use_gradient_checkpointing_offload: | |
| with torch.autograd.graph.save_on_cpu(): | |
| x = torch.utils.checkpoint.checkpoint( | |
| create_custom_forward(block), | |
| x, context, t_mod, freqs, | |
| use_reentrant=False, | |
| ) | |
| else: | |
| x = torch.utils.checkpoint.checkpoint( | |
| create_custom_forward(block), | |
| x, context, t_mod, freqs, | |
| use_reentrant=False, | |
| ) | |
| else: | |
| x = block(x, context, t_mod, freqs) | |
| x = self.head(x, t) | |
| x = self.unpatchify(x, (f, )) | |
| return x | |
| def state_dict_converter(): | |
| return WanModelStateDictConverter() | |
| class WanModelStateDictConverter: | |
| def __init__(self): | |
| pass | |
| def from_diffusers(self, state_dict): | |
| rename_dict = { | |
| "blocks.0.attn1.norm_k.weight": "blocks.0.self_attn.norm_k.weight", | |
| "blocks.0.attn1.norm_q.weight": "blocks.0.self_attn.norm_q.weight", | |
| "blocks.0.attn1.to_k.bias": "blocks.0.self_attn.k.bias", | |
| "blocks.0.attn1.to_k.weight": "blocks.0.self_attn.k.weight", | |
| "blocks.0.attn1.to_out.0.bias": "blocks.0.self_attn.o.bias", | |
| "blocks.0.attn1.to_out.0.weight": "blocks.0.self_attn.o.weight", | |
| "blocks.0.attn1.to_q.bias": "blocks.0.self_attn.q.bias", | |
| "blocks.0.attn1.to_q.weight": "blocks.0.self_attn.q.weight", | |
| "blocks.0.attn1.to_v.bias": "blocks.0.self_attn.v.bias", | |
| "blocks.0.attn1.to_v.weight": "blocks.0.self_attn.v.weight", | |
| "blocks.0.attn2.norm_k.weight": "blocks.0.cross_attn.norm_k.weight", | |
| "blocks.0.attn2.norm_q.weight": "blocks.0.cross_attn.norm_q.weight", | |
| "blocks.0.attn2.to_k.bias": "blocks.0.cross_attn.k.bias", | |
| "blocks.0.attn2.to_k.weight": "blocks.0.cross_attn.k.weight", | |
| "blocks.0.attn2.to_out.0.bias": "blocks.0.cross_attn.o.bias", | |
| "blocks.0.attn2.to_out.0.weight": "blocks.0.cross_attn.o.weight", | |
| "blocks.0.attn2.to_q.bias": "blocks.0.cross_attn.q.bias", | |
| "blocks.0.attn2.to_q.weight": "blocks.0.cross_attn.q.weight", | |
| "blocks.0.attn2.to_v.bias": "blocks.0.cross_attn.v.bias", | |
| "blocks.0.attn2.to_v.weight": "blocks.0.cross_attn.v.weight", | |
| "blocks.0.ffn.net.0.proj.bias": "blocks.0.ffn.0.bias", | |
| "blocks.0.ffn.net.0.proj.weight": "blocks.0.ffn.0.weight", | |
| "blocks.0.ffn.net.2.bias": "blocks.0.ffn.2.bias", | |
| "blocks.0.ffn.net.2.weight": "blocks.0.ffn.2.weight", | |
| "blocks.0.norm2.bias": "blocks.0.norm3.bias", | |
| "blocks.0.norm2.weight": "blocks.0.norm3.weight", | |
| "blocks.0.scale_shift_table": "blocks.0.modulation", | |
| "condition_embedder.text_embedder.linear_1.bias": "text_embedding.0.bias", | |
| "condition_embedder.text_embedder.linear_1.weight": "text_embedding.0.weight", | |
| "condition_embedder.text_embedder.linear_2.bias": "text_embedding.2.bias", | |
| "condition_embedder.text_embedder.linear_2.weight": "text_embedding.2.weight", | |
| "condition_embedder.time_embedder.linear_1.bias": "time_embedding.0.bias", | |
| "condition_embedder.time_embedder.linear_1.weight": "time_embedding.0.weight", | |
| "condition_embedder.time_embedder.linear_2.bias": "time_embedding.2.bias", | |
| "condition_embedder.time_embedder.linear_2.weight": "time_embedding.2.weight", | |
| "condition_embedder.time_proj.bias": "time_projection.1.bias", | |
| "condition_embedder.time_proj.weight": "time_projection.1.weight", | |
| "patch_embedding.bias": "patch_embedding.bias", | |
| "patch_embedding.weight": "patch_embedding.weight", | |
| "scale_shift_table": "head.modulation", | |
| "proj_out.bias": "head.head.bias", | |
| "proj_out.weight": "head.head.weight", | |
| } | |
| state_dict_ = {} | |
| for name, param in state_dict.items(): | |
| if name in rename_dict: | |
| state_dict_[rename_dict[name]] = param | |
| else: | |
| name_ = ".".join(name.split(".")[:1] + ["0"] + name.split(".")[2:]) | |
| if name_ in rename_dict: | |
| name_ = rename_dict[name_] | |
| name_ = ".".join(name_.split(".")[:1] + [name.split(".")[1]] + name_.split(".")[2:]) | |
| state_dict_[name_] = param | |
| if hash_state_dict_keys(state_dict) == "cb104773c6c2cb6df4f9529ad5c60d0b": | |
| config = { | |
| "model_type": "t2v", | |
| "patch_size": (1, 2, 2), | |
| "text_len": 512, | |
| "in_dim": 16, | |
| "dim": 5120, | |
| "ffn_dim": 13824, | |
| "freq_dim": 256, | |
| "text_dim": 4096, | |
| "out_dim": 16, | |
| "num_heads": 40, | |
| "num_layers": 40, | |
| "window_size": (-1, -1), | |
| "qk_norm": True, | |
| "cross_attn_norm": True, | |
| "eps": 1e-6, | |
| } | |
| else: | |
| config = {} | |
| return state_dict_, config | |
| def from_civitai(self, state_dict): | |
| state_dict = {name: param for name, param in state_dict.items() if not name.startswith("vace")} | |
| if hash_state_dict_keys(state_dict) == "9269f8db9040a9d860eaca435be61814": | |
| config = { | |
| "has_image_input": False, | |
| "patch_size": [1, 2, 2], | |
| "in_dim": 16, | |
| "dim": 1536, | |
| "ffn_dim": 8960, | |
| "freq_dim": 256, | |
| "text_dim": 4096, | |
| "out_dim": 16, | |
| "num_heads": 12, | |
| "num_layers": 30, | |
| "eps": 1e-6 | |
| } | |
| elif hash_state_dict_keys(state_dict) == "aafcfd9672c3a2456dc46e1cb6e52c70": | |
| config = { | |
| "has_image_input": False, | |
| "patch_size": [1, 2, 2], | |
| "in_dim": 16, | |
| "dim": 5120, | |
| "ffn_dim": 13824, | |
| "freq_dim": 256, | |
| "text_dim": 4096, | |
| "out_dim": 16, | |
| "num_heads": 40, | |
| "num_layers": 40, | |
| "eps": 1e-6 | |
| } | |
| elif hash_state_dict_keys(state_dict) == "6bfcfb3b342cb286ce886889d519a77e": | |
| config = { | |
| "has_image_input": True, | |
| "patch_size": [1, 2, 2], | |
| "in_dim": 36, | |
| "dim": 5120, | |
| "ffn_dim": 13824, | |
| "freq_dim": 256, | |
| "text_dim": 4096, | |
| "out_dim": 16, | |
| "num_heads": 40, | |
| "num_layers": 40, | |
| "eps": 1e-6 | |
| } | |
| elif hash_state_dict_keys(state_dict) == "6d6ccde6845b95ad9114ab993d917893": | |
| config = { | |
| "has_image_input": True, | |
| "patch_size": [1, 2, 2], | |
| "in_dim": 36, | |
| "dim": 1536, | |
| "ffn_dim": 8960, | |
| "freq_dim": 256, | |
| "text_dim": 4096, | |
| "out_dim": 16, | |
| "num_heads": 12, | |
| "num_layers": 30, | |
| "eps": 1e-6 | |
| } | |
| elif hash_state_dict_keys(state_dict) == "6bfcfb3b342cb286ce886889d519a77e": | |
| config = { | |
| "has_image_input": True, | |
| "patch_size": [1, 2, 2], | |
| "in_dim": 36, | |
| "dim": 5120, | |
| "ffn_dim": 13824, | |
| "freq_dim": 256, | |
| "text_dim": 4096, | |
| "out_dim": 16, | |
| "num_heads": 40, | |
| "num_layers": 40, | |
| "eps": 1e-6 | |
| } | |
| elif hash_state_dict_keys(state_dict) == "349723183fc063b2bfc10bb2835cf677": | |
| # 1.3B PAI control | |
| config = { | |
| "has_image_input": True, | |
| "patch_size": [1, 2, 2], | |
| "in_dim": 48, | |
| "dim": 1536, | |
| "ffn_dim": 8960, | |
| "freq_dim": 256, | |
| "text_dim": 4096, | |
| "out_dim": 16, | |
| "num_heads": 12, | |
| "num_layers": 30, | |
| "eps": 1e-6 | |
| } | |
| elif hash_state_dict_keys(state_dict) == "efa44cddf936c70abd0ea28b6cbe946c": | |
| # 14B PAI control | |
| config = { | |
| "has_image_input": True, | |
| "patch_size": [1, 2, 2], | |
| "in_dim": 48, | |
| "dim": 5120, | |
| "ffn_dim": 13824, | |
| "freq_dim": 256, | |
| "text_dim": 4096, | |
| "out_dim": 16, | |
| "num_heads": 40, | |
| "num_layers": 40, | |
| "eps": 1e-6 | |
| } | |
| elif hash_state_dict_keys(state_dict) == "3ef3b1f8e1dab83d5b71fd7b617f859f": | |
| config = { | |
| "has_image_input": True, | |
| "patch_size": [1, 2, 2], | |
| "in_dim": 36, | |
| "dim": 5120, | |
| "ffn_dim": 13824, | |
| "freq_dim": 256, | |
| "text_dim": 4096, | |
| "out_dim": 16, | |
| "num_heads": 40, | |
| "num_layers": 40, | |
| "eps": 1e-6, | |
| "has_image_pos_emb": True | |
| } | |
| elif hash_state_dict_keys(state_dict) == "70ddad9d3a133785da5ea371aae09504": | |
| # 1.3B PAI control v1.1 | |
| config = { | |
| "has_image_input": True, | |
| "patch_size": [1, 2, 2], | |
| "in_dim": 48, | |
| "dim": 1536, | |
| "ffn_dim": 8960, | |
| "freq_dim": 256, | |
| "text_dim": 4096, | |
| "out_dim": 16, | |
| "num_heads": 12, | |
| "num_layers": 30, | |
| "eps": 1e-6, | |
| "has_ref_conv": True | |
| } | |
| elif hash_state_dict_keys(state_dict) == "26bde73488a92e64cc20b0a7485b9e5b": | |
| # 14B PAI control v1.1 | |
| config = { | |
| "has_image_input": True, | |
| "patch_size": [1, 2, 2], | |
| "in_dim": 48, | |
| "dim": 5120, | |
| "ffn_dim": 13824, | |
| "freq_dim": 256, | |
| "text_dim": 4096, | |
| "out_dim": 16, | |
| "num_heads": 40, | |
| "num_layers": 40, | |
| "eps": 1e-6, | |
| "has_ref_conv": True | |
| } | |
| elif hash_state_dict_keys(state_dict) == "ac6a5aa74f4a0aab6f64eb9a72f19901": | |
| # 1.3B PAI control-camera v1.1 | |
| config = { | |
| "has_image_input": True, | |
| "patch_size": [1, 2, 2], | |
| "in_dim": 32, | |
| "dim": 1536, | |
| "ffn_dim": 8960, | |
| "freq_dim": 256, | |
| "text_dim": 4096, | |
| "out_dim": 16, | |
| "num_heads": 12, | |
| "num_layers": 30, | |
| "eps": 1e-6, | |
| "has_ref_conv": False, | |
| "add_control_adapter": True, | |
| "in_dim_control_adapter": 24, | |
| } | |
| elif hash_state_dict_keys(state_dict) == "b61c605c2adbd23124d152ed28e049ae": | |
| # 14B PAI control-camera v1.1 | |
| config = { | |
| "has_image_input": True, | |
| "patch_size": [1, 2, 2], | |
| "in_dim": 32, | |
| "dim": 5120, | |
| "ffn_dim": 13824, | |
| "freq_dim": 256, | |
| "text_dim": 4096, | |
| "out_dim": 16, | |
| "num_heads": 40, | |
| "num_layers": 40, | |
| "eps": 1e-6, | |
| "has_ref_conv": False, | |
| "add_control_adapter": True, | |
| "in_dim_control_adapter": 24, | |
| } | |
| elif hash_state_dict_keys(state_dict) == "1f5ab7703c6fc803fdded85ff040c316": | |
| # Wan-AI/Wan2.2-TI2V-5B | |
| config = { | |
| "has_image_input": False, | |
| "patch_size": [1, 2, 2], | |
| "in_dim": 48, | |
| "dim": 3072, | |
| "ffn_dim": 14336, | |
| "freq_dim": 256, | |
| "text_dim": 4096, | |
| "out_dim": 48, | |
| "num_heads": 24, | |
| "num_layers": 30, | |
| "eps": 1e-6, | |
| "seperated_timestep": True, | |
| "require_clip_embedding": False, | |
| "require_vae_embedding": False, | |
| "fuse_vae_embedding_in_latents": True, | |
| } | |
| elif hash_state_dict_keys(state_dict) == "5b013604280dd715f8457c6ed6d6a626": | |
| # Wan-AI/Wan2.2-I2V-A14B | |
| config = { | |
| "has_image_input": False, | |
| "patch_size": [1, 2, 2], | |
| "in_dim": 36, | |
| "dim": 5120, | |
| "ffn_dim": 13824, | |
| "freq_dim": 256, | |
| "text_dim": 4096, | |
| "out_dim": 16, | |
| "num_heads": 40, | |
| "num_layers": 40, | |
| "eps": 1e-6, | |
| "require_clip_embedding": False, | |
| } | |
| else: | |
| config = {} | |
| return state_dict, config | |