惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Visual Studio Blog
爱范儿
爱范儿
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
雷峰网
雷峰网
V
V2EX
博客园_首页
Engineering at Meta
Engineering at Meta
博客园 - 聂微东
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Apple Machine Learning Research
Apple Machine Learning Research
GbyAI
GbyAI
H
Help Net Security
A
About on SuperTechFans
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Blog — PlanetScale
Blog — PlanetScale
W
WeLiveSecurity
云风的 BLOG
云风的 BLOG
D
Docker
Security Archives - TechRepublic
Security Archives - TechRepublic
Help Net Security
Help Net Security
N
News and Events Feed by Topic
Simon Willison's Weblog
Simon Willison's Weblog
G
Google Developers Blog
A
Arctic Wolf
T
The Blog of Author Tim Ferriss
博客园 - 叶小钗
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Google DeepMind News
Google DeepMind News
博客园 - 三生石上(FineUI控件)
aimingoo的专栏
aimingoo的专栏
Hacker News: Ask HN
Hacker News: Ask HN
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 司徒正美
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Privacy International News Feed
T
Troy Hunt's Blog
T
Tenable Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Recorded Future
Recorded Future
F
Fortinet All Blogs
D
DataBreaches.Net
B
Blog
T
Threat Research - Cisco Blogs
MyScale Blog
MyScale Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
The GitHub Blog
The GitHub Blog
Security Latest
Security Latest
M
MIT News - Artificial intelligence

博客园_首页

