LaneGCN 部署流水线(DMLaneGCN)
面向自动驾驶 motion forecasting 的 LaneGCN 模型 ONNX / TensorRT 部署流水线,在 TensorRT 10.x 上实现 ≤ 10ms 端到端推理延迟,包含 ONNX 导出、动态 shape 引擎构建、weight-only INT8 量化与可视化验证。
✨ 核心特性
- ⚡ 低延迟推理:在 TensorRT 10.x 上实现 ≤ 10ms 端到端推理,满足自动驾驶实时性约束
- 🔧 Shape Input Tensor 消除:通过
torch.where(valid, ...)零化替代动态切片,规避 TensorRT 10.xexecute_async_v3段错误 - 🧊 Weight-only INT8 量化:将 Conv1d 转 Conv2d(Unsqueeze/Squeeze axis=2)以启用 INT8 Conv2d kernel,对 Turing GPU 上非方形的 (1, K>1) 卷积层跳过 INT8
- 🛣️ 完整部署流水线:从 PyTorch checkpoint → ONNX(dynamic axes)→ ONNX-Simplifier → TensorRT engine → 推理可视化全链路打通
- 🎬 可视化验证:在 Argoverse 验证集上生成 6 个场景 GIF,验证 ONNX 图、TRT engine 与预处理器的数值一致性
🏗️ 技术栈
| 类别 | 技术选型 |
|---|---|
| 基础模型 | LaneGCN(Uber ATG, ECCV 2020 Oral) |
| 深度学习框架 | PyTorch + NumPy |
| 模型导出 | ONNX + onnx-simplifier |
| 推理引擎 | TensorRT 10.x(FP32 / FP16 / w8a16 / w8a32) |
| 量化校准 | polygraphy + 自研 activation_calibration.py |
| 数据集 | Argoverse Motion Forecasting v1.1 |
| 部署容器 | TensorRTNewest Docker(TensorRT 10.x) |
🚀 部署流水线
| 阶段 | 脚本 | 描述 |
|---|---|---|
| 1. Refactor | lanegcn_onnx.py |
将 dict/list 输入展平为 23 个张量,图预处理移出模型 |
| 2. Export | onnx_exporter.py |
PyTorch → ONNX,dynamic axes 支持变长 actor / lane-node |
| 3. Simplify | onnx-simplifier | 化简 ONNX 图以适配 TRT |
| 4. Build | trt_exporter.py |
ONNX → TensorRT engine(fp32 / fp16 / 动态 shape) |
| 5. Inference | demo_inference.py |
TRT engine 推理 + 可视化 |
| 6. Profile | onnx_inference.py / benchmark_all.py |
ORT 与 TRT 延迟 / 吞吐基准 |
🛠️ 关键工程贡献
1. 消除 Shape Input Tensor
原始 LaneGCN 使用 pre_mask / suc_mask 动态切片选择前驱 / 后继 lane-node 对,这些 mask 在 ONNX 图中会产生 shape input tensor,触发 TensorRT 10.x execute_async_v3 段错误。
解决方案:用 valid mask 零化替代动态切片,数学等价但消除所有 shape input tensor。
# Before (creates shape input tensors → TRT segfault):
edge_u = edge_u[pre_mask]
# After (mathematically equivalent, no shape inputs):
valid = pre_mask # boolean mask
edge_u_safe = torch.where(valid, edge_u, torch.zeros_like(edge_u))
2. Conv1d → Conv2d 转换以启用 INT8
TensorRT 10.x 缺少 Conv1d(3D 权重张量)的 INT8 kernel。通过 Unsqueeze/Squeeze(axis=2)将 Conv1d 转为 Conv2d,即可使用 INT8 Conv2d kernel。
注:Turing 架构 GPU(compute 7.5)对非方形 (1, K>1) kernel 缺少 INT8 Conv2d kernel,这类层需跳过 INT8 或使用 FP16。
3. ScatterElements 精度保护
TensorRT 10.x 中 ScatterElements 层无法通过 set_output_type 或 layer.precision 进行精度约束,需通过上游层 FP32 输出保护以确保 FP32 累加。
📊 性能基准
5 后端基准(Argoverse val 序列 110,100 次迭代):
| 后端 | 精度 | 备注 |
|---|---|---|
| PyTorch Eager | FP32 | 基线 |
| ONNX Runtime (CUDA) | FP32 | 需要 CUDA 12.x nvidia pip libs |
| TensorRT | FP32 | 动态 shape |
| TensorRT | w8a16 | weight-only INT8 |
| TensorRT | w8a32 | weight-only INT8 / FP32 accum |
详细结果见 benchmark_results.json 与 misc/benchmark_comparison.png。
🎬 推理可视化
6 个 Argoverse 验证集场景的 TRT 推理结果(agent 局部坐标系下:蓝=观测 2s 历史,绿=真值 3s 未来,红/黄/…=top-K 预测候选,灰=lane-graph 上下文):
- Scene 03189 / 05412 / 09481 / 11605 / 11803 / 12775
引擎:trt_engines_w8a32/lanegcn.engine(weight-only INT8 / FP32 accum)。
🔗 相关链接
- 论文:LaneGCN: Predicting Structured Trajectories via Graph Convolutional Networks(ECCV 2020 Oral)
- 原始仓库:uber-research/LaneGCN(作为 git submodule 集成)
- 竞赛:Argoverse Motion Forecasting Competition — Rank 1st
📥 快速开始
# 克隆(含 submodule)
git clone --recursive https://gitee.com/junhuisirup/lanegcn_deployment.git DMLaneGCN
cd DMLaneGCN
# 安装依赖
conda create --name lanegcn python=3.10
conda activate lanegcn
pip install -r requirements.txt
pip install tensorrt pycuda polygraphy
# 导出 ONNX
python onnx_exporter.py --weight results/lanegcn/36.000.ckpt
# 构建 TensorRT engine
python trt_exporter.py --onnx lanegcn.onnx --output-dir trt_engines --precision fp32
# 推理与可视化
python demo_inference.py --engine trt_engines/lanegcn.engine --seq 155
更多信息请参考项目仓库 README。