【论文阅读】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 的参数"滑动"到自己身上,从而提供一个稳定又缓慢变化的伪标签,防止自蒸馏崩溃。

相关推荐
骚戴2 小时前
在科研与项目开发中:如何高效调用大语言模型(LLM)API
人工智能·语言模型·自然语言处理·大模型·llm·api
czijin2 小时前
【论文阅读】LoRA: Low-Rank Adaptation of Large Language Models
论文阅读·人工智能·语言模型
AndrewHZ2 小时前
【图像处理基石】图像梯度:核心算法原理与经典应用场景全解析
图像处理·算法·计算机视觉·cv·算子·边缘提取·图像梯度
有Li3 小时前
诊断文本引导的分层分类全玻片图像表征学习|文献速递-医疗影像分割与目标检测最新技术
论文阅读·深度学习·文献·医学生
CoderJia程序员甲13 小时前
GitHub 热榜项目 - 日榜(2025-12-21)
开源·大模型·llm·github·ai教程
AI即插即用14 小时前
即插即用系列 | ECCV 2024 WTConv:利用小波变换实现超大感受野的卷积神经网络
图像处理·人工智能·深度学习·神经网络·计算机视觉·cnn·视觉检测
喜欢吃豆15 小时前
我把 LLM 技术栈做成了一张“可复用的认知地图”:notes-on-llms 开源仓库介绍
学习·语言模型·架构·开源·大模型·多模态
m0_6924571016 小时前
阈值分割图像
图像处理·深度学习·计算机视觉
北邮刘老师16 小时前
【智能体互联协议解析】需要“智能体名字系统”(ANS)吗?
网络·人工智能·大模型·智能体·智能体互联网