Convert/import Torch model to PyTorch

@minsukchang With PyTorch you just need to warp your model with nn.DataParallel() to create a DataParallel model. But you cannot deserialize a DPT model saved from Lua.

1 Like

@SelvamArul Ahhhh that makes perfect sense. Thanks a bunch!!

Hi, did you solve it?

I am trying to convert a Torch model with a cudnn backend into a Torch model with an nn backend so that I can load it into PyTorch using load_lua. When I use cudnn.convert and then try to load the model without the CUDA libraries, I get the following error:

/home/gwg3/torch/share/lua/5.1/torch/File.lua:343: unknown Torch class <torch.CudaTensor>
stack traceback:
	[C]: in function 'error'
	/home/gwg3/torch/share/lua/5.1/torch/File.lua:343: in function 'readObject'
	/home/gwg3/torch/share/lua/5.1/torch/File.lua:369: in function 'readObject'
	/home/gwg3/torch/share/lua/5.1/nn/Module.lua:192: in function 'read'
	/home/gwg3/torch/share/lua/5.1/torch/File.lua:351: in function 'readObject'
	/home/gwg3/torch/share/lua/5.1/torch/File.lua:409: in function 'load'
	[string "_RESULT={torch.load('alexnet_pretrained_nn_ba..."]:1: in main chunk
	[C]: in function 'xpcall'
	/home/gwg3/torch/share/lua/5.1/trepl/init.lua:661: in function 'repl'
	/home/gwg3/torch/lib/luarocks/rocks/trepl/scm-1/bin/th:204: in main chunk
	[C]: at 0x004064f0

But if I require cunn and cudnn and then load the model, I do not see any non-nn layers:

nn.Sequential {
  [input -> (1) -> (2) -> output]
  (1): nn.Sequential {
    [input -> (1) -> (2) -> (3) -> (4) -> (5) -> (6) -> (7) -> (8) -> (9) -> (10) -> (11) -> (12) -> (13) -> (14) -> output]
    (1): nn.SpatialConvolution(3 -> 96, 11x11, 4,4, 5,5)
    (2): nn.ReLU
    (3): nn.SpatialMaxPooling(3x3, 2,2, 1,1)
    (4): nn.SpatialCrossMapLRN
    (5): nn.SpatialConvolution(96 -> 256, 5x5, 1,1, 2,2)
    (6): nn.ReLU
    (7): nn.SpatialMaxPooling(3x3, 2,2, 1,1)
    (8): nn.SpatialCrossMapLRN
    (9): nn.SpatialConvolution(256 -> 384, 3x3, 1,1, 1,1)
    (10): nn.ReLU
    (11): nn.SpatialConvolution(384 -> 384, 3x3, 1,1, 1,1)
    (12): nn.ReLU
    (13): nn.SpatialConvolution(384 -> 256, 3x3, 1,1, 1,1)
    (14): nn.ReLU
  }
  (2): nn.Sequential {
    [input -> (1) -> (2) -> (3) -> (4) -> (5) -> output]
    (1): nn.SpatialAdaptiveMaxPooling
    (2): nn.View(-1)
    (3): nn.Linear(9216 -> 4096)
    (4): nn.ReLU
    (5): nn.Dropout(0.500000)
  }
}

Does anyone know what causes this?

when I try to import the following torch model to pytorch,

require 'torch’
require 'nn’
require 'nnx’
require 'optim’
require ‘rnn’

function buildModel_MeanPool_RNN(nFltrs1,nFltrs2,nFltrs3,nPersonsTrain)

local nFilters = {nFltrs1,nFltrs2,nFltrs3}

local filtsize = {5,5,5}
local poolsize = {2,2,2}
local stepSize = {2,2,2}

-- remember this adds padding to ALL SIDES of the image
local padDim = 4

local cnn = nn.Sequential()

local ninputChannels = 5
cnn:add(nn.SpatialZeroPadding(padDim, padDim, padDim, padDim))
cnn:add(nn.SpatialConvolutionMM(ninputChannels, nFilters[1], filtsize[1], filtsize[1], 1, 1))
cnn:add(nn.Tanh())
cnn:add(nn.SpatialMaxPooling(poolsize[1],poolsize[1],stepSize[1],stepSize[1]))

ninputChannels = nFilters[1]
cnn:add(nn.SpatialZeroPadding(padDim, padDim, padDim, padDim))
cnn:add(nn.SpatialConvolutionMM(ninputChannels, nFilters[2], filtsize[2], filtsize[2], 1, 1))
cnn:add(nn.Tanh())
cnn:add(nn.SpatialMaxPooling(poolsize[2],poolsize[2],stepSize[2],stepSize[2]))

