天天看點

妙到毫巅,在阿裡雲容器服務中體驗RAPIDS加速資料科學

摘要

算法、資料和算力稱為人工智能的三大要素,如果沒有算力的支撐,人工智能難以落地。而Nvidia GPU的強勁算力是AI模型訓練加速的首選,但是它的價格也确實不菲。如何能夠簡單,有效同時低成本的使用Nvidia GPU的算力,使用阿裡雲容器服務+ECI+Arena的方案是一個可以參考的選項。

而一談起Nvidia GPU,大家首先會想到的就是深度學習,傳統的機器學習和資料分析的方法對GPU的利用卻很少,實際上Nvidia有一個非常優秀的項目RAPIDS,全稱Real-time Acceleration Platform for Integrated Data Science,是NVIDIA針對資料科學和機器學習推出的GPU加速庫。更多RAPIDS資訊請參見官方網站。這是一個緻力于将GPU加速帶給傳統算法的項目,并且提供了與Pandas和scikit-learn一緻的用法和體驗。實際上RAPIDS有三個子產品:cuDF相當于Pandas,cuML相當于scikit-learn,cuGraph則是處理圖資料的。由于它的相容性很好,我們可以把RAPIDS與深度學習架構結合,用cuDF來利用GPU加速處理資料,然後使用TensorFlow和PyTorch的深度學習模型架構處理任務。

妙到毫巅,在阿裡雲容器服務中體驗RAPIDS加速資料科學
在本文中,我們将介紹如何利用TensorFlow和Rapids實作在阿裡雲容器服務上以圖搜圖的功能;同時通過ECI實作GPU資源的使用即申請,秒級的GPU資源準備速度,完成即釋放,使用者無需提前準備GPU執行個體;而站在使用者的角度,他并不需要和Kubernetes的基礎設施打交道,通過arena的指令行,就可以實作包含GPU的RAPIDS環境的建構和運作,并且完成對GPU基礎設施的管理。

執行步驟

步驟1:準備叢集

準備托管k8s的叢集,所謂托管k8s的叢集就是這個k8s的管控節點由阿裡雲承擔資源和運維成本,并且建立了虛拟的Kubelet節點

需要您已建立好容器服務 Kubernetes叢集。 您可以選擇管版的Kubernetes叢集。

由于需要運作系統元件容器,節點中至少有一個Worker節點。

  • 安裝虛拟節點,具體可以參考 虛拟節點
  • 配置virtual-kubelet-autoscaler,當叢集内的GPU資源不足的時候,通過virtual-kubelet-autoscaler将彈出使用GPU的ECI執行個體。具體參考 文檔

步驟2:從無到有運作arena建立RAPIDS服務

1.安裝arena

$ wget http://kubeflow.oss-cn-beijing.aliyuncs.com/arena-installer-0.3.0-b556a36-linux-amd64.tar.gz
$ tar -xvf arena*.tar.gz
$ cd arena-installer
$ ./install.sh           

2.先運作一下arena指令檢視叢集的GPU資源, 可以看到在該使用者叢集下,有一個真實節點并沒有包含GPU資源,同時存在了一個虛拟節點,該節點并不真實存在,無需付費,同時它提供了無限的GPU資源可以擴充。

$ arena top node
arena top node
NAME                       IPADDRESS      ROLE    STATUS  GPU(Total)  GPU(Allocated)
cn-shanghai.192.168.1.248  192.168.1.248  <none>  ready   0           0
virtual-kubelet            172.20.2.18    agent   ready   1000        0
-----------------------------------------------------------------------------------------
Allocated/Total GPUs In Cluster:
0/1000 (0%)           

3.再送出rapids任務前,我們需要做一些準備。準備的目的是加速建立過程和簡化通路操作。

3.1.設定通路方式。将通路方式設定為LoadBalancer(該方法隻是為了示例簡單,并不推薦您在生産環境開放外網ip方通路)

$ find /charts/ -name "*.yaml" | xargs sed -i "s/NodePort/LoadBalancer/g"           

3.2.加速啟動速度

