Shortcuts

Quickstart

Packaging a model for torch::deploy

torch::deploy can load and run Python models that are packaged with torch.package. You can find torch.package’s documentation here.

For now, let’s create a simple model that we can load and run in torch::deploy.

import torchvision
from torch.package import PackageExporter

# Instantiate some model
model = torchvision.models.resnet.resnet18()

# Package and export it.
with PackageExporter("my_package.pt") as e:
    e.intern("torchvision.**")
    e.extern("numpy.**")
    e.extern("sys")
    e.extern("PIL.*")
    e.extern("typing_extensions")
    e.save_pickle("model", "model.pkl", model)

Note that since “numpy”, “sys”, “PIL” were marked as “extern”, torch.package will look for these dependencies on the system that loads this package. They will not be packaged with the model.

Now, there should be a file named my_package.pt in your working directory.

Load the model in C++

#include <multipy/runtime/deploy.h>
#include <multipy/runtime/path_environment.h>
#include <torch/script.h>
#include <torch/torch.h>

#include <iostream>
#include <memory>

int main(int argc, const char* argv[]) {
  if (argc != 2) {
    std::cerr << "usage: example-app <path-to-exported-script-module>\n";
    return -1;
  }

  // Start an interpreter manager governing 4 embedded interpreters.
  torch::deploy::InterpreterManager manager(4);
  torch::deploy::ReplicatedObj model;
  try {
    // Load the model from the multipy.package.
    torch::deploy::Package package = manager.loadPackage(argv[1]);
    model = package.loadPickle("model", "model.pkl");
  } catch (const c10::Error& e) {
    std::cerr << "error loading the model\n";
    std::cerr << e.msg();
    return -1;
  }

  // Create a vector of inputs.
  std::vector<torch::jit::IValue> inputs;
  inputs.push_back(torch::ones({1, 3, 224, 224}));

  // Execute the model and turn its output into a tensor.
  at::Tensor output = model(inputs).toTensor();
  std::cout << output.slice(/*dim=*/1, /*start=*/0, /*end=*/5) << '\n';

  std::cout << "ok\n";
}

This small program introduces many of the core concepts of torch::deploy.

An InterpreterManager abstracts over a collection of independent Python interpreters, allowing you to load balance across them when running your code.

Using the InterpreterManager::loadPackage method, you can load a torch.package from disk and make it available to all interpreters.

Package::loadPickle allows you to retrieve specific Python objects from the package, like the ResNet model we saved earlier.

Finally, the model itself is a ReplicatedObj. This is an abstract handle to an object that is replicated across multiple interpreters. When you interact with a ReplicatedObj (for example, by calling forward), it will select an free interpreter to execute that interaction.

Build and execute the C++ example

Assuming the above C++ program was stored in a file called example-app.cpp, a minimal CMakeLists.txt file would look like:

cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
project(multipy_tutorial)

set(MULTIPY_PATH ".." CACHE PATH "The repo where multipy is built or the PYTHONPATH")

# include the multipy utils to help link against
include(${MULTIPY_PATH}/multipy/runtime/utils.cmake)

# add headers from multipy
include_directories(${MULTIPY_PATH})

# link the multipy prebuilt binary
add_library(multipy_internal STATIC IMPORTED)
set_target_properties(multipy_internal
    PROPERTIES
    IMPORTED_LOCATION
    ${MULTIPY_PATH}/multipy/runtime/build/libtorch_deploy.a)
caffe2_interface_library(multipy_internal multipy)

# build our examples
add_executable(quickstart quickstart/quickstart.cpp)
target_link_libraries(quickstart PUBLIC "-Wl,--no-as-needed -rdynamic" dl pthread util multipy c10 torch_cpu)

The -rdynamic and --no-as-needed flags are needed when linking to the executable to ensure that symbols are exported to the dynamic table, making them accessible to the torch::deploy interpreters (which are dynamically loaded).

The last step is configuring and building the project. Assuming that our code directory is laid out like this:

example-app/
    CMakeLists.txt
    quickstart.cpp

We can now run the following commands to build the application from within the example-app/ folder:

cmake -S . -B build -DMULTIPY_PATH="/home/user/repos/multipy" # the parent directory of multipy (i.e. the git repo)
cmake --build build --config Release -j

Now we can run our app:

./example-app /path/to/my_package.pt

Docs

Access comprehensive developer documentation for PyTorch

View Docs

Tutorials

Get in-depth tutorials for beginners and advanced developers

View Tutorials

Resources

Find development resources and get your questions answered

View Resources