Post

CoTyle 论文阅读记录

CoTyle 论文阅读记录

同事让我有空看看这个,我就简单读了一下。

项目地址

概况

这个模型做到了使用 code(编码而非代码)控制图像风格。也就是说,在 code 相同的情况下,改变 prompt 和种子可以生成一组风格相似的图片。

CoTyle 卖家秀

粗略看了下 GitHub 首页,不过它对不同风格之间似乎并没有一种可以查表的方式,让人自己选择需要什么风格;code 的数值也非常大,看起来和 seed 一样需要”抽卡”。所以我怀疑它的侧重点并不在于引导单张图片风格化生成,而是维持一组图片保持同样的风格(同样的 code)。

好奇的问题

  1. 这看起来似乎就是一个类似 CLIP 的东西。
  2. 同事好奇的问题:Figure 4 中用红框圈出了 “suboptimal style consistency.”,这个一致性是怎么判断的?
  3. 有没有办法优雅地上线?

后来又花时间把论文完整读了一遍,一些当初的疑问也有了答案。

它是为了解决什么问题

要让 AI 画一组图,要求”风格一致”。传统做法有几种:

  • 写很长的 prompt 描述风格 —— 但每次理解都不太一样,一致性差
  • 扔一张参考图 —— 可以,但你只能复现已有风格,创造不了新风格
  • 训一个 LoRA —— 得分享权重文件,麻烦

CoTyle 的想法很简单:风格这东西,能不能就用一个数字来代表?

你给我数字 12345,我就知道你要什么风格。换个数字 67890,就是另一种风格。同一个数字,不管画猫还是画城市,风格都一样。

听起来很神奇,但问题来了:这个数字和风格之间,有什么对应关系?

答案是:没有对应关系。

这才是关键。这个数字不是”风格索引”,不能像查字典一样说”我要赛博朋克风格,给我 code=XXX”。它更像一个掷骰子的方式——同一个掷法,每次都落在同一个风格上;但你看了掷骰子的参数,猜不出会落在哪里。

所以实际生成图片时还是得抽卡,试不同的 code,看看哪个风格喜欢。但一旦找到喜欢的,就能用这个 code 生成任意内容的图,风格始终一致。

它是怎么做到的?

整体思路分三步。

第一步,造一本”风格词典”

论文先收集一堆图片,训练一个 Style Codebook。这个码本里有几万个”风格词”,每个词是一个向量,代表某种风格特征。

但在说这个码本之前,得先解释一下 VQ-VAE,因为 CoTyle 的 Style Codebook 其实是从 VQ-VAE 借来的概念。

先说说 VQ-VAE 是什么

普通的自编码器(AE)大家应该都见过:

1
图片 → 编码器 → 连续向量 z → 解码器 → 重建图片

问题是这个向量 z 是连续的,可以是任意小数,空间无限大。你想随机生成一张图,根本不知道从哪里采样。

VQ-VAE 的想法是:把连续向量”量化”成离散编码

它加了一个”码本”(codebook),就是一个查找表:

1
2
3
4
5
索引 0    →  [向量 A]
索引 1    →  [向量 B]
索引 2    →  [向量 C]
...
索引 K-1  →  [向量 Z]

流程变成:

1
2
3
4
5
6
7
8
9
图片 → 编码器 → 连续向量 z
                  ↓
            在码本里找最近的向量
                  ↓
            返回那个向量的索引(比如索引 42)
                  ↓
            用索引 42 查码本,得到量化向量 z_q
                  ↓
            解码器 → 重建图片

这样图片就变成了一串”离散编码”。这些编码可以像语言一样处理——你就能用 GPT 这样的模型来生成新图片了。

VQ-VAE 的码本是怎么训练的?目标是重建得越像越好。所以码本学到的每个向量,都是重建图像需要的”视觉元素”——比如某个向量代表”一条横线”,另一个代表”某个颜色的圆弧”。

CoTyle 的 Style Codebook 有什么不同?

结构一样,都是一个查找表。但目标完全不同

VQ-VAE 想重建图像,所以同一只猫和同一只狗会被编码成不同的向量——因为它们的视觉元素不同。

CoTyle 想提取风格,所以同一只猫和同一只狗,如果风格相同(比如都是水彩画),会被编码成相似的向量。

训练方式也不一样。VQ-VAE 用重建损失,CoTyle 用对比损失

1
2
两张图风格相同 → 让它们的编码距离近
两张图风格不同 → 让它们的编码距离远

论文原话:

“its purpose is to encode images with identical styles but different content into the same distribution, while encoding images with divergent styles into different distributions” — Sec 3.1

有个细节:光用对比损失的话,码本会”塌缩”——所有图片都被映射到同一个索引,因为这样”同风格”的约束永远满足,loss 最低。论文发现必须加一个重构损失,强制风格 embedding 不要离原始特征太远,这样码本的每一行才会学到有意义的东西。

第二步:学一个”风格写诗机”

有了码本之后,每张图片都能转换成一串”风格词”。

为什么要这一步?因为我们不想只能从已有图片里提取风格,我们要生成全新的风格

论文用一个自回归模型来学这些风格词的分布。比如它可能发现:”风格词 A 经常和风格词 B 一起出现”、”风格词 C 后面很少跟风格词 D”。学会了这些”语法”之后,就能自己写出没见过的风格组合。

还有个细节:码本里某些索引被用得特别频繁,论文发现这些高频索引代表的是”普通、没特色”的风格信息。所以在推理时会用 suppression coefficient 把这些高频索引的概率压下去,鼓励采样更独特的风格组合。

第三步:推理

1
2
3
4
5
6
7
8
9
10
11
输入一个数字 code(比如 12345)
    ↓
这个数字作为随机种子
    ↓
从码本里随机采样第一个风格词(种子固定,结果就固定)
    ↓
自回归模型生成后续的风格词
    ↓
查码本,把风格词拼成风格 embedding
    ↓
喂给扩散模型,生成图片

关键:同一个 code,每次都会采样到同样的风格词序列。所以风格是复现的。

但你看 code 的数字,完全猜不出对应什么风格。这就是为什么说是”抽卡”。

回答当初的疑问

问题 1:这看起来类似 CLIP?

读完论文发现不一样。CLIP 是图文对齐,CoTyle 是纯图片的”风格聚类”。而且 CoTyle 输出的是离散的”风格词”,不是连续向量,这样才能用自回归模型生成。

直觉”侧重批量一致风格生成”倒是对的——论文自己也把 consistency 放在第一位。

问题 2:那个 “suboptimal style consistency” 怎么判断的?

论文用了一个叫 CSD 的指标。简单说就是:同一个 code 生成多张图,用预训练的风格编码器提取特征,算这些特征的相似度。如果 variance 太大,说明一致性不够。

图里红框标注的是 Midjourney 的失败案例——同一个 code,生成的图风格跑偏了。

一点想法

这个工作的核心贡献是把”风格”从文本描述、参考图、LoRA 这些复杂的形式里抽象出来,变成一个简单的数字。

代价是这个数字本身没有语义——你不能像选 Pantone 色卡那样选风格,只能试。但对应用场景来说,这可能反而是优势:用户只管记住喜欢的数字,不需要懂风格的专业术语。

有意思的想法,但估计被 nano banana 干碎了,毕竟用提示词就能得到风格保证。可能这也是过了半年 kwai-kolors还没有 release the commercial version of CoTyle 的原因,这么看来做基座压力也很大,不是 sota 就没有意义了。


参考资料

This post is licensed under CC BY 4.0 by the author.