CUDA上的量化深度学习模型的自动化优化

深度学习已成功应用于各种任务。在诸如自动驾驶汽车推理之类的实时场景中,模型的推理速度至关重要。网络量化是加速深度学习模型的有效方法。在量化模型中,数据和模型参数都用诸如int8和的低精度数据类型表示float16。降低的数据带宽减少了推理时间和存储器/存储需求,以及功耗。同时,在适当的量化方案下,可以最小化量化模型的精度下降。量化模型特别适合研究人员和开发人员,使大型模型适合在各种设备(例如GPU,CPU和移动设备)上部署。

以前,通常通过手工微内核针对不同的工作量来优化量化算子,或者依靠cuDNN和TensorRT等黑盒专有解决方案。在集成中编写高性能微内核可能非常困难,并且通常需要大量的工程工作。此外,很难使这些临时微内核适应新兴的工作负载和新设备。

图1. TVM,TensorRT和MXNet上不同模型的推断时间

TVM通过全栈编译器和基于机器学习的优化器来自动生成计算内核,从而解决了这一难题。TVM可以通过在人为设计的搜索空间中进行自动搜索来生成有效的内核。在VGG和ResNet等标准工作负载中,TVM与其它最新框架相比具有竞争优势。在诸如ResNeXt和Deformable ConvNets之类的新兴模型中,自动优化使TVM可以轻松适应这些新工作负载并显着提高性能。

本文将展示如何使用TVM在CUDA上自动优化量化深度学习模型。

在TVM中表达量化的CUDA内核

通过张量化利用张量本征

许多平台都为特殊的计算模式提供了特定于体系结构的指令,例如x86上的SIMD指令dp4a以及hfmaCUDA上的和指令。这些内在指令针对特定设备进行了高度优化。通过利用硬件内在函数,可以为量化算子带来显着的性能提升。

目前,dp4a已被CUDA上的TVM int8算子广泛使用。 dp4a是Compute Capability 6.1设备上固有的CUDA。一种混合精度指令,可以高效地计算两个4元素8位整数向量之间的点积,并以32位格式累加结果。使用dp4a,可以在8位整数向量之间实现点积,其元素数可以被4整除。使用高效的点积算子,可以实现高级算子,例如2D卷积和密集层,因为这些算子通常由点积支持。

为了说明这一点,在二维卷积中,沿着内核的通道,宽度和高度轴进行累积。这是典型用例dp4a。TVM使用张量化来支持调用外部内在函数。不需要修改原始的计算声明;使用调度原语tensorizedp4a张量内在函数代替累加。

数据布局重排

张量化的挑战之一,可能需要设计特殊的计算逻辑以适应张量本征的要求。尽管在密集算子中沿张量的内轴累积是很自然的,conv2d可能更具挑战性。在conv2d期望采取切片在作为输入端的通道尺寸dp4a,因为信道数目通常是4的倍数(否则回落到原来conv2d在NCHW布局)。为了实现内存局部性,希望首先沿最内轴减小。考虑到这些因素,使用自定义数据布局来应对这一挑战。

在CUDA int8 2d卷积中,根据经验选择NCHW4c作为数据布局和OIHW4o4i权重布局。模板很容易地推广到NCHW[x]cOIHW[x]o[x]i,其中x是可以被四整除的任意正整数。在选择的数据布局中,通道切片位于打包的最里面维度。在权重的输入和输出通道尺寸中打包切片,以使输出与输入具有一致的数据布局,从而防止了图层之间的多余布局转换。

图2显示了2d卷积输出的一个元素的计算。超尺寸(包含打包元素的块状布局的外部尺寸)每个位置的元素NCHW和OIHW分别是打包的输入和内核。打包内核的每一列都来自不同的过滤器。使用计算压缩输入和压缩内核中每一行之间的点积dp4a,并将结果累加到输出张量。

图2. NCHW4c中的数据布局和OIHW4o4i中的权重布局的二维卷积。:NCHW4c布局中的输入张量。内核的一个移动的过滤器被染成蓝色。输入和内核的一个元素以灰色显示。 :灰色块的打包输入和内核。:NCHW4c布局中的输出。在所示的一个元素内,通道子维度中有四个压缩元素。

在指定卷积层的布局之后,其它算子(例如add和激活)可以在Relay中的AlterOpLayout传递期间自动适应所选的布局。权重的布局转换可以离线进行预先计算。可以在相同的布局中运行整个模型而无需额外的开销。

设计搜索空间以进行自动优化