Plist 二进制格式 Milvus 和 PGVector,哪个更好? OpenClaw 已过时?在 VS Code 中运行 Hermes Agent! 第30篇文章:一个大三计科生的自白 Manim如何在数学公式中完美显示中文? Docker 部署 RocketMQ 5 并发编程核心概念辨析 C#事务处理最佳实践:别再让“主表存了、明细丢了”的破事发生 CLI 是什么?为什么大厂突然集体卷命令行? 【从0到1构建一个ClaudeAgent】协作-自主Agent UIImageView 设置图片不生效的原因排查 最小二乘问题详解20:无先验约束下的增量式SFM自由网平差 痞子衡嵌入式:大话双核i.MXRT1180之XIP应用里借助MU实现可靠Flash IAP的方法 AI Chat 封装, SemanticKerne.AiProvider.Unified 已发布 Windows下右键编辑js文件无法打开记事本——在注册表中使用环境变量 在后台服务中使用 Scoped 服务,为什么总是报错? H200 安装驱动并使用sglang启动模型 wireshark 抓包Trap上报告警内容 我用 AI 辅助开发了一系列小工具(2):图片压缩工具 [A Primer On MC and CC] 2.1 Memory Consistency 1 - 指令重排序和 SC 模型 Oracle数据库SCN推进技术详解与实践指南 玩转控件:封装个带图片的Label控件 Claude Code 4.7 真正该升级的不是模型,而是你的工作流 前端小白一句话,AI 帮我做了个颜值拉满的桌面媒体播放器。当代码不再是门槛,一句话编程就是现实。 5. WorkBuddy: 小龙虾的灵魂三件套,让你的小龙虾不只是工具 SQLite 分片方案实战:三种分片策略的深度对比 告别简陋 UI!一款基于 Fluent Design 和基于 WinUI 的开源免费、现代化的 Avalonia UI 控件库 关于二进制排列组合枚举的总结 AI开发-python-LangGraph框架(3-27-LangGraph从零实现大模型智能决策工作流) ElasticSearch主分片和副本分片概念详解 【002】HTTPS 粗解:证书、TLS 握手与对后端配置的影响 Hermes Agent 一周暴涨五万 Star,但我劝你别急着追 明明连接的是Redis的DB0,为什么能查到DB3的数据? 【从0到1构建一个ClaudeAgent】协作-Agent团队 熟悉电子元器件之后,电子小白下一步该怎么走? MAF快速入门(23)通过C#类定义Skills .NET 高级开发 | 手写一个对象映射框架 FastAPI数据库ORM怎么选?我肝了三个Demo后,终于不再纠结了 mysqldump 参数拾遗:在遗忘与铭记之间 C# .NET 周刊|2026年3月5期 Claude code入门 - 陈彦斌 一文学习入门 ThingsBoard 开源物联网平台 GitHub 热门项目 | 2026年04月16日 如何为GIT设置全局勾子,为每次提交追加信息 Number.isFinite和isFinite与isNaN()和Number.isNaN的区别 PortSwigger SQL注入LAB2 推荐一个测试人必备的Skills,从功能到性能全搞定(附详细实操和安装下载方式) 筑基期:掌握Odoo基础核心知识点02(Odoo XML 开发方式详解) GLM模型这么火,咱们用vllm也咧一个呗! 深入理解 AbortController:从底层原理到跨语言设计哲学 字符串学习笔记 多租户系统框架的基础模块设计和分析设计 Apache SeaTunnel Zeta 为什么能做到“又快又稳”? AI开发-python-LangGraph框架(3-26-LangGraph基本概念及第一个简单样例) Vue 3 组件通信,别只会用 Props 和 Emits 了,这几个狠活儿你得看看 ElasticSearch7.X版本配置密码 用Manim实现动态交点计算--从一个动点问题说起 团结引擎+Addressable+Instant Game打包抖音小游戏 function call 实战:让 LLM 自动判断 pod 异常、调用日志工具并完成故障分析 bubseek —— 让 Agent 的足迹,变成团队的洞察 通过 C# 读取并导出 PDF 书签 如何用 GitHub Actions 实现 Steam 自动化发布 【从0到1构建一个ClaudeAgent】并发-后台任务 .NET 高级开发 | 定制 ASP.NET Core 框架 电子小白:什么是运算放大器(运放) zero2Agent:面向大厂面试的 Agent 工程教程,从概念到生产的完整学习路线 堆上的ORW HC32F460 USB CDC通信异常:非对齐访问异常排查 20260413-Hyperbridge 攻击事件:发生在默克尔山上的验证绕过 那些喊着AI 要淘汰你的人,正在靠你的焦虑赚大钱! 深度学习进阶(八)Swin Transformer 最小二乘问题详解19:带先验约束的增量式SFM优化与实现 SnapTranslate 3.0 正式发布:全局划词翻译 + 完整英语学习闭环,一站式搞定查词、记词、复习 工作的意义、工作的困难认知再思考 .NET + AI 进阶实战:基于类的技能开发 - 打造可治理的 Agent 能力模块 【从0到1构建一个ClaudeAgent】规划与协调-技能 上周热点回顾(4.6-4.12) 电子小白的工具三件套:面包板、杜邦线、万能板 单表五亿数据的查询优化 | Mysql、StarRocks 2. WorkBuddy:从“我是谁”到“帮我干活” C# 如何减少代码运行时间:7 个实战技巧 基于HelixToolkit.SharpDX 渲染3D模型 - 笺上知微 从零开始的双臂具身VLA起源及现阶段发展综述 - SkyXZ 记对 xonsh shell 的使用, 脚本编写, 迁移及调优 - pluvium27 受够了Vibe Coding的失控?换个起点,让AI事半功倍 从开始配置漏洞环境到漏洞复现流程 - 難しい 关于10年工作经验的程序员对OpenClaw的实战经验分享以及看法 - 虚无境 Any metadata 的内存布局 C# .NET 周刊|2026年3月2期 - InCerry 我帮你测过了,测试圈排名第二的 Skill 依然很牛逼 Skill Discovery | 无监督技能发现的经典工作总结 - MoonOut 上下文工程是什么?过时了么?一文讲明白! - 一枫说码 开了 TUN 模式还是直连?90% 的人都踩过这个坑 AScript扩展多种脚本语言 - rockey627 AI 学习笔记:Agent 的记忆机制 你能被装进一个文件里吗?——7 万人把同事"蒸馏"成了 AI - 我没有三颗心脏 Claude Code 通关手册(七):给 AI 装上技能包——Skills 完全指南 - 暮色之狐 在浏览器中快速编辑代码:VSCode Web 集成实践 - Newbe36524 蒸馏自己 skill?基于 Deepseek 的蒸馏器,丐版蒸馏方式,简单便捷 - To_Carpe_Diem Spring AI Aliababa和AgentScope,哪个更好? - 苏三说技术
CogVideo与CogVideoX笔记
永是珞珈一恐龙 · 2026-04-20 · via 博客园_首页

