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

news2025/1/11 4:50:22

扩散模型能够根据文本提示生成逼真的图像,这种能力促进了生成式人工智能的普及。人们已经开始把这些模型用在包括数据合成及内容创建在内的多个应用领域。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

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

64e2d5f66d69614f80c44542fcf1f3ad.jpeg30b6d5e6425638eb2a024797df38b92f.jpege390af4656e8ffaac23c7ebe6a4f0377.jpegf5dc9c418f9ce9dfb23253ccf6e94b6d.jpegfc7b6dea2c2d3596d7c9a095d1406011.jpeg

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

配置微调环境

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

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

8e3433ae2ab12e65cf0deea058c57803.png

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

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

4b30b97d28bb1a3e41e0db27cb2a797c.png

排障

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

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

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 命令是否有问题。不用担心,最终你会找到问题的 :)。

使用微调模型生成图像

经过 5 分钟的训练,训得的模型就保存在本地了,我们可以直接用 diffuserspipeline 加载该模型并进行图像生成。但这里,我们要使用 Optimum Intel 和 OpenVINO 以进一步对模型进行推理优化。正如 上一篇文章 中所讨论的,优化后,仅用单颗 CPU 就能让你在不到 5 秒的时间内生成一幅图像!

pip install optimum[openvino]

我们用下面的代码来加载模型,并对其针对固定输出形状进行优化,最后保存优化后的模型:

from optimum.intel.openvino import OVStableDiffusionPipeline

model_id = "./textual_inversion_output"

ov_pipe = OVStableDiffusionPipeline.from_pretrained(model_id, export=True)
ov_pipe.reshape(batch_size=5, height=512, width=512, num_images_per_prompt=1)
ov_pipe.save_pretrained("./textual_inversion_output_ov")

然后,我们加载优化后的模型,生成 5 张不同的图像并保存下来:

from optimum.intel.openvino import OVStableDiffusionPipeline

model_id = "./textual_inversion_output_ov"

ov_pipe = OVStableDiffusionPipeline.from_pretrained(model_id, num_inference_steps=20)
prompt = ["a yellow <dicoo> robot at the beach, high quality"]*5
images = ov_pipe(prompt).images
print(images)
for idx,img in enumerate(images):
    img.save(f"image{idx}.png")

下面是其生成的图像。令人惊艳的是,模型只需要五张图像就知道 dicoo 是戴眼镜的!

9b2ff2acdff40e3322ccfb73761d6565.png

你还可以对模型进行更多的微调,以期获得更好的效果。下面是一个经 3 千步 (大约一个小时) 微调而得的模型生成的图像,效果相当不错。

07a9fa54ab9f55618d712d55b7bd2eae.png

总结

得益于 Hugging Face 和英特尔的深度合作,现在大家可以用至强 CPU 服务器来生成满足各自业务需求的高质量图像。而 CPU 通常比 GPU 等专用硬件更便宜且更易得,同时至强 CPU 还是个多面手,它可以轻松地用于其他生产任务,如 Web 服务器、数据库等等不一而足。因此,CPU 理所当然地成为了 IT 基础设施的一个功能全面且灵活的备选方案。

以下资源可供入门,你可按需使用:

  • Diffusers 文档

  • Optimum Intel 文档

  • GitHub 上的 英特尔 IPEX

  • 英特尔和 Hugging Face 的 开发者资源

  • IDC、AWS 、GCP 以及 阿里云 上的第四代至强 CPU 实例

如果你有任何疑问或反馈,欢迎到 Hugging Face 论坛 留言。

感谢垂阅!


英文原文: https://hf.co/blog/stable-diffusion-finetuning-intel

原文作者: Julien Simon

译者: Matrix Yao (姚伟峰),英特尔深度学习工程师,工作方向为 transformer-family 模型在各模态数据上的应用及大规模模型的训练推理。

