本地大模型完整指南:从编译部署到 12GB 跑通 27B

1762 字
9 分钟
本地大模型完整指南:从编译部署到 12GB 跑通 27B

本地大模型完整指南:从编译部署到 12GB 跑通 27B#

环境 A(部署篇):Jetson AGX Thor / Ubuntu,Docker + CUDA 环境 B(调优篇):llama.cpp b10184(Clang 20.1.8 win-x64),GPU RTX 4070 SUPER 12GB 模型:Qwen3.8-27B-Uncensored,IQ2_M 量化

AI 越来越火,token 越来越贵,于是我想本地化部署一个大模型,顺便把 Agent 也跑起来,这样就能无限使用。真正动手之后才发现,「装上能跑」和「跑得好用」完全是两件事——前者是编译部署的体力活,后者是 KV 缓存和上下文的精细调优。

这篇把两个阶段合在一起:第一部分讲怎么装(编译、模型下载、systemd 常驻、Agent 部署),第二部分讲怎么调(为什么 12GB 能跑 27B、上下文甜点在哪、长对话怎么压缩)。


第一部分:部署——把 llama.cpp 跑起来#

一、前置条件#

  1. 安装 Docker
  2. 安装 docker-compose
  3. 安装 CUDA
  4. 设备示例:Jetson AGX Thor

二、安装编译依赖#

Terminal window
sudo apt update && sudo apt install -y build-essential git libopenblas-dev

三、拉取 llama.cpp 源码(国内加速克隆)#

Terminal window
# 加速克隆源码
git clone https://ghproxy.com/https://github.com/ggml-org/llama.cpp.git
# 进入项目目录
cd llama.cpp

四、编译 llama.cpp#

Terminal window
# 编译(带 CUDA 支持)
make clean && CUDA=1 make -j$(nproc)

五、下载模型#

1. 量化版本选择

  • Q4_K_P:显存占用低,适合小显存设备
  • Q8_K_P:输出精度更高,显存占用更大
  • 多模态模型额外下载配套 mmproj 视觉文件

2. HuggingFace 镜像替换规则

原地址: https://huggingface.co/xxx/模型仓库名
加速地址:https://hf-mirror.com/xxx/模型仓库名

3. 路径统一

将下载完成的 .gguf 模型放入项目内 models/ 文件夹,统一路径避免读取报错。

六、测试推理(验证编译与模型可用)#

Terminal window
./main \
-m models/你的模型.gguf \
--flash-attn \
--mlock \
-np $(nproc) \
-c 8192

参数说明:

参数作用
--flash-attn注意力计算加速,降低显存占用
--mlock锁定内存,防止系统交换分区卡顿
-np并行推理线程数,默认 1
-c上下文长度,默认 8192

七、配置 systemd 常驻后台服务#

实现开机自启、崩溃自动重启:

[Unit]
Description=Llama.cpp Local LLM Service
After=network.target
[Service]
User=你的用户名
WorkingDirectory=/home/你的用户名/llama.cpp
ExecStart=/home/你的用户名/llama.cpp/server -m models/你的模型.gguf --flash-attn --mlock -c 8192
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target

加载并启动:

Terminal window
sudo systemctl daemon-reload # 重载系统服务配置
sudo systemctl enable llama # 设置开机自启
sudo systemctl start llama # 启动推理服务
journalctl -u llama -f # 实时查看运行日志

八、部署 AstrBot(Agent 侧)#

Terminal window
mkdir astrbot && cd astrbot
sudo docker run -itd -p 6185:6185 -p 6199:6199 \
-v $PWD/data:/AstrBot/data \
-v /etc/localtime:/etc/localtime:ro \
-v /etc/timezone:/etc/timezone:ro \
--name astrbot \
m.daocloud.io/docker.io/soulter/astrbot:latest

到这一步,一个能跑、能自启、带 Agent 的本地推理环境就搭好了。但它能跑多长的上下文、能跑多大的模型,取决于下面这部分。


第二部分:调优——12GB 单卡跑通 27B#

很多人听到「12GB 显存跑 27B」第一反应是「不可能」。我之前也这么想,直到手撕了一眼 GGUF 头——这个 27B 根本不是 dense 模型,KV 缓存比按层全注意力估算的小了 3~4 倍。

九、关键发现:它不是 dense 模型#

用十六进制编辑器(或 strings + 头解析)看 GGUF 元数据,关键两行:

general.architecture = qwen35
qwen35.block_full_attention_interval = 4

qwen35 是混合架构:65 层里每 4 层才有 1 层全注意力,也就是只有 16 层需要存 KV 缓存;其余 49 层是 SSM(线性注意力),状态复杂度是 O(1),几乎不随上下文长度增长。

