在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 ...
随机推荐
- git基于master创建本地新分支
应用场景:开发过程中经常用到从master分支copy一个本地分支作为开发分支 步骤: 1.切换到被copy的分支(master),并且从远端拉取最新版本 $git checkout master $ ...
- C/C++ 手工实现IAT导入表注入劫持
DLL注入有多种方式,今天介绍的这一种注入方式是通过修改导入表,增加一项导入DLL以及导入函数,我们知道当程序在被运行起来之前,其导入表中的导入DLL与导入函数会被递归读取加载到目标空间中,我们向导入 ...
- c/c++ 指针函数 和 函数指针
指针函数:返回指针类型的函数,定义方法如下: 类型标识符 *函数名(参数列表) 函数指针:指向函数入口地址的指针,定义方法如下: 类型标识符 (*指针名称)(形参列表) 下面我们通过一段代码加深我们的 ...
- 【ECharts】报表联动,动态数据设计
说明: 数据没有拉取后台数据,仅仅前端模拟数据,Copy即可有效果.联动后台时,使用异步获取数据即可.鼠标点击,动态展示点击项的数据.有关更多实例,请移步到echarts官网查看. 成果展示: 相关代 ...
- NtQuerySystemInformation获取进程/线程状态
__kernel_entry NTSTATUS NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS SystemInformationClass, P ...
- python函数默认值只初始化一次
当在函数中定义默认值时,值初始化只会进行一次,就是执行到def methodname时执行.看下面代码: from datetime import datetime def test(t=dateti ...
- OO随笔之魔鬼的第一单元——多项式求导
OO是个借助Java交我们面向对象的课,可是萌新们总是喜欢带着面向过程的脑子去写求导,然后就是各种一面(main)到底.各种方法杂糅,然后就是被hack的很惨. 第一次作业:萌新入门面向对象 题目分析 ...
- Gateway导航
简介 最近都在弄微服务的东西,现在来记录下收获.我从一知半解到现在能从0搭建使用最大的感触有两点 1.微服务各大组件的版本很多,网上很多博客内容不一定适合你的版本,很多时候苦苦琢磨都是无用功 2.网上 ...
- 048.Python前端css
一 CSS介绍 1.1 CSS语法 CSS 规则由两个主要的部分构成:选择器,以及一条或多条声明. selector { property: value; property: value; prop ...
- 【转载】java与xml
原文地址:http://www.lai18.com/content/1198237.html java项目中,xml文件一般都是用来存储一些配置信息一般的编程, 多数用来存储配置信息 . 拿JDBC来 ...