总结Pytorch推理过程中的一些细节。
同步
优化手段
- 减少内存操作:尽量避免在循环或频繁调用的函数中创建和释放大量的
torch.Tensor
。 - 重复使用Tensor:在可能的情况下,尽量重复使用已经分配的
torch.Tensor
,而不是频繁地创建新的Tensor。 - 使用in-place操作:尽可能使用in-place操作,如
torch.Tensor.fill_()
或torch.Tensor.copy_()
,以减少内存分配。 - 手动释放内存:在不再需要的
torch.Tensor
上调用.detach()
或.detach_()
方法,手动释放内存。
并行
我需要为此写一份内部笔记。虽然不是特别紧急,但它基本上影响了那些适合在纯 Python 上进行的推理工作负载集合。使用 TorchScript 时,我们采用了一些请求合并和通过多线程实现并行处理的组合,以达到良好的 GPU 效率。多进程不太有效,因为 CUDA 上下文切换的开销相当大(即使在两个进程的情况下也有 10-20% 的开销)。
因此,如果没有对多线程的支持,我们将 Python 推理限制在只有 QPS 足够低或延迟要求足够宽松的用例中。话虽如此,目前甚至还不清楚对多线程的 torch.compile 支持能在多大程度上改善情况,因为 GIL 可能会非常成问题。但由于在尝试进行基准测试时会遇到这个问题,现在很难确定这会有多大帮助。
相关资源
参考
- How to maximize CPU <==> GPU memory transfer speeds? - #7 by ptrblck - PyTorch Forums
- https://pytorch.org/docs/stable/torch_cuda_memory.html
- https://pytorch.org/docs/stable/notes/cuda.html
- PyTorch 有哪些坑/bug? - 知乎
- https://pytorch.org/tutorials/recipes/recipes/tuning_guide.html
- https://pytorch-dev-podcast.simplecast.com/episodes