按 dense(65 层全注意力)去估 KV 显存,会高估 3~4 倍。我一开始算的上下文档位直接砍半就对了。

这也是为什么很多「27B 需要 XX GB」的经验公式在混合架构上会严重失准。

十、上下文甜点与断崖(实测 prefill 吞吐)#

光看「能不能启动」没用——KV 溢出时它不报错,只会静默变慢。真正要看的是 prefill 吞吐曲线:

上下文 -cKV 精度prefill 吞吐判定
32768q8_01106 tok/s显存内 ✓
65536q4_0970 tok/s显存内 ✓(甜点)
98304q4_0~103 tok/s落内存 ✗
131072q4_0~105 tok/s落内存 ✗

断崖清晰地落在 65536 与 98304 之间。我现在的默认:

-c 65536 -ctk q4_0 -ctv q4_0 -np 1
KVBUDGET=1200 MiB

中文 token 密度按文体取:连续自然语言约 0.595 字/token,编号条目式 0.654~0.747 字/token,估算可用上下文长度时别用 1<1>。

前缀缓存默认开启:同一段系统提示词第二轮起几乎不用重算,每轮省 6~7 秒。

十一、上下文压缩代理 ctx-proxy#

单卡 27B 的上下文再怎么抠也有限,长对话还是会顶到上限。我在客户端和推理服务之间加了一层零第三方依赖的压缩代理(ctx-proxy.py),客户端把 API 地址从 8080 改成 8787 即可,其余配置不动。

压缩策略按代价递增分四级:

  • L0 原样透传
  • L1 截断超长单条
  • L2 滚动摘要(把早期对话压成摘要)
  • L3 硬丢弃早期内容

事后若上游仍报超限,则激进压缩重试。

两个关键坑:

  1. Qwen3 默认 thinking 会把 content 掏空——答案写进 reasoning_content,content 是空的。代理默认注入 enable_thinking=False 并剔除历史里的 reasoning;需要思考链时再用 think 参数开。
  2. KV_SAFE_CAP = 42000:不必把 -c 顶到 65536,光是对话逼近上限就够让 KV 挤出显存、prefill 暴跌十几倍。提前压缩比撞墙再救更稳。

十二、写 .bat / 代理时的踩坑清单#

  1. .bat 必须 CRLF,中文必须存 GBK/CP936(chcp 65001 也救不了),可靠写回路径只有 PowerShell GetEncoding(936) 并回环校验。
  2. llama-server --list-devices 会永久污染控制台代码页(改成 65001),导致后续中文乱码 → 每次调用后立刻 chcp 936;注意 chcp 会覆盖 errorlevel,要先存退出码。
  3. 代理窗口中文乱码修了三版才对:最终用控制台 WriteConsoleW 写 UTF-16,由系统转码,不要在 Python 里猜代码页。
  4. 单实例守卫:一张 12GB 卡只能跑一个 27B-IQ2_M 实例;端口自动顺延会造出「僵尸实例」(/health 正常但补全 502)。
  5. --tools 有 7 个内置工具,schema 约 800 token;--agent/-ag ≈ --tools all --ui-mcp-proxy。

小结#

本地大模型的落地可以拆成两条线,顺序不能反:

第一条线是「装得上」——装依赖、编译 llama.cpp、下载量化模型、systemd 常驻、再挂上 Agent。这部分是确定性工作,照着做就能成,卡点主要在镜像加速和路径统一。

第二条线是「跑得好」——命门不是「模型装不装得下」,而是 KV 缓存随上下文的膨胀。而混合架构让这件事比直觉乐观得多。核心三件事:

  1. 手撕 GGUF 头确认架构,按真实注意力层数算 KV,别套 dense 的经验公式;
  2. 用吞吐曲线找上下文甜点(我这里是 65536),别信「能启动 = 够用」;
  3. 长对话交给分级压缩代理,并主动设 KV_SAFE_CAP 防止静默掉速。

如果你也在单卡上折腾大模型,欢迎交流你的甜点参数。

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

本地大模型完整指南:从编译部署到 12GB 跑通 27B
https://vtdd.vip/posts/本地大模型完整指南-从编译部署到12gb跑27b/
作者
Zero
发布于
2026-10-16
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
Zero
有三件事人类都要经历:出生、生活和死亡。他们出生时无知无觉,死到临头,痛不欲生,活着的时候却又怠慢了人生。——拉布吕耶尔
分类
标签
最新动态
站点统计
文章
33
动态
8
分类
10
标签
54
总字数
38,200
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
Local
博客版本
Firefly v6.14.3
文章许可
CC BY-NC-SA 4.0