ninputChannels = nFilters[2]
cnn:add(nn.SpatialZeroPadding(padDim, padDim, padDim, padDim))
cnn:add(nn.SpatialConvolutionMM(ninputChannels, nFilters[3], filtsize[3], filtsize[3], 1, 1))
cnn:add(nn.Tanh())
cnn:add(nn.SpatialMaxPooling(poolsize[3],poolsize[3],stepSize[3],stepSize[3]))

local nFullyConnected = nFilters[3]*10*8    

cnn:add(nn.Reshape(1,nFullyConnected))
cnn:add(nn.Dropout(0.6))    
cnn:add(nn.Linear(nFullyConnected,128))
-- cnn:cuda()

local h2h = nn.Sequential()
h2h:add(nn.Tanh())
h2h:add(nn.Dropout(0.6))
h2h:add(nn.Linear(128,128))
-- h2h:cuda()

local r1 = nn.Recurrent(
    128,
    cnn,
    h2h,
    nn.Identity(),
    16)

local rnn1 = nn.Sequencer(
    nn.Sequential()
    :add(r1)
    )

Combined_CNN_RNN_1 = nn.Sequential()
Combined_CNN_RNN_1:add(rnn1)
Combined_CNN_RNN_1:add(nn.JoinTable(1))
Combined_CNN_RNN_1:add(nn.Mean(1))

local r2 = nn.Recurrent(
    128,
    cnn:clone('weight','bias','gradWeight','gradBias'),
    h2h:clone('weight','bias','gradWeight','gradBias'),
    nn.Identity(),
    16)

local rnn2 = nn.Sequencer(
    nn.Sequential()
    :add(r2)
    )

Combined_CNN_RNN_2 = nn.Sequential()
Combined_CNN_RNN_2:add(rnn2)
Combined_CNN_RNN_2:add(nn.JoinTable(1))
Combined_CNN_RNN_2:add(nn.Mean(1))

-- Combined_CNN_RNN_2 = Combined_CNN_RNN_1:clone('weight','bias','gradWeight','gradBias')

local mlp2 = nn.ParallelTable()
mlp2:add(Combined_CNN_RNN_1)
mlp2:add(Combined_CNN_RNN_2)
-- mlp2:cuda()

local mlp3 = nn.ConcatTable()
mlp3:add(nn.Identity())
mlp3:add(nn.Identity())
mlp3:add(nn.Identity())
-- mlp3:cuda()

local mlp4 = nn.ParallelTable()
mlp4:add(nn.Identity())
mlp4:add(nn.SelectTable(1))
mlp4:add(nn.SelectTable(2))
-- mlp4:cuda()

-- used to predict the identity of each person
local classifierLayer = nn.Linear(128,nPersonsTrain)

-- identification
local mlp6 = nn.Sequential()
mlp6:add(classifierLayer)
mlp6:add(nn.LogSoftMax())
-- mlp6:cuda()

local mlp7 = nn.Sequential()
mlp7:add(classifierLayer:clone('weight','bias','gradWeight','gradBias'))
mlp7:add(nn.LogSoftMax())
-- mlp7:cuda()

local mlp5 = nn.ParallelTable()
mlp5:add(nn.PairwiseDistance(2))
mlp5:add(mlp6)
mlp5:add(mlp7)
-- mlp5:cuda()

local fullModel = nn.Sequential()
fullModel:add(mlp2)
fullModel:add(mlp3)
fullModel:add(mlp4)
fullModel:add(mlp5)
-- fullModel:cuda()

local crit = nn.SuperCriterion()
crit:add(nn.HingeEmbeddingCriterion(2),1)
crit:add(nn.ClassNLLCriterion(),1)
crit:add(nn.ClassNLLCriterion(),1)

return fullModel, crit, Combined_CNN_RNN_1, cnn

end
fullModel, crit, Combined_CNN_RNN_1, cnn = buildModel_MeanPool_RNN(16,32,32,150)
torch.save(‘Combined_CNN_RNN.t7’,Combined_CNN_RNN_1)

then in pytorch,

import torch
from torch.utils.serialization import load_lua

net = load_lua(‘Combined_CNN_RNN.t7’)

