Réglage fin du modèle de diffusion stable sur les processeurs Intel

La capacité des modèles de diffusion à générer des images réalistes basées sur des indices textuels a contribué à la vulgarisation de l'intelligence artificielle générative. Les gens ont commencé à utiliser ces modèles dans plusieurs domaines d'application, notamment la synthèse de données et la création de contenu. Hugging Face Hub contient plus de 5 000 modèles de graphes Vinsen pré-formés. Ces modèles, combinés à la bibliothèque Diffusers, facilitent incroyablement la création de workflows de génération d'images ou l'expérimentation de différents workflows de génération d'images.

À l'instar des modèles de transformateur, vous pouvez affiner les modèles de diffusion pour qu'ils génèrent du contenu mieux adapté aux besoins spécifiques de votre entreprise. Au début, vous ne pouviez affiner qu'avec le GPU, mais les choses changent ! Il y a quelques mois, Intel a lancé ses processeurs Xeon de quatrième génération, nommés Sapphire Rapids. Sapphire Rapids comprend l'Advanced Matrix eXtension (AMX) d'Intel, un nouvel accélérateur matériel pour les charges de travail d'apprentissage en profondeur. Dans plusieurs articles de blog précédents, nous avons montré les avantages d'AMX : ajustement fin des modèles de transformateurs NLP , inférence sur les modèles de transformateurs NLP et inférence sur les modèles de diffusion stable .

Cet article explique comment affiner le modèle de diffusion stable sur un cluster de processeurs Intel Xeon de 4e génération. Ce que nous utilisons pour affiner est la technique d'inversion textuelle, qui ne nécessite qu'un petit nombre d'échantillons d'apprentissage pour affiner efficacement le modèle. Dans cet article, on s'en sortira très bien avec 5 échantillons !

Commençons.

Configurer le cluster

Les petits partenaires d'Intel nous ont fourni 4 serveurs hébergés sur Intel Developer Cloud (Intel Developer Cloud, IDC). En tant que plate-forme de services cloud, IDC fournit un environnement de déploiement profondément optimisé par Intel et intègre les derniers processeurs Intel et des piles logicielles aux performances optimales. Les utilisateurs peuvent facilement développer et exécuter leurs charges de travail sur cet environnement.

Chaque serveur que nous avons obtenu était équipé de deux processeurs Intel Xeon de 4e génération, chacun avec 56 cœurs physiques et 112 threads. Voici sa lscpusortie :

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

Nous écrivons les adresses IP des quatre serveurs nodefiledans le fichier, où la première ligne est le serveur principal.

cat << EOF > nodefile
192.168.20.2
192.168.21.2
192.168.22.2
192.168.23.2
EOF

La formation distribuée nécessite sshune communication sans mot de passe entre le nœud maître et les autres nœuds. Si vous n'êtes pas très familier avec cela, vous pouvez vous référer à cet article et le suivre étape par étape pour configurer le sans mot de passe ssh.

Ensuite, nous configurons l'environnement d'exploitation et installons le logiciel requis sur chaque nœud. En particulier, nous avons installé deux bibliothèques optimisées par Intel : oneCCL pour la gestion des communications distribuées et l'extension Intel pour PyTorch (IPEX), qui inclut des optimisations logicielles pour tirer pleinement parti de l'accélération matérielle dans Sapphire Rapids. Nous avons également installé libtcmalloc, qui est une bibliothèque d'allocation de mémoire hautes performances, et ses dépendances logicielles 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

Ensuite, nous clonons le référentiel des diffuseurs sur chaque nœud et installons à partir de la source.

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

Ensuite, nous devons utiliser IPEX diffusers/examples/textual_inversionpour effectuer certaines optimisations sur le script de réglage fin afin d'inclure les optimisations d'IPEX pour diffusersles modèles d'inférence. L'optimisation de l'inférence de ses sous-modèles ne peut pas être effectuée dans la bibliothèque, mais uniquement dans le code du script. Et le réglage fin du modèle Clip-Text peut être effectué par ). Nous importons IPEX et optimisons pour l'inférence sur les modèles U-Net et d'auto-encodeur variationnel (VAE). Enfin, n'oubliez pas que ce changement doit être fait dans le code de chaque nœud.pipelinepipelineaccelerateaccelerate

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:

La dernière étape consiste à télécharger les images de formation. Normalement, nous utiliserions un dossier NFS partagé, mais ici, nous choisissons de télécharger l'image sur chaque nœud pour plus de simplicité. Assurez-vous que le répertoire des images d'entraînement a le même chemin ( ) sur tous les nœuds /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

Les images de formation que nous utilisons sont présentées ci-dessous :

64e2d5f66d69614f80c44542fcf1f3ad.jpeg 30b6d5e6425638eb2a024797df38b92f.jpeg e390af4656e8ffaac23c7ebe6a4f0377.jpeg f5dc9c418f9ce9dfb23253ccf6e94b6d.jpeg fc7b6dea2c2d3596d7c9a095d1406011.jpeg

À ce stade, la configuration du système est terminée. Ensuite, nous commençons à configurer la tâche d'entraînement.

Configurer l'environnement de réglage fin

