编译triton/tensorrtllm_backend Docker镜像
背景:
- 在Triton 23.10发布后,才会内置TensorRT-LLM支持
- 目前Triton最新版是23.09,暂时不支持,所以需要手动编译Docker镜像
- 拉取本项目代码
git clone https://github.com/triton-inference-server/tensorrtllm_backend.git -b release/0.5.0
cd tensorrtllm_backend
- 拉取子模块(目前只依赖TensorRT-LLM) 代码
git submodule update --init --recursive
git lfs install
git lfs pull
- 编译dokcer镜像
DOCKER_BUILDKIT=1 docker build -t triton_trt_llm -f dockerfile/Dockerfile.trt_llm_backend .
DOCKER_BUILDKIT=1 docker build -t triton_trt_llm --build-arg TORCH_INSTALL_TYPE="src_non_cxx11_abi" -f dockerfile/Dockerfile.trt_llm_backend .
- 编译完成后,你将看到有一个名为
triton_trt_llm
的镜像。
编译TensorRT Engine
开启inflight_batching(可选)
- 如果需要支持
inflight_batching
功能,则需要在build阶段加上下面三个参数:
--use_inflight_batching
--paged_kv_cache
--remove_input_padding
- 为啥要开这三个参数?从下面
qwen/build.py
中的这段代码可以看出来,第一个参数依赖后面两个参数,而use_gpt_attention_plugin
在本仓库是默认开启的,所以可以忽略。
if args.use_inflight_batching:
if not args.use_gpt_attention_plugin:
args.use_gpt_attention_plugin = 'float16'
logger.info(
f"Using GPT attention plugin for inflight batching mode. Setting to default '{args.use_gpt_attention_plugin}'"
)
if not args.remove_input_padding:
args.remove_input_padding = True
logger.info(
"Using remove input padding for inflight batching mode.")
if not args.paged_kv_cache:
args.paged_kv_cache = True
logger.info("Using paged KV cache for inflight batching mode.")
- 下面是一个简单示例(以smooth quant int8量化为例):
python3 hf_qwen_convert.py --smoothquant=0.5
python3 build.py \
--use_smooth_quant \
--per_token \
--per_channel \
--use_inflight_batching \
--paged_kv_cache \
--remove_input_padding
部署Triton 服务
- 进入
tensorrtllm_backend
的上一层目录,运行最开始编译好的容器,然后将tensorrtllm_backend
映射到容器里面去
docker run \
-d \
--name triton \
--net host \
--shm-size=2g \
--ulimit memlock=-1 \
--ulimit stack=67108864 \
--gpus all \
-v ${PWD}/tensorrtllm_backend:/tensorrtllm_backend \
triton_trt_llm sleep 8640000
- 进入容器
docker exec -it triton /bin/bash
- 观察映射是否ok,有输出文件,就是ok的
ls /tensorrtllm_backend
- 进入该目录,然后创建一个
triton_model_repo
目录,用于存放待推理的模型
cd /tensorrtllm_backend
mkdir triton_model_repo
- 拷贝一些默认的样例配置到刚刚创建的目录。
cp -r all_models/inflight_batcher_llm/* triton_model_repo/
- 将前面编译的TensorRT-LLM的Engine文件拷贝到Triton里面,可以参考下面的做法
cd /app/tensorrt_llm/examples/qwen/trt_engines/fp16/1-gpu/
cp -r ./* /tensorrtllm_backend/triton_model_repo/tensorrt_llm/1/
- 再把Qwen的tokenizer的文件拷贝给Triton,省事起见,可以将整个
qwen_7b_chat
都拷贝过去
cd /app/tensorrt_llm/examples/qwen/
cp -r qwen_7b_chat /tensorrtllm_backend/triton_model_repo/tensorrt_llm/
- 编写Triton中的预处理配置, 修改
triton_model_repo/preprocessing/config.pbtxt
文件
parameters {
key: "tokenizer_dir"
value: {
string_value: "${tokenizer_dir}"
}
}
parameters {
key: "tokenizer_type"
value: {
string_value: "${tokenizer_type}"
}
}
parameters {
key: "tokenizer_dir"
value: {
string_value: "/tensorrtllm_backend/triton_model_repo/tensorrt_llm/qwen_7b_chat"
}
}
parameters {
key: "tokenizer_type"
value: {
string_value: "auto"
}
}
- 编写Triton中的预处理配置, 修改
triton_model_repo/preprocessing/1/model.py
文件,加一个trust_remote_code=True
,否则会不兼容本地的tokenizer
elif tokenizer_type == 'auto':
self.tokenizer = AutoTokenizer.from_pretrained(tokenizer_dir, padding_side='left')
elif tokenizer_type == 'auto':
self.tokenizer = AutoTokenizer.from_pretrained(
tokenizer_dir,
padding_side='left',
trust_remote_code=True
)
- 改一下max-batch-size,默认是`max_batch_size: 128`改成你之前编译设置的max_batch_size即可,编译的设置max_batch_size=4,所以我这里也设置为4(测试发现最低需要设置为4,后面会讲到)。
- 编写Triton中的trt_llm配置, 修改
triton_model_repo/tensorrt_llm/config.pbtxt
文件
model_transaction_policy {
decoupled: ${decoupled_mode}
}
model_transaction_policy {
decoupled: true
}
parameters: {
key: "gpt_model_path"
value: {
string_value: "${engine_dir}"
}
}
parameters: {
key: "gpt_model_path"
value: {
string_value: "/tensorrtllm_backend/triton_model_repo/tensorrt_llm/1"
}
}
- 默认配置是开启了inflight-batching的,如果要关闭,需要做下面的修改
- 修改前:
parameters: {
key: "gpt_model_type"
value: {
string_value: "inflight_fused_batching"
}
}
parameters: {
key: "gpt_model_type"
value: {
string_value: "V1"
}
}
- 改一下max-batch-size,默认是
max_batch_size: 128
改成你之前编译设置的max_batch_size即可,编译的设置max_batch_size=4,所以我这里也设置为4(测试发现最低需要设置为4,后面会讲到)。
- 编写Triton中的trt_llm配置, 修改
triton_model_repo/postprocessing/config.pbtxt
,基本和修改triton_model_repo/preprocessing/
部分一样,不再重复阐述。 - 安装qwen需要的几个必选依赖
pip install sentencepiece~=0.1.99 tiktoken
- 启动Triton服务
cd /tensorrtllm_backend
python3 scripts/launch_triton_server.py --world_size=1 --model_repo=/tensorrtllm_backend/triton_model_repo
- 启动后发现报错,是tokenizer找不到eos_token,这个之前适配qwen到trt-llm时也遇到过,只需要简单修改一下preprocess/postprocess的model.py即可即可。
self.tokenizer.pad_token = self.tokenizer.eos_token
self.pad_id = self.tokenizer.encode(self.tokenizer.pad_token,
add_special_tokens=False)[0]
gen_config_path = os.path.join(tokenizer_dir, 'generation_config.json')
with open(gen_config_path, 'r') as f:
gen_config = json.load(f)
chat_format = gen_config['chat_format']
if chat_format == "raw":
self.eos_id = gen_config['eos_token_id']
self.pad_id = gen_config['pad_token_id']
elif chat_format == "chatml":
self.pad_id = self.eos_id = self.tokenizer.im_end_id
else:
raise Exception("unkown chat format ", chat_format)
eos_token = self.tokenizer.decode(self.eos_id)
self.tokenizer.eos_token = eos_token
self.tokenizer.pad_token = eos_token
- 再次启动发现还是报错,这次是显存不够。之前明明是可以的,为啥现在不够了呢?经排查发现,默认是max_batch_size>=4,设置成低于4的max_batch_size则不起作用。所以我再重新编译了一下int4 weight only的Engine,并且测试了benchmark下,batch_size=4时,确实会溢出。
- 我将default_config.py里面的
trt_max_batch_size
设置为4,max_input_len
和max_new_tokens
设置为1024,然后用int4/int8再次编译,然后测试max_batch_size=4下的benchmark,显存正常。 - 再次启动服务,提示8000端口被占用(被之前的qwen容器的api占用了),关闭对应的服务,或者删除对应的容器即可。
总结
# ....省略拉取两个仓库的过程.....
# 拷贝tensorrtllm_backend到tensorrtllm_backend目录中
cp -rf Qwen-7B-Chat-TensorRT-LLM/triton_model_repo tensorrtllm_backend
docker run \
-d \
--name triton \
--net host \
--shm-size=2g \
--ulimit memlock=-1 \
--ulimit stack=67108864 \
--gpus all \
-v ${PWD}/tensorrtllm_backend:/tensorrtllm_backend \
-v ${PWD}/Qwen-7B-Chat-TensorRT-LLM/qwen:/app/tensorrt_llm/examples/qwen\
triton_trt_llm sleep 8640000
- 安装python依赖并编译Engine
- 复制Engine文件
cd /app/tensorrt_llm/examples/qwen/trt_engines/fp16/1-gpu/
mkdir /tensorrtllm_backend/triton_model_repo/tensorrt_llm/1/
cp -r ./* /tensorrtllm_backend/triton_model_repo/tensorrt_llm/1/
cd /app/tensorrt_llm/examples/qwen
cp -r qwen_7b_chat /tensorrtllm_backend/triton_model_repo/tensorrt_llm/
cd /tensorrtllm_backend
python3 scripts/launch_triton_server.py --world_size=1 --model_repo=/tensorrtllm_backend/triton_model_repo