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