在NVIDIA A100 GPU中使用DALI和新的硬件JPEG解码器快速加载数据
在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。
对于深度学习的计算机视觉应用程序(其中有数百万个样本的训练数据集是通用的),压缩和有效存储图像数据比以往任何时候都更为重要。行业标准的数据集(例如ImageNet和COCO)使用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解码器快速加载数据的更多相关文章
- NVIDIA A100 GPUs上硬件JPEG解码器和NVIDIA nvJPEG库
NVIDIA A100 GPUs上硬件JPEG解码器和NVIDIA nvJPEG库 Leveraging the Hardware JPEG Decoder and NVIDIA nvJPEG Lib ...
- 在NVIDIA A100 GPU上利用硬件JPEG解码器和NVIDIA nvJPEG库
在NVIDIA A100 GPU上利用硬件JPEG解码器和NVIDIA nvJPEG库 根据调查,普通人产生的1.2万亿张图像可以通过电话或数码相机捕获.这样的图像的存储,尤其是以高分辨率的原始格式, ...
- echarts在.Net中使用实例(二) 使用ajax动态加载数据
通过上一篇文章可以知道和echarts参考手册可知,series字段就是用来存储我们显示的数据,所以我们只需要用ajax来获取series的值就可以. option 名称 描述 {color}back ...
- Flexigrid从对象中加载数据
(有问题,在找…………) Flexigrid是用来动态加载数据的一种比较好(老)的Jquery表插件,然后有些时候,我们需要其从本地或者jQuery对象中加载数据,比如有这么个需求,页面显示中有两个表 ...
- smarty中增加类似foreach的功能自动加载数据方法
第一步:在Smarty_Compiler.class.php的_compile_tag函数中增加: 复制代码 代码如下: //加载数据的开始标签case 'load': $this->_push ...
- WinForm中异步加载数据并使用进度条
在WinForm程序中,有时会因为加载大量数据导致UI界面假死,这种情况对于用户来说是非常不友好的.因此,在加载大量数据的情况下,首先应该将数据加载放在另一线程中进行,这样保证了UI界面的响应:其次可 ...
- ArcGIS Engine中加载数据
ArcGIS Engine中加载数据 http://blog.csdn.net/gisstar/article/details/4206822 分类: AE开发积累2009-05-21 16:49 ...
- Android中GridView滚动到底部加载数据终极版
之前在项目中有一个需求是需要GridView控件,滚动到底部自动加载.但是呢GridView控件并不提供诸如ListView监听滚动到底部的onScrollListener方法,为了实现这样一个效果, ...
- Android中ListView分页加载数据
public class MainActivity extends Activity { private ListView listView=null; //listview的数据填充器 privat ...
随机推荐
- POJ2044 深搜+剪枝(云彩下雨)
题意: 有一个城镇,是4*4的大小的,然后你控制一块云彩,2*2的,你每天可以有9种走的方法,上下左右,或者不动,走的时候可以走1或者2步,云彩所在的地方肯定会下雨,然后给你做多365天 ...
- Python爬虫之-动态网页数据抓取
什么是AJAX: AJAX(Asynchronouse JavaScript And XML)异步JavaScript和XML.过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新.这意 ...
- xxl-job滥用netty导致的问题和解决方案
netty作为一种高性能的网络编程框架,在很多开源项目中大放异彩,十分亮眼,但是在有些项目中却被滥用,导致使用者使用起来非常的难受. 本篇文章将会讲解xxl-job作为一款分布式任务调度系统是如何滥用 ...
- IOS Widget(4-1):创建可配置小组件(静态配置数据)
引言 经过前面几篇文章阅读,已经掌握开发一款小组件的基本技能了,接下来开始掌握一些相对高级一点的技能.本文创建一个可配置小组件,通过修改时间类型,让Text空间显示不同格式的时间. 本文大纲 添加 ...
- Day006 可变参数
可变参数(不定项参数) 在jdk1.5开始,java支持传递同类型的可变参数给一个方法. 在方法声明中,在指定参数类型后加一个省略号(...). 一个方法只能指定一个可变参数,它必须是方法的最后一个参 ...
- jupyter中那些神奇的第三方拓展魔术命令
1 简介 无论是jupyter notebook还是jupyter lab,都可以使用ipython中的众多自带魔术命令来实现丰富的辅助功能,诸如%time之类的. 这些都已经是老生常谈的知识没什么好 ...
- burp-suite(Web安全测试工具)教程
Burp Suite 是用于攻击web 应用程序的集成平台.它包含了许多工具,并为这些工具设计了许多接口,以促进加快攻击应用程序的过程.所有的工具都共享一个能处理并显示HTTP 消息,持久性,认证,代 ...
- 10个 解放双手的 IDEA 插件,这些代码都不用写(第二弹)
本文案例收录在 https://github.com/chengxy-nds/Springboot-Notebook 大家好,我是小富~ 鸽了很久没发文,不写文章的日子真的好惬意,每天也不用愁着写点什 ...
- 数据库调优(二)Inner Join Merge Join Hash Match
T-SQL 的编码习惯以及规范,影响的是查询优化器对执行计划的选择 健壮的SQL语句,更稳定.更高效 SELECT 几个部分: - 查询的数据来自什么表 - 需要查询表中哪些字段 (尽量不使用类似于 ...
- 初探MFC
MFC MFC(Microsoft Foundation Classes) 是微软基础类库,也就是用c++类将win32API封装起来. 应用程序对象 MFC程序都是以应用程序对象为核心,且程序中只有 ...