Buckets:

mishig's picture
|
download
raw
18.2 kB

Felsefe

🧨 Diffusers, birden fazla modalitede en son teknolojiye sahip önceden eğitilmiş difüzyon modelleri sunar. Amacı, hem çıkarım hem de eğitim için modüler bir araç kutusu olarak hizmet etmektir.

Zamanın testine dayanacak bir kütüphane inşa etmeyi hedeflediğimiz için API tasarımına büyük önem veriyoruz.

Kısaca, Diffusers, PyTorch'un doğal bir uzantısı olarak tasarlanmıştır. Bu nedenle, tasarım tercihlerimizin çoğu PyTorch Tasarım İlkeleri'ne dayanmaktadır. En önemlilerine göz atalım:

Performans yerine Kullanılabilirlik

  • Diffusers, birçok yerleşik performans artırıcı özelliğe sahip olsa da (bkz. Hafıza ve Hız), modeller her zaman en yüksek hassasiyetle ve en düşük optimizasyonla yüklenir. Bu nedenle, kullanıcı tarafından aksi belirtilmedikçe difüzyon hatları varsayılan olarak CPU üzerinde ve float32 hassasiyetiyle örneklenir. Bu durum, farklı platformlar ve hızlandırıcılar arasında kullanılabilirliği garanti eder ve kütüphanenin çalıştırılması için karmaşık kurulumların gerekli olmamasını sağlar.
  • Diffusers, hafif bir paket olmayı hedefler ve bu nedenle çok az zorunlu bağımlılığı vardır; ancak performansı iyileştirebilen (ör. accelerate, safetensors, onnx vb.) birçok isteğe bağlı bağımlılığı bulunur. Kütüphanenin mümkün olan en hafif hâlinde tutulmasına özen gösteriyoruz; böylece diğer paketlere bağımlılık olarak eklendiğinde endişe verici bir yük oluşturmadan kullanılabilir.
  • Diffusers, yoğunlaştırılmış ve sihirli kod yerine basit ve kendi kendini açıklayan kodu tercih eder. Bu, lambda fonksiyonları gibi kısa yoldan kod sözdizimleri ve gelişmiş PyTorch operatörlerinin genellikle istenmediği anlamına gelir.

Basit ve kolay

PyTorch’ün belirttiği gibi, açık olan, örtük olandan iyidir ve basit olan, karmaşıktan iyidir. Bu tasarım felsefesi, kütüphanenin birden fazla bölümünde kendini gösterir:

  • Kullanıcının cihaz yönetimini ele alabilmesi için DiffusionPipeline.to gibi yöntemlerle PyTorch API'sini takip ediyoruz.
  • Sessizce hatalı girdiyi düzeltmek yerine, öz hata mesajları fırlatmak tercih edilir. Diffusers, kütüphaneyi mümkün olduğunca kullanımı kolay hale getirmek yerine, kullanıcıyı eğitmeyi hedefler.
  • Karmaşık model ve zamanlayıcı mantığı, içinde sihirli bir şekilde ele alınmak yerine dışa açılır. Zamanlayıcılar/Örnekleyiciler, birbirlerine minimum bağımlılıkla difüzyon modellerinden ayrıştırılır. Bu, kullanıcının açılmış gürültü azaltma döngüsünü yazmasını zorunlu kılar. Ancak bu ayrıştırma, hata ayıklamayı kolaylaştırır ve kullanıcının gürültü azaltma sürecini uyarlaması veya difüzyon modellerini ya da zamanlayıcıları değiştirmesi üzerinde daha fazla kontrol sağlar.
  • Difüzyon hattının ayrı ayrı eğitilen bileşenleri, örneğin metin kodlayıcı, unet ve varyasyonel otoenkoder, her birinin kendi model sınıfına sahiptir. Bu durum, kullanıcının farklı model bileşenleri arasındaki etkileşimi yönetmesini zorunlu kılar ve seri hale getirme biçimi model bileşenlerini farklı dosyalara ayırır. Bununla birlikte, bu yapı daha kolay hata ayıklama ve özelleştirme imkanı sunar. DreamBooth veya Textual Inversion eğitimi Diffusers'ın difüzyon hattının tek bileşenlerini ayırabilme yeteneği sayesinde çok basittir.

Ayarlanabilir, katkıda bulunmaya uygun soyutlama katmanı

