AI 生态底层库全景:从硬件到框架
把 PyTorch、CUDA、Metal 及常见周边库放在同一张栈图里,标清边界与依赖。具体 API 与版本以各官方文档为准。
0. 读前对齐
读者:要写训练/推理、或做环境排障的工程背景读者;不要求会写 GPU 驱动。
不覆盖:各库逐函数手册;硬件微架构未公开细节;云厂商计费与配额细则。
读完应能:
- 画一张自顶向下栈图,标出「你的代码」落在哪一层。
- 判断「慢」更可能来自算子实现、显存带宽、CPU 预处理、Python 开销还是分布式通信。
- 说出 NVIDIA / Apple / AMD 三条路径各自依赖的驱动与运行时名字。
- 知道 PyTorch 的 eager / compile / distributed 分别主要和栈上哪些层打交道。
1. 一张总图:AI 软件栈分层模型
从下到上可以粗分为七层(层名是教学用划分,真实产品会有交叉):
- 硬件:GPU SM、Tensor Core、显存容量与带宽、L2/片内 SRAM;多卡 NVLink/PCIe;Apple 统一内存架构(CPU/GPU 共享同一物理内存池)。
- 固件与驱动:把「设备」暴露给操作系统与用户态:NVIDIA 的 CUDA Driver;Apple 的 Metal 驱动与 GPU 固件。
- 设备运行时与命令提交:CUDA Runtime / Driver API;Metal 的
MTLDevice、MTLCommandQueue、MTLCommandBuffer。这一层回答「如何把一段计算送到加速器上执行」。 - 数学与并行原语:稠密/稀疏线性代数(cuBLAS、cuSPARSE、hipBLAS…)、FFT、DNN 卷积/归一化等高度优化算子(cuDNN)、多 GPU 集合通信(NCCL)。这一层回答「常见算子谁已经写好了」。
- 深度学习运行时:张量内存布局、算子调度、算子融合、图或 trace 执行、CUDA Graph 一类降低 launch 开销的机制;以及把「框架算子」映射到上述库或自研 kernel。
- 框架层:PyTorch / JAX / TensorFlow:自动微分、优化器、模块 API、分布式封装、与 Python/C++ 边界。
- 更上层:数据管线、训练编排(Ray、Slurm)、推理服务(vLLM、TensorRT-LLM)、MLOps。
一句话:CUDA/Metal 解决「设备上能算什么」;cuBLAS/cuDNN/NCCL 解决「常见算子与多卡怎么快」;PyTorch 解决「你怎么写模型且可微分」;再往上解决「怎么在集群上跑完业务」。
[应用: 训练脚本 / 推理服务]
|
[框架: PyTorch JAX ...] ← autograd, nn, distributed
|
[DL 运行时: 调度/融合/图] ← torch.compile, inductor, ...
|
[原语库: cuBLAS cuDNN NCCL ...] / MPS / ROCm 等价物
|
[设备运行时: CUDA / Metal / HIP ...]
|
[驱动与硬件]
2. 硬件与厂商路线速览
2.1 NVIDIA GPU:生态默认假设从何而来
NVIDIA GPU 由大量 SM(流式多处理器) 组成,每个 SM 上执行大量线程束(warp)。Tensor Core 提供矩阵乘累加的硬件加速路径,是现代混合精度训练(FP16/BF16/FP8 等)吞吐的关键。显存(HBM/GDDR)带宽往往是大模型 attention 或宽激活的瓶颈,而不是峰值 FLOPs 本身。
为何论文与教程默认 CUDA:在数据中心与工作站上,NVIDIA GPU + CUDA 栈历史最长、工具链最全(分析器、调试器、多机通信、推理编译器),多数 DL 框架的「第一优化目标」也是这条路径。
2.2 Apple Silicon:统一内存与 GPU 计算路径
Apple Silicon 上 CPU、GPU、NPU 共享 统一内存(UMA):没有「把张量拷到离散显存」这一步的经典模型,CPU 与 GPU 指针有时可直接共享(仍要注意同步与缓存一致性)。Metal 是 Apple 的 GPU 计算与图形 API;MPS(Metal Performance Shaders) 提供一批苹果维护的常用算子/图元,PyTorch 的 mps 设备大量依赖其成熟算子。
与「离散 GPU + CUDA」相比:峰值算力与显存容量通常不是同一档位,但 数据在 CPU/GPU 间搬运成本 常更低;另一方面,生态上第三方 CUDA kernel 无法直接跑在 Apple GPU 上,许多前沿算子要等框架或 MPS 补齐。
2.3 AMD、Intel、其他加速器
- AMD + ROCm / HIP:HIP 在源码层刻意接近 CUDA C 习惯,许多项目可做「机械式移植」,但 wheel、驱动、框架 CI 覆盖 仍常弱于 NVIDIA,排障成本需计入。
- Intel GPU + oneAPI / SYCL:在数据中心与客户端都有布局;PyTorch 等可通过插件或 Intel 扩展对接,普及度因场景而异。
- Google TPU:硬件与 XLA 栈强绑定,心智模型更接近「在 TPU 上跑 XLA 程序」,与「买张 GPU 装 CUDA」路径不同。
选型结论:生产默认路径仍常是 NVIDIA;个人 Mac 开发走 Metal/MPS;成本/政策约束再评估 AMD/Intel/云 TPU。
3. CUDA 生态:不是「一个库」,而是一叠库
3.1 CUDA Toolkit 与驱动:Runtime vs Driver API
日常说的「装 CUDA」通常指 CUDA Toolkit(编译器 nvcc、开发头文件、示例、cuda-gdb 等)与 驱动支持的 CUDA 版本 的组合关系:驱动版本决定可用的最高 CUDA 特性,Toolkit 版本用于编译本地扩展。常见「版本地狱」:PyTorch wheel 内置的 CUDA runtime、本机 nvcc、驱动三者不一致导致 import 失败或仅部分算子可用。
概念区分:Driver API 更底层;Runtime API(cudaMalloc, <<<>>> launch)更常用。PyTorch 预编译包一般自带运行时,不强制你本机装完整 Toolkit,除非你要编译自定义 CUDA 扩展。
3.2 线性代数与 DNN 基元:cuBLAS、cuDNN、cuSPARSE 等
- cuBLAS:通用矩阵乘(GEMM)等 BLAS 操作;全连接、投影层、大量线性代数热点会落到这里。
- cuDNN:卷积、归一化、RNN、attention 等 DNN 专用高度优化实现;框架在「默认算子路径」上经常间接调用。
- cuSPARSE / cuFFT:稀疏与傅里叶变换;在特定模型结构里成为热点。
PyTorch 在 CUDA 上多数算子通过 ATen/第三方 kernel 最终落到这些库或自研 kernel。性能调优边界:算子是否支持你的 dtype/形状、是否走了融合路径、是否触发额外 memcpy。
3.3 编译与算子生成:NVRTC、CUDA C++、CUTLASS、Tensor Core 友好内核
实现层次从低到高大致是:
- 手写 CUDA C++ kernel:极致控制,维护成本高。
- CUTLASS 等模板库:在「可组合矩阵块」层面拼装高效 GEMM/conv。
- NVRTC 运行时编译:动态生成小 kernel。
- Triton / TorchInductor:用 Python 或编译器管线生成内核,与 PyTorch 2.x
torch.compile深度结合。
趋势:越来越少业务手写 CUDA,更多在框架编译层或 Triton 层解决;手写仍常见于全新算子或库尚未覆盖的极端形状。
3.4 多 GPU 与多机:NCCL、NVSHMEM、UCX(概念层)
NCCL(NVIDIA Collective Communications Library) 实现 all-reduce、broadcast 等集合通信,是 多卡训练(torch.distributed 默认 GPU 后端)的事实标准之一。NVSHMEM 提供更偏 GPU 内存模型的通信原语;UCX 常在 MPI/集群网络栈中出现。PyTorch 侧你写的是 distributed.all_reduce;底层在 NV 环境下常落到 NCCL 与驱动/PCIe/NVLink 拓扑。
3.5 推理与部署:TensorRT、CUDA Graphs
TensorRT:把模型图做强融合与内核选择,偏部署优化,与 PyTorch 训练图是不同产品阶段。CUDA Graphs:把一串 kernel launch 录成图,降低 CPU 提交开销,对 小 batch 推理 或 固定拓扑 很有效。与 PyTorch 的关系:torch.compile、专用推理引擎或导出 ONNX/TensorRT 各自衔接;选型看 延迟 vs 通用性 vs 维护成本。
4. Metal 与 Apple 上 ML 栈
4.1 Metal、MPS、Command Buffer 心智模型
Metal 里常见路径:MTLDevice 创建设备 → MTLCommandQueue → 编码 MTLCommandBuffer(渲染或计算 pass)→ commit 异步执行 → 必要时 waitUntilCompleted 或依赖 GPU 时间戳同步。
与 CUDA 类比:command buffer 像一串异步 work 的容器;commit 类似 launch;同步粒度与 CUDA stream/event 不同,但「默认异步、显式同步」的心智一致。Metal 同时服务 macOS/iOS,同一套 API 家族跨设备,但算力与内存模型依芯片差异很大。
4.2 PyTorch 在 Apple 上的后端:MPS 设备
使用 device = torch.device("mps") 时,算子由 PyTorch MPS 后端实现,底层依赖 Metal/MPS 是否已实现对应 op。支持算子集是 CUDA 的真子集:新论文里的自定义 CUDA kernel 往往不能一键迁移;dtype(如部分整数/稀疏)也可能与 CUDA 路径不一致。
何时仍落 CPU:算子未实现、数值路径需要 fallback、或某些 op 在 MPS 上暂不稳定。工程上应对:关键训练步骤在目标生产 GPU 上复现,Mac 上更多做代码与小规模试验。
4.3 MLX(可选)
MLX 是 Apple 推出的数组/自动微分框架,风格接近 NumPy + 轻量训练 API,强调 统一内存与函数变换。与 PyTorch 相比:生态与第三方模型库仍小得多;适合 Apple 平台原生实验、教学、或新项目愿押注 MLX。若团队已深度 PyTorch,多数场景继续 PyTorch+MPS,只在确有收益时引入 MLX。
5. PyTorch:在栈里扮演什么角色
5.1 核心组成:ATen、c10、Autograd、Dispatcher
- c10:张量元数据、设备类型、dtype、存储与内存管理的基础库。
- ATen:张量运算与算子实现的核心 C++ 库;
torch.Tensor的 C++ 侧主体。 - Autograd:记录计算图、反向传播引擎;与 ATen 算子包装结合。
- Dispatcher:根据 dispatch key(CPU、CUDA、Autograd、Functionalize 等)把一次
aten::op分派到具体实现,是「同一 Python API 多后端」的中枢。
你在 Python 里调 torch.mm,经 Dispatcher 可能走到 CUDA 的 GEMM 实现或别的后端;PyTorch 是胶水与抽象层,性能仍取决于最终落到的 kernel 与内存搬运。
5.2 执行与编译:Eager、torch.compile、Inductor、Triton
- Eager:逐算子执行,调试简单,但可能错过 算子融合 与 常量折叠 等优化。
torch.compile:捕获 FX Graph 或 Dynamo trace,交给后端(常见 Inductor)生成融合代码;在 CUDA 上可生成 Triton kernel 或回退其他路径。
关系概括:compile 主要优化「框架调度与 kernel 选择」;不能替代 合理的模型结构、batch 大小与 IO 设计。
5.3 分布式:torch.distributed、FSDP、RPC
torch.distributed:进程组、后端(NCCL / Gloo / …)、collective 原语;DDP 在单机多卡与多机上包装梯度同步。- FSDP:参数分片与通信重叠,适合大模型训练。
- RPC:更一般的分布式执行模型,小众于标准数据并行训练。
单机多卡瓶颈常在 NVLink/PCIe 拓扑与 batch;多机瓶颈常在 网络带宽与 all-reduce 算法。
5.4 互操作:ONNX、TorchScript、torch.export
- ONNX:交换图与算子约定,便于对接 TensorRT、ONNX Runtime 等;算子集是交集模型,复杂控制流需额外处理。
- TorchScript /
torch.export:把 PyTorch 程序变成可部署、可分析的中间表示;与训练时 eager 行为可能有 语义差异,需验证。
边界:训练多在 PyTorch 内完成;部署常换栈(专用 runtime、量化、静态形状),互操作层负责「可迁移的最小子集」。
6. 跨平台与「第三选择」库
6.1 OpenMP / MPI:CPU 并行与 HPC 传统栈
OpenMP:共享内存 CPU 并行;PyTorch 部分 CPU 算子、数据加载、数值库可间接使用。MPI:多进程消息传递,传统 HPC 与一些分布式数据并行原型仍可见。深度学习主路径在 GPU 上时,它们仍影响 DataLoader、预处理、CPU fallback。
6.2 ROCm / HIP:AMD GPU 上的 CUDA 类比物
ROCm 提供 HIP 语言与工具链,许多 CUDA 概念可映射。PyTorch 存在 ROCm 构建,但 第三方 wheel、教程默认命令、算子覆盖率 可能不如 CUDA。排障要点:驱动与 ROCm 版本矩阵、框架发行说明里 unsupported ops、性能分析工具链是否齐全。
6.3 oneAPI / SYCL、Vulkan 计算
SYCL 是单源 C++ 异构编程模型,Intel/社区有实现;与 CUDA/Metal 相比更「标准 C++」,但在 DL 框架主路径上曝光相对少。Vulkan compute 更偏图形生态的通用计算,部分引擎用它做跨厂商 GPU 计算,与 PyTorch 日常训练距离较远。
6.4 LLVM、MLIR、XLA 等在栈中的位置
LLVM:编译器基础设施(优化与代码生成)。MLIR:多级中间表示,便于把「框架图」降到不同硬件。XLA 常见于 JAX/TPU 或 TensorFlow 编译路径。对多数 PyTorch 用户:Inductor/Triton 是更常感知的一层;LLVM/MLIR 在「编译器后端」深处。
7. 算子与内核生态:Triton、CUDA Python、自定义扩展
何时写 C++/CUDA 扩展:需要全新算子、库未覆盖、或必须手工控制共享内存与 warp 级原语时。
何时用 Triton:算子可表达为块级 tile 程序、希望快速迭代且由 Inductor 生成或手写 Triton kernel;在 NVIDIA 上生态最成熟。
与 PyTorch 2.x:torch.compile 把许多融合机会交给 Inductor→Triton;仍可在 ATen 注册自定义 op。
Python GIL:数值热点应在 C++/CUDA/Triton 内;Python 负责编排。若 GPU 等 CPU,先 profiling Python 侧与 DataLoader,而不是先调 kernel。
8. Python 科学计算底座:与 PyTorch 共生的库
NumPy / SciPy:数据与科学计算事实标准;与 torch.Tensor 互转时注意 拷贝 vs 共享内存(numpy() 与 from_numpy 的规则)。布局 row-major 与框架默认一致时 memcpy 更少。
cuDF / RAPIDS(可选):GPU 上 DataFrame/表处理,适合 ETL 与大规模特征与训练前处理衔接;引入后依赖 CUDA 与 RAPIDS 版本矩阵。
Packaging 与动态库:预编译 PyTorch wheel 常捆绑 CUDA runtime;若混装多个 CUDA toolkit,可能出现 符号或 libcuda 版本 冲突。排障思路:ldd/otool 看实际加载的 .so/.dylib,用虚拟环境隔离,避免全局 LD_LIBRARY_PATH 污染(Linux);macOS 注意 Framework 与 多个 Python 混用。
9. 选型与排障:按症状下钻到哪一层
| 症状 | 更可能层级 | 可动手验证(示例) |
|---|---|---|
| GPU 利用率长期很低 | Python/IO/同步;或小 batch 导致 launch 开销 | py-spy、Profiler、看 DataLoader、CUDA_LAUNCH_BLOCKING(仅调试) |
| 显存 OOM | 框架张量生命周期;或 KV/激活峰值 | torch.cuda.memory_summary、减小 batch、checkpoint、推理侧PagedAttention 等 |
| 单机多卡 scaling 差 | 通信拓扑;或 bucket 过小 | nvidia-smi topo -m、NCCL 环境变量、profiler 通信时间线 |
| Mac 上 MPS 报错 / 慢 | 算子未实现 fallback;或未用 MPS | 查 PyTorch MPS 文档 issue、对比 CPU 路径、升级版本 |
| import torch 即崩 | 驱动/CUDA wheel 不匹配 | 驱动版本、PyTorch 安装页矩阵、干净 venv |
开发机 vs 生产:Mac+MPS 适合写代码与小实验;与线上 NVIDIA 行为对齐 仍建议在相同或接近的 CUDA/驱动版本上做回归,避免算子差异与数值差异。
10. 小结与延伸阅读
Takeaway:
- CUDA/Metal 是设备运行时;cuBLAS/cuDNN/NCCL 等才是多数「快」的来源之一。
- PyTorch = 抽象 + 调度 + 微分;性能要看 Dispatcher 最终落到的 kernel 与 内存与通信。
- Apple 统一内存改变数据搬运心智,但不自动等价「与数据中心 GPU 同速」。
torch.compile把优化重心上移到编译栈;仍替代不了分布式与 IO 设计。- 排障先 分层:Python → 框架 → 运行时库 → 驱动 → 硬件。
延伸阅读(完整 URL):
- PyTorch Documentation
- CUDA Toolkit Documentation
- NVIDIA cuDNN
- NVIDIA NCCL
- Metal
- Metal Performance Shaders
- PyTorch MPS Backend
- MLX
- AMD ROCm
附录 A:术语与中英对照
| 术语 | 一句话 |
|---|---|
| CUDA | NVIDIA GPU 计算平台:驱动 + 运行时 + 开发工具链。 |
| Metal / MPS | Apple GPU 计算 API;MPS 为常用算子与图元库。 |
| cuBLAS / cuDNN | NVIDIA 提供的 GPU 稠密 BLAS 与深度学习算子库。 |
| NCCL | NVIDIA 多 GPU 集合通信库,常用于 all-reduce 等。 |
| Triton | OpenAI 发起的 GPU 编程语言与编译器,常与 Inductor 生成内核配合。 |
| ROCm | AMD GPU 计算栈;HIP 为接近 CUDA 的 C++ 接口。 |
附录 B:推荐阅读顺序
- 第 1 节总图 → 第 5 节 PyTorch 在栈中的位置。
- 主力 NVIDIA:第 3 节 → 第 7 节(算子与编译)。
- 主力 Apple:第 4 节 → 第 5 节 MPS 与
compile预期。 - 上线排障:第 9 节;术语速查:附录 A。