Deepseek-Harness 单卡(7900XTX)运行Qwen3.8-27B 完整文档-1
-
将本地 llama.cpp 推理服务接入 DeepSeek Harness (DSH) 的全过程:环境准备、服务部署、shim 开发、DSH 配置、性能测试、日常运维与根因诊断。
本文档合并自《DSH 接入本地模型完整教程》与《本地模型接入 DSH —— 诊断与解决方案》。
实测环境:Ubuntu 22.04 · Intel CPU · 62GB RAM · AMD 7900 XTX (Vulkan, 25.75GB VRAM) · llama.cpp b11223 (Vulkan + MTP + ngram-k4v) · Node.js 24 · Qwen3.8-27B / Qwen3.6-27B (Q4_K_M)
实测日期:2026-09-29(含同日 shim A/B 复核与 k4v 投机解码实测)
目录
本次更新(2026-09-30)
- §9.8(重写)— CTX 从 256K 降到 128K 的根因:
vkAllocateMemory装不下 DEVICE_LOCAL,
Vulkan 把权重退回 GTT,decode 掉到 0.49 tok/s。llama.sh加-cram -1。
下界 64K(Hermes Agent 硬性要求 context >= 64000),上界 128K(实测 ~21.2GB/25.75GB 留余量)。 - §1.1 / §3.1 / §3.2 / §5.1 / §9.4 — 3.8 的 ctx 全面改为 131072;overlay 的
contextWindow: 131072/maxTokens: 32768(原先声明 262144,是超限的直接来源)。 - §3.1 内嵌代码块与
~/llama-bin/llama.sh逐行同步(含 systemd 自动检测、_USER_OVERRIDES机制);
§5.1 与~/llama-bin/dsh-shim-overlay.yml同步。 - 修正 §9.7 的锚点死链(
#97-补充复核shim-ab-与多轮稳定性)。
上次更新(2026-09-29)
- §1.2 / §9.1 / §9.7 — shim 必要性复核:直连
:8080现可正常完成工具调用,
原「直连 0/10」复现不出来;coerce()在 18 次强制采样中零次触发。结论改为
「shim 仍默认启用,但不应再被当作不可替代的必需品」。 - §6.3(新增)— 投机解码 k4v 实测:
code_refactor+30.7%、合成重复 +42.3%,
其余负载零退步。已默认启用,size-n必须 32。 - §3.1 / §5.1 — 内嵌代码块已与
~/llama-bin/下真实文件重新同步。 - §5.1 / §9.2 — overlay 默认模型由 3.6 改为 3.8。
1. 架构概览
1.1 三层架构
DSH (Agent 框架) │ OpenAI 兼容请求 (含 tools 定义) ▼ dsh-llm-shim (:8090, Node.js) │ tool_choice 改为 none,转发纯文本流 ▼ llama.cpp llama-server (Vulkan + MTP) :8080 Qwen3.8-27B (ctx=131072) :8081 Qwen3.6-27B (ctx=196608) ← 两实例互斥1.2 为什么需要 Shim
llama.cpp b11223 早期实测中自带的 tool-call 解析器(peg-native)解析不了 Qwen3.x 的 XML 工具调用:第二个参数起的整段被吞进第一个参数,并诱发模型无限重复 tool_call 标签直到 max_tokens(实测 32768 token / 7.7 分钟,零可用输出)。
shim 的策略:
- 把 tool_choice 强制改为 none,llama.cpp 不做工具语法约束
- 模型原始 XML 完整出现在 message.content 里
- shim 自行把 XML 解析成标准 OpenAI tool_calls
- 检测到重复 tool_call 时立即掐断上游流
方案 成功率 单次耗时 直连 llama.cpp(2026-09-29 首次) 0/10 ~30s(跑飞) 经 shim(同期) 10/10 ~1s
2026-09-29 复核:直连已可用,shim 的必要性需重新评估同日按当前配置重新做 A/B,「直连 0/10」复现不出来:
场景 结果 简单工具直连 :808010/10,无跑飞 DSH 真实复杂 schema(多工具)直连 2/2 上述 + thinking 开启 2/2 dsh headless端到端(仅换 baseURL 端口)66 文件 / ubuntu-ai,与经 shim 完全一致参数类型强制压测(7 字段全 required,含 number/boolean/array/object) 直连 12/12 类型全对、0 次字符串化;经 shim 6/6 原结论只有三种可能:① build 或依赖已变;② 模型行为随采样/上下文漂移;③ 原基准本身有问题。
本轮未能定位到确切原因。因此 shim 仍默认启用,但不应再被当作不可替代的必需品。另见 §9.7 对
coerce()类型强转分支的专项测试。
下线前的判断标准:切直连后连续跑真实 dsh 会话,观察是否出现工具参数校验失败。
2. 环境准备
2.1 硬件要求
组件 最低要求 实测配置 CPU 8 核 x86_64 Intel 多核 RAM 32 GB 62 GB GPU Vulkan 1.3 AMD 25.75 GB VRAM 磁盘 30 GB 可用 NVMe SSD 显存估算:Qwen3.8-27B Q4_K_M 文本约 23.72 GB,加视觉 mmproj 约 24.9 GB。两个 27B 模型不能同时运行。
2.2 软件依赖
依赖 版本 用途 Node.js >= 18 运行 shim(无第三方依赖) llama.cpp b11223 Vulkan 推理引擎 Python >= 3.8 基准测试 Vulkan 驱动 AMDGPU-Pro / Mesa GPU 加速 2.3 模型文件
ls ~/models/ # Qwen3.8-27B-UD-Q4_K_M.gguf (16.4GB) # Qwen3.6-27B-Q4_K_M-mtp.gguf # mmproj-model-bf16.gguf (视觉投影,可选)
3. 部署 llama.cpp 推理服务
3.1 管理脚本 llama.sh
存放到
~/llama-bin/llama.sh:#!/bin/bash # 本地 LLM 服务统一入口 — llama.cpp Vulkan + MTP # # ./llama.sh 38 启动 Qwen3.8-27B (:8080)(默认走 setsid 手动;systemd 托管时请用 systemctl --user start qwen38) # ./llama.sh 36 启动 Qwen3.6-27B (:8081)(顺带拉起 :8090 shim) # ./llama.sh stop 停止全部(38 自动走 systemctl --user stop qwen38,不会被自动拉回) # ./llama.sh status 查看状态 # ./llama.sh 36 --use 停掉当前,换成 3.6 # ./llama.sh 38 --vision 带视觉启动(加载期开关,需重启) # ./llama.sh 38 --fg 前台运行(给 systemd 用) # # 覆盖: CTX=196608 NMAX=2 UB=512 K4V=0 K4V_N=32 API_KEY=xxx MMPROJ=path LOG=path ./llama.sh 38 # 注意: 下面初始化 CTX/NMAX 前必须先抓取环境值,否则 CTX="" 会让 ${CTX:-默认} 失效 ENV_CTX="${CTX:-}"; ENV_NMAX="${NMAX:-}"; ENV_MMPROJ="${MMPROJ:-}"; ENV_EXTRA="${EXTRA:-}" set -uo pipefail BIN_DIR="${BIN_DIR:-$HOME/llama-bin/vulkan/llama-b11223}" BIN="$BIN_DIR/llama-server" SHIM="${SHIM:-$HOME/llama-bin/shim.sh}" # 工具调用中间层(DSH 本地模型用) VRAM_DEV=/sys/class/drm/card0/device # 密钥:独立文件,不进脚本、不进 shell 环境 ENV_FILE="${ENV_FILE:-$HOME/.config/qwen38/api.env}" [ -r "$ENV_FILE" ] && { set -a; . "$ENV_FILE"; set +a; } # profile: 别名|模型文件|ctx|nmax # 均为 qwen35 混合架构: 65 层但 full_attention_interval=4 → 仅 16 层真注意力, # 其余为 SSM 状态(常数大小, 与 ctx 无关). 训练上限均为 262144. # # 2026-09-30: CTX 从 262144 降到 131072。原注释说"多分配的 KV 不花钱"是错的—— # 24GB 卡上 256K 会把模型+KV 顶到 ~26.3GB/24.5GB,vkAllocateMemory 装不下 # DEVICE_LOCAL,Vulkan 后端把全部权重退回 GTT(系统内存)映射:实测 # vis_vram_used=567MiB / gtt_used=23490MiB,decode 掉到 0.49 tok/s、prefill 30 t/s。 # 「只有实际填满多少影响 decode」也不成立——溢出到 GTT 后每个 token 都要走 PCIe。 # # 下界 64K:Hermes Agent 硬性要求 context >= 64000,低于此直接拒绝连接。 # 上界实测:32K→17.4GB,128K→~21.2GB,256K→~26.3GB(爆)。128K 是留余量的最大值。 # 需要更大窗口用 ENV_CTX 覆盖,但别超 ~160K。 P38_ALIAS="qwen3.8-27b"; P38_MODEL="Qwen3.8-27B-UD-Q4_K_M.gguf"; P38_CTX=131072; P38_NMAX=3 P36_ALIAS="qwen3.6-27b"; P36_MODEL="Qwen3.6-27B-Q4_K_M-mtp.gguf"; P36_CTX=196608; P36_NMAX=3 P38_PORT="${P38_PORT:-8080}" P36_PORT="${P36_PORT:-8081}" MMPROJ_FULL="$HOME/models/mmproj-model-bf16.gguf" # 仅 3.8 有效 # 记下「用户自己设的」调优变量。必须在这里取:下面第 45 行起会把 CTX/NMAX 清空 # 并给 UB/HOST/LOG/K4V 赋默认值,等到启动路径上再判断就分不清是用户设的还是默认了。 _TUNABLE="CTX ENV_CTX UB B NMAX ENV_NMAX K4V K4V_N K4V_M K4V_HITS CRAM EXTRA ENV_EXTRA TEMP TOPK CKV CV LOG HOST MMPROJ" _USER_OVERRIDES="" for _v in $_TUNABLE; do [ -n "${!_v-}" ] && _USER_OVERRIDES="$_USER_OVERRIDES $_v"; done KEY=""; ALIAS=""; MODEL=""; CTX=""; NMAX=""; PORT=""; NAME="" case "${1:-}" in 38|qwen38) KEY=38; NAME="Qwen3.8-27B"; ALIAS=$P38_ALIAS; MODEL=$P38_MODEL; CTX="${ENV_CTX:-$P38_CTX}"; NMAX="${ENV_NMAX:-$P38_NMAX}"; PORT=$P38_PORT ;; 36|qwen36) KEY=36; NAME="Qwen3.6-27B"; ALIAS=$P36_ALIAS; MODEL=$P36_MODEL; CTX="${ENV_CTX:-$P36_CTX}"; NMAX="${ENV_NMAX:-$P36_NMAX}"; PORT=$P36_PORT ;; esac MODEL_PATH=""; [ -n "$MODEL" ] && MODEL_PATH="$HOME/models/$MODEL" API_KEY="${API_KEY:-${QWEN_API_KEY:-}}" HOST="${HOST:-0.0.0.0}" # 只匹配本模型的进程;用 alias 定位,避免 pkill -f "llama-server -m" # 连带杀掉另一个模型的实例 _running() { pgrep -f -- "--alias $1" 2>/dev/null; } # 有 systemd 用户服务托管的模型(38 → qwen38.service),stop 必须走 systemctl: # 否则 pkill 造成的"非正常退出"会被 Restart=on-failure 在 20s 后拉回来 _svc_of() { case "$1" in "$P38_ALIAS") echo qwen38.service ;; esac; } # 注意 kind 必须是 shell 变量;写成 awk 的 -v 变量时 shell 展开不到 _vram() { local kind="$1"; awk '{printf "%.2f", $1/1e9}' "$VRAM_DEV/mem_info_vram_$kind" 2>/dev/null; } stop() { local n=0 a svc for a in "$P38_ALIAS" "$P36_ALIAS"; do if _running "$a" >/dev/null; then svc=$(_svc_of "$a") if [ -n "$svc" ] && systemctl --user is-active --quiet "$svc" 2>/dev/null; then # systemd 接管中:受控停止,避免被 Restart 拉回;等进程真正退出 systemctl --user stop "$svc" 2>/dev/null for _ in $(seq 1 45); do _running "$a" >/dev/null || break; sleep 1; done else pkill -f -- "--alias $a" 2>/dev/null for _ in $(seq 1 45); do _running "$a" >/dev/null || break; sleep 1; done pkill -9 -f -- "--alias $a" 2>/dev/null fi n=$((n+1)) fi done [ "$n" -gt 0 ] && echo "已停止 $n 个实例" || echo "未在运行" # 模型都停了,工具调用中间层留着也没用;交给 shim.sh 用 PID 精确停, # 避免裸 pgrep/pkill 文件名误杀其它提到该文件的进程。 if [ -x "$SHIM" ]; then _out=$("$SHIM" stop 2>&1) case "$_out" in *已停止*) echo "$_out" ;; esac fi } status() { printf '%-10s %-7s %-6s %-11s %s\n' 模型 端口 状态 显存 模型文件 for spec in "Qwen3.8-27B|$P38_ALIAS|$P38_PORT|$P38_MODEL" "Qwen3.6-27B|$P36_ALIAS|$P36_PORT|$P36_MODEL"; do IFS='|' read -r name a p m <<<"$spec" if _running "$a" >/dev/null; then printf '%-10s %-7s %-6s %-11s %s\n' "$name" ":$p" "运行" "$(_vram used) GB" "$m" elif curl -fsS --max-time 2 "http://127.0.0.1:$p/health" >/dev/null 2>&1; then # 进程看不见但端口在服务(例如从别的命名空间/终端起来的)也算运行 printf '%-10s %-7s %-6s %-11s %s\n' "$name" ":$p" "运行" "-" "$m" else printf '%-10s %-7s %-6s %-11s %s\n' "$name" ":$p" "停止" "-" "$m" fi done # 以端口健康为准:shim 可能由别的终端/会话拉起,进程看不到但确实在服务 if curl -fsS --max-time 2 "http://127.0.0.1:8090/health" >/dev/null 2>&1; then _shim_state=运行; else _shim_state=停止; fi printf '%-10s %-7s %-6s %-11s %s\n' "shim" ":8090" "$_shim_state" "-" "dsh-llm-shim.mjs" echo "总显存: $(_vram used) / $(_vram total) GB" } if [ -z "$KEY" ]; then # 裸命令(函数已定义,可安全调用):stop/status,其余按 status 兜底 case "${1:-}" in stop) stop; exit 0 ;; status) status; exit 0 ;; *) status; exit 0 ;; esac fi MMPROJ="" for a in "$@"; do case "$a" in --vision) MMPROJ="$MMPROJ_FULL" ;; --stop) stop; exit 0 ;; --status) status; exit 0 ;; --restart|--use) for a2 in "$@"; do case "$a2" in 36|qwen36) NEXT=36 ;; esac done stop; sleep 2 case "${NEXT:-}" in 36) exec "$0" 36 --vision ;; *) exec "$0" 38 ;; esac ;; esac done [ -f "$MODEL_PATH" ] || { echo "模型缺失: $MODEL_PATH" >&2; exit 1; } [ -x "$BIN" ] || { echo "二进制缺失: $BIN" >&2; exit 1; } if _running "$ALIAS" >/dev/null; then echo "$NAME 已在 :$PORT 运行。要重启先 stop,或用 ./llama.sh $KEY --use" >&2 exit 1 fi # 另一个模型占着显存就停掉,否则必然 OOM if _running "$P38_ALIAS" >/dev/null || _running "$P36_ALIAS" >/dev/null; then echo "提示: 另一模型正在运行,将先停止(两者不能共存于 25.75GB 显存)" stop; sleep 2 fi [ -n "$MMPROJ" ] && [ ! -f "$MMPROJ" ] && { echo "mmproj 缺失,关闭视觉: $MMPROJ" >&2; MMPROJ=""; } # UB 默认 512:llama-bench 上 pp32768 有 399→414 t/s(+3.7%) 的提升, # 但服务端实测 decode 63.7→59.3 t/s(−7%)、显存 23.64→24.83 GB(96%), # 且触发 "failed to fit params to free device memory"(-ngl 999 写死无法自动收缩)。 # prefill 的收益抵不上 decode 的损失,故保持 512。保留变量以便复测。 UB="${UB:-512}"; B="${B:-$((UB * 4))}" # 实测: ub2048 纯文本 @256K 投影 22924 MiB, 视觉 mmproj 再 +1.19GB → 约 24.6GB / 25.75GB 极限 if [ -n "$MMPROJ" ] && [ "$CTX" -gt 196608 ] && [ "$UB" -gt 512 ]; then echo "⚠ ctx=$CTX + 视觉 + ub=$UB 会逼近 25.75GB 上限;建议 CTX=196608 或 UB=512" >&2 fi # 投机解码: MTP 自投机 + n-gram 查表叠加(k4v)。 # 3.8 实测(temp=0, 每项 2 轮取中位数, n_gen 两配置完全一致故无输出长度混淆): # 工作负载 draft-mtp +k4v(n=32) 变化 # code_refactor 86.1 112.6 +30.7% ← dsh 改文件典型负载 # repeat_synth 86.0 122.4 +42.3% # template_batch 47.2 46.7 -1.1% (噪音内) # reasoning 72.9 72.1 -1.1% (噪音内) # prose 47.2 46.7 -1.1% (噪音内) # 零 VRAM 成本, 零重编。n=32 是关键: n=12 在「格式重复但内容要换」的任务上倒扣 # 5~10%(n-gram 一直开火猜错时间轴), n=32 把所有负项收进 ±1.3% 噪音内。 # 原理: k4v 从已生成上下文做 n-gram 查表, 命中一次吐最多 48 token; 没命中退回 MTP。 # 来源: https://lcz.me/topic/1398 §二/§三(该文在 7900XTX Vulkan 上交叉验证过) K4V="${K4V:-1}" SPEC_TYPE="draft-mtp"; K4V_ARGS=() if [ "$K4V" = "1" ]; then SPEC_TYPE="ngram-map-k4v,draft-mtp" K4V_ARGS=( --spec-ngram-map-k4v-size-n "${K4V_N:-32}" --spec-ngram-map-k4v-size-m "${K4V_M:-48}" --spec-ngram-map-k4v-min-hits "${K4V_HITS:-1}" ) fi ARGS=( -m "$MODEL_PATH" -c "$CTX" -ngl 999 -fa 1 -ub "$UB" -b "$B" --reasoning off --parallel 1 -cram "${CRAM:--1}" --host "$HOST" --port "$PORT" --alias "$ALIAS" --spec-type "$SPEC_TYPE" --spec-draft-n-max "$NMAX" "${K4V_ARGS[@]}" ) # KV 精度与采样:草稿与目标共享 context,V cache 量化误差会压低接受率。 # 3.6 实测(reps=3, ctx196608, n-max4): 0.7/20 → 67.33 tok/s 接受0.544 # 0.3/5 → 68.70 tok/s 接受0.560 # 3.6 最佳: n-max3 + 0.3/5 → 69.54 tok/s 接受0.657 (V=q4_0 最优; q8_0/f16 反而更差更慢) # 3.8 保持 0.7/20 —— 其 83.30 tok/s 是在该采样下实测的 if [ "$KEY" = "36" ]; then ARGS+=( -ctk "${CKV:-q8_0}" -ctv "${CV:-q4_0}" --temp "${TEMP:-0.3}" --top-k "${TOPK:-5}" ) else ARGS+=( -ctk "${CKV:-q4_0}" -ctv "${CV:-q4_0}" --temp "${TEMP:-0.7}" --top-k "${TOPK:-20}" ) fi # EXTRA 透传调优参数,例如 EXTRA="--spec-draft-p-min 0.2" [ -n "$ENV_EXTRA" ] && ARGS+=( $ENV_EXTRA ) [ -n "$MMPROJ" ] && ARGS+=(--mmproj "$MMPROJ") # 关闭服务端认证: 配合 opencode 里 apiKey="" 使用,不传 --api-key LOG="${LOG:-/tmp/qwen${KEY}-vulkan.log}" echo "model : $NAME ($MODEL)" echo "config : ctx=$CTX n-max=$NMAX ub=$UB/b=$B 视觉=$([ -n "$MMPROJ" ] && echo 开 || echo 关) 认证=无" echo "listen : $HOST:$PORT log: $LOG" for a in "$@"; do if [ "$a" = "--fg" ]; then # systemd 用的就是 --fg:exec 之后脚本就结束了,所以 shim 必须在这里起, # 否则「起模型就自动带 shim」在 --fg 下不成立。start 是幂等的。 [ -x "$SHIM" ] && "$SHIM" start exec "$BIN" "${ARGS[@]}" fi done # 有 systemd 单元托管时一律交给 systemctl:手动 setsid 起的进程不受 # Restart=on-failure 保护,还会占住端口让单元以 exit-code 1 反复 crash-loop # (2026-09-30 22:10 就是这么把 qwen38 顶掉的)。 # systemctl 不继承当前 shell 的环境,所以存在调优变量或 --vision 时退回直起, # 否则 `CTX=163840 ./llama.sh 38` 会被静默吞掉。 VIA=direct _SVC=$(_svc_of "$ALIAS") if [ -n "$_SVC" ] && systemctl --user cat "$_SVC" >/dev/null 2>&1; then if [ -n "$_USER_OVERRIDES" ] || [ -n "$MMPROJ" ]; then echo "⚠ 有覆盖[${_USER_OVERRIDES:- --vision}] systemd 不继承 → 直起(无 Restart 保护)" >&2 else VIA=systemd fi fi PROBE=127.0.0.1; [ "$HOST" = "0.0.0.0" ] || PROBE="$HOST" _fail_hint() { [ "$VIA" = systemd ] && echo "journalctl --user -u $_SVC -n 50" || echo "$LOG"; } if [ "$VIA" = systemd ]; then echo "→ systemctl --user start $_SVC" systemctl --user start "$_SVC" else setsid nohup "$BIN" "${ARGS[@]}" </dev/null >"$LOG" 2>&1 & disown fi printf 'loading' for _ in $(seq 1 90); do sleep 4 curl -fsS --max-time 3 "http://$PROBE:$PORT/health" 2>/dev/null | grep -q '"ok"' && break _running "$ALIAS" >/dev/null || { echo; echo "启动失败,看: $(_fail_hint)" >&2; exit 1; } printf '.' done if curl -fsS --max-time 3 "http://$PROBE:$PORT/health" 2>/dev/null | grep -q '"ok"'; then echo; echo "就绪" awk -v u="$(_vram used)" -v t="$(_vram total)" \ 'BEGIN{printf "显存 : %s / %s GB (%.0f%%)\n", u, t, t?100*u/t:0}' LAN=$(ip route get 1.1.1.1 2>/dev/null | grep -oE 'src [0-9.]+' | cut -d' ' -f2) [ -n "$LAN" ] && echo "局域网: http://$LAN:$PORT/v1 (模型名 $ALIAS)" [ "$VIA" = direct ] && { grep -q "nextn.*ignoring" "$LOG" 2>/dev/null && \ echo "⚠ 日志显示 MTP 头被忽略,检查 --spec-type 是否生效" >&2; } # 工具调用中间层:llama.cpp b11223 自带的 tool-call 解析器解析不了 Qwen3.x 的 XML # 工具调用(参数被吞 + 诱发无限重复),改由 shim 代为解析。详见 # ~/桌面/本地模型接入DSH-诊断.md。shim 已在跑时 start 是幂等的。 if [ -x "$SHIM" ]; then "$SHIM" start else echo "⚠ 缺少 $SHIM,DSH 本地模型会拿不到工具调用" >&2 fi else echo; echo "超时,看 $(_fail_hint)" >&2; exit 1 fi3.2 使用说明
cd ~/llama-bin ./llama.sh 38 # 启动 Qwen3.8-27B (:8080) ./llama.sh 36 # 启动 Qwen3.6-27B (:8081) ./llama.sh status # 查看状态 ./llama.sh stop # 停止所有 ./llama.sh 36 --use # 切换到 3.6(先停当前再起 3.6) ./llama.sh 38 --vision # 带视觉启动 ./llama.sh 38 --fg # 前台运行(systemd 用)关键参数说明:
-ngl 999 -fa 1:全部层 offload 到 GPU-c 131072:默认 ctx 128K,不是训练上限 262144。256K 会把模型+KV 顶到 ~26.3GB/25.75GB,
Vulkan 装不下 DEVICE_LOCAL 而把权重退回 GTT(系统内存)映射,decode 掉到 0.49 tok/s。
下界 64K(Hermes Agent 硬性要求 context >= 64000)。
需要更大窗口用CTX=65536 ./llama.sh 38覆盖,但每次加大都要重新核对显存(详见 §9.8)-cram -1:KV cache 放内存而非显存。25.75GB 卡上省下的正是权重能留在 DEVICE_LOCAL 的那点余量--spec-type ngram-map-k4v,draft-mtp --spec-draft-n-max 3:投机解码。ngram-map-k4v不可省略,详见 §6.3--spec-ngram-map-k4v-size-n 32:n-gram 查表长度,必须 32。取 12 会在「格式重复但内容要换」的任务上倒扣 5~10%-ctk q4_0 -ctv q4_0:KV cache 量化(只换容量不换速度)--parallel 1:单并发(本地推理推荐)--reasoning off:关闭推理模式(Qwen3.x)- systemd 自动检测:有
qwen38.service单元时,无覆盖变量的启动自动走systemctl --user start;
有CTX/UB/K4V等覆盖或--vision时退回直起(systemd 不继承 shell 环境),并打印警告
常见误用:
./llama.sh use 36不是有效命令。切换模型用./llama.sh 36 --use,
或直接./llama.sh stop && ./llama.sh 36。在 32GB 以外的显存预算下两个 27B 无法共存,
脚本会自动先停另一个。
- §9.8(重写)— CTX 从 256K 降到 128K 的根因: