**先记输入、输出、真值:**Wan视频模型接收文字,I2V版本还接收起始图像,输出视频;训练数据是与文字配对的真实视频。真视频经VAE压缩后,与随机噪声一起构造速度监督。

DreamZero把这个已训练的视频模型继续训练为“未来视频+动作”的联合生成模型。Wan原始预训练、DreamZero机器人训练、Flash少步适配是不同阶段,训练目标与可训练模块不能混写。

1. 一张框架图,分别看训练与生成

在这里插入图片描述

**自绘教学图,按 Wan2.1 官方报告与公开仓库内嵌模块标注,不是原论文图。**图中的“视频latent GT”与“网络速度GT”是不同层次;推理时没有未来GT输入。

阶段训练输入/条件数据真值训练什么
VAE训练视频/图像输入本身压缩后还能还原内容
Wan DiT训练带噪latent、噪声时间、文本,I2V另有首图条件真实视频latent+噪声构成的速度从噪声生成视频的更新方向
DreamZero训练视频/动作噪声、真实历史、语言、机器人状态未来视频与记录动作构成的联合速度画面变化与动作的联系
DreamZero-Flash视频偏高噪声、动作独立噪声仍是联合速度适应少步动作生成

2. 原始数据和条件怎么准备

一条教学训练数据:文字“机械臂拿起桌上的杯子”,视频包含靠近、抓住、提起的连续画面。输入条件决定“生成哪类内容”,而GT视频提供“这段内容实际怎样变化”的答案。

通用Wan预训练使用大规模图像/视频与描述,先筛选质量和运动等,再进行训练;不是要求每个互联网视频都有机器人关节标签。DreamZero用的机器人动作标签是后续适配新增的监督。

I2V训练可以从视频中选择起始图像作为条件,目标仍是视频。在代码里同一段GT视频同时用于取得首图条件与生成目标;模型允许看到首图,不等于允许看到全部未来干净答案。

3. Wan-VAE:为什么先把视频压缩

3.1 看一次真实形状换算

设B为batch、T为原始视频帧数、H/W为图像高宽。Wan2.1 VAE的输出形式:

[ B , 3 , T , H , W ] → [ B , 16 , 1 + ( T − 1 ) / 4 , H / 8 , W / 8 ] , T = 4 n + 1. [B,3,T,H,W]\rightarrow[B,16,1+(T-1)/4,H/8,W/8],\quad T=4n+1. [B,3,T,H,W]→[B,16,1+(T−1)/4,H/8,W/8],T=4n+1.

例如DreamZero拼好的33帧352×640:

RGB视频:[1,3,33,352,640]
VAE表示:[1,16,9,44,80]

前者有22,302,720个数,后者506,880个数,约44倍元素压缩。这个比值含通道由3增到16、首帧保留的影响,不能直接把4×8×8=256说成最终元素减少256倍;更不能由元素数直接推断实际GPU显存比例。

**33→9的具体分组:**第一幅单独编码,剩余32幅每4幅产生一个压缩时间位置,得到1+32/4=9;每个位置仍是16通道的空间特征网格,不是单个token。含逐组对应和编码循环的解释见 源码导读§2.8。

3.2 本地实现怎样保证时间压缩与连续性

wan_video_vae.py:939中定义encoder/decoder与时间下采样。wan_video_vae.py:969的 encode:

  1. 建立卷积特征cache。
  2. 先编码第一帧。
  3. 之后每4帧送一次encoder,带着卷积历史特征。
  4. 汇总输出,经conv取 mu,按通道均值/标准差归一化后返回。

这里的“因果”是编码过去时不依赖未来帧。底层 CausalConv3d 将时间padding全部放在过去侧,若有 cache_x 就先拼历史特征再减去对应padding,见 wan_video_vae.py:34。VAE卷积的feature cache缓存特征,与DiT注意力的KV cache不同。

VAE内部有encoder输出均值/方差以及 sample 函数,不意味着DreamZero每次前向都随机采VAE后验:活动的 encode 返回标准化后的mu。其decoder在 wan_video_vae.py:998,高层封装在 wan_video_vae.py:1208。

**中间通道要分清:**本地 self.encoder 子网络输出32通道;conv1(...).chunk(2,dim=1)后才保留16通道mu。首帧与带历史cache的后续4帧均产生1个压缩时间位置。详见 单帧/四帧encoder输出形状与meta核验。

