ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

类脑大模型赋能智能驾驶决策:逻辑思维与安全状态机设计

类脑大模型赋能智能驾驶决策:逻辑思维与安全状态机设计

做自动驾驶的人多少都有一种焦虑:感知模型越来越准,可在碰到长尾场景时,决策还是容易露怯。我最近完成了一个“面向逻辑思维的程序设计方法”项目,核心思路是把类脑大模型接进汽车智能驾驶的决策链路,让模型不只会“感觉”,还懂得先想清楚再动手。这个项目解决的核心问题,是当前自动驾驶系统在规则泛化和可解释性之间的长期矛盾;适合正在做决策规划、端到端算法以及车端部署的工程师参考,也适合对类脑计算感兴趣、想入行智能驾驶的读者。

我把项目从思路拆解、程序设计到部署实测的完整过程整理了出来,重点会讲清楚为什么“逻辑思维”在智能驾驶里不能缺席,以及类脑大模型到底在哪个环节起作用、怎么和传统规则栈配合。最后还会把我在仿真和实车调试中踩过的坑、总结的排查方法一并写出来,给大家少走弯路的参考。

1. 项目定位与总体思路

1.1 为什么要把逻辑思维放进智能驾驶

智能驾驶系统里,感知层现在基本是深度学习的天下,物体检测、车道线识别、语义分割的效果已经相当能打。可到了决策层,大家通常还在两条路线之间摇摆。一条是传统规则方案,比如有限状态机加确定性逻辑,好处是可解释、安全边界清晰,坏处是遇到没定义过的场景就会呆住;另一条是端到端大模型方案,从传感器数据直接映射到车辆控制,泛化能力不错,但它是个黑盒,出了事很难反推是哪里判断错了。

我在这个项目里没有二选一,而是把“逻辑思维”作为程序设计的第一原则。所谓逻辑思维,不是简单堆几个if else,而是把驾驶任务拆成可验证的因果链条,明确什么条件下做什么动作、为什么这么做,并用结构化的数据和控制流把它约束住。这样即便类脑大模型给出一个看起来合理的输出,也不会直接作用到方向盘和踏板上,而是必须先通过逻辑层校验。

这个设计的触发点,来自一次仿真里遇到的情况。车辆在十字路口左转,感知模块同时给了一辆直行的车和一位站在路边玩手机的行人,端到端模型犹豫了四五秒,最终停在路中间。从数据看,它知道自己“很困惑”,但它没办法表达困惑的原因,也没办法基于场景给出一个风险最低的临时决策。这件事说明,决策层需要至少两个能力:一是把场景抽象成关键事件,二是根据事件之间的因果关系做推理。这正是逻辑思维擅长的事情。

所以项目最终定下来的总体架构是三层,底层负责感知融合,中间层是类脑大模型驱动的场景理解与意图推理,顶层是一套严格的安全状态机。类脑大模型不是独裁者,而是顾问,它的推理结果必须落到顶层状态机允许的动作集合里。

1.2 类脑大模型在项目中承担什么角色

聊“类脑大模型”之前,先说明一下我的理解。它并不是在生物层面百分之百复刻人脑神经元,而是借鉴大脑的几个关键特性:稀疏激活、脑区协同、事件驱动和时间记忆。这些特性落到工程上,就是模型不会对每一帧所有像素做同样强度的计算,而是先选出少数关键信息,再调用不同功能子网络协同处理,同时保留时序记忆能力来理解“刚才发生了什么”。

在智能驾驶场景里,这个角色定位很清晰,我一共分配了三个任务。

第一是场景语义抽取。类脑大模型把摄像头、毫米波雷达、激光雷达和导航地图信息统一抽象成一组结构化事件,例如“前方60米有车辆减速”“右侧行人进入非机动车道”“车道线左侧虚线右侧实线”。这一步相当于把连续的高维输入压缩成有限个可推理元组。

第二是意图推测和风险估计。比如看到行人虽然站在路边,但视线朝向路面,模型要根据身体朝向、车速、车距、红绿灯状态推断横穿概率。这里不是简单给一个百分比,而是输出概率的同时附带关键依据,方便逻辑层检查。

