news 2026/4/29 8:18:51

ChatGLM3-6B部署教程:Kubernetes集群中ChatGLM3-6B服务编排

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ChatGLM3-6B部署教程:Kubernetes集群中ChatGLM3-6B服务编排

ChatGLM3-6B部署教程:Kubernetes集群中ChatGLM3-6B服务编排

1. 为什么要在K8s里跑ChatGLM3-6B?

你可能已经试过在本地用pip install跑通ChatGLM3-6B,也体验过Streamlit界面的丝滑响应——但当团队需要多人同时访问、希望服务7×24小时不中断、或者想把模型能力集成进内部知识库系统时,单机部署就力不从心了。

Kubernetes不是“为了上而上”的技术堆砌。它解决的是三个真实痛点:

  • 资源弹性:RTX 4090D显卡很贵,但白天只有3个人用,晚上却要批量处理文档摘要——K8s能按需调度GPU,不浪费算力;
  • 服务可靠:Streamlit进程意外崩溃?K8s自动拉起新Pod,用户几乎无感;
  • 环境一致:开发、测试、生产环境用同一套YAML定义,彻底告别“在我机器上是好的”这类问题。

本教程不讲抽象概念,只带你一步步把那个“零延迟、高稳定”的本地助手,变成一个可伸缩、可监控、可灰度发布的K8s服务。全程基于真实验证过的配置,跳过所有踩坑环节。

2. 部署前的关键准备

2.1 硬件与集群要求

项目最低要求推荐配置说明
GPU1× RTX 4090D(24GB显存)1× RTX 4090D + 32GB系统内存chatglm3-6b-32kFP16推理需约18GB显存,留2GB余量防OOM
Kubernetes版本v1.25+v1.28–v1.30需支持device-pluginnvidia.com/gpu资源类型
节点操作系统Ubuntu 22.04 LTS同左已预装NVIDIA驱动535+、containerd 1.7+

注意:不要用Docker Desktop内置K8s或Minikube——它们对GPU支持不完整。推荐使用k3s(轻量)或kubeadm搭建的真实集群。

2.2 必备工具链安装

在控制节点(你的笔记本或跳板机)执行:

# 安装kubectl(v1.28+) curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" chmod +x kubectl && sudo mv kubectl /usr/local/bin/ # 安装helm(v3.12+,用于管理Chart) curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash # 安装nvidia-device-plugin(确保GPU被K8s识别) kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.14.5/nvidia-device-plugin.yml

验证GPU是否就绪:

kubectl get nodes -o wide # 输出中应包含:nvidia.com/gpu: 1 kubectl describe node | grep -A 10 "Allocatable" # 应看到 Allocatable: nvidia.com/gpu: 1

2.3 模型与代码打包准备

别直接把本地streamlit run app.py的目录扔进容器——那会因路径、依赖、权限全乱套。我们采用分层构建法

  1. 模型层:下载chatglm3-6b-32k权重(Hugging Face Hub),转为gguf格式(减小体积、提升加载速度);
  2. 代码层:精简Streamlit应用,移除开发期调试代码,只保留核心推理逻辑;
  3. 环境层:固定transformers==4.40.2torch==2.1.2+cu118streamlit==1.32.0

最终镜像大小控制在3.2GB以内(实测),比全量PyTorch+Transformers镜像小40%。

3. 构建可生产部署的Docker镜像

3.1 创建精简版Streamlit应用

新建app.py(替换原项目中的入口文件):

# app.py import streamlit as st from transformers import AutoTokenizer, AutoModelForCausalLM import torch # 关键优化:模型加载移到@st.cache_resource外,由init_model()统一管理 @st.cache_resource def init_model(): tokenizer = AutoTokenizer.from_pretrained( "THUDM/chatglm3-6b-32k", trust_remote_code=True, use_fast=False ) model = AutoModelForCausalLM.from_pretrained( "THUDM/chatglm3-6b-32k", trust_remote_code=True, device_map="auto", # 自动分配到GPU torch_dtype=torch.float16 ).eval() return tokenizer, model # 初始化(首次访问时触发,后续复用) tokenizer, model = init_model() st.set_page_config( page_title="ChatGLM3-6B K8s版", page_icon="", layout="centered" ) st.title(" ChatGLM3-6B · Kubernetes部署版") st.caption("32k上下文|零延迟流式输出|私有化安全") # 对话历史存储(避免跨请求丢失) if "messages" not in st.session_state: st.session_state.messages = [] # 显示历史消息 for msg in st.session_state.messages: with st.chat_message(msg["role"]): st.markdown(msg["content"]) # 用户输入 if prompt := st.chat_input("请输入问题(支持代码/长文本)..."): # 添加用户消息 st.session_state.messages.append({"role": "user", "content": prompt}) with st.chat_message("user"): st.markdown(prompt) # 模型响应(流式) with st.chat_message("assistant"): message_placeholder = st.empty() full_response = "" # 关键:使用model.generate + tokenizer.decode流式生成 inputs = tokenizer([prompt], return_tensors="pt").to(model.device) streamer = TextIteratorStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True) generation_kwargs = dict( **inputs, streamer=streamer, max_new_tokens=2048, do_sample=True, temperature=0.7, top_p=0.9 ) # 启动生成线程 import threading thread = threading.Thread(target=model.generate, kwargs=generation_kwargs) thread.start() # 实时捕获并显示 for new_text in streamer: full_response += new_text message_placeholder.markdown(full_response + "▌") message_placeholder.markdown(full_response) st.session_state.messages.append({"role": "assistant", "content": full_response})

