🏠 总目录📚 本教程 01 · 训练完才是开始
📑 本页目录(点开跳转)

01 · 训练完才是开始

36 分钟 | ⭐ 先建立正确的心理预期


🎯 一句话

离线分数是在一个玻璃罩里测出来的。 一上线,玻璃罩就没了 —— 数据会变、用户会变、你的模型自己也会改变环境。 这一章讲清楚"罩子外面"到底有什么。


🏚️ 一、一个真实的翻车序列

   周一:模型上线,离线 AUC 0.82,A/B 显示 CTR +3.2%   🎉
   周三:CTR 还是 +3%,一切正常
   下周二:CTR 降到 +1.1%,没人注意(还是正的)
   两周后:CTR 变成 −0.4%,产品经理来问
   排查三天,发现:
     上游一个字段的埋点在两周前改了单位(秒 → 毫秒)
     模型没报错,特征值大了 1000 倍,它照常给出预测

🔑 注意这个故事里的每一个细节: - 没有任何报错、没有告警、服务正常、延迟正常 - 离线指标依然很好(因为离线用的是旧数据) - 发现问题的是产品经理,不是你的监控 - 排查花了三天,而问题已经存在两周

这一套教程存在的全部理由,就是把上面每一环都补上。


🧊 二、"玻璃罩"里有哪些假设

训练时你默认成立、上线后全都可能不成立的四条:

假设 上线后为什么会破
训练和线上是同分布的 用户在变、季节在变、竞品在变、你自己的模型在改变用户行为 ⭐
特征算法两边一致 训练用离线批处理、线上用实时流,两套代码 💀
标签是及时且正确的 退货要等 7 天、欺诈要等 30 天、有些标签根本不会来
每个样本独立 用户会被同一个模型反复影响;A 用户的行为影响 B 的推荐

🔗 第一条的一个特殊形式你已经见过推荐算法第 2 章的反馈闭环 —— 模型决定推什么 → 用户只能对推的东西反馈 → 反馈变成训练数据模型在改变自己的训练数据。 这在推荐系统里最明显,但绝不只有推荐系统有。


📉 三、模型变差的四种方式(要能分清)

   ① 数据管道坏了      ← 突变,最容易查,但常常没人发现
        埋点改了、上游表没跑、字段类型变了

   ② 数据漂移          ← 渐变,输入分布变了
        用户群变了、新品类上线、疫情/大促这类外部冲击

   ③ 概念漂移          ← 渐变,输入→输出的【关系】变了 ⭐ 最难
        同样的用户特征,现在的购买意愿和半年前不一样了

   ④ 反馈闭环退化      ← 自己造成的
        模型只推它熟悉的 → 数据越来越窄 → 越来越窄

💡 一个区分它们的关键提问

问题 ① 管道 ② 数据漂移 ③ 概念漂移
输入特征分布变了吗 ✅ 突变 ✅ 渐变 ❌ 没变
输入→输出的关系变了吗 ✅ ⭐
重新训练能修好吗 要先修管道

最后一行最重要管道坏了的时候重训练是有害的 —— 你会把错误的数据学进模型, 从"临时故障"变成"永久固化"。 🔗 第 16 章会讲重训练前必须做的检查。


🎯 四、上线后你实际在优化的东西变了

训练时:让测试集上的 AUC / loss 最好 上线后:

业务指标(CTR、GMV、留存)↑ 你真正被考核的模型指标(AUC、准确率)↑ 你能直接控制的但它受一百个因素影响,你的模型只是其中之一
⭐ 这条虚线不是必然的:AUC 涨了但 CTR 没涨,是常态而不是意外 —— 整套《模型上线之后》都在处理这根虚线上的问题。

三个常见的断裂原因

断裂 说明
优化了错的指标 AUC 关心全局排序,但用户只看前 3 个 → 该看 NDCG@3
提升发生在不重要的地方 模型在长尾上变准了,但流量都在头部
有别的因素同时在变 运营做了活动、竞品降价、季节变了 —— 这正是第 12–15 章要解决的

🧭 五、这套教程的五个动作

① 放出去 安全地把它暴露给流量
  • 灰度 / 影子 / 回滚(第 3 章)