Kütüphanenin büyük bir bölümünde Diffusers, Transformers kütüphanesinin önemli bir tasarım ilkesini benimser: aceleci soyutlamalardan ziyade kopyala-yapıştır kodu tercih etmek. Bu tasarım ilkesi oldukça görüşlüdür ve Kendini tekrarlama (DRY) gibi popüler tasarım ilkeleriyle keskin bir tezat oluşturur. Kısacası, tıpkı Transformers'ın modelleme dosyaları için yaptığı gibi, Diffusers da pipeline'lar ve zamanlayıcılar için son derece düşük bir soyutlama düzeyini ve çok kendi kendine yeten kodu tercih eder. Fonksiyonlar, uzun kod blokları ve hatta sınıflar, ilk bakışta kütüphaneyi bakımsız kılacak kötü ve özensiz bir tasarım tercihi gibi görünen şekilde birden fazla dosya arasında kopyalanabilir. Bununla birlikte, bu tasarım Transformers için son derece başarılı kanıtlanmış ve topluluk odaklı, açık kaynak makine öğrenimi kütüphaneleri için çok mantıklıdır çünkü:

  • Makine Öğrenimi, paradigmaların, model mimarilerinin ve algoritmaların hızla değiştiği son derece hızlı ilerleyen bir alandır; bu durum, uzun ömürlü kod soyutlamaları tanımlamayı çok zor kılar.
  • Makine Öğrenimi uygulayıcıları, fikir üretimi ve araştırma için mevcut kodu hızla ayarlayabilmeyi tercih eder; bu nedenle birçok soyutlama içeren kod yerine kendi içinde tamamlanmış (self-contained) kodu tercih ederler.
  • Açık kaynak kütüphaneler topluluk katkılarına dayanır ve bu nedenle katkı sunmanın kolay olduğu bir kütüphane oluşturmak zorundadır. Kod ne kadar soyut olursa, bağımlılıklar o kadar artar, okunması ve katkı sunması o kadar zorlaşır. Katkıda bulunanlar, hayati işlevselliği bozma korkusuyla çok soyut kütüphanelere katkı sunmayı basitçe bırakır. Bir kütüphaneye katkı sunmak diğer temel kodu bozamıyorsa, bu durum yalnızca potansiyel yeni katkıda bulunanlar için daha davetkar olmakla kalmaz, aynı zamanda birden fazla parçaya paralel olarak incelemek ve katkı sunmak da daha kolay hale gelir.

Hugging Face'te bu tasarıma tek dosya politikası diyoruz; bu, belirli bir sınıfın neredeyse tüm kodunun tek, kendi içinde tamamlanmış bir dosyada yazılması gerektiği anlamına gelir. Felsefe hakkında daha fazla bilgi edinmek için bu blog yazısına göz atabilirsiniz.

Diffusers'da bu felsefeyi pipeline'lar, zamanlayıcılar ve modeller için eşit şekilde benimsiyoruz. Bu kuraldan önceki bazı eski modeller olduğu gibi korunur; tüm yeni model mimarileri kendi kendine yeten dosyalarında yer alır. Ayrıntılar için aşağıdaki Modeller bölümüne bakın.

Harika, şimdi 🧨 Diffusers'ın neden bu şekilde tasarlandığını genel olarak anlamış olmalısınız 🤗. Bu tasarım ilkelerini kütüphane genelinde tutarlı bir şekilde uygulamaya çalışıyoruz. Yine de, felsefeye dair bazı küçük istisnalar veya bazı talihsiz tasarım tercihleri mevcut. Tasarım hakkında geri bildiriminiz varsa, bunu doğrudan GitHub üzerinden duymaktan memnuniyet duyarız ❤️.

Detaylarda Tasarım Felsefesi

Şimdi tasarım felsefesinin inceliklerine geçelim. Diffusers, modelleri ve zamanlayıcıları çalıştırılabilir bir iş akışında birleştirmek için iki yol sunar: her pipeline sınıfının tek bir görevi olan, monolitik standart pipeline'lar ve birleştirilebilir, blok tabanlı Modular Diffusers. Aşağıdaki bölümler sırasıyla pipeline'ları, modüler pipeline'ları, modelleri ve zamanlayıcıları ele alır.

Hattalar

