自动驾驶-第五阶段-工程化 + 作品集打磨 + 面试准备
第五阶段:工程化 + 作品集打磨 + 面试准备
把前四阶段的学习成果转化为拿到Offer的武器
时间规划: 4周(第11-14周)
目标: 产出一个可展示的项目Portfolio + 掌握模型部署技能 + 准备面试
本阶段的核心原则
前四阶段你学会了"做",这个阶段你要学会"说"和"卖"。
做得好 × 说不好 = 没人知道你的能力
做得好 × 说得好 = 拿到面试机会 + 通过面试
Week 1(第11周):整合项目——打造一个完整的Demo
Day 1-2:定义你的核心展示项目
项目名称建议:E2E-Drive-Portfolio
一个从感知到规划的完整端到端自动驾驶系统,包含BEV感知、扩散模型规划、VLA推理、CARLA闭环评测。
项目结构:
E2E-Drive-Portfolio/
├── README.md # ← 最重要!面试官第一个看这个
├── docs/
│ ├── architecture.png # 系统架构图
│ ├── results_table.md # 评测结果对比表
│ └── demo_video.mp4 # 闭环驾驶演示视频
├── perception/
│ ├── bevformer_inference.py # BEV感知推理脚本
│ └── visualize_bev.py # BEV可视化
├── planning/
│ ├── diffusion_planner.py # 扩散模型规划器
│ ├── pid_controller.py # PID轨迹跟踪
│ └── evaluate_navsim.py # NAVSIM评测脚本
├── vla/
│ ├── mini_vla.py # 轻量VLA模型
│ ├── cot_inference.py # CoT推理演示
│ └── grpo_training.py # GRPO微调脚本
├── deployment/
│ ├── export_onnx.py # ONNX导出
│ ├── trt_benchmark.py # TensorRT推理测速
│ └── quantize_int8.py # INT8量化
├── carla_demo/
│ ├── collect_data.py # 数据采集(第一阶段)
│ ├── closed_loop_test.py # 闭环测试
│ └── record_video.py # 录制演示视频
└── configs/
└── model_configs.yaml # 统一配置文件
Day 3-4:撰写一个有说服力的README
README是你的"简历首页"——面试官打开你的GitHub,第一眼看的就是它。
# E2E-Drive-Portfolio: 端到端自动驾驶全栈实现
## 项目亮点
- 覆盖 **感知→预测→规划→VLA** 完整技术栈
- 在 **NAVSIM** 基准上实现端到端评测,PDMS达到XX分
- 基于 **DiffusionDrive** 的多模态扩散规划器
- 基于 **Qwen2.5-VL** 的轻量VLA驾驶场景推理
- **CARLA** 闭环驾驶演示,碰撞率低于X%
- **TensorRT** 部署加速,推理延迟从XXms降至XXms
## 技术栈
| 模块 | 方法 | 论文 |
|------|------|------|
| BEV感知 | BEVFormer | ECCV 2022 |
| 端到端规划 | VAD / SparseDrive | ICCV 2023 / 2024 |
| 扩散规划 | DiffusionDrive | CVPR 2025 |
| VLA推理 | ORION + Qwen2.5-VL | ICCV 2025 |
| 闭环评测 | NAVSIM + CARLA | NeurIPS 2024 |
| 模型部署 | TensorRT + ONNX | - |
## 快速开始
[安装、运行说明...]
## 评测结果
[结果表格 + 可视化图片...]
## 演示视频
[CARLA闭环驾驶视频截图/GIF...]
关键原则:面试官的时间不超过30秒。 README的前5行必须让他知道"这个项目做了什么、用了什么技术、效果如何"。把最有说服力的数字(PDMS分数、碰撞率、推理速度)放在最前面。
Day 5:录制CARLA闭环演示视频
"""
record_demo_video.py
在CARLA中运行你的模型并录制一段高质量的演示视频
"""
import carla
import cv2
import numpy as np
import torch
# === 录制配置 ===
VIDEO_WIDTH, VIDEO_HEIGHT = 1280, 720
FPS = 20
OUTPUT_FILE = 'demo_video.mp4'
# 创建视频写入器
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
video = cv2.VideoWriter(OUTPUT_FILE, fourcc, FPS, (VIDEO_WIDTH, VIDEO_HEIGHT))
# 在每一帧上叠加信息面板
def create_info_overlay(frame, info):
"""在画面上叠加模型状态信息"""
overlay = frame.copy()
# 半透明黑色背景
cv2.rectangle(overlay, (10, 10), (400, 180), (0, 0, 0), -1)
frame = cv2.addWeighted(overlay, 0.6, frame, 0.4, 0)
# 文字信息
texts = [
f"Speed: {info['speed']:.1f} m/s",
f"Steer: {info['steer']:.3f}",
f"Model: {info['model_name']}",
f"Inference: {info['inference_ms']:.1f} ms",
f"Distance: {info['distance']:.0f} m",
f"Collisions: {info['collisions']}",
]
for i, text in enumerate(texts):
cv2.putText(frame, text, (20, 35 + i * 25),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
return frame
# 在闭环测试循环中:
# frame = create_info_overlay(camera_image, info_dict)
# video.write(frame)
# 结束时:
# video.release()
视频要展示什么?
- 正常驾驶场景(直行、转弯、跟车)——证明基础能力
- 挑战性场景(急弯、避障、路口)——证明鲁棒性
- 画面上要有实时的模型状态信息——证明工程能力
- 视频时长控制在1-3分钟——太长面试官不会看完
Week 2(第12周):模型部署工程化
Day 6-7:ONNX导出与TensorRT加速
什么是ONNX?什么是TensorRT?
PyTorch模型(研究用)
↓ torch.onnx.export()
ONNX模型(跨平台中间格式)
↓ trtexec
TensorRT引擎(车端部署用)
PyTorch → 灵活但慢(研究阶段用)
ONNX → 标准化但一般快(跨框架交换用)
TensorRT → 极快但不灵活(部署阶段用)
概念解释:
ONNX(Open Neural Network Exchange): 一种开放的模型格式标准。就像PDF是文档的通用格式一样,ONNX是神经网络的通用格式。任何框架训练的模型都可以导出为ONNX,然后在任何支持ONNX的平台上运行。
TensorRT: NVIDIA专门为GPU推理优化的加速引擎。它做的事情包括:算子融合(把多个小操作合并成一个大操作)、精度优化(FP32→FP16→INT8)、内存优化(减少显存占用)。通常能把推理速度提升3-10倍。
完整的导出和加速流程
"""
deployment_pipeline.py
完整的模型部署Pipeline:PyTorch → ONNX → TensorRT → Benchmark
"""
import torch
import torch.onnx
import time
import numpy as np
# ========== Step 1: PyTorch → ONNX ==========
def export_to_onnx(model, save_path="model.onnx"):
"""导出PyTorch模型为ONNX格式"""
model.eval()
# 创建dummy输入(要和实际推理时的输入shape一致)
dummy_input = torch.randn(1, 3, 300, 400).cuda() # 假设输入是图像
torch.onnx.export(
model,
dummy_input,
save_path,
input_names=['image'],
output_names=['trajectory'],
dynamic_axes={
'image': {0: 'batch_size'}, # 支持动态batch
'trajectory': {0: 'batch_size'}
},
opset_version=17, # ONNX算子版本,越新支持的操作越多
do_constant_folding=True # 常量折叠优化
)
print(f"ONNX模型已导出到 {save_path}")
# 验证ONNX模型
import onnx
onnx_model = onnx.load(save_path)
onnx.checker.check_model(onnx_model)
print("ONNX模型验证通过")
# ========== Step 2: ONNX → TensorRT ==========
# 命令行方式(最简单):
# trtexec --onnx=model.onnx \
# --saveEngine=model.trt \
# --fp16 \ # 半精度加速
# --workspace=4096 \ # 工作空间4GB
# --minShapes=image:1x3x300x400 \
# --optShapes=image:4x3x300x400 \
# --maxShapes=image:8x3x300x400
# ========== Step 3: TensorRT推理 ==========
def trt_inference(engine_path, input_data):
"""用TensorRT引擎做推理"""
import tensorrt as trt
import pycuda.driver as cuda
import pycuda.autoinit
# 加载引擎
logger = trt.Logger(trt.Logger.WARNING)
with open(engine_path, 'rb') as f:
engine = trt.Runtime(logger).deserialize_cuda_engine(f.read())
context = engine.create_execution_context()
# 分配GPU内存
input_shape = input_data.shape
d_input = cuda.mem_alloc(input_data.nbytes)
output_shape = (input_shape[0], 6, 2) # 假设输出6个waypoints
output_data = np.empty(output_shape, dtype=np.float32)
d_output = cuda.mem_alloc(output_data.nbytes)
# 拷贝数据到GPU → 推理 → 拷贝结果回CPU
cuda.memcpy_htod(d_input, input_data)
context.execute_v2(bindings=[int(d_input), int(d_output)])
cuda.memcpy_dtoh(output_data, d_output)
return output_data
# ========== Step 4: Benchmark对比 ==========
def benchmark(model_pytorch, onnx_path, trt_path, input_shape=(1,3,300,400)):
"""对比三种推理方式的速度"""
dummy = torch.randn(*input_shape).cuda()
num_runs = 100
# PyTorch FP32
model_pytorch.eval().cuda()
torch.cuda.synchronize()
start = time.time()
for _ in range(num_runs):
with torch.no_grad():
_ = model_pytorch(dummy)
torch.cuda.synchronize()
pytorch_time = (time.time() - start) / num_runs * 1000
# PyTorch FP16
model_fp16 = model_pytorch.half()
dummy_fp16 = dummy.half()
torch.cuda.synchronize()
start = time.time()
for _ in range(num_runs):
with torch.no_grad():
_ = model_fp16(dummy_fp16)
torch.cuda.synchronize()
pytorch_fp16_time = (time.time() - start) / num_runs * 1000
# TensorRT FP16
dummy_np = dummy.cpu().numpy().astype(np.float32)
start = time.time()
for _ in range(num_runs):
_ = trt_inference(trt_path, dummy_np)
trt_time = (time.time() - start) / num_runs * 1000
print(f"{'方式':<20} {'延迟(ms)':<15} {'FPS':<10}")
print(f"{'='*45}")
print(f"{'PyTorch FP32':<20} {pytorch_time:<15.2f} {1000/pytorch_time:<10.1f}")
print(f"{'PyTorch FP16':<20} {pytorch_fp16_time:<15.2f} {1000/pytorch_fp16_time:<10.1f}")
print(f"{'TensorRT FP16':<20} {trt_time:<15.2f} {1000/trt_time:<10.1f}")
面试中一定会问的: "你的模型推理延迟是多少?能达到实时吗?"
你需要准备的回答模板:
"我的规划模型在RTX 3090上,PyTorch FP32推理约15ms,转TensorRT FP16后降到约3ms,远低于实时要求的100ms(10Hz)。BEV编码器的推理时间较长,约50ms,但通过图像分辨率降采样和特征缓存可以优化到30ms以内。"
Day 8-9:INT8量化
什么是量化?为什么要做?
FP32(32位浮点):精度最高,但最慢最费显存
每个参数占4字节 → 1亿参数 = 400MB
FP16(16位浮点):精度略降,速度翻倍
每个参数占2字节 → 1亿参数 = 200MB
INT8(8位整数):精度再降,速度再翻倍
每个参数占1字节 → 1亿参数 = 100MB
车端芯片(如Orin-X)的INT8算力远高于FP16/FP32
所以量化到INT8是车端部署的标准操作
概念解释:量化的精度损失
FP32用32位表示一个数,能表示非常精确的小数(如3.14159265)。INT8只用8位,只能表示-128到127之间的整数。量化就是把FP32映射到INT8的过程——需要找到一个合适的"缩放因子"(scale),使得映射后的误差最小。
好的量化方法能把精度损失控制在1%以内,但推理速度提升2-4倍。这就是车企部署时必须掌握的技能。
"""
quantize_int8.py
PTQ(训练后量化)示例
"""
import torch
from torch.quantization import quantize_dynamic, prepare, convert
# 方法1:动态量化(最简单,适合MLP类层)
model_int8 = quantize_dynamic(
model,
{torch.nn.Linear}, # 只量化Linear层
dtype=torch.qint8
)
# 方法2:TensorRT INT8量化(需要校准数据集)
# trtexec --onnx=model.onnx \
# --saveEngine=model_int8.trt \
# --int8 \
# --calib=calibration_cache.bin # 校准缓存
# 校准数据集:用100-500张真实数据跑一遍,
# TensorRT会统计每一层的数值分布,找到最佳的量化参数
Week 3(第13周):面试准备——技术深度 + 系统思维
Day 10-11:必须准备的50个面试问题
第一类:基础概念(10题)
Q1: BEV感知的核心思想是什么?BEVFormer是怎么实现的?
A: BEV把多视角图像统一到俯视图空间。BEVFormer用空间交叉注意力——
在BEV网格上预设查询点,通过相机内外参投影到各摄像头像素位置取特征,
再用时序自注意力融合历史帧信息。
Q2: 为什么VAD比UniAD更高效?
A: VAD用向量化表示替代栅格化表示——车道线用折线段而非像素图表示,
信息密度更高、计算量更小。推理速度提升2.5倍,碰撞率降低29%。
Q3: 一段式和两段式端到端的区别?
A: 两段式先训练感知再训练规划(如UniAD/VAD),感知误差无法被规划纠正。
一段式所有模块同时训练(如SparseDrive),规划的loss可以反传到感知,
让感知学会关注对规划有用的信息。
Q4: 什么是Mode Collapse?扩散模型怎么解决?
A: MSE回归只能输出一条轨迹,遇到多种合理选择时会输出"平均轨迹"
(不合理)。扩散模型能生成多条候选轨迹,每条对应一种驾驶模式,
再用碰撞检测等约束选最优的。
Q5: VLA和传统端到端的根本区别是什么?
A: 传统端到端只能模仿训练数据中的模式,遇到没见过的场景就懵了。
VLA引入了大语言模型的"世界知识"和推理能力,能像人一样分析
"前方有施工→应该绕行"——这种推理不需要在训练数据中见过施工场景。
第二类:技术深度(15题)
Q6: BEVFormer的空间交叉注意力和标准交叉注意力有什么区别?
Q7: Deformable Attention的核心创新是什么?为什么用它?
Q8: nuScenes的标注频率是多少?为什么选2Hz而不是更高?
Q9: NAVSIM的PDMS指标里EP为什么是乘法关系而不是加法?
Q10: DiffusionDrive的截断扩散策略为什么只需要2步去噪?
Q11: DDPM和Flow Matching的核心区别是什么?
Q12: GRPO和PPO的区别?GRPO的优势在哪?
Q13: VLA中的CoT SFT和普通SFT的区别?
Q14: QT-Former是怎么压缩多帧视觉信息的?
Q15: 为什么ORION用VAE而不是直接让VLM输出坐标?
Q16: Transformer的自注意力计算复杂度是多少?怎么优化?
Q17: ResNet的残差连接为什么有效?
Q18: Adam优化器和SGD的区别?什么时候用什么?
Q19: Batch Normalization和Layer Normalization的区别?
Q20: 什么是梯度消失/爆炸?怎么解决?
第三类:工程化(10题)
Q21: PyTorch模型转ONNX时常见的坑有哪些?
A: 动态shape支持(需要设dynamic_axes)、不支持的算子(需要自定义)、
控制流(if/else不能直接导出,需要用torch.jit.script)。
Q22: TensorRT的FP16加速原理是什么?
A: 把FP32的权重和激活值截断到FP16,减少一半的内存带宽和计算量。
现代GPU的FP16算力是FP32的2倍(Tensor Core),所以速度翻倍。
Q23: INT8量化的校准过程是什么?
A: 用一批有代表性的真实数据(100-500张),跑一遍前向传播,
统计每一层的激活值分布(min/max或直方图),
找到最优的scale和zero_point使量化误差最小。
Q24: 多GPU训练时,数据并行和模型并行的区别?
Q25: 如何处理训练中的OOM(显存溢出)问题?
Q26: 混合精度训练(AMP)的原理和使用方法?
Q27: 什么是梯度累积?什么时候用?
Q28: 分布式训练中的AllReduce操作是什么?
Q29: Docker在自动驾驶开发中的作用?
Q30: CI/CD在自动驾驶算法迭代中怎么用?
第四类:系统设计(10题)
Q31: 如果让你从零设计一个端到端自动驾驶系统,你会怎么做?
Q32: 你怎么看小鹏VLA和华为WA路线的区别?
Q33: 端到端系统的安全性怎么保证?
Q34: 数据闭环是什么?怎么设计?
Q35: 如果模型在某个corner case上表现差,你怎么排查和解决?
Q36: 训练数据中的标注噪声怎么处理?
Q37: 如何评估一个自动驾驶系统的泛化能力?
Q38: 模型上车后出了问题怎么回滚?
Q39: 仿真测试和实车测试的关系是什么?
Q40: 你对自动驾驶的未来技术方向怎么看?
第五类:你的项目(10题)
Q41: 介绍一下你的项目?(必问,准备2分钟版和5分钟版)
Q42: 你在项目中遇到的最大挑战是什么?怎么解决的?
Q43: 你的模型的推理延迟是多少?怎么优化的?
Q44: 你在NAVSIM上的PDMS是多少?和SOTA差多少?
Q45: 如果给你更多时间,你会怎么改进这个项目?
Q46: 你为什么选择DiffusionDrive而不是其他方法?
Q47: 你的VLA用的什么VLM?为什么选它?
Q48: 你在训练中遇到过loss不降的情况吗?怎么排查的?
Q49: 你做过哪些消融实验?结论是什么?
Q50: 你觉得现在端到端自动驾驶最大的瓶颈是什么?
Day 12-13:准备技术路线图讲解
面试中经常被问"你怎么理解自动驾驶的技术演进"。准备一个清晰的叙述:
自动驾驶技术演进路线(面试时画在白板上):
2020-2022: 模块化时代
感知(PointPillars/CenterPoint) → 预测(VectorNet) → 规划(Rule-based)
问题:模块间信息损失、累积误差
2022-2023: 端到端1.0——两段式
UniAD(CVPR23 Best Paper) → VAD(ICCV23)
创新:统一框架、Query-based架构
问题:BEV Dense计算量大、两段训练不能联合优化
2024: 端到端2.0——一段式
SparseDrive → DiffusionDrive(CVPR25)
创新:稀疏表示、扩散模型多模态规划
问题:纯模仿学习有mode collapse、缺乏推理能力
2025-2026: VLA时代
ORION(ICCV25) → 小鹏VLA2.0 → 理想MindVLA
创新:VLM推理能力 + 强化学习 + 世界模型
当前挑战:车端算力限制、推理延迟、安全验证
未来方向:
① 世界模型(生成式仿真)替代传统仿真器
② 强化学习(GRPO/PPO)超越模仿学习上限
③ 端云协同(云端大模型+车端小模型)
Week 4(第14周):简历打磨 + 模拟面试 + 投递
Day 14:简历撰写
简历中的项目描述模板
端到端自动驾驶系统全栈实现 2026.01 - 2026.03
────────────────────────────────────────────────
技术栈:PyTorch / BEVFormer / VAD / DiffusionDrive / Qwen2.5-VL /
TensorRT / CARLA / NAVSIM / nuScenes
• 复现BEVFormer多视角BEV感知算法,在nuScenes mini数据集上完成
3D目标检测推理和可视化,深入理解空间交叉注意力机制
• 复现VAD端到端自动驾驶框架,实现向量化场景表示和waypoints规划,
在nuScenes上完成开环评测
• 基于DiffusionDrive截断扩散策略,实现多模态轨迹规划器,
在NAVSIM基准上完成端到端评测
• 构建轻量VLA系统,基于Qwen2.5-VL-3B实现驾驶场景CoT推理
和轨迹预测,探索GRPO强化学习微调
• 完成CARLA仿真器闭环驾驶测试,录制演示视频,
实现TensorRT FP16加速(推理延迟降低X倍)
关键原则:用数字说话。 "完成了端到端系统"不如"在NAVSIM上PDMS达到XX分"。"做了模型加速"不如"TensorRT FP16将推理延迟从15ms降至3ms"。面试官需要量化的信息来判断你的水平。
Day 15-17:投递与面试
目标公司和岗位
第一梯队(算法深度要求高):
├── 小鹏汽车 — 端到端算法 / VLA算法
├── 华为智驾 — 端到端感知 / 规划算法
├── 理想汽车 — VLA算法 / 世界模型
├── 地平线 — 端到端算法 / 模型部署
└── 蔚来 — 感知算法 / 规划算法
第二梯队(工程化要求高,适合你的背景):
├── 比亚迪 — 智驾算法工程师
├── 元戎启行 — 端到端算法 / 数据闭环
├── 商汤/Momenta — 感知算法 / 部署
├── 德赛西威 — 智驾方案工程师
└── 纵目科技 — 泊车算法
投递渠道:
├── 公司官网(最正式)
├── Boss直聘(最快得到回复)
├── 内推(成功率最高——去自动驾驶之心社区找内推码)
└── 猎头(适合社招高级岗位)
Day 18-19:模拟面试
找一个同样在学自动驾驶的朋友,互相做模拟面试。如果找不到,对着镜子讲(或者录视频回看)。
2分钟自我介绍模板:
"面试官好,我是[名字],有10年Java/Python开发经验,过去也做过机器学习和计算机视觉的项目。最近3个月系统学习了自动驾驶端到端技术栈,从CARLA仿真入手,依次复现了BEVFormer、VAD、SparseDrive和DiffusionDrive,在NAVSIM基准上做了端到端评测。我还研究了VLA方向,跑通了小米的ORION框架,自己实现了一个基于Qwen2.5-VL的轻量VLA。工程化方面,我完成了TensorRT模型加速和INT8量化的实践。我的核心优势是既理解算法原理,又有很强的工程落地能力,这是我10年开发经验带来的。我对贵公司的[具体岗位]非常感兴趣,因为[具体原因]。"
Day 20-21:持续学习计划
拿到Offer不是终点,入职后还需要持续跟进前沿。建议关注:
必关注的信息源:
├── 论文:arXiv cs.CV + cs.RO 每周浏览
├── GitHub:OpenDriveLab、hustvl、autonomousvision
├── 社区:自动驾驶之心(知识星球/公众号)
├── 会议:CVPR / ICCV / NeurIPS / CoRL / ICRA
└── 公司技术博客:小鹏/理想/地平线的技术文章
需要持续深入的方向:
├── 世界模型(World Model)— 用于仿真和数据生成
├── 3DGS/NeRF — 用于场景重建和仿真渲染
├── 强化学习(PPO/GRPO)— 超越模仿学习的上限
├── 模型压缩与蒸馏 — 大模型上车的关键技术
└── 安全验证与形式化方法 — 自动驾驶量产的最后一关
恭喜!你已经完成了14周的完整学习路径
Week 1: CARLA环境搭建 + 第一辆自动驾驶车
Week 2: 数据采集 + 模仿学习 + 闭环测试
Week 3-4: BEV感知(BEVFormer)+ nuScenes
Week 5-6: 端到端(VAD)+ waypoints规划
Week 7-8: 一段式端到端(SparseDrive)+ 扩散模型(DiffusionDrive)
Week 9: NAVSIM评测基准
Week 10: VLA(ORION + Qwen2.5-VL + GRPO)
Week 11: 项目整合 + 演示视频
Week 12: 模型部署(ONNX + TensorRT + INT8)
Week 13: 面试题准备 + 技术路线图
Week 14: 简历 + 投递 + 模拟面试
你现在的能力:
✅ 理解从感知到规划的完整端到端技术栈
✅ 能复现BEVFormer/VAD/SparseDrive/DiffusionDrive等前沿算法
✅ 掌握VLA(当前最热门方向)的核心原理和实践
✅ 有NAVSIM + CARLA的标准化评测结果
✅ 具备TensorRT模型部署的工程化能力
✅ 有一个完整可展示的GitHub项目Portfolio
✅ 10年工程经验 + 自动驾驶算法理解 = 稀缺人才
去拿你的Offer吧。
为者常成,行者常至
自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)