掌桥专利:专业的专利平台
掌桥专利
首页

技术领域

本公开涉及神经网络领域,具体而言,涉及深度学习模型的调优方法、编译方法及计算装置。

背景技术

近年来,随着人工智能的不断兴起,深度学习模型成为当前广泛应用的一种预测模型。随着越来越多的应用程序配备深度学习模型,人们也越来越意识到,虽然较大尺寸的深度学习模型有助于提升深度学习模型的预测准确度,但是较大尺寸的深度学习模型在运行时也占据过多的内存含量和内存带宽,从而影响模型效率和响应速度。

为了解决这个问题,目前对深度学习模型的大小改进集中在两个方面:第一是设计更有效的网络架构,用相对较小尺寸的深度学习模型达到可接受的预测准确度;第二是通过压缩、编码等方式减小网络规模,量化是最广泛采用的压缩方法之一。量化将浮点运算转换为整型运算。整型运算比浮点运算快很多倍,因此理论上量化后的深度学习模型将比量化之前的深度学习模型快很多倍,但是现有技术中的方法在一些无需量化操作的位置添加了量化算子,从而使得量化后的深度学习模型的模型效率比预期较差。

发明内容

基于此,本公开的目的是提供一种深度学习模型的调优方法、编译方法及计算装置,进一步提升量化后的深度学习模型的模型效率。

本公开实施例提供一种计算装置,包括存储器、调度单元和指定加速单元,所述存储器存储指令,所述处理器读取所述指令,以执行:

在深度学习模型的算子流中,根据相邻算子的输入类型和输出类型在所述相邻算子之间插入用于执行量化操作的量化算子和/或用于执行反量化操作的反量化算子;

将所述算子流部署到所述指定加速单元上执行。

可选地,所述根据相邻算子的输入类型和输出类型在所述相邻算子之间插入量化算子和/或反量化算子包括:

当所述相邻算子的前一算子的输出类型与后一算子的输入类型不同时,则在所述相邻算子之间插入量化算子和/或反量化算子。

可选地,所述输入类型和输出类型被归类为高精度类型和低精度类型,所述当所述相邻算子的前一算子的输出类型与后一算子的输入类型不同时,则在所述相邻算子之间插入量化算子和/或反量化算子包括:

当所述相邻算子的前一算子的输出类型为高精度类型且后一算子的输入类型为低精度类型时,则插入量化算子;当所述前一节点的输出类型为低精类型且所述后一节点的输入算子为高精度类型时,则插入反量化算子。

可选地,所述当所述相邻算子的前一算子的输出类型与后一算子的输入类型不同时,则在所述相邻算子之间插入量化算子和/或反量化算子包括:

当所述相邻算子的前一算子的输出类型为第一数据类型,后一算子的输入类型为第二数据类型,如果所述第一数据类型和所述第二数据类型属于同一精度类型,则基于所述第一数据类型和所述第二数据类型在所述存储器中所占的比特位插入算子或反量化算子;如果所述第一数据类型和所述第二数据类型不属于同一精度类型,则按照精度类型插入量化算子或反量化算子。

可选地,在所述相邻算子之间插入量化算子和/反量化算子还与所述量化算子和所述反量化算子的输入类型和输出类型相关。

可选地,利用预定义的状态机,根据所述相邻算子的输入类型和输出类型在所述相邻算子之间插入用于执行量化操作的量化算子和/或用于执行反量化操作的反量化算子,所述状态机包括表示多个数据类型的多个状态标识以及连接每两个所述状态标识的、表示各个算子的输入类型和输出类型的多个有向连接边。

可选地,所述利用预定义的状态机,根据所述相邻算子的输入类型和输出类型在所述相邻算子之间插入量化算子和/或反量化算子包括:

将所述算子流的各个算子与所述状态机的多个有向连接边比对,以确定有向连接边是否被触发;

当一个有向连接边被触发时,如果被触发的有向连接边的源状态标识与所述被触发的有向连接表示的算子的输入类型不符,在相应算子之前插入所述量化算子和/或所述反量化算子,或,如果所述被触发的有向连接边的目标状态标识与所述被触发的有向连接边表示的算子的输出类型不符,在相应算子之后插入所述量化算子和/或所述反量化算子。

可选地,在所述状态机中,初始的状态标识表示的数据类型与所述算子流的第一个算子的输入类型一致。

可选地,在所述状态机中,所述有向连接边表示的算子的输入类型与所述有向连接边的源状态标识相同,和/或所述有向连接边表示的算子的输出类型与所述有向连接边的目标状态标识相同。

可选地,还包括:在所述算子流的开始位置插入所述量化算子,以及在所述算子流的结束位置插入所述反量化算子。

可选地,所述输入类型和输出类型分别为以下类型中的一种:16位浮点数、24位浮点数、32位浮点数、64位浮点数、32位有符号整型、 16位有符号整型、8位有符号整型、8位无符号整型。

第二方面,本公开实施例提供一种深度学习模型的调优方法,包括:

在深度学习模型的算子流中,根据相邻算子的输入类型和输出类型在所述相邻算子之间插入用于执行量化操作的量化算子和/或用于执行反量化操作的反量化算子;

将所述算子流部署到指定加速单元上执行。

可选地,所述根据相邻算子的输入类型和输出类型在所述相邻算子之间插入量化算子和/或反量化算子包括:

当所述相邻算子的前一算子的输出类型与后一算子的输入类型不同时,则确定在所述相邻算子之间插入量化算子和/或反量化算子。

可选地,所述输入类型和输出类型被归类为高精度类型和低精度类型,所述当所述相邻算子的前一算子的输出类型与后一算子的输入类型不同时,则在所述相邻算子之间插入量化算子和/或反量化算子包括:

当所述相邻算子的前一算子的输出类型为高精度类型且后一算子的输入类型为低精度类型时,则插入量化算子;当所述前一节点的输出类型为低精类型且所述后一节点的输入算子为高精度类型时,则插入反量化算子。

可选地,所述当所述相邻算子的前一算子的输出类型与后一算子的输入类型不同时,则在所述相邻算子之间插入量化算子和/或反量化算子包括:

当所述相邻算子的前一算子的输出类型为第一数据类型,后一算子的输入类型为第二数据类型,如果所述第一数据类型和所述第二数据类型属于同一精度类型,则基于所述第一数据类型和所述第二数据类型在所述存储器中所占的比特位插入算子或反量化算子;如果所述第一数据类型和所述第二数据类型不属于同一精度类型,则按照精度类型插入量化算子或反量化算子。

可选地,在所述相邻算子之间插入量化算子和/反量化算子还与所述量化算子和所述反量化算子的输入类型和输出类型相关。

