原文摘要
提出 FramePack 架构
一种新的视频生成模型结构。
基于“下一帧预测”的思路进行视频生成。
FramePack核心思想
压缩输入帧,固定上下文长度
将输入的多个帧压缩成固定长度的上下文。
无论视频有多少帧,Transformer 的输入长度都不变。
解决了随着视频长度增加而显存爆炸的问题。
提出 Anti-Drifting 反漂移采样策略
先生成视频的开头和结尾,再生成中间帧。
生成顺序是“时间反向”的。
目的:防止误差在逐帧生成中逐步累积。
支持大 Batch 训练
压缩上下文后,显存占用降低。
批量大小(batch size)可以显著提升,加速模型训练。
FramePack的效果
计算效率大幅提升
视频生成的计算成本接近图像生成。
可以处理更多帧、更长时间的视频片段。
兼容并优化已有视频扩散模型
可以在已有模型基础上微调 FramePack。
利用更“平衡”的扩散调度器,减少时间步的偏移。
带来更好的画面质量和流畅性。
问题与挑战
核心问题:视频逐帧(或逐片段)预测模型存在两大关键问题:
Dilemma:缓解遗忘的方法(如增强记忆)会加速误差传播(加剧漂移);而抑制漂移的方法(如打断时间依赖)会加重遗忘。
现有方法的局限性
效率问题:视频帧间存在大量冗余,全上下文编码效率低下。
漂移的复杂性:
解决方案框架
FramePack结构:
抗遗忘:通过重要性压缩输入帧,固定上下文长度上限,支持更多帧编码且不增加计算负担。
技术优势与发现
兼容性:可微调现有视频扩散模型(如HunyuanVideo、Wan)。
实验发现:
全视频生成的调度器问题:
由于一次性处理长序列,需在极端时间步(如极早或极晚的 timestep
)分配更多权重,以覆盖全局信息。
例如:早期时间步需快速降噪以捕捉整体运动,后期时间步需精细调整细节,导致调度器
激进(aggressive),表现为:
逐帧预测的调度器优势:
逐帧预测的每步张量更小,支持更平衡的扩散调度器(减少极端时间步偏移)。
温和的调度器可能间接提升视觉质量,超越解决遗忘/漂移的直接目标。
噪声调度与增强(Noise Scheduling & Augmentation)
基于分类器无关引导(Classifier-Free Guidance, CFG)的方法
锚定帧(Anchor Frames)规划
潜在空间压缩(Latent Space Compression)
遗忘与漂移的权衡讨论
潜在扩散与多提示生成
无需训练的扩展方法
分层与分布式生成
一致性长视频生成
其他前沿技术
线性注意力(Linear Attention)
稀疏注意力(Sparse Attention)
低比特计算(Low-bit Computation)
隐藏状态缓存(Hidden State Caching)
蒸馏(Distillation)
任务描述
模型类型:基于 扩散Transformer(DiT) 的预测模型,所有帧和像素均在潜在空间中操作。
核心挑战:上下文长度爆炸
单帧上下文长度:每帧的token数 L f L_f Lf(例如Hunyuan/Wan/Flux模型中480p的帧的 L f ≈ 1560 L_f \approx 1560 Lf≈1560)。
总上下文长度: L = L f ( T + S ) L = L_f (T + S) L=Lf(T+S)
重要性优先级假设
观察:输入帧 F 0 , F 1 , … , F T − 1 F_0, F_1, \dots, F_{T-1} F0,F1,…,FT−1 对下一帧预测的贡献不同。
简化假设:时间邻近性反映重要性(Temporal Proximity Prior)。
目标
通过动态分配每帧的上下文长度(token数),实现:
重要帧(如 F 0 F_0 F0 )保留更多细节(高token数)。
非重要帧(如 F T − 1 F_{T-1} FT−1 )高度压缩(低token数)。
总上下文长度 L L L 收敛到固定上界,与历史帧数 T T T 无关。
长度函数 ϕ ( F i ) \phi(F_i) ϕ(Fi)
定义:在VAE编码和Transformer Patchifying之后,第 i i i 帧 F i F_i Fi 的上下文长度(token数,不改变token的维度)为:
ϕ ( F i ) = L f λ i ( λ > 1 ) \phi(F_i) = \frac{L_f}{\lambda^i} \quad (\lambda > 1) ϕ(Fi)=λiLf(λ>1)
实现方式:动态Patchify核
公式
L = S ⋅ L f + L f ⋅ ∑ i = 0 T − 1 1 λ i = S ⋅ L f + L f ⋅ 1 − 1 / λ T 1 − 1 / λ L = S \cdot L_f + L_f \cdot \sum_{i=0}^{T-1} \frac{1}{\lambda^i} = S \cdot L_f + L_f \cdot \frac{1 - 1/\lambda^T}{1 - 1/\lambda} L=S⋅Lf+Lf⋅i=0∑T−1λi1=S⋅Lf+Lf⋅1−1/λ1−1/λT
第一项 S ⋅ L f S \cdot L_f S⋅Lf :预测帧 X X X 的原始token数。
第二项:历史帧压缩后的总token数(等比数列求和)。
极限行为( T → ∞ T \to \infty T→∞ )
lim T → ∞ L = ( S + λ λ − 1 ) ⋅ L f \lim_{T \to \infty} L = \left( S + \frac{\lambda}{\lambda - 1} \right) \cdot L_f T→∞limL=(S+λ−1λ)⋅Lf
结论:
当历史帧数 T T T 趋近无穷时, L L L 收敛到固定值。
因为 L L L 收敛为固定值,所以复杂度瓶颈和 T T T (即帧数) 无关
示例:若 λ = 2 \lambda=2 λ=2 , S = 1 S=1 S=1 , L f = 1560 L_f=1560 Lf=1560 :
L ∞ = ( 1 + 2 2 − 1 ) ⋅ 1560 = 4680 ( 与 T 无关 ) L_\infty = \left(1 + \frac{2}{2-1}\right) \cdot 1560 = 4680 \quad (\text{与} T \text{无关}) L∞=(1+2−12)⋅1560=4680(与T无关)
λ \lambda λ 选择
硬件优先:默认选择 λ = 2 λ=2 λ=2 的幂次核尺寸(如 ( 4 , 4 , 4 ) (4,4,4) (4,4,4) )。
灵活调整:通过复制/舍弃级数项适配不同压缩需求(如长视频需更高压缩率)。
核尺寸权衡:
静态内容 → 大空间核。
动态内容 → 大时间核。
3D Patchify核的维度表示
3D核尺寸: ( p f , p h , p w ) (p_f,p_h,p_w) (pf,ph,pw)
物理意义:
与FramePack结合:动态核调整实现抗遗忘(保留关键帧细节)与抗漂移(压缩非关键帧)。
独立patchifying的参数
核心问题
实验发现:
具体做法
选定3种主流压缩率来处理视频帧: ( 2 , 4 , 4 ) 、 ( 4 , 8 , 8 ) 、 ( 8 , 16 , 16 ) (2,4,4)、(4,8,8)、(8,16,16) (2,4,4)、(4,8,8)、(8,16,16)
对每种压缩率,他们都配了一套 单独的神经网络层 来做输入编码
处理极端压缩
如果某些帧需要更极端压缩(如 ( 16 , 32 , 32 ) (16,32,32) (16,32,32)),那就先做一次下采样(如用2×2×2卷积降分辨率);
然后用已有的最大卷积核 (8, 16, 16)
来继续编码。
优势:避免无限制地增加新的 projection 层数量,提高参数复用性。
为了加速收敛,防止训练不稳定:
新的 projection 层会从已有的预训练模型中“插值”初始化(比如从 HunyuanVideo 的 (2,4,4) patch 投影参数中插值得到)。
插值初始化 = 保留已有模型的知识 + 提升收敛效率 + 避免随机初始化带来的不稳定。
尾帧处理
问题背景
FramePack压缩过程通过一个 动态分配机制:
现实中,如果视频非常长,最后那一部分帧可能:
已经被压缩得非常极端(比如 16×32×32)
再压缩下去就没法再分出一个 patch(比如只剩 1 个 latent 像素)
这就是所谓的 “tail 区域”:即最后这部分帧,已不足以组成一个 patch 或 token。
处理方法
直接删除尾帧(Delete the tail)
如果某些尾帧压缩后不足以形成一个 token,就不处理了,直接舍弃。
好处:保持固定上下文长度,计算量小。
缺点:丢掉一些帧(但这些帧本来就不重要)。
让每个尾帧单独增加 1 个 latent token
虽然不能组成 patch,但每一帧都映射成 1 个 token 加进 transformer。
意味着上下文长度 轻微增加(每多一帧就多 1 个 token)。
更保守地保留全部信息,但轻微打破 context length 固定的假设。
把所有尾帧做全局平均池化,然后用最大 kernel 编码为一个 token
把所有 tail 帧的 latent 特征做 global average pooling
(类似做一个平均帧)。
然后用预设的最大压缩核(如 8×16×16)生成一个 token,代表全部尾帧。
既保留信息,也保证 context 长度不变。
实验观察
RoPE对齐
avg_pooling(kernel=4x4)
,变成 8×8 的相位典型几何级数(Typical Geometric Progression)
压缩率:按几何级数递减(如 1 , 1 2 , 1 4 , 1 8 , 1 16 1, \frac{1}{2}, \frac{1}{4}, \frac{1}{8}, \frac{1}{16} 1,21,41,81,161 )。
Patchify核:核尺寸逐级增大(如 ( 1 , 2 , 2 ) → ( 1 , 8 , 8 ) (1,2,2) \rightarrow (1,8,8) (1,2,2)→(1,8,8)),对应更粗粒度的分块。
特点:
带重复级别的级数(Progression with Duplicated Levels)
压缩率:非连续递减,部分级别重复(如 1 , 1 4 , 1 4 , 1 16 , … 1, \frac{1}{4}, \frac{1}{4}, \frac{1}{16}, \dots 1,41,41,161,… )。
Patchify核:相同核尺寸重复使用(如两个 ( 1 , 4 , 4 ) (1,4,4) (1,4,4) 连续应用)。
特点:
时空联合分块级数(Geometry Progression with Temporal Kernel)
压缩率:时空联合分块(如 ( 4 , 4 , 4 ) (4,4,4) (4,4,4) 表示跨4帧×4×4空间分块)。
Patchify核:核尺寸包含时间维度(如 ( 8 , 8 , 4 ) (8,8,4) (8,8,4) )。
特点:
重要起始级数(Progression with Important Start)
压缩率:与 1 相同,但强制首帧 F T − 1 F_{T-1} FT−1 保留完整token数。
Patchify核:同 1 ,但首帧不压缩。
特点:
对称级数(Symmetric Progression)
压缩率:首尾帧对称分配高token数(如 F T − 1 F_{T-1} FT−1 和 F 0 F_0 F0 均无压缩)。
Patchify核:同 4 ,但两端帧均保留完整信息。
特点:
抗漂移采样
问题定义
解决方法:提供未来帧的访问能力
采样方式
普通因果采样
就是传统的“从已知帧开始,一帧一帧往后生成”
完全因果,每次生成的帧依赖于前面的内容
缺点:越往后越不稳定 → 漂移现象严重
双向采样
第一轮就生成“开头帧”和“结尾帧”
后续轮次只负责填补中间的内容(inpainting)
好处:
生成过程有两个锚点(begin + end),
中间帧是受控生成 → 不易漂移
适合生成中等长度的高质量视频
反向采样
image-to-video中:
用户给的是高质量的第一帧
我们要生成后续帧,但要逐步逼近第一帧的风格和语义
即:
第一轮仍然生成末尾帧(作为 anchor)
然后反向采样 + 插值,保证前后帧都逼近第一帧
特别适合 image-to-video / prompt-to-video 任务
RoPE with random access
反向采样的问题:非连续RoPE编码
解决方法:
RoPE 编码仍然是“全局时间索引感知”的
但当我们不处理某些帧时(例如 frame 1~9),我们不生成这些帧的 RoPE 相位
只保留 frame 0、10、30、50 的 RoPE phase,且保持其真实时间位置
直观做法
# 原始位置 index:
positions = [0, 10, 30, 50]
# 假设你有一个 RoPE 编码器,支持任意 index 输入:
rope_encoding = get_rope_encoding(positions)
命名结构的总体格式:
结构形如:
td_f16k4f4k2f1k1_g9_x_f1k1
可以被拆解为几个部分:
字段名 | 含义 |
---|---|
td | tail 处理方式(如 td、ta、tc) |
f16k4f4k2f1k1 | 主干压缩结构(表示不同帧段使用了不同的 kernel) |
g9 | 表示要生成的帧数量 |
x | 表示“跳过”部分帧(防漂移) |
f1k1 | 表示在 x 之后使用的 anchor 帧压缩设置(例如后端锚点) |
Kernel 编码结构解释
完整表示法:
k1h2w2 → 表示 kernel=(1帧, 2高, 2宽)
k2h4w4 → 表示 kernel=(2帧, 4高, 4宽)
简写(常用)方式:
FramePack 为了简洁,引入如下缩写:
简写 | 实际 kernel |
---|---|
k1 | (1, 2, 2) |
k2 | (2, 4, 4) |
k4 | (4, 8, 8) |
k8 | (8, 16, 16) |
举例:
f16k4 → 表示 16 帧用 k4 编码(即 kernel=(4,8,8))
f4k2 → 表示 4 帧用 k2 编码(即 kernel=(2,4,4))
f1k1 → 表示 1 帧用 k1 编码(即 kernel=(1,2,2))
三种tail的策略
代码 | 含义 |
---|---|
td |
删除这些尾帧(delete) |
ta |
先使用 3D Pooling (1,32,32),再找最接近的 kernel 编码(append) |
tc |
对 tail 全局 average pooling,再编码(compress) |
Sampling 采样策略对应的命名结构
Vanilla 采样(顺序采样 Fig.2-a)
td_f16k4f4k2f1k1_g9
删除尾帧(td)
使用 f16k4f4k2f1k1 的三层结构来压缩连续的19帧的视频段
然后依次生成 9 帧(g9)
Anti-drifting 采样(双向锚点,Fig.2-b)
td_f16k4f4k2f1k1_g9_x_f1k1
在 Vanilla 基础上加了 _x_f1k1
表示:跳过中间帧,在最后加了一个锚点帧(也用 k1 编码)
所以是“双向锚定”,先生成开头和结尾,再补中间 → 防漂移
Inverted anti-drifting(倒序采样,Fig.2-c)
f1k1_x_g9_f1k1f4k2f16k4_td
倒过来:先以末尾帧为起点(f1k1)
加上前置 anchor,然后生成中间(g9)
再“反方向”补充前段(f4k2f16k4)
最后处理 tail(td)
跳帧 x
的作用
把中间帧留空,模型之后再去插补这些帧。
f1k1 + x + f1k1
:提供两端锚点帧
g9:指在中间补出 9 帧
模型知道前后锚点,就不会发生质量飘移
项目 | 内容 |
---|---|
框架模式 | Text-to-video 与 Image-to-video |
模型 | Wan2.1 和 HunyuanVideo(推荐) |
关键修改 | 冻结 LLaMA、多模态清除、使用 SigLip、持续训练 |
数据集 | 参考 LTXVideo,质量过滤 + 分辨率桶 |
训练配置 | Adafactor、1e-5 学习率、梯度裁剪 0.5 |
硬件支持 | A100/H100,支持大 batch |
训练时间 | ablation 实验 48h,最终模型 7 天 |
优势 | 快速、适合实验室,视频生成清晰、稳定 |
漂移测量:起始-结束对比度(start-end contrast)。
定义
含义
差值越大,表示前后质量差异越大,漂移越严重;
使用绝对值是为了忽略生成顺序的方向性(比如有的模型从前往后生成,有的从后往前)