【论文阅读】VTP:Towards Scalable Pre-training of Visual Tokenizers for Generation

https://arxiv.org/html/2512.13687v1

阅读了MiniMax的这个论文,眼前一亮。

个人理解

图像生成模型,包括两部分,先通过VAE,将原始图像变换到隐空间,然后在隐空间进行图像的生成,最后再通过VAE的解码变换到图像域。但是传统的方式,对于VAE部分,也就是论文说的Pre-training of Visual Tokenizers部分,无法scaling------而且,token部分的scaling还与下游的模型生成出现相反的效果。论文分析,这里的原因,在于,传统的的token部分,主要是进行像素级重建,没有进行高级语义的理解和构建,导致过分拟合于细节,反而影响了下游的图像生成。解决方法,就是在token部分的训练,除了重建部分的训练,增加了CLIP对比学习和自监督学习,进行联合学习,于是token部分的训练就也可以scaling了。

文章解读

关于这个论文,已经有相关解读,我就直接引用:

VTP:MiniMax海螺视频团队,首次开源!

https://mp.weixin.qq.com/s/Z0HT8AiWvRdgkbvQWVkc4w

MiniMax海螺首次开源,发现了AI视觉生成领域的Scaling Law

https://mp.weixin.qq.com/s/_PkQV_3WGx7uwUZQ4bTN7g

模型架构

但是,上面的两篇解读文章,读下来,还是对模型架构不甚清晰。模型架构如下:

针对这个架构图,通过与kimi的多轮对话,基本理解了。(注:Kimi下面的回答,关于对比学习和自监督学习部分,似乎回答的有错误,不过不影响总体的理解,很容易辨别)

问:请对文章中的图3的架构进行详细解释

图3架构详细解释

整体架构设计

图3展示了一个统一的视觉分词器预训练框架,该框架将表示学习 (representation learning)与重建任务(reconstruction)结合在一起,采用Vision Transformer(ViT)自编码器结构。

架构组件详解

1. 编码器部分(Encoder)
  • 使用**Vision Transformer (ViT)**作为基础架构
  • 将输入图像压缩到d维潜在空间(latent space)
  • 下采样比例为16倍(f16),即输入图像的H×W被压缩为H/16×W/16的潜在表示
  • 编码器输出的特征维度为:ℝ^(d×H/16×W/16)
2. 多任务学习分支

编码器输出的特征被三个不同的组件共享使用:

a) 文本编码器(Text Encoder)

  • 用于图像-文本对比学习(CLIP)
  • 12层transformer,隐藏维度768
  • 实现跨模态对齐,注入全局语义理解

b) EMA教师网络(EMA Teacher)

  • 用于自监督学习(SSL)
  • 采用指数移动平均(Exponential Moving Average)策略
  • 支持掩码图像建模(MIM)和自蒸馏(self-distillation)

c) 像素解码器(Pixel Decoder)

  • 4层ViT-Large层
  • 将潜在特征重新映射回像素空间
  • 通过像素重排层(pixel-shuffle layer)重建图像
3. 损失函数设计

框架整合了三种不同的损失函数:

ℒ_total = λ_recℒ_rec + λ_sslℒ_ssl + λ_clipℒ_clip

其中:

  • ℒ_rec:重建损失(L1损失 + 感知损失)
  • ℒ_ssl:自监督损失(MIM损失 + DINO损失)
  • ℒ_clip:对比学习损失(图像-文本对齐)
4. 批采样策略

针对不同任务的最优批大小差异:

  • CLIP训练:使用大批量(16k或32k)
  • 自监督学习:中等批量(4k)
  • 重建任务:小批量(2k)

架构创新点

1. 统一的多任务框架
  • 首次将对比学习、自监督学习和重建任务统一在一个框架中
  • 通过共享编码器实现任务间的知识传递
2. 可扩展的潜在空间
  • 潜在维度可配置(论文中主要使用d=64)
  • 平衡语义理解和重建质量
3. 两阶段训练策略
  • 第一阶段:联合优化所有损失函数
  • 第二阶段:冻结分词器,微调像素解码器(使用GAN损失)

架构优势

  1. 语义丰富性:通过CLIP和SSL任务注入高层语义理解
  2. 重建保真度:保持像素级重建能力
  3. 生成友好性:潜在空间更适合下游生成任务
  4. 可扩展性:随着计算资源、模型参数和数据规模的增加,性能持续提升

