Apollo仿真平台如何Hold住99.9999%的复杂场景?

1,876 阅读17分钟

作者|百度自动驾驶事业部毛继明
成稿|奇琳
编辑|Emily

本期 AI 前线社群分享我们很高兴邀请到了百度自动驾驶事业部的毛继明,为我们带来《适用于自动驾驶的分布式仿真平台》的干货分享。

首先给大家介绍下今天的讲师:毛继明,百度自动驾驶事业部资深架构师,自动驾驶事业部仿真团队技术负责人。 目前重点关注分布式自动驾驶仿真平台的构建以及百度内无人车仿真技术的研发。在分布式系统架构方面拥有丰富的经验。

本次分享主要为以下五个方面的内容:

  • 一、仿真产品的业务价值

  • 二、如何达到真实性

  • 三、如何完成更全面异常检测

  • 四、智能辅助驾驶和全自动无人驾驶的区别

  • 五、全面的无人车能力判定

一、仿真产品的业务价值

仿真器,顾名思义,用软件模拟真实。但是在 Apollo 中,对仿真平台的定位是不仅仅是真实,而是要能够进一步:能够发现无人车算法中的问题。因为在整个算法迭代闭环中,光有拟真是不够的,还需要能够发掘问题,发现了问题后才能去 fix 问题,也就是回到了开发过程。

如此这样,从开发到仿真再回到开发,仿真平台跟我们的开发过程串联成一个闭环。只有闭环的东西才能构成持续迭代和持续优化状态。所以仿真平台在整个无人车算法迭代中的地位非常重要。

如上所述,仿真平台的功能。

发现问题,进行功能拆解的话,可以拆成有因果关系的两部分:

先要能够真实,接下来要能够进行全面的异常检测。真实性,就是说要能够对世界进行数学建模;全面的异常检测,其中最难的是“全面”二字,这要看我们对“全面的异常”的定义。

二、真实→客观世界的数学建模

客观世界的真实性表达依赖于三部分:静态环境的真实性、动态环境的真实性、车辆行为(也就是主车)真实性。

准确来说,对于静态环境的真实建模本身并不难,比如游戏画面中,我们能经常看到“照片画质”的渲染,看着都很真。最难的是“成本”两个字,这个成本指的是:单位公里上全部环境建模的时间成本。无人车的场景重建跟游戏中不一样。游戏中是艺术家是造出的场景,它不考虑真实。而真实仿真器中的场景是要跟真实世界做 diff 的,需要做到毫厘不差。

(1)静态环境的真实性

静态环境是相对于动态障碍物而言的,比如道路(包括各种地面元素)、栅栏、红绿灯、路旁的路灯和绿植两侧的高楼。对于自动驾驶来说,它们属于背景元素。当然大家能够理解这跟行人、车辆等动态障碍物的不同。

大家都有过这样的经验,我们自己得到一个结果,这很简单,但若要让你得到一个跟别人一模一样的结果,这个成本就大太多了。百度内部有成熟的百度高精地图制作流水线,在厘米级精度的世界刻画能力的基础上,成本做到非常低。

那么大家会问,我讲了这么多地图生成的事,这跟仿真有什么关系?其实,Apollo 仿真器的静态世界的表达,正是直接使用了 Apollo 高精地图数据。所以它是真实的,且是具有足够低成本的。

(2)动态环境的真实性

然后是动态环境,也就是各种障碍物的行为真实性了。动态障碍物引入了人的因素,相对静态场景重建更难,因为人的行为“难以捉摸”。对于 Apollo 而言,最快和直接的做法,不是拟真,而是直接“真”。

用实际路上采集回的海量真实数据,经过 Apollo 感知算法,做动态场景重建。一方面,我们通过 Apollo 数据生态,会得到更多的数据用来补充场景,另一方面我们利用自身持续迭代的感知算法可以更精准的还原世界。从量和质上都得到持续的提升。

(3)车辆行为的真实性


