Wan2.1 通过首尾帧生成视频

Wan2.1 通过首尾帧生成视频

flyfish

使用 Wan2.1-FLF2V-14B-720P 模型,通过输入两张图像(起始帧和结束帧),生成一段连贯的视频。

First Last Frame-to-Video 即 "首末帧到视频" 技术

py 复制代码
import numpy as np
import torch
import torchvision.transforms.functional as TF
from modelscope import AutoencoderKLWan, WanImageToVideoPipeline
from diffusers.utils import export_to_video, load_image
from modelscope import CLIPVisionModel

# 加载模型
model_id = "Wan-AI/Wan2.1-FLF2V-14B-720P-Diffusers"
# 加载输入图像
first_frame = load_image("./first_frame.jpg")
last_frame = load_image("./last_frame.jpg")

image_encoder = CLIPVisionModel.from_pretrained(model_id, subfolder="image_encoder", torch_dtype=torch.float32)
vae = AutoencoderKLWan.from_pretrained(model_id, subfolder="vae", torch_dtype=torch.float32)
pipe = WanImageToVideoPipeline.from_pretrained(
    model_id, vae=vae, image_encoder=image_encoder, torch_dtype=torch.bfloat16
)
pipe.to("cuda")  # 将模型移至GPU



# 调整图像尺寸以匹配模型要求和最大面积限制
def aspect_ratio_resize(image, pipe, max_area=720 * 1280):
    aspect_ratio = image.height / image.width
    mod_value = pipe.vae_scale_factor_spatial * pipe.transformer.config.patch_size[1]
    height = round(np.sqrt(max_area * aspect_ratio)) // mod_value * mod_value
    width = round(np.sqrt(max_area / aspect_ratio)) // mod_value * mod_value
    image = image.resize((width, height))
    return image, height, width

# 居中裁剪并调整图像大小
def center_crop_resize(image, height, width):
    resize_ratio = max(width / image.width, height / image.height)
    width = round(image.width * resize_ratio)
    height = round(image.height * resize_ratio)
    size = [width, height]
    image = TF.center_crop(image, size)
    return image, height, width

# 预处理图像
first_frame, height, width = aspect_ratio_resize(first_frame, pipe)
if last_frame.size != first_frame.size:
    last_frame, _, _ = center_crop_resize(last_frame, height, width)

# 定义视频内容提示词
prompt = "CG animation style, a small blue bird takes off from the ground, flapping its wings. The bird's feathers are delicate, with a unique pattern on its chest. The background shows a blue sky with white clouds under bright sunshine. The camera follows the bird upward, capturing its flight and the vastness of the sky from a close-up, low-angle perspective."

# 生成视频
output = pipe(
    image=first_frame, last_image=last_frame, prompt=prompt, 
    height=height, width=width, guidance_scale=5.5
).frames[0]

# 导出视频
export_to_video(output, f"wan-ff2v.mp4", fps=16)

Wan2.1-FLF2V-14B-720P 模型文件结构

核心模型组件

  1. image_encoder
    • 它的功能是把输入图像转变为特征向量,这些向量能够被后续的生成模型所运用。
    • 该组件一般由预训练的视觉模型构成,像 CLIP 或者 ViT 模型。
  2. text_encoder
    • 其作用是对文本提示进行编码,生成对应的文本嵌入(text embeddings),以此来引导视频生成的过程。
    • 通常是基于 Transformer 架构的语言模型,例如 BERT 。
  3. transformer
    • 这是模型的核心生成网络,它会结合图像特征和文本嵌入,进而生成视频帧序列。
    • 模型名称中的 "14B" 代表该 Transformer 拥有 140 亿参数。
  4. vae (Variational Autoencoder)
    • 负责图像的压缩与解压缩工作,能够在潜在空间(latent space)中对视频帧进行高效处理。
    • 这里使用的是专门为视频生成优化过的 AutoencoderKLWan 版本。
  5. scheduler
    • 作为扩散过程的调度器,它能够控制噪声的添加和移除步骤,从而影响生成视频的质量和多样性。

配置与元数据

  1. configuration.json
    • 该文件包含了模型的基础配置信息,例如隐藏层维度、注意力头数量等架构参数。
  2. model_index.json
    • 这是模型权重文件的索引,在使用多个分片文件时,它的作用尤为重要。
  3. tokenizer
    • 其功能是将文本提示转换为模型能够理解的 token 序列,和 NLP 模型中的 tokenizer 作用相同。
  4. image_processor
    • 用于对输入图像进行预处理,比如调整尺寸、归一化等操作,是图像编码器的前置处理组件。

