第 24 节 · Model Pool:为什么一个模型不够¶
一个模型接不住所有活,也接不住所有风险。这一节讲模型池为什么不是「多买几个」,而是结构问题。
一、一份配置里,注册了 10 项,不是 1 项¶
我本来是想去那份本地模型的配置清单里核一个数字——那台跑 OCR 的服务占多少内存。打开之后,先被这份清单的长度绊了一下。
它注册了 10 项服务,一项一个端口:
| 用途 | 模型 | 内存 | 存活 | 端口 |
|---|---|---|---|---|
| 代码补全 | Qwen2.5-Coder-7B(4-bit) | 5.0 GB | 常驻 | 8100 |
| 语音转写(即序章里的"语音识别") | whisper-medium | 1.5 GB | 常驻 | 8200 |
| 图像理解(即序章里的"视觉理解") | Qwen2.5-VL-7B(4-bit) | 6.0 GB | 按需 | 8300 |
| 文生图(即序章里的"图像生成") | FLUX.2-Klein-4B | 8.0 GB | 按需 | 8301 |
| 语音合成 | kokoro-82M | 0.3 GB | 常驻 | 8400 |
| 意图分类 | 自研 0.8B + LoRA | 1.5 GB | 常驻 | 8500 |
| 情感分类 | 自研 0.5B + LoRA | 1.0 GB | 常驻 | 8501 |
| 文档 OCR | RapidOCR | 0.5 GB | 常驻 | 8600 |
| 协议路由(即序章里的"路由器") | 路由代理 | 0.1 GB | 常驻 | 9000 |
| HTML 渲染 | 截图服务 | 0.3 GB | 常驻 | 9100 |
十行,十个端口,从 8100 到 9100,中间不重号。
口径先钉死:这是配置里注册了 10 项,不是同时在跑 10 项。这份文件是账本,不是监控屏。
我把这张表横着读了一遍,才反应过来最容易被看漏的那件事:十项里,真正只吃文本的只有三格——补全、意图、情感。剩下的要么吃声音(转写、合成),要么吃图(图像理解、文生图、OCR),要么根本不是模型(路由、渲染)。这一个模型无论挑谁,都盖不住这张表。
而且池子还不是满的。把这张表和一份能力域矩阵对着看——矩阵一共 12 个能力域,逐格清点下来:由自研模型覆盖的只有 2 格(意图识别、情感分类)(这份矩阵的一版更新日期,早于情感分类过线;那份索引到今天还把这一格写成"待训练",跟它只记 5 个服务是同一笔没对上的账。这里按现在的口径数。),靠现成基座顶上的有 6 格(代码补全、图像理解、视频理解、语音转写、语音合成、文生图,由 5 个基座模型承担——视觉那个一人顶两格),剩下 4 格是空的(NER、摘要、音乐生成、视频生成)。2 + 6 + 4 = 12,一格不多、一格不少。空的那几格里,什么都没放。
图 A-24-1(待出):一份配置清单里的 10 项服务全景——用途、模型、内存、存活策略、端口
二、一项一个端点,两种活法¶
十个服务不是一个进程里切十份,是十个各自独立的端点。
看表里"存活"那一列:8 项常驻,2 项按需。
- 常驻的:配置里声明为常驻的,按定义是开机即载,一直占着内存,随时能答——代码补全、语音转写、语音合成、OCR、意图分类、情感分类、路由、渲染。
- 按需的只有两项:图像理解(空闲 120 秒自动卸载)和文生图(空闲 180 秒自动卸载)。它们启动时不加载模型,收到第一个请求才把权重读进内存;没人用了,自己走。
这不是偷懒,是分工。常驻的岗位像值班员,按需的岗位像外聘专家——事办完就走,桌子留着。
分界线画在哪,是有原因的。按需那两项,恰好是这张表里最重的两项:一个 6.0 GB,一个 8.0 GB,加起来 14 GB,比其余八项全部加起来还多。你不可能让两个最胖的成员同时坐在屋里。 所以它们被安排成"随叫随到"。
而最轻的模型格,轻到有点好笑:语音合成,82M 参数、0.3 GB。池子里最重的模型格是 8 GB,最轻的模型格是 0.3 GB,相差约 27 倍——但它和 8 GB 那一格,在配置里是同等的一行:各占一个端口,各干一件活。池子是按"格"算的,不是按"强的程度"排的。
三、内存是硬约束:池子是算出来的¶
现在算账。
把常驻那 8 项的内存相加:5.0 + 1.5 + 0.3 + 0.5 + 1.5 + 1.0 + 0.1 + 0.3 = 10.2 GB。
再把两个按需档算进去:+ 6.0 + 8.0 = 24.2 GB。
这个 24.2 是按配置相加算出来的预算上限,不是某一次实测的内存占用。清单上写的是一个数,机器上跑的是另一个数——这两个数我从不混着用。
这 10.2 GB 也不是平摊的。占掉一半的是代码补全那一格(5.0 GB);转写和意图各 1.5 GB;情感 1.0 GB;剩下四格——语音合成、OCR、路由、渲染——加起来才 1.2 GB。池子里真正吃内存的是"要生成"的那几格;只做转发和截图的,几乎不占地方。 所以"常驻"这个待遇,不是给模型发的,是发给"便宜到值得一直开着"的格的。
24.2 GB 是什么概念?这台机器还要留出系统自己用的部分,以及推理时必然产生的那部分缓存。池子的大小不是"我想要几个模型",是"我这几格站不站得下"。
我原先的直觉是"模型不够就多加一个"。算完这笔账才知道,加模型这个动作根本不由我说了算——内存是硬约束,池子是算出来的,不是挑出来的。
每加一格,都是一次取舍:要么砍掉一项常驻,要么把新成员改成按需,要么接受总预算再往上顶。池子的难点不是"放谁进去",是"这条线画在哪"。
图 A-24-2(待出):池子的内存预算——8 项常驻 10.2 GB,两个按需档再加 14.0 GB,上限 24.2 GB
四、池子里的成员,会被淘汰¶
池子不是一次建好就固定的。它会进人,也会清人。
清过人。有据可查的一次,是 OCR 那一格。清单里,旧方案那一行的注释还留着自白:
Unlimited-OCR(int8/bf16)实测密集文档不稳,已弃用
现在这一格里是 RapidOCR:0.5 GB、0.2 秒一页、中文置信度 0.9+。
注意它被清的理由——不是慢,是"密集文档上不稳"。普通文档它没问题;一叠密排的扫描件上去,就散架。池子淘汰成员的标准,不是平均表现,是它在最难的那批活上崩不崩。
这也让我给池子立下一条准入标准:不看你平均多好,看你在我最难的场景里过不过关。 一份好看的评测分数,挡不住一个真实文档把它打穿。
我当时没想着去救它,直接把这一格换成了另一个模型。
这件事的后果比"换了个模型"大:池子里的位置不是终身制。 一个成员能被放进来,就能因为一个真实场景里的失败被拿出去。从那天起,配置清单里每一行都不再是"选定的",而是"当前在岗的"。
五、池子不是设计出来的,是长出来的¶
说一件更根子上的事。
在这份 10 项的配置旁边,躺着另一份文件:模型资产索引,标题写着"完整目录"。翻到服务那一节,它记的是——5 个在线模型。
同一台机器,一份文件说 5 个,另一份说 10 个。这两份文件今天还摆在一起,一个 5、一个 10,账一直没对上。
多出来那 5 个是哪来的?不是某天开会定下来的。是长出来的:先要能补代码,加了第一格;要转写录音,加第二格;要合成语音,加第三格……OCR 那一格还换过人。没有一份"模型池规划",只有一份不断被追加的清单。
这就像一个仓库货架。我从没画过仓库的平面图,但东西一件件往里放;放满之后回头看,货架已经摆成了一种形状——那个形状不是设计出来的,是长出来的。
旧索引和这份新配置之间的差,本身就是证据:池子是长出来的,账本是补登的。 有人先往池子里放了十个成员,很久以后才有人去改那份写着 5 的目录——而且到今天,还没改完。
图 A-24-3(待出):池子的生长——旧索引记 5 项,配置里已是 10 项
六、为什么一个 AI System 需要 Model Pool¶
回到序章那张零件表,第一行是 Small Model / Model Pool:一个模型不够用,得按档放好几个。
这一节要说的只有一句:"不够",不是数量问题,是结构问题。
一个模型不够,不是因为它弱。是因为一个系统要干的活,本来就不止一种模态、不止一种成本、不止一种响应要求:有的活要快(意图分类),有的活要重(文生图),有的活得一直在(转写),有的活偶尔来一次(图像理解)。这四种要求,压不进同一行配置。
所以池子里必须备齐三样东西:
- 各档——从 82M 到 8 GB,不按"谁更强"排,按"这活配得起多贵的一个模型"排;
- 各存活策略——常驻还是按需,由"它多久被叫一次"和"它有多重"一起定;
- 各端点——一项一个端口,互不牵连,换一格不动其他九格。
这三样凑齐,才做得到一件事:换掉池子里的一个成员,不用动其他九个。
多买几个模型不是池子;多买几个模型,只是多花几份内存。 池子是把"谁在岗、谁待命、谁可以被换掉"这三件事,写进配置里。
它在链上的位置是第三格:先是 Model,再是 Small Model(池子里放谁、按什么标准放),然后才是 Model Pool(把它们编排成一池)。再往下是 Router——池子回答"有哪些人",路由回答"这一单派给谁"。没有池子,路由无从谈起;有了池子而不路由,就是一屋子人干等着。
数据与出处¶
- 本机模型配置清单(10 项服务注册、各端口、内存数值、常驻/按需标记、两项按需的空闲卸载秒数、Unlimited-OCR 弃用的注释与 RapidOCR 的性能描述)
- 模型资产索引(服务一节记 5 个在线模型、能力域矩阵、更新日期)
- 池子内存的两个数(常驻 10.2 GB / 含按需上限 24.2 GB)由配置清单中各项内存数值相加得出,为按配置计算的预算值,非实测占用
- 内存口径:本节 10.2 GB / 24.2 GB 是"纯权重按配置相加"的预算值,不含系统占用与推理缓存
本节所有数字均来自本机的模型配置清单与资产索引,读者拿同一份配置可以复算。