主要分传感器模拟和车辆动力学模拟。由于传统的商业仿真软件在这两个领域已经进行了数十年的研发,成果已经被各大车厂所认可。Apollo 倡导开放能力、合作共赢,不应该也不可能重复造轮子,自己新搞一套别人已有的东西。所以这两块功能 Apollo 仿真平台是以直接 involve 商业仿真软件的方式实现这两块 feature。后面在讲开放性的时候会提到。

三、全面的异常检测

在满足了真实性后,我们来看看如何完成下一个需求:更全面异常检测。

其实大家都知道,尤其是搞 IT 的同学可能会更清楚。所谓异常检测,就是先给一个条件,再给一个预期输出。就是大家写的 UnitTest 的常用版型。方法论上都是一样的。那么对于无人车的异常检测,什么是条件呢?就是车辆运行的场景。什么是预期输出?就是要有一整套判定准则或者说判定算法。

那么很显然,要做到全面的异常检测,这里重点或者说难点,肯定不在后四个字,而在于前面两个字“全面”。场景,要是全面的场景;判定,要是全面的判定。

全面的场景。全面这两个字很虚,而且“100% 全面”在理论上也无法达到。所以很显然,唯一可行的做法是:在受限场景下逼近 100%。这个“受限场景”,换种说法,就是我们无人车算法的问题域定义,也就是说这个算法要解决哪一种受限场景。不同的应用场景,仿真器的设计可能会大有不同。目前以我的理解,能够对仿真器设计产生革命性变化的,只有一种问题域的划分方式,就是智能驾驶 vs 无人驾驶。具体怎么个革命性变化,后面会讲。

全面的判定。这个取决于算法能力域的设计。什么叫算法能力域?就是指算法能达到的上限,也就是说,是 just work,还是 work well。对于判定算法而言,如果仅仅是做“just work”级别的判断其实并不难,难在对“work well”做判断。所以这里,也有一个对仿真器算法产生重大影响的能力域的划分方式,就是: “机器人型驾驶”(just work)的判定,以及“拟人型驾驶”(work well)的判定。

四、智能驾驶 vs. 无人驾驶

准确来讲,无人驾驶属于智能驾驶的一个分支。这么写可能不太确切。但是,我想强调的是,无人驾驶和自动驾驶之间的有一个非常大的差异,就是:是否有人。

“是否有人”这个事情,对整个智能驾驶无论是算法、还是硬件设计、还是仿真器的设计,都产生了极大的影响。“没有人来保底”决定了算法需要应对的占比从 80% 到 99.9999%。大家都了解 28 法则。从 80% 到 99.9999%,无论是算法、还是硬件、还是仿真,需要解决的问题或者说面临的困难要提高几个数量级。

五、复杂城市道路 +99.9999%

99.9999% 是无人驾驶特有的要求。而 99.9999% 需要的是算法“见多识广”。要解决长尾问题,也就是要应对全自动无人驾驶的 99.9999% 的场景 handle 能力,必须要累计起【海量场景】。

也许大家对海量场景这个事情并没有太多感觉。在实际的生产领域,拥有海量场景其实不是难事,难在海量场景的使用效率。我在前面讲了,算法需要高速迭代,我们的用户需求是:30 分钟,仿真平台能告诉我什么。30 分钟,大家算算,平均时速 30km/h,只能跑 15 公里,如果是这种能力的话,其实不用谈海量场景。

所以从百度内部最开始进行无人车项目时,就在着手考虑仿真平台的运行效率。Apollo 仿真平台通过 2 个不同层次的实现方式来进行大幅度优化。从宏观角度出发,通过大规模分布式化来进行;所以在 Apollo 仿真从最开始,就是以分布式仿真作为方向的。从微观角度出发,通过动态变速仿真来进行。

六、大规模分布式的架构设计思考

这个是分布式仿真框架的简图。了解分布式计算框架的同学应该看这个比较眼熟。整体上看,分布式仿真架构按层次和功能,可以按照如下几部分进行说明:

由于分布式仿真平台的计算模型很像传统的 MapReduce。所以整个分布式调度 follow 传统的 MR 架构。