② 看得见 知道它现在是什么状态
  • 三层监控 / 漂移检测(第 5-8 章)
③ 说得清 出问题时能定位到原因
  • 归因 / 排查(第 9-11 章)
④ 证得了 证明提升真的是你带来的
  • 实验 / 因果推断(第 12-15 章)
⑤ 活得久 让它能一直跑下去
  • 重训 / 回溯 / 成本(第 16-19 章)

💡 这五个动作是有顺序的没有②就做不了③,没有③就做不了④。 很多团队直接跳到④(做 A/B 证明效果),结果因为没有②③, 实验跑出负向时根本不知道是模型不行还是数据坏了。


⚖️ 六、一个务实的提醒:不是所有模型都值得这套

你的场景 建议投入
一次性分析 / 内部报表 🟡 只要能复现就够(第 17 章)
内部工具,用户是同事 🟡 加个基础监控(第 5 章)
面向用户、影响收入 整套都要
涉及钱 / 健康 / 安全 ✅ 整套 + 合规审计(第 19 章)

判据出错后多久会被发现、发现时已经影响了多少人。 这两个数决定了你该投多少 —— 而不是模型有多复杂。


🏚️ 七、另外两个真事故:静默的另外两种形状

第一节那个"单位变了"只是一种形状。下面两个的样子完全不同, 但共同点一模一样:没有任何东西报错。

💀 事故 A:模型五周没更新,没人知道

   第 0 天    发布流程重构,部署脚本里模型路径被写死成 v3
   第 1 周    团队上线 v4 —— 指标"没什么变化"
              → 归因成「这次改动本来就不大」
   第 3 周    上线 v5,还是没变化
              → 开始怀疑「是不是特征已经到顶了」
   第 5 周    有人手工核对线上版本号:一直是 v3  💀

   代价:五周迭代全部白做

这个事故最贵的部分不是那五周,是它差点改变了团队的技术判断。 「改了没效果」被解释成「这个方向不行」,而真相是改动根本没生效。 🔗 这就是第 5 章模型版本号放进最小监控清单的原因 —— 一个五分钟能加的指标,挡掉的是一个季度的错误结论。

💀 事故 B:静默降级 + 一个"说得通"的解释

   特征服务读不到当天分区时,代码里有个兜底:用昨天的值
   → 这个兜底从来没有任何告警

   国庆假期,上游调度没跑 → 连续 3 天用的都是 9 月 30 日的特征
   → CTR 从 4.1% 掉到 3.8%(相对 −7%)
   → 团队结论:「假期效应,正常」            ← 💀 归因错了
   → 假期结束 CTR 自己回来了,更坐实了这个结论
   → 接下来两周,团队在做「节假日专用模型」

   真相:三天前的一次调度失败,两分钟就能修
这个事故的伤害 说明
直接损失 3 天 × CTR −7%
归因损失 两周人力投在一个不存在的问题
信任损失 之后每次指标波动,第一反应都是「是不是假期」

一个通用教训「有一个说得通的解释」不等于「找到了原因」。 掉点时最危险的不是找不到原因,而是太快找到一个合理的原因 —— 因为找到之后,人就停止找了。 🔗 第 11 章给的排查流程,本质就是逼你在下结论前排除其他可能


📏 八、把这些串起来的一个数字:发现延迟

发现延迟 = 问题真正开始的时刻 → 有人知道它的时刻。

问题类型 没有专门监控时的典型发现延迟 通常谁先发现
服务挂了 / 500 暴涨 分钟级 系统告警
预测值全变成差不多的数 小时 ~ 天 运营说「推荐怎么都一样」
某个特征的单位/口径变了 1–3 周 产品经理看周报
模型版本没生效 数周 偶然核对
概念漂移(渐变型) 1–3 个月 💀 季度复盘

这张表就是本教程的路线图:越往下,发现延迟越长、代价越大、 越需要专门的手段才能看见。 你的目标不是"不出问题",是把这一列的数字压下来。 🔗 第 8 章会说明:发现延迟是衡量一个监控体系最好的单一指标 —— 比"我们有多少个告警"有意义得多。

