基于阿里云 Serverless 容器服务轻松部署企业级 AI 应用

2023年 7月 19日 24.5k 0

作者:元毅、坤仑

数禾科技 AI 模型服务基于云原生架构,为不同业务环节提供智能决策支持。随着业务的快速发展,摆在数禾面前的难题是支撑模型计算的底层应用资源无法根据请求量来调整机器资源支持运算能力。同时,随着模型在线推理服务数量的增加,数禾的模型服务也变得越来越庞大、臃肿,难以管理。这种状况不仅导致了资源浪费,还增加了维护和升级的成本。

为了解决这些“顽疾”,数禾科技采用阿里云 ASK 部署线上模型,无需 K8s 节点管理,根据实时流量动态使用 POD,资源成本节省 60%;通过 ASK Knative 服务,解决了数禾模型的灰度发布和多版本并存问题;得益于ASK 自动伸缩和缩容到 0 的优势,降低运行成本,大幅提升服务可用性。

目前,该系统已上线部署 500+AI 模型服务,每天能够提供上亿次查询决策服务,具备无限横向扩展的能力。同时,数禾科技 AI 模型服务支持自动调整容量,满足不同业务压力下的需求,从而保障业务的稳定运行。不仅如此,采用云原生架构方案,平均部署周期由之前的1天缩短至 0.5天,大幅提升了研发迭代效率,从而加速商业化应用的进程,为金融业务提供新的增长动力。

关于 Serverless Kubernetes(ASK)

Kubernetes(K8s)作为一个开源容器编排系统,被广泛运用于云原生应用的开发与管理。其优势在于降低运维成本,提高运维效率,形成了以 K8s 为核心的云原生生态。然而使用 K8s 常常需要用户面对的问题较多,例如资源规划、容量规划、Node 与 Pod 的亲和关系、容器网络规划、节点生命周期管理、操作系统版本、容器运行时版本兼容性等,这些问题显然不是用户所希望关心的,用户期望做的事情是专注在自身的业务逻辑,尽可能不关心这些基础设施。Serverless 的核心理念在于让开发者更聚焦业务逻辑,减少对基础设施的关注。因此我们将 K8s 复杂性下沉,提供 Serverless Kubernetes 的产品能力。

image

那么 Serverless Kubernetes 有哪些优势呢?主要包括以下三个方面:免运维、自动弹性、按需付费。

首先,Serverless Kubernetes 组件全托管免运维,支持自动升级 k8s 版本。其次,该产品具有极致弹性能力。可以根据业务需求,自动弹性、秒级扩容,从而在满足业务增长时自动容量规划。最后,使用 Serverless Kubernetes 的用户,只需根据实际使用量按需计费。除此之外,ASK 还提供了新增的 U 实例规格支持,统一支持多款处理器,相比上一代主售实例降价高达 40%。

image

为了让更多用户体验最佳实践,我们特地将其打造成了一个体验场景,配合热门开源的 AI 项目 Stable Diffusion,用户可以通过真实的云上环境,轻松体验容器化部署具备企业级弹性能力的 AI 模型。

在 ASK 中部署 Stable Diffusion

随着生成型 AI 技术的能力提升,越来越多的注意力放在了通过 AI 模型提升研发效率上。作为 AIGC(AI Generated Content)领域的知名项目 Stable Diffusion,可以帮助用户快速、准确地生成想要的场景及图片。不过当前直接在 K8s 使用 Stable Diffusion 面临如下问题:

  • 单个 Pod 处理请求的吞吐率有限,如果多个请求转发到同一个 Pod,会导致服务端过载异常,因此需要精准的控制单个 Pod 请求并发处理数。
  • GPU 资源很珍贵,期望做到按需使用资源,在业务低谷及时释放 GPU 资源

基于上面两个问题,我们提供 ASK + Knative 解决方案,可以做到基于并发精准弹性,缩容到 0,资源按需使用,打造生产可用的 Stable Diffusion 服务。

方案

这里我们在 ASK 中提供 Knative + MSE 方式解决上述问题:

  • 基于 MSE 网关,扩展 Knative 弹性插件机制,实现基于并发数精准弹性
  • 支持缩容到 0, 按需使用自动弹性
  • 多版本管理、镜像加速,助力模型快速发布迭代

image

实践

接下来我们介绍如何在 ASK 中部署 Stable Diffusion 服务。

