返回 DailyX Article2026年9月22日
文章封面图:推理服务商的请求路径示意

如何打造一家推理服务商

How to Build an Inference Provider

Ddanialhasandanialhasan
内容摘要一位一线工程师写给同行的端到端指南:先定义推理服务的边界,在选技术栈之前量化工作负载并设定服务级别目标,再跑通认证、准入、路由、调度、交付的完整请求路径,用好前缀缓存、连续批处理、量化与投机解码,守住容量规划、自动扩缩与失败语义,最后以合格结果的单位成本衡量这门生意是否成立,并给出第一版的最小上线清单。
核心要点(3条)

核心要点(3条)

  1. 1先定义工作负载与服务级别目标,技术栈选型必须服从实测出来的需求。
  2. 2为队列设上限、用好前缀缓存,按合格结果核算成本而非按 token 定价。
  3. 3过载、GPU 故障与错误发布的处理方式本身就是接口的一部分,必须提前设计。
查看原文

FULL TEXT

完整正文

How to Build an Inference Provider

AI 应用需要模型结果按时到达、满足质量要求,并符合预算。推理服务商提供的正是让这一切成为可能的服务。本文讲解如何构建这样一个服务,从第一个客户工作负载,到部署、容量和运维。

《A Beginner’s Guide to Inference Engineering》(推理工程入门指南)介绍了模型执行、硬件限制和性能实验。本指南则讲述围绕这些工作的服务。

从客户需要的服务出发

设想一个构建文档助理的软件团队。它的应用会找出相关的文档摘录,把这些摘录和一个问题发送给你的服务。你的服务运行一个模型并返回答案。应用将答案及其来源展示出来。

推理服务商为客户运营模型执行。客户可以是外部企业,也可以是同一家公司内部的其他团队。他们依赖的是一个接口、一组受支持的模型、可预期的行为,以及有人对故障负责。

要明确这条边界。在这个例子中,客户负责文档检索和访问权限;服务商负责请求准入、模型执行、响应交付,以及约定的运行限制。两个团队都要检验答案是否有所提供的文档支撑。仅靠模型执行无法保证引用正确。

业务在服务客户的过程中会产生问题。服务商团队负责其中特定的一类:排队的请求、失败的执行、不兼容的更新、数据隔离,以及可用容量的成本。这些问题决定了工程工作的内容。

当可衡量的需求足以证明其必要时,再构建专用服务:比如必须有某个特定模型、需要掌控部署、存在数据约束,或者在预期负载下更具成本优势。在需求和用量尚不确定时,使用现有的服务商可能仍是更好的选择。

先定义工作负载,再选技术栈

工作负载描述的是服务必须处理的请求以及这些请求到达的方式。两个客户可能调用同一个模型,却需要不同的系统。

对于文档助理,要记录输入长度、输出长度、并发请求数和到达速率。要涵盖长文档、重复出现的上下文、繁忙时段和空闲时段。还要明确用户需要的是文本流,还是应用必须等到完整答案才能继续。

设定质量底线:服务必须保持的最低结果质量。用有代表性的文档测试答案,要包括证据缺失、段落相互冲突,以及模型应当拒答的问题。验收样例要与调优样例分开。

设定服务级别目标(SLO):一个可衡量的运行目标。例如,规定在给定负载下必须在所选时间内完成的请求所占的比例。明确输入大小、输出大小、并发数、失败率和成本方面的限制。脱离工作负载谈延迟目标是不完整的。

专业化源自这些需求。文本生成、转录、图像生成、向量嵌入和机器人策略有不同的工作单元和截止时间。私有模型托管还会增加模型访问、版本管理和客户隔离方面的要求。一个服务商可以服务多个类别,但每个类别都需要各自的容量依据。

就接口和数据契约达成一致。定义请求字段、流式行为、错误、取消、数据保留,以及允许的部署地点。在将模型作为服务提供之前,先核查其许可证。

选定一套模型、运行时和硬件配置

模型决定了可能得到什么样的结果。运行时负责加载模型并执行其运算。硬件提供内存、算力和通信。要测试这个组合。

服务副本是某个部署的一份独立运行的实例。一个副本可以使用一块 GPU,也可以使用多块 GPU。多个副本可以分别处理不同的请求。

先选择一个能通过文档问答评估的模型。确认运行时支持它的架构、输入格式和所选硬件。固定模型修订版本(revision)、分词器、提示词模板、运行时版本和部署镜像。这些细节同时影响输出和性能。

要为整个运行中的系统规划内存:包括权重、缓存的注意力状态、中间值、临时工作区,以及运行余量。键值缓存(KV cache)存储语言模型生成过程中使用的注意力状态,其内存需求随活跃工作负载的增长而增长。

在引入分布式之前,先测量单个副本。记录并发上升时的质量、响应时间、内存占用和已完成的请求数。如果模型放得下但需求超出容量,就测试增加副本。如果算上工作内存后模型仍然放不下,则考虑更小的模型、受支持的量化,或模型并行。

用每个合格结果的硬件成本来比较不同配置。峰值算力并不能告诉你有多少客户请求能按时完成。

