我正在使用 PyTorch (libtorch
) 的 C++ API 开发机器学习系统。
我最近一直在做的一件事是研究 libtorch
的性能、CPU 利用率和 GPU 使用情况。通过我的研究,我了解到 Torch 在 CPU 上使用两种并行化方式:
操作间
并行化操作内
并行化
我的主要问题是:
- 两者的区别
- 如何利用
操作间
并行性
我知道我可以使用指定用于
函数,当我监视模型的性能时,我可以清楚地看到它使用了我使用此函数指定的线程数,并且通过更改线程数我可以看到明显的性能差异intra-op
并行性的线程数(根据我的理解,这是使用openmp
后端执行的) torch::set_num_threads()操作内
线程。
还有另一个函数torch::set_num_interop_threads()
,但似乎无论我指定多少个互操作线程,我都看不到性能有任何差异。
现在我已阅读this PyTorch documentation article但我仍然不清楚如何利用互操作线程池。
文档说:
PyTorch uses a single thread pool for the inter-op parallelism, this thread pool is shared by all inference tasks that are forked within the application process.
我对此部分有两个问题:
- 我是否需要自己创建新线程来利用
interop
线程,还是 torch 会在内部以某种方式为我完成此操作? - 如果我需要自己创建新线程,如何在 C++ 中执行此操作,以便从
interop
线程池创建新线程?
在python
示例中,他们使用torch.jit
模块中的fork
函数,但我在C++ API中找不到类似的东西。
最佳答案
问题
difference between these two
正如这张图片所示:
intra-op
- 针对单个操作完成并行化(例如matmul
或任何其他“每个张量”)inter-op
- 您有多个操作,并且它们的计算可以交织在一起
互操作
“示例”:
op1
启动并返回“Future”对象(这是一旦此操作完成我们可以查询结果的对象)op2
立即启动(因为op1
现在是非阻塞的)op2
完成- 我们可以查询
op1
以获得结果(希望已经完成或至少接近完成) - 我们将
op1
和op2
结果添加在一起(或者我们想用它们做的任何事情)
由于上述原因:
intra-op
无需任何添加即可工作(因为它是由 PyTorch 处理的),并且应该会提高性能inter-op
是用户驱动的(模型的架构,尤其是forward
),因此架构必须使用inter-op
创建牢记在心!
how can I utilize inter-op parallelism
除非您在构建模型时考虑到inter-op
(例如使用Futures
,请参阅您发布的链接中的第一个代码片段),否则您将看不到任何性能改进。
最有可能:
- 您的模型是用 Python 编写的,转换为
torchscript
,并且仅用 C++ 完成推理 - 您应该使用 Python 编写(或重构现有的)
inter-op
代码,例如使用torch.jit.fork
和torch.jit.wait
do I need to create new threads myself to utilize the interop threads, or does torch do it somehow for me internally?
不确定目前在 C++ 中是否可行,找不到任何 torch::jit::fork
或相关功能。
If I need to create new threads myself, how do I do it in C++, so that I create a new thread form the interop thread pool?
不太可能,因为 C++ 的 API 的目标是模仿 Python 的 API 尽可能接近现实。 您可能需要更深入地挖掘与之相关的源代码和/或在需要时在其 GitHub 存储库上发布功能请求
关于python - Pytorch C++ (Libtroch),使用操作间并行性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68361267/