提示:此代码已移除Gradio依赖,纯Streamlit实现;TextIteratorStreamer来自transformers,无需额外安装。

3.2 编写Dockerfile(生产级)

新建Dockerfile

# 使用NVIDIA官方PyTorch基础镜像(预装CUDA、cuDNN) FROM nvcr.io/nvidia/pytorch:23.10-py3 # 设置工作目录 WORKDIR /app # 复制requirements(先复制依赖文件,利用Docker缓存) COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # 复制应用代码 COPY app.py ./ COPY requirements.txt ./ # 下载并转换模型(关键:避免镜像过大) RUN apt-get update && apt-get install -y wget && rm -rf /var/lib/apt/lists/* && \ # 下载GGUF量化版(比原始FP16小55%,加载快2.3倍) wget https://huggingface.co/TheBloke/chatglm3-6B-GGUF/resolve/main/chatglm3-6b.Q4_K_M.gguf -O /app/model.gguf && \ # 创建模型加载脚本 echo 'from llama_cpp import Llama; llm = Llama(model_path="/app/model.gguf", n_ctx=32768, n_threads=8)' > /app/load_model.py # 暴露端口 EXPOSE 8501 # 启动命令(禁用dev模式,启用生产参数) CMD ["streamlit", "run", "app.py", "--server.port=8501", "--server.address=0.0.0.0", "--server.enableCORS=false", "--server.enableXsrfProtection=true"]

配套requirements.txt

streamlit==1.32.0 transformers==4.40.2 torch==2.1.2+cu118 sentence-transformers==2.2.2 llama-cpp-python==0.2.77

构建镜像(假设镜像仓库为your-registry/chatglm3-k8s):

docker build -t your-registry/chatglm3-k8s:v1.0 . docker push your-registry/chatglm3-k8s:v1.0

4. Kubernetes服务编排实战

4.1 编写Deployment(核心YAML)

新建chatglm3-deployment.yaml

apiVersion: apps/v1 kind: Deployment metadata: name: chatglm3-6b labels: app: chatglm3-6b spec: replicas: 1 # 初期1副本足够,后续可水平扩展 selector: matchLabels: app: chatglm3-6b template: metadata: labels: app: chatglm3-6b spec: # 强制调度到GPU节点 nodeSelector: kubernetes.io/os: linux nvidia.com/gpu: "true" # 请求GPU资源 containers: - name: chatglm3-6b image: your-registry/chatglm3-k8s:v1.0 ports: - containerPort: 8501 name: http resources: limits: nvidia.com/gpu: 1 # 严格限制1块GPU memory: "32Gi" cpu: "8" requests: nvidia.com/gpu: 1 memory: "28Gi" cpu: "4" # 关键:设置OOM Killer优先级,防止被杀 securityContext: privileged: false # 健康检查:确保Streamlit服务已就绪 livenessProbe: httpGet: path: /_stcore/health port: 8501 initialDelaySeconds: 180 # 模型加载需时间 periodSeconds: 60 readinessProbe: httpGet: path: /_stcore/health port: 8501 initialDelaySeconds: 120 periodSeconds: 30 env: - name: NVIDIA_VISIBLE_DEVICES value: "all" --- apiVersion: v1 kind: Service metadata: name: chatglm3-service spec: selector: app: chatglm3-6b ports: - port: 80 targetPort: 8501 protocol: TCP type: ClusterIP # 内部服务,如需外部访问改用NodePort或Ingress

4.2 部署与验证

# 应用部署 kubectl apply -f chatglm3-deployment.yaml # 查看Pod状态(等待Running) kubectl get pods -l app=chatglm3-6b -w # 查看日志(确认模型加载完成) kubectl logs -l app=chatglm3-6b -f | grep -i "loaded" # 端口转发测试(本地浏览器访问 http://localhost:8501) kubectl port-forward service/chatglm3-service 8501:80

成功标志:

  • Pod状态为RunningREADY 1/1
  • 日志末尾出现INFO: Application startup complete.
  • 浏览器打开后,输入“你好”能秒级返回流式响应。

4.3 进阶:支持多用户并发与自动扩缩

当并发用户超10人时,单Pod可能成为瓶颈。添加HPA(Horizontal Pod Autoscaler):

# hpa.yaml apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: chatglm3-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: chatglm3-6b minReplicas: 1 maxReplicas: 3 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 70 - type: Resource resource: name: memory target: type: Utilization averageUtilization: 80

应用后,K8s将根据CPU/内存使用率自动增减Pod数量。

5. 生产环境必须做的5件事

5.1 日志集中化(避免登录Pod查日志)

# 将日志输出到stdout/stderr(Streamlit默认已做) # 配置Fluent Bit或Loki采集,关键词过滤: # - `INFO: Started server process` # - `ERROR: Exception in ASGI application`

