pytorch libtorch中的CPU推断导致具有重复调用的OOM转发

wwwo4jvm  于 2022-11-09  发布在  其他
关注(0)|答案(2)|浏览(289)

我有一些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

5f0d552i

5f0d552i1#

这最终成为libtorch的windows实现中的一个bug。当从主线程(https://github.com/pytorch/pytorch/issues/24237)中调用单独的线程时,可能会发生内存泄漏,将forward调用移到主线程修复了这个问题。
即使问题标记为已关闭,Bug仍然存在。

qij5mzcb

qij5mzcb2#

我也遇到过类似的问题,我的forward方法占用了太多的内存却没有释放出来。这不是完全相同的代码,但你可以试试。最重要的是似乎把整个代码放在torch::NoGradGuard的作用域中,在我的例子中,我还强制输入Tensor与set_requires_grad(false)不grad。
编码:

void main(...){
   torch::NoGradGuard no_grad;
   Mat x;
   ... // in my case x was a gray image
   at::Tensor tensor_image = torch::from_blob(x.data, {1, x.rows, x.cols, 1}, at::kByte);
   ... // permute tensor channels
   tensor_image.set_requires_grad(false);

   vector<torch::jit::IValue> inputs;
   inputs.push_back(tensor_image);
   at::Tensor output;
   output = model.forward(inputs).toTensor();
   output = output.squeeze().detach();
   ...
}

之前在几秒钟内我的磁盘空间将完全充满,与这些修改磁盘内存现在是稳定的。

相关问题