Files
maths-cs-ai-compendium-zh/chapter 18: ML systems design/05. ML design examples.md
T
flykhan 2536c937e3 feat: 完整中文翻译 maths-cs-ai-compendium(数学·计算机科学·AI 知识大全)
翻译自英文原版 maths-cs-ai-compendium,共 20 章全部完成。

第01章 向量 | 第02章 矩阵 | 第03章 微积分
第04章 统计学 | 第05章 概率论 | 第06章 机器学习
第07章 计算语言学 | 第08章 计算机视觉 | 第09章 音频与语音
第10章 多模态学习 | 第11章 自主系统 | 第12章 图神经网络
第13章 计算与操作系统 | 第14章 数据结构与算法
第15章 生产级软件工程 | 第16章 SIMD与GPU编程
第17章 AI推理 | 第18章 ML系统设计
第19章 应用人工智能 | 第20章 前沿人工智能

翻译说明:
- 所有数学公式 $...$ / $$...$$、代码块、图片引用完整保留
- mkdocs.yml 配置中文导航 + language: zh
- README.md 已翻译为中文(兼 docs/index.md)
- docs/ 目录包含指向各章文件的 symlink
- 约 29,000 行中文内容,排除 .cache/ 构建缓存
2026-05-03 10:23:20 +08:00