流程

  1. image_encoder 对输入的首帧和末帧图像进行编码。
  2. text_encoder 对文本提示进行编码。
  3. transformer 结合图像和文本特征,在潜在空间中生成视频帧。
  4. vae 将潜在空间中的视频帧解码为实际的图像帧。
  5. scheduler 控制整个扩散生成过程。

image_encoder 组件

基于 CLIP-ViT-H-14 视觉编码器

核心参数解析

1. 模型基础信息
json 复制代码
"_name_or_path": "laion/CLIP-ViT-H-14-laion2B-s32B-b79K",
"architectures": ["CLIPVisionModelWithProjection"],
"model_type": "clip_vision_model",
  • CLIP-ViT-H-14 :是 OpenAI 开发的 Contrastive Language-Image Pretraining (CLIP) 模型的一种变体,使用 Vision Transformer (ViT) 架构,参数量约为 632M
  • H-14 :表示使用 Hybrid 架构(结合 CNN 和 Transformer),并且 patch 大小为 14×14 像素。
  • laion2B-s32B-b79K:表明该模型在 LAION-2B 数据集上训练,包含 20 亿图像-文本对。
2. 模型架构参数
json 复制代码
"hidden_size": 1280,
"num_hidden_layers": 32,
"num_attention_heads": 16,
"intermediate_size": 5120,
  • hidden_size=1280:每个 Transformer 层的隐藏状态维度为 1280(即特征向量长度)。
  • num_hidden_layers=32:模型包含 32 个 Transformer 块,属于较深的架构。
  • num_attention_heads=16:每层使用 16 个注意力头,并行处理不同子空间的信息。
  • intermediate_size=5120 :MLP 层的中间维度,通常是 hidden_size 的 4 倍(1280×4=5120)。
3. 图像输入参数
json 复制代码
"image_size": 224,
"patch_size": 14,
"num_channels": 3,
  • image_size=224 :模型输入图像的分辨率为 224×224 像素
  • patch_size=14:将图像分割为 14×14 的 patch,每个 patch 被展平为一维向量。
  • num_channels=3:输入图像为 RGB 三通道。
4. 投影层参数
json 复制代码
"projection_dim": 1024,
  • projection_dim=1024:模型输出的特征向量维度为 1024。这意味着输入图像最终会被编码为一个 1024 维的向量,用于后续的视频生成任务。
5. 正则化与数值稳定性
json 复制代码
"attention_dropout": 0.0,
"dropout": 0.0,
"layer_norm_eps": 1e-05,
"torch_dtype": "bfloat16",
  • dropout=0.0:不使用 dropout 正则化,因为预训练模型通常不需要。
  • layer_norm_eps=1e-5:LayerNorm 层的稳定常数,防止数值计算中的除零错误。
  • torch_dtype="bfloat16":使用 Brain Floating Point 16 位精度进行计算,比 FP16 更稳定,适合大规模模型。
6. 激活函数与初始化
json 复制代码
"hidden_act": "gelu",
"initializer_range": 0.02,
  • hidden_act="gelu":使用 GELU (Gaussian Error Linear Unit) 激活函数,比 ReLU 更平滑,能减少梯度消失问题。
  • initializer_range=0.02:权重初始化的标准差为 0.02,控制初始参数的分布范围。

模型工作流程

  1. 图像预处理:输入图像被缩放到 224×224,分割为 16×16=256 个 patch(每个 patch 14×14 像素)。
  2. 嵌入生成:每个 patch 被线性映射为 1280 维的嵌入向量,并添加位置编码。
  3. 特征提取:通过 32 层 Transformer 处理这些嵌入,捕获图像的全局和局部特征。
  4. 投影输出:最终特征通过线性投影层转换为 1024 维的向量,作为视频生成模型的输入。

在视频生成中的作用

Wan2.1-FLF2V-14B-720P 模型中,这个 image_encoder 负责:

  • 将输入的首帧和末帧图像编码为语义特征向量。
  • 这些特征向量与文本提示的编码(由 text_encoder 生成)结合,指导 transformer 生成中间帧。
  • 1024 维的特征向量包含了图像的高级语义信息(如物体、场景、动作),帮助模型理解"要生成什么"。

scheduler 组件

制着扩散模型生成视频帧的具体过程。UniPCMultistepScheduler 是一种先进的多步求解器调度器。调度器(Scheduler) 是控制生成过程的核心组件,其作用类似于 "导演",决定了如何逐步从噪声中 "提炼" 出最终的图像或视频。

核心参数解析

