首页 » 科学 » 超万字实录详解若何打造“好用”的自动驾驶智能芯片算法对象链_模子_算法

超万字实录详解若何打造“好用”的自动驾驶智能芯片算法对象链_模子_算法

少女玫瑰心 2025-01-10 10:12:25 0

扫一扫用手机浏览

文章目录 [+]

11月8日,地平线「你好,开拓者」工具链技能专场在智猩猩顺利完结直播。
专场由地平线工具链产品方案卖力人秦畅主讲,主题为《如何打造“好用”的自动驾驶智能芯片算法工具链》。

本文是这次专场主讲环节的实录整理。
如果对直播回放以及Q&A有需求,可以点击阅读原文前去不雅观看。

超万字实录详解若何打造“好用”的自动驾驶智能芯片算法对象链_模子_算法 超万字实录详解若何打造“好用”的自动驾驶智能芯片算法对象链_模子_算法 科学

大家好,我是地平线工具链产品方案卖力人秦畅。
本日我将会给大家先容《如何打造“好用”的自动驾驶智能芯片算法工具链》,并谈一下在实践过程中,地平线的履历和产生的思考。

超万字实录详解若何打造“好用”的自动驾驶智能芯片算法对象链_模子_算法 超万字实录详解若何打造“好用”的自动驾驶智能芯片算法对象链_模子_算法 科学
(图片来自网络侵删)

分享将从四个方面展开。
首先什么是算法工具链;我们须要去办理的关键问题;地平线在办理这些关键问题的过程中做的一些实践。
末了,谈一下我个人对未来工具链须要进一步若何做的一些思考。

01 什么是算法工具链

首先谈到智能芯片,它是如何表示智能的呢?芯片作为一个硬件电路实现的大集成,本身是不会有智能的观点涌现。
谈到智能芯片的智能性,实在是来自于智能神经网络算法的加持。

在slide的左上,是一个神经网络里面非常经典的感知机模型,由一系列的神经元通过确定的规则排布得到了一个网络构造。
这个网络构造将会建立起输入层与输出层的映射关系,通过喂入批量标记好的输入和 Label之后,经由学习可以对未来的、未知的、同类型的输入,达到预测输出的效果。
拆到单个神经元来看,内部所含的打算是很大略的。
比如我们对每一个输入乘以权重系数,再对其进行累加,这个过程也便是矩阵乘法里面的细颗粒的过程。
同样的,如果完备是这样的打算堆叠,我们就会看到它在数学上会等效于大量的矩阵连乘(连乘在数学上等价于某一个矩阵乘法的效果)。
如果仅仅是这样,就失落去了对繁芜函数的表达能力。
以是一样平常会在神经元后面加一些非线性激活函数,像引入ReLU、Sigmoid这些函数。
学习的过程便是通过喂批量输入的样本和标记好的Label,去学权重设置,使得这一套权重能够尽可能很好地拟合这些输入和标记好的Label的映射关系。
未来同类型的未知输入,就可以可靠地对须要的预测结果进行预测。

到智驾领域的算法运用,当然不再是感知机这样大略的运用了,当前我们仍旧看到的还是CNN。
虽然我们看到目前技能趋势上会有一些明显的变迁,但大部分运用中的方案仍因此CNN为主。
比如Tesla在2020年旁边表露的数据,在Tesla的一个方案里面,98%的打算量来自于卷积。
那么卷积又会是一个什么样的打算?

左下角这张图中间是一个卷积的参数,我们叫它卷积核。
左侧的是输入,右边是输出。
卷积打算的过程中,卷积核对应到输入部分可视区域内的数据。
我们将输入部分的数据与卷积核进行点积乘法,再做累加,这样就得到了输出的数据。
通过卷积核在输入上的可视窗的滑动,遍历完所有输入的区域之后,就得到了完全的输出,全体过程类似右边动态图的效果。
这个过程同样具有大量的矩阵打算特点。
以是我们现在通过这两点可以看到,在卷积神经网络的打算里面有一个非常光鲜的特点,涉及到大量的根本打算,以乘加为主,量会特殊大。

现在我们看到了一个明显的趋势便是未来Transformer的方案升级。
Transformer确实给打算架构带来了一些光鲜的寻衅,但是从刚刚剖析的打算特点的角度来说,至少在智驾领域上的运用,紧张的打算量贡献还是来自于矩阵乘打算和全连接打算,只管对整体的体系构造带来了很大的寻衅,但是打算的特点没有明显的变革。
比如一个98%的矩阵乘的贡献会落到90~95%之间,其他的引入了更多激活打算,比如LayerNorm、Softmax用的更重。
当然,对数据的形变、 layout管理方面,也会带来更高的寻衅。

那么,对付智能芯片来说,它办理的问题就会变成如何加速神经网络的打算。
这一页左上角是一个非常大略的打算模型的示意。
我们在打算过程中从memory里面拿数据,放到打算单元里实行,再把数据回写。
在这样的模型里面,怎么样更高效地做神经网络打算呢?我们会自然地想到,在让全体模型保持现状的情形下,使它算得更快、频率更高,但提升频率是非常有限的。
我们可以看到打算器件CPU在近几年频率上是没有非常大幅度提升的。
但是对付我们所须要承载的神经网络打算量而言,如果要提速,那不是一两倍的观点,而是一个数量级的观点,以是纯挚的提速是不可行的。

那么其余一条路是什么呢?我们看看左下的打算模型。

我会铺更多的打算单元,这里放到了6个。
这个打算模型一次获取6个数据,在一个打算周期之内,6个打算单元同时事情,它再去回写的时候就回写6个数据。
在一个打算模型里面,我们不考虑额外读写上的压力,大略去考虑,会带来6倍的性能提升。
这便是我们的神经网络加速器,或者说我们的智能化芯片去做加速的核心idea,便是去铺更多的打算单元。

