假期充电,用阿里云 Serverless K8s + AIGC 搭建私人代码助理

本文涉及的产品
云原生网关 MSE Higress,422元/月
应用实时监控服务-可观测链路OpenTelemetry版,每月50GB免费额度
应用实时监控服务-应用监控,每月50GB免费额度
简介: 假期充电,用阿里云 Serverless K8s + AIGC 搭建私人代码助理

作者:子白、冬岛


AI 技术正在引领科技创新浪潮,随着 ChatGPT 和 Midjourney 的走红,AIGC 技术正在世界范围内掀起一股 AI 技术浪潮。开源领域也涌现了许多类似模型,如 FastGPT、Moss、Stable Diffusion 等。这些模型展现出的惊人效果吸引企业和开发者们投身其中,但是复杂繁琐的部署方式成为了拦路虎。阿里云 ASK 提供 Serverless 化的容器服务,用户无需关心资源及环境配置,可以帮助开发者们零门槛快速部署 AI 模型。本文以开源的 FastChat 为例,详细展示如何在 ASK 中快速搭建一个私人代码助理。目前,ASK 已加入阿里云免费试用计划,为开发者、企业提供一定额度的试用资源。如对 ASK 感兴趣,欢迎大家通过点击文末的“此处” 访问并领取。



效果预览


Cursor + GPT-4 的代码生成是不是觉得很智能,我们通过 FastChat + VSCode 插件也能做到一样的效果!


  • 快速生成一个 Golang  Hello World

地址:https://yuque.antfin.com/images/lark/0/2023/gif/11431/1682574183392-11e16131-3dae-4969-a0d1-79a0a9eefb01.gif


  • 快速生成一个 Kubernetes  Deployment

地址:https://yuque.antfin.com/images/lark/0/2023/gif/11431/1682574192825-7a1d3c76-025d-45db-bea1-4ca5dd885520.gif


背景介绍


ASK(Alibaba Serverless Kubernetes)是阿里云容器服务团队提供的一款面向 Serverless 场景的容器产品。用户可以使用 Kubernetes API 直接创建 Workload,免去节点运维烦恼。ASK 作为容器 Serverless 平台,具有免运维、弹性扩容、兼容 K8s 社区、强隔离四大特性。



大规模 AI 应用训练和部署主要面临以下挑战。


  • GPU 资源受限且训练成本较高

大规模 AI 应用在训练及推理时都需要使用 GPU,但是很多开发者缺少 GPU 资源。单独购买 GPU 卡,或者购买 ECS 实例都需要较高成本。

  • 资源异构

并行训练时需要大量的 GPU 资源,这些 GPU 往往是不同系列的。不同 GPU 支持的 CUDA 版本不同,且跟内核版本、nvidia-container-cli 版本相互绑定,开发者需要关注底层资源,为 AI 应用开发增加了许多难度。

  • 镜像加载慢

AI 类应用镜像经常有几十 GB,下载往往需要几十分钟甚至数小时。


针对上述问题,ASK 提供了完美的解决方案。在ASK 中可以通过 Kubernetes Workload 十分方便的使用 GPU 资源,无需其前置准备使用,用完即可立即释放,使用成本低。ASK 屏蔽了底层资源,用户无需关心 GPU、CUDA 版本等等的依赖问题,只需关心 AI 应用的自身逻辑即可。同时,ASK 默认就提供了镜像缓存能力,当 Pod 第 2 次创建时可以秒级启动。


部署流程


1. 前提条件


  • 已创建 ASK 集群。具体操作,请参见创建 ASK 集群[1]
  • 下载 llama-7b 模型并上传到 OSS 。具体操作,请参见本文附录部分。


2. 使用 Kubectl 创建


替换 yaml 文件中变量

${your-ak} 您的 AK

${your-sk} 您的 SK

${oss-endpoint-url} OSS 的 enpoint

${llama-oss-path} 替换为存放 llama-7b 模型的地址(路径末尾不需要/),如 oss://xxxx/llama-7b-hf


apiVersion: v1
kind: Secret
metadata:
  name: oss-secret
