全部產品
Search
文件中心

Elastic GPU Service:通過Docker命令列使用cGPU服務

更新時間:Sep 20, 2024

使用cGPU服務可以隔離GPU資源,實現多個容器共用一張GPU卡。該服務作為阿里雲Container ServiceKubernetes版ACK(Container Service for Kubernetes)的組件對外提供服務,應用於高效能運算能力的情境,例如機器學習、深度學習、科學計算等,方便您更高效地利用GPU資源,以加速計算任務。本文介紹如何通過安裝並使用cGPU服務。

說明

cGPU服務的隔離功能不支援以UVM的方式(即調用CUDA API cudaMallocManaged())申請顯存,請您使用其他方式申請顯存,例如調用cudaMalloc()等。更多資訊,請參見NVIDIA官方文檔

前提條件

在進行本操作前,請確保GPU執行個體滿足以下要求:

  • GPU執行個體規格為gn7i、gn6i、gn6v、gn6e、gn5i、gn5、ebmgn7i、ebmgn6i、ebmgn7e、ebmgn6e。

  • GPU執行個體作業系統為CentOS、Ubuntu或Alibaba Cloud Linux。

  • GPU執行個體已安裝Tesla 418.87.01或更高版本的驅動。

  • GPU執行個體已安裝Docker 19.03.5或更高版本。

安裝cGPU服務

無論您是企業認證使用者還是個人實名認證使用者,推薦您通過ACK的Docker運行時環境安裝和使用cGPU服務。

重要

安裝1.5.7版本的cGPU組件,可能會導致cGPU核心驅動出現死結現象(即並發執行的進程互相牽制),從而導致Linux Kernel Panic(即核心錯誤)問題,建議您安裝1.5.8及以上版本的cGPU,或將低版本cGPU逐步升級到1.5.8及以上版本,避免在新業務上出現核心錯誤問題。

  1. 建立叢集。

    具體操作,請參見建立ACK託管叢集

  2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇應用 > 雲原生AI套件

  3. 雲原生AI套件頁面,單擊一鍵部署

  4. 基礎能力地區,選中調度策略擴充(批量任務調度、GPU共用、GPU拓撲感知)。

  5. 單擊頁面底部的部署雲原生AI套件

    組件安裝成功後,在雲原生AI套件頁面的組件列表中能看到已安裝的共用GPU組件ack-ai-installer

使用cGPU服務

本文以ecs.gn6i-c4g1.xlarge為例示範2個容器共用1張顯卡。

影響cGPU服務的環境變數說明

建立容器時指定環境變數的值,該值可以控制容器通過cGPU服務獲得算力。

環境變數名稱

取實值型別

說明

樣本

CGPU_DISABLE

Boolean

是否禁用cGPU服務,取值範圍:

  • false:啟用cGPU服務。

  • true:禁用cGPU服務,使用預設的NVIDIAContainer Service。

預設值:false。

true

ALIYUN_COM_GPU_MEM_DEV

Integer

設定GPU執行個體上每張顯卡的總顯存大小。

該參數值與執行個體規格有關,顯存大小按GiB取整數。例如:

對於ecs.gn6i-c4g1.xlarge執行個體,配備1張NVIDIA Tesla T4顯卡,在GPU執行個體上執行nvidia-smi可查看總顯存大小。

總顯存大小為15109 MiB,取整數為15 GiB。

ALIYUN_COM_GPU_MEM_CONTAINER

Integer

設定容器內可見的顯存大小,與ALIYUN_COM_GPU_MEM_DEV結合使用。例如:

在一張總顯存大小為15 GiB的顯卡上,設定ALIYUN_COM_GPU_MEM_DEV=15ALIYUN_COM_GPU_MEM_CONTAINER=1,即效果表示為容器分配1 GiB的顯存。

說明

如果不指定本參數或指定為0,則不使用cGPU服務,使用預設的NVIDIAContainer Service。

1 GiB

ALIYUN_COM_GPU_VISIBLE_DEVICES

Integer或uuid

指定容器內可見的GPU顯卡。例如:

在一台有4張顯卡的GPU執行個體上,執行nvidia-smi -L查看GPU顯卡裝置號和UUID。返回樣本如下所示:

GPU 0: Tesla T4 (UUID: GPU-b084ae33-e244-0959-cd97-83****)
GPU 1: Tesla T4 (UUID: GPU-3eb465ad-407c-4a23-0c5f-bb****)
GPU 2: Tesla T4 (UUID: GPU-2fce61ea-2424-27ec-a2f1-8b****)
GPU 3: Tesla T4 (UUID: GPU-22401369-db12-c6ce-fc48-d7****)

然後,您可以指定該參數為以下環境變數:

  • ALIYUN_COM_GPU_VISIBLE_DEVICES=0,1:表示為容器分配第1和第2張顯卡。

  • ALIYUN_COM_GPU_VISIBLE_DEVICES=GPU-b084ae33-e244-0959-cd97-83****,GPU-3eb465ad-407c-4a23-0c5f-bb****,GPU-2fce61ea-2424-27ec-a2f1-8b****:表示為容器分配3張指定UUID的顯卡。

0,1,即為容器分配第1和第2張顯卡。

ALIYUN_COM_GPU_SCHD_WEIGHT

Integer

設定容器的算力權重,取值範圍:1~max_inst。

ALIYUN_COM_GPU_HIGH_PRIO

Integer

設定容器的高優先順序,取值範圍:

  • 0:不設定容器為高優先順序(即普通優先順序)。

  • 1:設定容器為高優先順序。

預設值:0。

說明

建議每張GPU卡設定一個高優先順序,多個高優先順序容器之間遵循相應的調度策略(policy)。

  • 高優先順序容器有GPU任務時,不受調度策略(policy)限制,可以搶佔GPU的算力。

  • 高優先順序容器無GPU任務時,容器不參與調度過程,分配的算力為0。

0

運行cGPU服務

  1. 執行以下命令,建立容器並設定容器內可見的顯存。

    本樣本中,設定ALIYUN_COM_GPU_MEM_CONTAINERALIYUN_COM_GPU_MEM_DEV環境變數指定顯卡的總顯存和容器內可見的顯存。例如建立2個容器:

    • gpu_test1:分配6 GiB顯存。

      sudo docker run -d -t --gpus all --shm-size=1g --ulimit memlock=-1 --ulimit stack=67108864 --name gpu_test1 -v /mnt:/mnt -e ALIYUN_COM_GPU_MEM_CONTAINER=6 -e ALIYUN_COM_GPU_MEM_DEV=15 nvcr.io/nvidia/tensorflow:19.10-py3
    • gpu_test2:分配8 GiB顯存。

      sudo docker run -d -t --gpus all --shm-size=1g --ulimit memlock=-1 --ulimit stack=67108864 --name gpu_test2 -v /mnt:/mnt -e ALIYUN_COM_GPU_MEM_CONTAINER=8 -e ALIYUN_COM_GPU_MEM_DEV=15 nvcr.io/nvidia/tensorflow:19.10-py3
    說明

    該命令以使用TensorFlow鏡像nvcr.io/nvidia/tensorflow:19.10-py3為例,請根據實際情況更換為您自己的容器鏡像。使用TensorFlow鏡像搭建TensorFlow深度學習架構的操作,請參見部署NGC環境構建深度學習開發環境

  2. 執行以下命令,查看容器的顯存等GPU資訊。

    sudo docker exec -i gpu_test1 nvidia-smi

    以gpu_test1為例,容器gpu_test1中可見的顯存為6043 MiB,如下圖所示:gpu_test1

通過procfs節點查看cGPU服務

