在 Kubernetes 上部署 GLM-4.7 2bit量化模型
本文记录了在多节点 Kubernetes 集群上部署大模型 GLM-4.7-UD-Q2_K_XL 并调用的完整实践过程,包括资源调优、容器调度、NUMA 优化、Pod 调试以及模型调用示例。
hg下载 合计135g
https://huggingface.co/unsloth/GLM-4.7-GGUF?show_file_info=UD-Q2_K_XL%2FGLM-4.7-UD-Q2_K_XL-00001-of-00003.gguf
https://huggingface.co/unsloth/GLM-4.7-GGUF?show_file_info=UD-Q2_K_XL%2FGLM-4.7-UD-Q2_K_XL-00002-of-00003.gguf
https://huggingface.co/unsloth/GLM-4.7-GGUF?show_file_info=UD-Q2_K_XL%2FGLM-4.7-UD-Q2_K_XL-00003-of-00003.gguf
一、背景
我们有一台多节点集群,目标是部署一个单实例大模型(GGUF 文件,约 135GB),让模型充分利用整个节点的 CPU 和内存资源,同时通过 REST API 提供文本生成服务。
硬件环境(以 k8s-worker2 为例)
1 2 3 4 5 6 7 8 9 10 11
| lscpu ````
输出核心信息:
* CPU: 128 核(2 Socket × 32 核 × 2 线程/核) * NUMA 节点: 8 * 内存: 1.8TB
```bash free -h
|
- 总内存: 1.8T
- 已用: 86G
- 可用: 1.6T
说明内存和 CPU 资源都非常充裕,适合单实例部署大模型。
二、初始部署尝试
最初我们使用以下 Deployment YAML 配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| apiVersion: apps/v1 kind: Deployment metadata: name: glm-server spec: replicas: 1 selector: matchLabels: app: glm-server template: metadata: labels: app: glm-server spec: containers: - name: glm-server image: ghcr.io/ggml-org/llama.cpp:server args: - "-m" - "/models/GLM-4.7-UD-Q2_K_XL-00001-of-00003.gguf" - "--port" - "8181" - "--ctx-size" - "4096" - "--mmap" - "--chat-template" - "glm4" - "-c" - "32" ports: - containerPort: 8181 volumeMounts: - name: model-volume mountPath: /models resources: limits: memory: "200Gi" cpu: "32" volumes: - name: model-volume hostPath: path: /home/mnt/192.168.1.60/data/models/unsloth type: Directory
|
1️⃣ 问题一:Pod Pending
输出显示:
1
| glm-server-xxx 0/1 Pending ...
|
kubectl describe pod glm-server-xxx 显示:
1
| Warning FailedScheduling ... 0/3 nodes are available: 1 Insufficient cpu ...
|
原因:Pod 请求 CPU/内存资源过高,或者 NodeSelector 限制了节点,导致调度失败。
2️⃣ 问题二:Pod CrashLoopBackOff
当尝试将 CPU、内存调大,或者启用 NUMA 绑定时:
1 2 3 4 5 6 7 8 9 10 11 12
| args: - "numactl" - "--interleave=all" - "./server" - "-m" ... resources: limits: cpu: 128 memory: 500Gi requests: cpu: 8 memory: 32Gi
|
Pod 状态变为:
1 2
| CrashLoopBackOff Exit Code: 127
|
原因:容器内缺少 numactl 或命令路径错误,需要确保镜像内已经安装 numactl,并且 server 路径正确。
三、优化部署策略
根据节点资源与模型需求,采取以下措施:
增加 CPU 核数和内存限制
- 单实例请求 64 核、200Gi 内存
- 限制可用 128 核、300-400Gi 内存
- 保证单实例可以加载完整 GGUF 模型
NUMA 优化
- 对大模型推荐使用
numactl --interleave=all,在多 NUMA 节点之间均匀分配内存
- 或者绑定部分核心和内存,保证性能稳定
HostPath 挂载模型文件
- 模型文件过大(135G),直接挂载宿主机目录
- 避免使用容器镜像内嵌模型,减小镜像体积
最终 YAML 示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| apiVersion: apps/v1 kind: Deployment metadata: name: glm-server spec: replicas: 1 selector: matchLabels: app: glm-server template: metadata: labels: app: glm-server spec: containers: - name: glm-server image: ghcr.io/ggml-org/llama.cpp:server command: - "/bin/bash" - "-c" args: - | echo "====== CPU ======"; lscpu echo "====== MEM ======"; free -h echo "====== STARTING GLM ======"; numactl --interleave=all /app/server \ -m /models/GLM-4.7-UD-Q2_K_XL-00001-of-00003.gguf \ --port 8181 --host 0.0.0.0 --ctx-size 4096 --mmap \ --chat-template glm4 -c 128 ports: - containerPort: 8181 volumeMounts: - name: model-volume mountPath: /models resources: limits: cpu: "128" memory: "500Gi" requests: cpu: "64" memory: "200Gi" volumes: - name: model-volume hostPath: path: /home/mnt/192.168.1.60/data/models/unsloth type: Directory
|
四、Pod 调试
- 检查 Pod 状态:
1 2 3
| kubectl get pods kubectl describe pod glm-server-xxxx kubectl logs -f glm-server-xxxx
|
- 确认模型服务健康:
1 2
| curl http://<pod-ip>:8181/health
|
五、调用模型 API
1️⃣ 使用 curl 调用 completions
1 2 3 4 5 6 7
| curl -X POST http://10.244.126.56:8181/v1/completions \ -H "Content-Type: application/json" \ -d '{ "model": "GLM-4.7-UD-Q2_K_XL", "prompt": "介绍一下自己", "max_tokens": 100 }'
|
返回示例:
1 2 3 4 5 6 7 8 9
| { "choices":[ { "text":"我是一个喜欢写代码的人,写代码对我来说不仅仅是工作,更是一种乐趣...", "index":0 } ], "model":"GLM-4.7-UD-Q2_K_XL-00001-of-00003.gguf" }
|
2️⃣ 长文本请求示例
1 2 3 4 5 6 7
| curl -X POST http://10.244.126.56:8181/v1/completions \ -H "Content-Type: application/json" \ -d '{ "model": "GLM-4.7-UD-Q2_K_XL", "prompt": "用python写一个俄罗斯方块游戏", "max_tokens": 1000 }'
|
返回完整代码片段,支持直接执行。
注意:/chat 接口在该版本中不可用,会返回 404。
六、总结经验
资源调优
- 根据硬件资源调整 CPU、内存、NUMA 策略
- 大模型单实例可以充分利用多 NUMA 节点
镜像与依赖
- 确认容器内有
numactl 等必要工具
- 模型文件直接挂载宿主机,避免拉取大镜像
调试技巧
kubectl describe pod 查看调度和事件
kubectl logs 查看容器启动信息
/health 检查模型是否可用
调用方式
/v1/completions 是通用接口
- 大模型生成长文本时,需要适当增加
max_tokens
经过多次尝试,最终成功在单实例中跑满 CPU 并加载 135G 模型,提供可用的 REST API 调用。