审校/排版: zhongdongy (阿东)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/781426.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Qt】安装Qt 5.7.1 MSVC2013 64bit版本的说明

【Qt】安装Qt 5.7.1 MSVC2013 64bit版本的说明 1、背景2、安装Qt 5.7.13、运行Qt Creator 1、背景 刚开始Qt是C库&#xff0c;后来Qt发展就越来越强大了。后来Qt 发展成为一套跨平台C图形用户界面应用程序开发框架。 注意它不但可以开发GUI程序&#xff0c;而且也可用于开发非…

【数据架构】Data Fabric 架构是实现数据管理和集成现代化的关键

D&A 领导者应该了解数据编织架构的关键支柱&#xff0c;以实现机器支持的数据集成。 在日益多样化、分布式和复杂的环境中&#xff0c;数据管理敏捷性已成为组织的任务关键优先事项。为了减少人为错误和总体成本&#xff0c;数据和分析 (D&A) 领导者需要超越传统的数据…

LangChain+LLM大模型问答能力搭建与思考

1. 背景 最近&#xff0c;大模型&#xff08;LLMs&#xff0c;Large Language Models&#xff09;可谓是NLP领域&#xff0c;甚至整个科技领域最火热的技术了。凑巧的是&#xff0c;我本人恰好就是NLP算法工程师&#xff0c;面临着被LLMs浪潮淘汰的窘境&#xff0c;决定在焦虑…

【趟坑记录】d3.zoom()的正确使用姿势 @d3.v7

【趟坑记录】d3.zoom()的正确使用姿势 d3.v7 文章目录 【趟坑记录】d3.zoom()的正确使用姿势 d3.v7问题重现原因分析解决方案放缩平移写法特殊修改transform函数的写法 总结 在开发一个D3应用的时候遇到了一个 zoom相关的问题&#xff0c;记录解决思路与方案 问题重现 最近在…

nodejs+vue+elementui学习交流和学习笔记分享系统

Node.js 是一个基于 Chrome JavaScript 运行时建立的一个平台。 前端技术&#xff1a;nodejsvueelementui,视图层其实质就是vue页面&#xff0c;通过编写vue页面从而展示在浏览器中&#xff0c;编写完成的vue页面要能够和控制器类进行交互&#xff0c;从而使得用户在点击网页进…

【Hello mysql】 mysql的事务

Mysql专栏&#xff1a;Mysql 本篇博客简介&#xff1a;介绍mysql的事务 mysql的事务 事务的概念事务功能测试事务的隔离级别如何理解隔离性&#xff08;粗浅理解&#xff09;隔离级别查看和设置隔离级别四种隔离级别详解读 -- 未提交读 - 提交可重复读串行化一致性的理解 总结 …

前端学习——ajax (Day4)

同步代码和异步代码 回调函数地狱和 Promise 链式调用 回调函数地狱 Promise - 链式调用 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge&quo…

python识别极验4滑块验证码实战

闲得无聊&#xff0c;趁着休息研究了一下极验4滑块验证码的安全性&#xff0c;是否有机器识别、自动化拖拽的可能性。首先看一下效果 如何识别验证码 1、下载图片 下载图片可以参考博客《采集极验4滑块验证码图片数据》 2、标记图片 3、标记滑动距离 实现代码 __author__ &…

算法与数据结构(二十一)前缀和数组差分数组

前缀和技巧适用于快速、频繁地计算一个索引区间内的元素之和。 1. 一维数组中的前缀和 先看一道例题&#xff0c;力扣第 303 题「区域和检索 - 数组不可变」&#xff0c;让你计算数组区间内元素的和&#xff0c;这是一道标准的前缀和问题&#xff1a; 题目要求你实现这样一个…

多线程(JavaEE初阶系列2)

