Diffusers 文件

理念

Hugging Face's logo
加入 Hugging Face 社群

並獲得增強的文件體驗

開始使用

理念

🧨 Diffusers 提供了跨多種模態的**最先進**的預訓練擴散模型。其目的是作為一個用於推理和訓練的**模組化工具箱**。

我們的目標是建立一個經得起時間考驗的庫,因此我們非常重視 API 設計。

簡而言之,Diffusers 被構建為 PyTorch 的自然擴充套件。因此,我們的大部分設計選擇都基於 PyTorch 的設計原則。讓我們回顧一下最重要的幾條:

可用性優於效能

  • 雖然 Diffusers 有許多內建的效能增強功能(參見記憶體和速度),但模型總是以最高精度和最低最佳化級別載入。因此,預設情況下,如果使用者沒有另行定義,擴散 pipelines 始終在 CPU 上以 float32 精度例項化。這確保了在不同平臺和加速器上的可用性,也意味著執行該庫不需要複雜的安裝。
  • Diffusers 旨在成為一個**輕量級**的包,因此它只有很少的必需依賴項,但有許多可以提高效能的軟依賴項(例如 acceleratesafetensorsonnx 等)。我們努力保持庫的輕量級,以便可以毫無顧慮地將其作為其他包的依賴項新增。
  • Diffusers 偏愛簡單、自解釋的程式碼,而不是濃縮、神奇的程式碼。這意味著像 lambda 函式這樣的簡寫程式碼語法和高階 PyTorch 運算子通常是不受歡迎的。

簡單優於便捷

正如 PyTorch 所言,**顯式優於隱式**,**簡單優於複雜**。這一設計理念在庫的多個部分都有體現:

  • 我們遵循 PyTorch 的 API,使用像DiffusionPipeline.to這樣的方法,讓使用者自己處理裝置管理。
  • 引發簡潔的錯誤訊息優於靜默地糾正錯誤輸入。Diffusers 旨在教導使用者,而不是讓庫儘可能易於使用。
  • 複雜的模型與排程器邏輯被暴露出來,而不是在內部被神奇地處理。排程器/取樣器與擴散模型是分開的,它們之間的依賴關係極小。這迫使使用者編寫展開的去噪迴圈。然而,這種分離使得除錯更容易,並讓使用者在調整去噪過程或更換擴散模型或排程器時有更多的控制權。
  • 擴散 pipeline 中獨立訓練的元件,例如文字編碼器、U-Net 和變分自編碼器,各自擁有自己的模型類。這迫使使用者處理不同模型元件之間的互動,並且序列化格式將模型元件分離到不同的檔案中。然而,這使得除錯和定製變得更加容易。由於 Diffusers 能夠分離擴散 pipeline 的單個元件,DreamBooth 或 Textual Inversion 訓練變得非常簡單。

可調整、貢獻者友好優於抽象

對於庫的大部分內容,Diffusers 採用了Transformers 庫的一個重要設計原則,即偏愛複製貼上的程式碼而不是草率的抽象。這個設計原則非常主觀,與流行的設計原則如不要重複自己 (DRY) 形成鮮明對比。簡而言之,就像 Transformers 對待模型檔案一樣,Diffusers 偏愛為 pipelines 和排程器保持極低的抽象級別和非常自包含的程式碼。函式、長程式碼塊,甚至類都可以在多個檔案中複製,這起初可能看起來像一個糟糕、草率的設計選擇,使得庫難以維護。**然而**,這種設計已被證明對 Transformers 來說非常成功,並且對於社群驅動的開源機器學習庫非常有意義,因為:

  • 機器學習是一個極其快速發展的領域,其中正規化、模型架構和演算法變化迅速,因此很難定義持久的程式碼抽象。
  • 機器學習從業者喜歡能夠快速調整現有程式碼以進行構思和研究,因此他們更喜歡自包含的程式碼,而不是包含許多抽象的程式碼。
  • 開源庫依賴於社群貢獻,因此必須構建一個易於貢獻的庫。程式碼越抽象,依賴關係越多,就越難閱讀,也越難貢獻。貢獻者們會因為害怕破壞重要功能而停止為非常抽象的庫做貢獻。如果對庫的貢獻不會破壞其他基礎程式碼,這不僅對潛在的新貢獻者更具吸引力,而且也更容易並行地審查和貢獻到多個部分。

在 Hugging Face,我們稱這種設計為**單檔案策略**,這意味著某個特定類的幾乎所有程式碼都應該寫在一個單一的、自包含的檔案中。要了解更多關於這個理念的資訊,你可以檢視這篇部落格文章

在 Diffusers 中,我們對 pipelines 和排程器都遵循這一理念,但對於擴散模型只部分遵循。我們不完全遵循這一設計的原因是,幾乎所有的擴散 pipelines,如DDPMStable DiffusionunCLIP (DALL·E 2)Imagen 都依賴於同一個擴散模型,即U-Net

太好了,現在你應該大致理解了為什麼 🧨 Diffusers 被設計成這個樣子 🤗。我們試圖在整個庫中一致地應用這些設計原則。然而,這個理念也有一些小小的例外或一些不幸的設計選擇。如果你對設計有任何反饋,我們非常希望 ❤️ 在 GitHub 上直接聽到

設計理念詳解

現在,讓我們深入瞭解設計理念的一些細節。Diffusers 基本上由三個主要類別組成:pipelines模型排程器。讓我們詳細瞭解每個類別的設計決策。

