雲計算

NV Ampere GPU架構學習與思考

前言

這幾天,GTC2020上,Nvidia發佈了最新的Ampere架構。Ampere架構的改進重心,大部分放在AI上的改動,包括第三代的Tensor Core,以及相關的調度性能,以及互聯等。它展示了在加強算力,特別是TC (TC == Tensor Core,下同)算力的情況下,整個系統的改進。

整體上,可以看到NV的GPU向向AI方向快速發展,看起來跟隨市場的必然選擇。轉去吃AI芯片的蛋糕。原CUDA Core並行度增加放緩,A100所有大的改動,看起來都是以AI計算為主要目的,所以Tensor Core以及SM裡AI加速的模塊和功能大大加強。在數據中心AI芯片這塊,彎道超車時間快結束了。基本上大家都回到了vector+tensor混合架構上的直線競爭。

這樣,GPGPU逐漸成為了通用和專用混合的架構形態

•Core 架構:CUDA vector core + Tensor core

•Memory system:傳統的cache system + AI memory system

•Scale and connection:scale up + scale out in one GPU

•Program Model:original CUDA + WMMA

異構的難題在於利用率上:NV的一些提高效率的改變,包括

•資源動態分配,L1C, L2C, MIG

•軟硬件結合

這樣,軟件棧任務更重了。

 

因為我一直在GPU/AI軟件架構方面工作,我會比較多的從軟硬件結合,編程模型,軟件上層應用的角度出發來考慮問題。希望給大家不同的視野。

 

下面從幾個方面來學習和思考:

  • 核心算力
    • A100如何大幅度提升算力?
  • 數據帶寬
    • 如何解決算力高漲下的帶寬問題?
  • 計算效率
    • 如何提高計算效率?

 

核心算力

A100的算力提升主要集中在AI應用需要的FP16精度以下的類型。

  • 傳統FP32和FP64只有1.25x的增長。
  • FP16有了2.5x的增長 (both CUDA core and Tensor core)
  • 通過TF32的引入,讓FP32(應用層)的數據處理大幅提升
  • 再通過Sparsity的優化,對TC的幾個數據類型又double了算力

Tensor core精度

  • TF32 TC
    • FP16/FP32的混合精度訓練問題比較多,使用很麻煩,給軟件棧和框架都帶來不小的難題。(大家可以看一下混合精度訓練的實現和問題一些材料)
    • FP32 in/out的計算複雜,算力小
    • TF32 TC能很好的解決FP16/FP32的混合精度的問題,又能以較小的代價,獲得比較好的精度。

Fine-grained structured sparsity

非常棒的一個“快速”解決方案。之前我們關於AI芯片加速sparsity的優化想法,都是侷限在"被動"sparsity的方面,也就是上層應用和框架主動做剪枝以後,針對稀疏矩陣做被動的優化。難度很大。原因是各種剪枝出來的數據沒有共同特性,因此硬件上很難實現通用的加速。

A100的方法,是主動(由軟件)提供固定結構化的剪枝,對訓練好後的Dense權重剪枝後,再稍做Fine-tuning,這樣得到的稀疏矩陣可以直接使用針對這一特定結構的壓縮,硬件加速推理。獲得近乎兩倍的性能提升。精度方面,50%的剪枝,應該能保證足夠的精度。他們應該是論證過的。

截屏2020-05-17 下午5.56.00.png

整個方法是比較典型的軟硬件結合的思路:

  • 軟件提供包裝好的4選2的剪枝方案,(軟件實現,可升級算法,結合硬件)
  • 簡單的Fine-tuning訓練
  • 壓縮剪枝後的weight,得到非零數據和Index,用於推理
  • 提升
    • 減少一半MMA計算
    • weight數據,從host->device就開始節省帶寬
    • activation
      • 根據不同的實現,可以節省L1開始,或者L2開始的帶寬

數據帶寬

A100算力的暴漲,應該是讓原來的存儲系統,特別是SM內的存儲設計跟不上了。

特別的是TF32 TC的引入,帶寬需求和FP32一樣,但是算力上大了好多。以Tensor Core FP16作為對比,同樣使用Tensor Core,同樣的操作(Ops/byte ratio),要保證相同的計算吞吐,需要的存儲帶寬大大地增長了。

  • V100,FP16,FLOPS=125T,input data type FP16
  • A100,TF32 TC,FLOPS=312T,input data type FP32,