3.3 VAE本身怎么训练(官方报告,非本地训练入口)

Wan报告§4.1.2:先训练2D图像VAE,再扩展为3D因果VAE,在低分辨率短视频上训练,最后用更高质量、多分辨率/时长视频微调;损失包括系数3的L1、3e−6的KL、3的LPIPS,最后阶段加入3D判别器GAN损失。原文

用教学公式理解各项职责:

L V A E = 3 L L 1 + 3 L L P I P S + 3 × 10 − 6 L K L (最后阶段另有GAN项) . L_{VAE}=3L_{L1}+3L_{LPIPS}+3\times10^{-6}L_{KL}\quad\text{(最后阶段另有GAN项)}. LVAE​=3LL1​+3LLPIPS​+3×10−6LKL​(最后阶段另有GAN项).

  • L1:逐像素还原误差,颜色/位置有没有还原对。
  • LPIPS:比较感知特征,让还原画面的结构与视觉观感更接近原视频。
  • KL:约束压缩表示分布,避免编码器随意使用不受约束的表示;常见高斯后验对标准正态的教学公式为 0.5 Σ(μ²+σ²−logσ²−1),不是本地重新实现过这套训练。
  • GAN:判别器区分真实与还原视频,促使细节更自然;这不保证物理正确。

本地边界:这里只带VAE网络与权重加载,不含复现上述完整VAE训练的data/optimizer/判别器入口。DreamZero冻结它,当前loss没有把KL、LPIPS、GAN一起继续优化。wan_flow_matching_action_tf.py:361。

3.4 为什么latent通道设为16

2026-11-04核对官方报告§4.1.1/4.1.4与本地VAE初始化。16是作者选定的latent特征宽度(超参数),不是从RGB的3通道、图像尺寸或时间压缩率算出来的。 官方报告明确采用16通道,但本次所查部分没有证明“16必然优于8或32”的专门通道消融,不能编造这个最优性结论。官方报告

每个压缩时空格用16个数来保存图像/运动信息。RGB的3通道有红绿蓝的固定含义;latent的16通道是网络学出的内部表示,不能指定成“第1通道是颜色、第2通道是深度”。

设计直觉是表示容量与压缩成本之间的取舍:通道更少,表示更紧凑,但可能更难保留细节;通道更多,允许保存更多信息,但latent存储和相关投影/解码开销增加。这里是一般原理,具体重建/生成质量还要靠训练实验,不能仅凭通道更多就保证更好。

代码直接将它设成默认参数:

class VideoVAE_(nn.Module):
    def __init__(self, dim=96, z_dim=16, ...):
        self.z_dim = z_dim
        self.encoder = Encoder3d(dim, z_dim * 2, ...)
        self.conv1 = CausalConv3d(z_dim * 2, z_dim * 2, 1)
        self.conv2 = CausalConv3d(z_dim, z_dim, 1)
# encode中:
mu, _ = self.conv1(out).chunk(2, dim=1)

以上为教学节选,省略号不是完整可运行初始化。encoder先输出2×16=32通道,随后拆分并保留16通道mu;32的来源是先选定16再乘2,不能反过来说16由某个自然定律决定。

DreamZero继承Wan2.1预训练VAE及DiT,所以必须匹配已训练的16通道接口。改成32不只是改一个配置数:VAE编码/解码权重、通道标准化统计、DiT输入输出层以及训练数据表示都需适配。在保持同一种I2V条件设计时,输入通道为2×z_dim+4:16时36通道;32时68通道。

若时间/空间压缩率与patch大小不变,单纯改latent通道不会改变每时间位置880个token;变的是patch里的输入数及投影维度,DiT宽度5120也不必自动改变。不能说16→32会让整个14B网络计算量刚好翻倍。

记忆句:16是每个压缩时空格的特征宽度;Wan选定并训练好了这套16通道表示,DreamZero沿用它。

4. T5与CLIP:条件从哪里来

T5把指令编码成512个4096维token;注意力mask用于处理有效文本长度,见 wan_video_text_encoder.py:253、wan_flow_matching_action_tf.py:542。它给DiT“生成什么”的条件,不是让一个聊天模型逐字输出视频。

I2V还保留首图的两种条件:

  1. VAE首图latent+mask:保留空间布局与已知帧信息。
  2. CLIP首图特征:作为视觉上下文送cross-attention。