可选地,利用预定义的状态机,根据所述相邻算子的输入类型和输出类型在所述相邻算子之间插入所述量化算子和/或所述反量化算子,所述状态机包括表示多个数据类型的多个状态标识及连接每两个所述状态标识的、表示各个算子的输入类型和输出类型的多个有向连接边。

可选地,所述利用预定义的状态机,根据所述相邻算子的输入类型和输出类型在所述相邻算子之间插入所述量化算子和/或所述反量化算子包括:

将所述算子流的各个算子与所述状态机的多个有向连接边比对,以确定有向连接边是否被触发;

当一个有向连接边被触发时,如果被触发的有向连接边的源状态标识与所述被触发的有向连接表示的算子的输入类型不符,在相应算子之前插入所述量化算子和/或所述反量化算子,或,如果所述被触发的有向连接边的目标状态标识与所述被触发的有向连接边表示的算子的输出类型不符,在相应算子之后插入所述量化算子和/或所述反量化算子。

可选地,在所述状态机中,初始的状态标识表示的数据类型与所述算子流的第一个算子的输入类型一致。

可选地,在所述状态机中,所述有向连接边表示的算子的输入类型与所述有向连接边的源状态标识相同,和/或所述有向连接边表示的算子的输出类型与所述有向连接边的目标状态标识相同。

可选地,还包括:在所述算子流的开始位置插入所述量化算子,以及在所述算子流的结束位置插入所述反量化算子。

可选地,所述输入类型和输出类型分别为以下类型中的一种:16位浮点数、24位浮点数、32位浮点数、64位浮点数、32位有符号整型、 16位有符号整型、8位有符号整型、8位无符号整型。

第三方面,本公开实施例提供一种深度学习模型的编译方法,所述编译方法在编译器中实现,包括:

将深度学习模型从源代码编译为第一指令序列;

从所述第一指令序列中获取可在指定加速单元上执行的算子流;

在所述算子流中,根据相邻算子的输入类型和输出类型在所述相邻算子之间插入用于执行量化操作的量化算子和/或用于执行反量化操作的反量化算子;

将处理后的算子流部署到指定加速单元上执行。

可选地,所述第一指令序列为所述编译器产生的中间指令序列,所述第二指令序列为可执行指令序列。

第四方法,本公开实施例提供一种数据中心,包括上述任一项所述的计算装置。

本公开实施例的深度学习模型的调优方法,根据相邻算子的输入类型和输出类型确定是否在相邻算子之间插入量化算子和/或反量化算子并执行,以此避免插入冗余的量化算子和/或反量化算子,从而保证了由此得到的算子流的指令精简,并以此提高深度学习模型的模型效率和响应速度。

附图说明

通过参考以下附图对本公开实施例的描述,本公开的上述以及其它目的、特征和优点将更为清楚,在附图中:

图1示出本公开一个实施例所应用的数据中心的层级结构图;

图2是本公开一个实施例所应用的数据中心的结构图;

图3是本公开一个实施例的数据中心中一个服务器的内部结构框图;

图4是根据本公开一个实施例服务器内部的中央处理单元(CPU)和神经网络加速单元(NPU)的控制关系图;

图5是根据本公开一个实施例的NPU核的内部结构图;

图6是示例性的用于深度学习模型的编译和优化的软件平台的架构图;

图7A和图7B分别是插入量化算子之前和插入量化算子之后的算子流;

图8是本公开实施例提供的深度学习模型的调优方法的流程图;

图9是一个示例性的状态机;

图10是经由状态机转换的示例性的指令序列;

图11示出了基于同一个原始算子流,根据现有技术处理后得到的目标算子流和采用本公开实施例得到的目标算子流的对比例;

图12是本公开实施例提供的深度学习模型的编译方法的流程图。

具体实施方式

以下基于实施例对本公开进行描述,但是本公开并不仅仅限于这些实施例。在下文对本公开的细节描述中,详尽描述了一些特定的细节部分。对本领域技术人员来说没有这些细节部分的描述也可以完全理解本公开。为了避免混淆本公开的实质,公知的方法、过程、流程没有详细叙述。另外附图不一定是按比例绘制的。

在本文中使用以下术语。

加速单元:也称为神经网络加速单元,针对通用处理器在一些专门用途的领域(例如,处理图像、处理神经网络的各种运算,等等)效率不高的情况,为了提高在这些专门用途领域中的数据处理速度而设计的处理单元,它往往与通用处理器CPU配套使用,接受通用处理器的控制,执行一些特定用途或特定领域的处理,提高在特定用途或特定领域中的计算机处理效率。

片上内存:在主核或副核内单独使用,不能被共享的存储器。

命令处理器:在加速单元和驱动该加速单元工作的中央处理单元之间的命令接口。命令处理器接收中央处理单元让加速单元执行的指令,将这些指令分给加速单元中的各个核去执行。另外,它还负责加速单元中各个核的同步。

生命周期:操作数在指令序列中并不是在全部过程中都会涉及到,在指令序列中其第一次出现和最后一次用到的指令之间的部分,就是该操作数的生命周期。也就是说,过了该生命周期后,它就不再使用,没有必要留在片上内存中。

神经网络:一般指人工神经网络(Artificial Neural Network,简写为ANN),它是一种模仿动物神经网络行为特征,进行分布式并行信息处理的算法网络。一个经典的神经网络,也是最简单的神经网络结构,包含三个层次:输入层、输出层和中间层(又称隐藏层)。输入层、输出层和中间层又各自包括多个节点。节点是神经网络中的最小处理单元。经由大量、简单功能的神节点的广泛的互相连接能够形成非常复杂的神经网络结构。

神经网络模型:在神经网络中,将节点数学化,产生节点的数学模型,神经网络中的大量的节点的数学模型构成了神经网络模型。

深度学习模型:深度学习的概念源于神经网络的研究,将含有多个中间层的神经网络称为深度学习网络。因此,从这个意义上将,深度学习模型也是一种神经网络模型。深度学习模型和神经网络模型都必须经由训练产生。将样本数据输入到设计好的网络结构(即网络结构已经确定)中,经由多个中间层提取特征信息,并基于输出层的输出结果不断地修正神经元的权重参数,使输出层的输出结果愈来愈趋向于预设结果,直至确定最终的权重参数。训练好的深度学习模型可以真正地应用于实际场景中,同时还可以收集深度学习模型在实际场景中的使用情况,反过来优化深度学习模型。

算子:是指在深度学习模型中构建的用于实现特定功能的一系列操作的集合。深度学习模型可包含多个这样的算子,而且这些算子可在加速单元上的硬件执行单元上执行。

图1示出作为本公开实施例所应用的一种场景的数据中心的分层结构图。