CogVideo与CogVideoX模型结构

VQ-VAE(CogVideo使用的编码器)

VQ-VAE其实就是一个AE(自编码器)而不是VAE(变分自编码器)

PixelCNN

要追溯VQ-VAE的思想,就不得不谈到自回归模型。可以说,VQ-VAE做生成模型的思路,源于PixelRNN、PixelCNN之类的自回归模型,这类模型留意到我们要生成的图像,实际上是离散的而不是连续的。以cifar10的图像为例,它是32×32大小的3通道图像,换言之它是一个32×32×3的矩阵,矩阵的每个元素是0~255的任意一个整数,这样一来,我们可以将它看成是一个长度为32×32×3=3072的句子,而词表的大小是256,从而用语言模型的方法,来逐像素地、递归地生成一张图片(传入前面的所有像素,来预测下一个像素),这就是所谓的自回归方法:

\[p(x)=p(x_1)p(x_2|x_1)\dots p(x_{3n^2}|x_1,x_2,\dots,x_{3n^2-1}) \]

其中\(p(x_1),p(x_2|x_1),\dots,p(x_{3n^2}|x_1,x_2,\dots,x_{3n^2-1})\)每一个都是256分类问题,只不过所依赖的条件有所不同。

VQ-VAE

针对自回归模型的固有毛病,VQ-VAE提出的解决方案是:先降维,然后再对编码向量用PixelCNN建模。

降维离散化

因为PixelCNN生成的离散序列,你想用PixelCNN建模编码向量,那就意味着编码向量也是离散的才行。而我们常见的降维手段,比如自编码器,生成的编码向量都是连续性变量,无法直接生成离散变量。同时,生成离散型变量往往还意味着存在梯度消失的问题。

最邻近重构

在VQ-VAE中,一张n×n×3的图片x先被传入一个encoder中,得到连续的编码向量z:

\[z=encoder(x) \]

这里的z是一个大小为d的向量。另外,VQ-VAE还维护一个Embedding层,我们也可以称为编码表,记为

\[E=[e_1,e_2,\dots,e_K] \]

这里每个\(e_i\)都是一个大小为d的向量。接着,VQ-VAE通过最邻近搜索,将z映射为这K个向量之一:

\[z\to e_k,\quad k=\arg\min_j\|z-e_j\|_2 \]

我们可以将z对应的编码表向量记为\(z_q\),我们认为\(z_q\)才是最后的编码结果。最后将\(z_q\)传入一个decoder,希望重构原图\(\hat{x}=decoder(z_q)\)

整个流程是:

\[x\xrightarrow{encoder}z\xrightarrow{最邻近}z_q\xrightarrow{decoder}\hat{x} \]

这样一来,因为\(z_q\)是编码表E中的向量之一,所以它实际上就等价于\(1,2,\dots,K\)这K个整数之一,因此这整个流程相当于将整张图片编码为一个整数。

当然,上述过程是比较简化的,如果只编码为一个向量,重构时难免失真,而且泛化性难以得到保证。所以实际编码时直接用多层卷积将x编码为m×m个大小为d的向量:

\[z=\begin{pmatrix} z_{11}&z_{12}&\dots&z_{1m}\\ z_{21}&z_{22}&\dots&z_{2m}\\ \vdots&\vdots&\ddots&\vdots\\ z_{m1}&z_{m2}&\dots&z_{mm} \end{pmatrix}\]

也就是说,z的总大小为m×m×d,它依然保留着位置结构,然后每个向量都用前述方法映射为编码表中的一个,就得到一个同样大小的\(z_q\),然后再用它来重构。这样一来,\(z_q\)也等价于一个m×m的整数矩阵,这就实现了离散型编码。

自行设计梯度

我们知道,如果是普通的自编码器,直接用下述loss进行训练即可:

\[\|x-decoder(z)\|_2^2 \]

但是,在VQ-VAE中,我们用来重构的是\(z_q\)而不是z,那么似乎应该用这个loss才对:

\[\|x-decoder(z_q)\|_2^2 \]

但问题是\(z_q\)的构建过程包含了argmin,这个操作是没梯度的,所以如果用第二个loss的话,我们没法更新encoder。

换言之,我们的目标其实是\(\|x-decoder(z_q)\|_2^2\)最小,但是却不好优化,而\(\|x-decoder(z)\|_2^2\)容易优化,但却不是我们的优化目标。

VQ-VAE使用了一个很精巧也很直接的方法,称为Straight-Through Estimator,你也可以称之为"直通估计"。Straight-Through的思想很简单,就是前向传播的时候可以用想要的变量(哪怕不可导),而反向传播的时候,用你自己为它所设计的梯度。根据这个思想,我们设计的目标函数是:

\[\|x-decoder(z+sg[z_q-z])\|_2^2 \]

其中sg是stop gradient的意思,就是不要它的梯度。这样一来,前向传播计算(求loss)的时候,就直接等价于\(decoder(z+z_q-z)=decoder(z_q)\),然后反向传播(求梯度)的时候,由于\(z_q-z\)不提供梯度,所以它也等价于\(decoder(z)\),这个就允许我们对encoder进行优化了。

维护编码表

要注意,根据VQ-VAE的最邻近搜索的设计,我们应该期望\(z_q\)和z是很接近的(事实上编码表E的每个向量类似各个z的聚类中心出现),但事实上未必如此,即使\(\|x-decoder(z)\|_2^2\)\(\|x-decoder(z_q)\|_2^2\)都很小,也不意味着\(z_q\)和z差别很小(即\(f(z_1)=f(z_2)\)不意味着\(z_1=z_2\))。

所以,为了让\(z_q\)和z更接近,我们可以直接地将\(\|z-z_q\|_2^2\)加入到loss中:

\[\|x-decoder(z+sg[z_q-z])\|_2^2+\beta\|z-z_q\|_2^2 \]

除此之外,还可以做得更仔细一些。由于编码表(\(z_q\))相对是比较自由的,而z要尽力保证重构效果,所以我们应当尽量"让\(z_q\)去靠近z"而不是"让z去靠近\(z_q\)",而因为\(\|z_q-z\|_2^2\)的梯度等于对\(z_q\)的梯度加上对z的梯度,所以我们将它等价地分解为

\[\|sg[z]-z_q\|_2^2+\|z-sg[z_q]\|_2^2 \]

第一项相等于固定z,让\(z_q\)靠近z,第二项则反过来固定\(z_q\),让z靠近\(z_q\)。注意这个"等价"是对于反向传播(求梯度)来说的,对于前向传播(求loss)它是原来的两倍。根据我们刚才的讨论,我们希望"让\(z_q\)去靠近z"多于"让z去靠近\(z_q\)",所以可以调一下最终的loss比例:

\[\|x-decoder(z+sg[z_q-z])\|_2^2+\beta\|sg[z]-z_q\|_2^2+\gamma\|z-sg[z_q]\|_2^2 \]

其中\(\gamma<\beta\),在原论文中使用的是\(\gamma=0.25\beta\)