Utilisez la bibliothèque Accelerate pour faciliter la formation distribuée. Nous devons exécuter sur chaque nœud acclerate configet répondre à quelques questions simples.

Vous trouverez ci-dessous une capture d'écran du nœud maître. Sur les autres nœuds, vous devez rankdéfinir 1, 2 et 3, et laisser les autres réponses identiques.

8e3433ae2ab12e65cf0deea058c57803.png

Enfin, nous devons définir certaines variables d'environnement sur le nœud maître. Ces variables d'environnement sont propagées aux autres nœuds lorsque la tâche de réglage fin démarre. La première ligne définit le nom de l'interface réseau connectée au réseau local sur lequel tous les nœuds s'exécutent. Vous devrez peut-être utiliser ifconfigpour définir le nom de l'interface réseau qui vous convient.

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"

Ok, maintenant nous pouvons commencer à peaufiner.

Affiner le modèle

Nous mpiruncommençons à peaufiner avec , qui nodefileétablit automatiquement une communication distribuée entre les nœuds répertoriés dans . Ici, nous exécutons 16 processus ( -n), avec 4 processus exécutés sur chaque nœud ( -ppn). AccelerateLa bibliothèque configure automatiquement une formation distribuée sur tous les processus.

Nous commençons la commande ci-dessous pour former 200 étapes, cela ne prend que 5 minutes environ .

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

La capture d'écran ci-dessous montre l'état du cluster pendant l'entraînement :

4b30b97d28bb1a3e41e0db27cb2a797c.png

dépannage

La formation distribuée peut parfois être délicate, surtout si vous êtes novice. Les petites erreurs de configuration sur un seul nœud sont les problèmes les plus probables : dépendances manquantes, images stockées à différents endroits, etc.

Vous pouvez vous connecter à chaque nœud et vous entraîner localement pour localiser rapidement les problèmes. Tout d'abord, configurez le même environnement que le nœud maître, puis exécutez :

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

Si la formation démarre avec succès, arrêtez-la et passez au nœud suivant. Si la formation a démarré avec succès sur tous les nœuds, veuillez retourner au nœud principal et vérifier attentivement s'il y a un problème nodefileavec l'environnement et mpirunles commandes. Ne vous inquiétez pas, vous finirez par trouver le problème :).

Générer des images à l'aide du modèle affiné

Après 5 minutes de formation, le modèle formé est enregistré localement, et nous pouvons directement utiliser le pour diffuserscharger pipelinele modèle et générer des images. Mais ici, nous allons utiliser Optimum Intel et OpenVINO pour optimiser davantage le modèle d'inférence. Comme évoqué dans l' article précédent , optimisé pour vous permettre de générer une image en moins de 5 secondes sur un seul CPU !

pip install optimum[openvino]

Nous utilisons le code suivant pour charger le modèle, l'optimiser pour une forme de sortie fixe, et enfin enregistrer le modèle optimisé :

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")

Ensuite, nous chargeons le modèle optimisé, générons 5 images différentes et les sauvegardons :

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")

Ci-dessous, l'image qu'il produit. Étonnamment, il n'a fallu que cinq images pour que le modèle sache dicooqu'il portait des lunettes !

9b2ff2acdff40e3322ccfb73761d6565.png

Vous pouvez également affiner davantage le modèle pour obtenir de meilleurs résultats. Ci-dessous, une image générée par un modèle affiné pour 3k étapes (environ une heure), qui fonctionne assez bien.

07a9fa54ab9f55618d712d55b7bd2eae.png

Résumer

Grâce à la coopération approfondie entre Hugging Face et Intel, vous pouvez désormais utiliser les serveurs CPU Xeon pour générer des images de haute qualité qui répondent aux besoins de votre entreprise. Alors que les processeurs sont généralement moins chers et plus facilement disponibles que le matériel spécialisé tel que les GPU, les processeurs Xeon sont également des généralistes qui peuvent facilement être utilisés pour d'autres tâches productives telles que les serveurs Web, les bases de données, etc. En tant que tels, les processeurs sont un choix logique pour une infrastructure informatique complète et flexible.

Les ressources suivantes sont disponibles pour commencer et peuvent être utilisées selon les besoins :

  • Documentation Diffuseurs

  • Documentation Intel optimale

  • Intel IPEX sur GitHub

  • Ressources pour développeurs pour Intel et Hugging Face

  • Instances de CPU Xeon de 4e génération sur IDC, AWS, GCP et Alibaba Cloud

Si vous avez des questions ou des commentaires, n'hésitez pas à laisser un message sur le forum Hugging Face.

Merci d'avoir lu!


Anglais d'origine : https://hf.co/blog/stable-diffusion-finetuning-intel

Auteur : Julien Simon

Traductrice : Matrix Yao (Yao Weifeng), ingénieur en apprentissage profond d'Intel, travaille sur l'application de modèles de famille de transformateurs sur diverses données modales et sur l'entraînement et le raisonnement de modèles à grande échelle.

Relecture/Composition : zhongdongy (阿东)

Je suppose que tu aimes

Origine blog.csdn.net/HuggingFace/article/details/131820999
conseillé
Classement