cGPU服務運行時會在/proc/cgpu_km下產生並自動管理多個procfs節點,您可以通過procfs節點查看和配置cGPU服務相關的資訊。

  1. 執行以下命令,查看procfs節點資訊。

    ls /proc/cgpu_km/

    執行結果如下所示:

    Dingtalk_20240911164737.jpg

    節點資訊說明

    節點資訊

    讀寫類型

    說明

    0

    讀寫

    cGPU服務會針對GPU執行個體中的每張顯卡產生一個目錄。並使用數字作為目錄名稱,例如0、1、2。

    本樣本中只有一張顯卡,對應的目錄為0。

    default_memsize

    讀寫

    如果沒有設定ALIYUN_COM_GPU_MEM_CONTAINER參數,預設為新建立的容器分配的顯存大小。

    inst_ctl

    讀寫

    控制節點。

    upgrade

    讀寫

    控制cGPU服務的熱升級。

    version

    唯讀

    cGPU的版本。

  2. 執行以下命令,查看GPU執行個體的顯卡目錄內容。

    本樣本中,以顯卡0為例。

    ls /proc/cgpu_km/0

    執行結果如下所示:

    Dingtalk_20240911170725.jpg

    顯卡目錄內容說明

    顯卡目錄

    讀寫類型

    說明

    012b2edccd7a0852a381c0cf

    讀寫

    容器對應的目錄。

    cGPU服務會針對運行在GPU執行個體中的每個容器產生一個的目錄,並使用容器ID作為目錄名稱。

    說明

    您可以執行docker ps查看已建立的容器。

    free_weight

    唯讀

    用於查詢和修改顯卡上可用的權重。

    如果free_weight=0,新建立容器的權重值為0,該容器不能擷取GPU算力,不能用於運行需要GPU算力的應用。

    major

    唯讀

    表示cGPU的major number,即不同的裝置類型。

    max_inst

    讀寫

    用於設定容器的最大數量,取值範圍為1~25。

    policy

    讀寫

    cGPU服務支援以下算力調度策略:

    • 0:平均調度。每個容器佔用固定的時間片,時間片佔比為1/max_inst

    • 1:搶佔調度。每個容器佔用盡量多的時間片,時間片佔比為1/當前容器數

    • 2:權重搶佔調度。當ALIYUN_COM_GPU_SCHD_WEIGHT的取值大於1時,自動使用權重搶佔調度。

    • 3:固定算力調度。用於固定算力的百分比。

    • 4:算力弱調度。隔離性弱於搶佔調度。

    • 5:原生調度。即GPU驅動本身的調度方式。

    您可以通過修改policy的值即時調整調度策略。更多調度策略說明,請參見cGPU服務使用樣本

    prio_ratio

    讀寫

    線上和離線混合使用情境下,高優先順序容器最大可以搶佔的算力。取值範圍:20~99。

  3. 執行以下命令,查看容器對應的目錄內容。

    本樣本中,以012b2edccd7a容器為例。

    ls /proc/cgpu_km/0/012b2edccd7a

    執行結果如下所示:

    Dingtalk_20240911171620.jpg

    容器目錄內容說明

    容器目錄

    讀寫類型

    說明

    highprio

    讀寫

    用於設定容器的優先順序,預設值為0。

    ALIYUN_COM_GPU_HIGH_PRIO參數取值為1時,表示容器最大可以搶佔prio_ratio參數的算力。

    說明

    該功能用於線上和離線混合使用情境。

    id

    唯讀

    容器的ID。

    memsize

    讀寫

    用於設定容器內的顯存大小。cGPU服務會根據ALIYUN_COM_GPU_MEM_DEV參數自動設定此值。

    meminfo

    唯讀

    包括容器內剩餘顯存容量、正在使用GPU的進程ID及其顯存用量。輸出如下所示:

    Free: 6730809344
    PID: 19772 Mem: 200278016

    weight

    讀寫

    用於設定容器擷取顯卡最大算力的權重,預設值為1。所有運行中的容器的權重之和必須小於等於max_inst

  4. (可選)執行以下命令,配置cGPU服務。

    瞭解procfs節點的用途後,您可以在GPU執行個體中執行命令進行切換調度策略、修改權重等操作,樣本命令如下表所示。

    命令

    效果

    echo 2 > /proc/cgpu_km/0/policy

    將調度策略切換為權重搶佔調度。

    cat /proc/cgpu_km/0/free_weight

    查看顯卡上可用的權重。如果free_weight=0,新建立容器的權重值為0,該容器不能擷取GPU算力,不能用於運行需要GPU算力的應用。

    cat /proc/cgpu_km/0/$dockerid/weight

    查看指定容器的權重。

    echo 4 > /proc/cgpu_km/0/$dockerid/weight

    修改容器擷取GPU算力的權重。

