0

0

使用Ray创建高效的深度学习数据管道

WBOY

WBOY

发布时间:2023-11-02 20:17:15

|

1041人浏览过

|

来源于51CTO.COM

转载

深度学习模型训练所需的gpu功能强大,但价格昂贵。为了充分利用gpu,开发人员需要一个高效的数据传输通道,以便在gpu准备好计算下一个训练步骤时,能够迅速将数据传输到gpu。使用ray能够显著提高数据传输通道的效率

1、训练数据管道的结构

首先,我们来看一下模型训练的伪代码

for step in range(num_steps):sample, target = next(dataset) # 步骤1train_step(sample, target) # 步骤2

在步骤1中,获取下一个小批量的样本和标签。在步骤2中,它们被传递给train_step函数,该函数会将它们复制到GPU上,执行前向传递和反向传递以计算损失和梯度,并更新优化器的权重。

请详细了解步骤1。当数据集太大无法放入内存时,步骤1将从磁盘或网络中获取下一个小批量数据。此外,步骤1还包括一定量的预处理。输入数据必须被转换为数字张量或张量集合,然后再馈送给模型。在某些情况下,还会在传递给模型之前对张量进行其他转换,如归一化、绕轴旋转、随机打乱等

如果工作流程是严格按顺序执行的,即先执行步骤1,然后再执行步骤2,那么模型将始终需要等待下一批数据的输入、输出和预处理操作。GPU将无法得到有效利用,它将在加载下一个小批量数据时处于空闲状态。

为了解决这个问题,可以将数据管道视为生产者——消费者的问题。数据管道生成小批量数据并写入有界缓冲区。模型/GPU从缓冲区中消费小批量数据,执行前向/反向计算并更新模型权重。如果数据管道能够以模型/GPU消费的速度快速生成小批量数据,那么训练过程将会非常高效。

☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜

使用Ray创建高效的深度学习数据管道图片

2、Tensorflow tf.data API

Tensorflow tf.data API提供了一组丰富的功能,可用于高效创建数据管道,使用后台线程获取小批量数据,使模型无需等待。仅仅预先获取数据还不够,如果生成小批量数据的速度比GPU消费数据的速度慢,那么就需要使用并行化来加快数据的读取和转换。为此,Tensorflow提供了交错功能以利用多个线程并行读取数据,以及并行映射功能使用多个线程对小批量数据进行转换。

由于这些API是基于多线程的,所以可能会受到Python全局解释器锁(GIL)的限制。Python的GIL限制了一次只能运行单个线程的字节码。如果在管道中使用纯TensorFlow代码,通常不会受到这种限制,因为TensorFlow核心执行引擎在GIL的范围之外工作。但是,如果使用的第三方库没有解除GIL限制或者使用Python进行大量计算,那么依赖多线程来并行化管道就不可行

3、使用多进程并行化数据管道

考虑以下生成器函数,该函数模拟加载和执行一些计算以生成小批量数据样本和标签。

Nanonets
Nanonets

基于AI的自学习OCR文档处理,自动捕获文档数据

下载
def data_generator():for _ in range(10):# 模拟获取# 从磁盘/网络time.sleep(0.5)# 模拟计算for _ in range(10000):passyield (np.random.random((4, 1000000, 3)).astype(np.float32), np.random.random((4, 1)).astype(np.float32))

接下来,在虚拟的训练管道中使用该生成器,并测量生成小批量数据所花费的平均时间。

generator_dataset = tf.data.Dataset.from_generator(data_generator,output_types=(tf.float64, tf.float64),output_shapes=((4, 1000000, 3), (4, 1))).prefetch(tf.data.experimental.AUTOTUNE)st = time.perf_counter()times = []for _ in generator_dataset:en = time.perf_counter()times.append(en - st)# 模拟训练步骤time.sleep(0.1)st = time.perf_counter()print(np.mean(times))

据观察,平均耗时约为0.57秒(在配备Intel Core i7处理器的Mac笔记本电脑上测量)。如果这是一个真实的训练循环,GPU的利用率将相当低,它只需花费0.1秒进行计算,然后闲置0.57秒等待下一个批次数据。

为了加快数据加载速度,可以使用多进程生成器。