type: Opaque
stringData:
  .ossutilconfig: |
    [Credentials]
    language=ch
    accessKeyID=${your-ak}
    accessKeySecret=${your-sk}
    endpoint=${oss-endpoint-url}
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: fastchat
  name: fastchat
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: fastchat
  strategy:
    rollingUpdate:
      maxSurge: 100%
      maxUnavailable: 100%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: fastchat
        alibabacloud.com/eci: "true" 
      annotations:
        k8s.aliyun.com/eci-use-specs: ecs.gn6e-c12g1.3xlarge
    spec:
      volumes:
      - name: data
        emptyDir: {}
      - name: oss-volume
        secret:
          secretName: oss-secret
      dnsPolicy: Default
      initContainers:
      - name: llama-7b
        image: yunqi-registry.cn-shanghai.cr.aliyuncs.com/lab/ossutil:v1
        volumeMounts:
          - name: data
            mountPath: /data
          - name: oss-volume
            mountPath: /root/
            readOnly: true
        command: 
        - sh
        - -c
        - ossutil cp -r ${llama-oss-path} /data/
        resources:
          limits:
            ephemeral-storage: 50Gi
      containers:
      - command:
        - sh
        - -c 
        - "/root/webui.sh"
        image: yunqi-registry.cn-shanghai.cr.aliyuncs.com/lab/fastchat:v1.0.0
        imagePullPolicy: IfNotPresent
        name: fastchat
        ports:
        - containerPort: 7860
          protocol: TCP
        - containerPort: 8000
          protocol: TCP
        readinessProbe:
          failureThreshold: 3
          initialDelaySeconds: 5
          periodSeconds: 10
          successThreshold: 1
          tcpSocket:
            port: 7860
          timeoutSeconds: 1
        resources:
          requests:
            cpu: "4"
            memory: 8Gi
          limits:
            nvidia.com/gpu: 1
            ephemeral-storage: 100Gi
        volumeMounts:
        - mountPath: /data
          name: data
---
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: fastchat
  namespace: default
spec:
  externalTrafficPolicy: Local
  ports:
  - port: 7860
    protocol: TCP
    targetPort: 7860
    name: web
  - port: 8000
    protocol: TCP
    targetPort: 8000
    name: api
  selector:
    app: fastchat
  type: LoadBalancer


3. 等待 FastChat Ready


等待 pod ready 后,在浏览器中访问 http://${externa-ip}:7860

📍启动后需要下载 vicuna-7b 模型,模型大小约 13GB

下载模型时间大概耗时约 20 分钟左右,如果提前做好磁盘快照,通过磁盘快照创建磁盘并挂载到 pod,就是秒级生效


kubectl get po |grep fastchat
# NAME                        READY   STATUS    RESTARTS   AGE
# fastchat-69ff78cf46-tpbvp   1/1     Running   0          20m
kubectl get svc fastchat
# NAME       TYPE           CLUSTER-IP        EXTERNAL-IP    PORT(S)          AGE
# fastchat   LoadBalancer   192.168.230.108   xxx.xx.x.xxx   7860:31444/TCP   22m


效果展示


Case 1:通过控制台使用 FastChat


在浏览器中访问 http://${externa-ip}:7860,可以直接测试聊天功能。比如使用自然语言让 FastChat 写一段代码。


输入:基于 Nginx 镜像编写 Kubernetes Deployment Yaml 文件


FastChat 输出如下图所示。



Case 2:通过 API 使用 FastChat


FastChat API 监听在 8000 端口,如下所示,通过 curl 发起一个 API 调用,然后返回结果。


  • curl 命令


curl http://xxx:xxx:xxx:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "vicuna-7b-v1.1",
    "messages": [{"role": "user", "content": "golang 生成一个 hello world"}]
  }'


  • 输出结果


{"id":"3xqtJcXSLnBomSWocuLW2b","object":"chat.completion","created":1682574393,"choices":[{"index":0,"message":{"role":"assistant","content":"下面是使用 Go 语言生成 \"Hello, World!\" 的代码:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n    fmt.Println(\"Hello, World!\")\n}\n```\n运行该代码后,会输出 \"Hello, World!\"。"},"finish_reason":"stop"}],"usage":null}


Case 3: VSCode 插件


