在 Intel CPU 上微調 Stable Diffusion 模型
擴散模型憑藉其從文字提示生成逼真影像的驚人能力,助力生成式 AI 普及。這些模型現已應用於企業用例,例如合成數據生成或內容創作。Hugging Face Hub 包含 5000 多個預訓練文字到影像模型。將它們與 Diffusers 庫結合使用,啟動實驗和構建影像生成工作流程變得前所未有的簡單。
與 Transformer 模型一樣,您可以微調擴散模型,以幫助它們生成符合您業務需求的內容。最初,微調只能在 GPU 基礎設施上進行,但情況正在改變!幾個月前,Intel 推出了第四代 Xeon CPU,代號 Sapphire Rapids。Sapphire Rapids 引入了 Intel Advanced Matrix Extensions (AMX),這是一種用於深度學習工作負載的新硬體加速器。我們已經在多篇部落格文章中展示了 AMX 的優勢:微調 NLP Transformer、使用 NLP Transformer 進行推理以及使用 Stable Diffusion 模型進行推理。
本文將向您展示如何在 Intel Sapphire Rapids CPU 叢集上微調 Stable Diffusion 模型。我們將使用文字反轉,這是一種只需要少量示例影像的技術。我們將只使用五張!
讓我們開始吧。
設定叢集
我們的朋友 Intel 在 Intel 開發人員雲 (IDC) 上提供了四臺伺服器,IDC 是一個服務平臺,用於在採用最新 Intel 處理器和效能最佳化軟體堆疊的 Intel® 最佳化部署環境中開發和執行工作負載。
每臺伺服器都由兩個 Intel Sapphire Rapids 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
我們首先在 nodefile
中列出伺服器的 IP 地址。第一行指的是主伺服器。
cat << EOF > nodefile
192.168.20.2
192.168.21.2
192.168.22.2
192.168.23.2
EOF
分散式訓練需要在主節點和其他節點之間進行免密碼 ssh
連線。如果您不熟悉此過程,這裡有一篇不錯的文章介紹瞭如何實現。
接下來,我們在每個節點上建立一個新環境並安裝軟體依賴項。我們特別安裝了兩個 Intel 庫:oneCCL,用於管理分散式通訊,以及 Intel Extension for PyTorch (IPEX),用於利用 Sapphire Rapids 中存在的硬體加速功能。我們還添加了 gperftools
來安裝 libtcmalloc
,一個高效能記憶體分配庫。
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 並最佳化 U-Net 和變分自動編碼器模型。請確保此操作應用於所有節點。
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 庫使得執行分散式訓練變得非常容易。我們只需要在每個節點上執行它並回答簡單的問題即可。
以下是主節點的螢幕截圖。在其他節點上,您需要將秩設定為 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 步,這大約需要五分鐘。
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
如果訓練成功啟動,請停止它並轉到下一個節點。如果所有節點上的訓練都成功啟動,請返回主節點並仔細檢查節點檔案、環境和 mpirun
命令。別擔心,您會找到問題的 :)
使用微調模型生成影像
經過 5 分鐘的訓練,模型將儲存在本地。我們可以使用普通的 diffusers
管道載入它並進行預測。相反,讓我們使用 Optimum Intel 和 OpenVINO 來最佳化模型。如上一篇文章所述,這使您可以在不到 5 秒的時間內在單個 CPU 上生成影像!
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")
然後,我們載入最佳化後的模型,生成五張不同的影像並儲存它們。
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")
這是一張生成的影像。令人印象深刻的是,模型僅用了五張影像就學會了 dicoos 戴著眼鏡!

如果您願意,可以進一步微調模型。以下是經過 3000 步訓練(大約一小時訓練)的模型生成的精美示例。

結論
感謝 Hugging Face 和 Intel,您現在可以使用 Xeon CPU 伺服器生成高質量、符合您業務需求的影像。與 GPU 等專用硬體相比,它們通常更經濟實惠且更廣泛可用。Xeon CPU 還可以輕鬆地重新用於其他生產任務,從 Web 伺服器到資料庫,使其成為 IT 基礎設施的多功能靈活選擇。
以下是一些資源可幫助您入門:
- Diffusers 文件
- Optimum Intel 文件
- Intel IPEX 在 GitHub 上
- Intel 和 Hugging Face 提供的開發人員資源。
- Intel Developer Cloud、AWS 和 GCP 上的 Sapphire Rapids 伺服器。
如果您有任何問題或反饋,我們非常樂意在 Hugging Face 論壇上閱讀。
感謝閱讀!