反模式:闭包捕获大对象会损害性能
Contents
反模式:闭包捕获大对象会损害性能#
TLDR: 避免在远程函数或类中使用闭包捕获大对象,而是使用对象存储。
当定义一个 ray.remote 函数或类时,
很容易意外地在定义中隐式捕获大型(超过几 MB)对象。
这可能会导致性能下降甚至 OOM,因为 Ray 并非设计用于处理非常大的序列化函数或类。
对于如此大的对象,有两种方法可以解决这个问题:
使用
ray.put来将大对象放入 Ray 对象存储中,然后将对象引用作为参数传递给远程函数或类(下面的 “更好的方法 #1”)在远程函数或类中创建大对象,通过 lambda 方法传递(下面的 “更好的方法 #2”)。这也是使用不可序列化对象的唯一选项。
代码示例#
反模式
import ray
import numpy as np
ray.init()
large_object = np.zeros(10 * 1024 * 1024)
@ray.remote
def f1():
return len(large_object) # large_object is serialized along with f1!
ray.get(f1.remote())
更好的方法 #1:
large_object_ref = ray.put(np.zeros(10 * 1024 * 1024))
@ray.remote
def f2(large_object):
return len(large_object)
# Large object is passed through object store.
ray.get(f2.remote(large_object_ref))
更好的方法 #2:
large_object_creator = lambda: np.zeros(10 * 1024 * 1024) # noqa E731
@ray.remote
def f3():
large_object = (
large_object_creator()
) # Lambda is small compared with the large object.
return len(large_object)
ray.get(f3.remote())