ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

从单模型到LLM推理平台:架构演进、选型与避坑指南

从单模型到LLM推理平台:架构演进、选型与避坑指南 模型部署这件事圈里一直有个很有意思的现象单模型服务阶段大家聊的是怎么把模型跑起来恨不得用一条命令完成部署可一旦进入LLM推理平台的阶段聊的就变成了怎么让模型服务长期稳定地跑下去涉及的东西也从模型文件本身扩展到了网关、调度、监控、版本管理、推理引擎选型甚至周边应用框架。我这两年刚好完整经历了这个过程先是用SpringBoot封装了几个单模型服务后来为了支撑多模型、多租户的正式环境一步步搭起了LLM推理平台。这一路踩过的坑、做过的选型对比、最后沉淀下来的架构思路我觉得值得单独拿出来说一说——因为很多团队在从单体走向平台的路上痛点其实高度相似但网上能把这条演进路径完整讲透的内容并不多。这篇文章我会从单模型服务的常见形态讲起分析它为什么会在正式环境下撑不住然后给出LLM推理平台的关键架构拆解包括推理引擎、GPU资源编排、统一网关、测试回归这些核心模块。最后我会把从单体到平台的迁移路线和避坑清单整理出来。无论你目前是刚把第一个模型部署上线还是已经在评估要不要建设推理平台这篇文章应该都能给你一个比较完整的参考坐标系。1. 单模型服务的常见形态与正式环境下的真实瓶颈先聊聊大多数团队的起点单模型服务。这个词听起来很简单——一个模型、一个接口、一个服务但实际上不同团队做出来的东西差异非常大。有的就是个Jupyter Notebook里的推理脚本有的是SpringBoot工程里包了一层HTTP接口有的已经用上了Docker和Ollama这类部署工具。我见过的真实案例基本可以归纳成三种形态。1.1 从能跑的脚本到能用的服务最原始的形态是推理脚本直接对外提供能力。比如用PyTorch写了一个推理函数通过Flask或者FastAPI暴露成HTTP接口。这种方案在Demo阶段完全够用模型文件放在本地推理函数加载一次请求进来就调用forward方法返回一个JSON结果。我当时做第一个OCR模型服务的时候就是这种结构代码量很少几十行就能跑通。但一旦放到正式环境问题就来了。首先是并发能力PyTorch的模型默认是同步推理的一个进程同时只能处理一个请求如果请求量上来要么排队要么超时。其次是部署一致性你的模型可能依赖特定版本的Python包、特定版本的CUDA库换一台机器就水土不服了。我和不少团队聊过普遍的做法是直接用Anaconda管理环境然后在服务器上手动激活环境、启动服务。这种做法的隐患在于服务器一旦重启服务不会自动恢复模型更新的时候旧版本没有保留多个人协作部署服务器上的环境很容易变得一团糟。所以在单模型服务阶段最值得做的一件事就是先把它容器化。不管你后面要不要上推理平台容器化都是必经之路。1.2 SpringBoot封装模型服务的架构与取舍在Java技术栈比较重的团队里很常见的一种做法是用SpringBoot来封装模型推理接口。这种架构的逻辑是模型推理通过Python实现但对外暴露API、做权限校验、对接内部系统的活交给Java更顺手。于是就有了一个典型的双层结构SpringBoot应用负责接收HTTP请求、做参数校验、调用Python推理服务Python侧只负责模型推理本身。我见过不少团队把Python推理服务嵌在SpringBoot进程里面通过Jython或者直接调用命令行来实现——这条路我劝你别走性能和稳定性都很难保证。更合理的方式是把Python推理做成一个独立的服务SpringBoot通过HTTP或RPC去调用。这里有一个很实用的建议定义一个统一的推理接口规范比如请求参数、响应结构、错误码都约定好这样后续接入不同模型的时候SpringBoot侧的代码几乎不用改只需要新增一个Python服务的适配器。但即便做到了这一步单模型服务的瓶颈依然是客观存在的一个模型就是一个独立的部署单元资源无法共享GPU利用率很难提上去。比如你的OCR模型和实体识别模型分别部署在两个GPU上但OCR模型的请求量是实体识别的十倍那实体识别那张卡大部分时间就是在空转而OCR那张卡已经扛到极限了。这种资源碎片化的问题靠单模型服务的思路是解决不了的必须往平台化走。1.3 Ollama、Docker与模型文件的本地化部署实践再聊聊这两年很火的本地化部署路线。Ollama的出现确实把模型部署的门槛拉低了一大截——我之前在一台树莓派5上部署YOLOv5模型折腾了半天环境后来用Docker部署Ollama模型十几分钟就搞定了。这个体验的差异很大程度上来自Ollama对GGUF格式的原生支持和自动化的模型管理。如果你也打算走Ollama路线我有几个实操建议。版本固定Ollama的镜像在持续更新不同版本的API行为可能有细微差异。记得在部署时锁定镜像版本比如用ollama/ollama:0.1.3x这样的标签而不是直接拉latest。Modelfile的用法Ollama除了直接拉模型还可以通过Modelfile来自定义运行参数比如设置温度、上下文长度、量化等级甚至可以挂载一些自定义的提示词模板。这个文件建议纳入版本管理方便回溯。端口映射和资源限制Docker启动Ollama时一定要映射好端口通常是11434并且通过环境变量限制模型能占用的最大显存或内存防止某个模型把整台机器的资源吃光。不过也要说句公道话Ollama本身更适合个人开发者和中小团队的轻量部署。它的定位是单机易用当你面对多模型、多GPU、高并发、多租户这些需求的时候Ollama能做的就很有限了。GGUF格式虽然在模型分片上做得很方便但要支撑正式环境的大流量还是得找更专业的推理方案。2. 从单体走向平台哪些痛点逼着你必须升级我经常在技术社区看到有人问我现在的团队只有一个模型在跑用得着搞推理平台吗这个问题的答案其实取决于一个关键指标——你的模型服务到底要为多少个业务方提供服务。如果你的模型只服务一个内部系统每天调用量几百次那真的不用折腾平台单模型服务完全够用。但当你遇到下面这些情况升级就不是选择题而是必答题了。2.1 并发压力与GPU资源调度的失控第一个征兆是并发压测过不了。单模型服务通常是一个进程一个模型并发上来之后要么排队要么OOM。你可能想到的解决方案是多开几个实例但问题接踵而至这几个实例怎么负载均衡同一个模型加载多份显存够不够模型在容器里的副本状态怎么同步我在压测一个命名实体识别服务的时候就遇到过这样的情况100个并发请求打过来有两个容器实例直接崩溃了但是负载均衡器还继续往崩溃的实例上派请求最后整个服务雪崩。单模型服务在并发这一关不是优化一下就能过的而是架构本身就有瓶颈——推理引擎、排队策略、健康检查、优雅启停、动态扩容这些都需要平台层的能力来支撑。第二个征兆更隐蔽但更致命GPU利用率极低。我还见过一个极端的案例某个团队有四个模型服务分别部署在四张A100上但其中一个模型每天只有几百次调用那张卡的空闲率超过95%。而另外一个模型的调用量在持续增长已经需要第二张卡了。把资源池化统一调度让所有模型共享同一个GPU资源池按需分配、按量回收这才是平台化要解决的核心问题。2.2 多模型版本管理与回滚的失控风险模型迭代的频率比很多人想象的高得多。我在做LLM应用的测试时一个新的SFT版本一天之内可能更新两三次。单模型服务的模式下版本管理基本靠文件夹日期命名来完成比如model_v1.0_1108.pt这种命名方式。一旦要回滚就得手动把旧模型文件拷贝回去、重启服务整个过程基本不可追溯。平台的另一个核心价值就是让模型版本成为一等公民每个模型可以有多个版本指定哪个是生产版本、哪个是预发布版本流量可以按比例切到新版本出了问题一键回滚。没有这套机制你永远是在用手工运维的方式对抗高速迭代早晚会出事故。2.3 接入方变多带来的认证、限流与可观测性需求单模型服务的接口可能只有一两个业务方在调用认证一般就是共享一个API Key甚至裸奔没有鉴权。但当模型能力开放给多个内部系统甚至外部合作方的时候你必须有严谨的认证、授权、限流体系。谁在调用、调了多少、配额够不够、哪些调用失败了、失败原因是什么——这些信息散落在不同的服务实例里没有统一的可观测平台排查问题的时候会痛苦到怀疑人生。我个人的判断标准是当你的模型服务开始被超过三个业务方依赖或者每周的调用量开始以十万甚至百万计或者模型数量超过五个——这三个满足任何一个单模型服务的架构就已经到了必须升级的临界点。别等到线上出事故了再补课那时候的代价往往比提前规划大得多。3. LLM推理平台的核心架构引擎、协议、调度与网关当我说到LLM推理平台的时候指的并不是某一个工具而是一整套围绕模型推理展开的基础设施。它至少要包含四个核心模块推理引擎、推理协议、GPU资源编排、统一网关。下面我把每一层拆开来详细讲。3.1 推理引擎选型vLLM、TGI与Ollama的场景对比推理引擎是整个平台的技术核心它直接决定了模型的吞吐、延迟和显存效率。目前常用的推理引擎主要有vLLM、Text Generation InferenceTGI和Ollama它们的定位差别其实挺大的。我的选择建议是正式的多模型、多租户平台优先考虑vLLM如果主要依赖HuggingFace生态TGI也很稳Ollama适合小规模、快速部署的场景。这三者最大的技术差异在于对Continuous Batching持续批处理的支持程度。传统做法是动态批处理攒够一批请求再一起推理实际效率不高因为短的请求也要等长的请求一起完成。vLLM做的很聪明的一点是引入了PagedAttention机制把显存中的KV Cache像虚拟内存一样分页管理配合continuous batchingtoken级别的调度让推理吞吐量提升非常明显在同等GPU资源下vLLM的吞吐经常可以达到普通实现的两到三倍。TGI也有类似思路但整体实现上更偏HuggingFace生态Ollama则在易用性上最友好——毕竟它面向的从来不是大规模生产场景。选型的时候不要只看Benchmark数据要结合自己的实际负载。这里有一个小经验如果你的场景是以长文本为主vLLM的PagedAttention优势会被进一步放大如果你的场景是短文本、高并发、多租户那么多实例部署和网关侧的智能路由反而比引擎本身更重要。3.2 OpenAI兼容协议为什么这几乎是唯一正确的选择在平台化建设里有一个决定会让后续省掉大量麻烦——统一对外推理协议。现在主流的做法是直接兼容OpenAI的API协议也就是/v1/chat/completions这套规范。为什么选它理由很现实生态已经用脚投票了LangChain、LlamaIndex、各种Agent框架以及市面上几乎所有的LLM应用SDK都原生支持OpenAI兼容协议。你只要把推理引擎的入口改为OpenAI格式应用端不需要写任何适配代码配置一个base_url和api_key就能接进来。我见过一些团队自己定义了一套推理协议理由是OpenAI的协议太简单不支持我们需要的额外参数。这种想法可以理解但不太建议。你完全可以保留内部扩展字段——通过在OpenAI协议的顶层加几个自定义参数比如app_id、model_version、max_tokens这些应用侧不知道也无所谓网关侧可以透传或者改写。对外保持兼容对内保留扩展这才是务实的做法。在我搭的平台里网关层实际收到的请求就是标准OpenAI格式网关负责把请求路由到不同的推理引擎再转换成各个引擎内部的格式。因为vLLM本身就支持OpenAI兼容APITGI和Ollama也提供转换层所以在网关这一层做一个统一协议的翻译器并不复杂但对业务方来说他们看到的是一套完全一致的接口——这为平台后续统一接入和纳管多模型扫清了障碍。3.3 GPU资源编排与Kubernetes原生方案GPUStack的实践推理引擎选好之后下一步要考虑的是GPU资源池怎么管理。在正式环境里GPU资源一定会被多个模型共享这时候就离不开资源编排。目前我比较推荐的方式是基于Kubernetes的GPU管理和调度尤其是如果已经在用K8s那GPU的纳管会更顺滑。不过K8s上管理GPU有一个老问题GPU资源的分片不好做。K8s默认把一张GPU卡作为一个可调度单位但实际场景里一个推理实例可能只需要半张卡或者几个模型要共享一张卡。这种情况下默认的device-plugin就无能为力了。市面上做GPU虚拟化、MIG多实例GPU调度的方案不少我实测下来觉得NVIDIA官方的GPUStack值得关注——它把GPU资源抽象成了池化资源支持MIG调度、按需分配、多租户隔离而且天然适配K8s生态。如果你的推理平台跑在K8s上GPUStack会是补上资源调度短板的重要拼图。在实际部署中我为GPU工作负载加了一个统一的标签体系比如gpu-typeampere、gpu-memory40g这样通过节点亲和性把不同的推理引擎调度到适合的GPU节点上。另一件很关键的事是给每个推理Pod设置合理的resources requests/limits——不要只写CPU和内存GPU的显存占用也要提前规划好否则K8s调度器根本不知道你的Pod会占多少显存调度结果就会很随机。3.4 统一网关认证、限流、灰度与可观测性的落地如果说推理引擎是平台的心脏那网关就是平台的门面。所有业务方的请求都从网关进出网关要给每个调用方做认证授权、配额控制、流量调度、灰度发布、日志审计。这部分如果不用平台你自己用代码去实现工程量会非常恐怖。网关层我建议优先考虑开源的API网关方案像Kong、APISIX这类或者直接在服务编排层用Envoy。做过API网关的人应该都明白网关的核心不是转发一个HTTP请求而是在转发的前后干一堆脏活累活认证与授权接入方先用API Key换取短期Token后续每个请求带着Token走。限流与配额不同业务方配额不同超过配额直接拒绝并返回明确错误码。灰度路由同一个模型的不同版本通过网关的权重路由把一定比例的流量打到新版本。可观测性每个请求到哪个引擎、耗时多少、Token消耗多少、成功还是失败全部落日志。网关配好了平台的体验会有质的提升。我做灰度发布的时候依赖的就是网关侧的路由权重配置——新版本模型上线先放5%的流量观察错误率和延迟确认没问题再逐步放大。这种能力单体服务模式根本不可能做到这么平滑。4. 平台上的LLM应用生态RAG、Agent框架与测试回归平台搭起来之后接下来的事情就变得有意思了——因为LLM推理平台不是终点它只是LLM应用的地基。真正让平台发挥价值的是地基之上跑的各种应用和生态工具。这里我重点聊聊三个和搜索热词高度相关的方向RAG与知识库工程、Agent框架集成、自动化测试回归。4.1 知识库增强RAG、GraphRAG与本体OntologyLLM的幻觉问题是绕不开的。你在平台上部署一个开源模型不做任何知识注入它只会凭训练时的记忆回答问题无法结合私有知识库。RAG检索增强生成就是为解决这个问题而来的——查询进来先检索知识库把检索到的相关片段拼进提示词让模型基于给定的上下文作答。但RAG也有它的局限性。传统的向量检索是语义相似度匹配一团文本切块之后块与块之间的关联信息会丢失。所以这两年GraphRAG受到了很多关注它把知识库先抽成实体-关系的图结构检索的时候在图里走一跳、两跳把相关子图也喂给模型。如果你的知识库领域性很强、实体关系密集GraphRAG的效果往往比纯向量检索好。再往深一点说热词里有个LLM Wiki和本体Ontology的概念。这其实是一种知识组织方式——先给领域定义一套本体明确实体类型、属性、关系再用这套本体来约束知识抽取和检索的过程。简单说本体的价值是让机器对知识领域的理解更结构化预先约定了这张图里有哪些节点、哪些边那么在做GraphRAG的时候路径检索的精准度会大大提升。我自己在做私有知识库系统的时候就把本体定义放在第一步后面无论是向量检索、图检索还是RAG管线都以这个本体为基准效果很稳。4.2 智能体框架与提示词模式Co-STAR的思路平台不光要提供模型能力还要支撑各种各样的LLM应用。这两年的应用形态已经明显从单次问答走向了智能体Agent。Agent的典型特征是可以自主规划步骤、调用外部工具、多轮交互。一个完整的Agent框架至少包含规划Planning、工具调用Tool Use、记忆Memory和反思Reflection几个模块。那个搜索热词Co-STAR框架是什么其实是一种提示词构建方法论。它把提示词拆成几个组成部分Context背景、Objective目标、Style风格、Tone语气、Audience受众、Response响应格式。实际写Agent的System Prompt时用这个框架逐项填写往往能得到更稳定、更符合预期的表现。我在调一个客服Agent的时候对比过用Co-STAR重新组织System Prompt之后回答的相关性提升非常直观。从平台视角看Agent框架更像是平台之上的应用层。你可以在网关上做统一的Agent调度入口让不同的Agent共享同一批模型和知识库同时通过平台的日志能力去分析Agent的每一轮思考过程。4.3 自动化测试与回归pytest在LLM场景下的改造平台上了生产之后模型迭代和提示词改动就不能靠肉眼看好不好来验收了。LLM输出的不确定性让传统测试框架直接失效——同一个Prompt模型两次的答案可能完全不同。这时候基于pytest扩展出一套LLM回归测试是很多实战团队的共同选择。这套测试不是简单断言返回200 OK而是要校验输出的质量维度。我会把测试维度拆成几类格式正确性输出是否包含期望的JSON字段、是否符合约定的摘要长度。内容相关性输出和输入主题是否相关可以用语义相似度或关键词覆盖率来量化。事实一致性回答的问题是否基于给定的知识库片段是否出现了幻觉内容。安全合规输出中是否包含敏感词、违禁内容可以再接一个分类器做自动审核。pytest作为底层框架的好处是生态成熟、断言灵活、和CI/CD集成方便。我一般会在测试环境里固定一套模型版本用固定的测试集跑回归每次升级模型或者改Prompt之后跑一遍全量回归用指标对比来判断改动是否可接受。单模型服务时代测试靠开发者的感觉平台化之后这套机制能让质量回归变成一个客观的、自动化的流程——这给整个团队带来的信心提升是巨大的。5. 从单体到平台的迁移路线与避坑清单讲了这么多架构层面的东西最后一个部分我想落到执行——如果你现在还在单体服务阶段想往LLM推理平台走第一步应该做什么迁移过程中最容易踩的坑又是哪些5.1 迁移的关键步骤先统一协议再造平台我见过很多团队在迁移时犯同一个错误一上来就想把所有功能都做成平台结果一两个月过去了平台没搭完原有服务也不敢动两边都在空转。我的建议是先把对外协议统一成OpenAI兼容格式再逐步引入平台组件。第一步把现有的单模型服务做一层适配对外暴露OpenAI格式的接口内部逻辑不动。这样你的业务方不需要任何改造仍然正常调用。第二步引入网关把通行流量切到网关由网关转发到后面的模型服务。这一步完成之后你已经具备了限流、认证、日志的基础能力。第三步逐步把模型服务的底层从自己写的推理脚本替换成vLLM之类的专业推理引擎——因为前面协议已经统一了替换时对业务方完全透明。第四步再把GPU编排、版本管理、灰度发布这些能力补上去。这套顺序的好处是每一步都有独立产出业务方几乎无感风险被均匀地摊开了。5.2 迁移避坑清单几个必须提前踩实的细节再分享几个我实际踩过的坑。模型的并发参数不要盲从默认值。vLLM默认的并发配置不一定是你的业务最优解短文本高并发和长文本低并发的场景max_num_seqs、max_batch_tokens这些参数要重新调。量化格式务必和推理引擎匹配。GGUF是Ollama和llama.cpp常用的格式但vLLM对GGUF的支持程度和ONNX不一样。换引擎的时候模型文件可能也要换格式转换工具重新导出一遍这个过程别嫌麻烦。GPU显存预留要留足。KV Cache是动态占用的尤其长上下文场景下显存很有可能会突然被打满。调度层的策略里一定要给每个模型保留一定的显存余量不要用满。可观测性必须在平台建设初期就接入。如果日志、指标、链路追踪这些能力是后期补课补上的前面踩过的所有坑都不会留下可供分析的数据排查问题会非常被动。安全与合规不要等平台都建设好了再补。多租户场景下每个租户的Prompt、模型输出都可能包含敏感数据网关层必须从一开始就做数据脱敏和审计。这块如果漏了后面的合规审计会非常痛苦。5.3 平台落地后的常态模型运营与持续优化平台上线之后并不意味着工作的结束反而是另一种工作的开始。我现在的日常已经从部署模型变成了运营模型关注每个模型的调用量、Token消耗、延迟分布、错误率定期用pytest回归测试集评估新版本模型根据业务方的反馈去调整Prompt和RAG管线的参数再结合GPU资源水位去做扩缩容和调度优化。这套东西做下来模型部署这件事才算真正从项目制变成了平台化。因为流转的每一个环节——从代码提交、模型上传到回归测试、灰度发布再到全量上线、监控告警——都有清晰的流程和记录而不是靠某个同事在服务器上敲命令来保证。这也是我最深的体会模型部署框架的价值从来不是把模型文件放到机器上而已而是让整个组织对模型这个资产拥有了系统化的管理能力。走到这一步你手里的就不再是几个孤立的模型服务而是一个真正能支撑业务持续迭代的LLM推理平台。
返回列表