拟合编码分布

经过上述一大通设计之后,我们终于将图片编码为m×m的整数矩阵了,由于这个m×m的矩阵一定程度上也保留了原来输入图片的位置信息,所以我们可以用自回归模型比如PixelCNN,来对编码矩阵进行拟合(即建模先验分布)。通过PixelCNN得到编码分布后,就可以随机生成一个新的编码矩阵,然后通过编码表E映射为3维的实数矩阵\(z_q\)(行×列×编码维度),最后经过decoder得到一张图片。

CogVideo

CogVideo 是基于大规模预训练 Transformer 进行视频生成的工作,也是近期推出的 CogVideoX 的前身。相比于文生图任务,文生视频的主要难点在于两个方面:首先是数据更加稀缺,视频-文本配对数据比较少;其次是视频多了时序信息。

本模型基于文生图模型 CogView2 进行训练,在训练时使用了 5.4 M 视频-文本对数据。在训练时,文本条件是通过 in context learning,也就是将文本 token 直接拼接在图像 token 序列前方的方式实现的。除此之外还引入了多帧率层次化训练的训练策略,通过调整帧率来动态地调整视频的长度。在生成时,首先生成关键帧,然后用一个插值模型生成中间帧。

alt text

多帧率层次化训练

CogVideo 也采用了比较常见的方式,用 VQVAE 将视频序列转换为离散的 token 序列,再使用 transformer 对 token 序列进行学习。在训练时,token 序列的长度是固定的,也就是总共包含对应于 5 帧的 token 序列。不过和通常的方法不同的是,这里虽然序列的长度是固定的,但是实际上对应的视频的长度是可变的。

具体来说,CogVideo 在序列开始的时候加入了一个表示帧率的 token Frame Rate。虽然论文原文直接把这个称为 frame rate,不过这个和实际上视频的帧率感觉还是有一点区别的。这个表示的是在这个序列的 5 帧中,每两帧之间相隔的视频中帧的数量。这样,对于比较长的视频,可以设置两帧之间相隔较多帧,反之亦然。有了这个设定,无论训练视频多长都可以用固定的序列长度表示,可以实现对变长视频的处理。

这样做主要有两点好处:

首先是可以处理变长视频,防止因对视频进行截断导致与文字之间的不对齐现象;
其次是在一般的视频中,相邻帧一般比较类似,如果直接对原始数据进行学习,容易让模型学到直接 copy 上一帧的 shortcut,导致模型退化。
不过这样训练之后的模型生成的两帧之间也会比较跳跃,因此需要用一个额外的插帧模型对生成的关键帧进行插帧。

在生成阶段,首先依然是需要生成最开始的五个关键帧,在生成关键帧后,CogVideo 采用了一种递归的插帧方式。具体来说就是在现有帧的基础上,将帧率减半,然后在每两帧之间再用自回归的方式生成一帧,这样每次生成之后序列的长度就会变成原来的 2 倍。(但因为整体的 token 序列长度不变,所以每次需要拆成两半插帧两次)

除此之外,CogVideo 还使用了 CogLM 的双向注意力机制,不同于 GPT 等只有单向注意力的模型,引入双向注意力可以使生成过程关注前后文的信息。

双通道注意力

相比于图像生成模型,视频生成模型需要关注时序信息。为此,CogVideo 直接在文生图模型 CogView2 上进行改进,因为后者已经能比较好地处理文本-图像的信息,所以可以作为视频生成模型的预训练。

为了使模型能够比较好地处理时序信息,CogVideo 在原有的 attention 的基础上又加入了一个 3D attention,如下图所示。图中的 Attention-base 就是原来的 CogView2 自带的 attention,其是以图像作为单位进行处理,可以理解为每次计算 attention 都是在图像内部做,主要关注的是图像级别的生成。而 Attention-plus 则是 3D 注意力,在进行 attention 计算的时候有多帧的内容都参与计算,这样可以关注时序信息。