跟随一个请求走完整个服务流程

文档助理发送来一个问题和若干摘录。服务商必须决定:能否接受这项工作、应该在哪里运行、何时执行。

认证:识别客户身份,并检查其对所请求模型的访问权限。校验请求的大小和格式。在昂贵的计算开始之前,先应用客户配额和并发限制。

准入:只接受服务在自身队列和容量策略下能够承受的工作。对超出部分,以明确的响应加以拒绝或延后。不设上限的队列会把流量尖峰变成长时间的等待和被浪费的工作。

路由:选择一个符合条件的副本。检查模型版本、位置、健康状况、可用容量以及任何可复用的状态。最短的队列并不总是成本最低的目的地。

调度:决定在副本内部接下来运行哪项已接受的工作。运行时可以把来自多个请求的工作合并进一个批次。调度器必须遵守执行和内存限制。

交付:按约定以流式输出或返回完整结果。当客户端离开时,要传播取消操作。使用有界的重试,并提供能让运维人员将客户端与服务器事件关联起来的请求标识符。不要悄悄地重新启动一个已部分交付的答案,装作什么都没有发生。

商业化的服务商还需要用量记录和计费规则。要明确失败的请求、重试、缓存输入和被取消的生成各如何计数。将客户可见的用量与执行记录进行对账。不要把私有提示词写进日常日志。

利用工作负载的结构来减少工作量

文档助理可能会用同一个文档前缀搭配许多不同的问题。这种重复带来的机会,与队列中互不相关的短提示词所带来的机会并不相同。

前缀缓存(Prefix caching)在执行条件兼容的前提下,为匹配的输入前缀复用注意力状态,从而减少重复的输入处理。私有上下文只能在正确的客户与授权边界内路由。要在缓存局部性与排队延迟之间取得平衡。

批处理(Batching)把来自多个请求的工作合并在一起。连续批处理(continuous batching)会随着请求完成、新工作进入而改变当前活跃的批次。它可以提高吞吐量,但更大的活跃批次会消耗更多内存,也可能改变响应时间。

量化(Quantization)用更少的位数存储选定的数值,可以减少内存占用和数据搬运。要重新检验任务质量,并确认运行时对该格式有高效支持。

投机解码(Speculative decoding)先提出 token,再用目标模型加以验证。当被采纳的提议所节省的工作量超过起草与验证所增加的工作量时,它可以缩短生成时间。要在目标并发下进行测试。

模型并行(Model parallelism)把一个模型的工作拆分到多个设备上。它增加了容量,但也增加了通信。更多的设备并不保证响应更快或更便宜。

阅读 vLLM 的调度器,了解 token 预算决策和缓存分配;阅读 SGLang 的基数缓存(radix cache),了解前缀匹配与淘汰机制。这些只是实现示例,并不是对你工作负载的承诺。

对于其他类型的模型,Triton 的批处理文档区分了面向无状态模型的动态批处理和面向有状态请求的序列批处理。要选择能保持模型执行要求的调度器。

每次实验只改变一个主要变量,并保持工作负载和质量检查不变。在逐一修改之后,还要测试组合后的配置,因为各项改动的影响可能相互作用。

运营部署与容量

请求路径是数据面。控制面管理这条路径所使用的配置:已部署的版本、副本数量、健康状况和发布决策。请求时的路由器直接使用这份配置,而不让每个请求都去等待部署控制器。

Ray Serve 的架构给出了一个具体例子:代理(proxy)和部署副本负责处理请求,而一个控制器负责管理部署。可以阅读控制器的实现,了解部署状态如何与运行中的服务关联起来。

自动扩缩容(Autoscaling)随需求变化调整副本数量。要使用请求形态、活跃工作量、队列等待时长和资源压力作为依据。十个未命中缓存的长提示词所需的工作量,可能超过大量命中缓存的短提示词。仅凭请求数无法确定容量。

设定最小和最大副本数、预算上限以及缩容行为。测量完整的冷启动过程:获取容量、启动机器、加载软件和权重、初始化运行时,然后通过就绪检查。新容量只有在就绪之后才能发挥作用。

对文档助理来说,早晨突发的流量高峰可能来得比新 GPU 就绪的速度更快。预热容量和准入限制必须填补这段空档。只有在首个请求的延迟可以接受时,扩容到零(scale-to-zero)才适用。

先向一小部分流量发布新模型或新运行时。将其质量、失败率、延迟和成本与已验收的版本进行比较。保留足够的容量以便回滚。进程健康检查并不能证明模型能够处理预期的请求。

让失败行为成为接口的一部分

客户需要知道当服务无法交付时会发生什么。要在事故发生之前就把这一点定义清楚。

对于过载,要限制队列长度和等待时间,让已无法满足截止时间的工作过期作废。告知客户端何时应降低流量或重试。限制重试次数并加入延迟,使重试不至于放大最初的流量尖峰。

对于运行时或 GPU 故障,要把副本从路由中移除,替换它、预热它并验证就绪状态。要决定哪些请求可以安全地重试。断开的流需要客户端显式处理。

