GPU架构与CUDA编程模型

Catalogue
  1. 0.前言
    1. 0.1 相关概念
  2. 1.GPU架构
  3. 2.CUDA编程模型
    1. 2.1 CUDA介绍
    2. 2.2 CUDA编程模型
    3. 2.3 CUDA的核心概念(重点)
    4. 2.4 开发和优化CUDA程序
    5. 2.5 CUDA环境架构
      1. 1. GPU硬件
      2. 2. CUDA Driver
      3. 3. CUDA Runtime API
      4. 4. CUDA Toolkit
        1. 4.1 CUDA Toolkit的版本选择
      5. 5. CUDA 编程模型
      6. 6. 疑问
        1. 6.1 nvcc & nvidia-smi
        2. 6.2 pytorch中使用gpu失败
    6. 2.6 Window WSL中的CUDA
      1. 1. 官方资料
      2. 2. CUDA on WSL User Guide
      3. 3. CUDA多版本管理和切换
      4. 4. Docker中使用nvidia GPU加速
        1. 4.1 前言
        2. 4.2 NVIDIA Container Toolkit
        3. 4.3 NVIDIA Docker 2
        4. 4.4 验证及使用方式
        5. 4.5 NVIDIA Docker原理
        6. 4.6 关于docker中的cuda版本
      5. 5. 基于nvidia/cuda镜像搭建容器开发环境
        1. 5.1 安装Miniconda3
        2. 5.2 python及其它框架安装

0.前言

高性能推理引擎、AI算法工程 对GPU CUDA性能优化的诉求目前是AI行业各个公司在算法工程上需要解决的问题。 以实现高效的并行计算,充分利用GPU计算资源,实现AI算法高性能推理.

AI行业可以分为两块:基础设施(infra)和算法模型. 一方面是建设和优化支持AI应用的基础设施,让GPU更好的使用起来。另一方面是研究和应用在这些基础设施上运行的先进算法。

其中infra包括:硬件基础设施(比如GPU架构、云计算平台)、软件工具(比如深度学习框架、数据处理工具)、以及相关的网络基础设施(比如高速网络连接)。GPU架构和CUDA编程模型可以被视为在这一基础设施层面的重要组成部分
而算法方面包括:机器学习算法(如监督学习、无监督学习、强化学习)、深度学习模型(如神经网络结构和训练方法)、以及在特定领域中的应用优化算法等。这些算法和模型构成了AI技术的核心,决定了AI系统在解决问题时的效果和性能。

本文介绍了CUDA编程模型(属于底层计算资源/硬件原理与加速)。 也包含了cuda环境搭建实践(理解cuda编程模型和GPU架构),后续对实践部分单独拆出来。

0.1 相关概念

并行计算 CUDA核心加速库

GPU池化、 GPU虚拟化 - 对GPU资源的分配和管控

算力平台:资源规划

国产智算芯片生态架构

1.GPU架构

2.CUDA编程模型

2.1 CUDA介绍

CUDA 是一种并行计算平台和编程模型,利用GPU的并行性能加速计算密集型任务。

熟悉并行计算的概念,如线程、块、网格等。

2.2 CUDA编程模型

  • CUDA 编程模型涉及编写主机(CPU)和设备(GPU)端代码。
  • 理解如何在CUDA中编写核函数(kernel functions)来在GPU上执行并行计算任务。

2.3 CUDA的核心概念(重点)

理解CUDA线程层次结构和内存管理。
学习如何使用CUDA工具集编译和调试CUDA程序。

2.4 开发和优化CUDA程序

实际开发并优化具有挑战性的任务,如矩阵乘法、向量加法等。
学习如何优化内存访问和并行计算以提高性能。

2.5 CUDA环境架构

CUDA是由NVIDIA推出的并行计算平台和编程模型,主要用于利用GPU进行通用目的的并行计算

是不是应该有个图?

1. GPU硬件

CUDA环境的核心是支持CUDA的NVIDIA GPU。这些GPU具有大量的并行处理单元(CUDA核心),专门设计用于高性能并行计算。CUDA能够利用这些核心并行处理大规模数据和复杂计算任务。

