tensorflow2.x(二)多进程并行模型

在上一篇文章中,我们解决了tensorflow在大样本训练中内存不足的问题,但是可能无法最大化利用GPU资源,在这篇文章中,我们继续挖掘如何充分利用GPU资源,将显卡的内存、算力全部拉满。

为了进一步挖掘显卡性能,进一步提升资源利用率,进一步解放双手,在这篇文章中,我们试图使用多进程,分配不同的显卡资源给多个模型,同时并行训练多个模型。
(虽然tf官方也有将显卡并行,使用多张显卡资源来提升计算效率的解决方案,但是仍然需要多源模型代码进行相关改变,且在笔者当下的尝试中,这种并行在生成环境中并不稳定)
因此,这里我们提出,同时并行多个模型的解决方案。

废话到此为止,直接上代码:

gpus = tf.config.experimental.list_physical_devices('GPU')
tf.config.experimental.set_visible_devices(gpus[0], 'GPU')
tf.config.experimental.set_virtual_device_configuration(
    gpus[0],
    [tf.config.experimental.VirtualDeviceConfiguration(memory_limit=1024)])
logical_gpus = tf.config.experimental.list_logical_devices('GPU')

这段代码是我前文中给出过的,也是tf官网里或是各种教程里轻而易举可以找到的。意思是,先获取你电脑中的全部可用GPU:gpus,然后给你当前进程中分配可见的gpus[0],再然后给当前可见的的gpus[0]分配可用内存memory_limit=1024。经过以上代码,你的当前进程中,就只能看到一张显卡,且显卡内存为memory_limit=1024

之后,通过多进程操作,我们就可以同时虚拟出多张显卡,每张显卡内独立跑各自的模型。

# 初始化cuda环境
def initial_cuda(gpu_name, memory_limit):
    gpus = tf.config.experimental.list_physical_devices('GPU')
    tf.config.experimental.set_visible_devices(gpus[gpu_name], 'GPU')
    tf.config.experimental.set_virtual_device_configuration(
        gpus[gpu_name],
        [tf.config.experimental.VirtualDeviceConfiguration(memory_limit=memory_limit)])
    logical_gpus = tf.config.experimental.list_logical_devices('GPU')

# 配置当前进程中的cuda
def get_cuda(use_cuda):
    gpu_name, memory_limit, name = use_cuda
    initial_cuda(gpu_name, memory_limit)
    print("USE CUDA:", gpu_name, memory_limit, name)

# 根据显卡内存容量,每次开6个线程,结束后全部关闭,重新开,防止cuda初始化失败
def allocate_mp(param_all, func, cuda_list):
    mp_num = 6
    for i in range((int(len(param_all) / mp_num) + 1)):
        param_group = param_all[i * mp_num:(i + 1) * mp_num]
        for v in range(len(param_group)):
            param_group[v] = param_group[v] + (cuda_list[v], )
        pool = mp.Pool(processes=mp_num)
        pool.map(func, param_group)
        pool.close()

# 需要执行的tf函数
def func(parma):
	a,b,use_cuda = parma
    get_cuda(use_cuda)
    
# 根据自己情况,给GPU分组
cuda_list = list(itertools.product([0, 1], [2048], ['a', 'b', 'c']))
# 参数组
param_all = [(1,2),(3,4),(5,6)]
# 执行多线程
allocate_mp(param_all, func, cuda_list)

对于cuda_list的解释: 这里我有[0,1]两张GPU,每个GPU分为[‘a’, ‘b’, ‘c’]三块,每块分配2048M内存。这样我可以得到6个虚拟GPU,支持6进程。

这里需要注意的一个坑在多进程中,进程池一旦打开,比如开2个进程,跑10组不同参数的函数。所有的函数是都在这固定的2个进程中进行,并不会在一个函数运行结束后关闭当前进程,然后重新开一个进程跑下一个函数。
因此,在我们的allocate_mp函数中,写了一个循环,对于超出6个参数组的情况,我们需要等上6个进程全部结束,然后再重新开新的6个进程,运行下一组。因为,在进程开启后,tensorflow的cuda初始化仅第一次有效,第二次执行带有cuda初始化的函数便会报错。

至此,就可以愉快地并行运行tensorflow模型,充分挖掘GPU算力。

运行nvidia-smi可看到如下,开启了6个线程,同时运行模型:
在这里插入图片描述

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Python中的多进程并行可以很大程度上提高程序的执行效率和速度。下面是一个简单的例子,演示了使用多进程并行和单进程执行同一个任务所需的时间对比: ``` import time import multiprocessing # 任务函数 def task(num): time.sleep(1) return num*num # 单进程执行 start_time = time.time() results = [] for i in range(10): results.append(task(i)) end_time = time.time() print("单进程执行时间:", end_time - start_time) # 多进程并行执行 start_time = time.time() pool = multiprocessing.Pool(processes=4) # 创建进程池,最大进程数为4 results = [pool.apply_async(task, (i,)) for i in range(10)] # 在进程池中异步执行任务 pool.close() pool.join() end_time = time.time() print("多进程并行执行时间:", end_time - start_time) ``` 在这个例子中,我们定义了一个任务函数task,这个函数接收一个参数num,执行一个简单的计算任务,并返回计算结果。我们首先使用单进程执行这个任务,并记录执行时间。然后,我们使用多进程并行执行同样的任务,并记录执行时间。在多进程并行执行时,我们使用了multiprocessing库中的Pool类来创建进程池,并使用apply_async方法在进程池中异步执行任务。 我们可以运行这段代码,得到输出结果。一般来说,多进程并行执行的时间会比单进程执行的时间更短,可以看到在这个例子中,多进程并行执行的时间要比单进程执行的时间快了很多。但是需要注意的是,并不是所有的任务都适合使用多进程并行,有时候多进程并行执行的效率反而会变得更低。因此,在实际的应用中,需要根据具体的情况选择是否使用多进程并行

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RicardoOzZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值