本地 wan_flow_matching_action_tf.py:563 把首图和后续零帧编码得到16通道条件,再拼4通道mask,得到20通道y;与16通道噪声视频拼接成为36通道。CLIP输出257个1280维token,经MLP投到5120维。两条路不是重复命名同一张量。

I2V分量通道/形状作用
noisy video16通道待生成的视频内容
condition latent16通道从首图+零帧编码得到的条件
known-frame mask4通道指示已知/待生成位置
合计DiT输入36通道channel轴拼接,不是时间轴拼接
CLIP条件[B,257,1280]另走图像cross-attention

官方Wan I2V机制见报告§5.1、官方image2video.py。本地mask组装为首latent位置置1的实现,不能不加核验就泛化到首尾帧插值等其他模式。

术语白话:I2V条件是什么,patchify是什么?含首图双分支与实际代码。

5. DiT:真正做生成的大网络

5.1 Patchify → 时空token

卷积核与步长 (1,2,2):时间维不再缩小,latent空间每2×2变一个token。wan_video_dit_action_casual_chunk.py:1386。

L = F × ( H z / 2 ) × ( W z / 2 ) . L=F\times(H_z/2)\times(W_z/2). L=F×(Hz​/2)×(Wz​/2).

示例F=9、Hz=44、Wz=80,得到L=9×22×40=7920,每token5120维。三维位置编码让不同时间/空间位置可区分。

看逐步图解:latent时间位置是什么,7920与5120分别怎么来。包含144→5120投影与flatten/transpose代码。

5.2 每个block怎样读取信息

基本顺序为:归一化/噪声时间调制→self-attention→残差→cross-attention→残差→FFN→门控残差。wan_video_dit_action_casual_chunk.py:1151。

  • self-attention让视频token相互读取,建模同帧空间关系和帧间变化。
  • cross-attention让当前生成内容读取文本/首图条件。
  • timestep embedding告诉网络当前是高噪声还是接近完成,以调整更新方式。
  • FFN对每个token进一步加工,不是单独执行一次机器人规划。

通用Wan的视频生成窗口可以做双向时空注意力;DreamZero为分块闭环改成因果历史访问并加入动作/状态token。不能把DreamZero的所有mask和KV规则当成原始Wan的默认结构。

活动类边界:本地DreamZero用 wan_video_dit_action_casual_chunk.CausalWanModel;普通Wan类在 wan2_1_submodule.WanModel等文件里存在,但不是当前训练配置的 _target_。I2V cross-attention实际由 wan2_1_submodule.py:308 提供。

5.3 输出是什么

输出head把token映射回patch内16通道的数值,再unpatchify回video latent形状。这一轮输出的是更新方向,不是最终视频RGB,也不是一定已经干净的latent。 scheduler用它推进当前样本;生成完成后才由VAE decoder还原RGB。

6. Wan的Flow Matching训练:一条样本如何变成loss

6.1 两种时间记法必须对应

Wan报告正文:x_t=t x_data+(1−t)ε,t从噪声0到数据1,target为 x_data−ε。本地scheduler则使用σ:

x σ = ( 1 − σ ) z + σ ϵ , v ∗ = ϵ − z , t = 1 − σ . x_\sigma=(1-\sigma)z+\sigma\epsilon,\quad v^*=\epsilon-z,\quad t=1-\sigma. xσ​=(1−σ)z+σϵ,v∗=ϵ−z,t=1−σ.

本地 flow_match_scheduler.py:73、flow_match_scheduler.py:83。不是两个互相矛盾的目标,而是沿同一直线采用相反坐标方向。

6.2 六步训练流程

# 教学伪代码;本地实际返回的是视频/动作两分支
z = frozen_vae.encode(real_video)       # 干净压缩视频GT
c = frozen_text_encoder(instruction)   # 条件
noise = randn_like(z)
sigma = sample_schedule()
z_noisy = (1-sigma)*z + sigma*noise
pred_velocity = dit(z_noisy, sigma, c, image_condition)
target_velocity = noise-z
loss = weighted_mse(pred_velocity, target_velocity)
loss.backward()                       # 梯度更新DiT
optimizer.step()

为什么不需要标签员标注“噪声去哪里”? 因为z来自真实视频,noise是程序自己抽的,两者都已知,差值就能算出来。这与机器人动作GT不同:动作GT仍需演示记录,原始Wan不会凭视频自动知道某台机器人的关节数值。