第三是决策建议生成。模型输出建议动作,包括加速、保持、减速、变道、停车、鸣笛提示等,并给出建议置信度。这里特意不直接输出方向盘转角,因为横向控制细节应该由更底层的控制算法处理,大模型过于关注微观控制反而容易抖动。

有人可能会问,为什么不用普通的Transformer大模型?我确实在前期对比测试过,效果不差,但车端部署时有两个痛点:一是注意力计算量随序列长度非线性增长,车内芯片的功耗和散热撑不住;二是Transformer缺少明显的时序记忆机制,对“前者刹车、我也刹车、后面车跟得很近要注意追尾”这类连续推理,表现不如类脑结构下的稀疏脉冲建模。后面第三章我会写具体的模型选择和压缩方法。

2. 程序设计方法:面向逻辑思维的过程

2.1 从场景出发拆功能模块,而不是从网络出发

写程序最怕一上来就改网络结构。我看过不少团队,先租几十张卡,把模型训起来,再回头补业务逻辑,最后发现模型只能应对训练集里的场景。这个项目的第一步是坐在会议室里做场景清单,把所有能想到的驾驶场景按“感知复杂度”和“决策复杂度”两个维度铺开。

逻辑上用的是MECE原则,把场景拆成互不重叠又覆盖完整的集合。比如按道路类型分:高速直行、高速汇入、城市路口、施工区、小区窄路、地下车库;按交互对象分:机动车、非机动车、行人、静态障碍、突发动物;按环境条件分:晴、雨、雾、强光、夜晚、逆光。每个场景卡片里写清楚输入变量、可执行动作集合和成功标准。

一个典型的例子是“行人过马路”场景。输入变量包括斑马线位置、红绿灯状态、行人位置、行人速度、行人朝向、车辆速度、当前车道。成功标准定义为车辆能在距离行人至少1.5米处完全停止,或平稳减速通过,且没有造成后车急刹。这个卡片不仅给算法工程师看,也给测试工程师和标注团队看,大家对齐的是边界条件,而不只是几个指标数字。

这样设计的好处是,后续训练数据采集和模型微调都可以按场景卡片下钻。某个场景效果差,直接定位到对应模块,而不是把所有问题都扔给“提高模型能力”这个模糊目标。

2.2 用有限状态机加时序逻辑约束驾驶行为

有了场景卡片后,下一步是把驾驶行为抽象成有限状态机。状态集合我定义成六个:常态保持、路口通行、变道超车、跟车减速、停车等待、人工接管。状态之间的转移受事件触发,事件来自场景语义抽取模块,不同时满足触发条件就不能跳转。

举个例子,从常态保持切换到变道超车,至少需要四个条件同时成立,我用谓词公式表达为:

CanOvertake = LanesValid AND SafeGap AND NoSolidLine AND SpeedRangeOK

其中LanesValid表示当前车道和目标车道线清晰存在,SafeGap表示目标车道后方车辆距离大于安全阈值,NoSolidLine表示不是实线,SpeedRangeOK表示车速在允许超车的范围区间内。所有变量都是布尔值或布尔表达式的结果,程序里可以用一组成熟的断言函数去检查。

这里有一条铁律:类脑大模型只能作为状态内的动作建议器,禁止它直接修改状态机的状态变量。大模型输出“建议左变道”之后,状态机检查上述四个条件,如果有一条不满足,变道动作就会被硬性否决。有人觉得这样太保守,但实际跑下来,这套设计救了不少次测试。因为大模型的建议再聪明,也可能受感知噪声影响,把虚线误判成实线,或者对后方车辆的测距出现偏差,状态机就是最后一道安全防线。

时序逻辑同样重要。驾驶决策不是单帧问题,我专门维护了一个长度为3秒的“事件环”,保存最近发生的关键事件序列。程序卡车上要判断的事不是“现在有没有风险”,而是“风险是在增大还是在减小”。比如前车刹车灯亮起,紧接着刹车灯熄灭,但车辆间距还在缩小,这时候就不能因为灯灭就解除刹车指令,必须等间距重新拉大且持续0.5秒以上,才允许结束跟车减速状态。这个0.5秒实际上就是根据人脑反应时间加控制周期加传感器延迟一起算出来的。