服务部署

  • 在集群列表页面,单击目标集群 knative-sd-demo 进入集群信息页面,然后在左侧导航栏,选择应用>Knative。

  • 在 Knative 页面,单击服务管理页签,然后单击使用模板创建。

  • 在命名空间下拉列表中,选择 default,在示例模板下拉列表中,选择 Resouce-Knative Service,将以下消息处理服务的 YAML 示例粘贴至模板,然后单击创建。

  • 默认创建一个名为 knative-sd-demo 的服务。

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: knative-sd-demo
      annotations:
        serving.knative.dev.alibabacloud/affinity: "cookie"
        serving.knative.dev.alibabacloud/cookie-name: "sd"
        serving.knative.dev.alibabacloud/cookie-timeout: "1800"
    spec:
      template:
        metadata:
          annotations:
            autoscaling.knative.dev/class: mpa.autoscaling.knative.dev
            autoscaling.knative.dev/maxScale: '10'
            autoscaling.knative.dev/targetUtilizationPercentage: "100"
            k8s.aliyun.com/eci-use-specs: ecs.gn5-c4g1.xlarge,ecs.gn5i-c8g1.2xlarge,ecs.gn5-c8g1.2xlarge  
        spec:
          containerConcurrency: 1
          containers:
          - args:
            - --listen
            - --skip-torch-cuda-test
            - --api
            command:
            - python3
            - launch.py
            image: yunqi-registry.cn-shanghai.cr.aliyuncs.com/lab/stable-diffusion@sha256:64999ff1aba706f65a2234d861d46318f7d58e2790b31ace0d567a96e65b617c
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 7860
              name: http1
              protocol: TCP
            name: stable-diffusion
            readinessProbe:
              tcpSocket:
                port: 7860
              initialDelaySeconds: 5
              periodSeconds: 1
              failureThreshold: 3
    

    参数说明:

    • 支持 Cookie 会话保持:serving.knative.dev.alibabacloud/affinity
    • 支持多种 GPU 规格配置:k8s.aliyun.com/eci-use-specs
    • 支持并发数设置:containerConcurrency

    image

  • 在服务管理页签,刷新页面后,当 knative-sd-demo 的状态变为成功时,表明 SD 服务部署成功。
  • image.png

    服务访问并进行压测

    部署压测服务 portal-server,用于 Stable Diffusion 效果展示并发起压测。

  • 在 Knative 页面,单击服务管理页签,然后单击使用模板创建。

  • 在命名空间下拉列表中,选择 default,在示例模板下拉列表中,选择自定义,将以下 portal-server 压测服务的 YAML 示例粘贴至模板,然后单击创建。

  • ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: portal-server
      name: portal-server
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: portal-server
      template:
        metadata:
          labels:
            app: portal-server
        spec:
          serviceAccountName: portal-server
          containers:
            - name: portal-server
              image: registry-vpc.cn-beijing.aliyuncs.com/acs/sd-yunqi-server:v1.0.2
              imagePullPolicy: IfNotPresent
              env:
                - name: MAX_CONCURRENT_REQUESTS
                  value: "5"
                - name: POD_NAMESPACE
                  value: "default"
              readinessProbe:
                failureThreshold: 3
                periodSeconds: 1
                successThreshold: 1
                tcpSocket:
                  port: 8080
                timeoutSeconds: 1
    ---
    apiVersion: v1
    kind: Service
    metadata:
      annotations:
        service.beta.kubernetes.io/alibaba-cloud-loadbalancer-address-type: internet
        service.beta.kubernetes.io/alibaba-cloud-loadbalancer-instance-charge-type: PayByCLCU
      name: portal-server
    spec:
      externalTrafficPolicy: Local
      ports:
        - name: http-80
          port: 80
          protocol: TCP
          targetPort: 8080
        - name: http-8888
          port: 8888
          protocol: TCP
          targetPort: 8888
      selector:
        app: portal-server
      type: LoadBalancer
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: pod-list-cluster-role
    rules:
      - apiGroups: [""]
        resources: ["pods"]
        verbs: ["list"]
      - apiGroups: ["networking.k8s.io"]
        resources: ["ingresses"]
        verbs: ["get"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: pod-list-cluster-role-binding
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: pod-list-cluster-role
    subjects:
      - kind: ServiceAccount
        name: portal-server
        namespace: default
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: portal-server
      namespace: default
    
  • 选择网络>服务, 在服务页面,查看 portal-server 压测服务,获取访问 IP 为 123.56.XX.XX。
  • image

  • 在浏览器中输入 123.56.XX.XX,然后在该页面单击 Stable Diffusion 跳转至 Stable Diffusion 访问页面。
  • image

    a. Stable Diffusion 访问页面如下所示。例如,在如下文本框中输入 cat,然后单击 Generate,将展示与输入有关的图片信息。

    image

    b. 在压测访问页面,设置并发数为 5,总请求数为 20,然后单击开始压测,查看压测的结果。

    image

    压测期间,可以看到创建了 5 个 Pod,并且每个请求均会生成一个图片,图片生成后将展示到页面中。

    查看可观测大盘

    此外在 Knative 提供了开箱即用的可观测能力,在 Knative 页面,单击监控大盘页签。即可看到 Stable Diffusion 服务的请求量(Request Volume)、请求成功率(Success Rate)、4xx(客户端错误)、5xx(服务器端错误)和Pod扩缩容趋势的监控数据。

    image

    在 Response Time 区域,查看 Knative 的响应延迟数据,包括 P50、P90、P95 和 P99。

    image

    小结

    基于 ASK Knative 并发精准弹性,缩容到 0,多版本管理等功能,可以轻松部署企业级 AI 服务。当前已在阿里云云起实验提供《基于 ASK 轻松部署企业级 Stable Diffusion》动手实践,欢迎体验:

    developer.aliyun.com/adc/scenari…

    相关文章

    KubeSphere 部署向量数据库 Milvus 实战指南
    探索 Kubernetes 持久化存储之 Longhorn 初窥门径
    征服 Docker 镜像访问限制!KubeSphere v3.4.1 成功部署全攻略
    那些年在 Terraform 上吃到的糖和踩过的坑
    无需 Kubernetes 测试 Kubernetes 网络实现
    Kubernetes v1.31 中的移除和主要变更

    发布评论