How to Debug Saving Model TypeError: can't pickle SwigPyObject objects?

RylanSchaeffer: <p>I’m trying to save a model, which is an object of a class that inherits from <code>nn.Module</code>. It trains fine without problem, but when I try running the code:</p>
<pre><code class="lang-auto">    torch.save(
        obj=model,
        f=os.path.join(tensorboard_writer.get_logdir(), 'model.ckpt'))
</code></pre>
<p>I receive the error: <code>TypeError: can't pickle SwigPyObject objects</code></p>
<p>I have no idea what a <code>SwigPyObject</code> object is. How do I debug this error to save my model?</p>
<p>Full Traceback:</p>
<pre><code class="lang-auto">Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/torch/serialization.py", line 149, in _with_file_like
    return body(f)
  File "/usr/local/lib/python3.6/dist-packages/torch/serialization.py", line 224, in &lt;lambda&gt;
    return _with_file_like(f, "wb", lambda f: _save(obj, f, pickle_module, pickle_protocol))
  File "/usr/local/lib/python3.6/dist-packages/torch/serialization.py", line 296, in _save
    pickler.dump(obj)
TypeError: can't pickle SwigPyObject objects
</code></pre>
<p>In case it helps, my model is an object of the following class:</p>
<pre><code class="lang-auto">class RecurrentModel(nn.Module):

    def __init__(self,
                 core_str,
                 core_kwargs,
                 tensorboard_writer=None,
                 input_size=1,
                 hidden_size=32,
                 output_size=2):

        super(RecurrentModel, self).__init__()
        self.tensorboard_writer = tensorboard_writer
        self.input_size = input_size
        self.hidden_size = hidden_size
        self.output_size = output_size

        self.core = self._create_core(core_str=core_str, core_kwargs=core_kwargs)
        self.core_hidden = None
        self.linear = nn.Linear(
            in_features=hidden_size,
            out_features=output_size,
            bias=True)
        self.softmax = nn.Softmax(dim=-1)

        # converts all weights into doubles i.e. float64
        # this prevents PyTorch from breaking when multiplying float32 * flaot64
        self.double()

        # TODO figure out why writing the model to tensorboard doesn't work
        # dummy_input = torch.zeros(size=(10, 1, 1), dtype=torch.double)
        # tensorboard_writer.add_graph(
        #     model=self,
        #     input_to_model=dict(stimulus=dummy_input))

    def _create_core(self, core_str, core_kwargs):
        if core_str == 'lstm':
            core_constructor = nn.LSTM
        elif core_str == 'rnn':
            core_constructor = nn.RNN
        elif core_str == 'gru':
            core_constructor = nn.GRU
        else:
            raise ValueError('Unknown core string')

        core = core_constructor(
            input_size=self.input_size,
            hidden_size=self.hidden_size,
            batch_first=True,
            **core_kwargs)
        return core

    def forward(self, model_input):

        if self.core_hidden is None:
            core_output, self.core_hidden = self.core(
                model_input['stimulus'])
        else:
            core_output, self.core_hidden = self.core(
                model_input['stimulus'],
                self.core_hidden)

        linear_output = self.linear(core_output)

        softmax_output = self.softmax(linear_output)

        forward_output = dict(
            core_output=core_output,
            core_hidden=self.core_hidden,
            linear_output=linear_output,
            softmax_output=softmax_output)

        return forward_output

    def reset_core_hidden(self):
        self.core_hidden = None
</code></pre>
<p>I then construct and save the model:</p>
<pre><code class="lang-auto">    tensorboard_writer = SummaryWriter()

    model = RecurrentModel(
        core_str='rnn',
        core_kwargs={},
        tensorboard_writer=tensorboard_writer)

    torch.save(
        obj=model,
        f=os.path.join(tensorboard_writer.get_logdir(), 'model.ckpt')
    )

</code></pre>

ptrblck: <p>Are you importing <code>dill</code> or any other serialization library in your script?</p>

RylanSchaeffer: <p>None. Someone helped me identify the problem when I opened an issue. Turns out the problem was</p>
<p><code>self.tensorboard_writer = tensorboard_writer</code></p>
<p>Apparently, file handles can’t typically serialized.</p>
<aside class="onebox githubissue">
  <header class="source">
      <a href="https://github.com/pytorch/pytorch/issues/32046" target="_blank" rel="nofollow noopener">github.com/pytorch/pytorch</a>
  </header>
  <article class="onebox-body">
    <div class="github-row">
  <div class="github-icon-container" title="Issue">
	  <svg width="60" height="60" class="github-icon" viewbox="0 0 14 16" aria-hidden="true"><path d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg>
  </div>

  <div class="github-info-container">
    <h4>
      <a href="https://github.com/pytorch/pytorch/issues/32046" target="_blank" rel="nofollow noopener">torch.save causes TypeError: can't pickle SwigPyObject objects</a>
    </h4>

    <div class="github-info">
      <div class="date">
        opened <span class="discourse-local-date" data-format="ll" data-date="2020-01-10" data-time="16:46:10" data-timezone="UTC">04:46PM - 10 Jan 20 UTC</span>
      </div>

        <div class="date">
          closed <span class="discourse-local-date" data-format="ll" data-date="2020-01-10" data-time="18:34:25" data-timezone="UTC">06:34PM - 10 Jan 20 UTC</span>
        </div>

      <div class="user">
        <a href="https://github.com/RylanSchaeffer" target="_blank" rel="nofollow noopener">
          <img alt="RylanSchaeffer" src="https://avatars3.githubusercontent.com/u/8942987?v=4" class="onebox-avatar-inline" width="20" height="20">
          RylanSchaeffer
        </a>
      </div>
    </div>
  </div>
</div>

<div class="github-row">
  <p class="github-content">🐛 Bug
I create a simple class that inherits from nn.Module. When I try to save an instance of this class, I...</p>
</div>

<div class="labels">
</div>

  </article>
  <div class="onebox-metadata">
    
    
  </div>
  <div style="clear: both"></div>
</aside>