跳转到主要内容

torch::deploy (multipy) 是一个 C++ 库,通过使用独立的 Python 解释器来避免 GIL,使得在生产环境中运行 eager PyTorch 模型更加容易。

项目描述

License Runtime Tests

torch::deploy (MultiPy)

torch::deploy (MultiPy for non-PyTorch use cases) 是一个 C++ 库,允许您在不修改模型以支持跟踪的情况下,在生产环境中运行 eager 模式 PyTorch 模型。torch::deploy 提供了一种方式,在单个进程中使用多个独立的 Python 解释器来运行,而不需要共享的全局解释器锁 (GIL)。有关 torch::deploy 内部工作方式的更多信息,请参阅相关的 arXiv 论文

要了解如何使用 torch::deploy,请参阅 安装示例

需求

  • PyTorch 1.13+ 或 PyTorch 夜间版本
  • Linux (基于 ELF)
    • x86_64 (测试版)
    • arm64/aarch64 (原型)

ℹ️ torch::deploy 已准备好在生产环境中使用,但目前处于测试版,可能存在一些需要持续改进的粗糙边缘。我们始终欢迎您提供反馈和可能的应用场景。请随时联系我们!

安装

通过 Docker 构建

通过 Docker 构建和安装解释器依赖项是最简单的方法。

git clone --recurse-submodules https://github.com/pytorch/multipy.git
cd multipy
export DOCKER_BUILDKIT=1
docker build -t multipy .

构建的工件位于 multipy/runtime/build

运行测试

docker run --rm multipy multipy/runtime/build/test_deploy

通过 pip install 安装

我们支持使用 pip install 安装 Python 模块和运行时库,但前提是您必须先手动安装 C++ 依赖项。这相当于一个单命令的源构建,本质上是一个围绕 python setup.py develop 的包装器,一旦所有依赖项都已安装。

首先,应该克隆 multipy 仓库

git clone --recurse-submodules https://github.com/pytorch/multipy.git
cd multipy

# (optional) if using existing checkout
git submodule sync && git submodule update --init --recursive

安装系统依赖项

运行时系统依赖项在 build-requirements.txt 中指定。要在基于 Debian 的系统上安装它们,可以运行

sudo apt update
xargs sudo apt install -y -qq --no-install-recommends <build-requirements.txt

Python 环境设置

我们支持使用 condapyenv+virtualenv 创建隔离环境以进行构建和运行。由于 multipy 需要一个位置无关的 Python 版本来启动解释器,对于 conda 环境,我们使用来自 conda-forge 的预构建 libpython-static=3.x 库来在构建时链接,而对于 virtualenv/pyenv,我们通过编译带有 -fPIC 的 Python 来创建可链接库。

注意 我们支持 multipy 的 Python 版本 3.7 到 3.10;请注意,对于 conda 环境,从 3.8 开始提供了 libpython-static 库。对于 virtualenv/pyenv,可以使用 3.7 到 3.10 之间的任何版本,因为显式构建了 PIC 库。

点击展开

安装 conda 的示例命令

curl -fsSL -v -o ~/miniconda.sh -O  https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh  && \
chmod +x ~/miniconda.sh && \
~/miniconda.sh -b -p /opt/conda && \
rm ~/miniconda.sh

Virtualenv / pyenv 可以按照以下方式安装

pip3 install virtualenv
git clone https://github.com/pyenv/pyenv.git ~/.pyenv

安装 python、pytorch 和相关依赖项

Multipy 需要最新的 Pytorch 版本来成功运行模型,我们建议获取 Pytorch 的最新 nightlies 版本,如果需要,还可以获取 cuda。

conda 环境中,我们会做以下操作
conda create -n newenv
conda activate newenv
conda install python=3.8
conda install -c conda-forge libpython-static=3.8

# cuda
conda install pytorch torchvision torchaudio cudatoolkit=11.3 -c pytorch-nightly

# cpu only
conda install pytorch torchvision torchaudio cpuonly -c pytorch-nightly
对于 pyenv / virtualenv 设置,可以这样做
export CFLAGS="-fPIC -g"
~/.pyenv/bin/pyenv install --force 3.8.6
virtualenv -p ~/.pyenv/versions/3.8.6/bin/python3 ~/venvs/multipy
source ~/venvs/multipy/bin/activate
pip install -r dev-requirements.txt

# cuda
pip3 install --pre torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/nightly/cu113

# cpu only
pip3 install --pre torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/nightly/cpu

运行 pip install

一旦所有依赖项都成功安装,最重要的是包括 Python 的 PIC 库和 Pytorch 的最新 nightly 版本,我们可以在 condavirtualenv 中运行以下命令,安装 Python 模块和运行时/解释器库

# from base multipy directory
pip install -e .

C++ 二进制文件应位于 /opt/dist

或者,可以按照以下方式仅安装 Python 模块,而无需调用 cmake

pip install  -e . --install-option="--cmakeoff"