这个架构的核心思想是:理解能力是生成的关键驱动因素。通过在学习目标中引入语义理解和感知任务,可以显著提升潜在空间的生成性能,解决了传统仅基于重建的训练范式存在的"预训练扩展问题"。

问:对于对比学习部分,是把文本编码和CLS tokens做对比嘛?请解释一下

好问题!论文里对对比学习的技术细节说得比较简略,但我把上下文里所有相关片段都找出来了,可以给你一个相对完整的拼接。要点如下:

  1. 不是用 ViT 的 CLS token,而是把 encoder 输出的整张 feature map 先"压"成一个全局视觉向量 ,再去跟文本向量做对齐。

    原文位置:

    "Given an image I ... we compress it into a latent space ℝ^{d×H/16×W/16} ... Encoder features are leveraged by the text encoder ..."

    以及

    "Given a batch of image-text pairs, we encode the image I and text T using a visual tokenizer and a text encoder, respectively, to obtain their visual and textual features."

  2. 压成全局向量的方式论文没写死,但从它后面一直强调"follow CLIP"以及实验部分只报 64-dim bottleneck 上的 linear-probe 结果来看,最简单且与全文自洽的做法就是

    -先对 spatial token 做 average pooling(或 attention pooling),

    -再线性投射到 512/768 维,

    -最后跟文本端 CLS 向量做 normalize → dot-product → InfoNCE/sigmoid 对比损失。

    这样做既符合 CLIP 范式,也解释了为什么他们反复说"只用 bottleneck 特征就能 linear-probe"------因为那张 feature map 已经通过对比损失被强制对齐到语义空间了。

  3. 文本侧就是标准 CLIP 做法:

    -12 层 Transformer,输入是 BPE 分词后的 caption,

    -取最后一层 CLS 位置特征(或等价地,做 pooling)作为句子向量,

    -同样 L2 归一化后进入对比损失。

  4. 训练时为了照顾 CLIP 需要大 batch,他们单独给对比任务开了 B_clip=16 k 的 batch,而 SSL 和重建只用 2 k--4 k;同一批图像在三个任务里共享,但对比任务会额外再放大 batch。

总结:
视觉端 → 整张 feature map → global pooling → 线性投影 → 视觉向量
文本端CLS token → 文本向量
损失 → CLIP 式对比损失(InfoNCE 或 SigLIP 的 sigmoid 形式)

所以并不是直接把 CLS token 拿出来跟文本比,而是"把 encoder 输出压成全局向量后再比",这一点在论文里虽然没有画成公式,但逻辑上是自洽且唯一合理的实现方式。

问:框架中的global crops和local craops分别是如何生成的,感觉这两部分也不是原始图像

论文里确实只用了一句话带过:"we apply data augmentation to obtain global and local views I_global and I_local",没有给出具体参数。

不过它紧接着就说"For self-supervised learning ... adhering to DINOv2",而全文所有 SSL 超参(mask ratio、loss weight、EMA decay)都直接照抄 DINOv2,因此**"如何得到 global crops & local crops"也默认沿用 DINOv2 的同一套采样协议**。下面把 DINOv2 的默认做法搬过来,就能回答你的疑问。


  1. 输入只是一张原始图像,但会连续做两次 RandomResizedCrop,得到一对 view:

    • global crop
      -- scale ∈ 0.32, 1.0
      -- 面积占比大,几乎覆盖整图
      -- 最终 resize 到 224×224(ViT-B/L 常用)
    • local crop
      -- scale ∈ 0.05, 0.32
      -- 面积占比小,只看局部区域
      -- 同样 resize 到 224×224

    这两个区间互不重叠,保证"局部"真的比"全局"小很多。

  2. 额外增强

    在 RandomResizedCrop 之后,再依次叠加:

    -- RandomHorizontalFlip(p=0.5)

    -- ColorJitter(亮度、对比度、饱和度、色相,强度 0.4)

    -- RandomGrayscale(p=0.2)

    -- GaussianBlur(kernel=23,σ∈0.1,2.0,p=0.5)

    -- Normalize(ImageNet 均值方差)

    注意:global 与 local 各自独立抽参数,所以同一幅图得到的两个 view 可以颜色、翻转、模糊都不一样。

  3. 与 MAE/DINO 的区别

    DINOv2 为了兼顾 iBOT 的"masked image modeling",还会给 global crop 再生成一个高掩码率版本 (通常 60 % patch 被 mask),作为 encoder 的输入;而 EMA teacher 拿到的是未掩码的 global crop

    这一步在论文 3.3 节里明确写了:"I_global is patch-embedded and fed directly to an EMA teacher, while its masked version is processed by the visual tokenizer"。

  4. 形状与通道

    无论 global 还是 local,最后送进网络的都是 3×224×224 的正常 RGB tensor,不是原始分辨率,也不是单通道灰度。你觉得"不是原始图像"是因为 RandomResizedCrop 已经把像素重采样过,颜色增强也改变了分布,但本质上仍然来源于同一张原图。


