提交 10e4285b 编写于 作者: 绝不原创的飞龙's avatar 绝不原创的飞龙

2024-02-05 14:08:18

上级 b6e05554
# PyTorch 2.2 文档
来源:[https://pytorch.org/docs/stable/](https://pytorch.org/docs/stable/)
来源:[`pytorch.org/docs/stable/`](https://pytorch.org/docs/stable/)
# PyTorch治理 | 构建 + CI
# PyTorch 治理 | 构建 + CI
> 原文:[https://pytorch.org/docs/stable/community/build_ci_governance.html](https://pytorch.org/docs/stable/community/build_ci_governance.html)
> 原文:[`pytorch.org/docs/stable/community/build_ci_governance.html`](https://pytorch.org/docs/stable/community/build_ci_governance.html)
## 如何添加新的维护者[](#how-to-add-a-new-maintainer "跳转到此标题")
要成为维护者,一个人需要:
+PyTorch仓库的相关部分至少提交六次提交。
+ PyTorch 仓库的相关部分至少提交六次提交。
+ 这些提交中至少有一个必须在过去的六个月内提交
要将合格的人员添加到维护者列表中,请创建一个PR,将一个人添加到[感兴趣的人](https://pytorch.org/docs/main/community/persons_of_interest.html)页面和[merge_rules](https://github.com/pytorch/pytorch/blob/main/.github/merge_rules.yaml)文件中。当前维护者将投票支持。批准PR的决策标准:
要将合格的人员添加到维护者列表中,请创建一个 PR,将一个人添加到[感兴趣的人](https://pytorch.org/docs/main/community/persons_of_interest.html)页面和[merge_rules](https://github.com/pytorch/pytorch/blob/main/.github/merge_rules.yaml)文件中。当前维护者将投票支持。批准 PR 的决策标准:
+ 在合并之前至少过去了两个工作日(确保大多数贡献者已经看到)
+ PR具有正确的标签(module: ci)
+ PR 具有正确的标签(module: ci)
+ 当前维护者没有异议
+ 当前维护者中至少有三个网站点赞(或者当模块的维护者少于3人时,所有维护者都投票赞成)。
+ 当前维护者中至少有三个网站点赞(或者当模块的维护者少于 3 人时,所有维护者都投票赞成)。
此差异已折叠。
# PyTorch设计哲学
# PyTorch 设计哲学
> 原文:[https://pytorch.org/docs/stable/community/design.html](https://pytorch.org/docs/stable/community/design.html)
> 原文:[`pytorch.org/docs/stable/community/design.html`](https://pytorch.org/docs/stable/community/design.html)
本文旨在帮助贡献者和模块维护者了解PyTorch中随着时间发展而形成的高层设计原则。这些并不是硬性规则,而是作为指导,帮助权衡不同的考虑因素,并解决在开发PyTorch过程中可能出现的分歧。有关更多贡献信息,模块维护和如何将分歧升级到核心维护者,请参阅[PyTorch Governance](https://pytorch.org/docs/main/community/governance.html)
本文旨在帮助贡献者和模块维护者了解 PyTorch 中随着时间发展而形成的高层设计原则。这些并不是硬性规则,而是作为指导,帮助权衡不同的考虑因素,并解决在开发 PyTorch 过程中可能出现的分歧。有关更多贡献信息,模块维护和如何将分歧升级到核心维护者,请参阅[PyTorch Governance](https://pytorch.org/docs/main/community/governance.html)
## 设计原则
### 原则1:可用性优于性能
### 原则 1:可用性优于性能
这个原则可能会让人感到惊讶!正如一位Hacker News的作者写道:*PyTorch太棒了![…]尽管我感到困惑。一个机器学习框架怎么可能不痴迷于速度/性能?*参见[Hacker News关于PyTorch的讨论](https://news.ycombinator.com/item?id=28066093)
这个原则可能会让人感到惊讶!正如一位 Hacker News 的作者写道:*PyTorch 太棒了![…]尽管我感到困惑。一个机器学习框架怎么可能不痴迷于速度/性能?*参见[Hacker News 关于 PyTorch 的讨论](https://news.ycombinator.com/item?id=28066093)
Soumith在[Growing the PyTorch Community](https://soumith.ch/posts/2021/02/growing-opensource/?fbclid=IwAR1bvN_xZ8avGvu14ODJzS8Zp7jX1BOyfuGUf-zoRawpyL-s95Vjxf88W7s)的博客文章中深入探讨了这一点,但在高层次上:
Soumith [Growing the PyTorch Community](https://soumith.ch/posts/2021/02/growing-opensource/?fbclid=IwAR1bvN_xZ8avGvu14ODJzS8Zp7jX1BOyfuGUf-zoRawpyL-s95Vjxf88W7s)的博客文章中深入探讨了这一点,但在高层次上:
+ PyTorch的主要目标是可用性
+ PyTorch 的主要目标是可用性
+ 一个次要目标是具有*合理*的性能
我们相信保持灵活性以支持在我们的抽象之上构建的研究人员的能力仍然至关重要。我们无法预见工作负载的未来会是什么样子,但我们知道我们希望它们首先建立在PyTorch上,这需要灵活性。
我们相信保持灵活性以支持在我们的抽象之上构建的研究人员的能力仍然至关重要。我们无法预见工作负载的未来会是什么样子,但我们知道我们希望它们首先建立在 PyTorch 上,这需要灵活性。
更具体地说,我们以*可用性为先*的方式运作,并尝试避免在没有清晰看法的情况下跳到*限制为先*的制度(例如,静态形状,仅图模式)。通常会有一种诱惑,即在一开始就对用户施加严格的限制,因为这样可以简化实现,但这也带来了风险:
......@@ -24,39 +24,39 @@ Soumith在[Growing the PyTorch Community](https://soumith.ch/posts/2021/02/growi
+ 即使性能优势引人注目,限制也可能将生态系统分割成不同的限制集,这些限制集很快就会变得令用户难以理解。
我们希望用户能够无缝地将他们的PyTorch代码移植到不同的硬件和软件平台,与不同的库和框架进行互操作,并体验PyTorch用户体验的全部丰富性,而不是最低公共分母子集。
我们希望用户能够无缝地将他们的 PyTorch 代码移植到不同的硬件和软件平台,与不同的库和框架进行互操作,并体验 PyTorch 用户体验的全部丰富性,而不是最低公共分母子集。
### 原则2:简单胜于容易
### 原则 2:简单胜于容易
在这里,我们借鉴了[Python之禅](https://peps.python.org/pep-0020/)
在这里,我们借鉴了[Python 之禅](https://peps.python.org/pep-0020/)
+ *显式胜于隐式*
+ *简单胜于复杂*
描述这两个目标的更简洁方式是[Simple Over Easy](https://www.infoq.com/presentations/Simple-Made-Easy/)。让我们从一个例子开始,因为*简单**容易*在日常英语中经常被互换使用。考虑如何在PyTorch中建模[设备](https://pytorch.org/docs/main/tensor_attributes.html#torch.device)
描述这两个目标的更简洁方式是[Simple Over Easy](https://www.infoq.com/presentations/Simple-Made-Easy/)。让我们从一个例子开始,因为*简单**容易*在日常英语中经常被互换使用。考虑如何在 PyTorch 中建模[设备](https://pytorch.org/docs/main/tensor_attributes.html#torch.device)
+ **简单/显式(易于理解,调试):**每个张量都与一个设备相关联。用户明确指定张量设备移动。需要跨设备移动的操作会导致错误。
+ **容易/隐式(使用):**用户不必担心设备;系统会找出全局最佳设备放置。
在这种特定情况下,以及作为一种一般的设计哲学,PyTorch更倾向于暴露简单和明确的构建块,而不是易于使用的API。简单版本对新的PyTorch用户来说是立即可理解和可调试的:如果在程序中调用需要跨设备移动的操作符,您会在操作符实际调用的地方得到清晰的错误。简单的解决方案可能让新用户最初移动得更快,但调试这样的系统可能会很复杂:系统是如何做出决定的?如何插入这样一个系统的API以及对象在其IR中是如何表示的?
在这种特定情况下,以及作为一种一般的设计哲学,PyTorch 更倾向于暴露简单和明确的构建块,而不是易于使用的 API。简单版本对新的 PyTorch 用户来说是立即可理解和可调试的:如果在程序中调用需要跨设备移动的操作符,您会在操作符实际调用的地方得到清晰的错误。简单的解决方案可能让新用户最初移动得更快,但调试这样的系统可能会很复杂:系统是如何做出决定的?如何插入这样一个系统的 API 以及对象在其 IR 中是如何表示的?
这种设计的一些经典论点来自于[A Note on Distributed Computation](https://dl.acm.org/doi/book/10.5555/974938)(TLDR:不要用非常不同性能特征的资源统一建模,细节会泄漏)和[End-to-End Principle](http://web.mit.edu/Saltzer/www/publications/endtoend/endtoend.pdf)(TLDR:在堆栈的较低层构建智能可以防止在堆栈的较高层构建高性能功能,并且通常也不起作用)。例如,我们可以构建操作级别或全局设备移动规则,但具体选择并不明显,构建一个可扩展的机制会带来不可避免的复杂性和延迟成本。
这里的一个警告是,这并不意味着更高级的“易用”API没有价值;当然,例如,在堆栈的更高层支持在大型集群中跨异构计算进行有效的张量计算是有价值的。相反,我们的意思是专注于简单的低级构建块有助于指导易用API,同时在用户需要离开常规路径时仍保持良好的体验。这也为创新和更具观点的工具的增长提供了空间,这是我们在PyTorch核心库中无法支持的速度,但最终会受益于我们的[丰富生态系统](https://pytorch.org/ecosystem/)。换句话说,不在开始自动化可以让我们更快地达到良好自动化水平的可能性。
这里的一个警告是,这并不意味着更高级的“易用”API 没有价值;当然,例如,在堆栈的更高层支持在大型集群中跨异构计算进行有效的张量计算是有价值的。相反,我们的意思是专注于简单的低级构建块有助于指导易用 API,同时在用户需要离开常规路径时仍保持良好的体验。这也为创新和更具观点的工具的增长提供了空间,这是我们在 PyTorch 核心库中无法支持的速度,但最终会受益于我们的[丰富生态系统](https://pytorch.org/ecosystem/)。换句话说,不在开始自动化可以让我们更快地达到良好自动化水平的可能性。
### 原则3:Python First with Best In Class Language Interoperability(Python优先,具有最佳类语言互操作性)
### 原则 3:Python First with Best In Class Language Interoperability(Python 优先,具有最佳类语言互操作性)
这个原则始于**Python First**
> PyTorch不是Python绑定到一个单片C++框架。它被构建为与Python深度集成。您可以像使用[NumPy](https://www.numpy.org/)、[SciPy](https://www.scipy.org/)、[scikit-learn]((https://scikit-learn.org/)或其他Python库一样自然地使用它。您可以在Python中编写您自己的新神经网络层,使用您喜欢的库,并使用诸如[Cython](https://cython.org/)和[Numba](http://numba.pydata.org/)等包。我们的目标是在适当的情况下不重新发明轮子。
> PyTorch 不是 Python 绑定到一个单片 C++框架。它被构建为与 Python 深度集成。您可以像使用[NumPy](https://www.numpy.org/)、[SciPy](https://www.scipy.org/)、scikit-learn 或其他 Python 库一样自然地使用它。您可以在 Python 中编写您自己的新神经网络层,使用您喜欢的库,并使用诸如[Cython](https://cython.org/)和[Numba](http://numba.pydata.org/)等包。我们的目标是在适当的情况下不重新发明轮子。
多年来PyTorch需要处理的一个问题是Python开销:我们首先用C++重写了自动求导引擎,然后是大部分操作符定义,然后开发了TorchScript和C++前端。
多年来 PyTorch 需要处理的一个问题是 Python 开销:我们首先用 C++重写了自动求导引擎,然后是大部分操作符定义,然后开发了 TorchScript 和 C++前端。
然而,在Python中工作为我们的用户提供了最好的体验:它灵活、熟悉,也许最重要的是,有一个巨大的科学计算库和扩展生态系统可供使用。这个事实激励了我们最近一些贡献,试图在接近Python可用性端的Pareto最优点上达到一个平衡点:
然而,在 Python 中工作为我们的用户提供了最好的体验:它灵活、熟悉,也许最重要的是,有一个巨大的科学计算库和扩展生态系统可供使用。这个事实激励了我们最近一些贡献,试图在接近 Python 可用性端的 Pareto 最优点上达到一个平衡点:
+ [TorchDynamo](https://dev-discuss.pytorch.org/t/torchdynamo-an-experiment-in-dynamic-python-bytecode-transformation/361),这是一个Python帧评估工具,能够在最小程度用户干预的情况下加速现有的急切模式PyTorch程序。
+ [TorchDynamo](https://dev-discuss.pytorch.org/t/torchdynamo-an-experiment-in-dynamic-python-bytecode-transformation/361),这是一个 Python 帧评估工具,能够在最小程度用户干预的情况下加速现有的急切模式 PyTorch 程序。
+ [torch_function](https://pytorch.org/docs/main/notes/extending.html#extending-torch)[torch_dispatch](https://dev-discuss.pytorch.org/t/what-and-why-is-torch-dispatch/557) 扩展点,使得可以在 C++ 内部构建基于 Python 的功能,例如 [torch.fx tracer](https://pytorch.org/docs/stable/fx.html)[functorch](https://github.com/pytorch/functorch)
......
# PyTorch治理 | 机制
# PyTorch 治理 | 机制
> 原文:[https://pytorch.org/docs/stable/community/governance.html](https://pytorch.org/docs/stable/community/governance.html)
> 原文:[`pytorch.org/docs/stable/community/governance.html`](https://pytorch.org/docs/stable/community/governance.html)
## 总结
PyTorch采用了一个分层的技术治理结构。
PyTorch 采用了一个分层的技术治理结构。
+ 一个**贡献者**社区,提交问题,拉取请求,并为项目做出贡献。
+ 一小部分**模块维护者**推动PyTorch项目的每个模块。
+ 一小部分**模块维护者**推动 PyTorch 项目的每个模块。
+ 他们由**核心维护者**监督,推动整个项目的方向。
+ 核心维护者有一个**首席核心维护者**,他是最终决策者。
所有维护者都应该对PyTorch的设计理念有强烈偏见。
所有维护者都应该对 PyTorch 的设计理念有强烈偏见。
除了维护者,鼓励社区贡献、提交问题、提出建议、审查拉取请求并参与社区。根据贡献和愿意投入,任何人都可以被接受为维护者,并获得代码库部分的写入访问权限或所有权。
......@@ -22,7 +22,7 @@ PyTorch采用了一个分层的技术治理结构。
## 模块维护者
模块被定义为PyTorch组织中的GitHub存储库,或者作为核心存储库[pytorch/pytorch](https://github.com/pytorch/pytorch)中的目录。每个模块都将有自己的维护者组。维护者组负责审查和批准提交,改进设计,以及更改模块的范围。每个维护者组可以采用自己的规则和程序来做决定(默认情况下是多数投票)。模块维护者有权对其他模块维护者做出的决定提出异议 - 尤其是如果这影响到他们。在发生争议时,模块维护者组应提供一个合理且公开的争议解释,相关论点以及解决方案。在极端情况下,如果模块维护者无法自行达成结论,他们将升级到核心维护者进行审查。升级由核心维护者根据其规则和程序解决。
模块被定义为 PyTorch 组织中的 GitHub 存储库,或者作为核心存储库[pytorch/pytorch](https://github.com/pytorch/pytorch)中的目录。每个模块都将有自己的维护者组。维护者组负责审查和批准提交,改进设计,以及更改模块的范围。每个维护者组可以采用自己的规则和程序来做决定(默认情况下是多数投票)。模块维护者有权对其他模块维护者做出的决定提出异议 - 尤其是如果这影响到他们。在发生争议时,模块维护者组应提供一个合理且公开的争议解释,相关论点以及解决方案。在极端情况下,如果模块维护者无法自行达成结论,他们将升级到核心维护者进行审查。升级由核心维护者根据其规则和程序解决。
每个维护者组应该公开发布他们模块的可用通信(愿景、大致路线图、设计文档、任何争议和争议解决方案),以便贡献者和其他感兴趣的方了解项目的未来方向,并参与讨论。
......@@ -38,21 +38,21 @@ PyTorch采用了一个分层的技术治理结构。
## 核心维护者
核心维护者应该对PyTorch代码库和设计理念有深入的了解。他们的责任包括:
核心维护者应该对 PyTorch 代码库和设计理念有深入的了解。他们的责任包括:
+ 阐明项目的长期愿景
+ 协商和解决有争议的问题,以符合所有涉及方的要求
+ 接收来自PyTorch利益相关者的广泛变更请求,并评估/接受它们(小模块级别的请求由模块维护者处理)
+ 接收来自 PyTorch 利益相关者的广泛变更请求,并评估/接受它们(小模块级别的请求由模块维护者处理)
核心维护者作为一个团体有权否决模块维护者层面做出的任何决定。核心维护者有权解决争议,如他们认为合适的那样。核心维护者应该公开阐明他们的决策,并对他们的决定、否决和争议解决给出清晰的理由。
核心维护者是PyTorch GitHub组织的管理员,并列在[Maintainers](https://pytorch.org/docs/stable/community/persons_of_interest.html)中。
核心维护者是 PyTorch GitHub 组织的管理员,并列在[Maintainers](https://pytorch.org/docs/stable/community/persons_of_interest.html)中。
## 首席核心维护者(BDFL)
核心维护者可能无法达成共识的决定。为了做出这样的困难决定,核心维护者中有一个指定的并公开声明的首席核心维护者,也在开源治理模型中通常被称为BDFL。
核心维护者可能无法达成共识的决定。为了做出这样的困难决定,核心维护者中有一个指定的并公开声明的首席核心维护者,也在开源治理模型中通常被称为 BDFL。
首席核心维护者应公开表明他们的决策,并对其决定给出清晰的理由。首席核心维护者还负责确认或删除核心维护者。
......@@ -60,9 +60,9 @@ PyTorch采用了一个分层的技术治理结构。
### 原则
+ 模块维护者组的成员资格是基于个人的优点,经过贡献、审查和讨论展示出对组件的强大专业知识,并与组件如何符合整体PyTorch方向保持一致。
+ 模块维护者组的成员资格是基于个人的优点,经过贡献、审查和讨论展示出对组件的强大专业知识,并与组件如何符合整体 PyTorch 方向保持一致。
+ 成为维护者组成员的个人必须展示与整体PyTorch原则的强烈和持续的一致性。
+ 成为维护者组成员的个人必须展示与整体 PyTorch 原则的强烈和持续的一致性。
+ 模块维护者或核心维护者没有任期限制
......@@ -112,7 +112,7 @@ PyTorch采用了一个分层的技术治理结构。
+ 其他核心和模块维护者的支持信
+ PyTorch社区内利益相关者的一般支持信
+ PyTorch 社区内利益相关者的一般支持信
+ 任何适合候选人的新相关信息
......@@ -126,7 +126,7 @@ PyTorch采用了一个分层的技术治理结构。
## 添加、删除和重新范围化模块和项目[](#add-remove-and-re-scope-modules-and-projects "跳转到此标题")
核心维护者共同负责决定在PyTorch组织中添加、删除和重新范围化新模块,无论是作为PyTorch GitHub组织中的新存储库,还是作为[pytorch/pytorch](https://github.com/pytorch/pytorch)存储库中的文件夹。
核心维护者共同负责决定在 PyTorch 组织中添加、删除和重新范围化新模块,无论是作为 PyTorch GitHub 组织中的新存储库,还是作为[pytorch/pytorch](https://github.com/pytorch/pytorch)存储库中的文件夹。
他们邀请社区成员(包括自己)提出这些更改的提案。提案是开放式的,但应该有一些基本工作来提出一个令人信服的理由。以下是这个过程的一个示例方法:
......@@ -134,7 +134,7 @@ PyTorch采用了一个分层的技术治理结构。
1. 阅读论文,参加会议,根据经验构建示例流程;
1. 创建一个世界状态 - 确保这种更改是必要的,例如添加一个新项目或模块是否值得维护成本;或者删除一个项目或模块不会从PyTorch中删除太多价值;
1. 创建一个世界状态 - 确保这种更改是必要的,例如添加一个新项目或模块是否值得维护成本;或者删除一个项目或模块不会从 PyTorch 中删除太多价值;
1. 创建一个提案;提案涵盖了一旦提案获得批准后的维护、开发和社区计划。
......@@ -144,17 +144,17 @@ PyTorch采用了一个分层的技术治理结构。
### 无争议的更改
主要工作通过GitHub上的问题和拉取请求进行。维护者应避免直接将更改推送到PyTorch存储库,而是依赖于拉取请求。核心或模块维护者批准拉取请求后,可以在不经过进一步流程的情况下合并。核心和模块维护者,如[维护者](https://pytorch.org/docs/stable/community/persons_of_interest.html)页面和[CODEOWNERS](https://github.com/pytorch/pytorch/blob/master/CODEOWNERS)中列出的那样,最终批准这些更改。
主要工作通过 GitHub 上的问题和拉取请求进行。维护者应避免直接将更改推送到 PyTorch 存储库,而是依赖于拉取请求。核心或模块维护者批准拉取请求后,可以在不经过进一步流程的情况下合并。核心和模块维护者,如[维护者](https://pytorch.org/docs/stable/community/persons_of_interest.html)页面和[CODEOWNERS](https://github.com/pytorch/pytorch/blob/master/CODEOWNERS)中列出的那样,最终批准这些更改。
通知相关专家有关问题或拉取请求是重要的。强烈建议在给定兴趣领域的专家进行审查,特别是在拉取请求的批准上。如果未能这样做,可能会导致相关专家撤销更改。
### 有争议的决策过程[](#controversial-decision-process "跳转到此标题")
在给定兴趣领域进行重大更改需要打开一个GitHub问题进行讨论。这包括:
在给定兴趣领域进行重大更改需要打开一个 GitHub 问题进行讨论。这包括:
+PyTorch框架或库的任何语义或语法更改。
+ PyTorch 框架或库的任何语义或语法更改。
+Python或C++ API的不兼容更改。
+ Python 或 C++ API 的不兼容更改。
+ 核心框架或库的添加,包括现有库中的重大新功能。
......@@ -164,20 +164,20 @@ PyTorch采用了一个分层的技术治理结构。
### 一般项目政策
PyTorch已被建立为PyTorch系列的LF项目,LLC。适用于PyTorch和PyTorch参与者的政策,包括商标使用指南,位于[https://www.lfprojects.org/policies/](https://www.lfprojects.org/policies/)
PyTorch 已被建立为 PyTorch 系列的 LF 项目,LLC。适用于 PyTorch 和 PyTorch 参与者的政策,包括商标使用指南,位于[`www.lfprojects.org/policies/`](https://www.lfprojects.org/policies/)
PyTorch参与者承认,所有新贡献的版权将由版权持有者保留为独立的作品,并且没有贡献者或版权持有者需要将版权分配给项目。除非另有说明,所有对项目的代码贡献必须使用此处提供的3-Clause-BSD许可证进行:[https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause)(“项目许可证”)。所有出站代码将根据项目许可证提供。维护者可以根据特殊情况批准使用替代的开放许可证或许可证进行入站或出站贡献。
PyTorch 参与者承认,所有新贡献的版权将由版权持有者保留为独立的作品,并且没有贡献者或版权持有者需要将版权分配给项目。除非另有说明,所有对项目的代码贡献必须使用此处提供的 3-Clause-BSD 许可证进行:[`opensource.org/licenses/BSD-3-Clause`](https://opensource.org/licenses/BSD-3-Clause)(“项目许可证”)。所有出站代码将根据项目许可证提供。维护者可以根据特殊情况批准使用替代的开放许可证或许可证进行入站或出站贡献。
## 常见问题
**问:如果我想拥有(或部分拥有)项目的某个部分,比如功能区域或领域库,例如** [线性代数](https://github.com/pytorch/pytorch/tree/master/torch/linalg) **或** [Torch Vision](https://github.com/pytorch/vision) **?** 这是完全可能的。第一步是开始为现有项目领域做出贡献并支持其健康和成功。此外,您可以通过GitHub问题提出新功能或改进项目领域的建议。
**问:如果我想拥有(或部分拥有)项目的某个部分,比如功能区域或领域库,例如** [线性代数](https://github.com/pytorch/pytorch/tree/master/torch/linalg) **或** [Torch Vision](https://github.com/pytorch/vision) **?** 这是完全可能的。第一步是开始为现有项目领域做出贡献并支持其健康和成功。此外,您可以通过 GitHub 问题提出新功能或改进项目领域的建议。
**问:如果我是一家公司,希望在内部开发中使用PyTorch,可以获得或购买董事会席位来推动项目方向吗?** 不可以,PyTorch项目严格遵循维护者项目理念,明确区分技术治理和业务治理。但是,如果您想参与赞助和支持,可以通过PyTorch基金会(PTF)和赞助参与。您还可以让个人工程师成为维护者,但这并不是保证,而是基于成绩。
**问:如果我是一家公司,希望在内部开发中使用 PyTorch,可以获得或购买董事会席位来推动项目方向吗?** 不可以,PyTorch 项目严格遵循维护者项目理念,明确区分技术治理和业务治理。但是,如果您想参与赞助和支持,可以通过 PyTorch 基金会(PTF)和赞助参与。您还可以让个人工程师成为维护者,但这并不是保证,而是基于成绩。
**问:PyTorch项目是否支持资助或支持独立开发者使用或贡献项目的方式?** 目前不支持。但我们正在寻找更好地支持PyTorch周围独立开发者社区的方法。如果您有建议或意见,请在PyTorch论坛上联系讨论。
**问:PyTorch 项目是否支持资助或支持独立开发者使用或贡献项目的方式?** 目前不支持。但我们正在寻找更好地支持 PyTorch 周围独立开发者社区的方法。如果您有建议或意见,请在 PyTorch 论坛上联系讨论。
**问:我如何向项目贡献代码?** 如果更改相对较小,可以立即在GitHub上发起拉取请求,由项目提交者进行审查和合并。对于较大的更改,请先提出问题以进行讨论。请参阅[PyTorch贡献者Wiki](https://github.com/pytorch/pytorch/wiki/The-Ultimate-Guide-to-PyTorch-Contributions)以获取详细步骤。
**问:我如何向项目贡献代码?** 如果更改相对较小,可以立即在 GitHub 上发起拉取请求,由项目提交者进行审查和合并。对于较大的更改,请先提出问题以进行讨论。请参阅[PyTorch 贡献者 Wiki](https://github.com/pytorch/pytorch/wiki/The-Ultimate-Guide-to-PyTorch-Contributions)以获取详细步骤。
**问:我可以成为项目的提交者吗?** 不幸的是,目前向PyTorch提交的过程涉及与Facebook基础设施的交互,只能由Facebook员工触发。但是,我们正在寻找扩大提交者群体至Facebook以外个人的方式,并将在工具存在允许时提供更新。
**问:我可以成为项目的提交者吗?** 不幸的是,目前向 PyTorch 提交的过程涉及与 Facebook 基础设施的交互,只能由 Facebook 员工触发。但是,我们正在寻找扩大提交者群体至 Facebook 以外个人的方式,并将在工具存在允许时提供更新。
**问:如果我想在会议或其他场合提供PyTorch教程怎么办?我需要‘官方’成为提交者吗?** 不需要,我们鼓励社区成员在任何地方展示他们的工作。请联系[marketing@pytorch.org](mailto:marketing%40pytorch.org)以获取营销支持。
**问:如果我想在会议或其他场合提供 PyTorch 教程怎么办?我需要‘官方’成为提交者吗?** 不需要,我们鼓励社区成员在任何地方展示他们的工作。请联系 marketing@pytorch.org 以获取营销支持。
# PyTorch治理 | 维护者
# PyTorch 治理 | 维护者
> 原文:[https://pytorch.org/docs/stable/community/persons_of_interest.html](https://pytorch.org/docs/stable/community/persons_of_interest.html)
> 原文:[`pytorch.org/docs/stable/community/persons_of_interest.html`](https://pytorch.org/docs/stable/community/persons_of_interest.html)
## 责任
......@@ -182,7 +182,7 @@
+ 彼得·贝尔([peterbell10](https://github.com/peterbell10)
### CPU性能(Torch Inductor / MKLDNN)[](#cpu-performance-torch-inductor-mkldnn "跳转到此标题的永久链接")
### CPU 性能(Torch Inductor / MKLDNN)[](#cpu-performance-torch-inductor-mkldnn "跳转到此标题的永久链接")
+ 马明飞([mingfeima](https://github.com/mingfeima)
......@@ -206,7 +206,7 @@
+ (名誉退休)李建辉([Jianhui-Li](https://github.com/Jianhui-Li)
### GPU性能(Torch Inductor / Triton / CUDA)[](#gpu-performance-torch-inductor-triton-cuda "跳转到此标题的永久链接")
### GPU 性能(Torch Inductor / Triton / CUDA)[](#gpu-performance-torch-inductor-triton-cuda "跳转到此标题的永久链接")
+ 娜塔莉亚·吉梅尔谢因([ngimel](https://github.com/ngimel)
......@@ -300,7 +300,7 @@
+ (名誉退休)Sebastian Messmer([smessmer](https://github.com/smessmer)
### ONNX导出器
### ONNX 导出器
+ Aaron Bockover([abock](https://github.com/abock)
......
# CUDA自动混合精度示例
# CUDA 自动混合精度示例
> [https://pytorch.org/docs/stable/notes/amp_examples.html](https://pytorch.org/docs/stable/notes/amp_examples.html)
> [`pytorch.org/docs/stable/notes/amp_examples.html`](https://pytorch.org/docs/stable/notes/amp_examples.html)
通常,“自动混合精度训练”意味着同时使用[`torch.autocast`](../amp.html#torch.autocast "torch.autocast")[`torch.cuda.amp.GradScaler`](../amp.html#torch.cuda.amp.GradScaler "torch.cuda.amp.GradScaler")进行训练。
通常,“自动混合精度训练”意味着同时使用`torch.autocast``torch.cuda.amp.GradScaler`进行训练。
[`torch.autocast`](../amp.html#torch.autocast "torch.autocast")的实例使得可以为选择的区域进行自动转换。自动转换会自动选择GPU操作的精度,以提高性能同时保持准确性。
`torch.autocast`的实例使得可以为选择的区域进行自动转换。自动转换会自动选择 GPU 操作的精度,以提高性能同时保持准确性。
[`torch.cuda.amp.GradScaler`](../amp.html#torch.cuda.amp.GradScaler "torch.cuda.amp.GradScaler")的实例有助于方便地执行梯度缩放的步骤。梯度缩放通过最小化梯度下溢来提高具有`float16`梯度的网络的收敛性,如[此处](../amp.html#gradient-scaling)所解释。
`torch.cuda.amp.GradScaler`的实例有助于方便地执行梯度缩放的步骤。梯度缩放通过最小化梯度下溢来提高具有`float16`梯度的网络的收敛性,如此处所解释。
[`torch.autocast`](../amp.html#torch.autocast "torch.autocast")[`torch.cuda.amp.GradScaler`](../amp.html#torch.cuda.amp.GradScaler "torch.cuda.amp.GradScaler")是模块化的。在下面的示例中,每个都按照其各自的文档建议使用。
`torch.autocast``torch.cuda.amp.GradScaler`是模块化的。在下面的示例中,每个都按照其各自的文档建议使用。
(这里的示例仅供参考。请查看[自动混合精度教程](https://pytorch.org/tutorials/recipes/recipes/amp_recipe.html)以获得可运行的步骤。)
+ [典型的混合精度训练](#typical-mixed-precision-training)
+ 典型的混合精度训练
+ [使用未缩放梯度](#working-with-unscaled-gradients)
+ 使用未缩放梯度
+ [梯度裁剪](#gradient-clipping)
+ 梯度裁剪
+ [使用缩放梯度](#working-with-scaled-gradients)
+ 使用缩放梯度
+ [梯度累积](#gradient-accumulation)
+ 梯度累积
+ [梯度惩罚](#gradient-penalty)
+ 梯度惩罚
+ [使用多个模型、损失和优化器](#working-with-multiple-models-losses-and-optimizers)
+ 使用多个模型、损失和优化器
+ [使用多个GPU](#working-with-multiple-gpus)
+ 使用多个 GPU
+ [单进程中的DataParallel](#dataparallel-in-a-single-process)
+ 单进程中的 DataParallel
+ [DistributedDataParallel,每个进程一个GPU](#distributeddataparallel-one-gpu-per-process)
+ DistributedDataParallel,每个进程一个 GPU
+ [DistributedDataParallel,每个进程多个GPU](#distributeddataparallel-multiple-gpus-per-process)
+ DistributedDataParallel,每个进程多个 GPU
+ [自动转换和自定义自动梯度函数](#autocast-and-custom-autograd-functions)
+ 自动转换和自定义自动梯度函数
+ [具有多个输入或可自动转换操作的函数](#functions-with-multiple-inputs-or-autocastable-ops)
+ 具有多个输入或可自动转换操作的函数
+ [需要特定`dtype`的函数](#functions-that-need-a-particular-dtype)
+ 需要特定`dtype`的函数
## [典型的混合精度训练](#id2)[](#typical-mixed-precision-training "跳转到此标题")
## 典型的混合精度训练[](#typical-mixed-precision-training "跳转到此标题")
```py
# Creates model and optimizer in default precision
......@@ -73,13 +73,13 @@ for epoch in epochs:
scaler.update()
```
## [使用未缩放梯度](#id3)[](#working-with-unscaled-gradients "跳转到此标题")
## 使用未缩放梯度[](#working-with-unscaled-gradients "跳转到此标题")
`scaler.scale(loss).backward()`产生的所有梯度都是经过缩放的。如果您希望在`backward()``scaler.step(optimizer)`之间修改或检查参数的`.grad`属性,您应该首先取消缩放它们。例如,梯度裁剪操作会操纵一组梯度,使它们的全局范数(参见[`torch.nn.utils.clip_grad_norm_()`](../generated/torch.nn.utils.clip_grad_norm_.html#torch.nn.utils.clip_grad_norm_ "torch.nn.utils.clip_grad_norm_"))或最大幅度(参见[`torch.nn.utils.clip_grad_value_()`](../generated/torch.nn.utils.clip_grad_value_.html#torch.nn.utils.clip_grad_value_ "torch.nn.utils.clip_grad_value_"))小于某个用户设定的阈值。如果您尝试在不取消缩放的情况下裁剪梯度,梯度的范数/最大幅度也会被缩放,因此您请求的阈值(本来是用于*未缩放*梯度的阈值)将无效。
`scaler.scale(loss).backward()`产生的所有梯度都是经过缩放的。如果您希望在`backward()``scaler.step(optimizer)`之间修改或检查参数的`.grad`属性,您应该首先取消缩放它们。例如,梯度裁剪操作会操纵一组梯度,使它们的全局范数(参见`torch.nn.utils.clip_grad_norm_()`)或最大幅度(参见`torch.nn.utils.clip_grad_value_()`)小于某个用户设定的阈值。如果您尝试在不取消缩放的情况下裁剪梯度,梯度的范数/最大幅度也会被缩放,因此您请求的阈值(本来是用于*未缩放*梯度的阈值)将无效。
`scaler.unscale_(optimizer)`取消缩放`optimizer`的参数所持有的梯度。如果您的模型包含其他分配给另一个优化器(比如`optimizer2`)的参数,您可以单独调用`scaler.unscale_(optimizer2)`来取消缩放这些参数的梯度。
### [梯度裁剪](#id4)
### 梯度裁剪
在裁剪之前调用`scaler.unscale_(optimizer)`使您可以像往常一样裁剪未缩放的梯度:
......@@ -112,15 +112,15 @@ for epoch in epochs:
警告
[`unscale_`](../amp.html#torch.cuda.amp.GradScaler.unscale_ "torch.cuda.amp.GradScaler.unscale_")应该每个优化器每次[`step`](../amp.html#torch.cuda.amp.GradScaler.step "torch.cuda.amp.GradScaler.step")调用只调用一次,并且只在为该优化器分配的参数的所有梯度都被累积之后才调用。在每个[`step`](../amp.html#torch.cuda.amp.GradScaler.step "torch.cuda.amp.GradScaler.step")之间为给定的优化器调用两次[`unscale_`](../amp.html#torch.cuda.amp.GradScaler.unscale_ "torch.cuda.amp.GradScaler.unscale_")会触发一个运行时错误。
`unscale_`应该每个优化器每次`step`调用只调用一次,并且只在为该优化器分配的参数的所有梯度都被累积之后才调用。在每个`step`之间为给定的优化器调用两次`unscale_`会触发一个运行时错误。
## [使用缩放梯度](#id5)[](#working-with-scaled-gradients "跳转到此标题")
## 使用缩放梯度[](#working-with-scaled-gradients "跳转到此标题")
### [梯度累积](#id6)[](#gradient-accumulation "跳转到此标题")
### 梯度累积[](#gradient-accumulation "跳转到此标题")
梯度累积会在一个有效批次的大小上添加梯度,大小为`batch_per_iter * iters_to_accumulate`(如果是分布式的话还要乘以`num_procs`)。尺度应该校准到有效批次,这意味着在有效批次粒度上进行inf/NaN检查,如果发现inf/NaN梯度,则跳过步骤,同时尺度更新应该在有效批次粒度上发生。此外,梯度应该保持缩放,尺度因子应该保持恒定,而给定有效批次的梯度被累积。如果在累积完成之前梯度未被缩放(或尺度因子发生变化),下一个反向传播将会在将缩放的梯度添加到未缩放的梯度(或使用不同因子缩放的梯度)之后,无法恢复已累积的未缩放梯度,必须调用[`step`](../amp.html#torch.cuda.amp.GradScaler.step "torch.cuda.amp.GradScaler.step")
梯度累积会在一个有效批次的大小上添加梯度,大小为`batch_per_iter * iters_to_accumulate`(如果是分布式的话还要乘以`num_procs`)。尺度应该校准到有效批次,这意味着在有效批次粒度上进行 inf/NaN 检查,如果发现 inf/NaN 梯度,则跳过步骤,同时尺度更新应该在有效批次粒度上发生。此外,梯度应该保持缩放,尺度因子应该保持恒定,而给定有效批次的梯度被累积。如果在累积完成之前梯度未被缩放(或尺度因子发生变化),下一个反向传播将会在将缩放的梯度添加到未缩放的梯度(或使用不同因子缩放的梯度)之后,无法恢复已累积的未缩放梯度,必须调用`step`
因此,如果要对梯度进行[`unscale_`](../amp.html#torch.cuda.amp.GradScaler.unscale_ "torch.cuda.amp.GradScaler.unscale_")(例如,允许裁剪未缩放的梯度),请在所有(缩放的)梯度为即将到来的[`step`](../amp.html#torch.cuda.amp.GradScaler.step "torch.cuda.amp.GradScaler.step")累积完成之后,在[`step`](../amp.html#torch.cuda.amp.GradScaler.step "torch.cuda.amp.GradScaler.step")之前调用[`unscale_`](../amp.html#torch.cuda.amp.GradScaler.unscale_ "torch.cuda.amp.GradScaler.unscale_")。此外,只在调用了[`step`](../amp.html#torch.cuda.amp.GradScaler.step "torch.cuda.amp.GradScaler.step")进行完整有效批次的迭代结束时才调用[`update`](../amp.html#torch.cuda.amp.GradScaler.update "torch.cuda.amp.GradScaler.update")
因此,如果要对梯度进行`unscale_`(例如,允许裁剪未缩放的梯度),请在所有(缩放的)梯度为即将到来的`step`累积完成之后,在`step`之前调用`unscale_`。此外,只在调用了`step`进行完整有效批次的迭代结束时才调用`update`
```py
scaler = GradScaler()
......@@ -143,11 +143,11 @@ for epoch in epochs:
optimizer.zero_grad()
```
### [梯度惩罚](#id7)
### 梯度惩罚
梯度惩罚的实现通常使用[`torch.autograd.grad()`](../generated/torch.autograd.grad.html#torch.autograd.grad "torch.autograd.grad")创建梯度,将它们组合以创建惩罚值,并将惩罚值添加到损失中。
梯度惩罚的实现通常使用`torch.autograd.grad()`创建梯度,将它们组合以创建惩罚值,并将惩罚值添加到损失中。
这是一个普通的L2惩罚的例子,没有梯度缩放或自动转换:
这是一个普通的 L2 惩罚的例子,没有梯度缩放或自动转换:
```py
for epoch in epochs:
......@@ -175,11 +175,11 @@ for epoch in epochs:
optimizer.step()
```
要实现带有梯度缩放的梯度惩罚,传递给[`torch.autograd.grad()`](../generated/torch.autograd.grad.html#torch.autograd.grad "torch.autograd.grad")`outputs`张量应该被缩放。因此,得到的梯度将被缩放,应该在组合创建惩罚值之前取消缩放。
要实现带有梯度缩放的梯度惩罚,传递给`torch.autograd.grad()``outputs`张量应该被缩放。因此,得到的梯度将被缩放,应该在组合创建惩罚值之前取消缩放。
此外,惩罚项的计算是前向传播的一部分,因此应该在[`autocast`](../amp.html#torch.cuda.amp.autocast "torch.cuda.amp.autocast")上下文中。
此外,惩罚项的计算是前向传播的一部分,因此应该在`autocast`上下文中。
对于相同的L2惩罚,看起来是这样的:
对于相同的 L2 惩罚,看起来是这样的:
```py
scaler = GradScaler()
......@@ -220,7 +220,7 @@ for epoch in epochs:
scaler.update()
```
## [使用多个模型、损失和优化器](#id8)[](#working-with-multiple-models-losses-and-optimizers "跳转到此标题")
## 使用多个模型、损失和优化器[](#working-with-multiple-models-losses-and-optimizers "跳转到此标题")
如果您的网络有多个损失,您必须分别对每个损失调用`scaler.scale`。如果您的网络有多个优化器,您可以分别对其中任何一个调用`scaler.unscale_`,并且您必须分别对每个调用`scaler.step`
......@@ -256,11 +256,11 @@ for epoch in epochs:
每个优化器都会检查其梯度是否包含无穷大/NaN,并独立决定是否跳过该步骤。这可能导致一个优化器跳过该步骤,而另一个不跳过。由于很少发生跳过步骤(每几百次迭代一次),这不应该影响收敛。如果您在将梯度缩放添加到多优化器模型后观察到收敛不佳,请报告错误。
## [使用多个GPU](#id9)
## 使用多个 GPU
这里描述的问题只影响`autocast``GradScaler`的使用方式没有改变。
### [单进程中的DataParallel](#id10)
### 单进程中的 DataParallel
即使`torch.nn.DataParallel`会生成线程来在每个设备上运行前向传播。自动转换状态在每个线程中传播,并且以下操作将起作用:
......@@ -276,21 +276,21 @@ with autocast(device_type='cuda', dtype=torch.float16):
loss = loss_fn(output)
```
### [分布式数据并行,每个进程一个GPU](#id11)
### 分布式数据并行,每个进程一个 GPU
`torch.nn.parallel.DistributedDataParallel`的文档建议每个进程一个GPU以获得最佳性能。在这种情况下,`DistributedDataParallel`不会在内部生成线程,因此对`autocast``GradScaler`的使用不受影响。
`torch.nn.parallel.DistributedDataParallel`的文档建议每个进程一个 GPU 以获得最佳性能。在这种情况下,`DistributedDataParallel`不会在内部生成线程,因此对`autocast``GradScaler`的使用不受影响。
### [分布式数据并行,每个进程多个GPU](#id12)
### 分布式数据并行,每个进程多个 GPU
在这里,`torch.nn.parallel.DistributedDataParallel`可能会生成一个辅助线程来在每个设备上运行前向传播,就像`torch.nn.DataParallel`一样。[修复方法相同](#amp-dataparallel):在模型的`forward`方法中应用autocast,以确保在辅助线程中启用它。## [自动转换和自定义自动求导函数](#id13)
在这里,`torch.nn.parallel.DistributedDataParallel`可能会生成一个辅助线程来在每个设备上运行前向传播,就像`torch.nn.DataParallel`一样。修复方法相同:在模型的`forward`方法中应用 autocast,以确保在辅助线程中启用它。## 自动转换和自定义自动求导函数
如果您的网络使用[自定义自动求导函数](extending.html#extending-autograd)`torch.autograd.Function`的子类),则需要对自动转换兼容性进行更改,如果任何函数
如果您的网络使用自定义自动求导函数`torch.autograd.Function`的子类),则需要对自动转换兼容性进行更改,如果任何函数
+ 接受多个浮点张量输入,
+ 包装任何可自动转换的操作(参见[自动转换操作参考](../amp.html#autocast-op-reference),或者
+ 包装任何可自动转换的操作(参见自动转换操作参考,或者
+ 需要特定的`dtype`(例如,如果它包装了仅为`dtype`编译的[CUDA扩展](https://pytorch.org/tutorials/advanced/cpp_extension.html))。
+ 需要特定的`dtype`(例如,如果它包装了仅为`dtype`编译的[CUDA 扩展](https://pytorch.org/tutorials/advanced/cpp_extension.html))。
在所有情况下,如果您正在导入该函数并且无法更改其定义,一个安全的备选方案是在出现错误的任何使用点禁用自动转换并强制执行为`float32`(或`dtype`):
......@@ -301,11 +301,11 @@ with autocast(device_type='cuda', dtype=torch.float16):
output = imported_function(input1.float(), input2.float())
```
如果您是函数的作者(或可以更改其定义),更好的解决方案是在下面相关案例中所示使用[`torch.cuda.amp.custom_fwd()`](../amp.html#torch.cuda.amp.custom_fwd)[`torch.cuda.amp.custom_bwd()`](../amp.html#torch.cuda.amp.custom_bwd)装饰器。
如果您是函数的作者(或可以更改其定义),更好的解决方案是在下面相关案例中所示使用`torch.cuda.amp.custom_fwd()``torch.cuda.amp.custom_bwd()`装饰器。
### [具有多个输入或可自动转换操作的函数](#id14)
### 具有多个输入或可自动转换操作的函数
[`custom_fwd`](../amp.html#torch.cuda.amp.custom_fwd)[`custom_bwd`](../amp.html#torch.cuda.amp.custom_bwd)(不带参数)分别应用于`forward``backward`。这些确保`forward`以当前自动转换状态执行,`backward`以与`forward`相同的自动转换状态执行(可以防止类型不匹配错误):
`custom_fwd``custom_bwd`(不带参数)分别应用于`forward``backward`。这些确保`forward`以当前自动转换状态执行,`backward`以与`forward`相同的自动转换状态执行(可以防止类型不匹配错误):
```py
class MyMM(torch.autograd.Function):
......@@ -330,9 +330,9 @@ with autocast(device_type='cuda', dtype=torch.float16):
output = mymm(input1, input2)
```
### [需要特定`dtype`的函数](#id15)
### 需要特定`dtype`的函数
考虑一个需要`torch.float32`输入的自定义函数。将[`custom_fwd(cast_inputs=torch.float32)`](../amp.html#torch.cuda.amp.custom_fwd)应用于`forward`,将[`custom_bwd`](../amp.html#torch.cuda.amp.custom_bwd)(不带参数)应用于`backward`。如果`forward`在启用自动转换的区域运行,则装饰器将浮点CUDA张量输入转换为`float32`,并在`forward``backward`期间本地禁用自动转换:
考虑一个需要`torch.float32`输入的自定义函数。将`custom_fwd(cast_inputs=torch.float32)`应用于`forward`,将`custom_bwd`(不带参数)应用于`backward`。如果`forward`在启用自动转换的区域运行,则装饰器将浮点 CUDA 张量输入转换为`float32`,并在`forward``backward`期间本地禁用自动转换:
```py
class MyFloat32Func(torch.autograd.Function):
......
此差异已折叠。
# 广播语义
> 原文:[https://pytorch.org/docs/stable/notes/broadcasting.html](https://pytorch.org/docs/stable/notes/broadcasting.html)
> 原文:[`pytorch.org/docs/stable/notes/broadcasting.html`](https://pytorch.org/docs/stable/notes/broadcasting.html)
许多PyTorch操作支持NumPy的广播语义。有关详细信息,请参阅[https://numpy.org/doc/stable/user/basics.broadcasting.html](https://numpy.org/doc/stable/user/basics.broadcasting.html)
许多 PyTorch 操作支持 NumPy 的广播语义。有关详细信息,请参阅[`numpy.org/doc/stable/user/basics.broadcasting.html`](https://numpy.org/doc/stable/user/basics.broadcasting.html)
简而言之,如果PyTorch操作支持广播,则其张量参数可以自动扩展为相等大小(而不会复制数据)。
简而言之,如果 PyTorch 操作支持广播,则其张量参数可以自动扩展为相等大小(而不会复制数据)。
## 一般语义
......@@ -12,7 +12,7 @@
+ 每个张量至少有一个维度。
+ 在迭代维度大小时,从尾部维度开始,维度大小必须要么相等,要么其中一个为1,要么其中一个不存在。
+ 在迭代维度大小时,从尾部维度开始,维度大小必须要么相等,要么其中一个为 1,要么其中一个不存在。
例如:
......@@ -42,7 +42,7 @@
如果两个张量`x``y`是“可广播的”,则结果张量大小计算如下:
+ 如果`x``y`的维度数不相等,则在较少维度的张量的维度前添加1,使它们长度相等。
+ 如果`x``y`的维度数不相等,则在较少维度的张量的维度前添加 1,使它们长度相等。
+ 然后,对于每个维度大小,结果维度大小是沿该维度的`x``y`的大小的最大值。
......@@ -88,7 +88,7 @@ RuntimeError: The expanded size of the tensor (1) must match the existing size (
## 向后兼容性
PyTorch的先前版本允许某些逐点函数在具有不同形状的张量上执行,只要每个张量中的元素数量相等即可。然后,逐点操作将通过将每个张量视为1维来执行。PyTorch现在支持广播,而“1维”逐点行为被视为已弃用,并且在张量不可广播但具有相同数量的元素的情况下会生成Python警告。
PyTorch 的先前版本允许某些逐点函数在具有不同形状的张量上执行,只要每个张量中的元素数量相等即可。然后,逐点操作将通过将每个张量视为 1 维来执行。PyTorch 现在支持广播,而“1 维”逐点行为被视为已弃用,并且在张量不可广播但具有相同数量的元素的情况下会生成 Python 警告。
请注意,广播的引入可能会导致向后不兼容的更改,即两个张量的形状不相同,但可以广播并且具有相同数量的元素的情况。例如:
......@@ -96,7 +96,7 @@ PyTorch的先前版本允许某些逐点函数在具有不同形状的张量上
>>> torch.add(torch.ones(4,1), torch.randn(4))
```
以前会产生一个大小为torch.Size([4,1])的张量,但现在会产生一个大小为torch.Size([4,4])的张量。为了帮助识别代码中可能存在的由广播引入的向后不兼容性,您可以将torch.utils.backcompat.broadcast_warning.enabled设置为True,在这种情况下会生成一个Python警告。
以前会产生一个大小为 torch.Size([4,1])的张量,但现在会产生一个大小为 torch.Size([4,4])的张量。为了帮助识别代码中可能存在的由广播引入的向后不兼容性,您可以将 torch.utils.backcompat.broadcast_warning.enabled 设置为 True,在这种情况下会生成一个 Python 警告。
例如:
......
# CPU 线程和 TorchScript 推理
> [https://pytorch.org/docs/stable/notes/cpu_threading_torchscript_inference.html](https://pytorch.org/docs/stable/notes/cpu_threading_torchscript_inference.html)
> [`pytorch.org/docs/stable/notes/cpu_threading_torchscript_inference.html`](https://pytorch.org/docs/stable/notes/cpu_threading_torchscript_inference.html)
PyTorch 允许在 TorchScript 模型推理期间使用多个 CPU 线程。以下图显示了在典型应用程序中可能找到的不同级别的并行性:
[![../_images/cpu_threading_torchscript_inference.svg](../Images/8df78fa0159321538b2e2a438f6cae52.png)](../_images/cpu_threading_torchscript_inference.svg)
![../_images/cpu_threading_torchscript_inference.svg](img/cpu_threading_torchscript_inference.svg)
一个或多个推理线程在给定输入上执行模型的前向传递。每个推理线程调用 JIT 解释器,逐个执行模型的操作。模型可以利用 `fork` TorchScript 原语启动一个异步任务。一次分叉多个操作会导致并行执行的任务。`fork` 操作符返回一个 `Future` 对象,可以稍后用于同步,例如:
......@@ -62,8 +62,8 @@ PyTorch 允许在构建时选择 ATen 和其他库使用的并行化后端,具
| 并行性类型 | 设置 | 备注 |
| --- | --- | --- |
| 操作间的并行性 | `at::set_num_interop_threads``at::get_num_interop_threads`(C++)`set_num_interop_threads``get_num_interop_threads`(Python,[`torch`](../torch.html#module-torch "torch") 模块) | 默认线程数:CPU 核心数。 |
| 手术过程中的并行性 | `at::set_num_threads``at::get_num_threads`(C++)`set_num_threads``get_num_threads`(Python,[`torch`](../torch.html#module-torch "torch") 模块)环境变量:`OMP_NUM_THREADS``MKL_NUM_THREADS` |
| 操作间的并行性 | `at::set_num_interop_threads``at::get_num_interop_threads`(C++)`set_num_interop_threads``get_num_interop_threads`(Python,`torch` 模块) | 默认线程数:CPU 核心数。 |
| 手术过程中的并行性 | `at::set_num_threads``at::get_num_threads`(C++)`set_num_threads``get_num_threads`(Python,`torch` 模块)环境变量:`OMP_NUM_THREADS``MKL_NUM_THREADS` |
对于内部操作并行设置,`at::set_num_threads``torch.set_num_threads`始终优先于环境变量,`MKL_NUM_THREADS`变量优先于`OMP_NUM_THREADS`
......@@ -82,9 +82,9 @@ for t in threads:
# ... plotting (threads, runtimes) ...
```
在具有24个物理CPU核心的系统(基于Xeon E5-2680、MKL和OpenMP构建)上运行脚本会产生以下运行时间:
在具有 24 个物理 CPU 核心的系统(基于 Xeon E5-2680、MKL 和 OpenMP 构建)上运行脚本会产生以下运行时间:
[![../_images/cpu_threading_runtimes.svg](../Images/50cb089741be0ac4482f410e4d719b4b.png)](../_images/cpu_threading_runtimes.svg)
![../_images/cpu_threading_runtimes.svg](img/cpu_threading_runtimes.svg)
调整内部和外部操作线程数量时应考虑以下因素:
......@@ -94,12 +94,12 @@ for t in threads:
警告
OpenMP不能保证应用程序将使用单个进程内部操作线程池。相反,两个不同的应用程序或内部操作线程可能会使用不同的OpenMP线程池进行内部操作工作。这可能导致应用程序使用大量线程。在OpenMP情况下,需要特别注意调整线程数量,以避免多线程应用程序中的过度订阅。
OpenMP 不能保证应用程序将使用单个进程内部操作线程池。相反,两个不同的应用程序或内部操作线程可能会使用不同的 OpenMP 线程池进行内部操作工作。这可能导致应用程序使用大量线程。在 OpenMP 情况下,需要特别注意调整线程数量,以避免多线程应用程序中的过度订阅。
注意
预编译的PyTorch版本已编译为支持OpenMP。
预编译的 PyTorch 版本已编译为支持 OpenMP。
注意
`parallel_info`实用程序打印有关线程设置的信息,可用于调试。在Python中也可以通过`torch.__config__.parallel_info()`调用获得类似的输出。
`parallel_info`实用程序打印有关线程设置的信息,可用于调试。在 Python 中也可以通过`torch.__config__.parallel_info()`调用获得类似的输出。
此差异已折叠。
# 分布式数据并行
> 原文:[https://pytorch.org/docs/stable/notes/ddp.html](https://pytorch.org/docs/stable/notes/ddp.html)
> 原文:[`pytorch.org/docs/stable/notes/ddp.html`](https://pytorch.org/docs/stable/notes/ddp.html)
警告
[`torch.nn.parallel.DistributedDataParallel`](../generated/torch.nn.parallel.DistributedDataParallel.html#torch.nn.parallel.DistributedDataParallel "torch.nn.parallel.DistributedDataParallel")的实现随时间推移而发展。本设计说明是基于v1.4状态编写的。
`torch.nn.parallel.DistributedDataParallel`的实现随时间推移而发展。本设计说明是基于 v1.4 状态编写的。
[`torch.nn.parallel.DistributedDataParallel`](../generated/torch.nn.parallel.DistributedDataParallel.html#torch.nn.parallel.DistributedDataParallel "torch.nn.parallel.DistributedDataParallel")(DDP)透明地执行分布式数据并行训练。本页描述了它的工作原理并揭示了实现细节。
`torch.nn.parallel.DistributedDataParallel`(DDP)透明地执行分布式数据并行训练。本页描述了它的工作原理并揭示了实现细节。
## 示例
让我们从一个简单的[`torch.nn.parallel.DistributedDataParallel`](../generated/torch.nn.parallel.DistributedDataParallel.html#torch.nn.parallel.DistributedDataParallel "torch.nn.parallel.DistributedDataParallel")示例开始。这个示例使用一个[`torch.nn.Linear`](../generated/torch.nn.Linear.html#torch.nn.Linear "torch.nn.Linear")作为本地模型,将其与DDP包装起来,然后在DDP模型上运行一次前向传递,一次反向传递和一个优化器步骤。之后,本地模型上的参数将被更新,并且不同进程上的所有模型应该完全相同。
让我们从一个简单的`torch.nn.parallel.DistributedDataParallel`示例开始。这个示例使用一个`torch.nn.Linear`作为本地模型,将其与 DDP 包装起来,然后在 DDP 模型上运行一次前向传递,一次反向传递和一个优化器步骤。之后,本地模型上的参数将被更新,并且不同进程上的所有模型应该完全相同。
```py
import torch
......@@ -56,7 +56,7 @@ if __name__=="__main__":
main()
```
DDP与TorchDynamo一起使用。当与TorchDynamo一起使用时,在编译模型之前应用DDP模型包装器,以便torchdynamo可以根据DDP桶大小应用`DDPOptimizer`(基于DDP桶大小的图断点优化)。 (有关更多信息,请参见[TorchDynamo DDPOptimizer](./ddp.html#torchdynamo-ddpoptimizer)。)
DDP 与 TorchDynamo 一起使用。当与 TorchDynamo 一起使用时,在编译模型之前应用 DDP 模型包装器,以便 torchdynamo 可以根据 DDP 桶大小应用`DDPOptimizer`(基于 DDP 桶大小的图断点优化)。 (有关更多信息,请参见 TorchDynamo DDPOptimizer。)
```py
ddp_model = DDP(model, device_ids=[rank])
......@@ -65,37 +65,37 @@ ddp_model = torch.compile(ddp_model)
## 内部设计
本节通过深入探讨每个迭代步骤的细节,揭示了[`torch.nn.parallel.DistributedDataParallel`](../generated/torch.nn.parallel.DistributedDataParallel.html#torch.nn.parallel.DistributedDataParallel "torch.nn.parallel.DistributedDataParallel")的内部工作原理。
本节通过深入探讨每个迭代步骤的细节,揭示了`torch.nn.parallel.DistributedDataParallel`的内部工作原理。
+ **先决条件**:DDP依赖于c10d`ProcessGroup`进行通信。因此,应用程序在构造DDP之前必须创建`ProcessGroup`实例。
+ **先决条件**:DDP 依赖于 c10d`ProcessGroup`进行通信。因此,应用程序在构造 DDP 之前必须创建`ProcessGroup`实例。
+ **构造**:DDP构造函数接受对本地模块的引用,并从排名为0的进程向组中的所有其他进程广播`state_dict()`,以确保所有模型副本从完全相同的状态开始。然后,每个DDP进程创建一个本地的`Reducer`,后者将在反向传递期间负责梯度同步。为了提高通信效率,`Reducer`将参数梯度组织成桶,并一次减少一个桶。可以通过在DDP构造函数中设置bucket_cap_mb参数来配置桶大小。参数梯度到桶的映射是在构造时确定的,基于桶大小限制和参数大小。模型参数按照给定模型的`Model.parameters()`的(大致)相反顺序分配到桶中。使用相反顺序的原因是因为DDP期望梯度在反向传递期间以大致相同的顺序准备就绪。下面的图显示了一个示例。请注意,`grad0``grad1``bucket1`中,另外两个梯度在`bucket0`中。当然,这种假设可能并不总是正确,当发生这种情况时,可能会影响DDP反向传递速度,因为`Reducer`无法在可能的最早时间开始通信。除了分桶,`Reducer`还在构造过程中注册自动求导钩子,每个参数一个钩子。这些钩子将在梯度准备就绪时在反向传递期间触发。
+ **构造**:DDP 构造函数接受对本地模块的引用,并从排名为 0 的进程向组中的所有其他进程广播`state_dict()`,以确保所有模型副本从完全相同的状态开始。然后,每个 DDP 进程创建一个本地的`Reducer`,后者将在反向传递期间负责梯度同步。为了提高通信效率,`Reducer`将参数梯度组织成桶,并一次减少一个桶。可以通过在 DDP 构造函数中设置 bucket_cap_mb 参数来配置桶大小。参数梯度到桶的映射是在构造时确定的,基于桶大小限制和参数大小。模型参数按照给定模型的`Model.parameters()`的(大致)相反顺序分配到桶中。使用相反顺序的原因是因为 DDP 期望梯度在反向传递期间以大致相同的顺序准备就绪。下面的图显示了一个示例。请注意,`grad0``grad1``bucket1`中,另外两个梯度在`bucket0`中。当然,这种假设可能并不总是正确,当发生这种情况时,可能会影响 DDP 反向传递速度,因为`Reducer`无法在可能的最早时间开始通信。除了分桶,`Reducer`还在构造过程中注册自动求导钩子,每个参数一个钩子。这些钩子将在梯度准备就绪时在反向传递期间触发。
+ **前向传播**:DDP接受输入并将其传递给本地模型,然后分析本地模型的输出,如果`find_unused_parameters`设置为`True`。此模式允许在模型的子图上运行反向传播,DDP通过从模型输出遍历自动求导图并标记所有未使用的参数为准备好进行减少。在反向传播期间,`Reducer`只会等待未准备好的参数,但仍会减少所有桶。将参数梯度标记为准备好不会帮助DDP跳过桶,但它将防止DDP在反向传播期间永远等待缺失的梯度。请注意,遍历自动求导图会引入额外的开销,因此应用程序只应在必要时将`find_unused_parameters`设置为`True`
+ **前向传播**:DDP 接受输入并将其传递给本地模型,然后分析本地模型的输出,如果`find_unused_parameters`设置为`True`。此模式允许在模型的子图上运行反向传播,DDP 通过从模型输出遍历自动求导图并标记所有未使用的参数为准备好进行减少。在反向传播期间,`Reducer`只会等待未准备好的参数,但仍会减少所有桶。将参数梯度标记为准备好不会帮助 DDP 跳过桶,但它将防止 DDP 在反向传播期间永远等待缺失的梯度。请注意,遍历自动求导图会引入额外的开销,因此应用程序只应在必要时将`find_unused_parameters`设置为`True`
+ **反向传播**`backward()`函数直接在损失`Tensor`上调用,这是DDP无法控制的,DDP在构造时使用的自动求导钩子来触发梯度同步。当一个梯度准备就绪时,其对应的DDP钩子将触发该梯度累加器上的梯度,并且DDP将标记该参数梯度为准备好进行减少。当一个桶中的梯度都准备就绪时,`Reducer`会在该桶上启动一个异步的`allreduce`来计算所有进程中梯度的平均值。当所有桶都准备就绪时,`Reducer`将阻塞等待所有`allreduce`操作完成。完成后,平均梯度将写入所有参数的`param.grad`字段。因此,在反向传播之后,不同DDP进程中相应参数的grad字段应该是相同的。
+ **反向传播**`backward()`函数直接在损失`Tensor`上调用,这是 DDP 无法控制的,DDP 在构造时使用的自动求导钩子来触发梯度同步。当一个梯度准备就绪时,其对应的 DDP 钩子将触发该梯度累加器上的梯度,并且 DDP 将标记该参数梯度为准备好进行减少。当一个桶中的梯度都准备就绪时,`Reducer`会在该桶上启动一个异步的`allreduce`来计算所有进程中梯度的平均值。当所有桶都准备就绪时,`Reducer`将阻塞等待所有`allreduce`操作完成。完成后,平均梯度将写入所有参数的`param.grad`字段。因此,在反向传播之后,不同 DDP 进程中相应参数的 grad 字段应该是相同的。
+ **优化器步骤**:从优化器的角度来看,它正在优化一个本地模型。所有DDP进程上的模型副本可以保持同步,因为它们都从相同的状态开始,并且它们在每次迭代中具有相同的平均梯度。
+ **优化器步骤**:从优化器的角度来看,它正在优化一个本地模型。所有 DDP 进程上的模型副本可以保持同步,因为它们都从相同的状态开始,并且它们在每次迭代中具有相同的平均梯度。
[![ddp_grad_sync.png](../Images/7fd0c1da1ad18ef7e8187a73ace04695.png)](https://user-images.githubusercontent.com/16999635/72401724-d296d880-371a-11ea-90ab-737f86543df9.png)
![ddp_grad_sync.png](https://user-images.githubusercontent.com/16999635/72401724-d296d880-371a-11ea-90ab-737f86543df9.png)
注意
DDP要求所有进程上的`Reducer`实例以完全相同的顺序调用`allreduce`,这是通过始终按照桶索引顺序而不是实际桶准备就绪顺序来运行`allreduce`来实现的。跨进程的`allreduce`顺序不匹配可能导致错误的结果或DDP反向传播挂起。
DDP 要求所有进程上的`Reducer`实例以完全相同的顺序调用`allreduce`,这是通过始终按照桶索引顺序而不是实际桶准备就绪顺序来运行`allreduce`来实现的。跨进程的`allreduce`顺序不匹配可能导致错误的结果或 DDP 反向传播挂起。
## 实现
以下是DDP实现组件的指针。堆叠图显示了代码的结构。
以下是 DDP 实现组件的指针。堆叠图显示了代码的结构。
### ProcessGroup
+ [ProcessGroup.hpp](https://github.com/pytorch/pytorch/blob/v1.7.0/torch/lib/c10d/ProcessGroup.hpp):包含所有进程组实现的抽象API。`c10d`库提供了3种开箱即用的实现,即ProcessGroupGloo、ProcessGroupNCCL和ProcessGroupMPI。`DistributedDataParallel`使用`ProcessGroup::broadcast()`在初始化期间从排名为0的进程向其他进程发送模型状态,并使用`ProcessGroup::allreduce()`来求和梯度。
+ [ProcessGroup.hpp](https://github.com/pytorch/pytorch/blob/v1.7.0/torch/lib/c10d/ProcessGroup.hpp):包含所有进程组实现的抽象 API。`c10d`库提供了 3 种开箱即用的实现,即 ProcessGroupGloo、ProcessGroupNCCL 和 ProcessGroupMPI。`DistributedDataParallel`使用`ProcessGroup::broadcast()`在初始化期间从排名为 0 的进程向其他进程发送模型状态,并使用`ProcessGroup::allreduce()`来求和梯度。
+ [Store.hpp](https://github.com/pytorch/pytorch/blob/v1.7.0/torch/lib/c10d/Store.hpp):协助进程组实例的会合服务找到彼此。
### DistributedDataParallel
+ [distributed.py](https://github.com/pytorch/pytorch/blob/v1.7.0/torch/nn/parallel/distributed.py):是DDP的Python入口点。它实现了初始化步骤和`nn.parallel.DistributedDataParallel`模块的`forward`函数,该函数调用C++库。其`_sync_param`函数在一个DDP进程在多个设备上工作时执行进程内参数同步,并且它还会将模型缓冲区从排名为0的进程广播到所有其他进程。进程间参数同步发生在`Reducer.cpp`中。
+ [distributed.py](https://github.com/pytorch/pytorch/blob/v1.7.0/torch/nn/parallel/distributed.py):是 DDP 的 Python 入口点。它实现了初始化步骤和`nn.parallel.DistributedDataParallel`模块的`forward`函数,该函数调用 C++库。其`_sync_param`函数在一个 DDP 进程在多个设备上工作时执行进程内参数同步,并且它还会将模型缓冲区从排名为 0 的进程广播到所有其他进程。进程间参数同步发生在`Reducer.cpp`中。
+ [comm.h](https://github.com/pytorch/pytorch/blob/v1.7.0/torch/csrc/distributed/c10d/comm.h):实现了合并广播辅助函数,用于在初始化期间广播模型状态并在前向传递之前同步模型缓冲区。
......@@ -105,16 +105,16 @@ DDP要求所有进程上的`Reducer`实例以完全相同的顺序调用`allredu
+ `autograd_hook()`函数将在梯度准备就绪时被自动求导引擎调用。
+ `prepare_for_backward()`在`distributed.py`中的DDP前向传递结束时被调用。当在DDP构造函数中将`find_unused_parameters`设置为`True`时,它会遍历自动求导图以找到未使用的参数。
+ `prepare_for_backward()`在`distributed.py`中的 DDP 前向传递结束时被调用。当在 DDP 构造函数中将`find_unused_parameters`设置为`True`时,它会遍历自动求导图以找到未使用的参数。
[![ddp_code.png](../Images/0b2511513fe6a3326d13ebd545cfb730.png)](https://user-images.githubusercontent.com/16999635/72313120-4e7c1c80-3658-11ea-9c6d-44336b2daeac.png)
![ddp_code.png](https://user-images.githubusercontent.com/16999635/72313120-4e7c1c80-3658-11ea-9c6d-44336b2daeac.png)
### TorchDynamo DDPOptimizer
DDP的性能优势来自在反向传递期间将allreduce集体操作与计算重叠。当与TorchDynamo一起使用时,AotAutograd会阻止这种重叠,因为它用于编译整个前向和整个反向图形,这会导致在整个优化的反向计算完成后,梯度同步操作由自动求导钩子在之后启动。
DDP 的性能优势来自在反向传递期间将 allreduce 集体操作与计算重叠。当与 TorchDynamo 一起使用时,AotAutograd 会阻止这种重叠,因为它用于编译整个前向和整个反向图形,这会导致在整个优化的反向计算完成后,梯度同步操作由自动求导钩子在之后启动。
TorchDynamo的DDPOptimizer通过在反向传递期间在DDP的allreduce桶的逻辑边界处中断前向图来帮助。注意:目标是在反向传递期间中断图形,最简单的实现方式是在前向图形中断,然后在每个部分上调用AotAutograd和编译。这允许DDP的allreduce钩子在反向传递的各个部分之间触发,并安排通信与计算重叠。
TorchDynamo 的 DDPOptimizer 通过在反向传递期间在 DDP 的 allreduce 桶的逻辑边界处中断前向图来帮助。注意:目标是在反向传递期间中断图形,最简单的实现方式是在前向图形中断,然后在每个部分上调用 AotAutograd 和编译。这允许 DDP 的 allreduce 钩子在反向传递的各个部分之间触发,并安排通信与计算重叠。
查看[这篇博客文章](https://dev-discuss.pytorch.org/t/torchdynamo-update-9-making-ddp-work-with-torchdynamo/860/1)以获取更深入的解释和实验结果,或者在[torch/_dynamo/optimizations/distributed.py](https://github.com/pytorch/pytorch/blob/4908a12542798a3e8641faae6b74f068fdfc6778/torch/_dynamo/optimizations/distributed.py#L56)中阅读文档和代码
要调试DDPOptimizer,请将torch._dynamo.config.log_level设置为DEBUG(用于完整图形转储)或INFO(用于有关桶边界的基本信息)。要禁用DDPOptimizer,请将torch._dynamo.config.optimize_ddp设置为False。DDP和TorchDynamo应该在没有DDPOptimizer的情况下仍能正常工作,但性能会下降。
要调试 DDPOptimizer,请将 torch._dynamo.config.log_level 设置为 DEBUG(用于完整图形转储)或 INFO(用于有关桶边界的基本信息)。要禁用 DDPOptimizer,请将 torch._dynamo.config.optimize_ddp 设置为 False。DDP 和 TorchDynamo 应该在没有 DDPOptimizer 的情况下仍能正常工作,但性能会下降。
此差异已折叠。
此差异已折叠。
# 常见问题
> 原文:[https://pytorch.org/docs/stable/notes/faq.html](https://pytorch.org/docs/stable/notes/faq.html)
> 原文:[`pytorch.org/docs/stable/notes/faq.html`](https://pytorch.org/docs/stable/notes/faq.html)
## 我的模型报告“cuda运行时错误(2):内存不足”[](#my-model-reports-cuda-runtime-error-2-out-of-memory "跳转到此标题的永久链接")
## 我的模型报告“cuda 运行时错误(2):内存不足”[](#my-model-reports-cuda-runtime-error-2-out-of-memory "跳转到此标题的永久链接")
正如错误消息所示,您的GPU上的内存已耗尽。由于我们在PyTorch中经常处理大量数据,小错误可能迅速导致程序使用完所有GPU的内存;幸运的是,在这些情况下修复通常很简单。以下是一些常见的检查事项:
正如错误消息所示,您的 GPU 上的内存已耗尽。由于我们在 PyTorch 中经常处理大量数据,小错误可能迅速导致程序使用完所有 GPU 的内存;幸运的是,在这些情况下修复通常很简单。以下是一些常见的检查事项:
**不要在整个训练循环中积累历史。**默认情况下,涉及需要梯度的变量的计算将保留历史记录。这意味着您应该避免在超出训练循环的计算中使用这些变量,例如跟踪统计数据。相反,您应该分离变量或访问其基础数据。
......@@ -21,11 +21,11 @@ for i in range(10000):
total_loss += loss
```
在这里,`total_loss`在整个训练循环中积累历史,因为`loss`是一个具有自动求导历史的可微变量。您可以通过编写total_loss += float(loss)来修复这个问题。
在这里,`total_loss`在整个训练循环中积累历史,因为`loss`是一个具有自动求导历史的可微变量。您可以通过编写 total_loss += float(loss)来修复这个问题。
此问题的其他实例:[1](https://discuss.pytorch.org/t/resolved-gpu-out-of-memory-error-with-batch-size-1/3719)
**不要保留不需要的张量和变量。**如果将Tensor或Variable分配给本地变量,Python将不会释放,直到本地变量超出作用域。您可以通过使用`del x`来释放此引用。同样,如果将Tensor或Variable分配给对象的成员变量,直到对象超出作用域,它将不会释放。如果不保留不需要的临时变量,您将获得最佳的内存使用情况。
**不要保留不需要的张量和变量。**如果将 Tensor 或 Variable 分配给本地变量,Python 将不会释放,直到本地变量超出作用域。您可以通过使用`del x`来释放此引用。同样,如果将 Tensor 或 Variable 分配给对象的成员变量,直到对象超出作用域,它将不会释放。如果不保留不需要的临时变量,您将获得最佳的内存使用情况。
本地变量的作用域可能比您预期的要大。例如:
......@@ -39,19 +39,19 @@ return output
在这里,`intermediate`即使在`h`执行时仍然存在,因为其作用域延伸到循环结束之后。为了更早释放它,您应该在完成后`del intermediate`
**避免在太大的序列上运行RNN。**通过RNN进行反向传播所需的内存量与RNN输入的长度成线性关系;因此,如果尝试向RNN提供太长的序列,将会耗尽内存。
**避免在太大的序列上运行 RNN。**通过 RNN 进行反向传播所需的内存量与 RNN 输入的长度成线性关系;因此,如果尝试向 RNN 提供太长的序列,将会耗尽内存。
这种现象的技术术语是[时间反向传播](https://en.wikipedia.org/wiki/Backpropagation_through_time),有很多关于如何实现截断BPTT的参考资料,包括在[word语言模型](https://github.com/pytorch/examples/tree/master/word_language_model)示例中;截断由`repackage`函数处理,如[this forum post](https://discuss.pytorch.org/t/help-clarifying-repackage-hidden-in-word-language-model/226)中所述。
这种现象的技术术语是[时间反向传播](https://en.wikipedia.org/wiki/Backpropagation_through_time),有很多关于如何实现截断 BPTT 的参考资料,包括在[word 语言模型](https://github.com/pytorch/examples/tree/master/word_language_model)示例中;截断由`repackage`函数处理,如[this forum post](https://discuss.pytorch.org/t/help-clarifying-repackage-hidden-in-word-language-model/226)中所述。
**不要使用太大的线性层。**线性层`nn.Linear(m, n)`使用$O(nm)$O(nm)内存:也就是说,权重的内存需求与特征数量呈二次比例。通过这种方式很容易[耗尽内存](https://github.com/pytorch/pytorch/issues/958)(请记住,您至少需要两倍于权重大小的内存,因为您还需要存储梯度)。
**考虑使用检查点。**您可以通过使用[checkpoint](https://pytorch.org/docs/stable/checkpoint.html)来在内存和计算之间进行权衡。
## 我的GPU内存没有正确释放[](#my-gpu-memory-isn-t-freed-properly "跳转到此标题的永久链接")
## 我的 GPU 内存没有正确释放[](#my-gpu-memory-isn-t-freed-properly "跳转到此标题的永久链接")
PyTorch使用缓存内存分配器来加速内存分配。因此,`nvidia-smi`中显示的值通常不反映真实的内存使用情况。有关GPU内存管理的更多详细信息,请参见[内存管理](cuda.html#cuda-memory-management)
PyTorch 使用缓存内存分配器来加速内存分配。因此,`nvidia-smi`中显示的值通常不反映真实的内存使用情况。有关 GPU 内存管理的更多详细信息,请参见内存管理
如果即使在Python退出后GPU内存仍未释放,很可能仍有一些Python子进程在运行。您可以通过`ps -elf | grep python`找到它们,并使用`kill -9 [pid]`手动杀死它们。
如果即使在 Python 退出后 GPU 内存仍未释放,很可能仍有一些 Python 子进程在运行。您可以通过`ps -elf | grep python`找到它们,并使用`kill -9 [pid]`手动杀死它们。
## 我的内存不足异常处理程序无法分配内存[](#my-out-of-memory-exception-handler-can-t-allocate-memory "跳转到此标题")
......@@ -65,7 +65,7 @@ except RuntimeError: # Out of memory
run_model(1)
```
但是发现当内存不足时,您的恢复代码也无法分配。这是因为Python异常对象保留了引用到引发错误的堆栈帧。这会阻止原始张量对象被释放。解决方案是将OOM恢复代码移出`except`子句。
但是发现当内存不足时,您的恢复代码也无法分配。这是因为 Python 异常对象保留了引用到引发错误的堆栈帧。这会阻止原始张量对象被释放。解决方案是将 OOM 恢复代码移出`except`子句。
```py
oom = False
......@@ -81,9 +81,9 @@ if oom:
## 我的数据加载器工作程序返回相同的随机数[](#my-data-loader-workers-return-identical-random-numbers "跳转到此标题")
您可能正在使用其他库在数据集中生成随机数,并且工作程序子进程是通过`fork`启动的。请查看[`torch.utils.data.DataLoader`](../data.html#torch.utils.data.DataLoader "torch.utils.data.DataLoader")的文档,了解如何使用其`worker_init_fn`选项正确设置工作程序中的随机种子。## 我的循环网络无法与数据并行性一起工作[](#my-recurrent-network-doesn-t-work-with-data-parallelism "跳转到此标题")
您可能正在使用其他库在数据集中生成随机数,并且工作程序子进程是通过`fork`启动的。请查看`torch.utils.data.DataLoader`的文档,了解如何使用其`worker_init_fn`选项正确设置工作程序中的随机种子。## 我的循环网络无法与数据并行性一起工作[](#my-recurrent-network-doesn-t-work-with-data-parallelism "跳转到此标题")
在使用[`Module`](../generated/torch.nn.Module.html#torch.nn.Module "torch.nn.Module")[`DataParallel`](../generated/torch.nn.DataParallel.html#torch.nn.DataParallel "torch.nn.DataParallel")[`data_parallel()`](../nn.html#module-torch.nn.parallel.data_parallel "torch.nn.parallel.data_parallel")时,使用`pack sequence -> recurrent network -> unpack sequence`模式存在一个微妙之处。每个设备上的`forward()`的输入只会是整个输入的一部分。因为解包操作[`torch.nn.utils.rnn.pad_packed_sequence()`](../generated/torch.nn.utils.rnn.pad_packed_sequence.html#torch.nn.utils.rnn.pad_packed_sequence "torch.nn.utils.rnn.pad_packed_sequence")默认只填充到它看到的最长输入,即该特定设备上的最长输入,当结果被收集在一起时会发生大小不匹配。因此,您可以利用[`pad_packed_sequence()`](../generated/torch.nn.utils.rnn.pad_packed_sequence.html#torch.nn.utils.rnn.pad_packed_sequence "torch.nn.utils.rnn.pad_packed_sequence")`total_length`参数,以确保`forward()`调用返回相同长度的序列。例如,您可以编写:
在使用`Module``DataParallel``data_parallel()`时,使用`pack sequence -> recurrent network -> unpack sequence`模式存在一个微妙之处。每个设备上的`forward()`的输入只会是整个输入的一部分。因为解包操作`torch.nn.utils.rnn.pad_packed_sequence()`默认只填充到它看到的最长输入,即该特定设备上的最长输入,当结果被收集在一起时会发生大小不匹配。因此,您可以利用`pad_packed_sequence()``total_length`参数,以确保`forward()`调用返回相同长度的序列。例如,您可以编写:
```py
from torch.nn.utils.rnn import pack_padded_sequence, pad_packed_sequence
......
# Gradcheck机制
# Gradcheck 机制
> [https://pytorch.org/docs/stable/notes/gradcheck.html](https://pytorch.org/docs/stable/notes/gradcheck.html)
> [`pytorch.org/docs/stable/notes/gradcheck.html`](https://pytorch.org/docs/stable/notes/gradcheck.html)
本说明概述了[`gradcheck()`](../autograd.html#module-torch.autograd.gradcheck)`gradgradcheck()`函数的工作原理。
本说明概述了`gradcheck()``gradgradcheck()`函数的工作原理。
它将涵盖实数和复数值函数的前向和反向模式AD,以及高阶导数。本说明还涵盖了gradcheck的默认行为以及传递`fast_mode=True`参数的情况(以下简称为快速gradcheck)。
它将涵盖实数和复数值函数的前向和反向模式 AD,以及高阶导数。本说明还涵盖了 gradcheck 的默认行为以及传递`fast_mode=True`参数的情况(以下简称为快速 gradcheck)。
+ [符号和背景信息]
+ [默认的反向模式gradcheck行为]
+ [默认的反向模式 gradcheck 行为]
+ [实数到实数函数]
......@@ -16,15 +16,15 @@
+ [具有复数输出的函数]
+ [快速反向模式gradcheck]
+ [快速反向模式 gradcheck]
+ [实数到实数函数的快速gradcheck]
+ [实数到实数函数的快速 gradcheck]
+ [复数到实数函数的快速gradcheck]
+ [复数到实数函数的快速 gradcheck]
+ [具有复数输出的函数的快速gradcheck]
+ [具有复数输出的函数的快速 gradcheck]
+ [Gradgradcheck实现]
+ [Gradgradcheck 实现]
## [符号和背景信息]
......@@ -38,23 +38,23 @@
1. $g: \mathcal{C}^N \to \mathcal{R}^M$是我们的基本复数到实数函数,使得$y = g(z)$。
对于简单的实数到实数情况,我们将与$f$相关的雅可比矩阵记为$J_f$,大小为$M \times N$。这个矩阵包含所有偏导数,使得位置$(i, j)$处的条目包含$\frac{\partial y_i}{\partial x_j}$。然后,反向模式AD计算给定大小为$M$的向量$v$的数量$v^T J_f$。另一方面,前向模式AD计算给定大小为$N$的向量$u$的数量$J_f u$。
对于简单的实数到实数情况,我们将与$f$相关的雅可比矩阵记为$J_f$,大小为$M \times N$。这个矩阵包含所有偏导数,使得位置$(i, j)$处的条目包含$\frac{\partial y_i}{\partial x_j}$。然后,反向模式 AD 计算给定大小为$M$的向量$v$的数量$v^T J_f$。另一方面,前向模式 AD 计算给定大小为$N$的向量$u$的数量$J_f u$。
对于包含复数值的函数,情况要复杂得多。我们这里只提供概要,完整描述可以在[复数数值的Autograd](autograd.html#complex-autograd-doc)中找到。
对于包含复数值的函数,情况要复杂得多。我们这里只提供概要,完整描述可以在复数数值的 Autograd 中找到。
满足复数可微性(柯西-黎曼方程)的约束对于所有实值损失函数来说太过严格,因此我们选择使用Wirtinger微积分。在Wirtinger微积分的基本设置中,链式法则要求同时访问Wirtinger导数(以下称为$W$)和共轭Wirtinger导数(以下称为$CW$)。由于一般情况下,尽管它们的名称如此,但$W$和$CW$都需要传播,因为它们不是彼此的复共轭。
满足复数可微性(柯西-黎曼方程)的约束对于所有实值损失函数来说太过严格,因此我们选择使用 Wirtinger 微积分。在 Wirtinger 微积分的基本设置中,链式法则要求同时访问 Wirtinger 导数(以下称为$W$)和共轭 Wirtinger 导数(以下称为$CW$)。由于一般情况下,尽管它们的名称如此,但$W$和$CW$都需要传播,因为它们不是彼此的复共轭。
为了避免传播两个值,对于反向模式AD,我们总是假设正在计算导数的函数要么是实值函数,要么是更大的实值函数的一部分。这个假设意味着我们在反向传递过程中计算的所有中间梯度也与实值函数相关联。在实践中,当进行优化时,这个假设并不具限制性,因为这样的问题需要实值目标(复数之间没有自然的排序)。
为了避免传播两个值,对于反向模式 AD,我们总是假设正在计算导数的函数要么是实值函数,要么是更大的实值函数的一部分。这个假设意味着我们在反向传递过程中计算的所有中间梯度也与实值函数相关联。在实践中,当进行优化时,这个假设并不具限制性,因为这样的问题需要实值目标(复数之间没有自然的排序)。
在这种假设下,使用$W$和$CW$的定义,我们可以展示$W = CW^*$,因此只需要“通过图形向后传递”两个值中的一个,另一个可以轻松恢复。为了简化内部计算,PyTorch使用$2 * CW$作为向后传递和用户请求梯度时返回的值。类似于实数情况,当输出实际上在$\mathcal{R}^M$时,反向模式AD不会计算$2 * CW$,而只会计算$v^T (2 * CW)$,其中$v \in \mathcal{R}^M$。
在这种假设下,使用$W$和$CW$的定义,我们可以展示$W = CW^*$,因此只需要“通过图形向后传递”两个值中的一个,另一个可以轻松恢复。为了简化内部计算,PyTorch 使用$2 * CW$作为向后传递和用户请求梯度时返回的值。类似于实数情况,当输出实际上在$\mathcal{R}^M$时,反向模式 AD 不会计算$2 * CW$,而只会计算$v^T (2 * CW)$,其中$v \in \mathcal{R}^M$。
对于前向模式AD,我们使用类似的逻辑,假设函数是更大函数的一部分,其输入在$\mathcal{R}$中。在这种假设下,我们可以做出类似的声明,即每个中间结果对应于一个输入在$\mathcal{R}$中的函数,并且在这种情况下,使用$W$和$CW$的定义,我们可以展示中间函数的$W = CW$。为了确保前向和后向模式在一维函数的基本情况下计算相同的量,前向模式还计算$2 * CW$。类似于实数情况,当输入实际上在$\mathcal{R}^N$时,前向模式AD不会计算$2 * CW$,而只会计算$(2 * CW) u$,其中$u \in \mathcal{R}^N$。
对于前向模式 AD,我们使用类似的逻辑,假设函数是更大函数的一部分,其输入在$\mathcal{R}$中。在这种假设下,我们可以做出类似的声明,即每个中间结果对应于一个输入在$\mathcal{R}$中的函数,并且在这种情况下,使用$W$和$CW$的定义,我们可以展示中间函数的$W = CW$。为了确保前向和后向模式在一维函数的基本情况下计算相同的量,前向模式还计算$2 * CW$。类似于实数情况,当输入实际上在$\mathcal{R}^N$时,前向模式 AD 不会计算$2 * CW$,而只会计算$(2 * CW) u$,其中$u \in \mathcal{R}^N$。
## [默认反向模式gradcheck行为](#id3)
## 默认反向模式 gradcheck 行为
### [实数到实数函数](#id4)
### 实数到实数函数
为了测试一个函数$f: \mathcal{R}^N \to \mathcal{R}^M, x \to y$,我们以两种方式重建大小为$M \times N$的完整雅可比矩阵$J_f$:分析和数值。分析版本使用我们的反向模式AD,而数值版本使用有限差分。然后,逐个元素比较这两个重建的雅可比矩阵是否相等。
为了测试一个函数$f: \mathcal{R}^N \to \mathcal{R}^M, x \to y$,我们以两种方式重建大小为$M \times N$的完整雅可比矩阵$J_f$:分析和数值。分析版本使用我们的反向模式 AD,而数值版本使用有限差分。然后,逐个元素比较这两个重建的雅可比矩阵是否相等。
#### 默认实数输入数值评估
......@@ -68,11 +68,11 @@ $\frac{\partial y}{\partial x} \approx \frac{f(x + eps) - f(x - eps)}{2 * eps}$
#### 默认实数输入分析评估
对于分析评估,我们使用如上所述的事实,即反向模式AD计算$v^T J_f$。对于具有单个输出的函数,我们简单地使用$v = 1$来通过单个反向传递恢复完整的雅可比矩阵。
对于分析评估,我们使用如上所述的事实,即反向模式 AD 计算$v^T J_f$。对于具有单个输出的函数,我们简单地使用$v = 1$来通过单个反向传递恢复完整的雅可比矩阵。
对于具有多个输出的函数,我们使用一个for循环,迭代输出,其中每个$v$是一个依次对应于每个输出的one-hot向量。这样可以逐行重建$J_f$矩阵。
对于具有多个输出的函数,我们使用一个 for 循环,迭代输出,其中每个$v$是一个依次对应于每个输出的 one-hot 向量。这样可以逐行重建$J_f$矩阵。
### [复数到实数函数](#id5)
### 复数到实数函数
为了测试一个函数 $g: \mathcal{C}^N \to \mathcal{R}^M, z \to y$,其中 $z = a + i b$,我们重建包含 $2 * CW$ 的(复数值)矩阵。
......@@ -107,7 +107,7 @@ d[d_idx] = grad_out.conjugate() * conj_w_d + grad_out * w_d.conj()
由于反向模式 AD 已经精确计算了两倍的 $CW$ 导数,因此我们在这里与实数到实数情况一样使用相同的技巧,并在有多个实数输出时逐行重建矩阵。
### [具有复数输出的函数](#id6)
### 具有复数输出的函数
在这种情况下,用户提供的函数不符合自动微分的假设,即我们为其计算反向 AD 的函数是实值的。这意味着直接在这个函数上使用自动微分是不明确定义的。为了解决这个问题,我们将测试函数 $h: \mathcal{P}^N \to \mathcal{C}^M$(其中 $\mathcal{P}$ 可以是 $\mathcal{R}$ 或 $\mathcal{C}$)替换为两个函数:$hr$ 和 $hi$,使得:
......@@ -117,13 +117,13 @@ $\begin{aligned} hr(q) &:= real(f(q)) \\ hi(q) &:= imag(f(q)) \end{aligned}$
请注意,截至撰写时,代码并没有显式创建这些函数,而是通过将 $\text{grad\_out}$ 参数传递给不同的函数,手动使用 $real$ 或 $imag$ 函数执行链式规则。当 $\text{grad\_out} = 1$ 时,我们考虑 $hr$。当 $\text{grad\_out} = 1j$ 时,我们考虑 $hi$。
## [快速反向模式梯度检查](#id7)
## 快速反向模式梯度检查
尽管上述梯度检查的公式很好,为了确保正确性和可调试性,它非常慢,因为它重建了完整的雅可比矩阵。本节介绍了一种以更快的方式执行梯度检查的方法,而不影响其正确性。通过在检测到错误时添加特殊逻辑,可以恢复可调试性。在这种情况下,我们可以运行重建完整矩阵的默认版本,以向用户提供完整的细节。
这里的高级策略是找到一个标量量,可以通过数值和解析方法高效计算,并且能够很好地代表慢梯度检查计算的完整矩阵,以确保它能够捕捉雅可比矩阵中的任何差异。
### [实数到实数函数的快速梯度检查](#id8)
### 实数到实数函数的快速梯度检查
我们想要计算的标量量是给定随机向量 $v \in \mathcal{R}^M$ 和随机单位范数向量 $u \in \mathcal{R}^N$ 时的 $v^T J_f u$。
......@@ -157,7 +157,7 @@ $\begin{aligned} s &= 2 * v^T (real(CW) ur + i * imag(CW) ui) \\ &= 2 * v^T (\fr
对于分析情况,事情更简单,我们将公式重写为:
[复杂到实数函数的快速梯度检查](#id9)
复杂到实数函数的快速梯度检查
因此,我们可以利用反向模式自动微分提供的有效方法来计算$v^T (2 * CW)$,然后在重建最终复数标量$s$之前,将实部与$ur$和虚部与$ui$进行点积。
......@@ -169,11 +169,11 @@ $\begin{aligned} 2*CW u' &= (\frac{\partial y}{\partial a} + i \frac{\partial y}
这将需要四次实数到实数有限差分的评估(与上述方法相比多两倍)。由于这种方法没有更多的自由度(相同数量的实值变量),我们尝试在这里获得最快的评估,因此使用上述的另一种公式。
### [对于具有复杂输出的函数的快速 gradcheck](#id10)[](#fast-gradcheck-for-functions-with-complex-outputs "跳转到本标题")
### 对于具有复杂输出的函数的快速 gradcheck[](#fast-gradcheck-for-functions-with-complex-outputs "跳转到本标题")
就像在慢速情况下一样,我们考虑两个实值函数,并对每个函数使用上面的适当规则。
## [Gradgradcheck 实现](#id11)[](#gradgradcheck-implementation "跳转到本标题")
## Gradgradcheck 实现[](#gradgradcheck-implementation "跳转到本标题")
PyTorch 还提供了一个工具来验证二阶梯度。这里的目标是确保反向实现也是正确可微的,并计算正确的结果。
......
# HIP(ROCm)语义
> 原文:[https://pytorch.org/docs/stable/notes/hip.html](https://pytorch.org/docs/stable/notes/hip.html)
> 原文:[`pytorch.org/docs/stable/notes/hip.html`](https://pytorch.org/docs/stable/notes/hip.html)
ROCm™是AMD的开源软件平台,用于GPU加速的高性能计算和机器学习。HIP是ROCm的C++方言,旨在简化将CUDA应用程序转换为可移植的C++代码。在将现有CUDA应用程序(如PyTorch)转换为可移植的C++以及需要在AMD和NVIDIA之间实现可移植性的新项目中使用HIP。
ROCm™是 AMD 的开源软件平台,用于 GPU 加速的高性能计算和机器学习。HIP 是 ROCm 的 C++方言,旨在简化将 CUDA 应用程序转换为可移植的 C++代码。在将现有 CUDA 应用程序(如 PyTorch)转换为可移植的 C++以及需要在 AMD 和 NVIDIA 之间实现可移植性的新项目中使用 HIP。
## HIP接口重用CUDA接口
## HIP 接口重用 CUDA 接口
PyTorch for HIP有意重用现有的[`torch.cuda`](../cuda.html#module-torch.cuda)接口。这有助于加速现有PyTorch代码和模型的移植,因为几乎不需要进行任何代码更改。
PyTorch for HIP 有意重用现有的`torch.cuda`接口。这有助于加速现有 PyTorch 代码和模型的移植,因为几乎不需要进行任何代码更改。
来自[CUDA语义](cuda.html#cuda-semantics)的示例将在HIP上完全相同:
来自 CUDA 语义的示例将在 HIP 上完全相同:
```py
cuda = torch.device('cuda') # Default HIP device
......@@ -44,30 +44,30 @@ with torch.cuda.device(1):
e = torch.randn(2).to(cuda2)
f = torch.randn(2).cuda(cuda2)
# d.device, e.device, and f.device are all device(type='cuda', index=2)
```## 检查HIP
```## 检查 HIP
无论您是在CUDA还是HIP上使用PyTorch,调用[`is_available()`](../generated/torch.cuda.is_available.html#torch.cuda.is_available)的结果都将是相同的。如果您使用已构建有GPU支持的PyTorch,它将返回True。如果您必须检查正在使用的PyTorch版本,请参考下面的示例:
无论您是在 CUDA 还是 HIP 上使用 PyTorch,调用`is_available()`的结果都将是相同的。如果您使用已构建有 GPU 支持的 PyTorch,它将返回 True。如果您必须检查正在使用的 PyTorch 版本,请参考下面的示例:
```py
if torch.cuda.is_available() and torch.version.hip:
# do something specific for HIP
elif torch.cuda.is_available() and torch.version.cuda:
# do something specific for CUDA
```## ROCm上的TensorFloat-32(TF32)
```## ROCm 上的 TensorFloat-32(TF32)
ROCm上不支持TF32。## 内存管理
ROCm 上不支持 TF32。## 内存管理
PyTorch使用缓存内存分配器来加速内存分配。这允许快速的内存释放而无需设备同步。然而,分配器管理的未使用内存仍会显示为在`rocm-smi`中使用。您可以使用[`memory_allocated()`](../generated/torch.cuda.memory_allocated.html#torch.cuda.memory_allocated)[`max_memory_allocated()`](../generated/torch.cuda.max_memory_allocated.html#torch.cuda.max_memory_allocated)来监视张量占用的内存,并使用[`memory_reserved()`](../generated/torch.cuda.memory_reserved.html#torch.cuda.memory_reserved)[`max_memory_reserved()`](../generated/torch.cuda.max_memory_reserved.html#torch.cuda.max_memory_reserved)来监视缓存分配器管理的总内存量。调用[`empty_cache()`](../generated/torch.cuda.empty_cache.html#torch.cuda.empty_cache)会释放PyTorch中所有**未使用**的缓存内存,以便其他GPU应用程序可以使用。然而,张量占用的GPU内存不会被释放,因此不能增加供PyTorch使用的GPU内存量。
PyTorch 使用缓存内存分配器来加速内存分配。这允许快速的内存释放而无需设备同步。然而,分配器管理的未使用内存仍会显示为在`rocm-smi`中使用。您可以使用`memory_allocated()``max_memory_allocated()`来监视张量占用的内存,并使用`memory_reserved()``max_memory_reserved()`来监视缓存分配器管理的总内存量。调用`empty_cache()`会释放 PyTorch 中所有**未使用**的缓存内存,以便其他 GPU 应用程序可以使用。然而,张量占用的 GPU 内存不会被释放,因此不能增加供 PyTorch 使用的 GPU 内存量。
对于更高级的用户,我们通过[`memory_stats()`](../generated/torch.cuda.memory_stats.html#torch.cuda.memory_stats)提供更全面的内存基准测试。我们还提供通过[`memory_snapshot()`](../generated/torch.cuda.memory_snapshot.html#torch.cuda.memory_snapshot)捕获内存分配器状态的完整快照的能力,这可以帮助您了解代码产生的底层分配模式。
对于更高级的用户,我们通过`memory_stats()`提供更全面的内存基准测试。我们还提供通过`memory_snapshot()`捕获内存分配器状态的完整快照的能力,这可以帮助您了解代码产生的底层分配模式。
要调试内存错误,请在环境中设置`PYTORCH_NO_CUDA_MEMORY_CACHING=1`以禁用缓存。## hipFFT/rocFFT计划缓存
要调试内存错误,请在环境中设置`PYTORCH_NO_CUDA_MEMORY_CACHING=1`以禁用缓存。## hipFFT/rocFFT 计划缓存
不支持设置hipFFT/rocFFT计划的缓存大小。## torch.distributed后端
不支持设置 hipFFT/rocFFT 计划的缓存大小。## torch.distributed 后端
目前,仅支持“nccl”和“gloo”后端的torch.distributed在ROCm上。## C++中的CUDA API到HIP API映射
目前,仅支持“nccl”和“gloo”后端的 torch.distributed 在 ROCm 上。## C++中的 CUDA API 到 HIP API 映射
请参考:[https://rocmdocs.amd.com/en/latest/Programming_Guides/HIP_API_Guide.html](https://rocmdocs.amd.com/en/latest/Programming_Guides/HIP_API_Guide.html)
请参考:[`rocmdocs.amd.com/en/latest/Programming_Guides/HIP_API_Guide.html`](https://rocmdocs.amd.com/en/latest/Programming_Guides/HIP_API_Guide.html)
注意:CUDA_VERSION 宏、cudaRuntimeGetVersion 和 cudaDriverGetVersion API 的语义映射与 HIP_VERSION 宏、hipRuntimeGetVersion 和 hipDriverGetVersion API 的值不同。在进行版本检查时,请不要混用它们。
......@@ -89,7 +89,7 @@ PyTorch使用缓存内存分配器来加速内存分配。这允许快速的内
## 参考 CUDA 语义文档[](#refer-to-cuda-semantics-doc "跳转到此标题")
对于此处未列出的任何部分,请参考 CUDA 语义文档:[CUDA 语义](cuda.html#cuda-semantics)
对于此处未列出的任何部分,请参考 CUDA 语义文档:CUDA 语义
## 启用内核断言
......
# 大规模部署的功能
> 原文:[https://pytorch.org/docs/stable/notes/large_scale_deployments.html](https://pytorch.org/docs/stable/notes/large_scale_deployments.html)
> 原文:[`pytorch.org/docs/stable/notes/large_scale_deployments.html`](https://pytorch.org/docs/stable/notes/large_scale_deployments.html)
+ [全局操作符分析](#fleet-wide-operator-profiling)
+ 全局操作符分析
+ [API 使用日志记录](#api-usage-logging)
+ API 使用日志记录
+ [将元数据附加到保存的 TorchScript 模型](#attaching-metadata-to-saved-torchscript-models)
+ 将元数据附加到保存的 TorchScript 模型
+ [构建环境注意事项](#build-environment-considerations)
+ 构建环境注意事项
+ [常见扩展点](#common-extension-points)
+ 常见扩展点
本说明介绍了在更大系统中运行 PyTorch 或在更大组织中操作使用 PyTorch 的多个系统时可能有用的几个扩展点和技巧。
这并不涵盖将模型部署到生产环境的主题。请查看 [`torch.jit`](../jit.html#module-torch.jit "torch.jit") 或其中一个相应的教程。
这并不涵盖将模型部署到生产环境的主题。请查看 `torch.jit` 或其中一个相应的教程。
该说明假定您要么在组织中从源代码构建 PyTorch,要么具有在 PyTorch 使用时加载附加代码的静态链接能力。因此,许多钩子都公开为可以在集中位置触发一次的 C++ API,例如在静态初始化代码中。
## [全局操作符分析](#id1)[](#fleet-wide-operator-profiling "跳转到此标题")
## 全局操作符分析[](#fleet-wide-operator-profiling "跳转到此标题")
PyTorch 自带 [`torch.autograd.profiler`](../autograd.html#module-torch.autograd.profiler "torch.autograd.profiler"),能够按需测量各个操作符所花费的时间。可以使用相同的机制对运行 PyTorch 的任何进程进行“始终开启”测量。这对于收集在给定进程或整个机器集上运行的 PyTorch 工作负载信息可能很有用。
PyTorch 自带 `torch.autograd.profiler`,能够按需测量各个操作符所花费的时间。可以使用相同的机制对运行 PyTorch 的任何进程进行“始终开启”测量。这对于收集在给定进程或整个机器集上运行的 PyTorch 工作负载信息可能很有用。
可以使用 `torch::addGlobalCallback` 为任何操作符调用添加新的回调。钩子将使用描述调用上下文(例如名称)的 `torch::RecordFunction` 结构进行调用。如果启用,`RecordFunction::inputs()` 包含作为 `torch::IValue` 变体类型表示的函数参数。请注意,输入日志记录相对昂贵,因此必须显式启用。
......@@ -57,7 +57,7 @@ void onFunctionExit(const RecordFunction& fn) {
}
```
## [API 使用日志记录](#id2)
## API 使用日志记录
在更广泛的生态系统中运行时,例如在托管作业调度程序中,跟踪调用特定 PyTorch API 的二进制文件通常很有用。在几个重要的 API 点注入了简单的仪器,触发给定的回调。因为通常 PyTorch 在一次性的 Python 脚本中被调用,所以对于每个 API,回调只会在给定进程中触发一次。
......@@ -71,13 +71,13 @@ SetAPIUsageLogger([](const std::string& event_name) {
开发者注意:可以在 C++ 代码中使用 `C10_LOG_API_USAGE_ONCE("my_api")` 或在 Python 中使用 `torch._C._log_api_usage_once("my.api")` 来添加新的 API 触发点。
## [将元数据附加到保存的TorchScript模型](#id3)[](#attaching-metadata-to-saved-torchscript-models "跳转到此标题")
## 将元数据附加到保存的 TorchScript 模型[](#attaching-metadata-to-saved-torchscript-models "跳转到此标题")
TorchScript模块可以保存为捆绑序列化参数和模块代码的存档文件,作为TorchScript(参见[`torch.jit.save()`](../generated/torch.jit.save.html#torch.jit.save "torch.jit.save"))。通常方便将附加信息与模型一起捆绑,例如,模型生产者的描述或辅助工件。
TorchScript 模块可以保存为捆绑序列化参数和模块代码的存档文件,作为 TorchScript(参见`torch.jit.save()`)。通常方便将附加信息与模型一起捆绑,例如,模型生产者的描述或辅助工件。
可以通过将`_extra_files`参数传递给[`torch.jit.save()`](../generated/torch.jit.save.html#torch.jit.save "torch.jit.save")`torch::jit::load`来在保存过程中存储和检索任意二进制数据块。由于TorchScript文件是常规ZIP存档,额外信息被存储为存档的`extra/`目录中的常规文件。
可以通过将`_extra_files`参数传递给`torch.jit.save()``torch::jit::load`来在保存过程中存储和检索任意二进制数据块。由于 TorchScript 文件是常规 ZIP 存档,额外信息被存储为存档的`extra/`目录中的常规文件。
还有一个全局钩子,允许在当前进程中的任何TorchScript存档上附加额外文件。类似于数字相机生成的JPEG元数据,可能有助于使用生产者元数据标记模型。示例用法可能如下:
还有一个全局钩子,允许在当前进程中的任何 TorchScript 存档上附加额外文件。类似于数字相机生成的 JPEG 元数据,可能有助于使用生产者元数据标记模型。示例用法可能如下:
```py
SetExportModuleExtraFilesHook([](const Module&) {
......@@ -87,14 +87,14 @@ SetExportModuleExtraFilesHook([](const Module&) {
});
```
## [构建环境考虑](#id4)[](#build-environment-considerations "跳转到此标题")
## 构建环境考虑[](#build-environment-considerations "跳转到此标题")
TorchScript的编译需要访问原始的Python文件,因为它使用Python`inspect.getsource`调用。在某些生产环境中,可能需要显式部署`.py`文件以及预编译的`.pyc`文件。
TorchScript 的编译需要访问原始的 Python 文件,因为它使用 Python `inspect.getsource`调用。在某些生产环境中,可能需要显式部署`.py`文件以及预编译的`.pyc`文件。
## [常见扩展点](#id5)[](#common-extension-points "跳转到此标题")
## 常见扩展点[](#common-extension-points "跳转到此标题")
PyTorch的API通常松散耦合,很容易用专门版本替换组件。常见的扩展点包括:
PyTorch 的 API 通常松散耦合,很容易用专门版本替换组件。常见的扩展点包括:
+ 在C++中实现的自定义运算符 - 详细信息请参阅[教程](https://pytorch.org/tutorials/advanced/cpp_extension.html)
+ C++中实现的自定义运算符 - 详细信息请参阅[教程](https://pytorch.org/tutorials/advanced/cpp_extension.html)
+ 通常可以通过调用相应的Python库直接集成自定义数据读取。通过扩展[`Dataset`](../data.html#torch.utils.data.Dataset "torch.utils.data.Dataset")[`IterableDataset`](../data.html#torch.utils.data.IterableDataset "torch.utils.data.IterableDataset"),可以利用[`torch.utils.data`](../data.html#module-torch.utils.data "torch.utils.data")的现有功能。
+ 通常可以通过调用相应的 Python 库直接集成自定义数据读取。通过扩展`Dataset``IterableDataset`,可以利用`torch.utils.data`的现有功能。
此差异已折叠。
# MPS后端
# MPS 后端
> 原文:[https://pytorch.org/docs/stable/notes/mps.html](https://pytorch.org/docs/stable/notes/mps.html)
> 原文:[`pytorch.org/docs/stable/notes/mps.html`](https://pytorch.org/docs/stable/notes/mps.html)
`mps`设备使MacOS设备上的高性能训练成为可能,使用Metal编程框架。它引入了一个新设备,将机器学习计算图和基元映射到高效的Metal Performance Shaders图框架和分别由Metal Performance Shaders框架提供的调整过的内核。
`mps`设备使 MacOS 设备上的高性能训练成为可能,使用 Metal 编程框架。它引入了一个新设备,将机器学习计算图和基元映射到高效的 Metal Performance Shaders 图框架和分别由 Metal Performance Shaders 框架提供的调整过的内核。
新的MPS后端扩展了PyTorch生态系统,并为现有脚本提供了在GPU上设置和运行操作的能力。
新的 MPS 后端扩展了 PyTorch 生态系统,并为现有脚本提供了在 GPU 上设置和运行操作的能力。
要开始使用,只需将您的张量和模块移动到`mps`设备上:
......
# 多进程最佳实践
> 原文:[https://pytorch.org/docs/stable/notes/multiprocessing.html](https://pytorch.org/docs/stable/notes/multiprocessing.html)
> 原文:[`pytorch.org/docs/stable/notes/multiprocessing.html`](https://pytorch.org/docs/stable/notes/multiprocessing.html)
[`torch.multiprocessing`](../multiprocessing.html#module-torch.multiprocessing "torch.multiprocessing")是Python的[`multiprocessing`](https://docs.python.org/3/library/multiprocessing.html#module-multiprocessing "(在Python v3.12中)")模块的一个替代品。它支持完全相同的操作,但扩展了它,使得通过[`multiprocessing.Queue`](https://docs.python.org/3/library/multiprocessing.html#multiprocessing.Queue "(在Python v3.12中)")发送的所有张量的数据都会移动到共享内存中,并且只会发送一个句柄给另一个进程。
`torch.multiprocessing`是 Python 的[`multiprocessing`](https://docs.python.org/3/library/multiprocessing.html#module-multiprocessing "(在 Python v3.12 中)")模块的一个替代品。它支持完全相同的操作,但扩展了它,使得通过[`multiprocessing.Queue`](https://docs.python.org/3/library/multiprocessing.html#multiprocessing.Queue "(在 Python v3.12 中)")发送的所有张量的数据都会移动到共享内存中,并且只会发送一个句柄给另一个进程。
注意
当一个[`Tensor`](../tensors.html#torch.Tensor "torch.Tensor")被发送到另一个进程时,[`Tensor`](../tensors.html#torch.Tensor "torch.Tensor")的数据是共享的。如果[`torch.Tensor.grad`](../generated/torch.Tensor.grad.html#torch.Tensor.grad "torch.Tensor.grad")不是`None`,它也是共享的。在将一个没有[`torch.Tensor.grad`](../generated/torch.Tensor.grad.html#torch.Tensor.grad "torch.Tensor.grad")字段的[`Tensor`](../tensors.html#torch.Tensor "torch.Tensor")发送到另一个进程后,它会创建一个标准的进程特定的`.grad` [`Tensor`](../tensors.html#torch.Tensor "torch.Tensor"),这个`.grad` [`Tensor`](../tensors.html#torch.Tensor "torch.Tensor")不会自动在所有进程之间共享,不像[`Tensor`](../tensors.html#torch.Tensor "torch.Tensor")的数据已经被共享了。
当一个`Tensor`被发送到另一个进程时,`Tensor`的数据是共享的。如果`torch.Tensor.grad`不是`None`,它也是共享的。在将一个没有`torch.Tensor.grad`字段的`Tensor`发送到另一个进程后,它会创建一个标准的进程特定的`.grad` `Tensor`,这个`.grad` `Tensor`不会自动在所有进程之间共享,不像`Tensor`的数据已经被共享了。
这允许实现各种训练方法,如Hogwild、A3C或其他需要异步操作的方法。
这允许实现各种训练方法,如 Hogwild、A3C 或其他需要异步操作的方法。
## 多进程中的CUDA
## 多进程中的 CUDA
CUDA运行时不支持`fork`启动方法;在子进程中使用CUDA需要`spawn``forkserver`启动方法。
CUDA 运行时不支持`fork`启动方法;在子进程中使用 CUDA 需要`spawn``forkserver`启动方法。
注意
启动方法可以通过创建一个上下文`multiprocessing.get_context(...)`或直接使用`multiprocessing.set_start_method(...)`来设置。
CPU张量不同,发送进程需要保留原始张量,只要接收进程保留了张量的副本。这是在底层实现的,但需要用户遵循程序正确运行的最佳实践。例如,发送进程必须保持活动状态,只要消费者进程引用了张量,如果消费者进程通过致命信号异常退出,引用计数无法帮助您。请参阅[此部分](../multiprocessing.html#multiprocessing-cuda-sharing-details)
CPU 张量不同,发送进程需要保留原始张量,只要接收进程保留了张量的副本。这是在底层实现的,但需要用户遵循程序正确运行的最佳实践。例如,发送进程必须保持活动状态,只要消费者进程引用了张量,如果消费者进程通过致命信号异常退出,引用计数无法帮助您。请参阅此部分
另请参阅:[使用nn.parallel.DistributedDataParallel代替multiprocessing或nn.DataParallel](cuda.html#cuda-nn-ddp-instead)
另请参阅:使用 nn.parallel.DistributedDataParallel 代替 multiprocessing 或 nn.DataParallel
## 最佳实践和提示
### 避免和解决死锁[](#avoiding-and-fighting-deadlocks "跳转到此标题")
当生成一个新进程时,有很多事情可能会出错,最常见的死锁原因是后台线程。如果有任何持有锁或导入模块的线程,并且调用了`fork`,那么子进程很可能处于损坏状态,并且会发生死锁或以不同方式失败。请注意,即使您没有,Python内置库也会 - 不需要查看比[`multiprocessing`](https://docs.python.org/3/library/multiprocessing.html#module-multiprocessing "(在Python v3.12中)")更远的地方。[`multiprocessing.Queue`](https://docs.python.org/3/library/multiprocessing.html#multiprocessing.Queue "(在Python v3.12中)")实际上是一个非常复杂的类,它生成多个线程用于序列化、发送和接收对象,它们也可能引起上述问题。如果您发现自己处于这种情况,请尝试使用`SimpleQueue`,它不使用任何额外的线程。
当生成一个新进程时,有很多事情可能会出错,最常见的死锁原因是后台线程。如果有任何持有锁或导入模块的线程,并且调用了`fork`,那么子进程很可能处于损坏状态,并且会发生死锁或以不同方式失败。请注意,即使您没有,Python 内置库也会 - 不需要查看比[`multiprocessing`](https://docs.python.org/3/library/multiprocessing.html#module-multiprocessing "(在 Python v3.12 中)")更远的地方。[`multiprocessing.Queue`](https://docs.python.org/3/library/multiprocessing.html#multiprocessing.Queue "(在 Python v3.12 中)")实际上是一个非常复杂的类,它生成多个线程用于序列化、发送和接收对象,它们也可能引起上述问题。如果您发现自己处于这种情况,请尝试使用`SimpleQueue`,它不使用任何额外的线程。
我们正在尽力让您轻松使用,并确保这些死锁不会发生,但有些事情超出我们的控制。如果您遇到无法解决的问题,请尝试在论坛上寻求帮助,我们会看看是否可以解决。
### 通过队列传递的缓冲区[](#reuse-buffers-passed-through-a-queue "跳转到此标题")
请记住,每次将[`Tensor`](../tensors.html#torch.Tensor "torch.Tensor")放入[`multiprocessing.Queue`](https://docs.python.org/3/library/multiprocessing.html#multiprocessing.Queue "(在Python v3.12中)")时,它必须被移动到共享内存中。如果已经是共享的,则不会执行任何操作,否则将产生额外的内存复制,可能会减慢整个过程的速度。即使您有一组进程向单个进程发送数据,也要让它发送缓冲区回来 - 这几乎是免费的,并且可以避免在发送下一批数据时进行复制。
请记住,每次将`Tensor`放入[`multiprocessing.Queue`](https://docs.python.org/3/library/multiprocessing.html#multiprocessing.Queue "(在 Python v3.12 中)")时,它必须被移动到共享内存中。如果已经是共享的,则不会执行任何操作,否则将产生额外的内存复制,可能会减慢整个过程的速度。即使您有一组进程向单个进程发送数据,也要让它发送缓冲区回来 - 这几乎是免费的,并且可以避免在发送下一批数据时进行复制。
### 异步多进程训练(例如Hogwild)[](#asynchronous-multiprocess-training-e-g-hogwild "跳转到此标题")
### 异步多进程训练(例如 Hogwild)[](#asynchronous-multiprocess-training-e-g-hogwild "跳转到此标题")
使用[`torch.multiprocessing`](../multiprocessing.html#module-torch.multiprocessing "torch.multiprocessing"),可以异步训练模型,参数可以始终共享,或者定期同步。在第一种情况下,我们建议发送整个模型对象,而在后一种情况下,我们建议只发送[`state_dict()`](../generated/torch.nn.Module.html#torch.nn.Module.state_dict "torch.nn.Module.state_dict")
使用`torch.multiprocessing`,可以异步训练模型,参数可以始终共享,或者定期同步。在第一种情况下,我们建议发送整个模型对象,而在后一种情况下,我们建议只发送`state_dict()`
我们建议使用[`multiprocessing.Queue`](https://docs.python.org/3/library/multiprocessing.html#multiprocessing.Queue "(在Python v3.12中)")来在进程之间传递各种PyTorch对象。例如,当使用`fork`启动方法时,可以继承已经在共享内存中的张量和存储,但这很容易出错,应谨慎使用,仅供高级用户使用。队列,即使它们有时不够优雅,也会在所有情况下正常工作。
我们建议使用[`multiprocessing.Queue`](https://docs.python.org/3/library/multiprocessing.html#multiprocessing.Queue "(在 Python v3.12 中)")来在进程之间传递各种 PyTorch 对象。例如,当使用`fork`启动方法时,可以继承已经在共享内存中的张量和存储,但这很容易出错,应谨慎使用,仅供高级用户使用。队列,即使它们有时不够优雅,也会在所有情况下正常工作。
警告
......@@ -46,7 +46,7 @@ CUDA运行时不支持`fork`启动方法;在子进程中使用CUDA需要`spawn
#### Hogwild
[示例存储库](https://github.com/pytorch/examples/tree/master/mnist_hogwild)中可以找到一个具体的Hogwild实现,但为了展示代码的整体结构,下面也有一个最小示例:
[示例存储库](https://github.com/pytorch/examples/tree/master/mnist_hogwild)中可以找到一个具体的 Hogwild 实现,但为了展示代码的整体结构,下面也有一个最小示例:
```py
import torch.multiprocessing as mp
......@@ -73,41 +73,41 @@ if __name__ == '__main__':
p.join()
```
## 多进程中的CPU
## 多进程中的 CPU
不当的多进程可能导致CPU过度订阅,导致不同进程竞争CPU资源,导致效率低下。
不当的多进程可能导致 CPU 过度订阅,导致不同进程竞争 CPU 资源,导致效率低下。
本教程将解释什么是CPU过度订阅以及如何避免它。
本教程将解释什么是 CPU 过度订阅以及如何避免它。
### CPU过度订阅
### CPU 过度订阅
CPU过度订阅是一个技术术语,指的是分配给系统的虚拟CPU总数超过硬件上可用的虚拟CPU总数的情况。
CPU 过度订阅是一个技术术语,指的是分配给系统的虚拟 CPU 总数超过硬件上可用的虚拟 CPU 总数的情况。
这会导致CPU资源的严重争用。在这种情况下,进程之间频繁切换,增加了进程切换开销,降低了整个系统的效率。
这会导致 CPU 资源的严重争用。在这种情况下,进程之间频繁切换,增加了进程切换开销,降低了整个系统的效率。
[Hogwild实现](https://github.com/pytorch/examples/tree/main/mnist_hogwild)中的代码示例中查看CPU过度订阅。
[Hogwild 实现](https://github.com/pytorch/examples/tree/main/mnist_hogwild)中的代码示例中查看 CPU 过度订阅。
CPU上使用4个进程运行以下命令的训练示例:
CPU 上使用 4 个进程运行以下命令的训练示例:
```py
python main.py --num-processes 4
```
假设机器上有N个虚拟CPU可用,执行上述命令将生成4个子进程。每个子进程将为自己分配N个虚拟CPU,导致需要4*N个虚拟CPU。然而,机器上只有N个虚拟CPU可用。因此,不同的进程将竞争资源,导致频繁的进程切换。
假设机器上有 N 个虚拟 CPU 可用,执行上述命令将生成 4 个子进程。每个子进程将为自己分配 N 个虚拟 CPU,导致需要 4*N 个虚拟 CPU。然而,机器上只有 N 个虚拟 CPU 可用。因此,不同的进程将竞争资源,导致频繁的进程切换。
以下观察结果表明存在CPU过度订阅:
以下观察结果表明存在 CPU 过度订阅:
1.CPU利用率:通过使用`htop`命令,您可以观察到CPU利用率始终很高,经常达到或超过其最大容量。这表明对CPU资源的需求超过了可用的物理核心,导致进程之间的争用和竞争。
1. CPU 利用率:通过使用`htop`命令,您可以观察到 CPU 利用率始终很高,经常达到或超过其最大容量。这表明对 CPU 资源的需求超过了可用的物理核心,导致进程之间的争用和竞争。
1. 低系统效率下的频繁上下文切换:在CPU过度订阅的情况下,进程竞争CPU时间,操作系统需要快速在不同进程之间切换以公平分配资源。这种频繁的上下文切换会增加开销并降低整个系统的效率。
1. 低系统效率下的频繁上下文切换:在 CPU 过度订阅的情况下,进程竞争 CPU 时间,操作系统需要快速在不同进程之间切换以公平分配资源。这种频繁的上下文切换会增加开销并降低整个系统的效率。
### 避免CPU过度订阅
### 避免 CPU 过度订阅
避免CPU过度订阅的一个好方法是适当的资源分配。确保同时运行的进程或线程数量不超过可用的CPU资源。
避免 CPU 过度订阅的一个好方法是适当的资源分配。确保同时运行的进程或线程数量不超过可用的 CPU 资源。
在这种情况下,一个解决方案是在子进程中指定适当数量的线程。这可以通过在子进程中使用`torch.set_num_threads(int)`函数为每个进程设置线程数来实现。
假设机器上有N个虚拟CPU,并且将生成M个进程,每个进程使用的最大`num_threads`值将为`floor(N/M)`。为了避免在mnist_hogwild示例中出现CPU过度订阅,需要对[示例存储库](https://github.com/pytorch/examples/tree/main/mnist_hogwild)中的`train.py`文件进行以下更改。
假设机器上有 N 个虚拟 CPU,并且将生成 M 个进程,每个进程使用的最大`num_threads`值将为`floor(N/M)`。为了避免在 mnist_hogwild 示例中出现 CPU 过度订阅,需要对[示例存储库](https://github.com/pytorch/examples/tree/main/mnist_hogwild)中的`train.py`文件进行以下更改。
```py
def train(rank, args, model, device, dataset, dataloader_kwargs):
......@@ -123,4 +123,4 @@ def train(rank, args, model, device, dataset, dataloader_kwargs):
train_epoch(epoch, args, model, device, train_loader, optimizer)
```
使用`torch.set_num_threads(floor(N/M))`为每个进程设置`num_thread`。其中,将N替换为可用的虚拟CPU数量,将M替换为选择的进程数量。适当的`num_thread`值将根据手头的具体任务而变化。然而,作为一般准则,`num_thread`的最大值应为`floor(N/M)`,以避免CPU过度订阅。在[mnist_hogwild](https://github.com/pytorch/examples/tree/main/mnist_hogwild)训练示例中,在避免CPU过度订阅后,您可以实现30倍的性能提升。
使用`torch.set_num_threads(floor(N/M))`为每个进程设置`num_thread`。其中,将 N 替换为可用的虚拟 CPU 数量,将 M 替换为选择的进程数量。适当的`num_thread`值将根据手头的具体任务而变化。然而,作为一般准则,`num_thread`的最大值应为`floor(N/M)`,以避免 CPU 过度订阅。在[mnist_hogwild](https://github.com/pytorch/examples/tree/main/mnist_hogwild)训练示例中,在避免 CPU 过度订阅后,您可以实现 30 倍的性能提升。
# 数值精度
> 原文:[https://pytorch.org/docs/stable/notes/numerical_accuracy.html](https://pytorch.org/docs/stable/notes/numerical_accuracy.html)
> 原文:[`pytorch.org/docs/stable/notes/numerical_accuracy.html`](https://pytorch.org/docs/stable/notes/numerical_accuracy.html)
在现代计算机中,浮点数使用IEEE 754标准表示。有关浮点运算和IEEE 754标准的更多详细信息,请参见[浮点运算](https://en.wikipedia.org/wiki/Floating-point_arithmetic)。特别要注意的是,浮点提供有限的精度(单精度浮点数约为7位小数,双精度浮点数约为16位小数),浮点加法和乘法不是结合的,因此操作的顺序会影响结果。因此,PyTorch不能保证对于数学上相同的浮点计算产生按位相同的结果。同样,即使在控制随机源后,PyTorch发布、单个提交或不同平台之间也不能保证按位相同的结果。特别是,即使输入按位相同,CPU和GPU的结果也可能不同。
在现代计算机中,浮点数使用 IEEE 754 标准表示。有关浮点运算和 IEEE 754 标准的更多详细信息,请参见[浮点运算](https://en.wikipedia.org/wiki/Floating-point_arithmetic)。特别要注意的是,浮点提供有限的精度(单精度浮点数约为 7 位小数,双精度浮点数约为 16 位小数),浮点加法和乘法不是结合的,因此操作的顺序会影响结果。因此,PyTorch 不能保证对于数学上相同的浮点计算产生按位相同的结果。同样,即使在控制随机源后,PyTorch 发布、单个提交或不同平台之间也不能保证按位相同的结果。特别是,即使输入按位相同,CPU 和 GPU 的结果也可能不同。
## 批处理计算或切片计算[](#batched-computations-or-slice-computations "跳转到此标题")
PyTorch中的许多操作支持批处理计算,其中对输入批次的元素执行相同的操作。一个例子是[`torch.mm()`](../generated/torch.mm.html#torch.mm "torch.mm")[`torch.bmm()`](../generated/torch.bmm.html#torch.bmm "torch.bmm")。可以将批处理计算实现为对批处理元素的循环,并对各个批处理元素应用必要的数学操作,出于效率原因,我们没有这样做,通常对整个批次进行计算。在这种情况下,我们调用的数学库和PyTorch内部操作的实现可能与非批处理计算产生略有不同的结果。特别是,设`A``B`为适合批处理矩阵乘法的三维张量。那么`(A@B)[0]`(批处理结果的第一个元素)不能保证与`A[0]@B[0]`(输入批次的第一个元素的矩阵乘积)按位相同,尽管在数学上它是相同的计算。
PyTorch 中的许多操作支持批处理计算,其中对输入批次的元素执行相同的操作。一个例子是`torch.mm()``torch.bmm()`。可以将批处理计算实现为对批处理元素的循环,并对各个批处理元素应用必要的数学操作,出于效率原因,我们没有这样做,通常对整个批次进行计算。在这种情况下,我们调用的数学库和 PyTorch 内部操作的实现可能与非批处理计算产生略有不同的结果。特别是,设`A``B`为适合批处理矩阵乘法的三维张量。那么`(A@B)[0]`(批处理结果的第一个元素)不能保证与`A[0]@B[0]`(输入批次的第一个元素的矩阵乘积)按位相同,尽管在数学上它是相同的计算。
类似地,对张量切片应用的操作不能保证产生与对完整张量应用相同操作的结果切片相同。例如,设`A`为一个二维张量。`A.sum(-1)[0]`不能保证与`A[:,0].sum()`按位相等。
......@@ -27,47 +27,47 @@ a.double().norm() # produces tensor(1.4142e+20, dtype=torch.float64), representa
`torch.linalg` 使用的外部库(后端)在输入具有非有限值(如`inf``NaN`)时不提供其行为的任何保证。因此,PyTorch 也不提供。这些操作可能返回一个带有非有限值的张量,或引发异常,甚至导致段错误。
在调用这些函数之前考虑使用[`torch.isfinite()`](../generated/torch.isfinite.html#torch.isfinite "torch.isfinite")来检测这种情况。
在调用这些函数之前考虑使用`torch.isfinite()`来检测这种情况。
### linalg中的极端值
### linalg 中的极端值
`torch.linalg` 中的函数比其他PyTorch函数具有更多的[极端值](#extremal-values)
`torch.linalg` 中的函数比其他 PyTorch 函数具有更多的极端值
[求解器](../linalg.html#linalg-solvers)[逆矩阵](../linalg.html#linalg-inverses)假设输入矩阵`A`是可逆的。如果它接近不可逆(例如,如果它具有非常小的奇异值),那么这些算法可能会悄悄返回不正确的结果。这些矩阵被称为[病态矩阵](https://nhigham.com/2020/03/19/what-is-a-condition-number/)。如果提供了病态输入,这些函数的结果可能会因在不同设备上使用相同输入或通过关键字`driver`使用不同后端而有所不同。
求解器和逆矩阵假设输入矩阵`A`是可逆的。如果它接近不可逆(例如,如果它具有非常小的奇异值),那么这些算法可能会悄悄返回不正确的结果。这些矩阵被称为[病态矩阵](https://nhigham.com/2020/03/19/what-is-a-condition-number/)。如果提供了病态输入,这些函数的结果可能会因在不同设备上使用相同输入或通过关键字`driver`使用不同后端而有所不同。
`svd``eig``eigh`这样的谱操作在它们的输入具有接近的奇异值时也可能返回不正确的结果(它们的梯度可能是无穷大的)。这是因为用于计算这些分解的算法在这些输入上很难收敛。
`float64`(默认情况下NumPy所做的)运行计算通常有所帮助,但并不总是解决所有问题。通过[`torch.linalg.svdvals()`](../generated/torch.linalg.svdvals.html#torch.linalg.svdvals "torch.linalg.svdvals")分析输入的频谱或通过[`torch.linalg.cond()`](../generated/torch.linalg.cond.html#torch.linalg.cond "torch.linalg.cond")分析它们的条件数可能有助于检测这些问题。
`float64`(默认情况下 NumPy 所做的)运行计算通常有所帮助,但并不总是解决所有问题。通过`torch.linalg.svdvals()`分析输入的频谱或通过`torch.linalg.cond()`分析它们的条件数可能有助于检测这些问题。
## Nvidia Ampere(以及之后)设备上的TensorFloat-32(TF32)[](#tensorfloat-32-tf32-on-nvidia-ampere-and-later-devices "跳转到此标题的永久链接")
## Nvidia Ampere(以及之后)设备上的 TensorFloat-32(TF32)[](#tensorfloat-32-tf32-on-nvidia-ampere-and-later-devices "跳转到此标题的永久链接")
Ampere(以及之后)的Nvidia GPU上,PyTorch可以使用TensorFloat32(TF32)来加速数学密集型操作,特别是矩阵乘法和卷积。当使用TF32张量核心执行操作时,只读取输入尾数的前10位。这可能会降低精度并产生令人惊讶的结果(例如,将矩阵乘以单位矩阵可能会产生与输入不同的结果)。默认情况下,TF32张量核心在矩阵乘法中被禁用,并在卷积中启用,尽管大多数神经网络工作负载在使用TF32时具有与fp32相同的收敛行为。如果您的网络不需要完整的float32精度,我们建议通过`torch.backends.cuda.matmul.allow_tf32 = True`启用TF32张量核心进行矩阵乘法。如果您的网络在矩阵乘法和卷积中都需要完整的float32精度,则可以通过`torch.backends.cudnn.allow_tf32 = False`禁用卷积的TF32张量核心。
Ampere(以及之后)的 Nvidia GPU 上,PyTorch 可以使用 TensorFloat32(TF32)来加速数学密集型操作,特别是矩阵乘法和卷积。当使用 TF32 张量核心执行操作时,只读取输入尾数的前 10 位。这可能会降低精度并产生令人惊讶的结果(例如,将矩阵乘以单位矩阵可能会产生与输入不同的结果)。默认情况下,TF32 张量核心在矩阵乘法中被禁用,并在卷积中启用,尽管大多数神经网络工作负载在使用 TF32 时具有与 fp32 相同的收敛行为。如果您的网络不需要完整的 float32 精度,我们建议通过`torch.backends.cuda.matmul.allow_tf32 = True`启用 TF32 张量核心进行矩阵乘法。如果您的网络在矩阵乘法和卷积中都需要完整的 float32 精度,则可以通过`torch.backends.cudnn.allow_tf32 = False`禁用卷积的 TF32 张量核心。
有关更多信息,请参阅[TensorFloat32](cuda.html#tf32-on-ampere)
有关更多信息,请参阅 TensorFloat32
## FP16和BF16 GEMM的降低精度[](#reduced-precision-reduction-for-fp16-and-bf16-gemms "跳转到此标题的永久链接")
## FP16 和 BF16 GEMM 的降低精度[](#reduced-precision-reduction-for-fp16-and-bf16-gemms "跳转到此标题的永久链接")
半精度GEMM操作通常使用单精度进行中间累积(降低)以提高数值精度和对溢出的抵抗力。为了性能,某些GPU架构,特别是较新的架构,允许将中间累积结果截断为降低精度(例如,半精度)。从模型收敛的角度来看,这种变化通常是良性的,尽管它可能导致意外的结果(例如,当最终结果应该在半精度中表示时出现`inf`值)。如果降低精度的降低造成问题,可以通过`torch.backends.cuda.matmul.allow_fp16_reduced_precision_reduction = False`关闭。
半精度 GEMM 操作通常使用单精度进行中间累积(降低)以提高数值精度和对溢出的抵抗力。为了性能,某些 GPU 架构,特别是较新的架构,允许将中间累积结果截断为降低精度(例如,半精度)。从模型收敛的角度来看,这种变化通常是良性的,尽管它可能导致意外的结果(例如,当最终结果应该在半精度中表示时出现`inf`值)。如果降低精度的降低造成问题,可以通过`torch.backends.cuda.matmul.allow_fp16_reduced_precision_reduction = False`关闭。
BF16 GEMM操作也有类似的标志,默认情况下是打开的。如果BF16降低精度造成问题,可以通过`torch.backends.cuda.matmul.allow_bf16_reduced_precision_reduction = False`关闭。
BF16 GEMM 操作也有类似的标志,默认情况下是打开的。如果 BF16 降低精度造成问题,可以通过`torch.backends.cuda.matmul.allow_bf16_reduced_precision_reduction = False`关闭。
有关更多信息,请参阅[allow_fp16_reduced_precision_reduction](cuda.html#fp16reducedprecision)[allow_bf16_reduced_precision_reduction](cuda.html#bf16reducedprecision)
有关更多信息,请参阅 allow_fp16_reduced_precision_reduction 和 allow_bf16_reduced_precision_reduction
## 在AMD Instinct MI200设备上降低精度的FP16和BF16 GEMMs和卷积[](#reduced-precision-fp16-and-bf16-gemms-and-convolutions-on-amd-instinct-mi200-devices "跳转到此标题的永久链接")
## 在 AMD Instinct MI200 设备上降低精度的 FP16 和 BF16 GEMMs 和卷积[](#reduced-precision-fp16-and-bf16-gemms-and-convolutions-on-amd-instinct-mi200-devices "跳转到此标题的永久链接")
AMD Instinct MI200 GPU上,FP16和BF16 V_DOT2和MFMA矩阵指令会将输入和输出的非规范化值刷新为零。FP32和FP64 MFMA矩阵指令不会将输入和输出的非规范化值刷新为零。受影响的指令仅由rocBLAS(GEMM)和MIOpen(卷积)内核使用;所有其他PyTorch操作不会遇到这种行为。所有其他支持的AMD GPU不会遇到这种行为。
AMD Instinct MI200 GPU 上,FP16 和 BF16 V_DOT2 和 MFMA 矩阵指令会将输入和输出的非规范化值刷新为零。FP32 和 FP64 MFMA 矩阵指令不会将输入和输出的非规范化值刷新为零。受影响的指令仅由 rocBLAS(GEMM)和 MIOpen(卷积)内核使用;所有其他 PyTorch 操作不会遇到这种行为。所有其他支持的 AMD GPU 不会遇到这种行为。
rocBLAS和MIOpen为受影响的FP16操作提供了替代实现。不提供BF16操作的替代实现;BF16数字的动态范围比FP16数字大,不太可能遇到非规范化值。对于FP16替代实现,FP16输入值被转换为中间BF16值,然后在累积FP32操作后转换回FP16输出。通过这种方式,输入和输出类型保持不变。
rocBLAS 和 MIOpen 为受影响的 FP16 操作提供了替代实现。不提供 BF16 操作的替代实现;BF16 数字的动态范围比 FP16 数字大,不太可能遇到非规范化值。对于 FP16 替代实现,FP16 输入值被转换为中间 BF16 值,然后在累积 FP32 操作后转换回 FP16 输出。通过这种方式,输入和输出类型保持不变。
在使用FP16精度训练时,一些模型可能无法收敛,因为FP16 denorms被刷新为零。在训练的反向传播过程中,梯度计算过程中更频繁地出现非规范化值。PyTorch默认会在反向传播过程中使用rocBLAS和MIOpen的替代实现。可以使用环境变量ROCBLAS_INTERNAL_FP16_ALT_IMPL和MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL来覆盖默认行为。这些环境变量的行为如下:
在使用 FP16 精度训练时,一些模型可能无法收敛,因为 FP16 denorms 被刷新为零。在训练的反向传播过程中,梯度计算过程中更频繁地出现非规范化值。PyTorch 默认会在反向传播过程中使用 rocBLAS 和 MIOpen 的替代实现。可以使用环境变量 ROCBLAS_INTERNAL_FP16_ALT_IMPL 和 MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL 来覆盖默认行为。这些环境变量的行为如下:
| | 前向 | 反向 |
| --- | --- | --- |
| 环境取消设置 | 原始 | 替代 |
| 环境设置为1 | 替代 | 替代 |
| 环境设置为0 | 原始 | 原始 |
| 环境设置为 1 | 替代 | 替代 |
| 环境设置为 0 | 原始 | 原始 |
以下是可能使用rocBLAS的操作列表:
以下是可能使用 rocBLAS 的操作列表:
+ torch.addbmm
......@@ -87,7 +87,7 @@ rocBLAS和MIOpen为受影响的FP16操作提供了替代实现。不提供BF16
+ torch.sparse.addmm
+ 以下是torch._C._ConvBackend实现列表:
+ 以下是 torch._C._ConvBackend 实现列表:
+ slowNd
......@@ -97,11 +97,11 @@ rocBLAS和MIOpen为受影响的FP16操作提供了替代实现。不提供BF16
+ slowNd_dilated_transposed
以下是可能使用MIOpen的操作列表:
以下是可能使用 MIOpen 的操作列表:
+ torch.nn.Conv[Transpose]Nd
+ 以下是torch._C._ConvBackend实现列表:
+ 以下是 torch._C._ConvBackend 实现列表:
+ ConvBackend::Miopen
......
# 可复制性
> 原文:[https://pytorch.org/docs/stable/notes/randomness.html](https://pytorch.org/docs/stable/notes/randomness.html)
> 原文:[`pytorch.org/docs/stable/notes/randomness.html`](https://pytorch.org/docs/stable/notes/randomness.html)
PyTorch发布、单个提交或不同平台之间不能保证完全可复制的结果。此外,即使使用相同的种子,在CPU和GPU执行之间的结果也可能无法复制。
PyTorch 发布、单个提交或不同平台之间不能保证完全可复制的结果。此外,即使使用相同的种子,在 CPU 和 GPU 执行之间的结果也可能无法复制。
然而,您可以采取一些步骤来限制特定平台、设备和PyTorch发布的不确定行为源的数量。首先,您可以控制可能导致应用程序多次执行时行为不同的随机性源。其次,您可以配置PyTorch以避免对某些操作使用非确定性算法,以便对这些操作进行多次调用时,给定相同的输入,将产生相同的结果。
然而,您可以采取一些步骤来限制特定平台、设备和 PyTorch 发布的不确定行为源的数量。首先,您可以控制可能导致应用程序多次执行时行为不同的随机性源。其次,您可以配置 PyTorch 以避免对某些操作使用非确定性算法,以便对这些操作进行多次调用时,给定相同的输入,将产生相同的结果。
警告
......@@ -12,22 +12,22 @@
## 控制随机性源[](#controlling-sources-of-randomness "Permalink to this heading")
### PyTorch随机数生成器[](#pytorch-random-number-generator "Permalink to this heading")
### PyTorch 随机数生成器[](#pytorch-random-number-generator "Permalink to this heading")
您可以使用[`torch.manual_seed()`](../generated/torch.manual_seed.html#torch.manual_seed "torch.manual_seed")为所有设备(CPU和CUDA)设置RNG的种子:
您可以使用`torch.manual_seed()`为所有设备(CPU 和 CUDA)设置 RNG 的种子:
```py
import torch
torch.manual_seed(0)
```
一些PyTorch操作可能在内部使用随机数。例如,[`torch.svd_lowrank()`](../generated/torch.svd_lowrank.html#torch.svd_lowrank "torch.svd_lowrank")就是这样。因此,连续多次使用相同的输入参数调用它可能会产生不同的结果。然而,只要在应用程序开头将[`torch.manual_seed()`](../generated/torch.manual_seed.html#torch.manual_seed "torch.manual_seed")设置为常量,并且已经消除了所有其他不确定性源,每次在相同环境中运行应用程序时都会生成相同系列的随机数。
一些 PyTorch 操作可能在内部使用随机数。例如,`torch.svd_lowrank()`就是这样。因此,连续多次使用相同的输入参数调用它可能会产生不同的结果。然而,只要在应用程序开头将`torch.manual_seed()`设置为常量,并且已经消除了所有其他不确定性源,每次在相同环境中运行应用程序时都会生成相同系列的随机数。
通过在连续调用之间将[`torch.manual_seed()`](../generated/torch.manual_seed.html#torch.manual_seed "torch.manual_seed")设置为相同的值,也可以从使用随机数的操作中获得相同的结果。
通过在连续调用之间将`torch.manual_seed()`设置为相同的值,也可以从使用随机数的操作中获得相同的结果。
### Python
对于自定义操作符,您可能还需要设置python种子:
对于自定义操作符,您可能还需要设置 python 种子:
```py
import random
......@@ -36,22 +36,22 @@ random.seed(0)
### 其他库中的随机数生成器[](#random-number-generators-in-other-libraries "Permalink to this heading")
如果您或您正在使用的任何库依赖于NumPy,您可以使用以下方法为全局NumPy RNG设置种子:
如果您或您正在使用的任何库依赖于 NumPy,您可以使用以下方法为全局 NumPy RNG 设置种子:
```py
import numpy as np
np.random.seed(0)
```
然而,一些应用程序和库可能使用NumPy随机生成器对象,而不是全局RNG ([https://numpy.org/doc/stable/reference/random/generator.html](https://numpy.org/doc/stable/reference/random/generator.html)),这些对象也需要一致地设置种子。
然而,一些应用程序和库可能使用 NumPy 随机生成器对象,而不是全局 RNG ([`numpy.org/doc/stable/reference/random/generator.html`](https://numpy.org/doc/stable/reference/random/generator.html)),这些对象也需要一致地设置种子。
如果您正在使用任何其他使用随机数生成器的库,请参考这些库的文档,看看如何为它们设置一致的种子。
### CUDA卷积基准测试[](#cuda-convolution-benchmarking "Permalink to this heading")
### CUDA 卷积基准测试[](#cuda-convolution-benchmarking "Permalink to this heading")
CUDA卷积操作使用的cuDNN库可能是应用程序多次执行中的不确定性源。当使用新的大小参数集调用cuDNN卷积时,一个可选功能可以运行多个卷积算法,并对它们进行基准测试以找到最快的算法。然后,在接下来的过程中,将始终使用最快的算法来处理相应的大小参数集。由于基准测试噪声和不同的硬件,基准测试可能会在后续运行中选择不同的算法,即使在同一台机器上也是如此。
CUDA 卷积操作使用的 cuDNN 库可能是应用程序多次执行中的不确定性源。当使用新的大小参数集调用 cuDNN 卷积时,一个可选功能可以运行多个卷积算法,并对它们进行基准测试以找到最快的算法。然后,在接下来的过程中,将始终使用最快的算法来处理相应的大小参数集。由于基准测试噪声和不同的硬件,基准测试可能会在后续运行中选择不同的算法,即使在同一台机器上也是如此。
通过使用`torch.backends.cudnn.benchmark = False`禁用基准测试功能,可以使cuDNN确定性地选择算法,可能会以降低性能为代价。
通过使用`torch.backends.cudnn.benchmark = False`禁用基准测试功能,可以使 cuDNN 确定性地选择算法,可能会以降低性能为代价。
然而,如果您不需要在应用程序的多次执行之间实现可重现性,则启用基准测试功能可能会提高性能,方法是使用`torch.backends.cudnn.benchmark = True`
......@@ -59,11 +59,11 @@ np.random.seed(0)
## 避免非确定性算法[](#avoiding-nondeterministic-algorithms "跳转到此标题")
[`torch.use_deterministic_algorithms()`](../generated/torch.use_deterministic_algorithms.html#torch.use_deterministic_algorithms "torch.use_deterministic_algorithms")允许您配置PyTorch使用确定性算法,而不是非确定性算法(如果有的话),并且如果已知某个操作是非确定性的(且没有确定性替代方案),则会引发错误。
`torch.use_deterministic_algorithms()`允许您配置 PyTorch 使用确定性算法,而不是非确定性算法(如果有的话),并且如果已知某个操作是非确定性的(且没有确定性替代方案),则会引发错误。
请查看[`torch.use_deterministic_algorithms()`](../generated/torch.use_deterministic_algorithms.html#torch.use_deterministic_algorithms "torch.use_deterministic_algorithms")文档,获取受影响操作的完整列表。如果某个操作未按照文档正确执行,或者您需要一个没有确定性实现的操作的确定性实现,请提交一个问题:[https://github.com/pytorch/pytorch/issues?q=label:%22module:%20determinism%22](https://github.com/pytorch/pytorch/issues?q=label:%22module:%20determinism%22)
请查看`torch.use_deterministic_algorithms()`文档,获取受影响操作的完整列表。如果某个操作未按照文档正确执行,或者您需要一个没有确定性实现的操作的确定性实现,请提交一个问题:[`github.com/pytorch/pytorch/issues?q=label:%22module:%20determinism%22`](https://github.com/pytorch/pytorch/issues?q=label:%22module:%20determinism%22)
例如,运行[`torch.Tensor.index_add_()`](../generated/torch.Tensor.index_add_.html#torch.Tensor.index_add_ "torch.Tensor.index_add_")的非确定性CUDA实现将引发错误:
例如,运行`torch.Tensor.index_add_()`的非确定性 CUDA 实现将引发错误:
```py
>>> import torch
......@@ -75,7 +75,7 @@ RuntimeError: index_add_cuda_ does not have a deterministic implementation, but
'torch.use_deterministic_algorithms(True)'. ...
```
当使用稀疏-稠密CUDA张量调用[`torch.bmm()`](../generated/torch.bmm.html#torch.bmm "torch.bmm")时,通常会使用一个非确定性算法,但当打开确定性标志时,将使用其备用确定性实现:
当使用稀疏-稠密 CUDA 张量调用`torch.bmm()`时,通常会使用一个非确定性算法,但当打开确定性标志时,将使用其备用确定性实现:
```py
>>> import torch
......@@ -87,25 +87,25 @@ tensor([[[ 1.1900, -2.3409],
[ 0.0333, -1.1444]]], device='cuda:0')
```
此外,如果您正在使用CUDA张量,并且CUDA版本为10.2或更高,则应根据CUDA文档设置环境变量CUBLAS_WORKSPACE_CONFIG:[https://docs.nvidia.com/cuda/cublas/index.html#cublasApi_reproducibility](https://docs.nvidia.com/cuda/cublas/index.html#cublasApi_reproducibility)
此外,如果您正在使用 CUDA 张量,并且 CUDA 版本为 10.2 或更高,则应根据 CUDA 文档设置环境变量 CUBLAS_WORKSPACE_CONFIG:[`docs.nvidia.com/cuda/cublas/index.html#cublasApi_reproducibility`](https://docs.nvidia.com/cuda/cublas/index.html#cublasApi_reproducibility)
### CUDA卷积确定性性[](#cuda-convolution-determinism "跳转到此标题")
### CUDA 卷积确定性性[](#cuda-convolution-determinism "跳转到此标题")
虽然禁用CUDA卷积基准测试(如上所述)确保CUDA每次运行应用程序时选择相同的算法,但该算法本身可能是非确定性的,除非设置`torch.use_deterministic_algorithms(True)``torch.backends.cudnn.deterministic = True`。后者仅控制此行为,不像[`torch.use_deterministic_algorithms()`](../generated/torch.use_deterministic_algorithms.html#torch.use_deterministic_algorithms "torch.use_deterministic_algorithms")会使其他PyTorch操作也表现出确定性。
虽然禁用 CUDA 卷积基准测试(如上所述)确保 CUDA 每次运行应用程序时选择相同的算法,但该算法本身可能是非确定性的,除非设置`torch.use_deterministic_algorithms(True)``torch.backends.cudnn.deterministic = True`。后者仅控制此行为,不像`torch.use_deterministic_algorithms()`会使其他 PyTorch 操作也表现出确定性。
### CUDA RNNLSTM
### CUDA RNNLSTM
在某些版本的CUDA中,RNN和LSTM网络可能具有非确定性行为。有关详细信息和解决方法,请参阅[`torch.nn.RNN()`](../generated/torch.nn.RNN.html#torch.nn.RNN "torch.nn.RNN")[`torch.nn.LSTM()`](../generated/torch.nn.LSTM.html#torch.nn.LSTM "torch.nn.LSTM")
在某些版本的 CUDA 中,RNN 和 LSTM 网络可能具有非确定性行为。有关详细信息和解决方法,请参阅`torch.nn.RNN()``torch.nn.LSTM()`
### 填充未初始化内存[](#filling-uninitialized-memory "跳转到此标题")
[`torch.empty()`](../generated/torch.empty.html#torch.empty "torch.empty")[`torch.Tensor.resize_()`](../generated/torch.Tensor.resize_.html#torch.Tensor.resize_ "torch.Tensor.resize_")这样的操作可能返回具有未初始化内存的张量,其中包含未定义的值。如果需要确定性,将这样的张量用作另一个操作的输入是无效的,因为输出将是不确定的。但实际上没有任何东西可以阻止运行这种无效代码。因此,为了安全起见,默认情况下将[`torch.utils.deterministic.fill_uninitialized_memory`](../deterministic.html#torch.utils.deterministic.fill_uninitialized_memory "torch.utils.deterministic.fill_uninitialized_memory")设置为`True`,如果设置了`torch.use_deterministic_algorithms(True)`,则会使用已知值填充未初始化的内存。这将防止这种非确定性行为的可能性。
`torch.empty()``torch.Tensor.resize_()`这样的操作可能返回具有未初始化内存的张量,其中包含未定义的值。如果需要确定性,将这样的张量用作另一个操作的输入是无效的,因为输出将是不确定的。但实际上没有任何东西可以阻止运行这种无效代码。因此,为了安全起见,默认情况下将`torch.utils.deterministic.fill_uninitialized_memory`设置为`True`,如果设置了`torch.use_deterministic_algorithms(True)`,则会使用已知值填充未初始化的内存。这将防止这种非确定性行为的可能性。
然而,填充未初始化内存对性能有害。因此,如果您的程序有效且不将未初始化内存用作操作的输入,则可以关闭此设置以获得更好的性能。
## DataLoader
DataLoader将根据[多进程数据加载中的随机性](../data.html#data-loading-randomness)算法重新播种工作进程。使用`worker_init_fn()`和生成器来保持可重现性:
DataLoader 将根据多进程数据加载中的随机性算法重新播种工作进程。使用`worker_init_fn()`和生成器来保持可重现性:
```py
def seed_worker(worker_id):
......
此差异已折叠。
# Windows 常见问题
> 原文:[https://pytorch.org/docs/stable/notes/windows.html](https://pytorch.org/docs/stable/notes/windows.html)
> 原文:[`pytorch.org/docs/stable/notes/windows.html`](https://pytorch.org/docs/stable/notes/windows.html)
## 从源代码构建
......@@ -176,7 +176,7 @@ ForkingPickler(file, protocol).dump(obj)
BrokenPipeError: [Errno 32] Broken pipe
```
当子进程在父进程完成发送数据之前结束时,就会出现这个问题。您的代码可能有问题。您可以通过将 [`DataLoader`](../data.html#torch.utils.data.DataLoader "torch.utils.data.DataLoader")`num_worker` 减少到零来调试您的代码,看看问题是否仍然存在。
当子进程在父进程完成发送数据之前结束时,就会出现这个问题。您的代码可能有问题。您可以通过将 `DataLoader``num_worker` 减少到零来调试您的代码,看看问题是否仍然存在。
### 多进程错误“驱动程序关闭”[](#multiprocessing-error-driver-shut-down "跳转到此标题的永久链接")
......@@ -196,6 +196,6 @@ THCudaCheck FAIL file=torch\csrc\generic\StorageSharing.cpp line=252 error=63 :
它们不支持 Windows。例如,在 CUDA 张量上进行多进程操作是不可能成功的,有两种替代方案。
1\. 不要使用 `multiprocessing`。将 [`DataLoader`](../data.html#torch.utils.data.DataLoader "torch.utils.data.DataLoader")`num_worker` 设置为零。
1\. 不要使用 `multiprocessing`。将 `DataLoader``num_worker` 设置为零。
2. 共享 CPU 张量。确保您的自定义 `DataSet` 返回 CPU 张量。
# C++
> 原文:[https://pytorch.org/docs/stable/cpp_index.html](https://pytorch.org/docs/stable/cpp_index.html)
> 原文:[`pytorch.org/docs/stable/cpp_index.html`](https://pytorch.org/docs/stable/cpp_index.html)
注意
如果您正在寻找PyTorch C++ API文档,请直接前往[此处](https://pytorch.org/cppdocs/)
如果您正在寻找 PyTorch C++ API 文档,请直接前往[此处](https://pytorch.org/cppdocs/)
PyTorch提供了几个用于处理C++的功能,最好根据您的需求选择其中之一。在高层次上,以下支持可用:
PyTorch 提供了几个用于处理 C++的功能,最好根据您的需求选择其中之一。在高层次上,以下支持可用:
## TorchScript C++ API
[TorchScript](https://pytorch.org/docs/stable/jit.html)允许将在Python中定义的PyTorch模型序列化,然后在C++中加载和运行,通过编译或跟踪其执行来捕获模型代码。您可以在[在C++中加载TorchScript模型](https://pytorch.org/tutorials/advanced/cpp_export.html)教程中了解更多信息。这意味着您可以尽可能在Python中定义模型,但随后通过TorchScript导出它们,以在生产或嵌入式环境中进行无Python执行。TorchScript C++ API用于与这些模型和TorchScript执行引擎进行交互,包括:
[TorchScript](https://pytorch.org/docs/stable/jit.html)允许将在 Python 中定义的 PyTorch 模型序列化,然后在 C++中加载和运行,通过编译或跟踪其执行来捕获模型代码。您可以在[在 C++中加载 TorchScript 模型](https://pytorch.org/tutorials/advanced/cpp_export.html)教程中了解更多信息。这意味着您可以尽可能在 Python 中定义模型,但随后通过 TorchScript 导出它们,以在生产或嵌入式环境中进行无 Python 执行。TorchScript C++ API 用于与这些模型和 TorchScript 执行引擎进行交互,包括:
+ 加载从Python保存的序列化TorchScript模型
+ 加载从 Python 保存的序列化 TorchScript 模型
+ 如果需要,进行简单的模型修改(例如,提取子模块)
+ 使用C++ Tensor API构建输入并进行预处理
+ 使用 C++ Tensor API 构建输入并进行预处理
## 使用C++扩展扩展PyTorch和TorchScript[](#extending-pytorch-and-torchscript-with-c-extensions "跳转到此标题的永久链接")
## 使用 C++扩展扩展 PyTorch 和 TorchScript[](#extending-pytorch-and-torchscript-with-c-extensions "跳转到此标题的永久链接")
TorchScript可以通过自定义运算符和自定义类增强用户提供的代码。一旦在TorchScript中注册了这些运算符和类,这些运算符和类可以在Python中运行的TorchScript代码中被调用,或者作为序列化的TorchScript模型的一部分在C++中被调用。[使用自定义C++运算符扩展TorchScript](https://pytorch.org/tutorials/advanced/torch_script_custom_ops.html)教程介绍了如何将TorchScript与OpenCV进行接口。除了使用自定义运算符包装函数调用外,C++类和结构体还可以通过类似于pybind11的接口绑定到TorchScript中,这在[使用自定义C++类扩展TorchScript](https://pytorch.org/tutorials/advanced/torch_script_custom_classes.html)教程中有解释。
TorchScript 可以通过自定义运算符和自定义类增强用户提供的代码。一旦在 TorchScript 中注册了这些运算符和类,这些运算符和类可以在 Python 中运行的 TorchScript 代码中被调用,或者作为序列化的 TorchScript 模型的一部分在 C++中被调用。[使用自定义 C++运算符扩展 TorchScript](https://pytorch.org/tutorials/advanced/torch_script_custom_ops.html)教程介绍了如何将 TorchScript 与 OpenCV 进行接口。除了使用自定义运算符包装函数调用外,C++类和结构体还可以通过类似于 pybind11 的接口绑定到 TorchScript 中,这在[使用自定义 C++类扩展 TorchScript](https://pytorch.org/tutorials/advanced/torch_script_custom_classes.html)教程中有解释。
## 在C++中的Tensor和Autograd
## 在 C++中的 Tensor 和 Autograd
PyTorch Python API中的大多数张量和自动求导操作也可在C++ API中使用。包括:
PyTorch Python API 中的大多数张量和自动求导操作也可在 C++ API 中使用。包括:
+ `torch::Tensor`方法,如`add` / `reshape` / `clone`。有关可用方法的完整列表,请参阅:[https://pytorch.org/cppdocs/api/classat_1_1_tensor.html](https://pytorch.org/cppdocs/api/classat_1_1_tensor.html)
+ `torch::Tensor`方法,如`add` / `reshape` / `clone`。有关可用方法的完整列表,请参阅:[`pytorch.org/cppdocs/api/classat_1_1_tensor.html`](https://pytorch.org/cppdocs/api/classat_1_1_tensor.html)
+ C++张量索引API,看起来和行为与Python API相同。有关其用法的详细信息,请参阅:[https://pytorch.org/cppdocs/notes/tensor_indexing.html](https://pytorch.org/cppdocs/notes/tensor_indexing.html)
+ C++张量索引 API,看起来和行为与 Python API 相同。有关其用法的详细信息,请参阅:[`pytorch.org/cppdocs/notes/tensor_indexing.html`](https://pytorch.org/cppdocs/notes/tensor_indexing.html)
+C++前端构建动态神经网络至关重要的张量自动求导API和`torch::autograd`包。有关更多详细信息,请参阅:[https://pytorch.org/tutorials/advanced/cpp_autograd.html](https://pytorch.org/tutorials/advanced/cpp_autograd.html)
+ C++前端构建动态神经网络至关重要的张量自动求导 API 和`torch::autograd`包。有关更多详细信息,请参阅:[`pytorch.org/tutorials/advanced/cpp_autograd.html`](https://pytorch.org/tutorials/advanced/cpp_autograd.html)
## 在C++中编写模型
## 在 C++中编写模型
“在TorchScript中编写,使用C++进行推断”的工作流程要求在TorchScript中进行模型编写。但是,可能存在必须在C++中编写模型的情况(例如,在不希望使用Python组件的工作流程中)。为了满足这种用例,我们提供了在C++中完全编写和训练神经网络模型的完整功能,其中包括`torch::nn` / `torch::nn::functional` / `torch::optim`等熟悉的组件,这些组件与Python API非常相似。
“在 TorchScript 中编写,使用 C++进行推断”的工作流程要求在 TorchScript 中进行模型编写。但是,可能存在必须在 C++中编写模型的情况(例如,在不希望使用 Python 组件的工作流程中)。为了满足这种用例,我们提供了在 C++中完全编写和训练神经网络模型的完整功能,其中包括`torch::nn` / `torch::nn::functional` / `torch::optim`等熟悉的组件,这些组件与 Python API 非常相似。
+ 有关PyTorch C++模型编写和训练API的概述,请参阅:[https://pytorch.org/cppdocs/frontend.html](https://pytorch.org/cppdocs/frontend.html)
+ 有关 PyTorch C++模型编写和训练 API 的概述,请参阅:[`pytorch.org/cppdocs/frontend.html`](https://pytorch.org/cppdocs/frontend.html)
+ 有关如何使用API的详细教程,请参阅:[https://pytorch.org/tutorials/advanced/cpp_frontend.html](https://pytorch.org/tutorials/advanced/cpp_frontend.html)
+ 有关如何使用 API 的详细教程,请参阅:[`pytorch.org/tutorials/advanced/cpp_frontend.html`](https://pytorch.org/tutorials/advanced/cpp_frontend.html)
+ 有关诸如`torch::nn` / `torch::nn::functional` / `torch::optim`等组件的文档,请访问:[https://pytorch.org/cppdocs/api/library_root.html](https://pytorch.org/cppdocs/api/library_root.html)
+ 有关诸如`torch::nn` / `torch::nn::functional` / `torch::optim`等组件的文档,请访问:[`pytorch.org/cppdocs/api/library_root.html`](https://pytorch.org/cppdocs/api/library_root.html)
## C++包装
有关如何安装和链接libtorch(包含所有上述C++ API的库)的指导,请参阅:[https://pytorch.org/cppdocs/installing.html](https://pytorch.org/cppdocs/installing.html)。请注意,在Linux上提供了两种类型的libtorch二进制文件:一种是使用GCC pre-cxx11 ABI编译的,另一种是使用GCC cxx11 ABI编译的,您应该根据系统使用的GCC ABI进行选择。
有关如何安装和链接 libtorch(包含所有上述 C++ API 的库)的指导,请参阅:[`pytorch.org/cppdocs/installing.html`](https://pytorch.org/cppdocs/installing.html)。请注意,在 Linux 上提供了两种类型的 libtorch 二进制文件:一种是使用 GCC pre-cxx11 ABI 编译的,另一种是使用 GCC cxx11 ABI 编译的,您应该根据系统使用的 GCC ABI 进行选择。
# torch::deploy 已经迁移到 pytorch/multipy
> 原文:[https://pytorch.org/docs/stable/deploy.html](https://pytorch.org/docs/stable/deploy.html)
> 原文:[`pytorch.org/docs/stable/deploy.html`](https://pytorch.org/docs/stable/deploy.html)
`torch::deploy` 已经迁移到了它的新家 [https://github.com/pytorch/multipy](https://github.com/pytorch/multipy)
`torch::deploy` 已经迁移到了它的新家 [`github.com/pytorch/multipy`](https://github.com/pytorch/multipy)
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
# torch.cpu
> 原文:[https://pytorch.org/docs/stable/cpu.html](https://pytorch.org/docs/stable/cpu.html)
> 原文:[`pytorch.org/docs/stable/cpu.html`](https://pytorch.org/docs/stable/cpu.html)
该软件包实现了在`torch.cuda`中找到的抽象,以便编写与设备无关的代码。
| [`current_device`](generated/torch.cpu.current_device.html#torch.cpu.current_device "torch.cpu.current_device") | 返回CPU的当前设备。 |
| `current_device` | 返回 CPU 的当前设备。 |
| --- | --- |
| [`current_stream`](generated/torch.cpu.current_stream.html#torch.cpu.current_stream "torch.cpu.current_stream") | 返回给定设备的当前选择的[`Stream`](generated/torch.cpu.Stream.html#torch.cpu.Stream "torch.cpu.Stream")。 |
| [`is_available`](generated/torch.cpu.is_available.html#torch.cpu.is_available "torch.cpu.is_available") | 返回一个布尔值,指示CPU当前是否可用。 |
| [`synchronize`](generated/torch.cpu.synchronize.html#torch.cpu.synchronize "torch.cpu.synchronize") | 等待CPU设备上所有流中的所有内核完成。 |
| [`stream`](generated/torch.cpu.stream.html#torch.cpu.stream "torch.cpu.stream") | 包装器,围绕选择给定流的上下文管理器StreamContext。 |
| [`set_device`](generated/torch.cpu.set_device.html#torch.cpu.set_device "torch.cpu.set_device") | 设置当前设备,在CPU上我们不做任何操作。 |
| [`device_count`](generated/torch.cpu.device_count.html#torch.cpu.device_count "torch.cpu.device_count") | 返回CPU设备的数量(不是核心数)。 |
| [`StreamContext`](generated/torch.cpu.StreamContext.html#torch.cpu.StreamContext "torch.cpu.StreamContext") | 选择给定流的上下文管理器。 |
| `current_stream` | 返回给定设备的当前选择的`Stream`。 |
| `is_available` | 返回一个布尔值,指示 CPU 当前是否可用。 |
| `synchronize` | 等待 CPU 设备上所有流中的所有内核完成。 |
| `stream` | 包装器,围绕选择给定流的上下文管理器 StreamContext。 |
| `set_device` | 设置当前设备,在 CPU 上我们不做任何操作。 |
| `device_count` | 返回 CPU 设备的数量(不是核心数)。 |
| `StreamContext` | 选择给定流的上下文管理器。 |
## 流和事件
| [`Stream`](generated/torch.cpu.Stream.html#torch.cpu.Stream "torch.cpu.Stream") | 注: |
| `Stream` | 注: |
| --- | --- |
此差异已折叠。
此差异已折叠。
# torch.mps
> 原文:[https://pytorch.org/docs/stable/mps.html](https://pytorch.org/docs/stable/mps.html)
> 原文:[`pytorch.org/docs/stable/mps.html`](https://pytorch.org/docs/stable/mps.html)
该软件包提供了一个接口,用于在Python中访问MPS(Metal Performance Shaders)后端。Metal是苹果用于编程金属GPU(图形处理器单元)的API。使用MPS意味着可以通过在金属GPU上运行工作来实现增加的性能。有关更多详细信息,请参见[https://developer.apple.com/documentation/metalperformanceshaders](https://developer.apple.com/documentation/metalperformanceshaders)
该软件包提供了一个接口,用于在 Python 中访问 MPS(Metal Performance Shaders)后端。Metal 是苹果用于编程金属 GPU(图形处理器单元)的 API。使用 MPS 意味着可以通过在金属 GPU 上运行工作来实现增加的性能。有关更多详细信息,请参见[`developer.apple.com/documentation/metalperformanceshaders`](https://developer.apple.com/documentation/metalperformanceshaders)
| [`synchronize`](generated/torch.mps.synchronize.html#torch.mps.synchronize "torch.mps.synchronize") | 等待MPS设备上所有流中的所有内核完成。 |
| `synchronize` | 等待 MPS 设备上所有流中的所有内核完成。 |
| --- | --- |
| [`get_rng_state`](generated/torch.mps.get_rng_state.html#torch.mps.get_rng_state "torch.mps.get_rng_state") | 将随机数生成器状态作为ByteTensor返回。 |
| [`set_rng_state`](generated/torch.mps.set_rng_state.html#torch.mps.set_rng_state "torch.mps.set_rng_state") | 设置随机数生成器状态。 |
| [`manual_seed`](generated/torch.mps.manual_seed.html#torch.mps.manual_seed "torch.mps.manual_seed") | 设置生成随机数的种子。 |
| [`seed`](generated/torch.mps.seed.html#torch.mps.seed "torch.mps.seed") | 将生成随机数的种子设置为一个随机数。 |
| [`empty_cache`](generated/torch.mps.empty_cache.html#torch.mps.empty_cache "torch.mps.empty_cache") | 释放缓存分配器当前持有的所有未使用缓存内存,以便这些内存可以用于其他GPU应用程序。 |
| [`set_per_process_memory_fraction`](generated/torch.mps.set_per_process_memory_fraction.html#torch.mps.set_per_process_memory_fraction "torch.mps.set_per_process_memory_fraction") | 设置限制进程在MPS设备上内存分配的内存分数。 |
| [`current_allocated_memory`](generated/torch.mps.current_allocated_memory.html#torch.mps.current_allocated_memory "torch.mps.current_allocated_memory") | 返回张量占用的当前GPU内存(以字节为单位)。 |
| [`driver_allocated_memory`](generated/torch.mps.driver_allocated_memory.html#torch.mps.driver_allocated_memory "torch.mps.driver_allocated_memory") | 返回Metal驱动程序为进程分配的总GPU内存(以字节为单位)。 |
| `get_rng_state` | 将随机数生成器状态作为 ByteTensor 返回。 |
| `set_rng_state` | 设置随机数生成器状态。 |
| `manual_seed` | 设置生成随机数的种子。 |
| `seed` | 将生成随机数的种子设置为一个随机数。 |
| `empty_cache` | 释放缓存分配器当前持有的所有未使用缓存内存,以便这些内存可以用于其他 GPU 应用程序。 |
| `set_per_process_memory_fraction` | 设置限制进程在 MPS 设备上内存分配的内存分数。 |
| `current_allocated_memory` | 返回张量占用的当前 GPU 内存(以字节为单位)。 |
| `driver_allocated_memory` | 返回 Metal 驱动程序为进程分配的总 GPU 内存(以字节为单位)。 |
## MPS Profiler
| [`profiler.start`](generated/torch.mps.profiler.start.html#torch.mps.profiler.start "torch.mps.profiler.start") | 从MPS后端开始OS Signpost跟踪。 |
| `profiler.start` | 从 MPS 后端开始 OS Signpost 跟踪。 |
| --- | --- |
| [`profiler.stop`](generated/torch.mps.profiler.stop.html#torch.mps.profiler.stop "torch.mps.profiler.stop") | 停止从MPS后端生成OS Signpost跟踪。 |
| [`profiler.profile`](generated/torch.mps.profiler.profile.html#torch.mps.profiler.profile "torch.mps.profiler.profile") | 上下文管理器,用于启用从MPS后端生成OS Signpost跟踪。 |
| `profiler.stop` | 停止从 MPS 后端生成 OS Signpost 跟踪。 |
| `profiler.profile` | 上下文管理器,用于启用从 MPS 后端生成 OS Signpost 跟踪。 |
## MPS Event
| [`event.Event`](generated/torch.mps.event.Event.html#torch.mps.event.Event "torch.mps.event.Event") | MPS事件的包装器。 |
| `event.Event` | MPS 事件的包装器。 |
| --- | --- |
此差异已折叠。
此差异已折叠。
此差异已折叠。
# 通用加入上下文管理器
> 原文:[https://pytorch.org/docs/stable/distributed.algorithms.join.html](https://pytorch.org/docs/stable/distributed.algorithms.join.html)
> 原文:[`pytorch.org/docs/stable/distributed.algorithms.join.html`](https://pytorch.org/docs/stable/distributed.algorithms.join.html)
通用加入上下文管理器促进了不均匀输入的分布式训练。本页概述了相关类的API:`Join``Joinable``JoinHook`。有关教程,请参阅[使用加入上下文管理器进行不均匀输入的分布式训练](https://pytorch.org/tutorials/advanced/generic_join.html)
通用加入上下文管理器促进了不均匀输入的分布式训练。本页概述了相关类的 API:`Join``Joinable``JoinHook`。有关教程,请参阅[使用加入上下文管理器进行不均匀输入的分布式训练](https://pytorch.org/tutorials/advanced/generic_join.html)
```py
class torch.distributed.algorithms.Join(joinables, enable=True, throw_on_early_termination=False, **kwargs)
......@@ -10,19 +10,19 @@ class torch.distributed.algorithms.Join(joinables, enable=True, throw_on_early_t
此类定义了通用加入上下文管理器,允许在进程加入后调用自定义钩子。
这些钩子应该遮蔽未加入进程的集体通信,以防止挂起和出错,并确保算法的正确性。有关钩子定义的详细信息,请参阅[`JoinHook`](#torch.distributed.algorithms.JoinHook "torch.distributed.algorithms.JoinHook")
这些钩子应该遮蔽未加入进程的集体通信,以防止挂起和出错,并确保算法的正确性。有关钩子定义的详细信息,请参阅`JoinHook`
警告
上下文管理器要求每个参与的[`Joinable`](#torch.distributed.algorithms.Joinable "torch.distributed.algorithms.Joinable")在自己的每次迭代集体通信之前调用方法[`notify_join_context()`](#torch.distributed.algorithms.Join.notify_join_context "torch.distributed.algorithms.Join.notify_join_context")以确保正确性。
上下文管理器要求每个参与的`Joinable`在自己的每次迭代集体通信之前调用方法`notify_join_context()`以确保正确性。
警告
上下文管理器要求[`JoinHook`](#torch.distributed.algorithms.JoinHook "torch.distributed.algorithms.JoinHook")对象中的所有`process_group`属性都相同。如果有多个[`JoinHook`](#torch.distributed.algorithms.JoinHook "torch.distributed.algorithms.JoinHook")对象,则使用第一个的`device`。进程组和设备信息用于检查未加入的进程,并通知进程在启用`throw_on_early_termination`时抛出异常,两者都使用全局归约。
上下文管理器要求`JoinHook`对象中的所有`process_group`属性都相同。如果有多个`JoinHook`对象,则使用第一个的`device`。进程组和设备信息用于检查未加入的进程,并通知进程在启用`throw_on_early_termination`时抛出异常,两者都使用全局归约。
参数
+ **joinables***List**[*[*Joinable*](#torch.distributed.algorithms.Joinable "torch.distributed.algorithms.Joinable")*]*) - 参与的[`Joinable`](#torch.distributed.algorithms.Joinable "torch.distributed.algorithms.Joinable")对象的列表;它们的钩子按给定顺序迭代。
+ **joinables***List***[*Joinable**]*) - 参与的`Joinable`对象的列表;它们的钩子按给定顺序迭代。
+ **enable**[*bool*](https://docs.python.org/3/library/functions.html#bool "(in Python v3.12)")) - 一个标志,用于启用不均匀输入检测;设置为`False`会禁用上下文管理器的功能,只有在用户知道输入不会不均匀时才应设置(默认值:`True`)。
......@@ -62,13 +62,13 @@ static notify_join_context(joinable)¶
然后,如果`throw_on_early_termination=True`,则检查是否检测到不均匀的输入(即如果一个进程已经加入),如果是,则抛出异常。
此方法应该在[`Joinable`](#torch.distributed.algorithms.Joinable "torch.distributed.algorithms.Joinable")对象的每次迭代集体通信之前调用。例如,在`DistributedDataParallel`的前向传递开始时应调用此方法。
此方法应该在`Joinable`对象的每次迭代集体通信之前调用。例如,在`DistributedDataParallel`的前向传递开始时应调用此方法。
只有第一个传递到上下文管理器的[`Joinable`](#torch.distributed.algorithms.Joinable "torch.distributed.algorithms.Joinable")对象在此方法中执行集体通信,对于其他对象,此方法为空。
只有第一个传递到上下文管理器的`Joinable`对象在此方法中执行集体通信,对于其他对象,此方法为空。
参数
**joinable**[*Joinable*](#torch.distributed.algorithms.Joinable "torch.distributed.algorithms.Joinable")) - 调用此方法的[`Joinable`](#torch.distributed.algorithms.Joinable "torch.distributed.algorithms.Joinable")对象。
**joinable***Joinable*) - 调用此方法的`Joinable`对象。
返回
......@@ -80,7 +80,7 @@ class torch.distributed.algorithms.Joinable¶
这为可加入类定义了一个抽象基类。
一个可加入的类(从[`Joinable`](#torch.distributed.algorithms.Joinable "torch.distributed.algorithms.Joinable")继承)应该实现[`join_hook()`](#torch.distributed.algorithms.Joinable.join_hook "torch.distributed.algorithms.Joinable.join_hook"),它返回一个[`JoinHook`](#torch.distributed.algorithms.JoinHook "torch.distributed.algorithms.JoinHook")实例,另外还应该实现[`join_device()`](#torch.distributed.algorithms.Joinable.join_device "torch.distributed.algorithms.Joinable.join_device")[`join_process_group()`](#torch.distributed.algorithms.Joinable.join_process_group "torch.distributed.algorithms.Joinable.join_process_group")来分别返回设备和进程组信息。
一个可加入的类(从`Joinable`继承)应该实现`join_hook()`,它返回一个`JoinHook`实例,另外还应该实现`join_device()``join_process_group()`来分别返回设备和进程组信息。
```py
abstract property join_device: device
......@@ -92,15 +92,15 @@ abstract property join_device: device¶
abstract join_hook(**kwargs)
```
为给定的[`Joinable`](#torch.distributed.algorithms.Joinable "torch.distributed.algorithms.Joinable")返回一个[`JoinHook`](#torch.distributed.algorithms.JoinHook "torch.distributed.algorithms.JoinHook")实例。
为给定的`Joinable`返回一个`JoinHook`实例。
参数
**kwargs**[*dict*](https://docs.python.org/3/library/stdtypes.html#dict "(in Python v3.12)")) - 包含任何关键字参数以在运行时修改加入钩子行为的[`dict`](https://docs.python.org/3/library/stdtypes.html#dict "(in Python v3.12)");所有共享相同加入上下文管理器的[`Joinable`](#torch.distributed.algorithms.Joinable "torch.distributed.algorithms.Joinable")实例将被转发相同的`kwargs`值。
**kwargs**[*dict*](https://docs.python.org/3/library/stdtypes.html#dict "(in Python v3.12)")) - 包含任何关键字参数以在运行时修改加入钩子行为的[`dict`](https://docs.python.org/3/library/stdtypes.html#dict "(in Python v3.12)");所有共享相同加入上下文管理器的`Joinable`实例将被转发相同的`kwargs`值。
返回类型
[*JoinHook*](#torch.distributed.algorithms.JoinHook "torch.distributed.algorithms.join.JoinHook")
*JoinHook*
```py
abstract property join_process_group: Any
......@@ -116,7 +116,7 @@ class torch.distributed.algorithms.JoinHook¶
入口点:一个主要的钩子,当存在一个未加入的进程时会被重复调用,以及一个后置钩子,当所有进程都已加入时会被调用一次。
要为通用加入上下文管理器实现一个加入钩子,需要定义一个从[`JoinHook`](#torch.distributed.algorithms.JoinHook "torch.distributed.algorithms.JoinHook")继承的类,并适当地重写`main_hook()``post_hook()`
要为通用加入上下文管理器实现一个加入钩子,需要定义一个从`JoinHook`继承的类,并适当地重写`main_hook()``post_hook()`
```py
main_hook()
......
# Torch分布式弹性
# Torch 分布式弹性
> 原文:[https://pytorch.org/docs/stable/distributed.elastic.html](https://pytorch.org/docs/stable/distributed.elastic.html)
> 原文:[`pytorch.org/docs/stable/distributed.elastic.html`](https://pytorch.org/docs/stable/distributed.elastic.html)
使分布式PyTorch具有容错性和弹性。
使分布式 PyTorch 具有容错性和弹性。
## 入门
用法
+ [快速入门](elastic/quickstart.html)
+ 快速入门
+ [训练脚本](elastic/train_script.html)
+ 训练脚本
+ [示例](elastic/examples.html)
+ 示例
## 文档
API
+ [torchrun(弹性启动)](elastic/run.html)
+ torchrun(弹性启动)
+ [弹性代理](elastic/agent.html)
+ 弹性代理
+ [多进程](elastic/multiprocessing.html)
+ 多进程
+ [错误传播](elastic/errors.html)
+ 错误传播
+ [会合](elastic/rendezvous.html)
+ 会合
+ [过期计时器](elastic/timer.html)
+ 过期计时器
+ [指标](elastic/metrics.html)
+ 指标
+ [事件](elastic/events.html)
+ 事件
高级
+ [定制](elastic/customization.html)
+ 定制
插件
+ [TorchElastic Kubernetes](elastic/kubernetes.html)
+ TorchElastic Kubernetes
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
# torch.compiler
> 原文:[https://pytorch.org/docs/stable/torch.compiler.html](https://pytorch.org/docs/stable/torch.compiler.html)
> 原文:[`pytorch.org/docs/stable/torch.compiler.html`](https://pytorch.org/docs/stable/torch.compiler.html)
`torch.compiler` 是一个命名空间,通过该命名空间,一些内部编译器方法被公开供用户使用。该命名空间中的主要函数和特性是 `torch.compile`
......@@ -29,7 +29,7 @@
| `torch.compile(m, backend="inductor")` | 使用 TorchInductor 后端。[阅读更多](https://dev-discuss.pytorch.org/t/torchinductor-a-pytorch-native-compiler-with-define-by-run-ir-and-symbolic-shapes/747) |
| `torch.compile(m, backend="cudagraphs")` | 使用 CUDA 图形与 AOT Autograd。[阅读更多](https://github.com/pytorch/torchdynamo/pull/757) |
| `torch.compile(m, backend="ipex")` | 在 CPU 上使用 IPEX。[阅读更多](https://github.com/intel/intel-extension-for-pytorch) |
| `torch.compile(m, backend="onnxrt")` | 使用 ONNX Runtime 在 CPU/GPU 上进行训练。[阅读更多](onnx_dynamo_onnxruntime_backend.html) |
| `torch.compile(m, backend="onnxrt")` | 使用 ONNX Runtime 在 CPU/GPU 上进行训练。阅读更多 |
**仅推理后端**
......@@ -44,44 +44,44 @@
PyTorch 用户入门
+ [入门指南](torch.compiler_get_started.html)
+ 入门指南
+ [torch.compiler API 参考](torch.compiler_api.html)
+ torch.compiler API 参考
+ [TorchDynamo 用于细粒度跟踪的 API](torch.compiler_fine_grain_apis.html)
+ TorchDynamo 用于细粒度跟踪的 API
+ [AOTInductor:Torch.Export-ed 模型的预编译](torch.compiler_aot_inductor.html)
+ AOTInductor:Torch.Export-ed 模型的预编译
+ [TorchInductor GPU Profiling](torch.compiler_inductor_profiling.html)
+ TorchInductor GPU Profiling
+ [分析以了解 torch.compile 性能](torch.compiler_profiling_torch_compile.html)
+ 分析以了解 torch.compile 性能
+ [常见问题解答](torch.compiler_faq.html)
+ 常见问题解答
+ [PyTorch 2.0 故障排除](torch.compiler_troubleshooting.html)
+ PyTorch 2.0 故障排除
+ [PyTorch 2.0 性能仪表板](torch.compiler_performance_dashboard.html)
+ PyTorch 2.0 性能仪表板
PyTorch 开发者深入研究
+ [TorchDynamo 深入研究](torch.compiler_deepdive.html)
+ TorchDynamo 深入研究
+ [守卫概述](torch.compiler_guards_overview.html)
+ 守卫概述
+ [动态形状](torch.compiler_dynamic_shapes.html)
+ 动态形状
+ [PyTorch 2.0 NNModule 支持](torch.compiler_nn_module.html)
+ PyTorch 2.0 NNModule 支持
+ [后端最佳实践](torch.compiler_best_practices_for_backends.html)
+ 后端最佳实践
+ [CUDAGraph 树](torch.compiler_cudagraph_trees.html)
+ CUDAGraph 树
+ [伪张量](torch.compiler_fake_tensor.html)
+ 伪张量
PyTorch 后端供应商操作指南
+ [自定义后端](torch.compiler_custom_backends.html)
+ 自定义后端
+ [在 ATen IR 上编写图转换](torch.compiler_transformations.html)
+ 在 ATen IR 上编写图转换
+ [IRs](torch.compiler_ir.html)
+ IRs
# torch.fft
> 原文:[https://pytorch.org/docs/stable/fft.html](https://pytorch.org/docs/stable/fft.html)
> 原文:[`pytorch.org/docs/stable/fft.html`](https://pytorch.org/docs/stable/fft.html)
离散傅里叶变换和相关函数。
## 快速傅里叶变换
| [`fft`](generated/torch.fft.fft.html#torch.fft.fft "torch.fft.fft") | 计算`input`的一维离散傅里叶变换。 |
| `fft` | 计算`input`的一维离散傅里叶变换。 |
| --- | --- |
| [`ifft`](generated/torch.fft.ifft.html#torch.fft.ifft "torch.fft.ifft") | 计算`input`的一维逆离散傅里叶变换。 |
| [`fft2`](generated/torch.fft.fft2.html#torch.fft.fft2 "torch.fft.fft2") | 计算`input`的二维离散傅里叶变换。 |
| [`ifft2`](generated/torch.fft.ifft2.html#torch.fft.ifft2 "torch.fft.ifft2") | 计算`input`的二维逆离散傅里叶变换。 |
| [`fftn`](generated/torch.fft.fftn.html#torch.fft.fftn "torch.fft.fftn") | 计算`input`的N维离散傅里叶变换。 |
| [`ifftn`](generated/torch.fft.ifftn.html#torch.fft.ifftn "torch.fft.ifftn") | 计算`input`的N维逆离散傅里叶变换。 |
| [`rfft`](generated/torch.fft.rfft.html#torch.fft.rfft "torch.fft.rfft") | 计算实值`input`的一维傅里叶变换。 |
| [`irfft`](generated/torch.fft.irfft.html#torch.fft.irfft "torch.fft.irfft") | 计算[`rfft()`](generated/torch.fft.rfft.html#torch.fft.rfft "torch.fft.rfft")的逆变换。 |
| [`rfft2`](generated/torch.fft.rfft2.html#torch.fft.rfft2 "torch.fft.rfft2") | 计算实数`input`的二维离散傅里叶变换。 |
| [`irfft2`](generated/torch.fft.irfft2.html#torch.fft.irfft2 "torch.fft.irfft2") | 计算[`rfft2()`](generated/torch.fft.rfft2.html#torch.fft.rfft2 "torch.fft.rfft2")的逆变换。 |
| [`rfftn`](generated/torch.fft.rfftn.html#torch.fft.rfftn "torch.fft.rfftn") | 计算实数`input`的N维离散傅里叶变换。 |
| [`irfftn`](generated/torch.fft.irfftn.html#torch.fft.irfftn "torch.fft.irfftn") | 计算[`rfftn()`](generated/torch.fft.rfftn.html#torch.fft.rfftn "torch.fft.rfftn")的逆变换。 |
| [`hfft`](generated/torch.fft.hfft.html#torch.fft.hfft "torch.fft.hfft") | 计算埃尔米特对称`input`信号的一维离散傅里叶变换。 |
| [`ihfft`](generated/torch.fft.ihfft.html#torch.fft.ihfft "torch.fft.ihfft") | 计算[`hfft()`](generated/torch.fft.hfft.html#torch.fft.hfft "torch.fft.hfft")的逆变换。 |
| [`hfft2`](generated/torch.fft.hfft2.html#torch.fft.hfft2 "torch.fft.hfft2") | 计算埃尔米特对称`input`信号的二维离散傅里叶变换。 |
| [`ihfft2`](generated/torch.fft.ihfft2.html#torch.fft.ihfft2 "torch.fft.ihfft2") | 计算实数`input`的二维逆离散傅里叶变换。 |
| [`hfftn`](generated/torch.fft.hfftn.html#torch.fft.hfftn "torch.fft.hfftn") | 计算埃尔米特对称`input`信号的n维离散傅里叶变换。 |
| [`ihfftn`](generated/torch.fft.ihfftn.html#torch.fft.ihfftn "torch.fft.ihfftn") | 计算实数`input`的N维逆离散傅里叶变换。 |
| `ifft` | 计算`input`的一维逆离散傅里叶变换。 |
| `fft2` | 计算`input`的二维离散傅里叶变换。 |
| `ifft2` | 计算`input`的二维逆离散傅里叶变换。 |
| `fftn` | 计算`input`的 N 维离散傅里叶变换。 |
| `ifftn` | 计算`input`的 N 维逆离散傅里叶变换。 |
| `rfft` | 计算实值`input`的一维傅里叶变换。 |
| `irfft` | 计算`rfft()`的逆变换。 |
| `rfft2` | 计算实数`input`的二维离散傅里叶变换。 |
| `irfft2` | 计算`rfft2()`的逆变换。 |
| `rfftn` | 计算实数`input`的 N 维离散傅里叶变换。 |
| `irfftn` | 计算`rfftn()`的逆变换。 |
| `hfft` | 计算埃尔米特对称`input`信号的一维离散傅里叶变换。 |
| `ihfft` | 计算`hfft()`的逆变换。 |
| `hfft2` | 计算埃尔米特对称`input`信号的二维离散傅里叶变换。 |
| `ihfft2` | 计算实数`input`的二维逆离散傅里叶变换。 |
| `hfftn` | 计算埃尔米特对称`input`信号的 n 维离散傅里叶变换。 |
| `ihfftn` | 计算实数`input`的 N 维逆离散傅里叶变换。 |
## 辅助函数
| [`fftfreq`](generated/torch.fft.fftfreq.html#torch.fft.fftfreq "torch.fft.fftfreq") | 计算大小为`n`的信号的离散傅里叶变换采样频率。 |
| `fftfreq` | 计算大小为`n`的信号的离散傅里叶变换采样频率。 |
| --- | --- |
| [`rfftfreq`](generated/torch.fft.rfftfreq.html#torch.fft.rfftfreq "torch.fft.rfftfreq") | 计算具有大小`n`的信号的[`rfft()`](generated/torch.fft.rfft.html#torch.fft.rfft "torch.fft.rfft")的采样频率。 |
| [`fftshift`](generated/torch.fft.fftshift.html#torch.fft.fftshift "torch.fft.fftshift") | 重新排列n维FFT数据,如[`fftn()`](generated/torch.fft.fftn.html#torch.fft.fftn "torch.fft.fftn")提供的,以使负频率项优先。 |
| [`ifftshift`](生成/torch.fft.ifftshift.html#torch.fft.ifftshift "torch.fft.ifftshift") | [`fftshift()`](生成/torch.fft.fftshift.html#torch.fft.fftshift "torch.fft.fftshift") 的逆操作。 |
| `rfftfreq` | 计算具有大小`n`的信号的`rfft()`的采样频率。 |
| `fftshift` | 重新排列 n 维 FFT 数据,如`fftn()`提供的,以使负频率项优先。 |
| `ifftshift` | `fftshift()` 的逆操作。 |
# torch.func
> 原文:[https://pytorch.org/docs/stable/func.html](https://pytorch.org/docs/stable/func.html)
> 原文:[`pytorch.org/docs/stable/func.html`](https://pytorch.org/docs/stable/func.html)
torch.func,以前称为“functorch”,是PyTorch[JAX-like](https://github.com/google/jax)可组合函数变换。
torch.func,以前称为“functorch”,是 PyTorch [JAX-like](https://github.com/google/jax)可组合函数变换。
注意
该库目前处于[测试版](https://pytorch.org/blog/pytorch-feature-classification-changes/#beta)。这意味着功能通常可用(除非另有说明),我们(PyTorch团队)致力于推进该库。但是,API可能会根据用户反馈进行更改,我们对PyTorch操作的覆盖范围不完整。
该库目前处于[测试版](https://pytorch.org/blog/pytorch-feature-classification-changes/#beta)。这意味着功能通常可用(除非另有说明),我们(PyTorch 团队)致力于推进该库。但是,API 可能会根据用户反馈进行更改,我们对 PyTorch 操作的覆盖范围不完整。
如果您对API或用例有建议,请打开GitHub问题或联系我们。我们很乐意听听您如何使用库。
如果您对 API 或用例有建议,请打开 GitHub 问题或联系我们。我们很乐意听听您如何使用库。
## 什么是可组合的函数变换?[](#what-are-composable-function-transforms "跳转到此标题")
+ “函数变换”是一个高阶函数,接受一个数值函数并返回一个计算不同量的新函数。
+ [`torch.func`](func.api.html#module-torch.func "torch.func")具有自动微分变换(`grad(f)`返回一个计算`f`梯度的函数),矢量化/批处理变换(`vmap(f)`返回一个计算输入批次上的`f`的函数)等。
+ `torch.func`具有自动微分变换(`grad(f)`返回一个计算`f`梯度的函数),矢量化/批处理变换(`vmap(f)`返回一个计算输入批次上的`f`的函数)等。
+ 这些函数变换可以任意组合。例如,组合`vmap(grad(f))`计算一种称为每样本梯度的量,目前原始PyTorch无法高效计算。
+ 这些函数变换可以任意组合。例如,组合`vmap(grad(f))`计算一种称为每样本梯度的量,目前原始 PyTorch 无法高效计算。
## 为什么使用可组合的函数变换?[](#why-composable-function-transforms "跳转到此标题")
目前在PyTorch中有一些棘手的用例:
目前在 PyTorch 中有一些棘手的用例:
+ 计算每样本梯度(或其他每样本量)
+ 在单台机器上运行模型集合
+MAML的内循环中高效批处理任务
+ MAML 的内循环中高效批处理任务
+ 高效计算雅可比矩阵和海森矩阵
+ 高效计算批量雅可比矩阵和海森矩阵
组合[`vmap()`](generated/torch.func.vmap.html#torch.func.vmap "torch.func.vmap")[`grad()`](generated/torch.func.grad.html#torch.func.grad "torch.func.grad")[`vjp()`](generated/torch.func.vjp.html#torch.func.vjp "torch.func.vjp")变换使我们能够表达上述内容,而无需为每个设计单独的子系统。这种可组合函数变换的想法来自[JAX框架](https://github.com/google/jax)
组合`vmap()``grad()``vjp()`变换使我们能够表达上述内容,而无需为每个设计单独的子系统。这种可组合函数变换的想法来自[JAX 框架](https://github.com/google/jax)
## 阅读更多
+ [torch.func快速浏览](func.whirlwind_tour.html)
+ torch.func 快速浏览
+ [什么是torch.func?](func.whirlwind_tour.html#what-is-torch-func)
+ 什么是 torch.func?
+ [为什么使用可组合的函数变换?](func.whirlwind_tour.html#why-composable-function-transforms)
+ 为什么使用可组合的函数变换?
+ [什么是变换?](func.whirlwind_tour.html#what-are-the-transforms)
+ 什么是变换?
+ [torch.func API参考](func.api.html)
+ torch.func API 参考
+ [函数变换](func.api.html#function-transforms)
+ 函数变换
+ [与torch.nn.Modules一起工作的实用程序](func.api.html#utilities-for-working-with-torch-nn-modules)
+ 与 torch.nn.Modules 一起工作的实用程序
+ [用户体验限制](func.ux_limitations.html)
+ 用户体验限制
+ [一般限制](func.ux_limitations.html#general-limitations)
+ 一般限制
+ [torch.autograd API](func.ux_limitations.html#torch-autograd-apis)
+ torch.autograd API
+ [vmap限制](func.ux_limitations.html#vmap-limitations)
+ vmap 限制
+ [随机性](func.ux_limitations.html#randomness)
+ 随机性
+ [从functorch迁移到torch.func](func.migrating.html)
+ 从 functorch 迁移到 torch.func
+ [函数变换](func.migrating.html#function-transforms)
+ 函数变换
+ [NN模块实用程序](func.migrating.html#nn-module-utilities)
+ NN 模块实用程序
+ [functorch.compile](func.migrating.html#functorch-compile)
+ functorch.compile
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
# torch.signal
> 原文:[https://pytorch.org/docs/stable/signal.html](https://pytorch.org/docs/stable/signal.html)
> 原文:[`pytorch.org/docs/stable/signal.html`](https://pytorch.org/docs/stable/signal.html)
torch.signal模块,模仿自SciPy[signal](https://docs.scipy.org/doc/scipy/reference/signal.html)模块。
torch.signal 模块,模仿自 SciPy [signal](https://docs.scipy.org/doc/scipy/reference/signal.html)模块。
## torch.signal.windows[](#module-torch.signal.windows "Permalink to this heading")
| [`bartlett`](generated/torch.signal.windows.bartlett.html#torch.signal.windows.bartlett "torch.signal.windows.bartlett") | 计算巴特利特窗口。 |
| `bartlett` | 计算巴特利特窗口。 |
| --- | --- |
| [`blackman`](generated/torch.signal.windows.blackman.html#torch.signal.windows.blackman "torch.signal.windows.blackman") | 计算布莱克曼窗口。 |
| [`cosine`](generated/torch.signal.windows.cosine.html#torch.signal.windows.cosine "torch.signal.windows.cosine") | 计算具有简单余弦波形的窗口。 |
| [`exponential`](generated/torch.signal.windows.exponential.html#torch.signal.windows.exponential "torch.signal.windows.exponential") | 计算具有指数波形的窗口。 |
| [`gaussian`](generated/torch.signal.windows.gaussian.html#torch.signal.windows.gaussian "torch.signal.windows.gaussian") | 计算具有高斯波形的窗口。 |
| [`general_cosine`](generated/torch.signal.windows.general_cosine.html#torch.signal.windows.general_cosine "torch.signal.windows.general_cosine") | 计算通用余弦窗口。 |
| [`general_hamming`](generated/torch.signal.windows.general_hamming.html#torch.signal.windows.general_hamming "torch.signal.windows.general_hamming") | 计算通用汉明窗口。 |
| [`hamming`](generated/torch.signal.windows.hamming.html#torch.signal.windows.hamming "torch.signal.windows.hamming") | 计算汉明窗口。 |
| [`hann`](generated/torch.signal.windows.hann.html#torch.signal.windows.hann "torch.signal.windows.hann") | 计算汉宁窗口。 |
| [`kaiser`](generated/torch.signal.windows.kaiser.html#torch.signal.windows.kaiser "torch.signal.windows.kaiser") | 计算凯泽窗口。 |
| [`nuttall`](generated/torch.signal.windows.nuttall.html#torch.signal.windows.nuttall "torch.signal.windows.nuttall") | 根据Nuttall计算最小的4项布莱克曼-哈里斯窗口。 |
| `blackman` | 计算布莱克曼窗口。 |
| `cosine` | 计算具有简单余弦波形的窗口。 |
| `exponential` | 计算具有指数波形的窗口。 |
| `gaussian` | 计算具有高斯波形的窗口。 |
| `general_cosine` | 计算通用余弦窗口。 |
| `general_hamming` | 计算通用汉明窗口。 |
| `hamming` | 计算汉明窗口。 |
| `hann` | 计算汉宁窗口。 |
| `kaiser` | 计算凯泽窗口。 |
| `nuttall` | 根据 Nuttall 计算最小的 4 项布莱克曼-哈里斯窗口。 |
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
# torch.onnx
> 原文:[https://pytorch.org/docs/stable/onnx.html](https://pytorch.org/docs/stable/onnx.html)
> 原文:[`pytorch.org/docs/stable/onnx.html`](https://pytorch.org/docs/stable/onnx.html)
## 概述
[Open Neural Network eXchange (ONNX)](https://onnx.ai/) 是表示机器学习模型的开放标准格式。`torch.onnx` 模块从本机 PyTorch [`torch.nn.Module`](generated/torch.nn.Module.html#torch.nn.Module "torch.nn.Module") 模型中捕获计算图,并将其转换为 [ONNX 图](https://github.com/onnx/onnx/blob/main/docs/IR.md)
[Open Neural Network eXchange (ONNX)](https://onnx.ai/) 是表示机器学习模型的开放标准格式。`torch.onnx` 模块从本机 PyTorch `torch.nn.Module` 模型中捕获计算图,并将其转换为 [ONNX 图](https://github.com/onnx/onnx/blob/main/docs/IR.md)
导出的模型可以被支持 ONNX 的许多 [运行时](https://onnx.ai/supported-tools.html#deployModel) 使用,包括微软的 [ONNX Runtime](https://www.onnxruntime.ai)
......@@ -18,13 +18,13 @@ TorchDynamo 引擎被用来钩入 Python 的帧评估 API 并动态重写其字
这种方法的主要优势在于,[FX 图](https://pytorch.org/docs/stable/fx.html) 是通过保留模型的动态特性而不是使用传统的静态追踪技术来捕获的。
[了解基于 TorchDynamo 的 ONNX 导出器](onnx_dynamo.html)
了解基于 TorchDynamo 的 ONNX 导出器
## 基于 TorchScript 的 ONNX 导出器[](#torchscript-based-onnx-exporter "跳转到此标题")
*基于 TorchScript 的 ONNX 导出器自 PyTorch 1.2.0 起可用*
[TorchScript](https://pytorch.org/docs/stable/jit.html) 被利用来追踪(通过 [`torch.jit.trace()`](generated/torch.jit.trace.html#torch.jit.trace "torch.jit.trace"))模型并捕获静态计算图。
[TorchScript](https://pytorch.org/docs/stable/jit.html) 被利用来追踪(通过 `torch.jit.trace()`)模型并捕获静态计算图。
因此,生成的图有一些限制:
......@@ -34,9 +34,9 @@ TorchDynamo 引擎被用来钩入 Python 的帧评估 API 并动态重写其字
+ 不真正处理动态输入
为了支持静态追踪的限制,导出器还支持 TorchScript 脚本化(通过 [`torch.jit.script()`](generated/torch.jit.script.html#torch.jit.script "torch.jit.script")),这增加了对数据相关控制流的支持,例如。然而,TorchScript 本身是 Python 语言的一个子集,因此并不支持 Python 中的所有功能,比如原地操作。
为了支持静态追踪的限制,导出器还支持 TorchScript 脚本化(通过 `torch.jit.script()`),这增加了对数据相关控制流的支持,例如。然而,TorchScript 本身是 Python 语言的一个子集,因此并不支持 Python 中的所有功能,比如原地操作。
[了解基于 TorchScript 的 ONNX 导出器](onnx_torchscript.html)
了解基于 TorchScript 的 ONNX 导出器
## 贡献 / 开发
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
# torch.utils
> 原文:[https://pytorch.org/docs/stable/utils.html](https://pytorch.org/docs/stable/utils.html)
> 原文:[`pytorch.org/docs/stable/utils.html`](https://pytorch.org/docs/stable/utils.html)
| [`rename_privateuse1_backend`](generated/torch.utils.rename_privateuse1_backend.html#torch.utils.rename_privateuse1_backend "torch.utils.rename_privateuse1_backend") | 将privateuse1后端设备重命名,使其在PyTorch API中更方便使用作为设备名称。 |
| `rename_privateuse1_backend` | 将 privateuse1 后端设备重命名,使其在 PyTorch API 中更方便使用作为设备名称。 |
| --- | --- |
| [`generate_methods_for_privateuse1_backend`](generated/torch.utils.generate_methods_for_privateuse1_backend.html#torch.utils.generate_methods_for_privateuse1_backend "torch.utils.generate_methods_for_privateuse1_backend") | 在将privateuse1后端重命名后,自动生成自定义后端的属性和方法。 |
| [`get_cpp_backtrace`](generated/torch.utils.get_cpp_backtrace.html#torch.utils.get_cpp_backtrace "torch.utils.get_cpp_backtrace") | 返回一个包含当前线程C++堆栈跟踪的字符串。 |
| [`set_module`](generated/torch.utils.set_module.html#torch.utils.set_module "torch.utils.set_module") | 为给定对象设置python对象的模块属性,以便更好地打印。 |
| `generate_methods_for_privateuse1_backend` | 在将 privateuse1 后端重命名后,自动生成自定义后端的属性和方法。 |
| `get_cpp_backtrace` | 返回一个包含当前线程 C++堆栈跟踪的字符串。 |
| `set_module` | 为给定对象设置 python 对象的模块属性,以便更好地打印。 |
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
# JIT Utils - torch.utils.jit
> 原文:[https://pytorch.org/docs/stable/jit_utils.html](https://pytorch.org/docs/stable/jit_utils.html)
> 原文:[`pytorch.org/docs/stable/jit_utils.html`](https://pytorch.org/docs/stable/jit_utils.html)
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册