前言
本文记录一次使用 TensorRT-LLM + Triton Server 部署 Llama-3.2-1B-Instruct 的完整过程。目标是将 HuggingFace 格式模型转换为 TensorRT-LLM engine,然后通过 Triton Inference Server 对外提供 HTTP 推理服务。
整个流程涉及三个终端:
- 终端 1:使用 TensorRT-LLM 容器完成 checkpoint 转换和 engine 构建
- 终端 2:使用 Triton Server 容器准备 model repository 并启动服务
- 终端 3:在宿主机测试 Triton HTTP 接口
最终完成的效果是:模型被转换为 INT8 weight-only engine,并通过 Triton HTTP 端口 8010 提供推理服务。本文同时记录了 engine 构建参数过大导致 OOM、fill_template.py 重复执行报错、gpt_model_path 未正确替换和端口占用等问题的排查过程。
核心结论
这次部署过程中最关键的结论有四个:
- 不要直接使用默认
trtllm-build参数。默认构建出的 engine 可能具有很大的maxBatchSize、maxSequenceLen和maxNumTokens,低显存 GPU 容易在 Triton 加载阶段 OOM。 - RTX 4060 单卡环境应主动构建小规格 engine。本文使用
max_batch_size=1、max_seq_len=640、max_num_tokens=512。 fill_template.py替换的是模板变量名,不一定是最终config.pbtxt字段名。例如最终字段是gpt_model_path,但填充时要传engine_dir:${ENGINE_DIR}。- 不要对已经填充过的
config.pbtxt重复执行fill_template.py。更稳妥的做法是每次重新拷贝模板,再统一填充。
环境说明
| 项目 | 版本 / 规格 |
|---|---|
| GPU | NVIDIA GeForce RTX 4060 |
| TensorRT-LLM 镜像 | nvcr.io/nvidia/tensorrt-llm/release:1.1.0 |
| Triton Server 镜像 | nvcr.io/nvidia/tritonserver:25.12-trtllm-python-py3 |
| 模型 | Llama-3.2-1B-Instruct |
| 模型原始大小 | 约 2.4GB |
| engine 输出大小 | 约 2GB |
| Triton HTTP 端口 | 8010 |
| Triton gRPC 端口 | 8011 |
| Triton metrics 端口 | 8012 |
| 项目路径 | /home/minge/my_repo/tensorrt-llm-study |
注意:RTX 4060 显存有限,不建议使用
trtllm-build默认参数。默认 engine 可能出现maxBatchSize=2048、maxSequenceLen=131072、maxNumTokens=8192,容易导致 Triton 加载阶段显存 OOM。本文使用小规格 engine:max_batch_size=1、max_seq_len=640、max_num_tokens=512。
项目目录说明
/home/minge/my_repo/tensorrt-llm-study/
├── llm-model/
│ └── Llama-3.2-1B-Instruct/ # HuggingFace 格式模型
│ ├── model.safetensors # 模型权重 (~2.4GB)
│ ├── tokenizer.json # tokenizer 文件
│ ├── config.json # 模型配置
│ └── generation_config.json
└── trtllm-output/ # 输出目录
├── llama32_1b_int8wo_ckpt/ # TensorRT-LLM checkpoint
├── llama32_1b_int8wo_engine_b1_s640/ # 最终 engine
│ ├── config.json # engine 配置
│ └── rank0.engine # engine 文件 (~2GB)
└── triton_model_repo/ # Triton model repository
├── ensemble/ # ensemble 模型
├── preprocessing/ # 预处理模型
├── tensorrt_llm/ # TensorRT-LLM 模型
├── postprocessing/ # 后处理模型
└── tensorrt_llm_bls/ # BLS 模型
整体流程概览
本文流程可以分为以下步骤:
- 准备阶段:拉取 Docker 镜像、下载模型
- 终端 1:启动 TensorRT-LLM 容器、转换 checkpoint、构建 engine
- 终端 2:启动 Triton Server 容器、准备 model repository、启动服务
- 终端 3:测试 Triton HTTP 接口
流程图:
[HuggingFace 模型]
│
▼ convert_checkpoint.py
[TensorRT-LLM checkpoint]
│
▼ trtllm-build
[TensorRT engine]
│
▼ fill_template.py + Triton config
[Triton model repository]
│
▼ tritonserver
[Triton 推理服务]
终端 1:构建 TensorRT-LLM Engine
1. 拉取 TensorRT-LLM 镜像
在宿主机执行:
docker pull nvcr.io/nvidia/tensorrt-llm/release:1.1.0
2. 准备模型目录
如果模型已在 /home/minge/my_repo/tensorrt-llm-study/llm-model/Llama-3.2-1B-Instruct 目录中,可跳过本步。
如果没有模型,在宿主机执行:
cd /home/minge/my_repo/tensorrt-llm-study/llm-model
git lfs install
git clone https://www.modelscope.cn/LLM-Research/Llama-3.2-1B-Instruct.git
本示例使用 ModelScope 国内镜像源,下载速度更快。也可使用 HuggingFace 源。
3. 启动 TensorRT-LLM 容器
在宿主机执行:
docker run --rm \
-it \
--ipc=host \
--ulimit memlock=-1 \
--ulimit stack=67108864 \
--gpus=all \
-v /home/minge/my_repo/tensorrt-llm-study/llm-model/Llama-3.2-1B-Instruct:/models/Llama-3.2-1B-Instruct:ro \
-v /home/minge/my_repo/tensorrt-llm-study/trtllm-output:/trtllm-output \
nvcr.io/nvidia/tensorrt-llm/release:1.1.0
参数说明:
--ipc=host:共享宿主机 IPC namespace,提升共享内存性能--ulimit memlock=-1:允许锁定任意大小内存,避免 CUDA 内存分配失败--ulimit stack=67108864:设置栈大小为 64MB-v ...:ro:模型目录以只读模式挂载,防止误操作修改-v /home/minge/my_repo/tensorrt-llm-study/trtllm-output:/trtllm-output:输出目录挂载,engine 将写入此目录
4. 转换 checkpoint
进入容器后,执行:
cd /app/tensorrt_llm/examples/models/core/llama
python convert_checkpoint.py \
--model_dir /models/Llama-3.2-1B-Instruct \
--output_dir /trtllm-output/llama32_1b_int8wo_ckpt \
--dtype float16 \
--use_weight_only \
--weight_only_precision int8 \
--tp_size 1
成功输出:
Total time of reading and converting: 8.440 s
Total time of saving checkpoint: 1.780 s
Total time of converting checkpoints: 00:00:10
参数说明:
--dtype float16:模型权重精度为 FP16--use_weight_only:启用 weight-only 量化--weight_only_precision int8:量化精度为 INT8--tp_size 1:Tensor Parallel size 为 1(单 GPU)
5. 构建小规格 Engine
执行:
trtllm-build \
--checkpoint_dir /trtllm-output/llama32_1b_int8wo_ckpt \
--output_dir /trtllm-output/llama32_1b_int8wo_engine_b1_s640 \
--gemm_plugin auto \
--max_batch_size 1 \
--max_input_len 512 \
--max_seq_len 640 \
--max_num_tokens 512 \
--opt_num_tokens 128
成功输出:
[04/29/2026-11:04:07] [TRT-LLM] [I] Total time of building Unnamed Network 0: 00:00:31
[04/29/2026-11:04:07] [TRT] [I] Serialized 27 bytes of code generator cache.
[04/29/2026-11:04:07] [TRT] [I] Serialized 134685 bytes of compilation cache.
[04/29/2026-11:04:07] [TRT] [I] Serialized 12 timing cache entries
[04/29/2026-11:04:07] [TRT-LLM] [I] Timing cache serialized to model.cache
[04/29/2026-11:04:07] [TRT-LLM] [I] Build phase peak memory: 10421.96 MB, children: 6296.07 MB
[04/29/2026-11:04:08] [TRT-LLM] [I] Serializing engine to /trtllm-output/llama32_1b_int8wo_engine_b1_s640/rank0.engine...
[04/29/2026-11:04:09] [TRT-LLM] [I] Engine serialized. Total time: 00:00:01
[04/29/2026-11:04:09] [TRT-LLM] [I] Total time of building all engines: 00:00:34
构建参数说明:
| 参数 | 值 | 说明 |
|---|---|---|
--max_batch_size | 1 | 最大批大小,影响 KV cache 预分配 |
--max_input_len | 512 | 最大输入序列长度 |
--max_seq_len | 640 | 最大总序列长度(输入 + 输出) |
--max_num_tokens | 512 | 最大 token 数,影响运行时显存占用 |
--opt_num_tokens | 128 | 优化目标 token 数 |
这些参数直接影响 engine 运行时的显存占用。RTX 4060 显存有限,不建议使用默认参数。
6. 检查 Engine 文件
ls -lh /trtllm-output/llama32_1b_int8wo_engine_b1_s640
应看到:
-rw-r--r-- 1 root root 7680 config.json
-rw-r--r-- 1 root root 2062328900 rank0.engine
检查 engine 参数:
cat /trtllm-output/llama32_1b_int8wo_engine_b1_s640/config.json | grep -E "max_batch_size|max_seq_len|max_num_tokens|max_input_len"
应看到:
"max_input_len": 512,
"max_seq_len": 640,
"max_batch_size": 1,
"max_num_tokens": 512,
终端 2:启动 Triton Server 并生成 Model Repository
1. 拉取 Triton Server 镜像
在宿主机执行:
docker pull nvcr.io/nvidia/tritonserver:25.12-trtllm-python-py3
2. 启动 Triton Server 容器
在宿主机执行:
docker run --rm \
-it \
--name=trt_llm \
--gpus=all \
--net=host \
--shm-size=2g \
--ulimit memlock=-1 \
--ulimit stack=67108864 \
-v /home/minge/my_repo/tensorrt-llm-study/llm-model/Llama-3.2-1B-Instruct:/Llama-3.2-1B-Instruct \
-v /home/minge/my_repo/tensorrt-llm-study/trtllm-output:/trtllm-output \
nvcr.io/nvidia/tritonserver:25.12-trtllm-python-py3
参数说明:
--net=host:使用宿主机网络,容器直接访问宿主机端口--shm-size=2g:共享内存 2GB,CUDA 和 Triton 需要足够的共享内存
3. 创建 setup_triton_repo.sh 脚本
进入容器后,创建脚本:
cd /app/tools
touch setup_triton_repo.sh
vim setup_triton_repo.sh
按 i 进入插入模式,粘贴以下脚本内容:
#!/usr/bin/env bash
set -euo pipefail
ENGINE_DIR=${ENGINE_DIR:-/trtllm-output/llama32_1b_int8wo_engine_b1_s640}
TOKENIZER_DIR=${TOKENIZER_DIR:-/Llama-3.2-1B-Instruct}
MODEL_REPO=${MODEL_REPO:-/trtllm-output/triton_model_repo}
TEMPLATE_DIR=${TEMPLATE_DIR:-/app/all_models/inflight_batcher_llm}
FILL_TEMPLATE_SCRIPT=${FILL_TEMPLATE_SCRIPT:-/app/tools/fill_template.py}
echo "ENGINE_DIR=${ENGINE_DIR}"
echo "TOKENIZER_DIR=${TOKENIZER_DIR}"
echo "MODEL_REPO=${MODEL_REPO}"
echo "TEMPLATE_DIR=${TEMPLATE_DIR}"
echo "FILL_TEMPLATE_SCRIPT=${FILL_TEMPLATE_SCRIPT}"
echo
echo "== Check paths =="
test -d "${ENGINE_DIR}" || { echo "ERROR: ENGINE_DIR not found: ${ENGINE_DIR}"; exit 1; }
test -f "${ENGINE_DIR}/rank0.engine" || { echo "ERROR: rank0.engine not found in ${ENGINE_DIR}"; exit 1; }
test -f "${ENGINE_DIR}/config.json" || { echo "ERROR: config.json not found in ${ENGINE_DIR}"; exit 1; }
test -d "${TOKENIZER_DIR}" || { echo "ERROR: TOKENIZER_DIR not found: ${TOKENIZER_DIR}"; exit 1; }
test -d "${TEMPLATE_DIR}" || { echo "ERROR: TEMPLATE_DIR not found: ${TEMPLATE_DIR}"; exit 1; }
test -f "${FILL_TEMPLATE_SCRIPT}" || { echo "ERROR: fill_template.py not found: ${FILL_TEMPLATE_SCRIPT}"; exit 1; }
echo
echo "== Recreate model repository =="
rm -rf "${MODEL_REPO}"
mkdir -p "${MODEL_REPO}"
cp -r "${TEMPLATE_DIR}"/* "${MODEL_REPO}/"
echo
echo "== Fill ensemble config =="
python3 "${FILL_TEMPLATE_SCRIPT}" \
-i "${MODEL_REPO}/ensemble/config.pbtxt" \
"triton_max_batch_size:1,logits_datatype:TYPE_FP32"
echo
echo "== Fill preprocessing config =="
python3 "${FILL_TEMPLATE_SCRIPT}" \
-i "${MODEL_REPO}/preprocessing/config.pbtxt" \
"tokenizer_dir:${TOKENIZER_DIR},triton_max_batch_size:1,preprocessing_instance_count:1,add_special_tokens:true,multimodal_model_path:,engine_dir:${ENGINE_DIR},max_num_images:0"
echo
echo "== Fill tensorrt_llm config =="
python3 "${FILL_TEMPLATE_SCRIPT}" \
-i "${MODEL_REPO}/tensorrt_llm/config.pbtxt" \
"triton_backend:tensorrtllm,triton_max_batch_size:1,decoupled_mode:false,engine_dir:${ENGINE_DIR},max_queue_delay_microseconds:0,batching_strategy:inflight_fused_batching,max_queue_size:0,encoder_input_features_data_type:TYPE_FP16,logits_datatype:TYPE_FP32,prompt_embedding_table_data_type:TYPE_FP16,max_beam_width:1,encoder_engine_dir:,max_tokens_in_paged_kv_cache:1024,max_attention_window_size:,sink_token_length:,batch_scheduler_policy:guaranteed_no_evict,kv_cache_free_gpu_mem_fraction:0.2,cross_kv_cache_fraction:,kv_cache_host_memory_bytes:0,kv_cache_onboard_blocks:true,exclude_input_in_output:false,cancellation_check_period_ms:100,stats_check_period_ms:100,iter_stats_max_iterations:1000,request_stats_max_iterations:0,enable_kv_cache_reuse:false,normalize_log_probs:true,enable_chunked_context:false,gpu_device_ids:0,participant_ids:0,num_nodes:1,lora_cache_optimal_adapter_size:8,lora_cache_max_adapter_size:64,lora_cache_gpu_memory_fraction:0.0,lora_cache_host_memory_bytes:0,lora_prefetch_dir:,decoding_mode:,lookahead_window_size:,lookahead_ngram_size:,lookahead_verification_set_size:,medusa_choices:,eagle_choices:,gpu_weights_percent:,enable_context_fmha_fp32_acc:false,multi_block_mode:false,cuda_graph_mode:false,cuda_graph_cache_size:0,speculative_decoding_fast_logits:false,tokenizer_dir:${TOKENIZER_DIR},guided_decoding_backend:,xgrammar_tokenizer_info_path:"
echo
echo "== Fill postprocessing config =="
python3 "${FILL_TEMPLATE_SCRIPT}" \
-i "${MODEL_REPO}/postprocessing/config.pbtxt" \
"tokenizer_dir:${TOKENIZER_DIR},triton_max_batch_size:1,postprocessing_instance_count:1,skip_special_tokens:true"
echo
echo "== Fill tensorrt_llm_bls config =="
python3 "${FILL_TEMPLATE_SCRIPT}" \
-i "${MODEL_REPO}/tensorrt_llm_bls/config.pbtxt" \
"triton_max_batch_size:1,decoupled_mode:false,bls_instance_count:1,logits_datatype:TYPE_FP32,prompt_embedding_table_data_type:TYPE_FP16,accumulate_tokens:false,tensorrt_llm_model_name:tensorrt_llm,tensorrt_llm_draft_model_name:,multimodal_encoders_name:"
echo
echo "== Check unresolved template variables =="
UNRESOLVED=$(grep -R '\${' -n "${MODEL_REPO}"/*/config.pbtxt || true)
if echo "${UNRESOLVED}" | grep -v 'enable_trt_overlap' | grep -q '\${'; then
echo "ERROR: unresolved template variables found:"
echo "${UNRESOLVED}" | grep -v 'enable_trt_overlap'
exit 1
else
echo "OK: no active unresolved template variables."
fi
echo
echo "== Check gpt_model_path =="
grep -n -A3 -B2 "gpt_model_path" "${MODEL_REPO}/tensorrt_llm/config.pbtxt"
echo
echo "== Check tokenizer_dir =="
grep -R -n -A3 -B2 "tokenizer_dir" \
"${MODEL_REPO}/preprocessing/config.pbtxt" \
"${MODEL_REPO}/postprocessing/config.pbtxt" || true
echo
echo "== Done =="
echo "Model repository is ready: ${MODEL_REPO}"
粘贴完成后,按 Esc,输入 :wq,回车保存退出。
4. 给脚本执行权限
chmod +x /app/tools/setup_triton_repo.sh
5. 检查脚本语法
bash -n /app/tools/setup_triton_repo.sh
没有输出说明语法正常。
6. 执行脚本生成 model repository
/app/tools/setup_triton_repo.sh
成功时应看到:
OK: no active unresolved template variables.
并且 gpt_model_path 应是:
string_value: "/trtllm-output/llama32_1b_int8wo_engine_b1_s640"
tokenizer_dir 应是:
string_value: "/Llama-3.2-1B-Instruct"
这里尤其要确认 gpt_model_path。如果它仍然是 ${engine_dir},Triton 启动时会认为模型路径为空,并报 gpt_model_path is not specified。
7. 启动 Triton Server
tritonserver \
--model-repository=/trtllm-output/triton_model_repo \
--http-port=8010 \
--grpc-port=8011 \
--metrics-port=8012
成功时应看到:
Started HTTPService at 0.0.0.0:8010
Started GRPCInferenceService at 0.0.0.0:8011
Started Metrics Service at 0.0.0.0:8012
模型表中应看到:
tensorrt_llm | 1 | READY
ensemble | 1 | READY
如果看到以下警告,可以忽略:
Unable to get power usage for GPU 0
Unable to get energy consumption for GPU 0
终端 3:测试 Triton 服务
另开宿主机终端执行。
1. 检查 Triton 服务 Ready
curl -s localhost:8010/v2/health/ready
2. 检查模型 Ready
curl -s localhost:8010/v2/models/tensorrt_llm/ready
curl -s localhost:8010/v2/models/ensemble/ready
3. 推理测试
curl -s -X POST localhost:8010/v2/models/ensemble/generate \
-H "Content-Type: application/json" \
-d '{
"text_input": "<|begin_of_text|><|start_header_id|>user<|end_header_id|>\n\n请用三句话解释 TensorRT-LLM 的作用。<|eot_id|><|start_header_id|>assistant<|end_header_id|>\n\n",
"max_tokens": 96,
"bad_words": "",
"stop_words": ""
}'
如果返回中包含 text_output,说明 Triton Server 部署成功。
关键知识点
1. TensorRT-LLM 的作用
TensorRT-LLM 是 NVIDIA 推出的 LLM 推理优化库,核心功能包括:
- 量化:将 FP16/FP32 权重压缩为 INT8/INT4,减少显存和带宽需求
- Kernel Fusion:合并多个 GPU 操作为单一 kernel,减少 kernel launch 开销
- 优化 Attention:使用 Flash Attention、Paged Attention 等高效实现
- KV Cache 管理:优化缓存策略,支持更长的序列和更高的 batch size
2. checkpoint 和 engine 的区别
- checkpoint:TensorRT-LLM 中间格式,包含量化后的权重和配置,由
convert_checkpoint.py生成 - engine:TensorRT 最终优化产物,可直接用于推理,由
trtllm-build构建
流程:HuggingFace 模型 → checkpoint → engine
3. weight-only int8 量化
Weight-only quantization (W8A16) 只量化权重,激活值保持 FP16:
- 权重从 FP16 (2 bytes) → INT8 (1 byte),显存占用减半
- 推理时权重反量化为 FP16 进行计算
- 适合显存受限场景,精度损失较小
4. Triton Model Repository 结构
Triton model repository 包含多个模型组件:
| 目录 | 作用 |
|---|---|
ensemble | 组合多个模型形成完整推理流水线 |
preprocessing | 文本 → token IDs,加载 tokenizer |
tensorrt_llm | 执行 engine 推理 |
postprocessing | token IDs → 文本,解码输出 |
tensorrt_llm_bls | Business Logic Script,处理复杂推理逻辑 |
5. fill_template.py 的作用
fill_template.py 用于填充 Triton config.pbtxt 模板中的变量:
- 模板文件包含
${variable_name}占位符 fill_template.py接收key:value参数,替换对应占位符- 注意:参数名和模板变量名可能不一致(如
engine_dir对应${engine_dir},但最终写入gpt_model_path字段)。这一点是本文最容易踩坑的地方。
6. max_batch_size / max_seq_len / max_num_tokens 与显存的关系
这三个参数直接影响 engine 运行时显存占用:
max_batch_size:最大并发请求数,影响 KV cache 预分配max_seq_len:最大序列长度,决定单请求 KV cache 大小max_num_tokens:最大 token 数,影响运行时显存峰值
公式(简化):KV cache 显存 ≈ max_batch_size × max_seq_len × hidden_size × num_layers × 2
低显存 GPU 需降低这些参数,否则 Triton 加载 engine 时可能 OOM。
踩坑记录
问题一:fill_template.py 报 key xxx does not exist
现象
执行 fill_template.py 时报错:
key xxx does not exist
原因
对已经填充过的 config.pbtxt 又重复执行了 fill_template.py。模板变量已被替换,再次执行时找不到对应 key。
解决
重新执行脚本,它会先删除旧 model repository,再重新拷贝模板并填充:
/app/tools/setup_triton_repo.sh
验证
检查 config.pbtxt,不应有未替换的 ${...} 变量:
grep -R '\${' /trtllm-output/triton_model_repo/*/config.pbtxt
问题二:Triton 加载时报 gpt_model_path is not specified
现象
启动 Triton 后出现:
gpt_model_path is not specified
Both encoder and decoder model paths are empty
原因
tensorrt_llm/config.pbtxt 中 gpt_model_path 没有被正确替换。
关键点:在 fill_template.py 命令里应该写 engine_dir:${ENGINE_DIR},不要写 gpt_model_path:${ENGINE_DIR}。
虽然最终 config.pbtxt 中的字段名是 gpt_model_path,但模板占位符是 ${engine_dir}。
解决
检查填充结果:
grep -n -A3 -B2 "gpt_model_path" \
/trtllm-output/triton_model_repo/tensorrt_llm/config.pbtxt
正确结果应是:
string_value: "/trtllm-output/llama32_1b_int8wo_engine_b1_s640"
如果不对,重新执行脚本:
/app/tools/setup_triton_repo.sh
验证
启动 Triton 后检查日志,应看到:
tensorrt_llm | 1 | READY
问题三:Triton 报 cudaMallocAsync ... out of memory
现象
启动 Triton 加载 engine 时报:
cudaMallocAsync ... out of memory
或 Triton 进程直接被 kill。
原因
engine 构建规格过大(使用了 trtllm-build 默认参数)。默认参数可能是:
maxBatchSize: 2048
maxSequenceLen: 131072
maxNumTokens: 8192
这些值远超低显存 GPU 的承受能力。
解决
重新构建小规格 engine:
trtllm-build \
--checkpoint_dir /trtllm-output/llama32_1b_int8wo_ckpt \
--output_dir /trtllm-output/llama32_1b_int8wo_engine_b1_s640 \
--gemm_plugin auto \
--max_batch_size 1 \
--max_input_len 512 \
--max_seq_len 640 \
--max_num_tokens 512 \
--opt_num_tokens 128
验证
检查 engine config.json:
cat /trtllm-output/llama32_1b_int8wo_engine_b1_s640/config.json | grep -E "max_batch_size|max_seq_len|max_num_tokens"
应看到:
"max_batch_size": 1,
"max_seq_len": 640,
"max_num_tokens": 512,
问题四:Socket '0.0.0.0:8000' already in use
现象
启动 Triton 时报:
Socket '0.0.0.0:8000' already in use
原因
默认 8000 端口被占用(可能之前启动的 Triton 进程未清理)。
解决
方法一:杀掉旧进程
pkill -f tritonserver || true
pkill -f launch_triton_server.py || true
pkill -f mpirun || true
方法二:使用其他端口(本文采用)
tritonserver \
--model-repository=/trtllm-output/triton_model_repo \
--http-port=8010 \
--grpc-port=8011 \
--metrics-port=8012
验证
启动后检查端口:
curl -s localhost:8010/v2/health/ready
最终命令汇总
终端 1:构建 Engine
# 拉取镜像
docker pull nvcr.io/nvidia/tensorrt-llm/release:1.1.0
# 启动容器
docker run --rm -it --ipc=host --ulimit memlock=-1 --ulimit stack=67108864 --gpus=all \
-v /home/minge/my_repo/tensorrt-llm-study/llm-model/Llama-3.2-1B-Instruct:/models/Llama-3.2-1B-Instruct:ro \
-v /home/minge/my_repo/tensorrt-llm-study/trtllm-output:/trtllm-output \
nvcr.io/nvidia/tensorrt-llm/release:1.1.0
# 容器内:转换 checkpoint
python /app/tensorrt_llm/examples/models/core/llama/convert_checkpoint.py \
--model_dir /models/Llama-3.2-1B-Instruct \
--output_dir /trtllm-output/llama32_1b_int8wo_ckpt \
--dtype float16 --use_weight_only --weight_only_precision int8 --tp_size 1
# 容器内:构建 engine
trtllm-build \
--checkpoint_dir /trtllm-output/llama32_1b_int8wo_ckpt \
--output_dir /trtllm-output/llama32_1b_int8wo_engine_b1_s640 \
--gemm_plugin auto \
--max_batch_size 1 --max_input_len 512 --max_seq_len 640 --max_num_tokens 512 --opt_num_tokens 128
终端 2:启动 Triton
# 拉取镜像
docker pull nvcr.io/nvidia/tritonserver:25.12-trtllm-python-py3
# 启动容器
docker run --rm -it --name=trt_llm --gpus=all --net=host --shm-size=2g \
--ulimit memlock=-1 --ulimit stack=67108864 \
-v /home/minge/my_repo/tensorrt-llm-study/llm-model/Llama-3.2-1B-Instruct:/Llama-3.2-1B-Instruct \
-v /home/minge/my_repo/tensorrt-llm-study/trtllm-output:/trtllm-output \
nvcr.io/nvidia/tritonserver:25.12-trtllm-python-py3
# 容器内:执行 setup_triton_repo.sh(脚本内容见上文)
/app/tools/setup_triton_repo.sh
# 容器内:启动 Triton
tritonserver --model-repository=/trtllm-output/triton_model_repo --http-port=8010 --grpc-port=8011 --metrics-port=8012
终端 3:测试服务
curl -s localhost:8010/v2/health/ready
curl -s localhost:8010/v2/models/ensemble/ready
curl -s -X POST localhost:8010/v2/models/ensemble/generate \
-H "Content-Type: application/json" \
-d '{"text_input": "<|begin_of_text|><|start_header_id|>user<|end_header_id|>\n\n请用三句话解释 TensorRT-LLM 的作用。<|eot_id|><|start_header_id|>assistant<|end_header_id|>\n\n", "max_tokens": 96, "bad_words": "", "stop_words": ""}'
总结
本文完整记录了 TensorRT-LLM + Triton Server 部署 Llama-3.2-1B-Instruct 的流程:
- 使用
convert_checkpoint.py将 HuggingFace 模型转换为 TensorRT-LLM checkpoint - 使用
trtllm-build构建小规格 engine(适配低显存 GPU) - 使用 Triton Server +
fill_template.py部署推理服务 - 通过 HTTP 接口测试推理
关键经验:
- 低显存 GPU 必须主动限制
max_batch_size、max_seq_len、max_num_tokens。 fill_template.py的参数名要和模板变量名一致,而不是和最终字段名一致。- Triton model repository 中的
ensemble、preprocessing、tensorrt_llm、postprocessing、tensorrt_llm_bls需要协同工作。 - 如果 Triton 日志中仍然出现旧 engine 的大参数,要优先检查
gpt_model_path是否指向了新 engine。
后续可尝试:
- 更大模型(如 Llama-3.1-8B)的多 GPU 部署
- INT4 量化进一步压缩显存
- 动态 batching 提升吞吐量
- Kubernetes 上部署 Triton 集群