【大模型Qwen3.8 27B】llama.cpp 本地大模型部署与使用

llama.cpp 本地大模型部署与使用文档

环境:Ubuntu 26.04(kernel 7.0.0-34)+ AMD Radeon RX 7900 XTX 24GB(gfx1100)+ Granite Ridge 核显

部署:llama.cpp b11227(Vulkan/RADV) + Qwen3.8-27B UD-Q4_K_M (16.46GB)

当前配置:上下文 131072(128k) ,KV q4_0,MTP 投机解码,显存 19.98GB (留 ~4GB 余量)

实测:prefill 387--781 tok/s ,decode 37.7--72 tok/s

prompt cache 已验证 :32k 文档重复请求 48.4s → 0.5s

服务:systemd 开机自启,监听 0.0.0.0:8080


0. 方案要点(为什么这样配)

配置 原因
KV cache 用 q4_0 量化 RDNA3没有原生 FP8 支持 ,KV 压缩只能用整数路径。本模型 64 层中 16 层是全注意力,fp16 KV 要 64 KiB/token (128k 需 8.6GB,加权重必然超 24GB);q4_0 只要 16.5 KiB/token(128k 仅 2.2GB)
用 Vulkan 而非 ROCm/HIP 官方提供预编译 Vulkan 二进制,免编译、免补丁、免 ROCm,开箱即用
-fa on 必开 Flash Attention 是长上下文 + KV 量化的前提,不开则 90k 以上上下文创建失败
开 MTP 投机解码 GGUF 自带 BF16 MTP 头,decode 速度约翻倍(36 → 66+ tok/s),无需额外模型文件
--parallel 1 MTP 是单流优化,多并发会失去投机收益
GGML_VK_VISIBLE_DEVICES=1 本机有核显 + 独显两块 Vulkan 设备,必须锁定独显(见 §5.1)

能力边界 :24GB 单卡上,128k 上下文占 20GB(留 4GB 余量);把 -c 调到 262144 可达 256k 窗口(实测吃到 248,872 token),但显存会吃满(24.1GB)且长上下文速度下降(见 §3.5)。


1. 环境前提

项目 本机 说明
GPU RX 7900 XTX 24GB(Vulkan1)+ 核显(Vulkan0) 必须锁定独显(见 §5.1)
Vulkan 运行时 libvulkan1 1.4.341 + mesa-vulkan-drivers 26.0.8(RADV) + vulkan-tools 26.04 默认已装,无需额外安装
磁盘 GGUF 16.46GB + 二进制 31MB 当前可用 38GB
内存占用 19.98GB @128k / 24.14GB @256k 128k 配置留 ~4GB 余量
依赖 无 ------ 不需要 ROCm、不需要编译 预编译 Vulkan 版开箱即用

2. 安装步骤(实际执行过的)

2.1 确认 Vulkan 运行时

bash 复制代码
ls /usr/share/vulkan/icd.d/          # 应看到 radeon_icd.json
dpkg -l | grep -E "libvulkan1|mesa-vulkan-drivers|vulkan-tools"

2.2 下载 llama.cpp 预编译 Vulkan 版

bash 复制代码
mkdir -p /home/<用户名>/llm/llama-vk && cd /home/<用户名>/llm/llama-vk
# GitHub 直连在国内不通,走 gh-proxy 镜像
curl -fL --max-time 1800 -o llama-vulkan.tar.gz \
  "https://gh-proxy.com/https://github.com/ggml-org/llama.cpp/releases/download/b11227/llama-b11227-bin-ubuntu-vulkan-x64.tar.gz"
tar xzf llama-vulkan.tar.gz          # 得到 /home/<用户名>/llm/llama-vk/llama-b11227/

2.3 下载模型(GGUF)

选 unsloth/Qwen3.8-27B-GGUF 的 Qwen3.8-27B-UD-Q4_K_M.gguf (16,464,440,224 字节),

GGUF 里自带 BF16 MTP 头,投机解码无需额外文件。

bash 复制代码
cat > /tmp/dl_gguf.py <<'EOF'
import os
os.environ["HF_ENDPOINT"] = "https://hf-mirror.com"
os.environ["HF_HUB_DISABLE_XET"] = "1"     # 必须:Xet 协议镜像不支持(401)
from huggingface_hub import hf_hub_download
print(hf_hub_download("unsloth/Qwen3.8-27B-GGUF",
      "Qwen3.8-27B-UD-Q4_K_M.gguf", local_dir=os.path.expanduser("~") + "/llm/models/gguf"))
EOF
python3 /tmp/dl_gguf.py

2.4 确认 GPU 设备编号

bash 复制代码
cd /home/<用户名>/llm/llama-vk/llama-b11227
LD_LIBRARY_PATH=. ./llama-server --list-devices

本机输出:

复制代码
Vulkan0: AMD Radeon Graphics    ← 核显,别用
Vulkan1: Radeon RX 7900 XTX     ← 独显,目标

2.5 安装 systemd 服务(当前生效的配置)

单元文件里必须写绝对路径 :把 <用户名> 换成实际运行服务的 Linux 用户(例如 /home/alice/...)。