对于一次糟糕的发布,要停止发布并恢复到已验收的版本。要测试旧部署是否仍能加载,并且还有足够的容量。如果需要进行区域级恢复,要在该区域测试备用容量、兼容的构建产物、数据规则以及流量转移。

在缓存、日志、凭据和用量记录中保护客户边界。要测试一个客户既无法消耗另一个客户的预留容量,也无法获取其私有状态。

Ray Serve 的生产指南提供了有界排队工作和背压(backpressure)的示例。背压是在告诉上游调用方:服务无法按当前速率接受更多工作。

度量客户收到的结果

既要从客户端度量,也要在服务器内部度量。上传、排队、执行和交付都会计入等待时间。

对文档助理而言,要记录到首个输出的时间和到完整答案的时间。首个 token 能让人看到进展,但需要拿到经过验证的输出的应用必须等待更久。要跟踪通过质量检查的答案所占的比例。

在每个测试负载下报告延迟百分位数。P95 是这样一个值:95% 的观测值都小于或等于它。要包括样本数、输入和输出长度以及测试时段。在报告成功响应延迟的同时,也要报告被拒绝的请求、失败、取消和重试。

要把缓存命中与未命中分开,把冷启动与预热后的运行分开。在延迟之外,还要记录排队时间和内存压力。这些度量有助于区分容量不足、模型变慢和输入分布变化这几种情况。

用总服务成本除以满足既定质量和截止时间标准的结果数量,得到每个合格结果的成本。要把运行中和空闲的硬件、网络、存储、监控以及工程运维都计算在内。要把失败的尝试计入成本。要比较正常、高峰和低需求时期。

按 token 收费和运营有盈利的容量是两笔不同的账。客户定价必须覆盖你承诺提供的服务,包括在需求低迷时仍然待命的容量。

为机器人策略调整设计

现在设想一个分拣物体的机器人。摄像头和关节传感器提供观测数据。策略(policy)是一个模型,它把这些观测数据和任务指令映射为动作。控制器再将这些动作转换为发送给机器的命令。

服务商可以在远离机器人的地方运行这个策略,比如在附近的服务器上或数据中心里。这样一来,网络延迟就成为控制路径的一部分。

OpenPI 的远程推理示例把图像、机器人状态和一条指令发送给策略服务器。服务器返回一个动作块(action chunk):一系列提议的动作。它的 WebSocket 服务器展示了观测解码、策略执行、计时和响应交付。

客户端在两次推理调用之间可以消费多个动作。OpenPI 的 ActionChunkBroker 会存储返回的动作块,并按顺序逐个提供动作。该实现会在配置的动作范围(horizon)消耗完毕后请求下一个动作块。它并不会自动建立远程推理与本地执行之间的重叠。

动作块可以降低调用频率,但也意味着提前锁定了基于较早观测生成的工作。较长的动作块可能延长策略对场景变化做出反应之前的等待时间。允许的动作范围取决于机器人、任务、策略和本地控制系统。

要测量从观测到动作的延迟、延迟的波动、错过截止时间的情况、任务成功率,以及网络中断期间的行为。要丢弃过期的命令。要把经过验证的安全行为保留在本地。返回一个动作块并不能证明在条件变化后它仍然可以安全执行。

要区分远程规划器(remote planner)和远程动作策略(remote action policy)。规划器可能向本地策略返回“拿起红色物体”这样的结果,而远程策略返回的是动作。这两种接口有不同的时序和失败要求。

OpenPI 示例展示的是一条传输和执行路径。服务商仍然必须补充认证、隔离、截止时间处理、容量控制和经过测试的恢复流程。不要假设一个参考实现服务器就是可以直接投入整个机队使用的服务。

构建第一个版本

从文档助理和一个受支持的模型开始。选定一种运行时和硬件配置。把检索保留在客户应用中,使服务商边界保持清晰。

  1. 编写请求、响应、数据和错误契约。
  2. 创建有代表性的工作负载和单独的质量测试集。
  3. 固定模型、运行时、硬件和配置。
  4. 在认证、大小限制和有界准入的保护下部署一个副本。
  5. 添加客户端计时、请求标识符、用量记录和受保护的日志。
  6. 测试正常负载、突发流量、长输入、取消、过载和副本故障。
  7. 建立可重复的发布和回滚流程。
  8. 在接入客户之前,记录可支持的负载、质量、成本和已知限制。

在你需要的层次上使用现有组件。vLLM 和 SGLang 提供模型执行和调度。Triton 支持跨多种模型后端进行服务。Ray Serve 提供分布式部署与组合。KServe 提供 Kubernetes 模型服务资源。llama.cpp 的服务器适合用来研究本地和受限部署。这些项目处于不同的层次,它们并不是六个可以互相替换的完整服务商。

第一个交付物是一个小型服务:有明确记录的容量上限、经过测量的质量、清晰的失败行为,以及经过测试的回滚。当客户需求暴露出下一个限制时,再对它进行扩展。

主要参考书:Philip Kiely 的《Inference Engineering》,尤其是关于生产环境的第 7 章。文中图表为原创插图。项目链接用于标识所讨论的实现;文中不对所提出的服务作任何性能结果声明。