在NVIDIA A100 GPU中使用DALI和新的硬件JPEG解码器快速加载数据

如今,最流行的拍照设备智能手机可以捕获高达4K UHD的图像(3840×2160图像),原始数据超过25 MB。即使考虑到令人尴尬的低HD分辨率(1280×720),原始图像也需要超过2.5 MB的存储空间。存储少至100张UHD图像将需要近3 GB的可用空间。

显然,如果以这种方式存储数据,则会很快耗尽空间。这是图像压缩派上用场的地方。众所周知的JPEG格式可以将图像大小从30 MB缩小到3 MB。

对于深度学习的计算机视觉应用程序(其中有数百万个样本的训练数据集是通用的),压缩和有效存储图像数据比以往任何时候都更为重要。行业标准的数据集(例如ImageNetCOCO)使用JPEG格式存储数据。因此,ImageNet仅占用150 GB的空间,而不是惊人的32 TB的未压缩数据。

压缩效果很好-它可以节省大量磁盘空间。不幸的是,它突出了另一项挑战,在与计算机视觉相关的深度学习应用程序中尤为明显:图像解压缩是一项计算密集型任务。实际上,这是数据处理管道中最耗时的任务,直到JPEG解码在GPU上运行的训练变得空缺。

面对这一问题,开发了NVIDIA数据加载库(DALI)来加速图像解码,增强和管道预处理。它缓解了此CPU瓶颈。DALI通过利用nvJPEG(用于JPEG解码的CUDA库)来加速图像解码。不仅如此,还可以采用数据处理管道,从解码到扩充再到训练,再到更高的性能水平。

最近,推出了基于NVIDIA Ampere架构A100 GPU。它添加了硬件JPEG解码器以进一步提高性能。它是负责解码JPEG图像的专用硬件模块。

先前的架构没有这种硬件单元,并且JPEG解码是使用CPU和GPU可编程SM单元的纯软件(CUDA)解决方案。利用专用的硬件单元,解码不再与CUDA核心竞争其它计算密集型任务,例如在神经网络训练期间进行正向和反向馈送。

它通过CUDA工具包的一部分nvJPEG库公开。有关更多信息,请参阅在NVIDIA A100 GPU上利用硬件JPEG解码器和NVIDIA nvJPEG库。作为DALI用户,随着DALI和NVJPEG集成的抽象化,将自动受益于硬件加速的解码,而无需更改任何代码。

通过将JPEG硬件解码器与DALI配合使用,可以轻松地为深度学习应用程序访问此JPEG硬件解码器功能。如果将DALI ImageDecoder与后端混合使用,则无需更改代码。获取CUDA 11的最新DALI版本,并享受NVIDIA Ampere架构支持的,硬件加速的JPEG解码。

以下代码示例显示了DALI管道,该管道可加载图像并使用GPU对其进行解码:

class SimplePipeline(Pipeline):     def __init__(self, batch_size, num_threads, device_id):         super().__init__(batch_size, num_threads, device_id, seed = 12)         self.input = ops.FileReader(file_root = image_dir)         self.decode = ops.ImageDecoder(device = 'mixed', output_type = types.RGB)     def define_graph(self):         jpegs, labels = self.input()         images = self.decode(jpegs)         return images, labels

混合GPU解码器

借助DALI,可以更进一步,并将基于硬件,软件和基于CUDA的方法结合起来进行JPEG解码,并行运行它们以获得更高的吞吐量。图1显示了这样一种管道如何工作。

图1:采用软件/ CUDA和硬件加速JPEG图像解码并行使用的DALI管线图

可以通过调整hw_decoder_load参数来决定工作量,以决定将多少解码负载分配给硬件解码器,以及通过GPU加速的CUDA方法同时完成多少负载。

结果取决于现有的GPU工作负载(GPU必须完成的工作量),并且可以根据经验进行调整以最大程度地提高每种用例的吞吐量。

