← 返回
IT技术

在人工智能系统中,部署不是瓶颈,推理经济才是关键

✍️ zhirenhun 📅 2026/10/10 👁 324 阅读 ⏱ 25 分钟
在人工智能系统中,部署不是瓶颈,推理经济才是关键

介绍

搜索“如何部署 AI 模型”,每次得到的答案形状都一样。用 FastAPI 或 Flask 应用包装模型。放进 Docker 容器。推送到 GPU 实例或 Kubernetes 集群。添加健康检查。完成。

这个答案正确。它也是简单的部分。

大多数使用开源模型构建的团队在一天或两天内就能得到一个可用的端点。模型加载,请求进来,token 输出。随后第一波真实流量到来,随之出现一组不同的问题。端点在空闲期后对第一个请求的响应时间达到 90 秒。GPU 费用是估算的五倍。GPU 本身利用率只有 15%,而用户在排队等待。这些问题并非由部署步骤失误导致,而是因为没有考虑部署之后会发生什么。

本文的观点很简单:问“如何部署模型”是错误的第一个问题。正确的第一个问题是“我回答一次请求的成本是多少,为什么。”一旦你梳理了冷启动、GPU 利用率和每次推理的成本,部署决策基本就会自然得出。容器、框架和编排器只是遵循经济学的细节,而不是反过来。

这里没有逐步部署教程。网上有很多那样的教程。相反,本文将逐步讲解决定生产环境中模型是否负担得起的三个因素:模型准备好服务所需的时间,实际使用的 GPU 比例,以及把所有费用加起来后每个请求的成本。在此过程中,它用直观的数字展示了这些计算,以便你能为自己的模型进行同样的运算。

为什么部署问题感觉重要

部署问题之所以被频繁提起,是因为它是人们遇到的第一道墙。在笔记本里运行模型是一回事,让它响应他人的 HTTP 请求是另一回事。这一步涉及新工具(容器、服务框架、GPU 驱动),而这些工具本身就有棘手的地方。

但请注意,部署问题并未询问:

忽略这些问题的部署仍然能够运行,只是成本更高。这种费用不会出现在部署教程里,而是会在一个月后的发票上体现。

本文其余内容将讨论这些被遗漏的问题。

推理的成本结构(通俗解释)

在深入探讨这三个问题之前,先明确你到底在为什么付费。使用 GPU 时,你租用的是时间,而不是请求或 token。无论 GPU 每秒处理 200 个请求还是空闲等待下一个请求,计费速率都保持不变。

这一事实决定了其他一切。以下是使用整数近似值的一个粗略示例:

在这两种情况下,模型本身并未发生变化。唯一变化的是租用时间中用于有效工作的比例。这就是为什么应该关注利用率而非部署情况。

接下来的三个小节将探讨最常导致该指标偏离的三个因素。

问题一:冷启动

冷启动指的是从“请求到达但模型尚未就绪”到“模型输出第一个 token”所经历的时间。这是三个问题中最明显的一个,因为用户能够直接感受到。

时间花费在哪里

