问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

深度强化学习训练优化:如何平衡CPU和GPU使用

创作时间:
作者:
@小白创作中心

深度强化学习训练优化:如何平衡CPU和GPU使用

引用
CSDN
1.
https://blog.csdn.net/weixin_56760882/article/details/139098003

在深度强化学习训练中,如何平衡CPU和GPU的使用以达到最佳训练速度是一个值得探讨的问题。本文通过实验和分析,提出了CPU采样+GPU训练模型的方法,并提供了具体的实现逻辑和代码示例。

问题背景

在深度强化学习中,模型训练通常需要大量的计算资源。传统的做法是使用GPU进行全量训练,但作者在实践中发现,将模型从CPU拷贝到GPU会消耗大量时间,导致整体训练速度变慢。因此,作者开始研究如何更有效地利用CPU和GPU的特性来优化训练过程。

实验环境

  • 算法:PPO(Proximal Policy Optimization)
  • 环境:CartPole-v0
  • 模型:128单隐层
  • 样本数:0(on-line)

原始GPU训练结果

  • 耗时:2分钟8秒
  • GPU占用:45%左右
  • CPU占用:27%

CPU训练结果

  • 耗时:47.4秒(经常CPU满载后,CPU会变慢,后续测时为53秒)
  • CPU占用:满载100%

解决方案

参考文献解释了CPU训练速度快、GPU训练速度慢的原因:模型从CPU拷贝到GPU花了大量时间,且环境交互时的少量运算,CPU比GPU运算速度更快。基于此,作者提出了CPU采样+GPU训练模型的方法。

CPU采样+GPU训练的优势

  1. 环境交互方面:强化学习时要进行大量的环境交互,也就是进行文件的读取操作或者少量计算操作。CPU对于文件读取和少量计算往往比GPU更快,更准确,是因为CPU有少量且强大的核心,设计时是为了专注于处理不同的任务。

  2. 模型训练方面:模型中有大量的参数,但模型更新时都是简单的矩阵运算。GPU有大量的小核心,专注于图形处理和矩阵运算,在这方面速度比CPU要快。

实现逻辑

模型都在CPU上生成,由CPU与环境交互,由GPU训练模型。

  1. 在环境采样前将模型参数上传到(copy到)CPU上
  2. 在模型训练前(更新前)将模型copy到GPU上

PPO算法示例代码

from tqdm import tqdm

def train_on_policy_agent(env, agent, num_episodes):
    return_list = []
    for i in range(10):
        with tqdm(total=int(num_episodes/10), desc='Iteration %d' % i) as pbar:
            for i_episode in range(int(num_episodes/10)):
                episode_return = 0
                transition_dict = {'states': [], 'actions': [], 'next_states': [], 'rewards': [], 'dones': []}
                state = env.reset(seed =0)[0] #1.改 gym 0.26.0版本后,env.reset()返回的是一个字典,所以需要加上[0]
                agent.actor.to('cpu')
                done = False
                while not done:
                    action = agent.take_action(state) 
                    next_state, reward,terminated, truncated, _ = env.step(action) #2.改看gym版本0.26.2版本的 
                    done = terminated or truncated
                    transition_dict['states'].append(state)
                    transition_dict['actions'].append(action)
                    transition_dict['next_states'].append(next_state)
                    transition_dict['rewards'].append(reward)
                    transition_dict['dones'].append(done)
                    state = next_state
                    episode_return += reward
                return_list.append(episode_return)
                agent.actor.to('cuda') #
                agent.critic.to('cuda')
                agent.update(transition_dict)
                if (i_episode+1) % 10 == 0:
                    pbar.set_postfix({'episode': '%d' % (num_episodes/10 * i + i_episode+1), 'return': '%.3f' % np.mean(return_list[-10:])})
                pbar.update(1)
    return return_list

实验结果

  • CPU+GPU方法耗时:43.4秒至45.1秒
  • CPU占用:比单GPU训练低5%,比单CPU训练低75%
  • GPU占用:比单GPU训练低23%

结论:几乎在运用到深度网络的场景下,平衡CPU和GPU的方法比只单用一个的方法好的多。

硬件购买建议

  • CPU:核数越大,速度越快
  • GPU:入门有就行,训练图像时显存越大越好
  • 内存:越大越好(有经验池时)

附加实验:离线版本的修改

在离线版本(有经验池)中,需要在更新完毕之后,将要采样环境的模型放回CPU上。这样可以避免同时使用两个设备的错误。

进一步优化

作者尝试了通过减少模型从GPU到CPU的拷贝次数来优化性能。具体方法是调整更新频率,使得每次更新时只进行一次拷贝。这种方法在DDPG算法中得到了验证,但在PPO+经验池的算法中效果不佳。

性能分析

通过cProfile性能分析器,作者发现:

  • 在CPU下,一次update是0.004或0.003s
  • 在GPU下,一次update是0.005s

这说明在小模型下,CPU的更新速度确实比GPU快。但是,随着模型复杂度的增加,GPU的优势会逐渐显现。

最终总结

  1. 对于单隐层64和双隐层64x64的模型:
  • off-online方法:使用CPU版本最快
  • on-line方法:先采样后更新+CPU版本最快
  1. 对于单隐层128和双隐层128x128的模型:
  • off-online方法:先采样后更新+轨迹经验池+(CPU+GPU版本)最快
  • on-line方法:先采样后更新+(CPU+GPU版本)或先采样后更新+(CPU版本)
  1. 对于单隐层256和双隐层256x256的模型:
  • off-online:先采样后更新+轨迹经验池+(CPU+GPU)
  • on-line:先采样后更新+(CPU+GPU)

一般来说,隐层数量越多,收敛的越快。

CPU+GPU版本的改法

主要就是环境采样时的模型和张量改为CPU;更新参数的模型和张量改为GPU。如果是A-C的算法,Actor初始化为CPU,Critic初始化为GPU。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号