# 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](https://pytorch.org/docs/stable/community/design.html#pytorch-design-philosophy). Mari kita bahas yang paling penting:

## Kegunaan di Atas Performa

- Meskipun Diffusers memiliki banyak fitur bawaan untuk meningkatkan performa (lihat [Optimalkan dan skala](../optimization/overview)), 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.to`](../api/pipelines/overview#diffusers.DiffusionPipeline.to) untuk 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 pipeline difusi yang dilatih secara terpisah, *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 yang berbeda. Namun, hal ini memungkinkan debugging dan kustomisasi yang lebih mudah. Pelatihan DreamBooth atau Textual Inversion
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](https://github.com/huggingface/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)](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself). Singkatnya, sama seperti yang dilakukan Transformers untuk file modeling, Diffusers lebih memilih untuk menjaga tingkat abstraksi yang sangat rendah dan kode yang sangat self-contained 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](https://huggingface.co/blog/transformers-design-philosophy).

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](#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](https://github.com/huggingface/diffusers/issues/new?assignees=&labels=&template=feedback.md&title=).

## Filosofi Desain Secara Rinci

Sekarang masuk ke detail teknis dari filosofi desain. Diffusers memberikan Anda dua cara untuk menyusun [model](https://github.com/huggingface/diffusers/tree/main/src/diffusers/models) dan [scheduler](https://github.com/huggingface/diffusers/tree/main/src/diffusers/schedulers) menjadi workflow yang dapat dijalankan: [pipeline](https://github.com/huggingface/diffusers/tree/main/src/diffusers/pipelines) 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](#simple-over-easy)): mudah dibaca, mudah dipahami, mudah disesuaikan, dan sebaiknya dipandang sebagai contoh cara menggunakan [models](#models) dan [schedulers](#schedulers). Mereka tidak memiliki fitur lengkap. Untuk membangun antarmuka pengguna yang lengkap di atas Diffusers, gunakan [Modular Diffusers](../modular_diffusers/overview).

Prinsip-prinsip desain berikut diikuti:
- Pipelines mengikuti kebijakan file tunggal. Semua pipeline dapat ditemukan di direktori individual di bawah src/diffusers/pipelines. Satu folder pipeline sesuai dengan satu paper/proyek/rilis difusi. Beberapa file pipeline dapat dikumpulkan dalam satu folder pipeline, seperti yang dilakukan untuk [`src/diffusers/pipelines/stable-diffusion`](https://github.com/huggingface/diffusers/tree/main/src/diffusers/pipelines/stable_diffusion). Jika pipeline memiliki fungsionalitas yang serupa, seseorang dapat memanfaatkan [# Copied from mechanism](https://github.com/huggingface/diffusers/blob/125d783076e5bd9785beb05367a2d2566843a271/src/diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion_img2img.py#L251).
- Semua Pipelines mewarisi dari [DiffusionPipeline](/docs/diffusers/main/id/api/pipelines/overview#diffusers.DiffusionPipeline).
- Setiap pipeline terdiri dari komponen model dan scheduler yang berbeda, yang didokumentasikan dalam [file `model_index.json`](https://huggingface.co/stable-diffusion-v1-5/stable-diffusion-v1-5/blob/main/model_index.json), dapat diakses sebagai atribut pipeline dengan nama yang sama, dan dapat dibagikan antar pipeline dengan fungsi [`DiffusionPipeline.components`](../api/pipelines/overview#diffusers.DiffusionPipeline.components).
- Setiap pipeline harus dapat dimuat melalui fungsi [`DiffusionPipeline.from_pretrained`](../api/pipelines/overview#diffusers.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/](https://github.com/huggingface/diffusers/tree/main/src/diffusers/modular_pipelines), dan folder tersebut membagi alur kerja menjadi satu file per tahap: `encoders.py`, `before_denoise.py`, `denoise.py`, dan `decoders.py`. Dua file lainnya melengkapi pipeline. `modular_blocks_<model>.py` merangkai tahap-tahap tersebut, dan `modular_pipeline.py` mendefinisikan subkelas [ModularPipeline](/docs/diffusers/main/id/api/modular_diffusers/pipeline#diffusers.ModularPipeline) per model. Pipeline modular tidak saling mengimpor.
- Setiap pipeline modular didefinisikan sebagai kumpulan [ModularPipelineBlocks](/docs/diffusers/main/id/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks). Blok daun berada di file tahap (`encoders.py`, `before_denoise.py`, `denoise.py`, `decoders.py`), dan `modular_blocks_<model>.py` merangkainya menjadi alur kerja lengkap dengan kelas kontainer seperti [SequentialPipelineBlocks](/docs/diffusers/main/id/api/modular_diffusers/pipeline_blocks#diffusers.SequentialPipelineBlocks) dan [AutoPipelineBlocks](/docs/diffusers/main/id/api/modular_diffusers/pipeline_blocks#diffusers.AutoPipelineBlocks). Hal ini memisahkan dua konsep yang `DiffusionPipeline combines`. Sebuah blok adalah definisi murni. Blok menyatakan input, output, dan dependensi komponen, tetapi tidak menyimpan bobot dan tidak dapat dijalankan. [ModularPipeline](/docs/diffusers/main/id/api/modular_diffusers/pipeline#diffusers.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_map` pada perakitan blok tingkat atas. Satu `ModularPipeline` dapat mendukung banyak alur kerja, seperti teks-ke-gambar, gambar-ke-gambar, dan inpainting, sedangkan `DiffusionPipeline` hanya menjalankan satu.