3.2.1.GPU的容器鏡像通常很大,以本實驗要使用的rapids容器鏡像為例,它的容量為14.7GB.通常啟動時間會在10分鐘左右。而通過

鏡像緩存的能力

可以将這個從無到有的過程縮短到20s左右。

docker images | grep rapids
registry.cn-shanghai.aliyuncs.com/tensorflow-samples/rapids-samples                0.8.2-cuda10.0-runtime-ubuntu16.04   4597a0334d41        12 days ago         14.7GB           

3.2.2.而在serverless kubernetes中,你隻需要建立一個ImageCache CRD,就可以直接使用鏡像緩存的能力。

$ cat > imagecache.yaml << EOF
apiVersion: eci.alibabacloud.com/v1
kind: ImageCache
metadata:
  name: imagecache-rapids
spec:
  images:
  - registry.cn-shanghai.aliyuncs.com/tensorflow-samples/rapids-samples:0.8.2-cuda10.0-runtime-ubuntu16.04
  imageCacheSize:
   50
EOF

$ kubectl create -f imagecache.yaml           

3.2.3.送出後稍等片刻。檢視ImageCache狀态,其中CACHID可以做後面送出任務時指定的snapshot-id

$ kubectl get imagecache
NAME                AGE    CACHEID                    PHASE   PROGRESS
imagecache-rapids   3d9h   imc-uf6dxdji7txxxxx        Ready   100%           

具體操作可以參考

4.送出rapids的開發環境

$ arena serve custom \
     --name=rapids \
     --selector=type=virtual-kubelet \
     --toleration=all \
     --annotation=k8s.aliyun.com/eci-image-snapshot-id=imc-uf6dxdji7txxxxx \
     --annotation=k8s.aliyun.com/eci-instance-type=ecs.gn5i-c8g1.2xlarge \
     --gpus=1 \
     -e=PASSWORD=mypassw0rd \
     --restful-port=80 \
     --image=registry.cn-shanghai.aliyuncs.com/tensorflow-samples/rapids-samples:0.8.2-cuda10.0-runtime-ubuntu16.04
configmap/rapids-201912011815-custom-serving created
configmap/rapids-201912011815-custom-serving labeled
service/rapids-201912011815 created
deployment.extensions/rapids-201912011815-custom-serving created           

--selector=type=virtual-kubelet表示通過Virtual Node啟動Pod

--annotation=k8s.aliyun.com/eci-instance-type=ecs.gn5i-c8g1.2xlarge表示指定使用ECI的執行個體類型,ecs.gn5i-c8g1.2xlarge代表阿裡雲P4機型。具體規格可以檢視文檔

--annotation=k8s.aliyun.com/eci-image-snapshot-id=imc-uf6dxdji7txxxxx指定3.2.3步中的CACHEID

-e=PASSWORD=mypassw0rd就是通過環境變量PASSWORD設定通路RAPIDS notebook

--gpus=1表示申請的GPU數目

4.檢視通路位址,這裡是ENDPOINT_ADDRESS和PORTS的組合, 在本示例中它是106.15.173.2:80。同時發現該任務在32秒的時候就可以變成Running狀态

$ arena serve list
NAME    TYPE    VERSION       DESIRED  AVAILABLE  ENDPOINT_ADDRESS  PORTS
rapids  CUSTOM  201911181827  1        1          105.13.58.3      restful:80

$ arena serve get rapids
 arena serve get rapids
NAME:             rapids
NAMESPACE:        default
VERSION:          201912011815
DESIRED:          1
AVAILABLE:        1
SERVING TYPE:     CUSTOM
ENDPOINT ADDRESS: 106.15.173.2
ENDPOINT PORTS:   restful:80
AGE:              32s

INSTANCE                                           STATUS   AGE  READY  RESTARTS  NODE
rapids-201912011815-custom-serving-6b54d5cd-swcwz  Running  32s  1/1    0         N/A           

5.再次檢視叢集的GPU使用情況,發現已經有一個GPU資源被占用了

