第 23 章 / 共 57 章 · 约 5 分钟
ML 系统设计框架
ML 系统设计面试(常见于机器学习工程师岗位)同样是 45–60 分钟、一句话的题目,比如“设计视频首页推荐”“设计支付欺诈检测”。和传统系统设计相比,面试官更关心:你能不能把业务目标翻译成可以训练的 ML 任务,标签从哪里来,用什么特征,怎么离线和线上评估,模型上线以后怎么提供服务、怎么发现它变差。
基础设施仍然重要,但通常只占一部分时间。架构图画得再漂亮,标签定义错了,整个系统也是在优化错误的目标。
1. 六个步骤与时间分配
| 步骤 | 时间 | 产出 |
|---|---|---|
| 1. 需求与业务目标 | ~5 分钟 | 业务指标、规模、延迟、范围 |
| 2. 问题形式化 | ~5 分钟 | ML 任务类型、标签定义、输入输出 |
| 3. 数据与特征 | ~10 分钟 | 数据来源、样本构造、特征列表 |
| 4. 模型 | ~10 分钟 | 基线和主模型,以及选择理由 |
| 5. 训练与评估 | ~8 分钟 | 数据切分、离线指标、A/B 方案 |
| 6. 服务与监控 | ~7 分钟 | 在线推理链路、监控、重训与兜底 |
查看图表源码
flowchart LR
accTitle: ML 系统设计的六个步骤
goal["需求与业务目标"] --> frame["问题形式化"] --> data["数据与特征"] --> model["模型"] --> evalx["训练与评估"] --> serve["服务与监控"]
serve -->|"线上数据和新标签"| data
最后一条回边是 ML 系统和普通服务最大的不同:模型上线后产生的数据,会成为下一版模型的训练数据。
2. 需求与业务目标
先问清楚“成功”是什么意思。以视频推荐为例:
- 业务目标:提升用户的长期活跃和满意度,而不是单纯多几次点击
- 规模:日活、候选物品数量、每秒请求数
- 延迟:推荐接口 p99 在 200 ms 以内,留给模型的可能只有几十毫秒
- 约束:新用户和新物品(冷启动)、内容安全、隐私、地区合规
- 范围:说明不做什么,比如不设计视频上传和转码
业务指标往往无法直接优化(“30 天留存”要等 30 天才知道),所以要找一个代理目标,比如“这次推荐被点开并观看超过 30 秒的概率”。主动说出代理目标和业务目标之间的差距:只优化点击率,模型会学会推标题党。
3. 问题形式化
把业务问题翻译成 ML 任务:
| 任务类型 | 例子 | 输出 |
|---|---|---|
| 二分类 | 点击预估、欺诈检测 | 概率 |
| 回归 | 到达时间、观看时长 | 数值 |
| 排序 | 搜索结果、推荐列表 | 物品的相对顺序 |
| 多任务 | 同时预测点击、时长、点赞 | 多个输出加权组合 |
标签定义要具体:“正样本 = 曝光后 10 分钟内点击,且观看超过 30 秒”;“负样本 = 曝光但没有点击”。同时说明标签什么时候到达:点击几分钟内就有,购买转化可能晚几天,欺诈的拒付要等一到三个月。
也要能说出什么时候不该用 ML:规则已经足够好、没有可用的标签、或者每个决定都必须能完整解释。
4. 数据与特征
数据来源:曝光和点击日志、用户和物品的属性表、人工标注、第三方数据。
样本构造:
- 只有被展示过的物品才有反馈,这是选择偏差;排在前面的结果天然点击更多,这是位置偏差
- 正负样本极不均衡时(欺诈约 0.1%),可以对负样本降采样,但预测概率要校正回来
特征分四类:用户特征、物品特征、上下文特征(时间、设备、位置)、交叉特征(比如用户对这个类目的历史点击率)。高基数的 ID 用 embedding 或哈希分桶。
两个最常见的失分点:
- 数据泄漏:特征必须按事件发生那一刻的状态计算(point-in-time),不能用到之后才知道的信息
- 训练与服务不一致(train-serve skew):训练时用离线 SQL 算特征,线上用另一套代码算,结果对不上。解决办法是用特征平台共享特征定义,或者在线上请求时把特征值记进日志,直接拿来训练
5. 模型
先给基线:热门榜、规则、逻辑回归或 GBDT。基线帮你确认数据和评估链路是通的,也给后面的复杂模型一个比较对象。
然后按数据量和问题选主模型:
- 表格类特征、样本在千万级以内:GBDT 往往就很强,训练快、好解释
- 海量稀疏特征和 ID:深度模型(embedding 加特征交叉层),可以做多任务
- 候选集巨大的推荐和搜索:多阶段漏斗,先用便宜的模型召回一千个左右,再用重模型精排
每个选择都说清代价:延迟、训练成本、可解释性、需要多少数据。
6. 训练与评估
数据切分按时间:用前几周训练,后一周验证。随机切分会把未来的信息泄漏进训练集,离线指标虚高。
离线指标:
| 场景 | 指标 |
|---|---|
| 分类(样本均衡) | AUC、log loss |
| 分类(正样本极少) | PR-AUC、固定误报率下的召回 |
| 排序 | NDCG@k、MRR |
| 召回 | Recall@k |
| 概率要被下游直接使用 | 校准:预测均值与实际比例之比接近 1 |
线上评估:A/B 测试才是最终裁判。定一个主指标(比如人均观看时长)和几个护栏指标(延迟、投诉率、收入)。实验至少覆盖一两个完整的周,避开新奇效应。离线指标涨了、线上没涨很常见,原因通常是代理目标与业务目标不一致,或者训练与服务不一致。
7. 服务与监控
在线还是批量:输入能提前知道、几小时的延迟可以接受(每日推荐邮件),就离线批量算好存起来;依赖实时上下文(当前搜索词、刚看完的视频),就在线推理。
在线链路:请求 → 召回候选 → 从在线特征库取特征 → 模型服务打分 → 业务规则重排 → 返回,并把曝光和当时的特征记进日志。给每一段分配延迟预算。
上线方式:影子模式(只打分不生效)→ 小流量灰度 → A/B → 全量,保留一键回滚。
监控:
- 输入特征的分布漂移、缺失率
- 预测分数的分布
- 标签到达后的真实效果(往往有延迟)
- 系统指标:延迟、超时率
兜底:模型服务超时或特征缺失时,退回热门榜或规则,不能让整个功能挂掉。重训节奏按数据变化速度定:广告可能每小时更新,推荐每天,风控每周。
8. 常见的坑
- 没定义标签和基线,开口就上深度模型
- 时间相关的数据随机切分
- 只讲离线指标,没有 A/B 方案
- 忽略训练与服务不一致、特征新鲜度
- 忽略反馈闭环:模型只能从自己展示过的结果里学习
- 没有监控,也没有兜底
9. 面试节奏建议
目标和形式化控制在 10 分钟内,这一步定错,后面全错;数据和特征通常是最能拉开差距的部分,值得多花时间;模型部分讲清基线和取舍即可,不必背论文;最后留几分钟讲上线、监控和兜底,很多候选人在这里没时间而丢分。