对于 Attention-plus 的选择,原文使用了两种选择,即 3D local attention 和 3D Swin attention。两个通道的 attention 加权求和后作为双通道注意力的整体输出。

alt text

生成阶段的滑窗注意力

正常的 3D Swin attention 是不支持自回归生成过程的,因此 CogVideo 为了让这个注意力机制能够支持自回归生成,加入了一个自回归 mask 机制。并且这样可以让不同的帧能够在一定程度上并行生成。

具体的做法如下图所示,这里展示的是窗口大小为 2 的情况。图中的 t=i、t=i+1、t=i+2 表示相邻的三帧,后边的帧可以看到的前帧的范围就只有不是灰色的部分,因为窗口有一定的大小,所以可以看到的前帧中 token 的范围比当前已经生成的更多。这样就相当于第 i 帧的深绿色部分生成完的时候,第 i+1 帧就可以生成浅绿色的部分,第 i+2 帧就可以生成红框圈住的 token,从而实现并行。

alt text

CogVideoX

和上一个工作 CogVideo 不同,这个方法是基于扩散模型实现的。从框架图来看,感觉 CogVideoX 同时吸取了 Sora 和 Stable Diffusion 3 的优势,不仅使用了 3D VAE,还引入了双路 DiT 的架构。

具体来说,CogVideoX 主要进行了以下几个方面的工作:

  1. 使用 3D VAE 编码视频,有效地压缩视频维度、保证视频的连续性;
  2. 引入双路 DiT 分别对文本和视频进行编码,并用 3D attention 进行信息交换;
  3. 开发了一个视频标注的 pipeline,用于对视频给出准确的文本标注;
  4. 提出了一种渐进式训练方法和一种均匀采样方法。

CogVideoX 的整体架构如下图所示,文本和视频分别经过文本编码器(这里是 T5)和 3D VAE 编码后输入主干网络。文本和视频分别经过一条支路,并在注意力部分进行交互。

alt text

3D Causal VAE

由于视频相比图像多了时序信息,所以需要对多出来的时间维度进行处理。先前的视频生成模型都采用 2D VAE,这样会导致生成的视频在时间上连续性比较差,并且出现闪烁的情况。

和通常的 VAE 相同,3D Causal VAE 包括一个编码器、一个解码器以及一个 KL 约束。在编码的前两个阶段,分别在时间和空间维度上进行 2 倍下采样,在最后一个阶段只在空间维度上进行下采样。因此最后的下采样倍数是 488,时间维度倍数为 4,空间为 8 倍。

为了防止未来的时序信息泄漏到当前或更早的时间中,这里采取了一种特殊的 padding 方式,也就是只在前方进行 padding,这样卷积时就不会把后续 token 的信息泄露到当前 token。并且这种卷积还可以在不同 GPU 之间进行并行,只需要在不同的 GPU 之间拷贝少量的数据(图 b 中的粉色 token)即可。

alt text

Expert Transformer

CogVideoX 采取和 SD3 类似的 MMDiT 架构,下面来依次介绍这种架构中的各组成部分。

Patchify

CogVideoX 的分块策略和 DiT 的相同,同时为了使模型能够同时在视频和图像数据上进行训练(这部分会在训练策略部分介绍),并不在时间维度上进行分块。也就是说对于一个大小为 \(T\times H\times W\times C\) 的输入,会分成长度为 \(T\times H/p\times W/p\) 的序列。

3D 旋转位置编码

视频经过 patchify 后,每个位置可以用一个三维坐标 \((x,y,t)\) 来表示,CogVideoX 的做法是对每一个坐标分别进行旋转位置编码,再沿通道直接拼接到一起。其中,表示空间位置的坐标分别占 \(3/8\),表示时间的坐标占 \(2/8\)

专家自适应层归一化