下层是 Hardware Resource Scheduler。由于仿真节点的运行会用到 GPU+CPU/only CPU/CPU+FPGA 多种硬件组合,又由于仿真的运行是一种弹性的资源使用。所以我们单独的剥离出来一层 Hardware Resource Scheduler。这层 Scheduler 是支持更换的。比如在百度内部,我们使用了百度内部已有的资源调度器 Matrix,如果是在开源系统里,我们支持使用 K8S,再比如我们跟 Microsoft azure 合作的 Apollo Simulation Global 中,我们使用了 MS 的 cosmos。未来如果做大客户定制化,我们也可以支持大客户内部专门的 Resource Scheduler。

上层是 Batch-job Scheduler。因为分布式仿真运行模式为 Batch-job,所以我们单独剥离了一层 Batch-job Scheduler。它负责 job 的整个生命周期的运行状态的推进,比如各种部署、启动、运行状态检查、重试、优先级、弹性伸缩……等逻辑。这块同样的,我们单独剥离出一层的原因在于,我们解耦了这层标准化的分布式计算模型,也允许根据用户特别的需要进行替换。在内部我们使用了百度的 Normandy 调度框架,在外部我们支持更换成业界主流的 K8S 等。

中间这层是仿真核心。它运行在 Docker container 中。仿真核心中运行的是客户的算法 + 仿真逻辑:包括场景重建 + 动力学模型 + 精细化度量。由于运行模型复杂,所以我们在 Container 内抽象了上下两层:上层,我们内部叫做 Task Engine,专门负责复杂的仿真执行流程调度。下层是 Sim-Core,用来放置用户的自己的算法。

在外层有两个 Storage Component:Scene Store,Result Store。围绕着计算,统一管理了数据。Simulation-platform 主要提供了提交接口、数据分析、Dashboard 接口,串通起完整的仿真流程,供用户使用。

七、动态变速仿真技术

这里做一下对比,真实道路情况下,车载算法是在车载电脑上运行,此时实时性要求很高,所以往往需要保留较多的系统资源冗余(以应对随时到来的系统处理颠簸的情况),万一出现颠簸状态,实时系统会采用丢帧的方式以保证运行时消息处理的低延迟。

在仿真系统里,这是在离线运行。如果不做任何处理,我们需要用更强力的服务器,保留更多的系统资源,或者降低运行速率,以保证不丢帧。很显然,这种做法一方面带来大量的运行资源的闲置,另一方面降低了我们的运行速度。所以我们引入了动态变速仿真技术。

动态变速仿真技术,本质上是对无人车复杂数据流进行流控的过程。分解来讲:

1)对于处理时间较短的帧,压缩了数据处理的间隔;

2)对于处理时间较长的帧,等待处理完成再继续处理后续的帧。而整个调度系统是一种根据当前处理帧的耗时做弹性变化。

通过这两项改造,可以达到:不等待 & 不丢帧,这样就可以充分的利用硬件资源,以最快速度运行。据实际测试,采用了动态变速仿真技术,在不影响仿真结果的前提下,单机仿真效率可以提升数倍以上。

八、全面的无人车能力判定


从自动驾驶的能力上看,能力分成两个层面:低端能力(能 work)以及高端能力(像人一样 work well),所以从能力判定的算法上,会有较大的不同。后一种(高端能力级别的判定)很显然是非常有挑战的。

我们先看一下低端的能力判定方法,它包括了两层判定:

Level1:模块的运行可靠性判定。类似模块的 coredump、非法 exit、帧率异常等。

Level2:无人车基础能力的判定。包括:到达目的地、碰撞、违章等。

很显然,这样的两层判定可以通过“通用的规则”来实现。但是此时的通过仅仅代表了无人车能力的下限已经达到。此时无人车仅仅是能够像是机器人一样进行驾驶。

既然有低端能力,就对应有高端能力。何为高端能力?——像自然人一样开车,可以通过图灵测试。它仍然包括了两层判定:

Level3:体感判定。体感判定包括了横摆角,顿挫感等评估体系。

Level4:心理感受。心理感受包括了心理安全感以及迟钝感等。

高端能力的判定。可以是一种图灵测试的验证,是场景特化的。它代表了无人车的能力的上限。

