我尝试在Pytorch中实现一种高效的并发推理方法。
现在,我在我的GPU上启动了两个进程(我只有一个GPU,两个进程在同一个设备上),每个进程加载我的Pytorch模型并执行推理步骤。
我的问题是我的模型在内存上占用了相当多的空间。我在GPU上有12 GB的内存,而模型单独占用了~3GB的内存(没有数据)。这意味着我的2个进程加在一起,仅为模型就占用了6 GB的内存。
现在我想知道是否有可能只加载一次模型,并使用此模型对2个不同的进程进行推理。我想要的是模型只消耗3GB内存,但仍然有2个进程。
我遇到this answer时提到了IPC,但据我所知,这意味着进程#2将从进程#1复制模型,因此我最终仍将为模型分配6 Gb。
我还检查了Pytorch文档,关于DataParallel和DistributedDataParallel,但这似乎是不可能的。
This似乎是我想要的,但是我找不到任何关于如何在推理模式下使用Pytorch的代码示例。
我知道在训练中做这样的事情可能很困难,但请注意我只是在讨论推理步骤(模型处于只读模式,不需要更新梯度)。在这种假设下,我不确定它是否可行。
2条答案
按热度按时间q3qa4bjr1#
GPU本身有很多线程。当执行数组/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?),但这似乎只是在引擎盖下使用时间分片实现的,所以我不确定我们是否应该期望更高的总吞吐量:
如何使用Nvidia多进程服务(MPS)运行多个非MPI CUDA应用程序?
如果您确实需要在两个并行推理调用之间共享一个模型的内存,那么您可以使用多个线程而不是进程,并从两个线程引用同一个模型吗?
要让GPU真正并行运行多个内核,您可以在PyTorch中使用nn.Parallel。https://discuss.pytorch.org/t/how-can-l-run-two-blocks-in-parallel/61618/3
a2mppw5e2#
通过在数据加载和模型推理中执行并发,您可以在单个(只读)推理进程中获得与单个模型并发的大部分好处。
数据加载是和模型运行过程分开的,这可以手工完成,据我所知,
tensorflow
有一些原生的支持优化并行data preloading,你可以看看它的例子。模型推理在GPU上自动并行。您可以通过使用更大的批处理来最大化这种并发性。
从体系结构的Angular 来看,多个用户也可以通过更高级别的接口与模型对话。