当前位置:   article > 正文

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

serverless gpu

AI 技术正在引领科技创新浪潮,随着 ChatGPT 和 Midjourney 的走红,AIGC 技术正在世界范围内掀起一股 AI 技术浪潮。开源领域也涌现了许多类似模型,如 FastGPT、Moss、Stable Diffusion 等。这些模型展现出的惊人效果吸引企业和开发者们投身其中,但是复杂繁琐的部署方式成为了拦路虎。阿里云 ASK 提供 Serverless 化的容器服务,用户无需关心资源及环境配置,可以帮助开发者们零门槛快速部署 AI 模型。本文以开源的 FastChat 为例,详细展示如何在 ASK 中快速搭建一个私人代码助理。

效果预览

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

  • 快速生成一个 Golang Hello World

地址:https://intranetproxy.alipay.com/skylark/lark/0/2023/gif/11431/1682574183392-11e16131-3dae-4969-a0d1-79a0a9eefb01.gif

  • 快速生成一个 Kubernetes Deployment

地址:https://intranetproxy.alipay.com/skylark/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

  1. apiVersion: v1
  2. kind: Secret
  3. metadata:
  4. name: oss-secret
  5. type: Opaque
  6. stringData:
  7. .ossutilconfig: |
  8. [Credentials]
  9. language=ch
  10. accessKeyID=${your-ak}
  11. accessKeySecret=${your-sk}
  12. endpoint=${oss-endpoint-url}
  13. ---
  14. apiVersion: apps/v1
  15. kind: Deployment
  16. metadata:
  17. labels:
  18. app: fastchat
  19. name: fastchat
  20. namespace: default
  21. spec:
  22. replicas: 1
  23. selector:
  24. matchLabels:
  25. app: fastchat
  26. strategy:
  27. rollingUpdate:
  28. maxSurge: 100%
  29. maxUnavailable: 100%
  30. type: RollingUpdate
  31. template:
  32. metadata:
  33. labels:
  34. app: fastchat
  35. alibabacloud.com/eci: "true"
  36. annotations:
  37. k8s.aliyun.com/eci-use-specs: ecs.gn6e-c12g1.3xlarge
  38. spec:
  39. volumes:
  40. - name: data
  41. emptyDir: {}
  42. - name: oss-volume
  43. secret:
  44. secretName: oss-secret
  45. dnsPolicy: Default
  46. initContainers:
  47. - name: llama-7b
  48. image: yunqi-registry.cn-shanghai.cr.aliyuncs.com/lab/ossutil:v1
  49. volumeMounts:
  50. - name: data
  51. mountPath: /data
  52. - name: oss-volume
  53. mountPath: /root/
  54. readOnly: true
  55. command:
  56. - sh
  57. - -c
  58. - ossutil cp -r ${llama-oss-path} /data/
  59. resources:
  60. limits:
  61. ephemeral-storage: 50Gi
  62. containers:
  63. - command:
  64. - sh
  65. - -c
  66. - "/root/webui.sh"
  67. image: yunqi-registry.cn-shanghai.cr.aliyuncs.com/lab/fastchat:v1.0.0
  68. imagePullPolicy: IfNotPresent
  69. name: fastchat
  70. ports:
  71. - containerPort: 7860
  72. protocol: TCP
  73. - containerPort: 8000
  74. protocol: TCP
  75. readinessProbe:
  76. failureThreshold: 3
  77. initialDelaySeconds: 5
  78. periodSeconds: 10
  79. successThreshold: 1
  80. tcpSocket:
  81. port: 7860
  82. timeoutSeconds: 1
  83. resources:
  84. requests:
  85. cpu: "4"
  86. memory: 8Gi
  87. limits:
  88. nvidia.com/gpu: 1
  89. ephemeral-storage: 100Gi
  90. volumeMounts:
  91. - mountPath: /data
  92. name: data
  93. ---
  94. apiVersion: v1
  95. kind: Service
  96. metadata:
  97. annotations:
  98. service.beta.kubernetes.io/alibaba-cloud-loadbalancer-address-type: internet
  99. service.beta.kubernetes.io/alibaba-cloud-loadbalancer-instance-charge-type: PayByCLCU
  100. name: fastchat
  101. namespace: default
  102. spec:
  103. externalTrafficPolicy: Local
  104. ports:
  105. - port: 7860
  106. protocol: TCP
  107. targetPort: 7860
  108. name: web
  109. - port: 8000
  110. protocol: TCP
  111. targetPort: 8000
  112. name: api
  113. selector:
  114. app: fastchat
  115. type: LoadBalancer

