序列化射线未来并稍后返回结果

Serialising a ray future and returning the results later

我将 Ray 包裹在网 API 中(使用 ray start --head 和 uvicorn ray.init)。现在我正在尝试:

  1. 向 Ray 提交工作(通过 API)并将未来和 return 序列化给用户
  2. 稍后,让用户点击 API 以查看任务是否完成以及 return 结果

问题在于,作为多线程,我无法保证下一次调用将来自同一线程。这是我天真地会工作的方法:

id = my_function.remote()
id_hex = id.hex()

然后在另一个request/invocation:

id = ray._raylet.ObjectID(binascii.unhexlify(id_hex))
ray.get(id)

现在这永远不会完成(它超时),即使我知道未来已经完成并且如果我 运行 它与原始请求在同一个线程中,代码就可以工作。

我猜这与使用 Ray 的另一个初始化有关。

有没有办法强制 Ray "refresh" 来自 Redis 的期货结果?

不支持将射线未来序列化为带外字符串,然后反序列化。这样做的原因是因为这些期货不仅仅是 ID,它们在各种系统组件中有很多与之关联的状态。

要支持这种 API,您可以做的一件事是让 actor 管理这些任务的生命周期。启动任务时,将其 ObjectID 传递给参与者。然后,当用户点击端点以检查它是否完成时,它会 ping 查找相应 ObjectID 并在其上调用 ray.wait() 的 actor。

由于 Ray 的引用计数/优化机制,以您的方式直接获取 objectID 可能会导致意外行为。一项建议是使用 "detached actor"。您可以创建一个分离的演员并在其中委托调用。分离的演员将在雷的一生中存活(除非你杀死它),所以你不需要担心你提到的问题。是的。它可能会使程序变慢一点,因为它需要 2 个跃点,但我想这种开销对您的工作负载(客户端提交模型)无关紧要。

https://docs.ray.io/en/latest/advanced.html?highlight=detached#detached-actors

ray.remote
class TaskInvocator:
    def __init__(self):
        self.futures = {}
    def your_function(self):
        object_id = real_function.remote()
        self.futures[object_id.hex()] = object_id
    def get_result(self, hex_object_id):
        return ray.get(self.futures[hex_object_id])

TaskInvocator.remote(detached=True, name='invocator-1')
task_invocator = ray.util.get_actor('invocator-1')
object_id = task_invocator.your_function.remote()
blah blah...
result = ray.get(task_invocator.get_result.remote(object_id.hex()))