中文 | English
标准化的 LLM 本地部署启动参数优化评估流程,通过严格的控制变量测试,找到最佳的性能/质量平衡点。
A standardized methodology for optimizing local LLM deployment parameters, using rigorous control variable testing to find the optimal performance/quality balance.
⚠️ 安全声明 / Safety Notice
127.0.0.1(localhost),生产环境必须通过反向代理 + HTTPS 暴露服务。中文 | English
新模型首次部署,需要找到最佳启动参数
First-time deployment of a new model, finding optimal launch parameters
新硬件环境下的性能调优
Performance tuning on new hardware
llama.cpp / llama-server 启动参数优化
llama.cpp / llama-server launch parameter optimization
验证量化损失、长上下文能力等核心特性
Verify quantization loss, long context capabilities, and other core features
4 phases, 10 steps
中文 | English
在默认参数下运行,记录基础性能数据:
Run with default parameters and record baseline performance:
text
✅ 记录项 / Metrics to record:
- 生成速度 / Generation speed (tokens/s)
- Prompt 处理速度 / Prompt processing speed (tokens/s)
- 显存占用峰值 / Peak VRAM usage (GB)
- 首字延迟 / Time to first token (ms)
中文 | English
列出所有可能影响性能的参数:
List all parameters that may affect performance:
参数 / Parameter典型测试值 / Typical values--threads4 / 8 / 12 / 16 / CPU 核心数-b / --batch-size512 / 1024 / 2048 / 4096--ctx-size重要!优先测试!先找甜点阈值,再测其他参数--flash-attnon / off--cache-type-k/v不量化 / q8_0 / q4_0--parallel1 / 2 / 4--ubatch-size256 / 512 / 1024
中文 | English
核心原则:每次只改一个参数,其他所有参数保持基准不变!
Core principle: Change only ONE parameter each time, keep ALL others at baseline!
❌ 错误做法 / Wrong way:链式修改,改完线程改上下文,再改 FA,结果混在一起无法归因
Chain modification - change threads, then context, then FA - results can't be attributed
✅ 正确做法 / Correct way:每次测试都回到基准配置,只改一个参数
Return to baseline config for each test, change only one parameter
⚠️ 重要反常识发现 / Critical Counterintuitive Findings
❌ --parallel 2 不一定好 / Not always good:在 4060Ti + 35B 组合上,单请求速度反而下降 40%,调度开销超过了并发收益
On 4060Ti + 35B Dense, parallel=2 slows single request by 40% - scheduling overhead exceeds concurrency benefit
✅ --flash-attn on 对长 Prompt 影响巨大 / Huge impact on long prompts:开启前 300-500 token/s,开启后 1858 token/s,快了 3-5 倍
300-500 → 1858 token/s, 3-5x faster, but only ±5% effect on regular generation
❌ KV 缓存激进量化不一定好 / Aggressive KV quantization not always good:q4_K 在某些版本的 llama.cpp 上会导致模型加载速度极慢,优先用 q8_0
q4_K can cause extremely slow loading on some llama.cpp versions - prefer q8_0
中文 | English
每个参数测试完成后,记录完整的对比表:
After each parameter test, record complete comparison table:
示例:线程数对比 / Example: Thread count comparison
线程数 / Threads生成速度 / Gen SpeedPrompt 速度 / Prompt Speed变化 / Change推荐 / Recommend884.880.0基准 / Baseline🏆 最佳 / Best1283.170.2-2.0%1683.575.0-1.5%
MUST DO first - highest ROI optimization!
中文 | English
这是所有优化里性价比最高的一项,通常能白嫖 50-100% 的速度提升,零质量损失!
This is the highest ROI optimization you can do - typically 50-100% speed boost with ZERO quality loss!
中文 | English
几乎所有模型+显卡的组合,都存在一个断崖式的性能阈值:
Almost every model + GPU combination has a cliff-like performance threshold:
✅ 阈值以下:GPU 跑满,速度达到理论最大值
Below threshold: GPU fully utilized, maximum theoretical speed
❌ 阈值以上:速度直接腰斩(40-60%),但显存只多占了 30-50MB
Above threshold: Speed drops by 40-60% (half speed), but VRAM only increases 30-50MB
这不是线性下降,是跳崖式下降!原因通常是:
This is NOT a linear degradation, but a cliff! Common causes:
GDDR 显存 Bank 对齐边界,跨 Bank 访问延迟翻 3-5 倍
GDDR memory bank alignment - cross-bank access latency increases 3-5x
FlashAttention 的 Tile 块大小阈值,超过之后触发缓存换页
FlashAttention tile size threshold - exceeding triggers cache swapping
大页内存分配失败,TLB 命中率骤降
Large page memory allocation failure - TLB hit rate plummets
中文 | English
Qwen3.6-35B + RTX 4060Ti 16GB
上下文大小 / Context生成速度 / Speed显存占用 / VRAM状态 / Status122880 (120K, 默认)30 token/s15.2 GB❌ 内存紧张118000 (118K)29-36 token/s15.1 GB❌ 内存紧张**110000 (110K)****90 token/s**14.5 GB✅ 满速64K15.0 GB✅ 满速96K86 token/s88 token/s14.0 GB✅ 满速
中文 | English
通常甜点阈值 = 厂商标称最大值的 90-95%
Typically sweet spot = 90-95% of advertised maximum
上下文只少 5-10%(完全感知不到),速度提升 50-100%
Only 5-10% less context (completely unnoticeable) for 50-100% speed boost
这一步必须第一个做! 所有后续参数测试都应该在甜点阈值下进行
DO THIS FIRST! All subsequent parameter testing should be done at the sweet spot
对比开/关量化的输出质量,使用相同的 Prompt + 温度=0.1 最小化随机性:
text
测试方法:
1. 关 KV 量化(FP16),输出结果 A
2. 开 KV q8_0 量化,相同 Prompt,输出结果 B
3. 人工对比 A 和 B,判断是否有可感知的质量损失
使用「密钥召回法」验证长上下文能力:
text
测试方法:
1. 构造长 Prompt:前面是大量无关填充文本
2. 在 Prompt 的 10% / 50% / 90% 位置分别藏一个随机密钥
3. 问模型:「文档中的秘密密钥是什么?」
4. 记录不同距离的召回成功率
典型测试距离:
验证模型的基础能力没有因为参数调整而下降:
text
测试用例:
1. 简单数学题:小明有5个苹果,给了小红2个,又买了3个,现在有几个?
2. 简单逻辑题:正方形边长4cm,面积是多少?
3. 简单代码题:用Python写一个函数求列表偶数的和
维度权重评分标准(10分制)性能50%生成速度(30%) + Prompt速度(20%)质量40%量化损失(15%) + 上下文回忆(15%) + 基本能力(10%)稳定性10%启动成功率、运行稳定性、API兼容性
必须记录所有反直觉的结论! 这些是最有价值的经验:
示例(来自 Qwen3.5-MoE 实战):
最终输出:
初始速度:23.4 tokens/s → 最终速度:84.8 tokens/s,提升 262%!
参数最佳值收益--threads8+2.4%-b / --batch-size2048+67.7% 最大提升!--ctx-size65536(最快)或 262144(最大)64K 比 256K 快 3.7 倍--flash-attnonPrompt +128%,生成 -1.3%--cache-type-k/vq8_0Prompt +128%,省 512MB,零质量损失--parallel2Prompt 最快,支持 2 并发--ubatch-size默认 512改了反而慢 17-60%
初始速度:~30 tokens/s → 最终速度:~90 tokens/s,提升 2-3 倍!
📋 验证方法:
bash
# 标准 curl 测速命令(固定 temperature=0.7, max_tokens=100)
curl -s http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"messages":[{"role":"user","content":"请写一段500字左右的技术博客文章,讨论本地部署大语言模型的性能优化方法"}],"max_tokens":100,"temperature":0.7}'
⚠️ 关键原则:GPU 内存覆盖就是生命线
"GPU 内存就是生命线,够用就快,不够用就慢。"
公式: 最大上下文 = (GPU VRAM - 模型权重 - 安全缓冲) ÷ KV 缓存每 token开销
以 RTX 4060Ti 16GB + Qwen3.6-35B 为例:
上下文速度状态122880 (120K)~30 token/s❌ GPU 内存不足118000 (118K)~29-36 token/s❌ GPU 内存不足**110000 (110K)****90 token/s**✅ GPU 完全覆盖96K / 64K / 32K86-88 token/s✅ 满速
减少 8% 上下文,速度提升 2-3 倍,零质量损失!
GPU 内存分析 / GPU Memory Analysis:
项目 / Item占用 / Usage模型权重~13.4 GBKV 缓存 (ctx 120K)1.2 GB计算缓冲区0.5 GB总计****~15.2 GBGPU 总 VRAM16 GB剩余****~0.8 GB
参数最佳值说明--ctx-size**110000(110K)**GPU 完全覆盖,速度最快--threads8最佳-b / --batch-size2048最佳--parallel1❗ Dense 模型上 parallel=2 反而慢 40%--flash-attnon必须开,长 Prompt 处理快 3-5 倍--cache-type-k/vq8_0q4_K 有兼容性问题
bash
# Linux/WSL2(推荐,绑定到 localhost)
llama-server -m "你的模型路径.gguf" --n-gpu-layers 9999 --ctx-size 110000 --port 8080 --host 127.0.0.1 --threads 8 --mlock --parallel 1 --kv-unified --flash-attn on -b 2048 --cache-type-k q8_0 --cache-type-v q8_0
⚠️ 生产环境建议:如需对外提供服务,应通过 Nginx/Caddy 等反向代理 + HTTPS,不要直接暴露 llama-server。
⚠️ 模型说明:Qwen3.6-27B 是 Qwen3.6-35B 的更轻量版本,权重更小(~12GB vs ~13.4GB),但优化结论不完全相同!
纯生成速度:~23.6 tok/s
1. 理论计算不可靠!实际测试才是王道
2. Batch Size 对 27B 的影响与 35B 相反
3. 推理模型的思考开销是硬伤
项目占用模型权重~12 GBKV 缓存 (ctx 96K)1.2 GB计算缓冲区1.0 GB总计****~14.2 GBGPU 总 VRAM16 GB剩余****~1.8 GB
参数最佳值说明--ctx-size96000实测甜点(110K OOM)--threads8比 16 省 50% CPU,速度差异 <2%-b / --batch-size51227B 上 512 比 2048 快 6.6%--parallel1Dense 模型单请求最快--flash-attnonoff 会崩溃--cache-type-k/vq8_0零质量损失,省显存
bash
llama-server -m "Qwen3.6-27B-Q3_K_S.gguf" \
--n-gpu-layers 9999 --ctx-size 96000 --port 8080 --host 127.0.0.1 \
--threads 8 --threads-batch 8 --mlock --parallel 1 \
--kv-unified --flash-attn on -b 512 \
--cache-type-k q8_0 --cache-type-v q8_0
llama-server 守护进程 ( ~/.config/systemd/user/llama-server.service)
ini
[Service]
ExecStart=/home/fenglai/llama.cpp/build/bin/llama-server \
-m /home/fenglai/models/Qwen3.6-27B-Q3_K_S.gguf \
--n-gpu-layers 9999 --ctx-size 96000 --port 8080 --host 127.0.0.1 \
--threads 8 --threads-batch 8 --mlock --parallel 1 \
--kv-unified --flash-attn on -b 512 \
--cache-type-k q8_0 --cache-type-v q8_0
OpenClaw 配置 ( ~/.openclaw/openclaw.json)
json
"contextWindow": 96000,
"maxTokens": 48000
⚠️ OpenClaw 的 contextWindow 必须与 llama-server 的 --ctx-size 保持一致,否则会导致上下文截断或 OOM。maxTokens 设为 ctx-size 的一半左右,给 prompt 留出空间。
contextWindow 必须等于 --ctx-size(96000)maxTokens 建议设为 ctx-size / 2(48000),为 prompt 预留空间reserveTokensFloor(compaction 保留 token)建议设为 20000,避免频繁压缩reasoning: true 需开启,否则思考内容无法正确解析Linux/WSL2 下可以用 taskset 把线程绑到同一物理核心簇上,减少跨核通讯开销:
bash
taskset -c 0-7 llama-server ...
注意:核心范围要和你的 --threads 参数对应,不要跨 CCX 模块。
⚠️ 安全提示:此功能仅在 Linux/WSL2 下可用,Windows 下无等效命令。
contextWindow 必须等于 --ctx-size, maxTokens 约等于 ctx-size / 2,否则上下文异常每次优化前过一遍:
nvidia-smi 实时观察,确保不突破 GPU 上限--ctx-size 或 --batch-size必须记录所有反直觉的结论! 这些是最有价值的经验:
示例(来自 Qwen3.5-MoE 35B 实战):
示例(来自 Qwen3.6-27B Dense 实战,2026-04-28):
💡 重要提醒:不同模型、不同量化版本的最佳参数差异可能很大。 不要直接套用 他人参数,必须实际测试。如果本地模型因参数设置不当频繁崩溃,可先用云端模型做逻辑验证,本地只用于性能调优。