ray教程-00-前言与导读

1 阅读20分钟

仓库地址:github.com/hhk-png/cyc…

欢迎。这份教程的目标是让你真正懂 Ray —— 不只是会写 @ray.remote, 而是知道它内部发生了什么、为什么这么设计、边界在哪、以及 2026 年它正走向哪里。 配套还有一个 1.1 万行、可运行、有 192 个测试的简化实现(mini-ray), 把书里的每个机制都亲手写了一遍。


0.1 这是一份什么样的教程

Ray 是当下最主流的分布式计算框架之一。但关于它的中文资料,常见的有两类:

  • 入门文章:讲 ray.init() / @ray.remote / ray.get 三件套,跑通一个 demo 就结束;
  • 源码分析:直接扎进 C++ 的 raylet 与 GCS,读起来门槛极高。

这两类之间有一大片空白:「机制到底是怎么运作的、设计取舍是什么、 为什么我的任务不跑、内存为什么下不去」 —— 这恰好是实际工作中最需要的东西。

这份教程瞄准的就是这片空白。它有三个特点:

特点一:机制讲到能排查问题的深度

不是"Ray 用对象存储",而是:

  • 对象存储多大、在哪(/dev/shm 还是 /tmp)、什么时候溢出、溢出参数是什么;
  • 对象什么时候被回收(引用计数归零后批量上报释放,不是瞬时)、pin 的语义、owner 死了会怎样;
  • 一个任务的状态机(Ray 有 14 个状态枚举)分别意味着什么、卡在每个状态该查什么;
  • 调度是两层 + 租约、策略家族有哪几种、放置组为什么能避免死锁。

每个机制都配了「出问题时怎么查」,第 11 章还有一份按症状索引的排查手册。

特点二:配套一个真的能跑的简化实现

ray-toturial/mini-ray/ 是一个用纯 Python 标准库 + NumPy 写的 Ray 简化版: 任务调度、共享内存零拷贝对象存储、Actor(含并发组与 async)、 lineage 重建、放置组、State API、timeline、分布式队列 util.queue.Queue、 自定义指标 util.metrics —— 全都有,192 个测试全部通过。

ray-toturial/mini-ray/
├── miniray/              # 25 个顶层模块(含子包共 35 个文件)、1.15 万行
├── tests/                # 192 个测试
└── examples/             # 12 个可运行示例(对应各章)

为什么值得读一个简化实现? 因为 Ray 真正的难点不在分布式算法, 而在边界约定:pickle 的写入顺序、模块属性被装饰器替换、 multiprocessing 的 spawn 会重新 import 用户脚本、参数名冲突导致超时语义错位…… 这些东西论文和文档都不会写。第 6 章有一节「踩过的 12 个坑」, 每个坑都来自真实调试过程。

特点三:事实有来源,不确定就明说

教程里的版本号、默认值、行为描述都尽量标注来源(release notes、官方文档页、 issue/PR 编号)。查不到的一律写"未确认",并且把 「已发生的事实」「官方路线图」「我的判断」严格分开(见第 20 章)。

这一点在 2026 年尤其重要 —— Ray 的生态位置正在变化 (vLLM 正在把 Ray 从执行引擎降级为放置层), 网上有大量过时或想当然的说法。


0.2 怎么读这份教程

六条路径,按你的目标选:

你的目标推荐路径预计时间
快速用起来01 → 04 → 05 → 12/13/15半天
搞懂原理01 → 02 → 03 → 06 → 07–112–3 天
上生产01 → 04 → 17 → 18 → 19(配合 11)1–2 天
做技术选型01 → 19 → 202 小时
做 LLM 微调/推理01 → 04 → 29 → 30 → 13 → 311–2 天
做 Agent / LLM 应用01 → 04 → 15 → 37 → 381 天
性能出问题31 → 18 → 11 → 30(GPU 时)半天

如果只读三章:第 6 章(从零实现)、第 8 章(调度)、第 18 章(反模式)。