Lihat [dokumentasi Modular Diffusers](../modular_diffusers/overview) untuk panduan desain dan penggunaan lengkap.

### Model

Model dirancang sebagai kotak alat yang dapat dikonfigurasi, yang merupakan perpanjangan alami dari [kelas Module PyTorch](https://pytorch.org/docs/stable/generated/torch.nn.Module.html). Model harus mengikuti *kebijakan satu file*. Beberapa model lama mendahului konvensi ini dan tetap dipertahankan apa adanya. Perlakukan mereka sebagai pengecualian legacy, bukan pola yang harus diikuti untuk model baru. Misalnya, kelas [UNet2DConditionModel](/docs/diffusers/main/id/api/models/unet2d-cond#diffusers.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](https://github.com/huggingface/diffusers/tree/main/src/diffusers/models), misalnya [transformers/](https://github.com/huggingface/diffusers/tree/main/src/diffusers/models/transformers), [autoencoders/](https://github.com/huggingface/diffusers/tree/main/src/diffusers/models/autoencoders), atau [unets/](https://github.com/huggingface/diffusers/tree/main/src/diffusers/models/unets). Setiap keluarga model memiliki file tersendiri di dalam folder tersebut, seperti [transformer_flux.py](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/transformers/transformer_flux.py) dan [transformer_wan.py](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/transformers/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](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/embeddings.py) dan [normalization.py](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/normalization.py).
- Model dirancang untuk mengekspos kompleksitas, sama seperti kelas `Module` dari PyTorch, dan memberikan pesan error yang jelas.
- Semua model mewarisi dari `ModelMixin` dan `ConfigMixin`.
- 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 from`](./contribution#copied-from-mechanism) pada lapisan yang tetap identik agar `make fix-copies` menjaganya 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`](https://github.com/huggingface/diffusers/tree/main/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 `SchedulerMixin` dan `ConfigMixin`.
- Schedulers dapat dengan mudah diganti menggunakan metode [`ConfigMixin.from_config`](../api/configuration#diffusers.ConfigMixin.from_config) seperti yang dijelaskan secara rinci [di sini](../using-diffusers/schedulers).
- Setiap scheduler harus memiliki `set_num_inference_steps`, dan fungsi `step`. `set_num_inference_steps(...)` harus dipanggil sebelum setiap proses denoising, *yaitu* sebelum `step(...)` 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 `step` tidak mengekspos seluruh kompleksitas tersebut dan bisa sedikit menjadi "kotak hitam".
- Dalam hampir semua kasus, penjadwal baru harus diimplementasikan dalam file penjadwalan baru.

