本文首先会介绍无人车引擎的概念,并以仿真环境面临的挑战为线索介绍美团无人车引擎的核心设计。
01 引言
过去几年,自动驾驶技术有了飞速发展。国内也出现了许多自动驾驶创业企业,这些公司以百度开源项目Apollo为起点,大都可以直接进行公开道路测试,公开道路测试也成为促进技术进步的主要方法。基础问题得以解决之后,行业面临的更多是长尾问题,依靠路测驱动自动驾驶能力建设的方式变得不再高效,离线仿真的地位日益凸显。行业头部企业在仿真的投入十分巨大,Waymo公司2019年公布的仿真里程是100亿英里,是路测里程的1000倍。
相应地,美团无人车团队在仿真上的投入也在逐渐增大。在仿真平台的建设中,团队发现公开道路测试和仿真测试看似相似,实际上差异巨大:在车载环境下,为了确保系统的稳定运行,通常要保证一定资源处于空闲状态;仿真环境则不同,如何高效利用资源,如何实现压榨资源的同时确保仿真结果与路测结果一致成为了关键目标。在应对这些挑战的过程中,美团提出了无人车引擎的概念,将车载与离线环境的差异隔离起来:功能模块无需任何更改便可以满足两种场景的需要。
02 无人车引擎
概念
无人车引擎是自动驾驶的基础设施,在机制、工具和计算模型上对功能模块提供支持,隔离自动驾驶所处环境,使各功能模块专注于自身功能。
在机制层,他为各功能模块提供通信、调度、数据、配置、异常监控等支持;
在应用层,引擎为各功能模块提供调试、可视化、性能调优、效果评估等工具支持;
在模块层,引擎为各功能模块提供统一的计算模型和运行环境,确保他们在车上环境、分布式环境、调试环境下的行为一致。
美团无人车引擎的架构图如下:
图1 无人车引擎布局
如图1所示,作为引擎支撑的主要部分,Perception、Localization、Planning等是自动驾驶系统中重要的功能模块,它们实现了无人车系统的核心功能。引擎则在机制和工具,上下两个方向上支撑他们:各功能模块按照引擎的规范开发,直接或者间接地使用引擎机制层提供的功能并自然而然地获得工具的支持。比如,功能模块只要使用引擎的通信工具,就能直接获得数据落盘、性能报表调试信息可视化的支持,同时基于这些路测数据,在仿真环境下,功能模块会自动获得单步调试、效果评估等功能支持。
自动驾驶引擎面临的挑战
图1中所列举的功能是引擎的基础组成部分,引擎所提供的远不止于此,对于多种环境的支持才是美团无人车团队引入引擎概念的真正原因。前面提到,无人车首先运行在车载系统中,随着技术和环境的变化,更多地运行于仿真环境下,二者截然不同。车载环境下,无人车系统的运行环境较好,为了保障各功能模块能够正常运行,CPU、GPU、内存等资源要提供一定程度的冗余。
而仿真环境的要求完全不同:从用户的角度看,仿真的用户是工程师,他们期望仿真任务能够在确定时间内完成尽量多的任务;从集群的角度看,他们希望仿真能够尽量提升资源利用率。接下来的部分将介绍无人车系统在这两类环境下会面临哪些挑战,以及美团无人车团队如何通过引擎应对这些挑战。
03 行为一致性的挑战
早期,美团无人车团队依赖于ROS搭建无人车系统,在车载环境下,ROS的表现合格。然而在开始仿真建设后,团队遇到很多问题,其中最突出的是“行为一致性问题”,这个问题具体是指:无人车系统在运行过程中,当出现系统资源的变化,行为也随之发生变化。比如,当仿真任务在一台机器上运行时,系统产生的结果和这台机器的状态有关,这台机器被独占地使用或是和其它任务同时运行,结果会有差异。而且,即使不考虑资源利用率,让仿真任务独占机器资源,同一个任务运行两次,结果也会有微弱的扰动。
更严重情况发生在离线环境,此情境追求资源利用率的最大化,意味着计算资源的十分紧张,扰动将变得不再轻微,结果将变得更不可靠,仿真的结果也就失去了价值。
因此,如何在车上和离线两套截然不同的环境下确保结果的一致性,是仿真引擎必须解决的问题。此问题由以下两个原因造成:一是功能模块时序的不一致;二是功能模块内部执行的不一致。
时序一致性
为了介绍什么是时序一致性,首先要介绍一下无人车系统中时序的概念。
无人车系统由多个功能模块组成,功能模块之间有数据依赖关系,比如 Perception 依赖于Lidar、Camera的数据,Prediction依赖于Prediction的输出。不同模块的触发条件不同,比如Planning是依据时钟触发的而Prediction是依赖于Perception的数据触发的。由数据关系和触发条件形成的功能模块的执行顺序就是自动驾驶系统的时序。在理想情况下,每个模块都能在满足触发条件时立刻执行并在预期的时间内完成任务,也就是说,只要保留各模块的输出就可以完全复现线上的问题,离线仿真出现的问题在路测时也必然出现。
图2 无人车系统理想时序
然而现实情况远比这复杂,举例来说,当无人车经过拥堵路段时,Perception需要处理的数据会显著增多,Planning也可能因为交通参与者过多导致耗时增长,时序必然与理想情况不符合。如下图3所示,在车载环境下这种行为方式是没问题的,然而在仿真环境时却会导致严重后果:每一次计算环境的些许变化都有可能导致时序的变化,进而导致系统行为的差异。
图3 无人车系统实际时序
这就是时序一致性问题。为了解决这种问题,美团无人车引入了调度器,时序的一致性由调度器保证。此外,引擎按照不同的应用场景,进一步细化了调度器的种类。其中最简单的调度器是“在线调度器”,它的目标只有一个:在功能模块处于Ready状态时执行它,车载系统中就是使用的这种调度器,它的行为方式也与 ROS 类似,不过他会记录下调度时序以备使用。除此之外,引擎还提供一组离线调度器,以应对不同的使用场景。这里在线和离线的差异根据数据来源判断,如果数据来自传感器那么就是在线调度器;如果数据来自路测记录那就是离线调度器,具体分类如下图4所示:
图4 调度器分类
以下是美团无人车引擎提供的调度器种类及他们的使用场景:
在线调度器:在满足触发条件时立即触发功能模块,通常在车载环境下会使用。
复现调度器:按照调度器保存的调度信息复现调度时序,在调试时或复现路测场景时使用。
理想调度器:按照理想时序调度资源,通常在仿真时使用。
条件驱动调度器:在条件满足时调度功能模块运行。在这种调度方式下,功能模块的调度密度介于理想调度器和复现调度器之间,他的实现也相对简单,是应用最广泛的调度器。
在他们的帮助下,功能模块执行的时序就能得到保障:只要调度器和输入数据不变,那么无论计算环境如何变化,各功能模块的执行时序总能保持一致。
功能模块的计算模型
时序一致性除了需要调度保证之外,功能模块的内部计算必须是受到调度器调度的。功能模块必须在调度器允许时才能开始执行,在结束时调度器能得到通知。如果存在脱离调度器之外的计算线程,那么系统的一致性必然无法保证。为此,引擎引入了标准计算模型,任何一个功能模块都有应该遵守这个计算模型,从而获得引擎包括一致性保障、单步调试支持、信息可视化等功能的支持。
标准计算模型如下:每一个功能模块都有且仅有一个计算过程并以迭代为单位,每一次调度完成一帧的计算。当然引擎并不控制帧计算内部的细节,帧计算内部的优化由功能模块负责。
图5 功能模块的标准模型
标准模型的定义并不一定符合每一个功能模块的实际情况:比如Localization,它订阅多类频率不同的传感器数据并以不同的频率输出。在实践中,引擎通过对Localization功能的重新拆分实现了标准化。此外,对于像Perception这类计算量很大、同时兼具异构计算的功能模块来说,多线程,异步I/O的机制必须引入,引擎同时提供了相应的支持确保符合标准模型。
在实践过程中,美团无人车团队花费了相当时间来完成这些改造。改造完成后仿真结果的权威性得到了加强,更重要的是:系统的行为不再受外部资源(GPU、CPU、内存等)的影响,这也为离线环境提升资源利用率扫清了障碍。接下来介绍无人车引擎如何在功能模块完全无感的情况下提升资源利用率。
04 资源利用率问题
前面提到过,车载系统和仿真系统环境差异很大:车载系统为了追求系统的平稳运行会保证关键资源有一定程度的富裕;对于仿真系统,保留idle就是对资源的浪费。在系统的一致性得到保障之后,资源利用率才能成为引擎的优化目标。优化资源利用率包含了很多方面,比如数据调度等,由于篇幅所限,这里只介绍与引擎相关的优化工作。接下来的部分,将根据无人车系统在仿真环境运行时的特点进行优化,他们分别是资源需求不均、功能模块的重复计算、GPU/CPU计算不平衡。
数据需求不均匀
从数据的输入规模上讲,各功能模块是极不均衡的:Perception和Localization依赖于 Lidar和Camera数据,数据使用量占到系统的 85% 以上(按照数据存储的规模计算,忽略中间数据,具体比例与开启的Camera相关,此处给出概数)。从资源消耗上讲,Perception和Prediction消耗较多的GPU计算资源。为了提升云计算资源的效率,无人车引擎必须支持分布式部署:即一套自动驾驶系统分别部署与多台机器甚至是跨机房的机器之上的。
图6 分布式部署
为了实现分布式部署,引擎参考了计算图模型的概念,采用了类似于Tensorflow的设计:将功能模块分成了Node和Module两个部分。其中Node负责定义依赖关系,而Module负责完成计算。对于远程部署的Module来说,引擎提供了ADVContext和 Node Stub的概念用于协助Module完成运算,对于Module而言,它对于自身处于环境(远程或者本地)一无所知。
图7 Stub Nude
基于图7的设计,自动驾驶系统有了分布式部署的能力:一套自动驾驶系统可以运行于一组机器之上。提升离线效率的努力不再局限于单台机器,无人车系统的离线优化获得了更多的手段和更广的空间。
重复计算
仿真任务分成多种类型,即有运行单个模块的任务,也有同时执行Perception、Prediction、Planning的任务。对于同时运行多个Module的任务,放在集群的角度看,很多计算都是重复的。试想一个场景:Planning引入新方法,工程师希望能够在最新 Perception版本上的获得新方法的效果评估结果。对于仿真而言,这是一个经典场景,常用的方法是离线执行Perception、Prediction和Planning三个模块并执行Evaluation产生报表、评估结果。
图8 分模块Evaluation
一般而言,Perception的结果受到数据和本身算法迭代的影响,当Planning的迭代时,Perception的结果不会受到影响,它的输出完全可以复用。得益于Node和Module概念的分离,Perception Node所绑定的Module完全可以是一个非计算单元,而是一个数据服务 Module。
在美团无人车数据平台和无人车引擎共同努力下,通过Data Service Module, 这个常见的仿真任务的流程在工程师感知不到的情况下变成了图9这样。不同版本的 Perception的输出结果被保存下来,Prediction和Planning只要使用之前的结果,避免了 Perception的反复计算。
图9 数据复用
GPU计算分流
无人车系统是一个同时具备重度CPU计算和重度GPU计算系统,两部分的计算是不平衡的。引擎为了提升GPU资源的利用效率,在内部集成了模型管理的功能同时提供了本地和远程两种Prediction的机制。再结合分布式部署方式,系统可以完全部署于 CPU集群之上,模型相关的计算可以通过RPC请求在Model Serving上完成。通过GPU和CPU计算的隔离,引擎帮助提升了GPU和CPU计算资源的利用率。
05 结论
在持续的实践中,美团无人配送团队抽离出一套自动驾驶引擎,为功能模块提供机制和工具的同时,它还提供了对车载(低时延)和仿真(高吞吐)两套环境的适配。此外,配合美团的大数据基础设施以及在此基础之上专为无人车建立的数据平台,美团无人车逐步建立了完善的自动驾驶基础设施。未来,希望在引擎的帮助下能够隔离功能模块、计算平台、运行环境,使得自动驾驶能力迭代与自动驾驶落地应用两个方向上的工作能够独立开展,齐头并进,加快美团无人车的落地步伐。
关于美团无人配送
美团无人车配送中心成立于2016年,由美团首席科学家夏华夏博士领导。美团无人车配送围绕美团外卖、美团跑腿等核心业务,通过与现有复杂配送流程的结合,形成了无人配送整体解决方案,满足在楼宇、园区、公开道路等不同场景下最后三公里的外卖即时配送需求,提升配送效率和用户体验,最终实现“用无人配送让服务触达世界每个角落”的愿景。
招聘信息
美团无人车配送中心大量岗位持续招聘中,诚招算法/系统/硬件开发工程师及专家。欢迎感兴趣的同学发送简历至:[email protected](邮件标题注明:美团无人车团队)