读第 6 章的正确方式:不要只看文字 —— 把 mini-ray/tests/ 跑一遍, 再把 examples/ 跑一遍,然后挑一个模块(建议从 object_store.py 或 scheduler.py 开始)精读。1.1 万行不算多,但足够让你把"会用"变成"懂"。

加粗提醒:第 29–38 章都没有 mini-ray 对照实现 —— 它们讲的是 GPU、NCCL、HuggingFace / GBDT 生态、剖析工具、 MLOps、分布式追踪、LLM 推理引擎与 Agent 工作负载,这些都超出 「纯 Python + NumPy」能演示的范围。 这是设计取舍,不是遗漏(第 29 章起每章末尾都有一节说明「与 mini-ray 的关系」; 第 38 章 §38.13 把这条讲得最直白:有些能力不是 mini-ray 做不到, 而是它本来就不该做)。 第 26–28 章(Compiled Graph / runtime_env / CI-CD)则是另一回事: 它们没有「与 mini-ray 的关系」小节,只在正文里点到为止 (mini-ray 确实没有编译图,但它的对象存储与依赖索引可以直接类比 —— 见第 26 章 §26.9)。


0.3 前置知识

需要:

  • Python 能写(函数、类、装饰器、异常、with);
  • 知道进程/线程的区别,听说过"序列化"(pickle);
  • 会在命令行里跑 pip install 和 python xxx.py。

不需要:

  • 分布式系统背景(需要的部分第 3 章会补);
  • Ray 使用经验(第 1、2 章从零讲);
  • GPU / Kubernetes(涉及的地方会标注,不要求动手)。

环境建议:任何装了 Python ≥ 3.10 的机器。mini-ray 只需要 NumPy, 在笔记本上就能跑完全部示例与测试。


0.4 章节地图

第 1 部分  概念与架构
  01 认识 Ray ................. 是什么、为什么、生态全景、2026 年的现状
  02 核心概念与 API ........... 任务/对象/Actor/ObjectRef/依赖/资源/错误模型
  03 架构设计 ................. GCS、raylet、core worker、对象存储、调度、数据面

第 2 部分  动手
  04 快速上手 ................. 安装、起集群、第一个程序、五个迁移套路、Jobs API
  05 任务、对象与依赖(深入) ... 生命周期状态机、序列化代价、引用计数与泄漏

第 3 部分  从零实现
  06 从零实现简化版 Ray ........ mini-ray 走读 + 踩过的 12 个坑 + 验证矩阵

第 4 部分  深入机制
  07 对象存储与内存管理 ........ 容量/位置/零拷贝/pin/溢出/四类内存事故
  08 调度与资源模型 ............ 资源语义、两层调度、策略家族、放置组、排查表
  09 Actor 模型与并发 .......... 邮箱、三种并发模型、async、五个经典模式、四个反模式
  10 容错机制 ................. 重试、崩溃恢复、lineage 重建、检查点、故障注入
  11 可观测性与调试 ............ State API、Dashboard、日志、指标、timeline、排查手册

第 5 部分  AI 库
  12 Ray Data 与数据管道 ....... 流式执行、背压、DataSourceV2、Data LLM
  13 Ray Train 与分布式训练 .... Train V2、并行策略、checkpoint 恢复、vs torchrun
  14 Ray Tune 与超参搜索 ....... Tuner、采样器、ASHA、成本控制
  15 Ray Serve 与 LLM 服务 ..... 部署/扩缩/路由、Serve LLM、PD 分离、KV 路由
  16 RLlib 与强化学习 .......... 新 API stack、RL 生态地图(verl/SkyRL/OpenRLHF)

第 6 部分  工程实践
  17 生产部署与安全 ............ KubeRay、自动扩缩、可观测性接入、CVE 与加固清单
  18 性能调优与反模式 .......... 10 条反模式、内存/调度/序列化调优、实测模板
  19 生态对比与选型 ............ vs Spark/Dask/torchrun/Monarch/K8s,决策树

