Diffusers documentation
Filsafat
Filsafat
🧨 Diffusers menyediakan model difusi pra-terlatih terkini di berbagai modalitas. Tujuannya adalah untuk berfungsi sebagai kotak perkakas modular untuk inferensi dan pelatihan.
Kami bertujuan membangun pustaka yang tahan uji waktu, dan oleh karena itu sangat serius dalam mendesain API.
Secara singkat, Diffusers dibangun sebagai ekstensi alami dari PyTorch. Oleh karena itu, sebagian besar pilihan desain kami didasarkan pada Prinsip Desain PyTorch. Mari kita bahas yang paling penting:
Kegunaan di Atas Performa
- Meskipun Diffusers memiliki banyak fitur bawaan untuk meningkatkan performa (lihat Memory and Speed), model selalu dimuat dengan presisi tertinggi dan optimasi terendah. Oleh karena itu, secara default, pipeline difusi selalu diinstansiasi pada CPU dengan presisi float32 jika tidak didefinisikan lain oleh pengguna. Hal ini memastikan kegunaan di berbagai platform dan akselerator, serta berarti tidak diperlukan instalasi yang rumit untuk menjalankan pustaka ini.
- Diffusers bertujuan menjadi paket yang ringan dan karenanya memiliki sangat sedikit dependensi wajib, tetapi banyak dependensi lunak yang dapat meningkatkan kinerja (seperti
accelerate,safetensors,onnx, dst…). Kami berusaha menjaga pustaka ini tetap seringan mungkin agar dapat ditambahkan sebagai dependensi pada paket lain tanpa banyak kekhawatiran. - Diffusers lebih memilih kode yang sederhana dan dapat menjelaskan dirinya sendiri daripada kode yang ringkas dan magis. Artinya, sintaks kode singkat seperti fungsi lambda dan operator PyTorch tingkat lanjut sering kali tidak diinginkan.
Sederhana dan mudah
Seperti yang dinyatakan oleh PyTorch, eksplisit lebih baik daripada implisit dan sederhana lebih baik daripada kompleks. Filosofi desain ini tercermin di berbagai bagian pustaka:
- Kami mengikuti API PyTorch dengan metode seperti
DiffusionPipeline.tountuk memungkinkan pengguna mengelola perangkat. - Membuat pesan error yang ringkas lebih disarankan daripada memperbaiki input yang salah secara diam-diam. Diffusers bertujuan untuk mengajari pengguna, bukan membuat pustaka ini semudah mungkin digunakan.
- Logika model yang kompleks dibandingkan dengan logika scheduler diekspos alih-alih ditangani secara magis di dalam. Scheduler/Sampler dipisahkan dari model difusi dengan dependensi minimal satu sama lain. Hal ini memaksa pengguna untuk menulis loop denoising yang diurai. Namun, pemisahan ini memungkinkan debugging yang lebih mudah dan memberikan pengguna lebih banyak kendali untuk menyesuaikan proses denoising atau mengganti model difusi atau scheduler.
- Komponen-komponen yang dilatih secara terpisah dalam pipeline difusi, misalnya text encoder, unet, dan variational autoencoder, masing-masing memiliki kelas modelnya sendiri. Hal ini memaksa pengguna untuk menangani interaksi antar komponen model yang berbeda, dan format serialisasi memisahkan komponen model ke dalam file-file yang berbeda. Namun, hal ini memungkinkan debugging dan kustomisasi yang lebih mudah. Pelatihan DreamBooth atau Textual Inversion menjadi sangat sederhana berkat kemampuan Diffusers untuk memisahkan komponen tunggal dari pipeline difusi.
Abstraksi yang dapat disesuaikan dan ramah kontributor
Untuk sebagian besar pustaka, Diffusers mengadopsi prinsip desain penting dari pustaka Transformers, yaitu lebih memilih kode yang disalin-tempel daripada abstraksi yang terburu-buru. Prinsip desain ini sangat opinionated dan bertentangan secara tajam dengan prinsip desain populer seperti Don’t repeat yourself (DRY). Singkatnya, sama seperti yang dilakukan Transformers untuk file pemodelan, Diffusers lebih memilih untuk menjaga tingkat abstraksi yang sangat rendah dan kode yang sangat mandiri untuk pipeline dan scheduler. Fungsi, blok kode panjang, dan bahkan kelas dapat disalin ke beberapa file yang pada awalnya mungkin terlihat seperti pilihan desain yang buruk dan ceroboh yang membuat pustaka sulit dipelihara. Namun, desain ini telah terbukti sangat sukses untuk Transformers dan sangat masuk akal untuk pustaka machine learning open-source yang didorong oleh komunitas karena:
- Machine Learning adalah bidang yang berkembang sangat pesat, di mana paradigma, arsitektur model, dan algoritma berubah dengan cepat, sehingga sangat sulit untuk mendefinisikan abstraksi kode yang bertahan lama.
- Praktisi Machine Learning menyukai kemampuan untuk dengan cepat menyesuaikan kode yang sudah ada untuk ideasi dan penelitian, sehingga mereka lebih memilih kode yang mandiri (self-contained) daripada kode yang mengandung banyak abstraksi.
- Perpustakaan sumber terbuka bergantung pada kontribusi komunitas dan oleh karena itu harus membangun perpustakaan yang mudah untuk berkontribusi. Semakin abstrak kodenya, semakin banyak dependensi, semakin sulit dibaca, dan semakin sulit untuk berkontribusi. Kontributor secara sederhana berhenti berkontribusi pada perpustakaan yang sangat abstrak karena takut merusak fungsionalitas vital. Jika berkontribusi pada perpustakaan tidak dapat merusak kode fundamental lainnya, tidak hanya hal itu lebih mengundang bagi kontributor baru potensial, tetapi juga lebih mudah untuk meninjau dan berkontribusi pada beberapa bagian secara paralel.
Di Hugging Face, kami menyebut desain ini sebagai single-file policy, yang berarti hampir semua kode dari kelas tertentu harus ditulis dalam satu file yang mandiri. Untuk membaca lebih lanjut tentang filosofi ini, Anda dapat melihat artikel blog ini.
Di Diffusers, kami mengikuti filosofi ini untuk pipeline, scheduler, dan model. Beberapa model lama mendahului konvensi ini dan tetap dipertahankan apa adanya; semua arsitektur model baru berada di file mandiri yang terpisah. Lihat bagian Models di bawah untuk detailnya.
Bagus, sekarang Anda seharusnya sudah memahami secara umum mengapa 🧨 Diffusers dirancang seperti ini 🤗. Kami berusaha menerapkan prinsip desain ini secara konsisten di seluruh pustaka. Namun, ada beberapa pengecualian kecil terhadap filosofi tersebut atau beberapa pilihan desain yang kurang beruntung. Jika Anda memiliki masukan mengenai desain, kami akan ❤️ senang mendengarnya langsung di GitHub.
Filosofi Desain Secara Rinci
Sekarang masuk ke detail teknis dari filosofi desain. Diffusers memberikan Anda dua cara untuk menyusun model dan scheduler menjadi workflow yang dapat dijalankan: pipeline standar, yang bersifat monolitik dengan satu tugas per kelas pipeline, dan Modular Diffusers, yang bersifat komposabel dan berbasis blok. Bagian-bagian di bawah ini membahas pipeline, pipeline modular, model, dan scheduler secara berurutan.
Pipelines
Pipelines, baik standar maupun modular, hanya ditujukan untuk inferensi. Mereka dirancang agar mudah digunakan (sehingga tidak 100% mengikuti Simple over easy): mudah dibaca, mudah dipahami, mudah disesuaikan, dan sebaiknya dipandang sebagai contoh cara menggunakan models dan schedulers. Mereka tidak memiliki fitur lengkap. Untuk membangun antarmuka pengguna yang lengkap di atas Diffusers, gunakan Modular Diffusers.
Prinsip-prinsip desain berikut diikuti:
- 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. - Semua Pipelines mewarisi dari DiffusionPipeline.
- Setiap pipeline terdiri dari komponen model dan scheduler yang berbeda, yang didokumentasikan dalam file
model_index.json, dapat diakses sebagai atribut pipeline dengan nama yang sama, dan dapat dibagikan antar pipeline dengan fungsiDiffusionPipeline.components. - Setiap pipeline harus dapat dimuat melalui fungsi
DiffusionPipeline.from_pretrained. - Setiap pipeline harus memiliki satu dan hanya satu cara untuk menjalankannya melalui metode
__call__. Penamaan argumen__call__harus konsisten di semua pipeline. - Pipelines harus diberi nama sesuai dengan tugas yang ingin diselesaikan.
Diffusers Modular
Modular Diffusers adalah alternatif yang dapat dikomposisikan dari pipeline standar. Anda membangun alur kerja dari blok pipeline yang dapat digunakan kembali, yang bisa dicampur, dipadukan, ditukar, dan dibagikan. Pipeline standar adalah contoh referensi longgar tentang cara menggunakan model dan scheduler. Modular Diffusers adalah jalur yang direkomendasikan untuk membangun antarmuka pengguna yang lengkap dengan fitur di atas Diffusers, dan bagi komunitas untuk membangun serta membagikan pipeline baru secara terdesentralisasi.
Prinsip-prinsip desain berikut diikuti:
- Pipeline modular mengikuti kebijakan satu file. Masing-masing berada di foldernya sendiri di bawah src/diffusers/modular_pipelines/, dan folder tersebut membagi alur kerja menjadi satu file per tahap:
encoders.py,before_denoise.py,denoise.py, dandecoders.py. Dua file lainnya melengkapi pipeline.modular_blocks_<model>.pymerangkai tahap-tahap tersebut, danmodular_pipeline.pymendefinisikan subkelas ModularPipeline per model. Pipeline modular tidak saling mengimpor. - Setiap pipeline modular didefinisikan sebagai kumpulan ModularPipelineBlocks. Blok daun berada di file tahap (
encoders.py,before_denoise.py,denoise.py,decoders.py), danmodular_blocks_<model>.pymerangkainya menjadi alur kerja lengkap dengan kelas kontainer seperti SequentialPipelineBlocks dan AutoPipelineBlocks. Hal ini memisahkan dua konsep yangDiffusionPipeline combines. Sebuah blok adalah definisi murni. Blok menyatakan input, output, dan dependensi komponen, tetapi tidak menyimpan bobot dan tidak dapat dijalankan. ModularPipeline, yang dibuat dengan.init_pipeline(repo_id), adalah padanan yang dapat dijalankan. Menjaga blok tetap tanpa status dan tanpa bobot adalah yang membuatnya dapat dikomposisikan, ditukar, dan dibagikan secara bebas di antara alur kerja. - Untuk mendukung tugas baru, tulis blok yang spesifik untuk tugas tersebut, gabungkan dengan blok yang sudah ada, dan daftarkan alur kerja di
_workflow_mappada perakitan blok tingkat atas. SatuModularPipelinedapat mendukung banyak alur kerja, seperti teks-ke-gambar, gambar-ke-gambar, dan inpainting, sedangkanDiffusionPipelinehanya menjalankan satu.
Lihat dokumentasi Modular Diffusers untuk panduan desain dan penggunaan lengkap.
Model
Model dirancang sebagai kotak alat yang dapat dikonfigurasi, yang merupakan perpanjangan alami dari kelas Module PyTorch. Model harus mengikuti kebijakan satu file. Beberapa model lama dibuat sebelum konvensi ini dan tetap dipertahankan apa adanya. Perlakukan model tersebut sebagai pengecualian legacy, bukan pola yang harus diikuti untuk model baru. Sebagai contoh, kelas UNet2DConditionModel asli digunakan untuk beberapa variasi UNet.
Prinsip-prinsip desain berikut diikuti:
- Setiap tipe arsitektur model berada di foldernya sendiri di bawah src/diffusers/models, misalnya transformers/, autoencoders/, atau unets/. Setiap keluarga model memiliki file tersendiri di dalam folder tersebut, seperti transformer_flux.py dan transformer_wan.py.
- Model mengikuti kebijakan file tunggal. Setiap file model harus mandiri, kecuali sejumlah kecil modul standar yang digunakan secara identik oleh setiap model, seperti embedding timestep dan lapisan normalisasi. Impor modul tersebut dari embeddings.py dan normalization.py.
- Model dirancang untuk mengekspos kompleksitas, sama seperti kelas
Moduledari PyTorch, dan memberikan pesan kesalahan yang jelas. - Semua model mewarisi dari
ModelMixindanConfigMixin. - Model dapat dioptimalkan untuk performa ketika hal tersebut tidak memerlukan perubahan kode yang besar, tetap menjaga kompatibilitas mundur, dan memberikan peningkatan memori atau komputasi yang signifikan.
- Model secara default harus memiliki pengaturan presisi tertinggi dan kinerja terendah.
- Untuk mengintegrasikan arsitektur model baru yang mirip dengan arsitektur yang sudah ada, salin file yang ada sebagai titik awal dan sesuaikan. Gunakan anotasi
# Copied frompada lapisan yang tetap identik agarmake fix-copiesmenjaganya tetap sinkron.
Penjadwal
Schedulers bertanggung jawab untuk memandu proses denoising saat inferensi serta mendefinisikan jadwal noise untuk pelatihan. Mereka dirancang sebagai kelas individual dengan file konfigurasi yang dapat dimuat dan sangat mengikuti kebijakan file tunggal.
Prinsip-prinsip desain berikut diikuti:
- Semua scheduler dapat ditemukan di
src/diffusers/schedulers. - Schedulers tidak diizinkan untuk mengimpor dari file utils yang besar dan harus dijaga agar sangat mandiri.
- Satu file Python scheduler berkorespondensi dengan satu algoritma scheduler (seperti yang mungkin didefinisikan dalam sebuah paper).
- Jika scheduler memiliki fungsionalitas yang serupa, kita dapat memanfaatkan mekanisme
# Copied from. - Semua Schedulers mewarisi dari
SchedulerMixindanConfigMixin. - Schedulers dapat dengan mudah diganti menggunakan metode
ConfigMixin.from_configseperti yang dijelaskan secara rinci di sini. - Setiap scheduler harus memiliki
set_num_inference_steps, dan fungsistep.set_num_inference_steps(...)harus dipanggil sebelum setiap proses denoising, yaitu sebelumstep(...)dipanggil. - Setiap scheduler mengekspos timesteps yang akan “diproses” melalui atribut
timesteps, yaitu array dari timesteps yang akan dipanggil oleh model. - Fungsi
step(...)menerima output model yang diprediksi dan sampel “saat ini” (x_t), lalu mengembalikan sampel “sebelumnya” yang sedikit lebih bebas derau (x_t-1). - Mengingat kompleksitas penjadwal difusi, fungsi
steptidak mengungkapkan seluruh kompleksitas tersebut dan bisa terasa seperti “kotak hitam”. - Dalam hampir semua kasus, penjadwal baru harus diimplementasikan dalam file penjadwalan baru.