本文总结了我们在 Windows + WSL Ubuntu 环境中,把 Med-Copilot-7B 量化模型部署到本地 CPU,并进一步尝试通过本地 API 和简易 Agent 控制器调用它的全过程。
1. 整体目标
我们的目标不是训练模型,而是:
- 在本地 CPU 上运行 Med-Copilot-7B。
- 用
llama.cpp加载 GGUF 量化模型。 - 启动一个本地 API 服务。
- 用
curl和 Python 调用本地模型。 - 进一步尝试让模型作为 Agent 调用工具执行任务。
最终结构大致是:
text
Windows 电脑
└── WSL Ubuntu
├── MedCopilot-7B.Q4_K_M.gguf
├── llama.cpp
├── llama-server 本地 API
└── Python Agent 控制脚本
2. 为什么选择 Q4_K_M 量化
我们使用的模型文件是:
text
MedCopilot-7B.Q4_K_M.gguf
拆开理解:
text
MedCopilot-7B = 模型名称,约 70 亿参数
Q4_K_M = 4-bit K-quant Medium 量化格式
gguf = llama.cpp 使用的模型格式
为什么需要量化
原始 FP16 7B 模型大约需要:
text
7B × 2 bytes ≈ 14GB
再加上运行时内存、上下文缓存,15GB 内存机器很容易吃紧。
量化后:
text
FP16 7B:约 14GB+
Q8 7B:约 7GB+
Q4 7B:约 4GB~5GB
所以 Q4_K_M 是比较适合 CPU 本地部署的平衡选择。
量化的代价
量化会牺牲一点模型精度和稳定性。
我们后面看到模型 JSON 输出不稳定,原因包括:
- Med-Copilot-7B 本身是小模型。
- 它是 Agent 风格模型,不是普通聊天模型。
- Q4 量化可能进一步影响格式遵循能力。
- 我们自己写的 Agent controller 还很简陋。
3. 用 llama-cli 测试模型是否能跑
执行:
bash
cd ~/llama.cpp
./build/bin/llama-cli \
-m ~/models/medcopilot-7b/MedCopilot-7B.Q4_K_M.gguf \
-cnv \
-c 2048 \
-t 10
参数解释:
text
-m 指定模型文件
-cnv conversation 聊天模式
-c 2048 上下文长度
-t 10 使用 10 个 CPU 线程
模型成功运行后出现了:
text
Generation: 6.5 t/s
这说明模型已经成功在 CPU 上本地推理。


4. 启动本地 API 服务
执行:
bash
cd ~/llama.cpp
./build/bin/llama-server \
-m ~/models/medcopilot-7b/MedCopilot-7B.Q4_K_M.gguf \
--host 0.0.0.0 \
--port 8000 \
-c 2048 \
-t 10 \
--repeat-penalty 1.35
这一步的作用是把模型变成一个本地服务:
text
http://127.0.0.1:8000
此时窗口不要关闭,因为它就是模型后台服务。
参数解释:
text
llama-server 启动本地 API 服务
--host 0.0.0.0 允许 WSL/本机访问
--port 8000 服务端口
-c 2048 上下文长度
-t 10 CPU 线程数
--repeat-penalty 减少重复输出
5. 用 curl 测试本地 API
另开一个 WSL 终端,执行:
bash
curl -s http://127.0.0.1:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "medcopilot-7b",
"messages": [
{
"role": "system",
"content": "You are Med-Copilot, a biomedical coding agent. Return a JSON action with code when solving coding tasks."
},
{
"role": "user",
"content": "Write Python code to load patients.csv and calculate the mean of the age column."
}
],
"temperature": 0.1,
"max_tokens": 512
}' | jq -r '.choices[0].message.content'
成功后,模型返回了代码,但也出现了重复 validate/debug 的问题。
这说明:
text
本地 API 成功
模型输出不稳定