当然铺的话也是有讲究的。
右边是2017年谷歌发布的TPU-V1的架构。
这是一个非常经典的实验。
很多的行业同仁会拿它来举例子。
我们可以看到在黄色部分是它所供应的打算单元的情形,这个地方的面积基本上也表示出了配重的占比,以大型的矩阵乘单元为最紧张的核心,同时会辅以一些激活单元,刚刚也提到在神经网络里面会加一些非线性激活函数去处理这些任务。
同时,一个网络不会这么的纯粹,只有激活加一些矩阵乘,同时像Pooling、Normalize这些操作会加上一个特定的单元,一样平常会称呼为DSU。
它的浸染非常明确是用来做什么的,而且可能是一系列不好在其他部件去实现的能力凑集。

同时,为了支撑这套系统去运转,可以看到蓝色部分干系的内容,它放置了一个支撑存储数据管理的干系系统,掩护适宜于这一套架构的SRAM缓存,再去管理和DDR数据交互。
在这个过程中,赤色部分会涉及到一些驱动全体异构系统运作的必要掌握单元。
这仍旧是一个非常经典的设计,现在各家的架构多多少少在这里面都能看到一些影子。
当然现在会有所变革,比如会考虑在BPU加速核里引入一些标量单元,去处理未来神经网络里可能面临的一些分支打算,或者做核内调度。

在向量打算方面,如果须要考虑处理的特殊打算越来越多,如果还是一个DSU的观点,那么DSU会越来越繁芜。
它承载的详细实行的打算种别会越来越多,以是也会涌现一些更换。
用一个更加刁悍、灵巧的可编程单元去承载一个任务,不仅仅可以去承载一些已经预见的、其他部件不好去做的事情,同时供应给未来开拓者一个完备开放、具有可编程性,能够去做未来可能产生的新的打算类型。

那么对付我们工具链来说,恰好夹在中间了。
我们会看到这样的情形,往上看,面向各种算法Deep Learning开拓的框架,算法开拓者基于这些框架得到各式的模型,这是输入;往下看,在地平线的工具链打造里面,面向地平线征程系列的平台,包括我们已经量产的征程2、征程3和征程5,以及未来将会采取在今年车展上发布的BPU纳什架构的下一代,该当是征程6系列。

我们要在他们之间去建立一个桥梁,使得算法能够在这些芯片上跑起来。

02 自动驾驶智能芯片算法工具链办理的关键问题

跑起来是条件,跑起来之后桥梁是否稳定有两个核心要素:第一个是我的算法支配在你的芯片上是否足够准确。
没有准确为条件,所有的高效也都是免谈。
以是“准确”我放在前面了。

第二个便是它的效率是否足够高。
这将会成为算法工具链所须要办理的两个关键的问题。

在现在算法工具链语境下,我讲的准确性问题不是像算法演习一样,模型是否能够有很好的预测能力,是否训得足够好,它并不是这样的准确性问题。
准确性的问题来自于硬件的选择。
刚刚提到智能化的芯片加速神经网络模型,会堆叠更多的打算单元,堆叠也便是意味着更高的本钱。
本钱会表示在两个方面:

第一个是须要更多的面积去承载这些打算单元;另一个则是更多的功耗。
一次推一批打算的时候,须要的功耗也是一个很主要的成分。

我们做出来的芯片毕竟是面向商业化的场景,须要综合考虑本钱及利用功耗的问题,以是在堆叠这些打算单元的同时,我们也想到它一定会增加本钱,同时去考虑如何减少这样的本钱。

这里面有一个主要的方向是数值精度上的选择。
这一页贴了两张图,这个图是一个加减运算器的实现,整数和浮点数的比拟。
我们要看到的一点是,浮点数的电路实现的繁芜度明显高于整型的硬件实现的。
核心缘故原由来自于二进制的浮点数表示和整数的形式很不一样,缘故原由在这里不穷究。

下面这张图是我比较喜好用的一列数,现在可能看起来比较老了。
虽然是2014年的数据,但里面还可以看到一个明显的特点:中间偏左的部分是它能效的代价,右边是面积的代价。
我们以加法为例,做加法的时候用8b的加法实现,和16b的半精度和 float32去比较可以看到,随着打算精度的提升,能耗面积的代价都在增长,以是这就成为了一个很好的选择。
我们在铺大量的算力单元时会充分考虑利用 Int8的打算,当然也会做出一些不同的选择。
我认为完备的Int8可能用起来会比较困难,会适当的去考虑比如在一些向量激活的打算上引入浮点,或在矩阵的打算上适当的保留一些浮点。
比如Int16是不是能够保留?以是各家去看芯片表示它有多少个cost时,一样平常都会指明它支持什么样的打算精度。
当然,如果加速的平台没有与演习的平台做到完备同等的浮点打算,它就会带来一个准确性的寻衅。
训模型的时候,在这个算法的开拓环境下做算法验证,它便是一个完备的float32乃至更高的验证办法,你在芯片上改变了打算精度,你肯定对我的打算支配准确性是有一定的影响的。

到工具链的层面,我们要去做好量化的过程,使得我们虽然要去合营硬件做详细打算单元的打算精度降级,但整体模型的预测效果不能有太明显的丢失。
比如在智驾行业,基本上也会有一些共识:我们在驾驶干系的模型支配上,接管一些压缩的方法去换取更高的性能,但精度的偏差不能太大。
比如较于我的浮点的验证环境下作为base,它的相对的精度丢失一样平常会掌握在1%以内。
如何去做好这个事情呢?这就牵扯到神经网络,神经网络是支持我们去做这个事情的,涉及到模型的量化压缩的一个技能方向。
这个事情怎么阐明呢?一个神经网络里面每一层都在做打算,每一层都会输出一些结果,我们把这些中间结果叫做特色。

