在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. POJ2044 深搜+剪枝(云彩下雨)

    题意:        有一个城镇,是4*4的大小的,然后你控制一块云彩,2*2的,你每天可以有9种走的方法,上下左右,或者不动,走的时候可以走1或者2步,云彩所在的地方肯定会下雨,然后给你做多365天 ...

  2. Python爬虫之-动态网页数据抓取

    什么是AJAX: AJAX(Asynchronouse JavaScript And XML)异步JavaScript和XML.过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新.这意 ...

  3. xxl-job滥用netty导致的问题和解决方案

    netty作为一种高性能的网络编程框架,在很多开源项目中大放异彩,十分亮眼,但是在有些项目中却被滥用,导致使用者使用起来非常的难受. 本篇文章将会讲解xxl-job作为一款分布式任务调度系统是如何滥用 ...

  4. IOS Widget(4-1):创建可配置小组件(静态配置数据)

    引言   经过前面几篇文章阅读,已经掌握开发一款小组件的基本技能了,接下来开始掌握一些相对高级一点的技能.本文创建一个可配置小组件,通过修改时间类型,让Text空间显示不同格式的时间. 本文大纲 添加 ...

  5. Day006 可变参数

    可变参数(不定项参数) 在jdk1.5开始,java支持传递同类型的可变参数给一个方法. 在方法声明中,在指定参数类型后加一个省略号(...). 一个方法只能指定一个可变参数,它必须是方法的最后一个参 ...

  6. jupyter中那些神奇的第三方拓展魔术命令

    1 简介 无论是jupyter notebook还是jupyter lab,都可以使用ipython中的众多自带魔术命令来实现丰富的辅助功能,诸如%time之类的. 这些都已经是老生常谈的知识没什么好 ...

  7. burp-suite(Web安全测试工具)教程

    Burp Suite 是用于攻击web 应用程序的集成平台.它包含了许多工具,并为这些工具设计了许多接口,以促进加快攻击应用程序的过程.所有的工具都共享一个能处理并显示HTTP 消息,持久性,认证,代 ...

  8. 10个 解放双手的 IDEA 插件,这些代码都不用写(第二弹)

    本文案例收录在 https://github.com/chengxy-nds/Springboot-Notebook 大家好,我是小富~ 鸽了很久没发文,不写文章的日子真的好惬意,每天也不用愁着写点什 ...

  9. 数据库调优(二)Inner Join Merge Join Hash Match

    T-SQL 的编码习惯以及规范,影响的是查询优化器对执行计划的选择 健壮的SQL语句,更稳定.更高效 SELECT 几个部分: - 查询的数据来自什么表 - 需要查询表中哪些字段 (尽量不使用类似于 ...

  10. 初探MFC

    MFC MFC(Microsoft Foundation Classes) 是微软基础类库,也就是用c++类将win32API封装起来. 应用程序对象 MFC程序都是以应用程序对象为核心,且程序中只有 ...