首页 > 其他分享 >在英特尔 CPU 上微调 Stable Diffusion 模型

在英特尔 CPU 上微调 Stable Diffusion 模型

时间:2023-07-19 22:12:02浏览次数:46  
标签:Diffusion inversion -- 模型 textual 节点 Stable CPU

扩散模型能够根据文本提示生成逼真的图像,这种能力促进了生成式人工智能的普及。人们已经开始把这些模型用在包括数据合成及内容创建在内的多个应用领域。 Hugging Face Hub 包含超过 5 千个预训练的文生图 模型。这些模型与 Diffusers 库 结合使用,使得构建图像生成工作流或者对不同的图像生成工作流进行实验变得无比简单。

和 transformer 模型一样,你可以微调扩散模型以让它们生成更符合特定业务需求的内容。起初,大家只能用 GPU 进行微调,但情况正在发生变化!几个月前,英特尔 推出 了代号为 Sapphire Rapids 的第四代至强 CPU。Sapphire Rapids 中包含了英特尔先进矩阵扩展 (Advanced Matrix eXtension,AMX),它是一种用于深度学习工作负载的新型硬件加速器。在之前的几篇博文中,我们已经展示了 AMX 的优势: 微调 NLP transformers 模型对 NLP transformers 模型进行推理,以及 对 Stable Diffusion 模型进行推理

本文将展示如何在英特尔第四代至强 CPU 集群上微调 Stable Diffusion 模型。我们用于微调的是 文本逆向 (Textual Inversion) 技术,该技术仅需少量训练样本即可对模型进行有效微调。在本文中,我们仅用 5 个样本就行了!

我们开始吧。

配置集群

英特尔 的小伙伴给我们提供了 4 台托管在 英特尔开发者云 (Intel Developer Cloud,IDC) 上的服务器。IDC 作为一个云服务平台,提供了一个英特尔深度优化的、集成了最新英特尔处理器及 最优性能软件栈 的部署环境,用户可以很容易地在此环境上开发、运行其工作负载。

我们得到的每台服务器均配备两颗英特尔第四代至强 CPU,每颗 CPU 有 56 个物理核和 112 个线程。以下是其 lscpu 的输出:

Architecture: x86_64
  CPU op-mode(s): 32-bit, 64-bit
  Address sizes: 52 bits physical, 57 bits virtual
  Byte Order: Little Endian
CPU(s): 224
  On-line CPU(s) list: 0-223
Vendor ID: GenuineIntel
  Model name: Intel(R) Xeon(R) Platinum 8480+
    CPU family: 6
    Model: 143
    Thread(s) per core: 2
    Core(s) per socket: 56
    Socket(s): 2
    Stepping: 8
    CPU max MHz: 3800.0000
    CPU min MHz: 800.0000
    BogoMIPS: 4000.00
    Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_per fmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb cat_l3 cat_l2 cdp_l3 invpcid_single intel_ppin cdp_l2 ssbd mba ibrs ibpb stibp ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb intel_pt avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local split_lock_detect avx_vnni avx512_bf16 wbnoinvd dtherm ida arat pln pts hwp hwp_act_window hwp_epp hwp_pkg_req avx512vbmi umip pku ospke waitpkg avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg tme avx512_vpopcntdq la57 rdpid bus_lock_detect cldemote movdiri movdir64b enqcmd fsrm md_clear serialize tsxldtrk pconfig arch_lbr amx_bf16 avx512_fp16 amx_tile amx_int8 flush_l1d arch_capabilities

我们把四台服务器的 IP 地址写到 nodefile 文件中,其中,第一行是主服务器。

cat << EOF > nodefile
192.168.20.2
192.168.21.2
192.168.22.2
192.168.23.2
EOF

分布式训练要求主节点和其他节点之间实现无密码 ssh 通信。如果你对此不是很熟悉,可以参考这篇 文章,并跟着它一步步设置好无密码 ssh

接下来,我们在每个节点上搭建运行环境并安装所需软件。我们特别安装了两个英特尔优化库: 用于管理分布式通信的 oneCCL 以及 Intel Extension for PyTorch (IPEX),IPEX 中包含了能充分利用 Sapphire Rapids 中的硬件加速功能的软件优化。我们还安装了 libtcmalloc ,它是一个高性能内存分配库,及其软件依赖项 gperftools

conda create -n diffuser python==3.9
conda activate diffuser
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu
pip3 install transformers accelerate==0.19.0
pip3 install oneccl_bind_pt -f https://developer.intel.com/ipex-whl-stable-cpu
pip3 install intel_extension_for_pytorch
conda install gperftools -c conda-forge -y

下面,我们在每个节点上克隆 diffusers 代码库并进行源码安装。

git clone https://github.com/huggingface/diffusers.git
cd diffusers
pip install .