第 7 部分  展望与附录
  20 现状与未来方向 ............ 三条主线、路线图、竞争格局、批评与回应、趋势判断
  21 附录 A:API 速查表 ........ 全 API + **mini-ray 对照列**
  22 附录 B:mini-ray 工程手册 .. API 参考、数据约定、配置、验证矩阵、练习
  23 附录 C:术语表 ............ 约 200 条术语,分主题 + 索引
  24 附录 D:FAQ 与排错 ........ 按症状组织的 Q/A
  25 附录 E:端到端实战案例 .... 数据→推理→训练→服务→观测→容错 全流程

第 8 部分  补齐的三块(第一轮修订新增)
  26 Ray Compiled Graph 与 DAG API ... bind()/InputNode、experimental_compile()、
                                      通道数据面、多 GPU 通信、与普通任务的分工
  27 附录 F:Ray Client、runtime_env 与多语言
                                    依赖怎么送到集群、ray:// 还能不能用、Java/C++
  28 附录 G:CI/CD、Slurm 与云上调度
                                    集群形状的测试、Ray on Slurm、成本模型、编排集成

第 9 部分  生态、GPU 与工具链(第二轮修订新增)
  29 Ray 与 PyTorch / HuggingFace 生态集成
                                    HF Datasets 互转、HF Trainer 接 Ray、
                                    LoRA/QLoRA 分布式微调、三层边界
  30 GPU 编程、集合通信与显存管理
                                    CUDA_VISIBLE_DEVICES 语义、分数 GPU、
                                    NCCL 排查顺序、四种 OOM、多机拓扑
  31 性能剖析与调试工具链
                                    py-spy / memray / nsys / timeline、
                                    火焰图怎么读、一条完整的定位路径

第 10 部分  收口(第三、第四轮修订新增)
  32 实验追踪与 MLOps 集成 ........ MLflow / W&B / TensorBoard、
                                    RunConfig(callbacks=)、checkpoint 之后的事
  33 Ray CLI 全集与交互式开发 ..... CLI 四套体系速查、Notebook 工作流、
                                    按现象查命令的定位流程图(§33.9)
  34 表格数据与传统 ML ............ XGBoost / LightGBM / scikit-learn、
                                    Ray Train 的 GBDT 路径、零改造上分布式
  35 数据版本、产物血缘与模型注册 ... DVC / 数据指纹 / Model Registry、
                                    接着第 32 章"registry 是你的事"往下讲
  36 分布式追踪与 OpenTelemetry ... 跨 actor 的一条请求怎么追、
                                    补上第 11 章四层观测模型里空的"追踪"那一层

第 11 部分  推理引擎那一层(第六轮修订新增)
  37 LLM 推理引擎与性能优化 ....... 编排层 vs 引擎层、TTFT/TPOT 四指标、
                                    continuous batching、KV cache 与 PagedAttention、
                                    prefix caching、chunked prefill、投机解码、
                                    量化、CUDA Graph、TP/PP/DP 选型、
                                    引擎全景与分离式服务(§37.15)

第 12 部分  Agent 工作负载(第七轮修订新增)
  38 Ray 与 Agent 工作负载 ........ Agent 负载的五个特征、三层分工(编排/运行时/引擎)、
                                    会话亲和性的真实边界(session_id 管道 vs 默认 Pow2)、
                                    会话状态四种放法、工具沙箱与超时取消、
                                    OTel GenAI 语义约定、轨迹数据、agentic RL、成本

第 13 部分  核查方法(第八轮修订新增,全书的收尾)
  39 Ray 源码阅读与事实核查指南 .... 三种拿到源码的办法(含 C++ 侧)、仓库地图与
                                    八个最常查的文件、五个问题走读法、
                                    证据的三个等级与"怎么证明不存在"、
                                    稳定性与弃用的判读、一份七步核查清单
                                    —— **它教的是怎么否决前面 38 章**

0.4.1 全书的结构是怎么长成这样的(以及为什么章号看起来乱)

这份教程经过八轮修订,多数轮次都在末尾追加章节,所以章号顺序不等于阅读顺序。 按"该什么时候读"重新排一遍:

