|
我们发布了一个 Qwen-Image 的“图生 LoRA”模型。
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
是的,输入一张图,输出一个 LoRA 模型的权重,端到端直出的那种。
本文,我们将介绍我们是如何设计并训练出 Qwen-Image-i2L(Image to LoRA)模型的,我们记录了实验过程中走的弯路,希望本文能够启发更多有价值的研究。
01
技术路线
可行性分析给定一张或几张图,用 GPU 花费几个小时训练一个 LoRA,这已经是每一位 Diffusion 模型玩家的必备技能。魔搭社区一直以来都在提供高质量的免费 LoRA 训练功能,也借此发展出了繁荣的社区 LoRA 模型生态。
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
“图生 LoRA”模型是一个非常疯狂的想法,既然图像数据可以训练成 LoRA 模型,那么我们能否把动辄几个小时的 LoRA 训练过程压缩到一个模型的前向推理过程中呢? - 理论上这是完全可行的,模型的输入和输出具有极强的相关关系,甚至可以说不是“相关关系”,而是更强的“因果关系”。
- 实践上也是完全可行的,LoRA 模型的权重是张量,是张量就能传梯度,能传梯度就能训练,一切都是走得通的。
模型结构设计我们在模型结构设计上遇到了非常多的挑战。根据 OpenAI 提出的 Scaling Law,有多大的参数量,就有多大的泛化能力。但实际上由于计算资源的限制,我们需要在有限的参数量上尽可能实现更强的泛化能力。
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
LoRA 模型是由一系列张量构成的,且每一个张量的每一维发挥的作用都是完全不同的,如果我们将这些张量做成序列化的 embedding(就像大多数大语言模型一样)并用 transformer 架构模型处理,模型很难产生有价值的输出。
我们在早期的实验中,使用了 transformer 架构,在一个数万张图片的小数据集上进行了实验,使用 8*A100 GPU 进行训练,结果模型退化为了一个普通 LoRA,无论输入的图片是什么,输出的 LoRA 效果差别不大。相当于用这数万张图片训练了一个普通的静态 LoRA。
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
我们不确定这种模型结构是否需要更多的训练资源才能出现“顿悟时刻”,计算资源的限制迫使我们更换为其他收敛更快的模型结构。最关键的一点是,每一个 LoRA 权重中的张量都应当由不同的层处理,因为每一个张量的作用都是完全不同的。一个简单直接的方案是用单层的全连接层,但这带来了另一个问题——参数量爆炸。LoRA 权重的维数非常大,即使用单层的全连接层,参数量也会轻易地突破 100B。
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
我们采用了一种更加轻量的方式,把单层的全连接层改为双层的全连接层,并降低中间的维数。这样一来,参数量就会大幅减少。但这再次引入了新的问题——泛化能力不足。所以,我们在输入端使用了更强的图像编码模型,包括 SigLIP2、DINOv3,后来又增加了 Qwen-VL。 | | |
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
| 至此,我们得到了最终的 Image to LoRA 模型结构:多个图像编码器 + 多个双层全连接。
训练方案
由于工作量的原因,Qwen-Image-i2L 模型的训练代码还未公开,我们会在晚些时候将代码整理后公开(一定会公开的,毕竟我们是开源社区的团队!)
02
模型版本迭代
Qwen-Image-i2L-Style我们训练了多个模型版本,第一个版本是 Qwen-Image-i2L-Style,除去图像编码器,它只有 2.4B 的参数量。这个模型使用了一个东拼西凑的数据集,包括: 每个数据集中各随机采样了 25 万张图,总共得到 100 万张图,使用 8*A100 GPU 训练了两周,所有数据集都是开源的,你如果有兴趣可以试着复现它。
这个模型产生的 LoRA 对于图像内容的记忆能力是极其糟糕的。将一张图片输入给模型,然后用模型产生的 LoRA 生成图像,你会发现生成的图像和输入图像只能做到语义相同。换言之,当输入一只猫的图像,它输出的 LoRA 确实能够生成一只猫,但这只猫与输入的猫完全不是同一只猫。但另一方面,我们发现这个模型具备出色的风格提取能力,我们可以用它轻松地产生风格 LoRA。
例如,我们用这些图作为输入:
用产生的 LoRA 生成图像,其中随机种子均为 0: | | |
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
那么,我们是如何处理多张输入图片的?这很简单,每张图片都会产生一个 LoRA,我们把所有 LoRA 在 rank 上拼接起来就可以了。
看起来效果还不错,我们取得了阶段性的成果! Qwen-Image-i2L-Coarse下一步,我们要 Scale Up 了。我们希望能够实现更强的细节保持能力,例如用一只猫产生的 LoRA 生成这只猫做其他动作的图像。我们在 Qwen-Image-i2L-Style 的基础上,把参数量增加到了 7.9B,把训练数据量增加到了两千万张图,GPU 集群增加到了 80 * AMD MI308X。
下一个版本的模型——Qwen-Image-i2L-Coarse 来了。好消息是,猫猫越来越像了。
| | | |
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
坏消息是,风格保持能力急转直下。
模型产生的 LoRA 会倾向于复现输入图中的内容,出现了一定的“语义入侵”现象。换言之,当我们用动漫风格的猫产生 LoRA 时,生成的任何东西都像一只猫,尽管语义入侵现象可以通过增加更多的输入图像来缓解,但如果需要大量图像才能得到一个风格 LoRA,这一模型就会失去意义。
Qwen-Image-i2L-Fine不过,我们认为风格保持能力的下降是正常的,生成的内容与输入图很相似,这说明模型确实学到了更多细节保持能力。事已至此,我们继续改进模型效果。在这一模型训练收敛后,我们借鉴了一些 MoE 架构的模型,例如 DeepSeekMoE。
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
而 LoRA 模型本身就可以实现多模型融合,只需在 rank 维度拼接即可。不同于传统意义上的 MoE 架构模型,我们让每一个 Image to LoRA 专家模型都参与计算,只不过每个专家模型负责不同的 rank。在下一个专家模型的训练过程中,Qwen-Image-i2L-Coarse 的参数冻结,只训练新的专家模型。
好在 AMD MI308X GPU 的 192G 显存可以让我们忘记显存不足的烦恼,在推理阶段,DiffSynth-Studio 新版的 Disk Offload 能力可以让低显存 GPU 也能进行推理。
下一个版本的模型——Qwen-Image-i2L-Fine 来了。好消息是,猫猫更像了。坏消息是,猫猫更丑了。
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
Qwen-Image-i2L-Bias必须试图挽救一下!出现这个问题的主要原因,是我们的训练数据集分布和 Qwen-Image 模型预训练的数据集分布有很大偏差,所以应当将数据集的分布重新对齐到 Qwen-Image 上。
我们采集了 100 张 Qwen-Image 生成的图像,用 Qwen-Image-i2L-Coarse 和 Qwen-Image-i2L-Fine 产生 LoRA,然后训练了另一个 LoRA 将生成的图像重新导向 Qwen-Image 自身生成的图像。这个新的模型是一个静态的普通 LoRA,我们把它命名为 Qwen-Image-i2L-Bias。
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
至此,Coarse + Fine + Bias 这一缝缝补补的 MoE 架构模型,终于勉强达到了我们的预期效果。这个模型可以用来做什么呢?很遗憾,和常规训练的 LoRA 相比,它生成的 LoRA 仍有差距,但我们可以用它来作为 LoRA 训练的初始化权重。
但是,模型产生的 LoRA rank 是固定的,如何用于 LoRA 训练的初始化呢?很简单,对 LoRA 权重重新进行 PCA 矩阵分解,就可以把 rank 重置为任意数值。
现在我们试一下用它初始化 LoRA 训练的权重。
训练数据: |
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
| |
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
|
训练中的样图生成: | | | |
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
| |
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
| |
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
| |
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
| |
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
一张图秒生 LoRA ? Qwen-Image-i2L 诞生记
|
可以看到,使用 Image to LoRA 模型做 LoRA 训练的初始化时,在训练的早期阶段就已能够生成与训练数据相似的物体。
03
未来工作
“图生 LoRA”的概念非常疯狂,在我们梭哈了一把之后,已经取得了不错的模型效果,但我们也清晰地感受到模型还有非常大的改进空间,所以,未来我们将会进一步挖掘这类模型的潜力,至于之后我们会做什么更酷的事情,暂且保持悬念,敬请期待后续的惊喜(ゝω・)!
👇点击关注ModelScope公众号获取更多技术信息~
|