注意 截至 2022 年 10 月 11 日,从 conda-forge 下载的预构建静态 fPIC 版本的 Python 在某些系统上(例如 Centos 8)可能会出现链接问题(例如,链接错误 libpython_multipy.a: error adding symbols: File format not recognized)。这似乎是 binutils 的问题,而 https://wiki.gentoo.org/wiki/Project:Toolchain/Binutils_2.32_upgrade_notes/elfutils_0.175:_unable_to_initialize_decompress_status_for_section_.debug_info 中的步骤可以有所帮助。或者,用户可以选择上述的 virtualenv/pyenv 流程。

开发

从源代码手动构建 multipy::runtime

上述的 dockerpip install 选项都是围绕 multipy 运行时的 cmake 构建包装器。对于开发目的,通常需要单独调用 cmake

请参阅安装部分,了解如何正确设置 Python 环境。

# checkout repo
git clone --recurse-submodules https://github.com/pytorch/multipy.git
cd multipy

# (optional) if using existing checkout
git submodule sync && git submodule update --init --recursive

cd multipy
# install python parts of `torch::deploy` in multipy/multipy/utils
pip install -e . --install-option="--cmakeoff"

cd multipy/runtime

# configure runtime to build/
cmake -S . -B build
# if you need to override the ABI setting you can pass
cmake -S . -B build -D_GLIBCXX_USE_CXX11_ABI=<0/1>

# compile the files in build/
cmake --build build --config Release -j

运行 multipy::runtime 的单元测试

我们首先需要生成必要的示例。首先确保您的Python环境已安装torch。之后,一旦构建了multipy::runtime,请运行以下命令(对于上面的dockerpip,这些命令会自动执行)

cd multipy/multipy/runtime
python example/generate_examples.py
cd build
./test_deploy

示例

请参阅示例目录以获取完整示例。

multipy::runtime打包模型

multipy::runtime可以加载并运行与torch.package打包的Python模型。您可以在torch.package文档中了解更多信息。

现在,让我们创建一个简单的模型,我们可以在multipy::runtime中加载并运行。

from torch.package import PackageExporter
import torchvision

# 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)

注意,由于“numpy”、“sys”、“PIL”被标记为“extern”,torch.package将在加载此包的系统上查找这些依赖项。它们不会与模型一起打包。

现在,您的工作目录中应该有一个名为my_package.pt的文件。


在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.
    std::shared_ptr<multipy::runtime::Environment> env =
        std::make_shared<multipy::runtime::PathEnvironment>(
            std::getenv("PATH_TO_EXTERN_PYTHON_PACKAGES") // Ensure to set this environment variable (e.g. /home/user/anaconda3/envs/multipy-example/lib/python3.8/site-packages)
        );
    multipy::runtime::InterpreterManager manager(4, env);

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

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

这个小程序介绍了multipy::runtime的许多核心概念。

InterpreterManager封装了一组独立的Python解释器,允许您在运行代码时在这些解释器之间进行负载均衡。

PathEnvironment允许您指定系统上Python包的位置,这些包对于您的模型来说是外部但必要的。

使用InterpreterManager::loadPackage方法,您可以从磁盘加载一个multipy.package并将其提供给所有解释器。

Package::loadPickle允许您从包中检索特定的Python对象,例如我们之前保存的ResNet模型。

最后,模型本身是一个ReplicatedObj。这是对多个解释器上复制的对象的抽象引用。当您与ReplicatedObj(例如,通过调用forward)交互时,它将选择一个空闲的解释器来执行该交互。


构建和执行C++示例

假设上述C++程序存储在一个名为example-app.cpp的文件中,一个最小的CMakeLists.txt文件可能如下所示

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)

add_executable(example-app example-app.cpp)
target_link_libraries(example-app PUBLIC "-Wl,--no-as-needed -rdynamic" dl pthread util multipy c10 torch_cpu)

目前,必须将multipy::runtime作为静态库构建。为了正确链接到静态库,使用caffe2_interface_library实用程序来适当地设置和取消设置--whole-archive标志。

此外,在链接到可执行文件时需要使用-rdynamic标志,以确保符号被导出到动态表,使它们可供部署解释器(这些解释器是动态加载的)访问。

更新LIBRARY_PATH和LD_LIBRARY_PATH

为了定位PyTorch提供的依赖项(例如libshm),我们需要更新LIBRARY_PATHLD_LIBRARY_PATH环境变量,以包含PyTorch C++库的路径。如果您使用pip或conda安装了PyTorch,此路径通常位于site-packages。下面提供了一个示例。

export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/home/user/anaconda3/envs/multipy-example/lib/python3.8/site-packages/torch/lib"
export LIBRARY_PATH="$LIBRARY_PATH:/home/user/anaconda3/envs/multipy-example/lib/python3.8/site-packages/torch/lib"

最后一步是配置和构建项目。假设我们的代码目录布局如下

example-app/
    CMakeLists.txt
    example-app.cpp

现在,我们可以在example-app/文件夹中运行以下命令来从该项目构建应用程序

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

现在我们可以运行我们的应用程序

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

贡献

我们欢迎PR!请参阅CONTRIBUTING文件。

许可证

MultiPy遵循BSD许可,如LICENSE文件中所示。

法律

使用条款 隐私政策

版权(c)Meta Platforms,Inc.及其附属公司。保留所有权利。

项目详情


下载文件

下载您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源分发

torchdeploy-0.1.0.tar.gz (230.5 kB 查看哈希值)

上传时间

支持