Pipelines

Pipelines 的設計旨在易於使用(因此不完全遵循簡單優於便捷原則),功能不求完備,應大致視為如何使用模型排程器進行推理的示例。

遵循以下設計原則:

  • Pipelines 遵循單檔案策略。所有 pipelines 都可以在 src/diffusers/pipelines 下的獨立目錄中找到。一個 pipeline 資料夾對應一篇擴散論文/專案/釋出。多個 pipeline 檔案可以聚集在一個 pipeline 資料夾中,就像src/diffusers/pipelines/stable-diffusion所做的那樣。如果 pipelines 共享相似的功能,可以利用# Copied from 機制
  • 所有 pipelines 都繼承自 DiffusionPipeline
  • 每個 pipeline 由不同的模型和排程器元件組成,這些元件在model_index.json 檔案中記錄,並可以透過與 pipeline 屬性相同的名稱訪問,並且可以使用DiffusionPipeline.components函式在 pipelines 之間共享。
  • 每個 pipeline 都應該可以透過DiffusionPipeline.from_pretrained函式載入。
  • Pipelines 應該**僅**用於推理。
  • Pipelines 應該非常易讀、自解釋,並且易於調整。
  • Pipelines 應該被設計成可以相互構建,並且易於整合到更高級別的 API 中。
  • Pipelines **不**旨在成為功能完備的使用者介面。對於功能完備的使用者介面,應參考InvokeAIDiffuzerslama-cleaner
  • 每個 pipeline 都應該有且只有一種透過 __call__ 方法執行它的方式。__call__ 引數的命名應該在所有 pipelines 中共享。
  • Pipelines 應該以它們旨在解決的任務命名。
  • 在幾乎所有情況下,新穎的擴散 pipelines 都應在新的 pipeline 資料夾/檔案中實現。

模型

模型被設計為可配置的工具箱,是PyTorch 的 Module 類的自然擴充套件。它們只部分遵循**單檔案策略**。

遵循以下設計原則:

  • 模型對應於**一種模型架構型別**。例如,UNet2DConditionModel 類用於所有期望 2D 影像輸入並以某些上下文為條件的 U-Net 變體。
  • 所有模型都可以在src/diffusers/models中找到,並且每種模型架構都應在其自己的檔案中定義,例如unets/unet_2d_condition.pytransformers/transformer_2d.py等。
  • 模型**不**遵循單檔案策略,應該利用更小的模型構建塊,例如attention.pyresnet.pyembeddings.py等。**注意**:這與 Transformers 的建模檔案形成鮮明對比,表明模型並不真正遵循單檔案策略。
  • 模型旨在暴露覆雜性,就像 PyTorch 的 Module 類一樣,並提供清晰的錯誤訊息。
  • 所有模型都繼承自 ModelMixinConfigMixin
  • 當不要求重大程式碼更改、保持向後相容性並能帶來顯著的記憶體或計算增益時,模型可以進行效能最佳化。
  • 模型預設應該具有最高精度和最低效能設定。
  • 要整合新的模型檢查點,如果其通用架構可以歸類為 Diffusers 中已有的架構,則應調整現有模型架構以使其與新檢查點相容。只有當模型架構根本不同時,才應建立新檔案。
  • 模型的設計應易於擴充套件以適應未來的變化。這可以透過限制公共函式引數、配置引數以及“預見”未來的變化來實現,例如,新增可以輕鬆擴充套件到未來新型別的string“...type”引數通常比添加布爾型is_..._type引數更好。為了使新的模型檢查點能夠工作,對現有架構的更改應儘可能少。
  • 模型設計是在保持程式碼可讀性和簡潔性與支援許多模型檢查點之間的一個困難權衡。對於大部分建模程式碼,應為新的模型檢查點調整類,但在某些情況下,為了確保程式碼長期保持簡潔和可讀,最好新增新的類,例如U-Net 塊注意力處理器

排程器

排程器負責在推理過程中引導去噪過程,以及為訓練定義噪聲排程。它們被設計為具有可載入配置檔案的獨立類,並嚴格遵循**單檔案策略**。

遵循以下設計原則:

  • 所有排程器都可以在src/diffusers/schedulers中找到。
  • 排程器**不**允許從大型工具檔案中匯入,並且應保持非常自包含。
  • 一個排程器 Python 檔案對應一個排程器演算法(可能在論文中定義)。
  • 如果排程器共享相似的功能,我們可以利用 # Copied from 機制。
  • 所有排程器都繼承自 SchedulerMixinConfigMixin
  • 排程器可以透過 ConfigMixin.from_config 方法輕鬆更換,具體細節在這裡有詳細解釋。
  • 每個排程器都必須有一個 set_num_inference_steps 和一個 step 函式。set_num_inference_steps(...) 必須在每個去噪過程之前呼叫,即在呼叫 step(...) 之前。
  • 每個排程器透過一個 timesteps 屬性暴露要“迴圈遍歷”的時間步長,這是一個模型將被呼叫的時間步長陣列。
  • step(...) 函式接受一個預測的模型輸出和“當前”樣本 (x_t),並返回“前一個”、稍微去噪更多的樣本 (x_t-1)。
  • 鑑於擴散排程器的複雜性,step 函式不暴露所有複雜性,可能有點像一個“黑匣子”。
  • 在幾乎所有情況下,新穎的排程器都應在新的排程檔案中實現。
< > 在 GitHub 上更新

© . This site is unofficial and not affiliated with Hugging Face, Inc.