Integração de Criação e Edição de Vídeo e Áudio com Wan2.1 VACE

Arquitetura do Modelo e Design de Fusão Multimodal

O sistema Wan2.1 VACE (Video-Audio Creation and Editing) inrtoduz uma abordagem unificada para geração e manipulação de vídeo, combinando processamento visual e sonoro em uma arquitetura coesa. Seu núcleo é baseado em uma estrutura de transformador de difusão (DiT) com ramificações especializadas.

Estrutura Principal

O modelo emprega uma arquitetura de ramificação dupla: um tronco principal para processamento geral e um ramo VACE dedicado ao controle de edição. Isso permite a ingestão precisa de múltiplos inputs modais.

Mecanismo de Codificação de Recursos Multimodal

O sistema processa entradas diversas, como descrições textuais, quadros-fonte de vídeo, máscaras de edição e imagens de referência, através de codificadores especializados.


def codificar_entradas_vace(self, quadros, imagens_ref, mascaras=None, codificador_vae=None):
    if mascaras is None:
        recursos_latentes = codificador_vae.encode(quadros)
    else:
        # Isola regiões ativas e inativas com base na máscara
        mascaras_bin = [torch.where(m > 0.5, 1.0, 0.0) for m in mascaras]
        regioes_inativas = [q * (1 - m) for q, m in zip(quadros, mascaras_bin)]
        regioes_ativas = [q * m for q, m in zip(quadros, mascaras_bin)]
        recursos_inativos = codificador_vae.encode(regioes_inativas)
        recursos_ativos = codificador_vae.encode(regioes_ativas)
        recursos_latentes = [torch.cat((ri, ra), dim=0) for ri, ra in zip(recursos_inativos, recursos_ativos)]

    recursos_fusao = []
    for recurso_latente, refs in zip(recursos_latentes, imagens_ref):
        if refs is not None:
            recursos_ref = codificador_vae.encode(refs)
            recurso_latente = torch.cat([*recursos_ref, recurso_latente], dim=1)
        recursos_fusao.append(recurso_latente)
    return recursos_fusao

Estratégia de Fusão por Atenção Hierárquica

Os sinais de controle de edição são injetados em diferentes profundidades da rede através de um mecanismo de atenção em camadas.

Camada Função Método de Fusão
Entrada Extração inicial de características Codificação por convolução 3D
Intermediária Fusão de características multimodais Atenção cruzada
Profunda Controle refinado Conexões residuais
Saída Geração final Projeção linear

Mecanismo de Garantia de Consistência Espaço-Temporal

Para assegurar coerência visual ao longo do tempo, o modelo implementa codificação 3D com sensibilidade tmeporal e um sistema de injeção de dicas em camadas.


self.incorporacao_recursos_vace = nn.Conv3d(
    self.dim_entrada_vace,
    self.dim_interna,
    kernel_size=self.tamanho_bloco,
    stride=self.tamanho_bloco)

def processar_recursos_vace(self, x, contexto_vace, comprimento_seq, kwargs):
    recursos_vace = [self.incorporacao_recursos_vace(u.unsqueeze(0)) for u in contexto_vace]
    recursos_vace = [u.flatten(2).transpose(1, 2) for u in recursos_vace]
    recursos_vace = torch.cat([torch.cat([u, u.new_zeros(1, comprimento_seq - u.size(1), u.size(2))],
                  dim=1) for u in recursos_vace])

    dicas_hierarquicas = []
    for bloco in self.blocos_vace:
        recursos_vace, dica_skip = bloco(recursos_vace, **kwargs)
        dicas_hierarquicas.append(dica_skip)
    return dicas_hierarquicas

Arquitetura de Suporte a Múltiplas Resoluções

O modelo suporta saída em várias resoluções configurando o stride do VAE e o tamanho dos blocos de processamento.

Resolução Stride VAE Tamanho do Bloco Dimensão Latente
480P (1, 8, 8) (1, 2, 2) 16
720P (1, 8, 8) (1, 2, 2) 16
1080P (1, 8, 8) (1, 2, 2) 16

Mecanismo de Coordenação entre Edição de Vídeo e Geração de Áudio

O VACE integra a edição visual com a síntese de áudio através de uma arquitetura de fusão multimodal e um mecanismo de alinhamento temporal, garantindo sincronia precisa.

Mecanismo de Alinhamento Temporal

Um módulo dedicado alinha os recursos de vídeo e áudio no domínio do tempo utilizando atenção cruzada e incorporações temporais.


