Taiyi-Stable-Diffusion Finetune示例的使用

运行对象:https://github.com/IDEA-CCNL/Fengshenbang-LM/tree/main/fengshen/examples/finetune_taiyi_stable_diffusion

安装环境:一台拥有八台3090显卡的服务器中内建的linux ubuntu 20.04虚拟机。因为这个服务器还有很多其他人要用所以账号权限较低。使用白名单机制的ssh协议连接。

第一步:配置本机ssh环境以便连接服务器

先在本机windows环境中安装OpenSSH协议,然后使用vscode配置ssh。配置好以后使用ssh命令通过powershell直接访问远程服务器。具体流程参考https://blog.csdn.net/qq_45956730/article/details/124277747
配置好以后直接在powershell里面输入ssh g231就可以访问远程主机。
这里不使用xshell、finalshell之类的远程连接软件是因为浙大这边的博士都是直接通过命令行访问主机的,我也只好入乡随俗了。而且vscode既然又能编程又能处理ssh配置那不妨都用它来处理代码相关的工作。而且,vscode还可以直接编辑远程主机上的文件,比vim方便多了:

第二步:安装太乙

2.1 基本流程

主要参考文档:https://github.com/IDEA-CCNL/Fengshenbang-LM#%E5%AE%89%E8%A3%85
采用本地安装方式:

git clone https://github.com/IDEA-CCNL/Fengshenbang-LM.git
cd Fengshenbang-LM
git submodule init
git submodule update

submodule是我们用来管理数据集的fs_datasets,通过ssh的方式拉取,如果用户没有在机器上配置ssh-key的话可能会拉取失败

如果拉取失败,需要到.gitmodules文件中把ssh地址改为https地址即可。

pip install --editable .

2.2 插曲:github配置ssh-key

git submodule update 这一步果然出错。将ssh地址改成https地址好几次都不成功,干脆配置个ssh-key吧,反正申请浙大服务器的时候也用的这套方式。具体流程如下。

  1. 打开Git Bash命令窗口。
  2. 输入以下命令以生成SSH密钥:ssh-keygen -t rsa -C "your_email@example.com"。其中,your_email@example.com是您的电子邮件地址。
  3. 按Enter键,接受默认文件位置和文件名。
  4. 在提示符下输入密码短语。如果您不想在每次使用SSH密钥时输入密码短语,请将其留空并直接按Enter键。
  5. 重新输入密码短语以确认。
  6. 在Git Bash命令窗口中,输入以下命令以将SSH密钥添加到ssh-agent:eval $(ssh-agent -s)
  7. 输入以下命令以将SSH密钥添加到ssh-agent:ssh-add ~/.ssh/id_rsa。其中,id_rsa是您的私钥文件名。
  8. 将公钥添加到您的GitHub帐户或其他Git托管服务中。复制公钥的内容,然后在GitHub或其他Git托管服务的网站上打开设置页面,找到SSH密钥部分,并将公钥粘贴到该部分中。

配置了ssh key以后终于git update成功。

2.3 使用miniconda安装所有依赖