层章节性质
主线(从头读到尾)00 → 20概念 → 动手 → 从零实现 → 机制 → AI 库 → 工程 → 展望
参考层(当字典翻)21 附录 A API 速查 · 22 附录 B mini-ray 手册 · 23 附录 C 术语表 · 24 附录 D FAQ 排错 · 25 附录 E 端到端案例 · 27 附录 F runtime_env 与多语言 · 28 附录 G CI/CD、Slurm 与云上调度不必通读,按需查
纵深(按需深入)26 Compiled Graph · 29 PyTorch/HF · 30 GPU · 31 剖析工具链 · 32 MLOps · 33 CLI · 34 表格数据 · 35 数据血缘 · 36 OTel · 37 推理引擎 · 38 Agent 工作负载真上手做训练/推理/调优/Agent 时再读
方法层(收尾)39 源码阅读与事实核查指南当你想核实本书某个结论、或要自己去查 Ray 的某个事实时(建议读完主线后再看)

⚠️ 为什么 26 排在附录后面:它是第一轮修订时按"补缺口"追加的, 当时没重排章号(重排会打断所有跨章引用)。 第 20 章 §20.10 有一张同样结构的表,两处口径一致。 按用途找章节比按章号找更快 —— 见下一节的"按问题找章节"。

为什么新增第 26–28 章:前 25 章已经覆盖了 Core、调度、容错、AI 库与生产实践, 但审计下来有三块系统性缺口 —— ① Compiled Graph 只在 §3.8 有半页,而它是张量并行推理的底座; ② runtime_env 与 Ray Client 只在附录 A 的表格和术语表里出现, 却是"环境送不到集群"这类问题的高发区; ③ CI/CD 与 Slurm 完全没讲,而"怎么测 Ray 应用""没有 K8s 怎么办" 是落地时最先撞到的两个问题。这三章就是补这三个洞。


0.5 代码约定

  • 示例统一用 import miniray as ray(与 Ray 同名 API), 真实 Ray 的示例用 import ray —— 从 mini-ray 迁移只需改 import;
  • 代码块都标注语言,可以直接复制运行;
  • 篇幅较长的完整实现放在 mini-ray/,正文只摘关键片段(并注明文件与函数);
  • 需要 GPU / 集群才能跑的例子会明确标注「无需运行,理解即可」。

0.6 关于事实与时效性

这份教程写作于 2026 年 9 月,Ray 的最新稳定版是 2.58.0(2026-08-23)。 为了让你能判断"这条还准不准",正文里做了三级标注:

标注含义例子
(无标注)来自官方文档/源码的确定事实"对象存储默认占可用内存的 30%"
(某版本 release notes / issue #编号)有明确一手来源"内嵌 RocksDB 自 2.57 起"
未确认检索不到可靠来源,或来源冲突"Ray 是否有独立 TSC"

第 20 章还专门把「已发生的事实 / 官方路线图 / 我的判断」分开写 —— 不要把判断当事实引用。


0.7 验证状态

本教程配套代码的验证结果(可在你机器上复现):

cd ray-toturial/mini-ray
python -m pytest tests/ -q          # 192 passed
for f in examples/*.py; do python "$f"; done    # 12 个示例全部 exit=0
项状态
测试用例192 个,全部通过(12 个测试文件,覆盖序列化/对象存储/任务/actor/调度/容错/可观测/local_mode/工具/队列与指标/第六七轮回归/第八轮回归)
示例12 个,全部可运行(含端到端流水线、故障注入演练与队列流水线)
跨进程验证零拷贝写穿、__main__ 函数跨解释器执行、lineage 重建 —— 三个"必须真跨进程"的测试
依赖Python ≥ 3.10 + NumPy(无其它第三方依赖)
环境已在 Windows 11 + Python 3.14.6 + NumPy 2.5.1 上验证
第六轮修订后重跑测试全绿(当时的 165 个用例)、示例 12/12 exit 0(记录见 mini-ray/.verify_r6_full.txt)
第七轮修订后重跑当时的 174 个用例全绿 / exit 0、示例 12/12 exit 0、结构自检 exit 0(记录见 mini-ray/.verify_r7_final.txt)
第八轮修订后重跑(本次)测试 192 passed / exit 0、示例 12/12 exit 0、结构自检 exit 0(三条命令一次跑完的记录见 mini-ray/.verify_r8_final.txt)
第二轮修订新增第 29–31 章;mini-ray 补上 util.queue.Queue 与 util.metrics;修正 40 余条事实错误(清单见 README.md)
第三轮修订新增第 32–33 章(MLOps 集成、CLI 全集);修正 90 余条事实错误
第四轮修订新增第 34–36 章(表格数据与传统 ML、数据版本与模型注册、分布式追踪与 OTel);合计改动 100 余处(事实修正 / 跨章对齐 / 内容补充),前 33 章几乎每章都有条目
第五轮修订不新增章节;80 余处修正与补齐,覆盖 00–36 全部章节。这一轮的关键词是**「回源码核对」**:配置名、默认值、异常类层次一律 curl 回 Ray 2.58.0 源码 grep,既用来确认、也用来驳回(驳回了 2 条"看起来该改、其实不该改"的建议)
第六轮修订新增第 37 章(LLM 推理引擎与性能优化);mini-ray 修掉 10 个真实缺陷(含 GPU actor 完全不可用、生成器失败导致消费端永久挂起、引用计数链路 5 轮未生效);补齐缺失的测试
第七轮修订新增第 38 章(Ray 与 Agent 工作负载);mini-ray 代码审计与四路文档审计并行;修正"加了新章之后全书收尾点全部过期"这一类由本轮改动自身引发的连锁错误(第 31/32/33/36/37 章共 8 处);补齐 tqdm_ray、ray.widgets、Delta/Hudi/Kinesis、多租户配额、非 x86 架构、第 37 章的引擎全景等缺口
第八轮修订(本次)新增第 39 章(Ray 源码阅读与事实核查指南)—— 补上全书唯一一处章节级结构缺口:本书反复宣示"回源码核对",却从未把这件事作为方法教出来;结语随之移入第 39 章。另外:mini-ray 代码审计再抓出一批真实缺陷、四路文档审计修正 30 余条事实错误(其中多条会直接 ValueError/结论说反)、check_docs.py 新增两项对"自指计数"的自动核对 —— 把连续两轮踩到的"加了新章导致收尾点过期"交给脚本拦下
文档结构自检40 篇正文章号连续(00–39)、跨章引用无悬空、本地链接可达、代码围栏闭合、表格列数一致、自指计数与实际章号一致、"结语在哪一章"指向正确。自检脚本 mini-ray/tools/check_docs.py(python tools/check_docs.py),可复现

这本书改过八轮,每一轮都印证了同一件事。

  • 第二轮补了第 26–28 章(Compiled Graph、runtime_env、CI/CD);
  • 第三轮补了第 32–33 章(MLOps、CLI),修了 90 余条事实错误;
  • 第四轮补了第 34–36 章(表格数据与传统 ML、数据版本与模型注册、 分布式追踪与 OTel),并修掉 100 余处 —— 附录层是逐行对照 mini-ray 源码核的(抓到 OwnerDiedError 标错、num_returns 字面量不同这类硬错)。
  • 第五轮不新增章节,改的全是"已有的错",并确立一条纪律: 凡"配置名、默认值、异常文案、类层次"这类能被源码定死的条目,一律回源码核对, 不靠二手摘要。这一轮靠它驳回了 2 条"看起来该改、其实不该改"的建议。
  • 第六轮新增第 37 章(LLM 推理引擎与性能优化),并第一次把审计的 重心转回代码本身 —— 四路文档审计之外加了一路 mini-ray 代码审计, 结果抓到 10 个真实缺陷,其中四个是"用户拿到错误结果或永远卡住、 却没有任何诊断信息"的那一类(详见 README.md 的「第六批修订清单」)。
  • 第七轮(本次)新增第 38 章(Agent 工作负载),并第一次遇到一类 "由本轮改动自身引发"的错误:加了新的一章之后,全书里 "全书结语在哪""后面还有几章"的说法集体过期(第 31/32/33/36/37 章共 8 处)—— 这和第四轮那次"三章各自主张自己是全书结尾"是同一个形状又发生了一次。 它还贡献了一条更硬的教训:本轮主线程在核实"某个 router 在不在 2.58.0 里"时, 只列了一个目录就下了结论,把"我没在这个目录里找到"当成了"它不存在"—— 而本书第 15 章上一轮就已经把那个类写进表里了,等于本书自己证伪了这句话 (完整记录见第 37 章 §37.15 的 ⚠️)。

而最有价值的一类发现往往不是"新知识",而是"上一轮改了正文、漏了小结" —— 第四轮修掉的最高危错误里有 6 条属于这种: 第 2 章 §2.8 改对了、§2.11 小结还写着错的; 第 5/10 章正文改对了、两处小结还写着"断点续传"; 第 3 章 §3.2 改对了、§3.4 与第 8 章 §8.7 还写着"10 秒"。 它们不会让代码报错,只会让结论错 —— 这正是最难发现的一类。

第五轮又识别出这类错误的一个更隐蔽的变体:"上一轮自己修出来的错" —— 上一轮引入了新结论,却没回头验证那个结论本身。最典型的一条是 把三处配置名"统一"成了 free_objects_period_ms —— 三处对上了, 但对的是错的值(真名是 free_objects_period_milliseconds)。 推论是:一致性还有时间维度,上一轮的修正本身也必须被下一轮验证。

完整清单见 README.md 的「第六批修订清单」(本轮)与更早的各批清单。 把这件事写在这里,是因为它正好示范了本教程 §0.6 的态度: 文档会错,而且错得最隐蔽的往往是"看起来合理"的那类事实。 所以每条关键结论都请你按版本核对,教程给你的是来源与判别方法,不是权威。

教程正文里对 Ray 的行为描述基于官方文档与 release notes, 但本机没有安装真实 Ray(2.58 对 Python 3.14 的支持情况未验证), 所以所有 Ray 侧的示例代码是"文档级准确"而非"本机跑过"。 这一点如实说明 —— 也是为什么每个事实都尽量标了来源。


0.8 一份 7 天学习计划(可选)

天内容产出
1第 1–2 章 + 跑通 examples/01、02能写任务与依赖
2第 4–5 章 + examples/03、04会用 actor、理解对象存储
3第 6 章上半(序列化 + 对象存储)+ 跑测试理解跨进程传值
4第 6 章下半(调度 + actor + 容错)+ examples/06、10能读懂 mini-ray 全部源码
5第 7–9 章能排查内存、调度、actor 问题
6第 10–11 章 + examples/05、09会做容错设计、会看状态
7第 12–19 章(按需挑)+ 第 20 章知道该用哪个库、走向哪里
8(可选)第 32–36 章(按你的负载挑:MLOps / CLI / 表格数据 / 数据血缘 / 追踪)工程收口

七天之后:挑一个你工作里的真实问题,用第 25 章的路径把它搬到 Ray 上 —— 第一层(骨架)先跑通,再逐层替换。这是最快的内化方式。

注意这个计划只覆盖到第 20 章。第 21–28 章是参考层(当字典查,不必通读), 第 26、29–36 章是按需深入的纵深。真正的阅读顺序表见 §0.4.1。


0.9 致谢与参考

  • Ray 官方文档(docs.ray.io)与 ray-project/ray 仓库的 release notes、issue、PR;
  • Ray 论文:Ray: A Distributed Framework for Emerging AI Applications(OSDI 2018);
  • Ray 2.0 Architecture whitepaper(官方推荐的架构入门材料);
  • PyTorch Foundation / Linux Foundation 关于 Ray 加入基金会的新闻稿;
  • Anyscale 官方博客(Ray Summit 各届 recap、KubeRay、GB300 拓扑感知等);
  • 以及 vLLM、verl、KubeRay 等项目的公开 RFC/文档 —— 它们从"使用者"的角度 给出了 Ray 边界最诚实的描述。

最后一句:Ray 的 API 很稳定,但它的生态位置在变。 学 API 是一次性投入;理解"它为什么在那里、边界在哪"才是长期能力。 这份教程的每一章都在朝这个方向写。

开始吧 —— 第 1 章见。