我有一些libtorch代码,它使用pytorch训练的模型在cpu上进行推理,然后导出到torchscript。下面的代码是一个被重复调用的方法的简化版本。
void Backend::perform(std::vector<float *> in_buffer,
std::vector<float *> out_buffer) {
c10::InferenceMode guard;
at::Tensor tensor_out;
at::Tensor tensor_in = torch::zeros({ 1, 16, 2 });
std::vector<torch::jit::IValue> inputs = { tensor_in };
// calling forward on the model "decode," this is where
// the memory leak happens
tensor_out = m_model.get_method("decode")(inputs).toTensor();
auto out_ptr = tensor_out.contiguous().data_ptr<float>();
for (int i(0); i < out_buffer.size(); i++) {
memcpy(out_buffer[i], out_ptr + i * n_vec, n_vec * sizeof(float));
}
}
m_model是通过以下方式加载的.ts文件:
m_model = torch::jit::load(path);
m_model.eval();
每次调用似乎都有更多的 Torch 图被分配,并且没有被释放,导致程序最终OOM并崩溃。注解掉前向调用会使内存使用稳定下来。
我的理解是,推理模式后卫应该关闭autograd内存积累,这似乎是这些问题的正常原因。
我试着在pytorch中模仿这一点(通过反复从循环中调用forward),没有内存问题,这似乎表明这是libtorch的问题,而不是模型本身的问题。
我的系统:
操作系统:Windows 10
pytorch版本:1.11.0
libtorch版本:1.11.0
2条答案
按热度按时间5f0d552i1#
这最终成为libtorch的windows实现中的一个bug。当从主线程(https://github.com/pytorch/pytorch/issues/24237)中调用单独的线程时,可能会发生内存泄漏,将forward调用移到主线程修复了这个问题。
即使问题标记为已关闭,Bug仍然存在。
qij5mzcb2#
我也遇到过类似的问题,我的forward方法占用了太多的内存却没有释放出来。这不是完全相同的代码,但你可以试试。最重要的是似乎把整个代码放在
torch::NoGradGuard
的作用域中,在我的例子中,我还强制输入Tensor与set_requires_grad(false)
不grad。编码:
之前在几秒钟内我的磁盘空间将完全充满,与这些修改磁盘内存现在是稳定的。