怎么去理解特色呢?便是一个知识性理解,一些研究对中间产出的特色做可视化。
比如在一个人脸的任务里面,一些浅层的特色里面可视化之后可以看到一些前景、背景的区分,一些边缘的特色涌现;在中层的特色上,我们看到了人眼、人脸、眉毛这样一些中层特色;到偏高层的时候开始见到全体人脸,再在这个根本上做预测。
这是可视化的效果,但打算机二进制数值的表示是数据的分布效果。
比如更常用、更随意马虎理解的是在打算机屏幕上大家本日看的直播活动,看到了很多画面,画面每一页代表了各式各样不同的信息。
整体来说,它在打算层面上便是各种 RGB数值的组合,这便是数值的分布带来的效果。

数值分布会留下了一些可压缩的空间,这一页左下角的部分是谈到量化压缩时候常常会引用的一张非常经典的图。
上面是压缩之前在浮点数据分布的空间之内,我们去建立的一个到Int的等比映射,相应的数据都等比例落下来。
这样我们数据的表达范围变少了,但可以看到里面由于 Int的表达能力,比如不映射过来的时候能到111.5,取一个round函数的方法,四舍五入映射到整型数据上会有一些偏差。
但是整体来说,它的分布不会有太明显的变革,当然条件是量化做得好。

还有一种数值的分布改变,压缩有一种更普通但不是很严谨的理解。
拿一个像素的办法去举例:我找了一张猫的图片,原图在左边,它的像素会偏高一点;右边对它进行了一些处理,把它的像素值减少了。
虽然我们可以明显看到里面是有一些丢失存在的,没那么清晰了,但实在不影响我们去理解它。
两个比拟之下,不影响我去理解它是同一只猫。
这便是我所理解量化的、比较好通报的核心认知。

在工具链详细的履行上,我们真正把这个想法落到工具的实现里面去。
刚刚讲到的量化会很大略,在这种情形下可以直接做一个映射,但适用性就会非常有限的。
如果把量化直接暴力阐明为映射,各种数据分布就会给我们带来寻衅。

在原始的数字分布中间,很明显会是一些有效的数据在两端噪声比较多。
如果完备根据它的最大值、最小值的区间,映射到 Int8的表示范围内真正有效的数据去表示的时候,用到 Int8表达能力就会很少。
这就会严重导致数据相对分布的表达失落真。
对应到刚刚那张猫的图片,像素丢失太严重了,我不能够再认识出来它是一只猫了,更别说是同一只猫。

为了做好这件事,工具链常见两条路径,一个是后量化的路径,另一个是量化演习的路径。
后量化的“后”侧重讲的是演习后的观点,我利用一定数量的样本,用演习好的模型去推理,这样就会拿到一批用真实数据去推并产出各层的数据分布。
大概像左边这张图,能够看到普遍都具有这个特点:中间的分布非常密集,两端散得非常开且数据非常稀疏。
我们可以先做一个假设性的认定,数值分布该当在中间取,规则可以在大略示意图上做非常大略的划分,把有效的空间截取出来之后,其他的直接丢弃,只在有效的数据范围内做映射。
这样就能只管即便有效地还原数值的分布,把量化做好。

为什么说是只管即便呢?有一些后量化理论上也不能确保我们办理所有问题。
我们在用后量化去办理问题的时候,会提到一个观点叫“量化不友好”,但是这个观点我考试测验去做后量化的时候,可能会创造这样一种情形:呈现数值分布是集中的,但是集中不在一个点上,分布在旁边两头,中间比较稀疏的分布特点。
这样去找范围再去映射,就很难真正有效地运用到 Int8的表达能力,由于中间原始数据会有一段空档。
为理解决这个问题,确保量化办法的稳定性,对各种情形都能处理,就会提到“量化演习”的观点。
我们把量化的行为追加到演习的过程中的好处是:创造了量化不友好的问题之后,可以调度权重分布,使它达到所谓的“量化友好”的状态。
由于在演习过程中,权重本来便是在调度的过程中的,训到一定程度之后,又可以开始做前面的统计、映射这些过程了。
核心便是权重可变,办理问题的潜力也就越来越高了。

当然还有一些其他的办理办法,比如稠浊精度。
例如在做后量化的时候只是部分分类的数据呈现这样的特点时,量化不好做,那干脆就不要做了,我在这一层直接用浮点的打算。
还有一些是只要分布是范例的,就可以在量化的办法上选择更多样的办法。
我之前认为量化数据在一个集中点,如果数据分布在两个集中点,那么也可以推出相应的量化办法。
办理问题的办法是多样的,目前后量化加稠浊精度进行量化演习会是一个利用比较广泛的办法。

下面是第二个关键问题:高效性。

我们的工具链要去把上级算法框架得到的模型在芯片上支配起来,使它能够跑起来。
以是,最大略的原始idea可以怎么样去做呢?

在打算图里的每一层打算是确定的,然后将打算拆解出来,映射到相应的打算部件上去。
它们的实行次序也是确定的,然后按照实行次序,该加载数据的时候加载数据,该算 Conv或者算Matmul的时候就去上Matmul,该Pooling的时候就Pooling,非常守旧地一步一步去做,就会得到下面示意的时序图。

这个图实在是一个非常不理想的支配结果,可以看到打算资源没有被充分的利用。
以是,高效性的问题对付编译层面来说,是如何把打算的资源充分地调动起来。

地平线做的该当也是行业内普遍会做的事情,从两个方面提高它的性能:第一个是去提升数据的复用度,第二个是提升并行度。

