PyTorch 设计理念#
创建于: Jun 10, 2022 | 最后更新于: Apr 16, 2025
本文档旨在帮助贡献者和模块维护者理解 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 模式 PyTorch 程序。
torch_function 和 torch_dispatch 扩展点,它们使得可以在 C++ 内部之上构建 Python 优先的功能,例如 torch.fx tracer 和 functorch。
这些设计原则并非硬性规定,而是艰难选择的结果,并且是我们构建 PyTorch 成为当今可调试、易于修改和灵活的框架的基石。随着我们拥有更多的贡献者和维护者,我们期待与您一起在我们的库和生态系统中应用这些核心原则。我们也乐于在学习新事物和人工智能领域不断发展时对其进行演进,因为我们知道它会如此。