Show-o 与离散扩散统一模型


文档摘要

Show-o 与离散扩散统一模型 本节摘要:Transfusion 混合连续与离散表示。Show-o(Xie 等人,2024 年 8 月)走另一条路:文本 token 用因果下一 token 预测,图像 token 用 MaskGIT 风格的掩码离散扩散。两者都坐进一个带混合注意力掩码的 Transformer。结果在一个主干、每模态一个分词器、一种损失形式(下一 token 推广到掩码预测)上,统一了 VQA、文生图、图像补全与混合模态生成。本节走读 Show-o 的设计——为什么掩码离散扩散是一种并行的、少步的图像生成器——并与 Transfusion、Emu3 对比。

Show-o 与离散扩散统一模型

本节摘要:Transfusion 混合连续与离散表示。Show-o(Xie 等人,2024 年 8 月)走另一条路:文本 token 用因果下一 token 预测,图像 token 用 MaskGIT 风格的掩码离散扩散。两者都坐进一个带混合注意力掩码的 Transformer。结果在一个主干、每模态一个分词器、一种损失形式(下一 token 推广到掩码预测)上,统一了 VQA、文生图、图像补全与混合模态生成。本节走读 Show-o 的设计——为什么掩码离散扩散是一种并行的、少步的图像生成器——并与 Transfusion、Emu3 对比。

学习目标

阅读完本节,你应当能够:

  1. 解释掩码离散扩散:先统一掩码 token,再让 Transformer 把它们恢复出来的调度。
  2. 在速度与质量上,对比并行图像解码(Show-o、MaskGIT)与自回归图像解码(Chameleon、Emu3)。
  3. 说出 Show-o 用一个 checkpoint 处理的三种任务:T2I、VQA、图像补全。
  4. 挑一种掩码调度(余弦、线性、截断),推理它对采样质量的影响。

一、问题与直觉

Transfusion 的双损失训练有效,但动力学更棘手——连续扩散损失与离散 NTP 损失不在一个数值量级上,平衡损失权重是个超参搜索,架构有效但复杂。

Show-o 的回答:两种模态都保持离散(像 Chameleon),但图像用掩码离散扩散并行生成,而非逐 token 串行。训练目标变成单一的掩码 token 预测,自然地推广了下一 token 预测。

掩码离散扩散(MaskGIT)

Chang 等人(2022)的 MaskGIT 技巧很优雅。从一张全掩码图像(每个 token 都是特殊 <MASK> ID)出发,每步并行预测所有掩码 token,然后保留 top-K 最有信心的预测,把其余重新掩码。约 8~16 次迭代后所有 token 填满。每步揭示多少 token 的调度要调——余弦调度效果好。

训练很简单:从 [0, 1] 均匀采样一个掩码比例,应用到图像的 VQ token 上,训练 Transformer 恢复被掩码的。这正是 BERT 对文本做的事,扩到图像生成。

Show-o:一个 Transformer,混合掩码

Show-o 把 MaskGIT 放进一个因果语言模型 Transformer。注意力掩码是:

  • 文本 token:因果(标准 LLM)。
  • 图像 token:图像块内全双向(掩码 token 预测时能看到其他所有图像 token)。
  • 文本到图像:文本关注之前的图像,图像关注之前的文本。

训练交替:

  1. 文本序列上的标准 NTP。
  2. T2I 样本:文本 → 图像,图像 token 被掩码,掩码 token 预测损失。
  3. VQA 样本:图像 → 文本,文本 token 被掩码(其实就是 NTP)。

统一损失是 <MASK> token 上的交叉熵,同时覆盖文本 NTP(只有最后一个 token 算「掩码」)与图像掩码扩散(随机子集被掩码)。

并行采样

Show-o 约 16 步生成一张图,而非约 1000 步(逐 token 自回归)或约 20 步(扩散)。每步并行预测所有掩码 token,提交 top-K 有信心的,重复。

