1. 为什么 any-to-any 的状态问题比普通 token decode 更大
普通 AR 请求的核心暂态是 token sequence 与每层 KV。Omni 请求还会带来媒体原始字节、预处理配置、encoder feature、Thinker hidden state、DiT latent、Talker feedback、codec code、vocoder overlap window、流式输出位置、工具/会话语义和跨进程 payload reference。它们的大小、可重建成本、敏感性和生命周期都不同。
将这些对象统称为“缓存”会导致两个常见错误:一是为了保留会话语义而无限持有 GPU KV;二是为了提高命中率而将模型/媒体派生状态跨请求、跨租户或跨 revision 复用。正确模型是:每一个对象都必须回答它由谁创建、谁消费、何时失效、能否重算、是否可持久化、谁负责释放。
2. 状态分类:先按语义与重建成本分层
| 状态 | 典型内容 | 正确生命周期重点 |
|---|---|---|
| 请求身份与不可变输入 | request id、tenant、模型/processor revision、prompt、媒体 hash、采样/输出合同、deadline。 | 是所有子状态的根;重试必须保留或显式创建新的 attempt,不能悄悄变更 revision。 |
| AR KV | prefill 后的每层 key/value、position、layout、精度、adapter 相关状态。 | 通常昂贵但可由规范化输入重算;只能在模型与位置语义相容时复用。 |
| 媒体 feature | 图像/视频/audio encoder 输出、tokenized media、预处理元数据。 | cache key 必须覆盖原媒体、resize/抽帧/采样率、processor revision 与访问策略。 |
| latent / hidden state | Thinker hidden state、DiT conditioning、VAE latent、CFG companion 依赖。 | 常在跨 stage 边上短暂存在;需要明确 producer、consumer、字节预算和传输完整性。 |
| codec / vocoder state | codec token、Talker feedback、overlap-add window、已 emit 样本数、尾部 flush 状态。 | 必须保持 chunk 顺序与样本边界;cancel 后不能继续发布旧 chunk。 |
| 会话/业务状态 | messages、工具结果、权限、预算、turn、用户偏好与持久 checkpoint。 | 是可恢复的业务真相,不能把临时 GPU KV 当作唯一副本。 |
| 运输与调度状态 | queue item、DataRef、credit、ACK、lease、worker epoch、retry attempt。 | 短寿命却最容易泄漏;必须在成功、超时、abort 和 worker loss 的每条路径归还。 |
vLLM-Omni 的 connector 文档将跨 stage payload、KV 与 chunk 置于统一 connector 合同;SGLang-Omni 则公开 AR KV、媒体 encoder cache、relay reference 与流式 vocoder state。这说明至少存在多类状态,但不说明两套 runtime 的具体 key、TTL 或恢复策略完全相同。
3. 状态 identity:内容相同不等于计算语义相同
一个可复用对象的 identity 不能只用文本或文件 hash。以媒体 feature 为例,输入身份至少应包括媒体内容、decode/resize/crop/抽帧规则、采样率、processor revision 和输出 dtype。KV 还需要 tokenizer/template、token ids、position/RoPE policy、模型/adapter revision、KV layout/precision 和模型并行布局。latent 需要 upstream node、shape、随机种子或 diffusion step、condition revision。
建议将不可变 identity 与可变 location 分开。前者解释“这份数据是什么”,后者只解释“它现在在哪个 GPU、SHM segment、RDMA buffer 或对象存储中”。location 可以失效并被重新解析;identity 若不匹配,必须拒绝复用而不是尝试“兼容读取”。
request_id、attempt、tenant_namespace、producer_stage、state_kind、schema_version、identity_digest 与 epoch。DataRef 只是位置,不是身份。4. 生命周期:从准备到终态,状态必须可追踪
REQUEST ACCEPTED
-> ADMITTED
-> MEDIA_READY
-> STAGE_READY
-> RUNNING
-> OUTPUT_OPEN
-> SUCCEEDED | CANCELLED | DEADLINE_EXCEEDED | FAILED | REJECTED
每类派生状态:
absent -> producing -> ready -> leased -> consumed -> released
\-> invalid | evicted | orphaned-for-cleanup
请求的终态和对象的终态不是同一个状态机。请求可能已向客户端返回 CANCELLED,但某个 GPU kernel、RDMA transfer 或 SHM reader 仍在收尾;反之一个 feature cache 被驱逐也不必意味着请求失败,只要上游能重算。系统必须把“客户端可见终态”与“资源已经完全释放”分别观测。
建议将 terminal transition 设计成单调的:一旦请求进入成功、取消、超时、拒绝或失败中的一种,就不得再把同一 attempt 变回运行。后到的消息只能触发清理或被记为 stale,而不能重新打开输出流。
5. Owner、refcount、lease 与 epoch:谁有权释放什么
| 对象 | 推荐 owner | 释放或失效触发 |
|---|---|---|
| 请求目录与 terminal 聚合 | ingress/orchestrator/coordinator。 | 全部所需 terminal 完成,或一次明确 abort/deadline;保留轻量审计记录,不继续持有大对象。 |
| stage queue item 与本地 batch slot | 对应 stage scheduler。 | 已消费、被取消、过期或 worker 重启;必须归还 admission slot。 |
| KV block / feature cache entry | 本地 cache manager;共享项以 namespace 和 pin/refcount 管理。 | 最后一个合法引用离开、TTL/eviction、revision 变化或 memory pressure;仍被 in-flight request 使用时不能回收。 |
| latent / codec payload | producer 创建,receiver 在 ACK 后承担消费 lease;目录只保存引用。 | 所有 consumer ACK、cancel fan-out 完成,或 lease 过期后的可控重算/清理。 |
| 外部会话 checkpoint | 会话服务/应用,而不是 GPU worker。 | 产品 retention/用户删除/权限变更;必须和 runtime 的短期对象解耦。 |
refcount 只在所有引用都可靠送达时足够;分布式系统还需要 lease 与 epoch。worker 重启后,旧 epoch 的 DataRef、ACK 或 output chunk 不能继续影响新 owner。lease 到期不代表立刻物理释放,而是触发“确认 consumer 是否存活、重试、标记孤儿、再清理”的恢复流程。
6. Queue 不是一个数:至少同时预算 request、字节和 GPU 状态
一个 entry queue 深度为 20,可能只含 20 个短文本,也可能含 20 个待传的大 latent。Talker queue 有 2 个请求也可能累计数分钟的 codec output;vocoder queue 看似很短,却因下游客户端停读而占满 output buffer。每条边至少独立限制 items、bytes、GPU-resident bytes、stream chunks 与可播放音频秒数。
在稳定窗口内,Little 定律 \(L_s=\lambda_s W_s\) 能帮助解释某 stage \(s\) 的积压:平均在途数 \(L_s\) 等于到达率 \(\lambda_s\) 和平均等待/服务时间 \(W_s\) 的乘积。它是诊断关系,不是对突发、优先级、cancel 或有限 buffer 的精确预测;生产告警仍应看 oldest wait、字节和 lease 年龄。
建议每个 queue 项包含 predicted/observed cost 和 deadline。媒体 payload 在 decode 前不具备可靠估值时,至少在 decode 后重新记账,避免 admission 仅按“请求数”而让一个超长视频或高分辨率图像挤掉整个 queue。
7. Credit 与 backpressure:容量必须沿依赖边反向传播
对从 producer \(u\) 到 consumer \(v\) 的边 \(e\),可把可用 credit 记为 \(c_e\),单位必须明确为 item、bytes、token、codec frames 或 GPU slots 之一。若 payload \(x\) 占用 \(b_e(x)\) 个单位,建议发送前满足:
\[ 0 \leq b_e(x) \leq c_e,\qquad c_e^{\prime}=c_e-b_e(x),\qquad c_e^{\prime\prime}=c_e^{\prime}+b_e(x)\ \text{after release}. \]
这里的 release 只能在 consumer 已消费、明确拒绝、取消清理或确认超时回收后发生;“控制消息已发送”不等于 payload 已被接收。fan-out 需要为每个 consumer 单独记 credit 或采用共享对象加多个 lease,不能在第一个 consumer ACK 后释放仍被第二个 consumer 读取的 latent。
backpressure 要从慢端向上游传播:客户端慢读会收紧 output credit,vocoder 停止取新 codec token,Talker 降低或停止生成,Thinker 不再推进会制造新 Talker state 的请求,入口最终做 admission/reject。仅在最后一层丢 chunk 会得到低 queue 深度和错误的“健康”指标,却损坏用户看到的流。
8. Admission 与 fairness:先拒绝可控,后 OOM 不可控
入口 admission 应检查的不只是全局并发,还包括每条必经路径的容量:媒体 decode/encoder queue、Thinker KV/sequence budget、Talker/vocoder credit、connector pool、输出 buffer、tenant quota 和 deadline 可行性。若路径在提交前就不能在 deadline 内取得最小资源,应返回可解释的 rejected 或 deadline_exceeded,而不是先将其推进多个 stage 再因 OOM 或孤儿 payload 失败。
公平性也需要按成本而非请求数设计。一个持续的高分辨率视频/长语音租户会占用 encoder、KV、latent 和网络,而大量短文本请求的成本不同。可采用分 tenant queue、weighted fair queuing、并发/字节/token 配额、aging 与最大 in-flight state;策略必须保留系统级过载保护,不能让租户权重绕过内存上限。
9. Cancel:不是 HTTP 断开,而是一条带 epoch 的终止协议
客户端断开连接不保证 GPU stage 已经停止。一个正确的 cancel 至少经历:入口记录 terminal intent;orchestrator/coordinator 将 cancel 传播到所有已知和可能已投递的后代;每个 stage 从 queue 移除未运行工作、标记运行中工作不再发布;connector 关闭或作废未消费引用;cache/lease manager 在最后引用离开后回收;最终审计确认没有继续增加的 GPU、SHM、RDMA 或 output bytes。
建议 cancel message 包含 request、attempt 和取消 epoch。stage 收到旧 epoch 的 DataReady 或 stream chunk 时应丢弃并记录,而不是把它重新放入新 attempt。kernel 不支持物理抢占时,系统可先让用户看到取消终态,再在后台等待安全点释放;但 dashboard 必须展示“client done”与“resource drained”之间的 lag。
vLLM-Omni 和 SGLang-Omni 都公开了 abort/cleanup 相关入口或测试/文档,这说明取消是 runtime 的正式考虑对象。具体 connector 是否已覆盖每个 race,仍只能由目标 commit、部署和故障注入验证;历史 issue 只能提供测试线索。
10. Timeout、deadline 与 retry:不同原因不能共用一个“失败”
建议至少区分 admission deadline、queue deadline、stage service deadline、connector transfer deadline、stream idle deadline 和整个 request deadline。它们的动作不同:queue deadline 可不启动计算;transfer deadline 可能重试或重算上游对象;stream idle deadline 需要先确认客户端是否仍在消费;整个 request deadline 触发取消所有后代。
retry 必须从对象的重建边界开始。幂等的媒体 decode 或 encoder forward 可以带新 attempt 重跑;已对外输出副作用的工具调用、外部写入或一段已经发送的音频不能悄悄“再来一次”并混入原流。对于输出,采用 at-most-once publish 加可检测 gap,或给每块稳定序号并由客户端/网关去重;不要无声明地把内部 at-least-once delivery呈现为恰好一次。
11. Stream correctness:可播放的第一个 chunk 不等于完整且正确的流
流式文本最小合同是每个 delta 有单调序号、同一 attempt 不重复、终态恰好一次、finish 后不再发 payload。流式音频还要携带 sample rate、channels、format、chunk sequence、起始 sample offset、有效 samples、是否可播放和是否 final。codec/vocoder 的 overlap window、flush 与尾部 padding 也必须进入状态,而不是由客户端猜测。
若 \(y_k\) 是第 \(k\) 个输出音频块,\(o_k\) 是其首样本偏移,连续无空洞的基本检查为
\[ o_{k+1}=o_k+\lvert y_k\rvert . \]
该式只验证样本覆盖,不保证声学质量;还要验证同一语音在 stream 拼接与非 stream 输出中的波形/容许误差、codec sample rate、header、静音尾部和取消时不出现旧 attempt 的片段。实时语音若允许内容回滚,需要额外定义 watermark:watermark 前的样本不可撤回,之后的缓存音频才可丢弃或替换。
12. Tenant isolation:cache 命中不应成为数据泄漏通道
租户隔离至少覆盖身份、调度、存储、可观测性和恢复。cache key 或 namespace 要纳入 tenant/ACL、模型/adapter、敏感版本和媒体 identity;queue 需要在高成本租户下保护其他租户;日志与 trace 不能把原始音频、prompt 或 feature handle 暴露给无权限调试者;故障重试不能将一位用户的 DataRef 交给另一位用户的 worker。
可共享的公共模型权重和经过明确授权的公共 feature 与可共享的“用户状态”不是同一件事。即使两个请求的 prompt bytes 相同,若权限、工具结果、系统提示或媒体来源不同,也应默认不共享。任何跨租户 cache 方案都需要独立的访问控制证明、命中审计和负向测试,而不是只看吞吐提升。
13. Fault ownership:先定位谁发现、谁隔离、谁恢复
| 故障域 | 第一发现/隔离 owner | 恢复决策 |
|---|---|---|
| 客户端断开、慢读、输入格式错误 | API gateway/client adapter。 | 停止接收/发送、传播 cancel 或返回 validation error;不把慢读伪装成模型慢。 |
| 排队过期、admission 满、terminal 丢失 | orchestrator/coordinator。 | rejection、deadline cancel、补全 terminal 或将 attempt 判失败;负责全图终态一致性。 |
| stage OOM、kernel error、进程退出 | stage supervisor / worker runtime。 | 隔离 worker epoch、报告受影响 request、重建可重算对象或 fail-fast。 |
| SHM/RDMA/relay 超时、ACK 丢失、buffer 泄漏 | connector owner。 | 作废 DataRef、撤销 lease、健康检查/重连、清理孤儿 buffer;不应让上游无限重发。 |
| 模型/processor 不匹配、输出契约损坏 | model integration 与质量 gate。 | 拒绝复用、回退到完整重算或停止该 deployment;不能通过重新标记 payload 来掩盖不匹配。 |
| 会话 checkpoint 或权限服务不可用 | 应用/session owner。 | 选择 fail-closed、只读降级或有版本的恢复;GPU runtime 不应自行编造业务状态。 |
将 owner 指定到组件不是为了推卸责任,而是防止每一层都重试。若 gateway、coordinator、stage 和 connector 同时重试同一个大型 latent,瞬间会产生多份 payload、重复输出和内存雪崩。全局 attempt id、epoch 和可见终态是协调这些 owner 的最小共同语言。
14. 恢复策略:先区分可重算、可迁移与必须持久化
媒体原始输入、规范化 prompt 和会话 checkpoint 通常可持久化;encoder feature、KV、hidden state、latent 与 codec buffer 常可从上游重算;正在 RDMA 的 buffer、CUDA IPC handle 和 scheduler batch 则通常只能作废后重建。每个 deployment 应明确恢复点,而不是在 worker 损失后尝试从任意内存地址“续跑”。
适合恢复的最小日志是轻量目录:输入 identity、完成过的 stage、每个可重算状态的 producer、terminal 已发布的 chunk watermark、retry budget、deadline 和权限上下文。它不应保存或广播所有 GPU tensor。若必须恢复长会话,持久真相应是消息/工具/授权 checkpoint,runtime KV 只是可选加速项。
对于多 terminal 请求,恢复还要知道用户要的是哪些 terminal。文本 terminal 已成功并不表示语音 terminal 已成功;若 API 已把文本交给用户,重试声音时应使用新 attempt 和明确的 stream identity,避免后到 audio 被误拼到旧 response。
15. 观测与故障注入:让不变量可被反证
每个 request/attempt/stage/edge/chunk 需要单调时钟事件:admitted、queue enter/leave、batch start/end、payload produced、credit consumed/released、ACK、output published、cancel received、terminal set、lease expired、resource freed。指标按 tenant、模型 revision、stage、connector、state kind 和失败原因分组,同时控制日志中敏感媒体和 prompt 的暴露。
最小故障套件应包含:慢消费者和断连;在 encoder、Thinker、Talker、vocoder 各阶段 kill worker;丢/延迟 DataReady 或 ACK;让 connector memory pool 耗尽;在 stream 中取消;在 terminal 前超时;用旧 epoch 注入迟到 chunk;跨租户构造相同文本但不同媒体/权限。每次都检查四件事:客户端终态正确、无重复/越界输出、credit 和 lease 回收、显存/SHM/网络 buffer 回到基线。
16. 如何使用公开 issue、文档和代码证据
固定代码与官方文档可用来证明某条 handler、scheduler、connector、cache key 或配置在该 revision 存在。论文可用来证明其明确实验设置下的机制与数字。GitHub issue 则更适合产生测试用例:它可能描述一个曾经存在的 bug、特定环境的复现、开放设计或未完成优化,但不自动代表目标 commit、所有模型或所有集群。
例如,SGLang-Omni 的通信文档可以支持“控制面与大 payload 数据面分开”的说法;vLLM-Omni connector 文档可以支持“connector 有 cleanup/health 合同”的说法。是否在本次部署中没有泄漏、所有 cancel race 都正确、跨节点恢复已生产化,仍需按本页不变量做本地测试。保留这种缺口比把 issue 标题升级为系统定律更诚实,也更利于复现。
17. 一手来源与适用范围
- vLLM-Omni 固定源码树,包括 stage configuration、SharedMemoryConnector 与 Mooncake Transfer Engine connector:stage/connector 对象和释放风险的实现范围。
- vLLM-Omni 论文:异构 stage、per-stage batching、连接器和完全解耦的系统背景。
- SGLang-Omni 固定源码树、通信文档、stage cache:AR、媒体、relay 和 stream 状态的具体入口。
- 上一页:runtime 逐层比较;下一页:可复现评测与容量实验。本页的 credit、epoch、ownership、tenant 与恢复规则是以这些公开机制为基础提出的跨 runtime 验收合同。