AI 时代的 GPU 生存工具包:每个开发人员必须知道的最低限度[阿里云]

AI技术迎来了“百花齐放”的春天,这既是我们的挑战也是机会。而AI+千行百业创造了无限可能,也为独立开发者提供了大量的资源、支持以及学习经验的机会。接下来分享一篇摘录自Hexmos 期刊的AI 时代的 GPU 生存工具包。

一、为什么 CPU 知识已经不够了?

在当今的 AI 时代,大多数开发人员都以 CPU 方式进行训练。这些知识也一直是我们学术的一部分,因此以面向 CPU 的方式思考和解决问题是显而易见的。然而,CPU 的问题在于它们依赖于顺序架构。在当今世界,我们依赖于许多并行任务,CPU 在这些场景中无法正常工作。开发人员面临的一些问题包括:

  • 执行并行任务
  • 传统上,CPU 是线性运行的,一次执行一条指令。这种限制源于这样一个事实,即 CPU 通常具有一些针对单线程性能进行优化的强大内核。当面对多个任务时,CPU 会分配其资源来一个接一个地处理每个任务,从而导致指令的顺序执行。在需要同时关注大量任务的情况下,这种方法变得效率低下。虽然我们努力通过多线程等技术提高 CPU 性能,但 CPU 的基本设计理念优先考虑顺序执行。

  • 高效运行 AI 模型
  • AI 模型采用 Transformer 等高级架构,利用并行处理来提高性能。与按顺序运行的旧递归神经网络 (RNN) 不同,GPT 等现代转换器可以同时处理多个单词,从而提高训练的效率和能力。因为当我们并行训练时,它会产生更大的模型,而更大的模型将产生更好的输出。并行性的概念超越了自然语言处理,扩展到图像识别等其他领域。例如,图像识别中的一种架构 AlexNet 通过同时处理图像的不同部分来展示并行处理的强大功能,从而实现准确的模式识别。然而,CPU在设计时注重单线程性能,难以充分利用并行处理的潜力。他们面临着有效分发和执行复杂 AI 模型所需的大量并行计算的困难。因此,GPU 的发展已经变得普遍,以满足 AI 应用中并行处理的特定需求,从而释放更高的效率和更快的计算速度。

    二、GPU 驱动开发如何解决这些问题

  • 与 GPU 内核的大规模并行性
  • 与 CPU 中更大、更强大的内核相比,工程师设计的 GPU 具有更小、高度专业化的内核。这种架构允许 GPU 同时执行大量并行任务。GPU 中的大量内核非常适合取决于并行度的工作负载,例如图形渲染和复杂的数学计算。我们很快将演示如何使用 GPU 并行性来减少复杂任务所需的时间。

  • AI 模型中使用的并行性
  • AI 模型,尤其是那些基于 TensorFlow 等深度学习框架构建的模型,表现出高度的并行性。神经网络训练涉及大量矩阵运算,而 GPU 凭借其庞大的核心数量,在并行化这些运算方面表现出色。TensorFlow 以及其他流行的深度学习框架进行了优化,以利用 GPU 的强大功能来加速模型训练和推理。我们将很快展示如何使用 GPU 的强大功能训练神经网络的演示。​

    三、CPU 与 GPU:有什么区别?

  • 中央处理器
    • 顺序架构

    中央处理器 (CPU) 的设计侧重于顺序处理。他们擅长线性执行一组指令。CPU 针对需要高单线程性能的任务进行了优化,例如:

      • 通用计算
      • 系统操作
      • 处理涉及条件分支的复杂算法
      • 用于并行任务的有限内核

    CPU 的内核数量较少,在消费级处理器中通常在 2-16 个内核的范围内。每个内核都能够独立处理自己的指令集。

  • 图形处理器
    • 并行架构

    图形处理单元 (GPU) 采用并行架构设计,使其在并行处理任务中非常高效。适用于:

      • 渲染图形
      • 执行复杂的数学计算
      • 运行可并行化的算法

    GPU 通过将多个任务分解为更小的并行子任务来同时处理多个任务。

    • 数以千计的内核用于并行任务

    与 CPU 不同,GPU 拥有更多的核心,通常有数千个。这些内核被组织成流式多处理器 (SM) 或类似结构。丰富的内核使 GPU 能够同时处理大量数据,非常适合并行任务,例如图像和视频处理、深度学习和科学模拟。

    四、使用 Nvidia 的 CUDA 进行 GPU 驱动的开发,

  • 什么是 Cuda?
  • CUDA 是 NVIDIA 开发的并行计算平台和编程模型,使开发人员能够利用 GPU 加速器的强大功能来加速他们的应用程序。演示中的实际示例将使用 CUDA。

  • 如何在您的机器上设置 Cuda
  • 要在您的机器上设置 CUDA,您可以按照以下步骤操作。

    • 下载 CUDA
    • 从上面的链接下载基本安装程序和驱动程序安装程序
    • 转到主文件夹中的 .bashrc
    • 在下面添加以下行
    • export PATH=”/usr/local/cuda-12.3/bin:$PATH”
    • export LD_LIBRARY_PATH=”/usr/local/cuda-12.3/lib64:$LD_LIBRARY_PATH”
    • 执行以下命令
    • sudo apt-get install cuda-toolkit
    • sudo apt-get install nvidia-gds
    • 重新启动系统以使更改生效
  • 要使用的基本命令
  • 安装 CUDA 后,这里有一些有用的命令。

    • LSPCI | grep VGA

    此命令可识别并列出系统中的 GPU。

    • nvidia-smi

    此命令为 NVIDIA System Management Interface(NVIDIA 系统管理界面)的缩写,可提供系统中有关 NVIDIA GPU 的详细信息,包括利用率、温度、内存使用情况等。

    • sudo lshw -C display

    此命令可提供系统中有关显示控制器(包括显卡)的详细信息。

    • inxi -G

    此命令可提供有关图形子系统的信息,包括有关 GPU 和显示器的详细信息。

    • sudo hwinfo –gfxcard

    此命令可提供系统中有关显卡的详细信息。

  • 使用 CUDA 框架
  • 下面,我们来展示 CUDA 的一些具体功能。

    • 数组加法问题

    数组加法问题很适合演示 GPU 并行化。考虑以下数组:

      • 数组 A =  [1,2,3,4,5,6]
      • 数组 B =  [7,8,9,10,11,12]
      • 我们需要计算每个元素之和,并存储在数组C中。
      • 即 C = [1+7,2+8,3+9,4+10,5+11,6+12] = [8,10,12,14,16,18]

    如果由 CPU 来执行整个操作,则代码如下:前一个循环遍历数组的每个元素,并依次执行加法。当需要处理大量数字时,这种方法就会由于其顺序执行的性质而变得缓慢。为了克服这个限制,GPU 提供了一种解决方案:并行化加法运算。不同于依次执行运算的 CPU,GPU 可以同时执行多项加法。例如,运算 1+7、2+8、3+9、4+10、5+11 和 6+12 可以借助 GPU 并行化同时执行。利用 CUDA,实现并行加法的代码如下:我们将使用内核文件(.cu)进行演示。我们来逐行讲解代码。

      • __global__ 表明该函数是一个内核函数,将在 GPU 上调用。
      • vectorAdd 接受三个整数指针(a、b 和 c)作为参数,代表相加的向量。
      • threadIdx.x 获取当前线程的索引(在一维网格中)。
      • 向量 a 和 b 的相应元素之和存储在向量 c 中。

    下面,我们来看看 main 函数。创建指针 cudaA、cudaB 和 cudaC,指向 GPU 上的内存。我们使用 cudaMalloc,为向量 cudaA、cudaB 和 cudaC 分配 GPU上的内存。使用 cudaMemcpy 将向量 a 和b 的内容从主机复制到 GPU。使用一个块和多个(数量等于向量大小)线程调用内核函数 vectorAdd。 将结果向量 cudaC 从 GPU 复制回主机。然后就可以正常输出结果了:我们使用 nvcc 命令执行这段代码。输出如下:完整的代码,请参见这里:https://github.com/RijulTP/GPUToolkit/tree/main/array-addition?ref=journal.hexmos.com

    五、使用 GPU 优化 Python 中的图像生成

    下面,我们来探讨如何使用 GPU 处理来优化性能密集型任务,例如图像生成。

    • 曼德博集合是一种数学结构,可根据指定方程中特定数字的行为形成复杂的视觉模式。生成这种集合是一项资源密集型操作。

    通过下面的代码片段,你可以了解到使用 CPU 处理生成曼德博集合的传统方法,该方法的速度很慢。上面的代码生成结果需要耗费 4.07 秒。为了提高速度,我们可以通过 Numba 库利用 GPU 的并行化。具体方法如下。首先,我们导入 Numba 库的即时编译、用于 GPU 加速的 CUDA 以及其他实用程序。mandel_gpu 是使用cuda.jit 创建的 mandel 函数的 GPU 兼容版本。它可以将 mandel 的逻辑卸载到 GPU。为此,我们需要使用@cuda.jit,并指定函数参数的数据类型(f8 表示浮点数,uint32 表示无符号整数)。device=True 参数表示该函数将在GPU 上运行。根据定义,mandel_kernel 将在 CUDA GPU 上执行。负责跨 GPU 线程并行生成曼德博集合。接下来,我们可以在 create_fractal_gpu 函数中使用 GPU 加速的曼德博集合生成。create_fractal_gpu 函数需要分配 GPU 内存,启动 GPU 内核 (mandel_kernel),并将结果复制回 CPU。上述代码只需 0.0046 秒内就能执行完成。比之前的 CPU 的代码要快许多。完整的代码,请参见这里https://github.com/RijulTP/GPUToolkit/tree/main/mandelbrot?ref=journal.hexmos.com

    六、使用 GPU 训练区分猫狗的神经网络

    GPU在 AI 领域的应用是如今的热门话题之一,出于演示的目的,下面我们来创建一个用于区分猫和狗神经网络。准备工作:

    • CUDA
    • 安装Tensorflow:pip install tensorflow[and-cuda]
    • 我们将使用kaggle 的猫狗数据集。
    • 下载完成后,解压,将训练文件夹中的猫狗图片整理到不同的子文件夹,如下所示:

    导入库:

    • pandas 和 numpy:用于操作数据。
    • Sequential:用于创建神经网络中叠放的线性层。
    • Convolution2D、MaxPooling2D、Dense 和 Flatten:构建卷积神经网络(CNN)的各层。
    • ImageDataGenerator:用于在训练期间进行实时数据增强。

    初始化卷积神经网络(CNN)加载训练数据构建 CNN 架构编译模型训练模型训练完成后,使用 classifier.save 将模型存储在 .h5 文件中。在下面的代码中,我们将使用 trained_model.h5 来识别猫和狗。输出如下:完整的代码,请参见这里:https://github.com/RijulTP/GPUToolkit/tree/main/neural-network?ref=journal.hexmos.com​

    七、总结:

    在即将到来的AI时代,GPU不容忽视,我们应该更加了解它的功能。随着我们从传统的顺序算法过渡到日益流行的并行化算法,GPU 成为不可或缺的工具,能够加速复杂计算。GPU 的并行处理能力在处理人工智能和机器学习任务固有的海量数据集和复杂的神经网络架构方面特别有利。此外,GPU 的作用超越了传统的机器学习领域,在科学研究、模拟和数据密集型任务中得到了应用。事实证明,GPU 的并行处理能力有助于解决从药物发现和气候建模到金融模拟等不同领域的挑战。​好啦!小弹的分享到此为止。我们更欢迎您分享您对阿里云产品的设想、对功能的建议或者各种吐槽,请扫描提交问卷并获得社区积分或精美礼品一份。https://survey.aliyun.com/apps/zhiliao/P4y44bm_8【扫码填写上方调研问卷】欢迎每位来到弹性计算的开发者们来反馈问题哦~