之前看到Eric Fu发布的《狼与香辛料》中的赫萝的LoRA 模型。心里燃起一股冲动,谁不想为自己老婆炼一份模型呢,赶紧搜搜看怎么做。从基本一无所知到训练成功花了一天多,记录过程供大家参考。
完成这个事需要:
- 对 Python 编写和环境搭建有一定了解,ML 项目或者老项目免不了有点依赖冲突。为了避免依赖混淆,我给每个工具都准备了独立的 venv。
- 如果电脑是 Nvidia 支持 cuda 的 GPU,记得每个项目安装依赖前先把 pytorch-cuda 给装了,这个用 GPU,pytorch 是用 CPU 的。安装参考这个讨论。
- 一台不错的电脑,即使最后训练配置不够,是用 colab 之类在云上跑,数据集预处理之类还是本地跑比较方便。最后我是在本地炼的。装的是 pytorch-cuda,最后 torch 还是选择了用 CPU 跑,不是很懂怎么回事,但也有好处:虽然慢但不用担心内存溢出。
用到的工具/项目:
- 著名的stable-diffusion-webui(预处理数据)
- 模型:anime-segmentation - SkyTNT(扣除图片的背景)
- 模型:anime-face-detector - qhgz2013(面部识别+裁剪)
- 用lora-scripts - Akegarasu控制sd-scripts - kohya-ss训练LyCORIS (LoCon 改进型?)模型(能凑出这个名字作者真爱啊)
另外注意一下,模型各有专长,我这套流程用到的工具都是针对 anime 角色的,如果炼真人(比如以Chilloutmax为基底模型)的话,要另寻相同用途的工具。如果不是训练 LoRA 模型,而是训练 embedding(textual inversion),所需要数据集的形式会和本文有差异。
#一些懂了更好的前置知识
-
Stable Diffusion 是个 text-img 模型,它通过观察图片逐步加噪声学会了如何反向给噪声图片去噪。
-
LoRA 是一种 fine-tune(模型微调)技术。
- article: Hugging face: Using LoRA for Efficient Stable Diffusion Fine-Tuning, 中文译文
- 几种微调技术的对比:video: LoRA vs Dreambooth vs Textual Inversion vs Hypernetworks, 不想看视频还有一张直观的对比图
除了这些“基础知识”,实践过程中看到不明白的名词就搜一下看看概念,这些名词会逐渐连成知识体系。现在的 AI 生成的参数大多是专业术语,为了弄清楚设置什么值合适,只好自己去学习其含义,在理解的基础上操作。我发现"<不懂的名词>" [ML|stable diffusion|fine-tune|lora]
关键字搜索效果好(只搜名词容易被更一般的含义混淆搜索结果,加一个领域词好很多)。
#准备数据集
#收集图片
我先搜到了Stable Diffusion Training for Personal Embedding这篇文章,其中提到这个视频讲到训练个人肖像模型需要:三张不同角度全身图,五张不同角度半身图,十二张不同角度面部图。准备这个数据集可简单,找个白墙自拍就行,反正模特是自己。
虚拟人物可不能给我摆拍……去哪找图片?这个要分角色,是否载体作品有多种多媒体衍生,是否热门角色……都有影响。比如 Eric Fu 的赫萝用了轻小说的插图和漫画。我要炼的是一位不太热门的角色,能截到的“官方图片”不多,不过我从 Eric Fu 那得知“设定需接近,画风可以有些变化”,所以……我打开了同人图收藏目录,加上“官方图片”挑了约莫一百张图(什么,没有收藏目录?爱还不够啊)(虽然我觉得自己玩玩不发布没什么大不了的,但用同人图炼模型这件事在部分人看来是十恶不赦的。这里说清,如果用同人图训练,别声张别发布,我是没图了才用的) 。结合结果来看,效果也还行。
不知是否合适,我个人挑选图片的标准是“特征明显”,炼就是炼特征嘛。比如:
- ✔️人物装扮“符合官方设定”(大部分图片都会符合的)
- ✔️人物装扮非设定,但发型、面部细节等“很像”
- ✔️多人图,舍不得的话截一下能用
- ❌受环境光影影响导致人物色调变化很大
- ❌画师画风非常独特,或者太好看了超出了平均值
- ❌非彩色图片
#去除背景
是这样,首先我观察到刚刚炼肖像的两位的肖像照,似乎特意挑选了白色背景拍照。然后我看过Glitch Tokens - Computerphile这个视频,视频中提到研究人员发现某模型对哑铃文字学到的图像特征是有肌肉的上臂。这些让我不禁猜测图片背景对人物特征学习是一种噪音,所以我决定把背景删掉。(后来我学到可以用caption把图片中的某些特征做减法,让模型不要学,但我觉得这样也不如直接删背景来得效果好。)
2023年了,用普通用户的关键字photo remove background
在茫茫想赚你钱的网站中找个自动去背景的工具可累了,倒是找到一个 Photoshop 脚本,但效果不尽人意。经朋友推荐有这么一个项目anime-segmentation - SkyTNT,让我发现了image segmentation图像分割这个 ML 细分领域,而且朋友给的这个项目的效果已经非常好了。谢谢你,我的朋友。
Python3.9搭建成功,要注意它似乎只支持 png 和 jpg 格式的输入。这样我们把原图转为了 png 格式的只剩下人物的透明背景图。有些输出可能没有去除干净,我没有麻烦自己再手动去除。
#无效操作:扩大图片尺寸到正方形
我先实验了一次 resize,发现这样会截掉图片的边角部分。但是我不想丢掉任何特征(尤其是稀少的官方设定服饰的鞋子),于是在网上找了个Photoshop 脚本,把所有图片按照长和宽中大的那个把图片扩展成正方形了,这样 resize 时会把整个图片 resize。事后证明这个步骤毫无作用,把特征变得更小更模糊了,反而不利于训练。
#裁剪面部
根据肖像数据集的说法,面部(到肩部)图片的占比不少。但是同人图画肯定不会只画个证件照,看来面部图片要从同人图(透明背景)里截出来。这回尝到 ML 的甜头了,直接搜anime face detect ML
,Github给出了一些项目。挑项目,尤其挑 Python ML 项目(要基于项目写两行代码把图片裁出来保存),比起 star 我更在意开发时间,生怕年代久远的项目依赖有问题。anime-face-detector - hysts
是最新的,两年前开发,但是折腾了很久也没解决关于 mmcv 的依赖的版本问题。转向第二新(三年前开发)的项目anime-face-detector - qhgz2013。
哎,Python3.9成了,于是我 fork 了项目改了两行,让裁剪出的图片大于面部识别结果,把发型和肩部和兽耳(兽耳往上长的)也截下来(谢谢 qhgz2013已经开发了 crop 功能,省事了)。这样从每张图截取出面部,训练集大小翻个倍。
#resize + caption
现在算是收集好了原始数据集,打开 web-ui -> Train -> Preprocess images,按照这个教程中的步骤来:
- 把图片 resize 到512*512(虽然 LoRA 是支持非该大小的,但我没太明白 LoRA 对训练集图片的要求,为了保险还是经典512(stable diffusion v1.*版本的输入图片大小)吧)。
- 勾上
Auto focal point crop
焦点聚集 - 勾上
Use Deepbooru for caption
用DeepDanbooru - KichangKim这个为 anime 角色训练的图片 tag 提取模型,自动为训练集标注 tag,存这些 tag 的文件(或这些 tag 的集合)叫 caption,如上文所述,作用是不让模型学(=强化这些 tag 的权重)这些标注的特征,专注于学习“新的”(角色)特征。
现在我们终于把训练集准备好了,一堆512*512的图片和对应的 caption 文本文件。根据结果来看,face detect、 web-ui 两者生成的图片都把透明背景替换成了黑色纯色背景,这些黑色背景的训练集确实会影响结果模型的生成效果,在不给背景 tag 的时候,倾向于生成简单背景(simple background)或黑色纯色背景,但是给了背景 tag,生成就正常了,无需担心。
#检查与修改 caption
资料:Do image captions have any effect during training?
经过进一步搜索与实验,我发现 caption 对模型的训练和使用有很大用途。我写了几个简单脚本做相关的自动化工作。我训练的角色是手机游戏公主连结里的姫宮真歩,以她作为示例。
|
|
#对于训练
通过把角色特征浓厚的 tag 从 caption 中删除,可强化模型学习那些特征。这些特征应该是在未来你想生成的所有场景中该角色都具有的(比如眼镜的志村新八)。比如服饰不该被删除,因为不同场景角色服饰会变。对于真步,我删除了以下 tag:
blunt_bangs
: 平刘海。eyebrows_visible_through_hair
: 所谓图层错误眉毛,在真步上不明显,其他角色如犬山葵更是当官方梗玩。low_twintails
: 扎在低位的双马尾。*_breasts
: 为什么要删除胸部 tag?不删除这类 tag 训练出的初版模型,在不指定胸部大小的情况下100%生成巨乳。故删了 tag 让模型学学真步的真实。
我没删除诸如fox_ear, fox_tail, (brown|gold) hair, long_hair, green_eyes,
这些非常基础的特征,以我目前的知识储备判断,这些删了也可以。
有想要避免的特征,在每张图片的 caption 中都加上对应 tag,极力避免模型去学习。对于真步,我删除了bare_shoulders(露肩膀)
。抽卡手机游戏嘛,换皮,真步有好几套衣服,我用来训练的同人图大多是通常服(如图所示的和服)和泳装两套。在训练出的初版模型中,我观察到生成的绝大多数通常服图片,都是像花魁一样露肩膀的,不符合真步的角色印象。开始我以为是模型把泳装的露肩学混了,之后检查训练集发现原来我用的同人图里不少通常图也是露肩的。图片不方便另外收集,怎么解决这个问题?最后我想到用 caption 控制,实验发现效果不错,终于不再露肩膀了。
#对于使用
对所有 caption 文件内容做统计,可直观得知如果想生成目标角色该用什么 tag。对于我这英语词汇量不过关的人非常开眼界,学到好多新单词,它们能帮你更精确地与模型沟通。
caption 帮助模型在学习时理解训练集中的图片:
训练图片的 prompt = caption(模型不学的)+ 模型学到的
等到使用时我们就可以把这个公式倒过来:通过查看 caption 得知的 tags + 模型 = 看起来像训练图片的结果!如果你想生成和训练集中某图片相似的结果,看一下它的 caption 吧。
#开炼
首先我的 fine-tune 技术就是跟着 Eric Fu 选的 LoRA,因为我听说 LoRA 技术不仅在时间线上更新鲜,而且似乎对内存需求低。然后 LoRA 也分几个算法,跟着选的LyCORIS模型,走别人已经验证过可行性的路准没错,而且自己也没有足够 ML 知识做选型。LyCORIS 的 README 和顺着论坛教程找到的lora-scripts - Akegarasu 项目的 README 都指向这个项目:sd-scripts - kohya-ss。他们三者的关系是:
- sd-scripts 集成了方便直接使用的 fine-tune 脚本,可以炼所有四种 fine-tune 方式。
- lora-scripts 进一步针对 LoRA 训练简化了对 sd-scripts 的使用,而且每个参数都有推荐值,帮大忙了。
- 运行 sd-scripts 时用参数指定 LyCORIS 为算法。
Python3.10,先安装 lora-scripts(同时会安装 sd-scripts 的依赖),再 install LyCORIS 库,这三个项目共用一个 venv。基底模型用的anything-v4.5。我改了一下lora-scripts,加上了关于 LyCORIS 的新参数。这里注意 sd-scripts 是在 lora-scripts 目录下的,但运行配置中的数据集目录似乎要加上..
父目录(sd-scripts 运行时的 work directory 是自己本目录?)。
#结语
如果我能用通过Feature Visualization (对图片任务模型)、token 聚类(对文本任务模型)这些技术可视化地研究一下我生成的 LoRA 模型内部就好了,好奇它学了真步哪些特征。搜了下还没有基于 stable diffusion 模型的现成工具,作罢。另外我仍然对 caption 如何起作用不太清楚,但在网上搜不到更多解释。如果你知道相关材料,请不惜赐教。
祝大家都能炼出自己老婆,实现妄想自由。