⚠️ systemd 单元不展开 ~ ,所以这里一律写成 /home/<用户名>/llm/...;也可以用 systemd 的 %h 代替家目录(如 %h/llm/llama-vk/llama-b11227)。

bash 复制代码
sudo tee /etc/systemd/system/llama-server.service > /dev/null <<'EOF'
[Unit]
Description=llama.cpp server (Qwen3.8-27B UD-Q4_K_M, 128k ctx, q4_0 KV, MTP spec-decode)
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=<用户名>
WorkingDirectory=/home/<用户名>/llm/llama-vk/llama-b11227
SupplementaryGroups=video render
Environment=PATH=/usr/local/bin:/usr/bin:/bin
Environment=LD_LIBRARY_PATH=/home/<用户名>/llm/llama-vk/llama-b11227
Environment=GGML_VK_VISIBLE_DEVICES=1
ExecStart=/home/<用户名>/llm/llama-vk/llama-b11227/llama-server \
  -m /home/<用户名>/llm/models/gguf/Qwen3.8-27B-UD-Q4_K_M.gguf \
  -c 131072 -ngl 999 -fa on \
  -ctk q4_0 -ctv q4_0 \
  --spec-type draft-mtp --spec-draft-n-max 2 --parallel 1 \
  --jinja \
  --host 0.0.0.0 --port 8080
Restart=always
RestartSec=10
TimeoutStartSec=1800
StandardOutput=append:/home/<用户名>/llm/llama-server.log
StandardError=append:/home/<用户名>/llm/llama-server.log

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now llama-server.service

3. 使用

3.1 服务管理

bash 复制代码
systemctl status llama-server        # 状态
systemctl restart llama-server       # 重启(改参数后)
systemctl stop llama-server          # 停止
systemctl disable llama-server       # 取消开机自启
tail -f /home/<用户名>/llm/llama-server.log       # 看日志(含 prefill 进度、每条请求计时)

启动到可用约 15--30 秒(等待期间 health 返回 000/503 属正常)。

3.2 调用 API

服务同时提供 OpenAI 兼容接口和 llama.cpp 原生接口。

bash 复制代码
# 对话(OpenAI 格式,客户端推荐用这个)
curl http://127.0.0.1:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen3.8",
    "messages": [{"role": "user", "content": "介绍一下 ROCm"}],
    "max_tokens": 512,
    "temperature": 0.7
  }'

# 流式(打字机效果)
curl http://127.0.0.1:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model":"qwen3.8","messages":[{"role":"user","content":"讲个故事"}],
       "max_tokens":800,"stream":true}'

# 原生接口(返回详细 timings,便于看速度)
curl http://127.0.0.1:8080/completion \
  -H "Content-Type: application/json" \
  -d '{"prompt":"写一首关于星空的短诗:","n_predict":256}'

# 运维接口
curl http://127.0.0.1:8080/health        # 200 = 正常
curl http://127.0.0.1:8080/v1/models     # 模型信息(含 n_ctx)
curl http://127.0.0.1:8080/props         # 服务器完整配置

Python 客户端:

python 复制代码
from openai import OpenAI
client = OpenAI(base_url="http://127.0.0.1:8080/v1", api_key="EMPTY")
r = client.chat.completions.create(
    model="qwen3.8",
    messages=[{"role": "user", "content": "你好"}],
    max_tokens=300)
print(r.choices[0].message.content)

响应 usage.prompt_tokens_details.cached_tokens 会告诉你这次复用了多少缓存 token。

3.3 访问方式

场景 地址
服务器本机 http://127.0.0.1:8080
局域网其他设备 http://<服务器IP>:8080(监听 0.0.0.0)

3.4 关键启动参数

参数 值 含义
-m /home/<用户名>/llm/models/gguf/Qwen3.8-27B-UD-Q4_K_M.gguf 模型文件
-c 131072 上下文长度(128k)。可调到 262144(256k,已验证,但显存吃满)
-ngl 999 --- 全部层卸载到 GPU
-fa on --- Flash Attention(必须开,长上下文+KV 量化的前提)
-ctk q4_0 / -ctv q4_0 --- K/V cache 量化(关键:不量化则 90k 以上上下文创建失败)
--spec-type draft-mtp --- 启用模型自带 MTP 投机解码(decode 提速约 1 倍)
--spec-draft-n-max 2 --- 每轮草稿 token 数(同卡实测 2 最优)
--parallel 1 --- 单并发(MTP 最优设置,多并发会失去投机收益)
GGML_VK_VISIBLE_DEVICES=1 环境变量 只暴露独显,避免误用核显

3.5 常用调整

bash 复制代码
sudo nano /etc/systemd/system/llama-server.service   # 改 -c / --spec-draft-n-max 等
sudo systemctl daemon-reload && sudo systemctl restart llama-server

上下文长度的取舍(都是实测值):

-c 值 最大输入 显存 满载冷 prefill 满载 decode
131072(当前) 128k 20.0 GB(留 4GB) 5.4 min 37.7 tok/s
262144 256k(实测 248,872) 24.1 GB(无余量) 16.9 min 25.6 tok/s