2. CUDA Driver

CUDA Driver是与NVIDIA GPU硬件交互的底层驱动程序。它负责管理GPU设备、分配计算资源并与操作系统进行交互。CUDA Driver与操作系统紧密结合,确保CUDA程序能够正确地访问和控制GPU资源。

3. CUDA Runtime API

CUDA Runtime API是一组库函数和接口,为开发人员提供了在CUDA环境中编写和执行GPU计算任务的方法。这些API包括设备管理、内存管理、执行控制和数据传输等功能。开发人员可以使用CUDA Runtime API来编写高效的GPU并行计算程序。

4. CUDA Toolkit

CUDA Toolkit是一个完整的开发工具包,包括CUDA编译器、调试器、性能分析工具和开发文档等。它提供了开发、编译和优化CUDA程序所需的所有工具和资源。CUDA Toolkit还包括针对不同NVIDIA GPU架构的优化库和示例代码,帮助开发人员实现最佳的性能和兼容性。

1
2
3
4
5
6
7
8
9
10
CUDA Toolkit不仅包含了CUDA Runtime API,还提供了更多的工具和资源,帮助开发者进行CUDA程序的开发、编译、优化和调试。
CUDA Toolkit中的CUDA Runtime API是其中一个重要的组成部分,但并不是整个Toolkit的全部内容。

- 关系
依赖关系:CUDA Toolkit依赖于CUDA Runtime API。也就是说,在使用CUDA Toolkit进行CUDA程序的开发时,
开发者需要调用CUDA Runtime API中提供的函数来实现与CUDA设备的交互和控制。
功能关系:CUDA Toolkit提供了比CUDA Runtime
API更广泛的功能,包括编译器、调试器和性能分析工具等,这些工具帮助开发者更高效地开发和优化CUDA应用程序。
使用方式:开发者通常会安装CUDA Toolkit来获取CUDA编译器、文档、示例代码等资源,并通过Toolkit中提供的工具
和CUDA Runtime API来编写、编译和调试CUDA程序。

4.1 CUDA Toolkit的版本选择

不同的深度学习框架的版本依赖的cuda(toolkit)版本也是不同的,存在兼容性问题。 所以不同的项目对CUDA toolkit的版本选择也需要慎重。
目前大体上 cuda11.x是稳定在用的版本,因此先选择11.x版本来学习深度学习项目。

  • 也可以在linux(我用的WSL)对cuda多版本管理.
  • 选择方式:综合考虑cuda和深度学习框架稳定、兼容的版本,如:
版本 Pytorch官方文档 Pytorch版本选择 tensorflow官方文档 tensorflow版本选择建议
11.x pytorch与cuda版本 Pytorch2.3.1;cuda:11.8 Tensorflow与cuda版本 tensorflow-2.12.0;py 3.8-3.11;GCC 9.3.1;Bazel 5.3.0;cuDNN8.6;CUDA11.8
12.x - - - tensorflow-2.15.0;py 3.9-3.11 ;Clang 16.0.0;Bazel 6.1.0;cuDNN8.9;12.2

总之,选择相互兼容的版本,安装合适版本的cuda toolkit。 选择的示例见以下:Window WSL中的CUDA

tensorflow安装:官方文档:Install TensorFlow with pip

1
2
3
# 如果是使用tensorflow,通过以下方式安装
python3 -m pip install tensorflow[and-cuda]
# 实际的版本是 tensorflow-2.13.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

5. CUDA 编程模型

CUDA 编程模型基于主机(CPU)与设备(GPU)之间的协同工作。开发者可以通过定义核函数(也称为CUDA核函数或者GPU核函数)来在GPU上并行执行操作,从而充分利用GPU的并行计算能力。核函数由开发者编写,并通过CUDA编译器转换为能够在GPU上执行的代码。

总结来说,CUDA环境架构包括GPU硬件、CUDA Driver、CUDA Runtime API、CUDA Toolkit和CUDA编程模型,为开发者提供了丰富的工具和资源,支持高效的并行计算和GPU加速应用程序的开发与优化。

