想象你是一个从没拍过电影的孩子,手里只有一桶乐高积木。要把脑海里“小方块在屏幕上跳动”的故事变成视频,最高明的做法是:先把每一帧画面翻译成一格一格的乐高积木(视觉 Token),再请一位看过成千上万部“积木说明书”的建筑师(Transformer),让它一块一块地决定下一块积木该放在哪里——每放一块,都要参考前面已经放好的所有积木。等 8 帧全部搭完,再由一位“还原师”把积木图纸变回流畅的画面。这个“先翻译成积木 → 逐块预测 → 还原成画面”的流程,就是自回归视频生成 VideoGPT 的核心思想。本文会沿着这条积木流水线,从视觉分词器、VideoGPT 架构、采样推理一路讲到 Phenaki 增强、评估体系和工程实践,顺带看看 Sora、可灵、Pika 这些影视巨头是怎么“拍电影”的。

岗位关联

理解自回归视频生成,等于掌握了视频 AI 领域“Token 化 + 自回归”这条主干道的底层原理,无论是复现 Sora 还是调优可灵 Pika 类产品,你都能快速定位问题、优化效果。

目录
  1. 可视化演示
  2. 视频生成总览:两条拍“乐高电影”的路线
  3. 视觉分词器:把画面变成乐高积木的“翻译工厂”
  4. VideoGPT架构:看过万部电影的积木建筑师
  5. 采样推理:建筑师落子的“创意温度”
  6. Phenaki增强:读了剧本的导演型建筑师
  7. 评估体系:如何给积木电影打分
  8. 工程实践:积木电影工厂的流水线
  9. 行业前沿:Sora 冲击下的自回归之路
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

交互展示VideoGPT的视频token化、自回归帧预测和时间注意力机制三个核心过程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

VQ-VAE:视频Token化 视频帧经编码器映射到离散码本 每个patch对应一个token ID z_q = argmin ||e - z_e||² VQ-VAE将连续视频压缩为离散token序列

视频生成总览:两条拍“乐高电影”的路线

同样是拍乐高电影,主流导演分两派。一派用“模铸法”——像把融化的塑料倒进整面墙的大模具,一次成型整段画面,这就是扩散模型,Sora、可灵、Pika 是它最出名的代表作。另一派用“逐块搭建法”——从第一块积木开始,一块一块往上垒,每一块的位置都由前面的积木决定,这就是自回归生成,VideoGPT 和 Phenaki 是这套流派的代表。

把两条路线放进技术语境:扩散模型从纯噪声出发,通过多步去噪逐步逼近目标视频,擅长生成高质量、语义连贯的长镜头;自回归模型则把视频看作一串离散符号(Token),用“预测下一个符号”的方式逐 Token 生成。前者像雕塑家从石块中凿出作品,后者像作家逐字逐句写出小说。

在视频生成领域,扩散派的画面细腻度目前更胜一筹,所以 Sora 能生成惊艳的长视频;但自回归派有一个独特优势——视频被 Token 化后可以直接复用 NLP 领域成熟的 Transformer 技术栈,而且天然适合做“文本到视频”的条件生成。理解两派差异,是进入视频 AI 的第一步。

理解了这条路线图,你就知道为什么自回归视频生成被称作“搭积木的电影”:它不像扩散那样一次浇铸整面墙,而是相信“每一块都放对,整部电影自然就对了”。Sora 们的出现没有让这条路消失——恰恰相反,VideoGPT 的简洁让它在统一视觉与语言模型的时代重新发光。

p(x1,x2,…,xT)=∏t=1Tp(xt∣x1,x2,…,xt−1)p(x_1, x_2, \dots, x_T) = \prod_{t=1}^{T} p(x_t \mid x_1, x_2, \dots, x_{t-1})
这个公式用最简洁的语言说清了“自回归”:整段视频出现的概率,等于“第一帧的概率 × 在看到第一帧后第二帧的概率 × 在看到前两帧后第三帧的概率……”一直乘到最后。放积木时,整面墙成功的概率就是每一块积木放对概率的乘积。
  1. 连乘符号 ∏把 T 个条件概率依次相乘。建筑师搭整面墙时,“整部电影的成立”依赖于每一块积木都放对位置。
    ∏t=1T(⋯ )\prod_{t=1}^{T} (\cdots)
  2. 条件概率 p(x_t | x_{<t})生成第 t 帧时,模型只能“看见”前面 t-1 帧,不能偷看未来。这正是乐高建筑师只看已搭好的部分、再决定下一块的写照。
    p(xt∣x1,…,xt−1)p(x_t \mid x_1, \dots, x_{t-1})

视觉分词器:把画面变成乐高积木的“翻译工厂”