数据中心是全球协作的特定设备网络,用来在互联网网络基础设施上传递、加速、展示、计算、存储数据信息。在今后的发展中,数据中心也将会成为企业竞争的资产。随着数据中心应用的广泛化,人工智能等越来越多地应用到数据中心。而神经网络作为人工智能的重要技术,已经大量应用到数据中心大数据分析运算中。

在传统的大型数据中心,网络结构通常是图1所示的三层结构,即分级的互连网络模型(hierarchical inter-networkingmodel)。这个模型包含了以下三层:

接入层(Access Layer)103:有时也称为边缘层,包括接入交换机 130和接入交换机所连接的各服务器140。各服务器140是数据中心的处理和存储实体,数据中心中大量数据的处理和存储都是由这些服务器 140完成的。接入交换机130是用来让这些服务器接入到数据中心中的交换机。一台接入交换机130接入多台服务器140。接入交换机130通常位于机架顶部,所以它们也被称为机顶(Top of Rack)交换机,它们物理连接服务器。

汇聚层(Aggregation Layer)102:有时候也称为分发层,包括汇聚交换机120。每台汇聚交换机120连接多台接入交换机,同时提供其他的服务,例如防火墙,入侵检测,网络分析等。

核心层(Core Layer)101:包括核心交换机110。核心交换机110 为进出数据中心的包提供高速的转发,为多个汇聚层提供连接性。整个数据中心的网络分为L3层路由网络和L2层路由网络,核心交换机110 为通常为整个数据中心的网络提供一个弹性的L3层路由网络。

通常情况下,汇聚交换机120是L2和L3层路由网络的分界点,汇聚交换机120以下的是L2网络,以上是L3网络。每组汇聚交换机管理一个传送点(POD,Point Of Delivery),每个POD内都是独立的VLAN 网络。服务器在POD内迁移不必修改IP地址和默认网关,因为一个POD 对应一个L2广播域。

汇聚交换机120和接入交换机130之间通常使用生成树协议(STP,Spanning TreeProtocol)。STP使得对于一个VLAN网络只有一个汇聚层交换机120可用,其他的汇聚层交换机120在出现故障时才被使用(上图中的虚线)。也就是说,在汇聚层,做不到水平扩展,因为就算加入多个汇聚交换机120,仍然只有一个在工作。

图2示出了图1的分层的数据中心中各部件的物理连接。如图2所示,一个核心交换机110连接多个汇聚交换机120,一个汇聚交换机120 连接多个接入交换机130,一个接入交换机130接入多个服务器140。

由于服务器140才是数据中心真实的计算装置,图3示出了一个服务器140内部的结构框图。服务器140包括有总线连接的存储器210、中央处理器(CPU)220和各种加速单元。这些加速单元包括神经网络加速单元(NPU)230、数据传输单元(DTU)260、图形处理单元(GPU,未示)、专用集成电路(ASIC,未示)和现场可编程门阵列(FPGA,未示)。

传统的处理器的架构设计,使得在架构中控制单元、存储单元占用了很大一部分空间,而计算单元占用的空间反而不足,因此其在逻辑控制方面十分有效,而在大规模并行计算方面则效率不够。因此,开发出了各种专门的加速单元,用来针对不同功能和不同领域的计算进行更有效的提高运算速度的处理。本公开提出的加速单元可以是它们中的任一种,下面对这些加速单元分别进行介绍。

神经网络加速单元(NPU)230:它是采用数据驱动并行计算的架构,用于处理各神经网络节点的大量运算(例如卷积、池化等)的处理单元。由于各神经网络节点的大量运算(例如卷积、池化等)中的数据和中间结果在整个计算过程中紧密联系,会被经常用到,用现有的CPU构架,由于CPU核内的内存容量很小,因此要大量频繁访问核外存储器,造成处理的低效。采用NPU,每个核中具有适于神经网络计算用到的存储容量的片上内存,避免频繁访问核外部的存储器,就能大大提高处理效率,提高计算性能。

数据传输单元(DTU)260:它是专门用于将串口数据转换为IP数据或将IP数据转换为串口数据通过无线通信网络进行传送的无线终端设备。DTU的主要功能是把远端设备的数据通过无线的方式传送回后台中心。在前端,DTU和客户的设备通过接口相连。DTU上电运行后先注册到移动的GPRS网络,然后去和设置在DTU中的后台中心建立套接字连接。后台中心作为套接字连接的服务端,DTU是套接字连接的客户端。因此 DTU和后台软件配合一起使用,在建立连接后,前端的设备和后台的中心就可以通过DTU进行无线数据传输。

图形处理单元(GPU):是专门做图像和图形相关运算工作的微处理器。GPU开发了CPU中计算单元的空间过少的缺点,采用大量用于专门做图形计算的计算单元,使显卡减少了对CPU的依赖,承担了CPU原来承担的一些计算密集的图形图像处理工作。

专用集成电路(ASIC):是指应特定用户要求和特定电子系统的需要而设计、制造的集成电路。由于这种集成电路是按照用户要求定制的,其结构往往与特定用户要求相适应。

现场可编程门阵列(FPGA):是在PAL、GAL等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电路数有限的缺点。

加速单元虽然有对于特定的应用或领域来说,执行效率大大高于普通处理器的优点,但也要接受调度单元220的控制。以NPU为例,存储器210中存储有各种深度学习模型,包括这些模型的神经元和神经元的权重数据等。这些深度学习模型当需要时被图3中的一个调度单元220 部署到一个加速单元230。具体地,调度单元220可以通过指令的形式向加速单元230告知加速单元230深度学习模型在存储器210的存储位置。加速单元230然后可以根据这些位置进行寻址,将待执行指令存储在其片上内存中。调度单元220也可以通过指令的形式向加速单元230 发送加速单元230的待执行指令,加速单元230接收指令并存储到到片上内存中。同理,加速单元230也可以通过上述方式获取输入数据。加速单元230获取待执行指令和输入数据,以进行推理计算。节点的权重参数可以包含在深度学习模型的指令序列中,由加速单元230一并从存储器210中取出。当然节点的权重参数也可以独立存储,由加速单元230 在需要时从存储器210中取出。此处调度单元220可以理解为具有调度和控制能力的硬件单元,一般可为中央处理器(CPU)、微控制器、微处理器等硬件单元。

下面结合图4的调度单元与加速单元的内部结构图,具体说明调度单元是如何控制加速单元进行工作的。

如图4所示,调度单元220内包含多个处理器核222和被多个处理器核222共享的高速缓存221。每个处理器核222包括取指令单元203、指令译码单元224、指令发射单元225、指令执行单元226。