数据复用和效率的关系怎么理解呢?我们刚刚看到 GPU的打算模型里面,核内会有一套缓存管理系统,同时也卖力和DDR的交互。
这样我们就可以看到两层的存储的观点。
第一层是核内的缓存系统,比如SRAM;第二层便是核外的动态存储DDR。
越靠近打算部件的缓存器的性能会更高,如果能把数据勾留在缓存里面,充分地复用减少跟 DDR的交互,整体来说性能会更高。
从时序图上来看,我就会尽可能地避免打算等数据涌现这样的情形。
那复用怎么做呢?首先会提到两个观点,地平线是打算的拆分和领悟。
拆分是一个非常常见的做法,比如还以GPU为例,Conv打算的时候把两份输入,一份Feature的输入,另一份ViT输入,按照确定的规则展开之后,变成一个非常大的矩阵乘。
这种方法在一定程度上是用一定的存储空间去换得打算效率,或者使打算得以实现。
但从拿到的结果上会看到是一个非常大的矩阵乘,在打算的加速核心里面所供应的一个矩阵乘单元的力度不会那么大,便是几十乘几十,撑去世了100×100。
至少我还没见过100×100这样大的规模,做到这个程度已经不得明晰。
但矩阵乘法的规格肯定不止这样,以是这个过程中就必须要拆分。

在地平线的实现中,比如在Conv上面,有一点特殊的是我们不会把它展开,而是直接拆 Conv,这样也方便我们去做领悟,提升数据的复用。
怎么理解呢?在这样的打算示意里假设还是卷积打算,第一层做完部分打算之后,同时也在准备第二层的输入。
那么如果是一层层 layer by layer的打算,每一层输入的打算结果是非常大的,特殊是在智驾的场景下图像的输入分辨率普遍都不低,产出的中间Feature每一个layer都会非常大。
比如几兆的缓存空间是不足的,不敷以成像的,等第一层算完,必定第一层的过程中就要回写DDR。

在地平线的策略里,我们采取先拆完之后再去做领悟的策略。
这指的是第一层做完部分打算,第二层的部分已经输入准备好了,这时候会优先跳到打算下一层部分。
依次这样递推下去,找到一个得当的位置停下,后面创造这个策略不能再走了,又回到前面,连续做这样的打算。
相对付layer by layer,我们能够很大程度上避免DDR的回写。
实际上拿到地平线的芯片去评估的时候,大家每每会考虑两个要素:第一个是它的性能构造怎么样?第二个是它的带宽情形怎么样?

首先我们看单帧读写。
同样的模型在地平线的芯片平台上,单帧读写所需读写的数据量该当是明显偏少的状态,这是一个非常好的结果。
这样在一个确定好设计帧率的系统上去运行,须要用到的带宽资源就更少,这样就给运用腾挪出了更多的资源。

其次是指令并行方面,指令并行也便是编译器,基本上是各家都要充分去做的一个事情。
在打算的过程中要充分的Pipeline起来,每一个打算单元各司其职,最范例的便是数据的加载、存储单元和打算单元并行。
我们要只管即便避免打算单元闲置,数据搬运的单元一贯在事情,也便是打算等数据。
这是一个指令并行的优化,基本上每家都会做这个事情。

是不是有了这些之后就足够了呢,把数据的复用做得很好,想到了办法在并行度上也充分地优化,是不是就能够办理所有的问题呢?答案肯定是否定的,现实的算法构造的多样性每每可以给我们带来各种各样的寻衅。

举一个有点老的例子,但也是一个非常范例的例子。
在末了一层的打算中,我们乃至须要用到第一层的打算结果,这对付数据复用来说是一个非常大的寻衅。
在持续推理的过程中,最空想的情形是算完即弃用。
这种网络构造不哀求把数据不断地留下来给后面用。
这种网络使得推理芯片比做演习数据的芯片更大略,由于不须要缓存每一层的结果,相对来说是算完即弃用,拿着新的数据再连续往下去算。
如果它失落去了这个特点之后会变得更困难,这也是业内普遍会认识到这样的一个问题。
这也导致了大家会非常关心一个结果,便是有多大的SRAM。
在刚刚提到的用缓存策略去加速打算,避免打算瓶颈的运作模式里面,理论上有更大的SRAM潜力是越高的。
另一个方面还是会看到SRAM不可能无限大。
相对来说,它集成到芯片里面的本钱远比DDR要明显高很多。
以是一样平常都是有限地集成多少个兆,在边缘侧的推理芯片里面,单核放十几兆已经非常大了。
有限的空间一定放不下所有的东西,以是数据回写还是不可避免的。
回写又关注到带宽,数据的搬运能力怎么样?存不下,就使得它的数据搬运和DDR交互来的更快,这些是由带宽决定的。
比如在公路运输的时候,把4车道拓成12车道;铁路运输的情形下,把绿皮换高铁,这都是为了更高的运力。
理论上也是没错的,但全体模型性能的终极确认是一个繁芜的系统过程,这些根本的成分确实能够保障得到更好的性能。
但实在各家都有一个共同的目标,便是达到更好的性能,但里面会做出不同的权衡,由于并不是提升之后,对你关注的所有网络都是有帮助的。
比如供应一个更高的SRAM,但未来所须要的运用里面极有可能是卡打算的,更多SRAM实在对性能没有非常明显的帮助。
理论上会好一点,好5%,反正不是非常亮眼的这样的存在,但SRAM提升的代价是实实在在的。

以是我们认为总的来说这些都是中间的过程或者成分,真正要去看我们未来所要利用的打算平台性能如何,最好还是用实际的物理芯片、打算平台和开拓板,拿到它相应的工具链去实测未来要用到的这些模型在芯片上的性能是怎么样的?当然有时候样本少看到的结果是非常不一样,有时会看到的结果非常乐不雅观,有一些非常悲观,以是理论上还是只管即便去看更多的模型,给芯片一个客不雅观的评价。

