全部產品
Search
文件中心

Function Compute:基於非同步任務調用GPU函數

更新時間:Jan 16, 2025

本文介紹如何通過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執行個體

事件函數

實現原理簡單概括如下圖。

前提條件

步驟一:部署成功回呼函數

  1. 初始化專案。

    s init devsapp/start-fc-event-python3 -d async-succ-callback

    建立的專案目錄如下所示。

    ├── async-succ-callback
    │ ├── code
    │ │ └── index.py
    │ └── s.yaml
  2. 進入專案所在目錄。

    cd async-succ-callback
  3. 按照實際情況修改目錄檔案中的參數配置。

    • 編輯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'
  4. 部署代碼至Function Compute

    s deploy

    您可以在Function Compute控制台查看部署成功的函數。

  5. 本地調用調試函數。

    s invoke

    調用完成後,返回結果hello async callback succ

步驟二:部署失敗回呼函數

  1. 初始化專案。

    s init devsapp/start-fc-event-python3 -d async-fail-callback

    建立的專案目錄如下所示。

    ├── async-fail-callback
    │ ├── code
    │ │ └── index.py
    │ └── s.yaml
  2. 進入專案所在目錄。

    cd async-fail-callback
  3. 按照實際情況修改目錄檔案中的參數配置。

    • 編輯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'
  4. 部署代碼至Function Compute

    s deploy

    您可以在Function Compute控制台查看部署成功的函數。

  5. 本地調用調試函數。

    s invoke

    調用完成後,返回結果hello async callback fail

步驟三:部署GPU函數

  1. 建立專案目錄。

    mkdir fc-gpu-async-job&&cd fc-gpu-async-job
  2. 按照以下目錄結構建立檔案並根據實際情況修改檔案中的參數配置。

    目錄結構如下所示。

    ├── 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()
  3. 部署代碼至Function Compute

    s deploy

    您可以在Function Compute控制台查看部署成功的GPU函數,以及該函數的非同步配置。dg-gpu-async-result

  4. 本地調用調試函數。

    s invoke

    調用完成後,返回結果Hello, World!

  5. 提交非同步任務。

    1. 查看GPU函數的鏡像加速準備狀態。

      建議鏡像加速準備狀態為可用後,再發起非同步任務,否則可能會引起鏈路逾時等異常問題。dg-gpu-iamge-state

    2. 登入Function Compute控制台,找到已建立的GPU函數tgpu_basic_func,在非同步工作清單頁簽,單擊提交任務

    執行完成後,任務狀態為執行成功。

    此時,您可以找到配置的成功回呼函數async-callback-succ-func,依次選擇調用日誌 > 調用請求列表頁簽,然後找到本次非同步請求結果行,查看調用結果是否為調用成功。dg-gpu-success-result

更多資訊

更多關於GPU函數的最佳實務,請參見Serverless GPU應用模板案例