取指令单元223用于将要执行的指令从存储器210中搬运到指令寄存器(可以是图4示出的寄存器堆229中的一个用于存放指令的寄存器) 中,并接收下一个取指地址或根据取指算法计算获得下一个取指地址,取指算法例如包括:根据指令长度递增地址或递减地址。

取出指令后,调度单元220进入指令译码阶段,指令译码单元224 按照预定的指令格式,对取回的指令进行解码,以获得取回的指令所需的操作数获取信息,从而为指令执行单元225的操作做准备。操作数获取信息例如指向立即数、寄存器或其他能够提供源操作数的软件/硬件。

指令发射单元225位于指令译码单元224与指令执行单元226之间,用于指令的调度和控制,以将各个指令高效地分配至不同的指令执行单元226,使得多个指令的并行操作成为可能。

指令发射单元225将指令发射到指令执行单元226后,指令执行单元226开始执行指令。但如果该指令执行单元226判断该指令应该是加速单元执行的,则将其转发到相应的加速单元执行。例如,如果该指令是一条神经网络推理(inference)的指令,指令执行单元226不再执行该指令,而是将该指令通过总线发送到加速单元230,由加速单元230 执行。

加速单元230内部包括多个核236(图4中示出了4个核,但本领域技术人员应当理解,加速单元230中也可以包含其它数目的核236)、命令处理器237、直接存储访问机制235、和总线通道231。

总线通道231是指令从总线进出加速单元230的通道。按照不同的机制,总线通道231可以包括PCIE通道232、I2C通道233、JTAG通道234。

PCIE即PCI-Express,是一种高速串行计算机扩展总线标准,是由英特尔在2001年提出的,旨在替代旧的PCI,PCI-X和AGP总线标准。 PCIE属于高速串行点对点双通道高带宽传输,所连接的设备分配独享通道带宽,不共享总线带宽,主要支持主动电源管理,错误报告,端对端的可靠性传输,热插拔以及服务质量等功能。它的主要优势就是数据传输速率高,而且还有相当大的发展潜力。目前,PCIE的总线大多是PCIE GEN3,但本公开实施例也可以采用PCIE GEN4,即遵循PCI-Express4.0 标准的总线通道。

I2C通道233是由Philips公司开发的一种简单、双向二线制同步串行总线通道。它只需要两根线即可在连接于总线上的器件之间传送信息。

JTAG是联合测试工作组(Joint Test Action Group)的简称,是在名为标准测试访问端口和边界扫描结构的IEEE的标准1149.1的常用名称。此标准用于验证设计与测试生产出的印刷电路板功能。1990年 JTAG正式由IEEE的1149.1-1990号文档标准化,在1994年,加入了补充文档对边界扫描描述语言(BSDL)进行了说明。从那时开始,这个标准被全球的电子企业广泛采用。边界扫描几乎成为了JTAG的同义词。 JTAG通道234即是遵循该标准的总线通道。

直接内存访问(DMA,Direct Memory Access)机制235是一些计算机总线架构提供的功能,它能使数据从附加设备(例如外部的存储器)直接写入到加速单元230的片上内存中。这种方式相比于设备之间所有的数据传输都要通过命令处理器237的方式,大大提高了数据访问的效率。正是因为有这样的机制,加速单元230的核可以直接访问存储器210,读取深度学习模型中的参数(例如各节点的权重参数)等,大大提高了数据访问效率。虽然图上示出直接内存访问机制235位于处理器237和总线通道231之间,但是加速单元230的设计不局限于此。在某些硬件设计中,每个NPU核236都可以包含一个直接内存访问机制235,从而NPU核236无需经由命令处理器237,而是直接从附加设备上读取数据并写入到加速单元230的片上内存中。

命令处理器237将由调度单元220送至加速单元230的指令分配给核236执行。指令执行单元226将需要加速单元230执行的待执行指令发送给加速单元230或者指令执行单元226告知待执行指令在存储器 210上的存储位置。待执行指令序列从总线通道231进入后,缓存在命令处理器237,由命令处理器237选择核236,将指令序列分配给其执行。待执行指令来自编译好的深度学习模型。需要明白的是,待执行指令序列中,可以包括在调度单元220执行的待执行指令和需要在加速单元230 执行的待执行指令。

图5是根据本公开一个实施例的NPU核的内部结构图。

在一个实施例中,如图5所示,NPU核236包括张量引擎310、池化引擎320、卷积处理330、激活操作380、定序器350、指令缓存器340、片上内存360、常数缓冲器370。其中,张量引擎310、池化引擎320、卷积处理330和激活操作380都是硬件执行单元。硬件执行单元是加速单元中真正用于执行各项运算的硬件模块。还有一些硬件执行单元未在图上示出。

命令处理器237分配给NPU核236的指令序列首先进入指令缓存器 340缓存。然后,定序器350从指令缓存器340中按照先进先出的顺序取指令,根据指令的性质分配给各个硬件执行单元执行。张量引擎310 负责处理深度学习模型中的张量相关操作。池化引擎320负责处理深度学习模型中的池化操作。卷积处理330负责深度学习模型中的卷积操作。激活操作380用于执行深度学习模型中的激活函数所对应的操作。定序器350根据取出的指令是卷积、矩阵乘法还是池化等操作性质,决定将指令分配给各个硬件执行单元执行。

片上内存360是存储深度学习模型中的权重参数以及深度学习模型实际使用时的输入和各种中间结果的核内存储器。常数缓冲器370是存储深度学习模型中除权重参数之外的其它常量参数(例如,深度学习模型中的超参)的缓冲器。如上所述,在调度单元220将深度学习模型预先配置在加速单元230的过程中,调度单元220可以通过指令的形式向加速单元230发送模型中的参数在存储器210中的位置。这些参数包括节点的权重和其它参数(例如超参)。对于权重,加速单元230需要时就会从存储器210相应的位置取出,放在片上内存360中。对于其它参数,加速单元230需要时就会从存储器210相应的位置取出,放在常数缓冲器370中。另外,当可执行指令由命令处理器237分配给核236执行后,指令中的输入参数(给深度学习模型的输入)也存储在片上内存 360。另外,当张量引擎310和池化引擎320进行卷积或池化运算后,得到的各种中间结果也存放在片上内存360中。

深度学习模型的改进不仅需要上述硬件层的支持,而且需要软件层和算法层持续的改进。只能将底层最好的硬件支持和上面最好的深度学习算法结构结合起来,才能交付一个强大的计算引擎。

图6示出了示例性的深度学习模型的软件平台。该软件平台部署在研发人员的终端设备,提供适用于深度学习模型的各种环境,包括编辑环境、编译环境、量化运行环境、模拟运行环境,研发人员能够基于该平台实现深度学习模型的代码编辑、代码编译、参数调整、量化、模拟运行(即在CPU上运行模型)等一系列的操作。