紧接着,我们需要使用 IPEX 对 diffusers/examples/textual_inversion 中的微调脚本进行一些优化,以将 IPEX 对推理模型的优化包含在内 (译者注: diffusers 的设计中,其 pipeline 与 transformers 的 pipeline 虽然名称相似,但无继承关系,所以其子模型的推理优化无法在库内完成,只能在脚本代码内完成。而 Clip-Text 模型的微调由于使用了 accelerate ,所以其优化可由 accelerate 完成)。我们导入 IPEX 并对 U-Net 和变分自编码器 (VAE) 模型进行推理优化。最后,不要忘了这个改动对每个节点的代码都要做。

diff --git a/examples/textual_inversion/textual_inversion.py b/examples/textual_inversion/textual_inversion.py
index 4a193abc..91c2edd1 100644
--- a/examples/textual_inversion/textual_inversion.py
+++ b/examples/textual_inversion/textual_inversion.py
@@ -765,6 +765,10 @@ def main():
     unet.to(accelerator.device, dtype=weight_dtype)
     vae.to(accelerator.device, dtype=weight_dtype)

+ import intel_extension_for_pytorch as ipex
+ unet = ipex.optimize(unet, dtype=weight_dtype)
+ vae = ipex.optimize(vae, dtype=weight_dtype)
+
     # We need to recalculate our total training steps as the size of the training dataloader may have changed.
     num_update_steps_per_epoch = math.ceil(len(train_dataloader) / args.gradient_accumulation_steps)
     if overrode_max_train_steps:

最后一步是下载 训练图像。一般我们会使用共享 NFS 文件夹,但为了简单起见,这里我们选择在每个节点上下载图像。请确保训练图像的目录在所有节点上的路径都相同 ( /home/devcloud/dicoo )。

mkdir /home/devcloud/dicoo
cd /home/devcloud/dicoo
wget https://huggingface.co/sd-concepts-library/dicoo/resolve/main/concept_images/0.jpeg
wget https://huggingface.co/sd-concepts-library/dicoo/resolve/main/concept_images/1.jpeg
wget https://huggingface.co/sd-concepts-library/dicoo/resolve/main/concept_images/2.jpeg
wget https://huggingface.co/sd-concepts-library/dicoo/resolve/main/concept_images/3.jpeg
wget https://huggingface.co/sd-concepts-library/dicoo/resolve/main/concept_images/4.jpeg

下面展示了我们使用的训练图像:

至此,系统配置就完成了。下面,我们开始配置训练任务。

配置微调环境

使用 accelerate 库让分布式训练更容易。我们需要在每个节点上运行 acclerate config 并回答一些简单问题。

下面是主节点的屏幕截图。在其他节点上,你需要将 rank 设置为 1、2 和 3,其他答案保持不变即可。

最后,我们需要在主节点上设置一些环境变量。微调任务启动时,这些环境变量会传播到其他节点。第一行设置连接到所有节点运行的本地网络的网络接口的名称。你可能需要使用 ifconfig 来设置适合你的网络接口名称。

export I_MPI_HYDRA_IFACE=ens786f1
oneccl_bindings_for_pytorch_path=$(python -c "from oneccl_bindings_for_pytorch import cwd; print(cwd)")
source $oneccl_bindings_for_pytorch_path/env/setvars.sh
export LD_PRELOAD=${LD_PRELOAD}:${CONDA_PREFIX}/lib/libiomp5.so
export LD_PRELOAD=${LD_PRELOAD}:${CONDA_PREFIX}/lib/libtcmalloc.so
export CCL_ATL_TRANSPORT=ofi
export CCL_WORKER_COUNT=1

export MODEL_NAME="runwayml/stable-diffusion-v1-5"
export DATA_DIR="/home/devcloud/dicoo"

好了,现在我们可以启动微调了。

微调模型

我们使用 mpirun 启动微调,它会自动在 nodefile 中列出的节点之间建立分布式通信。这里,我们运行 16 个进程 ( -n ),其中每个节点运行 4 个进程 ( -ppn )。 Accelerate 库会自动在所有进程间建立分布式的训练。

我们启动下面的命令训练 200 步,仅需约 5 分钟

mpirun -f nodefile -n 16 -ppn 4                                                         \
accelerate launch diffusers/examples/textual_inversion/textual_inversion.py \
--pretrained_model_name_or_path=$MODEL_NAME --train_data_dir=$DATA_DIR \
--learnable_property="object" --placeholder_token="<dicoo>" --initializer_token="toy" \
--resolution=512 --train_batch_size=1 --seed=7 --gradient_accumulation_steps=1 \
--max_train_steps=200 --learning_rate=2.0e-03 --scale_lr --lr_scheduler="constant" \
--lr_warmup_steps=0 --output_dir=./textual_inversion_output --mixed_precision bf16 \
--save_as_full_pipeline

下面的截图显示了训练过程中集群的状态:

排障

分布式训练有时候会出现一些棘手的问题,尤其是当你新涉足于此。单节点上的小的配置错误是最可能出现的问题: 缺少依赖项、图像存储在不同位置等。

你可以登录各个节点并在本地进行训练来快速定位问题。首先,设置与主节点相同的环境,然后运行:

python diffusers/examples/textual_inversion/textual_inversion.py \
--pretrained_model_name_or_path=$MODEL_NAME --train_data_dir=$DATA_DIR \
--learnable_property="object" --placeholder_token="<dicoo>" --initializer_token="toy" \
--resolution=512 --train_batch_size=1 --seed=7 --gradient_accumulation_steps=1 \
--max_train_steps=200 --learning_rate=2.0e-03 --scale_lr --lr_scheduler="constant" \
--lr_warmup_steps=0 --output_dir=./textual_inversion_output --mixed_precision bf16 \
--save_as_full_pipeline

如果训练成功启动,就停止它并移至下一个节点。如果在所有节点上训练都成功启动了,请返回主节点并仔细检查 nodefile 、环境以及 mpirun 命令是否有问题。不用担心,最终你会找到问题的

标签:Diffusion,inversion,--,模型,textual,节点,Stable,CPU
From: https://www.cnblogs.com/huggingface/p/17566922.html

相关文章

  • CPU环境下运行基于yolov5的行人检测代码(pedestrain detection based on yolov5 in CPU
    最近在捣腾基于yolov5的行人检测代码,在github上下载一个案例之后因为没用GPU运行一直碰壁,出现了许多bug,现在整理了下error和解决方法,成功调试出了基于yolov5的行人检测代码,分享给大家~1.运行环境:window10,CPU,VisualStudioCode2.项目路径:dyh的 unbox_yolov5_deep......
  • Stable-Diffusion-webUI 代码阅读02 —— 按钮?按一下!
    Stable-Diffusion-webUI代码阅读02——按钮?按一下!由于实习工作需要,决定用几天时间阅读一遍stable-diffusion-webui的代码。本文参考知乎专栏,并且添加了一些自己的理解,感谢大佬!知乎专栏:自动做游戏:AI技术落地于游戏开发-知乎(zhihu.com)最近工作主要侧重于OneFlow框架应用......
  • zoj 1576 Marriage is Stable
    稳定婚姻问题对于稳定婚姻问题,必然存在一个解,所以此题不用考虑无解的情况。用Gale-Shapley+map可以直接搞定。注意:男女名字可能相同。Gale-Shapley算法详解:http://wenku.baidu.com/view/2b5a4c7a1711cc7931b7164a.html #include<iostream>#include<cstdio>#include<map>usin......
  • AIGC 之 Stable Diffusion 生成的带文字图片示例
    文字文字为HOTAIGC网址导航效果图片1图片2图片3图片4图片5图片6图片7图片8大家觉得效果如何,要是大家感兴趣下篇分享生成原理及参数。......
  • 简单了解下最近正火的SwissTable
    去年看到字节跳动给golang提了issue建议把map的底层实现改成SwissTable的时候,我就有想写这篇博客了,不过因为种种原因一直拖着。直到最近遇golang官方开始讨论为了是否要接受SwissTable作为map的默认实现,以及实际遇到了一个hashtable有关的问题,促使我重新思考了常见的hashtable算......
  • 用 perfcollect 洞察 Linux 上.NET程序 CPU爆高
    一:背景1.讲故事如果要分析Linux上的.NET程序CPU爆高,按以往的个性我肯定是抓个dump下来做事后分析,这种分析模式虽然不重但也不轻,还需要一定的底层知识,那有没有傻瓜式的CPU爆高分析方式呢?相信有很多朋友知道B站713事件,最终就是用perf找到了那个让cpu100%的lua函......
  • 微软计划在 Direct3D 12 新增工作图功能,可解除 GPU 与 CPU 间通信带宽限制
    导读微软计划在3D图形程序开发接口Direct3D12中加入工作图(WorkGraphs)功能,这项功能可解除目前GPU程序开发模型中的限制,让GPU通用运算能够处理更多的工作负载,更广泛地被应用。IT之家注意到,在传统情况下,GPU的工作负载需要由CPU决定,即GPU运算的每一个结果,都需......
  • Stable-Diffusion-webUI 代码阅读01 —— 从启动开始
    Stable-Diffusion-webUI代码阅读01——从启动开始由于实习工作需要,决定用几天时间阅读一遍stable-diffusion-webui的代码。本文参考知乎专栏,并且做出了一定程度上的改进,感谢大佬!知乎专栏:自动做游戏:AI技术落地于游戏开发-知乎(zhihu.com)最近工作主要侧重于OneFlow框架应......
  • Stable Diffusion修复老照片-图生图
    修复老照片的意义就不多说了,相信大家都明白,这里直接开讲方法。1、原理这个方法需要一个真实模型,以便让修复的照片看起来比较真实,我这里选择:realisticVisionV20,大家有更好的给我推荐哦。还需用搭配两个特殊设置:ControlNetTile:这是一个ControlNet模型,用于放大和补充细节。在......
  • AI绘画StableDiffusion实操教程:冰霜旗袍美女
    飞书原文链接,获取更多资源:AI绘画StableDiffusion实操教程:冰霜旗袍美女前几天分享了StableDiffusion的入门到精通教程:AI绘画:StableDiffusion终极炼丹宝典:从入门到精通但是还有人就问:安装是安装好了,可是为什么生成的图片和你生成的图片差距那么远呢?怎么真实感和质感一个天一个......