📖 AI/ML系统设计¶
⚠️ 时效性说明:本章涉及前沿模型/价格/榜单等信息,可能随版本快速变化;请以论文原文、官方发布页和 API 文档为准。
学习时间:8小时 | 难度:⭐⭐⭐⭐⭐ | 前置知识:系统设计01-06章 + 机器学习基础
🎯 学习目标¶
完成本章学习后,你将能够: - 掌握ML系统设计面试的标准框架和回答模板 - 设计端到端的机器学习Pipeline(数据→训练→部署→监控) - 理解推荐系统、搜索排序、广告系统等经典ML系统架构 - 设计高性能的模型推理服务(Serving Infrastructure) - 掌握特征工程平台(Feature Store)和ML实验平台设计 - 理解LLM应用系统架构设计(RAG、Agent、Gateway)
📋 目录¶
- 1. ML系统设计方法论
- 2. ML Pipeline设计
- 3. 推荐系统架构
- 4. 搜索排序系统
- 5. 模型推理服务
- 6. 特征工程平台
- 7. LLM应用系统设计
- 8. ML系统监控与治理
- 9. 经典ML系统设计案例
- 10. 面试准备与高频题
1. ML系统设计方法论¶
1.1 ML系统设计 vs 传统系统设计¶
| 维度 | 传统系统设计 | ML系统设计 |
|---|---|---|
| 核心挑战 | 高并发、可用性 | 模型质量 + 系统性能 |
| 数据角色 | 被动存储/查询 | 核心资产,驱动迭代 |
| 正确性 | 确定性逻辑 | 概率性预测 |
| 迭代速度 | 代码发布 | 模型训练→评估→上线 |
| 失败模式 | 系统崩溃/超时 | 静默退化(模型漂移) |
| 评估方式 | SLA/延迟/可用性 | 离线指标 + 在线A/B |
1.2 ML系统设计面试框架(7步法)¶
┌────────────────────────────────────────────────────┐
│ ML系统设计面试7步法(45分钟) │
├────────────────────────────────────────────────────┤
│ │
│ Step 1: 问题理解与业务目标(5min) │
│ ├── 业务目标是什么?(提升点击率/降低成本/...) │
│ ├── 用户是谁?使用场景? │
│ └── 成功指标?(北极星指标) │
│ │
│ Step 2: 机器学习问题定义(5min) │
│ ├── 这是 分类/回归/排序/生成 问题? │
│ ├── 输入(X)和输出(Y)是什么? │
│ └── 有无标注数据?如何获取? │
│ │
│ Step 3: 数据与特征设计(8min) │
│ ├── 有哪些数据源?(用户/物品/上下文) │
│ ├── 特征类别:稠密/稀疏/交叉/时序 │
│ └── 特征处理Pipeline │
│ │
│ Step 4: 模型选择与架构(8min) │
│ ├── Baseline方案 │
│ ├── 进阶模型(深度学习/多任务等) │
│ └── 模型复杂度 vs 延迟权衡 │
│ │
│ Step 5: 训练与评估(5min) │
│ ├── 离线评估指标(AUC/NDCG/...) │
│ ├── 在线评估(A/B测试) │
│ └── 训练策略(增量/全量/迁移) │
│ │
│ Step 6: 部署与服务(8min) │
│ ├── 推理架构(实时/近实时/离线) │
│ ├── 延迟优化方案 │
│ └── 扩展性与容错 │
│ │
│ Step 7: 监控与迭代(6min) │
│ ├── 模型监控(漂移/性能退化) │
│ ├── 数据质量监控 │
│ └── 持续训练策略 │
│ │
└────────────────────────────────────────────────────┘
1.3 ML系统中的核心权衡¶
"""ML系统设计中的5大权衡"""
TRADE_OFFS = {
"模型复杂度 vs 延迟": {
"高复杂度": "精度高但推理慢(Transformer类)",
"低复杂度": "延迟低但精度可能不够(LR/小模型)",
"解法": "多阶段架构:召回(简单) → 粗排(中等) → 精排(复杂) → 重排(业务)"
},
"实时性 vs 准确性": {
"实时特征": "最新但计算复杂(如实时CTR统计)",
"离线特征": "延迟低但有信息滞后",
"解法": "Lambda架构:离线批量 + 实时流式 双路特征"
},
"个性化 vs 冷启动": {
"强个性化": "老用户体验好但新用户无数据",
"泛化模型": "冷启动好但老用户体验差",
"解法": "ESMM多任务学习 + 基于内容的冷启动补偿"
},
"探索 vs 利用": {
"利用(Exploit)": "推荐已知高质量内容,用户满意度高",
"探索(Explore)": "推荐新内容,可能发现长尾价值",
"解法": "Thompson Sampling / ε-greedy / UCB"
},
"模型公平性 vs 收益优化": {
"纯收益优化": "可能产生偏见和马太效应",
"公平性约束": "降低短期收益但长期健康",
"解法": "多目标优化 + 公平性正则化 + 反偏见采样"
}
}
2. ML Pipeline设计¶
2.1 端到端ML Pipeline架构¶
┌─────────────────────────────────────────────────────────────┐
│ ML Pipeline 全景架构 │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────────┐ │
│ │ 数据源 │→│ 数据处理 │→│ 特征工程 │→│ 模型训练 │ │
│ │ Kafka │ │ Spark/ │ │ Feature │ │ PyTorch/ │ │
│ │ MySQL │ │ Flink │ │ Store │ │ TensorFlow │ │
│ │ S3/HDFS │ │ │ │ │ │ (GPU集群) │ │
│ └─────────┘ └─────────┘ └─────────┘ └──────┬──────┘ │
│ │ │
│ ┌─────────────────────────────────────────────┐ │ │
│ │ 模型评估 & 验证 │←┘ │
│ │ 离线评估(AUC/NDCG) → A/B测试 → 灰度发布 │ │
│ └──────────────────────┬──────────────────────┘ │
│ │ │
│ ┌──────────────────────▼──────────────────────┐ │
│ │ 模型服务 (Serving) │ │
│ │ 模型加载 → 特征获取 → 推理 → 后处理 │ │
│ │ (TensorRT/ONNX/Triton) │ │
│ └──────────────────────┬──────────────────────┘ │
│ │ │
│ ┌──────────────────────▼──────────────────────┐ │
│ │ 监控 & 反馈闭环 │ │
│ │ 数据质量 → 模型性能 → 业务指标 → 自动告警 │ │
│ └─────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
2.2 数据Pipeline设计¶
"""数据Pipeline设计模板"""
class DataPipeline:
"""
数据Pipeline三层架构:
1. 数据接入层(Ingestion):多源采集
2. 数据处理层(Processing):清洗、转换
3. 数据存储层(Storage):分层存储
"""
def __init__(self):
self.architecture = {
"数据接入": {
"实时流": "Kafka/Pulsar → Flink → 实时特征",
"批量": "MySQL/Hive → Spark → 离线特征",
"日志": "Flume/Filebeat → ES → 行为分析"
},
"数据处理": {
"清洗": ["去重", "补缺失值", "异常检测", "格式统一"],
"转换": ["编码", "归一化", "时间窗口聚合", "特征交叉"],
"验证": ["Schema检查", "分布偏移检测", "数据新鲜度"]
},
"数据存储": {
"原始层(Raw)": "S3/HDFS — 保存原始数据,不可修改",
"清洗层(Clean)": "Hive/Iceberg — 清洗后的结构化数据",
"特征层(Feature)": "Redis/DynamoDB — 线上线下一致的特征",
"标注层(Label)": "Hive — 标注数据和样本"
}
}
def design_sample_generation(self):
"""样本构建是ML Pipeline中最关键的环节"""
return {
"正样本": "用户点击/购买/完播 → label=1",
"负样本": {
"曝光未点击": "最直接,但有展示位置偏差",
"随机负采样": "缓解位置偏差,但可能引入噪声",
"Hard Negative": "提升模型区分能力"
},
"样本偏差处理": {
"位置偏差": "Position-aware模型 / IPW(逆倾向加权)",
"选择偏差": "因果推断方法 / 无偏估计",
"时间偏差": "使用训练时间截断,避免未来信息泄露"
},
"样本比例": "正负样本比通常 1:5~1:20,根据业务调整"
}
2.3 训练Pipeline设计¶
"""分布式训练Pipeline"""
class TrainingPipeline:
def __init__(self):
self.config = {
"训练框架": {
"小模型(<1B参数)": "单机多卡 DataParallel",
"中模型(1B-10B)": "多机多卡 DDP + ZeRO",
"大模型(>10B)": "Megatron-LM / DeepSpeed / FSDP"
},
"训练策略": {
"全量训练": "每天/每周 全量数据重训",
"增量训练": "基于新数据微调,每小时/每天",
"持续学习": "Online Learning,实时更新"
},
"超参调优": {
"Grid Search": "小规模参数空间(<100组合)",
"Bayesian Optimization": "中等参数空间(Optuna)",
"Population Based Training": "大规模资源(Ray Tune)"
}
}
def model_versioning(self):
"""模型版本管理——跟踪模型的全生命周期:从实验到生产到归档"""
return {
"模型注册表": "MLflow Model Registry / 自建",
"版本信息": {
"模型ID": "唯一标识",
"训练数据": "数据版本 + 时间范围",
"超参数": "完整的超参配置",
"评估指标": "离线指标(AUC/F1/NDCG等)",
"依赖环境": "Python版本 + 包版本 + CUDA版本"
},
"生命周期": "Staging → Canary → Production → Archived"
}
3. 推荐系统架构¶
3.1 工业级推荐系统全景¶
用户请求
│
▼
┌─────────────────────────────────────────────────────┐
│ 召回层(Recall) │
│ 目标:从千万级候选中选出 ~1000 个 │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────┐│
│ │ 协同过滤 │ │双塔向量召回│ │ 热门/新品 │ │ 图召回 ││
│ │ ItemCF │ │DSSM/YTB │ │ 冷启动补充│ │GraphSAGE││
│ │ UserCF │ │ ANN检索 │ │ │ │ ││
│ └──────────┘ └──────────┘ └──────────┘ └────────┘│
│ │(合并去重) │
└─────────────────────┼─────────────────────────────┘
▼
┌─────────────────────────────────────────────────────┐
│ 粗排层(Pre-ranking) │
│ 目标:1000 → 200,轻量级模型(延迟<5ms) │
│ 模型:双塔蒸馏 / 小型MLP / 向量内积 │
└─────────────────────┼─────────────────────────────┘
▼
┌─────────────────────────────────────────────────────┐
│ 精排层(Ranking) │
│ 目标:200 → 50,复杂模型(延迟<50ms) │
│ │
│ ┌────────────────────────────────────────────┐ │
│ │ 多任务模型(MMOE/PLE/ESMM) │ │
│ │ │ │
│ │ 输入特征: │ │
│ │ User: [ID, 年龄, 兴趣, 历史行为序列] │ │
│ │ Item: [ID, 类目, 标签, 统计特征] │ │
│ │ Context: [时间, 设备, 位置, 网络] │ │
│ │ Cross: [历史交互, 行为序列中的Item特征] │ │
│ │ │ │
│ │ 输出目标: │ │
│ │ Task1: P(click) 点击率预估 │ │
│ │ Task2: P(like) 点赞概率 │ │
│ │ Task3: P(follow) 关注概率 │ │
│ │ Task4: E(time) 期望观看时长 │ │
│ └────────────────────────────────────────────┘ │
│ 融合公式:Score = w1*P(clk) + w2*P(like) + │
│ w3*P(follow) + w4*E(time) │
└─────────────────────┼─────────────────────────────┘
▼
┌─────────────────────────────────────────────────────┐
│ 重排层(Re-ranking) │
│ 目标:50 → 最终展示,加入业务规则 │
│ │
│ ├── 多样性打散(MMR / DPP) │
│ ├── 去重过滤(已看/不喜欢/黑名单) │
│ ├── 运营干预(置顶/加权/定向投放) │
│ ├── 广告混排(竞价 + 体验平衡) │
│ └── 生态调控(创作者激励/新人扶持) │
└─────────────────────────────────────────────────────┘
3.2 双塔模型与向量召回¶
"""双塔模型(Two-Tower)向量召回实现"""
import torch
import torch.nn as nn
class TwoTowerModel(nn.Module):
"""
双塔模型:
- User Tower: 用户特征 → 用户向量 (128d)
- Item Tower: 物品特征 → 物品向量 (128d)
- 训练时:内积 + Softmax交叉熵
- 推理时:User向量在线计算,Item向量离线存入ANN索引
"""
def __init__(self, user_feat_dim, item_feat_dim, embed_dim=128):
super().__init__()
# 用户塔:将用户特征映射到embed_dim维的向量空间
# 三层MLP + BatchNorm,逐步压缩特征维度
self.user_tower = nn.Sequential(
nn.Linear(user_feat_dim, 256),
nn.ReLU(),
nn.BatchNorm1d(256), # 批归一化加速收敛
nn.Linear(256, 128),
nn.ReLU(),
nn.Linear(128, embed_dim),
# 注意:L2归一化在 forward() 中用 F.normalize 实现
)
# 物品塔:结构与用户塔对称,保证向量空间一致
self.item_tower = nn.Sequential(
nn.Linear(item_feat_dim, 256),
nn.ReLU(),
nn.BatchNorm1d(256),
nn.Linear(256, 128),
nn.ReLU(),
nn.Linear(128, embed_dim),
)
# 温度参数:控制softmax分布的锐度,可学习优化
self.temperature = nn.Parameter(torch.tensor(0.07))
def forward(self, user_feat, item_feat):
# 用户塔前向传播 + L2归一化,得到单位向量
user_emb = torch.nn.functional.normalize(
self.user_tower(user_feat), dim=-1
)
# 物品塔前向传播 + L2归一化
item_emb = torch.nn.functional.normalize(
self.item_tower(item_feat), dim=-1
)
# 计算用户-物品相似度矩阵:[batch_u, batch_i]
# 除以温度参数调节softmax分布的平滑程度
logits = torch.matmul(user_emb, item_emb.T) / self.temperature.exp()
return logits, user_emb, item_emb
# ---------- 向量检索服务 ----------
class ANNService:
"""
近似最近邻检索服务
离线:Item向量 → 构建ANN索引(Faiss/Milvus/Pinecone)
在线:User向量 → ANN topK检索 → 召回候选集
"""
def __init__(self, index_type="IVF_PQ"):
self.index_configs = {
"Flat": {
"精度": "100%(精确)",
"速度": "慢,仅适合 <100万",
"内存": "高"
},
"IVF_PQ": {
"精度": "~95%",
"速度": "快,适合 千万~亿级",
"内存": "低(压缩向量)",
"参数": "nlist=1024, m=32, nprobe=64"
},
"HNSW": {
"精度": "~98%",
"速度": "极快",
"内存": "高(需要构建图)",
"参数": "M=32, ef_construction=200, ef_search=128"
}
}
3.3 多任务学习模型(MMOE/PLE)¶
"""MMOE (Multi-gate Mixture-of-Experts) 实现"""
class MMOE(nn.Module):
"""
多任务学习核心架构:
- 多个Expert网络提取不同特征模式
- 每个Task有独立的Gate网络选择Expert组合
- 解决任务冲突问题(如点击率 vs 完播率)
对比:
- Shared-Bottom: 底层全共享,任务冲突严重
- MMOE: Expert + Gate,灵活共享
- PLE (CGC): 任务独有Expert + 共享Expert,效果最好
"""
def __init__(self, input_dim, num_experts=8, num_tasks=3,
expert_dim=64):
super().__init__() # super()调用父类方法
self.num_experts = num_experts
self.num_tasks = num_tasks
# Expert网络组:多个独立的MLP,每个学习不同的特征模式
self.experts = nn.ModuleList([
nn.Sequential(
nn.Linear(input_dim, expert_dim),
nn.ReLU(),
nn.Linear(expert_dim, expert_dim)
) for _ in range(num_experts)
])
# 门控网络(每个任务一个):学习如何加权组合各Expert的输出
# Softmax保证权重和为1,实现“软选择”而非“硬切换”
self.gates = nn.ModuleList([
nn.Sequential(
nn.Linear(input_dim, num_experts),
nn.Softmax(dim=-1)
) for _ in range(num_tasks)
])
# 任务塔(每个任务一个):将Expert混合特征映射为最终预测值
# Sigmoid输出[0,1]概率值,适用于点击率/点赞率等二分类任务
self.towers = nn.ModuleList([
nn.Sequential(
nn.Linear(expert_dim, 32),
nn.ReLU(),
nn.Linear(32, 1),
nn.Sigmoid()
) for _ in range(num_tasks)
])
def forward(self, x):
# 所有Expert并行计算,得到 [batch, num_experts, expert_dim]
expert_outputs = torch.stack(
[expert(x) for expert in self.experts], dim=1
)
task_outputs = []
for i in range(self.num_tasks):
# 第i个任务的门控权重: [batch, num_experts] → 扩展维度用于加权
gate = self.gates[i](x).unsqueeze(-1)
# Expert加权求和:根据门控权重融合多个Expert的输出
mixture = (expert_outputs * gate).sum(dim=1)
# 经过任务塔得到最终预测: [batch, 1]
output = self.towers[i](mixture)
task_outputs.append(output)
# 返回各任务预测结果,如 [P(click), P(like), P(follow)]
return task_outputs # [P(click), P(like), P(follow)]
4. 搜索排序系统¶
4.1 搜索系统架构¶
用户Query: "适合冬天的保暖外套"
│
▼
┌──────────────────────────────────────────────────┐
│ Query理解(NLU) │
│ ├── Query改写: "冬天保暖外套" → "冬季保暖外套" │
│ ├── 意图识别: 商品搜索(购买意图) │
│ ├── Query扩展: +羽绒服 +棉服 +冲锋衣 │
│ ├── 实体识别: [季节:冬天] [属性:保暖] [类目:外套] │
│ └── 纠错: "保暧" → "保暖" │
└────────────────────┼─────────────────────────────┘
▼
┌──────────────────────────────────────────────────┐
│ 召回(Retrieval) │
│ ├── 文本召回: 倒排索引(Elasticsearch/Lucene) │
│ ├── 向量召回: Query向量 → ANN检索 │
│ ├── 图谱召回: 知识图谱扩展 │
│ └── 个性化召回: 用户历史偏好 │
│ → 合并去重 ~5000条候选 │
└────────────────────┼─────────────────────────────┘
▼
┌──────────────────────────────────────────────────┐
│ 排序(Ranking) │
│ L1粗排: 双塔模型,5000→500(<5ms) │
│ L2精排: 交叉特征模型,500→100(<50ms) │
│ └── 相关性特征: Query-Doc匹配度 │
│ └── 质量特征: 销量/评分/品牌权重 │
│ └── 个性化特征: 用户偏好/历史行为 │
│ └── 时效性特征: 新品加权/季节相关 │
│ L3重排: 多样性+业务规则+广告混排 │
└──────────────────────────────────────────────────┘
4.2 Learning to Rank(LTR)¶
"""搜索排序模型设计"""
class SearchRanker:
"""
三种LTR范式对比:
| 范式 | 损失函数 | 特点 | 代表模型 |
|------|---------|------|---------|
| Pointwise | 交叉熵/MSE | 独立打分 | LR/GBDT |
| Pairwise | BPR/Hinge | 学习偏序 | RankNet/LambdaRank |
| Listwise | ListMLE/ApproxNDCG | 优化列表指标 | LambdaMART |
"""
def __init__(self):
# 特征分组:搜索排序的特征按来源分为四大类
self.feature_groups = {
"Query特征": [ # 描述搜索词本身的属性
"query_length", # Query长度(字数/词数)
"query_intent", # 意图类别(导航/信息/交易)
"query_frequency", # 搜索频次(热门词 vs 长尾词)
],
"Doc特征": [ # 描述候选文档/商品的质量
"title_quality", # 标题质量分(可读性/规范性)
"doc_freshness", # 内容新鲜度(时间衰减因子)
"authority_score", # 权威性/PageRank(来源可信度)
"click_rate", # 历史点击率(曝光后的点击比例)
],
"Query-Doc交叉特征": [ # 衡量搜索词与文档的匹配程度
"bm25_score", # BM25文本相关性(经典统计方法)
"semantic_similarity", # 语义相似度(Embedding向量内积)
"title_match_ratio", # 标题匹配度(Query词在标题中的覆盖率)
"exact_match", # 完全匹配(布尔值,极强相关性信号)
],
"用户个性化特征": [ # 利用用户历史行为进行个性化排序
"user_category_pref", # 类目偏好(基于历史点击统计)
"user_brand_pref", # 品牌偏好(购买/收藏品牌分布)
"user_price_range", # 价格偏好(历史消费价格区间)
"click_history_sim", # 历史点击相似度(当前Doc与历史点击的相似度)
]
}
def evaluation_metrics(self):
"""搜索排序评估指标"""
return {
"NDCG@K": "归一化折损累计增益,衡量排序质量",
"MRR": "第一个相关结果的排名倒数",
"MAP": "平均精度均值",
"P@K": "TopK中的准确率",
"离线-在线GAP": "离线指标提升不等于在线收益,"
"必须A/B测试验证"
}
5. 模型推理服务¶
5.1 模型Serving架构¶
┌─────────────────────────────────────────────────────────┐
│ 模型推理服务架构 │
│ │
│ 客户端请求 │
│ │ │
│ ▼ │
│ ┌─────────┐ │
│ │ API │ ← REST/gRPC │
│ │ Gateway │ ← 限流/鉴权/路由 │
│ └────┬────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────┐ │
│ │ Model Router (模型路由) │ │
│ │ ├── A/B测试路由(5%流量→新模型) │ │
│ │ ├── 多模型Ensemble │ │
│ │ └── 降级策略(GPU不可用→CPU模型) │ │
│ └────────────────┬────────────────────┘ │
│ │ │
│ ┌───────────┼───────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │Model A │ │Model B │ │Model C │ │
│ │(v1.0) │ │(v1.1) │ │(canary) │ │
│ │TensorRT │ │ONNX │ │PyTorch │ │
│ │GPU x4 │ │GPU x2 │ │GPU x1 │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │
│ 底层组件: │
│ ├── Model Store: S3/MinIO存储模型文件 │
│ ├── Feature Store: Redis获取实时特征 │
│ ├── Inference Engine: TensorRT/ONNX Runtime/Triton │
│ └── Auto-scaling: K8s HPA / 自定义GPU调度 │
└─────────────────────────────────────────────────────────┘
5.2 推理优化技术¶
"""模型推理优化方案全览"""
INFERENCE_OPTIMIZATION = {
"模型层面": {
"量化(Quantization)": {
"INT8量化": "精度损失<1%,推理速度提升2-4x",
"FP16混合精度": "几乎无损,速度提升1.5-2x",
"INT4/GPTQ": "LLM专用,内存降4x",
"校准方法": "Post-Training Quantization / "
"Quantization-Aware Training"
},
"剪枝(Pruning)": {
"非结构化剪枝": "置零权重,需硬件支持稀疏计算",
"结构化剪枝": "删除整个通道/Head,直接加速"
},
"蒸馏(Distillation)": {
"思路": "大模型Teacher → 小模型Student",
"场景": "线上用Student模型,保持90%+精度",
"代表": "DistilBERT(BERT→6层), TinyLlama"
},
"模型编译": {
"TensorRT": "NVIDIA GPU,最优的推理优化",
"ONNX Runtime": "跨平台,CPU/GPU通用",
"TVM/XLA": "自动算子优化和内存调度"
}
},
"系统层面": {
"Dynamic Batching": {
"原理": "收集多个请求合并为一个batch推理",
"参数": "max_batch_size=64, max_delay=10ms",
"收益": "GPU利用率从20%→80%+"
},
"Continuous Batching": {
"原理": "LLM场景,不同请求不同生成长度",
"实现": "vLLM PagedAttention,减少GPU内存浪费",
"收益": "LLM吞吐量提升2-4x"
},
"KV Cache优化": {
"PagedAttention": "分页管理KV Cache(vLLM)",
"Prefix Caching": "缓存公共前缀,减少重复计算",
"Multi-Query Attention": "多query共享KV Head"
},
"模型并行": {
"Tensor Parallelism": "模型参数切分到多GPU",
"Pipeline Parallelism": "模型层切分到多GPU",
"Speculative Decoding": "小模型猜测 + 大模型验证"
}
}
}
5.3 推理服务延迟优化实战¶
"""推理延迟优化实战方案"""
class LatencyOptimization:
"""
目标:推理延迟 P99 < 100ms
延迟分解(典型推荐系统精排):
┌────────────────────────────────────────┐
│ 总延迟 = 特征获取 + 模型推理 + 后处理 │
│ 30ms + 40ms + 10ms │
│ = 80ms (P50) │
│ = 120ms (P99) ← 需要优化! │
└────────────────────────────────────────┘
"""
def optimize_feature_fetch(self):
"""特征获取优化:30ms → 15ms——减少网络往返和计算开销"""
return {
"并行获取": "用户特征/物品特征/上下文特征 并行请求Redis",
"本地缓存": "热门物品特征LRU缓存(命中率>80%)",
"特征预计算": "用户画像T+1更新,不用实时计算",
"Pipeline": "特征获取与模型预热并行"
}
def optimize_inference(self):
"""模型推理优化:40ms → 20ms——从计算图和GPU利用率着手"""
return {
"TensorRT编译": "FP16 + layer fusion → 2x加速",
"Dynamic Batching": "合并多个请求提升GPU利用率",
"算子融合": "多个小算子合并为一个大算子",
"GPU内存池": "预分配显存,避免malloc延迟"
}
def optimize_end_to_end(self):
"""端到端优化——从流水线架构和降级方案两个维度优化"""
return {
"异步Pipeline": "召回/粗排/精排 流水线并行",
"提前截断": "精排200候选足够,不需要更多",
"降级方案": {
"P99>200ms": "切换到轻量模型",
"GPU故障": "CPU Fallback(精度-5%但可用)",
"特征缺失": "用默认值填充,不阻塞推理"
}
}
6. 特征工程平台¶
6.1 Feature Store架构¶
┌─────────────────────────────────────────────────────────┐
│ Feature Store 架构 │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Feature Registry(注册中心) │ │
│ │ ├── Feature定义(名称/类型/计算逻辑/Owner) │ │
│ │ ├── 血缘关系(数据源→特征→模型) │ │
│ │ ├── 质量监控(分布/覆盖率/延迟) │ │
│ │ └── 权限管理(读写权限/AB桶隔离) │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────┐ ┌─────────────────────────┐ │
│ │ 离线特征计算 │ │ 在线特征计算 │ │
│ │ │ │ │ │
│ │ Spark/Flink │ │ Flink实时聚合 │ │
│ │ ↓ │ │ ↓ │ │
│ │ Hive/Iceberg │ │ Redis/DynamoDB │ │
│ │ (训练用) │ │ (推理用) │ │
│ │ │ │ │ │
│ │ T+1批量更新 │ │ 秒级/分钟级更新 │ │
│ └─────────────────────┘ └─────────────────────────┘ │
│ │
│ 关键设计原则: │
│ 1. 训练-推理一致性:同一份特征计算逻辑 │
│ 2. 时间旅行:训练时能获取历史任意时间点的特征 │
│ 3. 特征复用:一次计算,多模型共享 │
│ 4. 特征回填:新特征可以回填历史数据用于训练 │
└─────────────────────────────────────────────────────────┘
6.2 特征设计最佳实践¶
"""工业级特征设计模板"""
FEATURE_DESIGN = {
"用户侧特征": {
"静态特征": ["user_id", "age", "gender", "city", "注册天数"],
"行为统计": [
"最近7天点击次数", "最近30天购买金额",
"最近3个月活跃天数", "最近1天观看时长"
],
"行为序列": [
"最近50个点击Item ID序列",
"最近20个购买Item ID序列",
"最近搜索Query序列"
],
"实时特征": [
"当前Session点击次数",
"距上次活跃时间",
"当前页面停留时长"
]
},
"物品侧特征": {
"基础属性": ["item_id", "类目", "品牌", "价格", "发布时间"],
"统计特征": [
"7日点击率", "30日转化率", "平均评分",
"评价数", "收藏数"
],
"内容特征": [
"标题Embedding", "图片Embedding",
"标签/关键词", "类目路径"
]
},
"交叉特征": {
"User-Item交叉": [
"用户对该类目的历史点击率",
"用户对该品牌的偏好度",
"用户历史价格范围 vs 物品价格"
],
"Context特征": [
"时间(工作日/周末, 上午/下午/晚上)",
"设备(iOS/Android/PC)",
"网络(WiFi/4G/5G)",
"展示位置(第几位)"
]
}
}
7. LLM应用系统设计¶
7.1 LLM应用架构全景¶
┌─────────────────────────────────────────────────────────┐
│ LLM应用系统设计全景 │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 接入层 │ │
│ │ API Gateway → 限流/鉴权 → 请求路由 │ │
│ └────────────────────┬────────────────────────────┘ │
│ ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 编排层(Orchestration) │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │ │
│ │ │ Prompt │ │ Agent │ │ RAG │ │ │
│ │ │ Template │ │ Planner │ │ Pipeline │ │ │
│ │ │ 管理 │ │ ReAct/ │ │ Query→ │ │ │
│ │ │ │ │ Plan-Act │ │ Retrieve→ │ │ │
│ │ │ │ │ │ │ Generate │ │ │
│ │ └──────────┘ └──────────┘ └──────────────┘ │ │
│ └────────────────────┬────────────────────────────┘ │
│ ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ LLM Gateway │ │
│ │ ├── 模型路由(GPT-4/Claude/开源 按任务选择) │ │
│ │ ├── 负载均衡(多Provider分流) │ │
│ │ ├── 缓存(语义缓存,相似Query复用) │ │
│ │ ├── 监控(Token用量/延迟/错误率) │ │
│ │ └── 安全(内容过滤/Prompt注入检测) │ │
│ └────────────────────┬────────────────────────────┘ │
│ ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ LLM Provider │ │
│ │ OpenAI / Anthropic / 本地部署(vLLM/TGI) │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ 支撑系统: │
│ ├── 向量数据库: Milvus/Qdrant(RAG检索) │
│ ├── 缓存层: Redis(KV缓存 + 语义缓存) │
│ ├── 日志系统: ELK(对话日志 + 审计) │
│ └── 评估系统: LLM-as-Judge + 人工标注 │
└─────────────────────────────────────────────────────────┘
7.2 RAG系统设计¶
"""生产级RAG系统架构设计"""
class ProductionRAG:
"""
RAG系统设计要点:
1. 索引构建Pipeline
2. 查询理解与路由
3. 检索与重排
4. 生成与后处理
5. 评估与迭代
"""
def indexing_pipeline(self):
"""索引构建Pipeline——将原始文档转化为可检索的向量索引"""
return {
"文档处理": {
"解析": "PDF/Word/HTML → 纯文本(Unstructured)",
"分块": {
"固定大小": "chunk_size=512, overlap=50",
"语义分块": "基于句子边界 + 主题切换",
"递归分块": "先段落→再句子→再固定长度",
"最佳实践": "chunk_size=500-1000 tokens, overlap=10-20%"
},
"增强": "标题+摘要 作为元数据一同嵌入"
},
"向量化": {
"Embedding模型": "bge-large-zh / text-embedding-3-large",
"多路索引": "稠密向量 + 稀疏向量(BM25) + 知识图谱",
"存储": "Milvus/Qdrant/Weaviate"
},
"增量更新": {
"策略": "CDC(Change Data Capture) → 增量索引",
"去重": "基于文档hash去重 + 版本管理",
"刷新": "定时全量重建 + 实时增量更新"
}
}
def query_pipeline(self):
"""查询Pipeline——从用户Query到最终回答的全链路处理"""
return {
"查询理解": {
"Query改写": "LLM将用户问题改写为更适合检索的query",
"HyDE": "用LLM先生成假设答案,用答案做检索",
"多Query": "将复杂问题拆分为子查询,分别检索"
},
"检索策略": {
"混合检索": "Dense(0.7) + Sparse BM25(0.3)",
"重排序": "Cross-encoder reranker (bge-reranker-v2)",
"TopK选择": "检索Top20 → 重排后取Top5"
},
"上下文构建": {
"窗口扩展": "召回chunk的前后各1个chunk",
"压缩": "LongContext → 压缩器提取关键信息",
"排序": "最相关的chunk离prompt最近"
},
"生成": {
"Prompt": "基于以下参考信息回答问题:\n{context}\n问题:{query}",
"Citation": "要求模型标注引用来源[1][2]...",
"后处理": "检测幻觉 + 一致性验证"
}
}
def evaluation(self):
"""多层次RAG评估体系:检索质量 + 生成质量 + 端到端效果"""
return {
"检索评估": {
"Recall@K": "召回相关文档的比例",
"MRR": "第一个相关文档的排名",
"Context Relevance": "检索结果与问题的相关性"
},
"生成评估": {
"Faithfulness": "回答是否忠于检索到的信息",
"Answer Relevance": "回答是否切题",
"Hallucination Rate": "幻觉率"
},
"端到端评估": {
"EM/F1": "与标准答案的匹配度",
"LLM-as-Judge": "用GPT-4评分",
"人工评估": "相关性/准确性/完整性 三维评分"
},
"框架": "RAGAS / TruLens / DeepEval"
}
7.3 LLM Gateway设计¶
"""LLM Gateway核心设计"""
class LLMGateway:
"""
LLM Gateway是LLM应用的统一入口,
负责路由、缓存、安全、监控。
面试关键点:
1. 为什么需要Gateway?(统一管理多Provider)
2. 语义缓存如何实现?(embedding相似度)
3. 如何做成本优化?(模型路由策略)
"""
def routing_strategy(self):
"""智能模型路由——根据任务复杂度、成本、可用性选择最优模型"""
return {
"基于任务复杂度": {
"简单任务": "GPT-3.5 / Claude Haiku(便宜快速)",
"复杂推理": "GPT-4o / Claude Opus(高质量)",
"代码生成": "Claude Sonnet / GPT-4o",
"判断方法": "基于Query分类器 或 级联调用"
},
"基于成本": {
"策略": "先用小模型,不满意再升级大模型",
"实现": "小模型输出 → 质量评估器 → "
"通过则返回 / 不通过则调用大模型"
},
"基于可用性": {
"主备切换": "OpenAI故障 → 自动切换Anthropic",
"负载均衡": "多API Key轮询避免限流",
"降级": "大模型过载 → 降级到小模型"
}
}
def semantic_cache(self):
"""语义缓存——基于向量相似度复用历史回答,降低LLM调用成本"""
return {
"原理": "相似的Query返回缓存的响应",
"实现步骤": [
"1. Query → Embedding",
"2. 在向量数据库中搜索最相似的历史Query",
"3. 相似度 > 阈值(0.95) → 返回缓存",
"4. 否则 → 调用LLM → 结果写入缓存"
],
"效果": "缓存命中率20-40%,节省对应成本",
"注意": "时效性内容不适合缓存,需设置TTL"
}
def safety(self):
"""安全防护——输入过滤、输出审核、全链路审计三层防线"""
return {
"输入安全": {
"Prompt注入检测": "规则 + 分类模型双重检测",
"PII检测": "检测并脱敏个人信息",
"内容过滤": "敏感词 + 内容分类"
},
"输出安全": {
"输出过滤": "检测有害内容/虚假信息",
"格式验证": "JSON Schema验证结构化输出",
"引用验证": "检查引用来源的真实性"
},
"审计日志": "所有请求/响应完整记录,支持回溯"
}
8. ML系统监控与治理¶
8.1 模型监控体系¶
"""ML系统监控全景"""
ML_MONITORING = {
"数据质量监控": {
"Schema检查": "字段类型/非空约束/值域范围",
"分布偏移": {
"PSI": "Population Stability Index > 0.2 告警",
"KS检验": "分布差异检验",
"监控频率": "每小时检查特征分布"
},
"新鲜度": "数据延迟超过SLA → 告警",
"覆盖率": "特征缺失率 > 5% → 告警"
},
"模型性能监控": {
"精度指标": {
"实时AUC": "每小时计算,下降>1%告警",
"转化率": "日环比,下降>5%告警",
"NDCG@10": "搜索质量,每天评估"
},
"系统指标": {
"推理延迟": "P50/P95/P99",
"吞吐量": "QPS",
"错误率": "推理失败比例",
"GPU利用率": "GPU Memory / GPU Compute"
},
"业务指标": {
"CTR": "点击率",
"CVR": "转化率",
"ARPU": "用户平均收入",
"DAU/留存": "用户活跃度"
}
},
"模型漂移检测": {
"概念漂移": "P(Y|X)变化 — 用户偏好变了",
"数据漂移": "P(X)变化 — 输入分布变了",
"检测方法": [
"ADWIN: 自适应窗口检测",
"DDM: 基于学习器错误率",
"Page-Hinkley: 均值变化检测"
],
"应对策略": {
"轻微漂移": "增量训练/微调",
"显著漂移": "全量重训",
"突变": "立即回滚到上一版本 + 排查原因"
}
}
}
8.2 A/B测试与实验平台¶
"""A/B测试系统设计"""
class ABTestPlatform:
"""
ML模型上线必须经过严格的A/B测试
面试关键问题:
1. 如何计算需要的实验样本量?
2. 如何避免辛普森悖论?
3. 如何处理多个实验的干扰?
"""
def experiment_design(self):
"""实验设计——覆盖样本量计算、分流方案和统计检验方法"""
return {
"样本量计算": {
"公式": "n = (Z_α/2 + Z_β)² × 2σ² / δ²",
"参数": {
"α": "显著性水平,通常0.05",
"β": "1-Power,通常0.2(Power=80%)",
"δ": "最小可检测效应(MDE)",
"σ": "指标标准差"
},
"经验值": "CTR类实验通常需要 每组 10万+ 样本"
},
"分流方案": {
"用户级分流": "hash(user_id) % 100",
"层级设计": "多个实验层互不干扰",
"AA测试": "先跑AA验证分流无偏"
},
"统计检验": {
"T检验": "连续指标(如观看时长)",
"Z检验": "比例指标(如CTR)",
"Bootstrap": "复杂指标(如人均GMV)",
"多重检验校正": "Bonferroni / FDR"
}
}
def common_pitfalls(self):
"""避坑指南——A/B测试中的常见统计陷阱和偏差问题"""
return {
"过早停止": "看到显著就停,增加假阳性",
"辛普森悖论": "分层分析 vs 总体分析结论相反",
"新奇效应": "用户对新功能的短期兴奋",
"长期效应": "短期正向但长期负面(如更多推送)",
"网络效应": "社交场景中实验组和对照组互相影响",
"SRM": "Sample Ratio Mismatch,分流比例异常"
}
9. 经典ML系统设计案例¶
9.1 设计抖音/TikTok推荐系统¶
面试题:设计一个短视频推荐系统(日活1亿,视频库10亿)
Step 1: 业务理解
├── 北极星指标:用户总观看时长(而非点击率)
├── 辅助指标:DAU/留存/创作者发布量
└── 约束:推理延迟<200ms,单次刷新推荐30条
Step 2: ML问题定义
├── 多任务预测:P(click), P(完播), E(观看时长), P(互动)
├── 融合公式:Score = w1*P(clk)*E(time) + w2*P(like) + w3*diversity
└── 标签生成:播放>3s=曝光,完播=正,滑走<1s=强负
Step 3: 数据与特征
├── 用户:人口属性 + 兴趣标签 + 最近100个互动视频序列
├── 视频:类目/标签/时长/创作者 + 历史统计 + 视觉/音频Embedding
├── 上下文:时间/设备/网络/所在城市/当前Session行为
└── 实时特征:Flink流式计算最近10分钟互动统计
Step 4: 多阶段架构
├── 召回(~1000):多路召回(ItemCF + 双塔 + 热门 + 关注 + 同城)
├── 粗排(~200):蒸馏双塔,向量内积快速打分
├── 精排(~50):MMOE/PLE多任务模型,交叉特征
└── 重排:MMR多样性 + 已看去重 + 低质过滤 + 广告插入
Step 5: 关键设计决策
├── 用户行为序列建模:DIN/SIM(target attention)
├── 长短期兴趣分离:长期(历史统计) + 短期(Session序列)
├── 冷启动:新视频先投少量曝光 → 收集信号 → 决定是否放大
└── 探索机制:ε-greedy + 创作者激励池
9.2 设计大模型智能客服系统¶
面试题:设计一个基于LLM的企业智能客服系统(日均10万对话)
Step 1: 业务理解
├── 目标:自动解决80%+的用户问题,降低人工成本
├── 指标:自动解决率/用户满意度/平均对话轮次/转人工率
└── 约束:单轮响应<3s,支持多轮对话,7×24可用
Step 2: 系统架构
用户消息
│
▼
┌─────────────────────────────────────────┐
│ 意图路由 (Intent Router) │
│ ├── FAQ类 → RAG检索回答 │
│ ├── 操作类 → Agent调用工具/API │
│ ├── 闲聊类 → 通用对话模型 │
│ └── 投诉类 → 安抚话术 + 转人工 │
└─────────────┬───────────────────────────┘
▼
┌─────────────────────────────────────────┐
│ RAG + Agent 执行层 │
│ ├── 知识检索:企业知识库(产品手册/FAQ) │
│ ├── 工具调用:查订单/改地址/退换货API │
│ ├── 多轮管理:对话上下文+槽位追踪 │
│ └── 安全过滤:敏感信息脱敏+合规检查 │
└─────────────┬───────────────────────────┘
▼
┌─────────────────────────────────────────┐
│ 质量保障层 │
│ ├── 置信度检测:不确定时主动转人工 │
│ ├── 满意度预测:预测用户即将不满→介入 │
│ └── 人机协作:复杂问题 人工+AI 协同 │
└─────────────────────────────────────────┘
Step 3: 关键设计点
├── 知识库管理:每周自动更新,支持多文档格式
├── 多轮对话:Session管理 + 对话状态追踪
├── 降级策略:LLM超时→规则匹配→转人工
├── 成本控制:GPT-3.5处理简单问题(80%) + GPT-4处理复杂问题(20%)
└── 持续优化:Bad Case采集 → 知识库补充 → 模型微调
9.3 设计广告点击率预估系统¶
"""广告CTR预估系统设计要点"""
CTR_SYSTEM = {
"问题定义": {
"目标": "预估P(click|user, ad, context)",
"收入公式": "Revenue = Σ(bid × P(click)) — eCPM排序",
"约束": "推理延迟<10ms(广告对延迟要求极高)"
},
"模型演进": {
"V1 LR": "手工特征 + LR,简单但需大量特征工程",
"V2 GBDT+LR": "GBDT自动交叉特征 → LR",
"V3 Wide&Deep": "Wide(记忆) + Deep(泛化)",
"V4 DIN": "用户行为序列 + Target Attention",
"V5 DIEN": "兴趣进化网络,GRU建模兴趣演变",
"V6 多任务": "MMOE预测 click/convert/uninstall",
"当前": "多任务 + 行为序列 + 实时特征 + 因果去偏"
},
"样本工程": {
"正样本": "点击",
"负样本": "曝光未点击(注意位置偏差)",
"校准": "Platt Scaling校准预测概率",
"延迟转化": "CVR使用延迟反馈模型(FSIW/DFM)"
},
"部署考虑": {
"延迟要求": "<10ms,必须极致优化",
"量化": "INT8量化 + TensorRT编译",
"特征缓存": "用户特征预加载,物品特征本地缓存",
"模型更新": "实时增量更新(Online Learning)"
}
}
10. 面试准备与高频题¶
10.1 ML系统设计高频面试题¶
| 题目 | 核心考点 | 难度 | 公司 |
|---|---|---|---|
| 设计推荐系统 | 多阶段架构/多任务/特征 | ⭐⭐⭐⭐ | 字节/快手/Meta |
| 设计搜索排序 | LTR/Query理解/相关性 | ⭐⭐⭐⭐ | 百度/Google/阿里 |
| 设计广告系统 | CTR/竞价/实时性 | ⭐⭐⭐⭐⭐ | 字节/腾讯/Google |
| 设计内容审核 | 多模态/规则+模型/延迟 | ⭐⭐⭐ | 字节/快手 |
| 设计反欺诈系统 | 异常检测/实时/图网络 | ⭐⭐⭐⭐ | 蚂蚁/美团 |
| 设计智能客服 | RAG/Agent/多轮对话 | ⭐⭐⭐⭐ | 各大厂 |
| 设计人脸识别系统 | 特征提取/1:N检索/活体 | ⭐⭐⭐ | 商汤/旷视 |
| 设计翻译系统 | Seq2Seq/质量评估/缓存 | ⭐⭐⭐ | 字节/Google |
| 设计推送系统 | 时机预测/频控/个性化 | ⭐⭐⭐ | 字节/快手/美团 |
| 设计LLM应用 | RAG/Agent/Gateway/安全 | ⭐⭐⭐⭐ | 各大厂(2024新增) |
10.2 面试回答模板¶
ML系统设计面试回答模板(适用于所有ML系统设计题)
"这是一个关于[X]的ML系统设计题,让我按以下步骤来分析:"
1️⃣ 业务理解
"首先,我想确认几个问题:
- 系统的主要用户是?使用场景是?
- 日活/数据量级大概是多少?
- 最核心的业务指标是什么?"
2️⃣ ML问题定义
"这本质上是一个[分类/排序/生成]问题:
- 输入是[X],输出是[Y]
- 标注/标签来自[用户行为/人工标注/...]"
3️⃣ 数据与特征
"关键数据源有[...],我会设计以下特征:
- 用户侧:[...]
- 物品侧:[...]
- 交叉特征:[...]
- 实时特征需要Flink流式计算"
4️⃣ 模型设计
"Baseline我会用[LR/GBDT]快速验证,
进阶方案用[DNN/多任务/序列模型]。
这里有一个trade-off:[复杂度 vs 延迟],
我的考虑是[...]"
5️⃣ 训练与评估
"离线评估用[AUC/NDCG],
在线用A/B测试验证[核心业务指标],
需要[X]万样本跑[Y]天才能达到统计显著"
6️⃣ 部署与服务
"推理架构用[...],延迟要求[X]ms,
我会通过[量化/缓存/batching]优化"
7️⃣ 监控与迭代
"上线后监控[数据/模型/业务]三层指标,
设置自动告警,定期重训防止模型漂移"
10.3 深度追问准备¶
"""常见深度追问及回答思路"""
DEEP_DIVE_QUESTIONS = {
"如果数据有偏差怎么办?": {
"回答思路": [
"1. 识别偏差类型:位置偏差/选择偏差/曝光偏差",
"2. 数据层面:IPW逆倾向加权/因果推断",
"3. 模型层面:Position-aware模型/去偏正则",
"4. 评估层面:离线评估使用无偏估计方法"
]
},
"冷启动怎么处理?": {
"回答思路": [
"新用户:基于人口属性相似用户的推荐 + 热门补充",
"新物品:基于内容特征(标题/标签Embedding)召回",
"跨域迁移:从其他产品线迁移用户偏好",
"主动探索:Bandit方法(Thompson Sampling)"
]
},
"模型更新频率怎么确定?": {
"回答思路": [
"取决于数据分布变化速度",
"广告系统:实时/小时级(用户兴趣快速变化)",
"推荐系统:天级增量 + 周级全量",
"搜索排序:周级更新(查询模式相对稳定)",
"监控漂移指标自动触发重训"
]
},
"如何处理模型和业务指标不一致?": {
"回答思路": [
"离线AUC提升但线上CTR没变 → 可能是离线评估方法有问题",
"CTR提升但留存下降 → 模型过度优化短期指标",
"解法:多目标优化 + 设置护栏指标(Guardrail Metrics)",
"长期指标纳入评估(如留存/LTV不能降低)"
]
},
"系统延迟怎么优化到<10ms?": {
"回答思路": [
"1. 减少候选:更激进的截断(精排只看100个)",
"2. 模型压缩:量化 + 蒸馏 + 剪枝",
"3. 系统优化:Pipeline并行 + 本地缓存 + GPU优化",
"4. 架构优化:预计算(用户特征预加载到GPU)",
"5. 降级方案:超时用简单模型兜底"
]
},
"如何保证训练和推理一致性?": {
"回答思路": [
"Feature Store统一管理:训练和推理用同一份特征定义",
"Point-in-time join:训练时用历史快照避免信息泄露",
"Feature validation:自动对比训练特征和线上特征分布",
"End-to-end测试:用线上数据回放验证推理结果"
]
}
}
📝 本章面试题¶
基础题¶
Q1:ML系统设计面试和传统系统设计面试有什么不同?需要额外关注哪些方面?
参考答案:ML系统设计额外关注:(1) 数据——标注获取、样本偏差、特征工程;(2) 模型——选型、训练策略、评估指标;(3) 部署——推理延迟优化、模型版本管理;(4) 监控——模型漂移、数据质量、在线/离线指标一致性。本质区别是ML系统是概率性的,需要持续评估和迭代。
Q2:推荐系统为什么要分召回/粗排/精排/重排四个阶段?能不能用一个大模型直接排序?
参考答案:候选池太大(千万级),一个模型不可能在<200ms内对所有物品打分。四阶段是效率与效果的权衡:召回(简单模型,万→千)→粗排(轻量模型,千→百)→精排(复杂模型,百→几十)→重排(业务规则)。越后面的阶段候选越少,可以用越复杂的模型。
进阶题¶
Q3:设计一个Feature Store,需要满足哪些核心需求?训练-推理一致性如何保证?
参考答案:核心需求:(1) 训练-推理一致性——同一份特征定义和计算逻辑;(2) 时间旅行——训练时获取历史时间点特征,避免信息泄露(point-in-time join);(3) 低延迟在线服务——Redis/DynamoDB,P99<5ms;(4) 特征复用——一次计算多模型共享。一致性保证:统一的特征计算DAG,离线(Spark)和在线(Flink)共用同一份特征变换逻辑。
Q4:RAG系统中如何评估检索质量和生成质量?如果检索召回率低怎么优化?
参考答案:检索评估:Recall@K/MRR/Context Relevance;生成评估:Faithfulness/Answer Relevance/Hallucination Rate。如果召回率低:(1) 分块策略优化(减小chunk_size增加召回);(2) 混合检索(Dense+BM25);(3) Query改写/HyDE;(4) 多Query拆分;(5) 增加元数据过滤缩小搜索范围;(6) 知识图谱辅助检索。
Q5:在线A/B测试中,你发现离线AUC提升了2%,但线上CTR没有变化,可能的原因是什么?
参考答案:(1) 离线评估数据和线上分布不一致(如离线用旧数据,线上用户行为已变);(2) AUC不是和业务指标强相关的指标(AUC衡量排序能力不等于CTR提升);(3) 特征穿越——训练时不小心用了未来信息;(4) 模型在头部(高流量)样本上改善不大,在长尾改善多,但头部贡献了大部分流量;(5) A/B实验样本量不足,CTR提升在统计上不显著。
Q6:设计一个LLM Gateway,如何做成本优化和安全防护?
参考答案:成本优化:(1) 模型路由——简单问题用小模型(80%请求),复杂用大模型(20%);(2) 语义缓存——相似query复用结果(节省20-40%);(3) Prompt压缩——减少不必要的token;(4) 级联策略——小模型不确定时才升级。安全防护:(1) Prompt注入检测(规则+分类模型);(2) PII脱敏(正则+NER);(3) 输出过滤(有害内容/幻觉检测);(4) 审计日志(全链路记录);(5) Rate Limiting(防滥用)。
✅ 学习检查清单¶
- 能完整讲述ML系统设计7步法
- 理解推荐系统四阶段架构及每阶段的关键技术
- 能画出Feature Store架构图并解释一致性保证
- 理解模型推理优化的各种手段(量化/蒸馏/Batching)
- 能设计一个完整的RAG系统并说明评估方法
- 了解A/B测试的统计原理和常见陷阱
- 至少完整准备3个ML系统设计案例
🔗 延伸阅读¶
← 返回系统设计目录