滴滴自动驾驶团队成立于 2016 年,目前已在中美多地建立了研发、测试、以及用户体验中心。团队自组建以来,在整车系统工程、传感器硬件、自动驾驶算法等方面都取得了长足的发展。如果说传感器硬件是汽车的眼睛和耳朵,那么运行在车载系统中的自动驾驶算法,就是汽车感知周围环境并做出驾驶决策的大脑中枢。
一名合格的人类司机需要积累大量的驾驶经验。同样,在滴滴自动驾驶团队,我们也投入了大量的资源来“训练”这个“大脑中枢”。对于自动驾驶,最真实的“训练场”莫过于现实中的道路环境。然而,道路测试面临着安全、成本、时效、规模等诸多方面的巨大挑战。
因此,我们开发了仿真测试系统——在虚拟的三维环境中,输入预定义的交通场景,通过软件的方式来模拟自动驾驶汽车的行为以及和周围环境的互动,并且自动评估其表现、性能,以发现问题,指导研发。
▲利用仿真系统,工程师在研发阶段
发现了规划的路径与隔离带距离过近的问题
▲通过创建完全虚拟的场景
工程师测试了自动驾驶汽车针对摩托车逆行的反应
在软件仿真的帮助下,研发工程师可以回放道路测试中暴露的问题;无需上路,就可以反复迭代算法。此外,工程师还能创建任意的虚拟场景,以测试自动驾驶程序在特定环境下的表现。同时,仿真测试也成为了软件版本准出流程中不可或缺的一环。
▲ 自动驾驶研发的工作流程
在滴滴自动驾驶仿真团队,我们的目标是打造一套高性能、可靠、易用的仿真系统,将其融入到研发工具链中,提高算法工程师的工作效率,并在自动驾驶软件上路前及时发现其中的潜在隐患。
我们将这个系统拆解成了三个有机结合的部分:
▲ 仿真系统的三个核心模块
以下,我们在这三个部分中选取部分核心问题进行详细阐述。
模拟器是整个仿真系统的基石,其开发存在诸多的挑战。其中要解决的问题之一,是确保自动驾驶汽车的行为以及与交通环境的交互达到与现实世界的高度一致。确保这样一种高可信度是能够有效发现问题、指导研发的基础。
自动驾驶算法在车上运行时,针对车载服务器的硬件配置作了专门的资源分配与优化,并且各个模块以特定的频率并行运行。与之相比,模拟器运行的典型环境是开发机器或云计算平台中的容器,与车载环境有显著的差异,例如 CPU 核数少、GPU 较弱或者没有 GPU,等等。如果仿真时软件完全按照车端的模式运行,各个模块就不能进行有效的同步与协作。
为了解决这个问题,我们在模拟器中应用了虚拟时钟的概念去控制时间的流逝,并且引入了“时序仿真”(Timing simulation)的概念,将实际路测中收集到的时序信息应用于仿真中。一方面,单次路测收集到的时间信息可以用于精确重现当时车上系统的事件时序,重建车上系统的状态,用于诊断该次路测中出现的问题。另一方面,大量路测中收集到的时间信息可以用于对时延分布状况的建模,使得模拟中的时间流逝总体上更加符合实际情况。
上述的方法可以在异质化的运行环境中比较精确地重现自驾车算法的运行结果,但是这种方式无法得到性能方面的评估结果。为此,模拟器也能运行在车载服务器硬件上,直接以车端运行模式进行仿真,从而得到准确的性能数据。
在交通场景方面,真实路测场景的回放可以精确地重现历史场景,并且具备真实的传感器数据,因此具备良好的可信度,但也存在交通对象互动性弱、场覆盖度受限等不足。另一方面,虚拟场景具备良好的灵活性,随着对长尾与边界问题的仿真测试不断深入,虚拟场景的作用也日益提高。同时,虚拟场景也必须植根于现实,从宏观的整体交通流模式,到微观的交通对象的行为特点,都需要在统计意义上与现实世界中的相应实体的行为相一致。
模拟器负责处理单个驾驶场景的仿真。然而,验证自动驾驶系统需要成千上万的驾驶场景,靠单机运行显然不能满足研发工作的需要。所幸的是,不同的驾驶场景天生具有数据并发的特性(data-parallelism),每一个场景都可以独立运行。同时,模拟仿真中采用了虚拟时钟的概念,对运算的实时性没有任何要求,可以适应大多数的硬件环境和进行排队处理。因此,云仿真平台应运而生。我们把对单个场景的仿真封装到一个个独立的任务中,通过云计算平台为这些任务调度所需的算力、存储、带宽等资源,实现了分布式的大规模仿真运算。
与大多数传统的方案一样,我们构建的云仿真平台具有良好的扩展性和伸缩性——其仿真计算能力的总吞吐量与加入其中的工作节点的数量呈正比。同时,优化单个节点的运算性能也能直接提升平台的总吞吐量。
▍1. 增加工作节点数量
在传统的云计算平台的实现中,工作节点以虚拟机或者容器的形式部署在物理机器集群上(宿主机)。由于对业务方运行的任务无法预知,云平台方必须非常保守地做好工作节点之间的资源隔离,避免不同用户的业务在共享的宿主机上出现资源抢占的冲突。
滴滴作为一家大型互联网公司,已经拥有大量的服务器资源。这些硬件资源必须满足主营业务高峰期的峰值需求。从时间上来看,主营的网约车等业务具有早晚高峰的“潮汐”特点。在低峰期,我们将云仿真平台的工作节点部署到网约车业务所在的宿主机上,从而利用了本来闲置的算力资源来运行仿真任务。在高峰期,工作节点关闭,确保主营业务不受影响,直到高峰期结束下一个低峰期的到来。如此周而复始如同潮起潮落。
从空间上来看,一部分服务器作为大数据存储节点,CPU 利用率不高;一部分服务器作为备用机器,长期处于闲置状态。而自动驾驶仿真却具有 CPU 运算密集但 I/O 压力相对较小的特点。因此,我们将运行仿真任务的工作节点长期部署到这些服务器上,充分混合了不同业务的资源需求,让现有的服务器能力得到最大程度的发挥。
从成本上来看,我们在已有的硬件资源上,通过这种“混合部署”的方式额外提供了大量工作节点,大大降低了仿真运算的单位成本。换句话说,在固定预算支出的限制下,我们大大提升了云仿真平台的总吞吐量,为更快更高效地迭代自动驾驶技术提供了坚实的基础。
▍2. 优化单节点运算性能
众所周知,自动驾驶算法依赖于深度神经网络模型。这些模型非常复杂,即使在推理过程中,也会消耗大量的计算能力。由于成本的限制,云仿真平台中大部分的工作节点都没有配置 GPU。
结合仿真应用的特点,即回放路测数据,我们知道,模型的输入往往是重复的。如果模型本身保持不变,推理的输出结果也是可重复的。因此,我们开发了神经网络缓存(neural net cache)技术,对推理结果进行缓存。每次推理的时候,我们根据模型自身的属性和输入向量值计算出一个哈希值,向后台 KV 存储系统查询。如果缓存命中,就无需在本地用 CPU 进行推理。可以想象,当反复仿真同一批驾驶场景时,缓存的命中率是非常可观的。
我们的实验发现,当缓存完全命中时,模拟器的性能比本地有 GPU 加速还快了好几倍。随着深度神经网络模型在未来变得更加复杂,神经网络缓存的提速收益也将越来越大。
云仿真系统解决了自动驾驶研发中大规模仿真所需的算力、带宽等资源。然而,大规模仿真势必产生大量的结果。显然,靠人工来审阅成千上万的场景结果是不现实的。我们构建了一套数据系统来管理仿真所需的大量数据,并对仿真产生的大量结果进行自动化的分析、过滤、和可视化。
首先,我们建立了一个场景库系统来描述和管理众多的仿真场景,包括他们的特征、属性、相应的安全级别等。场景资源是仿真系统的核心资产。我们采用了灵活的树状结构标签对场景进行分类管理,让场景标识变得清晰规范,可以很容易地被不同的使用方理解和使用。
其次,为了保证场景资源的质量,我们创建了对路测数据的索引、检索、分析的工具链,以便高效地获取仿真所需的输入数据。这套工具链能半自动化地从海量的数据源中找到工程师感兴趣的数据片段、以及符合某些特征的数据点,使仿真能更有针对性地去验证自动驾驶的算法迭代。
另外,对于仿真后产生的大量数据,我们能对仿真结果进行自动化的打分和评估。我们也支持在仿真中产生自定义的统计数据和日志事件,对这些数据进行聚合(同一算法在不同场景下表现的综合)和对比(算法迭代前后的 A/B 测试),并以可视化的图表方式把结果呈现给工程师。
随着自动驾驶技术的不断完善进步,仿真系统的整体效率对于技术迭代的速度也起到日益重要的作用。当 MPI(Mileage Per Intervention, 即发现问题的平均里程数)提升 10 倍时,如果不加选择地进行随机测试,那么发现问题的效率也会相应地下降为原来的 1/10。相对于有安全驾驶员参与的有限路测,实现大规模无人化的安全运营要求 MPI 有多个数量级的提升。这就对仿真系统的能力提出了极高的要求:
能否有效发挥仿真系统的“加速器”与“放大器”的能力,或许将是自动驾驶技术能否最终获得广泛应用的决定因素之一。
领取专属 10元无门槛券
私享最新 技术干货