3. 等待 FastChat Ready

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

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

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

  1. kubectl get po |grep fastchat
  2. # NAME READY STATUS RESTARTS AGE
  3. # fastchat-69ff78cf46-tpbvp 1/1 Running 0 20m
  4. kubectl get svc fastchat
  5. # NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  6. # 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 命令
  1. kubectl get po |grep fastchat
  2. # NAME READY STATUS RESTARTS AGE
  3. # fastchat-69ff78cf46-tpbvp 1/1 Running 0 20m
  4. kubectl get svc fastchat
  5. # NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  6. # fastchat LoadBalancer 192.168.230.108 xxx.xx.x.xxx 7860:31444/TCP 22m
  • 输出结果
{"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
  1. import * as vscode from 'vscode';
  2. import axios from 'axios';
  3. import { ExtensionContext, commands, window } from "vscode";
  4. const editor = window.activeTextEditor
  5. export function activate(context: vscode.ExtensionContext) {
  6. let fastchat = async () => {
  7. vscode.window.showInputBox({ prompt: '请输入代码提示语' }).then((inputValue) => {
  8. if (!inputValue) {
  9. return;
  10. }
  11. vscode.window.withProgress({
  12. location: vscode.ProgressLocation.Notification,
  13. title: '正在请求...',
  14. cancellable: false
  15. }, (progress, token) => {
  16. return axios.post('http://example.com:8000/v1/chat/completions', {
  17. model: 'vicuna-7b-v1.1',
  18. messages: [{ role: 'user', content: inputValue }]
  19. }, {
  20. headers: {
  21. 'Content-Type': 'application/json'
  22. }
  23. }).then((response) => {
  24. // const content = JSON.stringify(response.data);
  25. const content = response.data.choices[0].message.content;
  26. console.log(response.data)
  27. const regex = /```.*\n([\s\S]*?)```/
  28. const matches = content.match(regex)
  29. if (matches && matches.length > 1) {
  30. editor?.edit(editBuilder => {
  31. let position = editor.selection.active;
  32. position && editBuilder.insert(position, matches[1].trim())
  33. })
  34. }
  35. }).catch((error) => {
  36. console.log(error);
  37. });
  38. });
  39. });
  40. }
  41. let command = commands.registerCommand(
  42. "fastchat",
  43. fastchat
  44. )
  45. context.subscriptions.push(command)
  46. }
  • package.json
  1. {
  2. "name": "fastchat",
  3. "version": "1.0.0",
  4. "publisher": "yourname",
  5. "engines": {
  6. "vscode": "^1.0.0"
  7. },
  8. "categories": [
  9. "Other"
  10. ],
  11. "activationEvents": [
  12. "onCommand:fastchat"
  13. ],
  14. "main": "./dist/extension.js",
  15. "contributes": {
  16. "commands": [
  17. {
  18. "command": "fastchat",
  19. "title": "fastchat code generator"
  20. }
  21. ]
  22. },
  23. "devDependencies": {
  24. "@types/node": "^18.16.1",
  25. "@types/vscode": "^1.77.0",
  26. "axios": "^1.3.6",
  27. "typescript": "^5.0.4"
  28. }
  29. }
  • tsconfig.json
  1. {
  2. "compilerOptions": {
  3. "target": "ES2018",
  4. "module": "commonjs",
  5. "outDir": "./dist",
  6. "strict": true,
  7. "esModuleInterop": true,
  8. "resolveJsonModule": true,
  9. "declaration": true
  10. },
  11. "include": ["src/**/*"],
  12. "exclude": ["node_modules", "**/*.test.ts"]
  13. }

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

  • 快速生成一个 Golang Hello World

地址:https://intranetproxy.alipay.com/skylark/lark/0/2023/gif/11431/1682574183392-11e16131-3dae-4969-a0d1-79a0a9eefb01.gif

  • 快速生成一个 Kubernetes Deployment

地址:https://intranetproxy.alipay.com/skylark/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

  1. # 如果使用的是阿里云 ECS,需要运行如下命令安装 git-lfs
  2. # yum install git-lfs
  3. git clone https://huggingface.co/decapoda-research/llama-7b-hf
  4. git lfs install
  5. 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

作者:子白、冬岛

原文链接

本文为阿里云原创内容,未经允许不得转载。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/98878
推荐阅读
相关标签
  

闽ICP备14008679号