日期:2026-08-19
我们私有化底座里跑着几十个模型,尴尬的是大部分一天就几次调用,却常驻占着显存,贵的卡被这些闲模型吃满,真正忙的模型反而抢不到资源。我们算过一笔账,常驻的闲模型占掉六成显存,真正跑业务的不到十个模型在抢剩下四成,排队是常态。反过来,把低频模型回收掉之后,冷启动要几十秒,调用方直接超时,用户以为服务挂了。两头不讨好,显存账单和超时工单一起涨。有次一个高频模型因为抢不到显存,推理延迟从两百毫秒涨到两秒,业务方以为是模型退化,排查半天才发现是隔壁那个一周没被调用的闲模型占着位。
我们当时判断,显存不是大锅饭,不能让闲模型一直占着,也不能回收太狠把真用户冻住,关键在分档,把资源给到真正在干活的人。后来我们干脆把显存水位也接进告警,接近回收线时提前提醒,运营能预判哪些模型快被收了,提前安排保活。
方案分五块。一是高频模型保活:调用频率高的模型常驻显存,随时可答。二是低频模型缩容回收:长时间无调用的模型卸载显存,释放给忙模型。三是冷启动预热:回收的模型被请求触发时,异步预载权重,不阻塞首个请求太久。四是请求触发预加载:网关层感知到冷模型请求,先发预热信号再转发。五是回收策略可配:保活阈值、回收宽限期都做成后台可调,不写死,运营按业务节奏改。
最磨人的是常驻与回收的平衡。保活太多显存还是紧,回收太狠冷启动误杀用户。我们按近七天调用频率分三档:高频常驻、中频缩容保权重、低频全回收,档位随周级统计滚动调整,避免某天突发调用被打懵。
另一个坎是冷启动预热。模型权重几个 G,加载要时间,我们让预热走异步,请求进来先返回加载中状态并挂起,权重就绪再执行,而不是让用户干等超时。这个挂起有上限,超过就转提示而不是卡死,用户体验比硬超时好得多。
还有回收误杀。第一版回收阈值定太激进,把正在被定时任务调用的低频模型也收了,任务失败两次。后来给这类模型加白名单,并且回收前发即将卸载信号,预留宽限期,让在途任务先跑完。
还有一处细节,是冷启动时的首批请求怎么处理。模型权重在加载,用户请求已经进来了,如果直接拒,用户体验是服务挂了;如果干等,又超时。我们用了一个挂起加提示的策略,请求进来先返回加载中并挂起,权重就绪再执行,挂起有上限,超时就转提示而不是卡死。这个度要调,挂起太短用户没等到就走,太长又占连接。我们按模型大小设了不同的挂起上限,小模型十几秒、大模型半分钟,实测下来大多数冷启动能在这个窗口内完成,用户基本无感。少数超大模型偶尔超窗,我们才转提示并触发预热加速,这种极端情况占比很低。另外保活档位的阈值我们不是拍的,是按真实调用曲线滚出来的,每周重算一次,业务有季节性波动时档位会自动跟着动,不用人工去调,这也省了我们不少运维精力。新模型接入时默认按调用频率归档,不用我们再单独为它配策略。
案例片段(已脱敏): 模型保活与回收策略(配置节选):
tiers: hot: calls_7d > 5000 -> keep_resident warm: 500 < calls_7d <= 5000 -> keep_weights_only cold: calls_7d <= 500 -> unload preheat: async: true warmup_on_request: true grace_period: 300s whitelist: [scheduled_model_a]调整后显存常驻占用从 92% 降到 64%,忙模型推理延迟下降约 22%,冷启动触发次数从日均 40 次降到 9 次,预热命中率约 85%。案例片段(已脱敏): 某业务方每周一凌晨跑一次低频报表模型,调用量极低,按档位会被回收。第一版没加白名单,周一任务连续两次因模型被回收而失败,运维被叫起。加白名单并设五分钟宽限期后,回收信号发出时任务已在跑,跑完才卸载,之后再没出过问题,那个报表模型也第一次准时出数。
显存利用率从长期 90% 以上降到 65% 左右,忙模型平均推理延迟下降约两成。冷启动触发次数日均从 40 降到 9,预热命中率约 85%。回收误杀率从最初约 5% 压到接近零,定时任务再没因回收失败过。文中数据为项目复盘口径,已做脱敏。
显存不能让闲模型占着,也不能回收太狠把真用户冻住,按调用频率分档保活是最稳的折中。冷启动预热要走异步,别让用户干等超时,但挂起要设上限。回收阈值要留宽限期加白名单,我们误杀过两次才把这条写进规范。说到底,资源调度没有一劳永逸的参数,周级统计滚动调才是常态,这部分我们现在还每周看一眼报表,防止业务变了策略没跟上。显存和算力都是钱,闲模型占着不释放,账单会说话,这套分档回收帮我们把单位推理成本压下来一截,财务那边也能交代。