大模型的冷启动包含多个阶段,每个阶段的速度都慢于人们的预期:

  • 将权重加载到 GPU 内存。 从磁盘读取到 GPU 内存相比网络传输很快,但仍可测量;对大型模型,几十秒的延迟是正常的。
  • 框架预热。 服务框架在就绪前常会编译 CUDA 图、构建 KV 缓存池,或跑几个假批次。根据配置不同,这会额外增加 30 秒到几分钟不等的时间。
  • 把这些加起来,中等规模模型的冷启动通常需要两到五分钟;70B 模型可能更久。发送聊天消息的用户不会等那么久。

    这实际上是一个成本问题

    显而易见的办法是永不让模型处于冷状态——始终保持至少一个副本运行。这确实有效,也是大多数团队的做法。但这样意味着:无论是否有人使用,你都要为 GPU 付费 24 小时。按每小时 3 美元计算,一直开启的单个 GPU 每月约需 2,200 美元,即便尚未服务任何请求也已经产生这笔费用。

    于是冷启动问题变成了一种权衡:

    没有任何部署命令能够解决这个问题。这是一个成本决策,你需要根据流量模式来做出选择。

    实际上是什么缩短了冷启动

    如果你选择第三种方案,以下这些杠杆是关键:

    每一点都能带来实际的改进。但请注意,这些技巧在标准部署教程中很少出现,因为它们并不是关于如何让模型运行,而是关于如何让模型以低成本运行。

    问题二:GPU 利用率

    这是大多数团队都未觉察的问题,因为表面上一切正常。端点能够响应,延迟也正常。实际上 GPU 只是在做远低于其能力的工作。

    为什么在处理请求时 GPU 会闲置

    左侧:一次只处理一个请求。模型权重在每生成一个新词时都要从内存读取,此时大部分 GPU 处于空闲。右侧:一次处理 32 个请求。权重只读取一次,被所有 32 个请求共享,GPU 始终保持忙碌。硬件相同,租金相同,产出提高 32 倍。

    LLM 推理分为两个阶段。第一阶段称为 prefill,负责处理输入提示词;这一阶段计算量大,能够充分利用 GPU。第二阶段称为 decode,逐个生成输出 token。每一步都需要从内存读取完整的模型权重来产生一个 token,此时 GPU 大部分时间都在等待内存,而不是进行计算。

    如果一次只处理一个请求,decode 阶段会让 GPU 的大部分算力闲置。权重在生成每个 token 时都会被读取一次,对应单条序列。算术单元大部分时间都在等待。

    使用批处理可以解决这个问题。如果一次处理 32 个请求,每次 decode 步骤仍然只读取一次权重,但能够一次产出 32 个 token,而不是 1 个。内存开销几乎不变,而有效输出提高了 32 倍。

    这就是导致在相同硬件上运行相同模型的不同团队,每 token 成本相差悬殊的主要原因。一个团队使用 batch size 为 1,另一个团队使用 64。硬件成本相同,但产出却不同。

    连续批处理及其重要性

    简单批处理有一个弱点:批处理中请求完成时间不一致。如果一个请求需要 50 个 token,另一个需要 500 个 token,则短请求会提前结束,对应的槽位会保持空闲,直到整个批处理完成。

    现代服务框架通过连续批处理解决了这个问题。当一个请求结束时,新请求会立即占用该槽位,即便是在批处理进行中。这样 GPU 能够保持满负荷。这是 vLLM、TensorRT-LLM、SGLang 等框架相比原始 PyTorch 循环能够显著提升性能的主要原因之一。它们并没有让模型运行得更快,而是提高了 GPU 的利用率。

    内存才是真正的瓶颈

    批次大小受 GPU 显存限制。每个活跃请求都需要为其 KV 缓存分配空间,KV 缓存存储中间注意力值,以免为每个新 token 重新计算。KV 缓存会随序列长度和批次大小而增长。

    具体来说:

    这就是为什么量化能提高利用率,而不仅仅是减少冷启动。更小的权重为 KV 缓存留出更多空间,从而允许更大的批次,进而提高吞吐量,进而降低每个 token 的成本。一次改动就能改善三个指标。

    衡量它

    如果不进行测量,就无法提高利用率。值得跟踪的指标有:

    有了这四个指标,你就能判断自己是否在为一个几乎不使用的 GPU 付费。

    问题三:每次推理的成本

    进行算术运算

    每个请求的成本可以用一个简单的公式来表示:

    cost per request = (GPU hourly rate / requests served per hour)
    

    分母是所有复杂性所在。每小时处理的请求数取决于利用率、批次大小、平均提示词和输出长度,以及在这一小时中GPU实际处于活跃状态并接收流量的比例。

    以下是一个使用整数的示例:

    现在是同样的配置,但流量低且批处理不佳:

    模型相同、硬件相同、部署相同。每请求成本相差十三倍,这完全取决于 GPU 每小时租用时间内完成的工作量。

    影响该数值的因素

    根据该公式,以下因素会影响每次推理的成本:

    这些并不是通常意义上的部署选择。它们属于模型、数据和容量的决策。但它们决定了账单。

    与 API 的对比

    当你获得自己部署的实际每 token 成本后,可以将其与托管 API 定价进行比较。这种比较常常令人谦卑。托管提供商在众多客户之间保持非常高的利用率,因此其每 token 价格可能低于利用率低的自托管 GPU。

    常见的模式:

    跳过这一步的团队常常自托管过早,付出的成本高于使用 API,进而认为开源模型很昂贵。其实模型本身并不贵,是闲置的 GPU 导致了高成本。

    把三者结合起来

    这三个问题相互关联,而这种关联正是本文要点。

    按此顺序阅读,部署决策放在最后。你根据能承受的每请求成本来选择模型大小、精度和服务框架。你根据流量形状和冷启动所需时间来决定保持温暖的副本数量。只有在这之后,你才会确定容器的外观以及运行位置。

    以下是按应提问顺序排列的问题序列:

    第七步是教程所涵盖的步骤。第一步到第六步决定了第七步是否能得到你负担得起的运行结果。

    结论

    问“我该如何部署一个 AI 模型”之所以常见,是因为它是第一个可见的障碍,也是最容易跨越的障碍。一个容器、一个服务框架和一个 GPU 实例就能让模型在下午内开始响应请求。但那下午不会告诉你每个请求的成本到底是多少,或者为什么会是这样。 在生产环境中运行模型的真正工作,不是让它启动起来,而是让租用的 GPU 保持足够忙碌,以至于租金值得付出。这就需要弄清楚冷启动时间花在了哪里,并决定是为温备副本付费,还是通过技术手段加快启动。这就需要测量利用率,认识到一次只服务一个请求的 GPU 大部分时间是空闲的,即便看起来很忙。还有就是用真实吞吐量的数字,而不是基准测试数字,来计算每个请求的成本,并诚实地与其他方案进行对比。 做这项工作的团队在部署选择上与不做这项工作的团队不同。他们会选用更小或经过量化的模型,因为算算后发现更大的模型不值得。他们会减少温备副本的数量,因为他们把冷启动时间压缩了。他们会使用支持连续批处理的服务框架,因为他们观察到批次大小一直停留在两。他们的部署看起来不同,但这种差异并不是来自更好的部署教程,而是源于首先考虑经济问题。 所以下次当有人问“我该如何部署这个模型”时,不妨把问题换成“一次请求的成本是多少,哪些因素决定了它。”部署方案自然会随之而来。你实际上在设计的,是账单。

    参考文献

  • Verma, S. 和 Vaidya, N.(2023)。《掌握大模型技术:推理优化》,NVIDIA 技术博客。
  • Agarwal, M.、Qureshi, A.、Sardana, N.、Li, L.、Quevedo, J. 和 Khudia, D.(2023)。《大模型推理性能工程:最佳实践》,Databricks。
  • Hugging Face。《面向速度与内存的大模型优化》,Transformers 官方文档。
  • Frantar, E.、Ashkboos, S.、Hoefler, T. 和 Alistarh, D.(2022)。《GPTQ:面向生成式预训练 Transformer 的精准训练后量化》。
  • Lin, J.、Tang, J.、Tang, H.、Yang, S.、Chen, W.-M.、Wang, W.-C.、Xiao, G.、Dang, X.、Gan, C. 和 Han, S.(2023)。《AWQ:面向大模型压缩与加速的激活感知权重量化》。
  • ——

    广告 广告
    🧑‍💻

    zhirenhun

    一个热爱技术的程序员,喜欢分享前沿AI知识和开发经验。