pytorch模型多次推理时显存累积,解决办法

时间:2025-04-05 09:06:43

pytorch模型多次推理时显存累积,解决办法

  • 【问题描述】
  • 【解决办法】
    • 1.梯度计算:
    • 2.中间变量保留:
    • 3.模型和张量未从GPU移除:
    • 4.数据累积:
  • 完整示例代码
  • 解决我的问题使用的代码
  • 监控显存使用

【问题描述】

最近在做一个项目时发现:模型部署到生产环境后,多次调用此服务会出现随着推理次数的增加,显存占用逐渐增大,于是就研究了解决这个问题的方法。

通过本文的方法,项目模型推理时显存占用缩小了10倍,模型效果没有影响

【解决办法】

在PyTorch中,显存累积通常是由于在推理过程中未能正确管理和释放张量所占用的GPU资源。以下是一些可能的原因和相应的解决方法:

1.梯度计算:

在推理时,确保不需要计算梯度。使用torch.no_grad()上下文管理器来避免梯度的存储。

model.eval()
with torch.no_grad():
    # 推理代码

2.中间变量保留:

确保推理过程中不保留不必要的中间变量。如果使用了变量,推理结束后使用del关键字删除它们,并调用.empty_cache()来清理缓存。
这里注意确定output没用了再删!(del output我没有用这句话)

with torch.no_grad():
    output = model(input)
    # 使用output进行操作
    del output  # 删除不再需要的变量
torch.cuda.empty_cache()

3.模型和张量未从GPU移除:

如果在推理循环中更换了模型或不再需要某些张量,确保它们从GPU中移除。

del model  # 删除模型
del tensor  # 删除张量
torch.cuda.empty_cache()  # 清理缓存

4.数据累积:

如果你在推理过程中收集模型输出,确保将它们移动到CPU内存中,以避免GPU显存累积。

outputs = []
with torch.no_grad():
    for input in data_loader:
        output = model(input)
        outputs.append(output.cpu())  # 将输出移动到CPU

完整示例代码

import torch

# 确保模型在评估模式
model.eval()

# 推理过程中禁用梯度计算
with torch.no_grad():
    for input in data_loader:
        output = model(input)
        # 进行必要的操作
        del output  # 删除不再需要的变量
    torch.cuda.empty_cache()  # 清理未使用的缓存

解决我的问题使用的代码

with torch.no_grad():
    output = model(input) #这句话对应到自己项目中具体代码

torch.cuda.empty_cache()  # 清理未使用的缓存(放在了一次任务结束的最后)

监控显存使用

为了监控显存使用情况,可以使用nvidia-smi命令行工具,它可以显示当前GPU的显存使用情况。
如果要频繁看显存占用也可以watch -n 1 nvidia-smi每隔1秒刷新一次GPU使用情况,数字1可以换成别的数字,比如5,就是每隔5秒刷新。

此外,PyTorch提供了.memory_allocated().max_memory_allocated()函数,可以在程序中检查显存的使用情况。