Serverless 架构下的 AI 应用开发
Posted 阿里云云原生
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Serverless 架构下的 AI 应用开发相关的知识,希望对你有一定的参考价值。
作者:阿里云云原生
本篇内容连载自《Serverless 架构下的 AI 应用开发:入门、实战与性能优化》。
Serverless 架构与 CI/CD 工具的结合
CI/CD 是一种通过在应用开发阶段引入自动化流程以频繁向客户交付应用的方法。 如图所示,CI/CD 的核心概念是持续集成、持续交付和持续部署。
作为一个面向开发和运营团队的解决方案,CI/CD 主要针对集成新代码时所引发的问题。具体而言,CI/CD 可以让持续自动化和持续监控贯穿于应用的整个生命周期(从集成、测试阶段到交付和部署阶段)。这些关联的事务通常被统称为“CI/CD 管道”,由开发和运维团队以敏捷方式协同支持。
CI/CD 的概念与内容简图
在 Serverless 架构下,通常会有很多函数构成一个完整的功能或服务,这种比较细粒度的功能往往会给后期项目维护带来极大的不便,包括但不限于函数管理、项目的构建、发布层面等的不便。此时在 Serverless 架构中,CI/CD 就显得尤为重要。更加科学、安全的持续集成和部署过程不仅会让整体的业务流程更加规范,也会在一定程度上降低人为操作、手工集成部署所产生错误的概率,同时也会大规模减轻运维人员的工作负担。
如果想要通过 CI/CD 平台,科学且方便地进行 Serverless 应用的持续集成、交付和部署,通常情况下我们需要借助相应的开发者工具,例如 Serverless Framework、Serverless Devs 等。Serverless开发者工具配置到 CI/CD 平台的流程可以简化为下图。
Serverless开发者工具配置到 CI/CD 平台的流程
与 GitHub Action 的集成
在 GitHub Action 的 Yaml 文件中,增加 Serverless Devs 相关下载、配置以及命令执行相关内容。例如,在 GitHub 仓库中创建文件.github/workflows/publish.yml,文件内容如下:
name: Serverless Devs Project CI/CD
on:
push:
branches: [ master ]
jobs:
serverless-devs-cd:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 12
registry-url: https://registry.npmjs.org/
- run: npm install
- run: npm install -g @serverless-devs/s
- run: s config add --AccountID $secrets.AccountID --AccessKeyID
$secrets.AccessKeyID --AccessKeySecret $secrets.AccessKeySecret -a default
- run: s deploy
与 GitHub Action 集成主要包括以下几部分内容:
- 通过 NPM 安装最新版本的 Serverless Devs 开发者工具:
run: npm install -g @serverless-devs/s
- 通过 config 命令进行密钥等信息的配置:
run: s config add --AccountID $secrets.AccountID --AccessKeyID $secrets.
AccessKeyID --AccessKeySecret $secrets.AccessKeySecret -a default
- 执行某些命令,例如通过 deploy 命令进行项目的部署,或者通过 build 等命令进行项目的构建:
run: s deploy
关于密钥的配置:密钥信息是通过$secrets.*获取的,此时,需要将所需要的密钥和对应的 Key 配置到 GitHub Secrets 中,例如在上面的案例中,需要 AccountID、AccessKeyID、AccessKeySecret 三个密钥的 Key 就可以配置相关内容。找到 GitHub Secrets 页面,如图所示。
GitHub Secrets 页面
创建和配置密钥信息,如图所示。
创建和配置密钥信息页面
此处配置了 3 对密钥,如图所示。
GitHub 仓库配置密钥结果页面
与 Gitee Go 的集成
在开启 Gitee Go 的服务之后,在流水线的 Yaml 文件中,可以增加 Serverless Devs 的相关下载、配置以及命令执行相关内容。
例如,在 GitHub 仓库中创建文件.github/workflows/publish.yml,文件内容如下:
name: serverless-devs
displayName: 'Serverless Devs Project CI/CD'
triggers: #流水线触发器配置
push:
- matchType: PRECISE
branch: master
commitMessage: ''
stages:
- stage:
name: deploy-stage
displayName: 'Deploy Stage'
failFast: false
steps: #构建步骤配置
- step: npmbuild@1 #采用NPM编译环境
name: deploy-step
displayName: 'Deploy Step'
inputs: #构建输入参数设定
nodeVersion: 14.15 #指定 node 环境版本为 14.15
goals: | #安装依赖,配置相关主题、部署参数并发布部署
node -v
npm -v
npm install -g @serverless-devs/s
s co nfig add --AccountID $ACCOUNTID --AccessKeyID $ACCESSKEYID --AccessKeySecret $ACCESSKEYSECRET -a default
s deploy
与 GitHub Action 集成的流程类似,与 Gitee Go 集成主要包括以下几部分内容。
- 通过 NPM 安装最新版本的 Serverless Devs 开发者工具:
npm install -g @serverless-devs/s
- 通过 config 命令进行密钥等信息的配置:
s config add --AccountID $ACCOUNTID --AccessKeyID $ACCESSKEYID --AccessKeySecret
$ACCESSKEYSECRET -a default
- 执行某些命令,例如通过 deploy 命令进行项目的部署,或者通过 build 等命令进行项目的构建:
s deploy
关于密钥的配置:密钥信息是通过$*获取的,此时将所需的密钥和对应的 Key 配置到 Gitee 的环境变量管理中,例如在上面的案例中,需要 AccountID、AccessKeyID、AccessKeySecret 三个密钥的 Key 就可以配置相关内容。
找到 Gitee 的环境变量管理页面,如图所示。
Gitee 的环境变量管理页面
创建和配置密钥信息,如图所示。
创建和配置密钥信息页面
此处配置了 3 对密钥,如图所示。
Gitee 仓库完成密钥配置页面
与 Jenkins 的集成
在将 Serverless Devs 集成到 Jenkins 之前,需要先基于 Jenkins 官网安装并运行 Jenkins。本地启动 Jenkins,通过浏览器进入并配置完成基础设置,之后新增凭据设置,如下图所示。
浏览器链接:
http://localhost:8080
Jenkins 凭据设置页面
可以根据需要,增加密钥信息。以阿里云为例,新增 3 个全局凭据:
- jenkins-alicloud-account-id : 阿里云 accountId
- jenkins-alicloud-access-key-id : 阿里云 accessKeyId
- jenkins-alicloud-access-key-secret : 阿里云 accessKeySecret
此时,可以对自身的 Serverless Devs 项目进行完善。创建文件 Jenkinsfile:
pipeline
agent
docker
image 'maven:3.3-jdk-8'
environment
ALICLOUD_ACCESS = 'default'
ALICLOUD_ACCOUNT_ID = credentials('jenkins-alicloud-account-id')
ALICLOUD_ACCESS_KEY_ID = credentials('jenkins-alicloud-access-key-id')
ALICLOUD_ACCESS_KEY_SECRET = credentials('jenkins-alicloud-access-key-secret')
stages
stage('Setup')
steps
sh 'scripts/setup.sh'
与 Jenkins 集成主要内容包括以下两部分:
- environment 部分:主要是根据上面步骤配置的密钥信息,进行密钥的处理。
- stages 部分:包括 sh 'scripts/setup.sh’部分,即运行 scripts/setup.sh 文件,进行相关内容的准备和配置。
准备 scripts/setup.sh 文件,只需要在项目下创建该文件即可。
#!/usr/bin/env bash
echo $(pwd)
curl -o- -L http://cli.so/install.sh | bash
source ~/.bashrc
echo $ALICLOUD_ACCOUNT_ID
s config add --AccountID $ALICLOUD_ACCOUNT_ID --AccessKeyID $ALICLOUD_ACCESS_KEY_
ID --AccessKeySecret $ALICLOUD_ACCESS_KEY_SECRET -a $ALICLOUD_ACCESS
(cd code && mvn package && echo $(pwd))
s deploy -y --use-local --access $ALICLOUD_ACCESS
在该文件中,主要包括以下几个部分:
- 安装最新版本的 Serverless Devs 开发者工具:
curl -o- -L http://cli.so/install.sh | bash
- 通过 config 命令进行密钥等信息的配置:
s config add --AccountID $ALICLOUD_ACCOUNT_ID --AccessKeyID $ALICLOUD_ACCESS_
KEY_ID --AccessKeySecret $ALICLOUD_ACCESS_KEY_SECRET -a $ALICLOUD_ACCESS
- 执行某些命令,例如通过 deploy 命令进行项目的部署,或者通过 build 等命令进行项目构建:
s deploy -y --use-local --access $ALICLOUD_ACCESS
完成密钥配置之后,可以创建一个 Jenkins 流水线。该流水线的源是目标 GitHub地址。接下来,就可以开始运行 Jenkins 流水线,运行结束后可得到相关的结果。
与云效的集成
在云效中,可以直接选择 Serverless Devs 开发者工具,并在自定义命令中输入以下内容:
# input your command here
npm install -g @serverless-devs/s
s config add --AccountID $ACCOUNTID --AccessKeyID $ACCESSKEYID --AccessKeySecret
$ACCESSKEYSECRET -a default
s deploy
与 GitHub Action、Gitee Go 以及 Jenkins 的配置类似,与云效集成同样主要包括 3 部分。
- 安装最新版本的 Serverless Devs 开发者工具:
npm install -g @serverless-devs/s
- 通过 config 命令进行密钥等信息的配置:
s config add --AccountID $ACCOUNTID --AccessKeyID
$ACCESSKEYID --AccessKeySecret
- 执行某些命令,例如通过 deploy 命令进行项目的部署,或者通过 build 等命令进行项目的构建:
s deploy -y
效果如图所示。
云效命令配置页面
由于在命令中引用了 3 个重要的环境变量:ACCOUNTID、 ACCESSKEYID、 ACCESSKEYSECRET,因此还需要在环境变量中增加图所示的类似内容。
环境变量配置页面
CI/CD 平台集成
总结通过上面几个案例不难发现,在做自动化发布时,最核心的 3 个流程如下。
- 下载工具:命令为 npm install -g @Serverless-devs/s。
- 配置密钥:命令为s config add --AccountID $ACCOUNTID --AccessKeyID $ACCESSKEYID --AccessKeySecret $ACCESSKEYSECRET -a default。
- 项目部署:命令为s deploy。
虽然只是以 GitHub Action、Gitee Go、Jenkins、云效几个工具作为案例,实际上无论哪个工具与 CI/CD 平台集成,上述 3 个核心流程都不会发生本质变化。另外,上面所列举的流程更多是在做自动化发布,在发布之前有时还需要进行一些测试和重新构建,以便根据具体的实际需要进行适当的完善。
综上所述,如果想非常简单、快速、科学地完成 Serverless 应用的 CI/CD 建设,一个完善的开发者工具是必不可少的。
Serverless Devs 是一款多云开发者工具。我们可以通过该工具非常简单、快速、方便地部署 AWS、阿里云、腾讯云等多个云厂商的函数计算等相关服务。同时,Serverless Devs 也是一个开源项目,便于用户随时随地贡献组件、应用。
Serverless 应用的可观测性
Serverless 应用的可观测性被很多用户所关注。可观测性是通过外部表现判断系统内部状态的方式。在应用开发中,可观测性有助于判断系统内部的健康状况,在系统出现问题时,帮助定位问题、排查问题、分析问题;在系统平稳运行时,帮助评估风险,预测可能出现的问题。
在 Serverless 应用开发中,如果函数的并发度持续升高,很可能是业务推广团队业务规模迅速扩张。为了避免达到并发度限制而触发流控,开发者就需要提前提高并发度。
以阿里云函数计算为例,阿里云函数计算在可观测性层面提供了多种维度,包括 Logging、Metrics 以及 Tracing 等。如图所示:
函数计算可观测性整体图表
在控制台监控中心,我们可以查看整体的 Metrics、服务级 Metrics 以及每个函数的 Metrics,还可以看到当前函数计算的请求记录。
函数计算的请求记录
根据不同的请求记录,我们还可以查看函数计算的详细信息。
函数计算的请求详情
除了在控制台的监控中心查看函数的日志等信息,我们还可以在函数详情页面看到函数计算的详细日志信息,
函数计算的日志信息
还可以看到 Tracing 相关信息,如下图所示。
函数计算的 Tracing 相关信息
阿里云、蚂蚁集团的 4 位专家刘宇、田初东、卢萌凯、王仁达(排名不分先后)系统梳理阿里在 Serverless 架构下的 AI 经验,联袂推出新书 《Serverless 架构下的 AI 应用开发:入门、实战与性能优化》 。
本书是关于 Serverless 架构下机器学习实战的技术书,我们希望通过简单明了的语言、真实的案例,以及开放的源代码,为读者介绍 Serverless 架构与机器学习相关的基础知识,帮助读者在 Serverless 架构下开发、上线机器学习项目。
Serverless架构下的AI应用
近年来,Serverless架构逐渐被更多的开发者所认识、接受,逐渐被应用到了更多领域,其中包括如今非常热门的机器学习领域。
与其他领域不同的是,在Serverless架构上进行人工智能相关项目的应用实践具有极大的特殊性。
·人工智能领域的模型体积普遍较大,一般情况下模型加载需要比较长的时间,这就导致在Serverless架构上,机器学习项目的冷启动问题更为严重。
·目前来看,普遍的Serverless架构或者说大部分公有云FaaS产品很少支持GPU实例(阿里云函数计算也是在2021年的云栖大会才发布相关的能力支持),这给在Serverless架构上部署人工智能项目造成不小阻碍。
·人工智能项目通常会有比较多的依赖,而这些依赖等相关内容所占用的空间相对来说比较大。就目前来看,各个公有云FaaS产品所支持的代码包大小通常为50MB~200MB,实例内所拥有的整体空间大小为500MB,这就导致如果想要将一个稍具规模的人工智能项目部署到线上,就需要NAS等额外的产品进行配合,在一定程度上大大增加了项目的部署难度、调试难度等。
·由于Serverless架构通常是无状态的,所以在Serverless架构上进行AI模型的更新迭代相比传统的云主机架构要复杂,更困难。
综上所述,若想在Serverless架构上更好地进行机器学习相关项目的实践,就需要从开发、部署、冷启动优化以及GPU实例的融入等多个维度进行研究与探索。
1 项目的开发与部署
在基于Serverless架构进行机器学习项目实战时,最基础的就是项目开发和部署阶段的相关工作,其中包括以下几个重要内容。
·业务逻辑与模型拆离:由于机器学习算法通常需要比较多的资源,包括GPU资源、内存资源等,所以我们在Serverless架构上部署机器学习项目时,为了保证性能与成本的平衡,会将业务逻辑与模型的训练和推理部分分别部署。这可能会增加一个或多个函数,但可进一步实现降本提效。
·模型加载与实例复用:由于Serverless架构是无状态的,因此每次请求时相对应的方法会被重复调用。这就导致方法内的模型加载逻辑会在每次请求时被触发,严重影响业务的整体性能。我们可以利用实例复用特性,在初始化实例时进行相关模型加载,以最大限度地降低模型频繁加载带来的性能瓶颈。
·模型对象的释放与清理:尽管Serverless架构是无状态的,但是这并不等于前后两次执行毫无关联。在实例复用的前提下,前一次执行极有可能对后一次执行产生影响,尤其在人工智能项目中,某些对象、缓存资源复用时往往会受到前一次的干扰,进而影响本次推理的效果,所以某些对象或资源在使用过后需要被释放或清理。
·开发者工具加持机器学习项目:由于在Serverless架构下,云厂商所提供的实例环境与开发者的开发环境往往存在着较大差异,很多项目在本地进行开发、调试并部署到Serverless架构后无法找到对应的依赖或者安装包等。这种情况在Python项目中,尤其是涉及科学计算、机器学习等相关领域时,极为常见。所以与Serverless开发者工具的紧密结合,对机器学习项目的开发和部署有巨大帮助。
2 冷启动优化
即使不针对机器学习项目,不针对人工智能领域,Serverless架构下的冷启动问题依旧是值得关注和亟待解决的。这不仅需要云厂商侧的努力,还需要开发者侧的优化。
·减小交付物的体积:在Serverless架构的整个冷启动过程中,代码包的拉取、解压等流程相对来说是不可控的部分,因为代码包和容器镜像的体积决定了代码包拉取的效率,而压缩包中的文件数量,则可能决定冷启动效率。所以,如何尽可能地减小代码包的大小,进一步提升性能就成为非常重要的事情,其中包括减少非必要依赖的引用,引入相对轻量化的打包工具等。
·实例复用与单实例多并发:从实例角度出发,实例的复用以及处理好部分资源的初始化逻辑,在一定程度上可以有效地降低冷启动带来的影响;同时通过部分厂商提供的单实例多并发能力,在一定程度上可以有效地降低频繁加载模型而带来的冷启动影响。
·预留实例与性能提升:即使从复用、单实例多并发以及减小代码包角度出发,开发者可以进行冷启动的优化,但是并不能真正消除冷启动。尤其在突然高并发条件下,冷启动带来的危害显而易见。云厂商提供的预留实例功能,在一定程度上可以降低冷启动带来的危害。
·加载代码与挂载资源:很多时候,机器学习项目所需要依赖的资源非常多,所需要的模型文件也比较大,所以通过挂载硬盘等方式进行模型文件的加载、依赖的引入比单纯通过压缩包的下载、解压及装载效果好。但是,依赖与模型等文件通过硬盘挂载等手段引入项目在一定程度上会让项目丧失一些特性,例如版本控制与灰度等能力。
3 训练与推理性能优化
在Serverless架构上的机器学习项目包括两类:一类是在Serverless架构上进行机器学习项目的训练,另一类是在Serverless架构上进行机器学习项目的推理。无论训练还是推理,其所需要的资源相对来说是比较多的。此时,我们需要根据云厂商的实际情况进行资源选型。
·在具备GPU资源的前提下,可以优先选择Serverless的GPU实例,通过GPU实例进行项目的训练和推理都是相对科学与常见的。
·在不具备GPU资源的前提下,可以通过CPU模式进行项目的训练和推理,此时可以考虑选择性能实例进行相关的业务逻辑实现,以尽可能地保证整体性能和效率。
·在函数计算平台不具备GPU资源与性能实例的前提下,可以通过其他Serverless化的服务进行相关的训练和推理,而不需要过于固执地依赖函数计算平台实现相对应的业务逻辑。
4 模型更新迭代方案
在Serverless架构上进行机器学习项目的部署和应用时,我们会遇到模型的更新迭代,需完成以下两个层面的操作。
1)手动更新迭代:当训练集有了比较大的完善和改进,反馈机制有了比较大规模的反馈后,手动对模型文件进行更新,并通过开发者工具将模型手动部署到对象存储或者挂载硬盘中,以便后续使用。
2)自动更新迭代:当训练集的规模增加或变更且反馈机制反馈多次之后,系统将会触发某些函数进行模型的更新迭代。此时值得注意的是:
·如果触发模型更新迭代的阈值比较容易达到,可能会瞬时触发多个实例进行模型的更新迭代,极有可能造成模型时序错误。此时,我们可以考虑对模型更新迭代的函数资源进行使用量的配置,例如单个时间段内,实例的上限数量为1,超过限制的部分需要按照时序排队等待等。
·模型文件更新迭代时需要消除对模型读取和加载的影响。由于Serverless架构是无状态的,所以极有可能在模型文件更新迭代的过程中出现较为大规模的模型加载,这样极有可能出现模型文件系统错乱以及模型加载失败等问题。此时,我们可以借助一些云产品,例如对象存储等实现相对应的模型文件更新迭代。
尽管Serverless架构如今已经被应用到很多行业和领域,但是在人工智能领域,尤其是机器学习、深度学习领域,Serverless架构由于其天然分布式、无状态等特点,依旧面临着很大的挑战。在机器学习场景下,由于模型文件相对庞大,依赖的资源相对较多,Serverless架构上的机器学习困难重重。但是随着时间的推移,从开发技术升级的角度来看,Serverless架构也在不断完善,包括云厂商提供的预留实例、资源池化、实例复用服务,以及引入的GPU实例、性能实例等。若想Serverless架构上的机器学习项目有更好的应用效果,还需要从多个维度进行分析和优化。
以上是关于Serverless 架构下的 AI 应用开发的主要内容,如果未能解决你的问题,请参考以下文章
Serverless 架构下的 AI 应用开发:入门实战与性能优化