简介
Dense 多任务感知是在统一的稠密空间特征上,联合完成多个感知任务的模型设计。在自动驾驶中,通常将多视角图像转换到鸟瞰视角(Bird’s Eye View,BEV),得到具有统一空间坐标的特征,再通过不同任务头分别输出目标、道路结构与空间占用信息。
常见应用包括:
- 动态目标感知:车辆、行人、骑行者等目标的类别、位置、尺寸、朝向和运动信息,为预测与规划提供输入。
- 静态障碍物感知:交通锥、隔离栏等道路设施的定位和识别。
- 在线地图构建:车道分隔线、人行横道、道路边界及停止线的识别,补充道路结构信息。
- Occupancy 感知:以体素语义描述周围空间,补充目标框之外的场景信息。
本模型采用 Dense BEV,主要为了让检测、地图和 Occupancy 共享统一的空间特征,满足稠密占用预测对场景覆盖的需求,避免仅使用实例级 Sparse query 时另建稠密特征分支。整体采用“Dense 共享 BEV + 任务专用 Adapter+ Sparse query 任务头”结构。
性能精度指标
性能指标
模型 | 输入大小 | backbone | bevsize(H×W) | mapsize(H×W) | occsize | J6M Latency | J6M FPS |
|---|---|---|---|---|---|---|---|
bev_multitask_henet_tinym | 6×3×512×960 | HENet-tinym | 128×128,0.8 m/格 | 100×50,0.8 m/格 | 100×100,0.8 m/格 | 74.77ms | 13.41 |
精度指标
任务 | 数据集 | Metric | Float | Calibration |
|---|---|---|---|---|
动态目标检测 | nuScenes | NDS / mAP | 0.4554 / 0.3141 | 0.4479/0.3084 |
静态目标检测 | nuScenes | NDS / mAP | 0.4872 / 0.5333 | 0.4843/0.5294 |
Occupancy | nuScenes | MeanIOU | 0.3422 | 0.3401 |
离散地图 | nuScenes | NDS / mAP | 0.4803 / 0.3342 | 0.4758/0.3297 |
在线矢量地图 | nuScenes | mAP | 0.5487 | 0.5401 |
各任务预测类别如下:
- 动态目标检测(8 类):汽车(car)、卡车(truck)、拖车(trailer)、公交车(bus)、工程车辆(construction_vehicle)、自行车(bicycle)、摩托车(motorcycle)、行人(pedestrian)。
- 静态目标检测(2 类):交通锥(traffic_cone)、隔离栏(barrier)。
- 离散地图(1 类):停止线(stop_line),由独立任务头预测。
- 在线矢量地图(3 类):分隔线(divider)、人行横道(ped_crossing)、道路边界(boundary),不包含停止线。
- Occupancy (18 类):others、barrier、bicycle、bus、car、construction_vehicle、motorcycle、pedestrian、traffic_cone、trailer、truck、driveable_surface、other_flat、sidewalk、terrain、manmade、vegetation、free(不计入评测)。
模型介绍
暂时无法在飞书文档外展示此内容
- 动态与静态目标检测:均使用 DenseBEVSparseHead,从 BEV 特征采样并迭代细化目标框,分别预测 8 类动态目标和交通锥、隔离栏两类静态目标;通过历史实例缓存模块(MemoryBank)融合时序信息。
- Occupancy:裁剪共享 BEV 的中心区域,通过二维卷积、上采样和高度维展开生成体素语义预测。
- 离散地图:基于完整 BEV,通过 query 解码预测停止线的二维定向框。
- 在线矢量地图:裁剪地图区域,通过 MapTR 解码器预测车道分隔线、人行横道和道路边界,每条地图实例由 20 个二维点表示。
地平线部署说明
模型优化
本模型共享图像特征提取与 BEV 生成。主要结构设计、参考模型及区别如下:
模块 | 参考链接 | 设计特点 | 性能优化点 | 精度优化点 | 区别点 | 对应代码 |
|---|---|---|---|---|---|---|
图像特征提取 | henet_tinym HENet_v3.0 | 使用地平线自研高性能backbone |
| 无,复用 HENet-tinym backbone 配置 | heal/models/backbones/henet.py heal/models/base_modules/fpn.py | |
BEV 特征生成 | 将当前帧的多相机特征转换为共享 BEV,供各任务使用 |
|
|
| heal/models/task_modules/bevformer/view_transformer.py heal/models/task_modules/bevformer/encoder.py | |
动态/静态目标检测 | bev_sparse_henet_tinym bev_sparse_v3.0 | 基于共享 BEV 特征,通过独立的动态、静态检测头预测目标,并利用MemoryBank 融合时序信息; 训练使用 DN 去噪分支(部署时不使用) | - | - |
| heal/models/task_modules/sparsebev/dense_bev_head.py heal/models/task_modules/sparsebev/det_blocks.py heal/models/task_modules/sparsebev/memory_bank.py |
在线矢量地图 | maptr_sparse_henet_tinym MapTR_v3.0 | 基于共享 BEV 特征,通过实例 query 预测地图类别与点集;训练增加地图要素区域的辅助分割监督(部署时不使用) |
| 训练时增加了三种学习约束:
|
| heal/models/task_modules/maptr/decoder.py heal/models/task_modules/maptr/instance_decoder.py |
Occupancy | flashocc_henet_lss_occ3d FlashOcc_v3.0 | 基于共享 BEV 特征,对每个平面网格位置的不同高度层分别预测类别,生成三维空间占用结果。 |
|
| heal/models/task_modules/flashocc/decoder.py heal/models/task_modules/flashocc/bev_occ_head.py | |
离散地图 | — | 基于共享 BEV 特征采样,由独立任务头预测停止线的二维定向框,描述其位置、范围和朝向 | - | — | heal/models/task_modules/bevformer_decoder/decoder.py |
其他代码路径见附录.B
模型训练
Adapter设计
多任务包括动态障碍物检测、静态障碍物检测、Occ、在线矢量地图和离散地图要素。
障碍物检测更关注局部细节,Occ 和地图任务更关注特征的平滑性与空间连续性,各任务的梯度传递到共享 view_transformer 时可能产生冲突。因此,在共享 BEV 与各任务头之间设置独立的轻量 Adapter,学习任务专用的特征调整,缓解不同任务对共享特征的梯度冲突。
Adapter 由两层卷积组成,通过残差连接保留原有 BEV 信息:
各任务的 Adapter 不共享参数,输出通道数和空间尺寸保持不变。
前向计算以 Occ/地图任务为例:
训练策略
任务可以被分为以下三类:
- 动态障碍物/静态障碍物:关注 BEV feature 的局部特征,比较稀疏。
- Occ:关注密集、平滑的特征。
- 在线矢量地图/离散地图:关注平滑的特征,需要更高的空间连续性。
实验观察到:
动态障碍物/静态障碍物与 Occ 联合训练时,动态障碍物/静态障碍物的 mAP 会轻微下降(1~2 个点),但 NDS 能保持单任务水平。即特征变平滑影响了检测,但 mAVE 有改善,使得 NDS 不掉点。
动态障碍物/静态障碍物、Occ 与在线矢量地图联合训练时,动态障碍物/静态障碍物指标掉点非常严重,说明在线矢量地图的加入对障碍物检测影响较大。
如果使用异源数据,需要增加一个所有任务联合训练的阶段,并冻结 BN。
因此,设计了三阶段训练策略:
阶段 | 训练策略 | 训练步数 |
|---|---|---|
Stage 1 | 动态障碍物、静态障碍物、Occ、离散地图联合训练,得到一个 checkpoint | 基准训练步数 |
Stage 2 | 加载 Stage 1 的 checkpoint,仅放开 MapTR head,其余模块冻结 | Stage 1 步数 × 0.5 |
Stage 3 | 五个任务联合训练,学习率降为 Stage 1 的 1/5,同时降低除在线矢量地图 head(MapTR head) 外的其他 head 及 backbone 的学习率 | Stage 1 步数 × 0.2 |
- Stage 1:加入离散地图要素,是因为 nuScenes 中的离散地图要素大部分是较小的框,对前三个任务的影响不大。
- Stage 2:让 MapTR head 先适应 Stage 1 的 BEV feature,后续放开共享特征训练时会更稳定,避免一开始就更新 BEV feature,使其偏向在线矢量地图任务。
- Stage 3:障碍物检测与在线矢量地图任务之间存在相互制约,使用较少的训练步数取得综合较好的效果即可,也可以使用极低的学习率继续训练。
实验数据可参考:
训练策略 | 超参配置 | 模型表现 | |
|---|---|---|---|
直接联合训练 |
![]() |
| |
多阶段训练 | stage1 |
![]() |
|
stage2 |
| ||
stage3 |
![]() |
| |
Loss 权重设计
多任务训练中需要为每个任务设置不同的loss权重。权重参数调整的核心点在于希望不同任务的梯度传递到共享层时数量级基本相当,即不同任务对共享层的影响相当,不会出现被某几个任务带偏的情况。
确定权重步骤:
每个任务loss权重设置为1,多任务联合训练一定的step数(比如10000)。
加载上一步的参数,每个任务单独跑500个step,统计在view_transformer上的梯度norm值。
按照梯度norm值设计权重,在梯度norm值*权重后每个任务的数量级基本相当,最后再根据联合训练时各个任务的指标微调权重。
交付版本的配置为:
任务 | Stage 1 | Stage 2 | Stage 3 / 默认完整模型 |
|---|---|---|---|
动态检测 | 4 | — | 4 |
静态检测 | 2 | — | 2 |
Occ | 90 | — | 96 |
离散地图 | 2 | — | 2 |
MapTR | — | 1 | 1.1 |
训练总损失由任务内部各子损失乘以任务级权重后汇总。例如 Stage 3:
模型量化
模型使用 int8 + int16 混合精度量化配置,辅助分支因为不参与部署,保持 float32 不量化。
qconfig配置 | 代码配置 |
|---|---|
INT8 基础模板 | 全局 qint8,Conv 输入/权重 INT8,Matmul 两输入 INT8 |
图像归一化后固定值域 | camera_net.backbone.quant:dtype=qint8、threshold=1.0 |
anchor使用高精度量化 | instance_bank.anchor_quant_stub:qint16、threshold=60、freeze=True |
基于debug结果对敏感算子配置高精度 | ModuleNameTemplate(sensitive_ops) |
总结与建议
部署建议如下:
- 根据性能和精度要求调整模型规模。可适当调整 BEV 大小、注意力采样点数(num_points)、query 数、 Encoder /Decoder层数、特征维度、高度层数等进行裁剪或扩容。调整后需同步检查 ROI、采样网格及任务输出的尺寸,并通过分任务精度和部署性能评测确认取舍。
- 使用任务专用 Adapter 适配共享特征。障碍物检测、Occ 和地图任务对局部细节、特征平滑程度及空间连续性的需求不同。各任务使用独立、不共享参数的残差 Adapter,在保留共享 BEV 的基础上学习任务所需特征,缓解不同任务对共享特征的冲突。
- 通过分阶段训练和冻结策略协调任务优化。多任务联合训练难以收敛或某些任务明显掉点时,可先训练基础任务,再冻结共享模块、训练新增任务头,最后以小学习率联合微调。Loss weight 应结合各任务的损失尺度和验证指标设置,避免某个任务主导共享特征更新;调整时同时观察原始损失、加权损失和分任务指标,不直接照搬其他任务或模型的权重。
- 不盲目增加 INT16 节点或照搬单任务 qconfig。结合敏感度结果与任务指标,为确有需要的节点保留高精度;在满足精度要求时,减少不必要的高精度覆盖,并复测部署性能。
附录
A. 参考链接
- 参考算法(modellabs)官网:https://oe.horizon.auto/labs
参考文档:
B. 代码依据
相对于 HEAL 仓库根目录:
文件 | 核对内容 |
configs/bev_multitask_henet_tinym/common.py | 输入、空间范围、类别、训练步数、march |
configs/bev_multitask_henet_tinym/model.py | 任务头、三阶段 loss weight、部署输入输出 |
configs/bev_multitask_henet_tinym/train.py | 优化器、学习率倍率、训练与校准流程 |
configs/bev_multitask_henet_tinym/data.py | 数据关联、增强、预处理、校准 batch size |
configs/bev_multitask_henet_tinym/callback.py | 指标、冻结模块、梯度裁剪、checkpoint |
configs/bev_multitask_henet_tinym/qconfig.py | INT8 基础模板、局部覆盖、校准及导出转换 |
configs/bev_multitask_henet_tinym/deploy.py | HBIR/HBM 配置和输入来源 |
configs/bev_multitask_henet_tinym/predict.py/ quant_analysis.py | 分阶段评测与精度分析入口 |
heal/models/structures/bevfusion_multitask.py | 纯相机执行路径、图外预处理与历史缓存 |
heal/models/backbones/henet.py | backbone 分辨率与特征选择 |
heal/models/task_modules/sparsebev/dense_bev_head.py/ det_blocks.py / decoder.py | 稠密 BEV 检测头、框编码、后处理默认值 |
heal/models/task_modules/flashocc/bev_occ_head.py/ decoder.py | Occ Adapter、上采样与输出重排 |
heal/models/task_modules/maptr/decoder.py / instance_decoder.py | 地图 Adapter、ROI、训练/推理 query 区别 |
heal/models/task_modules/bevformer_decoder/decoder.py | 离散地图部署输出 |
heal/models/base_modules/roi_feat_extractors.py | ROI 坐标顺序和裁剪规则 |
hat_engine/callbacks/checkpoint.py / hat_engine/engine/calibrator.py | best 保存条件与校准 skip_step 行为 |
三个单任务配置的 model.py / common.py | 与 bev_sparse、maptr_sparse、flashocc 的异同 |



