科学计算技术层次结构
AI 算力技术层次结构,从上层应用到硬件的计算资源调用链路如下。注意 GPU 计算为异构计算,包含运行在 CPU 上的管控面代码和运行在 GPU 上的数据面代码。
| 层次 | CPU 管控面 | GPU 数据面 |
|---|---|---|
| 大模型应用层 | 提示词与记忆管理 | 不感知 |
| 模型算法层 | 实现具体的 AI 模型算法 | 不感知 |
| AI 引擎层 | 按照模型结构定义运行 AI 模型 | 按照模型算法要求实现张量计算的算子 |
| 科学计算接口层 | 规定跨硬件厂商的加速计算调用规范 | 提供 GPU 编程语言,供上层进行算子编写,编译产生 GPU 目标程序 |
| HAL 层 + 系统调用 | 各硬件厂商提供的用户态 API 接口,封装硬件调用 | 透传 GPU 目标程序 |
| drm | 显卡管理的"大内总管" | 不感知 |
| 内核驱动层 | 按照操作系统驱动规范实现硬件驱动 | 透传 GPU 目标程序到显存中 |
| 硬件层 | 硬件资源管理 | 执行 GPU 目标程序 |
各层详解
大模型应用层
使用 AI 模型完成业务逻辑,负责具体的应用落地,增加应用层的优化技术以提高用户使用体验,例如:提示词、调度与记忆管理等。代表技术:LangChain 框架;
模型算法层
定义模型的核心逻辑,使用数学和算法构建网络结构,如 Transformer、CNN 等,用 Python 或框架 API 编码,不直接涉及硬件优化,重点是模型设计和训练逻辑。代表技术:Transformer、CNN、CLIP;
AI 引擎层
引擎层负责加载和运行 AI 模型。向上,引擎指定支持的模型格式,支持 AI 模型的持久化和再加载;在本层,引擎将模型的结构和权重进行展开,按照模型的算法运行模型;向下,引擎使用各家硬件厂商提供的硬件资源进行加速计算,核心动作是编写运行在各家硬件上的张量计算算子,使得模型的推理和训练速度尽量地大,压榨硬件的性能。PyTorch 等框架提供抽象接口,让开发者无需关心硬件细节。框架定义统一的张量算子接口(如 add、matmul),由各厂商后端实现具体调用。自定义算子可封装 torch.Tensor 操作,调用下层 API。NVIDIA 的 CUDA C++ 用于编写内核,框架编译这些为可执行代码。桥接算法和硬件,允许跨设备移植代码。
代表技术:PyTorch 框架、vllm 引擎、deepspeed 引擎、llama.cpp;
加速计算 API 接口层
提供编程接口,编写运行在加速硬件上的程序。CUDA C++ 是 NVIDIA 的 DSL,编写算子代码编译为 PTX,支持线程块和共享内存管理。Triton 是 OpenAI 的开源 DSL,简化内核编写并支持自动调优。接口层编译高层代码为中间码交给驱动处理,重点是性能优化。代表技术:CUDA C++、Triton;
HAL + 系统调用
硬件抽象层提供用户空间库,隐藏内核细节,由硬件厂商编写提供。提供libcuda.so用于计算任务(如 cuBLAS 库的线性代数),libnvidia-glcore.so处理图形渲染,这一层是闭源的,厂商需要确保兼容性。PyTorch 通过 torch.cuda 调用libcuda.so使用 CUDA 功能,libcuda.so继续向下通过/dev/nvidia*节点和文件操作进入内核态调用硬件。内核驱动
内核驱动透传控制和 GPU 程序到硬件,由硬件厂商编写提供。NVIDIA 驱动曾是数百 MB 的大型 blob,且是闭源的,驱动将 PTX 转为 SASS(特定于 GPU 架构的机器码),调度 SM、内存分配和上下文切换。后通过 GSP 架构重构为模块化设计,将闭源代码和编译逻辑向 HAL 层和硬件转移,驱动层则面向了开源。AMD 的 ROCm 驱动类似但开源程度更高。硬件层
底层物理芯片执行计算,包括 NVIDIA GPU(A100/H100)、AMD GPU(MI300 系列)、Google TPU、华为昇腾 NPU 等。硬件决定峰值性能,如 H100 的 80 TFLOPS FP16。趋势是向定制 ASIC 发展以降低功耗。
PyTorch
Pytorch 是 Facebook 开源的深度学习框架,它引导社区的 AI 模型训练生态,让社区形成许多无形的路径依赖。目前,多数 AI 引擎多会围绕 Pytorch 继续构建,从而复用当前已有的社区生态。
Triton
OpenAI 牵头的标准接口,PyTorch 2.0 成为其一等公民,有望成为统一硬件数据面的 DSL。
GSP 架构
GSP(GPU System Processor)是 NVIDIA 从 Turing 架构开始在 GPU 芯片上集成的专用 RISC-V 处理器,将原本运行在内核驱动中的复杂逻辑下沉到 GPU 固件中执行,然后将计算语法编译的任务上移到用户态去做。
背景
早期 NVIDIA 驱动的 .ko 内核模块体积高达数百 MB,原因在于它承担了过多职责:接收 GLSL、HLSL、PTX 等多种上层代码,在内核态完成编译并生成机器码。这种设计带来两个严重问题:
- 驱动膨胀:内核模块承载编译器、调度器等复杂逻辑,代码体积难以控制。
- 维护困境:闭源驱动与 Linux 内核演进冲突频发,社区无法介入修复。
GSP 的引入改变了这一局面。内核驱动现在只负责透传命令到 GSP 固件,由固件完成 GPU 初始化、任务调度、PTX 编译等核心工作。这带来以下收益:
- 驱动瘦身:内核模块仅保留必要的信令逻辑,体积大幅缩减。
- 固件可控:NVIDIA 可通过固件更新修复问题,无需重发驱动。
- 开源契机:内核态逻辑简化后,NVIDIA 得以发布开源内核模块(Open Kernel Modules),改善了与 Linux 社区的关系。
现状
GSP 固件由内核驱动在初始化阶段加载到 GPU 的专用显存区域执行。它接管了显示引擎、电源管理、上下文切换等核心职能,内核驱动通过 RPC 机制与 GSP 通信,提交计算任务和查询状态。
在 GSP 架构下,编译职责被重新分配:
- GSP 固件:负责 GPU 硬件初始化、任务调度、电源管理、显示输出控制等底层职能。
- 内核驱动:仅保留设备枚举、内存映射、中断处理等薄层逻辑,透传命令到 GSP。
- 用户态运行时:负责将上层计算语法(CUDA、HLSL、GLSL)编译为中间表示(PTX 或 SPIR-V),再通过 HAL 层接口提交给驱动。
这种分层使得 NVIDIA 能够开放内核驱动源码(Open Kernel Modules),同时将编译器等复杂逻辑保留在用户态闭源库中。对于上层开发者,NVIDIA 推荐直接通过 HAL 层提交 PTX(计算)或 SPIR-V(图形),而算子语言(如 Triton)和着色器语言则可作为前端 DSL 自由定制,只要最终编译到这些中间表示即可。
PTX 和 SPIR-V
PTX(Parallel Thread Execution)是 NVIDIA 的虚拟指令集架构,类似于 Java Bytecode 或 WebAssembly。它以可读的文本/汇编形式存在,核心价值是跨代兼容——从 Maxwell 到 Blackwell,GPU 硬件架构差异巨大,PTX 提供了一套稳定的带寄存器抽象的指令,让开发者无需为每代显卡重写代码。GSP 内置的 ptxas 编译器会在运行时将 PTX 即时编译为 GPU 真正执行的机器码 SASS(Streaming Assembly)。
SPIR-V(Standard Portable Intermediate Representation)则是 Khronos 制定的跨厂商中间表示,服务于 Vulkan 和 OpenCL 生态。与 PTX 的 NVIDIA 专有定位不同,SPIR-V 的目标是跨硬件兼容——同一份 SPIR-V 二进制可在 AMD、Intel、NVIDIA 等不同 GPU 上执行。SPIR-V 采用二进制格式而非文本格式,更紧凑但不可直接阅读。
| 特性 | PTX | SPIR-V |
|---|---|---|
| 制定方 | NVIDIA | Khronos |
| 格式 | 文本/汇编 | 二进制 |
| 兼容范围 | 仅 NVIDIA GPU | 跨厂商(AMD/Intel 等) |
| 主要用途 | CUDA 计算 | Vulkan 图形、OpenCL 计算 |
| 运行时编译 | 驱动内置 ptxas | 驱动内置 SPIR-V 编译器 |
在新架构下,NVIDIA 的 HAL 层同时支持接收 PTX 和 SPIR-V,开发者可根据目标平台选择合适的中间表示。