Diffusers documentation

الدقة والتجميع

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.43.0).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

الدقة والتجميع

الدقة المنخفضة والتجميع هما طريقتان لتسريع استنتاج Diffusers. حمّل الأوزان بـ bfloat16 أو float16، ثم اجمع مُزيل الضوضاء (UNet أو transformer) باستخدام torch.compile أو التجميع الإقليمي.

نوع بيانات النموذج

تؤثر دقة أوزان النموذج ونوع البيانات على سرعة الاستدلال، لأن الدقة الأعلى تتطلب ذاكرة أكبر للتحميل ووقتًا أطول لتنفيذ العمليات الحسابية. يقوم Diffusers بتحميل أوزان النموذج بنوع float32 عند إهمال dtype، لذا فإن تغيير نوع البيانات طريقة بسيطة للحصول بسرعة على استدلال أسرع.

bfloat16
float16
TensorFloat-32

يُشبه bfloat16 النوع float16 لكنه أكثر مقاومةً للأخطاء العددية. يختلف دعم الأجهزة للنوع bfloat16، لكن معظم وحدات معالجة الرسوميات الحديثة قادرة على دعم bfloat16.

import torch
from diffusers import StableDiffusionXLPipeline

pipeline = StableDiffusionXLPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0", dtype=torch.bfloat16
).to("cuda")  # or "mps", "xpu", "cpu"

prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"
pipeline(prompt, num_inference_steps=30).images[0]

انتباه منتج نقطي مُصعّد

انتباه حاصل الضرب النقطي المُقَيَّم (SDPA) هو الانتباه الافتراضي في PyTorch 2.0 وما بعده، من خلال AttnProcessor2_0 أو الخلفية native لمُوزِّع الانتباه. يختار PyTorch نواة SDPA مناسبة لعطادتك. لمزيد من المعلومات حول FlashAttention وSageAttention وxFormers وأنوية Hub وغيرها من الخلفيات، راجع خلفيات الانتباه.

torch.compile

يسرّع torch.compile الاستدلال من خلال ترميز كود PyTorch وعملياته إلى نوى مُحسّنة. عادةً ما يتم ترميز مُزيل الضوضاء الذي يستهلك معظم وقت التشغيل، وهو إما pipeline.unet أو pipeline.transformer، وأحيانًا يتم ترميز VAE أيضًا.

فعّل إعدادات المُجمِّع التالية للحصول على أقصى سرعة (راجع القائمة الكاملة لمعرفة المزيد من الخيارات).

import torch
from diffusers import StableDiffusionXLPipeline

torch._inductor.config.conv_1x1_as_mm = True
torch._inductor.config.coordinate_descent_tuning = True
torch._inductor.config.epilogue_fusion = False
torch._inductor.config.coordinate_descent_check_all_directions = True

حمّل مُزيل الضوضاء ووحدة الترميز/الفك (VAE) وجمعهما. استخدم pipeline.unet في خطوط أنابيب UNet مثل Stable Diffusion XL، أو pipeline.transformer في خطوط أنابيب Flux وأنماط DiT. هناك عدة أوضاع مختلفة يمكنك الاختيار من بينها، لكن "max-autotune" يبحث عن أسرع النوى (kernels) ويستخدم رسوميات CUDA. تقلل رسوميات CUDA من العبء الإضافي من خلال إطلاق عمليات GPU متعددة عبر عملية CPU واحدة.

يمكن أن يؤدي تغيير تخطيط الذاكرة إلى channels_last أيضًا إلى تسريع النماذج التي تعتمد بشكل كبير على الالتفاف مثل UNets وVAEs. قم بإجراء اختبار الأداء أولاً، لأن بعض النماذج تعمل بشكل أبطأ.

pipeline = StableDiffusionXLPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0", dtype=torch.float16
).to("cuda")  # or "mps", "xpu", "cpu"
pipeline.unet.to(memory_format=torch.channels_last)
pipeline.unet = torch.compile(
    pipeline.unet, mode="max-autotune", fullgraph=True
)
pipeline.vae.to(memory_format=torch.channels_last)
pipeline.vae.decode = torch.compile(
    pipeline.vae.decode,
    mode="max-autotune",
    fullgraph=True
)

prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"
pipeline(prompt, num_inference_steps=30).images[0]

تكون عملية التجميع بطيئة في المرة الأولى، خاصةً عند استخدام "max-autotune"، لأن المُجمِّع يبحث عن الأنوية (kernels) ثم يستمر في استخدام نفس كائن خط الأنابيب المُجمَّع لاحقًا (انظر تخزين وقت التجميع مؤقتًا وإعدادات التخزين المؤقت لمعرفة كيفية تكوين سلوك التخزين المؤقت). استدعاء خط الأنابيب المُجمَّع على حجم صورة مختلف يُطلق عملية إعادة تجميع.

تجميع الأشكال الديناميكية

يحافظ torch.compile على تتبع أشكال المدخلات والشروط، وإذا كانت هذه مختلفة، يعيد تجميع النموذج. على سبيل المثال، إذا تم تجميع نموذج على صورة بدقة 1024x1024 واستُخدم على صورة بدقة مختلفة، فإن ذلك يستدعي إعادة التجميع.

لتجنب إعادة التجميع، أضف dynamic=True لمحاولة توليد نواة (kernel) أكثر ديناميكية لتجنب إعادة التجميع عند تغيّر الشروط.

+ torch.fx.experimental._config.use_duck_shape = False
+ pipeline.unet = torch.compile(
    pipeline.unet, fullgraph=True, dynamic=True
)

يُوجِّه تحديد use_duck_shape=False المُجمِّع (Compiler) بشأن ما إذا كان ينبغي له استخدام المتغير الرمزي نفسه لتمثيل أحجام المدخلات المتطابقة. لمزيد من التفاصيل، راجع هذا تعليق.

قد لا تستفيد جميع النماذج من التجميع الديناميكي بشكل مباشر وقد تتطلب تعديلات. راجع هذا PR الذي حسّن تنفيذ AuraFlowPipeline للاستفادة من التجميع الديناميكي.

لا تتردد في فتح مشكلة إذا لم يعمل التجميع الديناميكي كما هو متوقع لنموذج Diffusers.

التجميع الإقليمي

يقوم التجميع الإقليمي بتقليل زمن بدء التشغيل البارد من خلال تجميع الكتلة أو الكتل الصغيرة والمتكررة بشكل متكرر من النموذج - وهي عادةً طبقة محوّلة - مما يتيح إعادة استخدام المخرجات المُجمَّعة لكل ظهور تالٍ. بالنسبة للعديد من معماريات الانتشار، يوفر هذا تسريعًا وقت التشغيل مماثلًا لتجميع المخطط الكامل، ويمكنه تقليل زمن التجميع بنسبة تصل إلى 8-10 أضعاف.

استخدم طريقة compile_repeated_blocks()، وهي أداة مساعدة تغلف torch.compile، على مُزيل الضوضاء. استدعِها على pipeline.unet أو pipeline.transformer، اعتماداً على خط الأنابيب.

import torch
from diffusers import StableDiffusionXLPipeline

pipeline = StableDiffusionXLPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    dtype=torch.float16,
).to("cuda")  # or "mps", "xpu", "cpu"
pipeline.unet.compile_repeated_blocks(fullgraph=True)

لتفعيل التجميع الإقليمي لنموذج جديد، اضبط _repeated_blocks على أسماء فئات الكتل المتكررة (نصوص). بالنسبة إلى UNet الخاص بـ SDXL، استخدم BasicTransformerBlock. تدرج مُزيلات الضوضاء التحويلية أسماء فئات كتلها المتكررة بنفس الطريقة.

_repeated_blocks = ["BasicTransformerBlock"]

يوجد أيضاً طريقة compile_regions في Accelerate تختار تلقائياً الكتل المرشحة داخل النموذج لتجميعها. يتم تجميع بقية الرسم البياني بشكل منفصل. وهذا مفيد للتجارب السريعة لأنه لا توجد خيارات كثيرة لتحديد الكتل المراد تجميعها أو تعديل أعلام التجميع.

