该示例为参考算法,仅作为在J6上模型部署的设计参考,非量产算法。
1. 简介
轨迹预测任务的目的是在给定历史轨迹的情况下预测未来轨迹。这项任务在自动驾驶、智能监控、运动分析等领域有着广泛应用。传统方法通常直接利用历史轨迹来预测未来,而忽略了预测目标的上下文或查询信息的影响。这种忽视可能导致预测精度的下降,特别是在复杂场景中。
本文将介绍轨迹预测算法QCNet在地平线征程6平台上的优化部署。
2.性能精度指标
模型参数:

性能精度表现:

3. 公版模型介绍
由于轨迹预测的归一化要求,现有方法采用以agent为中心的编码范式来实现空间旋转平移不变性,其中每个代理都在由其当前时间步长位置和偏航角确定的局部坐标系中编码。但是观测窗口每次移动时,场景元素的几何属性需要根据agent最新状态的位置重新归一化,不断变化的时空坐标系统阻碍了先前计算编码的重用,即使观测窗口存在很大程度上的重叠。为了解决这个问题,QCNet引入了以查询为中心的编码范式,为查询向量派生的每个场景元素建立一个局部时空坐标系,并在其局部参考系中处理查询元素的特征。然后,在进行基于注意力的场景上下文融合时,将相对时空位置注入Key和Value元素中。下图展示了场景元素的局部坐标系示例:

QCNet主要由编码器和解码器组成,其作用分别为:
编码器:对输入的场景元素进行编码,采用了目前流行的factorized attention实现了时间维度attention、Agent-Map cross attention和Agent与Agent间隔的attention;
解码器:借鉴DETR的解码器,将编码器的输出解码为每个目标agent的K个未来轨迹。
3.1 以查询为中心的场景上下文编码
QCNet首先进行了场景元素编码、相对位置编码和地图编码,对于每个agent状态和map上的每个采样点,将傅里叶特征与语义属性(例如:agent的类别)连接起来,并通过MLP进行编码,为了进一步生成车道和人行横道的多边形级表示,采用基于注意力的池化对每个地图多边形内采样点进行。这些操作产生形状为[A, T, D]的agent编码和形状为[M, D]的map编码,其中D表示隐藏的特征维度。为了帮助agent编码捕获更多信息,编码器还考虑了跨agent时间step、agent之间以及agent与map之间的注意力并重复多次。如下图所示:

3.2 基于查询的轨迹解码
轨迹预测的第二步是利用编码器输出的场景编码来解码每个目标agent的K个未来轨迹。受目标检测任务的启发,采用类似detr的解码器来处理这种一对多问题,并且利用了一个递归的、无锚点的proposal模块来生成自适应轨迹锚点,然后是一个基于锚点的模块,进一步完善初始proposals。相关流程如下所示:

4. 地平线部署优化
整体情况:
QCNet网络主要由MapEncoder, AgentEncoder, QCDecoder构成,其中MapEncoder计算地图元素embedding,AgentEncoder计算agent元素embedding,核心组件为FourierEmbedding和AttentionLayer。
改动点:
优化FourierEmbedding结构,去除其中的所有edge_index,直接计算形状为[B, lenq, lenk, D]的相对信息r;
将AttentionLayer中的query形状设为[B, lenq, 1, D] , key形状为[B, 1, lenk, D], r形状为[B, lenq, lenk, D],利于性能提升;
4.1 性能优化
4.1.1代码重构
FourierEmbedding将每个场景元素的极坐标转换成傅里叶特征,以方便高频信号的学习。 但是公版QCNet 使用了大量edge_index索引操作, 使得模型中存在大量BPU暂不支持的index_select、scatter等操作。QCNet参考算法重构了代码,去除了FourierEmbedding中的所有edge_index,agent_encoder编码器注意力层的query形状设为[B, lenq, 1, D] , key形状为[B, 1, lenk, D], r形状为[B, lenq, lenk, D],相关代码如下所示:
4.1.2 FourierConvEmbedding
为了提升性能,主要对FourierConvEmbedding做了以下改进:
Embedding和Linear层全部替换为了对BPU更友好的Conv1x1;
删除self.mlps层中的LayerNorm,对精度基本无影响;
- 将公版代码中的torch.stack(continuous_embs).sum(dim=0)直接优化为了add操作,从而获得了比较大的性能收益。
对应代码如下所示:
4.1.3 RAttentionLayer
为了提升性能,去除 RAttentionLayer的对相对时空编码r的LayerNorm,相关代码如下:
4.2 量化精度优化
4.2.1 FourierConvEmbedding
4.2.2 量化配置
首先使用QAT的精度debug工具获取量化敏感节点,然后在Calibration和量化训练时,对20%敏感节点配置为int16量化,相关代码如下:
4.3 不支持算子替换
4.3.1 cumsum
代码路径:
/usr/local/python3.10/dist-packages/hat/models/models/task_moddules/qcnet/qc_decoder.py
4.3.2 取余操作
公版:
参考算法:
5.总结与建议
5.1 index_select和scatter算子
J6仅支持index_select和scatter等索引类算子的CPU运行,计算效率较低。QCNet通过重构代码的形式,优化掉了index_select和scatter操作,实现了性能的提升。
5.2 ScatterND算子
模型中 nn.embedding操作引入了目前仅支持在CPU上运行的GatherND算子,后续将考虑进行优化。
附录
- 论文:QCNet
公版模型代码:https://github.com/ZikangZhou/QCNet



