LibTorch's save_to & load_from function - Model Archiving

username: themightyfid
cooked: <p>I’m fairly new to LibTorch and it’s Model Archiving system.</p>
<p>At the moment, I’m trying to save my model configuration from one module, and load it a different module, but I’m raising an error in LibTorch that I don’t quite understand.</p>
<p>To do this, i’ve been reading the API documentation here: <a href="https://pytorch.org/cppdocs/api/classtorch_1_1serialize_1_1_output_archive.html#class-documentation" class="inline-onebox" rel="noopener nofollow ugc">Class OutputArchive — PyTorch master documentation</a><br>
which doesn’t seem to be all that helpful on the matter.</p>
<p>I’ve been trying utilise as much of LibTorch as possible here, but I’m suspecting a JSON or similar storage structure might infact be easier. I’m doing it this way (rather than using a <code>.clone()</code> or similar) as I intend to send the data at some point in the future.</p>
<p>I’ve simplified my code below;</p>
<pre><code class="lang-auto">torch::serialize::OutputArchive
NewModule::getArchive()
{
   torch::serialize::OutputArchive archive;
   auto params = named_parameters(true /*recurse*/);
   auto buffers = named_buffers(true /*recurse*/);
   
   for (const auto&amp; val : params)
   {
      if (!is_empty(val.value()))
				archive.write(val.key(), val.value());
      // Same again with a write-buffers.
      return archive;
   }
}
</code></pre>
<p>This function aims to copy the contents to a <code>torch::serialise::OutputArchive</code>, which can then be saved to disk, passed into an ostream or “writer function”. It’s the last of these I’m struggling to get working successfully.</p>
<p>Torch specifies that the writer function must be of type <code>std::function&lt;size_t(const void*, size_t)&gt;</code> I’m assuming (as the docs don’t specify!) that the <code>const void*</code> is actually an array of bytes which length is determined by the second parameter, <code>size_t</code> I am unsure why the return value is also a <code>size_t</code> here.</p>
<p>My next block of code reads this data blob and attempts to read it using <code>torch::serialise::InputArchive</code>. Calling <code>load_from</code> here produces the error: “PytorchStreamReader failed reading zip archive: failed finding central directory”</p>
<p>Can anyone help resolve why this is the case?</p>
<p>Code below:</p>
<pre><code class="lang-auto">void
NewModule::LoadFromData(const char* data, size_t data_size)
{
   torch::serialize::InputArchive archive;
   archive.load_from(data, data_size);
   auto params = named_parameters(true);
   auto buffers = named_buffers(true);
   for (auto&amp; val : params)
   {
      archive.read(val.key(), val.value());
   }
   // Same again with a copy buffers
}

torch::serialize::OutputArchive
NewModule::copyArchive()
{
   NewModule other_module;
   auto archive = getArchive();
   std::function&lt;size_t(const void*, size_t)&gt; writer_lambda = [this, other_module](const void* data, size_t size) mutable -&gt; size_t {
      other_module.LoadFromData(reinterpret_cast&lt;const char*&gt;(data), size);
   }
   archive.save_to(writer_lambda);
}</code></pre>

username: Andrew_Edmondson
cooked: <p>Not sure exactly your need but have you seen this for saving to disk:</p><aside class="quote quote-modified" data-post="5" data-topic="34234">
  <div class="title">
    <div class="quote-controls"></div>
    <img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/mhubii/48/71033_2.png" class="avatar">
    <a href="https://discuss.pytorch.org/t/libtorch-how-to-save-model-in-mnist-cpp-example/34234/5">(libtorch) How to save model in MNIST cpp example?</a> <a class="badge-category__wrapper " href="/c/c/11"><span data-category-id="11" style="--category-badge-color: #9EB83B; --category-badge-text-color: #FFFFFF;" data-drop-close="true" class="badge-category " title="Topics related to the C++ Frontend, C++ API or C++ Extensions"><span class="badge-category__name">C++</span></span></a>
  </div>
  <blockquote>
    I think, the example was written prior to the stable release of libtorch. The way you would implement the torch::nn::Module now is as follows 
struct NetImpl : torch::nn::Module {       // replaced Net by NetImpl
  NetImpl()                                // replaced Net by NetImpl
      : conv1(torch::nn::Conv2dOptions(1, 10, /*kernel_size=*/5)),
        conv2(torch::nn::Conv2dOptions(10, 20, /*kernel_size=*/5)),
        fc1(320, 50),
        fc2(50, 10) {
    register_module("conv1", conv1);
 …
  </blockquote>
</aside>

<p>and this for transferring parameters between modules without saving:</p><aside class="quote" data-post="5" data-topic="55226">
  <div class="title">
    <div class="quote-controls"></div>
    <img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/carol_ye_liu/48/19402_2.png" class="avatar">
    <a href="https://discuss.pytorch.org/t/can-libtorch-load-model-from-memory/55226/5">Can libtorch load model from memory?</a> <a class="badge-category__wrapper " href="/c/c/11"><span data-category-id="11" style="--category-badge-color: #9EB83B; --category-badge-text-color: #FFFFFF;" data-drop-close="true" class="badge-category " title="Topics related to the C++ Frontend, C++ API or C++ Extensions"><span class="badge-category__name">C++</span></span></a>
  </div>
  <blockquote>
    This is super helpful! Thank you!
  </blockquote>
</aside>


username: Matthias_Moller
cooked: <p>Even if this might be a solution for the original poster, I’d be interested in understanding how <code>archive.save_to(std::function&lt;size_t(const void*, size_t)&gt;)</code> should be used. I would like to “save” the archive into a JSON object (<a href="https://json.nlohmann.me/features/binary_values/#sizes" class="inline-onebox" rel="noopener nofollow ugc">Binary Values - JSON for Modern C++</a>) for which I wanted to use the callback to convert the <code>OutputArchive</code> into an <code>std::vector&lt;std::uint8_t&gt;</code> and proceed with the JSON binary machinery. Any help is appreciated.</p>