一次大模型 API 请求是怎么跑起来的:从 Harness 到 GPU、并发与 KV Cache

1 阅读9分钟

一次大模型 API 请求是怎么跑起来的:从 Harness 到 GPU、并发与 KV Cache

前面聊模型部署时,我一直有一个疑问:一个模型实例明明只有一份模型参数,为什么它可以同时处理很多人的请求?

要理解这个问题,不能只盯着模型本身。一次 API 请求真正经过的是一整套系统:

image.png

可以把它简单理解成:

  • Harness 决定这次准备什么材料、调用哪个模型。
  • 服务商前台决定请求能不能进入、应该送到哪里。
  • 推理引擎决定多个请求怎么一起使用 GPU。
  • 模型负责根据输入计算下一个 Token 的概率。

1. 请求到达模型厂商之前

用户在客户端里提出问题后,通常不会立刻把原始文字发送给模型。客户端或 Harness 还要做一些准备工作:

  1. 根据用户选择、Agent 配置或路由规则确定模型。
  2. 获取这个模型的上下文上限、输出上限和能力配置。
  3. 选择历史消息、记忆、Skill、工具定义和附件。
  4. 使用对应 Tokenizer 估算输入长度。
  5. 必要时压缩、裁剪上下文,并给输出预留空间。
  6. 组织最终 API 参数并发出请求。
原始会话和资料
      ↓
Harness 选择与组装
      ↓
本次真正发送的上下文
      ↓
模型 API

这里的模型路由不一定调用模型。简单场景可以使用普通程序规则,例如按任务类型、成本、延迟和模型能力进行选择;只有语义难以判断时,才可能额外调用一个分类模型。

API Key 主要用于证明调用者身份和计算配额。它不是模型的记忆,也不代表一个模型实例或一个会话。

2. 服务商前台:鉴权、限流、路由和排队

请求到达模型厂商后,通常先经过网关和调度层,而不是直接进入 GPU。

2.1 鉴权

检查 API Key 是否有效、是否有权调用目标模型,以及账户状态是否正常。

2.2 限流

控制请求数、Token 数和并发量,避免某个调用者占满整个集群。常见限制可以按分钟请求数、分钟 Token 数、同时进行中的请求数或账户额度计算。

2.3 路由

把请求送到支持目标模型的健康集群。这里可能综合考虑地区、模型版本、机器负载、故障状态和容量。

需要区分两种路由:

Harness 的模型路由:决定调用哪个模型
服务商的实例路由:决定送到哪台机器或哪个模型实例

2.4 排队

如果推理容量暂时不足,请求会等待;等待过久则可能超时或被拒绝。

实际上可能存在两层队列:

网关队列:等待进入可用的推理服务
引擎队列:已经进入实例,等待下一轮 GPU 计算

这一层大部分是普通代码、配置和调度算法,一般不需要调用大模型。

3. 什么是模型实例

模型实例可以理解成:模型权重已经加载到显存或内存中,并且处于可以执行推理的状态。

它不是一个用户、一个会话,也不是只能处理一个请求的进程。

多个请求共用的是:

  • 同一份模型权重。
  • 同一套 GPU 计算资源。
  • 推理引擎组织出的计算批次。

每个请求独立保存的是:

  • 自己的输入上下文。
  • 自己的 KV Cache。
  • 自己的生成参数和停止条件。
  • 自己已经生成的 Token。

image.png

所以,一个模型实例可以同时维护很多请求。它的上限不是一个固定数字,而是受到模型大小、GPU 数量、显存容量、平均上下文长度、输出长度、延迟目标和推理引擎效率共同影响。

上下文越长,每个请求占用的 KV Cache 通常越大,同一实例可以同时容纳的请求就越少。

4. 推理引擎怎么让多个请求一起运行

模型只定义怎么计算,推理引擎负责把真实请求组织成 GPU 能高效执行的任务。

一轮生成大概是:推理引擎把当前活跃请求组成一个 Batch,让 GPU 一起计算下一个 Token;完成的请求退出后,新请求可以立即补入。

image.png

这种方式常被称为连续批处理。它不是等一批请求全部结束后再处理下一批,而是在每一轮生成之间动态加入和移除请求。

GPU 擅长同时执行大量相同类型的矩阵计算。推理引擎把不同请求当前需要计算的 Token 组织到一起,GPU 就能并行处理,而不需要给每个请求单独准备一套模型。

因此,多请求共享的不是彼此的上下文,而是模型权重和一次批量计算的机会。

5. KV Cache 到底是什么

Transformer 在生成新 Token 时,需要使用前面所有 Token 的注意力信息。如果每生成一个 Token 都重新计算全部历史,成本会非常高。

KV Cache 会保存历史 Token 已经计算出的 Key 和 Value。下一轮生成时,只计算新增 Token,再读取前面的缓存。

