How can I train in C++ using a Pytorch torchscript model

ChenyijunAaron: <p>I trained a model in the PyTorch, and then saved it to Torchscript format using torch.jit.save.<br>
Now, I want to retrain on this model. I have a question about whether the torchscript  model can be used for training.</p>
<p>thanks</p>

ptrblck: <p>Yes, you can train your model in <code>libtorch</code> and <a class="mention" href="/u/krshrimali">@krshrimali</a> has published some blog posts with examples in <a href="https://discuss.pytorch.org/t/a-series-of-blogs-on-pytorch-c-api-transfer-learning-jupyter-notebook-with-libtorch-xeus-cling-and-more/54628">this post</a>.</p>

ChenyijunAaron: <p>Thanks for your reply. I read <a class="mention" href="/u/krshrimali">@krshrimali</a> 's blog. I have a few different questions about how to train the Torchscript model in C++.<br>
I want to use a trained model for fine tuning. I generated the Torchscript model in pytorch. In C++ API, I load the model using torch::jit::load function. And then I want to retrain the model.<br>
In my code:<br>
torch::jit::script::Module m_model = torch::jit::load(m_modulePath);<br>
torch::optim::SGD optimizer(m_model.parameters(), SGDoptions);</p>
<p>When I set up the optimizer, I was told that the first parameter was incorrect.</p>

krshrimali: <p>Thanks <a class="mention" href="/u/ptrblck">@ptrblck</a> for the mention. <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=9" title=":slight_smile:" class="emoji" alt=":slight_smile:"></p>
<p>Just to understand the error better, <a class="mention" href="/u/chenyijunaaron">@ChenyijunAaron</a> - it will help if you could share the exact error here.</p>

ChenyijunAaron: <p>Thanks for your reply. <img src="https://discuss.pytorch.org/images/emoji/apple/slightly_smiling_face.png?v=9" title=":slightly_smiling_face:" class="emoji" alt=":slightly_smiling_face:"></p>
<p>I want fine-tune a model. The model is generated using pytorch. And then I load the .pt model in libtorch.<br>
When I’m initializing the constructor of class torch::optim::SGD, the compiler prompts me that the first argument I entered does not match. See the following code:<br>
torch::jit::script::Module m_model = torch::jit::load(m_modulePath);<br>
torch::optim::SGDOptions SGDoptions(m_train_lr);<br>
torch::optim::SGD optimizer(m_model.parameters(), SGDoptions);<br>
**m_model is generated using PyTorch torch::jit::trace &amp;torch::jit::save</p>
<p>But when I use the following code, I get no error. ( Use your blog code)<br>
See the following code:<br>
torch::nn::Linear linear_layer{ 512,2 };<br>
torch::optim::Adam optimizer(linear_layer-&gt;parameters(), torch::optim::AdamOptions(1e-3));</p>
<p>Is it because the torchscript model can’t backpropagate in libtorch？ If I want to train the Torchscript model, what should I do.</p>
<p>Thank you so much. <img src="https://discuss.pytorch.org/images/emoji/apple/slightly_smiling_face.png?v=9" title=":slightly_smiling_face:" class="emoji" alt=":slightly_smiling_face:"></p>

RobinChen: <p>Hi ChenyijunAaron,</p>
<p>Glad to discuss with you here about training or fine-tuning the python saved   .pt  module in C++ with libtorch.  It is caused by the different types of modules: torch::jit::parameter_list and  std::vector<a>at::Tensor</a>.</p>
<p>I also meet this problem and am still debugging it.</p>
<p>How to fix it？ By now I goes to train it with pure C++ and give up importing python. I will also try the import way when free. If you solve it, it would be great to share it here.</p>
<p>Enjoy the coding！</p>

vectorphresh: <p>I got a little farther by passing the gradients as a list to the optimizer, following the GitHub example <a href="https://github.com/pytorch/pytorch/issues/17614#issuecomment-769151466" rel="noopener nofollow ugc">here</a> but I got a bunch of inplace errors when calculating loss.</p>
<p>I too am thinking a pure C++ approach may be the path to moving forward for reinforcement learning applications.</p>

SeaShellAtSeaSide: <p>Still no answer to this? is there no easy way to do this? I’m also stuck in this problem. I can’t construct the optimizer using the loaded jit’ed model’s parameters.</p>

vectorphresh: <p>I was able to load torchscript GRU model after making some modifications. I was getting a lot of inplace exceptions which I had to address.</p>
<p>On the Python side I avoided any inplace operations. I set inplace=False for nn.ReLU in my layers definition and altered any self assignments (-=, x = x * …) to model layers.</p>
<p>To troubleshoot where the inplace writes were, I traced the model and then printed the output from dump_alias_db() (for ex print(traced_script_model.graph.dump_alias_db()) ). This will show you where the writes are happening in your torchscript model.</p>
<p>On the C++ side you may also need to clone tensors that are being modified. Only the loss tensor needed to be cloned in my case because I believe the call to backward() would cause an inplace operation when computing the gradients. Enabling anomaly detection also helped.</p>
<p>Also, I was trying to reuse hidden state tensor between calls to training step function, which caused an inplace exception until I switched to preserving the floating point values instead, and recreating the tensor each time.</p>

vectorphresh: <p>For the optimizer you read out the parameters and then pass them to your optimizer instance</p>
<pre><code class="lang-auto">    std::vector&lt;torch::Tensor&gt; params;
    for (const auto&amp; p : torchscript_model.named_parameters()) {
        params.push_back(p.value);
    }

    torch::optim::Adam optimizer(params,     torch::optim::AdamOptions(0.005));
    optimizer.zero_grad();
    loss.backward({}, true);
    optimizer.step();
</code></pre>