夜雨聆风学习资料网

ARTICLE · 1235632

每日AI开源项目推荐 #65:Ray —— 大模型时代的分布式计算底座,Open 都在用

每日AI开源项目推荐 #65:Ray —— 大模型时代的分布式计算底座,Open 都在用

一、为什么值得单独写一期

如果说这个系列前面几期聊的是"模型怎么训、怎么调",那这一期要回答一个更底层的问题:算力怎么调度。当你手里的任务从"一张卡跑个脚本"变成"几百个超参组合并行搜索""PB 级数据预处理""几千路并发模型推理",单机 Python 就到头了——而 Ray 就是为这一步而生的。

截至 2026-10-09,ray-project/ray 在 GitHub 拿到 43,995 Star,Apache-2.0 协议,主仓库当天仍有提交。它出身 UC Berkeley RISELab(就是孵化了 Spark 的那个实验室),创始团队后来成立了 Anyscale 商业化公司。OpenAI 训练 GPT 系列用的就是 Ray,Uber、Spotify、蚂蚁、字节跳动也都是公开的大规模用户——vLLM 的多机推理、大部分主流 RLHF 框架的底层调度,都能看到 Ray 的影子。

值得单独写一期的核心理由:Ray 把"分布式"这件事的门槛压到了不可思议的低——同一个 Python 函数,加一个装饰器就能从笔记本扩展到上千台机器的集群,不需要学 Kubernetes YAML,不需要改代码结构。而且它不只是计算引擎,上层的 Data、Train、Tune、RLlib、Serve 五个 AI 库覆盖了机器学习从数据到上线的全生命周期,是事实上的"AI 分布式操作系统"。

二、Ray Core:三个原语撑起分布式世界

Ray 的设计哲学是"少即是多"。整个 Ray Core 只给你三个抽象:

  • Task(任务)
    :无状态的远程函数。普通 Python 函数加 @ray.remote,调用时换成 .remote(),它就被调度到集群任意节点执行,返回一个 future(Ray 叫 ObjectRef)。
  • Actor(演员)
    :有状态的远程类。实例化一个 Actor,Ray 会在集群里起一个专属 worker 进程,方法调用串行执行、状态在多次调用间保持——这是封装模型实例、环境模拟器、有状态服务的标准姿势。
  • Object(对象)
    :分布式对象存储里的不可变值。任务返回值自动入库存成引用,也可以 ray.put() 显式放入;引用在任务间传递时走共享内存,大数组零拷贝,不经过 Python 序列化的性能税。

这三个原语看起来简单,但组合起来可以表达几乎任何分布式计算模式:并行流水线、参数服务器、MapReduce、树搜索、联邦学习……官方的说法是 "general-purpose",实际用下来确实名副其实。

三、代码实战(一):函数变任务,类变 Actor

安装就是 pip install -U ray,然后 ray.init() 初始化(不显式调用的话,第一次用 remote API 会自动初始化)。下面两段代码全部取自官方 Ray Core walkthrough:

import ray  ray.init()  # 定义一个远程任务 @ray.remote def square(x):     return x * x  # 并行发起 4 个任务 futures = [square.remote(i) for i in range(4)]  # 取回结果 print(ray.get(futures)) # -> [0, 1, 4, 9]  # 定义一个有状态的 Actor @ray.remote class Counter:     def __init__(self):         self.i = 0      def get(self):         return self.i      def incr(self, value):         self.i += value  # 在集群某处创建一个 Counter 实例 c = Counter.remote()  # 异步提交 10 次调用,按提交顺序在远端串行执行 for _ in range(10):     c.incr.remote(1)  print(ray.get(c.get.remote())) # -> 10

注意这段代码里没有任何"集群"的痕迹——在本机跑就是多进程并行,把 ray.init() 换成 ray.init(address="ray://集群头节点:10001"),同样的代码立刻跑在几百台机器上。这种"笔记本到集群零改动"的体验,是 Ray 区别于其他分布式框架的灵魂。

四、代码实战(二):大对象零拷贝传递

分布式计算真正的性能杀手往往不是算力,而是数据搬运。Ray 的分布式对象存储(基于 Plasma 共享内存)专门解决这个问题:

import numpy as np  @ray.remote def sum_matrix(matrix):     return np.sum(matrix)  # 方式一:字面量参数,Ray 自动序列化传入 print(ray.get(sum_matrix.remote(np.ones((100, 100))))) # -> 10000.0  # 方式二:大数组显式放进对象存储,只传引用 matrix_ref = ray.put(np.ones((1000, 1000)))  print(ray.get(sum_matrix.remote(matrix_ref))) # -> 1000000.0

关键在第二种方式:ray.put() 把大数组放进共享内存对象存储后,后续无论多少个任务引用它,都是传一个轻量的 ObjectRef,同节点任务直接共享内存读取,不发生拷贝。对参数服务器、批量推理这类"一份数据喂多个 worker"的模式,这是数量级的性能差异。2026 年的新版本还实验性引入了 Ray Direct Transport,支持用 GLOO/NCCL/NIXL 直接做 GPU 间对象传输,大模型张量并行场景收益明显。

