0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

图像预处理库 CV-CUDA 开源了,打破预处理瓶颈,提升推理吞吐量 20 多倍

NVIDIA英伟达 来源:未知 2022-12-26 22:50 次阅读

本文转载自机器之心

CPU 图像预处理成为视觉任务的瓶颈,最新开源的 CV-CUDA,将为图像预处理算子提速百倍。

在如今信息化时代中,图像或者说视觉内容早已成为日常生活中承载信息最主要的载体,深度学习模型凭借着对视觉内容强大的理解能力,能对其进行各种处理与优化。

然而在以往的视觉模型开发与应用中,我们更关注模型本身的优化,提升其速度与效果。相反,对于图像的预处理与后处理阶段,很少认真思考如何去优化它们。所以,当模型计算效率越来越高,反观图像的预处理与后处理,没想到它们竟成了整个图像任务的瓶颈。

为了解决这样的瓶颈,NVIDIA 携手字节跳动机器学习团队开源众多图像预处理算子库 CV-CUDA,它们能高效地运行在 GPU 上,算子速度能达到 OpenCV(运行在 CPU)的百倍左右。如果我们使用 CV-CUDA 作为后端替换 OpenCV 和 TorchVision,整个推理的吞吐量能达到原来的二十多倍。此外,不仅是速度的提升,同时在效果上 CV-CUDA 在计算精度上已经对齐了 OpenCV,因此训练推理能无缝衔接,大大降低工程师的工作量。

feab39c2-852b-11ed-bfe3-dac502259ad0.png

以图像背景模糊算法为例,将 CV-CUDA 替换 OpenCV 作为图像预/后处理的后端,整个推理过程吞吐量能加 20多倍。

如果小伙伴们想试试更快、更好用的视觉预处理库,可以试试这一开源工具。

开源地址:https://github.com/CVCUDA/CV-CUDA

图像预/后处理已成为CV瓶颈

很多涉及到工程与产品的算法工程师都知道,虽然我们常常只讨论模型结构和训练任务这类「前沿研究」,但实际要做成一个可靠的产品,中间会遇到很多工程问题,反而模型训练是最轻松的一环了。

图像预处理就是这样的工程难题,我们也许在实验或者训练中只是简单地调用一些 API 对图像进行几何变换、滤波、色彩变换等等,很可能并不是特别在意。但是当我们重新思考整个推理流程时会发现,图像预处理已经成为了性能瓶颈,尤其是对于预处理过程复杂的视觉任务。

这样的性能瓶颈,主要体现在 CPU 上。一般而言,对于常规的图像处理流程,我们都会先在 CPU 上进行预处理,再放到 GPU 运行模型,最后又会回到 CPU,并可能需要做一些后处理。

febdce84-852b-11ed-bfe3-dac502259ad0.png

以图像背景模糊算法为例,常规的图像处理流程中预后处理主要在 CPU 完成,占据整体 90% 的工作负载,其已经成为该任务的瓶颈。

因此对于视频应用,或者 3D 图像建模等复杂场景,因为图像帧的数量或者图像信息足够大,预处理过程足够复杂,并且延迟要求足够低,优化预/后处理算子就已经迫在眉睫了。一个更好地做法,当然是替换掉 OpenCV,使用更快的解决方案。

为什么 OpenCV 仍不够好?

在 CV 中,应用最广泛的图像处理库当然就是长久维护的 OpenCV 了,它拥有非常广泛的图像处理操作,基本能满足各种视觉任务的预/后处理所需。但是随着图像任务负载的加大,它的速度已经有点慢慢跟不上了,因为 OpenCV 绝大多数图像操作都是 CPU 实现,缺少 GPU 实现,或者 GPU 实现本来就存在一些问题。

在 NVIDIA 与字节跳动算法同学的研发经验中,他们发现 OpenCV 中那些少数有 GPU 实现的算子存在三大问题:

  1. 部分算子的 CPU 和 GPU 结果精度无法对齐;

  2. 部分算子 GPU 性能比 CPU 性能还弱;

  3. 同时存在各种 CPU 算子与各种GPU算子,当处理流程需要同时使用两种,就额外增加了内存与显存中的空间申请与数据迁移/数据拷贝