2.3 因果链与不确定性表达

逻辑思维并不等于非黑即白,相反,好的逻辑设计会给关键判断加上置信度和因果关系。我在程序里引入了一个轻量贝叶斯推断器,专门处理感知层输出的多源信息。

以“行人是否要横穿”为例,我把行人朝向、行人速度、注视方向、是否在斑马线附近、是否有过马路的预备动作作为证据变量,计算横穿意图的后验概率。后验概率再与距离、车速做加权风险指数计算:

Risk = P(CrossIntent) * (V_vehicle + V_pedestrian) / Distance

如果Risk超过一定阈值,系统进入预减速状态,而不是等行人真的迈出一步才触发紧急刹车。这种方法的好处是,系统具备“提前量”,更接近有经验的驾驶员的操作习惯。

不确定性的表达也不能省。我在每个关键事件的元数据里都加了一个可信度字段,当感知模块对某个障碍物的置信度低于0.6时,状态机自动进入保守模式:优先减速,避免变道,并把场景标为“需人工复核”。这个策略来自真实的测试教训——有一次车辆在隧道入口因为光影急剧变化,把路面阴影误判成了障碍物,如果模型直接按刹车处理,后车很容易追尾。加入不确定性表达后,系统知道“这个障碍物可能是假的”,所以不会一脚刹死,而是先松开加速踏板、准备制动,等连续几帧确认后再执行全刹车。

3. 类脑大模型选型与算法细节

3.1 为什么选择类脑结构而不是纯Transformer

我在项目预研阶段做过三版对比实验。第一版是纯ViT(Vision Transformer)做场景编码,接一个标准GPT风格的决策头;第二版是CNN做感知,Transformer做时序融合;第三版是混合类脑架构,感知主干用轻量CNN,中间层用稀疏注意力,决策层用少量脉冲神经元网络。对比维度包括精度、延迟、功耗和可解释性。

纯Transformer的问题在第一版测试里就暴露了。自动驾驶场景每秒钟有10到30帧图像,每帧还要同时处理多个目标数据,Transformer在长序列上的自注意力矩阵计算量非常大。在NVIDIA Orin这样的车规芯片上跑起来,虽然能到实时,但功耗和发热量明显偏高,留给其他感知模块的算力就吃紧了。

第三版混合架构的思路是,先让CNN快速抽取视觉特征,再用类脑的Top-K稀疏注意力机制,每个时间步只保留响应最强烈的K个token参与全局交互。这相当于开车时你不会同时盯着窗外所有的广告牌、路灯和树叶,而是会不自觉聚焦在车道、车辆、行人、交通标志这些关键元素上。稀疏注意力把原先O(n^2)的计算量压到O(n*k),实测下来决策延迟降到原来的三分之一左右。

决策层用脉冲神经元处理时序记忆。脉冲神经网络的天然优势是把信息编码成“是否发生、何时发生”的事件序列,这跟驾驶场景里突发事件驱动的特点很吻合。比如前车刹车灯点亮这件事,本身就是个短时脉冲信号,神经网络只需在事件发生的时刻产生强烈的膜电位变化,而不是每个时间步都全量前向计算。

3.2 数据闭环与思维链生成

再好的模型设计,没有数据也白搭。智能驾驶项目里最稀缺的不是普通驾驶数据,而是“极端场景下的人类推理过程”。普通数据告诉你“驾驶员踩了刹车、转了方向盘”,但没告诉你“因为看到前车左后轮有压线趋势,所以预判它可能变道,提前收油”。这种推理过程,我在项目里叫“思维链监督信号”。

