Is torch::load able to load the bytestring saved in Python (getting file not found: archive/constants.pkl error)?

Hello everyone,
I have a module in Python that converts a pytorch tensor into a bytestring and then serialize it using protobuf.
I then try to load it in C++ using libtorch’s torch::load like this :

torch::Tensor deserialize_tensor(std::string input)
{
    torch::Tensor tensor;
    std::stringstream stream(input);
    torch::load(tensor, stream);
    return tensor;
}
//use protobuf to load the vector
std::vector<std::tuple<std::string, torch::Tensor>> embeddings;
libtorch::EmbeddingVector vec;
std::ifstream stream(file_path, std::ios::in | std::ios::binary);
if (!vec.ParseFromIstream(&stream))
{
    cout << "Failed to parse embedding.";
    return embeddings;
}

for (size_t i = 0; i < vec.row_size(); i++)
{
    auto tuple = vec.row(i);
    std::string key = tuple.key();
    auto tensor =  deserialize_tensor(tuple.tensor());
    //...    
}

and this is the snippet that I use to deserialize the tensors. this works just fine for C++. But it fails with an exception message when I try to load a string that was created in Python.
This is the exception I get when I try to do this :

[enforce fail at ..\..\caffe2\serialize\inline_container.cc:209] . file not found: archive/constants.pkl
00007FFD13E87BC800007FFD13E87A30 c10.dll!c10::MessageLogger::~MessageLogger [<unknown file> @ <unknown line number>]
00007FFD13E880B300007FFD13E88080 c10.dll!c10::ThrowEnforceNotMet [<unknown file> @ <unknown line number>]
00007FFCF4E51F8C00007FFCF4E51EA0 torch_cpu.dll!caffe2::serialize::PyTorchStreamReader::getRecordID [<unknown file> @ <unknown line number>]
00007FFCF4E51DA600007FFCF4E51D70 torch_cpu.dll!caffe2::serialize::PyTorchStreamReader::getRecord [<unknown file> @ <unknown line number>]
00007FFCF5DB5F7D00007FFCF5DB5EB0 torch_cpu.dll!torch::jit::readArchiveAndTensors [<unknown file> @ <unknown line number>]
00007FFCF5DB5E7F00007FFCF5DB4A00 torch_cpu.dll!torch::jit::load [<unknown file> @ <unknown line number>]
00007FFCF5DB3BC400007FFCF5DA3D50 torch_cpu.dll!torch::jit::hasGradientInfoForSchema [<unknown file> @ <unknown line number>]
00007FFCF5DB4BB300007FFCF5DB4A00 torch_cpu.dll!torch::jit::load [<unknown file> @ <unknown line number>]
00007FFCF5DB495B00007FFCF5DB48E0 torch_cpu.dll!torch::jit::load [<unknown file> @ <unknown line number>]
00007FFCF5FBEF5C00007FFCF5FBEF20 torch_cpu.dll!torch::serialize::InputArchive::load_from [<unknown file> @ <unknown line number>]
00007FFD171EE48B00007FFD171EE2B0 FV.dll!deserialize_tensor [D:\Codes\fac_ver\cpp\port\LibtorchPort\Dependencies\include\Utility.h @ 1014]
00007FFD171F311100007FFD171F2E00 FV.dll!FVImpl::ReadEmbeddings [D:\Codes\fac_ver\cpp\port\LibtorchPort\Dependencies\include\FV\FV.cpp @ 729]
00007FFD171F35A700007FFD171F3380 FV.dll!FVImpl::LoadEmbeddings [D:\Codes\fac_ver\cpp\port\LibtorchPort\Dependencies\include\FV\FV.cpp @ 752]
00007FFD171EECCA00007FFD171EE5E0 FV.dll!FVImpl::FVImpl [D:\Codes\fac_ver\cpp\port\LibtorchPort\Dependencies\include\FV\FV.cpp @ 345]
00007FFD171FC93C00007FFD171FC8F0 FV.dll!FV::FV [D:\Codes\fac_ver\cpp\port\LibtorchPort\Dependencies\include\FV\FV.cpp @ 1749]
00007FF66F13BA6A00007FF66F13B5F0 FV_Test.exe!test_qmodel [D:\Codes\fac_ver\cpp\port\LibtorchPort\FV_Test\FV_Test.cpp @ 847]
00007FF66F13BFA500007FF66F13BDA0 FV_Test.exe!main [D:\Codes\fac_ver\cpp\port\LibtorchPort\FV_Test\FV_Test.cpp @ 937]
00007FF66F1CF58400007FF66F1CF478 FV_Test.exe!__scrt_common_main_seh [D:\agent\_work\9\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 288]
00007FFD82187BD400007FFD82187BC0 KERNEL32.DLL!BaseThreadInitThunk [<unknown file> @ <unknown line number>]
00007FFD8288CE5100007FFD8288CE30 ntdll.dll!RtlUserThreadStart [<unknown file> @ <unknown line number>]

Note:
this is how I save the bytestring in python, if its of any help:

# my protobuf module thats used both in c++ and 
# python to serialize and deserialize tensors.
import io
import torch 
from Manager import TorchSerializer_pb2 as ts

rec = ts.EmbeddingVector()

features = self.model(tensor_img.unsqueeze(0)).cpu().detach()
buffer = io.BytesIO()
torch.save(features, buffer)
tpl = rec.row.add()
tpl.key = key
buffer.seek(0)
tpl.tensor = buffer.read()
#...

Whats going on?
Any help is greatly apprecaited

I think this means you’re not having the right format.
Note that PyTorch 1.6 changed the default serialization format of Python’s torch.save, which may bring a better experience moving between Python and C++.

Best regards

Thomas

1 Like

Thanks a lot really apprecaite it. but I’m using 1.6 both on Python and C++ side. and the process is the same Could you kindly elaborate a bit more on the not right format bit ?

@Shisho_Sama I am facing the exact same issue while loading a model saved using Python using a Java library. Were you able to find a solution?

If my memory serves me right, I went the prototype route! you save your model/object as a protobuf object and then load it using protobuf in the other language like Java.
In your Python code, export your model as a protobuf object, and in Java simply read it and do as you wish