参见图上所示,从上往下,架构图包括应用层401,框架层402,功能层403。

应用层401是深度学习模型在特定场景下的应用,例如视觉405,自然语言406,推荐407等方面的应用。这些应用使用本架构构建,也可以在应用中调用架构提供运行接口,以在应用中获得推理能力。

框架层402整合TensorFlow 408,MXNet 409,Caffe 410等开源平台,并且提供算子库和工具,使得可以继续对各种算法进行优化和改进。 TensorFlow408是一个基于数据流编程的符号数学系统,被广泛应用于各类机器学习(machine learning)算法的编程实现。MXNet 409是亚马逊(Amazon)选择的深度学习库。Caffe 410,全称ConvolutionalArchitecture for Fast Feature Embedding,是一个兼具表达性、速度和思维模块化的深度学习框架。

功能层403包括编译栈403和运行栈404。编译栈403用于对各种模型进行转化(converter)411、量化(quantization)412、优化(optimization)413和编译(compile)414。转化411是提供模型的内部数据转化为中间(IR)格式。量化412是将深度学习模型中的权重参数以及给深度学习模型的输入参数从高精度类型转换为低精度类型。优化413包括模型内部的算子进行融合,多模型优化链接等操作。编译 414是根据加速单元对模型进行优化,生成硬件能够识别的二进制模型。运行栈404包括运行API 415、执行管理器416、用户模式驱动器417 和内核模式驱动器418。执行管理器416执行的资源分配,批量调度。优化运行API 415用于提供各种运行时可以调用的接口。用户模式驱动器417和用于提供内核模式下的硬件命令,资源调度。内核模式驱动器 418用于提供内核模式下的任务调度和硬件控制等。

应理解,图6所示的为一个通用型的软件平台。市面上还有一些专用于构建特定类型的深度学习模型的软件平台。当然,本公开实施例并不依赖于特定软件平台。

本公开所述的量化操作是将深度学习模型的输入数据从高精度数据转换为低精度数据,反量化操作是将深度学习模型的输入数据从低精度数据转换为高精度数据。一般来说,我们将浮点数据划分为高精度数据,整型划分为低精度数据,则从高精度数据转换为低精度数据为量化操作,反之为反量化操作。如果两个数据同为一个精度,则根据两个数据各自占据的比特位确定精度类型。目前深度学习模型可以采用的数据类型包括但不局限于以下几种:16位浮点数、24位浮点数、32位浮点数(fp32)、 64位浮点数(fp64)、32位有符号整型(int32)、16位有符号整型(int16)、 8位有符号整型(int8)、8位无符号整型(uint8)。例如,将32位浮点数据转换为8位有符号整型数据需要执行量化操作,反之执行反量化操作。再例如,将32位浮点数据转换为16位浮点数据需要执行量化操作,反之执行反量化操作。

具体实施时,量化操作和反量化操作还可区分为线性映射方法和非线性映射方法。在线性量化的情况下,可以通过如下的公式来进行量化。δ是缩放系数,相当于每单位的量化后数值代表着量化前的数值差。由于考虑到零点问题(浮点数为0的无误差表示),需要为量化方法增加一个偏移量,即zq。δ和zq是由待量化输入的最大值xmax、最小值xmin 决定的。它将【xmin,xmax】内的待量化输入量化为0到n-1之间(包括0和n-1)的任意一个整数。设q(x)是待量化输入x量化成的数值,有公式:

其中,clamp为限值函数,公式1表示将round((x-x

考虑到零点问题后的缩放系数δ如下计算:

由于考虑到零点问题,不能单纯根据(x/δ)的数值来确定将其量化为0到n-1中的哪一个,要考虑偏移量z

考虑该偏移量z

应当注意,上述仅给出了一种量化方式,本领域技术人员已知,还存在其它量化方式。在其它量化方式中,具有其它量化公式。

现结合图7A和图7B的示例进行进一步说明。在图7A中,序列701 是深度学习模型的算子流,由可在指定加速单元上运行的算子组成,表示未插入量化算子之前的深度学习模型(只是其中的一部分)。序列701 包括卷积(conv)算子、池化(pooling)算子和又一卷积(conv)算子。

在加速单元中,由于每个硬件执行单元的输入输出类型已经固定,因此需要根据计算和存取的要求时刻注意深度学习模型的输入输出数据的高精度和低精度的状态转换,即有时需要高精度数据转换为低精度数据,有时需要将低精度数据转换为高精度数据。

图7B示出了根据现有技术中插入量化算子之后的深度学习模型。在图7B中,序列702是深度学习模型的算子流,表示插入量化算子之后的深度学习模型(只是其中的一部分)。序列702包括卷积(conv)算子、反量化算子(DQ)、量化算子(Q)、池化算子(pooling)、反量化算子 (DQ)、量化算子(Q)、卷积算子(conv)、反量化算子(DQ)和量化算子(Q)。

深度学习模型经过图6所示的软件平台编译后,得到可在指定加速单元上执行的指令序列,调度单元220控制将可在加速单元上执行的算子流部署到加速单元230上,加速单元230不能执行的指令序列部署到调度单元220上执行。加速单元230从存储器210上读取可执行的算子流后,将其分发给多个NPU核236上执行。NPU核236包括多个硬件执行单元。每个硬件执行单元可以执行一个或多个算子。可执行的算子被 NPU核236内的定序器350分配给相应的硬件执行单元。例如,序列702 经过图6所示的软件平台编译后,转换为可以在加速单元230上执行的算子流,加速单元230将算子流分配给各个硬件执行单元:池化算子对应的指令对应的被定序器350分配给池化引擎320执行,卷积算子被定序器350分配给卷积处理330执行,量化算子会被分配给量化执行单元执行,反量化算子会被分配反量化执行单元执行,以完成量化操作和反量化操作。

现有技术中,基于单一算子的输入输出类型确定是否插入量化或反量化算子。例如图7B所示的序列702,先看池化算子,池化算子的输出类型为8位有符号整型,将其转换为量化值,再看卷积算子,卷积算子的输入类型也为8位有符号整型,因此再插入一个反量化算子。

图8是根据本公开实施例提供的深度学习模型的调优方法的流程图。该量化方法应用于算法层面,涉及对深度学习模型的源代码的改进。该方法具体包括以下步骤。

步骤S801,在深度学习模型的算子流中,根据相邻算子的输入类型和输出类型在相邻算子之间插入用于执行量化操作的量化算子和/或用于执行反量化操作的反量化算子。

步骤S802,将算子流部署到指定加速单元上执行。

首先得到深度学习模型的算子流。该算子流可以基于深度学习模型的源代码或可执行代码得到。该算子流包含的每个算子都可以在指定加速单元上执行,即该算子流中的每个算子都在指定加速单元上有对应的硬件执行单元。我们知道,加速单元专门为人工智能神经网络而设计,用于加速神经网络的运算,解决传统芯片在神经网络运算时效率低下的问题。在加速单元上构建了很多硬件执行单元,这些硬件执行单元在执行指令时具有很高的执行效率。相应地,在如图6所示的框架层,根据指定加速单元上的各种硬件执行单元,为深度学习模型构建了多个算子。这些算子可以在相应硬件执行单元上执行,且每个算子的输入和输出类型与相应的硬件执行单元的输入和输出类型保持一致,例如在框架层构建卷积算子、池化算子、量化算子、反量化算子等等。

然后确定算子流的每个算子的输入和输出类型。深度学习模型的各个算子的输入和输出类型可以存储在表格1中。表格1列出了一个示例性的各个算子的输入和输出类型。如图上所示,例如,卷积算子的输入和输出类型为8位有符号整型的低精度数据类型,池化算子的输入和输出类型也为8位有符号整型的低精度数据类型。基于表格1,能够得到上述算子流中的每个算子的输入和输出类型。

表格1

然后根据相邻算子的输入类型和输出类型在相邻算子之间插入用于执行量化操作的量化算子和/或用于执行反量化操作的反量化算子。基于表格1,以相邻的卷积算子和激活算子为例。卷积算子的输入为8位有符号整型,输出类型为32位有符号整型,激活算子的输入和输出类型也为24位浮点数,因此在卷积算子和激活算子之间需要插入反量化算子,将卷积算子的输出数据从32位有符号整型转换为24位浮点数。再例如,基于表格1,以相邻的卷积算子和池化算子为例。由于卷积算子的输入为8位有符号整型,输出类型为32位有符号整型,池化算子的输入和输出类型均为8位有符号整型,因此需要在卷积算子和池化算子之间先插入反量化算子,再插入量化算子。

最终将算子流部署到指定加速单元上执行,也即将插入了量化算子和/或反量化算子的算子流部署到指定加速单元上执行。

综上,本实施例根据各个算子的输入和输出类型确定是否在相邻算子之间插入量化算子和/或反量化算子并执行,以此避免插入冗余的量化算子和/或反量化算子,从而保证了由此得到的算子流的指令精简,从而提高了深度学习模型的模型效率和响应速度。

在一些实施例中,相邻算子的输入和输出类型指的是相邻算子的前一个算子的输出类型和后一个算子的输入类型,当前一算子的输出类型和后一节点的输入类型相同,则确定不在该相邻算子之前增加量化算子和/或反量化算子,当相邻算子的前一算子的输出类型与相邻算子的后一算子的输入类型不同时,则确定在相邻算子之间增加量化算子和/或反量化算子。经过上述处理后的算子流可经由如图6所示的软件平台的编译后,部署到指定加速单元上执行。

在一些实施例中,可将各种算子的输入类型和输出类型归类为各种精度类型,例如高精度类型或低精度类型,则如果相邻算子的前一算子的输出类型为低精度类型,后一算子的输入类型为高精度类型,则在两个算子之间插入反量化算子,如果相邻算子的前一算子为高精度类型,后一算子的输入类型为低精度类型,则在两个算子之间插入量化算子,而前一算子的输出类型和后一算子的输入类型属于同一精度时,则无需插入。

在一些实施例中,当前一算子的输出类型为第一数据类型,后一算子的输入类型为第二数据类型,如果第一数据类型和第二数据类型属于同一精度类型,则基于第一数据类型和第二数据类型在存储器中所占的比特位确定插入的是量化算子还是反量化算子,如果第一数据类型和第二数据类型不属于同一精度类型,则按照精度类型确定插入的是量化算子还是反量化算子。第一数据类型和第二数据类型为以下数据类型中的一种:16位浮点数、24位浮点数、32位浮点数(fp32)、64位浮点数(fp64)、 32位有符号整型(int32)、16位有符号整型(int16)、8位有符号整型 (int8)、8位无符号整型(uint8)。本实施方式和上一实施方式的不同之处在于,上一实施方式对于同一精度类型下的数据,无需转换,本实施例方式从任意一种数据类型转换为另一种数据类型,都需要量化和/或反量化操作,例如从int32转换到int8,也需要执行量化操作。

在一些实施例中,将各个算子的输入和输出类型可以存储在一个数据库表内,当获取到深度学习模型的算子流时,根据每个算子的标识检索该数据库表,从而获得每个算子的输入和输出类型,然后根据相邻算子的输入和输出类型确定是否在相邻算子之间插入量化和/或反量化算子。

在一些实施例中,利用预定义的状态机确定是否插入量化算子和反量化算子。所述状态机包括表示多个数据类型的多个状态标识以及连接每两个所述状态标识的、表示各个算子的输入类型和输出类型的多个有向连接边。下面以图9所示的状态机10进行说明。

如图上所示,start标识表示初始状态,代表Int8的数据类型。状态1为中间状态,代表int32的数据类型。状态2为中间状态,表示fp24 的数据类型。start状态与状态1之间有两条有向连接边①和③。有向连接边①的箭头方向表示start标识为源状态,状态1为目标状态,有向连接边①的连接边表示卷积算子,并且在图上标出了卷积算子的输入和输出类型为int8和int32。有向连接边③的箭头方向表示状态1为源状态,start标识为目标状态,有向连接边③的连接边表示除了激活算子Relu之外的任意算子。状态1与状态2之间有一条有向连接边②。有向连接边②的箭头方向表示状态1为源状态,状态2为目标状态,有向连接边②的连接边表示激活算子,并且在图上标出了激活算子的输入和输出类型均为fp24。状态2与start标识之间有一条有向连接边④。有向连接边④的箭头方向表示状态2为源状态,start标识为目标状态,有向连接边④的连接边表示任意算子。

下面阐述如何利用状态机工作。定义状态标识i的数据类型为Si,两个状态标识之间的转换由算子流中的算子与图上的节点的比对结果来触发,定义图上的每个算子的输入类型Ti和输出类型To,例如卷积算子conv的Ti=int8,To=int32;激活算子relu的Ti=To=f24。对于任意一个算子流,从start标识开始,输入数据的类型必须是int8。这是因为,通常深度学习模型的算子流都从卷积算子开始,由于卷积算子的输入类型为int8,因此需要确保该算子流的输入类型也是int8。如果算子流的输入数据不是int8,还可以在算子流之前插入一个反量化算子,以得到int8的输入数据。将算子流的每个算子按顺序和状态机的有向连接边表示的算子按顺序逐一比对,算子导致状态转移时,状态会从i->j, 先检查当前状态的Si和Ti是否相同,如果不同,需要在其中插入相应量化和/或反量化节点(Q/DQ)来完成Si->Ti的转换。如果不符合条件,则经由failure回到start状态。每次failure状态转换的时候,需要检查Si和Sj(永远是start)是否相同,如果不同,需要插入相应的量化和反量化节点(Q/DQ)来完成转换。

下面继续以图10所示的序列为例对状态机的工作做进一步的说明。状态机的工作从start标识开始。首先看从start出发的有向连接边,只有一个有向连接边①,因此将左边的指令1和有向连接边①表示的算子比较,如果相同,则表示指令1引起状态机的状态变动,即从start 状态跳转到状态1。左边的指令1为卷积算子,正好和有向连接边①表示的算子相同,因此状态机从start状态跳转到状态1。然后将start 状态(即int8)与卷积算子conv的输入类型(即int8)比较,确定两者相同,因此无需在start和卷积算子conv之间(即在算子conv之前) 插入量化算子。由于在本例中,将每个有向连接边的目标状态设定与该有向连接边表示的算子的输出类型相同,因此无需比较有向连接边的目标状态与该有向连接边表示的算子的输出类型。

此时,由于指令1的原因,状态机已经处于状态1。从图上可以看出,从状态1出发的有向连接边有②和③。指令2是卷积算子conv。将指令2与有向连接边②比较,确定指令2与有向连接边②表示的算子不同。而有向连接边③是一个failure连接边,将状态机的状态重置为 start状态开始新一轮的状态跳转,即状态机需要从int32回到int8,此时需要在状态1和start状态之间(即指令1和2之间)插入反量化算子DQ和量化算子Q,通过DQ把int32转成fp24,Q把fp24转成int8。

此时,状态机回到了start状态。继续将左边的指令2和有向连接边①表示的算子比较,如果相同,则表示指令2引起状态机的状态变动,即从start状态跳转到状态1。左边的指令2为卷积算子,正好和有向连接边①表示的算子相同,因此状态机又从start状态跳转到状态1。然后将start状态(即int8)与卷积算子conv的输入类型(即int8) 比较,确定两者相同,因此无需在start和算子conv之间(即在算子 conv之前)插入量化算子。

此时,状态机来到了状态1。继续将左边的指令3和有向连接边②表示的算子比较,如果相同,则表示指令3引起状态机的状态变动。左边的指令3为激活算子,正好和有向连接边②表示的算子相同,因此状态机又从状态1状态跳转到状态2。然后将状态1(即int32)与激活算子的输入类型(即int24)比较,确定两者不同,因此需要在状态1和2 之间(即指令2和3之间)插入反量化算子DQ。

此时,状态机来到了状态2。继续将左边的指令4与从状态2出发的有向连接边④比较。左边的指令4是卷积算子。有向连接边④表示的是failure连接边,状态机需要回到start状态开始下一轮的状态跳转。状态机从fp32回到int8,因此需要在两个状态之间(指令3与状态4 之间)插入量化算子Q,因为Q把fp24转成int8。

此时,状态机回到了start状态。继续将左边的指令4和有向连接边①表示的算子比较,确定两者相同,则状态机跳转到状态1。量化后的指令序列是图上右边的序列所示。

需要指出的是,通常当算子流结束后,需要将算子流最后输出的数据转换为量化值,由于上述算子流的最后一个算子是卷积算子,输出类型为int32,因此需要在上述算子流的结束位置插入反量化算子和量化算子,以将算子流的输出数据转换为量化值。

还需要指出的是,上述状态机有一些特殊之处:1)将有向连接边表示的算子的输出类型设定与该有向连接边的目标状态相同,由此在进行比对时,可以只比较算子的输入类型与源状态;2)设定初始状态标识表示的数据类型与卷积算子的输入类型一致,为量化值;3)设置failure 连接边以回到初始状态标识,以开始下一轮的状态跳转。