思维链数据的生成分两条线。一条是仿真线,用CARLA模拟器大量生产危险场景。另一个是真实数据线,我组织标注员对采集到的真实路测数据做原因标注,要求每人至少写出三个决策理由。比如对同一个刹车事件,一个人写“前方车辆急刹”,另一个人写“前方车辆刹车灯亮且距离小于15米”,第三个人写“行人从右侧进入视线”。三个人的描述会有差异,我们把高频出现的因果要素提取出来,再结合规则引擎自动生成伪思维链,最后由人工审核。

训练时,类脑大模型不仅学习输出动作,还要生成一段结构化的推理理由,比如“感知到前方车辆速度骤降和刹车灯亮起,当前车速偏高,因此减速并准备停止”。这里用到了一个技巧,推理理由不是为了让模型显得聪明,而是为了在部署时把决策依据记录下来,方便回传到云端做可视化复盘。

数据闭环体现在这里:每辆车在实际行驶中,影子模式会持续记录模型决策和真实驾驶员操作的差异。差异大的数据会被自动打上标签,上传到云端,经过清洗后进入下一轮微调训练。整个闭环周期大概是一周一次小更新,一个月一次大版本。

3.3 端侧大模型的压缩与部署

类脑大模型的参数量不能和云端通用大模型比。我最初的Demo模型是7B参数,在模拟器里效果不错,但放到车端根本跑不动。后来通过四步压缩,把端侧模型压到1.5B。

第一步是蒸馏,用7B模型作为教师模型,把中间层的特征分布迁移给1.5B学生模型。第二步是剪枝,根据注意力稀疏化的结果,把长期不活跃的神经元剪掉,这部分大概能减少20%参数量。第三步是INT8量化,把权重从FP16压缩到INT8,推理速度提升接近一倍,精度损失控制在1%以内。第四步是算子融合,把常用的LayerNorm、Attention中的多个算子合并成单核执行,减少显存读写次数。

部署方案上,我没有选择把所有逻辑一股脑塞进端侧。车端跑轻量模型,负责90%以上的常规场景;一旦模型输出的置信度低于阈值,或者状态机进入“场景不明”的异常状态,系统会把脱敏后的传感器特征上传到云端大模型做进一步分析,然后把结果下发回车辆。这个车云协同的链路有一个前提——必须容忍网络断线。所以我在车端设计了一套兜底策略:如果网络不可用,系统进入保守状态,按限速的一半行驶,并且增加安全车距,等待下一次云端反馈。

这里提一个容易被忽略的点:模型压缩不只是为了跑得快,更是为了让系统有足够的算力余量去运行规则安全层和日志回放服务。智能驾驶的安全是多层次的,如果为了塞大模型把算力吃满,反而会让安全监控程序无法实时运行,那就本末倒置了。

4. 实操过程与关键环节实现

4.1 搭建环境与工具链

项目底层环境我主要用了三样东西:PyTorch作为深度学习框架,CARLA作为自动驾驶仿真器,ROS 2作为中间件。选择CARLA而不是别的模拟器,是因为它开源且能自由设置天气、交通流、行人行为,并且提供了Python API做细粒度的场景控制,特别适合批量生成长尾场景。

环境搭建的简要步骤是,先在一台配备NVIDIA GPU的工作站上安装Ubuntu和CUDA,再通过conda创建Python 3.10虚拟环境,安装PyTorch和CARLA客户端库。仿真服务端和训练环境分开跑,单机多卡训练时用PyTorch的DistributedDataParallel做同步,数据预处理则由独立进程完成,避免训练进程因为数据读取卡IO。

ROS 2这块主要用于实车和仿真器之间的通信。我定义了一套自定义消息类型,比如感知目标列表、交通灯状态、状态机状态和控制指令。仿真器里的感知模块接收CARLA的输出,转成ROS 2话题发布,决策层订阅这些话题,再把最终控制指令写成ROS 2服务,驱动仿真车模型或者真实车辆控制系统。

新手容易踩的一个坑是版本对齐。CARLA版本更新很快,和PyTorch、ROS 2的接口经常不兼容,我建议直接把所有依赖版本写死在一个requirements文件里,并且用Docker把训练和仿真环境封装起来。我前后因为环境问题重装过三次系统,最后老老实实做了一套镜像,后续团队其他人复制镜像就能直接使用。