我们在输入阶段将文本和视频的嵌入向量进行拼接,以更好地对齐视觉信息和语义信息。然而,这两种模态的特征空间差异显著,其嵌入向量甚至可能具有不同的数值尺度。为了在同一序列中更好地处理它们,我们采用专家自适应层归一化对每种模态进行独立处理。如图3所示,参考DiT的方法,我们将扩散过程的时间步长t作为调制模块的输入。随后,视觉专家自适应层归一化和文本专家自适应层归一化分别将该调制作用于视觉隐藏状态和文本隐藏状态。该策略在最小化额外参数的同时,促进了两种模态间特征空间的对齐。

3D Full Attention

先前的方法为了降低计算量而在时序和空间上分别计算 attention,这样会导致当视频的变化比较快速的时候出现前后不一致的情况。因此这里使用了 Full Attention,应该是对整体的所有 token 计算 attention,而不是时间和空间分开。

CogVideoX 的训练

Frame Pack

CogVideoX 采用了图像与视频混合训练的方式,在进行训练时,将图像视为长度只有一帧的视频。并且 CogVideoX 并没有采用和其他方法相同的定长视频训练,而是采用了一种打包训练的方法,通过把不同长度的视频都打包在一个 batch 中,来确保不同 batch 维度相同。

打包训练示意图

Resolution Progressive Training

CogVideoX 也采取了多分辨率训练的策略,一方面是为了充分利用从互联网得到的带有多种分辨率的数据,另一方面是为了使模型能够渐进式地学习从粗糙到精细的多种信息。

外推位置编码 VS 插值位置编码

由于模型最开始的训练阶段是在低分辨率数据上训练的,所以在高分辨数据上训练时,需要将位置编码拓展到高分辨率上。在拓展时,有两种策略,其一是将位置编码进行外推,这样可以比较好地维持不同像素之间的相对位置关系;其二是将位置编码进行插值,这样可以更好地维持像素在整个图像上的全局位置。经过测试可以发现前者可以更好地生成细节,而后者生成的结果比较模糊。最终 CogVideoX 使用的是前者。

在最后一个训练阶段,使用了高质量数据进行微调。主要包括移除了字幕以及水印的数据,这部分数据占全部数据的比例大概为 20%。

Explicit Uniform Sampling

在扩散模型进行训练时,会对时间步进行均匀采样。然而不同时间步对应的损失的尺度可能不一致,因此虽然对时间步的采样是均匀的,但最后得到的损失却不够均匀。为此,CogVideoX 使用了一种显式均匀采样的方法,具体来说,在并行训练时会为每个 rank 分配一个时间步的区间,然后每个 rank 都只在这个区间里进行均匀采样,这样能够得到比较均匀的 loss,有助于模型更好地收敛。

CogVideoX 条件注入

alt text

图像预处理

操作 形状 目的
PIL 读取 (H, W, 3) 加载原始图像
ToTensor + unsqueeze(0) (1, 3, H, W) 转为 batch 张量
resize + center crop (1, 3, 480, 720) 对齐模型训练分辨率
* 2 - 1 归一化 (1, 3, 480, 720) 像素值映射到 VAE 期望的 [-1, 1] 范围
unsqueeze(2) 插入时间维 (1, 3, 1, 480, 720) 构造单帧"视频",适配 3D VAE 接口
VAE encode 空间下采样 8× (1, 16, 1, 60, 90) 压缩到 latent 空间,降低后续计算量
permute(0,2,1,3,4) (1, 1, 16, 60, 90) 调整为 (B,T,C,H,W),统一视频张量格式
concat 零填充后续 12 帧 (1, 13, 16, 60, 90)c["concat"] 第 0 帧携带图像信息,后续帧置零表示"待生成",给模型明确的已知/未知信号

Channel Concat(OpenAIWrapper)