通過cgpu-smi工具查看cGPU容器

您可以通過cgpu-smi工具查看cGPU容器的相關資訊,包括容器ID、GPU利用率、算力限制、使用的顯存以及分配顯存的總量等資訊。

說明

cgpu-smi是cGPU的監控樣本。部署k8s時,您可以參考或使用cgpu-smi的樣本做二次開發整合。

cgpu-smi的監控展示資訊如下所示:

cgpu-smi

升級或卸載cGPU服務

升級cGPU服務

升級cGPU服務支援冷升級和熱升級兩種方式。

  • 冷升級

    Docker未使用cGPU服務的情況下,採用冷升級方式升級cGPU服務,操作步驟如下:

    1. 執行以下命令,關閉所有運行中的容器。

      sudo docker stop $(docker ps -a | awk '{ print $1}' | tail -n +2) 
    2. 執行以下命令,升級cGPU服務至最新版本。

      sudo sh upgrade.sh
  • 熱升級

    Docker使用cGPU服務的情況下,可以採用熱升級方式升級cGPU核心驅動,但是對於升級的版本有一定限制。 如需任何協助,請聯絡阿里雲售後技術團隊。

卸載cGPU服務

關於如何卸載節點上舊版本cGPU服務,具體操作,請參見通過命令升級節點cGPU版本

cGPU服務使用樣本

cGPU服務算力調度樣本

cGPU服務載入cgpu_km的模組時,會按照容器最大數量(max_inst)為每張顯卡設定時間片(X ms),用於為容器分配GPU算力,本樣本中以Slice 1、Slice 2或Slice N表示。使用不同調度策略時的調度樣本如下所示。

  • 平均調度(policy=0)

    在建立容器時,為容器分配時間片。cGPU服務會從Slice 1時間片開始調度,提交任務到物理GPU,並執行一個時間片(X ms)的時間,然後切換到下一個時間片。每個容器獲得的算力相同,都為1/max_inst,如下所示。

  • 搶佔調度(policy=1)

    在建立容器時,為容器分配時間片。cGPU服務會從Slice 1開始調度,但如果沒有使用某個容器,或者容器內沒有進程開啟GPU裝置,則跳過調度,切換到下一個時間片。

    樣本如下:

    1. 只建立一個容器Docker 1,獲得Slice 1時間片,在Docker 1中運行2個TensorFlow進程,此時Docker 1最大獲得整個物理GPU的算力。

    2. 再建立一個容器Docker 2,獲得Slice 2時間片。如果Docker 2內沒有進程開啟GPU裝置,調度時會跳過Docker 2的時間片Slice 2。

    3. 當Docker 2有進程開啟GPU裝置時,Slice 1和Slice 2都加入調度,Docker 1和Docker 2最大分別獲得1/2物理GPU的算力,如下所示。

  • 權重搶佔調度(policy=2)

    如果在建立容器時設定ALIYUN_COM_GPU_SCHD_WEIGHT大於1,則自動使用權重搶佔調度。cGPU服務按照容器數量(max_inst)將物理GPU算力劃分成max_inst份,但如果ALIYUN_COM_GPU_SCHD_WEIGHT大於1,cGPU服務會將多個時間片組合成一個更大的時間片分配給容器。

    設定樣本如下:

    • Docker 1:ALIYUN_COM_GPU_SCHD_WEIGHT=m

    • Docker 2:ALIYUN_COM_GPU_SCHD_WEIGHT=n

    調度效果如下:

    • 如果只有Docker 1運行, Docker 1搶佔整個物理GPU的算力。

    • 如果Docker 1和Docker 2同時運行,Docker 1和Docker 2獲得的理論算力比例是m:n。和搶佔調度不同的是,即使Docker 2中沒有GPU進程也會佔用n個時間片的時間。

      說明

      m:n設定為2:1和8:4時的運行表現存在差別。在1秒內切換時間片的次數,前者是後者的4倍。

    權重搶佔調度限制了容器使用GPU算力的理論最大值。但對算力很強的顯卡(例如NVIDIA V100顯卡),如果顯存使用較少,在一個時間片內即可完成計算任務。此時如果m:n值設定為8:4,則剩餘時間片內GPU算力會閑置,限制基本失效。

  • 固定算力調度(policy=3)

    您可以通過指定ALIYUN_COM_GPU_SCHD_WEIGHT和max_inst的佔比,固定算力的百分比。

  • 算力弱調度(policy=4)

    在建立容器時,為容器分配時間片,隔離性弱於搶佔調度。更多資訊,請參見搶佔調度(policy=1)

  • 原生調度(policy=5)

    只用來做顯存的隔離。原生調度表示NVIDIA GPU驅動本身的調度方式。

