1. 先聊聊我为什么放弃"全家桶式云API",转投本地推理
这事得从半年前说起。当时我手头有好几个项目都依赖云端大模型API,多模态理解、代码生成、长文本摘要全往里塞,月底一看账单,心里拔凉拔凉的。更要命的是,只要上游服务一限流或者某个模型突然下架,我的业务就得跟着抖动。做过在线服务的人都知道,"依赖第三方推理能力"这件事,本质上是把系统的可用性和成本控制权交到了别人手里。
所以当AI进入本地时代这个趋势越来越明显的时候,我几乎是第一时间就决定把推理能力收归己有。自己组一台机器,把主流模型跑在本地,不光是省钱的考虑,更重要的是能拿到完整的控制权——数据不出内网、请求不排队、模型随意换。而且随着开源模型生态的爆发,本地推理早就不是那种"能跑但很勉强"的玩具状态了,很多场景下的效果已经逼近甚至追平云端旗舰模型。
但"跑通一个模型"和"搭建一个推理平台"是两码事。前者用一条命令行就能搞定,后者要把多模型管理、Agent调度、Workflow编排这些工程问题全部串起来。我开源的这个推理平台,就是在这半年里被这些问题逼出来的产物:它把多模型接入、Agent执行、Workflow编排做成了一个开箱即用的本地服务,16G显存级别的消费级显卡也能搭起来。
这篇文章我会从架构设计讲到落地的踩坑细节,动手能力强的朋友可以直接照着搭一套,不感兴趣代码的也能从里面看到本地推理平台在工程层面到底要解决哪些问题。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 平台的整体架构:多模型、Agent、Workflow 是怎么在同一套系统里协作的
2.1 核心定位:不是一个"模型启动器",而是一个"推理操作系统"
先给这个平台定个性。市面上有不少工具能做模型加载和简单对话,但它们大多数停留在"单一模型启动"的层面,离"平台"还差一个量级。我对自己这个开源项目的定位是:它应该像操作系统管理进程一样管理模型,像消息队列一样调度请求,像工作流引擎一样编排任务。
整个系统从上到下分成了四层:
- 接入层:统一HTTP接口,兼容OpenAI风格的API格式,方便迁移。
- 调度层:负责多模型路由、并发控制、请求排队。
- 执行层:跑的是Agent和Workflow运行时,也是这个平台最有价值的部分。
- 推理层:对接各类推理后端,管理显存、进程和模型生命周期。
为什么一定要做多层拆分?因为模型本身的推理和业务逻辑的执行是两套完全不同频率的事情。模型推理一次可能花几秒,而一个Agent循环可能要调几十次模型;Workflow里还会夹着普通的代码执行、外部接口调用。如果全揉在一起,出问题的时候根本没法定位是模型挂了还是逻辑挂了。
2.2 多模型管理:不是"加载多个模型",而是"聪明地分配模型"
多模型支持听起来简单,实际上有不少坑要趟。第一个问题是显存。单卡16G显存,要同时驻留一个大尺寸模型和一个小尺寸模型,就得严格控制每个模型的显存占用。我的方案是把模型按尺寸分为"常驻级"和"按需级",常驻的占住显存不动,按需的用完之后立刻释放。虽然频繁加载模型会增加延迟,但在多模型场景下,资源冲突的概率会小很多。
第二个问题是路由策略。平台内置了几种路由方式,最基础的是模型名匹配,即请求里声明要用哪个模型就路由到哪个模型;进阶一点的是按任务类型自动路由,比如意图识别类的任务默认走小模型,复杂推理默认走大模型;还有一种是按队列长度动态分配,哪个模型的积压任务少就往哪个模型上送。
我们可以看一个实际的路由配置示例,这里展示按任务类型自动路由的设置方式:
yaml复制model_router:
default: qwen2.5-7b-instruct
task_routing:
intent_detection: qwen2.5-3b-instruct
code_generation: deepseek-coder-6.7b
visual_understanding: llava-v1.6-7b
这样的设计带来一个很直接的好处:整体吞吐上去了,而GPU的利用率也平滑了很多,不会出现一个模型闲着、另一个