比如说第一个问题结果精度无法对齐,NVIDIA 与字节跳动算法同学会发现,当我们在训练时 OpenCV 某个算子使用了 CPU,但是推理阶段考虑到性能问题,换而使用 OpenCV 对应的 GPU 算子,也许 CPU 和 GPU 结果精度无法对齐,导致整个推理过程出现精度上的异常。当出现这样的问题,要么换回 CPU 实现,要么需要费很多精力才有可能重新对齐精度,是个不好处理的难题。

既然 OpenCV 仍不够好,可能有读者会问,那 Torchvision 呢?它其实会面临和 OpenCV 一样的问题,除此之外,工程师部署模型为了效率更可能使用 C++ 实现推理过程,因此将没办法使用 Torchvision 而需要转向 OpenCV 这样的 C++视觉库,这不就带来了另一个难题:对齐 Torchvision 与 OpenCV 的精度。

总的来说,目前视觉任务在 CPU 上的预/后处理已经成为了瓶颈,然而当前 OpenCV 之类的传统工具也没办法很好地处理。因此,将操作迁移到 GPU 上,完全基于 CUDA 实现的高效图像处理算子库 CV-CUDA,就成为了新的解决方案。

fed7073c-852b-11ed-bfe3-dac502259ad0.png

完全在 GPU 上进行预处理与后处理,将大大降低图像处理部分的 CPU 瓶颈。

GPU 图像处理加速库:CV-CUDA

作为基于 CUDA 的预/后处理算子库,算法工程师可能最期待的是三点:足够快、足够通用、足够易用。NVIDIA 和字节跳动的机器学习团队联合开发的 CV-CUDA 正好能满足这三点,利用 GPU 并行计算能力提升算子速度,对齐 OpenCV 操作结果足够通用,对接 C++/Python 接口足够易用。

CV-CUDA 的速度

CV-CUDA 的快,首先体现在高效的算子实现,毕竟是 NVIDIA 写的,CUDA 并行计算代码肯定经过大量的优化的。其次是它支持批量操作,这就能充分利用 GPU 设备的计算能力,相比 CPU 上一张张图像串行执行,批量操作肯定是要快很多的。最后,还得益于 CV-CUDA 适配的 Volta、Turing、Ampere 等 GPU 架构,在各 GPU 的 CUDA kernel 层面进行了性能上的高度优化,从而获得最好的效果。也就是说,用的 GPU 卡越好,其加速能力越夸张。

正如前文的背景模糊吞吐量加速比图,如果采用 CV-CUDA 替代 OpenCV 和 TorchVision 的前后处理后,整个推理流程的吞吐率提升 20多倍。其中预处理对图像做 Resize、Padding、Image2Tensor 等操作,后处理对预测结果做的 Tensor2Mask、Crop、Resize、Denoise 等操作。

fee96abc-852b-11ed-bfe3-dac502259ad0.png

在同一个计算节点上(2x Intel Xeon Platinum 8168 CPUs,1x NVIDIA A100 GPU),以 30fps 的帧率处理 1080p 视频,采用不同 CV 库所能支持的最大的并行流数。测试采用了 4 个进程,每个进程 batchSize 为 64。

对于单个算子的性能,NVIDIA 和字节跳动的小伙伴也做了性能测试,很多算子在 GPU 上的吞吐量能达到 CPU 的百倍。

ff0ce690-852b-11ed-bfe3-dac502259ad0.png

图片大小为 480*360,CPU 选择为 Intel(R) Core(TM) i9-7900X,BatchSize 大小为 1,进程数为 1

尽管预/后处理算子很多都不是单纯的矩阵乘法等运算,为了达到上述高效的性能,CV-CUDA 其实做了很多算子层面的优化。例如采用大量的 kernel 融合策略,减少了 kernel launch 和 global memory 的访问时间;优化访存以提升数据读写效率;所有算子均采用异步处理的方式,以减少同步等待的耗时等等。

CV-CUDA 的通用与灵活

