

华东师范大学 数据科学与工程学院, 上海 200333
收稿日期:2021-07-15
基金项目:国家自然科学基金资助项目(61902128)
作者简介:丁光耀(1996—), 男, 博士研究生
通讯作者:徐辰, 副教授, E-mail: cxu@dase.ecnu.edu.cn
摘要:近年来, 学术和工业界广泛利用大数据处理系统来处理视频分析等领域基于深度神经网络(deep neural networks, DNN)的推理负载。在这种场景下, 因大数据系统中多个并行推理任务重复加载相同且只读的DNN模型, 导致系统无法充分利用GPU资源, 成为了推理性能提升的瓶颈。针对该问题, 该文提出了一个面向单GPU卡的模型共享技术, 在DNN推理任务之间共享同一份模型数据。在此基础上, 为了使模型共享技术作用于分布式环境下的每一块GPU, 该文还设计了支持多GPU卡模型共享的分配器。将上述优化技术集成到在GPU平台上运行的Spark中, 实现了一个支持大规模推理负载的分布式原型系统。实验结果表明, 针对基于YOLO-v3的交通视频处理负载, 相对于未采用模型共享技术的系统, 模型共享技术能够提升系统吞吐量达136%。
关键词:大数据处理系统DNN推理GPU显存模型共享
Model sharing for GPU-accelerated DNN inference in big data processing systems
DING Guangyao, CHEN Qihang, XU Chen


