🎉目的:解决GLM Coding Plan调用触发到限流,遂决定在本地电脑部署GLM-4.7-Flash
📖 在 RTX 5060 Ti 上部署 GLM-4.7-Flash 并接入 Claude Code 终极教程
🎯 教程目标
GLM-4.7-Flash参数量在30B,若在 RTX 5060 Ti (16GB显存) 上,需要使用 llama.cpp 部署 GLM-4.7-Flash 4-bit量化模型,并通过一个 OpenAI兼容的代理,让 Claude Code 等客户端能够直接调用。
⚙️ 核心配置
- 硬件: NVIDIA RTX 5060 Ti (16GB VRAM, CUDA 12.9)
- 系统: WSL2 (Ubuntu)
- 模型: GLM-4.7-Flash-UD-Q4_K_XL.gguf (来自 unsloth)
- 核心工具: llama.cpp + 自定义FastAPI代理
📝 第一阶段:基础环境与模型准备
1.1 解决WSL网络代理(关键前提)
确保WSL能通过Windows上的Clash访问外网。
# 获取Windows主机在WSL内的IP
export WIN_IP=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}')
# 设置代理环境变量(端口默认7890)
export http_proxy=http://$WIN_IP:7890
export https_proxy=http://$WIN_IP:7890
1.2 安装系统依赖
sudo apt-get update
sudo apt-get install -y build-essential cmake curl libcurl4-openssl-dev
1.3 安装并配置CUDA 12.9
RTX 50系列必须使用CUDA 12.9+。
- 从NVIDIA官网下载CUDA 12.9安装包。
- 安装后,将CUDA路径加入环境变量(临时):
export PATH=/usr/local/cuda-12.9/bin:$PATH export LD_LIBRARY_PATH=/usr/local/cuda-12.9/lib64:$LD_LIBRARY_PATH
🛠️ 第二阶段:编译与运行 llama.cpp
2.1 编译支持CUDA的llama.cpp
git clone https://github.com/ggml-org/llama.cpp
cd llama.cpp
mkdir -p build && cd build
cmake .. -DBUILD_SHARED_LIBS=OFF -DGGML_CUDA=ON -DLLAMA_OPENSSL=ON
cmake --build . --config Release -j --target llama-server
关键点:编译目标为 llama-server(不是 server)。
2.2 下载GLM-4.7-Flash GGUF模型
# 创建模型目录
mkdir -p ~/models
cd ~/models
# 使用代理下载量化模型(示例链接,请以实际可用为准)
curl -L -o GLM-4.7-Flash-UD-Q4_K_XL.gguf "https://huggingface.co/unsloth/GLM-4.7-Flash-GGUF/resolve/main/GLM-4.7-Flash-UD-Q4_K_XL.gguf"
2.3 启动llama-server后端服务
cd ~
./llama.cpp/build/bin/llama-server \
-m ~/models/GLM-4.7-Flash-UD-Q4_K_XL.gguf \
--host 0.0.0.0 \
--port 8080 \
--ctx-size 16384 \
--threads -1 \
--n-gpu-layers 99
重要:启动时不要使用 --chat-template 参数,避免兼容性问题。后续通过代理将响应格式转换。
验证后端:测试原始接口是否工作。
curl http://localhost:8080/completion \
-H "Content-Type: application/json" \
-d '{
"prompt": "<|im_start|>user\n你好<|im_end|>\n<|im_start|>assistant\n",
"n_predict": 50,
"stop": ["<|im_end|>"]
}'
成功将返回:{"content":"你好!很高兴为你服务。"...}
🔌 第三阶段:构建OpenAI兼容代理
3.1 创建Python虚拟环境并安装依赖
python3 -m venv ~/venv
source ~/venv/bin/activate
pip install fastapi uvicorn requests
3.2 创建代理脚本 glm_openai_proxy.py
将以下脚本保存到 ~/glm_openai_proxy.py。这是本教程的核心,它精确实现了GLM格式与OpenAI API的转换。
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import requests
import uvicorn
LLAMA_SERVER_URL = "http://127.0.0.1:8080/completion"
app = FastAPI()
class Message(BaseModel):
role: str
content: str
class ChatRequest(BaseModel):
model: str
messages: list[Message]
max_tokens: int = 200
def convert_to_glm_prompt(messages: list[Message]) -> str:
"""将OpenAI messages转换为GLM精确格式。"""
combined_user_content = []
prompt_parts = []
for msg in messages:
if msg.role in ['system', 'user']:
combined_user_content.append(msg.content)
elif msg.role == 'assistant':
if combined_user_content:
user_text = "\n".join(combined_user_content)
prompt_parts.append(f"<|im_start|>user\n{user_text}<|im_end|>")
combined_user_content = []
prompt_parts.append(f"<|im_start|>assistant\n{msg.content}<|im_end|>")
if combined_user_content:
user_text = "\n".join(combined_user_content)
prompt_parts.append(f"<|im_start|>user\n{user_text}<|im_end|>")
prompt_parts.append("<|im_start|>assistant\n")
return "\n".join(prompt_parts)
@app.post("/v1/chat/completions")
async def chat_completions(request: ChatRequest):
prompt = convert_to_glm_prompt(request.messages)
payload = {
"prompt": prompt,
"n_predict": request.max_tokens,
"temperature": 0.7,
"stop": ["<|im_end|>", "<|im_start|>"]
}
try:
resp = requests.post(LLAMA_SERVER_URL, json=payload, timeout=60)
resp.raise_for_status()
data = resp.json()
except Exception as e:
raise HTTPException(status_code=500, detail=f"后端调用失败: {e}")
return {
"id": "chatcmpl-local-glm",
"object": "chat.completion",
"choices": [{
"index": 0,
"message": {"role": "assistant", "content": data.get("content", "").strip()},
"finish_reason": "stop"
}],
"usage": {
"prompt_tokens": len(prompt),
"completion_tokens": len(data.get("content", "")),
"total_tokens": len(prompt) + len(data.get("content", ""))
}
}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=5001)
3.3 启动代理服务
source ~/venv/bin/activate
python ~/glm_openai_proxy.py
服务将在 http://0.0.0.0:5001 运行,提供 /v1/chat/completions 端点。
验证代理:
curl http://localhost:5001/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "GLM-4.7-Flash-UD-Q4_K_XL.gguf",
"messages": [{"role": "user", "content": "你好"}],
"max_tokens": 100
}'
测试效果
🚀 第四阶段:一键部署与管理脚本
4.1 创建启动脚本 start_glm_service.sh
#!/bin/bash
source ~/venv/bin/activate
# 启动后端
nohup ~/llama.cpp/build/bin/llama-server \
-m ~/models/GLM-4.7-Flash-UD-Q4_K_XL.gguf \
--host 0.0.0.0 --port 8080 \
--ctx-size 8192 --n-gpu-layers 40 \
> ~/llama.log 2>&1 &
echo $! > ~/llama.pid
sleep 10
# 启动代理
nohup python ~/glm_openai_proxy.py > ~/proxy.log 2>&1 &
echo $! > ~/proxy.pid
echo "服务已启动: 后端(8080), 代理(5001)"
4.2 创建停止脚本 stop_glm_service.sh
#!/bin/bash
kill $(cat ~/proxy.pid 2>/dev/null) 2>/dev/null
kill $(cat ~/llama.pid 2>/dev/null) 2>/dev/null
rm -f ~/proxy.pid ~/llama.pid
echo "服务已停止"
授权并运行:
chmod +x start_glm_service.sh stop_glm_service.sh
./start_glm_service.sh
🖥️ 第五阶段:在 Claude Code 中配置
-
获取Windows主机在局域网中的IP(在Windows命令提示符CMD运行
ipconfig,查看“IPv4地址”)。 -
在 Claude Code 设置中添加自定义模型:
- Base URL:
http://<你的Windows IP>:5001/v1 - Model Name:
GLM-4.7-Flash-UD-Q4_K_XL.gguf - API Key:
sk-local(或留空)
- Base URL:
-
选择该模型,开始与本地部署的GLM-4.7-Flash对话。
🔍 关键问题与解决方案总结(踩坑记录)
| 问题 | 现象 | 解决方案 |
|---|---|---|
| CUDA版本过低 | 编译错误 Unsupported gpu architecture 'compute_120a' | 升级至 CUDA 12.9+ |
| 模型格式不兼容 | API返回乱码或模板描述文本 | 弃用 --chat-template,由代理脚本做精确格式转换 |
| 网络连接失败 | Could not resolve host: github.com | 在WSL中正确配置HTTP代理环境变量 |
| 服务端口冲突 | 连接被拒绝 | 确保 8080 (后端) 和 5001 (代理) 端口可用 |
| 显存不足(OOM) | 模型加载失败 | 降低 --n-gpu-layers (从99降至40) |
📊 性能参考 (RTX 5060 Ti)
- 加载时间: 约30-60秒 (首次加载)
- 推理速度: 约15-40 tokens/秒 (取决于上下文长度)
- 显存占用: 约12-14GB (4-bit量化,
--n-gpu-layers 40) - 内存占用: 约2-3GB
✅ 最终验证
完成所有步骤后,你的本地AI服务栈如下:
- 后端 (
llama-server):http://localhost:8080(原始推理) - 代理 (
glm_openai_proxy.py):http://localhost:5001/v1(OpenAI兼容API) - 客户端 (Claude Code): 通过代理访问本地模型
🎉 成功标志
在Claude Code中成功发送消息并收到GLM-4.7-Flash的中文流畅回复,而非之前的乱码或错误信息。
这份教程凝聚了我解决众多兼容性问题的核心经验。你现在拥有了一套稳定、可重现的部署方案,尽情享受你的本地大模型吧! 如果需要在其他环境部署或有新的需求,可以随时参考此教程。