You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Ray中ObjectRef被自动收集并反序列化的异常原因咨询

Ray中ObjectRef被自动收集并反序列化的异常原因咨询

看起来你遇到的问题核心是不小心调用了两次buffer.add.remote,导致add方法被执行了两次,其中第二次的参数已经是反序列化后的numpy数组,而非ObjectRef,从而触发了ray.get的报错。我们来一步步拆解原因:

问题根源分析

先看你的循环代码:

while sp_refs:
     complete, sp_refs = ray.wait(sp_refs)
     print(f"{complete=}")
     buffer.add.remote(complete)  # 这里是多余的调用!
     for r in complete:
         buffer_refs.append(buffer.add.remote(r))

你在这里做了重复操作:

  • 第一行buffer.add.remote(complete):把整个已完成的ObjectRef列表传给了add方法
  • 随后循环complete里的每个r,调用buffer.add.remote(r):把单个ObjectRef传给add方法

这直接导致add方法被执行两次,对应两种不同的参数情况:

  1. 第一次调用:参数是ObjectRef列表
    • 你在add里调用ray.get(experience),会批量获取列表中所有ObjectRef的值,得到numpy数组的列表,这和你输出里的第一次打印结果完全吻合。
  2. 第二次调用:参数本应是单个ObjectRef,但实际变成了numpy数组
    • 当你第一次调用ray.get(complete)时,已经获取了这些ObjectRef对应的numpy数组。结合Ray Actor的执行逻辑,第二次传递同一个ObjectRef时,会自动传递已解析的值而非引用(虽然Ray的ObjectRef设计上支持重复使用,但你的代码执行顺序触发了自动解包)。
    • 此时add方法接收的是已经反序列化的numpy数组,再调用ray.get(experience)自然会报错——因为ray.get只接受ObjectRef或ObjectRef列表,不接受numpy数组。

解决方案

只需要去掉那行多余的buffer.add.remote(complete)即可,修改后的循环代码:

while sp_refs:
     complete, sp_refs = ray.wait(sp_refs)
     print(f"{complete=}")
     # 移除多余的批量调用
     for r in complete:
         buffer_refs.append(buffer.add.remote(r))

这样add方法只会被调用一次,每次接收单个ObjectRef,调用ray.get(experience)就能正确获取到numpy数组了。

另外,建议你调整add方法的参数类型标注,如果以后可能需要处理列表,可以改成Union[ray.ObjectRef, List[ray.ObjectRef]],避免类型混淆带来的问题。

备注:内容来源于stack exchange,提问作者Vaas

火山引擎 最新活动