五、AI Libraries:从数据到上线的全家桶

Ray Core 之上,官方维护了五个面向 ML 场景的库,共用同一套集群调度:

  • Ray Data
    :可扩展的数据集加载与预处理,流式执行、自动分片,常用来给多机训练喂数据,也支撑大规模离线批量推理。
  • Ray Train
    :分布式训练封装,PyTorch DDP、DeepSpeed、FSDP、XGBoost 都有现成集成,几行代码把单机训练脚本变成多机多卡。
  • Ray Tune
    :超参搜索,支持 Optuna、HyperOpt、贝叶斯优化等后端,上百组实验自动调度到集群并行跑,带早停和断点续跑。
  • RLlib
    :强化学习库,PPO、DQN、IMPALA 等算法开箱即用,OpenAI 早年打 Dota 的同类工作负载就是它的主场。
  • Ray Serve
    :模型在线服务,支持自动扩缩、多模型组合、请求批处理,写法和写普通 Python 类几乎一样。

重点是这五个库可以混搭:用 Ray Data 预处理、Train 训练、Tune 调参、Serve 上线,数据在它们之间通过对象存储流转,全链路不需要落地磁盘。这就是"AI 操作系统"说法的由来。

六、代码实战(三):Ray Serve 把模型变成 HTTP 服务

以下示例取自官方 Ray Serve 快速开始:把一个 T5 英译法模型部署成 HTTP 服务。num_replicas=2 声明两个副本,CPU 配额可以精确到 0.2 核——资源粒度之细,是 Ray 区别于 K8s 原生部署的一大特色:

# 文件名: serve_quickstart.py from starlette.requests import Request import ray from ray import serve from transformers import AutoModelForSeq2SeqLM, AutoTokenizer  @serve.deployment(num_replicas=2,                   ray_actor_options={"num_cpus": 0.2, "num_gpus": 0}) class Translator:     def __init__(self):         self.tokenizer = AutoTokenizer.from_pretrained("t5-small")         self.model = AutoModelForSeq2SeqLM.from_pretrained("t5-small")      def translate(self, text: str) -> str:         input_ids = self.tokenizer(             f"translate English to French: {text}",             return_tensors="pt").input_ids         output_ids = self.model.generate(             input_ids, num_beams=4, early_stopping=True, max_length=300)         return self.tokenizer.decode(             output_ids[0], skip_special_tokens=True)      async def __call__(self, http_request: Request) -> str:         english_text: str = await http_request.json()         return self.translate(english_text)  translator_app = Translator.bind()

启动只需要一条命令 serve run serve_quickstart:translator_app,服务默认监听 http://127.0.0.1:8000/,用 requests POST 一段英文就能拿到法语翻译。更进一步,多个 deployment 可以通过 DeploymentHandle 组合成"先摘要、再翻译"这种模型流水线,每个环节独立扩缩容——这套组合式设计在生产环境里比单体推理服务灵活得多。

七、和同类方案怎么选

维度
Ray
Dask
Celery
Spark
定位
通用 AI 分布式运行时
并行 Python 计算(偏数据科学)
异步任务队列
大数据批处理
编程模型
Task + Actor + 对象存储
任务图 / 类 Pandas API
消息队列 + worker
RDD/DataFrame
GPU 支持
一等公民(分数 GPU、NCCL 传输)
支持(RAPIDS)
无专门支持
有限
ML 全生命周期
Data/Train/Tune/RL/Serve 全覆盖
偏数据处理与训练
仅任务分发
MLlib 偏传统算法
典型用户
OpenAI、Uber、蚂蚁、字节
数据科学团队
Web 后端团队
大数据平台团队

一句话:数据处理为主选 Dask 或 Spark,Web 异步任务选 Celery,而只要是"大模型时代的训练/推理/强化学习要规模化",Ray 目前几乎没有对手——vLLM、SGLang、DeepSpeed 这些当红项目都原生支持或构建在 Ray 之上,生态飞轮已经形成。

八、注意事项与总结

  • 小任务别硬上
    :Ray 的价值在"单机装不下",单机多进程能解决的场景,multiprocessing 更轻。
  • 调试有学习成本
    :分布式报错栈横跨多个 worker,好在官方提供了 Ray Dashboard 和分布式调试器,排查前先学会看 Dashboard。
  • Windows 支持有限
    :生产集群基本都是 Linux;Windows 下单机开发可用,但部分功能(如部分对象存储特性)受限。
  • 集群运维
    :自建推荐 KubeRay(K8s Operator),不想运维就用 Anyscale 托管版。

总结:Ray 用三个原语(Task、Actor、Object)把分布式编程的复杂度藏在了优雅 API 后面,再用五个 AI 库把机器学习的全生命周期串成一条线。对个人开发者,它是"笔记本代码平滑上云"的最短路径;对团队,它是大模型基础设施的事实标准之一。项目地址:github.com/ray-project/ray,文档 docs.ray.io 的 walkthrough 一小时就能读完,强烈建议动手跑一遍。

相关学习资料