算力調度策略支援阿里雲所有的異構GPU執行個體,以及GPU執行個體所配備的NVIDIA顯卡,其型號包含Tesla P4、Tesla P100、Tesla T4、Tesla V100、Tesla A10。以下測試項使用2個容器共用一台單卡A10的GPU執行個體,並將2個容器的算力比設定為1:2,將顯存均分,每個容器的顯存為12 G。

說明

以下效能測試結果資料為實驗室資料,僅供參考。

  • 測試項1: 在基於TensorFlow架構訓練的ResNet50模型、精度為FP16的情境下,測試不同batch_size下的效能資料比較。結果如下所示:

    架構

    模型

    batch_size

    精度

    images/sec(容器1)

    images/sec(容器2)

    TensorFlow

    ResNet50

    16

    FP16

    151

    307

    TensorFlow

    ResNet50

    32

    FP16

    204

    418

    TensorFlow

    ResNet50

    64

    FP16

    247

    503

    TensorFlow

    ResNet50

    128

    FP16

    257

    516

    111

  • 測試項2:在基於TensorRT架構訓練的ResNet50模型、精度為FP16的情境下,測試不同batch_size下的效能資料比較。結果如下所示:

    架構

    模型

    batch_size

    精度

    images/sec(容器1)

    images/sec(容器2)

    TensorRT

    ResNet50

    1

    FP16

    568.05

    1132.08

    TensorRT

    ResNet50

    2

    FP16

    940.36

    1884.12

    TensorRT

    ResNet50

    4

    FP16

    1304.03

    2571.91

    TensorRT

    ResNet50

    8

    FP16

    1586.87

    3055.66

    TensorRT

    ResNet50

    16

    FP16

    1783.91

    3381.72

    TensorRT

    ResNet50

    32

    FP16

    1989.28

    3695.88

    TensorRT

    ResNet50

    64

    FP16

    2105.81

    3889.35

    TensorRT

    ResNet50

    128

    FP16

    2205.25

    3901.94

    2021-11-26_10-53-29

cGPU服務多卡劃分樣本

本樣本以設定4卡為例,設定0卡為3 G、1卡為4 G、2卡為5 G、3卡為6 G。多卡劃分範例程式碼如下所示:

docker run -d -t --runtime=nvidia  --name gpu_test0123 --shm-size=1g --ulimit memlock=-1 --ulimit stack=67108864 -v /mnt:/mnt -e ALIYUN_COM_GPU_MEM_CONTAINER=3,4,5,6 -e ALIYUN_COM_GPU_MEM_DEV=23 -e NVIDIA_VISIBLE_DEVICES=0,1,2,3 nvcr.io/nvidia/tensorflow:21.03-tf1-py3
docker exec -i gpu_test0123   nvidia-smi

執行結果顯示如下,您可以看到4卡顯存詳情。回顯結果

多卡設定顯存參數(即ALIYUN_COM_GPU_MEM_CONTAINER參數)說明如下所示:

參數取值

說明

ALIYUN_COM_GPU_MEM_CONTAINER=3

表示4卡的顯存都被設定為3 G。

ALIYUN_COM_GPU_MEM_CONTAINER=3,1

表示4卡的顯存依次被設定為3 G、1 G、1 G、1 G。

ALIYUN_COM_GPU_MEM_CONTAINER=3,4,5,6

表示4卡的顯存依次被設定為3 G、4 G、5 G、6 G。

ALIYUN_COM_GPU_MEM_CONTAINER未設定

表示禁用cGPU服務。

ALIYUN_COM_GPU_MEM_CONTAINER=0

ALIYUN_COM_GPU_MEM_CONTAINER=1,0,0