既然有了 API 接口,在 IDE 中怎么快速集成这个能力呢。你是不是想到了 Copilot、Cursor、Tabnine ,那咱们就通过 VSCode 插件集成一下 FastChat 看看吧。VSCode 插件几个核心文件:src/extension.ts、package.json 和 tsconfig.json


这三个文件的内容分别如下:


  • src/extension.ts


import * as vscode from 'vscode';
import axios from 'axios';
import { ExtensionContext, commands, window } from "vscode";
const editor = window.activeTextEditor
export function activate(context: vscode.ExtensionContext) {
    let fastchat = async () => {
        vscode.window.showInputBox({ prompt: '请输入代码提示语' }).then((inputValue) => {
            if (!inputValue) {
                return;
            }
            vscode.window.withProgress({
                location: vscode.ProgressLocation.Notification,
                title: '正在请求...',
                cancellable: false
            }, (progress, token) => {
                return axios.post('http://example.com:8000/v1/chat/completions', {
                    model: 'vicuna-7b-v1.1',
                    messages: [{ role: 'user', content: inputValue }]
                }, {
                    headers: {
                        'Content-Type': 'application/json'
                    }
                }).then((response) => {
                    // const content = JSON.stringify(response.data);
                    const content = response.data.choices[0].message.content;
                    console.log(response.data)
                    const regex = /```.*\n([\s\S]*?)```/
                    const matches = content.match(regex)
                    if (matches && matches.length > 1) {
                        editor?.edit(editBuilder => {
                            let position = editor.selection.active;
                            position && editBuilder.insert(position, matches[1].trim())
                        })
                    }
                }).catch((error) => {
                    console.log(error);
                });
            });
        });
    }
    let command = commands.registerCommand(
        "fastchat",
        fastchat
    )
    context.subscriptions.push(command)
}


  • package.json


{
    "name": "fastchat",
    "version": "1.0.0",
    "publisher": "yourname",
    "engines": {
        "vscode": "^1.0.0"
    },
    "categories": [
        "Other"
    ],
    "activationEvents": [
        "onCommand:fastchat"
    ],
    "main": "./dist/extension.js",
    "contributes": {
        "commands": [
            {
                "command": "fastchat",
                "title": "fastchat code generator"
            }
        ]
    },
    "devDependencies": {
        "@types/node": "^18.16.1",
        "@types/vscode": "^1.77.0",
        "axios": "^1.3.6",
        "typescript": "^5.0.4"
    }
}


  • tsconfig.json


{
    "compilerOptions": {
      "target": "ES2018",
      "module": "commonjs",
      "outDir": "./dist",
      "strict": true,
      "esModuleInterop": true,
      "resolveJsonModule": true,
      "declaration": true
    },
    "include": ["src/**/*"],
    "exclude": ["node_modules", "**/*.test.ts"]
  }


好,插件开发完咱们就看一下效果。


  • 快速生成一个 Golang  Hello World

地址:https://yuque.antfin.com/images/lark/0/2023/gif/11431/1682574183392-11e16131-3dae-4969-a0d1-79a0a9eefb01.gif


  • 快速生成一个 Kubernetes  Deployment

地址:https://yuque.antfin.com/images/lark/0/2023/gif/11431/1682574192825-7a1d3c76-025d-45db-bea1-4ca5dd885520.gif


总结


ASK 作为容器 Serverless 平台,具有免运维、弹性扩缩容、屏蔽异构资源、镜像加速等能力,非常适合 AI 大模型部署场景,欢迎试用。

附录:

1. 下载 llama-7b 模型

模型地址:

https://huggingface.co/decapoda-research/llama-7b-hf/tree/main


# 如果使用的是阿里云 ECS,需要运行如下命令安装 git-lfs
# yum install git-lfs
git clone https://huggingface.co/decapoda-research/llama-7b-hf
git lfs install
git lfs pull


2. 上传到 OSS

可参考文档:

https://help.aliyun.com/document_detail/195960.html

参考文档:

[1] 创建 ASK 集群

https://help.aliyun.com/document_detail/86377.htm?spm=a2c4g.186945.0.0.61eb3e0694K2ej#task-e3c-311-ydb

[2] ASK 概述

https://help.aliyun.com/document_detail/86366.html?spm=a2c4g.750001.0.i1