图2提供了比例为75:25的数字。但是,当GPU已被其它工作(例如正向传播和反向传播)占用时,可能会通过将较大一部分图像解码任务卸载到硬件解码器(例如80%甚至更多)来找到最佳位置。

以下代码示例显示了将75%的图像解码任务卸载到硬件解码器的管道:

class SimplePipeline(Pipeline):     def __init__(self, batch_size, num_threads, device_id):         super().__init__(batch_size, num_threads, device_id, seed = 12)         self.input = ops.FileReader(file_root = image_dir)         self.decode = ops.ImageDecoder(device = 'mixed', output_type = types.RGB, hw_decoder_load=0.75)     def define_graph(self):         jpegs, labels = self.input()         images = self.decode(jpegs)         return images, labels

图2显示了将DALI解码从CPU切换到各种基于GPU的方法时可以期望的性能提升。针对不同的批处理大小,CPU libjpeg-turbo解决方案,Volta CUDA解码,A100硬件JPEG解码器以及A100双硬件和CUDA解码器执行了测试。

图2:用于ImageNet训练数据集的CPU,CUDA,A100硬件以及双CUDA和硬件JPEG图像解码之间的解码速度比较。批次样品均分。

图2和4的测试配置:

  • NVIDIA V100 GPU: CPU – E5-2698 v4@2GHz 3.6GHz Turbo (Broadwell) HT On, GPU – Tesla V100-SXM2-16GB(GV100) 1*16160 MiB 1*80 SM, GPU Video Clock 1312, 4 threads used in DALI pipeline
  • NVIDIA A100 GPU: CPU – Platinum 8168@2GHz 3.7GHz Turbo (Skylake) HT On, GPU – A100-SXM4-40GB(GA100) 140557 MiB 1108 SM, GPU Video Clock 1095, 4 threads used in DALI pipeline
  • CPU: CPU – Platinum 8168@2GHz 3.7GHz Turbo (Skylake) HT On, Dataset – training set of ImageNet, 4 threads used in DALI pipeline

图3显示了典型的类似ResNet50的图像分类管道。

图3.类似ResNet50的图像分类管道。

图4显示了ResNet-50模型的端到端数据管道加速。总体管线加速看起来与前面图2中的解码加速相同。

图4:针对类似ResNet50的图像分类模型,CPU,CUDA,A100硬件加速以及双CUDA和硬件加速JPEG图像解码之间的端到端数据处理管道吞吐量比较。

以下是一些要点:

  • 对于基于图像的工作负载,解码是数据预处理管道中计算最密集的方面。通过加快速度,整个管道都能看到好处。
  • 端到端的训练吞吐量在很大程度上取决于可以为GPU提供数据的速度(管道的输出)。DALI专门用于确保GPU不断获得数据。有关如何确定的数据管道是否受CPU瓶颈以及DALI如何提供帮助的信息,请参阅案例研究:带有DALI的ResNet50

