在Linux下,PyTorch的内存管理策略主要涉及以下几个方面:
显存管理机制
- 动态申请:PyTorch在使用时根据用量实时地向GPU发出请求,避免了占用过量的显存,方便多人同时使用一个设备。
- 二次分配:将显存的申请与使用进行分离,即显存申请后会进行二次分配。PyTorch显存管理机制会先通过
cudamalloc
向GPU申请一个显存块segment,然后从segment分离出子块block,使用分离后的block显存,而不直接使用segment。 - 内存池:未分配的blocks依据size大小(是否大于1MB)分别划入large pool和small pool。用户创建tensor申请显存时,也会依据size大小优先在large pool或者small pool里查找是否有满足要求的block,如果没有才会向GPU申请新的segment显存块。
CUDA API的使用
- PyTorch使用nvidia CUDA runtime和driver API的方式,涉及的API及其在端到端计算过程中的作用。
延迟初始化
- PyTorch采用了“延迟初始化”策略,只有在第一次需要用到CUDA时才会真正调用驱动进行初始化。
清理缓存与释放内存
- 清空缓存:使用
torch.cuda.empty_cache()
函数可以清空GPU缓存,释放相应内存。 - 删除不再使用的变量:手动删除不再使用的变量或张量,可以立即释放其占用的内存。
- 降低批次大小:通过降低批次大小,可以减少每次训练过程中占用的内存。
内存优化技术
- 内存复用策略:grad_output缓冲区复用减少内存碎片。
- 原地操作检测:通过版本号检查防止非法内存修改。
- 梯度累加优化:使用
at::tensor::add_
实现原位累加。
通过这些策略和技术,PyTorch能够在Linux环境下高效地管理内存,提高深度学习模型的训练和推理性能。