要让建筑师搭积木,前提是画面能变成标准积木。VQVAE 就是这座翻译工厂:它把任意一张电影胶片送进“分拣传送带”(编码器),切成小块、压缩成特征,再从仓库里挑出最相似的标准积木(码本查找),最后“还原师”(解码器)把积木拼回画面。升级版 VQGAN 还加入了对抗与感知损失,让拼回的画面更逼真。

技术上说,VQVAE 包含三个部件:编码器 E 把图像映射为连续特征;可学习的码本 e(M 个离散向量)充当“标准积木仓库”;解码器 D 把量化后的特征还原为图像。查询规则只有一条——欧氏距离最近邻,谁的积木和特征最像就用谁。这个“查表”把连续图像变成了离散 Token,也就是视频的“字母表”。

VQVAE 的训练同时优化三项目标,缺一不可。它们共同保证:翻译工厂既能把画面还原得足够像,又不会让某块积木永远闲置,也不会让特征在积木之间摇摆不定。

翻译工厂稳定运转后,任何视频都能被编成一串积木编号。VideoGPT 拿到的就不再是复杂的像素海洋,而是一串简简单单的“积木编号序列”——故事,从这里开始。

L=∥x−D(zq)∥2+∥sg[E(x)]−e∥2+β∥E(x)−sg[e]∥2\mathcal{L} = \|\boldsymbol{x} - D(\boldsymbol{z}_q)\|^2 + \|\mathrm{sg}[E(\boldsymbol{x})] - \boldsymbol{e}\|^2 + \beta \|E(\boldsymbol{x}) - \mathrm{sg}[\boldsymbol{e}]\|^2
第一项是“还原度奖金”:拼回去的画面越像原图越好;第二项是“积木校准令”:仓库里的标准积木要向特征靠拢;第三项是“承诺约束”:特征必须忠于所选积木,不能三心二意。sg 表示停止梯度,防止三项互相拉扯。
  1. 重建损失解码器把积木拼回成画面,和原始画面逐像素算误差。误差小说明这盒积木足以表达视频内容。
    ∥x−D(zq)∥2\|\boldsymbol{x} - D(\boldsymbol{z}_q)\|^2
  2. 码本损失让最近的“标准积木”e 向编码器输出移动。相当于工厂根据实际需求,重新打磨仓库里积木的形状。
    ∥sg[E(x)]−e∥2\|\mathrm{sg}[E(\boldsymbol{x})] - \boldsymbol{e}\|^2
  3. 承诺损失让编码器输出向所选积木靠拢,克制“随便乱报一个码”的懒惰行为,保证每个码字被稳定使用。
    β∥E(x)−sg[e]∥2\beta \|E(\boldsymbol{x}) - \mathrm{sg}[\boldsymbol{e}]\|^2

VideoGPT架构:看过万部电影的积木建筑师

现在积木备好了,轮到建筑师登场。VideoGPT 的“建筑师”是一个 GPT 风格的 Transformer——它看过成千上万部由积木构成的“电影说明书”:每部说明书都是一长串积木编号。建筑师要学的只有一个任务:给定前面所有编号,猜下一个编号是什么。

具体地,把视频的时空 Token 按顺序展平:先是第 1 帧从左上角到右下角的积木编号,再是第 2 帧、第 3 帧……全部连成一串。这串编号喂给 Transformer,模型在每个位置输出一个“下一块积木”的概率分布,训练目标就是最大化所有“猜对”的概率之和。

与图像 GPT 不同,VideoGPT 的序列里同时包含“空间”与“时间”两种依赖:相邻位置的积木关系表征画面内容,相隔一帧的位置关系表征运动。因此它的位置编码按空间-时间分开设计,让模型清楚知道“这块积木在第几帧的哪个位置”。同时为了控制计算量,VideoGPT 还借鉴了稀疏注意力,只让每个 Token 关注附近的时空邻居。

训练完成后,这位建筑师已经“内化”了积木搭接的统计规律:什么颜色的积木该挨着什么颜色、什么样的运动线条最自然。接下来,轮到它真正开工——从空无一物的地基上,一块一块地搭建一部新电影。

L(θ)=−∑t=1Nlog⁡pθ(zt∣z1,…,zt−1)\mathcal{L}(\theta) = - \sum_{t=1}^{N} \log p_\theta (z_t \mid z_1, \dots, z_{t-1})
这是下一个 Token 预测的负对数似然损失:建筑师每猜错一次就记一笔“错误账”,猜得越准账越小。整个训练过程就是让账目总额不断下降,直到模型成为“积木搭接规律”的大师。
  1. 取负对数概率连乘容易数值下溢,取对数把连乘变连加,再加负号把“最大化概率”变成“最小化损失”,方便梯度下降优化。
    −∑t=1Nlog⁡pθ(⋯ )-\sum_{t=1}^{N} \log p_\theta (\cdots)
  2. 条件生成概率模型在第 t 步只依赖前 t-1 个 Token,通过 Transformer 的掩码注意力实现——未来的积木编号对当前预测严格保密,和电影按时间顺序拍摄同理。
    pθ(zt∣z<t)p_\theta (z_t \mid z_{<t})

