最近准备准备整合一个基于pytorch的深度学习平台,把常用的训练推理流程、模型、数据管理、metric测试以及各种有效的黑科技攒到一起,作为个人的使用工具可以提升算法开发和实验效率。为了验证不同特性的有效性选择在比较有说服力的imagenet上进行实验。之前也做过很多次imagenet的训练和模型复现,但是训练一次imagenet比较耗时。最近使用上了一个比较有效的数据预处理框架:nvidia.dali,感觉效果不错。
Nvidia DALI,NVIDIA’s Data Loading Library, is a collection of highly optimized building blocks, and an execution engine, to accelerate the pre-processing of the input data for deep learning applications。这是DALI的定义,说白了就是一个在神经网络中加速数据预处理(尤其是图像数据)的库。大家都知道,目前的神经网络任务中,基本可以分为以下几个步骤:
1、将数据(图片、视频、文本、音频或其他形式的数据)准备好存放在服务器的硬盘上;
2、通过CPU将硬盘上的数据读入内存,进行解码、数据增强等操作,将数据准备成可被神经网络使用的格式,这部分主要依赖于CPU的计算能力;
3、通过设备通信将内存中的数据传入GPU的显存中,进行神经网络计算,这部分主要依赖于GPU的计算能力。
整个流程中CPU和GPU的计算延时应该基本相当,这样CPU处理好的数据能被及时的被GPU利用,充分发挥二者的能力。如果CPU的处理速度大于GPU的计算速度,则会造成CPU算力浪费经常需要等待GPU;反之亦然。
随着黄教主不断发力发布算力越来越强的GPU以及计算机的硬件架构原因,这个过程的平衡逐渐被打破了。目前的神经网络应用中,经常看到GPU的算力较强而CPU较弱,数据预处理的过程耗时较长,成为了整个应用的bottleneck。而数据的预处理(以图像数据为例,数据的解码、图像翻转、resize等)大多都是计算密集型操作,这正是GPU擅长做的事情。那么为什么不考虑将这部分操作都从CPU挪到GPU上去做呢?于是nvidia做了dali这样一个库来实现这个transfer的过程。所以我们可以总结的说,
DALI就做了一件事:把一部分数据处理的操作从CPU挪到了GPU上去做,挪动的比例得当的话,刚好可以实现CPU和GPU的延时同步,充分利用二者的计算能力。
我们以一个图像问题来简单介绍dali的使用方法。在DALI中,一个完整的数据预处理过程叫做一个pipeline,在这个pipeline中用户需要自己定义一些必须的内容,比如原始数据是什么格式(图片?二进制文件?视频?),需要做哪些数据预处理操作(图像翻转?图像归一化?)以及每个操作过程是在什么设备上运行(cpu?gpu?mixed?)。完成pipeline定以后需要将其build起来,然后打包成一个可被循环访问的数据结构,就可以在for循环中不断拿数据了。首先回顾一下,如果在Pytorch中使用原生API构建一个数据模块,我们可以这么做:
class MyDataset(torch.utils.data.Dataset):
def __init__(self, ...):
...
def __getitem__(self, idx):
...
dataset = MyDataset(...)
data_loader = torch.utils.data.DataLoader(dataset, ...)
for index, data in enumerate(data_loader):
images, labels = data
images, labels = images.cuda(), labels.cuda()
...
这样的代码中,每张图片的预处理都在CPU上进行,最后通过Tensor.cuda()将其推到GPU的显存中参与运算。如果使用DALI,我们可以这么做:
from nvidia.dali.pipeline import Pipeline
import nvidia.dali.ops as ops
import nvidia.dali.types as types
from nvidia.dali.plugin.pytorch import DALIClassificationIterator
class SimplePipeline(Pipeline):
def __init__(self, batch_size, num_threads, device_id):
super(SimplePipeline, self).__init__(batch_size, num_threads, device_id, seed = 12)
self.input = ops.FileReader(file_root = image_dir)
self.decode = ops.ImageDecoder(device = 'cpu', output_type = types.RGB)
self.resize = ops.Resize(device='gpu', resize_shorter=224)
self.cmn = ops.CropMirrorNormalize(device='gpu', crop=(224, 224), dtype=types.FLOAT, mean=[0.485 * 255, 0.465 * 255, 0.406 * 255], std=[0.229 * 255, 0.224 * 255, 0.225 * 255], mirror=1)
def define_graph(self):
jpegs, labels = self.input()
images = self.decode(jpegs)
images = self.resize(images)
images = self.cmn(images)
return (images, labels)
pipe = SimplePipeline(8, 4, 0)
pipe.build()
train_loader = DALIClassificationIterator(pipe)
for index, data in enumerate(train_loader):
images, labels = data
labels = labels.squeeze(-1).cuda().long()
...
上面的代码中,我们看到了一个dali处理图像数据的很简单的例子,希望大家从中理解dali的大概运行原理,而不用纠结每个参数或者每个API的接口具体形式,这些内容可以再dali的doc网站中全部查到。如果想要准确的使用某一个类型的数据,还是需要去查找每个API的接口参数及其对应的含义,甚至可能需要去看一下部分API的源码。DALI支持多种数据类型,甚至连TFRecord类型的数据都支持,可以通过dali把tfrecord数据集成到一个pytorch框架下的应用中,确实还是很方便的。我把自己的渣渣CPU版本数据预处理换成DALI+TFRecord再搭配上DDP后,训练速度直接飙了将近8倍,4块Tesla P100上训练一个epoch的imagenet只需要12分钟,四块卡的GPU利用率全部顶到100%,深深地治愈了我的强迫症,感谢DALI!!!
水平有限,欢迎讨论。
最近准备准备整合一个基于pytorch的深度学习平台,把常用的训练推理流程、模型、数据管理、metric测试以及各种有效的黑科技攒到一起,作为个人的使用工具可以提升算法开发和实验效率。为了验证不同特性的有效性选择在比较有说服力的imagenet上进行实验。之前也做过很多次imagenet的训练和模型复现,但是训练一次imagenet比较耗时。最近使用上了一个比较有效的数据预处理框架:nvidia.dali,感觉效果不错。DALI的概念 Nvidia DALI,NVIDIA’s Data Loadi
NVIDIA_DALI
NVIDIA 数据加载库 (DALI: Data Loading Library) 是一个用于数据加载和预处理以加速深度学习应用程序的库。它提供了一组高度优化的构建块,用于加载和处理图像、视频和音频数据。它可以用作流行深度学习框架中内置数据加载器和数据迭代器的便携式替代品。
深度学习应用程序需要复杂的多阶段数据处理管道,包括加载、解码、裁剪、调整大小和许多其他增强功能。这些目前在 CPU 上执行的数据处理管道已成为瓶颈,限制了训练和推理的性能和可扩展性。
DALI 通过将数据预处理
NVIDIA/DALI(NVIDIA Data Loading Library) 库包含了用于加速深度学习应用的数据预处理的高度优化的构建模块(highly optimized building blocks)和执行引擎(execution engine).
深度学习应用中,往往需要复杂的、多阶段的数据预处理管道. 这些数据管道主要是在CPU上执行的数据密集型操作(compute-intensive o
NVIDIA DALI从入门到放弃之二:入门示例
NVIDIA DALI从入门到放弃之三:Data Loading
NVIDIA DALI从入门到放弃之四:Multiple GPU
NVIDIA DALI从入门到放弃之五:Image Processing
NVIDIA DALI从入门到放弃之六:Geometric Transforms
NVIDIA DALI从入门到放弃之七:Sequence Processing
NVIDIA DALI从入门到放弃之八:PyTo
NVIDIA DALI从入门到放弃之二:入门示例
NVIDIA DALI从入门到放弃之三:Data Loading
NVIDIA DALI从入门到放弃之四:Multiple GPU
NVIDIA DALI从入门到放弃之五:Image Processing
1 Image Decoder
-1 CPU
-2 GPU
Color Space Conversion
-1 CPU
-2 GPU
BrightnessContrast
-1 CPU
-2 GPU
多种多样的结构化和文本/图像等非结构化数据,譬如矩阵操作/标准化normalize/图像水平翻转等,深度学习应用程序需要复杂的多阶段预处理数据管道。此类数据管道涉及在CPU上执行的计算密集型操作。例如,诸如:从磁盘加载数据,解码,裁剪,随机调整大小,颜色和空间扩充以及格式转换等任务主要在CPU上执行,从而限制了训练和推理的性能和可伸缩性。
DALI当前支持计算机视觉任务,例如图像分类,识别和对象...
import nvidia.dali.ops as ops
import nvidia.dali.types as types
from nvidia.dali.pipeline import Pipeline
from nvidia.dali.plugin.pytorch import DALIClassific.
这允许以这样的方式对图像块进行局部表示,使得可以将它们与变形和照明都具有很强的不变性进行比较。
该代码的核心是用C编写的,旨在嵌入到应用程序中。
还应该可以编译为库并安装在系统级别。
<Francesc
Moreno-Noguer
INTERNATIONAL ELECTROTECHNICAL COMMISSION ____________
DIGITAL ADDRESSABLE LIGHTING INTERFACE –
Part 209: Particular requirements for control gear – Colour control (device type 8)
FOREWORD
1) The International Electrotechnical Commission (IEC) is a worldwide organization for standardization comprising all national electrotechnical committees (IEC National Committees). The object of IEC is to promote international co-operation on all questions concerning standardization in the electr
#import for dali dataloader
from nvidia.dali.pipeline import Pipeline
import nvidia.dali.fn as fn
from nvidia.dali import types
from nvidia.dali import math as math
from nvidia.dali.plugin...
深度学习数据加载慢的问题可以通过以下几种方法来解决:
1. 预处理提速:尽量减少每次读取数据时的预处理操作,可以考虑将一些固定的操作(如resize)事先处理好并保存下来,在训练时直接使用。此外,可以将预处理操作搬到GPU上进行加速,例如使用NVIDIA/DALI库。
2. IO提速:
- 使用更快的图片处理库,如opencv,它通常比PIL更快。对于JPEG读取,可以尝试使用jpeg4py存储为BMP图像以降低解码时间。
- 将小图拼起来存放,以降低读取次数。
3. 使用并行加载:PyTorch的默认DataLoader会创建一些worker线程来预读取新的数据,但是除非这些线程的数据全部都被清空,否则它们不会读取下一批数据。可以使用prefetch_generator或data_prefetcher等工具来确保线程不会等待,每个线程都有至少一个数据在加载。
4. 调整patience参数:在使用EarlyStopping时,patience参数表示能够容忍多少个epoch内都没有improvement。根据实际情况,可以调整patience的大小来在抖动和准确率下降之间做tradeoff。如果patience设置得大,最终得到的准确率可能略低于模型可以达到的最高准确率;如果patience设置得小,模型可能在前期抖动阶段就停止训练,准确率可能较差。
综上所述,通过预处理提速、IO提速、并行加载和调整patience参数等方法,可以有效解决深度学习数据加载慢的问题。
#### 引用[.reference_title]
- *1* [训练技巧之数据集太多,加载太慢怎么办?](https://blog.csdn.net/weixin_45250844/article/details/109300852)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item]
- *2* [深度学习框架_PyTorch_PyTorch数据读取加速方法](https://blog.csdn.net/Rocky6688/article/details/105317098)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item]
- *3* [CPU深度学习训练速度过慢+keras深度学习训练常见函数解释](https://blog.csdn.net/weixin_43201920/article/details/105889691)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item]
[ .reference_list ]