本文介紹如何通過Serverless Devs工具基於非同步任務調用GPU函數,並將調用結果自動回調至配置的非同步目標函數。
背景資訊
GPU執行個體
隨著機器學習,特別是深度學習的廣泛應用,大量向量、矩陣、張量運算所產生的算力需求,包括訓練情境對高精度計算的需求,以及推理情境對低精度計算的需求,傳統CPU儼然已無法勝任。2007年英偉達推出可程式化通用計算平台CUDA架構,大量的科研人員和開發人員將大量演算法進行改寫,從而獲得幾十至幾千倍的加速效果。在機器學習的趨勢來臨後,GPU更是成為各類工具、演算法、架構的基礎底層設施之一。
2021年雲棲大會,阿里雲Function Compute正式推出基於Turing架構的GPU執行個體,使得Serverless開發人員可以將AI訓練與推理的業務負載下沉到GPU硬體加速,從而加快模型訓練、推理服務的效率。
非同步任務
Function Compute提供非同步任務的分發、執行和觀測的全棧能力,使得您只需要專註於任務處理邏輯的編寫,建立任務處理函數,然後提交任務。Function Compute不但提供非同步任務日誌、指標以及各個處理階段耗時統計等豐富的可觀測能力,也提供執行個體自動Auto Scaling、任務去重、指定任務終止以及批量任務暫停、恢複和刪除等功能。更多資訊,請參見非同步任務。
應用情境
在面向非即時、偏離線的AI推理情境、AI訓練情境和音視頻生產情境,基於非同步任務調用GPU函數,使得開發人員可以聚焦於業務本身,縮短業務達成路徑。具體實現如下。
提供GPU虛擬化,支援以1/8、1/4、1/2或獨佔方式使用GPU,允許業務以更精細化的方式配置GPU執行個體。
提供非同步管理、任務去重、任務監控、任務重試、事件觸發、結果回調和任務編排等一系列成熟的非同步任務處理能力。
屏蔽營運GPU叢集的繁重負擔,包括驅動以及CUDA版本管理、機器運行管理和GPU壞卡管理等,使得開發人員專註於代碼開發,聚焦於營運目標的達成。
實現原理
本文以部署一個GPU函數tgpu_basic_func、非同步呼叫成功回呼函數async-callback-succ-func和非同步呼叫失敗回呼函數async-callback-fail-func為例,介紹非同步呼叫GPU函數並實現結果回調的功能原理。函數具體資訊,如下表所示。
函數名稱 | 函數說明 | 運行環境 | 執行個體類型 | 觸發類型 |
tgpu_basic_func | 基於Function Compute的GPU執行個體,運行AI准即時任務、AI離線任務等。 | Custom Container | GPU執行個體 | HTTP函數 |
async-callback-succ-func | 任務執行成功後的目標回呼函數。 | Python 3 | CPU執行個體 | 事件函數 |
async-callback-fail-func | 任務執行失敗後的目標回呼函數。 | Python 3 | CPU執行個體 | 事件函數 |
實現原理簡單概括如下圖。
前提條件
步驟一:部署成功回呼函數
初始化專案。
s init devsapp/start-fc-event-python3 -d async-succ-callback建立的專案目錄如下所示。
├── async-succ-callback │ ├── code │ │ └── index.py │ └── s.yaml進入專案所在目錄。
cd async-succ-callback按照實際情況修改目錄檔案中的參數配置。
編輯
s.yaml檔案。樣本如下。edition: 1.0.0 name: hello-world-app # access是當前應用所需要的密鑰資訊配置: # 密鑰配置請參見:https://www.serverless-devs.com/serverless-devs/command/config # 密鑰使用請參見:https://www.serverless-devs.com/serverless-devs/tool access: "default" vars: # 全域變數 region: "cn-shenzhen" services: helloworld: # 業務名稱/模組名稱 component: fc props: region: ${vars.region} service: name: "async-callback-service" description: 'async callback service' # logConfig配置文檔:https://gitee.com/devsapp/fc/blob/main/docs/zh/yaml/service.md#logconfig logConfig: project: tgpu-prj-sh # 建議配置,用於查看請求日誌,需要在SLSLog Service中提前建立相應的project logstore: tgpu-logstore-sh # 建議配置,用於查看請求日誌,需要在SLSLog Service中提前建立相應的logstore enableRequestMetrics: true enableInstanceMetrics: true logBeginRule: DefaultRegex function: name: "async-callback-succ-func" description: 'async callback succ func' runtime: python3 codeUri: ./code handler: index.handler memorySize: 128 timeout: 60編輯
index.py檔案。樣本如下:# -*- coding: utf-8 -*- import logging # To enable the initializer feature # please implement the initializer function as below: # def initializer(context): # logger = logging.getLogger() # logger.info('initializing') def handler(event, context): logger = logging.getLogger() logger.info('hello async callback succ') return 'hello async callback succ'
部署代碼至Function Compute。
s deploy您可以在Function Compute控制台查看部署成功的函數。
本地調用調試函數。
s invoke調用完成後,返回結果
hello async callback succ。
步驟二:部署失敗回呼函數
初始化專案。
s init devsapp/start-fc-event-python3 -d async-fail-callback建立的專案目錄如下所示。
├── async-fail-callback │ ├── code │ │ └── index.py │ └── s.yaml進入專案所在目錄。
cd async-fail-callback按照實際情況修改目錄檔案中的參數配置。
編輯
s.yaml檔案。樣本如下:edition: 1.0.0 name: hello-world-app # access是當前應用所需要的密鑰資訊配置: # 密鑰配置請參見:https://www.serverless-devs.com/serverless-devs/command/config # 密鑰使用請參見:https://www.serverless-devs.com/serverless-devs/tool access: "default" vars: # 全域變數 region: "cn-shenzhen" services: helloworld: # 業務名稱/模組名稱 component: fc props: region: ${vars.region} service: name: "async-callback-service" description: 'async callback service' # logConfig配置文檔:https://gitee.com/devsapp/fc/blob/main/docs/zh/yaml/service.md#logconfig logConfig: project: tgpu-prj-sh # 建議配置,用於查看請求日誌,需要在SLSLog Service中提前建立相應的project logstore: tgpu-logstore-sh # 建議配置,用於查看請求日誌,需要在SLSLog Service中提前建立相應的logstore enableRequestMetrics: true enableInstanceMetrics: true logBeginRule: DefaultRegex function: name: "async-callback-fail-func" description: 'async callback fail func' runtime: python3 codeUri: ./code handler: index.handler memorySize: 128 timeout: 60編輯
index.py檔案。樣本如下:# -*- coding: utf-8 -*- import logging # To enable the initializer feature # please implement the initializer function as below: # def initializer(context): # logger = logging.getLogger() # logger.info('initializing') def handler(event, context): logger = logging.getLogger() logger.info('hello async callback fail') return 'hello async callback fail'
部署代碼至Function Compute。
s deploy您可以在Function Compute控制台查看部署成功的函數。
本地調用調試函數。
s invoke調用完成後,返回結果
hello async callback fail。
步驟三:部署GPU函數
建立專案目錄。
mkdir fc-gpu-async-job&&cd fc-gpu-async-job按照以下目錄結構建立檔案並根據實際情況修改檔案中的參數配置。
目錄結構如下所示。
├── fc-gpu-async-job ├── code │ ├── app.py │ └── Dockerfile └── s.yaml編輯s.yaml檔案。樣本如下:
edition: 1.0.0 name: gpu-container-demo # access是當前應用所需要的密鑰資訊配置: # 密鑰配置請參見:https://www.serverless-devs.com/serverless-devs/command/config # 密鑰使用順序請參見:https://www.serverless-devs.com/serverless-devs/tool access: default vars: region: cn-shenzhen services: customContainer-demo: component: devsapp/fc props: region: ${vars.region} service: name: tgpu_basic_service internetAccess: true # logConfig配置文檔:https://gitee.com/devsapp/fc/blob/main/docs/zh/yaml/service.md#logconfig logConfig: project: aliyun**** # 建議配置,用於查看請求日誌,需要在SLSLog Service中提前建立相應的project logstore: func**** # 建議配置,用於查看請求日誌,需要在SLSLog Service中提前建立相應的logstore enableRequestMetrics: true enableInstanceMetrics: true logBeginRule: DefaultRegex function: name: tgpu_basic_func description: test gpu basic handler: not-used timeout: 600 caPort: 9000 # 業務可根據實際顯存佔用,選擇合適的GPU執行個體規格;如下例子展示1/8 GPU虛擬化規格 instanceType: fc.gpu.tesla.1 gpuMemorySize: 2048 cpu: 1 memorySize: 4096 diskSize: 512 instanceConcurrency: 1 runtime: custom-container customContainerConfig: # 填寫您的鏡像資訊。需要提前建立ACR個人版或企業版執行個體,並建立相應的命名空間與鏡像倉庫 image: registry.cn-shenzhen.aliyuncs.com/my****/my**** # 開啟鏡像加速,對於GB層級鏡像有非常好的冷啟動最佳化效果 accelerationType: Default codeUri: ./code # 非同步配置 # 詳細見:https://gitee.com/devsapp/fc/blob/main/docs/zh/yaml/function.md#asyncconfiguration asyncConfiguration: destination: # 填寫您建立的失敗回呼函數的ARN onFailure: "acs:fc:cn-shenzhen:164901546557****:services/async-callback-service.LATEST/functions/async-callback-fail-func" # 填寫您建立的成功回呼函數的ARN onSuccess: "acs:fc:cn-shenzhen:164901546557****:services/async-callback-service.LATEST/functions/async-callback-succ-func" statefulInvocation: true triggers: - name: httpTrigger type: http config: authType: anonymous methods: - GET編輯Dockerfile檔案。樣本如下:
FROM nvidia/cuda:11.0-base FROM ubuntu WORKDIR /usr/src/app RUN apt-get update RUN apt-get install -y python3 COPY . . CMD [ "python3", "-u", "/usr/src/app/app.py" ] EXPOSE 9000編輯app.py檔案。樣本如下:
# -*- coding: utf-8 -*- # python2 and python3 from __future__ import print_function from http.server import HTTPServer, BaseHTTPRequestHandler import json import sys import logging import os import time host = ('0.0.0.0', 9000) class Resquest(BaseHTTPRequestHandler): def do_GET(self): print("simulate long execution scenario, sleep 10 seconds") time.sleep(10) print("show me GPU info") msg = os.popen("nvidia-smi -L").read() data = {'result': msg} self.send_response(200) self.send_header('Content-type', 'application/json') self.end_headers() self.wfile.write(json.dumps(data).encode()) if __name__ == '__main__': server = HTTPServer(host, Resquest) print("Starting server, listen at: %s:%s" % host) server.serve_forever()
部署代碼至Function Compute。
s deploy您可以在Function Compute控制台查看部署成功的GPU函數,以及該函數的非同步配置。

本地調用調試函數。
s invoke調用完成後,返回結果
Hello, World!。提交非同步任務。
查看GPU函數的鏡像加速準備狀態。
建議鏡像加速準備狀態為可用後,再發起非同步任務,否則可能會引起鏈路逾時等異常問題。

登入Function Compute控制台,找到已建立的GPU函數
tgpu_basic_func,在非同步工作清單頁簽,單擊提交任務。
執行完成後,任務狀態為執行成功。
此時,您可以找到配置的成功回呼函數
async-callback-succ-func,依次選擇頁簽,然後找到本次非同步請求結果行,查看調用結果是否為調用成功。
更多資訊
更多關於GPU函數的最佳實務,請參見Serverless GPU應用模板案例。