采样推理:建筑师落子的“创意温度”

开工时,建筑师面对的不是唯一答案,而是一张“候选积木概率表”。每一块都带着一个得分,得分高的更可能被选中。如果永远选得分最高者,作品会千篇一律;如果乱抓一气,画面会像地震后的积木堆。采样策略就是“创意与稳妥”之间的旋钮。

最常用的旋钮叫温度 τ。把每个候选的得分除以 τ 后再归一化成概率:τ 小,分数差距被放大,高分区更容易被选,生成稳定保守;τ 大,分数差距被压平,冷门积木也有出头机会,生成多样跳跃。实际训练好的模型中,τ 取 0.6~1.0 附近效果最好。

另一个常用旋钮是 Top-k:只保留得分前 k 名的积木参与选择,其余全部排除。Top-k 能避免长尾中概率极低的奇怪积木偶尔被抽中,让画面更干净。两者经常配合使用:先用 Top-k 砍掉尾部候选,再用温度调节头部候选的形态。

这就像建筑师落子前的心理活动:温度低是“严格遵守说明书”,温度高是“大胆尝试新拼法”。配合 Top-k 这个“候选名单”,建筑师既能保质保量完工,又不失灵感——视频生成的质量与多样性,往往就藏在这两个旋钮的微妙平衡里。

pi=exp⁡(logiti/τ)∑j=1Mexp⁡(logitj/τ)p_i = \frac{\exp(\mathrm{logit}_i / \tau)}{\sum_{j=1}^{M} \exp(\mathrm{logit}_j / \tau)}
这就是带温度的 softmax:把模型输出的原始分数(logits)先除以温度,再做归一化,得到每个候选积木被选中的概率。τ=1 时就是原始分布,τ 越小分布越“尖”,τ 越大分布越“平”。
  1. 分数缩放 /ττ<1 时分数被放大,最大分与次大分的差距拉开,最终概率更集中于高分项;τ>1 时分数差被压平,大家机会趋同。
    logiti/τ\mathrm{logit}_i / \tau
  2. 指数归一化取指数保证概率非负,除以总和保证 M 块积木的概率之和为 1,构成一个合法的概率分布。
    exp⁡(⋅)∑j=1Mexp⁡(⋅)\frac{\exp(\cdot)}{\sum_{j=1}^{M} \exp(\cdot)}

Phenaki增强:读了剧本的导演型建筑师

VideoGPT 的建筑师只会“自由发挥”,但很多时候客户想要的是“按剧本演出”:给我一段提示词“一只猫在阳光下伸懒腰”,你就生成对应的视频。Phenaki 就是给建筑师配了一位读得懂剧本的导演——它把文本提示也当作输入,让生成的每一块积木都服从剧情。

技术上,Phenaki 使用 Transformer 同时建模文本与视频 Token。文本经编码器变成条件向量 c,视频序列则采用因果注意力——生成每一帧 Token 时只能看已经生成的帧和文本条件,即 p(z_t | z_{<t}, c)。为了让视频“持续更久”,Phenaki 还提出时序压缩:把相邻几帧的特征先合并再 Token 化,显著压缩 Token 数量,使同样长度的序列能表达更长的视频。

与 VideoGPT 相比,Phenaki 的 Token 是按“块”组织的:一个 Token 可能同时覆盖数帧的局部区域,这让长视频从“不可能训练”变成了现实。Phenaki 用实验证明,只需一段文字,就能搭出一部数秒到数十秒、结构完整的“积木电影”。

有了导演和剧本,乐高流水线真正成为“文生视频”的生产线——你说“阳光沙滩”,它就搭出阳光沙滩。Phenaki 证明了自回归不只是生成玩具视频,而是能与文本理解深度融合、生成结构完整长视频的成熟路线。

p(z∣c)=∏t=1Npθ(zt∣z1,…,zt−1,c)p(\boldsymbol{z} \mid \boldsymbol{c}) = \prod_{t=1}^{N} p_\theta (z_t \mid z_1, \dots, z_{t-1}, \boldsymbol{c})
这是条件自回归公式:与 VideoGPT 唯一的区别是多了一个条件项 c。文本像导演的剧本,时刻约束着建筑师下一步落子——生成的内容必须“演得像是剧本里发生的事”。
  1. 条件向量 c由文本编码器(如 T5/CLIP)把提示词映射成稠密向量,作为每个时间步的额外输入。相当于导演把剧本浓缩成一句叮嘱,贴在建筑师的工位上。
    c\boldsymbol{c}
  2. 因果注意力生成第 t 步时只允许看当前位置之前的内容(含条件 c),确保不“剧透”未来——与电影拍摄“按时间顺序一条条拍”同理。
    zt∣z<t,cz_t \mid z_{<t}, \boldsymbol{c}

