![]()
GPU 时间能否被复用,开始决定产品的扩张速度。
作者丨郑佳美
编辑丨岑 峰
8 月 23 日,奥特曼在 David Senra 的播客中谈到 OpenAI 内部的资源取舍时主动提到了 Sora。
他说得很直接:Sora 本身是个好产品,继续做下去也能成为一门不错的生意,但它实在太吃 compute,同一时期,Codex 的优先级更高,于是算力和团队投入开始往 Codex 倾斜。
![]()
但有趣的是,Codex 其实也一点都不省 GPU。Sora 生成一段视频,要让巨大的时空 latent 经过多轮 Transformer 计算;Codex 接到一句“把这个 bug 修掉”,后台则可能连续跑很多轮推理、读代码、调用工具、跑测试,再带着新的日志和上下文回来继续推理。
一个把算力压在单次视频生成里,另一个则是把算力摊进一条可能持续几十分钟甚至更久的 Agent 工作流里。于是,Sora 和 Codex 真正拉开差距的地方开始落到机房内部。
同样是一批 GPU,为什么视频生成的 compute 更难被摊开,而 Coding Agent 却能通过 KV cache、continuous batching、prefill / decode 调度和工具等待,把算力重新塞进更多并发任务里?
事实上,Sora 并非输在算力消耗的绝对值上,而是输在了工作负载架构上:Sora 的算力是连续且独占的,而 Codex 的算力是碎片且可复用的。正是这种调度机制的差异,拉开了两者的扩张速度。
沿着这条线往下看,会发现 Sora 输掉的那部分资源,背后或许是一场关于 GPU 时间应该怎么用的选择。
01
Sora 为什么难拆
Sora 的成本或许从视频进入模型时就已经开始膨胀了。它会先把原始视频压缩到 latent space,再切成 spacetime patches,让 Transformer 在这些 patch 上计算。
文本 token 主要沿序列方向增长,视频 patch 同时铺在时间、高度和宽度上,因此视频在模型内部天然是一块有体积的状态。
![]()
粗略来看,视觉 token 数可以理解成N_video ≈ T × H × W。这里的T、H和W已经过压缩和 patch 化,但三维乘法关系仍然存在。
视频时间拉长会增加时间方向上的 patch,画面尺寸提高又会扩大空间 patch。也就是说,视频长度和空间尺寸并不会彼此独立地增加成本,它们会一起把 latent 网格撑大。
这块网格进入 Transformer 后,还要面对 diffusion 带来的第二层计算。Sora 从带噪声的 latent 开始,每轮根据当前状态更新视频表示,再把新的 latent 送进下一轮。
![]()
单条视频的计算量可以粗略理解成C_video ≈ D × C_transformer(N_video),其中D是采样迭代次数。视频 latent 越大,每一轮越重;采样轮数增加,同一条视频又要多跑几轮网络。
这里能看出视频 diffusion 和 LLM 的关键差异。语言模型生成后续 token 时,前面的 Key 和 Value 可以保存在 KV cache 里,模型不需要在每一步重新构造整段历史状态。
视频 diffusion 每完成一轮更新,主体 latent 已经发生变化,下一轮面对的是一块新的时空状态,因此视频主体的大量计算仍然需要继续执行。
所以 Sora 的成本很难靠“复用历史”来大幅摊薄。它更像一段视效镜头在做多轮加工,每轮都要处理一整块已经变化的画面。视频越长、尺寸越高、采样越多,这条生成路径就越沉。
也正因为单个任务足够重,Sora 的 GPU utilization 反而可能很好看。大尺寸矩阵计算可以让 Tensor Core 长时间保持繁忙,监控图表里 GPU 几乎没闲着。
可利用率高只说明芯片一直在工作,并不代表单位时间交付了很多任务。一条视频如果连续占住一组 GPU 很久,那么 utilization 再漂亮,单条请求消耗的 GPU-seconds 依然很高。
![]()
视频 serving 还会被 shape 差异继续卡住。时长、分辨率和纵横比不同,会形成不同 tensor shape。服务端为了提高 batch 效率,需要把尺寸接近的请求放进相同 bucket。多等一会儿可以凑出更厚的 batch,却会增加排队延迟;立即执行可以缩短等待,batch 又可能填不满。
因此,Sora 的大部分算力成本已经锁在一条视频自己的生成路径里。采样轮数可以减少,latent 可以继续压缩,模型可以蒸馏,kernel 也可以继续优化,但 scheduler 能改动的主要是“这些重任务怎么排”,很难改变“一条视频本身就需要大量连续计算”这个事实。
这也是理解 Codex 的入口。Codex 同样昂贵,但它没有把全部成本压在一个连续计算块里,而是把任务拆成了许多可以暂停、恢复和重新组合的阶段。
02
Codex 为什么越跑越贵
用户给 Codex 一句“修掉这个 bug”,任务不会以一次模型调用结束。Agent 可能先读取仓库,让模型判断下一步,再执行 shell;拿到报错以后,把日志加入上下文,重新调用模型;随后修改代码、跑测试,再根据新的结果继续推理。
所以一条 Codex 任务更接近很多轮Prefill + Decode + Tool的累加。关键在于,每完成一轮工具调用,下一轮模型看到的上下文往往比上一轮更厚。
![]()
任务刚开始时,模型可能只有用户要求和少量代码。运行一段时间以后,更多文件、diff、终端输出、测试日志和工具结果不断进入 prompt。
用户最后看到的也许只是几百字完成说明,GPU 中间处理过的内容却可能已经非常庞大。Agent token consumption 的压力,就藏在这条不断增长的工作轨迹里。
![]()
如果每一轮 inference 都重新处理全部历史,长任务会很快被重复 prefill 拖住,所以 prompt caching 对 Codex 很关键。
假设一个 Agent 已经拥有 100K token 上下文,工具执行后只新增 3K token 日志,如果前面的稳定 prefix 能够命中缓存,本轮新增计算主要集中在后面这部分;一旦 prompt 前部变化导致 cache miss,系统就可能重新面对一次很重的 prefill。
这里出现了一个重要变化:逻辑 token 数已经不能直接代表实际 GPU 成本。两个请求都显示 100K input tokens,其中一个大部分内容已经缓存,另一个需要重新计算,它们对 GPU 的压力完全不同。Agent 的负载因此取决于上下文增长速度、cache hit,以及一个任务反复进入模型多少次。
![]()
进入单次 inference 后,prefill 和 decode 又有不同的硬件需求。Prefill 一次处理很多输入 token,矩阵尺寸较大,更容易形成 compute-heavy workload;decode 每条 sequence 每轮只生成少量 token,却要反复访问模型权重和 KV cache,因此更依赖 HBM bandwidth 和并发规模。
这意味着 decode 如果单独跑一条 sequence,会非常浪费。模型权重依然那么大,为了生成一个 token 也要参与一次完整前向计算。服务端只有把许多 sequence 放进同一个 batched forward,才能让一次权重访问同时推进更多请求。
而 batch 能不能继续增大,又会受到 KV cache 限制。每条 sequence 的上下文越长,占用的 HBM 越多。Agent 数量增加以后,GPU 可能还有算术余量,显存却已经装不下更多活跃状态。
PagedAttention 一类设计通过分页式管理 KV cache,降低显存碎片,本质上是在增加一张 GPU 能同时容纳的活跃 sequence 数量。
![]()
工具调用又把 Codex 的负载进一步拆开。Agent 跑测试、编译代码或等待 I/O 时,GPU 不需要继续为它工作,CPU、容器和文件系统会接手。等结果回来后,这个 Agent 再进入下一轮 inference。
于是一个运行 60 分钟的 Agent,并不意味着连续占用 60 分钟 GPU。它的任务时间被拆成了模型计算和外部执行两部分,这让 scheduler 获得了一个 Sora 很难提供的空间:当某个 Agent 去跑工具时,GPU 可以立刻去服务别的 sequence。
当然,这也会制造新的显存问题。等待工具的 Agent 要不要继续保留 KV cache?保留可以更快恢复,却会长期占据 HBM;驱逐可以腾出空间,任务回来时又需要承担恢复成本。Agent 数量越多,这类取舍越像操作系统在管理大量会休眠和唤醒的进程。
![]()
到这里,Codex 和 Sora 的差异已经不在“谁更重”,而在成本有没有被拆开。Sora 的算力集中在一条连续生成路径中,Codex 的算力分散在多个阶段里。正因为被拆开,Codex 才能进入下一层优化:让 scheduler 决定这些阶段怎样共享同一批 GPU。
03
Codex 的效率来自重新组织计算
大型模型线上运行时,权重通常要长期驻留 GPU,还要维持 tensor parallel、节点通信和缓存状态。因此 Sora 和 Codex 争资源,更多发生在 fleet level:一部分 GPU 长期进入视频 serving pool,另一部分长期进入 LLM pool,上层容量系统再决定哪边扩容、哪边缩容。
真正复杂的事情发生在 Codex pool 内部。假设系统里同时存在 200 条 Agent sequence,其中一部分正在 decode,一部分等待工具,还有几十条刚从工具环境回来,需要处理新的长上下文。Scheduler 面对的约束不只包括 FLOPs,还包括 HBM 容量、memory bandwidth、KV cache residency 和延迟预算。
![]()
Continuous batching 先解决 decode 的利用率问题。传统静态 batch 会让一组请求绑定在一起,短 sequence 结束以后,剩下的长请求还占着 batch。
Continuous batching 会在 token iteration 层面动态换人,一条 sequence 完成就移出,新的请求马上补进来。Batch 越厚,一轮模型计算可以推进的 sequence 越多,模型权重访问和内存带宽的成本就越容易被摊薄。
但这里很快会碰到显存墙。大量长 Agent 的 KV cache 会持续占用 HBM,一张 GPU 可能还没有把 Tensor Core 跑满,显存已经塞不进更多 sequence。此时继续堆算力没有意义,真正限制并发的是缓存容量和显存管理。
Prefill 和 decode 之间还存在另一种冲突。假设几十条 sequence 正在稳定 decode,这时一个 Agent 带着 100K token 的新上下文回来,需要执行大型 prefill。如果这个 prefill 一次占据很长的执行窗口,旁边请求的 TPOT 就会明显变差。
Chunked prefill 会把长输入切成多个小块,让 prefill 和 decode 交错执行;更进一步的做法,是把 prefill 和 decode 拆到不同 GPU pool。
![]()
原因在于,两类阶段本身就偏向不同硬件瓶颈:prefill 更偏计算吞吐,decode 更依赖 HBM bandwidth、KV cache 和稳定的逐 token 延迟。把它们分开以后,可以分别按各自需求配置资源。
这说明 Agent serving 的核心已经超出“把模型 kernel 写快一点”。很多容量提升来自重新安排任务什么时候运行、在哪运行、哪些状态值得留在显存,以及当前 batch 里应该塞谁。
因此,GPU utilization 到这里已经不够用了。容量团队需要同时看 GPU-seconds per task、TTFT(首字延迟,决定用户觉得卡不卡)、TPOT(单字生成时间,决定模型“说话”有多快)、queueing latency、prefix cache hit、KV cache occupancy 和 SLO goodput(有效吞吐量,代表真正能卖钱的算力)。
![]()
这些指标共同回答一个问题:在用户能够接受的延迟下,一小时 GPU 能维持多少有效任务。
Codex 的可调度性就体现在这里。Stable prefix 可以减少重复 prefill,decode 可以 continuous batch,KV cache 可以分页和驱逐,Agent 等待工具时还能让出 GPU。它的 workload 很碎,但这些碎片可以被 scheduler 重新编排。
这也把问题自然推向资源层:如果同一批 GPU 可以交错服务更多长期 Agent,那么一小时 GPU 实际上能够支撑的工作时间,就可能高于一小时。
![]()
04
为什么 Codex 更容易吸收新增算力
假设一个 Codex Agent 从接到任务到完成一共运行 60 分钟,其中只有一部分时间真的在做模型 prefill 和 decode,其余时间用于编译、测试、读写文件或者等待工具。这里的具体比例会随任务变化,但结构很重要:Agent wall-clock time 和 GPU compute time 并非一比一。
如果系统里同时存在大量 Agent,它们也不会在同一秒一起需要 GPU。有人正在 prefill,有人在 decode,有人在跑测试,还有人在等待文件系统。只要 scheduler 能把这些阶段交错起来,有限 GPU 就可以维持远高于 GPU 数量的活跃工作流。
![]()
可以把这个关系粗略理解成:Agent-hours 取决于 GPU-hours、模型推理占空比和调度效率。工具执行时间越多,batch 越厚,缓存命中越高,一小时 GPU 就越有机会支撑更长的 Agent wall-clock 工作。
这会直接改变新增 GPU 的含义。给 Codex 增加一批 GPU,带来的不只是单个任务更快,还可能让系统同时维持更多 Agent。一名工程师可以并行启动多个任务,一条改后端,一条补测试,一条处理另一个仓库,只要这些任务之间没有强依赖,机器工作时间就可以并行增长。
![]()
Sora 的容量曲线更直接。一条视频的大段 wall-clock 时间本身就在 GPU 上推进 diffusion,单条任务和 GPU 占用结合得更紧。新增 GPU 可以直接增加视频吞吐,但一小时 GPU 和视频计算时间之间的关系很难拉开太大距离。
Codex 的一条软件任务却会在 GPU、CPU、容器、文件系统和工具环境之间移动。GPU 负责模型推理,其他系统负责执行,多个 Agent 再通过 scheduler 交错共享 inference capacity。于是 GPU 从单纯的生成设备,变成了整个 Agent 系统里的稀缺“思考资源”。
![]()
这就是为什么 Codex 明明同样能吞掉大量 compute,却更容易获得新的 compute。OpenAI 需要看的不只是单次推理成本,还要看新增 capacity 能否迅速转化成更多并行工作量。
当一批 GPU 可以支撑更多长期 Agent,同时这些 Agent 又能持续接收新的软件任务时,资源就很容易继续向这个方向流动。
Altman 那句话的技术含义也因此清晰下来。Sora 的大量算力被锁在单条生成路径里,Codex 的算力被拆成多个可交错阶段。两边一样昂贵,资源回报曲线却不一样。
05
被 workload 形状影响命运
Sora 和 Codex 的资源转移说明,AI 产品开始多出一个会直接影响扩张速度的变量:workload architecture。
同样使用昂贵 GPU,一类任务把大量算力锁进单条生成路径,另一类任务可以通过缓存、batching、工具执行和调度,把同一批 inference capacity 交错给更多工作流,它们的资源曲线自然会分开。
所以未来一些看起来很底层的问题,会越来越接近产品问题。KV cache 怎么放,prefill 怎么切,decode batch 能塞多厚,等待工具的 Agent 要不要驱逐缓存,这些选择最后会决定一批 GPU 能同时维持多少任务。
Sora 和 Codex 的差别,也就不只是视频和代码的差别。
它们争的是同一小时 GPU,究竟能撑起多少工作。
参考链接:https://x.com/davidsenra/status/2091525869638434945
上车,带你看遍全球 AI 顶会精华
可独家畅览:
专家演讲PPT
大会报告全文
热门论文解读
学术新星访谈
未经「AI科技评论」授权,严禁以任何方式在网页、论坛、社区进行转载!
公众号转载请先在「AI科技评论」后台留言取得授权,转载时需标注来源并插入本公众号名片。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.