But it is not working:
Traceback (most recent call last):
File “/mnt/68FC8564543F417E/Pytorch/convert_torch_to_pytorch-master/load_torch_net.py”, line 4, in
net = load_lua(‘Combined_CNN_RNN.t7’)
File “/home/chengli/torch-env/local/lib/python2.7/site-packages/torch/utils/serialization/read_lua_file.py”, line 599, in load_lua
return reader.read()
File “/home/chengli/torch-env/local/lib/python2.7/site-packages/torch/utils/serialization/read_lua_file.py”, line 584, in read
return self.read_object()
File “/home/chengli/torch-env/local/lib/python2.7/site-packages/torch/utils/serialization/read_lua_file.py”, line 514, in wrapper
result = fn(self, *args, **kwargs)
File “/home/chengli/torch-env/local/lib/python2.7/site-packages/torch/utils/serialization/read_lua_file.py”, line 537, in read_object
return reader_registry[cls_name](self, version)
File “/home/chengli/torch-env/local/lib/python2.7/site-packages/torch/utils/serialization/read_lua_file.py”, line 242, in read_nn_class
attributes = reader.read()
File “/home/chengli/torch-env/local/lib/python2.7/site-packages/torch/utils/serialization/read_lua_file.py”, line 586, in read
return self.read_table()
File “/home/chengli/torch-env/local/lib/python2.7/site-packages/torch/utils/serialization/read_lua_file.py”, line 514, in wrapper
result = fn(self, *args, **kwargs)
File “/home/chengli/torch-env/local/lib/python2.7/site-packages/torch/utils/serialization/read_lua_file.py”, line 563, in read_table
v = self.read()
File “/home/chengli/torch-env/local/lib/python2.7/site-packages/torch/utils/serialization/read_lua_file.py”, line 586, in read
return self.read_table()
File “/home/chengli/torch-env/local/lib/python2.7/site-packages/torch/utils/serialization/read_lua_file.py”, line 514, in wrapper
result = fn(self, *args, **kwargs)
File “/home/chengli/torch-env/local/lib/python2.7/site-packages/torch/utils/serialization/read_lua_file.py”, line 563, in read_table
v = self.read()
File “/home/chengli/torch-env/local/lib/python2.7/site-packages/torch/utils/serialization/read_lua_file.py”, line 584, in read
return self.read_object()
File “/home/chengli/torch-env/local/lib/python2.7/site-packages/torch/utils/serialization/read_lua_file.py”, line 514, in wrapper
result = fn(self, *args, **kwargs)
File “/home/chengli/torch-env/local/lib/python2.7/site-packages/torch/utils/serialization/read_lua_file.py”, line 543, in read_object
"constructor").format(cls_name))
torch.utils.serialization.read_lua_file.T7ReaderException: don’t know how to deserialize Lua class nn.Sequencer. If you want to ignore this error and load this object as a dict, specify unknown_classes=True in reader’s constructor

what should I do to make it work?

I have a pretrained torch model that looks like this:

 m
{
  parameters : 
	{
	  1 : FloatTensor - size: 64x1x3x3
	  2 : FloatTensor - size: 64
	  3 : FloatTensor - size: 128x64x3x3
	  4 : FloatTensor - size: 128
	  5 : FloatTensor - size: 256x128x3x3
	  6 : FloatTensor - size: 256
	  7 : FloatTensor - size: 256
	  8 : FloatTensor - size: 256
	  9 : FloatTensor - size: 256x256x3x3
	  10 : FloatTensor - size: 256
	  11 : FloatTensor - size: 512x256x3x3
	  12 : FloatTensor - size: 512
	  13 : FloatTensor - size: 512
	  14 : FloatTensor - size: 512
	  15 : FloatTensor - size: 512x512x3x3
	  16 : FloatTensor - size: 512
	  17 : FloatTensor - size: 512x512x2x2
	  18 : FloatTensor - size: 512
	  19 : FloatTensor - size: 512
	  20 : FloatTensor - size: 512
	  21 : FloatTensor - size: 1024x512
	  22 : FloatTensor - size: 1024
	  23 : FloatTensor - size: 1024x256
	  24 : FloatTensor - size: 1024
	  25 : FloatTensor - size: 1024x512
	  26 : FloatTensor - size: 1024
	  27 : FloatTensor - size: 1024x256
	  28 : FloatTensor - size: 1024
	  29 : FloatTensor - size: 256x256
	  30 : FloatTensor - size: 256
	  31 : FloatTensor - size: 256x256
	  32 : FloatTensor - size: 256
	  33 : FloatTensor - size: 1024x256
	  34 : FloatTensor - size: 1024
	  35 : FloatTensor - size: 1024x256
	  36 : FloatTensor - size: 1024
	  37 : FloatTensor - size: 1024x256
	  38 : FloatTensor - size: 1024
	  39 : FloatTensor - size: 1024x256
	  40 : FloatTensor - size: 1024
	  41 : FloatTensor - size: 37x256
	  42 : FloatTensor - size: 37
	  43 : FloatTensor - size: 37x256
	  44 : FloatTensor - size: 37
	}
  bnVars : 
	{
	  1 : FloatTensor - size: 256
	  2 : FloatTensor - size: 256
	  3 : FloatTensor - size: 512
	  4 : FloatTensor - size: 512
	  5 : FloatTensor - size: 512
	  6 : FloatTensor - size: 512
	}
}

