Buckets:

mishig's picture
|
download
raw
17.5 kB

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

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

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

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

يُشبه 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]

float16 مشابه لـ bfloat16 لكنه قد يكون أكثر عرضة للأخطاء العددية.

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"

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

يُؤمَّن وضع TensorFloat-32 (tf32) على وحدات معالجة الرسوميات من NVIDIA Ampere والأحدث، حيث يُنفّذ عمليات الالتفاف وضرب المصفوفات في tf32. وتبقى التخزين والعمليات الأخرى في float32. فهو يُسرّع العمليات التي تعمل في float32، لذا يكون أكثر فائدة عندما يبقى خط الأنابيب أو أجزاء منه في float32.

PyTorch only enables tf32 mode for convolutions by default and you'll need to explicitly enable it for matrix multiplications.

import torch
from diffusers import StableDiffusionXLPipeline

torch.backends.cuda.matmul.allow_tf32 = True

pipeline = StableDiffusionXLPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0", dtype=torch.float32
).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.

Xet Storage Details

Size:
17.5 kB
·
Xet hash:
43f2c20d186adc7ae7da4e3356f8094f76f8541eff4715a027864f28d5861674

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.