03 结合实践做“好用”的算法工具链

涉及到在芯片上真正跑这个模型,就会用到算法工具链供应的一整套开拓套件。
目前展示的这一页便是地平线的算法工具链构成,大概分三个部分:

第一部分是演习侧干系的,倾向模型演习端和模型前端,框架去对接的这个部分。
我们会对接主流的深度学习框架,同时供应两种办法:

第一种是刚刚提到的后量化的办法,在大部分早期打仗里面,我们的客户都方向于去选择这种办法。
由于这种办法会有一个很好的特点是它和演习是解耦开的,交卸面是非常清晰的,操作起来也非常大略,评估会非常快捷。

其余一套便是刚刚提到的量化演习,我们在 Deep Learning的框架里面供应一些插件,在浮点阶段之后添加量化演习的过程,可以供应更稳定的精度保障。

第二部分是在量化问题办理完之后的一些编译优化性能保障的套件。

我们供应的工具范围包括模型的检讨器、模型的编译器、一些仿真推理性能的调试器等等。
如果预期顺利可以通过这一套得到一个上板支配的模型。

第三部分,算法工具链同时要基于前面这些规则得到的模型,在嵌入式端去供应一套支配预测库。
它在模型的支配层面会偏大略。
我们会供应一个必要的接谈锋能,包括模型的加载、输入数据的准备、一些推理的接口,当然也包含一些必要的模型调度干系的根本能力。

这便是大家能够打仗到的地面线当前最新一代J5的平台展现出来的面貌。
地平线肯定也不是一开始就做到了这样的形态,这个过程中实在还是有一些故事的,我们是逐步演化到了这样的状态。

地平线是在2017年开始做真正意义上支持生产的一套工具链,以相对独立的产品的存在形式去做。
当时我们选择的是 MXNet,在刚刚提到的偏前真个模型压缩的办法上,我们直接选择了QAT路线。
当时有一个判断,认为在智驾的场景下,由于是和安全干系,我们要尽统统可能去供应更高的准确度,而QAT相对来说的精度保障的稳定性更好。

当时也是自己做的,为什么呢?由于2017年做量化演习还是比较早的状态,至少在当时韶光点,市情上是没有更好可以去选择的根本的。
最早的可公开地得到的一些量化演习能力的框架,该当是2018年谷歌推出来的。
其实在2017年的时候,我们地平线就已经在做这样的事情,飞快地把它推到我们早期芯片里面,去支撑智驾的干系运用落地。
这一套工具链也在未来的一段韶光内在用,比如J2以及征程3的早期,都是用这一套框架支持它们的量产,带来了很大的出货量。

但是,往外推的时候就会有一些问题。

首先是地平线自己用好了,实在我自己也体验过。
当时我也参与了一些算法和嵌入式干系的中间模型支配优化的干系事情。
从嵌入式的角度去打仗MXNet之后,它的体感还是特殊好的,而且和后面又利用的TensorFlow比较,我认为还是一个非常好的体验。
但是很遗憾由于一些生态问题,工具本身好不好用是一方面,它的生态根本是不是很好也是一个很主要的影响。
我们会创造真正市情上用的时候,潜在伙伴并不是那么多,相对来说TensorFlow当时在工业界关注度更高。
因此在2019年的时候,我们又推出了一套在TensorFlow框架上去做的工具链。
当时同样还有一些选择,现阶段转头来看不是那么完美。
当时仍旧选择了走QAT路线,还是武断不移地认为高精度保障肯定是第一要务。

再便是我们定义了一套算子集。
一开始踩到了一个很大的坑,我们认为全体算法的搭建,从原始的idea开始就该当充分考虑未来怎么样去用。
比如在最前端和中间步骤有一些不契合的地方,在业务上大家该当就谈论避免掉。
因此,定制了一套算子集,这样达成了一个什么样的效果呢?用地平线我们所推出的算子集去重新构建网络,从零开始训出来,得到一个比较好的演习效果。
这样在图的优化层面,要做的事情就会比较少。
比如范例Conv+BN+Relu的领悟,我可以直接供应CBR这样的组合算子,再便是给一些未来可能须要在打算图里面去折叠、领悟的算子,就直接供应一个大算子重新去搭建。

这样做的效率肯定更高。
但实际上引入了一个问题,它对付我们的客户已有产出的延续,是一个非常不友好的状态,意味着用它须要从零去搭建,那以前的积累怎么办呢?这是一个现实的寻衅。

其余,它对付全体算法开拓过程侵入性非常强。
虽然算法设计的思路仍旧会得以延续,但是你把全体算法开拓过程都推翻了重来。
用这一套工具去做的过程中,它会把全体算法演习过程中产生的问题,都引到工具链或者支持的问题中来。

比如我们自己在用地平线的平台之前,要去在边缘平台或无关的算法开拓环境下去训一个模型出来,可能本身很多问题就会发生在这个阶段,比如创造训不上。
但如果一开始直接从那个阶段去切入,这些问题就都会落到工具链层面上来,这个是很难分清的。
在早期可能花很多韶光去训,但模型的效果精度不及预期,会创造是模型演习本身的问题,还没有到须要用工具链去办理的问题上来,也不是我们的算子涌现了什么问题。
但是当我们一旦供应这些工具的时候,我们的伙伴会很自然地优先方向于疑惑算子是不是有问题,你的演习框架是不是出了什么问题,以是支持的投入会偏大。

一个核心的缘故原由是跟用户的交卸面不是那么清楚,它的支持会非常繁芜,乃至会把我们的研发团队也卷入到一些支持事情中,这是一个非常不康健的状态。