当然,本领域的技术人员完全可以构建与图10不同结构的状态机,也能够实现本公开实施例,例如,考虑到深度学习模型的网络结构,完全可以构建具有更多状态标识和更多有向连接边的状态机,以进一步覆盖深度学习模型的算子流在指定加速单元上执行时可能出现的跳转情况。

图11示出了基于同一个原始算子流,根据现有技术处理后得到的目标算子流和采用本公开实施例得到的目标算子流的对比例。参考图上所示,原始算子流为:卷积算子(conv)->池化算子(pooling)->池化算子 (pooling)。左边示出了根据现有技术处理后得到的目标算子流为:卷积算子(conv)->反量化算子(DQ)->量化算子(Q)->池化算子(pooling) ->反量化算子(DQ)->量化算子(Q)->卷积算子(conv)->反量化算子 (DQ)->量化算子(Q)。右边示出了采用本公开实施例得到的目标算子流为:卷积算子(conv)->反量化算子(DQ)->量化算子(Q)->池化算子(pooling)->反量化算子(DQ)->量化算子(Q)->卷积算子(conv) ->反量化算子(DQ)->量化算子(Q)。通过对比可以看出,本公开实施例中,由于将相邻算子的输入和输出类型结合在一起考虑,由此发现了池化算子的输出类型为int8,而卷积算子的输入类型也为int8,这两个算子之间无需插入量化算子和反量化算子,从而避免了插入冗余算子。

图12是根据本公开实施例提供的深度学习模型的编译方法。该量化方法同样应用于算法层面,更具体地,该编译方法由深度学习的编译器实现,它可以应用于如图6所示的编译栈403中。该编译方法具体包括以下步骤。

步骤S110,将深度学习模型从源代码编译为第一指令序列。在本步骤中,将深度学习模型的源代码编译得到第一指令序列,第一指令序列可以是可执行指令序列,也可以是编译过程中产生的中间指令序列。

步骤S120,从第一指令序列中获取可在指定加速单元上执行的算子流。图4的调度单元会将第一指令序列中的一部分指令放在调度单元上执行,将另一部分指令放在指定加速单元上执行,因此本步骤将可在指定单元上执行的指令序列找到并提取出来作为算子流。

步骤S130,在算子流中,根据相邻算子的输入类型和输出类型在相邻算子之间插入用于执行量化操作的量化算子和/或用于执行反量化操作的反量化算子。收集深度学习模型的每个算子的输入和输出类型,然后根据相邻算子的输入和输出类型确定并执行在相邻算子之间插入量化或反量化算子。