🔨 上线第一天就该有的健康检查

不需要监控平台。一个跑在 cron 上的脚本,就能挡掉上表的前四行:

import datetime

EXPECTED_VERSION = "v5.2.1"

def health_check(pred_log, model_meta, feature_ts, base):
    """pred_log: 最近一小时的预测值数组
       base:     上线当天存下来的基线(均值/标准差)"""
    alerts = []

    # ⭐ ① 版本号 —— 挡掉事故 A 那类「改动根本没生效」
    if model_meta["version"] != EXPECTED_VERSION:
        alerts.append(f"线上版本 {model_meta['version']} ≠ 期望 {EXPECTED_VERSION}")

    # ⭐ ② 特征新鲜度 —— 挡掉事故 B 那类「静默用了昨天的数据」
    lag_h = (datetime.datetime.now() - feature_ts).total_seconds() / 3600
    if lag_h > 6:
        alerts.append(f"特征已过期 {lag_h:.1f} 小时")

    # ⭐ ③ 预测值标准差塌缩 —— 几乎总是特征大面积缺失的信号
    if pred_log.std() < base["pred_std"] * 0.5:
        alerts.append(f"预测标准差塌缩 {base['pred_std']:.3f}{pred_log.std():.3f}")

    # ④ 预测均值整体平移 —— 多半是某个特征口径变了(第一节那个事故)
    z = abs(pred_log.mean() - base["pred_mean"]) / base["pred_std"]
    if z > 3:
        alerts.append(f"预测均值漂移 {z:.1f}σ")

    return alerts

💡 这段代码不到 20 行,覆盖的是本章三个事故里的三个。 先有它,再谈监控平台。 很多团队的顺序反了 —— 花三个月搭平台,而这 20 行在第一天就能写完。


🚑 九、真出事了,第一个小时做什么

   ⭐ 第一原则:先止血,再查因。
      调查可以慢慢做,损失不会等你。
现象 第一动作 为什么
错误率 / 延迟暴涨 立刻回滚 工程指标客观,不需要讨论
预测值分布突变 立刻回滚 几乎总是坏消息,成本低
业务指标跌,但工程指标正常 先查是不是数据问题,再决定 可能是外部因素,回滚了也没用
只有某个人群跌 先按人群拆开看 可能是分流不均,不是模型问题
说不清哪里不对 回滚 回滚永远比"再观察一天"便宜

最后一行是本章最实用的一条回滚的成本是可预估的(少一次迭代),继续观察的成本是不可预估的。 🔗 怎么让回滚真的只要五分钟 → 第 3 章


🔗 十、和站内其他章的关系

相关的地方 和这一章的关系
ML基础 05数据泄漏 离线评估的坑;本教程讲上线后的
推荐算法 02反馈闭环 变差方式④的典型场景
推荐算法 12 A/B 第 12 章会讲它的深水区
推荐算法 15工程落地 推荐场景的具体版
智能体工程 16 Agent 场景的具体版

✅ 检查点

  1. 那个翻车序列里,有哪几个环节是本教程要补的?
  2. 「玻璃罩」里的四条假设是什么?
  3. 模型变差的四种方式?怎么用两个提问区分前三种?
  4. 为什么说「管道坏了的时候重训练是有害的」?
  5. 为什么 AUC 涨了 CTR 没涨是常态?(说出三个断裂原因)
  6. 五个动作为什么有顺序?跳过②③直接做④会怎样?
  7. 判断「该不该上这整套」的依据是什么?
  8. 「模型五周没更新」那个事故,最贵的损失是什么?用一个什么指标能挡掉?
  9. 「静默降级 + 假期效应」那个事故里,除了直接损失还有哪两种伤害?它给出的通用教训是什么?
  10. 「发现延迟」是什么?为什么说那张表是本教程的路线图?
  11. 20 行健康检查里的四项分别在挡什么?
  12. 真出事的第一个小时,说不清哪里不对时该做什么?为什么?