评估体系:如何给积木电影打分

电影拍完,总得有人打分。可“好不好看”是主观的,机器该怎么评?业内发明了三把尺子:一把量“像不像真实世界拍的”(FVD),一把量“有没有忠于剧本”(CLIPSIM),最后一把最朴素——请真人来看(人工评估)。三把尺子各有所长,也各有盲区。

FVD(Fréchet Video Distance)是视频生成最常用的客观指标。它先请一位“电影鉴赏家”——在真实视频上预训练好的动作识别网络 I3D——把真实视频和生成视频分别提成特征,再假设两组特征各自服从高斯分布,计算两个分布之间的 Fréchet 距离。距离越小,说明生成视频的“统计气质”越接近真实视频。

CLIPSIM 则用 CLIP 模型分别编码视频帧与提示词,计算两者的余弦相似度,衡量“视频内容与文本描述是否一致”。由于 CLIP 不擅长捕捉时间动态,CLIPSIM 通常对多帧取平均。配合人工评估(MOS,对观感、连贯性、语义一致性打分),才构成完整的评价体系。

三把尺子各有盲区:FVD 分低不代表画面清晰,CLIPSIM 高不代表动作连贯。真正的“评委团”必须是客观指标加人工评估的组合——就像乐高评委既量积木坡度,也会亲手摇一摇看会不会散架:多维度才算数。

FVD=∥μr−μg∥2+Tr(Σr+Σg−2(ΣrΣg)12)\mathrm{FVD} = \| \boldsymbol{\mu}_r - \boldsymbol{\mu}_g \|^2 + \mathrm{Tr}\left( \boldsymbol{\Sigma}_r + \boldsymbol{\Sigma}_g - 2(\boldsymbol{\Sigma}_r \boldsymbol{\Sigma}_g)^{\frac{1}{2}} \right)
Fréchet 距离像“两堆积木山的整体轮廓差”:第一项比两堆山的“重心”差多远,第二项比两堆山的“形状胖瘦”差多大。数值越小,代表真实视频与生成视频在特征空间里越像同一批货。
  1. 均值差项μ_r 与 μ_g 分别是真实/生成视频特征的均值向量,其欧氏距离刻画“整体偏向”的差异。重心偏移越大,分布越不像。
    ∥μr−μg∥2\|\boldsymbol{\mu}_r - \boldsymbol{\mu}_g\|^2
  2. 协方差迹项Σ 描述特征的散布形态,迹运算综合两个协方差的差异。这一项刻画“形状”是否一致——即使重心相同,一个胖一个瘦也算不像。
    Tr(Σr+Σg−2(ΣrΣg)12)\mathrm{Tr}\left( \boldsymbol{\Sigma}_r + \boldsymbol{\Sigma}_g - 2(\boldsymbol{\Sigma}_r \boldsymbol{\Sigma}_g)^{\frac{1}{2}} \right)

工程实践:积木电影工厂的流水线

原理懂了,真要造一座“自动积木电影工厂”,还得解决一堆工程问题。第一步是原料准备:原始视频要先抽帧、缩放、裁剪、归一化,再切成训练用的“等长积木串”;第二步是建厂选型:PyTorch 加 HuggingFace 生态是当前最主流的工具链,DeepSpeed 负责大规模训练。

训练中最扎心的瓶颈永远是显存。自回归模型的序列长度等于 Token 数量,而 Token 数量随分辨率与帧数急剧膨胀。常用三板斧:混合精度训练(fp16 减半显存)、梯度检查点(用重计算中间激活换显存)、以及把序列截断成小段分批训练。推理阶段则常用 KV 缓存加速——每放一块积木,不必重新计算前面所有积木的注意力键值。

如何估算一座工厂要多少“砖”?公式很简单:总 Token 数 = 帧数 × 每帧 Token 数,而这个公式直接决定序列长度、显存占用和训练时间,是开工前必算的“砖量清单”。块边长 p 就是一个关键旋钮:p 越大 Token 越少、越省资源,但画面细节也越粗。

工厂运转起来后,“砖量清单”每算一次,就能预估一台 GPU 能放多大的电影。乐高工厂不是越大越好,而是在砖块粗细、序列长度、画质之间找到平衡点——这也是视频自回归工程师每天在做的最实在的决策。

