我正在实现AlphaZero的一个版本(AlphaGo最新的演变形态),并将其应用于其他领域。
该算法的关键是对状态空间(CPU)进行蒙特卡罗树搜索,并与神经网络在评估模式下的“直觉”(概率)相互交错(GPU)。然后使用MCTS结果来训练神经网络。
我已经通过启动多个进程并使每个进程构建自己的树来实现CPU执行的并行化。这很有效,但现在导致了GPU瓶颈! (nvidia-smi显示GPU始终为100%)
我设计了两种策略来并行化GPU评估,但它们都存在问题。
1. 每个进程仅评估其自己树中的批次。在我的最初的天真实现中,这意味着批量大小为1。但是,通过重构一些代码并添加“虚拟损失”以防止(但并不完全阻止)选择同一节点两次,我们可以得到较大的1-4批处理数据。这里的问题是我们不能允许太长时间的延迟,否则准确性会受到影响,因此小批量处理非常关键。
2. 将批次发送到中央“神经网络工作线程”以进行组合和评估。这可以在32个或更多的大批次中完成,因此GPU可以非常有效地使用。这里的问题是树工人会将CUDA张量进行'round-trip'发送,而PyTorch不支持此操作。如果先克隆它们,则支持此方法,但所有这些常量副本使该方法比第一种方法慢。
我在考虑可能有一个巧妙的批处理方案可以使第一种方法生效。使用多个GPU也可以加速第一种方法,但是我想要的并行性不受PyTorch的本机支持。也许只保留NN工作器中的所有张量并仅发送id可以改善第二种方法,但困难在于如何有效地同步以获得大批量,而不让CPU线程等待太久。
在他们各自的论文中,我几乎找不到关于AlphaZero或AlphaGo Zero是如何并行化的信息。但我能在网上找到一些有限的信息,这些信息帮助我改进了第一种方法。
如果有任何建议,尤其是我忽略掉某些点或方法,我将不胜感激。
该算法的关键是对状态空间(CPU)进行蒙特卡罗树搜索,并与神经网络在评估模式下的“直觉”(概率)相互交错(GPU)。然后使用MCTS结果来训练神经网络。
我已经通过启动多个进程并使每个进程构建自己的树来实现CPU执行的并行化。这很有效,但现在导致了GPU瓶颈! (nvidia-smi显示GPU始终为100%)
我设计了两种策略来并行化GPU评估,但它们都存在问题。
1. 每个进程仅评估其自己树中的批次。在我的最初的天真实现中,这意味着批量大小为1。但是,通过重构一些代码并添加“虚拟损失”以防止(但并不完全阻止)选择同一节点两次,我们可以得到较大的1-4批处理数据。这里的问题是我们不能允许太长时间的延迟,否则准确性会受到影响,因此小批量处理非常关键。
2. 将批次发送到中央“神经网络工作线程”以进行组合和评估。这可以在32个或更多的大批次中完成,因此GPU可以非常有效地使用。这里的问题是树工人会将CUDA张量进行'round-trip'发送,而PyTorch不支持此操作。如果先克隆它们,则支持此方法,但所有这些常量副本使该方法比第一种方法慢。
我在考虑可能有一个巧妙的批处理方案可以使第一种方法生效。使用多个GPU也可以加速第一种方法,但是我想要的并行性不受PyTorch的本机支持。也许只保留NN工作器中的所有张量并仅发送id可以改善第二种方法,但困难在于如何有效地同步以获得大批量,而不让CPU线程等待太久。
在他们各自的论文中,我几乎找不到关于AlphaZero或AlphaGo Zero是如何并行化的信息。但我能在网上找到一些有限的信息,这些信息帮助我改进了第一种方法。
如果有任何建议,尤其是我忽略掉某些点或方法,我将不胜感激。