pip install -U accelerate
import torch
from diffusers import StableDiffusionXLPipeline
from accelerate.utils import compile_regions

pipeline = StableDiffusionXLPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0", dtype=torch.float16
).to("cuda")  # or "mps", "xpu", "cpu"
pipeline.unet = compile_regions(pipeline.unet, mode="reduce-overhead", fullgraph=True)

compile_repeated_blocks() صريحةٌ عمدًا. اذكر الكتل التي تريد تكرارها في _repeated_blocks ولن يُجمّع المُساعد سوى تلك الكتل. فهي توفر سلوكًا متوقعًا وسهولةً في الاستدلال حول إعادة استخدام ذاكرة التخزين المؤقت في سطرٍ واحد من الكود.

انقطاعات الرسم البياني

اضبط fullgraph=True حتى يرفع torch.compile خطأً عند حدوث انقطاع في الرسم البياني بدلاً من تقسيمه بصمت، مما يقلل من تسريع الأداء.

مزامنة وحدة معالجة الرسوميات

بعد كل تنبؤ من مُزيل الضوضاء، يستدعي خط الأنابيب طريقة step في المجدول، والتي تُفهرس sigmas. إبقاء sigmas على وحدة معالجة الرسوميات (GPU) قد يفرض مزامنة بين وحدة المعالجة المركزية (CPU) ووحدة معالجة الرسوميات (GPU) في كل خطوة. هذه التكلفة يسهل التغاضي عنها حتى يتم تجميع مُزيل الضوضاء. يُفضَّل إبقاء sigmas على وحدة المعالجة المركزية (CPU) (فمجداول Diffusers مثل Euler يفعلون ذلك بالفعل).

المعايير

راجع مجموعة بيانات diffusers/benchmarks للاطلاع على بيانات زمن الاستدلال واستهلاك الذاكرة للخطوط الأنابيب المُجمّعة.

تحتوي مستودعة diffusers-torchao أيضًا على نتائج قياس الأداء للإصدارات المُجمَّعة من Flux وCogVideoX.

النوى

Kernels هو مكتبة لبناء وتوزيع وتحميل نوى الحساب المُحسَّنة على Hub. يدعم مكتبة attention النوى المخصصة لنوى CUDA للعمليات مثل RMSNorm وGEGLU وRoPE وAdaLN.

يُبيّن دليل تكامل خط أنابيب Diffusers كيفية دمج نواة مع مهارة إضافة cuda-kernels. تُمكّن هذه المهارة وكيلًا، مثل Claude أو Codex، من كتابة نوى مخصصة موجهة نحو نموذج محدد وأجهزتك. ويحتوي منشور نوى مخصصة للجميع من Codex وClaude على مزيد من التفاصيل.

على سبيل المثال، نواة RMSNorm مخصصة (مولّدة بواسطة مهارة add cuda-kernels) مع torch.compile تسرّع توليد LTX-Video بمقدار 1.43x على H100.

التكميم الديناميكي

يتوفر تكميم التفعيل الديناميكي int8 في torchao. استخدم TorchAoConfig مع تكوين مثل Int8DynamicActivationInt8WeightConfig، أو واجهة برمجة التطبيقات quantize_ الخاصة بـ torchao. لا تستخدم مساعد apply_dynamic_quant الأقدم.

مصفوفات الإسقاط المدمجة

~DiffusionPipeline.fuse_qkv_projections تجريبي.

يُستَخرَج مدخل إلى ثلاثة فضاءات فرعية، ممثلة بمصفوفات الإسقاط Q وK وV، داخل كتلة الانتباه. عادةً ما تُحسب هذه الإسقاطات بشكل منفصل، لكن يمكنك دمجها أفقيًا في مصفوفة واحدة وتنفيذ الإسقاط في خطوة واحدة. يزيد هذا من حجم عمليات ضرب المصفوفات الخاصة بإسقاطات المدخلات، كما يحسّن أثر التكميم.

pipeline.fuse_qkv_projections()

الخطوات التالية

Update on GitHub