在量化算子中获得良好性能的关键是与基于机器学习的自动优化相集成。一个问题是如何设计有效的调度表搜索空间。有效的计划模板意味着在自动调整中,可以通过合理的迭代次数获得良好的性能。定义一个灵活的模板以覆盖搜索空间中的不同配置。利用性能优化方面的先验知识。例如,一种常见的做法是,在CUDA编程中将数据缓存在共享内存中,因此利用共享内存,使用机器学习来选择最佳的图块大小。还进行了一些手动平铺,例如将轴分割为4或16,以方便进行向量化内存访问。

在量化的2d卷积中,设计了一个搜索空间,其中包括一组可调选项,例如图块大小,要融合的轴,循环展开和双缓冲的配置。在CUDA上注册了量化模板conv2ddenseCUDA模板int8。在自动调整期间,可以通过设置template_key参数,为这些量化算子创建调整任务。有关如何启动自动优化的详细信息,请参见AutoTVM教程

一般工作流程

图3.运行量化模型的工作流程

TVM提供了一个简单的工作流程,可以量化其它框架中训练有素的模型,自动优化算子(使用AutoTVM)并部署到其它设备。

首先,使用Relay前端导入现有模型。在这里,以带有(1, 3, 224, 224)输入形状的MXNet模型为例。

sym, arg_params, aux_params = mxnet.model.load_checkpoint(model_path, epoch)
net, params = relay.from_mxnet(sym, shape={'data': (1, 3, 224, 224)}, arg_params=arg_params, aux_params=aux_params)

接下来,使用中继量化API将其转换为量化模型。

net = relay.quantize.quantize(net, params=params)

然后,使用AutoTVM为模型中的算子提取调整任务,并执行自动优化。

最后,建立模型并以量化模式运行推理。

with relay.build_config(opt_level=3):
    graph, lib, params = relay.build(net, target)

结果relay.build是可部署的库。可以直接在GPU上运行推理也可以通过RPC部署在远程设备上。

基准

为了验证TVM中量化算子的性能,对几种流行的网络模型(包括VGG-19,ResNet-50和Inception V3)的性能进行了基准测试。还对来自可变形卷积网络的DRN-C-26,ResNeXt-50和DCN-ResNet-101进行基准测试,以显示新兴模型的性能,其中包含较少的常规算子,例如膨胀卷积,组卷积和可变形卷积。选择NVIDIA TensorRT作为基准。据报道,在float32模式下MXNet 1.4 + cuDNN 7.3的结果显示了量化的加快。实验是在NVIDIA GTX 1080上进行的。当以批处理大小= 1和16运行时,输出每个图像的推理时间。

如图1所示,TVM使用量化实现了高达8倍的加速。在VNG和ResNet等标准CNN模型中,TVM与TensorRT的最新结果保持一致。

在对新兴模型进行基准测试时,TVM取得了令人印象深刻的结果。在ResNeXt和DCN-ResNet-101上获得了可观的性能提升。TensorRT的DCN-ResNet-101的结果不可用,因为尚无可变形卷积的正式实现。TVM中的自动优化可以轻松灵活地支持和优化新兴的工作负载。

