适用机器:fnOS-Ser8(Ryzen 8845HS + Radeon 780M 核显,系统可用内存约 38GB) 下载方式:wget 断点续传 + 单进程加锁 + 哈希校验 部署方式:docker compose,独立容器 lfm25-24b,端口 8088
本教程里的命令、文件大小、哈希和数据,都来自你这台机器上实际跑过的结果。没有验证过的地方,文中会明确写出来。
0. 先看这里
0.1 约定
所有命令在 SER8 的终端里执行,默认以 root 身份。如果你用普通用户登录,命令前加
sudo凡是
docker compose ...的命令,必须先cd /vol3/1000/docker/lfm25-24b,否则会报service "lfm25-24b" is not running之类的错(这个错你遇到过,原因是当时在 hermes 目录里)终端里中断一个正在运行的命令用 Ctrl+C,不是 Ctrl+X(Ctrl+X 是 nano 编辑器的退出键)
0.2 两个量化版怎么选
实测条件:同一台机器,同一个提问"用200字介绍一下量子计算",上下文 65536,其他服务(Frigate 等)照常运行,数字会有波动。
建议:先装 Q5_K_M,需要时再下 Q6_K 对比。Q6_K 比 Q5_K_M 慢约 15%、多占约 2Gi 内存,只有质量确实更好才值得。
0.3 两个官方校验值(后面要用)
这两个值是从官方仓库页面响应头里取到的,并且你本机下载后的文件校验通过了。文件必须同时满足"大小一致"和"哈希一致"才能用。
1. 准备工作
1.1 检查磁盘空间
df -h /vol3
可用空间要大于 25GB(Q5 和 Q6 都下的话)。你之前剩 449G,足够。
1.2 检查内存、确认没有别的模型在跑
free -h
docker ps --filter "name=llama" --filter "name=lfm25"
free -h看available那一列,空载时应在 26Gi 左右docker ps里如果出现llama-qwen36、llama-glm47、llama-qwen3-2507等模型容器处于Up,先停掉再继续:
docker stop <容器名>
注意:过滤结果里的
ollama只是因为名字里带 "llama" 才被列出来,它不是 llama.cpp 模型容器,不用管。如果想确认 ollama 没有常驻模型:docker exec ollama ollama ps,输出是空表就没问题
铁律:同一时刻只运行一个大模型容器。 你之前把 8GB swap 打满,就是同时跑了两个模型。
1.3 (可选)清理 swap 基线
只在 available 明显大于 swap 已用量时才做,不然会把换出的数据挤回物理内存导致卡死:
free -h
swapoff -a && swapon -a
free -h
不做也不影响后面的步骤。
1.4 创建目录
mkdir -p /vol3/1000/docker/lfm25-24b/models
cd /vol3/1000/docker/lfm25-24b/models
pwd
pwd 应输出 /vol3/1000/docker/lfm25-24b/models。
2. 下载 Q5_K_M(断点续传)
为什么用 wget,不用
hf download:你实测过hf download中途断开后进度基本丢失(缓存里只剩 11MB),不是真正的断点续传。wget -c基于 HTTP Range,断了重跑同一条命令就会接着下。
2.1 确认没有残留的下载进程
pgrep -a wget
必须没有任何输出。 有输出说明已经有下载在跑,不要再启动第二个。
这一步是血的教训:你之前有一次文件变成 49.9GB、哈希对不上,推测是同一个文件被多个 wget 同时写入。所以下载命令只能启动一次。
2.2 确认文件存在
URL="https://huggingface.co/LiquidAI/LFM2.5-24B-A2B-GGUF/resolve/main/LFM2.5-24B-A2B-Q5_K_M.gguf"
curl -sI "$URL" | head -1
输出 HTTP/2 302 就说明文件存在。如果是 404,去 https://huggingface.co/LiquidAI/LFM2.5-24B-A2B-GGUF/tree/main 核对实际文件名。
2.3 启动下载(后台、加锁、只启动一次)
cd /vol3/1000/docker/lfm25-24b/models
nohup flock -n /tmp/lfm-q5.lock wget -c --tries=0 --retry-connrefused --waitretry=5 --read-timeout=30 \
"$URL" > /tmp/lfm-q5.log 2>&1 &
sleep 3
pgrep -a wget
参数说明:
nohup ... &:放到后台,SSH 断开也不会中断flock -n /tmp/lfm-q5.lock:加锁,同一时间只允许一个下载进程,重复执行会直接退出而不是互相写坏文件wget -c:断点续传--tries=0 --retry-connrefused --waitretry=5:无限次重试,每次间隔最多 5 秒--read-timeout=30:30 秒没数据就重连
pgrep -a wget 应该只有 1 行。出现 2 行以上,立即 pkill wget 全部停掉,再从 2.1 重来。
2.4 看进度
tail -f /tmp/lfm-q5.log
日志里每一行末尾的百分比和速度就是进度
Ctrl+C 只是退出查看,下载不会停
目标大小约 17GB,你实测用了约 97 分钟(取决于当时网速)
下载期间旧的模型容器可以继续正常使用,下载占用的内存很少
2.5 断了怎么续传
任何时候下载中断(断网、重启、SSH 掉线),按这个顺序操作:
pgrep -a wget
有输出:说明还在下载,什么都不用做
没有输出但文件没下完:重新执行 2.2 和 2.3 的命令即可,wget 会从已下载的字节处接着下。新开的终端里
URL变量会丢,必须重新设置
2.6 校验(必须做,两项都要通过)
cd /vol3/1000/docker/lfm25-24b/models
ls -l LFM2.5-24B-A2B-Q5_K_M.gguf
echo "7f3029ea2a8e40175496e5022cf7defdcc587df9703d3ed613e64daa51427ecb LFM2.5-24B-A2B-Q5_K_M.gguf" | sha256sum -c -
第一条:大小必须正好是 17029602592
第二条:必须输出
LFM2.5-24B-A2B-Q5_K_M.gguf: OK,算 17GB 要几分钟,耐心等注意哈希和文件名之间是两个空格,别改成一个
任何一项不对,不要加载,见本文第 8 节的排查。
如果将来怀疑官方更新了文件,可以重新取官方值对照:
curl -sI "$URL" | grep -i '^x-linked-etag' curl -sIL "$URL" | grep -i '^content-length' | tail -1
3. 创建 docker compose 配置
cd /vol3/1000/docker/lfm25-24b
cat > docker-compose.yml << 'EOF'
services:
lfm25-24b:
image: ghcr.io/ggml-org/llama.cpp:server-vulkan
container_name: lfm25-24b
restart: unless-stopped
ports:
- "8088:8080"
volumes:
- ./models:/models
devices:
- /dev/dri:/dev/dri
command:
- -m
- /models/LFM2.5-24B-A2B-Q5_K_M.gguf
- -c
- "65536"
- -ngl
- "99"
- --host
- "0.0.0.0"
- --port
- "8080"
EOF
cat docker-compose.yml
逐项说明:
image: ...server-vulkan:必须是 vulkan 版本,核显加速走 Vulkan;普通server镜像是纯 CPUports: "8088:8080":宿主机 8088 对应容器 8080devices: /dev/dri:/dev/dri:把核显设备映射进容器,不能漏-c 65536:上下文长度 64K。Hermes Agent 要求至少 64000,设成 32768 会被拒绝(你遇到过,Hermes 日志报context window of 32,768 tokens, which is below the minimum 64,000)-ngl 99:请求把所有层交给 GPUrestart: unless-stopped:开机自启。如果你不想它随系统启动,删掉这一行
拉取最新镜像:
docker pull ghcr.io/ggml-org/llama.cpp:server-vulkan
4. 启动并验证
4.1 启动
cd /vol3/1000/docker/lfm25-24b
docker compose up -d
docker logs -f lfm25-24b
等日志里依次出现这几行(时间戳前缀会不同):
load_model: loading model '/models/LFM2.5-24B-A2B-Q5_K_M.gguf'
load_model: initializing, n_slots = 4, n_ctx_slot = 65536, ...
llama_server: model loaded
llama_server: listening on http://0.0.0.0:8080
看到 n_ctx_slot = 65536 和 listening on 就是成功了,按 Ctrl+C 退出日志查看(容器不会停)。首次加载可能比你之前看到的 7 秒更久。
日志里的两条警告可以忽略:
LLAMA_ARG_HOST environment variable is set, but will be overwritten by command line argument --host:只是命令行参数覆盖了环境变量CORS is set to allow all origins and no API key is set:提醒你这个端口没有密钥保护,局域网内任何人都能调用。不要把 8088 映射到公网
4.2 确认加载的是哪个文件
curl -s http://localhost:8088/v1/models | grep -o 'LFM2.5-24B-A2B-[A-Za-z0-9_]*' | head -1
应输出 LFM2.5-24B-A2B-Q5_K_M。
4.3 确认核显被识别
docker exec lfm25-24b /app/llama-server --list-devices
应看到类似:
Vulkan0: AMD Radeon 780M Graphics (RADV PHOENIX) (...)
括号里的显存数字我们两次看到过不同的值,原因不明,不影响判断,只要识别出 780M 即可。
需要说明的是:这一步只能确认核显被识别,我们没能验证模型层有多少真正被卸载到核显上运行(服务日志没有打印卸载信息,radeontop 生成期间的计算负载也很低)。所以别把它当成"核显加速已生效"的证明,速度以第 5 步的实测为准。
5. 测速和看内存
5.1 测生成速度
curl -s http://localhost:8088/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"messages":[{"role":"user","content":"用200字介绍一下量子计算"}]}' | grep -o '"predicted_per_second":[0-9.]*'
这条命令会卡一两分钟没有输出,是正常的:这个模型默认带很长的思考过程(你实测过一个简单问题生成了 4655 个 token、耗时约 131 秒),不是卡死了,耐心等。
参考值:Q5_K_M 约 35.56,Q6_K 约 30.31(单位 t/s)。
5.2 看内存
free -h
重点看 available:
Q5_K_M 加载后实测 11Gi
Q6_K 加载后实测 8.8Gi
建议警戒线:
available低于 5Gi,或 swap 在使用中持续上涨,就说明太紧了,换更小的量化或停掉别的服务(这条警戒线是我给的经验值,不是官方数值)
free 列显示很小(几百 MB)是正常的,内核把空闲内存拿去做缓存了,看 available 才准。docker stats 里的内存数字不要参考,模型是文件映射加载的,那个统计算不进去。
6. 下载 Q6_K 并切换(可选)
Q6_K 的下载流程与第 2 节完全相同,只是文件名、锁文件、日志名、大小和哈希不同。下载期间 Q5_K_M 容器可以照常运行。
6.1 下载
pgrep -a wget
必须没有输出,再继续:
URL="https://huggingface.co/LiquidAI/LFM2.5-24B-A2B-GGUF/resolve/main/LFM2.5-24B-A2B-Q6_K.gguf"
curl -sI "$URL" | head -1
cd /vol3/1000/docker/lfm25-24b/models
nohup flock -n /tmp/lfm-q6.lock wget -c --tries=0 --retry-connrefused --waitretry=5 --read-timeout=30 \
"$URL" > /tmp/lfm-q6.log 2>&1 &
sleep 3
pgrep -a wget
tail -f /tmp/lfm-q6.log
curl应输出HTTP/2 302pgrep只能有 1 行Ctrl+C 只退出查看;断了续传的规则同 2.5
6.2 校验
cd /vol3/1000/docker/lfm25-24b/models
ls -l LFM2.5-24B-A2B-Q6_K.gguf
echo "4c5f34cb94d4a29f0360d04eaa274bb1361ceae163f40f6361cb75d1bee139c2 LFM2.5-24B-A2B-Q6_K.gguf" | sha256sum -c -
大小必须是 19689405728,哈希必须输出 OK。哈希值直接写在命令里,不要用变量,你之前用 $EXPECT 变量在新终端里是空的,导致 no properly formatted checksum lines found,那不是文件问题。
6.3 切换到 Q6_K
cd /vol3/1000/docker/lfm25-24b
sed -i 's|LFM2.5-24B-A2B-Q5_K_M.gguf|LFM2.5-24B-A2B-Q6_K.gguf|' docker-compose.yml
grep -A1 -- "-m" docker-compose.yml
grep -A1 -- "-c" docker-compose.yml
确认两点:-m 后面是 /models/LFM2.5-24B-A2B-Q6_K.gguf,-c 后面仍是 "65536"。然后重建:
docker compose up -d --force-recreate
docker logs -f lfm25-24b
看到 n_ctx_slot = 65536 和 listening on 后 Ctrl+C 退出,再回到第 4.2、5.1、5.2 步验证模型名、速度和内存。
重建期间 8088 端口会短暂不可用,Hermes 此时发消息会失败,属正常现象。
6.4 回退到 Q5_K_M
把 sed 的新旧文件名对调再重建即可:
cd /vol3/1000/docker/lfm25-24b
sed -i 's|LFM2.5-24B-A2B-Q6_K.gguf|LFM2.5-24B-A2B-Q5_K_M.gguf|' docker-compose.yml
docker compose up -d --force-recreate
7. 接入 Hermes
确认容器上下文是 65536(见 4.1 的日志)。低于 64000 Hermes 会直接拒绝,表现为聊天时提示"意外错误"
换了模型文件后,在飞书里发
/reset开启新会话发一句"你好,你是哪个大模型"测试
工具调用本身的返回格式,我们在 unsloth 的 UD-Q4_K_XL 上验证过是规范的 OpenAI JSON 格式(finish_reason: tool_calls,参数解析正确)。在 Q5_K_M 和 Q6_K 上我们没有重复这个测试,如果你发现 Hermes 工具调用异常,用下面这条自测:
curl http://localhost:8088/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"messages":[{"role":"user","content":"现在北京天气怎么样"}],
"tools":[{"type":"function","function":{"name":"get_weather","description":"查询城市天气","parameters":{"type":"object","properties":{"city":{"type":"string"}},"required":["city"]}}}]
}'
返回里应有 "finish_reason":"tool_calls" 和 {"city":"北京"} 这样的参数。
8. 常见问题排查(都是你实际遇到过的)
9. 清理与停用
9.1 清掉下载残留
rm -rf /vol3/1000/docker/lfm25-24b/models/.cache
这是 hf download 留下的缓存和 0 字节锁文件,只用 wget 下载的话本来就没有,有的话就删,不影响 .gguf 文件。
9.2 确定用哪个版本后,删掉另一个释放空间
rm -f /vol3/1000/docker/lfm25-24b/models/LFM2.5-24B-A2B-Q6_K.gguf
(留 Q5_K_M 时删 Q6_K;反过来则删 Q5_K_M。删之前确认 compose 里 -m 指向的是你要留的那个。)
9.3 停止服务
cd /vol3/1000/docker/lfm25-24b
docker compose down
9.4 切到别的模型之前
lfm25-24b 是独立 compose,不受你其他模型切换脚本的互斥保护。启动别的 llama.cpp 模型容器前,先手动:
docker stop lfm25-24b
10. 下一步
Q6_K 的质量是否真的比 Q5_K_M 好,目前还没有验证。完成上面的安装后,可以用另外提供的 quant_eval.py 做固定题集的对比,配合你的 Hermes Probe 看工具调用表现,再决定留哪个。
附:命令速查
# 查下载进程(必须只有 0 或 1 行)
pgrep -a wget
# 看下载进度
tail -f /tmp/lfm-q5.log # Q5
tail -f /tmp/lfm-q6.log # Q6
# 服务日志 / 重建 / 停止(compose 命令先 cd 到 /vol3/1000/docker/lfm25-24b)
docker logs -f lfm25-24b
docker compose up -d --force-recreate
docker compose down
# 当前加载的是哪个模型
curl -s http://localhost:8088/v1/models | grep -o 'LFM2.5-24B-A2B-[A-Za-z0-9_]*' | head -1
# 内存
free -h
评论区