在一些实施例中,将各个算子的输入和输出类型可以存储在一个数据库表内,当获取到深度学习模型的算子流时,根据每个算子的标识检索该数据库表,从而获得每个算子的输入和输出类型,然后根据相邻算子的输入和输出类型确定是否在相邻算子之间插入量化和/或反量化算子。

在一些实施例中,构建状态机,所述状态机包括表示多个数据类型的多个状态标识以及连接每两个所述状态标识的、表示各个算子的输入类型和输出类型的多个有向连接边,然后将算子流与状态机的多个有向连接边比对,以确定深度学习模型的有向连接边是否被触发,当一个有向连接边被触发时,如果被触发的有向连接边的源状态标识与被触发的有向连接表示的算子的输入类型不符,在深度学习模型的相应算子之前插入所述量化算子和/或所述反量化算子,或,如果被触发的有向连接边的目标状态标识与被触发的有向连接边表示的算子的输出类型不符,在深度学习模型的相应算子之后插入量化算子和/或所述反量化算子。

步骤S140,将算子流部署到指定加速单元上执行。

最终得到的算子是插入了插入量化和/或反量化算子且能够在指定加速单元上执行的算子流,将其部署到指定加速单元上执行。

在一些实施例中,当相邻算子的前一算子的输出类型与后一算子的输入类型不同时,则确定在相邻算子之间插入量化算子和/或反量化算子。

在一些实施例中,输出类型和输出类型被归类为各种精度类型,当前一算子的输出类型为高精度类型且后一指令的输入类型为低精度类型时,确定插入量化算子;当前一算子的输出类型为低精度类型且后一指令的输入类型为高精度类型时,确定插入反量化算子。

在一些实施例中,当前一算子的输出类型为第一数据类型,后一算子的输入类型为第二数据类型,如果第一数据类型和第二数据类型属于同一精度类型,则基于第一数据类型和第二数据类型在存储器中所占的比特位确定插入量化算子还是反量化算子;如果第一数据类型和第二数据类型不属于同一精度类型,则按照精度类型确定插入量化算子或反量化算子。

作为可选的实施方法,在算子流的开始位置插入量化指令,以得到量化后的输入数据,以及在算子流的最后一条可执行指令之后插入反量化指令,以得到反量化后的输出数据。这样做的好处在于:输入数据来自调度单元220或存储器210,输出数据将返回给调度单元220或存储器210,通过量化和反量化操作,确保加速单元230得到的是量化后的输入数据,由此减少加速单元230的数据吞吐量,而调度单元220或存储器210得到的是反量化后的输出数据,由此保证数据在不同处理单元上的一致性。通过这种方式,使得调度单元和加速单元可以协同执行深度学习模型。

本公开实施例的深度学习模型的编译方法,根据相邻算子的输入类型和输出类型确定是否在相邻算子之间插入量化算子和/或反量化算子并执行,以此避免插入冗余的量化算子和/或反量化算子,从而保证了由此得到的算子流的指令精简,并以此提高深度学习模型的模型效率和响应速度。

需要说明的是,虽然上述描述的均是在算法层面对深度学习模型的改进的调优方案,但是实际上,也可以将本公开的核心思想应用于固件和硬件当中,例如应用于图4的加速单元230中。

本公开实施例利用在算法层面结合硬件特性执行量化操作,使得深度学习模型的推理性能得以提高,例如resnet50中,相比于传统的调优方案,本案有将近20%左右的性能提升。深度学习模型目前已经具有广泛而且成功的应用场景,使得对于该深度学习模型的任何微小的改进都变得如此重要,这种重要不仅体现在技术层面,更体现在商业层面。以人脸识别领域为例,通过摄像头收集视频监控,通过神经网络模型识别人脸图像,将人脸图像和云存储的人脸比对,能够识别监控视频中犯罪人员。再在语音识别领域,通过神经网络模型进行语音识别,实现同声传译。这些应用场景都能够带来巨大的商业利益。

本领域的技术人员能够理解,本公开可以实现为系统、方法和计算机程序产品。因此,本公开可以具体实现为以下形式,即完全的硬件、完全的软件(包括固件、驻留软件、微代码),还可以实现为软件和硬件结合的形式。此外,在一些实施例中,本公开还可以实现为一个或多个计算机可读介质中的计算机程序产品的形式,该计算机可读介质中包含计算机可读的程序代码。

可以采用一个或多个计算机可读介质的任意组合。计算机可读介质可以是计算机可读信号介质或者计算机可读存储介质。计算机可读存储介质例如但不限于为电、磁、光、电磁、红外线或半导体的系统、装置或器件,或其他任意以上的组合。计算机可读存储介质的更具体的例子包括:具体一个或多个导线的电连接,便携式计算机磁盘、硬盘、随机存取存储器(RAM)、只读存储器(ROM)、可擦除可编程只读存储器(EPROM 或者闪存)、光纤、便携式紧凑磁盘只读存储器(CD-ROM)、光存储器、磁存储器或者上述任意合适的组合。在本文中,计算机可读的存储介质可以是任意包含或存储程序的有形介质,该程序可以被处理单元、装置或者器件使用,或者与其结合使用。

计算机可读信号介质可以包括在基带中或者作为截波一部分传播的数据信号,其中承载了计算机可读的程序代码。这种传播的数据信号可以采用多种形式,包括但不限于电磁信号、光信号或者其他任意合适的组合。计算机可读的信号介质还可以是计算机可读存储介质之外的任何计算机可读介质,该计算机可读介质可以发送、传播或者传输用于由指令系统、装置或器件使用或者与其结合使用的程序。

计算机可读介质上包含的程序代码可以用任何适当的介质传输,包括但不限于无线、电线、光缆、RF等等,以及上述任意合适的组合。

可以以一种或者多种程序设计语言或者组合来编写用于执行本公开实施例的计算机程序代码。所述程序设计语言包括面向对象的程序设计语言,例如JAVA、C++,还可以包括常规的过程式程序设计语言,例如C。程序代码可以完全地在用户计算机上执行、部分地在用户计算机上执行、作为一个独立的软件包执行、部分在用户计算机上部分在远程计算机上执行、或者完全在远程计算机或服务器上执行。在涉及远程计算机的情形中,远程计算机可以通过任意种类的网络包括局域网(LAN)或广域网(WAN)连接到用户计算机,或者,可以连接到外部计算机(例如利用因特网服务提供商来通过因特网连接)。

以上所述仅为本公开的优选实施例,并不用于限制本公开,对于本领域技术人员而言,本公开可以有各种改动和变化。凡在本公开的精神和原理之内所作的任何修改、等同替换、改进等,均应包含在本公开的保护范围之内。

相关技术
  • 深度学习模型的调优方法、编译方法及计算装置
  • 一种深度学习模型的调优管理方法、装置、设备和介质
技术分类

06120113227987