在大模型在线推理中,首 token 延迟往往比完整响应耗时更影响用户体验。Amazon SageMaker Inference 新增的前缀感知路由,会把共享相同提示词前缀的请求发送到同一个实例,让该实例上的 KV cache 更容易保持温热。
根据摘要中的 Llama 3.1 70B 基准测试,这种路由策略将 P50 time-to-first-token 最多降低了 77%,KV cache 命中率也从约 25% 提升到 80% 以上。关键变化不在模型权重,而在请求如何到达推理实例。
为什么提示词前缀会影响延迟
Transformer 推理可以粗略分成两段:
- Prefill:处理输入提示词,并生成注意力所需的 KV cache。
- Decode:基于已有 KV cache,逐个生成输出 token。
企业应用的请求通常包含一段稳定的共享前缀,例如系统提示词、工具定义、业务规则、检索结果模板或租户级上下文。只有最后的用户问题不断变化:
[稳定前缀] 你是客服助手……工具定义……产品规则……
[动态后缀] 我的订单为什么还没有发货?
如果连续请求被随机分配到不同实例,每个实例都可能重复执行相同前缀的 prefill。请求虽然能够并行处理,但 GPU 计算和显存带宽被重复消耗,用户需要等待更久才能看到第一个 token。
前缀感知路由会利用请求之间的前缀相似性,把它们尽量发往同一实例。这样,已经生成的 KV cache 可以被后续请求复用。它并不会消除动态后缀的计算,也不意味着所有请求都会命中缓存,但在共享前缀明显的工作负载中,收益可能很大。
两个指标要一起看
只看平均响应时间容易掩盖问题。前缀感知路由更应该配合以下指标观察:
- TTFT,time-to-first-token:从请求进入服务到收到第一个输出 token 的时间,直接对应交互式体验。
- KV cache hit rate:反映请求是否成功复用了已有前缀计算结果。
- P50 与 P95 TTFT:P50 能展示典型请求改善,P95 则能暴露缓存容量不足、实例负载不均或前缀分布过于分散的问题。
- 吞吐与显存占用:缓存命中率提升可能增加 KV cache 的驻留压力,需要确认总吞吐和成本是否同步改善。
摘要中的基准结果给出了一个清晰信号:在 Llama 3.1 70B 场景下,P50 TTFT 最多降低 77%,KV cache 命中率从约 25% 提升到 80% 以上。但这不是所有流量都能自动获得的固定收益。若每个请求都有不同的系统提示词、随机前缀或极短生命周期的上下文,路由器很难找到可复用的前缀。
如何构造一个适合验证的请求流
验证时,至少准备两组流量:一组共享长前缀,另一组前缀高度分散。下面的命令可以直接改造成 SageMaker Endpoint 的调用脚本。它使用同一个 prefix 发送多次请求,只改变末尾的问题;ENDPOINT_NAME、请求格式和响应解析字段需要按实际部署的模型容器调整。
export AWS_REGION=us-east-1
export ENDPOINT_NAME=my-llama-endpoint
for question in \
"Where is my order?" \
"Can I change the delivery address?" \
"How do I request a refund?"; do
payload=$(python -c 'import json,sys; print(json.dumps({"inputs": sys.argv[1], "parameters": {"max_new_tokens": 64, "temperature": 0.0}}))' \
"You are a concise customer-service assistant. Follow the company policy below and answer in English. Company policy: refunds are available within 30 days. User question: ${question}")
aws sagemaker-runtime invoke-endpoint \
--region "$AWS_REGION" \
--endpoint-name "$ENDPOINT_NAME" \
--content-type application/json \
--body "$payload" \
/tmp/sagemaker-response.json >/dev/null
printf '%s => ' "$question"
cat /tmp/sagemaker-response.json
printf '\n'
done
这个例子重点是请求形态:稳定的系统指令和业务规则位于前面,用户问题位于后面。生产环境中还应避免在共享前缀中放入用户隐私、短期 token 或每次都会变化的时间戳,否则会降低前缀复用机会。
如果要做延迟基准,可以把调用改成并发客户端,并记录每个请求的发送时间与第一个 token 到达时间。不要只测完整响应耗时,因为较长的输出会把 decode 阶段的耗时混入结果,难以判断路由是否改善了 prefill 和缓存复用。
部署时需要确认的边界
前缀感知路由的收益依赖几个实际条件:
- 前缀必须稳定且足够长。只有一个很短的共同开头,缓存节省的计算可能抵不过路由和管理开销。
- 模型服务必须支持 KV cache 复用。路由本身不能替代模型服务器的缓存能力,也不能跨不兼容的模型版本复用缓存。
- 实例数量和缓存容量要平衡。实例越多,单个实例看到相同前缀的机会可能越低;缓存保留过多前缀又会增加显存压力。
- 租户隔离要明确。共享前缀只应包含可以安全复用的内容。租户身份、授权信息和敏感上下文应按服务的隔离机制处理。
- 流量分布要持续观测。当热点前缀变化很快时,命中率可能下降,甚至出现少数实例过热而其他实例空闲的情况。
具体的 SageMaker 配置字段取决于所使用的推理容器、模型服务器和发布版本。可以把下面的配置当作部署设计草图,而不是可直接提交的通用 API 参数:
# illustrative configuration sketch
# Replace keys with the names supported by your SageMaker runtime/container.
model_server:
model: llama-3.1-70b
kv_cache:
enabled: true
prefix_reuse: true
routing:
strategy: prefix-aware
prefix_key: request.prompt
metrics:
- time_to_first_token_p50
- time_to_first_token_p95
- kv_cache_hit_rate
- gpu_memory_utilization
上线前应先在固定模型版本、固定实例规格和可重复的请求集上做 A/B 对比:随机路由作为基线,前缀感知路由作为实验组。重点比较 P50/P95 TTFT、KV cache 命中率、GPU 利用率、错误率和每百万 token 成本,而不是只挑选一次最好的延迟数字。
一份可执行的采用清单
- 统计线上请求的共享前缀长度和重复频率。
- 将稳定指令、工具定义和业务规则尽量放在提示词前部。
- 把用户问题、时间戳和请求级随机信息放到后部。
- 用固定流量分别测试随机路由与前缀感知路由。
- 记录 P50/P95 TTFT、KV cache 命中率、显存占用和实例负载。
- 为低命中率、缓存压力过高和热点前缀倾斜设置告警。
- 在确认收益覆盖额外运维复杂度后,再扩大到更多模型和租户。
前缀感知路由最适合拥有长而稳定共享上下文的交互式应用。它不是对任意工作负载的通用加速开关,但当请求结构与 KV cache 复用条件匹配时,路由策略本身就能成为降低首 token 延迟的重要杠杆。