点击此处,领取 ASK 免费试用限额资源

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
17天前
|
弹性计算 人工智能 Serverless
阿里云ACK One:注册集群云上节点池(CPU/GPU)自动弹性伸缩,助力企业业务高效扩展
在当今数字化时代,企业业务的快速增长对IT基础设施提出了更高要求。然而,传统IDC数据中心却在业务存在扩容慢、缩容难等问题。为此,阿里云推出ACK One注册集群架构,通过云上节点池(CPU/GPU)自动弹性伸缩等特性,为企业带来全新突破。
|
1月前
|
专有云 Serverless 持续交付
亚太唯一,阿里云再度入选Gartner®容器管理魔力象限领导者
Gartner正式发布 2024《容器管理魔力象限》报告,阿里云再度成为中国唯一一家入选「领导者象限」的科技公司。
|
10天前
|
SQL 数据可视化 关系型数据库
阿里云DataV“山海计划” x Epic Fab:“中国风AIGC”助力智慧城市建设
DataV“山海计划”根据中国城市规划特色,建立城市地块、建筑、道路等“城市要素知识库”,基于AI大模型技术生成更贴近“中国特色”的城市场景。基于DataV“山海计划”的UE引擎插件已经登陆Epic Fab,广大UE引擎开发者可以通过该插件免费体验城市历史悠久的广州场景三维资产。除了三维城市场景生成,DataV为智慧城市提供完整的数据看板解决方案,提供200+基础图表、支持API、MySQL、SQL Server、人大金仓、达梦等30+数据源,通过DataV与UE引擎,广大开发者可以低成本获得“智慧城市”开发方案,将更多精力放在满足用户业务需求上,从而提升智慧城市项目的交付质量。
53 2
|
29天前
|
人工智能 专有云 Serverless
亚太唯一!阿里云再度入选Gartner®容器管理魔力象限领导者
亚太唯一!阿里云再度入选Gartner®容器管理魔力象限领导者
104 2
|
2月前
|
运维 Kubernetes 调度
阿里云容器服务 ACK One 分布式云容器企业落地实践
3年前的云栖大会,我们发布分布式云容器平台ACK One,随着3年的发展,很高兴看到ACK One在混合云,分布式云领域帮助到越来越多的客户,今天给大家汇报下ACK One 3年来的发展演进,以及如何帮助客户解决分布式领域多云多集群管理的挑战。
阿里云容器服务 ACK One 分布式云容器企业落地实践
|
2月前
|
人工智能 Prometheus 监控
使用 NVIDIA NIM 在阿里云容器服务(ACK)中加速 LLM 推理
本文介绍了在阿里云容器服务 ACK 上部署 NVIDIA NIM,结合云原生 AI 套件和 KServe 快速构建高性能模型推理服务的方法。通过阿里云 Prometheus 和 Grafana 实现实时监控,并基于排队请求数配置弹性扩缩容策略,提升服务稳定性和效率。文章提供了详细的部署步骤和示例,帮助读者快速搭建和优化模型推理服务。
165 7
使用 NVIDIA NIM 在阿里云容器服务(ACK)中加速 LLM 推理
|
2月前
|
人工智能 Prometheus 监控
使用NVIDIA NIM在阿里云ACK中加速LLM推理
介绍在阿里云ACK集群上结合AI套件能力快速部署NVIDIA NIM模型推理服务,同时提供全面的监控指标和实现弹性伸缩。
使用NVIDIA NIM在阿里云ACK中加速LLM推理
|
2月前
|
存储 Kubernetes 关系型数据库
阿里云ACK备份中心,K8s集群业务应用数据的一站式灾备方案
阿里云ACK备份中心,K8s集群业务应用数据的一站式灾备方案
|
2月前
|
人工智能 运维 监控
阿里云ACK容器服务生产级可观测体系建设实践
阿里云ACK容器服务生产级可观测体系建设实践
|
1月前
|
运维 Kubernetes 数据处理
阿里云Argo X K8s玩转工作流引擎,实现大规模并行计算
Kubernetes已经成为事实的云原生操作系统,成为业务上云、容器化的标准。从过去无状态应用、企业核心应用,到现在AI时代的数据处理、AI训练、科学仿真等,越来越多的离线任务跑在K8s上。

相关产品

  • 容器服务Kubernetes版
  • 函数计算