实际上,度量算法的本质可以认为是:f(场景描述,车辆轨迹),即某种场景和轨迹的二元函数。当我们拥有大量的正例以及负例,我们通过机器学习方法,基于大量数据,是可以得到一种具有足够泛化能力的,并且能够达到图灵测试判定能力的度量能力。

事实上,百度长期的无人车路测,使仿真拥有了大量的实际的运营 / 路跑数据,我们针对性的大量采集、标注了细粒度的体感异常的 badcase 样本,进而可以达到相当精准的异常判断能力。我们会在 Apollo 里将这样的能力释放给大家。

由于时间有限,本次内容分享到这里就结束了。更多学习资料和自动驾驶相关内容,大家可以关注 Apollo 开发者社区的公众号来获取,欢迎大家在这里沟通交流!

Q&A 环节
Q1: 能详细说说 General rule 和 rule-based

A1:这里的 general rule 是指“通用规则”。简单来讲,碰撞、到达目的地、交规违规,这些可以认为是“最基础的无人车能力”的判定。1)他们是通用的,在各个场景都应当存在且适用;2)他们可以用简单的规则加以描述,来判断无人车算法是否异常。所以称之为 rule-based。

Q2: 可以说一下真实场景数据是怎么应用到仿真环境中的吗?真实场景数据是不变的,怎么交互呢?是提取场景中交通参与者的行为模式吗?

A2: 这个问题非常好。其实百度在做的仿真平台的目标是能够提供给,达到商品级别的自动驾驶系统提供更高级的稳定性 / 安全性保证。所以才有了,我们是基于真实路况的真实数据,供给给算法做测试。

那么这种回放型,其实是一种静态的“环境重建”。此时“重构的环境”与“无人车算法”,是无法实现“与人博弈”的。目前,据我所知,全球只有 waymo 的无人车驾驶算法里,才有“与人博弈”的概念。

目前来看,支持“与人博弈”的仿真场景,有一种实现方案,我们在内部称之为“多主车平台”,即一个充满着虚拟障碍物(人、车)的虚拟世界。把我们的算法放在“虚拟世界”里,与其他车辆进行博弈运行。

但是这里有一个最大的前提,是要想达到期望的“博弈效果”,与你博弈的车辆必须是“足够像人的”。否则你会在与一个“机器人”进行博弈。这种“错误博弈”产生的无人车算法,上路会更加危险。当前“足够像人”这个前提,还非常难以证明。我们选择了一个更保守的回放型方案。

所以在百度内部,确实拥有“虚拟世界”这样的产品,还仅仅正在试用阶段。未来我们也会开放这样的仿真器产品给大家。

Q3: 老师您好,我有个问题,在动态环境的真实性这部分提到“用实际路上采集回的海量真实数据,经过 Apollo 感知算法,做动态场景重建”,麻烦问一下,采集回来的数据是什么形式的?图片还是环境状态数据;这块提到的 Apollo 感知算法是什么算法?

A3: 采集回来的数据是“lidar、camera、radar、gps”等全部数据的 fusion 后的数据。

因此包括点云(流)、图片(流)等数据部分。

感知算法的输入是“原始传感器数据”,输出就是这个世界的逻辑化表达。因此百度拥有的强大感知算法使得我们可以对这个世界进行低成本(因为是通过算法自动进行的),高精度的还原和重建。

Q4:CPU+FPGA 的硬件组合中,算力如何调度?

A4: 这块是离线的硬件资源调度方面的方法问题了。事实上在研发阶段,无人车算法往往是重 CPU-usage,轻 FGPA-usage。(当然量产后应该会反过来,大概率会把 fpga 切换到 asic 芯片)。所以如果简单的将所有算法构成一个完整包,部署在 cpu+fpga 机器上,会使得 cpu 压力很大,而 fpga 压力低,从而浪费 fpga 的算力。

因此我们会将车端“融合在一起的算法”剥离成 cpu+fpga 部分算法 以及 only-cpu 部分算法两块。通过模块在不同配置(cpu+fpga, only-cpu)的机器上的调度,更充分的使用 fpga 卡的计算能力,增加整个集群的吞吐。


更多干货内容请关注微信公众号“AI 前线”,(ID:ai-front),回复“公开课”可获得AI前线历史直播课程。