然后运行pip命令失败,apt安装python失败,apt更新失败,因为没有权限
得,那就安装miniconda然后把相关依赖一块儿装了。先看太乙所在得封神榜框架对应的python版本大概是3.10以上,因此去官网选择的对应版本的安装包:(https://docs.conda.io/en/latest/miniconda.html
执行命令下载安装包:

wget https://repo.anaconda.com/miniconda/Miniconda3-py310_23.3.1-0-Linux-x86_64.sh

运行sh脚本安装miniconda:

bash Miniconda3-py310_23.3.1-0-Linux-x86_64.sh

接下来按照安装程序的提示操作,一路输入回车或yes来完成安装。
然后关闭当前终端,重新打开一个新终端,miniconda才能生效。
此时可以查看版本号命令来查看miniconda是否已经正确安装。

conda --version
python --version

如果以上命令执行无误,则可以删除之前的miniconda安装脚本

rm Miniconda3-py310_23.3.1-0-Linux-x86_64.sh

更新miniconda

conda install --channel defaults conda python=3.10 --yes
conda update --channel defaults --all --yes

最后在Fenshenbang-LM框架下运行命令安装各种依赖:
pip install --editable .
中间下载torch因为read time out中断过一次,不过第二天重新执行上面的命令后成功安装。

可以看到依赖非常的多。其中关键的是torch版本是2.0.1, 这个很有可能会导致报错,因为我看到在官方文档中的docker安装说明中,使用的pytorch版本是1.10。而众所周知从pytorch1.X到2.X是一次重大版本更新,很多bug都没修,存在不能向下兼容的问题。所以特别记录一下(F**K后面果然因为这个报错了)。


第三步:运行太乙模型的finetune example

先打开Fengshenbang-LM/fengshen/examples/finetune_taiyi_stable_diffusion/目录下的finetune.sh查看细节。
如上图所示,文档默认是采用deepspeed的半精度训练。理论上一张3090显卡就能做。
执行一次finetune.sh脚本试试
bash finetune.sh
果然报错,说没有叫做diffusers的module
那就运行pip install diffusers安装一下这个库
依此类推,但凡遇到缺库的问题都这么解决
然后再执行finetune.sh文件,又报错:

说Trainer没有名为add_argparse_args的属性,这不是编程才有的错误吗?问题是这程序是官方文档给的,我还没来得及改任何东西呢。看看最终的执行文件finetune.py排错:

这Trainer对象来自于pytorch_lightning,这是一个轻量级的pytorch库,或者说本项目的torch对象都是依赖于pytorch_lighting的,这个库缺对象了怎么可能?这回给我整不会了

2.4 插曲:pytorch版本导致的bug修复

不行了,搬救兵:

张建伟博士凭借经验判断应该是版本问题。
首先查询pytorch版本
conda list|grep pytorch
然后查询该版本的pytorch的Trainer,有没有名为add_argparse_args的属性。结论是没有。
又去https://lightning.ai/docs/pytorch/2.0.2/search.html 官方文档里查了一下,确定是版本的问题导致没有对应的属性和方法
使用vscode远程连接服务器,修改fengshen的配置安装文件setup.py, 给pytorch_lighting的安装版本增加判断条件<2,让它不要安装2.0以上版本

然后重新运行setup.py文件
pip install --editable .
于是系统重装了1.9.5版本的pytorch_lighting
张建伟博士功成身退。对于我这种没有训练模型经验的人,遇到这种问题,没有仙人指路估计得整好几天耗尽耐心。
再执行bash finetune.sh
果然没有之前的错误了(该下一个错了)

接下来的错误是运行finetune.sh时,始终无法顺利的从huggingface上下载模型


2.5 下载和使用模型

有两条路线:

  1. 直接运行bash finetune.sh,会依据脚本自动地从huggingface上下载模型
  2. 自己先从huggingface上clone模型到本地,然后修改finetune.sh中的model-path,从而实现跟1类似的目标

两条路线我都试了,都失败了好多次。具体如下:

2.5.1 直接从huggingface上下载模型

直接运行bash finetune.sh,试了5,6次,每次都看起来很有希望地下载文件(总共14个),然后下到一半的时候read time out,简单的说就是网络连接超时/超过了尝试次数,断开了连接

然后做了测试网络速度等一系列的工作,无论是使用Ping命令,curl -I 命令,还是iperf之类的工具,都没发现有问题。网速都是浙大这边标准的3.5MB最高的网速。
于是想找个huggingface的镜像,结果:

还有一个办法是修改网络连接的timeout值,比如从10改到30,应该能缓解这个问题,但暂时还不清楚怎么去修改。
然后这个下载也比较奇怪的一点是,每次重新下载都是要把所有的东西全部重新开始,而不是从上次未完成的组件开是下载。下载的文件也不知道放在那里…… 哦,是在cache里

说实话我也搞不清这些名字奇怪的文件哪个是哪个,只知道不都下好了就不能用。遂改为第二条路线:

2.5.1 直接下载模型后修改model_path

首先按照姜智德之前的文档,用git下载模型然后修改model_path
先到workspace目录使用git下载数据
cd ~/Fengshenbang-LM/fengshen/workspace/Taiyi-Stable-Diffusion-1B-Chinese-v0.1
git clone [https://huggingface.co/IDEA-CCNL/Taiyi-Stable-Diffusion-1B-Chinese-v0.1](https://huggingface.co/IDEA-CCNL/Taiyi-Stable-Diffusion-1B-Chinese-v0.1)
然后修改example 目录下的 finetune.sh,将model_path改成下载路径的workspace/Taiyi-Stable-Diffusion-1B-Chinese-v0.1,
然后执行bash finetune.sh, 报错
简单的说,就是系统没有找到我下载的模型,默认还是得从huggingface上下载,而且这个路径还有问题,报401没有权限下载或404找不到对应文件

遂将路径改为绝对路径:

再执行bash finetune.sh, 成功避免了路径的错误,执行到下一个错误了。

2.5.3 切换清华镜像

下一个错误是系统提示缺少xformers这个module
使用pip install xformers连续网络超时
问浙大服务器管理员浙大博士冯浩哲,答曰服务器不提供科学上网,这种情况请使用清华tuna镜像,详见
https://mirrors.tuna.tsinghua.edu.cn/help/pypi/
总而言之使用清华tuna镜像以后果然下载神速,pip install xformers完成

2.6 fuse_adam错误的解决与训练成功

然后下一个错误,说RuntimeError: Error building extension 'fused_adam'
查了一下,"fused_adam" 是一个用于深度学习框架 PyTorch 的扩展,它提供了优化的 Adam 优化器实现。Adam 是一种常用的优化算法,用于训练神经网络模型。"fused_adam" 的设计目的是通过融合多个操作,提高 Adam 优化器的计算效率。与微软的deepSpeed有很深的关系。

2.6.1 死磕fuse_adam错误

chatGPT的回答:当您遇到 "RuntimeError: Error building extension 'fused_adam'" 错误时,通常表示在构建或安装 "fused_adam" 扩展时出现了问题。可能的原因包括:

  • 缺少相关的依赖项或库
  • 系统环境配置问题
  • PyTorch 版本与 "fused_adam" 不兼容等

我首先查询了一下本机与torch相关的配置都是如何的,这有一个命令很好用:
python -m torch.utils.collect_env
其中重点是:

  • [conda] pytorch-lightning 1.9.5 pypi_0 pypi
  • [conda] torch 2.0.0 pypi_0 pypi
  • [conda] torchmetrics 0.11.4 pypi_0 pypi
  • [conda] torchvision 0.15.2 pypi_0 pypi
  • Python version: 3.10.11 (main, Apr 20 2023, 19:02:41) [GCC 11.2.0] (64-bit runtime)
  • Python platform: Linux-4.15.0-193-generic-x86_64-with-glibc2.27
  • Is CUDA available: True
  • CUDA runtime version: 9.1.85
  • deepSpeed 0.9.2

对这个错误(RuntimeError: Error building extension 'fused_adam')进行各种查询,得到的普遍建议是更新cuda版本,至少升级到10.2以上,参见:
https://github.com/microsoft/DeepSpeed/issues/629
https://github.com/pytorch/vision/issues/1893
但是我用的这台8卡3服务器中的cuda版本是统一装好的9.1.85,并且我没有权限进行更新,我没有运行apt命令的权限(因为这台服务器还有好多人要用呢)
所以鉴定完毕,此路不通。

2.6.2 放弃使用deepSpeed试试

已知deepSpeed只是微软出的一种降低训练模型时显存消耗的方案,如果使用半精度训练不使用deepSpeed需要20G显存和40G左右内存,依然在我的服务器硬件支持的范围内,因此放弃deepSpeed直接使用半精度训练应该也可行。
为此将finetune.sh中标记使用deepSpeed的语句全部注释掉

还有这个变量ZERO_STAGE出现的地方也该删的删

重新运行bash finetune.sh

报错了,貌似是内存不足?翻译了一下最后的报错信息如下:

PyTorch 尝试分配 20.00 MiB 的 CUDA 内存,但无法满足需求。错误信息提供了一些关于 CUDA 内存状态的详细信息:
GPU 0 总共有 23.70 GiB 的容量。
已经分配了 172.17 MiB 的内存。
当前有 10.69 MiB 的空闲内存。
PyTorch 已经在总共的内存中保留了 184.00 MiB。

说实话我觉得有点看不明白,GPU0明明有23.7GB的显存但是空闲却只有10.69MB?
5月13日再次尝试,这下终于成功了:


运行bash finetune.sh, 使用示例数据总共进行10轮训练,耗时不到半个小时。
我估计之前没有运行成功显示显存不足,可能是有别人在用显卡,今天周六没人用服务器所以运行成功。

虽然训练好的模型怎么用之类的问题还没做,但终于跑通了taiyi模型的finetune例子,为以后工作打下了基础。