6. 疑问

6.1 nvcc & nvidia-smi

CUDA有 runtime api 和 driver api

  • runtime api
  • driver api

问题:nvcc -V 和 nvidia-smi 显示出来的CUDA版本不一致, 有没有问题?

1.下面先分析一下版本不一致的原因:

从编译器、设备监控管理角度看:

  • nvcc属于CUDA的编译器,将程序编译成可执行的二进制文件.
  • nvidia-smi(NVIDIA System Management Interface) 是帮助管理和监控NVIDIA GPU设备的命令行工具.

从api角度,CUDA有 runtime api和driver api(并且两者都有对应的版本 ):

  • nvcc -V显示的就是前者的版本
  • nvidia-smi显示的是后者对应的CUDA版本s

2.这两个api的必要文件(安装)都是哪些呢?

  • driver api的必要文件由 GPU driver install 安装, nvidia-smi就属于这一类API
  • 而用于支持 runtime api的必要文件是由 GUDA Toolkit installer 安装的

nvcc是 CUDA Toolkit一起安装的CUDA compiler-driver tool 它只知道它自身构建时的CUDA runtime版本,并不知道安装了什么版本的GPU driver, 甚至不知道是否安装了 GPU driver

tips: GUDA Toolkit installer通常会集成了GPU dirver installer,如果你的CUDA均通过CUDA Toolkit installer来安装,那么runtime api和driver api的版本应该是一致的。 否则可能是使用了单独的 GPU driver installer,这样就导致nvidia-smi和nvcc -V显示的版本不一致了

通常driver api的版本是向下兼容runtime api的版本,即nvida-smi显示的版本大于nvcc -V的版本通常不会有大问题.

6.2 pytorch中使用gpu失败

The NVIDIA driver on your system is too old
问题:当在wsl中通过 pytorch 使用gpu时。 出现以下错误:
CUDA initialization: The NVIDIA driver on your system is too old (found version 10010).

原因分析:驱动的兼容性。 找到pytorch 兼容版本的 cuda即可。 并且安装pytorch依赖的nvidia依赖(python库). 具体详见以下: Window WSL中的CUDA

tips:WSL中的CUDA程序实际上是通过Windows上的NVIDIA驱动来访问GPU资源的

2.6 Window WSL中的CUDA

1. 官方资料

(1).CUDA on Windows Subsystem for Linux (WSL)

  • Windows 11 上的wsl不再是预览版,而是正式发布的WSL2。

(2).CUDA on WSL User Guide,内容包括:

  • 在WSL 2上使用NVIDIA CUDA软件架构(软件堆栈)
  • Getting Started with CUDA on WSL 2 (讲述了在wsl2中使用cuda的一系列步骤:驱动版本和安装、WSL2安装、CUDA Toolkit等)
    (以上官方文档仔细阅读)
    tips:从官方文档看到,驱动程序仅安装 NVIDIA GeForce Game Ready或NVIDIA RTX Quadro Windows 11显示驱动程序。
    (其中GeForce和RTX Quadro是两种不同显卡产品,GeForce面向消费者 适用游戏娱乐, Quadro适用于用于专业工作站和专业应用程序)

2. CUDA on WSL User Guide

