Buckets:
Çıkarımı hızlandır
Diffusion modelleri, gürültünün belirli bir "adım" sayısı boyunca kademeli olarak bir görüntüye veya videoya dönüştürüldüğü iteratif bir süreç olduğu için çıkarım sırasında yavaştır. Bu süreci hızlandırmak için farklı schedulers ile deneyler yapabilir, daha hızlı hesaplamalar için model ağırlıklarının hassasiyetini düşürebilir, daha bellek verimli dikkat mekanizmaları kullanabilir ve daha fazlasını yapabilirsiniz.
Bu teknikleri birleştirerek ve birlikte kullanarak, herhangi bir tekniğin tek başına kullanılmasından daha hızlı çıkarım yapabilirsiniz.
Bu kılavuz, çıkarımın nasıl hızlandırılacağını ele alacaktır.
Model veri türü
Model ağırlıklarının hassasiyeti ve veri tipi, daha yüksek hassasiyetin yüklenmesi için daha fazla bellek ve hesaplamaların yapılması için daha fazla zaman gerektirmesi nedeniyle çıkarım hızını etkiler. PyTorch, model ağırlıklarını varsayılan olarak float32 veya tam hassasiyette yükler, bu nedenle veri tipini değiştirmek, daha hızlı çıkarım elde etmenin basit bir yoludur.
bfloat16, float16'ye benzer ancak sayısal hatalara karşı daha dayanıklıdır. bfloat16 için donanım desteği değişkenlik gösterse de, en son nesil GPU'ların çoğu bfloat16 desteğine sahiptir.
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'ye benzer ancak sayısal hatalara daha yatkın olabilir.
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) modu, NVIDIA Ampere GPU'lerde desteklenir ve konvolüsyon ile matris çarpma işlemlerini tf32'de hesaplar. Depolama ve diğer işlemler float32'de tutulur. Bu, bfloat16 veya float16 ile birleştirildiğinde önemli ölçüde daha hızlı hesaplama sağlar.
PyTorch varsayılan olarak yalnızca konvolüsyonlar için tf32 modunu etkinleştirir ve matris çarpımları için bunu açıkça etkinleştirmeniz gerekir.
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.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]
Daha fazla ayrıntı için karma hassasiyetli eğitim belgelerine bakın.
Ölçekli nokta çarpımı dikkati
Bellek verimli dikkat, çıkarım hızını ve bellek kullanımını optimize eder!
Scaled dot product attention (SDPA), FlashAttention, xFormers ve yerel bir C++ uygulaması olmak üzere çeşitli dikkat (attention) arka uçlarını (backend) uygular. Donanımınız için en optimal arka ucu otomatik olarak seçer.
PyTorch >= 2.0 kullanıyorsanız SDPA varsayılan olarak etkinleştirilir ve kodunuzda ek değişiklikler gerektirmez. Ancak kendi dikkat mekanizmanızı seçmek isterseniz, diğer dikkat arka uçlarıyla deneyler yapmayı deneyebilirsiniz. Aşağıdaki örnek, verimli dikkati etkinleştirmek için torch.nn.attention.sdpa_kernel bağlam yöneticisini kullanır.
from torch.nn.attention import SDPBackend, sdpa_kernel
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"
with sdpa_kernel(SDPBackend.EFFICIENT_ATTENTION):
image = pipeline(prompt, num_inference_steps=30).images[0]
torch.compile
torch.compile, PyTorch kodunu ve işlemlerini optimize edilmiş çekirdeklere derleyerek çıkarımı hızlandırır. Diffusers genellikle UNet, transformer veya VAE gibi daha fazla hesaplama yoğunluğuna sahip modelleri derler.
Maksimum hız için aşağıdaki derleyici ayarlarını etkinleştirin (daha fazla seçenek için tam listeye bakın).
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
UNet ve VAE'yi yükleyip derleyin. Seçebileceğiniz birkaç farklı mod vardır, ancak "max-autotune", CUDA grafiğine derleyerek en hızlı hızı optimize eder. CUDA grafikleri, birden fazla GPU işlemini tek bir CPU işlemiyle başlatarak etkin bir şekilde yükü azaltır.
With PyTorch 2.3.1, you can control the caching behavior of torch.compile. This is particularly beneficial for compilation modes like
"max-autotune"which performs a grid-search over several compilation flags to find the optimal configuration. Learn more in the Compile Time Caching in torch.compile tutorial.
Bellek yerleşimini channels_last olarak değiştirmek, belleği ve çıkarım hızını da optimize eder.
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.vae.to(memory_format=torch.channels_last)
pipeline.unet = torch.compile(
pipeline.unet, mode="max-autotune", fullgraph=True
)
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]
Derleme ilk seferde yavaştır, ancak bir kez derlendikten sonra önemli ölçüde daha hızlıdır. Derlenmiş hattı yalnızca aynı türde çıkarım işlemleri için kullanmaya çalışın. Derlenmiş hattı farklı bir görüntü boyutuyla çağırmak, yavaş ve verimsiz olan derlemeyi yeniden tetikler.
Dinamik şekil derlemesi
Daha iyi destek için her zaman PyTorch'un nightly sürümünü kullanmayı unutmayın.
torch.compile, girdi şekillerini ve koşulları takip eder ve bunlar farklıysa modeli yeniden derler. Örneğin, bir model 1024x1024 çözünürlüklü bir görüntü üzerinde derlenip farklı bir çözünürlüğe sahip bir görüntüde kullanılırsa yeniden derleme tetiklenir.
Yeniden derlemeyi önlemek için, koşullar değiştiğinde yeniden derlemeyi önlemek amacıyla daha dinamik bir çekirdek üretmeye çalışmak için dynamic=True ekleyin.
+ torch.fx.experimental._config.use_duck_shape = False
+ pipeline.unet = torch.compile(
pipeline.unet, fullgraph=True, dynamic=True
)
use_duck_shape=False parametresini belirtmek, derleyicinin aynı olan giriş boyutlarını temsil etmek için aynı sembolik değişkeni kullanıp kullanmaması gerektiğini belirtir. Daha fazla ayrıntı için bu yorumuna göz atın.
Tüm modeller, hazır olarak dinamik derlemeden faydalanmayabilir ve değişiklikler gerektirebilir. Dinamik derlemeden faydalanmak için AuraFlowPipeline uygulamasını iyileştiren bu PR'a bakın.
Bir Diffusers modeli için dinamik derleme beklenildiği gibi çalışmıyorsa bir sorun (issue) açmaktan çekinmeyin.
Bölgesel derleme
Bölgesel derleme, bir modelin yalnızca küçük ve sık tekrarlanan blok(lar)ını - genellikle bir transformer katmanı - derleyerek soğuk başlatma gecikmesini azaltır ve derlenmiş artefaktların her sonraki kullanımında yeniden kullanılmasını sağlar. Birçok difüzyon mimarisi için bu, tam grafik derlemesiyle aynı çalışma zamanı hızlanmalarını sağlar ve derleme süresini 8-10 kat kısaltır.
Aşağıda gösterildiği gibi, transformer modeli gibi herhangi bir bileşende, torch.compile işlevini saran yardımcı olan compile_repeated_blocks() yöntemini kullanın.
# pip install -U diffusers
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"
# compile only the repeated transformer layers inside the UNet
pipeline.unet.compile_repeated_blocks(fullgraph=True)
Yeni bir model için bölgesel derlemeyi etkinleştirmek için, derlemek istediğiniz blokların sınıf adlarını (dizeler olarak) içeren bir _repeated_blocks özniteliğini model sınıfına ekleyin.
class MyUNet(ModelMixin):
_repeated_blocks = ("Transformer2DModel",) # ← compiled by default
Daha fazla bölgesel derleme örneği için referans PR'na bakın.
Ayrıca Accelerate içinde, derlenecek aday blokları otomatik olarak seçen bir compile_regions metodu da vardır. Kalan grafik ayrı olarak derlenir. Hangi blokların derleneceğini belirlemek veya derleme bayraklarını ayarlamak için çok fazla seçenek olmadığından, bu durum hızlı deneyler için faydalıdır.
# 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() bilinçli olarak açık bir yapıdadır. Tekrarlanacak blokları _repeated_blocks içinde listeleyin ve yardımcı işlev yalnızca bu blokları derler. Bu, önbellek yeniden kullanımını tek satır kodda öngörülebilir bir davranış ve kolay bir çıkarım süreci sunar.
Grafik kırılmaları
Altta yatan modelde grafik kırılmalarının (graph break) olmamasını sağlamak için torch.compile içinde fullgraph=True belirtmek önemlidir. Bu sayede performans düşüşü yaşamadan torch.compile'in avantajlarından yararlanabilirsiniz. UNet ve VAE için bu durum, dönüş değişkenlerine erişim şeklinizi değiştirir.
- latents = unet(
- latents, timestep=timestep, encoder_hidden_states=prompt_embeds
-).sample
+ latents = unet(
+ latents, timestep=timestep, encoder_hidden_states=prompt_embeds, return_dict=False
+)[0]
GPU senkronizasyonu
step() fonksiyonu, gürültü giderici bir tahmin yaptıktan sonra her seferinde zamanlayıcıda çağrılır ve sigmas değişkeni dizine alınır. GPU'ya yerleştirildiğinde, CPU ile GPU arasındaki iletişim senkronizasyonu nedeniyle gecikmeye neden olur. Gürültü giderici zaten derlenmişse bu durum daha belirgin hale gelir.
Genel olarak, iletişim senkronizasyonunu ve gecikmesini önlemek için sigmas CPU'da kalmalıdır.
Difüzyon modelleri için
torch.compileile performansı en üst düzeye çıkarmak için torch.compile and Diffusers: A Hands-On Guide to Peak Performance blog yazısına bakın.
Benchmarks
Derlenmiş boru hatları için çıkarım gecikmesi ve bellek kullanımı verilerini görmek için diffusers/benchmarks veri setine başvurun.
diffusers-torchao deposu, Flux ve CogVideoX'in derlenmiş sürümlerine ait performans ölçümleme sonuçlarını da içerir.
Çekirdekler
Kernels, Hub üzerinde optimize edilmiş hesaplama çekirdekleri oluşturmak, dağıtmak ve yüklemek için bir kütüphanedir. RMSNorm, GEGLU, RoPE ve AdaLN gibi işlemler için attention çekirdeklerini ve özel CUDA çekirdeklerini destekler.
Diffusers Pipeline Integration kılavuzu, bir çekirdeğin add cuda-kernels becerisiyle nasıl entegre edileceğini gösterir. Bu beceri, Claude veya Codex gibi bir ajanın, belirli bir model ve donanımınıza yönelik özel çekirdekler yazmasını sağlar.
Bir ajanın çekirdek yazmasını öğretmek için add cuda-kernels becerisini yükleyin. Custom kernels for all from Codex and Claude blog yazısı bunu daha ayrıntılı olarak ele alıyor.
Örneğin, add cuda-kernels becerisiyle oluşturulan özel bir RMSNorm çekirdeği, torch.compile ile birlikte H100 üzerinde LTX-Video üretimini 1.43x hızlandırır.
Xet Storage Details
- Size:
- 19.5 kB
- Xet hash:
- 78ed3692fc246f12ddc3a043e175f138eaa66972f179f0afef519cfc05632ec6
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.