Nanbeige4.1-3B部署教程:Kubernetes Helm Chart封装,支持弹性扩缩容与滚动更新
如果你正在寻找一个既小巧又强大的开源语言模型,并且希望它能像现代云原生应用一样,在Kubernetes集群里稳定、弹性地运行,那么Nanbeige4.1-3B绝对值得你花时间了解一下。
这个仅有30亿参数的模型,在推理、代码生成和智能体任务上的表现,常常能媲美一些更大的模型。但今天我们不只聊模型本身,更重要的是,如何把它从“单机玩具”变成“生产级服务”。我们将一步步教你,如何用Helm Chart把Nanbeige4.1-3B封装起来,部署到Kubernetes上,让它具备弹性扩缩容、滚动更新、健康检查等企业级特性。无论你是想搭建一个内部AI助手平台,还是为你的应用提供一个稳定的推理后端,这篇教程都能给你一个清晰的路线图。
1. 为什么要在K8s上部署Nanbeige4.1-3B?
在直接动手之前,我们先聊聊为什么要把这个模型放到Kubernetes里。如果你只是简单测试,在本地用Python脚本跑一下当然没问题。但当你需要考虑下面这些情况时,K8s的优势就体现出来了:
- 资源弹性:白天用户访问多,需要更多GPU实例来处理请求;深夜流量低,可以自动缩容节省成本。手动开关机?太麻烦了。
- 高可用性:某个节点挂了,或者某个Pod(模型实例)崩溃了,K8s能自动在健康节点上重新拉起一个新的,保证服务不中断。
- 简化部署与更新:有了Helm Chart,部署一整套包含模型服务、监控、网络配置的应用,只需要一条命令。未来模型升级(比如从4.1升级到4.2),也可以通过滚动更新实现零停机。
- 统一管理:你的微服务、数据库、缓存都跑在K8s里,现在把AI模型也放进来,能用同样的工具(kubectl, Helm)和视角(监控仪表盘)来管理一切,运维效率大大提升。
简单说,K8s+Helm让Nanbeige4.1-3B从一个“项目”变成了一个“产品服务”。接下来,我们就开始打造这个产品。
2. 前期准备:模型与基础环境
我们的目标是将项目提供的本地部署能力,转化为容器化的、可编排的服务。首先,我们需要准备好“原材料”。
2.1 获取模型文件
根据项目说明,模型权重等文件通常存放在/root/ai-models/nanbeige/目录下。我们需要确保这些文件在后续的Docker构建过程中能够被访问到。一个标准的做法是使用git lfs克隆包含模型权重的仓库,或者直接从可信源下载模型文件包。
假设我们已经获得了模型文件,其核心目录结构如下:
/root/ai-models/nanbeige/Nanbeige4___1-3B/ ├── config.json ├── model.safetensors ├── tokenizer.json ├── tokenizer_config.json └── ... (其他必要文件)2.2 理解原始WebUI服务
项目提供了一个基于Gradio的WebUI(/root/nanbeige-webui/)和用Supervisor管理的启动方式。在容器化时,我们需要将其核心逻辑移植过来。主要包含两部分:
- 模型加载与推理脚本:即原始
webui.py中与模型交互的部分。 - HTTP服务接口:Gradio本身就是一个Web框架,我们会保留它作为API服务器,或者也可以选择更轻量的FastAPI进行重构。
我们的Helm Chart将负责把这份代码和模型文件一起打包,并配置好运行环境。
3. 构建模型推理的Docker镜像
容器化是K8s部署的第一步。我们需要创建一个Docker镜像,里面包含Python环境、依赖库、模型文件以及我们的应用代码。
3.1 创建Dockerfile
在你的项目目录下(例如nanbeige-helm/),创建一个Dockerfile:
# 使用带有CUDA的PyTorch基础镜像,确保GPU支持 FROM pytorch/pytorch:2.0.1-cuda11.7-cudnn8-runtime # 设置工作目录 WORKDIR /app # 安装系统依赖(如果需要) RUN apt-get update && apt-get install -y --no-install-recommends \ git \ && rm -rf /var/lib/apt/lists/* # 复制依赖列表并安装Python包 COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # 复制模型文件(假设在构建上下文的 `model/` 目录下) COPY model /app/model # 复制应用代码 COPY app /app # 暴露Gradio默认端口 EXPOSE 7860 # 设置健康检查(可选,但推荐) HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD python -c "import requests; requests.get('http://localhost:7860/')" # 启动命令,使用Gradio启动,并允许外部访问 CMD ["python", "app/webui.py"]3.2 创建精简的应用代码(app/webui.py)
我们将原始WebUI脚本稍作修改,使其更适应容器环境,例如固定模型路径:
import os import torch from transformers import AutoModelForCausalLM, AutoTokenizer import gradio as gr # 容器内固定的模型路径 MODEL_PATH = "/app/model/Nanbeige4___1-3B" # 加载模型和分词器(使用缓存,避免每次请求重复加载) tokenizer = None model = None def load_model(): global tokenizer, model if model is None: print("Loading tokenizer and model...") tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH, trust_remote_code=True) model = AutoModelForCausalLM.from_pretrained( MODEL_PATH, torch_dtype=torch.bfloat16, device_map="auto", trust_remote_code=True ) print("Model loaded successfully.") return tokenizer, model def predict(message, history, temperature, top_p, max_tokens): tokenizer, model = load_model() # 构建对话历史格式 messages = [{"role": "user", "content": message}] # 应用聊天模板并生成 input_ids = tokenizer.apply_chat_template(messages, return_tensors="pt").to(model.device) with torch.no_grad(): outputs = model.generate( input_ids, max_new_tokens=max_tokens, temperature=temperature, top_p=top_p, do_sample=True ) response = tokenizer.decode(outputs[0][len(input_ids[0]):], skip_special_tokens=True) return response # 创建Gradio界面 demo = gr.ChatInterface( fn=predict, additional_inputs=[ gr.Slider(0.0, 2.0, value=0.6, label="Temperature"), gr.Slider(0.0, 1.0, value=0.95, label="Top-P"), gr.Slider(128, 4096, value=1024, step=128, label="Max New Tokens") ], title="Nanbeige4.1-3B Chat", description="A 3B parameter open-source language model deployed on Kubernetes." ) # 允许服务器共享,监听所有地址 if __name__ == "__main__": demo.launch(server_name="0.0.0.0", server_port=7860, share=False)3.3 构建并测试镜像
在包含Dockerfile、requirements.txt、model/和app/的目录下执行:
# 构建镜像 docker build -t your-registry/nanbeige-api:4.1-3b-v1 . # 本地测试运行(确保有GPU) docker run --gpus all -p 7860:7860 your-registry/nanbeige-api:4.1-3b-v1 # 访问 http://localhost:7860 测试功能镜像构建成功后,将其推送到你的容器镜像仓库(如 Docker Hub, Harbor, AWS ECR等)。
4. 创建Helm Chart:实现弹性与可管理性
Helm是K8s的包管理工具。一个Chart就是一套预定义的K8s资源模板。我们来创建nanbeige这个Chart。
4.1 初始化Chart结构
helm create nanbeige cd nanbeige rm -rf templates/* values.yaml我们将从头开始创建核心文件。
4.2 配置核心参数(values.yaml)
values.yaml是Chart的配置中心,用户可以通过修改它来定制部署。
# values.yaml # 镜像配置 image: repository: your-registry/nanbeige-api tag: "4.1-3b-v1" pullPolicy: IfNotPresent # 模型服务配置 service: type: ClusterIP # 也可以是 NodePort 或 LoadBalancer port: 7860 # 资源请求与限制(关键!GPU资源在此声明) resources: requests: memory: "8Gi" cpu: "1" nvidia.com/gpu: 1 # 申请1个GPU limits: memory: "16Gi" cpu: "2" nvidia.com/gpu: 1 # 限制使用1个GPU # 副本数(即同时运行几个模型实例) replicaCount: 1 # 自动扩缩容配置(HPA) autoscaling: enabled: true minReplicas: 1 maxReplicas: 5 targetCPUUtilizationPercentage: 70 # 也可以基于自定义指标(如QPS)进行扩缩容 # 滚动更新策略 updateStrategy: type: RollingUpdate rollingUpdate: maxSurge: 1 # 更新时最多可以比期望副本数多出1个Pod maxUnavailable: 0 # 更新时保证至少有所有副本数在运行 # 探针配置(用于健康检查) probes: livenessProbe: httpGet: path: / port: http initialDelaySeconds: 60 # 模型加载需要时间,延迟检查 periodSeconds: 10 readinessProbe: httpGet: path: / port: http initialDelaySeconds: 30 periodSeconds: 5 # 持久化存储(如果需要缓存或保留日志) persistence: enabled: false # storageClass: "standard" # accessMode: ReadWriteOnce # size: 10Gi4.3 定义部署模板(templates/deployment.yaml)
这是最核心的模板,它定义了如何运行我们的模型容器。
# templates/deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "nanbeige.fullname" . }} labels: {{- include "nanbeige.labels" . | nindent 4 }} spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: {{- include "nanbeige.selectorLabels" . | nindent 6 }} strategy: {{- toYaml .Values.updateStrategy | nindent 4 }} template: metadata: labels: {{- include "nanbeige.selectorLabels" . | nindent 8 }} spec: containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - name: http containerPort: {{ .Values.service.port }} protocol: TCP {{- if .Values.probes.livenessProbe }} livenessProbe: {{- toYaml .Values.probes.livenessProbe | nindent 10 }} {{- end }} {{- if .Values.probes.readinessProbe }} readinessProbe: {{- toYaml .Values.probes.readinessProbe | nindent 10 }} {{- end }} resources: {{- toYaml .Values.resources | nindent 10 }} env: - name: CUDA_VISIBLE_DEVICES value: "0" # 指定容器内可见的GPU编号 --- # 如果启用,创建 HorizontalPodAutoscaler {{- if .Values.autoscaling.enabled }} apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: {{ include "nanbeige.fullname" . }}-hpa labels: {{- include "nanbeige.labels" . | nindent 4 }} spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: {{ include "nanbeige.fullname" . }} minReplicas: {{ .Values.autoscaling.minReplicas }} maxReplicas: {{ .Values.autoscaling.maxReplicas }} metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} {{- end }}4.4 创建服务访问模板(templates/service.yaml)
Service为Pod提供一个稳定的网络端点。
# templates/service.yaml apiVersion: v1 kind: Service metadata: name: {{ include "nanbeige.fullname" . }} labels: {{- include "nanbeige.labels" . | nindent 4 }} spec: type: {{ .Values.service.type }} ports: - port: {{ .Values.service.port }} targetPort: http protocol: TCP name: http selector: {{- include "nanbeige.selectorLabels" . | nindent 4 }}4.5 创建辅助模板(templates/_helpers.tpl)
这个文件包含一些可复用的模板逻辑,比如生成名称。
# templates/_helpers.tpl {{- define "nanbeige.name" -}} {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} {{- end }} {{- define "nanbeige.fullname" -}} {{- $name := default .Chart.Name .Values.nameOverride }} {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} {{- end }} {{- define "nanbeige.labels" -}} helm.sh/chart: {{ include "nanbeige.chart" . }} {{ include "nanbeige.selectorLabels" . }} {{- end }} {{- define "nanbeige.selectorLabels" -}} app.kubernetes.io/name: {{ include "nanbeige.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} {{- end }}5. 部署与验证:一键上云
现在,万事俱备,只差一条部署命令。
5.1 使用Helm部署到K8s集群
确保你的kubectl已经连接到正确的K8s集群,并且集群节点带有GPU(已安装NVIDIA GPU Operator或类似插件)。
# 添加Helm仓库(如果是本地Chart,则不需要) # helm repo add nanbeige-repo https://charts.your-domain.com/ # 安装Chart,命名为 nanbeige-in-production helm install nanbeige-in-production ./nanbeige -n ai-models --create-namespace # 或者,如果你想覆盖 values.yaml 中的某些配置,可以使用 --set # helm install nanbeige-in-production ./nanbeige -n ai-models \ # --set replicaCount=2 \ # --set resources.requests.nvidia.com/gpu=25.2 验证部署状态
部署后,使用以下命令检查状态:
# 查看Pod状态,等待状态变为 Running kubectl get pods -n ai-models -l app.kubernetes.io/name=nanbeige # 查看Service kubectl get svc -n ai-models -l app.kubernetes.io/name=nanbeige # 查看HPA状态(如果启用) kubectl get hpa -n ai-models # 查看Pod日志,确认模型加载成功 kubectl logs -f deployment/nanbeige-in-production-nanbeige -n ai-models5.3 访问服务
根据Service的类型访问服务:
- ClusterIP:在集群内部通过服务名
nanbeige-in-production-nanbeige.ai-models.svc.cluster.local:7860访问。 - NodePort/LoadBalancer:可以通过节点IP和端口或云服务商提供的负载均衡器外部IP从外部访问。
你也可以创建Ingress资源,通过域名来暴露服务。
5.4 测试弹性扩缩容
手动扩缩容:
kubectl scale deployment nanbeige-in-production-nanbeige --replicas=3 -n ai-models观察Pod数量变化。
自动扩缩容(HPA)测试: 如果配置了HPA,你可以通过增加负载来触发自动扩容。可以写一个简单的压测脚本,或者使用
kubectl run一个临时Pod来持续访问服务。观察HPA的CURRENT列是否会上升。
5.5 测试滚动更新
当我们有新的镜像版本(如v2)时,进行滚动更新:
# 方法1:使用Helm升级 helm upgrade nanbeige-in-production ./nanbeige -n ai-models --set image.tag=4.1-3b-v2 # 方法2:使用kubectl set image kubectl set image deployment/nanbeige-in-production-nanbeige nanbeige=your-registry/nanbeige-api:4.1-3b-v2 -n ai-models更新过程中,使用kubectl get pods -n ai-models -w观察,会看到旧Pod逐个被终止,新Pod逐个被创建,服务始终有可用的Pod在处理请求,实现了零停机更新。
6. 总结:从单机到云原生的飞跃
通过这篇教程,我们完成了将Nanbeige4.1-3B模型从本地部署到Kubernetes生产环境的完整旅程。回顾一下我们实现的核心能力:
- 标准化交付:通过Docker镜像,将模型、代码、环境固化,消除了“在我机器上能跑”的问题。
- 声明式部署:通过Helm Chart,将复杂的K8s资源配置(Deployment, Service, HPA等)模板化、参数化。部署和升级变得像安装软件包一样简单。
- 弹性伸缩:结合HPA,服务可以根据CPU等指标自动调整实例数量,从容应对流量波动,优化资源成本。
- 高可用与自愈:K8s确保指定数量的副本始终运行,任何Pod故障都会自动重启或重建。
- 平滑更新:利用滚动更新策略,可以安全、无缝地将服务升级到新版本。
这套方案不仅适用于Nanbeige4.1-3B,也为你部署其他AI模型提供了一个可复用的云原生范式。你可以在此基础上,继续添加监控(Prometheus指标)、日志收集(EFK栈)、服务网格(Istio流量管理)等高级特性,构建更加强大和稳健的AI服务平台。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。