class ModuloAlinhamentoTemporal(nn.Module):
    def __init__(self, dim=2048, num_cabecas=16):
        super().__init__()
        self.incorp_temp_video = nn.Linear(1, dim)
        self.incorp_temp_audio = nn.Linear(1, dim)
        self.atencao_cruzada = nn.MultiheadAttention(dim, num_cabecas)

    def forward(self, recursos_video, recursos_audio, carimbos_tempo):
        inc_video = self.incorp_temp_video(carimbos_tempo.unsqueeze(-1))
        inc_audio = self.incorp_temp_audio(carimbos_tempo.unsqueeze(-1))

        video_apr = recursos_video + inc_video
        audio_apr = recursos_audio + inc_audio

        video_alinhado, _ = self.atencao_cruzada(video_apr, audio_apr, audio_apr)
        audio_alinhado, _ = self.atencao_cruzada(audio_apr, video_apr, video_apr)

        return video_alinhado, audio_alinhado

Controle de Sincronização em Tempo Real

Um controlador gerencia buffers de vídeo e áudio, emparelhando quadros e amostras com base em seus carimbos de tempo para produzir saída sincronizada.


class ControladorSincronizacao:
    def __init__(self, taxa_quadros=30, taxa_amostragem=44100):
        self.taxa_quadros = taxa_quadros
        self.taxa_amostragem = taxa_amostragem
        self.buffer_video = []
        self.buffer_audio = []

    def sincronizar_buffers(self):
        dados_sincronizados = []
        idx_v, idx_a = A', 0

        while idx_v < len(self.buffer_video) and idx_a < len(self.buffer_audio):
            ts_v = self.buffer_video[idx_v][1]
            ts_a = self.buffer_audio[idx_a][1]

            if abs(ts_v - ts_a) < 0.033:
                dados_sincronizados.append((self.buffer_video[idx_v][0], self.buffer_audio[idx_a][0]))
                idx_v += 1
                idx_a += 1
            elif ts_v < ts_a:
                idx_v += 1
            else:
                idx_a += 1
        return dados_sincronizados

Técnicas de Processamento de Máscaras e Integração de Imagens de Referência

Para controle preciso da edição, o sistema VACE emprega processamento avançado de máscaras e integração de imagens-guia no espaço latente.

Processamento de Máscaras no Espaço Latente

Máscaras de segmentação são aplicadas para isolar regiões de interesse antes da codificação, permitindo edições localizadas.


def codificar_com_mascara(self, quadros, imagens_ref, mascaras, codificador_vae):
    mascaras_bin = [torch.where(m > 0.5, 1.0, 0.0) for m in mascaras]
    # Separa e codifica regiões inativas e ativas
    quadros_inativos = [q * (1 - m) for q, m in zip(quadros, mascaras_bin)]
    quadros_ativos = [q * m for q, m in zip(quadros, mascaras_bin)]
    latentes_inativos = codificador_vae.encode(quadros_inativos)
    latentes_ativos = codificador_vae.encode(quadros_ativos)
    # Concatena recursos das duas regiões
    latentes_combinados = [torch.cat((li, la), dim=0) for li, la in zip(latentes_inativos, latentes_ativos)]

    resultado_final = []
    for latente, refs in zip(latentes_combinados, imagens_ref):
        if refs is not None:
            latentes_ref = codificador_vae.encode(refs)
            latente = torch.cat([*latentes_ref, latente], dim=1)
        resultado_final.append(latente)
    return resultado_final

Redimensionamento e Alinhamento Espacial de Máscaras

As máscaras são redimensionadas para corresponder à resolução do espaço latente do VAE, utilizando interpolação, para garantir alinhamento correto com os recursos visuais codificados.


def ajustar_mascara_latente(self, mascaras, stride_vae):
    resultado = []
    for mascara in mascaras:
        c, prof, alt, larg = mascara.shape
        nova_profundidade = int((prof + 3) // stride_vae[0])
        nova_altura = 2 * (alt // (stride_vae[1] * 2))
        nova_largura = 2 * (larg // (stride_vae[2] * 2))

        mascara = mascara[0, :, :, :]
        mascara = mascara.view(prof, alt, stride_vae[1], larg, stride_vae[2])
        mascara = mascara.permute(2, 4, 0, 1, 3)
        mascara = mascara.reshape(stride_vae[1] * stride_vae[2], prof, alt, larg)

        mascara_redim = F.interpolate(
            mascara.unsqueeze(0),
            size=(nova_profundidade, nova_altura, nova_largura),
            mode='nearest-exact').squeeze(0)
        resultado.append(mascara_redim)
    return resultado

Tags: transformador de difusão processamento multimídia edição de vídeo Síntese de Áudio aprendizagem profunda

Publicado em 9-30 13:48