4.2 训练流程中的三个关键参数

训练过程中有三个参数是手工算出来的,不是调参师傅拍脑袋定出来的。

第一个是安全距离阈值。我用简化公式算:

SafeDist = v * perception_delay + v^2 / (2 * max_decel) + margin

假设车速v=20m/s,感知延迟1.2秒,最大减速度取-5m/s²,安全边际5米:

SafeDist = 20*1.2 + 400/10 + 5 = 24 + 40 + 5 = 69米

所以在高速场景下,系统至少要保持69米的车距。这个数值不是越远越好,太远会导致旁边车辆一直插入,增加决策次数,所以最终根据各路段的限速和典型车流密度做了动态调节。

第二个是决策超时上限。类脑大模型偶尔会遇到一个语义冲突,例如前车既像在减速又像是要变道,这时它可能需要更多时间做推理。我设定决策超时上限为500毫秒,超过这个时间无论是否产生结果,状态机都会启用保守预案:降低车速并保持当前车道,直到模型收敛出明确结果。

第三个是意图推理的置信度阈值。行人“假动作”很多,有人在路边打电话侧身,不一定要过马路;有人站在斑马线边反复看手机,可能是等人。我把横穿意图阈值设为0.7,当后验概率超过0.7才触发预减速。为了验证这个值合理,我统计了100组模拟行人数据,在0.7阈值下,真横穿场景的触发率是96%,滞留路人场景的误触发率只有4%。低于0.7会明显增加误刹次数,高于0.8则会漏掉部分起步前冲的行人。

4.3 模型性能实测记录

训练完成后,我在CARLA里搭了一条包含城市、高速、隧道和雨天的混合评测路线,跑了1000次重复测试。每次测试随机指定起点和终点,车流密度和天气也随机。主要统计三个指标:无碰撞率、平均接管率和平均决策延迟。

结果如下表所示:

  • 场景类型:城市路口;样本数250;无碰撞率97.2%;平均接管率1.6%;平均决策延迟85ms
  • 场景类型:高速汇入;样本数250;无碰撞率99.2%;平均接管率0.8%;平均决策延迟110ms
  • 场景类型:隧道/强光;样本数250;无碰撞率95.6%;平均接管率3.2%;平均决策延迟130ms
  • 场景类型:雨天复杂路况;样本数250;无碰撞率94.0%;平均接管率4.4%;平均决策延迟155ms

整体无碰撞率是96.5%,在所有测试中,真正需要人工接管并主动干预的平均占比是2.5%,剩下的接管事件是系统识别到自身置信度过低后主动发起的“邀请接管”,属于安全机制的一部分。

封闭场地实车测试也做了一轮,但规模不大,主要验证接口和控制指令的延迟。我记录到从传感器触发到制动指令下发的全链路延迟约为180ms,其中模型推理占80ms,CAN总线和执行器占100ms。这个数字在低速测试中是够用的,但如果在高速上遇到紧急事件,整体时延还需要进一步优化。实测中也发现,实车的悬挂系统对控制指令的反馈延迟明显高于仿真器,这提醒我必须把执行器延迟纳入决策超时计算,而不能只看模型输出时间。

5. 常见问题与排查技巧实录

5.1 模型决策和状态机冲突怎么办

第一个高频问题就是模型输出建议和状态机约束打架。典型场景是,模型建议向左变道避让前方静态障碍,但状态机检查发现当前车道是实线,于是否决变道。理论上否决是正确的,但模型重新推理出“停车等待”又需要时间,于是车辆会短暂地僵在路中间,后面的车都堵住。

我最终的解决方法是双通道融合。首先在模型训练时加入软约束损失函数,把状态机允许的动作集合作为一个Mask,让模型在训练阶段就要学会尽量只在允许动作里做选择。其次在决策运行时保留硬性否决权,不允许任何模型输出覆盖状态机安全条件。这两个机制同时生效后,冲突次数下降了80%。最关键的是,排查这类问题要建立冲突日志,把每一次状态机否决模型建议的事件都记录下来,包括当前状态、模型置信度和触发条件。每周复盘这些日志,会发现很多冲突其实源于感知层的错误,而不只是决策层的问题。