然后到2020年,我们迎来了一些变革,当时推出了征程3。
对地平线几代架构有理解的同学,该当有理解过架构的名称,特殊是用过工具链的。
征程2这一代BPU架构叫伯努利,在征程3上我们叫伯努利 V2。

它在BPU架构上没有一个非常大幅度的变革,仅仅迎来了眇小的架构调度。
从工具链层面看到一个非常光鲜的特点是什么呢?它在支持量化的办法上,从J2所支持的移位量化的办法,转成了支持乘scale系数的办法。
这也使得我们具备了做后量化工具链的条件。

在这个韶光点上,我们开始推出了一个在征程3和朝阳3上启动的浮点模型转换的工具链。
通过各个框架得到模型,把这个离线模型导出来,再放到全体集成工具里面去做校准、编译,得到一个上板的模型。
这个阶段好处就出来了,我们之前踩过的坑基本上也都填上了。
对付客户的已有模型的复用做的比较好,全体交卸面也是清晰的。
如果导出来的模型本身就有一些准确性的问题,问题可能不是我们做优化过程中产生的问题,交卸面是非常清晰的。
以是在这一段韶光,用户的体验上反馈比较好,利用量也有一些增长。

差不多在同一期间之内,深度学习框架又迎来了一次变革。
当然这个也不是那么溘然的,自然而然就到了这样的结果。
PyTorch的主要性越来越高,当时在用户群体里面去支持PyTorch框架的呼声越来越高。
那么,我们进一步就在PyTorch的环境下加入了一套量化演习的插件。
提出的这个插件沿用至今,也是量化演习里面最紧张利用的一个插件。

在做这一套插件的时候也是接管了一些之前的履历,只管即便还是不能省的时候不省,保持了和原始的浮点模型对接的阶段,不要侵入到原始的浮点模型演习阶段,而是在它的根本上追加量化演习。
之前浮点的演习阶段产出是量化演习阶段的输入,我们会去卖力PyTorch里面的一些必要算子更换,比如add。
为了做量化演习,我要去做特质化,使它能够加上量化节点,在学习的过程中演习量化参数类似的事情。
这一阶段,纵然在量化演习阶段,我们也开始和浮点模型演习有了比较清晰的边界。

做到刚刚这样的程度之后,基本上也就形成了前面给大家秀出来的我们工具链到目前为止所呈现的过程。
我们的用户群体也在这个时候开始快速增长,不管是我们在商业上一些To_B的互助伙伴,还是开拓者群体里面涌入了很多的用户。
但这也带来了一个很大的寻衅,便是算法的多样性。
我们看到各式各样的算法涌进来了,可能就会频繁地涌现了做不好的情形,里面的问题有很多。

范例的、紧张的问题便是如何让多样的模型高性能实现?常用的打算是可以去列举的,但在真正打算优化的时候,为了做到更高的性能,就会给打算的图上做一些优化。
比如一些能够折叠的算子去做折叠,小颗粒度的算子去做领悟,如果得到一个数学上等价的实现,我们要把它识别出来,使它能够做一个更大颗粒度的高效的打算,映射到已经充分优化好的实现上去。
以是我们就会根据输入去做大量打算、领悟范式的补充,很多的打算图层面的优化。
对付编辑器层面上来说,不断引入case也可以看到一些优化的方向,直白点说会意外地创造一些硬件上的优化技巧,编译器层面会产生出一些新数据的拆分办法,在并行优化的办法上也能够做出一些新的策略。

第二个维度是模型硬件友好度的问题。
软硬结合是地平线已经深深贴上去的理念。
我们认为一个好的网络,真正在目标打算平台发挥出极限性能的时候,一定要充分地契合硬件上的特性,使性能充分发挥。
纵然你当前跑的挺好挺满意的,但如果和硬件的契合度够高,它可以有更好的表现。
这也便是我们说的模型硬件友好度的问题。
模型是否硬件友好,实在很大程度上已经决定了它优化的天花板。

地平线从J2开始就有一个非常主要的、一贯延续至今的特点,便是对付Depthwise、Group Conv这些能明显减少打算量的 Conv打算有方向性地支持,这便是我们做软硬结合的时候认为未来哪一些东西是主要的。
实在神经网络从非常早期提出到很长的一段韶光之内,我们做芯片的时候去看打算模式,是没有发生非常明显变革的。
到2016年,Xception推出的时候带来Depthwise,我们当时认为这是一个非常主要的打算。
它很大程度上减少了打算量,但对付准确性不会有非常明显的影响,以是认为这是一个非常主要的打算。
由于打算这种东西是一个硬性的东西,这个层面如果一开始出发点很高,须要的打算压力负载也高,优化空间的极限也和打算量紧密干系。

我们认为Depthwise、Group Conv这些能明显减少打算量的操作是一个非常主要的方向,以是当时在芯片里加入了特殊优化支持。
但是涌现了一个很严重的问题是它的构造对付GPU的演习环境极度不友好,可以在支配的时候做到高效,乃至在一个智好手机的终端设备上做得非常高效,但它对付GPU演习平台是资源不友好的。
我们早期也会有一些同学去训这些模型的时候创造,在全体集群的打算资源监控平台上,资源利用的情形会特殊低,这也是一个很现实的问题,也是导致没有非常大面积开拓结果的缘故原由之一。
我们在很长的韶光之内善于做这样的事情,拿着MobileNet、GoogLeNet向我们的客户推举,但也仅限于此,很长的韶光内没有更多干系的学术界或家当界的持续补充。
好在坚持一段韶光之后,有两个方面的变革:

第一个方面是外部条件带来的利好,学术界、工业界呈现出来更多的最新实践。
先后像EfficientNet、EfficientNet-lite、EfficientDet这些系列的推出之后,在朝阳、征程早期的平台上用到了这些模型,使得我们也有一些互助伙伴得到了高效地支配实现。
这也是最近相对来说会新一点的 ConvNext,ConvNext还是Depthwise。
但在Depthwise打算上,当把卷集核放大的时候,比较较Normal Conv来说,ConvNext对打算量的增长影响还好,而且它在打算预测的准确度、演习环境的资源的友好度方面都有提升。
以是幸好行业内对这个方向有持续的关注和产出,我们可以直接复用。

其余一方面,也是看到这个问题之后认为我们不能止步于此,不能仅仅依赖行业内自然而然得到一些有帮助的成果,我们自己也该当主动的去做更多的事情。
从工具链的团队来说,我们开始不局限于做工具本身,会在算法层面上更加关注如何做一个高效的模型。
由于用户群体本身对我们也是有诉求的,当算法的模型不足高效时,在用到地平线芯片、工具链时候,自然而然会在工具链的支持团队里寻求一些建议如何去把它做的高效。
为了更好地做支撑事情,也为了更好地供应素材,我们在做工具的同时也在做高效模型的探索验证事情。

最早期我们在经典的视觉任务上推出了高效的BPU友好的视觉分类任务、检测任务、语义分割任务。
在2022年下半年至今,我们推出了基于自动驾驶场景任务拆分出的系列技能点,然后推出了大量的详细技能点的参考算法,以及在做这些参考算法的过程中,做的一些详细的优化。
针对为什么要去做优化,提出了大量的最佳实践,当然这些最佳实践都是 免费供应在我们工具链交付包里面去的。
这些很大程度上给我们的互助伙伴供应了很好的输入,如何去做好硬件友好度地提升。

第三个方面是一些精度问题的处理。
我们碰到的各种方面都会有个问题,考试测验了各种修补策略,比如哪些须要高精度策略的补充,再补充更多校准的算法,KL之后要MAX,MAX之后要MIX,再便是是否启用perchannel等等。
我们陆续把这些做齐之后,每项参数的涌现都对应一个详细问题,过段韶光就会创造真正去调的时候,它的参数量要配的参数是非常多的,后量化也像写代码一样要写非常多的参数。
很多情形下你不用去动这些参数,以是有一段韶光我们把它转成了默认值。
但是过一段韶光之后会创造设默认值是有方向的,在设默认值的时候选哪个实在也要纠结,由于默认值的设置会代表配置的方向。
后面我们也转向了一些自动策略,比如这些参数是否该当开启,是什么样的配置,是一个自动搜索的过程。
我们的研发该当在补充技能策略的同时,更多地考虑如何把过程做到自动化。
不能随着策略越来越多,客户所须要加强的认知就越来越多,搞得每个人都是工具链的量化专家,我们要避免这样的情形涌现。

还有一些非常零散的问题便是用户体验的问题。
我们会有各种各样的反馈,比如早期文档的体验不好,文档没有讲清楚,文档是一个形式化的存单,你写的和你到时候要给我的东西不太一样,这些东西又和我得到的效果不太一样。
在这个过程中,我们也经历了非常多的实践,也是在和用户的打磨之下,通过一条条详细问题的修复,带来了整体体验的提升。
我们早期用J3的客户,过两年再用J5的时候会有一定地提升,由于是平台化的开拓,所有的提升都一贯积累在这个平台上。
回到J5去看,经历两年的韶光有了一个翻天覆地的变革,体验有了更明显地提升。
在这种改进之后,产生了一个从全景来看的偏繁芜的利用体系。
在这个过程中,我也在思考怎么样去跟我们全体研发团队达到共识,该当有好的想法便是怎么样去把它做得好,里面的核心是什么?

我提出来的核心是,在空想的情形下核心路径是只管即便短的,步骤只管即便少的,就像GCC,我最好不要出任何问题。
如果没有任何问题涌现的情形下,我自己编码编好, GCC基本上是没有存在感的状态,这样就可以自然而然把代码变成运用。
我们认为算法工具链也会是类似的好的工具,我们追求是降落存在感。
当然存在感非常强的时候可以利用地很频繁,但真恰好用的时候,其实用户是感知不到它的存在的。

在现实中,现实与空想的差距总是存在的,我们有各种Debug旁路分支的涌现。
这里面的一个要素是什么呢?我们收到很多用户的反馈说出错了,但是他可能得到的结果是扩散的,或者是某一个 Python环境下的对账缺点,一个CHS的Print结果也看不懂,很多运用性的问题就来自于这方面。
以是我认为这个地方的一个辅导原则是非常清晰的,总结为“知错能改”。
“知错”是我们用户任何的反馈互动,要做到和用户的动作干系,他出错的时候知道是由于什么的操作导致了缺点结果。
相应的如果想要结果做得更好,他能够接管什么样的合法操作,这是一个知错能改的状态。
当然我们也没有完备做到这样的状态,只能说是一贯朝着这个方向去努力,这也是我个人的一些思考。

04 算法工具链的演进趋势

对付工具链,未来我们要去做一些什么样的事情呢?我们做工具链的几个核心能力实在是比较清晰的。
我们要把打算图从算法的演习环境下导出来、做模型量化等压缩技能、性能优化。
大略的说便是去干这些事,这些事情也是持续可干的。

比如打算图的表达。
我们最早期在FasterRCNN上,是范例的变成了两阶段的网络。
在第一阶段之后,通过一些Proposal、ROIPooling这样的中间衔接操作,把第二阶段连接起来。
在很多的芯片平台支配上,两阶段模型的支配是偏繁芜的。
在地平线现在的处理里面,我们会在公开的框架表达能力上追加一些我们的认为主流网络自定义算子,比如FasterRCNN,使得它能够得到一段打算图的表达,降落支配的难度。