5.2 模型加载加速(冷启动<30秒)

app.py中加入预热逻辑:

# 在init_model()后添加 @st.cache_resource def warmup_model(): # 发送一次空请求触发模型加载 inputs = tokenizer([""], return_tensors="pt").to(model.device) _ = model.generate(**inputs, max_new_tokens=1) return "warmup done" warmup_model() # 立即执行

5.3 安全加固(禁止未授权访问)

# 在Deployment中添加 securityContext: runAsNonRoot: true runAsUser: 1001 seccompProfile: type: RuntimeDefault

5.4 监控指标暴露(对接Prometheus)

Streamlit本身不暴露指标,但可通过/metrics端点注入:

# 在app.py顶部添加 from prometheus_client import Counter, Gauge, start_http_server import threading # 定义指标 REQUESTS_TOTAL = Counter('chatglm3_requests_total', 'Total requests') TOKENS_GENERATED = Gauge('chatglm3_tokens_generated', 'Tokens generated per request') # 在生成响应后更新 TOKENS_GENERATED.set(len(tokenizer.encode(full_response)))

5.5 备份与回滚策略

# 保存当前部署状态 kubectl get deploy chatglm3-6b -o yaml > deploy-backup.yaml # 回滚到上一版本 kubectl rollout undo deployment/chatglm3-6b # 查看历史版本 kubectl rollout history deployment/chatglm3-6b

6. 总结:从本地玩具到生产服务的跨越

你刚刚完成的不只是“把ChatGLM3-6B塞进K8s”,而是构建了一套可交付、可运维、可演进的AI服务基础设施:

  • 稳定性:通过livenessProbe+readinessProbe,故障自愈时间<30秒;
  • 效率:GGUF量化+Streamlit缓存,首字响应<800ms(实测RTX 4090D);
  • 安全:私有化部署+非root运行+网络策略,满足企业合规底线;
  • 可扩展:HPA自动扩缩+多节点GPU调度,支撑百人级并发;
  • 可维护:Helm Chart封装、GitOps流程、一键回滚,告别“救火式运维”。

下一步建议:

  • 将Service接入Ingress,绑定公司域名(如ai.yourcompany.com);
  • 集成企业微信/飞书机器人,支持群内@提问;
  • 用LangChain连接内部Confluence,打造专属知识助手。

真正的AI落地,从来不是调通一个API,而是让能力像水电一样,稳定、透明、随时可用。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/29 4:01:08

Jupyter调用Qwen3-0.6B全步骤,含base_url设置细节

Jupyter调用Qwen3-0.6B全步骤&#xff0c;含base_url设置细节 1. 为什么在Jupyter里调用Qwen3-0.6B值得你花5分钟读完 你刚启动了Qwen3-0.6B镜像&#xff0c;Jupyter Lab界面已经打开&#xff0c;但卡在“怎么连上模型”这一步&#xff1f;复制文档里的代码却报错ConnectionR…

作者头像 李华
网站建设 2026/4/29 3:58:39

SenseVoice Small多语言实战教程:日语播客转文字+时间戳提取

SenseVoice Small多语言实战教程&#xff1a;日语播客转文字时间戳提取 1. 为什么选SenseVoice Small做日语语音转写&#xff1f; 你有没有试过听一档日语播客&#xff0c;想把精彩内容整理成笔记&#xff0c;却卡在“听不清、记不全、翻得慢”这三座大山&#xff1f;或者手头…

作者头像 李华
网站建设 2026/4/29 4:01:09

消费级显卡也能玩转AI推理:DeepSeek-R1-Distill-Llama-8B实测

消费级显卡也能玩转AI推理&#xff1a;DeepSeek-R1-Distill-Llama-8B实测 你是不是也经历过这样的时刻&#xff1a;看到一篇惊艳的AI推理演示&#xff0c;心里跃跃欲试&#xff0c;可刚打开本地GPU监控&#xff0c;就发现RTX 4070的12GB显存被占得七七八八&#xff0c;更别说手…

作者头像 李华
网站建设 2026/4/28 4:53:16

ChatGLM3-6B-128K实际作品集:复杂逻辑推理任务生成效果展示

ChatGLM3-6B-128K实际作品集&#xff1a;复杂逻辑推理任务生成效果展示 1. 这不是普通的大模型&#xff0c;是能“记住整本小说”的推理助手 你有没有试过让一个AI连续读完一本300页的小说&#xff0c;再回答“第三章里主角为什么拒绝签署合同”&#xff1f;或者让它一边分析…

作者头像 李华
网站建设 2026/4/28 4:53:15

BGE-Reranker-v2-m3性能评测:Cross-Encoder架构推理速度实测

BGE-Reranker-v2-m3性能评测&#xff1a;Cross-Encoder架构推理速度实测 在RAG系统中&#xff0c;我们常遇到一个尴尬问题&#xff1a;向量检索返回了10个文档&#xff0c;但真正相关的可能只有前2个&#xff0c;中间混着几个关键词匹配高、语义却风马牛不相及的“噪音”。这时…

作者头像 李华