# DM_LaneGCN **Repository Path**: junhuisirup/lanegcn_deployment ## Basic Information - **Project Name**: DM_LaneGCN - **Description**: lanegcn模型部署 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-26 - **Last Updated**: 2026-07-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # LaneGCN: ONNX / TensorRT Deployment Pipeline ![CI](https://img.shields.io/badge/CI-ruff%20lint-green) ![Python](https://img.shields.io/badge/Python-3.10+-blue) ![TensorRT](https://img.shields.io/badge/TensorRT-10.x-orange) ![License](https://img.shields.io/badge/License-Non--Commercial-lightgrey) > A production-oriented deployment showcase for [LaneGCN](https://github.com/uber-research/LaneGCN) (ECCV 2020 Oral, Uber ATG). [Paper](https://arxiv.org/pdf/2007.13732) | [Slides](http://www.cs.toronto.edu/~byang/slides/LaneGCN.pdf) | [ECCV 2020 Oral Video](https://yun.sfo2.digitaloceanspaces.com/public/lanegcn/video.mp4) > **Original authors:** Ming Liang, Bin Yang, Rui Hu, Yun Chen, Renjie Liao, Song Feng, Raquel Urtasun > **Rank 1st** — [Argoverse Motion Forecasting Competition](https://evalai.cloudcv.org/web/challenges/challenge-page/454/leaderboard/1279) ![Deployment Pipeline](misc/pipeline.png) *** ## Table of Contents - [About This Repository](#about-this-repository) - [Demo Inference Visualizations](#demo-inference-visualizations) - [Benchmark Results](#benchmark-results) - [Repository Structure](#repository-structure) - [Deployment Pipeline](#deployment-pipeline) - [Key Engineering Contribution: Eliminating Shape Input Tensors](#key-engineering-contribution-eliminating-shape-input-tensors) - [Quick Start (Deployment Only)](#quick-start-deployment-only) - [Key Engineering Notes](#key-engineering-notes) - [License](#license) - [Citation](#citation) *** ## About This Repository This repository is a **deployment-focused fork** of LaneGCN. It wraps the original Uber LaneGCN as an unmodified git submodule and adds a complete **ONNX / TensorRT deployment toolchain** on top — refactoring the model for export, building TensorRT engines with dynamic shapes, and running low-latency inference. > **For training, testing, and data preparation, please refer to the original** **[`LaneGCN/README.MD`](LaneGCN/README.MD).** This README focuses exclusively on the deployment pipeline added by this fork. *** ## Demo Inference Visualizations The following six scenes are full-pipeline TensorRT inference results produced by [`demo_inference.py`](demo_inference.py) on the Argoverse forecasting validation set. Each animation shows, in the agent's local frame, the observed 2 s history (blue), the ground-truth 3 s future (green), the top-K predicted trajectories with confidence scores, and the lane-graph context used by the model. Engines used: `trt_engines_w8a32/lanegcn.engine` (weight-only INT8 / FP32 accum).
Scene 03189
Scene 3189
Scene 05412
Scene 5412
Scene 09481
Scene 9481
Scene 11605
Scene 11605
Scene 11803
Scene 11803
Scene 12775
Scene 12775
> **Color legend (per frame):** blue = observed trajectory (history), green = ground-truth future, red/yellow/… = predicted future candidates (color encodes the top-K rank; top-1 is the highest-confidence prediction), grey = lane-graph context. These clips are the actual on-device outputs from the deployed engine — they validate that the ONNX graph, the TensorRT engine, and the input preprocessor agree numerically (also cross-checked by [`_verify_aligned.py`](_verify_aligned.py)). *** ## Benchmark Results Latency, throughput, and engine size across **5 backends** on the same input sample (seq 110, 100 iterations after warmup). All backends share the same 23-tensor feed and use `time.perf_counter` for unified timing — see [`benchmark_all.py`](benchmark_all.py). ![Benchmark Comparison](misc/benchmark_comparison.png) | # | Backend | Engine / Weights | Notes | | --- | --- | --- | --- | | 1 | **PyTorch eager** | `lanegcn_onnx.py` + `36.000.ckpt` | eval + `no_grad` + `cuda.synchronize` | | 2 | **ONNX Runtime** | `lanegcn_simplified.onnx` | CUDAExecutionProvider | | 3 | **TensorRT FP32** | `trt_engines_fp32/lanegcn.engine` | full-precision reference | | 4 | **TensorRT w8a32** | `trt_engines_w8a32/lanegcn.engine` | INT8 weights + FP32 activations | | 5 | **TensorRT w8a16** | `trt_engines_w8a16/lanegcn.engine` | INT8 weights + FP16 activations | Reproduce with: ```sh python benchmark_all.py --seq 110 --iterations 100 --output benchmark_results.json ``` *** ## Repository Structure The original [Uber LaneGCN](https://github.com/uber-research/LaneGCN) is included as a **git submodule** at `LaneGCN/`. The parent repository only contains the deployment-specific code and two compatibility-patched files: ``` LaneGCN_white/ ← this repo (deployment showcase) ├── LaneGCN/ ← git submodule (original Uber LaneGCN, unmodified) │ ├── lanegcn.py ← original model │ ├── utils.py ← original utils (imported via sys.path) │ ├── train.py / test.py ← original training / testing scripts │ ├── get_data.sh ← data download script │ └── ... ├── lanegcn_onnx.py ← ★ NEW: ONNX-compatible model refactor ├── onnx_exporter.py ← ★ NEW: PyTorch → ONNX export ├── onnx_inference.py ← ★ NEW: ONNX Runtime benchmarking ├── trt_exporter.py ← ★ NEW: ONNX → TensorRT engine build ├── demo_inference.py ← ★ NEW: TRT inference + visualization ├── save_seq_data.py ← ★ NEW: debug data export ├── _verify_aligned.py ← ★ NEW: numerical alignment verification ├── data.py ← ★ MODIFIED: np.bool_ compat + _build_cross_edges + path config ├── layers.py ← ★ MODIFIED: math.gcd compat (Python 3.9+) ├── README.MD / LICENSE / .gitignore / requirements.txt / environment.yml ├── misc/ ← README images (for GitHub rendering) └── fonts/ ← visualization font ``` **Why** **`data.py`** **and** **`layers.py`** **are duplicated:** These two files contain small but necessary patches on top of the original — `np.bool` → `np.bool_` (NumPy 1.24+), `fractions.gcd` → `math.gcd` (Python 3.9+), and a new `_build_cross_edges` method for online graph construction when `preprocess=False`. The deployment scripts set `sys.path` so the local (patched) versions take precedence over the submodule's originals. *** ## Deployment Pipeline On top of the original LaneGCN, this repo adds a complete deployment toolchain: | Stage | Script | Description | | ------------ | ------------------- | ------------------------------------------------------------------------------------------------------------------ | | 1. Refactor | `lanegcn_onnx.py` | ONNX-compatible model: dict/list inputs flattened to 23 tensor inputs; graph preprocessing moved outside the model | | 2. Export | `onnx_exporter.py` | PyTorch → ONNX with dynamic axes (variable actor/lane-node counts) | | 3. Simplify | (onnx-simplifier) | Reduces ONNX graph for TRT compatibility | | 4. Build | `trt_exporter.py` | ONNX → TensorRT engine (fp32 / fp16, dynamic shapes) | | 5. Inference | `demo_inference.py` | TRT engine inference + visualization | | 6. Profile | `onnx_inference.py` | ONNX Runtime latency / throughput benchmarking | ### Key Engineering Contribution: Eliminating Shape Input Tensors The original LaneGCN uses dynamic slicing with `pre_mask` / `suc_mask` to select predecessor/successor lane-node pairs. These masks produce **shape input tensors** in the ONNX graph, which trigger a **segmentation fault in TensorRT 10.x** when called via `execute_async_v3`. **Solution:** Replace dynamic slicing with valid-mask zeroing. In `lanegcn_onnx.py`: ```python # 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)) ``` This is mathematically equivalent and eliminates all shape input tensors, allowing `execute_async_v3` to run without segfaults. See `MapNet.forward` and `M2M.forward` in `lanegcn_onnx.py` for details. *** ## Quick Start (Deployment Only) ### 1. Clone with submodule ```sh git clone --recursive https://gitee.com/junhuisirup/lanegcn_deployment.git DMLaneGCN cd DMLaneGCN # If already cloned without --recursive: git submodule update --init --recursive ``` ### 2. Install deployment dependencies ```sh conda create --name lanegcn python=3.10 conda activate lanegcn # PyTorch (adjust CUDA version to match your system) conda install pytorch torchvision cudatoolkit=11.8 -c pytorch # Argoverse API (required by the original data loader) pip install git+https://github.com/argoai/argoverse-api.git # Deployment-specific dependencies pip install -r requirements.txt pip install tensorrt pycuda polygraphy # TensorRT 10.x ``` > Training/testing dependencies (Horovod, etc.) are listed in the original [`LaneGCN/README.MD`](LaneGCN/README.MD). ### 3. Prepare a trained checkpoint Follow the original repo to train or download the pretrained `36.000.ckpt`, then place it under `results/lanegcn/`. Data preparation is also documented in `LaneGCN/README.MD`. ### 4. Export ONNX ```sh # From a trained checkpoint python onnx_exporter.py --weight results/lanegcn/36.000.ckpt # With --synthetic flag (no dataset needed, for quick testing) python onnx_exporter.py --weight results/lanegcn/36.000.ckpt --synthetic ``` Produces `lanegcn.onnx` (with dynamic axes for variable actor/lane-node counts). ### 5. Build TensorRT Engine ```sh # fp32 python trt_exporter.py --onnx lanegcn.onnx --output-dir trt_engines --precision fp32 # fp16 python trt_exporter.py --onnx lanegcn.onnx --output-dir trt_engines --precision fp16 ``` Produces `trt_engines/lanegcn.engine`. ### 6. Run Inference & Visualize ```sh python demo_inference.py --engine trt_engines/lanegcn.engine --seq 155 ``` ### 7. Benchmark (5 Backends) ```sh # ORT CUDA requires CUDA 12.x libs from nvidia pip packages # (container ships CUDA 13.0, incompatible with ORT 1.24) NVLIB=$(python -c "import nvidia, os, glob; print(':'.join(glob.glob(os.path.dirname(nvidia.__file__)+'/*/lib')))") export LD_LIBRARY_PATH="$NVLIB:$LD_LIBRARY_PATH" python benchmark_all.py --seq 110 --iterations 100 --output benchmark_results.json ``` For single-backend ONNX Runtime profiling: ```sh python onnx_inference.py --model lanegcn.onnx --provider CUDA --runs 100 ``` ### 8. Scene Selection (Demo Material) ```sh # Generate a 10×6 grid of candidate scenes for visual inspection python select_scenes.py --num 60 --output scene_candidates.png # Pick 4-6 scene IDs from the grid, then generate a high-quality GIF for each: python demo_inference.py --engine trt_engines_w8a32/lanegcn.engine --seq --output demo_scene_.gif --data val/data ``` ### 9. Generate Figures ```sh python generate_figures.py ``` Produces `misc/benchmark_comparison.png`, `misc/pipeline.png`, `misc/shape_input_before_after.png`, `misc/int8_sensitivity_heatmap.png`. *** ## Key Engineering Notes 1. **Shape input tensor elimination** — The `pre_mask` / `suc_mask` dynamic slicing is replaced with `torch.where(valid, ...)` zeroing. This removes all shape input tensors from the ONNX graph, working around a TensorRT 10.x `execute_async_v3` segfault. See [lanegcn\_onnx.py](lanegcn_onnx.py). 2. **Engine reuse** — `demo_inference.py` loads the TRT engine and persistent context once, then reuses them across inferences to avoid repeated deserialization overhead. 3. **`horovod`** **config** — Set to `False` in `lanegcn_onnx.py` (deployment variant). The training variant (`LaneGCN/lanegcn.py` in the submodule) keeps it `True` for distributed training. 4. **`MapQuery`** **map path** — Configurable via the `LANEGCN_MAP_DIR` environment variable (defaults to `./dataset/map_npy/`). 5. **Submodule + patched files** — `LaneGCN/` is a git submodule containing the original code. `data.py` and `layers.py` in the parent repo contain compatibility patches (`np.bool_`, `math.gcd`, `_build_cross_edges`). Deployment scripts configure `sys.path` so local patched files take precedence, then fall back to the submodule for unmodified modules (`utils.py`, etc.). *** ## License Released under the [Uber Non-Commercial License](LICENSE) (© Uber Technologies, Inc.). Use is restricted to **non-commercial purposes** such as teaching, academic research, and personal experimentation. Commercial use is prohibited. The ONNX / TensorRT deployment pipeline added by this repository is subject to the same license terms. ***