1. 调度器基础信息
json 复制代码
"_class_name": "UniPCMultistepScheduler",
"_diffusers_version": "0.34.0.dev0",
  • UniPCMultistepScheduler:是一种基于数值微分方程求解器的调度器,支持单步和多步模式,能以更少的采样步骤达到与 DDIM 等传统调度器相当的质量。
  • diffusers_version:表明该调度器是为 diffusers 库的 0.34.0 版本开发的。
2. 噪声调度参数
json 复制代码
"beta_start": 0.0001,
"beta_end": 0.02,
"beta_schedule": "linear",
"num_train_timesteps": 1000,
"timestep_spacing": "linspace",
  • beta_start/end:噪声调度的起始和结束噪声水平,控制图像加噪和去噪的强度范围。
  • beta_schedule="linear":噪声强度随时间线性增加(从 0.0001 到 0.02),这是扩散模型最常用的调度方式。
  • num_train_timesteps=1000 :训练时使用的时间步总数,实际推理时可通过 num_inference_steps 参数调整步数。
  • timestep_spacing="linspace":时间步均匀分布,即每个时间步的间距相等。
3. 求解器参数
json 复制代码
"solver_order": 2,
"solver_type": "bh2",
"lower_order_final": true,
"predict_x0": true,
"prediction_type": "flow_prediction",
  • solver_order=2:求解器的阶数,2 阶表示使用二阶方法,在精度和计算效率之间取得平衡。
  • solver_type="bh2" :使用 Burlish-Stoer 方法的二阶变体,比标准 Euler 方法更精确。
  • lower_order_final=true:在最后几步使用低阶方法,提高稳定性。
  • predict_x0=true :模型预测的是原始图像 x0(而非噪声),这是扩散模型的常见设置。
  • prediction_type="flow_prediction":特殊的预测类型,针对视频生成优化,预测帧之间的运动流(motion flow)。
4. 视频生成特有的参数
json 复制代码
"use_flow_sigmas": true,
"flow_shift": 16.0,
  • use_flow_sigmas=true:启用针对运动流的噪声调度,专门为视频生成设计,帮助模型学习帧间的平滑过渡。
  • flow_shift=16.0:运动流的缩放因子,控制帧间变化的幅度。较大的值会产生更明显的运动效果。
5. 阈值与稳定性参数
json 复制代码
"thresholding": false,
"dynamic_thresholding_ratio": 0.995,
"sample_max_value": 1.0,
  • thresholding=false:不使用动态阈值,这是一种防止生成图像过饱和的技术。
  • sample_max_value=1.0:生成样本的像素值范围为 [-1, 1],符合大多数扩散模型的输出规范。
6. 其他参数
json 复制代码
"disable_corrector": [],
"final_sigmas_type": "zero",
"rescale_betas_zero_snr": false,
  • disable_corrector=[]:不禁用校正器,允许调度器在每一步后微调预测结果。
  • final_sigmas_type="zero":最后一步的噪声水平为 0,确保生成的图像完全去噪。

调度器工作流程

  1. 初始化:从纯噪声图像(或低质量图像)开始。
  2. 多步去噪:使用二阶 Burlish-Stoer 方法,通过 20-50 步(通常少于训练时的 1000 步)逐步移除噪声。
  3. 运动流引导:在去噪过程中,模型不仅预测图像内容,还预测帧间的运动流,确保生成的视频帧具有时间连贯性。
  4. 低阶收尾:最后几步使用一阶方法,提高稳定性,减少可能的 artifacts。

在视频生成中的作用

Wan2.1-FLF2V-14B-720P 模型中,这个调度器负责:

  • 控制从首帧到末帧的过渡过程,生成中间帧序列。
  • 通过 flow_predictionuse_flow_sigmas 参数,特别优化了对运动的处理,使生成的视频更加流畅自然。
相关推荐
hhzz14 天前
【Vision人工智能设计 】Wan(万相) 内容创作平台与能力
人工智能·阿里·视觉大模型·wan·万相
hhzz18 天前
【Vision人工智能设计 】ComfyUI 基础文生图设计
人工智能·comfyui·视觉大模型·wan
西西弗Sisyphus9 个月前
Wan2.1 图生视频模型内部协作流程
wan
西西弗Sisyphus9 个月前
Wan2.1 文生视频 支持批量生成、参数化配置和多语言提示词管理
wan
西西弗Sisyphus9 个月前
Wan2.1 图生视频 支持批量生成
音视频·wan·anytext2
飞塔老梅子2 年前
【隧道篇 / WAN优化】(7.4) ❀ 01. 启动WAN优化 ❀ FortiGate 防火墙
缓存·优化·隧道·远程访问·wan