已有 Token:今天 / 天气 / 很好
已有 KV:   K1V1 / K2V2 / K3V3

新增 Token:啊
只计算新的 K4V4,再和已有 KV 一起参与注意力计算

KV Cache 不是模型权重的一部分,也通常不会写进模型文件。更准确的说法是:

KV Cache 位于模型权重之外、推理引擎之内,是请求运行时产生的临时状态。

模型结构决定计算中需要 K 和 V,推理引擎负责给缓存分配空间、分页、复用、迁移和释放。

6. 前缀缓存为什么可以命中

如果两个请求开头的 Token 完全一致,推理引擎可能复用这段前缀已经生成的 KV Cache。

请求 A:系统提示 + 工具定义 + 用户问题 A
请求 B:系统提示 + 工具定义 + 用户问题 B
        └────相同前缀────┘

它并不是看到文字意思相近就命中,而是通常需要满足:

  • Token 前缀完全一致。
  • 模型和版本一致。
  • Token 位置及相关推理配置兼容。
  • Adapter、多模态输入和缓存命名空间等身份一致。

命中后复用的是前缀计算,不是直接复用最终答案。后面的不同内容仍然需要正常计算。

7. KV Cache 放在显存、内存还是 SSD

最常见的分层可以理解成:

image.png

层级位置适合的数据特点
L1GPU 显存正在生成的活跃请求最快,但容量最贵、最有限
L2CPU 内存暂停或等待恢复的缓存容量更大,但搬回 GPU 有延迟
L3SSD 或远程存储冷缓存、持久化前缀容量最大,但速度最慢

不是所有推理系统都实现完整的三层缓存。最简单的实现可能只使用显存;规模更大的系统才会根据热度做迁移和淘汰。

普通服务器里的 CPU 内存,就是主板上的 DDR 内存。Mac 的 CPU 和 GPU 使用统一内存,物理边界没有独立显卡服务器那么明显,但仍然存在容量、带宽和调度成本。

缓存放在显存里会占用显存容量,也会消耗读取带宽,但不会因为“存在那里”就直接占用 GPU 计算核心。真正执行 Attention 和矩阵运算时,才会使用大量计算资源。

8. 上下文、速度和并发量的关系

模型支持更长上下文,不代表每个请求都能免费使用那么长的内容。

它们之间的关系如上图右侧所示:上下文变长后,单请求 KV Cache 变大,显存可容纳的并发请求减少;注意力计算和内存访问也会增加,因此延迟可能上升、吞吐可能下降。

因此,模型的上下文上限是一种能力边界;能否在高并发下高效运行,还取决于 GPU、缓存管理、批处理和服务目标。

这也是 Harness 要提前控制上下文的原因。少发送无关历史,不只是为了避免超过模型上限,也是在减少推理成本、缓存占用和等待时间。

9. Agent 场景为什么可能调用多次模型

一次普通问答可能只产生一次模型 API 请求。但 Agent 任务中,模型可能先返回工具调用,再由 Harness 执行工具,并把结果放进下一轮上下文。

用户任务
   ↓
第 1 次模型调用:决定查询工具
   ↓
Harness 执行工具
   ↓
第 2 次模型调用:分析工具结果
   ↓
Harness 发现证据不足,再执行工具
   ↓
第 3 次模型调用:形成最终回答

所以,一个用户任务不等于一次模型调用。调用几次、何时重试、是否换工具以及什么时候停止,由模型建议和 Harness 规则共同形成闭环。

10. 容易混淆的几个问题

常见理解更准确的理解
一个模型实例一次只能处理一个请求一个实例可以通过批处理同时维护多个请求
API Key 代表一个会话API Key 主要用于身份、权限和计费
多个请求共享上下文请求上下文独立,只共享模型权重和计算资源
KV Cache 是模型文件的一部分它是推理过程中生成的运行时状态
前缀缓存按照语义相似度命中通常按照完全一致且身份兼容的 Token 前缀命中
显存只存模型参数显存还可能存放 KV Cache、中间结果和运行时空间
上下文上限越大,并发能力就越强长上下文通常会增加单请求缓存和计算压力
路由一定需要调用模型大部分路由可以由规则和普通程序完成

总结

一次大模型 API 请求,可以压缩成四层:

客户端 / Harness
准备任务、上下文和模型参数
        ↓
网关与调度层
鉴权、限流、路由、排队
        ↓
推理引擎
Token、KV Cache、连续批处理、采样
        ↓
模型实例与 GPU
共享权重,并行计算各请求的下一个 Token

最核心的理解是:

模型负责计算,推理引擎负责并发,服务商前台负责流量,Harness 负责把用户任务组织成一次或多次可执行的模型调用。

把这四层分开以后,API Key、模型实例、并发请求、上下文、显存和 KV Cache 的关系就比较清楚了。