Files
maths-cs-ai-compendium-zh/chapter 17: AI inference/04. edge inference.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

213 lines
13 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.
# 边缘推理
*边缘推理在用户设备(手机、笔记本电脑、物联网传感器)上运行模型,无需将数据发送到云端。本文涵盖边缘限制、模型压缩流水线、设备端运行时、编译器栈、硬件目标(NPU、神经引擎)、设备端LLM、联邦学习和延迟优化*
- 云端推理需要网络连接,增加延迟(50-200毫秒往返),每次请求花费金钱,并将用户数据发送到第三方服务器。**边缘推理**消除了所有四个问题:模型本地运行,即时响应,每次推理零成本,且数据保持私密。
- 权衡:边缘设备的计算和内存比数据中心GPU小100-1000倍。使模型在这些约束下运行需要在每个层面进行积极优化。
- **Cactus**[github.com/cactus-compute/cactus](https://github.com/cactus-compute/cactus)) 是一个专为移动和可穿戴设备构建的低延迟AI引擎。它在生产中展示了本文涵盖的许多技术:自定义ARM SIMD内核用于注意力和矩阵运算(第16章)、KV缓存量化(第17章文件01)、分块预填充、Apple和Qualcomm芯片上的NPU加速推理、零拷贝内存映射实现10倍更低的RAM使用,以及在设备端计算不足时的自动云回退。Cactus支持跨iOS、Android、macOS和嵌入式Linux的多模态推理(LLM、视觉、语音),并提供Swift、Kotlin、Python、Flutter、React Native和Rust的SDK。其基准测试显示,在M4 Pro上1.2B INT4模型解码达到100 tokens/s,在iPhone 17 Pro上达到48 tokens/s——这是优化边缘推理的具体示例。
## 边缘约束
| 资源 | 云GPUH100) | 笔记本电脑(M4 | 手机(Snapdragon 8 Gen 3 | IoTESP32 |
|----------|-----------------|-------------|---------------------------|-------------|
| 内存 | 80 GB HBM3 | 16-36 GB 统一内存 | 8-12 GB LPDDR5 | 520 KB |
| 计算 | 989 TFLOPSFP8 | 38 TOPS(神经引擎) | 45 TOPSNPU | 0.001 TOPS |
| 功耗 | 700 W | 15-30 W | 5-10 W | 0.1 W |
| 存储 | TB | 256 GB-2 TB | 128-512 GB | 4 MB |
- 云GPU和手机NPU之间的计算差距约为20倍。GPU和微控制器之间的差距约为1,000,000倍。不同设备需要不同程度的压缩和不同的模型架构。
## 模型压缩流水线
- 对于边缘部署,压缩不是单一技术——它是一个按顺序应用的互补技术**流水线**:
```
完整模型(FP3270B参数)
↓ 知识蒸馏 → 更小模型(7B参数)
↓ 结构化剪枝 → 移除冗余头/层(4B有效)
↓ 量化(INT4) → 4倍更小(2 GB)
↓ 编译器优化 → 融合内核,优化内存布局
↓ 运行时 → 设备端执行
```
- 每一步减少大小和延迟。顺序很重要:先蒸馏(减少架构),然后剪枝(移除结构),然后量化(降低精度),最后编译(为目标硬件优化)。在量化之后进行蒸馏会试图压缩已经损失质量的模型。
## 设备端运行时
- **运行时**加载模型、分配内存并在目标硬件上执行推理。每个平台有其偏好的运行时:
- **ONNX Runtime**:跨平台(Windows、Linux、macOS、iOS、Android)。支持CPU、GPUCUDA、DirectML、CoreML、NNAPI)和许多加速器后端。最具可移植性的选项。模型从PyTorch/TensorFlow导出为ONNX格式。
- **TensorFlow LiteTFLite**Google的边缘运行时。针对ARM CPU和Android NPU优化。二进制文件小巧(约1 MB)。支持INT8和float16。Android部署的标准。
- **Core ML**Apple的iOS/macOS运行时。根据模型特征自动使用神经引擎、GPU或CPU。模型使用`coremltools`从PyTorch/TensorFlow转换。与Apple硬件紧密集成(统一内存、神经引擎)。
- **ExecuTorch**Meta新推出的设备端PyTorch运行时。专为边缘部署设计,具有提前编译和操作级硬件加速器委派功能。PyTorch Mobile的继任者。
- **TensorRT**NVIDIA的GPU推理优化运行时(第15章)。融合层、选择最优内核并自动量化。在NVIDIA GPU上比PyTorch eager模式快2-5倍。
- **llama.cpp**:用于LLM的单文件C++推理引擎。支持GGUF量化(Q4、Q5、Q8)、CPUAVX/NEON)、MetalApple GPU)、CUDA和Vulkan。在消费级硬件上运行LLM的首选方案。
## 编译器栈
- 在高级模型(PyTorch图)和硬件(NPU指令)之间是**编译器栈**,它为特定目标优化模型:
```
PyTorch模型
↓ 导出(torch.export、ONNX、TorchScript
图IR(中间表示)
↓ 图优化
- 常量折叠(编译时计算常量表达式)
- 死代码消除(移除未使用的操作)
- 算子融合(conv + bn + relu → 单个融合操作)
- 布局转换(NCHW → NHWC用于ARM,通道最后)
↓ 降级
硬件特定IR
↓ 后端优化
- 分块和循环排序(缓存友好的访问模式)
- 向量化(SIMD,第16章)
- 内存规划(重用缓冲区以最小化峰值内存)
- 内核选择(为每个操作选择最佳实现)
↓ 代码生成
机器代码 / NPU指令
```
- **算子融合**是影响最大的优化。一个Transformer块约有20个操作(矩阵乘、加法、层归一化、softmax等)。没有融合,每个操作将其输出写入内存,下一个操作再读回。有了融合,多个操作组合成一个内核,将数据保留在寄存器/缓存中。这可以使速度快2-5倍(第16章,屋顶模型)。
- **内存规划**:编译器分析模型图以确定哪些张量的生命周期重叠,可以共享相同的内存缓冲区。一个有100个中间张量的模型可能只需要10张量的内存,因为大多数张量在其他张量创建之前就被消耗和释放了。这在内存有限的设备上至关重要。
## 硬件目标
### 移动GPU
- **Qualcomm Adreno**Android):支持OpenCL、Vulkan计算(第16章)和Qualcomm专有的SNPESnapdragon神经处理引擎)。Adreno GPU具有256-1024个ALU,支持FP16和INT8。
- **ARM Mali**Android):支持OpenCL和Vulkan。Mali GPU使用基于图块的架构(与桌面GPU不同),这影响最优内存访问模式。
- **Apple GPU**iOS/macOS):通过MetalApple的GPU API)访问。统一内存架构意味着没有CPU↔GPU复制开销。Metal Performance ShadersMPS)提供优化的ML原语。
### 神经处理单元(NPU
- NPU是专门为ML推理设计的固定功能加速器。它们在标准ML操作(矩阵乘、卷积、激活)上比GPU节能得多。
- **Apple神经引擎**16核,约38 TOPSINT8)。通过Core ML访问。非常适合视觉模型和设备端扩散。不能运行任意代码——只支持Core ML支持的操作。
- **Qualcomm Hexagon NPU**:集成到Snapdragon SoC中。支持INT8和INT4推理。通过SNPE或ONNX Runtime(带QNN后端)访问。为设备端功能如背景虚化、语音识别和实时翻译提供支持。
- **Google Edge TPU**:云端TPU的小型低功耗版本。4 TOPS,2W。用于Coral设备进行设备端推理。仅支持INT8量化的TFLite模型。
- **委派模式**:运行时在NPU(用于支持的操作)和CPU(用于不支持的操作)之间拆分模型图。最大化在NPU上运行的部分是性能和能效的关键。
## 设备端LLM
- 在手机和笔记本电脑上运行LLM已变得可行,得益于小模型和积极的量化:
| 模型 | 参数 | 量化后大小 | 目标设备 | 性能 |
|-------|--------|---------------|---------------|-------------|
| Phi-3 Mini | 3.8B | ~2 GBQ4 | 手机/笔记本 | iPhone 15上~15 tokens/s |
| Gemma 2B | 2B | ~1.5 GBQ4 | 手机 | Pixel 8上~20 tokens/s |
| Llama 3.2 1B | 1B | ~700 MBQ4 | 手机 | ~30 tokens/s |
| Llama 3.2 3B | 3B | ~2 GBQ4 | 手机/笔记本 | ~15 tokens/s |
| Llama 3.1 8B | 8B | ~4.5 GBQ4 | 笔记本 | M2上~20 tokens/s |
- **挑战**
- **内存**:3B Q4模型占2 GB,但长对话的KV缓存增加了显著额外内存。手机上的上下文长度通常限制在2-4K token。
- **热节流**:持续推理使手机发热。连续生成30秒后,SoC会降低时钟速度以防止过热,性能下降30-50%。
- **电池**:以15 tokens/s运行3B模型消耗约3-5W。30分钟的对话消耗典型手机电池约5%。偶尔使用可以接受,但始终在线应用存在问题。
- **llama.cpp**是设备端LLM的标准。它在CPUAVX2、NEON、I8MM)、Apple GPUMetal)、NVIDIA GPUCUDA)、AMD GPUROCm/Vulkan)甚至手机上(通过Android上的Termux)运行。
## 联邦学习
- **联邦学习**在许多设备上训练模型,无需集中数据。每个设备在其本地数据上训练,计算梯度更新,并将只有更新(而非数据)发送到聚合更新的中央服务器。
- **算法**FedAvg):
1. 服务器将当前模型发送给$K$个选定设备。
2. 每个设备在其本地数据上微调模型几步。
3. 每个设备将其更新后的模型(或差异)发送回服务器。
4. 服务器平均更新:$W_{\text{new}} = \frac{1}{K} \sum_{k=1}^{K} W_k$。
5. 重复。
- **隐私**:原始数据从不离开设备。服务器只看到聚合的模型更新。**差分隐私**向更新添加噪声,使得无法从梯度中逆向推断单个数据点。
- **通信效率**:模型更新很大(与模型相同大小)。压缩技术减少了这一点:**梯度量化**(发送INT8梯度而不是FP32)、**稀疏化**(只发送最大的梯度)和**梯度累积**(做更多本地步骤,发送更少频率)。
- **应用**Google的键盘预测(Gboard)、Apple的语音识别、健康监测(在敏感健康数据上训练而不集中数据)。
## 延迟优化
- 除了压缩,还有几种技术减少端到端推理延迟:
- **提前退出**:在中间层添加分类头。如果模型在第6层(共24层)已经自信,则返回预测而不运行第7-24层。简单输入提前退出,困难输入使用完整模型。对于混合简单和困难输入的任务,平均延迟显著下降。
- **模型分区**:在NPU(对矩阵乘高效)、GPU(对不规则操作高效)和CPU(处理其他一切)之间拆分模型。编译器根据性能分析决定哪些操作去哪里。
- **缓存**:对于具有重复查询的应用(自动补全、代码补全),缓存最近的计算。如果用户输入"How do I"且模型最近生成了"How do I"的补全,可以重用缓存的KV缓存,完全跳过预填充阶段。
- **推测性预取**:预测用户下一步将做什么,在用户询问之前开始推理。聊天应用可能在用户阅读当前答案时开始生成可能后续问题的响应。
## 编程任务(使用CoLab或notebook
1. 模拟模型压缩流水线。从float32模型开始,依次应用蒸馏(模拟)、剪枝和量化,并跟踪每一步的大小。
```python
def compression_pipeline(original_params_M, original_bits=32):
size_mb = original_params_M * 1e6 * original_bits / 8 / 1e6
print(f"原始: {original_params_M}M 参数, {original_bits}-位 → {size_mb:.0f} MB")
# 步骤1:知识蒸馏(减少参数)
distilled_params = original_params_M * 0.15 # 70B → ~10B 等价
size_mb = distilled_params * 1e6 * original_bits / 8 / 1e6
print(f"蒸馏后 ({distilled_params:.0f}M 参数): {size_mb:.0f} MB")
# 步骤2:结构化剪枝(移除剩余30%)
pruned_params = distilled_params * 0.7
size_mb = pruned_params * 1e6 * original_bits / 8 / 1e6
print(f"剪枝后 ({pruned_params:.0f}M 参数): {size_mb:.0f} MB")
# 步骤3INT4量化
size_mb = pruned_params * 1e6 * 4 / 8 / 1e6
print(f"INT4量化后: {size_mb:.0f} MB")
print(f"总压缩比: {original_params_M * 1e6 * original_bits / 8 / 1e6 / size_mb:.0f}x")
print("=== 从70B模型开始 ===")
compression_pipeline(70000)
print("\n=== 从7B模型开始 ===")
compression_pipeline(7000)
```
2. 估计设备端推理延迟。给定模型的操作计数和硬件规格,计算是否满足延迟目标。
```python
def estimate_latency(model_name, params_M, bits, compute_tops, mem_bw_gbs, seq_len=256):
"""估计内存带宽受限模型的token生成延迟。"""
# 模型大小(字节)
model_bytes = params_M * 1e6 * bits / 8
# 解码是内存受限的:每token必须加载整个模型
time_per_token_ms = model_bytes / (mem_bw_gbs * 1e9) * 1000
# 每秒token数
tokens_per_sec = 1000 / time_per_token_ms
print(f"{model_name}: {params_M/1000:.1f}B 参数 @ {bits}-位 = {model_bytes/1e9:.1f} GB")
print(f" 内存带宽: {mem_bw_gbs} GB/s")
print(f" 每token时间: {time_per_token_ms:.1f} ms")
print(f" Tokens/秒: {tokens_per_sec:.0f}")
print()
# Apple M2 Pro200 GB/s 统一内存带宽
print("=== Apple M2 Pro (200 GB/s) ===")
estimate_latency("Llama-7B Q4", 7000, 4, 15.8, 200)
estimate_latency("Llama-7B Q8", 7000, 8, 15.8, 200)
estimate_latency("Llama-70B Q4", 70000, 4, 15.8, 200)
# 手机(Snapdragon 8 Gen 3):~50 GB/s LPDDR5
print("=== Snapdragon 8 Gen 3 (50 GB/s) ===")
estimate_latency("Phi-3 Mini Q4", 3800, 4, 45, 50)
estimate_latency("Llama-3B Q4", 3000, 4, 45, 50)
```