5.2 仿真能跑、实车乱来怎么办

这是仿真到实车迁移最常见的问题。仿真里模型表现很好,到了真实场地却频繁误判。我曾经在实车测试时,系统把路边一棵树的阴影当成了行人,连着触发了三次紧急制动,场面非常尴尬。

排查下来主要问题有三个。第一,仿真纹理和光照过于干净,模型学会了依赖一些噪声模式,到实车后这些模式不存在;第二,仿真传感器和真实传感器在标定上存在差异,尤其毫米波雷达点云的分布差异很大;第三,实车多了一整套底盘和CAN网络的状态信息,模型没见过这些特征。

解决方案也要分三层。传感器层面,我在仿真里加入了大量随机噪声、动态模糊和曝光扰动,做domain randomization,让模型见过足够“脏”的输入;训练层面,仿真数据只保留60%,另外40%用真实道路数据混合训练;部署层面,我特别重视影子模式,让模型在实车上只做实时推理和日志记录,不控制车辆,等离线对比结果达到阈值后才逐步切换到主动控制。两到三周的影子模式测试是非常值得投入的,宁可多花时间,也好过实车出了安全问题再补救。

5.3 标注数据不足和思维链质量低

思维链数据不可能完全靠人工标注,成本太高且标准不一。我先写了一个规则引擎,根据感知结果的序列自动生成初始推理理由,例如检测到前车刹车灯亮且间距缩小,就自动生成“前车减速导致本车需要减速”等理由。然后再交给标注员审核修稿,而不是让标注员从零开始写。这个方法把单条思维链的标注时间从三分钟缩短到三十秒,大幅提高了数据产量。

但自动生成的思维链容易变得套路化,缺乏层次感。后来我要求每条思维链至少包含三层意图:表层观察、因果推断、行动理由。例如,表层观察是“左前方有车打转向灯”,因果推断是“该车可能进入本车道”,行动理由是“所以本车减速让行,避免碰撞”。用这个模板约束后,思维链质量稳定了很多,模型也明显学会了解释自己的行为。

如果觉得思维链数据还是不够,可以试试数据增强的思路。在仿真器里用对抗扰动生成变体,比如把“前车急刹”改成“前车急刹且后车靠近”,模型需要同时解释多事件叠加;或者把“行人站在路边”改成“行人站在路边且突然低头看手机”,这种微妙的差异能逼模型学习更细粒度的因果关系。

5.4 模型推理时延抖动怎么处理

类脑大模型很难保证每次推理时间一致,特别是触发了大幅度场景变化时,注意力机制会调动更多token,推理时间可能从80ms跳到150ms。这种抖动对决策系统的稳定性是不利的,因为控制周期固定,不能因为某次推理慢了就让整个系统等待。

我做了两件事。第一,把模型推理拆成两段式,先用快速路径处理常规简单场景,不启动全局推理;只有快速路径的置信度偏低时,才启动完整推理。这样做90%场景的推理时间能稳定在60ms以内。

第二,给推理流程加超时中断机制。如果在规定时间内没有完成推理,就丢弃本次结果,沿用上一帧的有效决策输出,同时进入安全模式。这个机制听上去很简单,但实现起来要注意模型前向传播的线程管理,不能让中断操作造成CUDA上下文卡死。我踩过的坑是直接用Python取消线程,结果显存一直不释放,最后只能在每个关键节点设置纯Python级别的检查点,定时检查超时标志来退出循环。

以上这些问题,我在项目初期都逐一踩过。调试智能驾驶的决策系统,和写普通业务代码完全是两种体验,前者要求你在正确性之外还要考虑安全冗余和系统崩溃时的兜底策略。类脑大模型给了我很好的推理和泛化能力,但真正让它在车里可信赖的,还是那套不近人情的状态机和一次次从数据闭环里抠出来的边界条件。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进