第四章:工程化
从"能跑"到"能用",工程化是大模型落地的最后一公里。
本章聚焦大模型从研究到生产的关键工程实践,涵盖推理优化、模型压缩、分布式训练和系统评估四大核心主题。掌握这些技术,你就能真正将大模型部署到真实业务场景中。
本章内容
| 页面 | 主题 | 核心内容 |
|---|---|---|
| 推理优化 | 加速模型推理 | KV Cache、PagedAttention、Continuous Batching、vLLM |
| 量化 | 模型压缩 | INT8/INT4 量化、GPTQ、AWQ、GGUF 格式 |
| 分布式训练 | 多卡/多机训练 | 数据并行、模型并行、DeepSpeed ZeRO、FSDP |
| 评估 | 模型能力评测 | 基准测试、LLM-as-a-Judge、人类评估 |
学习路线建议
- 推理优化:理解从 naive inference 到生产级推理引擎的完整优化链路
- 量化:掌握用更少显存跑更大模型的核心技巧
- 分布式训练:当一张卡装不下模型时,如何扩展到多卡多机
- 评估:训练完了怎么知道好不好?系统化评估方法论
前置知识
- 理解 Transformer 架构(第二章)
- 了解 LLM 训练流程(第三章)
- 基本的 PyTorch 使用经验
详细内容索引
deployment.md — 模型部署 (833 lines)
- 在大模型体系中的位置 (L14)
- 部署形态总览 (L29)
- 不同规模模型的硬件需求估算 (L37)
- 推理框架对比 (L59)
- 选型决策树 (L76)
- Ollama 使用指南 (L91)
- 安装与基础使用 (L95)
- API 调用 (L120)
- 自定义 Modelfile (L191)
- llama.cpp 量化推理 (L241)
- GGUF 格式 (L245)
- 量化级别对比 (L260)
- 模型转换与量化 (L274)
- Python 调用 llama.cpp (L302)
- vLLM 服务化部署 (L343)
- 基础部署 (L347)
- 关键参数调优 (L371)
- Python SDK 调用 (L396)
- vLLM 性能基准测试 (L460)
- Docker 容器化部署 (L528)
- vLLM Docker 部署 (L530)
- 性能调优实战 (L614)
- GPU 利用率优化 (L616)
- 调优参数速查表 (L663)
- 成本估算 (L674)
- 监控指标 (L731)
- 苏格拉底时刻 (L793)
- 常见问题 & 面试考点 (L805)
- 推荐资源 (L825)
distributed-hands-on.md — 分布式训练实操代码 (688 lines)
- 集合通信原语实战 (L19)
- 1.1 Broadcast — 一对多广播 (L23)
- 1.2 All-Reduce — 全局规约 (L70)
- 1.3 All-Gather — 全局收集 (L88)
- 1.4 Ring All-Reduce — 带宽最优的规约 (L106)
- DDP 数据并行实战 (L155)
- ZeRO 从零实现 (L230)
- 3.1 ZeRO-1:优化器状态分片 (L234)
- 3.2 ZeRO-2 与 ZeRO-3 的关键差异 (L291)
- 张量并行从零实现 (L344)
- 4.1 Column Parallel Linear(列并行) (L348)
- 4.2 Row Parallel Linear(行并行) (L382)
- 4.3 Transformer 中的组合方式 (L414)
- 流水线并行从零实现 (L438)
- 5.1 朴素版:逐 Stage 前向 + 反向 (L442)
- 5.2 GPipe:Micro-Batch 减少 Bubble (L502)
- Ring Attention / 序列并行 (L571)
- 6.1 核心思想 (L575)
- 6.2 简化实现 (L586)
- 面试高频考点 (L662)
- 推荐资源 (L676)
distributed.md — 分布式训练 (1721 lines)
- 在大模型体系中的位置 (L14)
- 为什么需要分布式? (L34)
- 一个具体的例子:训练 Llama 70B (L36)
- 显存占用的"四大金刚" (L66)
- 计算需求也很惊人 (L84)
- 数据并行 (Data Parallelism) (L108)
- 基本原理 (L110)
- DDP 实现 (L143)
- 数据并行的瓶颈 (L204)
- DeepSpeed ZeRO (L218)
- ZeRO Stage 1:优化器状态分片 (L222)
- ZeRO Stage 2:梯度分片 (L251)
- ZeRO Stage 3:参数分片 (L272)
- ZeRO-Offload & ZeRO-Infinity (L328)
- DeepSpeed 配置实战 (L345)
- 张量并行 (Tensor Parallelism) (L397)
- Megatron-LM 的列并行与行并行 (L401)
- Self-Attention 的张量并行 (L482)
- MLP 的张量并行 (L515)
- 张量并行核心代码 (L550)
- 流水线并行 (Pipeline Parallelism) (L649)
- 朴素流水线的气泡问题 (L653)
- GPipe:微批次流水线 (L692)
- 1F1B 调度策略 (L717)
- Interleaved 1F1B (L738)
- 3D 并行 (L768)
- DP + TP + PP 如何组合 (L770)
- 通信拓扑设计原则 (L814)
- Context Parallelism / Ring Attention (L836)
- Expert Parallelism (L938)
- 3D/4D/5D 并行实践 (L1040)
- FSDP (Fully Sharded Data Parallel) (L1236)
- FSDP 简介 (L1238)
- FSDP vs DeepSpeed ZeRO Stage 3 (L1271)
- 分布式训练中的通信原语 (L1294)
- AllReduce, AllGather, ReduceScatter (L1296)
- Ring AllReduce 算法详解 (L1351)
- Ray 上的 AllReduce 示意 (L1393)
- 分布式训练系统实战:verl 的 Single-Controller 架构 (L1441)
- 实战:常见配置方案 (L1522)
- 不同规模模型的推荐并行策略 (L1524)
- 常见框架选择 (L1535)
- 实用配置示例 (L1546)
- 苏格拉底时刻 (L1594)
- 常见问题 & 面试考点 (L1660)
- 高频面试题 (L1662)
- 推荐资源 (L1699)
- 论文 (L1701)
- 开源框架 (L1709)
- 教程与博客 (L1716)
evaluation.md — 评估 (629 lines)
- 为什么评估很难? (L13)
- 主流 Benchmark 详解 (L22)
- MMLU(Massive Multitask Language Understanding) (L24)
- HumanEval(代码生成) (L46)
- GSM8K(数学推理) (L76)
- 其他重要 Benchmark (L96)
- 排行榜 (L108)
- Open LLM Leaderboard(HuggingFace) (L110)
- Chatbot Arena(LMSYS) (L127)
- AlpacaEval (L150)
- LLM-as-a-Judge 深度解析 (L159)
- Direct Scoring(直接打分) (L163)
- Pairwise Comparison(成对比较) (L179)
- Rubric Evaluation 与 HealthBench (L196)
- 常见偏差与缓解 (L248)
- MT-Bench 评测流程详解 (L267)
- 代码实现:构建一个简单的 LLM Judge (L286)
- 人类评估 (L363)
- 为什么仍然需要人类评估? (L365)
- Chatbot Arena 模式 (L372)
- 标注流程设计 (L381)
- 一致性指标:Cohen's Kappa (L419)
- 污染检测 (L437)
- 为什么需要关注污染? (L439)
- N-gram Overlap 检测 (L443)
- Benchmark 泄露的应对策略 (L467)
- 评估工具 (L477)
- lm-evaluation-harness (L479)
- Lighteval(HuggingFace) (L517)
- 面试考点 (L541)
- Benchmark 的局限性 (L543)
- 如何设计评估方案? (L554)
- 高频面试问答 (L592)
- 苏格拉底时刻 (L603)
inference.md — 推理优化 (1703 lines)
- 在大模型体系中的位置 (L14)
- LLM 推理的两个阶段 (L42)
- Prefill 阶段(计算密集) (L46)
- Decode 阶段(访存密集) (L57)
- 用 Roofline Model 分析为什么 Decode 是 Memory-Bound (L68)
- KV Cache (L100)
- 为什么需要 KV Cache (L102)
- KV Cache 的显存计算 (L121)
- PagedAttention (L151)
- 传统 KV Cache 的内存碎片问题 (L153)
- 虚拟内存的启发 (L162)
- 物理块与逻辑块 (L174)
- PagedAttention 内核实现 (L230)
- Copy-on-Write 优化(Beam Search 场景) (L304)
- Continuous Batching (L314)
- Static Batching 的低效 (L316)
- Continuous Batching 的调度策略 (L331)
- Chunked Prefill (L453)
- 长 Prefill 阻塞 Decode 的问题 (L455)
- 将 Prefill 拆分为 Chunks (L469)
- 投机采样 (Speculative Decoding) (L569)
- 核心思想:小模型草稿 + 大模型验证 (L571)
- 验证算法的数学保证(为什么输出分布不变) (L629)
- 接受率分析 (L681)
- EAGLE-3:基于特征层的树状投机采样 (L701)
- SpecExit:推理模型的思考早退 (L961)
- 投机采样方法对比 (L1041)
- Prefill-Decode 分离 (PD Disaggregation) (L1053)
- 为什么要分离? (L1055)
- 架构设计 (L1072)
- 关键组件职责 (L1085)
- KV Cache 传输策略 (L1093)
- vLLM 架构深度解析 (L1113)
- vLLM V0 架构 (L1117)
- vLLM V1 架构演进 (L1201)
- 端侧推理引擎 (L1356)
- 端侧推理的约束与机会 (L1367)
- 主流开源端侧引擎 (L1384)
- llama.cpp 的实现解读 (L1396)
- MLC LLM 的实现解读 (L1477)
- 移动端实战:Android 跑通最小例子 (L1528)
- 端侧 vs 云端推理对比 (L1564)
- 选型建议与常见坑 (L1584)
- 苏格拉底时刻 (L1604)
- 常见问题 & 面试考点 (L1645)
- 高频面试题 (L1647)
- 性能指标速查 (L1665)
- 推荐资源 (L1677)
- 必读论文 (L1679)
- 代码与工具 (L1689)
- 博客与视频 (L1698)
merging.md — 模型合并 (896 lines)
- 在大模型体系中的位置 (L13)
- 为什么要合并模型? (L30)
- 合并方法详解 (L48)
- Linear(线性插值) (L50)
- SLERP(球面线性插值) (L104)
- Task Arithmetic(任务算术) (L193)
- TIES(Trim, Elect Sign & Merge) (L241)
- DARE(Drop And REscale) (L318)
- 方法对比总结 (L372)
- mergekit 工具使用 (L384)
- 安装 (L388)
- 配置文件格式 (L399)
- 运行合并 (L466)
- 实战:合并 LoRA 适配器 (L488)
- 方法 1:先合并回基座再合并 (L492)
- 方法 2:直接合并 LoRA 权重 (L552)
- Frankenmerge(跨架构层拼接) (L597)
- MoE 合并 (L639)
- 合并后评估策略 (L687)
- 使用 lm-evaluation-harness (L749)
- 实战:完整合并流程 (L772)
- 苏格拉底时刻 (L853)
- 常见问题 & 面试考点 (L867)
- 推荐资源 (L887)
profiling.md — GPU 性能分析与调试 (463 lines)
- 在大模型体系中的位置 (L11)
- GPU 显存计算 (L27)
- 模型参数显存 (L29)
- 训练时的显存组成 (L46)
- 激活值显存 (L69)
- KV Cache 显存 (L95)
- 实用:快速估算脚本 (L109)
- torch.profiler 实战 (L158)
- 基础用法 (L160)
- 带 Warmup 的 Schedule Profiling (L201)
- 自定义标注 (L237)
- 常见性能瓶颈与优化 (L253)
- CPU-GPU 同步阻塞 (L255)
- 显存碎片化 (L278)
- 数据加载成为瓶颈 (L302)
- 矩阵维度不对齐 (L330)
- 实战:Profiling 一个 Transformer (L348)
- Roofline 模型:判断计算密集 vs 访存密集 (L407)
- 苏格拉底时刻 (L432)
- 常见问题 & 面试考点 (L442)
- 推荐资源 (L455)
quantization.md — 量化 (586 lines)
- 在大模型体系中的位置 (L14)
- 为什么需要量化? (L28)
- 显存计算 (L30)
- 推理延迟分析 (L51)
- 量化基础 (L65)
- 均匀量化 (L67)
- 量化粒度 (L106)
- 量化误差分析 (L118)
- INT8 量化 (L128)
- LLM.int8()(bitsandbytes) (L130)
- SmoothQuant (L160)
- INT4 量化 (L172)
- NormalFloat (NF4) (L176)
- bitsandbytes FP4 实现 (L193)
- GPTQ (L269)
- AWQ(Activation-aware Weight Quantization) (L303)
- GGUF 格式 (L320)
- 为什么需要 GGUF? (L322)
- 量化级别 (L330)
- llama.cpp 量化流程 (L345)
- PTQ vs QAT (L362)
- Post-Training Quantization (PTQ) (L364)
- Quantization-Aware Training (QAT) (L372)
- 选择指南 (L380)
- 各方案对比表格 (L389)
- 实战复现:手撕量化 (L400)
- Absmax 量化:对称量化的最简版本 (L404)
- Zero-point 量化:非对称量化的标准实现 (L428)
- 把整个模型量化掉:deepcopy + 原地替换 (L455)
- 用困惑度量化「量化的代价」 (L481)
- LLM.int8():交给 bitsandbytes 处理离群值 (L506)
- 跑通建议 (L530)
- 苏格拉底时刻 (L538)
- 常见问题 & 面试考点 (L562)
- 推荐资源 (L577)
ray-framework.md — Ray 分布式框架 (861 lines)
- 在大模型体系中的位置 (L13)
- Ray 核心概念 (L37)
- 1.1 四大组件 (L39)
- 1.2 执行模型 (L48)
- 1.3 为什么 vLLM 和 verl 都选择 Ray? (L65)
- Actor 编程模型 (L75)
- 2.1 远程函数(Task) (L77)
- 2.2 Actor(有状态远程对象) (L120)
- 2.3 异步执行模式 (L161)
- 分布式通信模式 (L208)
- 3.1 Actor 间直接通信 (L212)
- 3.2 多 Actor 并发通信 (L247)
- 3.3 Tensor 传输与共享对象 (L268)
- 3.4 Actor Group + 数据切片下发模式 (L291)
- 3.5 Ray + PyTorch Distributed 集合通信 (L348)
- Ray 分布式推理 (L436)
- 4.1 基本思路 (L438)
- 4.2 用 Ray 实现 All-Reduce (L450)
- 4.3 vLLM 中的 Ray 使用 (L467)
- verl 的 Single-Controller + Multi-Worker 架构 (L501)
- 5.1 设计哲学:把分布式藏在装饰器里 (L507)
- 5.2 启动一个 Worker Group (L528)
- 5.3 Dispatch 装饰器:把通信策略写进函数签名 (L561)
- 5.4 Hybrid Engine:让多个角色挤进同一个 Worker (L601)
- 5.5 PPO 主循环:Driver 视角的五步 (L632)
- 在 vLLM 和 verl 中的应用 (L674)
- 6.1 vLLM:多卡 Tensor Parallel 调度 (L676)
- 6.2 OpenRLHF:vLLM 权重热更新的两条通路 (L703)
- 苏格拉底时刻 (L802)
- 面试考点 (L826)
- Q1: Ray 的 Actor 和 Erlang/Akka 的 Actor 有什么区别? (L828)
- Q2: 为什么 vLLM 用 NCCL 而不用 Ray Object Store 做 tensor parallel 通信? (L832)
- Q3: verl Hybrid Engine 中 rollout 和 training 共享 GPU 的技术挑战? (L836)
- Q4: verl 的
@register(dispatch_mode=Dispatch.DP_COMPUTE_PROTO)装饰器到底做了什么? (L840) - Q5: OpenRLHF 为什么要支持 NCCL 和 CUDA IPC 两种权重同步通路? (L844)
- 推荐资源 (L850)
safety.md — LLM 安全 (1030 lines)
- 在大模型体系中的位置 (L13)
- 威胁全景:OWASP LLM Top 10 (L30)
- Prompt Injection(提示注入) (L51)
- 直接注入(Direct Prompt Injection) (L55)
- 间接注入(Indirect Prompt Injection) (L79)
- Prompt Injection 检测器实现 (L111)
- Jailbreaking(越狱攻击) (L270)
- 经典越狱手法 (L274)
- 为什么越狱难以根治? (L318)
- LLM 幻觉(Hallucination) (L332)
- 幻觉的分类 (L334)
- 幻觉的成因 (L342)
- 幻觉缓解策略 (L356)
- 数据投毒与后门攻击 (L414)
- 训练数据投毒 (L416)
- 供应链攻击 (L441)
- 防御体系 (L451)
- 输入过滤层 (L453)
- 输出安全过滤器 (L495)
- Guard Model(守卫模型) (L581)
- Red Teaming(红队测试) (L628)
- 安全评估工具 (L641)
- garak (L643)
- Rebuff (L671)
- 纵深防御架构 (L726)
- 实战复现:abliteration——把 refusal 从权重里减掉 (L787)
- 数据准备:harmful vs harmless 对照(Cell 1) (L799)
- 采集 residual stream 激活(Cell 4) (L825)
- 计算每一层的 refusal direction(Cell 5) (L861)
- 推理时验证:方向消融 hook(Cell 6 节选) (L893)
- 把方向"焊死"进权重(Cell 8) (L921)
- 跑通建议 (L951)
- 这告诉我们什么 (L973)
- 苏格拉底时刻 (L988)
- 常见问题 & 面试考点 (L1002)
- 推荐资源 (L1022)