因此,同樣利用率的情況下,大概就需要5倍(312/125*2)的帶寬了,在打開Sparsity的功能後,還需要更多的帶寬,因為Sparse Matrix只壓縮weight matrix。

作為對比基礎,先給出Volta的存儲體系:

截屏2020-05-17 上午10.30.15.png

數字上的增長

  • HBM2
    • 16GB to 40GB, achive 1.6TB/sec, 73% increase.
  • L2 cache
    • 6M L2 to 40MB, about 7x size, 2.3x read bandwidth with a new partitioned crossbar structure(沒有細節,還不理解,後續繼續學習)
  • L1 data cache and Shared memory
    • 128 KB to 196 KB1.5x larger

從數字上看,整個系統的吞吐/容量的純增長,基本是在2倍左右,偏下。這些改進,相對CUDA core算力1.25x-2.5x的改進,其實是差不多足夠了。但是,對於Tensor Core 5倍以上的需求增長,遠遠不夠,所以需要其他架構的改進和新的特性來進一步支持算力。另外,為什麼L2 cache急劇地增加到了40MB?

 

架構和特性的改進

思考

在理解這些改動之前,一定要充分地思考一下,AI特別是DNN的數據流特點,以及計算的特點。然後可以發現,主要的這些改進,都是充分考慮Tensor core的數據和計算特點,給Tensor Core做一些快速,簡潔,或者並行性更高的通道。而且,有些改進能在其他芯片中看到類似的理念,但A100的選擇和實現總是更通用,更“軟”,更巧妙

 

我理解的數據特點:

  • activation只讀,不會更改。流量大。
  • 權重複用度高,推理時const只讀,訓練時需要讀和寫。
  • AI數據裡冗餘數據多,本質上是稀疏的,特別是Relu之後activation,壓縮權重,Embedding輸入數據,broadcast數據等。

 

我理解的AI計算特點(暫時還沒有統計數據來支持):

  • 一個網絡模型由很多的小Kernel組成。
  • 單個Kernel寬而不深,也就是thread多,但kernel不長,指令數不多。
  • Tensor Core (MMA)和Compute core的並行優化可能比較難做(庫與編譯器)

 

看看A100的存儲系統改進,我關注了以下這些:

  • 新的異步Copy指令,從global memory直接load到shared memory。
  • 超大L2C,partitioned,use it smarter。

 

  • 新的指令做L2 cache residency control。
  • Compute Data Compression: 4x DRAM and L2 bandwidth, 2x L2 capacity. (不同於Structured Sparsity)
  • Combined L1 data cache and shared memory (其實是Volta架構開始就有的)

 

A100-Memory.png

Asynchronous copy

我理解為這是專為DNN Kernel裡的Input/Activation數據類似的數據流優化。

  • 因為這類數據,讀自Global Memory,大都一次使用,不需要到RF,用完不需寫回。因此沒必要走複雜的L1/RF。而把RF/L1的帶寬留給weigh和temp變量。
  • 另外,這是異步操作,和SM裡其他操作可併發,從而可以隱藏較長的copy cycles。使用新的shared-memory-based barrier來做同步。
  • 同時,需要新的編程模型(CUDA)支持和編譯器支持。

截屏2020-05-20 下午5.32.37.png

L2 cache residency control

首先,L2的設計很複雜,整理一下思路,根據新的特性出發來思考:

  • 大幅度增長的L2 size (40MB),
    • 首先,主要是為了大量的權重數據重用。
    • 其次,MIG architecture的引入,需要將L2分成最多7份,也需要更大的size
  • 大的L2,開始分區使用,類似於我們的LLC+L2的設計。
    • 分區以後,每個GPC直連L2了,帶寬增加(細節不懂。。。)
    • 每個區應該也繼續像以前一樣分類,這樣就是看,L2像是被做了兩維的拆分,不知道這個是不是就是NV提到的new partitioned crossbar structure。
    • 但整個L2Cache仍然保持“Shared”屬性,HW cache-coherence,以及CUDA編程模型。

 