如上文中官网的资料说明了CUDA on WSL User Guide,这里总结下实践流程(哪些改装,哪些不用装):

  1. 下载驱动程序。只下载和安装win环境驱动即可,选择符合要求的版本。注意如果是Quadro需要升级win11.
    tips: 安装了556.12版本/下载链接。在window环境中下载安装。
  2. 安装WSL2. (之前已经安装使用过,忽略。 建议升级win11)
    安装条件: win10登录windows账户并升级windows至预览版本, 大概1-2小时。win11应该可以直接使用了.
  3. CUDA Support for WSL 2(仅安装Linux CUDA Toolkit。在wsl中不用再安装Driver)
    安装toolkit那个版本? 见: wiki:CUDA Toolkit的版本选择与下载(wsl的在linux下)
  4. 安装CUDA toolkit 11.8版本(对pytorch、tensorflow兼容性好,python使用3.8及以后版本).
    官网:CUDA toolkit 版本选择.在wsl环境中下载安装.
    1
    2
    3
    4
    5
    6
    7
    # 下载和cuda toolkit 11.8(好几个G,有点大)
    wget .....
    sudo sh cuda_11.8.0_520.61.05_linux.run
    # 查看 cuda toolkit安装情况(查看路径下都有哪些版本的cuda)。
    ls -la /usr/local/
    # pytorch支持(创建python3.8环境后,安装PyTorch相关的库)
    pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
  5. 验证
    1
    2
    3
    4
    # 验证pytorch环境,python进入命令行模式后
    import torch
    torch.cuda.is_available()
    # 输出 True 则一切正常.
    1
    2
    # 验证 gpu tensorflow
    python3 -c "import tensorflow as tf; print(tf.config.list_physical_devices('GPU'))"

3. CUDA多版本管理和切换

linux环境中(包括wsl) 同链接文件路径方式生效,所以可以灵活选择切换

4. Docker中使用nvidia GPU加速

4.1 前言

以上 实现了 wsl中 搭建cuda环境以 使用GPU, 实现深度学习模型训练和推理。
但为了更好的移植性、通常会通过容器(docker) 实现 这些环境(cuda toolkit、python、pytorch、tensorflow、jupyter-lab)

关键词:容器环境启用GPU、NVIDIA Docker、GPU 服务器应用程序部署、可移植性
目的:在Docker中使用NVIDIA GPU加速.

以下是安装步骤(安装nvidia-docker)
前提:安装好了nvidia驱动、cuda、cudnn、docker基础版.
接下来需要安装的2个组件:NVIDIA Container Toolkit、NVIDIA Docker 2

4.2 NVIDIA Container Toolkit

NVIDIA Container Toolkit: 提供运行时环境和必要工具,以便Docker容器有效的访问和利用宿主机上的GPU资源. 主要包括 nvidia-container-runtime 和相关的库文件 (libnvidia-container)。它负责在容器内部管理 GPU 的访问和资源分配。

官方文档:cloud-native/container-toolkit

4.3 NVIDIA Docker 2

是一个 Docker 的插件,它与 Docker Engine 集成,简化了与 NVIDIA GPU 的交互和配置。它建立在 NVIDIA Container Toolkit 之上,通过 Docker CLI 扩展了对 GPU 的支持。

主要提供了 nvidia-docker 命令行工具,使得容器可以直接通过 —gpus 参数指定使用的 GPU 数量。

  • 依赖关系:NVIDIA Docker 2 依赖于 NVIDIA Container Toolkit 的运行时环境来管理和配置 GPU。

具体的安装步骤:在ubuntu中使用apt-get直接安装,具体不展开了.

1
2
3
4
5
6
# 保留下之前的安装方式. 最新的官方方式还没有尝试过,后续遇到问题可供参考
apt-get install nvidia-docker2:amd64=2.5.0-1 \
libnvidia-container-tools:amd64=1.3.3-1 \
nvidia-container-runtime:amd64=3.4.2-1 \
libnvidia-container1:amd64=1.3.3-1 \
nvidia-container-toolkit:amd64=1.4.2-1

4.4 验证及使用方式

官方文档:Sample Workload

Running a Sample Workload with Docker

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
sudo docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi

# 如果出现:docker: Error response from daemon: Unknown runtime specified nvidia.
# 则配置如下:
/etc/docker/daemon.json中添加
"runtimes": {
"nvidia": {
"path": "/usr/bin/nvidia-container-runtime",
"runtimeArgs": []
}
}
# 然后重启docker:sudo systemctl restart docker
----------
# 或者使用
docker run --gpus=all --rm nvidia/cuda:11.0-base nvidia-smi
# 测试nvidia-container及查看信息
sudo nvidia-container-cli -k -d /dev/tty info

4.5 NVIDIA Docker原理

在docker容器中使用GPU的原理是什么呢,硬件和软件架构是?