运算结果的稳定,对于实际的工程可太重要了,就比如常见的 Resize 操作,OpenCV、OpenCV-gpu 以及 Torchvision 的实现方式都不一样,那从训练到部署,就会多很多工作量以对齐结果。

CV-CUDA 在设计之初,就考虑到当前图像处理库中,很多工程师习惯使用 OpenCV 的 CPU 版本,因此在设计算子时,不管是函数参数还是图像处理结果上,尽可能对齐 OpenCV CPU 版本的算子。因此从 OpenCV 迁移到 CV-CUDA,只需要少量改动就能获得一致的运算结果,模型也就不必要重新训练。

此外,CV-CUDA 是从算子层面设计的,因此不论模型的预/后处理流程是什么样的,其都能自由组合,具有很高的灵活性。

字节跳动机器学习团队表示,在企业内部训练的模型多,需要的预处理逻辑也多种多样有许多定制的预处理逻辑需求。CV-CUDA 的灵活性能保证每个 OP 都支持 stream 对象和显存对象(Buffer 和 Tensor 类,内部存储了显存指针)的传入,从而能更加灵活地配置相应的 GPU 资源。每个 op 设计开发时,既兼顾了通用性,也能按需提供定制化接口,能够覆盖图片类预处理的各种需求。

CV-CUDA 的易用

可能很多工程师会想着,CV-CUDA 涉及到底层 CUDA 算子,那用起来应该比较费劲?但其实不然,即使不依赖更上层的 API,CV-CUDA 本身底层也会提供 Image 等结构体,提供 Allocator 类,这样在 C++ 上调起来也不麻烦。此外,往更上层,CV-CUDA 提供了 PyTorch、OpenCV 和 Pillow 的数据转化接口,工程师能快速地以之前熟悉的方式进行算子替换与调用。

此外,因为 CV-CUDA 同时拥有 C++ 接口与 Python 接口,它能同时用于训练与服务部署场景,在训练时用 Python 接口跟快速地验证模型能力,在部署时利用 C++ 接口进行更高效地预测。CV-CUDA 免于繁琐的预处理结果对齐过程,提高了整体流程的效率。

ff25296c-852b-11ed-bfe3-dac502259ad0.png

CV-CUDA 进行Resize的C++ 接口

实战,CV-CUDA 怎么用

如果我们在训练过程中使用 CV-CUDA 的 Python 接口,那其实使用起来就会很简单,只需要简单几步就能将原本在 CPU 上的预处理操作都迁移到 GPU 上。

以图片分类为例,基本上我们在预处理阶段需要将图片解码为张量,并进行裁切以符合模型输入大小,裁切完后还要将像素值转化为浮点数据类型并做归一化,之后传到深度学习模型就能进行前向传播了。下面我们将从一些简单的代码块,体验一下 CV-CUDA 是如何对图片进行预处理,如何与 Pytorch 进行交互。

ff349ea6-852b-11ed-bfe3-dac502259ad0.png

常规图像识别的预处理流程,使用 CV-CUDA 将会把预处理过程与模型计算都统一放在 GPU 上运行。

如下在使用 torchvision 的 API 加载图片到 GPU 之后,Torch Tensor 类型能直接通过 as_tensor 转化为 CV-CUDA 对象 nvcvInputTensor,这样就能直接调用 CV-CUDA 预处理操作的 API,在 GPU 中完成对图像的各种变换。

ff5abb04-852b-11ed-bfe3-dac502259ad0.png

如下几行代码将借助 CV-CUDA 在 GPU 中完成图像识别的预处理过程:裁剪图像并对像素进行归一化。其中 resize()将图像张量转化为模型的输入张量尺寸;convertto() 将像素值转化为单精度浮点值;normalize() 将归一化像素值,以令取值范围更适合模型进行训练。

CV-CUDA 各种预处理操作的使用与 OpenCV 或 Torchvision 中的不会有太大区别,只不过简单调个方法,其背后就已经在 GPU 上完成运算了。

ff877234-852b-11ed-bfe3-dac502259ad0.png