从 128k 切到 256k 的命令:

bash 复制代码
sudo sed -i 's/-c 131072/-c 262144/' /etc/systemd/system/llama-server.service
sudo systemctl daemon-reload && sudo systemctl restart llama-server
  • 想要更高解码速度 :把 --spec-draft-n-max 在 2--4 之间 sweep
  • 需要并发服务 :去掉 --parallel 1 并提高数值,但 MTP 收益会消失

4. 性能实测(本机,2026-09-28)

4.1 长上下文吞吐(q4_0 KV,MTP 开)

实际输入 prefill decode 备注
4k 781 tok/s 66.0 tok/s
34k 675 tok/s 55.4 tok/s
124k 387 tok/s(321.6s) 37.7 tok/s 128k 配置的满载区间
155,548 342.5 tok/s(454.1s) 35.7 tok/s *需-c 262144
248,872(≈95% 窗口) 245.8 tok/s(1012.6s) 25.6 tok/s *需-c 262144
  • prefill 速度随上下文增长而下降(4k 781 → 250k 246 tok/s),这是注意力计算量增长的必然结果
  • MTP 全程生效:日志 draft acceptance = 0.625, mean len = 2.25(250k 场景)
  • 短请求(~100 token 生成)实测 decode 可达 71.9 tok/s
  • 显存:131k 19.98GB ,262k 24.14GB

4.2 prompt cache 实测(32,260 token 文档)

请求 耗时 复用 token 实际 prefill
① 首次(冷启动) 48.4s 0 32,260 token(695 tok/s)
② 完全相同的请求 0.5s 32,256 仅 4 token
③ 同文档 + 新问题 1.5s 31,744 仅新增 517 token

结论 :一份长文档只需付一次 prefill;之后每轮提问 1--2 秒 出首字。

这是长上下文能实用的关键 ------ 例如 128k 文档首次 5.4 分钟,之后每次追加提问只要 1 秒级。

4.3 设备与显存读数注意

  • rocm-smi 把 RADV(Vulkan) 的分配记在 GTT 而不是 VRAM(本机 VRAM 读数恒为 ~28MB,实际占用看 GTT)
  • 判断有没有用对显卡,看 decode 速度:>50 tok/s = 独显正常;<5 tok/s = 误用核显

5. 踩坑与排错

5.1 双 GPU 必须锁定独显(最容易踩)

本机有两块 Vulkan 设备(核显 Vulkan0 / 独显 Vulkan1)。两个过滤方式不能叠加:

ini 复制代码
Environment=GGML_VK_VISIBLE_DEVICES=1   # 只保留独显 → 它变成 Vulkan0
ExecStart=... -dev Vulkan1              # ❌ 再指定 Vulkan1 就找不到了

→ 报错 error while handling argument "-dev": invalid device: Vulkan1 并无限重启。

正确做法(当前配置) :只用 GGML_VK_VISIBLE_DEVICES=1,不加 -dev。

5.2 常见现象对照

症状 原因 / 解决
health 返回 000/503 模型还在加载,等 15--60 秒
服务反复重启,日志有invalid device 设备过滤叠加了,见 §5.1
上下文创建失败(90k 以上) 没加-ctk q4_0 -ctv q4_0,或没开 -fa on
decode 只有几 tok/s 用了核显,或权重掉到系统内存(检查是否有其他程序占显存)
生成速度比预期慢很多 --parallel 设成了 >1,MTP 收益消失
长 prompt"卡住"很久 正常:看日志prompt processing, progress = 0.xx 有进度;也可 rocm-smi --showuse 确认 GPU 100%
输入超上限报错 输入超过-c 设定值;调大 -c 或缩短输入

复制代码
相关推荐
吃饱了得干活3 小时前
从 LLM 到 Agent:一文彻底搞懂什么是 AI Agent
llm·agent
李航19833 小时前
给自己的图形引擎,配上了AI渲染,做设计真是太方便了
人工智能·python·计算机视觉·ai·ai编程
笑小枫3 小时前
AgentScope 学习系列(开篇):Java 开发者如何搭建企业级智能体
agent·智能体开发·agentscope·java开发智能体
染指11104 小时前
128.Agent-LangChain核心组件-中间件-调用模型的时候
人工智能·windows·中间件·langchain·agent
似梦的苏烟4 小时前
gradio快速入门
agent
玫瑰互动GEO4 小时前
开发者学GEO优化:从算法基础到CoT推理链
大数据·人工智能·ai·geo·ai搜索·geo优化
voipmaker4 小时前
AI 赋能安防系统演进:从硬件单品到场景化融合调度架构
人工智能·ai·架构
做cv的小昊4 小时前
【World Model】π0.5:a Vision-Language-Action Model with Open-World Generalization
人工智能·算法·机器学习·大模型·多模态·vla·世界模型
玫瑰互动GEO5 小时前
GEM优化的三层量化维度:答案层·交互层·交易意图层
ai·ai助手·gem·gem优化·生成式引擎营销