338 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ML设计示例
*学习ML系统设计的最佳方式是通过实操示例。本文件详细介绍了七个完整的设计:推荐系统、搜索排序、广告点击预测、欺诈检测、内容审核、对话式AI和大规模图像搜索*
- 每个示例遵循一致的框架:
1. **问题定义**:我们在构建什么,用户是谁,约束是什么?
2. **数据**:我们有什么数据,如何收集,如何标注?
3. **特征**:模型需要什么特征?
4. **模型**:什么架构和训练方法?
5. **服务**:模型如何部署和提供服务?
6. **评估**:我们如何衡量成功?
7. **迭代**:随着时间的推移,我们会做哪些改进?
---
## 1. 推荐系统(例如YouTube、Netflix、Spotify
### 问题定义
- **目标**:向用户展示他们会喜欢的内容,最大化参与度(观看时间、收听次数、点击量)。
- **规模**:10亿+用户,1亿+项目,每秒10K+推荐。
- **延迟**:完整推荐流水线<200ms。
- **关键挑战**:候选空间巨大(1亿个项目)。无法为所有用户实时评分所有项目。
### 架构:两阶段流水线
![推荐流水线:1亿个项目通过候选生成缩小到1000个,排序到100个,重新排序到20个展示项目](../images/recommendation_pipeline.svg)
```
1亿个项目 → 候选生成(快速、粗略)→ 1000个候选
→ 排序(缓慢、精确)→ 100个排序项目
→ 重新排序(业务规则)→ 展示给用户的20个
```
### 候选生成
- **目标**:将1亿个项目减少到约1000个候选。必须快速(<50ms)。
- **双塔模型**:将用户和项目编码到相同的嵌入空间。用户嵌入捕获偏好;项目嵌入捕获内容特征。得分 = 用户嵌入和项目嵌入的点积。
- **训练**:在(用户、正样本、负样本)三元组上进行对比学习。正样本=用户参与过的项目。负样本=随机项目+难负样本(用户未参与过的热门项目)。
- **服务**:预先计算所有项目嵌入。在请求时:计算用户嵌入,ANN搜索(向量数据库中的HNSW)以找到最近的1000个项目嵌入。
### 排序
- **目标**:精确评分1000个候选。可以花费约100ms。
- **模型**:一个深度神经网络(MLP或Transformer),使用丰富特征:用户特征(人口统计、历史、上下文)、项目特征(内容、流行度、新鲜度)和交叉特征(用户-项目交互历史、上下文相关性)。
- **输出**:预测的参与概率(点击、观看50%+、点赞、分享)。多个目标可以组合:$\text{score} = w_1 \cdot P(\text{点击}) + w_2 \cdot P(\text{观看}) + w_3 \cdot P(\text{点赞})$。
### 重新排序
- 应用业务规则:多样性(不展示来自同一创作者的5个视频)、新鲜度(提升新内容)、安全(过滤被标记的内容)和个性化探索(展示一些用户可能发现的低排名项目)。
### 粗略估算数字
- **项目嵌入索引**1亿个项目×256维×float16 = 50 GB。HNSW索引增加约2倍开销→约100 GB。适合具有128 GB内存的单台机器,或分片到4×32 GB机器。
- **用户嵌入计算**:每个用户约5ms(小型MLP处理用户特征)。在10K QPS下,需要约50个模型副本处理负载。
- **ANN搜索**:使用HNSW从1亿个向量中搜索前1000个约需2ms。在10K QPS下,每个索引副本处理约500 QPS→需要20个副本。
- **排序模型**:1000个候选×每个候选约0.1ms = 每次请求100ms。在10K QPS下,需要每秒1000 GPU秒→仅排序就需要约10个A10G GPU。
- **总基础设施**:约20个嵌入索引副本+约50个用户嵌入服务器+约10个排序GPU+缓存+负载均衡器。成本:云价格下每月约$5万-$10万。
### 冷启动
- **新用户**(无历史记录):使用人口统计特征、设备/位置上下文和基于流行度的推荐。经过5-10次交互后,切换到个性化模型。
- **新项目**(无参与数据):使用基于内容的特征(标题、描述、缩略图嵌入)。分配探索预算:向一部分用户展示新项目以快速收集参与数据。在经过提升期后仍无参与的项目被降级。
- **冷启动是系统问题**:特征存储必须优雅地处理缺失特征(返回默认值,而不是错误)。模型必须使用缺失特征进行训练(训练期间对用户历史特征进行dropout可以模拟新用户)。
### 评估
- **离线**:NDCG(归一化折损累计增益)、Recall@K、Precision@K
- **在线**:测量观看时间、DAU、留存的A/B测试。长期A/B测试(数周)以捕获短期测试无法观察到的用户留存效应。
---
## 2. 搜索排序(例如Google、Bing
### 问题定义
- **目标**:给定用户查询,从数十亿文档的语料库中返回最相关的结果。
- **延迟**:总计<500ms(检索100ms + 排序200ms + 渲染100ms + 开销)。
### 架构:查询理解→检索→排序
### 查询理解
- 在检索之前,处理原始查询以改进结果:
- **拼写纠正**"reccomendation systm"→"recommendation system"。使用编辑距离模型或序列到序列模型,在(拼写错误,纠正)对上训练,数据来自搜索日志。
- **查询扩展**:添加相关术语以提高召回率。"Python ML"→"Python machine learning scikit-learn pytorch。"使用同义词词典、词嵌入或LLM生成扩展。
- **意图分类**:确定用户想要什么。"buy Nike shoes"是**交易型**(展示产品页面)。"How does backpropagation work"是**信息型**(展示文章)。"facebook.com"是**导航型**(直接转到网站)。不同意图应触发不同的检索策略和结果布局。
- **实体识别**:从查询中提取实体。"best restaurants near Times Square"→位置:"Times Square",实体类型:"restaurants。"路由到位置感知搜索流水线。
### 检索
- **BM25**(传统):使用倒排索引进行词匹配检索。快速,对关键词查询有效。没有语义理解("dog food"不匹配"canine nutrition")。
- **稠密检索**:将查询和文档编码为嵌入(使用如DPR或ColBERT的双编码器)。通过ANN搜索检索。捕获语义相似性("dog food"匹配"canine nutrition")。比BM25慢,但对于自然语言查询更好。
- **混合检索**:结合BM25和稠密检索。BM25找到精确关键词匹配;稠密检索找到语义匹配。合并并去重。两全其美。
### 排序
- **学习排序**:一个模型对每个(查询,文档)对评分。三种方法:
- **点式**:独立预测每个文档的相关性分数。简单但忽略相对顺序。
- **成对式**:预测两个文档中哪个更相关。LambdaMART(梯度提升树)是经典方法。
- **列表式**:直接针对列表级指标(NDCG)优化整个排序列表。更复杂但结果最好。
- **交叉编码器**:一个以`[查询,文档]`为输入并输出相关性分数的Transformer。比双编码器更准确(后者独立编码查询和文档),因为它捕获了细粒度的交互。但对于完整语料库来说太慢——仅用于对检索前100-1000个候选进行重新排序。
### 特征
- **查询特征**:查询长度、语言、意图分类(导航型、信息型、交易型)。
- **文档特征**:PageRank、新鲜度、内容质量分数、域名权威性。
- **查询-文档特征**:BM25分数、嵌入相似度、精确匹配数、历史日志中此(查询,文档)对的点击率。
---
## 3. 广告点击预测
### 问题定义
- **目标**:预测用户点击广告的概率。这决定在实时拍卖中出价多少。
- **规模**:每秒100K+次拍卖,每次预测需在10ms内完成。
- **收入影响**:点击预测准确率提高0.1%就相当于数百万的额外收入。
### 架构
- **特征工程**是广告系统的核心。特征包括:
- **用户特征**:人口统计、浏览历史、购买历史、设备、位置、一天中的时间。
- **广告特征**:创意(图片/文字)、广告主、类别、历史CTR、出价金额。
- **上下文特征**:页面内容、广告位置、设备类型、连接速度。
- **交叉特征**user_category×ad_category交互,user_region×ad_campaign交互。
- **模型**:历史上用逻辑回归(简单、快速、可解释)。现代系统使用深度学习:**DLRM**(深度学习推荐模型),对分类特征使用嵌入表,对稠密特征使用MLP。
- **校准**:预测概率必须准确(如果模型说P(点击)=0.05,那么实际上应该有5%的展示被点击)。校准至关重要,因为预测概率直接决定出价金额。
- **探索-利用**:总是展示预测的最佳广告在长期来看是次优的(你永远无法发现新广告可能更好)。Thompson采样或$\epsilon$-greedy探索确保有一部分展示分配给不确定性较高的广告以收集数据。
### 实时竞价
- 当用户加载页面时,广告拍卖在<100ms内进行:
1. 发布者向多个广告交易平台发送竞价请求(用户信息、页面上下文)。
2. 每个广告主的竞价服务器预测其广告的CTR。
3. 出价 = CTR × 每次点击的价值。出价高的赢得拍卖。
4. 获胜的广告被展示;如果被点击,广告主付费。
---
## 4. 欺诈检测
### 问题定义
- **目标**:实时检测欺诈性交易(信用卡欺诈、账户盗用、虚假评论)。
- **延迟**:<100ms(交易必须在支付处理前被批准或标记)。
- **关键挑战**:极端类别不平衡(欺诈率0.1%)。误报会阻止合法用户;漏报会造成金钱损失。
### 架构
![欺诈检测流水线:交易→实时特征流水线→ML模型→决策引擎→允许/审核/阻止,人工审核将标签反馈用于重新训练](../images/fraud_detection_pipeline.svg)
### 特征
- **交易特征**:金额、货币、商户类别、一天中的时间、是否跨国。
- **用户特征**:账户年龄、平均交易金额、近期交易次数、设备指纹。
- **速度特征**(实时,来自流处理流水线):过去5分钟内的交易次数、过去1小时内的不同商户数、与上次交易的地理距离。
- **图特征**:此商户是否与已知欺诈团伙有关联?此设备是否与被标记账户共享?
### 模型
- **梯度提升树**XGBoost、LightGBM)是表格数据欺诈检测的标准。它们处理混合特征类型、可解释(特征重要性)且训练快速。
- **处理不平衡**:对多数类进行欠采样、对少数类进行过采样(SMOTE),或在损失函数中使用类别权重。Focal loss(第8章)降低简单负样本的权重。
- **成本矩阵**:误报(阻止合法交易)有成本(用户挫败感、销售损失)。漏报(遗漏欺诈)有不同的成本(财务损失)。决策阈值应最小化总预期成本,而非最大化准确率。
### 人在回路中
- 不确定的预测(模型置信度在0.3和0.7之间)发送给人工审核员。审核员的决策成为重新训练的标签。这创建了一个反馈循环:随着模型看到更多标记的欺诈案例,它随着时间的推移而改进。
---
## 5. 内容审核
### 问题定义
- **目标**:自动检测并移除有害内容(仇恨言论、暴力、虚假信息、CSAM)从一个平台。
- **规模**:每天数十亿条帖子(文本、图片、视频)。
- **挑战**:上下文依赖(讽刺、戏仿、文化细微差别)。必须在言论自由和安全之间取得平衡。
### 架构
- **多模态分类**:文本、图片和视频分别使用单独的模型,加上融合层组合它们的信号。
- **文本审核**:微调的语言模型将文本分类为类别(骚扰、仇恨言论、虚假信息、垃圾信息)。多语言模型处理100+种语言。
- **图片审核**:视觉模型检测:露骨内容(裸体、暴力)、图片中的文字(OCR+文本分类器)和已知有害内容(哈希匹配与已知CSAM数据库进行比对)。
- **视频审核**:按固定间隔采样帧,对每帧运行图像分类器,结合音频转录(ASR→文本分类器)。
- **策略即代码**:审核策略以结构化规则定义,将模型输出映射到操作:
```python
if text_model.hate_speech_score > 0.9:
action = "remove"
elif text_model.hate_speech_score > 0.7:
action = "human_review"
else:
action = "allow"
```
- 策略频繁更改(新法规、不断发展的规范)。将策略与模型分离确保可以在不重新训练的情况下部署更改。
### 主动vs被动审核
- **主动审核**(发布前):在内容上线前运行分类器。高置信度违规自动阻止。这防止了有害内容被看到,但会增加发布延迟并存在误报风险(阻止合法内容)。
- **被动审核**(发布后):内容立即上线。用户可以举报违规。举报触发分类器+人工审核。发布者延迟低,但有害内容在检测到之前是可见的。
- **大多数平台两者都用**:对高严重性类别(CSAM:零容忍,发布前阻止)使用主动审核,对细微类别(虚假信息:需要人工判断,收到举报后审核)使用被动审核。
### 哈希匹配
- 对于已知有害内容(CSAM、恐怖主义宣传),使用**感知哈希**:计算对微小修改(裁剪、调整大小、压缩)鲁棒的图像/视频哈希值。与已知有害内容数据库(NCMEC的哈希数据库、GIFCT共享哈希数据库)进行比较。匹配→立即移除,无需分类器。
- **PhotoDNA**(微软)是CSAM检测的标准感知哈希。在许多司法管辖区这不仅是技术选择,更是法律义务。
### 粗略估算数字
- **规模**:每天10亿条帖子=约12K帖子/秒。每个帖子需要:文本分类(约5ms)、图片分类(约20ms)、哈希匹配(约1ms)。在12K QPS下:需要约60个文本分类器、约240个图片分类器和约12个哈希匹配器(加上冗余)。
- **人工审核**:如果2%的帖子被标记审核=每天2000万条。以每人每天100条审核计,需要20万审核员(这就是自动化准确率至关重要的原因:误报每降低0.1%就能每天节省100万条审核)。
- **延迟预算**:主动审核必须在发布流水线内完成(约500ms)。文本(5ms)+ 图片(20ms)+ 哈希(1ms)+ 开销=远在预算之内。视频是例外:即使从10分钟视频中每秒采样1帧,也需要600次分类器调用→异步处理。
### 升级工作流
- 自动移除→人工审核上诉→专家审核(法律、文化专家)→政策团队处理模糊案例。每个级别处理的案例更少但更细致。
- **反馈给模型**:人工审核决策是重新训练的最高质量标签。模型和审核员之间的分歧被优先用于主动学习——它们代表了模型处理最差的案例。
---
## 6. 对话式AI(基于RAG的聊天机器人)
### 问题定义
- **目标**:一个能回答关于公司产品问题的聊天机器人,使用其文档。
- **要求**:准确(不产生幻觉)、引用来源、处理后续问题、保持在产品领域内。
![RAG架构:嵌入查询,搜索向量数据库寻找相关块,重新排序,与原始查询一起输入LLM以生成有依据的响应](../images/rag_architecture.svg)
### 架构:检索增强生成(RAG
```
用户查询 → 查询嵌入 → 向量搜索(文档)→ Top-K块
用户查询 + 检索到的块 → LLM → 响应(含引用)
```
### 组件
- **文档摄入**:将文档分块并嵌入。**分块策略**非常重要:
- **固定大小分块**:每N个令牌(如500)分割,M个令牌(如50)重叠。简单,块大小可预测,但可能在句子中间或段落中间分割,丢失上下文。
- **语义分块**:在段落或章节边界分割。每个块是一个连贯的信息单元。大小可变(有些块100个令牌,其他800个),需要检索系统处理可变长度。
- **递归分块**:尝试在段落边界分割。如果段落太长,在句子边界分割。如果句子太长,在固定大小分割。连贯性和大小一致性的最佳平衡。
- **嵌入**:用文本编码器(如E5、BGE、Cohere embed)嵌入每个块。存储在向量数据库中。
- **检索**:嵌入用户查询,搜索向量数据库中最相似的$k$个块(通常$k = 5$-$10$)。可选地使用交叉编码器重新排序以提高精度。
- **生成**:构建包含检索块作为上下文的提示:
```
系统:你是一个有用的助手。仅基于提供的上下文回答。
如果答案不在上下文中,请说"我不知道。"
上下文:
[块 1]
[块 2]
...
用户:{问题}
```
- **护栏**:防止LLM回答产品领域外的问题、生成有害内容或与检索到的上下文相矛盾。实现为:输入过滤(拒绝离题查询)、输出过滤(检查响应是否与检索到的上下文一致)和宪法提示(指示模型拒绝某些请求)。
- **对话记忆**:维护最近$n$轮对话。将其包含在提示中,使模型能理解后续问题("定价如何?"→需要关于哪个产品的先前上下文)。
### 查询重写
- 用户经常问模糊的后续问题:"定价如何?"(什么产品的定价?)。**查询重写**使用对话历史生成独立查询:
- 输入:对话历史 + "定价如何?"
- 重写后:"产品X的企业版定价是多少?"
- 这个重写后的查询才是被嵌入并在向量数据库中搜索的。如果没有重写,检索会搜索"定价"而没有上下文,返回不相关的块。
- 查询重写可以用小型LLM调用(约50ms)或微调的序列到序列模型(约5ms)完成。
### 粗略估算数字
- **文档语料库**:10K页,每页平均2000个令牌=2000万令牌。以每块500个令牌、50个重叠计=约44K个块。
- **嵌入索引**44K块×768维×float16=约65 MB。轻松适合内存。即使1000万个块也仅约15 GB。
- **延迟分解**:查询嵌入(5ms)+ 向量搜索(2ms)+ 交叉编码器重新排序(前50个20ms+ LLM生成(500-2000ms= 总计约600-2100ms。LLM占主导地位。使用流式传输减少感知延迟。
- **成本**:以$3/100万令牌(Claude/GPT-4 API)计,每天1000次查询、每次约2000个令牌=约$6/天。大规模(每天100万次查询)下,在2个A10G GPU上自托管7B模型(约$50/天)可实现100倍成本降低。
### 评估
- **检索质量**Recall@K(前K个块是否包含答案?)、MRR(平均倒数排名)。
- **生成质量**:事实准确性(响应是否匹配检索到的上下文?)、有依据性(响应是否引用了正确块?)、答案相关性。
- **端到端**:用户满意度(赞/踩)、转接给人工客服的比率。
---
## 7. 大规模图像搜索
### 问题定义
- **目标**:给定一张图像,从10亿+图像的语料库中找到视觉上相似的图像。
- **应用**:反向图像搜索、产品搜索(照片→匹配的产品)、重复检测。
- **延迟**:<500ms(包括网络往返时间)。
### 架构
```
查询图像 → 嵌入模型(ViT/CLIP)→ 512维向量 → ANN搜索 → Top-K结果
```
### 嵌入提取
- **模型**:预训练的视觉编码器(ViT、CLIP的图像编码器、DINOv2)。如果需要,在特定领域(时尚、电商、医学影像)上进行微调。
- **训练**:对比学习(第10章)。正样本对=同一图像的不同视角(或图像+匹配的文本)。负样本对=随机图像。模型学习为相似图像生成相似嵌入,为不同图像生成不同嵌入。
### 索引
- **离线**:嵌入所有10亿张图像并构建ANN索引。对于HNSW(文件03),构建索引需要数小时,索引存储在内存中(10亿×512维×float16 + 图开销约128 GB)。
- **分片**:将索引拆分成跨多台机器。每台机器持有一个分片。查询时,并行搜索所有分片并合并前K个结果。
- **增量更新**:新图像(上传、新产品)必须添加到索引中。HNSW支持增量插入而无需重建。向量数据库(Milvus、Pinecone)原生处理此需求。
### 服务
- **嵌入服务**:运行ViT模型的GPU服务器。延迟:每张图像约20ms。批量处理多个查询以提高吞吐量。
- **搜索服务**:ANN索引服务器。延迟:对于10亿向量中搜索前100个(使用HNSW)约10ms。
- **缓存**:缓存热门查询的结果。对于重复检测,缓存最近上传的图像的嵌入,在搜索完整索引之前将新上传与缓存进行比较。
### 评估
- **Precision@K**:前K个结果是否实际相似?
- **Recall@K**:在语料库中所有真正相似的图像中,有多少在前K个中?
- **平均精度均值(mAP)**:精确率-召回率曲线下的面积。
- **人工评估**:对于主观相似性,人工评分员判断检索到的图像是否相关。
---
## 面试框架
- 当你遇到系统设计问题时,遵循此框架:
1. **澄清需求**(2-3分钟):询问规模、延迟、一致性要求和边缘情况。"多少用户?可接受的延迟是多少?故障时会发生什么?"
2. **高层设计**(5-7分钟):画出主要组件及其交互。从正常路径开始。使用文件01-03中的模式。
3. **深入探讨**(15-20分钟):选择最有趣/最具挑战性的组件并详细设计。这是你展示深度的地方。对于ML系统,深入探讨通常涉及:模型架构、特征流水线或服务架构。
4. **评估和监控**(3-5分钟):你如何衡量成功?可能出什么问题?你如何检测和响应问题?
5. **迭代**(2-3分钟):如果有更多时间/资源,你会改进什么?这表明你理解权衡并能设定优先级。
- **面试官看中的**:结构化思维(不是直接跳到解决方案)、权衡意识(每个选择都有代价)、实践知识(你确实构建过系统)和沟通能力(你能清晰解释你的设计吗?)。