目录 前言&#xff1a; 1.什么是线程 2.为什么要有线程 3.进程与线程的区别与联系 4.Java的线程和操作系统线程的关系 5.多线程编程示例 6.创建线程 6.1继承Thread类 6.2实现Runnable接口 6.3继承Thread&#xff0c;使用匿名内部类 6.4实现Runnable接口&#xff0c;使…

nodejs+vue+elementui学生选课系统awwm9

前端技术&#xff1a;nodejsvueelementui,视图层其实质就是vue页面&#xff0c;通过编写vue页面从而展示在浏览器中&#xff0c;编写完成的vue页面要能够和控制器类进行交互&#xff0c;从而使得用户在点击网页进行操作时能够正常。 可以设置中间件来响应 HTTP 请求。 (3) 教…

详细总结Webpack5的配置和使用

打包工具 使用框架&#xff08;React、Vue&#xff09;&#xff0c;ES6 模块化语法&#xff0c;Less/Sass 等 CSS预处理器等语法进行开发的代码要想在浏览器运行必须经过编译成浏览器能识别的 JS、CSS 等语法&#xff0c;才能运行。 所以需要打包工具帮我们做完这些事。除此之…

微信小程序学习笔记(三)——视图与逻辑

页面导航 什么是页面导航 页面导航指的是页面之间的相互跳转。例如&#xff0c;浏览器中实现页面导航的方式有如下两种&#xff1a; <a> 链接location.href 小程序中实现页面导航的两种方式 声明式导航、 在页面上声明一个 <navigator> 导航组件通过点击 <…

R语言手动安装包

包安装问题解决方案 1. Biocmanager安装 2. 手动安装 文章目录 包安装问题解决方案前言一、Rstudio手动安装二、conda手动安装R包2.1 在Linux环境中使用R2.2 anaconda官网包下载 总结 前言 大家好✨&#xff0c;这里是bio&#x1f996;。点赞关注不迷路。在上一篇blog中为大家…

Tabby - 本地化AI代码自动补全 - Linux Debian

参考&#xff1a; https://github.com/TabbyML/tabby Docker | Tabby Linux Debian上快速安装Docker并运行_Entropy-Go的博客-CSDN博客 Tabby - 本地化AI代码自动补全 - Windows10_Entropy-Go的博客-CSDN博客 为什么选择Tabby 已经有好几款类似强劲的代码补全工具&#xf…

自动驾驶感知系统-摄像头

车载摄像头的工作原理&#xff0c;首先是采集图像&#xff0c;将图像转换为二维数据&#xff1b;然后&#xff0c;对采集的图像进行模式识别&#xff0c;通过图像匹配算法识别行驶过程中的车辆、行人、交通标识等&#xff1b;最后&#xff0c;依据目标物体的运动模式或使用双目…

(202307)wonderful-sql:基础查询与排序(task2)

教程链接&#xff1a;Datawhale - 一个热爱学习的社区 知识学习 前提&#xff1a; 上一次任务中提出了本课程的用表&#xff0c;但是我并没有加入这个表&#xff0c;这次学习前先对这个表进行插入。 INSERT INTO product VALUES(0001, T恤衫, 衣服, 1000, 500, 2009-09-20)…

[Linux笔记]gdb调试器常用指令

gcc/g形成的可执行程序默认是release版的。若要生成debug版&#xff0c;应使用-g选项。 如&#xff1a;gcc -o mytest test.c -g -stdc99 可以看到debug版包含了调试信息&#xff1a; 使用&#xff1a;gdb 文件名&#xff1a; 补充&#xff1a; 以下所有的查看指令都不会影…

CMU 15-445 -- Parallel Execution - 11

CMU 15-445 -- Join Algorithms - 11 引言Parallel & DistributedInter-query vs. Intra-query Parallelism Process ModelApproach #1: Process per DBMS WorkerApproach #2: Process PoolApproach #3: Thread per DBMS Worker Execution ParallelismInter-query Parallel…

基于SpringBoot+vue的滴答拍摄影项目设计与实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…