在NVIDIA A100 GPU中使用DALI和新的硬件JPEG解码器快速加载数据的更多相关文章

  1. NVIDIA A100 GPUs上硬件JPEG解码器和NVIDIA nvJPEG库

    NVIDIA A100 GPUs上硬件JPEG解码器和NVIDIA nvJPEG库 Leveraging the Hardware JPEG Decoder and NVIDIA nvJPEG Lib ...

  2. 在NVIDIA A100 GPU上利用硬件JPEG解码器和NVIDIA nvJPEG库

    在NVIDIA A100 GPU上利用硬件JPEG解码器和NVIDIA nvJPEG库 根据调查,普通人产生的1.2万亿张图像可以通过电话或数码相机捕获.这样的图像的存储,尤其是以高分辨率的原始格式, ...

  3. echarts在.Net中使用实例(二) 使用ajax动态加载数据

    通过上一篇文章可以知道和echarts参考手册可知,series字段就是用来存储我们显示的数据,所以我们只需要用ajax来获取series的值就可以. option 名称 描述 {color}back ...

  4. Flexigrid从对象中加载数据

    (有问题,在找…………) Flexigrid是用来动态加载数据的一种比较好(老)的Jquery表插件,然后有些时候,我们需要其从本地或者jQuery对象中加载数据,比如有这么个需求,页面显示中有两个表 ...

  5. smarty中增加类似foreach的功能自动加载数据方法

    第一步:在Smarty_Compiler.class.php的_compile_tag函数中增加: 复制代码 代码如下: //加载数据的开始标签case 'load': $this->_push ...

  6. WinForm中异步加载数据并使用进度条

    在WinForm程序中,有时会因为加载大量数据导致UI界面假死,这种情况对于用户来说是非常不友好的.因此,在加载大量数据的情况下,首先应该将数据加载放在另一线程中进行,这样保证了UI界面的响应:其次可 ...

  7. ArcGIS Engine中加载数据

    ArcGIS Engine中加载数据 http://blog.csdn.net/gisstar/article/details/4206822   分类: AE开发积累2009-05-21 16:49 ...

  8. Android中GridView滚动到底部加载数据终极版

    之前在项目中有一个需求是需要GridView控件,滚动到底部自动加载.但是呢GridView控件并不提供诸如ListView监听滚动到底部的onScrollListener方法,为了实现这样一个效果, ...

  9. Android中ListView分页加载数据

    public class MainActivity extends Activity { private ListView listView=null; //listview的数据填充器 privat ...

随机推荐

  1. php和mysql数据库防SQL注入的有效解决办法

    <?php$mysqli = new mysqli("localhost", "my_user", "my_password", &q ...

  2. PHP正则匹配各种匹配方法

    平时做网站经常要用正则表达式,下面是一些讲解和例子,仅供大家参考和修改使用: 匹配数字 "^\d+$" //非负整数(正整数 + 0) "[1][1-9][0-9]$&q ...

  3. 常用的STL

    map      容器和数组一样,不过比较活用,相当于直接离散化数组 map<int ,int>mp 一维int map<string ,string>mp 一维 str ma ...

  4. LA3213加密

    题意:       白书上有些题的题意说的太蛋疼了,这个题的意思是说有两种加密方式,一种是交换位置,另一种是一一映射,交换位置是指如ABCD 可以加密成DCBA 也可以加密成ACBD就是把某些字母的位 ...

  5. Sqlmap的使用详解

    目录 Sqlmap Sqlmap的简单用法 探测指定URL是否存在SQL注入漏洞 查看数据库的所有用户 查看数据库所有用户名的密码 查看数据库当前用户 判断当前用户是否有管理权限 列出数据库管理员角色 ...

  6. 使用 WinAFL 图片解析软件进行模糊测试 - FreeImage 图片解析库

    看雪链接:https://bbs.pediy.com/thread-255162.htm

  7. SqlServer数据库主从同步

    分发/订阅模式实现SqlServer主从同步 在文章开始之前,我们先了解一下几个关键的概念: 分发服务器分发服务器是负责存储在同步过程中所用复制信息的服务器.可以比喻成报刊发行商. 分发数据库分发数据 ...

  8. 中国石油大学(华东)数学实验(MATLAB)复习

    作者:张世琛 函数的导数 $$ 求函数y=log(x+\sqrt{1+x^2})的一阶和二阶导数 $$ syms x; y=log(x+sqrt(1+x^2)); dydx=diff(y,x); dy ...

  9. 数据库导入时出现“2006 - MySQL server has gone away”问题的解决(windows)

    1.查到文件my.ini,在文件最后([mysqld]段最后),修改"max_allowed_packet = 50M",添加"interactive_timeout = ...

  10. 【js】Leetcode每日一题-停在原地的方案数

    [js]Leetcode每日一题-停在原地的方案数 [题目描述] 有一个长度为 arrLen 的数组,开始有一个指针在索引 0 处. 每一步操作中,你可以将指针向左或向右移动 1 步,或者停在原地(指 ...