NVIDIA,自动驾驶,DriveFI

解读NVIDIA的自动驾驶错误注入引擎DriveFI

大部分人对DriveFI这篇论文或多或少都有误读。所以笔者认真地读了几遍这篇文章,并想发表一下自己的理解。

本文作者为瑞典皇家理工学院(KTH)毕业的博士,现为KTH的研究员。他的研究方向为自动驾驶的安全分析,有多年汽车电子架构设计以及功能安全的研究经历。感谢作者的供稿。
 
以下为原文:
 
引言
 
前几日,发现几个自动驾驶的公众号里都提到了DriveFI这篇论文。这篇论文会成为热点的原因主要有两个,一是因为它的作者来自UIUC和英伟达(nVIDIA)。二是因为他们的实验采用了如今很流行的两个自动驾驶技术栈,百度的Apollo和英伟达的DriveAV。不过笔者认为,这些公众号的文章对这篇论文或多或少都有误读。所以笔者认真地读了几遍这篇文章,并想发表一下自己的理解。首先来明确几个重要的问题。
 
(关于这篇DriveFI论文原文,详见https://arxiv.org/pdf/1907.01051.pdf)
 
1.百度的Apollo和英伟达的DriveAV中真的有500多处错误吗?
 
答:没有!至少文章中没这么说。那论文中说的4小时找到了561个safety critical faults。这与找到了561个bugs有本质上的区别。到底是什么意思呢?下文中会解释。
 
2.DriveFI是用来找错误的吗?
 
答:不是!它是用来做错误注入(Fault Injection(FI))的。也就是说它是用来故意地往Apollo和DriveAV中加入错误的。人家本来没错,但我非要让它错一下,看看会有什么后果。那这么做的目的是什么呢?下文中会解释。
 
3.为什么这篇文章会有这么多误读呢?
 
答:因为文章写得太匆忙了。脉络不够清晰,读起来有些费劲。不过DriveFI确实是一个非常有意思的工作。那么DriveFI到底做了什么,以及它的优势和创新点到底是什么呢?下文中解释。
 
4.卖了这么多关子,那下文究竟要讲什么呢?
 
答:
 
错误注入的基本概念
 
错误注入应用于自动驾驶或是ADAS的难点
 
DriveFI的用途,优势和原理
 
错误注入(Fault Injection)和安全分析
 
对这两个概念很熟悉的读者,请跳个这一节。
 
首先来解释一下什么叫错误注入,以及它的用途。所谓错误注入就是将一个系统原本没有的错误,注入到系统当中去。比如说车子正在高速公路上快速直行,AEB(自动紧急刹车)控制器并没有让它刹车,可我却偏要强行注入一个来自于AEB的紧急刹车信号进去,来看看会发生什么后果。这个过程通常在仿真环境中进行。DriveFI的论文中用到了两个仿真工具,分别是Carla(如图1所示)和DriveSim。错误注入的目的通常来说有两个。一个是为了安全分析,来看看这个错误一旦发生,会不会造成致命的后果。另一个是来验证系统的容错能力,看看这个错误会不会被系统中的容错功能有效地处理掉。
 
图1.Carla仿真环境中的截图
 
那如果我证明了我的算法不会出这种错误(突然刹车),我还需要注入这个错误来验证吗?需要的。因为就算你的软件不会出这个错误,硬件的故障也可能会导致这个错误。比如内存突然地位翻转,或者死机了,断线了,甚至刹车坏了。更何况,我们也很难证明我们的软件就真的不会出现这种错误。越是复杂的算法,就越难证明它的准确性。
 
前文说,错误注入的一个主要目的就是用来辅助安全分析。下面简单梳理一下安全分析的基本思路。这里我们只考虑由系统故障所带来的安全问题,也就是功能安全问题。以ISO 26262为例,它假设一个故障,在某个特定的驾驶场景(operational situation)下,会造成一起事故(hazardous event)。这个造成事故的故障被叫做一个hazard。每一个hazardous event都是一个hazard和一个operational situation的组合。而安全分析的第一步,就是找出所有的hazardous event(由系统故障所造成的事故)。笔者认为,这一步有四个难点1)很难找出全部系统故障,2)很难找出全部驾驶场景,3)很难分析一个故障在一个驾驶场景中会造成什么影响,4)将所有可能的故障在所有驾驶场景中一一遍历需要大量的时间和人力。错误注入技术,主要针对难点3和4。
 
所以,一个错误注入引擎会不断地将各种各样的(系统中不存在的)错误注入到系统中去,并在不同的驾驶场景下观察其后果。回到我们要说明的第一个问题,什么叫safety critical fault?根据论文中的定义,如果一个注入的错误会在某个驾驶场景造成安全事故,那这个错误就叫做safety critical fault。所以DriveFI只是通过错误注入,找出了561个可能会造成事故的错误。而这些错误并不一定就存在于Apollo和DriveAV中。它们是被故意注入进去的。
 
如果系统出现了这些错误,可能会造成安全事故。而绝大部分其它的错误可能会带来一些舒适性,以及功能性上的一些问题,但不会造成安全事故。这样,在接下来的验证过程中,我们只需要重点关注这些safety critical faults就好了。
 
错误注入(FI)应用于自动驾驶或是ADAS中的难点
 
