摘要:大模型推理的延迟不是一个“服务器快不快”的问题,而是两阶段计算特性(Prefill / Decode)与承载层控制权分配的结果。本文将剥离营销术语,从 Transformer 推理的计算本质出发,拆解 TTFT 与 TPOT 的成因,映射到 AWS 上的三种承载形态(Bedrock 无服务器托管 / SageMaker 托管端点 / HyperPod 自建),并指出流式响应在 API Gateway、Lambda 与 CDN 链路上是如何被中间层悄悄“吃掉”的。

1. 延迟的两个来源:Prefill 与 Decode

在讨论“选哪个服务”之前,必须先明确一件事:一次大模型请求的时间,由两个物理性质完全不同的阶段构成。承载层的选型,本质上是在选择你对这两个阶段有多少控制权。

1.1 Prefill(预填充):计算密集阶段

请求到达后,模型要把整个输入(system prompt + 历史对话 + 检索到的上下文 + 用户问题)一次性前向计算一遍,生成每个位置的 K/V 并写入 KV Cache。

  • 特征:算力受限(compute-bound),大量矩阵乘法,GPU 的 Tensor Core 利用率可以打满。
  • 代价:计算量随输入长度增长,其中自注意力部分近似呈平方级增长。因此长 prompt 直接推高 TTFT(Time To First Token,首 token 延迟)。
  • 结论:TTFT 的主要矛盾是 prompt 长度与算力,而不是网络。

1.2 Decode(解码):显存带宽密集阶段

首 token 之后,模型逐个生成 token。每生成一个 token,都要把此前所有位置的 KV Cache 从显存读出来做注意力计算。

  • 特征:显存带宽受限(memory-bandwidth-bound),而非算力受限。GPU 大量时间在“等数据”,Tensor Core 利用率反而很低。
  • 代价:每生成一个 token 的成本,与 KV Cache 的体量成正比。
  • 结论:TPOT(Time Per Output Token)/ ITL(Inter-Token Latency)的主要矛盾是显存带宽与上下文长度,输出越长、上下文越长,每 token 越慢。

Decode(解码):显存带宽密集阶段.png

1.3 KV Cache 的体量公式

单个请求的 KV Cache 占用可近似表示为:

KV_Cache ≈ 2 × n_layers × n_kv_heads × d_head × bytes_per_param × seq_len
  • 乘 2:K 和 V 各一份;
  • n_kv_heads:采用 GQA / MQA 的模型该值远小于注意力头数,这正是现代模型压缩 KV Cache 的主要手段;
  • bytes_per_param:量化(FP8 / INT8)会直接线性降低占用;
  • 再乘以并发 batch size,就是这张卡的显存账单。

架构含义:并发不是免费的。想提升吞吐就抬高 batch,而 batch 抬高会同时抬高显存占用与带宽竞争——吞吐与单请求延迟是一对真实存在的矛盾,continuous batching 能缓解,但不能消除。


2. 承载层的三种形态:你交出了多少控制权

AWS 上的承载层可以按“控制权”排成一条光谱。这条光谱的每一格,都对应着不同的延迟可优化空间。

维度Bedrock(无服务器)SageMaker 托管端点HyperPod / EKS 自建
基础设施完全不可见,无 GPU 管理实例可见,规格可选集群自建,全栈可控
可控的延迟杠杆prompt 结构、参数、缓存前缀batching 策略、量化、推理引擎、实例类型全部,含算子与调度
冷启动无(共享池)实时端点无;Serverless 有取决于自身调度
计费单位token实例秒实例/集群秒
适用通用、快速上线、波动流量稳定高负载、需定制权重与引擎极致性能与成本优化

2.1 Bedrock:把控制权换成速度

Bedrock 通过统一 API(Converse / ConverseStream,以及 InvokeModel / InvokeModelWithResponseStream)屏蔽了模型差异,也屏蔽了底层硬件。

