目錄
- 前言
- 0. 簡介
- 1. FLOPS
- 2. TOPS
- 3. HPC的排行,CPU/GPU比較
- 4. FLOPs
- 5. FLOPS是如何計算的
- 6. CUDA Core vs Tensor Core
- 總結
- 參考
前言
自動駕駛之心推出的 《CUDA與TensorRT部署實戰課程》,鏈接。記錄下個人學習筆記,僅供自己參考
本次課程我們來學習課程第四章—TensorRT 模型部署優化,一起來了解模型部署的基礎知識
課程大綱可以看下面的思維導圖
0. 簡介
本小節目標:理解 FLOPS 和 TOPS 是什么,CPU/GPU 中計算 FLOPS/TOPS 的公式,以及 CUDA Core 和 Tensor Core 的區別
這節課程開始我們進入第四章節—TensorRT 模型部署優化的學習,這章節是偏理論的部分,知識點比較碎片化。我們這節主要講模型部署的基礎知識,這部分內容其實不僅僅局限于 TensorRT 模型部署,大家在做其它硬件上的模型部署的時候很多概念都是通用的
第四章節主要分為以下幾個部分:
- 模型部署基礎知識
- 模型部署的幾大誤區
- 模型量化
- 模型剪枝
- 層融合
模型部署基礎知識這小節主要教大家一些常見的東西比如 FLOPS、TOPS 等等,同時跟大家介紹一下 CUDA Core 和 Tensor Core 它們核心的區別是什么以及各個模型的 TOPS 是怎么計算的
模型部署的幾大誤區這小節簡單過一下,主要是大家在做模型部署時可能存在的一些誤解
模型量化這小節會跟大家講得比較細,不僅僅是大家常聽到的 PTQ 量化和 QAT 量化,會從基礎的地方去講模型量化是怎么做的以及模型量化的量化密度、校準算法選取、校準數據集 batch size 大小的影響、量化層融合等等
模型剪枝這小節會教大家 sparse pruning 是什么東西以及對 kernel 的剪枝和對 channnel 的剪枝它們的區別是什么,還有現在硬件上對模型剪枝的性能支持是怎么樣的
層融合這小節主要是做一個總結性的小節,層融合這個概念其實在前面的很多部分都會涉及到,比如 TensorRT 優化有涉及層融合,模型量化也有涉及層融合
今天我們來講第四章節第一小節—模型部署的基礎知識,這節課學完之后希望大家理解 FLOPS 和 TOPS 是什么,CPU/GPU 中的計算 FLOPS/TOPS 的公式以及 CUDA Core 和 Tensor Core 的區別
1. FLOPS
FLOPS(FLoating point number Operations Per Second)
- 指的是一秒鐘可以計算處理的浮動小數點運算的次數
- 衡量計算機硬件性能、計算能力的一個單位
- FLOPS 也可以寫作 FLOP/s,是一個意思,但千萬不能寫成 FLOPs
常見的 FLOPS 如下表所示:
2. TOPS
TOPS(Tera Operations Per Second)
- 指的是一秒鐘可以處理的整型運算的次數
- 衡量計算機硬件性能、計算能力的一個單位
3. HPC的排行,CPU/GPU比較
HPC(High Performance Compute)排名如下所示:
CPU 與 GPU 在 FLOPS 上的性能比如下圖所示:
我們可以看到 CPU 與 GPU 在 FLOPS 上的性能比還是比較大的,CPU 主要是處理復雜邏輯的,GPU 主要是做并行處理所以它的計算密度比較大,在 FLOPS 上的性能也比較強
4. FLOPs
FLOPs(Floating point number operations)
- 是衡量模型大小的一個指標
- 大家在 CVPR 的 paper 或者 Github 里經常能夠看到的就是這個信息
值得注意的是 FLOPs 不能夠用來衡量模型的推理性能,具體我們還是要看 FLOPS,看模型在硬件設備上的 FLOPS,FLOPs 只是衡量模型大小的一個指標具體還是要看硬件的
5. FLOPS是如何計算的
跟 FLOPS 有關的概念:
- Core 數量
- 時鐘頻率
- 每個時鐘周期可以處理的 FLOPS
FLOPS?=?頻率?*?core數量?*?每個時鐘周期可以處理的FLOPS \text{FLOPS = 頻率 * core數量 * 每個時鐘周期可以處理的FLOPS} FLOPS?=?頻率?*?core數量?*?每個時鐘周期可以處理的FLOPS
比如說 Intel i7 Haswell 架構(8 核,頻率 3.0GHz)它的 FLOPS 在雙精度的時候就是:
3.0*10^9Hz?*?8?core?*?16?FLOPS/clk?=?0.38?TFLOPS \text{3.0*10\textasciicircum 9Hz * 8 core * 16 FLOPS/clk = 0.38 TFLOPS} 3.0*10^9Hz?*?8?core?*?16?FLOPS/clk?=?0.38?TFLOPS
那么它的 FLOPS 在單精度的時候就是:
3.0?*?10^9Hz?*?8?core?*?32?FLOPS/clk?=?0.76?TFLOPS \text{3.0 * 10\textasciicircum9Hz * 8 core * 32 FLOPS/clk = 0.76 TFLOPS} 3.0?*?10^9Hz?*?8?core?*?32?FLOPS/clk?=?0.76?TFLOPS
我們思考下 16 FLOPS/clk 和 32 FLOPS/clk 是如何計算的呢?也就是每個時鐘周期可以處理的 FLOPS 是怎么來的呢?
這個其實和硬件的架構相關:
上圖是 Interl Haswell 的架構圖,可以看到它有兩個 FMA 以及支持 AVX-256 指令集
FMA(Fused Multiply Accumulation)是計算的一個硬件單元,下圖展示了 FMA 的功能:
我們可以看到沒有 FMA 乘法加法分開算,計算 D=A*B+C 需要兩個時鐘周期;有 FMA 乘法加法一起算,計算 D=A*B+C 需要一個時鐘周期
AVX-256 指令集其實跟我們之前講的 SIMD 操作相關即一個指令去處理多個數據,AVX-256 中一個寄存器可以存儲 8 個 32-bit 的 float 或者 4 個 64-bit 的 double(如下圖所示)那這也就意味著 AVX-256 在做 SIMD 操作時一個時鐘周期就可以處理 8 個 FP32 或者 4 個 FP64 的計算
所以我們回到之前的問題,16 FLOPS/clk 的計算如下:
2?FMA?*?4個FP64的SIMD運算?*?2?乘加融合?=?16?FLOPS/clk \text{2 FMA * 4個FP64的SIMD運算 * 2 乘加融合 = 16 FLOPS/clk} 2?FMA?*?4個FP64的SIMD運算?*?2?乘加融合?=?16?FLOPS/clk
32 FLOPS/clk 的計算如下:
2?FMA?*?8個FP32的SIMD運算?*?2?乘加融合?=?32?FLOPS/clk \text{2 FMA * 8個FP32的SIMD運算 * 2 乘加融合 = 32 FLOPS/clk} 2?FMA?*?8個FP32的SIMD運算?*?2?乘加融合?=?32?FLOPS/clk
FPLOS 在 GPU 中是如何計算的呢?跟 CPU 不同的是 GPU 它的特性如下:
- 沒有 AVX 這種東西
- 但是有大量的 core 來提高吞吐量
- 有 Tensor Core 來優化矩陣運算
- 有 Tensor Core 來優化矩陣運算
下圖展示了 Ampere 架構中一個 SM:
從上圖中我們可以看到一個 SM 里面有:
- 64 個處理 INT32 的 CUDA Core
- 64 個處理 FP32 的 CUDA Core
- 32 個處理 FP64 的 CUDA Core
- 4 個處理矩陣計算的 Tensor Core
每一種精度在一個 SM 中的吞吐量(一個時鐘周期可以處理的浮點運算的個數)如下表所示:
我們再來看 Ampere 架構的各個精度的吞吐量,如下圖所示:
我們思考下這些值是如何被計算出來的呢?我們以 Peak FP64 為例來講解,我們前面說過一個 SM 里面有 32 個處理 FP64 的 CUDA Core,每一個時鐘周期計算一個 FP64,而 Ampere 架構中的各項指標如下:
- 頻率:1.41 GHz
- SM 數量:108
- 一個 SM 中計算 FP64 的 CUDA core 的數量:32
- 一個 CUDA core 一個時鐘周期可以處理的 FP64:1
- 乘加:2
Throughout?=?1.41?GHz?*?108?*?32?*?1?*?2?=?9.7?TFLOPS \text{Throughout = 1.41 GHz * 108 * 32 * 1 * 2 = 9.7 TFLOPS} Throughout?=?1.41?GHz?*?108?*?32?*?1?*?2?=?9.7?TFLOPS
Peak FP32 也可以進行類似的計算,其吞吐量為:
Throughout?=?1.41?GHz?*?108?*?64?*?1?*?2?=?19.4?TFLOPS \text{Throughout = 1.41 GHz * 108 * 64 * 1 * 2 = 19.4 TFLOPS} Throughout?=?1.41?GHz?*?108?*?64?*?1?*?2?=?19.4?TFLOPS
值得注意的是 Ampere 中沒有專門針對 FP16 的 CUDA core,而是將 FP32 的 CUDA Core 和 FP64 的 CUDA Core 一起使用來計算 FP16。因此我們暫且說一個 SM 中計算 FP16 的 CUDA Core 的數量是:64x2+32x4=256
因此 Peak FP16 的吞吐量為:
Throughout?=?1.41?GHz?*?108?*?256?*?1?*?2?=?78?TFLOPS \text{Throughout = 1.41 GHz * 108 * 256 * 1 * 2 = 78 TFLOPS} Throughout?=?1.41?GHz?*?108?*?256?*?1?*?2?=?78?TFLOPS
同理 Ampere 中也沒有專門針對 INT8 的 CUDA Core,而是使用 INT32 的 CUDA Core 計算 INT8。因此我們暫且說一個 SM 中計算 INT8 的 CUDA Core 的數量是:64x4=256
因此 Peak INT8 的吞吐量為:
Throughout?=?1.41?GHz?*?108?*?256?*?1?*?2?=?78?TFLOPS \text{Throughout = 1.41 GHz * 108 * 256 * 1 * 2 = 78 TFLOPS} Throughout?=?1.41?GHz?*?108?*?256?*?1?*?2?=?78?TFLOPS
看完 CUDA Core 之后我們來分析 Tensor Core,Ampere 架構使用的是第三代 Tensor Core,它一個時鐘周期可以完成 256x4=1024 個 FP16 運算,準確來說是 4x8 的矩陣與 8x8 的矩陣的 FMA,而 Ampere 的各項指標如下:
- 頻率:1.41 GHz
- SM 數量:108
- 一個 SM 中計算 FP16 的 Tensor core 的數量:4
- 一個 Tensor core 一個時鐘周期可以處理的 FP16:256
- 乘加:2
因此 Peak FP16 Tensor Core 的吞吐量為:
Throughout?=?1.41?GHz?*?108?*?4?*?256?*?2?=?312?TFLOPS \text{Throughout = 1.41 GHz * 108 * 4 * 256 * 2 = 312 TFLOPS} Throughout?=?1.41?GHz?*?108?*?4?*?256?*?2?=?312?TFLOPS
6. CUDA Core vs Tensor Core
下面我們來看 CUDA Core 和 Tensor Core 的一個比較,我們如果使用一個 CUDA Core 計算矩陣乘法 A * B = C,則計算過程如下圖所示:
可以看到如果使用 CUDA Core 來做矩陣乘法的話,輸出中的一個元素就需要 8 次 FMA,也就是需要 8 個時鐘周期才可以完成一個 c(0,0) 的計算。要完成矩陣 4x8 與 8x4 的計算則需要 8x16=128 個時鐘周期才可以完成
當然如果我們有 16 個 CUDA Core 的話,這些計算其實是并行的,實際上只需要 8 個時鐘周期,不過為了與 Tensor Core 比較這里只用了一個 CUDA Core
我們再來看使用 1st Gen. Tensor Core(Volta 架構) 來計算矩陣乘法 A * B = C,其計算過程如下圖所示:
值得注意的是 Tensor Core 不是一個一個的對 FP16 進行處理,而是 4x4 個 FP16 一起處理,第一個時鐘周期先做 A 和 B 的前半段結果先存著,第二個時鐘周期再處理 A 和 B 的后半段,最后和前半段結果做個累加完成計算。所以說 Tensor Core 處理 4x8*8x4 的計算只需要 1+1=2 個時鐘周期
另外想說的是現在的 Ampere 架構中的 Tensor Core 已經是 3rd Gen. 了,它在一個時鐘周期就可以處理 4x8*8x8 的計算,也就是說一個時鐘周期可以處理 256 個 FP16
關于 CUDA Core 和 Tensor Core 的區別還可以看下圖更直觀的感受:
總結
本次課程我們主要學習了模型部署的一些基礎知識,包括 FLOPS、TOPS、FLOPs 代表的含義以及 FLOPS 是如何計算的,最后我們簡單聊了下 CUDA Core 和 Tensor Core 的一個區別。
OK,以上就是第 1 小節有關模型部署的基礎知識的全部內容了,下節我們來學習 Roofline model,敬請期待😄
參考
- AI Chips: A100 GPU with Nvidia Ampere architecture
- High performance computer TOP 6 in JUNE 2024
- A Massively Parallel Processor: the GPU
- Github: Swin Transformer
- EfficientNetV2: Smaller Models and Faster Training
- Intel Processor Architecture
- What is SSE and AVX?
- 深度了解 NVIDIA Ampere 架構
- AI Chips: A100 GPU with Nvidia Ampere architecture
- Programming Tensor Cores in CUDA 9
- YouTube: About NVIDIA Tensor Core