torch::deploy (multipy) 是一个 C++ 库,通过使用独立的 Python 解释器来避免 GIL,使得在生产环境中运行 eager PyTorch 模型更加容易。
项目描述
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 环境设置
我们支持使用 conda
和 pyenv
+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 版本,我们可以在 conda
或 virtualenv
中运行以下命令,安装 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
上述的 docker
和 pip 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
,请运行以下命令(对于上面的docker
和pip
,这些命令会自动执行)
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_PATH
和LD_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的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | f22b7cff346e5fb29fd88c8057dec1241287471cf24e6ecd851b5eb2ad775fc9 |
|
MD5 | 90767425304667c79c450f23e529a575 |
|
BLAKE2b-256 | fe51f773d84f100c9f544d3d659908facd0ef4ab6e2a8ddf42ec67f444754ded |