Pipelines, standart veya modüler olsun, yalnızca çıkarım (inference) için tasarlanmıştır. Kullanımı kolay olacak şekilde tasarlanmıştır (bu nedenle Simple over easy ilkesini %100 uygulamazlar): okunabilir, kendi kendini açıklayan, kolayca ayarlanabilir ve modellerin ile zamanlayıcıların nasıl kullanılacağına dair örnekler olarak en iyi şekilde değerlendirilmelidir. Özellik bakımından eksiksiz değildirler. Diffusers üzerine eksiksiz özelliklere sahip kullanıcı arayüzleri oluşturmak için Modular Diffusers kullanın.

Aşağıdaki tasarım ilkeleri takip edilir:

  • Pipelines follow the single-file policy. All pipelines can be found in individual directories under src/diffusers/pipelines. One pipeline folder corresponds to one diffusion paper/project/release. Multiple pipeline files can be gathered in one pipeline folder, as it’s done for src/diffusers/pipelines/stable-diffusion. If pipelines share similar functionality, one can make use of the # Copied from mechanism.
  • Tüm Pipelines, DiffusionPipeline'den devralır.
  • Her pipeline, model_index.json dosyasında belgelenen, pipeline öznitelikleri olarak aynı adla erişilebilen ve DiffusionPipeline.components işleviyle pipelinelar arasında paylaşılabilen farklı model ve zamanlayıcı bileşenlerinden oluşur.
  • Her pipeline, DiffusionPipeline.from_pretrained işlevi üzerinden yüklenebilir olmalıdır.
  • Her pipeline, __call__ yöntemi üzerinden çalıştırılacak tek ve yalnız bir yola sahip olmalıdır. __call__ argümanlarının adlandırılması tüm pipeline'lar arasında tutarlı olmalıdır.
  • Pipelines, çözmek üzere tasarlandıkları görevin adını taşımalıdır.

Modüler Diffusers

Modular Diffusers, standart pipeline'lerin birleştirilebilir alternatifi olarak öne çıkar. Yeniden kullanılabilir pipeline bloklarından oluşan, karıştırıp eşleştirebileceğiniz, değiştirebileceğiniz ve paylaşabileceğiniz bir iş akışı oluşturursunuz. Standart pipeline'lar, modellerin ve zamanlayıcıların nasıl kullanılacağına dair gevşek referans örnekleridir. Modular Diffusers, Diffusers üzerine tam özellikli kullanıcı arayüzleri oluşturmak ve topluluğun yeni pipeline'ları merkeziyetsiz bir şekilde oluşturup paylaşması için önerilen yoldur.

Aşağıdaki tasarım ilkeleri takip edilir:

  • Modüler hatlar, tek dosya politikasını izler. Her biri src/diffusers/modular_pipelines/ altında kendi klasöründe bulunur ve klasör, iş akışını aşama başına bir dosya olacak şekilde böler: encoders.py, before_denoise.py, denoise.py ve decoders.py. İki dosya daha hattı tamamlar. modular_blocks_<model>.py aşamaları bir araya getirir ve modular_pipeline.py, model başına ModularPipeline alt sınıfını tanımlar. Modüler hatlar birbirine çapraz içe aktarma yapmaz.
  • Each modular pipeline is defined as a set of ModularPipelineBlocks. Leaf blocks live in the stage files (encoders.py, before_denoise.py, denoise.py, decoders.py), and modular_blocks_<model>.py assembles them into the full workflow with container classes like SequentialPipelineBlocks and AutoPipelineBlocks. This splits apart two concepts that DiffusionPipeline combines. A block is a pure definition. It declares inputs, outputs, and component dependencies, but holds no weights and can't run. A ModularPipeline, created with .init_pipeline(repo_id), is the runnable counterpart. Keeping blocks stateless and weight-free is what makes them freely composable, swappable, and shareable across workflows.
  • Yeni bir görevi desteklemek için, görev özel blokları yazın, bunları mevcut bloklarla birleştirin ve üst düzey blok montajında iş akışını _workflow_map içinde kaydedin. Tek bir ModularPipeline, metinden görüntüye, görüntüden görüntüye ve inpainting gibi birçok iş akışını destekleyebilirken, bir DiffusionPipeline yalnızca birini çalıştırır.

Tasarım ve kullanım kılavuzunun tamamı için Modular Diffusers belgelerini inceleyin.

Modeller