CUDA上的量化深度学习模型的自动化优化的更多相关文章

  1. 移动端 CPU 的深度学习模型推理性能优化——NCHW44 和 Record 原理方法详解

    用户实践系列,将收录 MegEngine 用户在框架实践过程中的心得体会文章,希望能够帮助有同样使用场景的小伙伴,更好地了解和使用 MegEngine ~ 作者:王雷 | 旷视科技 研发工程师 背景 ...

  2. CUDA上深度学习模型量化的自动化优化

    CUDA上深度学习模型量化的自动化优化 深度学习已成功应用于各种任务.在诸如自动驾驶汽车推理之类的实时场景中,模型的推理速度至关重要.网络量化是加速深度学习模型的有效方法.在量化模型中,数据和模型参数 ...

  3. TVM 优化 ARM GPU 上的移动深度学习

    TVM 优化 ARM GPU 上的移动深度学习 随着深度学习的巨大成功,将深度神经网络部署到移动设备的需求正在迅速增长.与桌面平台上所做的类似,在移动设备中使用 GPU 既有利于推理速度,也有利于能源 ...

  4. TVM将深度学习模型编译为WebGL

    使用TVM将深度学习模型编译为WebGL TVM带有全新的OpenGL / WebGL后端! OpenGL / WebGL后端 TVM已经瞄准了涵盖各种平台的大量后端:CPU,GPU,移动设备等.这次 ...

  5. AI佳作解读系列(一)——深度学习模型训练痛点及解决方法

    1 模型训练基本步骤 进入了AI领域,学习了手写字识别等几个demo后,就会发现深度学习模型训练是十分关键和有挑战性的.选定了网络结构后,深度学习训练过程基本大同小异,一般分为如下几个步骤 定义算法公 ...

  6. 『高性能模型』Roofline Model与深度学习模型的性能分析

    转载自知乎:Roofline Model与深度学习模型的性能分析 在真实世界中,任何模型(例如 VGG / MobileNet 等)都必须依赖于具体的计算平台(例如CPU / GPU / ASIC 等 ...

  7. 深度学习模型stacking模型融合python代码,看了你就会使

    话不多说,直接上代码 def stacking_first(train, train_y, test): savepath = './stack_op{}_dt{}_tfidf{}/'.format( ...

  8. 利用 TFLearn 快速搭建经典深度学习模型

      利用 TFLearn 快速搭建经典深度学习模型 使用 TensorFlow 一个最大的好处是可以用各种运算符(Ops)灵活构建计算图,同时可以支持自定义运算符(见本公众号早期文章<Tenso ...

  9. Roofline Model与深度学习模型的性能分析

    原文链接: https://zhuanlan.zhihu.com/p/34204282 最近在不同的计算平台上验证几种经典深度学习模型的训练和预测性能时,经常遇到模型的实际测试性能表现和自己计算出的复 ...

随机推荐

  1. 【vue环境】vue : 无法加载文件 C:\Users\1111111\AppData\Roaming\npm\vue.ps1,因为在此系统禁止运行脚本

    在用脚手架搭建vue项目时,提示:无法加载文件 C:\Users\1111111\AppData\Roaming\npm\vue.ps1,因为在此系统禁止运行脚本 这是你笔记本禁止运行脚本,解决办法 ...

  2. 【JDK8】JDK 8 中Stream流中的去重的方法

    JDK 8 中Stream流中去重的方法 1.简单的去重,可以使用distinct()方法去重,该方法是通过比较equals和hashcode值去去重, 2.复杂的去重, 例如,在一个JavaBean ...

  3. CreateThread 线程操作与 _beginthreadex 线程安全(Windows核心编程)

    0x01 线程的创建 线程不同于进程,Windows 中的进程是拥有 '惰性' 的,本身并不执行任何代码,而执行代码的任务转交给主线程,列如使用 CreateProcess 创建一个进程打开 Cmd ...

  4. ListView 加载数据时 触摸报错

    问题起因: 在做一个从sd卡中加载数据显示在ListView中,由于数据可能比较多,考虑到用户体验,就使用AsyncTask来异步加载,数据一条一条的添加至ListView中. 开始数据比较少的时候, ...

  5. 爬虫:获取动态加载数据(selenium)(某站)

    如果网站数据是动态加载,需要不停往下拉进度条才能显示数据,用selenium模拟浏览器下拉进度条可以实现动态数据的抓取. 本文希望找到某乎某话题下讨论较多的问题,以此再寻找每一问题涉及的话题关键词(侵 ...

  6. ffmpeg实践

    将mov视频解码300帧,并保存为1024:576分辨率,yuv420格式 ffmpeg -i Community_SneakAttack.mov -aspect 16:9 -vf scale=102 ...

  7. 使用find_if算法搜寻map的value

    // // main.cpp // map_find // // Created by PKU on 14-9-8. // Copyright (c) 2014年 PKU. All rights re ...

  8. OO第一单元总结-多项式求导

    OO第一单元总结-多项式求导 一.第一.第二次作业总结 因为前两次作业设计复杂度差别不大,因而放在这里统一总结. 基于度量分析程序结构: 前两次作业确实存在缺乏可拓展设计的构想,基本还是面向过程的思维 ...

  9. Redis学习笔记六:持久化实验(AOF,RDB)

    作者:Grey 原文地址:Redis学习笔记六:持久化实验(AOF,RDB) Redis几种持久化方案介绍和对比 AOF方式:https://blog.csdn.net/ctwctw/article/ ...

  10. 解决nohup: 忽略输入并把输出追加到"nohup.out"或者nohup: 忽略输入重定向错误到标准输出端

    nohup启动脚本的时候,没有指定输出路径,默认使用当前目录的nohup.out 例如下面这句就是默认使用nohup.out作为输出文件: nohup script.sh & 改成下面的,则/ ...