SD1.5基于DevServer适配PyTorch NPU Finetune训练指导(6.3.904)
Stable Diffusion(简称SD)是一种基于Latent Diffusion(潜在扩散)模型,应用于文生图场景。对于输入的文字,它将会通过一个文本编码器将其转换为文本嵌入,然后和一个随机高斯噪声,一起输入到U-Net网络中进行不断去噪。在经过多次迭代后,最终模型将输出和文字相关的图像。
SD1.5 Finetune是指在已经训练好的SD1.5模型基础上,使用新的数据集进行微调(fine-tuning)以优化模型性能的过程。
本文档主要介绍如何利用训练框架PyTorch_npu+华为自研Ascend Snt9B硬件,对Stable Diffusion模型下不同数据集进行高性能训练调优,同时启用多卡作业方式提升训练速度,完成SD1.5 Finetune训练。
资源规格要求
推荐使用“西南-贵阳一”Region上的DevServer资源和Ascend Snt9B。
名称 |
版本 |
---|---|
CANN |
cann_8.0.rc1 |
PyTorch |
pytorch_2.1.0 |
获取软件和镜像
分类 |
名称 |
获取路径 |
---|---|---|
插件代码包 |
ascendcloud-aigc-6.3.904-xxx.tar.gz 文件名中的xxx表示具体的时间戳,以包的实际时间为准。 |
获取路径:Support-E网站。
说明:
如果没有软件下载权限,请联系您所在企业的华为方技术支持下载获取。 |
基础镜像 |
西南-贵阳一:swr.cn-southwest-2.myhuaweicloud.com/atelier/pytorch_2_1_ascend:pytorch_2.1.0-cann_8.0.rc1-py_3.9-hce_2.0.2312-aarch64-snt9b-20240516142953-ca51f42 |
SWR上拉取 |
Step1 检查环境
- 请参考DevServer资源开通,购买DevServer资源,并确保机器已开通,密码已获取,能通过SSH登录,不同机器之间网络互通。
当容器需要提供服务给多个用户,或者多个用户共享使用该容器时,应限制容器访问Openstack的管理地址(169.254.169.254),以防止容器获取宿主机的元数据。具体操作请参见禁止容器获取宿主机元数据。
- SSH登录机器后,检查NPU卡状态。运行如下命令,返回NPU设备信息。
npu-smi info # 在每个实例节点上运行此命令可以看到NPU卡状态 npu-smi info -l | grep Total # 在每个实例节点上运行此命令可以看到总卡数
如出现错误,可能是机器上的NPU设备没有正常安装,或者NPU镜像被其他容器挂载。请先正常安装固件和驱动,或释放被挂载的NPU。
- 检查是否安装docker。
docker -v #检查docker是否安装
如尚未安装,运行以下命令安装docker。
yum install -y docker-engine.aarch64 docker-engine-selinux.noarch docker-runc.aarch64
- 配置IP转发,用于容器内的网络访问。执行以下命令查看net.ipv4.ip_forward配置项的值,如果为1,可跳过此步骤。
sysctl -p | grep net.ipv4.ip_forward
如果net.ipv4.ip_forward配置项的值不为1,执行以下命令配置IP转发。sed -i 's/net\.ipv4\.ip_forward=0/net\.ipv4\.ip_forward=1/g' /etc/sysctl.conf sysctl -p | grep net.ipv4.ip_forward
Step2 启动镜像
- 获取基础镜像。建议使用官方提供的镜像。镜像地址{image_url}参考表2。
docker pull {image_url}
- 启动容器镜像。启动前请先按照参数说明修改${}中的参数。可以根据实际需要增加修改参数。
export work_dir="自定义挂载的工作目录" export container_work_dir="自定义挂载到容器内的工作目录" export container_name="自定义容器名称" export image_name="镜像地址" // 启动一个容器去运行镜像 docker run -itd \ --device=/dev/davinci0 \ --device=/dev/davinci1 \ --device=/dev/davinci2 \ --device=/dev/davinci3 \ --device=/dev/davinci4 \ --device=/dev/davinci5 \ --device=/dev/davinci6 \ --device=/dev/davinci7 \ --device=/dev/davinci_manager \ --device=/dev/devmm_svm \ --device=/dev/hisi_hdc \ -v /usr/local/sbin/npu-smi:/usr/local/sbin/npu-smi \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /etc/ascend_install.info:/etc/ascend_install.info \ -v /sys/fs/cgroup:/sys/fs/cgroup:ro \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ --shm-size 32g \ --net=bridge \ -v ${work_dir}:${container_work_dir} \ --name ${container_name} \ ${image_name} bash
参数说明:
- work_dir:工作目录,目录下存放着训练所需代码、数据等文件。
- container_work_dir:容器工作目录,一般同work_dir。
- container_name:自定义容器名。
- image_name:容器镜像的名称。
- 进入容器。需要将${container_name}替换为实际的容器名称。
docker exec -it ${container_name} bash
Step3 获取SD1.5插件代码包并安装依赖
- 将下载的SD1.5插件代码包ascendcloud-aigc-xxx-xxx.tar.gz文件,上传到容器的/home/ma-user/目录下,解压并安装相关依赖。插件代码包获取路径参见表2。
mkdir -p /home/ma-user/stable_diffusers_1.5 #创建stable_diffusers_1.5目录 cd /home/ma-user/stable_diffusers_1.5 #进入stable_diffusers_1.5目录 tar -zxvf ascendcloud-aigc-*.tar.gz tar -zxvf ascendcloud-aigc-poc-stable_diffusers_1.5.tar.gz rm -rf ascendcloud-aigc-xxx-xxx pip install -r requirements.txt #安装依赖
- 启动前配置。有两种方式修改配置文件:
- (可选)文件替换。
因增加nfa和使用npu_geglu算子(用于训练和推理加速),将diffusers源码包中的attention.py和attention_processor.py替换成代码包中对应的文件。
图2 文件替换
可以使用find命令来查找diffusers源码包位置。
find / -name attention.py find / -name attention_processor.py
图3 查找diffusers源码包位置
找到具体位置后可以cp替换,替换前可对diffusers原始文件做备份,如果没有备份则可以通过删除diffusers包重新安装的方式获取原始文件。
- 执行bash stable_diffusers_train.sh。
bash stable_diffusers_train.sh
Step4 下载模型和数据集
数据集下载地址:https://huggingface.co/datasets/lambdalabs/pokemon-blip-captions。
export MODEL_NAME="runwayml/stable-diffusion-v1-5" export DATASET_NAME="lambdalabs/pokemon-blip-captions"
Step5 启动训练服务
sh stable_diffusers_train.sh
如果启动前配置采用的是•可以参考解压出来的default_config...方式指定配置文件,就是在此stable_diffusers_train.sh脚本中增加--config_file=xxx.yaml参数。
刚开始会报一些Warning,可忽略。正常启动如下图所示,出现Steps: 1%字样。
如果启动过程中报SSL相关错误,如下图所示。
请修改相应路径下的/home/ma-user/anaconda3/envs/PyTorch-2.1.0/lib/python3.9/site-packages/requests/sessions.py文件,将self.verify的值由True改成False,如下图所示。
Step6 保存并查看训练结果
正常运行完成训练,会显示如下内容。
精度一般问题不大,step_loss都是一个较小值。
训练过程中,训练日志会在最后的Rank节点打印。可以使用可视化工具TrainingLogParser查看loss收敛情况。
其它注意事项
- 默认500step保存一个checkpoint,可以通过在启动脚本里添加参数--checkpointing_steps=num修改。
- 若显存较低可以调整batch_size保证正常运行,改为8或者更小。
- 本次训练step为1000,训练时间较长,可以改为500。
- 如开启deepspeed训练时,需要设置参数checkpointing_steps>max_train_steps(严格大于),否则会报错。