我不会用 Triton 系列:构建 Triton Server 过程记录
前言
这段时间一直在学习如何使用 Triton,期间也是一直在尝试构建 Triton Inference Server。这构建的过程感觉特别的痛苦,一方面是网络问题导致的构建速度慢、构建失败的问题,另一方面是 Triton 提供的构建脚本在我这儿并不有效,需要自己想一个办法。
按照官方的文档,我们有两种构建的方式。一种是在 Docker 内构建,另一种是在裸机上构建。
回想起来,这段时间构建的过程似乎没有做什么事情,就是在重复网络中断、构建失败、重试的这样一个过程。所以是痛苦的,因为时间是最宝贵的东西。
我尝试了如下四种方法来构建。
- 官方推荐的 docker 内构建,使用 build.py 构建;失败,因为 apt 安装依赖失败了(hash mismatch
- 裸机构建;(忘了有没有尝试,需要的依赖 TensorRT 都没有装,应该不行
- 进入 docker 中,手动安装依赖,然后假装裸机构建。(成功,只运行命令,可以;指定了模型仓库,core dump
- 将 build.py 执行的 CMake 命令导出来,裸机构建(试了,还没成功
上面的第三个方法是可行的,因为 core dump 的原因是我没有注意看 Triton 的默认配置导致的,我需要去做好配置才可以不会 core dump。其实除了第一个方法,其他几个方法应该都可以。
下面将会展开为构建和调试两个部分。
构建
构建的命令如下,按照下面的命令逐个执行就可以了。基本上就是下载代码、拉镜像、进入镜像、安装依赖、设置代理、调用脚本开始构建。
如果你需要在 docker 内构建 backend,那么你还要在 docker 里面安装一个 docker 🤣(即使你指定了 no-container-build 选项,这个构建脚本构建 backend 的时候还是要下载 docker。理由很简单,因为 pytorch 的依赖,当前的 docker 里没有。
git clone https://github.com/triton-inference-server/server
git checkout r21.10
docker pull nvcr.io/nvidia/tritonserver:21.10-py3
docker run --gpus=all --network=host --shm-size=2g -v/home/percent1/triton-build:/code -it nvcr.io/nvidia/tritonserver:21.10-py3 # 进入 docker
pip install docker
apt update
apt install libssl-dev libonig-dev zlib1g-dev libboost-all-dev libre2-dev libb64-dev rapidjson-dev -y
wget -O cmake.tar.gz https://github.com/Kitware/CMake/releases/download/v3.21.4/cmake-3.21.4-linux-x86_64.tar.gz
tar -zxvf cmake.tar.gz
export PATH=/code/cmake-3.21.4-linux-x86_64/bin/:$PATH
export http_proxy=socks5://172.17.0.1:1080
export https_proxy=socks5://172.17.0.1:1080
git config --global https.proxy http://172.17.0.1:1080
git config --global https.proxy https://172.17.0.1:1080
./build.py --cmake-dir=/code/server/build --build-dir=/tmp/citritonbuild --enable-logging --enable-stats --enable-tracing --enable-metrics --enable-gpu-metrics --enable-gpu --endpoint=http --endpoint=grpc --repo-tag=common:r21.10 --repo-tag=core:r21.10 --repo-tag=backend:r21.10 --repo-tag=thirdparty:r21.10 --backend=ensemble --no-container-build --build-type=Debug
core dump 的原因
运行 tritonserver 的结果:
# /tmp/citritonbuild/opt/tritonserver/bin/tritonserver --model-repository=/tmp/models
I1110 05:29:40.618876 19418 metrics.cc:298] Collecting metrics for GPU 0: GeForce RTX 2080 Ti
I1110 05:29:40.619735 19418 metrics.cc:298] Collecting metrics for GPU 1: GeForce RTX 2080 Ti
I1110 05:29:40.619904 19418 metrics.cc:298] Collecting metrics for GPU 2: GeForce RTX 2080 Ti
I1110 05:29:40.620003 19418 metrics.cc:298] Collecting metrics for GPU 3: GeForce RTX 2080 Ti
I1110 05:29:40.913877 19418 libtorch.cc:1092] TRITONBACKEND_Initialize: pytorch
I1110 05:29:40.913931 19418 libtorch.cc:1102] Triton TRITONBACKEND API version: 1.6
I1110 05:29:40.913945 19418 libtorch.cc:1108] 'pytorch' TRITONBACKEND API version: 1.6
Segmentation fault (core dumped)
仔细思考,就会发觉奇怪,为什么启动的时候会用到 libtorch 的东西呢,我明明没有指定 torch 相关的模型,也没有指定相关的 backend。当时没有发现问题的来源,后来是在看启动选项的时候发现的,原来是 --backend-directory 选项的问题:
--backend-directory <string>
The global directory searched for backend shared libraries.
Default is '/opt/tritonserver/backends'.
--repoagent-directory <string>
The global directory searched for repository agent shared
libraries. Default is '/opt/tritonserver/repoagents'.
因为我没有指定 backends 的目录,所以会用 docker 自带的 backends。这其实也暴露了 Triton 的一个问题,backend 并非完全独立于 tritonserver 的,不然用了 torch backend 就启动不了呢?backend 的设计应该是完全解耦于 tritonserver 的,不过可能是因为为了扩展一些功能,所以才会在 tritonserver 中加入了相关的代码。
调试
安装 ssh,用 root 用户登录到 docker 里面。
apt install ssh
vim /etc/ssh/sshd_config # 修改 port,允许 root 登录
/etc/init.d/ssh restart
passwd # 修改密码,用于登录
ps -e | grep ssh # 有输出则启动成功
apt install gdb
之后用 vscode 打开项目,安装 C++ 插件,然后按 F5,添加 launch.json。我的内容如下所示,之后就可以使用 gdb 进行调试啦。我们需要在 args 里面指定启动参数,指定 backend 目录,指定模型仓库。
{
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) 启动",
"type": "cppdbg",
"request": "launch",
"program": "/tmp/citritonbuild/tritonserver/install/bin/tritonserver",
"args": [
"--backend-directory",
"/opt/tritonserver/backends1/",
"--model-store",
"/code/models/"
],
"stopAtEntry": true,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "为 gdb 启用整齐打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}
好耶!可以开心的调试了。不过仍然没有代码提示,即使在 CMake 构建的选项中加了 compile commands 那个选项也没用... 这个后续在看看。