现在到BEVFormer,同样又会有类似的问题涌现。
当然BEVFormer之后,我们认为这个问题持续在扩散。
它实在是从单目感知做后领悟,到BEV感知,也是端到真个演化阶段性。
我们认为未来的感知任务将会升的更远,从一个记录的图像输入,不仅仅是一个向量空间,还有一些预测的动作都会包含到里面,全体打算图会越来越繁芜。
以是,打算图的表达仍旧会是很大的寻衅。
以是,我们看到PyTorch第二代的升级里面,有一个很主要的部分便是打算图的表达。
最近我也看到了一些边缘真个支配方向,我认为是契合的。

我们须要在这个趋势里面找到一个适宜自己的方向,是不是去复用Torch,还是一些其他的选择,我认为是值得探索的。

然后便是量化压缩方面,稠浊的量化办法。
我们未来该当去选择什么样的打算精度呢?现在看到的打算精度也是越来越多了,我刚刚反复以Int8、FP16为例,这个问题显得偏大略。
目前业界实际关注到这个问题的办理办法也是各种各样的,涌现了 Tf32、cFP8、FP8,还有更低的4bit等,打算精度的选择会越来越多。
工具链就要做出选择,选什么样的打算精度。
不能啥都要,由于啥都要的情形下,导致硬件没办法承受,不堪重负,做不出来。

性能优化方面也是同样,未来去承载一些什么样的打算?我们目前看到了全体的打算没有完备到收敛的状态,它在持续变革。
当然这是一个好事,更多精良成果的产出,使得做智驾的积累越来越厚,大家可以做的越来越好。
但是,对付芯片工具链是一个现实的寻衅。
那么我们如何去应对未来的变数呢?我们在数据的打算类型上要做选择,在数据的存储系统的设计上要做选择,我要几级的存储缓存构造,要多大的带宽等等,这些是各种问题导致的。

同样在未来也会产生一条更受重视的哀求,便是开拓效率。
我们持续在办理的过程,会创造这些技能的更迭是为了什么?这导致了一个结果,便是这个行业的发展变快。
如果行业的发展变快,大家就须要非常强的应变能力,不仅是我们自己,还有我们的目标客户。
他们须要在短期之内更快去OTA算法的效果,并且新的算法技能出来的时候,能够快速跟进。
在缩短从原型到真正量产的周期过程中,我们能够做什么?这是开拓效率的问题。
很永劫光内能做出来是豪杰,现在基本上我们看到最近各种热点话题卷向大家谁做的好,在以数据驱动的感知任务里面,效率是一个非常关键的问题。

为了做好效率方面的事情,我们在当代可以持续地打磨,然后给下一代提一些详细哀求。
但涉及到刚刚提到的打算精度的选择,以及下一代硬件的打算架构该当是怎么样的?它实在来自于一个判断。
这个判断便是未来我们须要一个什么样的打算。
以是有很主要的一点,我们做产品化的工具链的同时,须要去构建一个与芯片联动的平台。

我们做事于当代,也要做事于下一代。
对付下一代来说,我们不断接管这些问题,使它转化为下一代的Benchmark。
在Benchmark的凑集之上创造当代做的不是很好,那我有什么样的方法使它可以做得更好?比如我刚刚提到的特殊的量化的办法,我们要不要去选择?FP8要不要?FP4要不要?还有Vector Quanti要不要,等等,这些都要去做选择。
这些选择不能是一时兴起,我以为主要的是不能由于别人都有,从众生理不能有。
由于如果人家都有,你做一个缝合怪出来,是非常ugly的方案。
以是我们须要一套严格的剖析平台,先做精度仿真,一层层去确认未来须要什么样打算精度,这些打算精度分布在什么样的打算器件上。

同时打算的特点是怎么样的?我们通过这一套平台驱动了纳什架构下对Transformer的优化,通过Benchmark不雅观察识别出带宽会有非常大的压力,我们要去加带宽。
在打算的存储缓存的部件上,我们创造带宽和缓存两者会是一个相互交叉影响的关系,我们须要找到最佳的带宽与存储的配比,同时兼顾芯片的本钱成分。
详细反响到打算单元上,什么样的打算占到了什么比重?它算得不足快,在软件编译优化的层面,有没有条件去隐蔽到那些算得更慢的单元里面去?比如大型的矩阵打算须要更多的韶光,像Softmax、Layout这些不足快的激活打算,是不是能够粉饰在某一些matmul的打算里去,以是又能省一些。
不用把每一个东西都做得那么强,只须要终极的算法效果是有竞争力的。
以是我们在这个过程中要做很多的选择,通过Benchmark驱动,把未来我们须要加入的能力都在这样的仿真平台去验证。

当然这样的仿真平台还有一个好的效果是什么?当下一代芯片平台真正推出来之前,我们基本上能力验证完备,可以快速实现原型化,进而加速产品化,使得我们的开拓套件早早地领先于物理芯片。
比如我可以快速供应仿真开拓环境给我们运用的互助伙伴。
在芯片回片之前,我们就可以基于它做一些前期的算法运用的原型验证,到芯片回来的时候快速统统,空想状态便是这么丝滑。
这是一个行业内芯片厂商与未来运用厂商的异步开拓模式,整体上还是效率的问题,这将推向这个行业走向更高的迭代效率。

我本日要分享的内容就这些,感激大家。

标签:

相关文章

聚焦|美国的军事通信系统_通讯_美军

80年代,美军开始探求新的技能来升级军事通信网络,希望新的军事通信网络能够供应更广范围的覆盖、更好的纠错能力和更高的数据容量,并且...

科学 2025-01-12 阅读0 评论0