Modeller, PyTorch'un Module sınıfının doğal uzantıları olan yapılandırılabilir araç kutuları olarak tasarlanmıştır. tek dosya politikasına uymalıdırlar. Bu konvansiyondan önceki bazı eski modeller olduğu gibi korunmuştur. Bunları yeni modeller için takip edilecek kalıplar olarak değil, eski istisnalar olarak değerlendirin. Örneğin, orijinal UNet2DConditionModel sınıfı birkaç UNet varyasyonu için kullanılmıştır.

Aşağıdaki tasarım ilkeleri takip edilir:

  • Her model mimari türü, src/diffusers/models altında kendi klasöründe bulunur; örneğin transformers/, autoencoders/ veya unets/. Her model ailesi, o klasör içinde kendi dosyasına sahiptir; örneğin transformer_flux.py ve transformer_wan.py.
  • Modeller tek dosya politikasını izler. Her model dosyası, timestep gömme ve normalizasyon katmanları gibi her modelin aynı şekilde kullandığı küçük sayıda standart modül dışında kendi içinde tamamlanmış olmalıdır. Bunları embeddings.py ve normalization.py dosyalarından içe aktarın.
  • Modeller, PyTorch'un Module sınıfı gibi karmaşıklığı ortaya koymayı amaçlar ve açık hata mesajları verir.
  • Tüm modeller ModelMixin ve ConfigMixin sınıflarından devralır.
  • Kodda büyük değişiklikler gerektirmemesi, geriye dönük uyumluluğu koruması ve önemli ölçüde bellek veya hesaplama kazancı sağlaması koşullarını sağladığında modeller performans için optimize edilebilir.
  • Modeller varsayılan olarak en yüksek hassasiyete ve en düşük performans ayarına sahip olmalıdır.
  • Mevcut bir mimariye benzer yeni bir model mimarisi entegre etmek için, başlangıç noktası olarak mevcut dosyayı kopyalayın ve uyarlayın. Aynı kalan katmanlarda # Copied from etiketlerini kullanın ki make fix-copies bunları senkronize tutabilsin.

Zamanlayıcılar

Schedulers, hem çıkarım sırasında gürültü azaltma sürecini yönlendirmekten hem de eğitim için bir gürültü zamanlaması tanımlamaktan sorumludur. Bunlar, yüklenebilir yapılandırma dosyalarına sahip bireysel sınıflar olarak tasarlanmıştır ve tek dosya politikasını sıkı bir şekilde uygular.

Aşağıdaki tasarım ilkeleri takip edilir:

  • Tüm zamanlayıcılar src/diffusers/schedulers içinde bulunur.
  • Schedulers, büyük yardımcı dosyalardan içe aktarıma izinli değildir ve çok kendi kendine yeten bir yapıda tutulmalıdır.
  • Bir zamanlayıcı Python dosyası, bir zamanlayıcı algoritmasına (bir makalede tanımlanmış olabileceği gibi) karşılık gelir.
  • Eğer zamanlayıcılar benzer işlevlere sahipse, # Copied from mekanizmasından yararlanabiliriz.
  • Tüm zamanlayıcılar SchedulerMixin ve ConfigMixin sınıflarından devralır.
  • Zamanlayıcılar, burada ayrıntılı olarak açıklandığı gibi ConfigMixin.from_config yöntemiyle kolayca değiştirilebilir.
  • Her zamanlayıcının bir set_num_inference_steps ve bir step fonksiyonu olmalıdır. set_num_inference_steps(...), her gürültü azaltma sürecinden önce, yani step(...) çağrılmadan önce yani çağrılmalıdır.
  • Her zamanlayıcı, modelin çağrılacağı zaman adımlarından oluşan bir dizi olan timesteps özniteliği aracılığıyla üzerinde "döngü yapılacak" zaman adımlarını açığa çıkarır.
  • step(...) fonksiyonu, tahmini model çıktısını ve "mevcut" örneği (x_t) alır ve "önceki", biraz daha gürültüsü azaltılmış örneği (x_t-1) döndürür.
  • Difüzyon zamanlayıcılarının karmaşıklığı göz önüne alındığında, step fonksiyonu tüm bu karmaşıklığı ortaya koymaz ve biraz "siyah kutu" gibi davranabilir.
  • Neredeyse tüm durumlarda, yeni zamanlayıcılar yeni bir zamanlama dosyasında uygulanmalıdır.

Xet Storage Details

Size:
18.2 kB
·
Xet hash:
4095fc6171ea6b83e1f76930e1a092bc235086064425cd87fb615c7b617ea3d9

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