Ntokens=T×Hp×WpN_{\mathrm{tokens}} = T \times \frac{H}{p} \times \frac{W}{p}
总 Token 数等于帧数乘以每帧能切出的小块数。块边长 p 越大,Token 越少,训练越省资源,但画面细节也会越粗——这就是“砖块大小”的工程权衡。
  1. 每帧 Token 数高 H 和宽 W 各除以块边长 p,得到每帧在横竖方向的块数,两者相乘即每帧 Token 量。H/p 与 W/p 都必须整除,否则要补边或裁剪。
    Hp×Wp\frac{H}{p} \times \frac{W}{p}
  2. 总序列长度乘上帧数 T,得到完整视频 Token 序列长度。它是 Transformer 自注意力的输入维度,直接决定显存与算力需求;Phenaki 的时序压缩正是从 T 下手做减法。
    T×(⋯ )T \times (\cdots)

行业前沿:Sora 冲击下的自回归之路

当 OpenAI 在 2024 年初放出 Sora 生成的 60 秒连贯视频时,整个视频 AI 界为之震动。Sora 是扩散路线的集大成者:把视频切成 3D Patch,用 Transformer 做扩散去噪,实现了长镜头、多机位、物理合理的惊人效果。可灵、Pika 等商业产品也以扩散路线为核心,迅速落地到影视、广告行业。

自回归路线没有因此沉寂。一方面,Phenaki、NUWA、VideoGPT 不断证明“Token 化 + 自回归”能在文本到视频、长视频上取得竞争力;另一方面,把视频 Token 与文本 Token 放进同一个 Transformer,正是“视觉-语言统一模型”梦寐以求的架构——你已经有 LLM 了,只需把视频“翻译”成同一种语言。MagViT、Open-MAGVIT2 等新一代分词器让重建质量逼近扩散路线。

两条路线还开始互相借鉴:扩散模型借鉴自回归的因果结构做长视频;自回归模型借鉴扩散的评分蒸馏提升单帧质量。对从业者而言,与其押注某一条路线,不如理解两者的共性——一切模型都在学习“数据的统计规律”,差异只是表达与生成的方式。

站在行业前沿回望,乐高电影工业已经百花齐放:Sora 是顶级制片厂用最贵的模具一次铸出大片;可灵、Pika 是把模具搬上流水线的商业工作室;VideoGPT 与 Phenaki 则是坚持“逐块搭建”的独立导演,用最小的成本证明了一种可能——把视觉变成语言,让 AI 讲述流动的故事。对工程师而言,更好的时代才刚刚开始。

L(N,D)=CNNα+CDDβ+C0\mathcal{L}(N, D) = \frac{C_N}{N^{\alpha}} + \frac{C_D}{D^{\beta}} + C_0
这是缩放定律的简化形式:模型越大(N 增大)、数据越多(D 增大),损失按幂律下降,但最终会撞上数据本身的“不可约噪声”C₀。它解释了为什么 Sora 和 VideoGPT 都需要烧钱堆数据、堆算力。
  1. 模型规模项N 为参数量,α 为幂律指数。参数量越大,这项越小,说明“更强的建筑师”能搭出更复杂的积木结构。
    CNNα\frac{C_N}{N^{\alpha}}
  2. 数据规模项D 为训练数据量,β 为对应指数。数据越多,模型见过的“乐高说明书”越全,损失越低;C₀ 则是无论如何都无法消除的固有下限。
    CDDβ+C0\frac{C_D}{D^{\beta}} + C_0

AI 应用场景

文生视频内容创作平台

阶段:推理部署与产品化

解决的问题:传统影视广告制作需要演员、布景、拍摄、剪辑,成本高周期长。用自回归文生视频模型(如 Phenaki 路线),用户输入一句提示词即可在秒级生成短视频素材,把“拍片”变成“打字”。

具体案例:某短视频平台接入自回归文生视频 API,创作者输入“雨夜霓虹灯下的便利店”,系统返回 8 秒 720p 视频,用于信息流广告 A/B 测试,素材生产成本下降 90%。

视频数据增强与仿真

阶段:数据准备与训练

解决的问题:自动驾驶、机器人训练需要大量罕见场景视频(如极端天气、事故),真实采集昂贵且危险。用自回归视频生成模型按文本条件批量合成虚拟视频数据,低成本补齐长尾场景。

具体案例:某自动驾驶团队用 VideoGPT 类模型生成“雪天夜间行人横穿”的合成视频,扩充训练集后,模型在对应长尾场景的检测准确率提升 12 个百分点。

视觉Token化的统一多模态模型

阶段:模型架构设计

