Python ray 的分布式计算 Python API

2次阅读

ray.init()失败主因是localhost与集群模式混用,需清理残留进程、明确指定local_mode或address;remote函数禁用未序列化对象;actor初始化异常需用__ray_ready__检测。

Python ray 的分布式计算 Python API

ray.init() 启动失败:localhost 模式和集群模式不能混用

本地开发时直接调用 ray.init() 默认走 localhost 模式,但如果你之前手动启过 ray start --head,或者环境变量里残留了 RAY_ADDRESS,就会报 ConnectionError: Failed to connect to Ray instance 或静默失败。

  • 先清掉干扰项:ray stop(别信输出,再跑一遍 ps aux | grep ray 确认没残留进程)
  • 明确指定模式:ray.init(local_mode=True) 仅用于单进程调试(所有 actor/task 都不真正分布式);生产级本地测试用 ray.init(num_cpus=4) 即可,它会自动起轻量 head node
  • 远程集群必须显式传地址:ray.init(address="ray://10.0.1.5:10001"),且服务端得用 ray start --head --port=10001 启,端口不匹配是高频卡点

@ray.remote 函数里不能直接用未序列化的对象

比如你在函数里写了 pd.read_csv("data.csv"),看起来没问题,但一旦放到 remote 函数里,Ray 会在 worker 进程反序列化执行——而 worker 根本没加载 pandas,也没这个文件路径。错误现象通常是 ModuleNotFoundErrorFileNotFoundError还藏在 worker 日志里,主进程只报 timeout。

  • 所有依赖包必须在每个 worker 上安装一致(推荐用 pip install -r requirements.txt 预装,别靠 runtime_env 动态传,慢且易错)
  • 文件路径别写死,用 ray.get_runtime_context().get_job_id() 或传入绝对路径参数;更稳妥的是把数据提前放进 ray.put() 或用 ray.data 加载
  • 类实例、数据库连接、文件句柄这类非 pickleable 对象,一律禁止出现在 remote 函数作用域内——它们不会被复制,只会让任务永远卡住

ray.get() 调用阻塞太久?检查是不是忘了 .remote()

result = my_func.remote() 返回的是 ObjectRefray.get(result) 才真正取值;但新手常写成 result = my_func()(没加 .remote),结果变成同步调用,Ray 根本没参与,后续 ray.get() 就等一个不存在的 ref,超时后抛 ValueError: Expected an ObjectRef, got ...

  • ide 的类型提示:pycharm / VS Code 装好 ray 插件后,my_func() 会标黄,提示“Expected @ray.remote decorated function
  • 批量提交任务时别嵌套 ray.get()[ray.get(f.remote()) for f in funcs] 是串行的,要改成 refs = [f.remote() for f in funcs]; ray.get(refs)
  • 大对象传输慢?ray.get() 本身不压缩,如果返回几 GB 的 numpy Array,网络和反序列化都吃资源,考虑用 ray.put() + 引用传递,或改用 ray.data 流式处理

Actor 创建后无法调用方法:__init__ 报错会被吞掉

定义 Actor 类时,如果 __init__ 里有异常(比如连不上 redis、读配置失败),Ray 不会立刻抛出,而是等你第一次调用 actor.method.remote() 时才报 ActorDiedError,根本看不到原始错误。日志里可能只有 “The actor died unexpectedly before finishing this task”。

立即学习Python免费学习笔记(深入)”;

  • 强制触发初始化:创建后立刻 ray.get(actor.__ray_ready__.remote())(这是 Ray 内置的健康检查方法)
  • __init__ 开头加 print()Logging.info(),并确保 worker 日志能被收集(启动时加 --log-level=INFO
  • Actor 方法调用超时默认 30 秒,但初始化失败是另一回事;别盲目加大 timeout 参数,先确认是不是构造函数逻辑卡死

Ray 的坑不在 API 多难记,而在它把“分布”这件事藏得太深——本地跑通不等于分布式能跑,worker 环境和 driver 环境从来不是一回事,任何跨进程的东西,都得当成黑盒重新验证。

text=ZqhQzanResources