周三上午九点,3号会议室。
陈博士比林晨先到,正坐在会议桌旁翻看打印出来的实验数据。几页A4纸上用红色笔标注了密密麻麻的批注,看得出他昨晚花了时间。
陈博士抬起头,表情看不太出喜怒,数据我看了,先说结论。
林晨坐下来,笔记本摊开。
离线结果不错,效果和可解释性同时提升,这个方向站得住。陈博士放下笔,但是——
他顿了一下,看着林晨。
离线结果不等于线上结果。你知道ctR在离线和线上之间的差异通常有多大吗?
林晨想了想:离线和线上的ctR差异,受特征偏移、数据分布变化、以及用户实时行为反馈的影响,通常会有10%到30%的衰减。
陈博士点头,你的离线ctR提升1.5个百分点,线上可能在这个范围上下浮动。即使考虑衰减,最终线上效果也应该在1到1.5个百分点之间。这个数字在推荐系统里已经很不错了,但前提是——线上表现真的跟离线一致。
他站起来,走到白板前,写下三个词:灰度、监控、回滚。
上线之前,你要回答我三个问题。他放下笔,看着林晨,第一,你的灰度方案是什么?从多少流量开始,怎么放量?第二,你的监控指标有哪些?出了问题怎么第一时间发现?第三,你的回滚预案是什么?如果线上指标崩溃,怎么在最短时间内切回旧模型?
三个问题,像三记闷锤,砸得林晨的脑子嗡了一下。
他昨晚一直在想实验数据,想消融实验的结果,想超参数搜索的策略——但他还没有认真想过上线的事。在他的潜意识里,模型训练完了、效果验证了,上线不就是部署一下的事吗?
但他马上意识到自己错了。上线,才是最关键的一步。
在量化系统里,他也走过同样的路——回测结果再漂亮,实盘第一天就可能出现滑点、延迟、市场风格切换等回测无法预见的问题。推荐系统也是一样,离线指标再好看,线上环境有无数的变量是实验室里模拟不了的。
第一,灰度方案。林晨迅速冷静下来,翻开笔记本开始记录,我的想法是——5%流量灰度三天,观察核心指标;如果指标正常,10%流量再跑三天;然后30%、50%、100%,每次间隔两到三天。整个灰度周期大约两周。
陈博士没有表态,继续问:灰度用户的选取策略呢?随机分流还是按用户特征分层?
我倾向随机分流,但需要排除新用户和高活跃用户两类特殊群体。林晨说,新用户的推荐策略跟老用户差异很大,灰度期间不应该把新用户纳入实验组。高活跃用户对推荐结果更敏感,如果灰度组里高活跃用户占比异常,可能会放大效果。
陈博士微微点头,示意他继续。
第二,监控指标。林晨在笔记本上画了一个分层图,核心指标三层:第一层是业务指标——ctR、cVR、人均消费时长、用户留存率;第二层是模型指标——AUc、NdcG、归因一致性和稳定性;第三层是系统指标——推理延迟、qpS、GpU利用率、错误率。
归因一致性和稳定性怎么在线上监控?陈博士追问。
这个问题让林晨停了几秒。归因指标在离线评估中很容易计算,但线上环境要求实时性,Shapley值计算代价太高——虽然他们用了注意力权重归因的近似方案,但在线上每个请求都做一次归因计算,还是会有额外延迟。
线上不做实时归因计算,林晨想了想,我们在灰度期间对采样日志做离线归因评估。每天凌晨跑一批采样数据,计算归因一致性和稳定性,作为监控的补充维度。实时监控只看业务指标和系统指标。
可以。陈博士终于说了一个肯定的字,采样比例呢?
千分之一。
够了。
第三,回滚预案。林晨翻到下一页笔记,两种回滚方案。方案A:模型热切换,新模型挂载失败时自动切回旧模型,切换时间不超过30秒。方案b:流量回切,灰度期间任何一轮指标异常,立刻将灰度流量切回旧模型,回切时间不超过5分钟。两种方案都需要跟工程侧配合,提前把旧模型的部署包和配置保留在线上。
陈博士没有立刻回应。他走到窗边,看了一眼窗外的南山科技园,然后转过身。
回滚方案A,你考虑了新模型挂载失败的情况,但没考虑新模型挂载成功但效果缓慢恶化的情况。有些问题不是崩溃式的,而是渐进式的——ctR缓慢下降,用户时长逐渐萎缩,等你发现的时候可能已经影响了一大批用户。
林晨愣了一下。他说得对。热切换只能处理灾难性的失败,对于渐进式恶化,需要更灵敏的监控机制。
所以,陈博士走回桌旁,你还需要加一个监控机制——业务指标的同比环比。每天的ctR、cVR、时长,跟灰度前的同一天、同一时段做对比。如果任何指标出现连续两天的同比环比下降超过0.5个百分点,自动触发告警,人工决定是否回滚。
林晨在笔记本上飞快地记下这些要点,内心涌起一股复杂的情绪。他不是没考虑过上线风险——在量化系统里,他对风险的敏感度极高。但推荐系统的上线风险有它自己的特殊性,他还没有完全摸透。
陈博士显然看出了他的心思。
你之前做量化,风控意识很好,但推荐系统的风控跟交易系统的风控逻辑不一样。陈博士的语气缓和了一些,交易系统的风控是止损——出了问题立刻砍仓,损失可控。推荐系统的风控是纠偏——出了问题不能一刀切,因为流量切换本身也有成本。你需要的是渐进式的灰度、细粒度的监控、和快速但不粗暴的回滚。
林晨点头。这些经验,不是技术方案里能写出来的,而是在一次次上线事故中积累的。
回去写一份完整的上线方案,陈博士最后说,包含灰度计划、监控面板、回滚预案、和异常处理流程。写完先给王皓看一遍,他更了解工程侧的情况。然后再发给我review。
从会议室出来,林晨没有直接回工位,而是在走廊上站了一会儿。窗外的阳光照进来,在地板上画出一道明暗分界线。
他想起了老赵说过的——定方向、定标准、兜底。
方向定了,可解释性蒸馏的方向已经验证。
标准——实验指标、评估方法、上线标准——也在一步步建立。
但兜底,他做得还不够。上线方案里的回滚预案、监控机制、异常处理流程,就是兜底的具体体现。陈博士用三个问题帮他看到了这一点。
他回到工位,打开文档,开始写上线方案。
标题:透明蒸馏模型灰度上线方案
他一口气写了两个多小时,从灰度计划写到监控面板配置,从回滚预案写到异常处理流程,从流量分配策略写到数据采样方案。每一个细节都反复推敲,每一个假设都标注了风险点。
写到回滚预案那一段时,他特意加了一个小节:渐进式恶化的识别与处理。这是陈博士提醒他的,他不会忘记。
中间,陆小溪来问了一次:林晨,模型部署的容器化方案我写了一版,你看什么时候review?
先放着,我上线方案写完了一起看。林晨头也没抬。
陆小溪看他写得投入,没再打扰。
张明远也过来问了一次:消融实验的第二组结果出来了,要不要现在看?
发群里,我一会儿看。林晨继续敲键盘。
下午四点,上线方案的第一版完成。林晨通读了一遍,然后在文档最后加了一行:
附录:上线检查清单
他列了十二项检查点,从模型导出格式到日志埋点方案,从A/b实验分流逻辑到灰度切流配置,每一项都标注了负责人和截止时间。
十二项,不多不少。像十二道关卡,每一道都必须通过,模型才能安全地上线。
他把文档发给了王皓,抄送了陈博士。然后长出一口气,靠在椅背上闭了一会儿眼。
上线,是模型从实验室走向真实世界的最后一道门。门这边是干净的实验数据、可控的环境、可重复的实验;门那边是真实的用户、不可预测的行为、和一旦出错就无法收回的影响。
他必须确保,推开这道门的时候,手里握着的是一整套严密的方案,而不是一团模糊的信心。
晚上八点,他准时收拾东西。不是因为上线方案写完了——其实还有细节需要打磨——而是因为他跟苏婉约好了不超过九点。
走出大楼,11号线刚好进站。他挤进车厢,看着窗外的隧道灯光一闪而过。
手机上,王皓的回复已经来了:方案整体oK,有两个工程细节我标注了ment,你明天看。灰度时间线我建议压缩到十天,两周太长了。
林晨想了想,回复:明天上午对齐。
然后他切到家庭群,发了一条:快到家了,今晚讲故事。
乐乐的语音秒回:爸爸!我要听奥特曼打怪兽的故事!
林晨笑了。在他眼里,灰度上线才是真正的打怪兽——那个怪兽的名字叫,而他的武器是十二道关卡和一整套方案。