为什么训练只随机取一个噪声程度,生成却要多步? 训练在许多样本、许多随机噪声时间上学习局部速度;推理时拿这个学到的速度场从噪声走到数据,需要数值求解器分若干步更新。训练不是每条样本都先完整生成一段视频再算loss。

6.3 一次手算验证

假设一维干净latent z=2、噪声ε=10、σ=0.75:

  • 输入:xσ=0.25×2+0.75×10=8。
  • GT速度:ε−z=8。
  • 若预测速度7,未加权平方误差 (7−8)²=1。
  • 若预测正确,步长σ从0.75走到0.5:新值 8+(0.5−0.75)×8=6。
  • 再走到0:6+(0−0.5)×8=2。

实际是高维张量、非恒定网络速度,多步求解并不保证精确恢复任意GT;算例只帮助看清符号与方向。

6.4 大规模预训练的阶段

官方报告§4.2.2:先低分辨率图像预训练,再图像/视频联合训练,逐步增加分辨率与时长;使用Flow Matching,后训练进一步使用高质量视频。原始时间采样描述为logit-normal,与DreamZero本地按shift时间表抽索引不同。原文

因此“Wan怎么训练”包含两层:先训练可用的VAE,再用压缩视频训练DiT。DreamZero接收的是这些已学好的权重,继续做机器人适配,而不是从随机参数重新完成互联网规模的视频预训练。

7. Wan推理:从噪声到视频

文字/首图 → 条件编码
随机视频latent噪声
  → DiT给更新方向 → scheduler推进一次
  → DiT给更新方向 → scheduler再推进
  → … → 视频latent → VAE解码 → RGB视频

本地简单scheduler的更新式:x_next=x+(sigma_next−sigma)*pred_velocity,见 flow_match_scheduler.py:43。实际DreamZero推理调用FlowUniPC多步求解器,不能把这个Euler式当其每个分支逐行执行的完整算法。

CFG(无分类器引导)按有指令和空/负条件两次预测形成 v_uncond+s*(v_cond−v_uncond),强化条件影响;不是分类器输出概率。DreamZero对视频使用该组合,动作读取条件分支,见 wan_flow_matching_action_tf.py:1274。

8. 从Wan到DreamZero:哪些保留,哪些改变

部分保留/改变源码入口
T5、CLIP、VAE载入并冻结wan_flow_matching_action_tf.py:174、wan_flow_matching_action_tf.py:361
视频DiT参数从Wan初始化,再继续训练wan_flow_matching_action_tf.py:264
状态/动作接口新增编码和解码wan_video_dit_action_casual_chunk.py:1367
注意力改为分块历史条件,视频与当前动作互相读取wan_video_dit_action_casual_chunk.py:816
GT与loss视频速度以外,加动作速度MSEwan_flow_matching_action_tf.py:760
推理记忆已发生真实视频进入KVwan_flow_matching_action_tf.py:1143
Flash训练时视频和动作噪声采样解耦wan_flow_matching_action_tf.py:679

详细调用、真实shape、mask、loss缩放与配置陷阱见 2026-11-04 - DreamZero源码全链路与Wan2.1训练实现。

9. 代码阅读顺序与证据边界

  1. wan_flow_matching_action_tf.py:603:看完整训练前向,先知道各模块串在哪里。
  2. wan_video_vae.py:969:看时间压缩和mu返回;不必一开始读完全部卷积层。
  3. wan_flow_matching_action_tf.py:563:看I2V首图的双分支。
  4. wan_video_dit_action_casual_chunk.py:1998:看patch、action/state拼接、teacher-forcing和输出。
  5. wan2_1_submodule.py:308、wan_video_dit_action_casual_chunk.py:1151:看cross-attention和一个block。
  6. flow_match_scheduler.py:73、wan_flow_matching_action_tf.py:784:把target和loss与前向对应。
  7. wan_flow_matching_action_tf.py:973:最后看生成采样和KV,而不是从TensorRT/服务端优化开始。

图中的shape来自明确尺寸的教学记录和本地代码算术;CPU/meta核验不含整网VAE/DiT权重。VAE训练阶段据官方报告,不冒充公开仓库包含原始全量预训练配方。Wan2.2或其他后续版本的48通道VAE不能直接套用本文16/36通道图。

来源与交叉链接

10. Wan2.1 与 Wan2.2:先分清具体型号

2026-11-04 核对官方Wan2.2仓库/配置,以及本地DreamZero的两套YAML。以下比较基础T2V/I2V路线,不覆盖该系列所有语音/动画扩展型号。