现在借助借助 CV-CUDA 的各种 API,图像分类任务的预处理已经都做完了,其能高效地在 GPU 上完成并行计算,并很方便地融合到 PyTorch 这类主流深度学习框架的建模流程中。剩下的,只需要将 CV-CUDA 对象 nvcvPreprocessedTensor 转化为 Torch Tensor 类型就能馈送到模型了,这一步同样很简单,转换只需一行代码:

ffc07412-852b-11ed-bfe3-dac502259ad0.png

通过这个简单的例子,很容易发现 CV-CUDA 确实很容易就嵌入到正常的模型训练逻辑中。如果读者希望了解更多的使用细节,还是可以查阅前文 CV-CUDA 的开源地址。

CV-CUDA 对实际业务的提升

CV-CUDA 实际上已经经过了实际业务上的检验。在视觉任务,尤其是图像有比较复杂的预处理过程的任务,利用 GPU 庞大的算力进行预处理,能有效提神模型训练与推理的效率。CV-CUDA 目前在抖音集团内部的多个线上线下场景得到了应用,比如搜索多模态,图片分类等。

字节跳动机器学习团队表示,CV-CUDA 在内部的使用能显著提升训练与推理的性能。例如在训练方面,字节跳动一个视频相关的多模态任务,其预处理部分既有多帧视频的解码,也有很多的数据增强,导致这部分逻辑很复杂。复杂的预处理逻辑导致 CPU 多核性能在训练时仍然跟不上,因此采用 CV-CUDA 将所有 CPU 上的预处理逻辑迁移到 GPU,整体训练速度上获得了 90% 的加速。注意这可是整体训练速度上的提升,而不只是预处理部分的提速。

ffe62bc6-852b-11ed-bfe3-dac502259ad0.png

在字节跳动 OCR 与视频多模态任务上,通过使用 CV-CUDA,整体训练速度能提升 1 到 2 倍(注意:是模型整体训练速度的提升)

在推理过程也一样,字节跳动机器学习团队表示,在一个搜索多模态任务中使用 CV-CUDA 后,整体的上线吞吐量相比于用 CPU 做预处理时有了 2 倍多的提升。值得注意的是,这里的 CPU 基线结果本来就经过多核高度优化,并且该任务涉及到的预处理逻辑较简单,但使用 CV-CUDA 之后加速效果依然非常明显。

速度上足够高效以打破视觉任务中的预处理瓶颈,再加上使用也简单灵活,CV-CUDA 已经证明了在实际应用场景中能很大程度地提升模型推理与训练效果,所以要是读者们的视觉任务同样受限于预处理效率,那就试试最新开源的 CV-CUDA 吧。


原文标题:图像预处理库 CV-CUDA 开源了,打破预处理瓶颈,提升推理吞吐量 20 多倍

文章出处:【微信公众号:NVIDIA英伟达】欢迎添加关注!文章转载请注明出处。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 英伟达
    +关注

    关注

    22

    文章

    3648

    浏览量

    90109

原文标题:图像预处理库 CV-CUDA 开源了,打破预处理瓶颈,提升推理吞吐量 20 多倍