$ arena top node
NAME                       IPADDRESS      ROLE    STATUS  GPU(Total)  GPU(Allocated)
cn-shanghai.192.168.1.248  192.168.1.248  <none>  ready   0           0
virtual-kubelet            172.20.2.20    agent   ready   1000        1
-----------------------------------------------------------------------------------------
Allocated/Total GPUs In Cluster:
1/1000 (0%)           

6.如果想查詢是哪個Pod占用了這個GPU, 可以在原有指令中加一個-d就可以看到具體的Pod名稱。

$ arena top node -d


NAME:       cn-shanghai.192.168.1.248
IPADDRESS:  192.168.1.248
ROLE:       <none>

Total GPUs In Node cn-shanghai.192.168.1.248:      0
Allocated GPUs In Node cn-shanghai.192.168.1.248:  0 (0%)
-----------------------------------------------------------------------------------------

NAME:       virtual-kubelet
IPADDRESS:  172.20.2.20
ROLE:       agent

NAMESPACE  NAME                                                GPU REQUESTS
default    rapids-201912011815-custom-serving-6b54d5cd-swcwz  1

Total GPUs In Node virtual-kubelet:      1000
Allocated GPUs In Node virtual-kubelet:  1 (0%)
-----------------------------------------------------------------------------------------


Allocated/Total GPUs In Cluster:  1/1000 (0%)           

7.根據步驟4中的通路位址和端口,打開本地浏覽器。輸入

http://

{ENDPOINT ADDRESS}:{ENDPOINT PORT},在本例子中是

http://105.13.58.3:80

說明: 推薦使用Chrome浏覽器。

8.輸入啟動指令中設定的密碼,然後單擊Log in。 在本例子中,密碼為mypassw0rd

妙到毫巅,在阿裡雲容器服務中體驗RAPIDS加速資料科學

步驟三:執行以圖搜圖的示例

1.進入示例所在目錄cuml。

2.輕按兩下cuml_knn.ipynb檔案。

3.單擊

妙到毫巅,在阿裡雲容器服務中體驗RAPIDS加速資料科學

說明: 單擊一次執行一個cell,請單擊至示例執行結束,詳細說明請參見示例執行過程。

妙到毫巅,在阿裡雲容器服務中體驗RAPIDS加速資料科學

示例執行過程

圖像搜尋示例的執行過程分為三個步驟:處理資料集、提取圖檔特征和搜尋相似圖檔。本文示例結果中對比了GPU加速的RAPIDS cuml KNN與CPU實作的scikit-learn KNN的性能。

1.處理資料集。

1.1 下載下傳和解壓資料集。 本文示例中使用了STL-10資料集,該資料集中包含10萬張未打标的圖檔,圖檔的尺寸均為:96 x 96 x 3, 您可以使用其他資料集,為便于提取圖檔特征,請確定資料集中圖檔的尺寸相同。

本文示例提供了download_and_extract(data_dir)方法供您下載下傳和解壓STL-10資料集。RAPIDS鏡像中已經将資料集下載下傳到./data目錄,您可以執行download_and_extract()方法直接解壓資料集。

妙到毫巅,在阿裡雲容器服務中體驗RAPIDS加速資料科學

1.2. 讀取圖檔。 從資料集解壓出的資料為二進制格式,執行read_all_images(path_to_data)方法加載資料并轉換為NHWC(batch, height, width, channels)格式,以便用Tensorflow提取圖檔特征。

妙到毫巅,在阿裡雲容器服務中體驗RAPIDS加速資料科學

1.3. 展示圖檔。 執行show_image(image)方法随機展示一張資料集中的圖檔。

妙到毫巅,在阿裡雲容器服務中體驗RAPIDS加速資料科學

1.4. 分割資料集。 按照9:1的比例把資料集分為兩部分,分别用于建立圖檔索引庫和搜尋圖檔。

妙到毫巅,在阿裡雲容器服務中體驗RAPIDS加速資料科學

2.提取圖檔特征。 使用開源架構Tensorflow和Keras提取圖檔特征,其中模型為基于ImageNet資料集的ResNet50(notop)預訓練模型。