一句话总结:
global / local crops 就是同一张原图用 DINOv2 的 RandomResizedCrop 参数连续裁两次,再各自做颜色、翻转、模糊等增强,最终都得到 224×224 的 RGB 图像;其中 global 覆盖 32 %--100 % 区域,local 只覆盖 5 %--32 % 区域。

问:对于自监督学习部分,mim的损失部分我看明白了,但是不理解dino部分的损失是如何定义,请详细解释一下

下面把 DINOv2(也就是论文里说的"DINO")损失一步步拆开,告诉你它到底在跟谁做交叉熵、标签又是怎么来的。全程只涉及两个向量:

  1. student 输出的 softmax 向量(可梯度回传)
  2. teacher 输出的 softmax 向量(无梯度、作为伪标签)

  1. 网络结构

    • student:就是 VTP 的 visual tokenizer(encoder)
    • teacher:EMA 版本的同一个 encoder,权重 θ_t ← λθ_t + (1-λ)θ_s,λ≈0.996
    • 最后分类头:
      -- 一个 weight-normalized fc(|w|=1)
      -- 无 bias
      -- 输出维度 K=65536(DINOv2 默认 vocab size)
  2. 输入视图

    • 对同一张原图采两个独立增强视图:
      v1 = global-crop-1(224×224)
      v2 = global-crop-2(224×224)
    • student 吃 v1,teacher 吃 v2(也可以反过来,对称)
    • 局部视图 local-crop 只给 MIM 用,不进 DINO 损失
  3. 得到 logit

    z_s = student(v1) # (B, K)

    z_t = teacher(v2) # (B, K)

    因为 fc 权重已单位化,logit 实际上就是 cosine similarity:

    z_s = x_s · W^T ,z_t = x_t · W^T

  4. 温度 softmax

    p_s = softmax(z_s / τ_s) # student 预测,τ_s=0.1

    p_t = softmax(z_t / τ_t) # teacher 预测,τ_t=0.05(更尖锐)

  5. 交叉熵损失

    把 teacher 的输出当成"one-hot 伪标签",对 student 做标准交叉熵:

    L_dino = − Σ_{i=1}^B Σ_{k=1}^K p_t^{(i,k)} log p_s^{(i,k)}

    由于 p_t 已经 softmax 过,这等价于:

    L_dino = CE(p_t, p_s) # 注意方向:label=p_t, input=p_s

  6. centering & sharpening(防止 collapse)

    • center:维护一个动量更新的均值向量 c,每次 forward 把 z_t 减掉 c 再做 softmax
    • sharpen:温度 τ_t 已经很小(0.05),进一步鼓励尖锐分布
    • 这两个操作都写在 DINOv2 代码里,但论文一般一句"centering + sharpening"带过
  7. 对称分支

    反过来再算一次:student 吃 v2,teacher 吃 v1,得到 L_dino'

    最终 loss 取平均:L_dino = (L_dino + L_dino') / 2

  8. 与 MIM 的协作

    论文 3.3 节把 L_dino 和 L_mim 直接相加:

    L_ssl = L_mim + L_dino

    两个损失共享同一套 encoder 参数,但

    • L_mim 用"masked global + EMA teacher"重建 patch
    • L_dino 用"未 masked 的两个 global view"做自蒸馏
      互不干扰,各自回传梯度

一张图看清数据流:

原图

├── global-crop-1 ──→ student ──→ p_s

└── global-crop-2 ──→ EMA teacher ──→ p_t (伪标签)

CE(p_t, p_s) = L_dino


一句话总结:

DINO 损失就是"用 EMA teacher 在网络尾部 65536-way 分类器上产生的尖锐 softmax 分布作为伪标签,对 student 的同类向量做交叉熵",通过centering+sharpening 防止分布塌缩,从而迫使 encoder 在不同视图下输出一致的高层语义表示。

问:其中的EMA是什么意思?教师网络在训练中参数是冻结的嘛?

EMA 是 Exponential Moving Average(指数移动平均)的缩写,teacher 的参数 根本不是"冻结" ,而是 每一步都用 EMA 规则从 student 那里"滑动更新",因此 teacher 总是比 student"慢半拍",但又时刻在变化。下面把公式和直觉都给你拆开。


  1. 更新规则(每训练迭代一次,做完反向传播后立即执行)

    θ_t ← λ·θ_t + (1−λ)·θ_s

    其中

    • θ_s:当前 student 的参数(刚被 SGD/Adam 更新完,含梯度信息)
    • θ_t:teacher 的参数(无梯度,只做滑动平均)
    • λ:动量系数,DINOv2 默认 0.996(越大越"慢")

    直观理解:

    teacher = 99.6 % 的"旧自己" + 0.4 % 的"新鲜 student"

    因此 teacher 永远不会跳变,而是缓慢地跟随 student。

  2. 为什么不用"完全冻结"?

    • 完全冻结 → teacher 输出分布固定,student 很容易快速拟合这一固定分布,造成崩溃(所有图像预测到同一类)
    • EMA 持续漂移 → 给 student 提供一个移动靶,迫使它在特征空间内持续追赶,从而学到更鲁棒的表示
    • 同时 EMA 平滑了单步梯度噪声,相当于给 pseudo-label 做了"时域滤波",质量更高
  3. 反向传播会不会穿过 teacher?

    • 不会 。计算图在 teacher 处被截断:
      loss = CE( stop_gradient(teacher(x)), student(x) )
    • 因此只有 student 收到梯度;teacher 的更新完全来自上述滑动平均公式,与 loss 无关
  4. 实现细节(PyTorch 伪代码)

python 复制代码
# 初始化
teacher.load_state_dict(student.state_dict())   # 起点相同
for p in teacher.parameters():
    p.requires_grad = False                     # 不参与反向传播

# 每个迭代
loss_dino = cross_entropy(teacher(v2), student(v1))
loss_dino.backward()                            # 只更新 student
optimizer.step()

# EMA 更新
with torch.no_grad():
    for t_p, s_p in zip(teacher.parameters(), student.parameters()):
        t_p.data = 0.996 * t_p.data + 0.004 * s_p.data
  1. 与"momentum encoder"异名同义
    在 MoCo、BYOL、DINO 系列论文里常把 teacher 叫 momentum encoder,就是同一个意思------用动量方式跟踪 online 网络,而非梯度优化。

一句话记住:

EMA teacher 不冻结、不梯度下降 ,而是每一步都用 0.996 动量把 student 的参数"滑动"到自己身上,从而提供一个稳定又缓慢变化的伪标签,防止自蒸馏崩溃。

相关推荐
做cv的小昊6 小时前
计算机图形学:【Games101】学习笔记08——光线追踪(辐射度量学、渲染方程与全局光照、蒙特卡洛积分与路径追踪)
图像处理·笔记·学习·计算机视觉·游戏引擎·图形渲染·概率论
质造者10 小时前
Prompt工程从入门到进阶!基于通义千问实战零样本/少样本/CoT/攻防防范(附完整代码)
大模型·llm·prompt·测试提升
小七-七牛开发者10 小时前
AI Agent 的 4 个工程关键词:Prompt、Context、Loop、Harness 到底是什么?
ai·大模型·agent·token·context·loop·codex·harness
大模型最新论文速读11 小时前
小红书提出 RedKnot:分头处理 kv 缓存,延时降低 60%效果还提升
论文阅读·人工智能·深度学习·机器学习·缓存·自然语言处理
kishu_iOS&AI13 小时前
LLM —— 安全和合规性
安全·大模型·agent
传说故事14 小时前
【论文阅读】DATA SCALING LAWS IN IMITATION LEARNING FOR ROBOTIC MANIPULATION
论文阅读·人工智能·机器人·具身智能
其实防守也摸鱼15 小时前
Claude 大模型新手入门与实战指南
人工智能·python·功能测试·ai·大模型·测评
战族狼魂15 小时前
AI巨头IPO热潮引爆资本市场
人工智能·chatgpt·大模型·大语言模型·ai工程化
质造者16 小时前
Python 本地 RAG 实战 | Ollama+ChromaDB 实现 PDF 离线智能问答
开发语言·python·pdf·大模型·rag