核心区别:Wan2.2的大模型A14B路线引入高/低噪声双专家;TI2V-5B路线则是较小的稠密模型,配更高空间压缩的VAE。不能把“Wan2.2”整体等同于MoE或5B。

项目Wan2.1-I2V-14BWan2.2-I2V-A14BWan2.2-TI2V-5B
基本职责图像/文字条件生成视频图像/文字条件生成视频同一模型支持文生视频与图生视频
DiT结构单个稠密主干高噪声/低噪声双专家单个稠密主干
参数口径约14B官方约27B总参数,每步约14B活跃约5B
VAEWan2.1 VAE仍用Wan2.1 VAEWan2.2 VAE
时间×高×宽压缩4×8×84×8×84×16×16
latent通道161648
每个DiT的宽/层/头5120 / 40 / 405120 / 40 / 403072 / 30 / 24
与当前DreamZero关系原论文采用的基座本次所查Wan22配置不是这条路线公开仓库另有适配配置

来源:Wan2.2官方介绍、A14B官方配置、TI2V-5B官方配置。

10.1 MoE是什么意思:按去噪阶段分工

MoE是Mixture of Experts(混合专家),这里可理解为两套分别擅长不同噪声阶段的生成网络。

随机噪声 → 高噪声专家:先形成总体布局与运动
         → 到达切换阈值
         → 低噪声专家:进一步完善细节
         → 视频latent → 解码

Wan2.1主要由同一个主干处理各个噪声阶段;Wan2.2 A14B把阶段分给两位专家。这里是按去噪时间切换整套专家,不能直接套用某些语言MoE“每个token选择几个FFN专家”的细节。A14B的A可以按active参数口径理解;总参数与单步参与计算的参数不同。两位专家的权重仍需存储/装载,不能据单步14B断言存储开销与单模型完全一样。

10.2 5B为什么可能更省计算:空间token更少

用同样33帧、256×256视频做教学比较,T=33均变成9个latent时间位置:

量Wan2.1 VAEWan2.2 TI2V-5B VAE
latent形状(B=1)[1,16,9,32,32][1,48,9,16,16]
latent元素数147456110592
patch=(1,2,2)后每时间位置token16×16=2568×8=64
总视频token数2304576

高度宽度各多压缩2倍,所以空间token少至1/4;但通道由16变48,latent总元素仅变为3/4。不要把token减少4倍说成全部显存或推理必然快4倍。网络宽度/层数、注意力、采样步数、硬件和分辨率都会影响成本。

10.3 本地DreamZero实际换了什么

源码:Wan2.1配置、Wan2.2配置。

本地适配参数Wan2.1主线Wan2.2-TI2V-5B适配
DiT宽/层/头5120/40/403072/30/24
VAE通道/空间步长16 / 848 / 16
输入/输出通道36 / 1648 / 48
concat_first_frame_latenttruefalse
当前代码输入视频尺寸三路176×320拼成352×640在head内统一到160×320
每latent时间位置视频token88050

这里880→50同时包含分辨率改变和VAE压缩改变,不能全部归因于Wan升级。首图CLIP分支仍保留在本地DreamZero适配中;官方5B的独立生成pipeline不能简单按本地适配概括,见官方textimage2video.py。

本地 docs/WAN22_BACKBONE.md表格把Wan2.1-14B写成32层/16头,与活动YAML的40层/40头不一致;本文采用YAML与实际类参数,不照抄文档。该文档描述的5Hz串行执行也不能用来替代DreamZero原论文异步控制配方。

10.4 loss或机器人能力会自动变好吗

两者仍属于视频生成路线;换2.2不意味着自动改成语言交叉熵或新增机器人奖励。本地两套配置共用 WANPolicyHead.forward,仍回归视频/动作的Flow Matching速度,视频latent维度随VAE变化。

5B版本更轻、视频压缩更高,与机器人动作是否更准是两件事。 从2.1-14B切到2.2-5B改变了版本、参数规模、VAE和输入尺寸,应对同一机器人评测后才能下结论。本次未训练或比较两版本真机性能,也不把DreamZero论文中另一5B对照的数字自动套给此Wan2.2配置。

首图条件、状态数量与三维RoPE的展开例子

继续看 首图条件latent和4通道mask、状态4是四条状态token、三维RoPE的维度拆分、源码与旋转算例。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