对比:

  • Chameleon / Emu3(逐 token 自回归):N_tokens 次前向,典型每图 1024~4096。
  • Transfusion(连续扩散):约 20 步,每步一次完整 Transformer 前向。
  • Show-o(掩码离散扩散):约 16 步,每步一次完整 Transformer 前向。

Show-o 在同等规模下比 Chameleon 快,步数大致持平 Transfusion,但每步成本更低(离散词表 logits vs 连续 MSE 损失)。

一个 checkpoint 多任务

Show-o 推理时支持四种任务,按 prompt 格式选择:

  • 文本生成:标准自回归文本输出。
  • VQA:图像进,文本出。
  • T2I:文本进,经掩码离散扩散出图像。
  • 图像补全:图像部分 token 被掩码,填上。

补全能力从掩码预测训练免费获得——掩码 VQ 网格的一块,喂其余部分加文本 prompt,预测掩码 token。

掩码调度

每步揭示多少 token 的调度影响质量。Show-o 推荐余弦:

mask_ratio(t) = cos(pi * t / (2 * T)) # t = 0..T

第 0 步全掩码(比例 1.0),第 T 步全无掩码。余弦把质量集中在中段比例——那里预测最有信息量。线性调度也行,但平台化更快。

Show-o2

Show-o2(2025 后续,arXiv 2506.15564)扩规模:更大 LLM 基座、更好分词器、改进掩码调度,架构模式不变。

Show-o 的位置

2026 年的分类法里:

  • 离散 token + NTP:Chameleon、Emu3。简单但推理慢。
  • 离散 token + 掩码扩散:Show-o、MaskGIT、LlamaGen、Muse。并行采样,仍受分词器有损限制。
  • 连续 + 扩散:Transfusion、MMDiT、DiT。质量最高,训练更复杂。
  • 连续 + VLM 内流匹配:JanusFlow、InternVL-U。最新。

按任务挑:要在一个开源模型里同时做 T2I + 补全 + VQA 且速度合理,选 Show-o;质量 paramount 且能负担双损失管道,选 Transfusion。

二、从零实现

code/main.py 模拟 Show-o 采样:

  • 一个 16 个 VQ token 的玩具网格。
  • 一个 mock「Transformer」,按 prompt 与当前已揭示 token 预测 logits。
  • 余弦调度下 8 步并行掩码采样。
  • 打印中间状态(掩码模式演化)与最终 token。

掩码离散扩散采样的伪代码

def maskgit_sample(model, prompt, n_tokens=1024, steps=16): tokens = [MASK] * n_tokens # 全掩码起步 for t in range(steps): logits = model(prompt, tokens) # 并行预测所有掩码位置 probs = softmax(logits, axis=-1) confidence = probs.max(axis=-1) # 每个位置的最大概率 # 余弦调度: 本步揭示多少 keep_ratio = 1.0 - cos(pi * t / (2*steps)) n_keep = int(keep_ratio * n_tokens) # 只在仍是 MASK 的位置里挑 top-K 信心 masked_idx = [i for i,v in enumerate(tokens) if v == MASK] top_idx = topk(confidence[masked_idx], n_keep) for i in top_idx: tokens[masked_idx[i]] = argmax(probs[masked_idx[i]]) return tokens

统一损失

def show_o_loss(sequence, model): # 文本位置: 只掩码「下一个」(等价 NTP) # 图像位置: 随机掩码一个子集 masked_seq = apply_masking(sequence, strategy="mixed") logits = model(masked_seq, mask=hybrid_attention_mask(sequence)) # 统一交叉熵, 只算被掩码位置 return cross_entropy(logits[masked_positions], sequence[masked_positions])

💡 关键洞察:Show-o 把「下一 token」推广成「掩码 token」——NTP 是掩码预测的特例(只掩码最后一个)。这一个统一损失同时驱动文本生成与图像并行解码,是它比 Transfusion 双损失更简洁的根源。