6. 用 Python 调用本地模型
安装客户端:
bash
pip install openai
注意:这里的 openai 只是 Python 客户端库。
因为我们设置了:
python
base_url="http://127.0.0.1:8000/v1"
所以它调用的是本地模型,不是 OpenAI 云端。
创建测试脚本:
bash
cat > ~/test_medcopilot.py << 'PY'
from openai import OpenAI
client = OpenAI(
base_url="http://127.0.0.1:8000/v1",
api_key="local"
)
resp = client.chat.completions.create(
model="medcopilot-7b",
messages=[
{
"role": "system",
"content": (
"You are a helpful Python coding assistant. "
"Output only valid Python code. "
"Do not output JSON. "
"Do not explain."
)
},
{
"role": "user",
"content": (
"Write Python code to load patients.csv with pandas "
"and print the mean of the age column."
)
}
],
temperature=0,
max_tokens=120
)
print(resp.choices[0].message.content)
PY
运行:
bash
python ~/test_medcopilot.py
这一步确认:
text
Python 脚本 → 本地 llama-server → Med-Copilot → 返回文本
调用链路已经打通。
7. Agent 与 server 的区别
我们明确区分了:
text
Med-Copilot 模型 = 大脑
llama-server = 把大脑开放成 API
Agent = 大脑 + 工具 + 控制循环 + 执行反馈
llama-server 不是 Agent。
它只是模型服务。
真正的 Agent 应该有:
text
任务
↓
模型决定 action
↓
程序执行工具
↓
工具返回 observation
↓
模型继续下一步
↓
最终 finish
8. mini_agent.py:最小代码生成 + 执行闭环
先创建测试 CSV:
bash
cat > ~/patients.csv << 'CSV'
patient_id,age
1,45
2,60
3,75
4,50
CSV
正确答案:
text
57.5
运行 mini_agent.py 后,模型虽然输出了不标准 JSON,但里面包含代码:
python
import pandas as pd
df = pd.read_csv('/home/sabrinaaa/patients.csv')
mean_age = df['age'].astype(float).mean()
answer = mean_age
print(answer)
执行结果:
text
57.5
这说明:
text
本地模型不一定能稳定输出标准 JSON,
但作为代码生成器 + 受控执行器,它可以完成简单任务。

9. 自由工具调用 Agent 的问题
尝试让模型自由选择工具:
text
list_files
inspect_csv
run_python
finish
但模型输出了它更熟悉的动作:
json
{"action": "validate_code"}
以及:
json
{"action": "debug"}
说明:
text
模型不是完全不会做任务,
而是我们的工具协议和它训练时的动作协议不匹配。
后来兼容 validate_code、validate、debug 后,模型仍然容易:
- 编造不存在路径,例如
data/patient_data.csv。 - 把 CSV schema 当作回答复述出来。
- 输出不标准 JSON。
- 在多轮失败后超过 2048 上下文限制。
10. controller 自己的路径替换 bug
有一次模型已经生成正确代码:
python
import pandas as pd
df = pd.read_csv('/home/sabrinaaa/patients.csv')
answer = df['age'].mean()
print(answer)
但 controller 的 clean_code() 错误使用:
python
code = code.replace("patients.csv", CSV_PATH)
导致:
text
/home/sabrinaaa/patients.csv
变成:
text
/home/sabrinaaa//home/sabrinaaa/patients.csv
正确做法是只替换明显错误路径或相对路径:
python
code = code.replace("data/patient_data.csv", CSV_PATH)
code = code.replace("/home/sabrinaaa/patient_data.csv", CSV_PATH)
code = code.replace("./patients.csv", CSV_PATH)
code = code.replace("'patients.csv'", f"'{CSV_PATH}'")
code = code.replace('"patients.csv"', f'"{CSV_PATH}"')
不能盲目替换所有 "patients.csv"。

11. 当前结论
目前已经完成:
text
1. WSL Ubuntu 环境可用
2. Med-Copilot-7B Q4_K_M 模型下载完成
3. llama.cpp 编译完成
4. llama-cli 可以本地推理
5. llama-server 本地 API 可以启动
6. curl 可以调用本地模型
7. Python openai 客户端可以调用本地模型
8. 已经开始构建简易 Agent controller
当前遇到的主要问题:
text
1. Med-Copilot-7B Q4 输出 JSON/action 格式不稳定
2. 自由工具调用对 7B 小模型太难
3. 简易 controller 需要更强的格式校验和纠错
4. 路径清洗逻辑不能太粗暴