School of Data Science and Engineering, East China Normal University, Shanghai 200333, China
Abstract: Big data processing is being widely used in academia and industry to handle DNN-based inference workloads for fields such as video analyses. In such cases, multiple parallel inference tasks in the big data processing system repeatedly load the same, read-only DNN model so the system does not fully utilize the GPU resources which creates a bottleneck that limits the inference performance. This paper presents a model sharing technique for single GPU cards that enables sharing of the same model among various DNN inference tasks. An allocator is used to make the model sharing technique work for each GPU in the distributed environment. This method was implemented in Spark on a GPU platform in a distributed data processing system that supports large-scale inference workloads. Tests show that for video analyses on the YOLO-v3 model, the model sharing reduces the GPU memory overhead and improves system throughput by up to 136% compared to a system without the model sharing technique.
Key words: big data processing systemDNN inferenceGPUGPU memorymodel sharing
近年来,大数据处理系统[1-3]因其MapReduce的编程模式能有效地降低用户编写分布式程序的难度,被学术与工业界广泛使用。与此同时,DNN技术由于其出色的推理精确度,在视频图像数据处理领域[4-5]得到了广泛的应用。DNN模型拥有大量参数,每一次推理计算总量可达数十亿次[6],需要借助GPU加速计算。为支持大规模的数据处理以及DNN推理,一种可行的解决方案便是在大数据处理系统上进行GPU扩展。基于大数据处理系统的任务并行模式,该方案能够通过调度多个推理任务并行使用GPU资源[7]的方式提高GPU利用率,进而提升推理性能。
然而,多个并行执行的DNN推理任务会多次加载相同的模型,重复占用显存空间,限制了系统推理性能的进一步提升。例如,在大数据处理系统Spark软件平台以及型号为RTX 2080 Ti、显存为10 GB的GPU硬件平台的条件下,采用YOLO-v3[8]模型对交通视频数据中的车辆进行检测与追踪,如图 1a所示,随着GPU上并行执行的DNN推理任务数量的增加,系统吞吐量会不断增加。然而调度多个DNN推理任务并行使用GPU会加载多份相同且只读的模型,每个模型占用约2 500 MB显存。如图 1b所示,当GPU上并行任务数量超过4时会导致显存溢出,无法继续上升。系统吞吐量因此只能达到如图 1a所示的红色虚线位置,此时GPU的计算资源因显存限制没有得到充分利用。目前基于大数据处理系统执行DNN推理的工作[7, 9-10]均未考虑此问题,S3DNN[11]与DAMB[12]虽然解决了模型多次加载占用显存的问题,但均属于单机嵌入式系统上的工作,不是基于大数据处理系统的解决方案。本文针对基于大数据处理系统执行DNN推理时的显存开销问题提出了解决方案。
![]() |
图 1 GPU上并行执行DNN推理任务 |
图选项 |
具体而言,本文分别针对单GPU卡和多GPU卡的场景进行了研究。针对单GPU卡,本文提出了模型共享方法,使大数据处理系统在同一个工作进程中的线程之间能够共享GPU显存中的模型数据,有效地降低DNN推理应用的显存开销。针对多GPU卡,本文设计了GPU分配器,使模型共享技术可以作用于分布式集群中的每一块GPU卡。本文在大数据处理系统Spark中集成上述技术,实现了原型系统。实验结果表明,针对交通视频处理负载,相对于未采用模型共享技术的系统,模型共享技术能够提升系统吞吐量达136%。
1 相关工作目前主流DNN推理与训练的框架[13-15]提供了构建DNN必要的接口,降低了用户执行DNN推理与训练的难度。车载嵌入式系统S3DNN[11]、DAMB[12]需要同时处理来自不同位置摄像头获取的图像数据,其为了充分利用有限的GPU资源,在一块GPU上基于CUDA stream技术并行地执行多个DNN推理任务实例。其在嵌入式单机场景下,使多个DNN推理任务共享GPU显存中的模型数据。Spark-GPU[16]、HeteroSpark[17]通过GPU服务进程与原生Spark系统交互的方式使用GPU资源。GFlink[7]是基于Flink的GPU扩展,其通过CUDA stream技术使GPU服务进程内的多个任务线程能够并行使用GPU资源,提高了GPU加速计算的效果。但基于大数据处理系统的任务并行模式,以类似GFlink的多任务共享GPU资源的方式进行DNN推理,会不可避免地加载多个DNN模型,造成巨大显存开销。
TensorFlowOnSpark[9]、Flare[18]等将大数据处理系统Spark与深度学习系统TensorFlow[13]进行融合,Flink-ai-Extended[10]则将Flink与TensorFlow进行融合。这些融合系统同时具备分布式计算的完整机制和DNN算法的接口,能够方便地利用集群GPU资源进行大规模数据的DNN推理。但是作为一个支持训练或推理的融合系统,上述相关工作并未考虑多个DNN推理任务同时使用同一个GPU资源时模型的显存开销问题。与上述研究工作不同,本文面向基于大数据处理系统执行DNN推理场景,针对因加载多次模型占用大量显存的问题,提出了模型共享技术以降低显存开销,提升推理性能。
2 面向单GPU卡的模型共享2.1 任务并行模式下的模型冗余加载问题在大数据处理系统中,用户在主程序中定义的处理逻辑代码会被系统解析为任务,分别调度到待处理数据集的不同子集上并行执行,所有子集上执行的任务代码完全相同。对于DNN推理任务,其首先需要加载DNN模型到GPU显存,然后载入数据进行推理。在同一块GPU上启动多个DNN推理任务是一种提高GPU利用率,提升系统推理性能的方法。该方法基于大数据处理系统任务并行模式很容易实现,如图 2所示,但是由于GPU上并行执行的DNN推理任务代码完全一致,会加载多个相同的模型数据到显存,造成大量的显存开销。当GPU可使用的显存较小时,GPU上并行执行的任务数量在较低的情况就会占满GPU的显存,此时GPU计算资源未被充分利用,无法充分加速DNN推理。
![]() |
图 2 多推理任务加载模型 |
图选项 |
2.2 基于Spark的模型共享DNN推理过程不会修改模型数据,因此在多个任务并行计算的情况下只需要加载一份模型数据。在DNN推理过程中会不断地产生中间结果,为保证推理结果的正确性,多个任务各自的中间结果不可以共享。对于大数据处理系统下多个DNN推理任务并行使用同一个GPU卡的情况,显存应被划分为两部分,即用来存储DNN模型数据的模型空间以及用来存储中间结果的计算空间。模型空间是多个推理任务共享的,计算空间是每个推理任务独占的。Spark通过执行器进程中的线程执行任务,这为模型共享提供了技术基础,因为只有进程内部才可以共享显存空间。本文提出的模型共享支持进程内多个线程对应DNN推理任务之间的模型共享。对于进程之间的DNN推理任务,本文的方法并不能降低显存开销。基于上述理解,模型共享技术的设计原则如下:1) 当某一任务线程申请共享模型空间并加载模型后,其余任务无需重复申请模型空间,仅需申请自身的计算空间;2) 各个任务线程在推理过程中,从共享的模型空间中读取模型并将中间结果存放于各自的计算空间。下面将介绍如何基于该设计原则在Spark执行器进程内实现模型共享。
如图 3所示,基于模型共享的工作流程如下:(1) 首先采用排它锁实现进程内的同步。(2) 抢到锁的任务会绑定CUDA stream加载模型,申请计算空间,最后释放锁。没抢到锁的任务会自旋等待,直到获取到锁。(3) 其他任务获取锁后发现模型已经加载,其只需要绑定CUDA stream并申请一块计算空间,释放锁,不需要再加载DNN模型。(4) 每个任务加载待处理的图像数据到计算空间。(5) 每个任务读取DNN模型指定层的模型数据(标记层数,不会加载到计算空间)。(6) 每个任务根据模型数据对一帧图像数据执行推理,中间结果保存在计算空间。(7) 每个任务将当前层的推理输出作为下一层推理的输入,直到DNN最后一层的推理。(8) 每个任务从GPU计算空间中拉取处理后的结果数据,返回到流程(4),直到完成处理所有数据。
![]() |
图 3 Spark中的模型共享 |
图选项 |
3 支持多GPU卡模型共享的GPU分配器本节首先分析了单GPU卡环境下的模型共享在多GPU卡环境下的局限性,然后设计了能够支持多GPU卡环境下的模型共享的GPU分配器。
3.1 GPU资源的闲置问题GPU驱动会根据用户在代码中指定的GPU设备编号调度核函数,并在对应的GPU设备上执行。在单GPU卡环境下,用户在代码中指定设备号为0,便可使用0号GPU卡执行计算任务。但是在大数据处理系统中,所有并行的DNN推理任务都会使用相同的代码中所指定的GPU设备。在一个物理机上有多个GPU设备的情况下,这种在代码中直接指定GPU设备号的方法会导致未被指定的GPU设备处于闲置状态,造成资源浪费。
3.2 基于Spark的多GPU卡分配为了使DNN推理任务能够使用到不同的GPU设备,系统需要让并行任务中的GPU设备号是不同的值。因此,本文设计了一种GPU分配器,其借助外部服务进程为多个DNN推理任务动态分配GPU设备号。GPU分配器在分配GPU时应遵循以下原则:1) GPU分配器需要获取并维护集群节点的GPU资源情况,按节点分配GPU设备;2) 节点中的GPU设备应按进程分配,以支持在进程内部多个线程之间共享DNN模型;3) 节点中的GPU设备应被平均地分配到各个工作进程中,从而保证多个GPU卡负载均衡。下面介绍GPU分配器如何与Spark系统执行器进程交互。
如图 4所示,GPU分配器基于gRPC框架提供了一个获取GPU设备号的服务,Spark的执行器通过该服务获取GPU设备号。GPU分配器在应用提交前启动,其初始化期间会运行GPU资源信息收集程序,获取Spark集群内所有节点的GPU信息并保存在内存中。待初始化结束后,用户便可以向系统提交DNN推理应用,执行DNN推理任务。DNN推理任务执行的过程中会与GPU分配器进行交互:1) DNN推理任务在加载模型前会向GPU分配器请求GPU设备号;2) GPU分配器收到请求后,根据上述原则分配一个GPU设备号给调用服务的DNN推理任务。值得注意的是,发送请求的DNN推理任务收到返回值后会通过静态变量将GPU设备号共享给执行器内的所有DNN推理任务线程。之后,推理任务便根据GPU设备号加载并共享模型,执行DNN推理计算,具体过程已在2.2节介绍过,这里便不再赘述。
![]() |
图 4 GPU分配器和执行器的交互 |
图选项 |
4 实验4.1 实验环境实验使用的软件环境如表 1所示。
表 1 软件环境
软件类别 | 软件名称 |
操作系统 | Ubuntu 18.04 |
算法库 | Darknet, OpenCV3 |
编程语言 | gcc-7.5, openjdk-1.8 |
GPU操作环境 | cuda-10.0, cudnn-7.6 |
数据存储软件 | kafka_2.11-0.10.2.2、hadoop-2.9.1 |
计算引擎软件 | Spark-2.4.3 |
表选项
实验测试使用的硬件环境如表 2所示。
表 2 硬件环境
硬件类型 | 详细信息 |
GPU | NVIDIA GeFore RTX 2080 Ti×2(10 989 MB) |
CPU | Inter Xeon(R) Silver 4110×2 |
内存 | 120 GB |
硬盘 | 3 TB |
网络带宽 | 千兆网 |
表选项
本节测试采用的数据集为来自真实的交通路口视频(https://gitlab.com/Dinggy/traffic_video_dataset)。数据集通过专业摄像设备采集获得,包含3个交通路口的视频。视频中每一帧图片分辨率为640×480,视频中包含大量车辆行人数据,具有实际意义。如表 3所示,随着节点数量的增加,系统处理能力以及存储能力也随之加强,用来测试的数据量也随节点数量成比例增加,与此同时,本研究团队保证每个交通路口提供相同的数据量。需要说明的是,为了满足测试中交通路口数量的需求,本研究团队对数据集中分别代表 3个交通路口的视频进行了重复使用。
表 3 测试数据集
节点数量 | 数据量/帧 | 交通路口数量 |
1 | 4 000 | 4 |
2 | 8 000 | 8 |
4 | 16 000 | 16 |
8 | 32 000 | 32 |
表选项
实验采用基于Darknet实现的YOLO-v3推理算法以及基于OpenCV3实现的追踪算法,在Spark软件平台和GPU硬件平台下实现了对视频中的车辆进行检测与追踪的负载。如图 5所示,系统首先从外部存储系统读取数据,然后根据预先设定分区数量使用rePartition算子随机重新分区,每一个分区对应一个任务。接着使用mapPartition算子自定义逻辑对视频数据进行预处理,包括格式转换、数据大小归一化。然后同样使用mapPartition算子对视频数据执行基于DNN推理的检测,其内部通过JNI方式来访问算法动态链接库。之后按照交通路口对视频数据进行再分区,并使用Partition By算子,再分区操作之后的分区数量等于交通路口数量。接着通过mapPartition算子对视频数据中的车辆执行追踪任务。最后将得到的结果写入外部存储系统。
![]() |
图 5 车辆检测与追踪负载 |
图选项 |
实验的目标是证明本文提出的模型共享技术的有效性,因此比较的基准为在运行负载的过程中未使用模型共享技术的方案。
4.2 显存开销比较本节将介绍模型共享技术对GPU显存开销的降低效果。图 6展示了实验的结果,横坐标表示DNN推理任务的并行度,纵坐标表示DNN推理计算消耗的GPU显存。每一个模型参数所占用的模型空间和中间结果所占用的计算空间合计消耗约2 500 MB显存。模型不共享的方案每增加一个并行度,便需要约2 500 MB的显存空间,而模型共享方案每增加一个并行度,仅增加600 MB左右的用于存储中间结果的显存空间。在并行度相同的情况下,使用模型共享技术的方案显存开销更小。在高并行度的情况下,模型不共享方案因达到显存容量上限而无法运行,而模型共享方案仍可以正常运行。
![]() |
图 6 显存开销 |
图选项 |
4.3 吞吐量比较本节首先介绍模型共享技术在单个GPU卡环境的吞吐量测试效果,然后再介绍在分布式多GPU卡环境的吞吐量测试结果。式(1)为吞吐量P的计算公式,其中N为视频图片数据帧数,T为总运行时间,单位为s,总运行时间不包含从外部存储系统读取数据以及将结果写入外部系统的时间。
$P=N/T.$ | (1) |
![]() |
图 7 吞吐量 |
图选项 |
本节测试选择4、6、8以及10 GB作为4个测试用例。图 8为实验结果,横坐标表示GPU卡可以使用的显存大小,纵坐标表示在此显存下系统执行DNN推理负载的最大吞吐量。
![]() |
图 8 显存限制下吞吐量 |
图选项 |
图 8展示了在所有测试用的结果中,采用模型共享方案的最大吞吐量始终大于模型不共享方案的最大吞吐量。当可使用的显存为4 GB时,采用模型共享技术的方案相对于不采用模型共享方案的吞吐量加速比最高,此时加速比为2.36。因为此时可使用的显存很小,采用模型不共享的方案仅能运行一个DNN推理任务,GPU计算资源的利用率很低,系统的吞吐量很低。而采用模型共享的方案,每一个并行的DNN推理任务显存消耗较少,可以运行3个DNN推理任务,因此系统吞吐量要远大于模型不共享方案。当GPU的显存为10 GB时,系统吞吐量加速比最低,为1.19。此时可使用的显存很大,两种方案并行度均很高,模型不共享方案的并行度为4,模型共享方案的并行度可以达到8以上。但是并行度在较高水平时,随着并行度的增加,系统吞吐量上升的趋势减缓,因此两种方案差距缩小,加速比降低。下面介绍分布式环境下模型共享技术的效果。
4.3.2 单机单GPU卡环境图 9为分布式环境下的吞吐量测试结果。每一张图的横坐标表示使用物理节点数量,纵坐标表示系统的吞吐量。对于每一个测试用例,可以观察到随着节点数增加,不论是采用模型共享技术的方案,还是采用模型不共享的方案,其系统吞吐量都会随之近线性的增加。该测试结果充分体现了模型共享技术的可扩展性,在不同节点数量或者显存大小的情况下,采用模型共享的方案的最大吞吐量始终大于模型不共享的方案。其中,当可使用的显存为4 GB时,模型共享方案相比于模型不共享方案,有1.62~2.2倍的性能提升;当显存为6 GB时,性能提升为1.3~1.8倍;当显存为8 GB时,性能提升为1.17~1.47倍;当显存为10 GB时,性能提升达到1.12~1.15倍。在分布式多机多GPU卡环境下显存仍然是吞吐量性能提升的关键因素,每一块GPU卡可以使用的显存越少,模型共享技术方案相比于模型不共享方案的系统吞吐量提升越明显。
![]() |
图 9 分布式环境下的吞吐量 |
图选项 |
5 总结与展望本文针对基于大数据处理系统执行DNN推理时,多次加载DNN模型的问题,提出一种共享GPU显存中模型数据的方法。该方法有效降低了并行执行DNN推理任务时的显存开销,提升了系统性能。未来本研究团队还将在如下几方面开展工作:进程内核函数并行执行时的优化调度策略;分布式故障场景下的推理任务的快速恢复;基于大数据处理系统在混合CPU/GPU的异构环境的负载均衡。
参考文献
[1] | DEAN J, GHEMAWAT S. MapReduce: Simplified data processing on large clusters[C]// Proceedings of the 6th Symposium on Operating System Design and Implementation (OSDI). Carlsbad, USA: USENIX Association, 2004: 137-150. |
[2] | ZAHARIA M, CHOWDHURY M, DAS T, et al. Resilient distributed datasets: A fault-tolerant abstraction for in-memory cluster computing[C]// Proceedings of the 9th USENIX Conference on Networked Systems Design and Implementation. Berkeley, United States: USENIX Association, 2012: 15-28. |
[3] | CARBONE P, KATSIFODIMOS A, EWEN S, et al. Apache FlinkTM: Stream and batch processing in a single engine[J]. Bulletin of the IEEE Computer Society Technical Committee on Data Engineering, 2015, 36(4): 28-38. |
[4] | HE K M, ZHANG X Y, REN S Q, et al. Deep residual learning for image recognition[C]// 2016 IEEE Conference on Computer Vision and Pattern Recognition (CVPR). Las Vegas, USA: IEEE, 2016: 770-778. |
[5] | KRIZHEVSKY A, SUTSKEVER I, HINTON G E. ImageNet classification with deep convolutional neural networks[C]// Proceedings of the 25th International Conference on Neural Information Processing Systems. Red Hook, USA: Curran Associates Inc., 2012: 1097-1105. |
[6] | ANDERSON M R, CAFARELLA M, ROS G, et al. Physical representation-based predicate optimization for a visual analytics database[C]// 2019 IEEE 35th International Conference on Data Engineering (ICDE). Macao, China: IEEE, 2019: 1466-1477. |
[7] | CHEN C, LI K L, OUYANG A J, et al. GFlink: An in-memory computing architecture on heterogeneous CPU-GPU clusters for big data[J]. IEEE Transactions on Parallel and Distributed Systems, 2018, 29(6): 1275-1288. |
[8] | REDMON J, FARHADI A. YOLOv3: An incremental improvement[J/OL]. (2018-04-08). https://arxiv.org/abs/1804.02767. |
[9] | TensorFlowOnSpark[EB/OL]. [2021-10-16]. https://github.com/yahoo/TensorFlowOnSpark. |
[10] | Flink-ai-extented[EB/OL]. [2021-10-11]. https://github.com/alibaba/flink-ai-extended. |
[11] | ZHOU H S, BATENI S, LIU C et al. S3DNN: Supervised streaming and scheduling for GPU-accelerated real-time DNN workloads[C]//2018 IEEE Real-Time and Embedded Technology and Applications Symposium (RTAS). Porto, Portugal: IEEE, 2018: 190-201. |
[12] | HASSAAN M, ELGHANDOUR I. A real-time big data analysis framework on a CPU/GPU heterogeneous cluster: A meteorological application case study[C]// Proceedings of the 3rd ACM International Conference on Big Data Computing (BDCAT). New York, USA: ACM, 2016: 168-177. |
[13] | ABADI M, BARHAM P, CHEN J M, et al. TensorFlow: A System for Large-Scale Machine Learning[C]// Proceedings of the 12th USENIX Symposium on Operating Systems Design and Implementation (OSDI). Savannah, GA, USA: USENIX Association, 2016: 265-283. |
[14] | PASZKE A, GROSS S, MASSA F, et al. PyTorch: An imperative style, high-performance deep learning library[C]// Proceedings of the 32nd Advances in Neural Information Processing Systems (NeurIPS). Marylebone, London, UK: MIT Press, 2019: 8024-8035. |
[15] | Darknet: Open Source Neural Networks in C[EB/OL]. [2016-01-30]. http://pjreddie.com/darknet/. |
[16] | YUAN Y, SALMI M F, HUAI Y, et al. Spark-GPU: An accelerated in-memory data processing engine on clusters[C]// 2016 IEEE International Conference on Big Data (Big Data). Washington, USA: IEEE, 2016: 273-283. |
[17] | LI P L, LUO Y, ZHANG N, et al. HeteroSpark: A heterogeneous CPU/GPU Spark platform for machine learning algorithms[C]// 2015 IEEE International Conference on Networking, Architecture and Storage (NAS). Boston, USA: IEEE, 2015: 347-348. |
[18] | ESSERTEL G, TAHBOUB R, DECKER J. Flare: Optimizing apache spark with native compilation for scale-up architectures and medium-size data[C]// Proceedings of the 13th Symposium on Operating Systems Design and Implementation (OSDI). Carlsbad, USA: USENIX Association, 2018: 799-815. |