文章出处:【微信号:NVIDIA_China,微信公众号:NVIDIA英伟达】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    C55x CSL音频预处理

    电子发烧友网站提供《C55x CSL音频预处理.pdf》资料免费下载
    发表于 09-19 11:30 0次下载
    C55x CSL音频<b class='flag-5'>预处理</b>

    求助,关于使用iperf测量mesh节点吞吐量问题求解

    我把esp-mesh-lite的no-route例程和iperf例程合在一起,想测试两个mesh节点间tcp通信的吞吐量,实际过程中一开始流量正常,数秒后客户端发数据这边monitor卡死没有任何
    发表于 07-23 06:59

    机器学习中的数据预处理与特征工程

    在机器学习的整个流程中,数据预处理与特征工程是两个至关重要的步骤。它们直接决定模型的输入质量,进而影响模型的训练效果和泛化能力。本文将从数据预处理和特征工程的基本概念出发,详细探讨这两个步骤的具体内容、方法及其在机器学习中的应
    的头像 发表于 07-09 15:57 213次阅读

    信号的预处理包括哪些环节

    的各个环节,包括信号的采集、预滤波、采样、量化、编码、去噪、特征提取等。 信号采集 信号采集是信号预处理的第一步,它涉及到从实际物理现象中获取信号的过程。信号采集的方法取决于信号的类型和来源,例如声音、图像、温
    的头像 发表于 06-03 10:35 1537次阅读

    【RTC程序设计:实时音视频权威指南】音频采集与预处理

    音视频通信对音频采集的实时性和性能要求很高。为了降低延迟并提高吞吐量,可能需要采用一些优化技术,如硬件加速、多线程处理等。 最后,音频采集还需要考虑与后续处理步骤的衔接问题。例如,采集到的音频
    发表于 04-25 10:41

    C预处理器及其工作原理

    C预处理器(C Pre-Processor)也常简写为 CPP,是一个与 C 编译器独立的小程序,预编译器并不理解 C 语言语法,它仅是在程序源文件被编译之前,实现文本替换的功能。
    的头像 发表于 03-12 14:14 508次阅读
    C<b class='flag-5'>预处理</b>器及其工作原理

    C语言中的预处理

    所有的预处理器命令都是以井号(#)开头。它必须是第一个非空字符,为了增强可读性,预处理器指令应从第一列开始。
    发表于 03-01 12:16 690次阅读
    C语言中的<b class='flag-5'>预处理</b>器

    如何提高CYBT-243053-02吞吐量

    你好我们一直在使用“EZ-Serial Firmware: v1.4.13.13 Sep 22 2023 10:24:41”测试“CYBT-243053-02”,我们得到的吞吐量比 PUART 高
    发表于 02-27 06:56

    数据预处理和特征工程的常用功能

    机器学习最基础的5个流程,分别是数据获取,数据预处理,特征工程,建模、测试和预测,上线与部署。
    的头像 发表于 01-25 11:26 596次阅读

    C语言有哪些预处理操作?

    C语言的预处理是在编译之前对源代码进行处理的阶段,它主要由预处理器完成。预处理器是一个独立的程序,它负责对源代码进行一些文本替换和处理,生成
    的头像 发表于 12-08 15:40 504次阅读
    C语言有哪些<b class='flag-5'>预处理</b>操作?

    C语言必备知识编译预处理

    编译预处理就是在编译源代码之前进行的一系列处理,将源程序中的一些特殊命令进行展开或处理,生成扩展的源代码。这些特殊命令通常以“#”开头,占单独的行,语句尾部不需要加分号。
    的头像 发表于 12-01 18:27 973次阅读
    C语言必备知识编译<b class='flag-5'>预处理</b>

    影响ATE电源系统吞吐量的关键因素

    从串行设备测试改变为并行设备测试可以显著地增加测试系统吞吐量。测试执行活动的大部分可能涉及使用DC电源设置条件和进行测量。配置测试系统,使其能够使用多个直流电源同时对多个设备执行测试,是显著提高测试吞吐量的一种经济有效的方法。
    发表于 11-29 12:36 282次阅读
    影响ATE电源系统<b class='flag-5'>吞吐量</b>的关键因素

    激光雷达点云预处理介绍

    有效的收益。 点云预处理 1.1 指定区域获取点云 在实际使用中,我们可以看出,虽然点云的分布范围较广,但大部分的点都集中的中间区域,距离越远点云越稀疏,相对的信息也越小。 此外还能明显看到一些离群点,因此我们可以筛选
    的头像 发表于 11-27 18:11 738次阅读

    如何显著提高ATE电源吞吐量

    作为一名测试工程师,你的工作并不容易。降低成本和提高系统吞吐量的压力一直存在。本文中,我们将讨论影响系统吞吐量的关键因素以及如何降低ATE测试成本。
    的头像 发表于 11-08 14:59 599次阅读
    如何显著提高ATE电源<b class='flag-5'>吞吐量</b>?

    请问C语言文件中的预处理操作符#和##各有什么作用?

    C语言文件中的预处理操作符#和##各有什么作用?
    发表于 11-06 08:09