混合注意力掩码

def hybrid_mask(seq_layout): # 文本: 因果; 图像块内: 全双向; 跨模态: 文本看之前图, 图看之前文本 # 与 Transfusion 块三角掩码同构, 但图像块内是全双向而非因果 ...

三、框架对比

  • Show-o 官方:MaskGIT 风格掩码离散扩散 + 因果文本 NTP,混合注意力掩码,一个 checkpoint 四任务(T2I/VQA/补全/文本)。
  • MaskGIT:Show-o 的图像生成源头,纯图像并行掩码解码,余弦调度。
  • LlamaGen:类条件自回归图像模型,逐 token 串行,与 Show-o 并行掩码相对。
  • Transfusion / MMDiT(第 13 节):连续 + 扩散,质量更高但双损失更复杂。
  • Show-o2:扩规模,同架构模式。

工程取舍:要开源单模型多任务(理解+生成+补全)且速度合理用 Show-o;要最高生成质量用 Transfusion/MMDiT;要最简代码用 Chameleon/Emu3(逐 token NTP);要纯图像并行生成用 MaskGIT。

四、可复用产物

本节产出 outputs/skill-unified-gen-model-picker.md。给定一个既需理解(VQA、caption)又需生成(T2I、补全)、且有开源权重约束的产品,它在 Show-o 系、Transfusion/MMDiT 系、Emu3/Chameleon 系间选择,给出具体权衡。

五、练习

  1. 为何不只 1 步:掩码离散扩散约 16 步。为什么不能 1 步?第 0 步全揭示会崩什么?

  2. 补全用例:补全在掩码扩散里免费。提出一个真实或假想的产品用例,Show-o 的补全胜过专门模型。

  3. 调度对比:余弦 vs 线性调度,T=8 时追踪每步揭示的 token 数,哪个更均衡?

  4. 压缩比:512×512 的 Show-o 图是 1024 token,K=16384 词表,模型输出 1024·log2(16384)=14336 位(约 1.75 KiB)。Stable Diffusion 输出 512·512·24=6291456 位(约 768 KiB)原始像素。压缩比是多少?买到了什么质量?

  5. 读 LlamaGen:读 LlamaGen(arXiv:2406.06525),它的类条件自回归图像模型与 Show-o 的掩码方法有何不同?

本节要点回顾

  1. 掩码离散扩散:全掩码起步,每步并行预测所有掩码 token、提交 top-K,约 16 步填满。
  2. 训练即 BERT 化:均匀采样掩码比例,训练恢复被掩码 token——BERT 对文本做的事扩到图像。
  3. 混合注意力:文本因果、图像块内全双向、跨模态文本看之前图/图看之前文本。
  4. 统一损失:<MASK> 上的交叉熵,同时覆盖文本 NTP(掩码最后一个)与图像掩码扩散(掩码随机子集)。
  5. 并行 vs 串行:Show-o 约 16 步,比 Chameleon 1024~4096 步快,与 Transfusion 20 步持平但每步更便宜。
  6. 四任务一 checkpoint:文本生成、VQA、T2I、补全,按 prompt 格式选。
  7. 补全免费:从掩码预测训练直接获得,掩码一块预测即可。
  8. 余弦调度:mask_ratio(t)=cos(πt/2T),把质量集中在中段;线性也行但平台化快。
  9. 2026 分类:离散+NTP(慢)、离散+掩码扩散(Show-o,并行)、连续+扩散(最高质)、连续+VLM 内流匹配(最新)。
  10. 选型:开源单模型多任务且速度合理用 Show-o;质量 paramount 用 Transfusion。

下一节,我们将进入 Janus-Pro——它进一步解耦,让理解与生成各用最佳视觉编码器(SigLIP 理解、VQ 生成),共享 Transformer 主体,是「解耦编码器」路线的代表。


发布者: 作者: Rohit Gupta 转发
评论区 (0)
U