PyTorch 設計哲學¶
本文件旨在協助貢獻者和模組維護者瞭解 PyTorch 中隨著時間推移而發展出來的高階設計原則。這些並非硬性規定,而是作為一個指南,以協助在開發 PyTorch 時權衡不同的考量和解決可能出現的分歧。如需有關貢獻、模組維護以及如何將分歧提交給核心維護者的詳細資訊,請參閱PyTorch 治理。
設計原則¶
原則 1:易用性勝過效能¶
這個原則可能會讓人感到驚訝!正如一位 Hacker News 使用者所寫:*PyTorch 太棒了![…] 雖然我很困惑。一個機器學習框架怎麼可能不執著於速度/效能?* 請參閱Hacker News 上關於 PyTorch 的討論。
Soumith 在發展 PyTorch 社群的部落格文章中深入探討了這一點,但從高階層次來看
- PyTorch 的主要目標是易用性 
- 次要目標是具有*合理的*效能 
我們相信,維持我們的彈性以支援在我們的抽象概念之上建構的學術研究人員仍然至關重要。我們無法預見未來的工作負載會是什麼,但我們知道我們希望它們首先建構在 PyTorch 上,而這需要彈性。
更具體地說,我們以*易用性優先*的方式運作,並試圖避免在沒有清楚瞭解其取捨的情況下,跳到*限制優先*的制度(例如,靜態形狀、僅限圖形模式)。通常,人們會傾向於預先對使用者施加嚴格的限制,因為這樣可以簡化實作,但這伴隨著風險
- 效能可能不值得使用者付出摩擦,因為效能提升不夠引人注目,或者它只適用於相對狹隘的子問題。 
- 即使效能提升引人注目,這些限制也可能將生態系統分割成不同的限制集合,而這些限制很快就會讓使用者難以理解。 
我們希望使用者能夠將他們的 PyTorch 程式碼無縫地移轉到不同的硬體和軟體平台,與不同的函式庫和框架互通,並體驗 PyTorch 使用者體驗的豐富性,而不是最不重要的子集。
原則 2:簡單勝過容易¶
在這裡,我們借用了Python 之禪中的內容
- 明確勝過隱晦 
- 簡單勝過複雜 
更簡潔地描述這兩個目標的方式是簡單勝過容易。讓我們從一個例子開始,因為*簡單*和*容易*在日常英語中經常互換使用。請考慮如何在 PyTorch 中為裝置建模
- **簡單/明確(易於理解、除錯):**每個張量都與一個裝置相關聯。使用者明確指定張量裝置的移動。需要跨裝置移動的運算會導致錯誤。 
- **容易/隱晦(易於使用):**使用者不必擔心裝置;系統會找出全域最佳的裝置配置。 
在這種特定情況下,作為一種通用的設計哲學,PyTorch 傾向於公開簡單且明確的建構模塊,而不是實務者易於使用的 API。簡單的版本對於 PyTorch 新手來說是立即可理解和除錯的:如果在程式中實際呼叫運算子的地方呼叫需要跨裝置移動的運算子,則會收到明確的錯誤。容易的解決方案可能讓新手一開始就能更快上手,但除錯這樣的系統可能會很複雜:系統是如何做出決定的?插入這種系統的 API 是什麼?物件在其 IR 中是如何表示的?
支持這種設計的一些經典論點來自於分散式運算筆記(TLDR:不要對效能特徵差異很大的資源進行統一建模,細節會洩漏)和端到端原則(TLDR:在堆疊的較低層級建構智慧功能可能會阻止在較高層級建構高效能的功能,而且通常也行不通)。例如,我們可以在運算子級別或全域裝置移動規則,但精確的選擇並不顯而易見,而且建構一個可擴充的機制會不可避免地帶來複雜性和延遲成本。
這裡需要注意的是,這並不意味著更高級別的“簡單” API 沒有價值;當然,例如,堆疊中的更高級別支持在大型叢集中跨異構計算進行高效的張量計算是有價值的。相反,我們的意思是,專注於簡單的低級構建塊有助於在用戶需要跳脫常規時仍然保持良好的體驗的同時,為簡單的 API 提供信息。它還為創新和更多自以為是的工具的增長提供了空間,其速度是我們在 PyTorch 核心庫中無法支持的,但最終會从中受益,正如我們 豐富的生態系統 所證明的那樣。換句話說,不在一開始就自動化讓我們有可能更快地達到良好的自動化水平。
原則 3:Python 優先,以及一流的語言互操作性¶
這個原則一開始是 **Python 優先**
PyTorch 並不是一個綁定到單一 C++ 框架的 Python 綁定。它的構建是為了與 Python 深度集成。您可以像使用 NumPy、SciPy、scikit-learn 或其他 Python 庫一樣自然地使用它。您可以使用您最喜歡的庫用 Python 本身編寫新的神經網絡層,並使用 Cython 和 Numba 等套件。我們的目標是在適當的情況下不重複造輪子。
多年來,PyTorch 需要處理的一件事是 Python 的開銷:我們首先用 C++ 重寫了 autograd 引擎,然後是大多數運算符定義,然後開發了 TorchScript 和 C++ 前端。
儘管如此,在 Python 中工作仍然可以為我們的用戶提供最佳體驗:它靈活、熟悉,也許最重要的是,它擁有龐大的科學計算庫和擴展生態系統可供使用。這一事實促使我們最近做出了一些貢獻,這些貢獻試圖在接近 Python 可用性曲線末端的地方找到一個帕累托最優點
- TorchDynamo,一個 Python 框架評估工具,能夠在最小限度的人工干預下加速現有的 eager-mode PyTorch 程式。 
- torch_function 和 torch_dispatch 擴展點,它們允許在 C++ 內部構建 Python 優先的功能,例如 torch.fx 追蹤器 和 functorch。 
這些設計原則並不是一成不變的規則,而是來之不易的選擇,它們是我們如何將 PyTorch 打造成今天這樣可調試、可修改和靈活的框架的基礎。隨著我們擁有越來越多的貢獻者和維護者,我們期待著與您一起在我們的庫和生態系統中應用這些核心原則。隨著我們學習新事物和人工智慧領域的發展(我們知道它會發展),我們也樂於對它們進行改進。