CoolFace
Apppublic

durgappc/infinitetalk2

sourceHugging Faceapache-2.0updated 8mo agoView on Hugging Face
0likes
xdit_context_parallel.py550 linesDownload Raw Back to distributed
1# Copyright 2024-2025 The Alibaba Wan Team Authors. All rights reserved.2import numpy as np3import torch4import torch.nn as nn5import torch.cuda.amp as amp6from xfuser.core.distributed import (7    get_sequence_parallel_rank,8    get_sequence_parallel_world_size,9    get_sp_group,10)11from einops import rearrange12from xfuser.core.long_ctx_attention import xFuserLongContextAttention13import xformers.ops14 15from ..modules.model import sinusoidal_embedding_1d16from ..utils.multitalk_utils import get_attn_map_with_target, split_token_counts_and_frame_ids, normalize_and_scale17from ..modules.attention import SingleStreamAttention, SingleStreamMutiAttention18 19 20def pad_freqs(original_tensor, target_len):21    seq_len, s1, s2 = original_tensor.shape22    pad_size = target_len - seq_len23    padding_tensor = torch.ones(24        pad_size,25        s1,26        s2,27        dtype=original_tensor.dtype,28        device=original_tensor.device)29    padded_tensor = torch.cat([original_tensor, padding_tensor], dim=0)30    return padded_tensor31 32 33@amp.autocast(enabled=False)34def rope_apply(x, grid_sizes, freqs):35    """36    x:          [B, L, N, C].37    grid_sizes: [B, 3].38    freqs:      [M, C // 2].39    """40    s, n, c = x.size(1), x.size(2), x.size(3) // 241    # split freqs42    freqs = freqs.split([c - 2 * (c // 3), c // 3, c // 3], dim=1) # [[N, head_dim/2], [N, head_dim/2], [N, head_dim/2]] # T H W 极坐标43 44    # loop over samples45    output = []46    for i, (f, h, w) in enumerate(grid_sizes.tolist()):47        seq_len = f * h * w48 49        # precompute multipliers50        x_i = torch.view_as_complex(x[i, :s].to(torch.float64).reshape(51            s, n, -1, 2)) # [L, N, C/2] # 极坐标52        freqs_i = torch.cat([53            freqs[0][:f].view(f, 1, 1, -1).expand(f, h, w, -1),54            freqs[1][:h].view(1, h, 1, -1).expand(f, h, w, -1),55            freqs[2][:w].view(1, 1, w, -1).expand(f, h, w, -1)56        ],57                            dim=-1).reshape(seq_len, 1, -1) # seq_lens, 1,  3 * dim / 2 (T H W)58 59        # apply rotary embedding60        sp_size = get_sequence_parallel_world_size()61        sp_rank = get_sequence_parallel_rank()62        freqs_i = pad_freqs(freqs_i, s * sp_size)63        s_per_rank = s64        freqs_i_rank = freqs_i[(sp_rank * s_per_rank):((sp_rank + 1) *65                                                       s_per_rank), :, :]66        x_i = torch.view_as_real(x_i * freqs_i_rank).flatten(2)67        x_i = torch.cat([x_i, x[i, s:]])68 69        # append to collection70        output.append(x_i)71    return torch.stack(output).float()72 73 74def usp_dit_forward_vace(self, x, vace_context, seq_len, kwargs):75    # embeddings76    c = [self.vace_patch_embedding(u.unsqueeze(0)) for u in vace_context]77    c = [u.flatten(2).transpose(1, 2) for u in c]78    c = torch.cat([79        torch.cat([u, u.new_zeros(1, seq_len - u.size(1), u.size(2))], dim=1)80        for u in c81    ])82 83    # arguments84    new_kwargs = dict(x=x)85    new_kwargs.update(kwargs)86 87    # Context Parallel88    c = torch.chunk(89        c, get_sequence_parallel_world_size(),90        dim=1)[get_sequence_parallel_rank()]91 92    hints = []93    for block in self.vace_blocks:94        c, c_skip = block(c, **new_kwargs)95        hints.append(c_skip)96    return hints97 98 99def usp_dit_forward(100    self,101    x,102    t,103    context,104    seq_len,105    vace_context=None,106    vace_context_scale=1.0,107    clip_fea=None,108    y=None,109):110    """111    x:              A list of videos each with shape [C, T, H, W].112    t:              [B].113    context:        A list of text embeddings each with shape [L, C].114    """115    if self.model_type == 'i2v':116        assert clip_fea is not None and y is not None117    # params118    device = self.patch_embedding.weight.device119    if self.freqs.device != device:120        self.freqs = self.freqs.to(device)121 122    if self.model_type != 'vace' and y is not None:123        x = [torch.cat([u, v], dim=0) for u, v in zip(x, y)]124 125    # embeddings126    x = [self.patch_embedding(u.unsqueeze(0)) for u in x]127    grid_sizes = torch.stack(128        [torch.tensor(u.shape[2:], dtype=torch.long) for u in x])129    x = [u.flatten(2).transpose(1, 2) for u in x]130    seq_lens = torch.tensor([u.size(1) for u in x], dtype=torch.long)131    assert seq_lens.max() <= seq_len132    x = torch.cat([133        torch.cat([u, u.new_zeros(1, seq_len - u.size(1), u.size(2))], dim=1)134        for u in x135    ])136 137    # time embeddings138    with amp.autocast(dtype=torch.float32):139        e = self.time_embedding(140            sinusoidal_embedding_1d(self.freq_dim, t).float())141        e0 = self.time_projection(e).unflatten(1, (6, self.dim))142        assert e.dtype == torch.float32 and e0.dtype == torch.float32143 144    # context145    context_lens = None146    context = self.text_embedding(147        torch.stack([148            torch.cat([u, u.new_zeros(self.text_len - u.size(0), u.size(1))])149            for u in context150        ]))151 152    if self.model_type != 'vace' and clip_fea is not None:153        context_clip = self.img_emb(clip_fea)  # bs x 257 x dim154        context = torch.concat([context_clip, context], dim=1)155 156    # arguments157    kwargs = dict(158        e=e0,159        seq_lens=seq_lens,160        grid_sizes=grid_sizes,161        freqs=self.freqs,162        context=context,163        context_lens=context_lens)164    165    # Context Parallel166    x = torch.chunk(167        x, get_sequence_parallel_world_size(),168        dim=1)[get_sequence_parallel_rank()]169 170    for block in self.blocks:171        x = block(x, **kwargs)172 173    # head174    x = self.head(x, e)175 176    # Context Parallel177    x = get_sp_group().all_gather(x, dim=1)178 179    # unpatchify180    x = self.unpatchify(x, grid_sizes)181    return [u.float() for u in x]182 183 184def usp_attn_forward(self,185                     x,186                     seq_lens,187                     grid_sizes,188                     freqs,189                     dtype=torch.bfloat16):190    b, s, n, d = *x.shape[:2], self.num_heads, self.head_dim191    half_dtypes = (torch.float16, torch.bfloat16)192 193    def half(x):194        return x if x.dtype in half_dtypes else x.to(dtype)195 196    # query, key, value function197    def qkv_fn(x):198        q = self.norm_q(self.q(x)).view(b, s, n, d)199        k = self.norm_k(self.k(x)).view(b, s, n, d)200        v = self.v(x).view(b, s, n, d)201        return q, k, v202 203    q, k, v = qkv_fn(x)204    q = rope_apply(q, grid_sizes, freqs)205    k = rope_apply(k, grid_sizes, freqs)206 207    # TODO: We should use unpaded q,k,v for attention.208    # k_lens = seq_lens // get_sequence_parallel_world_size()209    # if k_lens is not None:210    #     q = torch.cat([u[:l] for u, l in zip(q, k_lens)]).unsqueeze(0)211    #     k = torch.cat([u[:l] for u, l in zip(k, k_lens)]).unsqueeze(0)212    #     v = torch.cat([u[:l] for u, l in zip(v, k_lens)]).unsqueeze(0)213 214    x = xFuserLongContextAttention()(215        None,216        query=half(q),217        key=half(k),218        value=half(v),219        window_size=self.window_size)220 221    # TODO: padding after attention.222    # x = torch.cat([x, x.new_zeros(b, s - x.size(1), n, d)], dim=1)223 224    # output225    x = x.flatten(2)226    x = self.o(x)227    return x228 229 230 231 232def usp_dit_forward_multitalk(233    self,234    x,235    t,236    context,237    seq_len,238    clip_fea=None,239    y=None,240    audio=None,241    ref_target_masks=None,242):243    """244    x:              A list of videos each with shape [C, T, H, W].245    t:              [B].246    context:        A list of text embeddings each with shape [L, C].247    """248    249    assert clip_fea is not None and y is not None250    # params251    device = self.patch_embedding.weight.device252    if self.freqs.device != device:253        self.freqs = self.freqs.to(device)254 255    _, T, H, W = x[0].shape256    N_t = T // self.patch_size[0]257    N_h = H // self.patch_size[1]258    N_w = W // self.patch_size[2]259 260    if y is not None:261        x = [torch.cat([u, v], dim=0) for u, v in zip(x, y)]262    x[0] = x[0].to(context[0].dtype)263 264    # embeddings265    x = [self.patch_embedding(u.unsqueeze(0)) for u in x]266    grid_sizes = torch.stack(267        [torch.tensor(u.shape[2:], dtype=torch.long) for u in x])268    x = [u.flatten(2).transpose(1, 2) for u in x]269    seq_lens = torch.tensor([u.size(1) for u in x], dtype=torch.long)270    assert seq_lens.max() <= seq_len271    x = torch.cat([272        torch.cat([u, u.new_zeros(1, seq_len - u.size(1), u.size(2))], dim=1)273        for u in x274    ])275 276    # time embeddings277    with amp.autocast(dtype=torch.float32):278        e = self.time_embedding(279            sinusoidal_embedding_1d(self.freq_dim, t).float())280        e0 = self.time_projection(e).unflatten(1, (6, self.dim))281        assert e.dtype == torch.float32 and e0.dtype == torch.float32282 283    # context284    context_lens = None285    context = self.text_embedding(286        torch.stack([287            torch.cat([u, u.new_zeros(self.text_len - u.size(0), u.size(1))])288            for u in context289        ]))290 291    if clip_fea is not None:292        context_clip = self.img_emb(clip_fea)  293        context = torch.concat([context_clip, context], dim=1)294 295    # get audio token296    audio_cond = audio.to(device=x.device, dtype=x.dtype)297    first_frame_audio_emb_s = audio_cond[:, :1, ...] 298    latter_frame_audio_emb = audio_cond[:, 1:, ...] 299    latter_frame_audio_emb = rearrange(latter_frame_audio_emb, "b (n_t n) w s c -> b n_t n w s c", n=self.vae_scale) 300    middle_index = self.audio_window // 2301    latter_first_frame_audio_emb = latter_frame_audio_emb[:, :, :1, :middle_index+1, ...] 302    latter_first_frame_audio_emb = rearrange(latter_first_frame_audio_emb, "b n_t n w s c -> b n_t (n w) s c") 303    latter_last_frame_audio_emb = latter_frame_audio_emb[:, :, -1:, middle_index:, ...] 304    latter_last_frame_audio_emb = rearrange(latter_last_frame_audio_emb, "b n_t n w s c -> b n_t (n w) s c") 305    latter_middle_frame_audio_emb = latter_frame_audio_emb[:, :, 1:-1, middle_index:middle_index+1, ...] 306    latter_middle_frame_audio_emb = rearrange(latter_middle_frame_audio_emb, "b n_t n w s c -> b n_t (n w) s c") 307    latter_frame_audio_emb_s = torch.concat([latter_first_frame_audio_emb, latter_middle_frame_audio_emb, latter_last_frame_audio_emb], dim=2) 308    audio_embedding = self.audio_proj(first_frame_audio_emb_s, latter_frame_audio_emb_s) 309    human_num = len(audio_embedding)310    audio_embedding = torch.concat(audio_embedding.split(1), dim=2).to(x.dtype)311 312 313    # convert ref_target_masks to token_ref_target_masks314    if ref_target_masks is not None:315        ref_target_masks = ref_target_masks.unsqueeze(0).to(torch.float32) 316        token_ref_target_masks = nn.functional.interpolate(ref_target_masks, size=(N_h, N_w), mode='nearest') 317        token_ref_target_masks = token_ref_target_masks.squeeze(0) 318        token_ref_target_masks = (token_ref_target_masks > 0)319        token_ref_target_masks = token_ref_target_masks.view(token_ref_target_masks.shape[0], -1) 320        token_ref_target_masks = token_ref_target_masks.to(x.dtype)321    322    if self.enable_teacache:323        modulated_inp = e0 if self.use_ret_steps else e324        if self.cnt%3==0: # cond325            if self.cnt < self.ret_steps or self.cnt >= self.cutoff_steps:326                should_calc_cond = True327                self.accumulated_rel_l1_distance_cond = 0328            else:329                rescale_func = np.poly1d(self.coefficients)330                self.accumulated_rel_l1_distance_cond += rescale_func(((modulated_inp-self.previous_e0_cond).abs().mean() / self.previous_e0_cond.abs().mean()).cpu().item())331                # print("accumulated_rel_l1_distance_even", self.accumulated_rel_l1_distance_even)332                if self.accumulated_rel_l1_distance_cond < self.teacache_thresh:333                    should_calc_cond = False334                else:335                    should_calc_cond = True336                    self.accumulated_rel_l1_distance_cond = 0337            self.previous_e0_cond = modulated_inp.clone()338        elif self.cnt%3==1: # drop_text339            if self.cnt < self.ret_steps or self.cnt >= self.cutoff_steps:340                should_calc_drop_text = True341                self.accumulated_rel_l1_distance_drop_text = 0342            else:343                rescale_func = np.poly1d(self.coefficients)344                self.accumulated_rel_l1_distance_drop_text += rescale_func(((modulated_inp-self.previous_e0_drop_text).abs().mean() / self.previous_e0_drop_text.abs().mean()).cpu().item())345                if self.accumulated_rel_l1_distance_drop_text < self.teacache_thresh:346                    should_calc_drop_text = False347                else:348                    should_calc_drop_text = True349                    self.accumulated_rel_l1_distance_drop_text = 0350            self.previous_e0_drop_text = modulated_inp.clone()351        else: # uncond352            if self.cnt < self.ret_steps or self.cnt >= self.cutoff_steps:353                should_calc_uncond = True354                self.accumulated_rel_l1_distance_uncond = 0355            else:356                rescale_func = np.poly1d(self.coefficients)357                self.accumulated_rel_l1_distance_uncond += rescale_func(((modulated_inp-self.previous_e0_uncond).abs().mean() / self.previous_e0_uncond.abs().mean()).cpu().item())358                if self.accumulated_rel_l1_distance_uncond < self.teacache_thresh:359                    should_calc_uncond = False360                else:361                    should_calc_uncond = True362                    self.accumulated_rel_l1_distance_uncond = 0363            self.previous_e0_uncond = modulated_inp.clone()364 365    # Context Parallel366    x = torch.chunk(367        x, get_sequence_parallel_world_size(),368        dim=1)[get_sequence_parallel_rank()]369 370    # arguments371    kwargs = dict(372        e=e0,373        seq_lens=seq_lens,374        grid_sizes=grid_sizes,375        freqs=self.freqs,376        context=context,377        context_lens=context_lens,378        audio_embedding=audio_embedding,379        ref_target_masks=token_ref_target_masks,380        human_num=human_num,381        )382 383    if self.enable_teacache:384        if self.cnt%3==0:385            if not should_calc_cond:386                x +=  self.previous_residual_cond387            else:388                ori_x = x.clone()389                for block in self.blocks:390                    x = block(x, **kwargs)391                self.previous_residual_cond = x - ori_x392        elif self.cnt%3==1:393            if not should_calc_drop_text:394                x +=  self.previous_residual_drop_text395            else:396                ori_x = x.clone()397                for block in self.blocks:398                    x = block(x, **kwargs)399                self.previous_residual_drop_text = x - ori_x400        else:401            if not should_calc_uncond:402                x +=  self.previous_residual_uncond403            else:404                ori_x = x.clone()405                for block in self.blocks:406                    x = block(x, **kwargs)407                self.previous_residual_uncond = x - ori_x408    else:409        for block in self.blocks:410            x = block(x, **kwargs)411 412    # head413    x = self.head(x, e)414 415    # Context Parallel416    x = get_sp_group().all_gather(x, dim=1)417 418    # unpatchify419    x = self.unpatchify(x, grid_sizes)420    if self.enable_teacache:421        self.cnt += 1422        if self.cnt >= self.num_steps:423            self.cnt = 0424        425    return torch.stack(x).float()426 427 428def usp_attn_forward_multitalk(self,429                     x,430                     seq_lens,431                     grid_sizes,432                     freqs,433                     dtype=torch.bfloat16,434                     ref_target_masks=None):435    b, s, n, d = *x.shape[:2], self.num_heads, self.head_dim436    half_dtypes = (torch.float16, torch.bfloat16)437 438    def half(x):439        return x if x.dtype in half_dtypes else x.to(dtype)440 441    # query, key, value function442    def qkv_fn(x):443        q = self.norm_q(self.q(x)).view(b, s, n, d)444        k = self.norm_k(self.k(x)).view(b, s, n, d)445        v = self.v(x).view(b, s, n, d)446        return q, k, v447 448    q, k, v = qkv_fn(x)449    q = rope_apply(q, grid_sizes, freqs)450    k = rope_apply(k, grid_sizes, freqs)451 452 453    x = xFuserLongContextAttention()(454        None,455        query=half(q),456        key=half(k),457        value=half(v),458        window_size=self.window_size)459 460 461    # output462    x = x.flatten(2)463    x = self.o(x)464 465    with torch.no_grad():466        x_ref_attn_map = get_attn_map_with_target(q.type_as(x), k.type_as(x), grid_sizes[0], 467                                            ref_target_masks=ref_target_masks, enable_sp=True) 468 469    return x, x_ref_attn_map470 471 472 473 474def usp_crossattn_multi_forward_multitalk(self, 475                                        x: torch.Tensor, 476                                        encoder_hidden_states: torch.Tensor,  # 1, 21, 64, C477                                        shape=None, 478                                        x_ref_attn_map=None,479                                        human_num=None) -> torch.Tensor:480        481        N_t, N_h, N_w = shape 482        sp_size = get_sequence_parallel_world_size()483        sp_rank = get_sequence_parallel_rank()484        audio_tokens_per_frame = 32485        visual_seqlen, frame_ids = split_token_counts_and_frame_ids(N_t, N_h * N_w, sp_size, sp_rank)486        encoder_hidden_states = encoder_hidden_states[:, min(frame_ids):max(frame_ids)+1, ...]487        encoder_hidden_states = rearrange(encoder_hidden_states, "B T N C -> B (T N) C")488        N_a = len(frame_ids)489        kv_seq = [audio_tokens_per_frame * human_num] * N_a490 491        if human_num == 1:492            return super(SingleStreamMutiAttention, self).forward(x, encoder_hidden_states, shape, enable_sp=True, kv_seq=kv_seq)493 494 495        # get q for hidden_state496        B, N, C = x.shape497        q = self.q_linear(x) 498        q_shape = (B, N, self.num_heads, self.head_dim) 499        q = q.view(q_shape).permute((0, 2, 1, 3))500 501        if self.qk_norm:502            q = self.q_norm(q)503 504        max_values = x_ref_attn_map.max(1).values[:, None, None] 505        min_values = x_ref_attn_map.min(1).values[:, None, None] 506        max_min_values = torch.cat([max_values, min_values], dim=2)507        max_min_values = get_sp_group().all_gather(max_min_values, dim=1)508 509        human1_max_value, human1_min_value = max_min_values[0, :, 0].max(), max_min_values[0, :, 1].min()510        human2_max_value, human2_min_value = max_min_values[1, :, 0].max(), max_min_values[1, :, 1].min()511 512        human1 = normalize_and_scale(x_ref_attn_map[0], (human1_min_value, human1_max_value), (self.rope_h1[0], self.rope_h1[1]))513        human2 = normalize_and_scale(x_ref_attn_map[1], (human2_min_value, human2_max_value), (self.rope_h2[0], self.rope_h2[1]))514        back   = torch.full((x_ref_attn_map.size(1),), self.rope_bak, dtype=human1.dtype).to(human1.device)515        max_indices = x_ref_attn_map.argmax(dim=0)516        normalized_map = torch.stack([human1, human2, back], dim=1)517        normalized_pos = normalized_map[range(x_ref_attn_map.size(1)), max_indices] # N 518        q = self.rope_1d(q, normalized_pos)519 520        encoder_kv = self.kv_linear(encoder_hidden_states) 521        encoder_kv_shape = (B, encoder_hidden_states.size(1), 2, self.num_heads, self.head_dim)522        encoder_kv = encoder_kv.view(encoder_kv_shape).permute((2, 0, 3, 1, 4)) 523        encoder_k, encoder_v = encoder_kv.unbind(0) # B H N C524 525        if self.qk_norm:526            encoder_k = self.add_k_norm(encoder_k)527 528        # position embedding for condition audio embeddings529        per_frame = torch.zeros(audio_tokens_per_frame * human_num, dtype=encoder_k.dtype).to(encoder_k.device)530        per_frame[:audio_tokens_per_frame] = (self.rope_h1[0] + self.rope_h1[1]) / 2531        per_frame[audio_tokens_per_frame:] = (self.rope_h2[0] + self.rope_h2[1]) / 2532        encoder_pos = torch.concat([per_frame]*N_a, dim=0)533        encoder_k = self.rope_1d(encoder_k, encoder_pos)534 535        # get attn536        q = rearrange(q, "B H M K -> B M H K")537        encoder_k = rearrange(encoder_k, "B H M K -> B M H K")538        encoder_v = rearrange(encoder_v, "B H M K -> B M H K")539        attn_bias = xformers.ops.fmha.attn_bias.BlockDiagonalMask.from_seqlens(visual_seqlen, kv_seq)540        x = xformers.ops.memory_efficient_attention(q, encoder_k, encoder_v, attn_bias=attn_bias, op=None,)541        x = rearrange(x, "B M H K -> B H M K")542 543        # linear transform544        x_output_shape = (B, N, C)545        x = x.transpose(1, 2) 546        x = x.reshape(x_output_shape) 547        x = self.proj(x) 548        x = self.proj_drop(x)549 550        return x