Use a zip archive as our container format (#14521)
authorZachary DeVito <zdevito@fb.com>
Sat, 1 Dec 2018 03:15:09 +0000 (19:15 -0800)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Sat, 1 Dec 2018 03:19:29 +0000 (19:19 -0800)
commit170ff7764f7ab6a5283d0d00853d01971b14079b
tree6ed5b6f13d0e73ceb97d6a143b10eba7c1f2988f
parent1c21dc6e169feb199ba0d02cbfcc6fd9bcb90512
Use a zip archive as our container format (#14521)

Summary:
After consulting with Owen, who pointed out the existence of the miniz library, I decided to take one last shot at using zip as our container format.
miniz makes this surprisingly feasible and I think the benefits of using zip are large enough that we should do it.

This replaces our custom container format with a zip archive, preserving all of the
desirable features of our custom format, such as append-oriented writing, and
mmap'able tensor data while adding a bunch of debugging advantages:

1. You can unzip and explore the container to debug what is going on with a model.
2. You can edit the model using a text editor (e.g. change the definition of a method,
   or editing the json-serialized meta-data), re-zip the file use OSX's native 'Compress'
   option, and re-load the result into pytorch. Note: this enables you to, e.g., print-debug
   serialized models.
3. We can easily enable features like compression in the future.
4. Stock python , without pytorch installed, and other programming languages
   can reasonably consume this format,using json  and zipfile packages, which enables
   people to build tools like visualizers without those visualizers depending on pytorch.
   This will be especially useful if you want to, for instance, write a visualizer in javascript.

Notes:

*  This add miniz (https://github.com/richgel999/miniz) as a dependency. miniz is a self-contained
   library for reading/writing zipfiles that unlike other zip libraries also includes libz
   compatible compress/decompress support. It is a single header and a single C file without
   any other dependencies. Note that the instructions for miniz explicitly state:

   > Please use the files from the releases page in your projects. Do not use the git checkout directly!

   So we have checked in the 'release' source. Miniz supports zip64, and its API is amenable
   to doing zip-align style things to align data.

*  Removes 'size' from RecordRef. This allows you to edit files in the zip archive without
   editing the meta-data file. Very important if you want to print-debug serialized models.

*  PyTorchStreamReader/PyTorchStreamWriter keep mostly the same API (though keys become strings)
   However, their implementation is completely swapped out to use miniz.

*  Code exists to check for the old magic number to give a decent warning to our preview users
   after we change the format.

*  Container version information is now put in a stand-alone 'version' file in the archive
   and serves a similar purpose to the other container version info.

*  All files in the zip archive start at 64-byte boundaries, using an approach similar to
   zip-align. Tests check that this property remains true. While the writer does this,
   the reader doesn't depend on it, allowing user-created archives that can use compression,
   and do not have to align data.

*  Added test to check for > 4GB files and archives. Disabled by default because it takes
   almost 2 minutes to run.

*  torchscript files are now optional: if a submodule does not have methods, it will
   not be written.
Pull Request resolved: https://github.com/pytorch/pytorch/pull/14521

Reviewed By: jamesr66a

Differential Revision: D13252945

Pulled By: zdevito

fbshipit-source-id: 01209294c0f6543d0fd716f85a38532249c52f8c
22 files changed:
caffe2/proto/torch.proto
caffe2/serialize/CMakeLists.txt
caffe2/serialize/inline_container.cc [new file with mode: 0644]
caffe2/serialize/inline_container.h
caffe2/serialize/inline_container_test.cc
test/test_jit.py
third_party/miniz-2.0.8/ChangeLog.md [new file with mode: 0755]
third_party/miniz-2.0.8/LICENSE [new file with mode: 0755]
third_party/miniz-2.0.8/examples/example1.c [new file with mode: 0755]
third_party/miniz-2.0.8/examples/example2.c [new file with mode: 0755]
third_party/miniz-2.0.8/examples/example3.c [new file with mode: 0755]
third_party/miniz-2.0.8/examples/example4.c [new file with mode: 0755]
third_party/miniz-2.0.8/examples/example5.c [new file with mode: 0755]
third_party/miniz-2.0.8/examples/example6.c [new file with mode: 0755]
third_party/miniz-2.0.8/miniz.c [new file with mode: 0755]
third_party/miniz-2.0.8/miniz.h [new file with mode: 0755]
third_party/miniz-2.0.8/readme.md [new file with mode: 0755]
torch/CMakeLists.txt
torch/csrc/jit/export.cpp
torch/csrc/jit/import.cpp
torch/csrc/jit/import_method.h
torch/csrc/jit/init.cpp