
开头干这行久了有个很深的感受一说“AI Infra”大家第一反应是训练集群、万卡调度但真正到了推理这一步画风完全变了。训练再牛模型最终要以服务的形式跑起来才算落地这中间的工程问题多到让人头皮发麻——显存怎么分、并发怎么控、延迟怎么压、成本怎么算。我最近梳理了一遍自己做MaaSModel as a Service模型即服务推理基础设施的完整结构把从模型部署到对外提供服务的整条链路拆开来看发现很多环节比想象中更考验细节。这篇博文不聊训练的分布式框架那一套就聚焦在“推理服务化”这件事上把AI Infra for Inference的结构从上到下捋一遍。适合正在做模型服务化、推理加速、GPU资源池化或者准备搭建私有化MaaS平台的团队参考。咱就从用户发来一个请求开始看这个请求在后台到底经历了什么。1. 内容整体设计与思路拆解1.1 MaaS的核心矛盾不是“能推理”而是“稳定地、低成本地推理”先说个经常被低估的事实把一个大模型跑起来只要一张能用的GPU就行哪怕慢点也无所谓。但MaaS要面对的问题远不止于此——你接的是外部流量有高峰有低谷有海量并发也有个别又长又复杂的请求把显存吃穿。真实场景下一个推理服务至少要过三道坎稳定性单卡挂了不能全站挂一个请求超时不能拖垮整个Worker进程。确定性P99延迟要可控响应时间抖动不能太大否则业务方会投诉。成本GPU利用率上不去就是纯烧钱。一个token的边际成本算不清楚整个定价体系都是空中楼阁。所以我梳理MaaS结构时习惯把它分成四层来看接入与网关层、调度与路由层、执行与引擎层、观测与运维层。这四层各干各的活又相互咬合。模型推理在整个架构里是核心但绝不是全部。1.2 基于nano-vllm入门是最务实的路线关于“如何上手大模型推理”我见过很多人一上来就啃vLLM源码结果被PagedAttention和各种Kernel劝退。我的经验是先跑通nano-vllmvLLM的精简教学版再去看生产级代码。nano-vllm把关键路径抽出来了包括Continuous Batching、KV Cache管理、Prefix Caching的实现逻辑用很小的代码量说清楚核心机制非常适合用来建立推理框架的“工程直觉”。要理解MaaS推理引擎的运行机制是地基。先搞懂请求、KVCache、显存管理、Batching策略这几个概念再看网关、调度、弹性伸缩等外层设施思路就清晰多了。后面我会用大量篇幅讲这些机制。2. 核心细节解析与实操要点2.1 推理引擎选型vLLM、TensorRT-LLM、SGLang 还是自研这一节必须先讲清楚因为整个MaaS的性能上限由推理引擎决定。市面上的引擎我基本都实际部署过简单说说感受引擎优势适用场景踩坑点vLLM生态好、吞吐高、易用性强、社区活跃通用对话、RAG、Function Calling长序列场景显存碎片化问题需要调参TensorRT-LLM单卡性能极致延迟低对时延敏感的线上SLA业务图编译耗时久、灵活性差SGLangRadixAttention做Prefix Cache多轮/多请求复用很猛高并发共享Prompt、Agent类场景新框架迭代快稳定性要等版本成熟自研完全可控、可极致定制算子与调度超大厂且场景极其固定成本极高非必要不碰选型逻辑很简单90%的团队直接用vLLM就行它已经把Continuous Batching、PagedAttention这些核心技术做成开箱即用的方案了。TensorRT-LLM适合那些“硬件型号统一、请求模式稳定、对延迟极度敏感”的纯线上业务。至于自研引擎的前提是——团队有CUDA优化能力并且业务形态确实超出了开源引擎的优化边界。2.2 一个请求在引擎内部的完整旅程从Prefill到Decode这部分是理解推理Infra的重中之重所以我会拆得细一点。假设用户输入“请写一段Python代码计算斐波那契数列”引擎内部大致发生这些事Tokenization把输入切成Token序列变成模型的输入向量。Prefill阶段一次前向计算把整段输入并行算完生成首个输出Token同时产生KV Cache。这个阶段是计算密集型GPU算力吃满吞吐高。Decode阶段一个Token一个Token地往后推每步只输入最近的一个Token用KV Cache加速上下文计算。这个阶段是访存密集型瓶颈在显存带宽。流式返回每生成一个Token就通过流式接口返回给用户这就是为什么你看到ChatGPT打字是一个字一个字蹦出来的。为什么KV Cache是命门因为Decode阶段每生成一个Token都要把之前所有Token的KV Cache读出来算Attention。序列越长Cache越大显存占用涨得越快。一个7B模型FP16权重只要14GB但一个1K长度的请求叠加16个并发KV Cache就能占到好几个GB。这也是为什么我们要引入PagedAttention和显存管理。实操要点一显存分配不要贪心很多人以为模型的KV Cache显存池越大越好实际上留太小会频繁触发换入换出Swap留太大又压缩了并发上限。我常用经验值是KV Cache显存 总显存 - 模型权重大小 - 激活值预留通常1-2GB - 计算储备。具体用gpu_memory_utilization参数控制在0.85到0.92之间先跑压测再微调。2.3 Continuous Batching和PagedAttention吞吐翻倍的功臣传统Batching是等一批请求都处理完再开下一批很蠢——只要有一个长请求没走完同批的短请求只能干等。Continuous Batching持续批处理的做法是批内任何一个请求生成完毕后立刻插入新请求。这样GPU始终在干活不会出现“等最后一个长尾”的情况。衡量这个逻辑有没有做对看一个指标——MJ/s每GPU每秒生成的百万token数。在长尾请求场景下Continuous Batching能让吞吐量提升2到3倍这是MaaS盈利模型能不能成立的核心变量。PagedAttention则是把KV Cache切成分页Page来管理类似操作系统的虚拟内存分页。不必给每个请求提前分配连续的最大长度空间而是按页动态分配。缺页时还能从CPU内存换入换出。这让显存利用率大幅上升vLLM在长序列场景下还能保持稳定。实操要点二Prefix Caching别忽略对于RAG系统用户问的问题前缀经常是固定的系统Prompt“你是AI助手...”、“请基于以下文档回答...”。启用Prefix Caching前缀缓存后重复前缀的KV Cache直接跳过Prefill重算能省下30%-50%的首Token延迟。vLLM里配置enable_prefix_cachingtrue即可。代价是前缀的LRU淘汰策略要观察Cache命中和业务问法强相关别盲目开。3. 实操过程与核心环节实现3.1 平台整体架构设计从网关到GPU池讲完引擎层再往上一层看MaaS平台的健壮性。项目里我的典型架构是这样Client → API Gateway → Router/Scheduler → Engine Pool (vLLM/TensorRT-LLM Workers) ↓ Metrics/Logging/Monitoring网关层负责鉴权、限流、计费、请求灰度。这是MaaS的入口也是商业化的第一道防线。常见做法是OpenResty或Go写的轻量网关统一处理Token计量。路由与调度层这个是AI Infra for推理和普通后端服务最大的分水岭。调度器要懂模型要知道哪些GPU上跑了哪个模型、剩余显存多少、当前并发多少然后把新请求送到最优的Worker上。我常用的调度策略有三种策略逻辑适用场景Round-Robin轮询分发同模型多副本负载均匀Least-Connections按当前请求数最少分发请求长短差异大的场景Load-Aware按GPU利用率/显存余量动态分发异构GPU池、混布场景想省事就直接用KServe或Serving框架自带的Router但到了规模后还是得自己写调度器。毕竟只有自己最清楚业务的请求画像。3.2 GPU显存管理与弹性伸缩算力资源池化推理场景下GPU很贵不能让每个模型固定独占一张卡。我在项目里用到的资源池化方案是模型分片部署 显存超卖 弹性收缩。先说显存超卖。一个模型实际部署时KV Cache是动态增长的但峰值显存需求并不总是满载。可以在系统层面设置enable_gpu_memory_utilization为一个安全上限但实际请求并发跑不满剩下的显存可以临时跑小模型任务。这里要特别小心显存溢出把Worker炸掉所以需要精细化记账每个Worker启动时记录基础显存占用模型权重静态结构运行时按请求池状态的增减实时更新剩余显存新任务申请前检查“剩余显存 峰值需用 20%缓冲”否则不调度再说弹性伸缩。MaaS流量潮汐效应非常明显白天上班高峰、晚上和周末下降。我们做了按请求量自动扩缩容指标触发为GPU利用率 70%持续5分钟扩容一个副本GPU利用率 25%持续30分钟缩容一个副本。缩容前要保证当前Worker上的请求全部排空否则会有大量超时。3.3 推理任务的加速细节从量化到算力换速度推理加速的手段很多但有一条原则贯穿始终延迟和成本不可兼得必须在业务SLA下做权衡。量化是降本提效的第一步。从FP16到INT8显存立减一半吞吐最高能提升60%-80%。如果对精度要求不那么苛刻的模型AWQ或GPTQ量化是首选。4-bit量化虽然能进一步压显存但实测下来某些模型的推理质量会掉特别是数学、代码类场景建议先跑一遍评测集再上。我常用的量化选型参考模型量级推荐量化显存节省精度损失7B-13BFP16/INT80-50%几乎没有13B-70BINT8/AWQ50%-75%可接受70B以上AWQ/GPTQ 4-bit80%-90%需业务侧验证还有一个容易忽略的点Batch Size与模型并发的匹配。推理引擎里的max_num_seqs、max_num_batched_tokens这些参数直接影响吞吐。我在7B模型上实测max_num_seqs256时P99延迟能控制在1.5秒内吞吐比默认配置高45%左右但显存压力也更大得对着监控逐步上调。3.4 Serving框架与API设计细节一个成熟的MaaS平台对外API要支持的参数远不止model和prompt。我这边实际开放的能力包括流式与非流式所有模型必须支持streamtrue否则用户感知“打字机效果”就没有了长文本场景超时风险也大。参数透传temperature、top_p、max_tokens这些基础参数要透传到引擎。结构化输出支持JSON Mode和Function Calling——这是Agent类应用的刚需底层要用到guided decoding对延迟有影响。自定义停词业务方常要求“输出到某个词就停止”这些做在网关层统一处理不侵入引擎。排队与超时高峰期不能让请求直接失败要有排队机制和明确的超时反馈。我这里的逻辑是排队超过10秒就拒绝并返回503让客户端自动重试。实操要点三长连接别全链路开流式接口用WebSocket或SSE时网关到引擎之间千万注意连接池大小。我踩过一个坑网关开500个连接引擎只配了256个并发槽位结果大量连接处于半开状态P99直接飙到10秒。后来改成“网关无状态转发 引擎从连接池取连接”就好多了。4. 常见问题与排查技巧实录4.1 排查问题的方法论先测引擎再查平台我自己调试MaaS平台有一套固定流程能省下大量时间先直连引擎测绕过网关和调度器用vllm serve或在代码里直接调用引擎接口定位问题在引擎还是平台其他层。这一步能在五分钟内排除掉80%的干扰项。再压测网关用Locust或wrk单独打网关看会不会引入额外延迟。重点看网关有没有超时截断、重试风暴、连接复用失效。最后观测调度决策查日志看请求被调度到哪个Worker、当时的显存和并发快照是否有问题。全程看监控没有PrometheusGrafana这套的话几乎没法排查。必须埋的指标PV、UV、请求延迟分位TP50/TP99/TP999、GPU利用率/显存/温度、KV Cache命中率、排队等待时长、请求拒绝率。4.2 经典报错与对应解法速查表现象根因解决方式CUDA OOMKV Cache池过大或并发暴涨降gpu_memory_utilization限流接入层检测并发护栏首Token延迟飙升Prefill计算过长或Prefix Cache未命中开启前缀缓存限制单请求输入长度对超长prompt拆分长时间卡顿后超时Decode阶段单批过长检查max_num_batched_tokens开启Continuous Batching生成质量突然下降量化精度受损回退FP16量化前跑评测集多卡设备利用率不均调度策略与模型放置不均匀手动绑定模型到卡调研设计负载感知调度Worker内存上涨无法回收长连接泄漏检查连接池生命周期设置加入max_requests周期性重启Worker部分请求流式输出中断网络层缓冲导致连接被切断检查代理缓冲区配置SSE event的flush节拍4.3 一个真实案例分析混布场景下显存“吸血鬼”有一次平台同时部署了三个模型其中一个是13B的代码模型另外两个是7B的对话模型。跑着跑着突然代码模型的P99延迟从1.2秒飙到4.5秒而且一查GPU显存代码模型Worker的显存占用一直在涨。排查过程先按前面说的方法直连代码模型引擎延迟正常。回到调度器看日志发现有一个7B模型的请求被调度到了代码模型所在的卡上因为这块卡“剩余显存”刚好够。问题出在7B模型压进来的那一刻把KV Cache池的剩余页挤掉了代码模型开始频繁做Swap换页全卡性能骤降。解法就是严格的“卡级隔离 显存超售阈值收紧”同卡只能跑同优先级的服务模型异模型混布时剩余显存阈值从20%提高到40%。这个案例再次验证了那句话——调度上的宽松最终代价都是延迟和稳定性。5. 资源与成本的量化分析5.1 推理成本怎么算才准很多团队算推理成本只算GPU租赁费这是不对的。实际成本包含五块硬件成本GPU服务器折旧/租赁大头电力成本单卡功耗按300W算实际机柜还有散热开销工程成本运维、MLOps、调参的人力分摊token成本输入和输出Token都消耗时间与显存输出Token更贵因为Decode慢失败成本超时重试、排队等待、坏掉的请求占用的资源成本计算公式我习惯按“单个请求的边际成本GPU单卡时成本×请求占用时长”然后向上取整到“每百万Token成本”做定价。一个典型例子8卡A100集群跑一个70B模型月成本约5万含电力和运维日均处理1000万输入Token、300万输出Token摊下来每百万输出Token成本约20元左右。定价低于这个数就是亏本做慈善了。5.2 提效与降本的实操经验总结从实际操作角度四个最有效的降本动作模型瘦身蒸馏量化双管齐下。能用7B不跑13B能用INT8不上FP16。Batch优化调大max_num_seqs把GPU的算力和带宽榨干。前提是显存管得住。负载转移Prefix Cache的复用率做上去后大量Prompt直接跳过Prefill计算成本下降立竿见影。缩容策略非高峰时段直接停止副本切到Serverless模式——VLM的镜像能秒级起。实操要点四利用率不是越高越好GPU利用率在95%以上看着爽但这时候延迟曲线通常已经翘尾了。我一般把长稳态目标放在70%-85%。太低是浪费钱太高是拿延迟换成本效率业务SLA会出事。6. 写在最后的一个经验这些年在推理侧做Infra心里最深的一个体会是AI Infra for推理的复杂度是系统的不是单点的。引擎再快网关和调度拖后腿用户体验还是烂显存算得再精业务请求一乱照样OOM。要从整体去看整条链路哪里是瓶颈就补哪里而不是迷信某个“神奇参数”。还有一个不得不提的细节日志和监控一定从第一天就做。很多平台上线后才发现上线的推理服务像“黑盒”出了事故只能靠猜。我经历过一个凌晨事故——新版本的推理引擎在某种Transformer结构下会出现偶发死锁没有完善的消息队列和心跳监控根本定位不到。后来我们给每个Worker加了心跳和请求级全链路Trace这类问题基本都能在五分钟内圈定范围。最后分享一个小技巧如果你刚开始搭建推理MaaS不要一上来就追求全功能。先把“单模型、单卡、稳定服务”这条最小闭环跑通再逐步加多模型、多卡、弹性伸缩、租户隔离。一口吃不成胖子把地基打扎实了后面加什么功能都顺。这套结构梳理到这里希望能帮正在做这个方向的你少走一点弯路。