在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. dedecms arclist分页

    https://blog.csdn.net/qq_41104911/article/details/81510589

  2. LA3403天平难题(4个DFS)

    题意:      给出房间的宽度r和每个吊坠的重量wi,设计一个尽量宽但宽度不能超过房间宽度的天平,挂着所有挂坠,每个天平的一段要么挂这一个吊坠,要么挂着另一个天平,每个天平的总长度是1,细节我给出题 ...

  3. dependencyManagement 版本管理

    帮别人解决bug的时候碰到,随便记录一下. 使用<dependencyManagement>标签, 做版本管理的时候,需要父子项目关联,就需要子模块中利用<parent> 否则 ...

  4. 解决客户端Redis中文乱码问题

    启动客户端的时候添加 --raw 选项即可 wangyulong@code-local:~$ redis-cli 127.0.0.1:6379> set key1 '上海' OK 127.0.0 ...

  5. 查询某软件所连接的外网IP地址

    一:背景环境: 1>:某机械公司用的某些特殊软件,需要实现所有使用某软件的屏蔽其软件所连接的外网ip,其他上网功能不做限制. 二:需求分析:可以查出此软件所连接的外网ip,在路由器的ip过滤中将 ...

  6. 5分钟,教你用Python每天跟女朋友说1000遍土味情话!

  7. hdu 2072 1106学一波字符串分割,C语言与C++两种方法

    hdu2072:题意:输出给定字符串中的单词数(一个句子中可能有两个相同的单词),这里的思想是把每个单词取出来,放入set(这个集合容器中不允许有相同的元素)中,最后输出该集合的大小即可. 现在的问题 ...

  8. Asp.NetCore Web开发之模型验证

    在开发中,验证表单数据是很重要的一环,如果对用户输入的数据不加限制,那么当错误的数据提交到后台后,轻则破坏数据的有效性,重则会导致服务器瘫痪,这是很致命的. 所以进行数据有效性验证是必要的,我们一般通 ...

  9. MySQL中使用Show Profile

    Show profile 默认是禁用的,用处是记录在服务器中运行的查询耗费的时间和其他一些查询执行状态变更相关的数据. 当前系统是win10,Mysql版本是8.0.15 1.查看当前profilin ...

  10. Jmeter(四十五) - 从入门到精通高级篇 - Jmeter之网页爬虫-上篇(详解教程)

    1.简介 上大学的时候,第一次听同学说网页爬虫,当时比较幼稚和懵懂,觉得就是几只电子虫子爬在网页上在抓取东西.后来又听说写代码可以实现网页爬虫,宏哥感觉高大上,后来工作又听说,有的公司做爬虫被抓的新闻 ...