I am trying to use the convert_torch script that @clcarwin put up here to convert the model from torch to pytorch. I am new to Torch so I am not aware of a lot of things, but the model I’m trying to convert doesn’t seem to have attributes like gradInput, model etc. Also, @smth said that there is no way to convert the model from nn.legacy* to nn*, so I’m wondering if my model maybe legacy nn, but how do I make sure? And how do I make my model have the missing attributes like other models (is that even possible) ?
Note: when I try type(model).name, it gives me ‘hashable_uniq_dict’, in case that helps

Hi,
I am having a different problem:
I try to load a t7 model with cudnn layers (cudnn.SpatialConvolution) to pytorch, and it works with not issues using lua_load.
However, once I loaded the model, I try to do a forward pass, but the output does not update according to the new input.
There is no error. The forward pass finished, and without updating the result.
The command I use is:
res = model.forward(img_pil.unsqueeze_(0))
BTW, there is no problem in forwarding using torch.
no metter what are the values of img_pil, res is always the same.
Do you have any suggestions how to solve this issue?

I have a model was trained on a GPU in Torch that I would like to test on a CPU in PyTorch. I converted the cunn/cudnn layers to nn layers using this script. I then converted the model from CudaTensors to FloatTensors using model = model:float() in Lua. So far, so good. load_lua worked fine after these steps.

But now when I try to call forward in PyTorch with an autograd Variable instance, I get the following error (discrepancy in bold):

TypeError: FloatSpatialConvolutionMM_updateOutput received an invalid combination of arguments - got (int, Variable, torch.FloatTensor, torch.FloatTensor, torch.FloatTensor, torch.FloatTensor, torch.FloatTensor, int, int, int, int, int, int), but expected (int state, torch.FloatTensor input, torch.FloatTensor output, torch.FloatTensor weight, [torch.FloatTensor bias or None], torch.FloatTensor finput, torch.FloatTensor fgradInput, int kW, int kH, int dW, int dH, int padW, int padH)

I’m confused by this error message, because I would expect a PyTorch model to expect an autograd Variable. What am I doing wrong?

@gwg if you convert a model via load_lua, it doesn’t support Variable as inputs, you have to pass in Tensors as inputs. We basically wrote a replica of Torch’s nn package as PyTorch’s torch.legacy.nn and we use those implementations for loading lua models, rather than pytorch torch.nn package (which takes Variable as inputs)

Hello I am trying to convert torch model to pytorch. However I always find this error
torch.utils.serialization.read_lua_file.T7ReaderException: unknown type id 218103808.
This is the model LINK
Any solution for this one?

@ashkamath I want to do the exact same thing , did you find out how to do it ?
I have saved the parameters in .pth file and trying to load it in torch , but not working , I am a beginner , can you please help !

Thanks in advance .

We getting the following error -

T7ReaderException: don’t know how to deserialize Lua class nn.PixelShuffle. If you want to ignore this error and load this object as a dict, specify unknown_classes=True in reader’s constructor.

Would appreciate your help very much!

1 Like

Hi, to solve the problem about gradInput, see this link.

I have a question of how to use modules from 'legacy.nn.’ in the network composed of "nn." modules?

hello How to solve this issue ? can you explain thanks in advance.

On trying to convert a cpu model from lua-torch (.t7) into pytorch i get the following error using the load_lua function:

/usr/local/lib/python3.6/dist-packages/torch/legacy/nn/SpatialFullConvolution.py in __repr__(self)
    211 
    212         s += ')'
--> 213         if self.bias is None:
    214             s += ' without bias'
    215         return s

AttributeError: 'SpatialFullConvolution' object has no attribute 'bias

How can I resolve this issue?
Please help.

hello, were you able to convert this to pytorch? if yes please reply i am working on this now

Sorry, I’ve been away for a long time. I gave up converting this model.

It seems the answers to this question are now obsolete and no longer work.

Suppose someone has an old pre-trained .t7 model lying around in 2021 and they want to convert it to PyTorch?

The solutions here require an old version of torch (0.4.1), which requires an old version of python (3.7). If you’re on a fairly modern operating system with a default python version > 3.7, you may want to use Docker to create the necessary environment for conversion.

Create a Dockerfile containing the folllowing:

FROM python:3.7

RUN pip install torch==0.4.1 -f https://download.pytorch.org/whl/torch_stable.html
RUN pip install numpy
RUN wget https://raw.githubusercontent.com/clcarwin/convert_torch_to_pytorch/master/convert_torch.py

First, pull down the python 3.7 image:

sudo docker pull python:3.7

Now build a docker container from your Dockerfile

sudo docker build -t torch-t7-to-pytorch:0.0.1 .

Finally, run the conversion in the docker container:

sudo docker run -v /path/to/directory/containing/t7/model:/models torch-t7-to-pytorch:0.0.1 python convert_torch.py -m /models/model_to_convert.t7

The converted model will be written out into the same directory as the model_to_convert.t7 file. You’ll get a .pth and .py file.