logo 🤗

技术视野

聚焦科技前沿,分享技术解析,洞见未来趋势。在这里,与您一起探索人工智能的无限可能,共赴技术盛宴。

编译triton/tensorrtllm_backend Docker镜像

背景:

  • 在Triton 23.10发布后,才会内置TensorRT-LLM支持
  • 目前Triton最新版是23.09,暂时不支持,所以需要手动编译Docker镜像
  1. 拉取本项目代码
git clone https://github.com/triton-inference-server/tensorrtllm_backend.git -b release/0.5.0

cd tensorrtllm_backend
  1. 拉取子模块(目前只依赖TensorRT-LLM) 代码
git submodule update --init --recursive
git lfs install
git lfs pull
  1. 编译dokcer镜像
  • For x86_64
DOCKER_BUILDKIT=1 docker build -t triton_trt_llm -f dockerfile/Dockerfile.trt_llm_backend .
  • For aarch64
DOCKER_BUILDKIT=1 docker build -t triton_trt_llm --build-arg TORCH_INSTALL_TYPE="src_non_cxx11_abi" -f dockerfile/Dockerfile.trt_llm_backend .
  1. 编译完成后,你将看到有一个名为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 服务

  1. 进入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
  1. 进入容器
docker exec -it triton /bin/bash
  1. 观察映射是否ok,有输出文件,就是ok的
ls /tensorrtllm_backend
  1. 进入该目录,然后创建一个triton_model_repo目录,用于存放待推理的模型
cd /tensorrtllm_backend
mkdir triton_model_repo
  1. 拷贝一些默认的样例配置到刚刚创建的目录。
cp -r all_models/inflight_batcher_llm/* triton_model_repo/
  1. 将前面编译的TensorRT-LLM的Engine文件拷贝到Triton里面,可以参考下面的做法
  • 进入Qwen里面的Engine路径
cd /app/tensorrt_llm/examples/qwen/trt_engines/fp16/1-gpu/
  • 再将Qwen Engine拷贝给Triton
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的容器
  1. 编写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"
  }
}
  1. 编写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,后面会讲到)。
  1. 编写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,后面会讲到)。
  1. 编写Triton中的trt_llm配置, 修改triton_model_repo/postprocessing/config.pbtxt,基本和修改triton_model_repo/preprocessing/部分一样,不再重复阐述。
  2. 安装qwen需要的几个必选依赖
pip install sentencepiece~=0.1.99 tiktoken
  1. 启动Triton服务
cd /tensorrtllm_backend
python3 scripts/launch_triton_server.py --world_size=1 --model_repo=/tensorrtllm_backend/triton_model_repo
  1. 启动后发现报错,是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
  1. 再次启动发现还是报错,这次是显存不够。之前明明是可以的,为啥现在不够了呢?经排查发现,默认是max_batch_size>=4,设置成低于4的max_batch_size则不起作用。所以我再重新编译了一下int4 weight only的Engine,并且测试了benchmark下,batch_size=4时,确实会溢出。
  2. 我将default_config.py里面的trt_max_batch_size设置为4,max_input_lenmax_new_tokens设置为1024,然后用int4/int8再次编译,然后测试max_batch_size=4下的benchmark,显存正常。
  3. 再次启动服务,提示8000端口被占用(被之前的qwen容器的api占用了),关闭对应的服务,或者删除对应的容器即可。

总结

# ....省略拉取两个仓库的过程.....
# 拷贝tensorrtllm_backend到tensorrtllm_backend目录中
cp -rf Qwen-7B-Chat-TensorRT-LLM/triton_model_repo tensorrtllm_backend
  • 参考docker启动命令
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/
  • 复制tokenzer文件
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
  • 附成功截图

image.png

版权属于:tlntin
作品采用:本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
更新于: 2023年11月10日 14:13


39 文章数
5 分类数
40 页面数
已在风雨中度过 1年160天10小时24分
目录
来自 《Triton部署TensorRT-LLM》
暗黑模式
暗黑模式
返回顶部
暗黑模式
暗黑模式
返回顶部