隨著傳統的順序算法到日益流行的并行算法,GPU 將成為加速復雜計算不可或缺的工具。在 AI 和機器學習任務等具有海量數據集和復雜的神經網絡的架構中,GPU 的并行處理能力具有很大的優勢。本文將深入探討學習。
原文鏈接:https://journal.hexmos.com/gpu-survival-toolkit/
作者 | Rijul Rajesh譯者| 彎月
責編 | 夏萌
出品 | CSDN(ID:CSDNnews)
為什么僅有 CPU 的知識還不夠
在如今的 AI 時代,大多數開發人員接受過 CPU 相關知識的培訓。這些知識已成為教學內容的一部分,因此一般我們都會以面向 CPU 的方式思考和解決問題。
然而,CPU 的問題在于它們依賴于順序架構。在當今世界,我們依賴于大量并行任務,而 CPU 并不適合這些情況。
開發人員面臨的問題包括:
執行并行任務
傳統的 CPU 是線性運行的,一次執行一條指令。有這種限制是因為 CPU 通常擁有若干針對單線程性能進行過優化的強大核心。
在面對多個任務時,CPU 會分配資源來依次處理每個任務,即順序執行指令。在需要同時關注大量任務的情況下,這種方法會變得效率低下。
雖然我們可以通過多線程等技術來提高 CPU 的性能,但其基本設計理念優先考慮的是順序執行。
高效運行 AI 模型
AI模型采用 Transformer 等先進架構,利用并行處理來提高性能。與順序運行的舊式循環神經網絡 (RNN)不同,GPT 等現代Transformer 可以同時處理多個單詞,從而提高訓練的效率和能力。因為當我們并行訓練時,就可以得到更大的模型,而更大的模型會生成更好的輸出。
并行性的概念超越了自然語言處理,擴展到了圖像識別等其他領域。例如,圖像識別架構 Ale.NET 可以同時處理圖像的不同部分,展現出了并行處理的強大功能,從而實現了準確的模式識別。
然而,以單線程性能為重心設計的 CPU 很難充分發揮并行處理的潛力。它們無法有效地分配和執行復雜的 AI 模型所需的大量并行計算。
因此,GPU 的開發變得越來越普遍,為的是滿足 AI 應用程序中并行處理的特定需求,從而實現更高的效率和更快的計算。
如何利用 GPU 驅動開發解決這些問題
GPU 核心的大規模并行性
與 CPU 的核心相比,工程師們設計的 GPU 具有更小、高度專業化的核心。這種架構允許 GPU 同時執行多個并行任務。
GPU中的大量核心非常適合依賴于并行性的工作負載,例如圖形渲染和復雜的數學計算。
在本文中,我們將演示如何利用 GPU 的并行性來縮短完成復雜的任務所需的時間。
AI 模型中使用的并行性
AI模型,特別是基于 TensorFlow 等深度學習框架構建的模型,展現出了高度的并行性。神經網絡的訓練涉及大量矩陣運算,而 GPU 憑借其龐大的核心數量,能夠并行化這些運算。TensorFlow 以及其他流行的深度學習框架都進行了優化,能夠利用 GPU 的能力來加速模型的訓練和推理。
在本文中,我們將展示如何利用 GPU 的強大功能來訓練神經網絡。
CPU與 GPU 有何不同?CPU
順序架構
中央處理單元(CPU)的設計重心是順序處理。它們擅長線性執行一組指令。
CPU針對需要高單線程性能的任務進行了優化,例如
- 通用計算
- 系統操作
- 處理涉及條件分支的復雜算法
處理并行任務的核心數量有限
CPU的核心數量較少,消費級的處理器通常有 2~16個核心。每個核心都能夠獨立處理自己的指令集。
GPU
并行架構
圖形處理單元(GPU)采用并行架構設計,能夠高效地執行并行處理任務。
適合于:
- 渲染圖形
- 執行復雜的數學計算
- 運行可并行的算法
GPU通過將多個任務分解為更小的并行子任務來同時處理多個任務。
數千個用于并行任務的核心
與 CPU 不同,GPU 擁有大量核心,通常高達數千個。這些核心組織成了流式多處理器(SM)或類似的結構。
豐富的核心使 GPU 能夠同時處理大量數據,非常適合并行任務,例如圖像和視頻處理、深度學習和科學模擬等。
AWS GPU 實例:初學者指南
Amazon Web Services(AWS)提供各種用于機器學習等任務的 GPU 實例。
以下是不同類型的 AWS GPU 實例及其用例:
通用 GPU 實例
- P3 和 P4 實例作為多功能通用 GPU 實例,非常適合各種工作負載。
- 其中包括機器學習訓練和推理、圖像處理和視頻編碼。它們的各方面能力都很平衡,因此成為了各種計算任務的可靠選擇。
- 價格:p3.2xlarge實例的費用為每小時 3.06 美元。
- 提供 1 個 16 GB GPU 內存的 NVIDIA Tesla V100 GPU。
推理優化 GPU 實例
- 推理指的是通過訓練好的 AI 模型運行實時數據以進行預測或解決任務的過程。
- P5 和 Inf1 實例專門針對機器學習推理,在十分注重低延遲和成本的場合中有著出色表現。
- 價格:p5.48xlarge實例的費用為每小時 98.32 美元。
- 提供 8 個 NVIDIA H100 GPU,每個 GPU 80 GB 內存,共計 640 GB 顯存。
圖形優化 GPU 實例
- G4 實例主要用于處理圖形密集型任務。
- 視頻游戲開發人員可以使用 G4 實例來渲染視頻游戲的 3D 圖形。
- 價格:g4dn.xlarge的費用為每小時 0.526 美元。
- 提供 1 個 16 GB 內存的 NVIDIA T4 GPU。
托管 GPU 實例
- Amazon SageMaker是一項機器學習托管服務。提供支持各種 GPU 實例的訪問,包括 P3、P4 和 P5 實例。
- 對于希望接觸機器學習,同時不想操心底層基礎設施管理的組織來說,SageMaker 是一個不錯的選擇。
- 價格:https://aws.amazon.com/sagemaker/pricing/?ref=journal.hexmos.com
使用 Nvidia 的 CUDA 進行GPU 驅動開發CUDA是什么?
CUDA是一款 NVIDIA 開發的并行計算平臺和編程模型,可幫助開發人員利用 GPU 加速器的強大功能來提高應用程序的速度。
下面,我們將使用 CUDA 來展示一個示例。
設置 CUDA
你可以按照以下步驟操作,在計算機上設置 CUDA。
- 下載CUDA(https://developer.nvidia.com/cuda-downloads?ref=journal.hexmos.com)
- 通過上面的鏈接,下載基本的安裝程序以及驅動程序安裝程序。
- 打開主文件夾中的.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/ target=_blank class=infotextkey>Python 中的圖像生成
下面,我們來探討如何使用 GPU 處理來優化性能密集型任務,例如圖像生成。
曼德博集合是一種數學結構,可根據指定方程中特定數字的行為形成復雜的視覺模式。生成這種集合是一項資源密集型操作。
通過下面的代碼片段,你可以了解到使用 CPU 處理生成曼德博集合的傳統方法,該方法的速度很慢。
上面的代碼生成結果需要耗費 4.07 秒。
為了提高速度,我們可以通過 Numba 庫利用 GPU 的并行化。具體方法如下。
首先,我們導入 Numba 庫的即時編譯、用于 GPU 加速的 CUDA 以及其他實用程序。
@jit指示 Numba 執行即時編譯,將 Python 代碼轉換為機器代碼,以提高執行速度。
- 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 將成為加速復雜計算不可或缺的工具。在 AI 和機器學習任務等具有海量數據集和復雜的神經網絡的架構中,GPU 的并行處理能力具有很大的優勢。
此外,GPU 已超出傳統的機器學習領域,在科學研究、模擬和數據密集型任務中也有找到了應用。事實證明,GPU 的并行處理能力有助于解決藥物發現、氣候建模以及金融模擬等各個領域的難題。