👀 答案
  1. 没有报错/告警(→监控)、离线指标依然好(→线上监控而非离线)、产品经理先发现(→告警设计)、排查花三天(→根因排查手册)、问题已存在两周(→漂移检测)。
  2. ①训练和线上同分布 ②特征算法两边一致 ③标签及时且正确 ④每个样本独立。
  3. ①管道坏了 ②数据漂移 ③概念漂移 ④反馈闭环退化。两个提问:输入特征分布变了吗(管道=突变、数据漂移=渐变、概念漂移=没变)、输入→输出关系变了吗(只有概念漂移=是)。
  4. 因为会把错误的数据学进模型,问题从"临时故障"变成"永久固化"。必须先修管道。
  5. 优化了错的指标(AUC 看全局排序,用户只看前 3 个)②提升发生在不重要的地方(长尾变准但流量在头部)③有别的因素同时在变(运营活动、竞品、季节)。
  6. 因为没有②看得见就做不了③说得清,没有③就做不了④证得了。跳过的话,实验跑出负向时根本不知道是模型不行还是数据坏了
  7. 出错后多久会被发现 + 发现时已经影响了多少人——不是模型有多复杂。
  8. 最贵的不是那五周,而是它差点改变团队的技术判断——「改了没效果」被解释成「这个方向不行」,真相是改动根本没生效。挡掉它只需要监控模型版本号(五分钟能加的一个指标)。
  9. 归因损失(两周人力投在一个不存在的问题上)和信任损失(之后每次波动都先猜"是不是假期")。通用教训:「有一个说得通的解释」不等于「找到了原因」——掉点时最危险的是太快找到一个合理的原因,因为找到之后人就停止找了。
  10. 发现延迟 = 问题真正开始的时刻 → 有人知道它的时刻。那张表越往下发现延迟越长(服务挂了分钟级 → 特征口径变了 1–3 周 → 概念漂移 1–3 个月),也越需要专门手段才能看见。目标不是不出问题,是把这一列的数字压下来。
  11. 版本号(挡「改动没生效」)②特征新鲜度(挡「静默用了昨天的数据」)③预测标准差塌缩(特征大面积缺失的信号)④预测均值漂移 >3σ(某个特征口径变了)。
  12. 回滚。因为回滚的成本是可预估的(少一次迭代),继续观察的成本是不可预估的

🛑 可以停在这里

走神救援

离线分数是在玻璃罩里测的,一上线罩子就没了。翻车序列的每个细节都值得记:没报错、没告警、离线指标依然好、产品经理先发现、排查三天而问题已存在两周——这套教程就是把每一环补上。四条会破的假设:同分布、特征算法两边一致、标签及时正确、样本独立。⭐变差的四种方式:①管道坏了(突变) ②数据漂移(输入分布渐变) ③概念漂移(输入→输出的关系变了,最难) ④反馈闭环退化。两个提问区分:输入分布变了吗、输入→输出关系变了吗。⚠️⭐管道坏了时重训练是有害的——会把错误数据学进模型,从临时故障变成永久固化。⭐AUC涨了CTR没涨是常态:优化了错的指标/提升在不重要的地方/有别的因素同时在变。五个动作有顺序:放出去→看得见→说得清→证得了→活得久没有②③就做不了④(实验负向时不知道是模型不行还是数据坏了)。判据:出错后多久被发现 + 影响多少人。💀另外两个事故模型五周没更新(部署脚本写死旧路径,三次上线"都没效果",最贵的是它差点让团队得出"这个方向不行"的错误结论——挡它只要监控版本号);静默降级被解释成"假期效应"(兜底用了昨天的特征,CTR 4.1%→3.8%,团队接着做了两周"节假日模型",真相是两分钟能修的调度失败)——⭐「有一个说得通的解释」不等于「找到了原因」,掉点时最危险的是太快找到一个合理的原因。⭐发现延迟(问题开始→有人知道)是全书路线图:服务挂了分钟级、特征口径变了1–3周概念漂移1–3个月。⭐20行健康检查先于监控平台:版本号、特征新鲜度、预测标准差塌缩、预测均值漂移>3σ。出事第一小时先止血再查因;⭐说不清哪里不对时就回滚——回滚成本可预估,继续观察的成本不可预估

下一节 👉 02-离线好不等于线上好.md

打卡记录保存在你的浏览器里,首页能看到总进度