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/ 构建缓存
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
# 部署与 DevOps
|
||||
|
||||
*部署是你的模型从研究产物变成产品的地方。本文涵盖用于机器学习的 Docker、模型推理、实验追踪、可重现性、生产环境监控、特征存储和管道编排——这些基础设施将一个训练好的模型从 notebook 带到数百万用户面前。*
|
||||
|
||||
- 一个只在你笔记本电脑上运行的模型是原型。一个能够可靠地大规模运行、在毫秒内提供预测结果、能够从故障中恢复并在不中断服务的情况下更新的模型才是产品。两者之间的差距就是**部署与 DevOps**。
|
||||
|
||||
- 大多数机器学习工程师在部署、监控和调试生产问题上花费的时间比训练模型还多。理解这些基础设施对于任何构建真实 ML 系统的人来说都不是可选项。
|
||||
|
||||
## 用于机器学习的 Docker
|
||||
|
||||
- 我们在第 13 章(操作系统)中概念性地介绍了容器。这里我们关注实践方面:为机器学习工作负载编写 Dockerfile。
|
||||
|
||||
- **Dockerfile** 是构建容器镜像的配方:
|
||||
|
||||
```dockerfile
|
||||
# 从官方的 CUDA 基础镜像开始
|
||||
FROM nvidia/cuda:12.1.0-cudnn8-runtime-ubuntu22.04
|
||||
|
||||
# 系统依赖
|
||||
RUN apt-get update && apt-get install -y \
|
||||
python3.11 python3-pip git \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Python 依赖(单独安装以利用缓存)
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# 复制源代码(频繁更改,因此此层放在最后)
|
||||
COPY src/ /app/src/
|
||||
COPY configs/ /app/configs/
|
||||
WORKDIR /app
|
||||
|
||||
# 入口点
|
||||
CMD ["python3", "src/scripts/serve.py", "--config", "configs/serve.yaml"]
|
||||
```
|
||||
|
||||
- **层缓存**:Docker 会缓存每一层。如果 `requirements.txt` 没有变化,`pip install` 在重新构建时会被跳过。将不常更改的层(系统包、pip 安装)放在频繁更改的层(源代码)之前。这将 10 分钟的构建变成 10 秒的重新构建。
|
||||
|
||||
- **GPU 访问**:使用 `nvidia/cuda` 基础镜像,并使用 `docker run --gpus all` 运行。`nvidia-container-toolkit` 提供从宿主机到容器的 GPU 透传。
|
||||
|
||||
- **多阶段构建**通过将构建环境与运行环境分离来减小镜像大小:
|
||||
|
||||
```dockerfile
|
||||
# 构建阶段:安装构建工具、编译依赖
|
||||
FROM python:3.11 AS builder
|
||||
COPY requirements.txt .
|
||||
RUN pip install --user -r requirements.txt
|
||||
|
||||
# 运行阶段:仅运行环境依赖
|
||||
FROM nvidia/cuda:12.1.0-cudnn8-runtime-ubuntu22.04
|
||||
COPY --from=builder /root/.local /root/.local
|
||||
COPY src/ /app/src/
|
||||
ENV PATH=/root/.local/bin:$PATH
|
||||
```
|
||||
|
||||
- 最终镜像只包含运行时库,不包含编译器、头文件或构建工具。一个 5GB 的构建镜像变成了 2GB 的运行镜像。
|
||||
|
||||
- **Docker Compose** 运行多容器设置(模型服务器 + 负载均衡器 + 监控):
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
services:
|
||||
model:
|
||||
build: .
|
||||
ports:
|
||||
- "8080:8080"
|
||||
deploy:
|
||||
resources:
|
||||
reservations:
|
||||
devices:
|
||||
- capabilities: [gpu]
|
||||
prometheus:
|
||||
image: prom/prometheus
|
||||
ports:
|
||||
- "9090:9090"
|
||||
```
|
||||
|
||||
## 模型推理
|
||||
|
||||
- **模型推理**是将推理作为服务运行:接收请求、运行模型、返回预测结果。
|
||||
|
||||
- **FastAPI**(在文件 03 中介绍)适用于低到中等吞吐量的最简单方法。对于高吞吐量和 GPU 优化推理,使用专用工具:
|
||||
|
||||
- **Triton Inference Server**(NVIDIA):以 TensorRT、ONNX、PyTorch 和 TensorFlow 格式提供模型。特性:
|
||||
- **动态批处理**:收集单个请求并将它们分批处理以提高 GPU 效率。单个请求流被分组为 32 的批次,大幅提高吞吐量。
|
||||
- **模型集成**:在单个请求中链式调用多个模型(预处理器 → 模型 → 后处理器)。
|
||||
- **多模型推理**:在同一 GPU 上提供多个模型,共享资源。
|
||||
- **并发模型执行**:在同一 GPU 上并行运行多个推理请求。
|
||||
|
||||
- **TorchServe**(PyTorch):以 REST/gRPC API 提供 PyTorch 模型。支持模型版本控制、A/B 测试和自定义处理器。
|
||||
|
||||
- **vLLM**:专门用于 LLM 推理。实现了 PagedAttention(高效的 KV 缓存管理)、连续批处理和跨 GPU 的张量并行。对于大语言模型,吞吐量比朴素推理高出 10-20 倍。
|
||||
|
||||
- **Cactus**([github.com/cactus-compute/cactus](https://github.com/cactus-compute/cactus)):一个用于移动端和边缘端设备推理的低延迟 AI 引擎。Cactus 提供**兼容 OpenAI 的 API**(聊天补全、流式传输、工具调用、转录、嵌入、RAG、视觉),完全在设备上运行,当本地模型无法处理请求时自动进行**云回退**。这种混合架构意味着你的应用程序代码使用相同的 API,无论推理是在本地还是在云端运行——引擎根据模型置信度和设备能力来决定。提供 Python、Swift、Kotlin、Flutter、React Native 和 Rust 的 SDK,以及 HuggingFace 上预转换的模型权重。支持多模态推理(LLM、视觉、语音),配备自定义 ARM SIMD 内核以实现 ARM CPU 上的最快推理,以及零拷贝内存映射以实现 10 倍 RAM 使用降低(第 16 章、第 17 章)。
|
||||
|
||||
- **模型格式优化**:
|
||||
- **ONNX**:用于互操作性的开放格式。从 PyTorch/TensorFlow 导出,在任何地方运行。
|
||||
- **TensorRT**:NVIDIA 的优化器。融合层、选择最佳内核、量化权重。在 NVIDIA GPU 上通常比 PyTorch 快 2-5 倍。
|
||||
- **GGUF/GGML**:适用于 CPU 高效推理的格式,在消费级硬件上运行 LLM 时很流行。
|
||||
|
||||
## 实验追踪
|
||||
|
||||
- 没有实验追踪,机器学习研究会退化为:"我觉得上周二那个我改了些配置的模型是最好的,但我不记得改了啥。"
|
||||
|
||||
- **Weights & Biases(W&B)**:最流行的实验追踪工具。从你的训练脚本中记录任何内容:
|
||||
|
||||
```python
|
||||
import wandb
|
||||
|
||||
wandb.init(project="my-project", config={
|
||||
"model": "transformer",
|
||||
"lr": 3e-4,
|
||||
"batch_size": 64,
|
||||
})
|
||||
|
||||
for epoch in range(num_epochs):
|
||||
train_loss = train_one_epoch()
|
||||
val_loss = validate()
|
||||
|
||||
wandb.log({
|
||||
"train/loss": train_loss,
|
||||
"val/loss": val_loss,
|
||||
"epoch": epoch,
|
||||
})
|
||||
|
||||
# 将模型记录为产物
|
||||
if val_loss < best_loss:
|
||||
wandb.save("best_model.pt")
|
||||
|
||||
wandb.finish()
|
||||
```
|
||||
|
||||
- W&B 提供:用于比较运行的仪表板、超参数扫描工具、模型注册表、数据集版本控制和团队协作。
|
||||
|
||||
- **MLflow**:开源替代方案。在本地或服务器上运行:
|
||||
|
||||
```python
|
||||
import mlflow
|
||||
|
||||
mlflow.set_experiment("my-experiment")
|
||||
|
||||
with mlflow.start_run():
|
||||
mlflow.log_params({"lr": 3e-4, "batch_size": 64})
|
||||
mlflow.log_metric("val_loss", 0.042, step=epoch)
|
||||
mlflow.pytorch.log_model(model, "model")
|
||||
```
|
||||
|
||||
- **模型注册表**:训练模型的中央存储,带版本控制、阶段(开发 → 预发布 → 生产)和元数据。W&B 和 MLflow 都提供注册表。注册表回答:"当前生产环境中的是哪个模型,谁训练的,其验证准确率是多少,以及由哪个代码/数据产生?"
|
||||
|
||||
## 可重现性
|
||||
|
||||
- 可重现性意味着:给定相同的代码、数据和配置,产生相同的模型。这在机器学习中出奇地困难,因为 GPU 操作的非确定性、数据打乱和浮点数累积。
|
||||
|
||||
- **可重现性检查清单**:
|
||||
|
||||
| 什么 | 如何做 |
|
||||
|------|------|
|
||||
| 代码版本 | Git 提交哈希值 |
|
||||
| 配置 / 超参数 | 配置文件(在 Git 中版本控制或记录到 W&B) |
|
||||
| 随机种子 | 设置并记录所有种子(Python、NumPy、PyTorch、CUDA) |
|
||||
| 数据版本 | DVC 哈希值、数据集版本标签或 S3 对象版本 |
|
||||
| 依赖项 | `pip freeze`、Docker 镜像哈希值或锁定文件 |
|
||||
| 硬件 | GPU 类型、GPU 数量、CUDA 版本 |
|
||||
| 非确定性 | `torch.backends.cudnn.deterministic = True`(较慢但可重现) |
|
||||
|
||||
- **锁定所有内容**:`pip install torch==2.2.1` 而不是 `torch>=2.0`。次版本号升级可能改变数值行为、优化器实现或默认超参数。
|
||||
|
||||
- **使用 Docker 实现可重现性**:Docker 镜像锁定了操作系统、系统库、Python 版本和 pip 包。镜像哈希值是完整的环境指纹。如果你能重现 Docker 镜像,就能重现训练。
|
||||
|
||||
## 生产环境监控
|
||||
|
||||
- 部署模型不是终点——而是一系列新问题的开始。随着现实世界的变化(**概念漂移**)以及输入数据分布的变化(**数据漂移**),模型会随时间推移而退化。
|
||||
|
||||
- **需要监控的内容**:
|
||||
|
||||
- **延迟**:推理需要多长时间?追踪 p50(中位数)、p95 和 p99。p99 为 500ms 意味着每 100 个用户中有 1 个要等待半秒钟,这可能不可接受。
|
||||
|
||||
- **吞吐量**:每秒处理多少个请求?系统是否跟得上需求?
|
||||
|
||||
- **错误率**:有多少比例的请求失败(异常、超时、无效输入)?
|
||||
|
||||
- **模型指标**:在验证集上的准确率、精确率、召回率。如果生产环境中存在标注数据(例如用户纠正),追踪在线指标。
|
||||
|
||||
- **数据漂移**:输入数据的分布是否发生了变化?在白天照片上训练的模型可能在夜间照片上失败。统计检验(KS 检验、PSI)将训练分布与在线分布进行比较。
|
||||
|
||||
- **特征漂移**:单个特征的分布是否发生了变化?训练时呈正态分布但在生产时呈双峰分布的特征,表明数据管道存在问题。
|
||||
|
||||
- **工具**:
|
||||
- **Prometheus** + **Grafana**:基础设施监控的标准方案。Prometheus 收集指标,Grafana 将其可视化为带告警的仪表板。
|
||||
- **Evidently AI**:开源机器学习监控。生成关于数据漂移、模型性能和数据质量的报告。
|
||||
|
||||
- **告警**:不要只放在仪表板上——设置自动告警。"如果 p99 延迟超过 200ms 持续 5 分钟,发送 Slack 通知。""如果数据漂移评分超过阈值,通知值班工程师。"
|
||||
|
||||
## 特征存储
|
||||
|
||||
- **特征存储**是预计算特征的集中式仓库,在训练和推理之间共享。它解决两个问题:
|
||||
|
||||
- **训练-推理偏差**:训练期间使用的特征必须与推理期间使用的特征完全相同。如果训练使用一种方式计算的 `user_age_at_signup`,而推理使用不同的方式计算,模型的预测结果会静默出错。
|
||||
|
||||
- **特征复用**:多个模型通常使用相同的特征(用户人口统计、物品嵌入、聚合统计)。计算一次并共享,避免了重复和不一致性。
|
||||
|
||||
- **Feast** 是最流行的开源特征存储。它管理在线特征(低延迟,从 Redis 或 DynamoDB 提供)和离线特征(批处理,存储在数据仓库中用于训练)。
|
||||
|
||||
- 特征存储对于推荐系统、欺诈检测以及任何特征从原始数据管道计算而来的应用都至关重要。
|
||||
|
||||
## 管道编排
|
||||
|
||||
- 生产级机器学习系统不仅仅是模型。它是一个**管道**:数据采集 → 预处理 → 特征计算 → 训练 → 评估 → 部署 → 监控。每个步骤依赖于前一步骤,可以独立失败,可能需要在不同的时间表上运行。
|
||||
|
||||
- **编排器**管理这些管道:
|
||||
|
||||
- **Apache Airflow**:数据管道编排的标准方案。DAG(有向无环图)定义任务依赖关系。每个任务独立运行,失败时可以重试,并通过 Web UI 进行监控。
|
||||
|
||||
```python
|
||||
# airflow DAG 示例(简化)
|
||||
from airflow import DAG
|
||||
from airflow.operators.python import PythonOperator
|
||||
|
||||
dag = DAG("training_pipeline", schedule="@daily")
|
||||
|
||||
preprocess = PythonOperator(task_id="preprocess", python_callable=preprocess_data, dag=dag)
|
||||
train = PythonOperator(task_id="train", python_callable=train_model, dag=dag)
|
||||
evaluate = PythonOperator(task_id="evaluate", python_callable=evaluate_model, dag=dag)
|
||||
deploy = PythonOperator(task_id="deploy", python_callable=deploy_model, dag=dag)
|
||||
|
||||
preprocess >> train >> evaluate >> deploy
|
||||
```
|
||||
|
||||
- **Kubeflow Pipelines**:在 Kubernetes 上运行机器学习特定编排。每个步骤在容器中运行,GPU 资源按需分配,实验自动追踪。
|
||||
|
||||
- **Prefect** 和 **Dagster**:Airflow 的现代替代方案,拥有更好的开发者体验、原生 Python API 和内置数据血缘追踪。
|
||||
|
||||
- **何时需要编排**:当你的管道有超过 2-3 个步骤、按计划运行、涉及多个团队或服务、或需要自动故障恢复时。单一脚本的训练任务不需要编排器。每天重新训练的管道——从 5 个数据源采集数据、训练 3 个模型、评估它们并部署最佳模型——绝对需要。
|
||||
Reference in New Issue
Block a user