资讯动态

Transfuser-202205:端到端自动驾驶的Transformer多模态融合实践

发布时间:2026/10/20 13:00:19 来源:尧图企业网站定制
2022年年中那阵子我在各种自动驾驶交流群里反复看到一个名字Transfuser。第一反应是又一个Transformer落地方案第二反应是一段式端到端这东西还没被吹爆吗等我把论文代码完整过了一遍又亲自在CARLA里把这个流程跑通之后才意识到它对当时主流技术路线到底意味着什么。简单说它直接把相机和多线激光雷达的原始数据丢进同一个网络在特征层面用Transformer做交叉注意力融合最终输出未来路点和控制指令中间不搞独立的物体检测、车道线提取。2022年5月这个版本正好是项目适配CARLA 0.9.14之后的一次完整训练配置更新所以很多复现的人会把它简称为Transfuser-202205。适合正在跟端到端、传感器融合方向的开发者也适合想从传统模块化方案往数据驱动方案转的同学这篇文章把模型原理、训练脚本、复现踩坑一次性讲透。1. 为什么2022年大家都在看Transfuser端到端方案的路线之争1.1 模块化方案和端到端方案的根本矛盾先说说当时的大背景。2022年之前业内量产自动驾驶主流还是模块化pipeline感知模块输出障碍物框、车道线、红绿灯预测模块算轨迹规划模块在这些抽象结果上做决策最后控制模块执行。听起来很合理但实际工程里最头疼的问题是信息在模块间传递时严重损耗。举个很常见的例子相机拍到路面上有一层薄薄的水渍激光雷达点云里能看出低矮路沿但感知模型在训练时可能根本没有这类标注所以输出到规划层的障碍物列表里压根没有它们。规划模块看到的是一个干净得有些失真世界。更麻烦的是感知误差会逐级放大——检测框偏了5厘米到预测模块变成轨迹偏移再到规划模块就可能产生一个危险的超车决策。这就像接力赛跑每一棒交接都有延误四棒下来跟对手的差距就被拉大了。端到端方案走的是另一条路从传感器原始数据直接学习控制指令。没有显式的物体框、车道线中间表示网络自己决定该看哪、该忽略什么。好处是信息链路最短坏处是训练难度爆炸。所以在Transfuser出现之前大部分人对端到端的印象还停留在小车上跑个模仿学习demo稍微复杂的城市路况就露馅。1.2 一段式和两段式的本质区别其实端到端内部也分两派。一派是两段式先用检测网络或者语义分割网络把传感器数据变成中级特征比如BEV语义栅格图再把这些特征喂给一个控制网络。Birds Eye View就是典型的感知编码器控制器两段式结构感知部分单独预训练控制部分单独训练两边不共享梯度。另一派就是Transfuser坚持的一段式从相机图像、LiDAR点云到最终的方向盘转角、油门刹车全部在同一个网络里反向传播。传感器编码器、融合Transformer、轨迹预测头、控制头所有子模块的梯度都共享训练时所有损失函数直接回传到输入端。为什么一段式让很多人觉得不可控因为传统工程思维追求中间结果可解释——你得能回答为什么在这里刹车。一段式网络中间出来的特征图你很难指着它说这是行人这是红灯。但Transfuser用实验结果证明了只要数据规模足够、任务定义清楚一段式不需要人为设计中间语义它内部的注意力机制会自己学会看该看的。最终效果比两段式更稳因为梯度贯穿整个学习过程感知部分也在为最终控制准确性调整自己。1.3 202205版本到底更新了什么很多初次接触的人会困惑Transfuser不是一个模型吗为什么标题里非要带个202205这实际上是项目组在迭代过程中的版本习惯。2022年5月这个时间点他们做了三件比较重要的事把整套数据收集流程迁移到了CARLA 0.9.14新版本模拟器里Town地图的布局、天气系统接口都有变化旧数据集不能直接复用。调整了训练配置场景采样策略里增加了环岛、U型转弯、行人横穿的比例之前模型在这几类场景下转弯失败率偏高。修了一版多传感器时间戳对齐的问题之前相机和LiDAR在高速场景下时序差个一两帧融合时会看着以前的点云下现在的方向盘。所以如果你在GitHub上看到202205这个标记意味着拿这套代码和配置重跑可以直接复现出那一版在公开仿真评测里的表现。对于做对比实验的人来说这个时间戳就是一把刻度尺。2. Transfuser的架构秘密Transformer和CNN不是二选一是互相打补丁2.1 相机和LiDAR在CARLA里分别怎么进网络先看单模态的部分。相机这边Transfuser取的不只一个视角。它会用前视、左前、右前等多路RGB图像每一路都过同一个共享的CNN骨干网络ResNet的某种变体提取空间语义特征。CNN在这个位置的作用很纯粹把图像里哪里有轮廓、哪里有纹理、哪里像障碍物这种局部信息压缩成特征图。因为CNN的卷积感受野是局部的天然适合处理图像的二维空间结构。LiDAR那边处理方式比相机更讲究。原始点云是一堆散乱的三维坐标点没法直接进CNN。项目里的做法是先把点云转到BEV俯视图按x-y平面划分成网格每个网格里统计高度值、点密度、强度等通道得到一张长什么样很像栅格地图的多通道俯视特征图。这张特征图再过另一个CNN骨干得到LiDAR分支的特征。到这里为止两个模态还是各走各的像两个部门分别写了份报告。接下来的问题就是怎么把这两份报告合起来而且合完不能打架。2.2 Transformer注意力在这里不是语言模型里的自注意力很多刚上手的人会误以为Transfuser的Transformer用的是语言模型那种序列中每个位置相互看的自注意力。其实不是。这里面用的是交叉注意力cross-attention操作逻辑完全不同。我打个比方自注意力是开会时所有人互相讨论每个人都发言、都听别人的而交叉注意力像是A部门带着问题去B部门查资料——A部门的每个查询query去B部门的键值key-value库里检索自己需要的信息拿回来融合。在Transfuser的融合Transformer里相机特征和BEV特征互为查询和键值库。相机图像里有丰富的纹理细节比如骑车人的轮廓、路沿的颜色变化这些信息去BEV特征里查这个位置在俯视图上对应的区域长什么样BEV特征拿着全局的几何布局去图像特征里确认这个位置是不是真的有东西。经过多层交叉注意力之后两个模态的特征在空间上对齐了。关键点在于叫transformer但没用位置编码是行不通的。项目里会显式地把空间坐标信息叠进注意力里否则模型分不清左上角的图像块对应BEV的哪个栅格。这个几何对齐能力是纯CNN融合做不到的——卷积只能在局部窗口内找对应关系遇到跨传感器、跨视角的对应它没有全局建模能力。2.3 从融合特征到驾驶指令的具体流程融合后的特征图会被压成一段固定维度的向量这相当于整个场景的摘要。在这个向量后面Transfuser接了两个输出头路点预测头输出未来若干秒内车辆要经过的一系列坐标点通常以车体当前位置为原点每个点带横向偏移和纵向距离时间上从前到后排列。有了路点序列就相当于有了一条期望轨迹。控制头直接回归方向盘转角、油门开度、刹车踏板的数值。训练的时候还额外做了一层离散化分类把转向预测拆成向左、直行、向右的分类任务和连续角度回归任务双管齐下让模型学到的控制信号更平滑。推理的时候有个细节模型先用自己的路点头给出期望轨迹然后交给一个下游的横纵向控制器去追踪。这个控制器可以用简单的PID也可以用带动力学约束的模型预测控制MPC。之所以不直接用模型输出的控制量是因为光靠神经网络直接输出刹车油门的抖动比较大跑在真实车上乘客会晕。先给轨迹再让轻量控制器去跟踪整个系统更稳。2.4 为什么选了Transformer而不是纯CNN多层融合这是我一开始最想问的问题。既然CNN也能做融合——两个分支的特征图在某个中间层做concat然后再堆几层卷积不就行了答案是纯CNN融合在复杂场景下会掉链子。从实验对比来看在简单直道和低速转弯路段CNN融合和Transformer融合差距不大但一旦进入有多个交通参与者、有遮挡、有强逆光的城市场景CNN融合的路线完成率断崖式下跌。原因不复杂CNN的感受野是局部的一个卷积核最多看周围K×K个像素范围两个传感器特征要在空间上建立远距离依赖关系非常吃力。而注意力机制让每个位置都能隔空取物直接看到另一个模态里的关键区域。另外一个很实用优点Transformer把特征当作一组token来处理对传感器数量变化不那么敏感。今天你可能只装了一个前视相机明天加装了四个环视相机只要把token数量加上去注意力模块能自适应处理不用大幅修改网络结构。3. 一段式训练的目标函数设计多任务监督和模仿学习是怎么拧成一股绳的3.1 数据从哪里来CARLA专家驾驶采集端到端训练最要命的是数据。Transfuser的数据全部来自CARLA模拟器里的专家驾驶系统autopilot。这个内置专家会给出安全、符合交规的驾驶行为在设定好的路线里不断开。采集的时候有几个关键点多地图多天气不是在单一地图里闷头跑而是在多个城镇布局、不同光照、不同天气晴天/雨天/大雾/夜晚下都采集让模型见过足够多变的场景。相机和LiDAR同步记录每一帧保存多视角相机图像、原始点云、路由目标点以及专家给出的方向盘/油门/刹车真值。路由目标怎么编码端到端不能真的零地图裸奔。每个路口往左、往右还是直行这个路由指令是外部给定的。Transfuser把路由目标点做成了embedding向量跟融合特征在高层拼接起来告诉模型接下来我要往哪走。这是很多一上来就搞端到端的人容易漏掉的部分——没有路由信息模型在一个多岔路口就会茫然。3.2 Loss函数到底拆成几块一段式训练不是简单输出和控制真值做个MSE。实际训练目标函数拆得很细我记得大致是这么几块转向预测一个离散化分类损失方向盘角度被切成有限个桶比如左、中、右加上一个连续回归损失。这样模型既知道大概该往哪边打又能学到精确角度。速度预测油门和刹车的回归用L1损失。轨迹点预测对每个路点坐标做平滑L1损失时间越靠后的点权重越低因为远期轨迹本身不确定性更大。辅助监督在特征输出上额外接了一些语义辅助头比如做物体检测或者可行驶区域分割。这些头只在训练时存在推理时丢掉。它起的作用是逼着编码器保留跟驾驶决策相关的结构化信息不至于为了拟合控制信号而把中间特征压缩成一个没有意义的黑盒。这套多任务设计对一段式训练意义重大整个网络从传感器原始数据到控制指令都是可微的所有任务损失会通过共享的编码器层和融合Transformer回传。也就是说路径点预测的错误、转向角度的误差、辅助语义分割的误差全部会调整融合注意力模块的权重。相比感知任务先训练好再固定住、控制任务单独跑的两段式Transfuser的每个模块都在为整体驾驶表现负责。3.3 训练避坑增广、平衡和灾难性遗忘训练过程里比较隐蔽的坑有三个。第一个是数据增广的语义一致性。相机图像可以做颜色抖动、随机裁剪、水平翻转这个简单。但BEV特征图如果也做随机旋转和平移必须保证它跟相机图像里的空间变换是一一对应的。两边的增广操作要同时做、参数一致否则等于是给模型喂了两份对不齐的矛盾数据融合模块直接学歪。第二个是场景采样比例。如果数据里90%都是直道模型很快学会反正直着开就行变道、环岛这类罕见但关键的行为一概不会。Transfuser的做法是设置场景采样概率人为提高复杂路口的出现比例。这也是为什么有人直接拿公开数据集重训一个效果不如原版——它们可能没注意到数据集里场景比例本身是调过的。第三个是灾难性遗忘。多地图数据混在一起训练时模型很容易学了新地图忘了旧地图的路况特征。解决办法是数据加载时做shuffle并且训练过程中用小的学习率退火cosine decay别一次性把学习率拉太低给特征提取层留出持续更新空间。4. 复现Transfuser的实操链路从CARLA数据到Benchmark分数4.1 环境准备和版本配套如果现在就想去复现先把环境配齐。我踩过一遍之后推荐这套组合操作系统Ubuntu 20.04或22.04都行Windows上CARLA也能跑但后面多进程并行处理会很别扭别自找麻烦。Python环境3.8或3.9配合PyTorch 1.12以上版本即可不必追最新版。CARLA版本严格匹配0.9.14。版本不对会直接导致数据集采集脚本报错或者加载地图接口不兼容。硬件我一开始用的单张24GB显存的显卡batch size调到16勉强能跑。如果手头有40GB或80GB的卡一个默认配置的batch size 32能直接跑起来省很多心。目录结构建议清爽一点CARLA服务器程序单独放一个文件夹项目代码单独放一个文件夹数据集单独放一个大硬盘目录。别把数据集和代码混在同一个目录里后面预处理的BEV缓存文件体积会很大。4.2 官方训练管线那一套脚本的顺序整个复现流程像流水线一样按固定顺序执行别跳步启动CARLA服务端用subprocess方式从Python里拉起CARLA服务器而不是手动开两个窗口。手动开容易遇到进程假死而且无人值守跑十几个小时采集时窗口一崩全白干。数据采集运行数据收集脚本指定目标城镇、天气列表、交通流量参数。这个过程会生成HDF5格式的原始数据集每个场景一个文件里面打包了相机图像、点云、路由点和控制真值。BEV预处理把原始点云转成BEV栅格特征这一步很吃CPU和内存。如果你在采集完直接训练数据加载环节CPU会一直满载GPU反而闲着。我建议把预处理好的BEV特征单独缓存成numpy数组训练时直接读缓存速度能快好几倍。训练主模型加载HDF5和预处理好的BEV缓存开始跑多任务损失训练。训练脚本会周期性保存checkpoint记录loss曲线。Benchmark验证用官方验证脚本在保留的测试场景上跑闭环评测看车辆能不能完整到达终点、有没有违反交规、有没有碰撞。这就是最后发论文时用的指标。可视化用route plotting脚本把预测的路点序列画出来跟真值轨迹叠在一起看偏差。每一步耗时都不短。我自己的经验是数据采集一晚上能收几百个场景预处理再花几个小时训练在中端单卡上要两三天起步。所以这个项目不适合今天拉下来明天出结果要复现就留出至少一周时间。4.3 最容易踩的三个坑我复现过程中踩掉三层皮先说最疼的三个坑一是CARLA服务端和Python客户端版本错位。如果你系统的Python环境里多装了一个别的地图的CARLA库会导致运行数据采集时卡死。最后我是把CARLA安装在干净目录、用绝对路径启动并且专门给项目建了一个独立conda环境才解决。坑二是BEV预处理内存爆炸。原始点云数量大多进程预处理时如果每批次攒太多帧内存直接拉满机器进入swap地狱。解决办法是限制同时预处理的场景数分批次写入磁盘释放中间变量。坑三是验证指标随机性大。单条路线跑一次失败不能立刻断定模型有问题。CARLA世界里的车辆、行人行为本身有随机性同一个模型同一条路线跑五遍结果可能三成五成。标准做法是用多seed、多个不同起点终点组合算平均路线完成率和平均碰撞率再下结论。4.4 从指标回推模型哪里出了问题跑完benchmark拿到分数不等于完事关键是要知道差在哪。我自己总结了一套排查逻辑很土但很管用如果总在变道时失败比如骑线压线甚至冲出车道优先去可视化融合Transformer的注意力图看模型的注意力有没有对BEV目标产生足够的关注。注意力权重的热力图能直接告诉你是重在了图像还是重在了LiDAR。如果总在路口转错方向大概率是路由embedding和目标点融合出了问题检查路由信息有没有被后续层稀释。如果总撞静止的障碍物比如路边停靠的车辆、施工锥问题集中在LiDAR分支对静态障碍物的感知缺失。可以调高BEV高度通道的权重或者在辅助语义头里增加静态障碍物分类的监督。如果速度控制特别抖说明控制头回归的尺度没学稳可以把控制头的分类分支权重调大让控制器输出更偏向离散桶的中心轨迹会更平滑。这些排查手段在纯两段式系统里不太用得上因为你可以直接去调检测模块的阈值。但端到端模型就只能通过可视化特征和输出来定位看指标的病灶在哪里。5. 2025年回头看Transfuser它给端到端自动驾驶留下了什么5.1 一段式从非主流变成了主流之一把时间拉回到现在再回头看2022年的Transfuser它的历史位置比当时看起来重要得多。它之后出现的很多新模型——比如BEV感知系列、VAD这类向量化端到端方案——走的路子基本都能看到Transfuser的影子多模态输入进特征融合网络、输出结构化轨迹、后端接控制交互。那个时代大家对一段式的最大顾虑是训练的不可解释性所以当时两段式在量产车里还是主流。随着后续数据采集手段和数据量大幅提升端到端模型的可训练性和泛化能力已经今非昔比。现在新提出的方案里一段式已经不是什么需要特别解释的异类了。你可以批评它数据需求大、闭环验证难但已经很少有人质疑传感器原始输入能不能直接学出控制指令这个基本命题——Transfuser把这个命题从口号变成了有完整工程实现的东西。5.2 在CARLA平台上的副作用刷榜问题是把双刃剑另一个值得说的点是Transfuser的广泛传播和CARLA排行榜的流行是互相成就的。它在排行榜上的亮眼表现让这个模型被大量引用也让CARLA benchmark变成了端到端方向的默认试验场。但这里有个副作用很多后续工作开始盯着排行榜指标做优化。有些模型把规划的reward单独拿出来做强化学习调整在特定地图和天气状态下表现很好换一个新的城镇布局就露馅。我在实际项目里看过一些在CARLA上刷到高分的模型跑到真实感更强的场景里转弯明显保守、对动态障碍物的反应迟钝。所以说CARLA分数是重要参照但别把它当成这个模型能上路的证明。仿真环境和真实世界的domain gap永远存在。5.3 我在后续项目里的三点体会Transfuser跑完之后我又陆陆续续做了好几个端到端相关项目回过头来想想有三件事是真正沉淀下来的多模态融合不是堆一个Transformer就完事查询和键值的设计要跟数据形态匹配。相机特征和BEV特征的分布差异极大硬拼在一起不如明确让一个当提问者、另一个当资料库。这个思路后来我用到点云和毫米波雷达融合上一样管用。端到端模型的debug方式要换一套。传统感知可以画框、可以数准确率端到端想定位问题只能靠可视化特征和设计消融实验。我当时是把几个模块的中间输出全部导出来做成网页交互界面才能一个个排除问题。想做端到端方向的人建议提早把可视化工具链搭起来不然后面调优寸步难行。最后是闭环仿真测试的必要性。单帧预测准确实在说明不了太多很多模型转向预测挺准、路点也挺准但放进闭环里一跑一个小偏差就累积成大事故。Transfuser从一开始就把闭环benchmark当核心指标这是个非常好的工程习惯。做端到端项目千万别只看离线指标沾沾自喜。如果现在有人问我入坑端到端自动驾驶该从哪开始我还是会首推复现一次Transfuser。它的代码量不算小但每个模块都清晰可读数据链路、训练链路、评测链路完整是一套少有的三段全齐的参考实现。把那套流程跑通你对多模态融合、模仿学习、闭环评测的理解会有一次实质性的提升。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