使用 Pytorch 在同一 GPU 上的进程之间共享 GPU 内存
Sharing GPU memory between process on a same GPU with Pytorch
我正在尝试实现一种在 Pytorch 中进行并发推理的有效方法。
现在,我在我的 GPU 上启动了 2 个进程(我只有 1 个 GPU,两个进程都在同一台设备上)。每个进程加载我的 Pytorch 模型并执行推理步骤。
我的问题是我的模型占用了相当多的 space 内存。我在 GPU 上有 12Gb 的内存,而模型仅占用 ~3Gb 的内存(没有数据)。这意味着我的 2 个进程一起占用了 6Gb 的内存用于模型。
现在我想知道是否可以只加载一次模型,然后使用该模型对 2 个不同的进程进行推理。我想要的是模型只消耗 3Gb 的内存,但仍然有 2 个进程。
我偶然发现 提到了 IPC,但据我了解,这意味着进程 #2 将从进程 #1 复制模型,因此我最终仍会为模型分配 6Gb。
我还查看了 Pytorch 文档,关于 DataParallel 和 DistributedDataParallel,但似乎不可能。
This 似乎是我想要的,但我找不到任何关于如何在推理模式下使用 Pytorch 的代码示例。
我知道这可能很难为训练做这样的事情,但请注意我只是在谈论推理步骤(模型处于只读模式,不需要更新梯度)。有了这个假设,我不确定它是否可能。
通过在数据加载和模型推理中进行并发,您可以在用于(只读)推理的单个进程中使用单个模型获得并发的大部分好处。
数据加载与模型运行过程分开,这可以手动完成。据我所知,tensorflow
对最佳并行 data preloading 有一些本机支持,您可以查看它的示例。
模型推理在 GPU 上自动并行。您可以通过使用更大的批次来最大化此并发性。
从架构的角度来看,多个用户还可以通过更高级别的界面与模型对话。
GPU本身有很多线程。执行 array/tensor 操作时,它在数组的一个或多个单元格上使用每个线程。这就是为什么一个可以充分利用 GPU 的运算似乎应该在没有多个进程的情况下有效地扩展——单个 GPU 内核已经被大规模并行化了。
在评论中,您提到在小型基准测试中使用多个进程看到了更好的结果。我建议 运行 将基准测试与更多作业结合起来以确保预热,十个内核似乎对测试来说太小了。不过,如果您正在寻找一个全面且具有代表性的基准测试,运行 始终如一地更快,我会相信良好的基准测试胜过我的直觉。
我的理解是,在默认 CUDA 流上启动的内核会按顺序执行。如果您希望它们并行 运行,我认为您需要多个流。查看 PyTorch 代码,我在内核中看到类似 getCurrentCUDAStream()
的代码,这让我认为 GPU 仍将按顺序 运行 来自所有进程的任何 PyTorch 代码。
这个 NVIDIA 讨论表明这是正确的:
https://devtalk.nvidia.com/default/topic/1028054/how-to-launch-cuda-kernel-in-different-processes/
较新的 GPU 可能能够 运行 并行处理多个内核(使用 MPI?),但似乎这只是在幕后通过时间切片实现的,所以我不确定我们是否应该期待更高的总吞吐量:
如果您确实需要在两个并行推理调用之间共享一个模型的内存,是否可以只使用多个线程而不是进程,并从两个线程引用同一模型?
要真正让 GPU 并行 运行 多个内核,您可以在 PyTorch 中使用 nn.Parallel。请参阅此处的讨论:
https://discuss.pytorch.org/t/how-can-l-run-two-blocks-in-parallel/61618/3
我正在尝试实现一种在 Pytorch 中进行并发推理的有效方法。
现在,我在我的 GPU 上启动了 2 个进程(我只有 1 个 GPU,两个进程都在同一台设备上)。每个进程加载我的 Pytorch 模型并执行推理步骤。
我的问题是我的模型占用了相当多的 space 内存。我在 GPU 上有 12Gb 的内存,而模型仅占用 ~3Gb 的内存(没有数据)。这意味着我的 2 个进程一起占用了 6Gb 的内存用于模型。
现在我想知道是否可以只加载一次模型,然后使用该模型对 2 个不同的进程进行推理。我想要的是模型只消耗 3Gb 的内存,但仍然有 2 个进程。
我偶然发现
我还查看了 Pytorch 文档,关于 DataParallel 和 DistributedDataParallel,但似乎不可能。
This 似乎是我想要的,但我找不到任何关于如何在推理模式下使用 Pytorch 的代码示例。
我知道这可能很难为训练做这样的事情,但请注意我只是在谈论推理步骤(模型处于只读模式,不需要更新梯度)。有了这个假设,我不确定它是否可能。
通过在数据加载和模型推理中进行并发,您可以在用于(只读)推理的单个进程中使用单个模型获得并发的大部分好处。
数据加载与模型运行过程分开,这可以手动完成。据我所知,tensorflow
对最佳并行 data preloading 有一些本机支持,您可以查看它的示例。
模型推理在 GPU 上自动并行。您可以通过使用更大的批次来最大化此并发性。
从架构的角度来看,多个用户还可以通过更高级别的界面与模型对话。
GPU本身有很多线程。执行 array/tensor 操作时,它在数组的一个或多个单元格上使用每个线程。这就是为什么一个可以充分利用 GPU 的运算似乎应该在没有多个进程的情况下有效地扩展——单个 GPU 内核已经被大规模并行化了。
在评论中,您提到在小型基准测试中使用多个进程看到了更好的结果。我建议 运行 将基准测试与更多作业结合起来以确保预热,十个内核似乎对测试来说太小了。不过,如果您正在寻找一个全面且具有代表性的基准测试,运行 始终如一地更快,我会相信良好的基准测试胜过我的直觉。
我的理解是,在默认 CUDA 流上启动的内核会按顺序执行。如果您希望它们并行 运行,我认为您需要多个流。查看 PyTorch 代码,我在内核中看到类似 getCurrentCUDAStream()
的代码,这让我认为 GPU 仍将按顺序 运行 来自所有进程的任何 PyTorch 代码。
这个 NVIDIA 讨论表明这是正确的:
https://devtalk.nvidia.com/default/topic/1028054/how-to-launch-cuda-kernel-in-different-processes/
较新的 GPU 可能能够 运行 并行处理多个内核(使用 MPI?),但似乎这只是在幕后通过时间切片实现的,所以我不确定我们是否应该期待更高的总吞吐量:
如果您确实需要在两个并行推理调用之间共享一个模型的内存,是否可以只使用多个线程而不是进程,并从两个线程引用同一模型?
要真正让 GPU 并行 运行 多个内核,您可以在 PyTorch 中使用 nn.Parallel。请参阅此处的讨论: https://discuss.pytorch.org/t/how-can-l-run-two-blocks-in-parallel/61618/3