张量 形状 目的
噪声 latent x (1, 13, 16, 60, 90) 去噪目标,携带当前扩散步的噪声信息
图像条件 c["concat"] (1, 13, 16, 60, 90) 参考图像的 latent,逐位置对齐噪声 latent
cat(dim=2) (1, 13, 32, 60, 90) 拼接后每个空间位置同时可见噪声与图像

DiffusionTransformer

操作 形状 目的
输入 x (1, 13, 32, 60, 90) 拼接后的 noise+image latent
timestep_embedding (1, 3072) 将标量时间步编码为高维向量
time_embed MLP (1, 512)emb 压缩到 time_embed_dim,用于后续 adaLN 调制
T5 文本特征 context (1, 226, 4096) 文本条件,将与 video token 拼接做全序列 attention
Patch Embedding(Conv2d 32→3072, k=2, s=2)
操作 形状 目的
view 展平时间 (13, 32, 60, 90) 批量处理所有帧
Conv2d (13, 3072, 30, 45) 空间再下采样 2×,同时映射到 hidden_size,完成 patch embedding
view 恢复时间 (1, 13, 3072, 30, 45) 恢复 batch 维度
flatten(3) (1, 13, 3072, 1350) 展平空间维度为 patch 序列
transpose(2,3) (1, 13, 1350, 3072) 调整为 (B,T,N,D) 格式
rearrange b t n d → b (t n) d (1, 17550, 3072) 展平时空为单一序列,13×1350=17550 个 video token
text_proj T5 4096→3072 (1, 226, 3072) 将 T5 文本特征投影到与 video 相同的 hidden_size
cat([text, video], dim=1) (1, 17776, 3072) 拼接文本与视频 token,后续做全序列 self-attention
3D RoPE(仅 video tokens)
操作 形状 目的
频率张量 (T,H,W,head_dim) (13, 30, 45, 64) 构建时间+高度+宽度三轴的旋转频率
rearrange → (T*H*W, head_dim) (17550, 64) 展平为与 video token 序列对齐的位置编码
应用到 q/k[:, :, 226:] (1, 48, 17550, 64) 只对 video token ([226:]) 施加位置感知,text token 不加,保持文本位置无关性
AdaLN Layer × 42
操作 形状 目的
emb → adaLN Linear(512→12×3072) 12 × (1, 3072) 生成 12 组调制参数(text/video × attn/mlp × shift/scale/gate),让时间步信息调制每层特征
分离 text / video (1,226,3072) / (1,17550,3072) 分别施加不同的 adaLN 参数
cat → full self-attention (1, 17776, 3072) text 与 video token 互相 attend,实现文本引导视频生成
分离 + 残差 + gate (1,226,3072) / (1,17550,3072) gate 控制每层更新幅度,稳定深层训练
cat 合并 (1, 17776, 3072) 输出到下一层
Final Layer
操作 形状 目的
丢弃 text tokens (1, 17550, 3072) 只需预测视频 latent,文本 token 不参与输出
Linear(3072 → 64) (1, 17550, 64) 将每个 token 映射到 patch_size²×out_channels = 2²×16 = 64
unpatchify b(thw)(cpq)→btc(hp)(wq) (1, 13, 16, 60, 90) 将 patch 序列还原为时空 latent,即模型预测的噪声/速度场

去噪 → VAE 解码

操作 形状 目的
DDPM/DDIM N 步去噪后 latent (1, 13, 16, 60, 90) 迭代去噪得到干净的 latent
/ scale_factor (1, 13, 16, 60, 90) 还原 VAE 编码时的缩放(scale_factor=0.7)
permute(0,2,1,3,4) (1, 16, 13, 60, 90) 调整为 VAE 期望的 (B,C,T,H,W) 格式
VAE decode 空间上采样 8×,时间还原 (1, 3, 49, 480, 720) 3D VAE 解码,空间恢复到原分辨率,时间从 13 帧插值到 49 帧
clamp + 转 uint8 生成视频 49 帧 像素值裁剪到 [0,1] 并量化为 8bit,输出最终视频