4.6 关于docker中的cuda版本

通过选择 指定版本的 docker镜像。
镜像站 国外的,超时下载不下来。建议使用以下:
NVIDIA官方的网站; nvcr.io/nvidia/

  • 此网站还包含了很多镜像和模型.推荐

对于版本的选择: 可以选择任意版本cuda的镜像,因为镜像里包含了完整的兼容的工具链(cuda toolkit、python、等等)
需要注意的是 镜像的版本类型,有base、runtime、cudnn8 等镜像。 它们的区别在于:

  • base是基础镜像,提供了cuda运行时库和基础工具. (大小一般仅 几十M 、 没有nvcc、没有python)
  • runtime基于base, 增加了一些必要的运行时依赖.(大小一般 1个G 、 有nvcc、没有conda和python)
  • (部署)cudnn8基于runtime,额外包含了cuNDD库,用于深度学习的加速,提供了优化的卷积操作等功能.(大小一般 近2个G)
  • (开发)devel(带有nvcc 等编译器。 其他的镜像没有开发工具, 仅用于运行已经编译好的CUDA应用程序)

由于在wsl中我们选择了cuda11.8,那在docker环境中 我们选择接近版本的(选错,应该选18结果选了16…大写的无语,pytorch对16支持不好…):nvcr.io/nvidia/cuda:11.8.0-cudnn8-runtime-ubuntu20.04
如果需要加速用到cudnn,则选择第三个tag类型的镜像.
由于以上镜像拉取超时,解决办法. 拉取 nvcr.io/nvidia/cuda:11.8.0-cudnn8-runtime-ubuntu20.04
推荐直接选择cudnn8-devel版本,用于开发环境. 如果是部署可以选择runtime版本

测试

1
2
nvidia-docker  run -it --rm   -p 3333:8888  nvcr.io/nvidia/cuda:11.8.0-cudnn8-devel-ubuntu20.04  /bin/bash
# 查看路径:/usr/local/cuda-11.6/ 是否存在

搭建一个长久运行的nvidia docker容器 以及notebook开发环境(重要)

1
2
3
4
docker run --name ai_devel --runtime=nvidia --gpus all --restart=always -d  -p 8081:8888 -v /mnt/d/jupyter/quanoc:/home/quanoc nvcr.io/nvidia/cuda:11.8.0-cudnn8-devel-ubuntu20.04 tail -f /dev/null
# 后面加tail -f /dev/null 是为了不让容器自动正常退出.
nvidia-docker run --name ai-devops --restart=always -d -p 8888:8888 -v /mnt/d/jupyter/quanoc:/home/quanoc nvcr.io/nvidia/cuda:11.6.1-runtime-ubuntu20.04
# 说明:将容器路径映射到宿主机. 提供nvidia docker容器环境

后面加tail -f /dev/null 是为了不让容器自动正常退出.

5. 基于nvidia/cuda镜像搭建容器开发环境

关键词:python、jupyter-lab、pytorch、tensorflow
下载下来镜像后,接下来搭建开发环境. 安装相关组件.

5.1 安装Miniconda3

参考:Anaconda安装

1
2
3
4
5
6
apt update
apt install wget
# 安装Miniconda3
## 下载Miniconda3-py38_23.3.1-0-Linux-x86_64.sh ; 安装
bash Miniconda3-py38_23.5.1-0-Linux-x86_64.sh
# 重新进入容器(安装完成后默认配置了环境变量,需要重新打开终端)

5.2 python及其它框架安装

1
2
3
conda create -n ml3.8 python=3.8
conda activate ml3.8
# pip安装jupterlab

Jupyterlab开发环境搭建

pytorch安装,见以上资料. 2.3.1版本 使用conda安装需要下载近2个G why? pip好像800+M.
如果你只需要安装Python包,且不需要管理环境或依赖关系,那么pip也可以胜任。

pytorch验证问题,torch.cuda.is_available() 出现500的错误。 解决办法:重新安装 nvidia-container-toolkit即可,详见:
Installing the NVIDIA Container Toolkit