解决的问题:大语言模型只能理解文本,无法直接看视频。把视频 Token 化后与文本拼进同一个自回归序列,让 LLM 拥有“看视频”的能力,这是多模态大模型的核心技术路径之一。

具体案例:某智能客服公司把产品操作录屏通过 VQ 分词器转成 Token 序列,与文本对话记录一起训练,最终模型能根据用户描述自动检索相关操作片段并生成动态图文教程。

Python 演示

python99 行
"""迷你 VideoGPT: 纯 NumPy 实现的自回归视频生成演示"""import numpy as np  def make_data(n_videos=80, frames=8, size=16):    videos = []    for _ in range(n_videos):        v = np.zeros((frames, size, size), dtype=np.float32)        x, y = np.random.rand(2) * (size - 1)        dx, dy = np.random.choice([-1, 1], 2) * np.random.uniform(0.2, 0.8)        for t in range(frames):            v[t, int(y) % size, int(x) % size] = 1.0            x, y = x + dx, y + dy        videos.append(v)    return np.stack(videos)  def block_patches(videos, block=4):    n, t, h, w = videos.shape    q = videos.reshape(n * t, h // block, block, w // block, block)    return q.transpose(0, 1, 3, 2, 4).reshape(-1, block * block)  class MiniVQ:    """视觉分词器: 把视频帧翻译成离散 Token (码本)"""     def __init__(self, n_codes=32, block=4):        self.n_codes = n_codes        self.block = block        self.codebook = None     def fit(self, videos, iters=12):        pats = block_patches(videos, self.block)        rng = np.random.default_rng(0)        self.codebook = pats[rng.choice(len(pats), self.n_codes, replace=False)].copy()        for _ in range(iters):            assign = ((pats[:, None] - self.codebook[None]) ** 2).sum(-1).argmin(-1)            for k in range(self.n_codes):                if np.any(assign == k):                    self.codebook[k] = pats[assign == k].mean(0)        return self     def encode(self, frame):        b = self.block        h, w = frame.shape        pats = frame.reshape(h // b, b, w // b, b).transpose(0, 2, 1, 3)        pats = pats.reshape(-1, b * b)        return ((pats[:, None] - self.codebook[None]) ** 2).sum(-1).argmin(-1)     def decode(self, tokens):        b = self.block        side = int(np.sqrt(len(tokens)))        grid = np.stack([self.codebook[t].reshape(b, b) for t in tokens])        return grid.reshape(side, side, b, b).transpose(0, 2, 1, 3).reshape(side * b, side * b)  class MiniGPT:    """极简自回归模型: 统计相邻 Token 的转移频率并采样"""     def __init__(self, n_codes):        self.n_codes = n_codes        self.counts = np.ones((n_codes, n_codes))     def fit(self, seqs):        for seq in seqs:            for a, b in zip(seq[:-1], seq[1:]):                self.counts[a, b] += 1        return self     def sample_next(self, last, temp=0.6):        logits = np.log(self.counts[last]) / temp        probs = np.exp(logits - logits.max())        probs /= probs.sum()        return int(np.random.choice(self.n_codes, p=probs))     def generate(self, first, length):        out = [first]        for _ in range(length - 1):            out.append(self.sample_next(out[-1]))        return np.array(out)  def main():    videos = make_data()    train, test = videos[:60], videos[60:]    vq = MiniVQ().fit(train)    seqs = [np.concatenate([vq.encode(f) for f in v]) for v in train]    gpt = MiniGPT(vq.n_codes).fit(seqs)    first = seqs[0][0]    toks = gpt.generate(first, len(seqs[0]))    frames = [vq.decode(toks[i * 16:(i + 1) * 16]) for i in range(8)]    recon = [vq.decode(vq.encode(test[0][i])) for i in range(8)]    rec_err = float(np.mean((test[0] - np.stack(recon)) ** 2))    print("重建误差(越小越好):", round(rec_err, 6))    print("生成视频总亮度(约8表示每帧一个亮点):", int(np.stack(frames).sum()))  if __name__ == "__main__":    main()
目的:用纯 NumPy 从零实现一条最简“VideoGPT 流水线”——合成弹跳小球视频 → VQ 分词器把它翻译成 Token → 自回归模型学习转移规律 → 采样生成新视频 → 解码还原。跑完你就直观理解了“积木电影”的完整流程。
  1. v[t, int(y) % size, int(x) % size] = 1.0在空白视频的第 t 帧画一个亮点,构成最简单的运动数据集
  2. self.codebook = pats[rng.choice(len(pats), self.n_codes, replace=False)].copy()随机初始化码本,作为“标准积木仓库”的种子
  3. assign = ((pats[:, None] - self.codebook[None]) ** 2).sum(-1).argmin(-1)K-means 迭代:每个小块找最近的标准积木,即最近邻量化
  4. pats = frame.reshape(h // b, b, w // b, b).transpose(0, 2, 1, 3)把一帧切成 b×b 小块并展平,相当于“把画面翻译成积木编号”
  5. seqs = [np.concatenate([vq.encode(f) for f in v]) for v in train]把 8 帧的 Token 首尾相接,形成时空展平的视频 Token 序列
  6. self.counts[a, b] += 1统计“积木 a 后面跟着积木 b”的次数,构成自回归转移表
  7. logits = np.log(self.counts[last]) / temp温度采样:除以温度后取指数归一化,控制生成随机性
  8. frames = [vq.decode(toks[i * 16:(i + 1) * 16]) for i in range(8)]把生成的 Token 序列还原成 8 帧画面,完成“积木 → 电影”

常见误区

误区VideoGPT 就是每生成一帧完整图片,像做 PPT 一样接在上一帧后面,一帧一帧串成视频。既然是“逐帧生成”,那它和普通的帧间插值没什么区别。

正解VideoGPT 生成的是“积木(Token)”序列,不是完整图片。它先把整段视频压成分词 Token 序列,再逐个预测 Token;一个帧内往往包含几十个 Token,生成完一帧的所有 Token 才进入下一帧。Token 之间既有帧内空间关系,也有帧间时间关系,全部混在同一个序列里由掩码注意力统一建模。

为何常见:名字里有“帧”、可视化又常按帧展示,初学者很容易把“Token 序列”误当成“图片序列”,忽略了 Token 化这个关键中间层。

误区码本就像调色盘,颜色越多画出来的图越丰富,所以码本越大越好,把码本从 512 加到 65536,画质肯定蹭蹭往上涨。

正解码本过大会导致“码本坍缩”——大量码字从未被使用,模型实际只用少数几个码字,多样性反而下降;码本太小又难以表达复杂画面。工程上常配合码字重新初始化、EMA 更新等技巧来维持码本利用率,码本大小需要和 token 数量、数据复杂度一起调优。

为何常见:直觉上“选择多 = 效果更好”,忽略了离散表征训练中码本利用率与优化稳定性的约束。

误区FVD 是视频生成最权威的指标,论文里都报它。只要 FVD 分数低,生成视频就肯定既清晰又符合提示词。

正解FVD 衡量的是真实视频与生成视频在 I3D 特征空间中的分布距离,偏向“整体统计上像不像真实视频”,而不是单条视频的清晰度与文本对齐度。生成一堆模糊但统计接近的视频也可能拿到低 FVD,所以必须结合 CLIPSIM 检验文本对齐、人工评估检验观感,多指标交叉验证。

为何常见:指标名字权威、论文都报 FVD,容易把它当成“唯一真理”,忽略了它只是分布相似度的一种近似。

误区生成时把温度调低到 0.1,模型只选最高概率的 Token,生成的视频一定更稳定、更高质量,所以温度越低越好。

正解温度过低会让分布过于尖锐,模型反复选择高分 Token,导致画面重复、运动退化(比如物体卡住不动);温度过高则画面随机乱跳。实际调参通常在 0.6~1.0 之间,并配合 Top-k 截断,在稳定性与多样性之间取平衡。

为何常见:“越低越确定”听起来像优化方向,容易忽略生成任务本身需要多样性和合理随机性,把分类任务的置信度思维错搬到了生成任务上。

误区Sora 用扩散模型生成 60 秒惊艳视频,VideoGPT/Phenaki 这种逐 Token 生成的老方法已经没有价值,学它纯属浪费时间。

正解Sora 代表了扩散大模型的巅峰,但自回归路线仍在活跃演进:Phenaki 支持文本驱动的长视频生成;视频 Token 化后与文本 Token 共用同一个 Transformer,正是“视觉-语言统一模型”的核心方向。两条路线会长期共存并互相借鉴,理解自回归反而能帮你读懂最新论文里“扩散 + 自回归”的混合架构。

为何常见:媒体聚焦 Sora 的惊艳效果,忽略了学术与工业界技术路线的多元性,以及自回归在统一模态建模上的结构性优势。

面试题

Q1. 在自回归视频生成中,“自回归”指的是什么?

单选题 · easy

  • A.模型反复对自己的输出做微调
  • B.根据已生成的 Token 预测下一个← 正确答案
  • C.一次性生成所有帧后拼接成片
  • D.用奖励模型不断修正生成结果

答案:B。自回归的核心是利用已生成内容预测下一个元素。A/D 描述的是生成后处理或强化学习,C 是并行/一次生成路线,都不符合逐 Token 预测的定义。B 正是 VideoGPT 每个时间步在做的事。

Q2. VideoGPT 建模视频时使用的中间表示是什么?

单选题 · easy

  • A.原始像素帧序列
  • B.特征金字塔特征
  • C.离散视觉Token序列← 正确答案
  • D.光流运动向量场

答案:C。VideoGPT 先通过 VQ 分词器把视频变成离散 Token 序列,再交给 Transformer 建模。直接预测原始像素是“像素自回归”,不是 VideoGPT 的做法;特征金字塔和光流也不是它的核心表示。

Q3. 下列哪项是 VQVAE 中“码本损失”的写法?(sg 表示停止梯度)

单选题 · mid

  • A.重建损失 ‖x-D(E(x))‖²
  • B.码本损失 ‖sg[E(x)]-e‖²← 正确答案
  • C.承诺损失 β‖E(x)-sg[e]‖²
  • D.对抗损失 ‖1-D(G(z))‖²

答案:B。重建损失是让解码还原接近原图;承诺损失让编码器输出向码本靠拢;B 才是码本损失,让码字向编码器输出移动。D 是生成对抗网络的损失,不属于 VQVAE 的标准三项损失。

Q4. 采样温度 τ 对生成分布的影响是什么?

单选题 · mid

  • A.τ 越大,生成越确定
  • B.τ 越小,生成越随机
  • C.τ 影响码本的大小
  • D.τ 越大,分布越平缓← 正确答案

答案:D。把 logits 除以 τ 后再做 softmax,τ>1 时分布变平坦、随机性增强,τ<1 时分布变尖锐、更确定。τ 不改变码本设置,只调节采样分布的形态,所以 D 正确。

Q5. 以下哪些是视频生成质量的常用评估指标?

多选题 · mid

  • A.视频分布距离 FVD← 正确答案
  • B.文本对齐 CLIPSIM← 正确答案
  • C.文本翻译指标 BLEU
  • D.人工主观评估观感← 正确答案

答案:ABD。FVD 衡量生成与真实视频的特征分布距离,CLIPSIM 衡量视频与提示词的对齐程度,人工评估是公认的金标准。BLEU 是机器翻译指标,不用于视频评估,故排除。

Q6. Phenaki 相比 VideoGPT 的关键改进是什么?

单选题 · mid

  • A.取消分词器直接预测像素
  • B.引入文本条件与时序压缩← 正确答案
  • C.用 LSTM 替代了注意力机制
  • D.只生成静态图片的内容块

答案:B。Phenaki 用文本编码器注入条件,并通过时序压缩显著减少 Token 数量、支持长视频生成。它仍然使用 Token 化和 Transformer,没有取消分词器,也不是只生成静态图片。

Q7. 训练 VideoGPT 时,下列哪些做法可以有效降低显存占用?

多选题 · hard

  • A.混合精度训练减少显存← 正确答案
  • B.使用梯度检查点重计算← 正确答案
  • C.扩大码本容量增加表达
  • D.减小视频分辨率与帧数← 正确答案

答案:ABD。混合精度用 fp16 省显存,梯度检查点用重计算换显存,降低分辨率和帧数直接减少 Token 数量。扩大码本容量会增加参数量和显存开销,与降低显存的目标相反。

Q8. 一段 8 帧、每帧 16×16、块边长 4×4 的视频,分词后每帧有多少个 Token?

单选题 · easy

  • A.大约只有 8 个
  • B.一共是 16 个← 正确答案
  • C.总共是 64 个
  • D.合计为 256 个

答案:B。16×16 图像按 4×4 小块切割,得到 (16/4)×(16/4)=4×4=16 个 Token。这个计算对应公式 N_tokens = T × (H/p) × (W/p),是估算序列长度和显存的基础。

Q9. 关于 VQ 码本,下列说法正确的有哪些?

多选题 · extreme

  • A.码本过大会导致码字利用率低← 正确答案
  • B.码本越小重建误差一定越小
  • C.码本通过最近邻查找匹配输入← 正确答案
  • D.码本参数随重建梯度反向更新

答案:AC。码本过大容易坍缩,大量码字闲置,A 正确;码本通过欧氏距离最近邻匹配特征,C 正确。码本大小与重建误差不是单调关系,B 错误;码本通过停止梯度配合码本损失或 EMA 更新,不直接随重建梯度更新,D 错误。

Q10. FVD 指标的计算基于什么特征?

单选题 · mid

  • A.图像分类网络中间层特征
  • B.视频动作识别网络提取特征← 正确答案
  • C.文本编码器的语义特征向量
  • D.音频频谱图的倒谱特征

答案:B。FVD 用 I3D 等视频动作识别网络提取视频特征,再假设特征近似高斯分布计算 Fréchet 距离。图像分类特征缺少时间信息,文本语义对应 CLIP 分数,音频特征与视频生成无关,均不对。