Janus-Pro:统一多模态模型的解耦编码器 本节摘要:统一多模态模型有个无法回避的张力。理解想要语义特征——SigLIP 或 DINOv2 输出向量,富含概念级信息;生成想要利于重建的编码——能组合回清晰像素的 VQ token。两个目标在单一编码器里不兼容。Janus(DeepSeek,2024 年 10 月)与 Janus-Pro(DeepSeek,2025 年 1 月)主张的解法是别再强求:解耦两个编码器。任务间共享 Transformer 主体,但理解走 SigLIP、生成走 VQ 分词器。7B 下,Janus-Pro 在 GenEval 上击败 DALL-E 3,同时在 MMMU 上追平 LLaVA。本节读为什么两个编码器能成、一个却不行。
本节摘要:统一多模态模型有个无法回避的张力。理解想要语义特征——SigLIP 或 DINOv2 输出向量,富含概念级信息;生成想要利于重建的编码——能组合回清晰像素的 VQ token。两个目标在单一编码器里不兼容。Janus(DeepSeek,2024 年 10 月)与 Janus-Pro(DeepSeek,2025 年 1 月)主张的解法是别再强求:解耦两个编码器。任务间共享 Transformer 主体,但理解走 SigLIP、生成走 VQ 分词器。7B 下,Janus-Pro 在 GenEval 上击败 DALL-E 3,同时在 MMMU 上追平 LLaVA。本节读为什么两个编码器能成、一个却不行。
阅读完本节,你应当能够:
统一模型在理解与生成间共享 Transformer 主体。此前的尝试(Chameleon、Show-o、Transfusion)都用同一个视觉分词器走两个方向。这个分词器是个妥协:
Show-o 与 Transfusion 为此在一个方向上付了可见的质量税。Janus-Pro 问:既然任务需求不同,为什么非要用一个分词器?
Janus-Pro 把两个编码器分开:
Transformer 主体共享,主体上下游都按任务专属。
输入按 prompt 格式消歧:<understand> 标签走 SigLIP;<generate> 走 VQ。或按任务隐式路由。
理解损失拿到 SigLIP 特征——CLIP 式预训练已把它调到语义相似。模型的感知基准胜过 Show-o/Transfusion,因为输入特征对任务更好。
生成损失拿到 VQ token——分词器已把它调到利于重建。图像质量胜过 Show-o,因为 VQ 编码能干净地组合回像素。
共享主体看到两种输入分布(SigLIP 与 VQ),学会与两者共事。声称:数据够多、参数够大,主体能吸收这种切换。
💡 融合的另一种解法:Transfusion 用「同一表示 + 两种损失」融合;Show-o 用「同一离散空间 + 掩码预测」融合;Janus-Pro 则承认模态需求不同,让每种模态用最佳编码器,只在主体层融合——这是「解耦编码、耦合推理」的思路。
Janus(原版,arXiv 2410.13848)提出了解耦,但规模小(13 亿参数、数据有限)。Janus-Pro(arXiv 2501.17811)扩展:
结果:Janus-Pro-7B 在 MMMU 上追平 LLaVA(60.3 vs 约 58),在 GenEval 上击败 DALL-E 3(0.80 vs 0.67)。一个开源模型,在统一谱系两侧都具竞争力。
JanusFlow(arXiv 2411.07975)把 VQ 生成路径换成整流流生成路径(连续)。切分变成「SigLIP 理解 + 整流流生成」。质量天花板进一步抬升,架构仍是「解耦编码器 + 共享主体」。
主体处理一条统一序列,但有两种输入分布。它的活是:
主体没有每块模态专属权重,就是你期望在 Qwen 或 Llama 里见到的那种文本式 Transformer,加上两个输入 adapter。
有趣的是,这意味着 Janus-Pro 的主体可以从预训练 LLM 初始化。Janus-Pro 确实从 DeepSeek-MoE-7B 初始化。这个选择重要:LLM 贡献了纯从零训练的统一模型难以企及的推理能力。
InternVL-U(第 10 节)是 2026 年的后续,结合:
InternVL-U 把 Janus-Pro 的架构选择吸收进更大框架。解耦编码器思路现在是大规模统一模型的默认。
解耦编码器增加架构复杂度:两个分词器要训、两条输入路径要维护、两套失败模式。对不需要生成的产品,Janus-Pro 过度设计——选 LLaVA 系理解模型。对不需要理解的产品,Janus-Pro 大材小用——选 Stable Diffusion 3 / Flux。对两者都需要的,Janus-Pro 现在是开源参考架构。
code/main.py 模拟 Janus-Pro 路由:
为三个例子打印路由路径:图像 QA、T2I、图像编辑。
def janus_route(prompt, image, task_tag): if task_tag == "understand": feats = siglip_encoder(image) # 语义向量 tokens = mlp_projector(feats) # → 主体维度 return body(tokens + text_tokens(prompt)), mode="text_out" elif task_tag == "generate": text = text_tokens(prompt) return body(text), mode="vq_out" # 自回归发 VQ token # 主体输出 → VQ 解码器 → 像素 def body(sequence): # 无模态专属权重, 标准 Transformer return transformer_forward(sequence)
def training_schedule(): stage1 = mix(alignment_pairs, weight=1.0) # 对齐 SigLIP/VQ 到主体 stage2 = mix(unified_data, weight=1.0) # 理解+生成混合 stage3 = mix(instruction_data + image_gen_200k) # 指令微调 # Janus-Pro 关键: 阶段 3 的 20 万图像生成指令样本拉开与 Janus 的差距
💡 为何 7B 能胜 DALL-E 3 于生成:Janus-Pro 主体从 DeepSeek-MoE-7B 初始化,继承了 LLM 的世界知识与指令跟随;VQ 头只负责「把概念变成像素」。而 DALL-E 3 的文本理解靠独立编码器,概念与像素的绑定反而弱于共享主体。
工程取舍:需理解+生成且要开源前沿质量用 Janus-Pro/InternVL-U;只要生成用扩散(SD3/Flux);只要理解用 LLaVA;要最高生成质量且能负担双损失用 Transfusion。
本节产出 outputs/skill-decoupled-encoder-picker.md。给定一个想要前沿级统一生成+理解的产品,它在 Janus-Pro、JanusFlow、InternVL-U 间选择,并给出具体的数据规模建议。
7B 胜 DALL-E 3:Janus-Pro-7B 在 GenEval 上击败 DALL-E 3。解释为什么 7B 开源模型能在生成上追平前沿闭源,却在理解上不能。
路由实现:实现一个路由函数,给定 prompt 文本分类为 understand 或 generate。「describe and then sketch」这种歧义 prompt 怎么处理?
JanusFlow 输出:JanusFlow 用整流流替换 VQ 路径。Transformer 主体现在输出什么?损失如何变化?
第四种任务:提出 Janus-Pro 架构再加一个解耦编码器能处理的第四种任务(如图像分割 DINO 风格、深度 MiDaS 风格)。
读论文:读 Janus-Pro 第 4.2 节关于数据扩展。哪个数据阶段对 T2I 质量增益(相对 Janus)贡献最大?
下一节,我们将进入 MIO——把解耦思路推到极致,支持任意模态到任意模态的流式生成(文本、图像、音频、视频),是「全模态流式」的探索。