返回博客
·端侧与硬件

本地跑 LLM 不崩溃:我的 llama.cpp 实战踩坑录

从模型选型到量化方案,手把手教你在本地稳定运行 LLM,附真实踩坑经验。

#LLM#llama.cpp#端侧推理#量化

# 本地跑 LLM 不崩溃:我的 llama.cpp 实战踩坑录

上个月接了个项目,客户要求 AI 功能不能走云端——数据敏感,过不了合规。只能本地跑。

一开始觉得"不就跑个模型吗",结果连周末都搭进去了。今天把踩过的坑都写出来,希望能帮你们省点头发。

选型:到底用谁

先说结论:如果你只想快速跑通,用 Ollama;如果需要精细控制或者要集成到项目里,用 llama.cpp。

我选的是 llama.cpp,原因很简单——Ollama 封装太死,我想换 quantization 方案的时候发现根本动不了。llama.cpp 虽然丑,但它是真·开源,源码几万个星,社区活跃。

模型选的是 Qwen2.5-7B-Instruct,阿里出的,中文能力强,比 Llama 3 在中文场景下靠谱得多。

环境搭建:比想象中麻烦

第一步:安装

git clone https://github.com/ggerganov/llama.cpp

cd llama.cpp

cmake -B build

cmake --build build --config Release -j$(nproc)

注意:你机器上没有 CUDA 也没关系,llama.cpp 默认走 CPU,用 AVX512 指令集加速。Mac 的话直接用 Metal 后端,性能更好。

我的 MacBook Pro M2 Max,跑 7B 模型,量化到 Q4_K_M,推理速度大概 25 tokens/s。够用了。

第二步:模型转换

llama.cpp 不直接支持 HuggingFace 的 safetensors 格式,需要转换:

python convert_hf_to_gguf.py Qwen/Qwen2.5-7B-Instruct \

--outfile qwen2.5-7b-instruct-q4_k_m.gguf \

--quantization q4_k_m

这个步骤我卡了整整一天。原因:Python 版本。项目要求 3.10+,我机器上是 3.8,装了 pyenv 切版本,又碰到了 numpy 编译问题。最后用 uv 装了一个隔离环境才搞定。

**经验:别在系统 Python 上折腾项目依赖,永远用 uv 或者 conda。**

量化方案的选择

这是我最想重点讲的。量化不是越小越好,要权衡速度、质量和显存/内存占用。

| 量化 | 模型大小 | 质量损失 | 推理速度(相对) |

|------|---------|---------|--------------|

| FP16 | 13.4GB | 无 | 1.0x |

| Q5_K_M | 7.7GB | 几乎不可感知 | 1.8x |

| Q4_K_M | 4.9GB | 轻微,中文影响不大 | 2.5x |

| Q3_K_M | 3.5GB | 明显,开始出现胡言乱语 | 3.5x |

| Q2_K | 2.6GB | 严重,不推荐 | 4.0x |

我的选择:Q4_K_M。对于 7B 模型来说,这个档位是性价比最高的——中文质量几乎无损,内存占用从 13GB 降到 5GB。

**踩坑:千万别用 Q2_K。我一开始图省内存选了 Q2,结果模型回答经常文不对题,像是喝醉了一样。**

实际调用

转换完之后,用官方的 server:

./server -m qwen2.5-7b-instruct-q4_k_m.gguf \

--port 8080 \

--ctx-size 8192 \

--n-gpu-layers 35

参数说明:

  • `--ctx-size`:上下文窗口。7B 模型给 8192 够了,给 32768 会爆内存
  • `--n-gpu-layers`:Mac 上用 Metal,这个值设大一点能充分利用 GPU。我设的是 35,基本上全放 GPU 上
  • 调用方式就是标准 OpenAI 兼容格式:

    curl http://localhost:8080/v1/chat/completions \

    -H "Content-Type: application/json" \

    -d '{

    "model": "qwen2.5-7b-instruct",

    "messages": [{"role": "user", "content": "解释一下量子计算"}],

    "temperature": 0.7

    }'

    集成到项目

    我的项目是 Next.js + TypeScript。封装了一个简单的 client:

    const LLAMA_URL = 'http://localhost:8080/v1';

    async function chat(messages: Array<{role: string; content: string}>) {

    const res = await fetch(${LLAMA_URL}/chat/completions, {

    method: 'POST',

    headers: { 'Content-Type': 'application/json' },

    body: JSON.stringify({

    model: 'qwen2.5-7b-instruct',

    messages,

    temperature: 0.7,

    stream: false,

    }),

    });

    const data = await res.json();

    return data.choices[0].message.content;

    }

    注意:本地模型响应时间比云端慢很多。7B Q4 模型回答一个问题通常需要 3-8 秒,比云端慢 10-20 倍。要做好 loading 状态和超时处理。

    常见问题

    **Q: 模型偶尔会"背诵"训练数据怎么办?**

    A: 这是本地小模型的通病。降低 temperature 到 0.3 左右能缓解,但治标不治本。最根本的解法是 RAG——把知识库灌进去,让模型只回答问题不编造。

    **Q: 多进程并发会崩?**

    A: llama.cpp 默认单线程。多用户场景需要自己用进程池或者上 vLLM(但 vLLM 需要 Linux + NVIDIA GPU,Mac 上跑不了)。

    **Q: 怎么监控推理性能?**

    A: 用 htop 看 CPU 占用,Mac 上用 top 看内存。llama.cpp 的 server 模式下会打印推理耗时,留意 eval time 那一行。

    总结

    本地跑 LLM 不难,难的是各种坑。总结三条经验:

  • **量化选 Q4_K_M,别贪便宜选更低的**
  • 2. **Python 环境用 uv 隔离,别碰系统 Python**

    3. **响应慢是常态,做好 UX 兜底**

    本地模型现在的能力还不足以替代云端,但在数据敏感的合规场景下,它是唯一的选择。随着端侧芯片性能提升,这个方案会越来越实用。