from multiprocessing import Queue, cpu_count, Processdef mp_data_generator():def producer(q):for _ in range(10):# 模拟获取# 从磁盘/网络time.sleep(0.5)# 模拟计算for _ in range(10000000):passq.put((np.random.random((4, 1000000, 3)).astype(np.float32),np.random.random((4, 1)).astype(np.float32)))q.put("DONE")queue = Queue(cpu_count()*2)num_parallel_processes = cpu_count()producers = []for _ in range(num_parallel_processes):p = Process(target=producer, args=(queue,))p.start()producers.append(p)done_counts = 0while done_counts < num_parallel_processes:msg = queue.get()if msg == "DONE":done_counts += 1else:yield msgqueue.join()

现在,如果测量等待下一个小批次数据所花费的时间,得到的平均时间为0.08秒。速度提高了近7倍,但理想情况下,希望这个时间接近0。

如果进行分析,可以发现相当多的时间都花在了准备数据的反序列化上。在多进程生成器中,生产者进程会返回大型NumPy数组,这些数组需要进行准备,然后在主进程中进行反序列化。那么在进程间传递大型数组时,如何提高效率呢?

4、使用Ray并行化数据管道

这就是Ray发挥作用的地方。Ray是一个用于在Python中运行分布式计算的框架。它带有一个共享内存对象存储区,可在不同进程间高效地传输对象。特别的是,在不进行任何序列化和反序列化的情况下,对象存储区中的Numpy数组可在同一节点上的worker之间共享。Ray还可以轻松实现数据加载在多台机器上的扩展,并使用Apache Arrow高效地序列化和反序列化大型数组。

Ray带有一个实用函数from_iterators,可以创建并行迭代器,开发者可以用它包装data_generator生成器函数。

import raydef ray_generator():num_parallel_processes = cpu_count()return ray.util.iter.from_iterators([data_generator]*num_parallel_processes).gather_async()

使用ray_generator,测量等待下一个小批量数据所花费的时间为0.02秒,比使用多进程处理的速度提高了4倍。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
什么是分布式
什么是分布式

分布式是一种计算和数据处理的方式,将计算任务或数据分散到多个计算机或节点中进行处理。本专题为大家提供分布式相关的文章、下载、课程内容,供大家免费下载体验。

407

2023.08.11

分布式和微服务的区别
分布式和微服务的区别

分布式和微服务的区别在定义和概念、设计思想、粒度和复杂性、服务边界和自治性、技术栈和部署方式等。本专题为大家提供分布式和微服务相关的文章、下载、课程内容,供大家免费下载体验。

251

2023.10.07

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

765

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

377

2025.12.24

java多线程相关教程合集
java多线程相关教程合集

本专题整合了java多线程相关教程,阅读专题下面的文章了解更多详细内容。

32

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

29

2026.01.21

C# 多线程与异步编程
C# 多线程与异步编程

本专题深入讲解 C# 中多线程与异步编程的核心概念与实战技巧,包括线程池管理、Task 类的使用、async/await 异步编程模式、并发控制与线程同步、死锁与竞态条件的解决方案。通过实际项目,帮助开发者掌握 如何在 C# 中构建高并发、低延迟的异步系统,提升应用性能和响应速度。

103

2026.02.06

apache是什么意思
apache是什么意思

Apache是Apache HTTP Server的简称,是一个开源的Web服务器软件。是目前全球使用最广泛的Web服务器软件之一,由Apache软件基金会开发和维护,Apache具有稳定、安全和高性能的特点,得益于其成熟的开发和广泛的应用实践,被广泛用于托管网站、搭建Web应用程序、构建Web服务和代理等场景。本专题为大家提供了Apache相关的各种文章、以及下载和课程,希望对各位有所帮助。

421

2023.08.23

Python异步编程与Asyncio高并发应用实践
Python异步编程与Asyncio高并发应用实践

本专题围绕 Python 异步编程模型展开,深入讲解 Asyncio 框架的核心原理与应用实践。内容包括事件循环机制、协程任务调度、异步 IO 处理以及并发任务管理策略。通过构建高并发网络请求与异步数据处理案例,帮助开发者掌握 Python 在高并发场景中的高效开发方法,并提升系统资源利用率与整体运行性能。

37

2026.03.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
从PHP基础到ThinkPHP6实战
从PHP基础到ThinkPHP6实战

共126课时 | 24.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号