2.1 設定Tensorflow參數。 Tensorflow預設使用所有GPU顯存,我們需要留出部分GPU顯存供cuML使用。您可以選擇一種方法設定GPU顯存參數:

  • 方法1:依據運作需求進行顯存配置設定。
config.gpu_options.allow_growth = True           
  • 方法2:設定可以使用的GPU顯存比例。本示例中使用方法2,并且GPU顯存比例預設設定為0.3,即Tensorflow可以使用整塊GPU顯存的30%,您可以依據應用場景修改比例。
config.gpu_options.per_process_gpu_memory_fraction = 0.3           
妙到毫巅,在阿裡雲容器服務中體驗RAPIDS加速資料科學

2.2 下載下傳ResNet50(notop)預訓練模型。 連接配接公網下載下傳模型(大小約91M),目前該模型已經被儲存到/root/.keras/models/目錄。

妙到毫巅,在阿裡雲容器服務中體驗RAPIDS加速資料科學
妙到毫巅,在阿裡雲容器服務中體驗RAPIDS加速資料科學

您可以執行model.summary()方法檢視模型的網絡結構。

妙到毫巅,在阿裡雲容器服務中體驗RAPIDS加速資料科學

2.2 提取圖檔特征。 對分割得到的兩個圖檔資料集執行model.predict()方法提取圖檔特征。

妙到毫巅,在阿裡雲容器服務中體驗RAPIDS加速資料科學

搜尋相似圖檔。

3.1 使用cuml KNN搜尋相似圖檔。 通過k=3設定K值為3,即查找最相似的3張圖檔,您可以依據使用場景自定義K值。

其中,knn_cuml.fit()方法為建立索引階段,knn_cuml.kneighbors()為搜尋近鄰階段。

妙到毫巅,在阿裡雲容器服務中體驗RAPIDS加速資料科學

KNN向量檢索耗時791 ms。

3.2 使用scikit-learn KNN搜尋相似圖檔。 通過n_neighbors=3設定K值為3,通過n_jobs=-1設定使用所有CPU進行近鄰搜尋。

說明: ecs.gn5i-c8g1.2xlarge的配置為8 vCPU。

妙到毫巅,在阿裡雲容器服務中體驗RAPIDS加速資料科學

KNN向量檢索耗時7分34秒。

3.3 對比cuml KNN和scikit-learn KNN的搜尋結果。 對比兩種方式的KNN向量檢索速度,使用GPU加速的cuml KNN耗時791 ms,使用CPU的scikit-learn KNN耗時7min 34s。前者為後者的近600倍。

驗證兩種方式的輸出結果是否相同,輸出結果為兩個數組:

  • distance:最小的K個距離值。本示例中搜尋了10000張圖檔,K值為3,是以distance.shape=(10000,3)。
  • indices:對應的圖檔索引。indices.shape=(10000, 3)。

    由于本示例所用資料集中存在重複圖檔,容易出現圖檔相同但索引不同的情況,是以使用distances,不使用indices對比結果。考慮到計算誤差,如果兩種方法得出的10000張圖檔中的3個最小距離值誤差都小于1,則認為結果相同。

妙到毫巅,在阿裡雲容器服務中體驗RAPIDS加速資料科學

圖檔搜尋結果

本示例從1萬張搜尋圖檔中随機選擇5張圖檔并搜尋相似圖檔,最終展示出5行4列圖檔。

第一列為搜尋圖檔,第二列至第四列為圖檔索引庫中的相似圖檔,且相似性依次遞減。每張相似圖檔的标題為計算的距離,數值越大相似性越低。

妙到毫巅,在阿裡雲容器服務中體驗RAPIDS加速資料科學

步驟4:清理工作

$ arena serve delete rapids
service "rapids-201912011815" deleted
deployment.extensions "rapids-201912011815-custom-serving" deleted
configmap "rapids-201912011815-custom-serving" deleted
INFO[0000] The Serving job rapids with version 201912011815 has been deleted successfully           

總結

本文介紹通過Arena+阿裡雲

Serverless Kubernetes

快速,簡單,低成本的使用RAPIDS加速資料科學。

繼續閱讀