AI應用中,L2C應該主要優化了權重的複用,根據模型的大小,可以有不同級別的重用粒度,這個思路和之前在V1.5裡提到的根據權重大小不同而產生的不同工作模式

  • 權重全部在L2C,就像V1一樣,整個模型權重只用裝載一次到L2C。
  • 權重需要分段輪流裝載L2C,
    • 裝載一部分權重後,把相關的計算一個一個batch做完。然後換下一段權重,繼續做。
    • 這個時候,多batch的工作模式比較有優勢。能公用更多的權重。
    • 使用double buffer (ping-pong buffer)的模式,可以讓計算和權重裝載並行。

 

說到這裡,大概就知道為什麼需要L2 cache residency control。就是用來分段裝載,實現ping-pong buffer的。

同樣,也需要指令和CUDA編程模型的支持。

截屏2020-05-20 下午6.21.03.png

Compute Data Compression

注意這不是Structured Sparsity,而是針對unstructured sparsity and other compressible data patterns.

我知道我們也在看相關的技術。只是現在還不知道A100是怎麼做的,但至少證明了這條路是可行的。需要大家一起持續關注。

截屏2020-05-20 下午6.20.16.png

 

Combined L1 cache and shared memory

從Volta架構開始,這個改變就發生了。理由看起來也比較充分:越來越多的計算場景,對Shared Memory和Cache的需求有很大不同。很難有一個固定比例能滿足大部分的場景。所以可以配置的Shared Memory和L1C應該能比較方便而顯著地提高性能。不需要為了固定的Shared Memory/L1C而絞盡腦汁地調整程序和調試性能。

之前的討論中鄒老師提到,做過一些實驗發現差別不大。我有一些猜測,可能是實驗面不夠廣,我們可以做進一步的實驗:

  • 這個改變是在Volta架構裡,隨著Tensor core一起引入。TC計算裡這種差別可能特別明顯,比如
    • 做Matmul/Conv等使用TC的Kernel,通常是Shared Memory要的比較多(絕大部分),而cache用的很少
    • 如果是LSTM的複雜Kernel,則會對Cache要求比較多。
  • 越來越多的通用/AI計算場景,

整體而言,這個靈活性是有價值的。非常有利用調整和控制Kernel訪存的性能和最終性能。

cache系統總結

首先是提供能力:BW/Capacity/利用率

  • 直接提高帶寬
  • Capacity

不止單純的大小,還包括動態分配等方式

  • DRAM BW

1.7x BW不足,通過6.7x L2 + Residency Control彌補

其次是減少需求:

  • Sparsity
  • Compression

 

截屏2020-05-20 下午8.53.44.png

計算效率

Task Graph Acceleration

這應該是對整體性能(整個模型甚至多個模型)非常意義的一個特性。針對的是“一個網絡模型由很多的小Kernel組成”這個特徵。

這個思路---把多個Tasks,memory copies(uploading/downloading)做成一個圖(Graph,Directed Acyclic Graph),加上Dependency關係,以前都是在軟件端實現的。比如:

  • GPU應用領域,多個draw batches,相互間或有複雜的dependency,為做到高效地並行,避免不必要的bubble,最好能做到out-of-order的執行。我知道的軟件棧,做過相關的優化處理:UMD建立有dependency關係的DAG,KMD根據DAG,dependency信息,以及硬件的執行狀態,動態的調度draw batches。
  • AI領域,DNN本身就是一個DAG。
    • 在NPU V1架構上,這個問題不明顯但也存在。不明顯的原因是大部分連續的可支持的算子被合併成了一個執行Engine。但遇到大的Engine需要拆分的時候,還是需要會有這個問題的,所以我們還是在軟件棧實現了基於DAG的推理引擎。
    • 在GPGPU架構,加上訓練功能,將會有很多很多小的Kernel了。因此特別需要這個優化。

因此存在CPU和GPU之間的來回調度。A100的創新是把這個移到了硬件上。去除了這個CPU-GPU調度代價。

 

CUDA Graph

CUDA 10開始支持的一個特性,是Task Graph Acceleration的基礎。首先把多個Kernel一起提交(submit)到GPU。減少kernel提交和同步的時間。不過submit之後的kernel只能按照順序執行。並行度比較差。

截屏2020-05-20 下午9.03.27.png

Task Graph Acceleration

Ampere架構支持以圖的方式提交,並帶有相互的依賴關係。因此GPU硬件可能更高效的調度kernel並行。

Leave a Reply

Your email address will not be published. Required fields are marked *