你能调的杠杆只有三个:

  1. Prompt 结构——既然 TTFT 由 prompt 长度决定,缩短前缀就是最直接的优化。
  2. 提示缓存(Prompt Caching)——把 system prompt、工具定义、长文档等重复前缀缓存起来,命中部分跳过 prefill 计算。AWS 官方口径为:对命中的缓存前缀,最高可降低约 85% 的延迟与 90% 的成本(均为官方上限值,实际收益取决于命中率)。这是 Bedrock 上唯一能显著改善长 prompt TTFT 的手段。
  3. 吞吐保障——对稳定高负载场景,可使用预置吞吐(Provisioned Throughput)锁定容量;跨区域推理(inference profile)能提升可用性,但会引入跨区网络跳数,在极致延迟场景下必须计入预算。

架构警示:Bedrock 是多租户共享服务。你无法独占硬件,因此 P99 尾延迟不在你的控制范围内。如果业务的 SLA 是“P99 < X ms 且抖动可控”,那么共享池本身就是风险项。

2.2 Bedrock Custom Model Import:中间态

若你需要自定义权重但不愿运维 GPU,Custom Model Import 是一条折中路径:导入自己的权重,部署到 Bedrock 的托管无服务器环境,用 InvokeModel / InvokeModelWithResponseStream 调用。

边界:支持的模型架构与区域是有限集合且持续变化,调用前需以官方文档为准;部分架构对 Converse API 的支持存在例外。

2.3 SageMaker 托管端点:拿回引擎控制权

当你需要自己决定 batching、量化与推理引擎时,承载层应换到 SageMaker:

  • 实时端点(Real-time Endpoint):常驻实例,无冷启动,适合稳定流量;
  • 推理组件(Inference Components):多模型打包到同一端点,隔离算力、独立扩缩,并支持缩容到零,把闲置 GPU 成本压下来;
  • OpenAI 兼容 API:已有 OpenAI SDK / 框架的应用可低成本迁移到自有 GPU。
  • Serverless Inference:缩容到零,但存在冷启动,不适合对 TTFT 敏感的实时对话。

架构收益:在这一层,你终于可以针对第 1 节的结论做工程动作——换 INT8/FP8 量化降低 KV Cache、调整 continuous batching 的并发窗口、选择带宽更高的实例类型来直接改善 TPOT。

2.4 HyperPod / EKS:把 prefill 与 decode 拆开

在自建层可以做托管层做不到的事:Prefill-Decode 分离部署。

由于两阶段一个是算力密集、一个是带宽密集,把它们放在同一批 GPU 上跑,必然互相干扰。分离部署后各自按瓶颈选型与扩缩,AWS 在 HyperPod 侧也提供了分层 KV Cache 与智能路由等面向长上下文、多轮对话的延迟优化能力。这是“混合流量下延迟一致性”的正解,代价是你接管了整条运维链路。

承载层的控制权光谱.png

说明: 从左至右,你能施加影响的延迟杠杆越来越多,同时需要自己运维的层次也越来越深。选型的第一步是确定自己站在光谱的哪一格。


3. 流式响应:别让中间层吃掉你的优化

一个高频误解:流式不改变总生成时间,只改变“可感知延迟”。用户看到第一个字的时间提前了,但最后一个字的时间一点没变。若链路中任一环节缓冲,连这个感知收益都会消失。

3.1 链路上的三个缓冲点

Client → CloudFront/CDN → API Gateway → Lambda → Bedrock
  • API Gateway(默认 BUFFERED):默认会等后端完整返回再转发。同时它有两类硬约束——29 秒集成超时与 10 MB 响应上限。长文本生成很容易撞上前者,表现为客户端收到 504。
  • CDN / 反向代理:自有 CloudFront 分发或前置 Nginx 有自己的响应超时与缓冲策略,同样会积压 chunk。
  • 客户端:浏览器或 SDK 若不按 SSE 解析,也会等到流结束才渲染。

流式响应链路上的三个缓冲点.png

说明: 响应沿 Bedrock → Lambda → API Gateway → CloudFront → Client 回流,其中 API Gateway、CloudFront 与客户端是最容易被忽略的三处缓冲。任意一处把 chunk 攒起来,前端表现就是“转圈很久后一次性刷出”。

3.2 API Gateway 的流式开关

REST API 支持把响应传输模式设为 STREAM,从而不必等后端算完就开始下发:

x-amazon-apigateway-integration:
  httpMethod: "POST"
  type: "aws_proxy"
  timeoutInMillis: 300000
  responseTransferMode: "STREAM"

使用该模式必须知道的边界(以官方文档为准):

  • 仅 REST API 支持,HTTP API 与 WebSocket API 不支持;且仅适用于 HTTP_PROXY / AWS_PROXY 集成;
  • 流式最长可达 15 分钟,但仍受空闲超时约束:区域端点和私有端点约 5 分钟,边缘优化端点仅 30 秒——边缘优化 + 流式是一个极易踩的坑;
  • 启用后不再支持端点缓存、内容编码与 VTL 响应转换;压缩必须在集成侧自己做;
  • 前 10 MB 不限速,超出部分限制在约 2 MB/s;
  • 整段流结束后服务端逻辑可能仍在跑,需自行对齐 Lambda 超时。

BUFFERED 与 STREAM 的对比.png

说明: 两种模式下后端完成生成的时刻完全一致(右侧虚线),差别只在首字节到达的时刻。这正是“流式只改善感知延迟”的含义——它不能让模型变得更快。

3.3 Lambda 侧:函数必须真的“边算边写”

export const handler = awslambda.streamifyResponse(
  async (event, responseStream) => {
    const stream = awslambda.HttpResponseStream.from(responseStream, {
      statusCode: 200,
      headers: { "Content-Type": "text/event-stream" }
    });
    for await (const chunk of bedrockStream()) {
      stream.write(chunk);   // 逐 chunk 下发,而非累积后返回
    }
    stream.end();
  }
);

Lambda 函数超时上限为 15 分钟,与 API Gateway 流式的上限一致,二者需要一起配置。若 Lambda 内部先聚合再返回,那么上游开不开流式都没有意义。


4. 选型决策:五个问题定承载层

按以下顺序自问,答案基本指向唯一解:

  1. 是否需要自定义权重 / 特定量化 / 自定义算子? 是 → SageMaker 或自建。
  2. P99 抖动是否写进了 SLA? 是 → 需要独占算力,排除共享池。
  3. 流量是尖峰波动还是长期稳定? 波动 → 按 token 计费的无服务器形态;长期稳定高负载 → 常驻实例的单位成本更优。
  4. 主延迟指标是 TTFT 还是 TPOT? TTFT 敏感(短输出、长输入)→ 优先优化 prompt 长度与前缀缓存;TPOT 敏感(长输出)→ 优先优化显存带宽与量化。
  5. 是否有数据不出 VPC / 不出区域的硬性合规要求? 有 → 需要能明确落到 VPC 与指定区域的承载形态,并把跨区域路由从预算里剔除。

5. 反模式与边界(Trade-offs)

常见反模式:

  • 把流式当成性能优化。 它只改善感知延迟,不改变总时长;真正的优化是缩短 prompt、提高缓存命中率、降低 KV Cache 占用。
  • 在 Lambda 与模型之间多加一层“纯转发”。 每一次跳转都叠加冷启动、序列化与网络 RTT。若只为加鉴权,应评估是否能让客户端直连(例如通过签名请求),把 Lambda 只用于必须编排的场景。
  • 忽略 29 秒集成超时与边缘端点 30 秒空闲超时。 这两条是生成式应用线上 504 与“流到一半断开”最常见的根因。
  • 用同步 HTTP 承载 Agent 长循环。 多轮工具调用的总时长很容易超过任何同步网关的上限,应改为异步任务 + 回调 / 轮询结果。

Bedrock 的反指征:

  • 需要独占 GPU 以获得可预测 P99;
  • 需要自定义推理引擎、算子或特殊量化方案;
  • 需要把模型权重留在自建体系内并完全掌控生命周期。

SageMaker / 自建的反指征:

  • 流量稀疏且不可预测(常驻实例在闲置时段是纯成本);
  • 团队不具备 GPU 运维与推理引擎调优能力——把控制权拿在手里却用不好,结果通常比托管更慢也更贵。
Last modification:October 29, 2026
分享是对我最大的赞赏