Ray Tensorflow-gpu 2.0 递归错误
Ray Tensorflow-gpu 2.0 RecursionError
系统信息
OS 平台和分发(例如,Linux Ubuntu 16.04):Ubuntu 18.04
Ray 安装自(源或二进制):二进制
射线版本:0.7.3
Python版本:3.7
Tensorflow版本:tensorflow-gpu 2.0.0rc0
要重现的确切命令:
# Importing packages
from time import time
import gym
import tensorflow as tf
import ray
# Creating our initial model
model = tf.keras.Sequential([
tf.keras.layers.Dense(64, input_shape=(24,), activation='relu'),
tf.keras.layers.Dense(4, activation='softmax')
])
# Setting parameters
episodes = 64
env_name = 'BipedalWalker-v2'
# Initializing ray
ray.init(num_cpus=8, num_gpus=1)
# Creating our ray function
@ray.remote
def play(weights):
actor = tf.keras.Sequential([
tf.keras.layers.Dense(64, input_shape=(24,), activation='relu'),
tf.keras.layers.Dense(4, activation='softmax')
])
actor = actor.set_weights(weights)
env = gym.make('BipedalWalker-v2').env
env._max_episode_steps=1e20
obs = env.reset()
for _ in range(1200):
action = actor.predict_classes(obs).flatten()[0]
action = env.action_space.sample()
obs, rt, done, info = env.step(action)
return rt
# Testing ray
start = time()
weights = model.get_weights()
weights = ray.put(weights)
results = ray.get([play.remote(weights) for i in range(episodes)])
ray.shutdown()
print('Ray done after:',time()-start)
描述问题
我正在尝试使用 Ray 并行化使用 Tensorflow 2.0-gpu Keras actor 的 OpenAI 健身房环境的推出。每次我尝试使用 @ray.remote 实例化 Keras 模型时,它都会引发递归深度达到错误。我正在关注 Ray 概述的文档,其中建议传递权重而不是模型。我不确定我在这里做错了什么,有什么想法吗?
源代码/日志
文件“/home/jacob/anaconda3/envs/tf-2.0-gpu/lib/python3.7/site-packages/tensorflow/init.py”,第 50 行,在 getattr 中
模块 = self._load()
文件“/home/jacob/anaconda3/envs/tf-2.0-gpu/lib/python3.7/site-packages/tensorflow/init.py”,第 44 行,在 _load
模块 = _importlib.import_module(self.name)
递归错误:超过最大递归深度
核心问题似乎是 cloudpickle(Ray 用来序列化远程函数并将它们传送到工作进程)无法 pickle tf.keras.Sequential
class。例如,我可以重现问题如下
import cloudpickle # cloudpickle.__version__ == '1.2.1'
import tensorflow as tf # tf.__version__ == '2.0.0-rc0'
def f():
tf.keras.Sequential
cloudpickle.loads(cloudpickle.dumps(f)) # This fails.
最后一行失败
---------------------------------------------------------------------------
RecursionError Traceback (most recent call last)
<ipython-input-23-25cc307e6227> in <module>
----> 1 cloudpickle.loads(cloudpickle.dumps(f))
~/anaconda3/lib/python3.6/site-packages/tensorflow/__init__.py in __getattr__(self, item)
48
49 def __getattr__(self, item):
---> 50 module = self._load()
51 return getattr(module, item)
52
~/anaconda3/lib/python3.6/site-packages/tensorflow/__init__.py in _load(self)
42 def _load(self):
43 """Import the target module and insert it into the parent's namespace."""
---> 44 module = _importlib.import_module(self.__name__)
45 self._parent_module_globals[self._local_name] = module
46 self.__dict__.update(module.__dict__)
... last 2 frames repeated, from the frame below ...
~/anaconda3/lib/python3.6/site-packages/tensorflow/__init__.py in __getattr__(self, item)
48
49 def __getattr__(self, item):
---> 50 module = self._load()
51 return getattr(module, item)
52
RecursionError: maximum recursion depth exceeded while calling a Python object
有趣的是,这个 成功 tensorflow==1.14.0
,但我想 keras 在 2.0 中已经改变了很多。
解决方法
作为 解决方法,您可以尝试在单独的模块或 Python 文件中定义 f
,例如
# helper_file.py
import tensorflow as tf
def f():
tf.keras.Sequential
然后在您的主脚本中使用它,如下所示。
import helper_file
import ray
ray.init(num_cpus=1)
@ray.remote
def use_f():
helper_file.f()
ray.get(use_f.remote())
这里的区别在于,当 cloudpickle 尝试序列化 use_f
时,它实际上不会查看 helper_file
的内容。当某个工作进程尝试反序列化 use_f
时,该工作进程将导入 helper_file
。这种额外的间接寻址似乎使 cloudpickle 的工作更加可靠。这与使用 tensorflow 或任何库 pickle 函数时发生的事情相同。 Cloudpickle 不会序列化整个库,它只是告诉反序列化进程导入相关库。
注意:为了在多台机器上工作,helper_file.py
必须存在并且在每台机器上的 Python 路径上(一种方法来完成这是通过将其作为 Python 模块安装在每台机器上)。
我确认这似乎可以解决您示例中的问题。修复后,我 运行 进入
File "<ipython-input-4-bb51dc74442c>", line 3, in play
File "/Users/rkn/Workspace/ray/helper_file.py", line 15, in play
action = actor.predict_classes(obs).flatten()[0]
AttributeError: 'NoneType' object has no attribute 'predict_classes'
但这看起来像是一个单独的问题。
查看 GitHub 对此问题的回复:https://github.com/ray-project/ray/issues/5614
所有需要做的就是在函数定义中导入tensorflow:
@ray.remote
def play(weights):
import tensorflow as tf
actor = tf.keras.Sequential([
tf.keras.layers.Dense(64, input_shape=(24,), activation='relu'),
tf.keras.layers.Dense(4, activation='softmax')
])
actor.set_weights(weights)
env = gym.make('BipedalWalker-v2').env
env._max_episode_steps=1e20
obs = env.reset()
for _ in range(1200):
action = actor.predict_classes(np.array([obs])).flatten()[0]
action = env.action_space.sample()
obs, rt, done, info = env.step(action)
return rt
系统信息
OS 平台和分发(例如,Linux Ubuntu 16.04):Ubuntu 18.04
Ray 安装自(源或二进制):二进制
射线版本:0.7.3
Python版本:3.7
Tensorflow版本:tensorflow-gpu 2.0.0rc0
要重现的确切命令:
# Importing packages
from time import time
import gym
import tensorflow as tf
import ray
# Creating our initial model
model = tf.keras.Sequential([
tf.keras.layers.Dense(64, input_shape=(24,), activation='relu'),
tf.keras.layers.Dense(4, activation='softmax')
])
# Setting parameters
episodes = 64
env_name = 'BipedalWalker-v2'
# Initializing ray
ray.init(num_cpus=8, num_gpus=1)
# Creating our ray function
@ray.remote
def play(weights):
actor = tf.keras.Sequential([
tf.keras.layers.Dense(64, input_shape=(24,), activation='relu'),
tf.keras.layers.Dense(4, activation='softmax')
])
actor = actor.set_weights(weights)
env = gym.make('BipedalWalker-v2').env
env._max_episode_steps=1e20
obs = env.reset()
for _ in range(1200):
action = actor.predict_classes(obs).flatten()[0]
action = env.action_space.sample()
obs, rt, done, info = env.step(action)
return rt
# Testing ray
start = time()
weights = model.get_weights()
weights = ray.put(weights)
results = ray.get([play.remote(weights) for i in range(episodes)])
ray.shutdown()
print('Ray done after:',time()-start)
描述问题
我正在尝试使用 Ray 并行化使用 Tensorflow 2.0-gpu Keras actor 的 OpenAI 健身房环境的推出。每次我尝试使用 @ray.remote 实例化 Keras 模型时,它都会引发递归深度达到错误。我正在关注 Ray 概述的文档,其中建议传递权重而不是模型。我不确定我在这里做错了什么,有什么想法吗?
源代码/日志
文件“/home/jacob/anaconda3/envs/tf-2.0-gpu/lib/python3.7/site-packages/tensorflow/init.py”,第 50 行,在 getattr 中 模块 = self._load()
文件“/home/jacob/anaconda3/envs/tf-2.0-gpu/lib/python3.7/site-packages/tensorflow/init.py”,第 44 行,在 _load 模块 = _importlib.import_module(self.name)
递归错误:超过最大递归深度
核心问题似乎是 cloudpickle(Ray 用来序列化远程函数并将它们传送到工作进程)无法 pickle tf.keras.Sequential
class。例如,我可以重现问题如下
import cloudpickle # cloudpickle.__version__ == '1.2.1'
import tensorflow as tf # tf.__version__ == '2.0.0-rc0'
def f():
tf.keras.Sequential
cloudpickle.loads(cloudpickle.dumps(f)) # This fails.
最后一行失败
---------------------------------------------------------------------------
RecursionError Traceback (most recent call last)
<ipython-input-23-25cc307e6227> in <module>
----> 1 cloudpickle.loads(cloudpickle.dumps(f))
~/anaconda3/lib/python3.6/site-packages/tensorflow/__init__.py in __getattr__(self, item)
48
49 def __getattr__(self, item):
---> 50 module = self._load()
51 return getattr(module, item)
52
~/anaconda3/lib/python3.6/site-packages/tensorflow/__init__.py in _load(self)
42 def _load(self):
43 """Import the target module and insert it into the parent's namespace."""
---> 44 module = _importlib.import_module(self.__name__)
45 self._parent_module_globals[self._local_name] = module
46 self.__dict__.update(module.__dict__)
... last 2 frames repeated, from the frame below ...
~/anaconda3/lib/python3.6/site-packages/tensorflow/__init__.py in __getattr__(self, item)
48
49 def __getattr__(self, item):
---> 50 module = self._load()
51 return getattr(module, item)
52
RecursionError: maximum recursion depth exceeded while calling a Python object
有趣的是,这个 成功 tensorflow==1.14.0
,但我想 keras 在 2.0 中已经改变了很多。
解决方法
作为 解决方法,您可以尝试在单独的模块或 Python 文件中定义 f
,例如
# helper_file.py
import tensorflow as tf
def f():
tf.keras.Sequential
然后在您的主脚本中使用它,如下所示。
import helper_file
import ray
ray.init(num_cpus=1)
@ray.remote
def use_f():
helper_file.f()
ray.get(use_f.remote())
这里的区别在于,当 cloudpickle 尝试序列化 use_f
时,它实际上不会查看 helper_file
的内容。当某个工作进程尝试反序列化 use_f
时,该工作进程将导入 helper_file
。这种额外的间接寻址似乎使 cloudpickle 的工作更加可靠。这与使用 tensorflow 或任何库 pickle 函数时发生的事情相同。 Cloudpickle 不会序列化整个库,它只是告诉反序列化进程导入相关库。
注意:为了在多台机器上工作,helper_file.py
必须存在并且在每台机器上的 Python 路径上(一种方法来完成这是通过将其作为 Python 模块安装在每台机器上)。
我确认这似乎可以解决您示例中的问题。修复后,我 运行 进入
File "<ipython-input-4-bb51dc74442c>", line 3, in play
File "/Users/rkn/Workspace/ray/helper_file.py", line 15, in play
action = actor.predict_classes(obs).flatten()[0]
AttributeError: 'NoneType' object has no attribute 'predict_classes'
但这看起来像是一个单独的问题。
查看 GitHub 对此问题的回复:https://github.com/ray-project/ray/issues/5614
所有需要做的就是在函数定义中导入tensorflow:
@ray.remote
def play(weights):
import tensorflow as tf
actor = tf.keras.Sequential([
tf.keras.layers.Dense(64, input_shape=(24,), activation='relu'),
tf.keras.layers.Dense(4, activation='softmax')
])
actor.set_weights(weights)
env = gym.make('BipedalWalker-v2').env
env._max_episode_steps=1e20
obs = env.reset()
for _ in range(1200):
action = actor.predict_classes(np.array([obs])).flatten()[0]
action = env.action_space.sample()
obs, rt, done, info = env.step(action)
return rt