对于自动驾驶这种复杂的系统来说,它可能有几十万种出错的方式。但并不是所有的错误都会造成安全事故。自动驾驶的算法,尤其是传感器融合与目标跟踪算法,具有很强的恢复力(resilience),会容忍很多感知(perception)系统所犯的错误,比如说,目标检测算法在某几帧图像上没检测到前方的某一辆车。这个错误很可能会被它下游的目标跟踪算法很好的纠正过来,从而不会造成任何影响。
 
而同一个错误,在不同的驾驶环境中所造成的后果又不同。同样的错误(比如判断错了前车的速度),在某些场景下可能是致命的,而在另一个场景下则不会造成太大危害。
 
即使车子没有故障,在某些场景下也会出现危险。比如旁边车道的车突然违规切入到一辆自动驾驶汽车的前方。这种情况下,无论系统中有没有出现错误,都极有可能发生事故。换句话说,这个事故并不是由这些错误直接造成的,而是由其它车的违规行为造成的。所以这些场景不属于功能安全所研究的范畴。
 
DriveFI
 
这一节主要介绍DriveFI相比于其它错误注入方法的优势,以及其工作原理。
 
目的:
 
DriveFI的目的是找出那些没有错误时不危险,但出了错才危险的hazardous event(前文提到过,它是一个hazard和一个operational situation的组合)。
 
优势:
 
DriveFI最主要的优势就是一个字,快!论文中说,在他们的实验中,他们一共定义了98,400种出错的可能和6种驾驶场景。如果采用暴力方法在这6种场景中遍历这98,400种错误,需要615天的时间。而DriveFI只用了4小时,就找出了561个可能的safety critical faults。经过验证这561个错误中有460个会真正造成事故。也就是说DriveFI找对460个,找错了101个。找对的比例还是相当高的。论文作者也尝试过随机错误注入。结果是几周之内未发现任何safety critical faults。由于文章中只尝试了6种驾驶场景。而实际要考虑的驾驶场景可能有成百上千个。从这个角度来说,DriveFI的优势还是很明显的。
 
原理:
 
首先介绍一下论文中所提到的暴力错误注入的原理。假设你的一个驾驶场景(Scenario)时长7秒。你的自动驾驶系统的运行周期为1ms。则该场景就包含700帧(Scene)。错误会被注入到每一帧上,然后来观察是否会发生事故。每一帧每一次注入多少错误取决于事先选定的注入方法。上文中说过,这么做很慢,因为跑一组仿真都需要很长时间。更何况是98,400 x 6组。
 
DriveFI采用贝叶斯错误注入(Bayesian FI)的方法来加速这个过程。其思路是用一组快很多,但不太准的仿真来找出潜在的hazardous events(fault+scene)。然后将这些潜在hazardous events送到真正的仿真环境中,看看他们是否真的会造成事故。实现这个很快的仿真的思路就是用一个机器学习的模型来代替真正仿真过程中比较慢的过程。如图2所示,DriveFI用一个贝叶斯网络来代替整个自动驾驶系统。这个贝叶斯网络的输入是k时刻的自动驾驶系统中的所有状态(注入错误之后的状态),以及驾驶环境的所有状态(比如其他物体的位置和速度等)。这个贝叶斯网络的输出则是预测出的k+1时刻的车速,朝向和转角。这三个值会给到一个汽车运动学模型(kinematic model of AV)中,去预测如果汽车从k+1时刻开始急刹车的话,会不会发生碰撞。如果会碰撞,则DriveFI认为这个被注入的错误是critical的。而当前这个scene则被标记为一个critical scene。
 
图2.贝叶斯错误注入引擎的工作原理
 
最左侧的时间轴代表一个scenario,上面每一个节点代表一个scene中的所有状态
 
贝叶斯网络的优势是它可以加入预先设定的先验知识,这些先验知识体现在哪些状态会影响哪些状态。比如说,我们知道k时刻的控制信号大概率会影响k时刻执行器的动作。但k时刻感知系统监测到的前车的位置,不会影响自己车上的IMU在k时刻的读值。这些先验知识决定了这个贝叶斯网络的结构。至于状态和状态之间如何影响,影响多大,则要通过训练过程来获得。那训练数据如何采集呢?还是通过仿真。数据来自于正常的仿真数据,以及被随即注入错误的仿真数据。
 
以上便是DriveFI的大体思路。DriveFI这篇论文一共双栏13页。其中提到了很多技术细节,比如贝叶斯网络如何建立,与哪些其它错误注入的方法进行了比较,训练集是如何构造的,以及该方法还能如何扩展等等。受篇幅所限,没法一一地在这篇文章中加以解释。感兴趣的朋友建议花时间读一读这篇论文。其中很多的参考文献也都非常有价值。
 
DriveFI这篇论文不太好读,因为论文的脉络很难理清。希望笔的这篇解读可以有效地加速大家对这篇论文的理解。如果有读者发现笔者对这篇论文的理解有误或是有所疏漏,也希望您多多指教。
关注自动驾驶之家微信公众号

扫描关注,获取干货

文章来源:Dr.罴 / 文章作者:RAMS工程师  →技术
声明:本文来源“RAMS工程师”作者“Dr.罴”,版权归作者所有,不代表自动驾驶之家官方立场。转载请注明出处、作者和文章链接,如果有侵权,请联系删除。
收藏