适用读者:要做 Agent/代码平台容量规划、要解释"GPU 才用 84%,任务却在排队"的人。
前置:S23-J22(Little 定律)、J26(启动与积压)。
覆盖旧文:A-4344 §11.1–§11.2(任务执行过程 + 环境创建保留释放,437 点)→ 437 点。
扩展点:E-S23-106(需求率 = 到达率 × 每任务需求:30 核 / 600 GiB / 270 次调用)、E-S23-107(容量判据:内存 168% 是瓶颈,平台只能接 5.9 项/s)、E-S23-108(环境数 Little:300 × 2 GiB = 600 GiB)、E-S23-109(三种环境策略:常驻 / 按需 / 预热)。
上一篇:S23-J28 · 流水调度、checkpoint 与强化学习
下一篇:S23-J30 · 调度、服务成本与扩容。
1. 一句话结论
瓶颈不在最贵的那块,而在最先到 100% 的那块。 代码修复平台:CPU 只用到 62.5%、模型并发 84%,内存却要 168%——358 GiB 只能同时留 178 个环境,于是平台每秒最多开始 5.9 项,其余排队。再加 CPU 或 GPU 都没用。
出处:AI Infra 教材 §11.1–§11.2(
id 4344),设计题:代码修复平台。
资源需求率 = 到达率 × 每任务平均需求
利用率 = 需求率 / 容量 → 最接近 1 的那一项就是瓶颈
2. 任务画像(设计输入)
| 项 | 给定值 |
|---|---|
| 任务到达率 | 10 项/s |
| 每任务 | 3 次模型调用 + 3 次工具执行 |
| 模型 | DeepSeek V4-Flash,4×B200/副本,32 会话/副本 |
| 单次调用 | 355 token × 25.3 ms ≈ 9.0 s |
| 模型容量 | 10 副本(40 B200)→ 320 并发 |
| 工具 | 1 CPU 核、1 s,读文件/跑测试/存结果/清状态 |
| 环境 | 1 vCPU + 2 GiB 的 microVM |
| 环境驻留 | 每任务 30 s |
3. 需求率:三个数一起算(E-S23-106)
CPU:10 × 3 × 1 s = 30 CPU·秒/秒 → 平均 30 核在跑
内存:10 × 60 GiB·s = 600 GiB
模型:10 × 3 × 9 s = 270 次调用在飞
| 资源 | 需求 | 容量 | 利用率 | 判定 |
|---|---|---|---|---|
| CPU | 30 核 | 48 核 | 62.5% | 有余 |
| 模型并发 | 270 | 320 | 84% | 紧 |
| 环境内存 | 600 GiB | 358 GiB | 168% | 瓶颈(可驻留 178 个) |
358 GiB / 2 GiB = 178 个环境;每环境 30 s
→ 每秒最多开始 178/30 ≈ 5.9 项(需求 10 项/s)
判据:"平均有 30 个核在跑"不等于"买了 30 个核"——峰值、碎片、预留都要算进去。而这里真正卡住的是同时驻留的环境数,不是算力。
4. 环境数:Little 定律的直接用法(E-S23-108)
N̄_env = λ_env × T̄_env = 10 × 30 = 300 个环境
300 × 2 GiB = 600 GiB
判据:"并发任务数"和"并发环境数"是同一个数——只要每个任务从头到尾占一个环境。每轮重建环境不会增加环境数,但会把创建次数变成 3 倍(10 → 30 次/s),这会打爆创建通路(镜像拉取、配额)。
推广:内存随时间变化时用面积法 λ_task × E[A_M],CPU 用 ∫n_busy(t)dt。
5. 任务完成条件与必须保留的状态(§11.1.3)
| 状态 | 能否重建 | 影响 |
|---|---|---|
| 工作目录 / 工具结果 | 持久存储 → 可以 | 环境可重建 |
| 对话上下文(模型侧) | 需 KV 或重新拼 prompt | 长上下文重建贵(J22) |
| 已执行副作用(测试、写文件) | 不可重放 | 必须记账,避免重复 |
判据:"能重建"和"重建便宜"是两件事。 工作目录能重建,但重建要花时间;上下文能重建,但要重算 prefill。
6. 环境策略:常驻 vs 按需 vs 预热(E-S23-109)
| 策略 | 环境数 | 冷启动 | 内存成本 | 适用 |
|---|---|---|---|---|
| 始终驻留 | 峰值并发 | 无 | 最高(300×2 GiB) | 延迟极敏感 |
| 按需创建 | 活跃数 | 每轮 1 次 | 最低 | 允许秒级等待 |
| 预热池 | 活跃 + 池 | 命中即用 | 中(池大小可控) | 生产默认 |
| 暂停/恢复 | 活跃 + 快照 | 从快照恢复 | 中(快照占存储) | 长任务、间断等待 |
按需:创建率 30 次/s(每轮重建)→ 创建通路压力 ×3
预热:池大小 = 到达率 × 冷启动时长(Little 的另一种用法)
判据:预热池大小 = λ × 冷启动时长。 10 项/s × 10 s = 100 个池,刚好抵掉启动期积压。
7. 工具执行路径与隔离边界(§11.2.1)
| 边界 | 隔离什么 | 代价 |
|---|---|---|
| microVM | 内核、文件系统、网络 | 启动慢、内存固定 |
| 容器 | 文件系统、进程 | 共享内核,隔离较弱 |
| 进程沙箱 | 权限、syscall | 最轻,最难隔离 |
判据:隔离级别决定"能不能复用"——microVM 可以整机快照恢复,容器只能重建。
8. 可复算(实测)
$ cd /root/博客运营官/blog-v2 && python3 tools/s23_book_calc.py | tail -6
需求率: CPU 30 核(62.5%)、模型 270 次(84%)、内存 600 GiB(168%)
环境 178 个 × 30 s → 每秒 5.9 项(需求 10)
Little: 10 × 30 = 300 个环境 × 2 GiB = 600 GiB
每轮重建: 创建率 10 → 30 次/s(×3)
预热池: 10 项/s × 10 s = 100 个
9. 前提与边界
| 结论 | 成立条件 | 不成立时 |
|---|---|---|
需求率 = λ×需求 |
稳态、需求独立 | 突发/相关 → 用峰值 |
| 内存 168% 是瓶颈 | 环境驻留 30 s | 提前释放 → 需求下降 |
| 环境数 = 任务数 | 一任务一环境 | 共享环境 → 需重算 |
| 预热池 = λ×启动 | 泊松到达 | 突发 → 池要更大 |
10. 常见误区
| 误区 | 纠正 |
|---|---|
| "GPU 没满就不是瓶颈" | 内存 168%,加 GPU 无效 |
| "CPU 62.5% 就能接更多任务" | 环境数卡在 178 |
| "每轮重建环境更干净" | 创建率 ×3,打爆创建通路 |
| "常驻最稳" | 300×2 GiB 内存最贵 |
| "能重建就不用存" | 重建要时间,副作用不可重放 |
11. 自测
- 10 项/s、每项 3 次工具各 1 s,平均多少核在跑?
- 每项占环境 30 s、10 项/s,平均多少环境?2 GiB 一个共多少内存?
- 358 GiB 能放几个环境?每秒最多开始几项?
- 冷启动 10 s、10 项/s,预热池要多大?
答案
- 30 核。
- 300 个;600 GiB。
178 个;178/30 ≈ 5.9 项/s。10 × 10 = 100 个。
12. 下一篇
S23-J30 · 调度、服务成本与扩容 —— 异构资源成组分配、队列与抢占、RL 生成/训练的动态配比,以及自建、按量 API、订阅的采购交点与"每百万 token 成本"。