深入解析连续批处理、内存调度、KV缓存等LLM推理性能瓶颈与优化策略。
高吞吐 LLM 推理很少受原始算力限制。在生产环境中,吞吐量(以每秒请求数或每秒总 token 数衡量)通常受限于内存带宽、KV Cache 增长和调度开销。优化吞吐量需要在模型运行时、服务基础设施和客户端请求模式之间进行协同设计。以下各节将详细分析那些真正能推动效果的技术杠杆,以及提供商的定价模式如何决定哪些杠杆是切实可行的。
静态批处理对生成式模型来说效率很低,因为序列长度各不相同。如果一个批处理中的一个请求生成 2000 个 token,另一个生成 200 个 token,那么较短的请求会在 GPU 槽位空闲等待较长的请求完成。Continuous Batching(也称为 Inflight Batching)通过允许推理引擎在每个前向传播中驱逐已完成的序列并让新请求进入活跃批处理来解决这个问题。vLLM 和 TensorRT-LLM 等框架在服务层实现了这一机制。
对开发者而言,实际的启示很简单:优先选择原生支持 Continuous Batching 的端点,而不是自行构建客户端批处理逻辑。客户端批处理会增加单个用户的延迟并使错误处理变得复杂,而服务端 Continuous Batching 可以透明地改善吞吐量和尾延迟。
在自回归解码过程中,KV Cache 消耗的 GPU 内存往往超过模型权重本身,尤其是在长上下文和高批大小的情况下。传统分配方式为每个请求的最大序列长度预留一段连续内存块,这会浪费内存并限制批大小。
PagedAttention 将 KV Cache 分割成固定大小的块,这些块以非连续方式分配,类似于操作系统的虚拟内存。这减少了内存碎片,使调度器能够在同一块 GPU 上容纳更多并发请求。在客户端侧,你应该设置紧凑但安全的 max_tokens 限制,并利用提供商的 Prefix Caching(如果支持的话),这样共享的系统提示词或文档上下文只需计算一次,然后在多个请求中复用。
在小批大小下,推理是内存带宽受限的:从 HBM 读取权重的时间主导了计算矩阵乘法的时间。量化为 INT8、FP8 或 4 位格式可以减轻带宽压力,并在达到内存限制之前提高可运行的有效批大小。
这其中存在权衡。激进的量化可能会降低推理或代码生成质量。正确的方法是使用你自己的数据评估困惑度和任务准确率,然后部署最小可行的精度。对于高吞吐量服务,即使适度降低精度也能显著提高请求并发量,而无需额外硬件。
应用程序和推理端点之间的网络路径往往被忽视。为每个请求建立新的 TCP 连接和 TLS 握手会增加数十到数百毫秒的延迟,并在两端消耗 CPU。
使用带有 HTTP/2 或持久 keep-alive 连接的异步 HTTP 客户端。流式响应可以改善首个 token 到达时间,并在下游消费者变慢时施加背压。使用信号量限制出站并发,并将其调整到提供商的队列深度。如果你同时突增数千个请求而没有服务端流控,你会触发速率限制或导致队列积压,从而抵消任何运行时优化。
基于 Token 的定价在吞吐量和成本之间产生了直接的张力。每一种增加上下文长度、批大小或输出长度的优化也会增加 token 数量,从而增加账单。这促使团队截断提示词、将长文档拆分成更小的块,或避免 Agentic Loop,所有这些都增加了工程复杂性,并可能降低模型准确性。
Oxlo.ai 使用基于请求的定价:无论输入长度或输出 token 如何,每次 API 调用统一收费。这消除了吞吐量优化和成本控制之间的冲突。你可以将大上下文打包到单个请求中,运行多轮 Agent 工作流,或生成长的输出,而无需边际成本递增。对于高吞吐量系统,这种可预测性简化了容量规划,并使长上下文和 Agentic 工作负载在经济上变得可行。
Oxlo.ai 还为热门模型提供无冷启动,并完全兼容 OpenAI SDK,因此你可以将其插入现有的 Python 或 Node.js 流水线中,而无需重写客户端代码。你可以在 https://oxlo.ai/pricing 了解计划和详情。
以下模式使用 Python asyncio 和指向 Oxlo.ai 的 OpenAI SDK。它流式传输响应,重用底层 HTTP 连接,并使用信号量限制并发,以避免压垮端点。
import asyncio
from openai import AsyncOpenAI
# Oxlo.ai is a drop-in replacement for the OpenAI client
client = AsyncOpenAI(
base_url="https://api.oxlo.ai/v1",
api_key="YOUR_API_KEY",
max_retries=2,
timeout=60.0,
)
async def generate(prompt: str, semaphore: asyncio.Semaphore):
async with semaphore:
response = await client.chat.completions.create(
model="qwen3-32b",
messages=[{"role": "user", "content": prompt}],
stream=True,
max_tokens=512,
)
content = ""
async for chunk in response:
delta = chunk.choices[0].delta.content
if delta:
content += delta
return content
async def main(prompts: list[str]):
# Tune concurrency to your workload and endpoint capacity
semaphore = asyncio.Semaphore(32)
tasks = [generate(p, semaphore) for p in prompts]
return await asyncio.gather(*tasks)
if __name__ == "__main__":
prompts = ["Summarize the key benefits of async I/O"] * 100
results = asyncio.run(main(prompts))
print(f"Completed {len(results)} requests")
此模式的关键细节:AsyncOpenAI 客户端自动维护连接池,stream=True 减少首个字节到达时间,信号量防止无限并发从而避免尾延迟恶化。
并非所有模型的硬件饱和度都一样。较小的 Dense 模型或高效的 MoE(Mixture-of-Experts)架构通常比大型单一模型提供更高的每秒请求数。Oxlo.ai 提供 45+ 种跨类别模型,让你可以在不更改集成代码的情况下根据延迟要求调整模型大小。
对于吞吐量敏感的场景,考虑高效选项如 DeepSeek V4 Flash(MoE 架构,1M 上下文窗口)或 Qwen 3 32B(强大的多语言性能,内存压力更低)。对于复杂推理任务,当每请求延迟不如准确性重要时,DeepSeek R1 671B 或 GLM 5 可在同一端点结构下使用。由于 Oxlo.ai 按请求收费,在不同管道阶段切换模型不会使成本预测复杂化。
优化 LLM 吞吐量是一个全栈问题。Continuous Batching、PagedAttention、量化和异步客户端模式各自针对不同的瓶颈。然而,推理提供商的经济模型决定了哪些优化在规模上部署是切实可行的。基于 Token 的计量方式会抑制那些能提高系统级吞吐量的技术,如大上下文批处理和 Agentic Loop。
Oxlo.ai 基于请求的定价消除了这一限制。结合无冷启动、OpenAI SDK 兼容性和广泛的模型目录,它是构建高吞吐量、长上下文或 Agentic 生产系统的团队的强有力选择。