本文介绍如何通过Serverless Devs工具基于异步任务调用GPU函数,并将调用结果自动回调至配置的异步目标函数。
背景信息
GPU实例
随着机器学习,特别是深度学习的广泛应用,大量向量、矩阵、张量运算所产生的算力需求,包括训练场景对高精度计算的需求,以及推理场景对低精度计算的需求,传统CPU俨然已无法胜任。2007年英伟达推出可编程通用计算平台CUDA框架,大量的科研人员和开发者将大量算法进行改写,从而获得几十至几千倍的加速效果。在机器学习的趋势来临后,GPU更是成为各类工具、算法、框架的基础底层设施之一。
2021年云栖大会,阿里云函数计算正式推出基于Turing架构的GPU实例,使得Serverless开发者可以将AI训练与推理的业务负载下沉到GPU硬件加速,从而加快模型训练、推理服务的效率。
异步任务
函数计算提供异步任务的分发、执行和观测的全栈能力,使得您只需要专注于任务处理逻辑的编写,创建任务处理函数,然后提交任务。函数计算不但提供异步任务日志、指标以及各个处理阶段耗时统计等丰富的可观测能力,也提供实例自动弹性伸缩、任务去重、指定任务终止以及批量任务暂停、恢复和删除等功能。更多信息,请参见异步任务。
应用场景
在面向非实时、偏离线的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 |
基于函数计算的GPU实例,运行AI准实时任务、AI离线任务等。 |
Custom Container |
GPU实例 |
HTTP函数 |
async-callback-succ-func |
任务执行成功后的目标回调函数。 |
Python 3 |
弹性实例 |
事件函数 |
async-callback-fail-func |
任务执行失败后的目标回调函数。 |
Python 3 |
弹性实例 |
事件函数 |
实现原理简单概括如下图。

步骤一:部署成功回调函数
- 初始化项目。
s init devsapp/start-fc-event-python3 -d async-succ-callback
创建的项目目录如下所示。
├── async-succ-callback
│ ├── code
│ │ └── index.py
│ └── s.yaml
- 进入项目所在目录。
- 按照实际情况修改目录文件中的参数配置。
- 编辑
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 # 建议配置,用于查看请求日志,需要在SLS日志服务中提前创建相应的project
logstore: tgpu-logstore-sh # 建议配置,用于查看请求日志,需要在SLS日志服务中提前创建相应的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'
- 部署代码至函数计算。
- 本地调用调试函数。
调用完成后,返回结果hello async callback succ
。
步骤二:部署失败回调函数
- 初始化项目。
s init devsapp/start-fc-event-python3 -d async-fail-callback
创建的项目目录如下所示。
├── async-fail-callback
│ ├── code
│ │ └── index.py
│ └── s.yaml
- 进入项目所在目录。
- 按照实际情况修改目录文件中的参数配置。
- 编辑
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 # 建议配置,用于查看请求日志,需要在SLS日志服务中提前创建相应的project
logstore: tgpu-logstore-sh # 建议配置,用于查看请求日志,需要在SLS日志服务中提前创建相应的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'
- 部署代码至函数计算。
- 本地调用调试函数。
调用完成后,返回结果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**** # 建议配置,用于查看请求日志,需要在SLS日志服务中提前创建相应的project
logstore: func**** # 建议配置,用于查看请求日志,需要在SLS日志服务中提前创建相应的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虚拟化规格
memorySize: 4096
gpuMemorySize: 2048
instanceType: g1
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()
- 部署代码至函数计算。
您可以在
函数计算控制台查看部署成功的GPU函数,以及该函数的异步配置。

- 本地调用调试函数。
调用完成后,返回结果Hello, World!
。
- 提交异步任务。
- 查看GPU函数的镜像加速准备状态。
建议镜像加速准备状态为
可用后,再发起异步任务,否则可能会引起链路超时等异常问题。

- 登录函数计算控制台,找到已创建的GPU函数
tgpu_basic_func
,在异步任务列表页签,单击提交任务。
执行完成后,任务状态为执行成功。
此时,您可以找到配置的成功回调函数
async-callback-succ-func
,依次选择页签,然后找到本次异步请求结果行,查看调用结果是否为调用成功。
