跳到主要内容

本地部署大模型调教记录(llama.cpp/ollama)

· 阅读需 5 分钟
RibomBalt
CTF enthusiastist, GeoPhysics PhD, Amateur coder

TL;DR;

  • 本文介绍了从Huggingface(或其镜像)下载大语言模型,通过llama.cpp转换格式、量化后在普通台式机上部署的过程。

目的需求

一般认为本地部署基座大模型不是划算的行为。例如deepseek全量模型671B参数,无法在家用显卡上进行部署。而7B,13B左右的模型参数性能相对孱弱,生成质量无法满足生产需求。另一方面,目前已经有相当多的低价大模型,硅基流动、openrouter等模型提供商的API可能更适合平时需求。

尽管如此,当内容不方便出网时,仍然有本地部署大模型的需求,其中的典型是无审查NSFW生成。通常的角色扮演对模型的要求没有那么高,13B左右的模型已经可以达到理想的效果。本文使用了mistral-nemo-instruct-2407模型,参数量为12.2B,以部署在NVIDIA RTX 4060Ti 8GB显卡的WSL2 CUDA上为例。

Huggingface下载模型

可以通过huggingface-cli下载模型,这一命令可以通过pip install -U "huggingface_hub[cli]"获取。考虑到Huggingface服务器在国外,可以考虑使用hf-mirror镜像,只需要指定环境变量即可。

HF_ENDPOINT=https://hf-mirror huggingface-cli download ${model_name} --local-dir ${model_dir}

转换Huggingface模型为gguf格式并量化

Huggingface模型一般是safetensors格式的,Ollama需要gguf格式的模型,需要转换。我这里使用llama.cpp转换,众所周知Ollama是llama.cpp的封装。

下载llama.cpp并编译。我的设备有CUDA,因此编译指令为:

cmake -B build -DGGML_CUDA=ON
cmake --build build --config Release

直接使用根目录的convert_hf_to_gguf.py脚本转换模型(注意带update的脚本是直接从huggingface下载的模型转换的,我们这里采用手动下载的模式)

python3 convert_hf_to_gguf.py ${model_dir}

转换完成后会在相同目录下生成{model_name}-F16.gguf的ggml F16模型,为了保证小显存能够跑起来,需要进行量化。具体量化到什么程度由模型-显存大小决定,最好在显存允许的情况下尽可能大。对于我的情况,跑mistral-nemo-instruct-2407-12b,在8GB显存下,可以量化到Q4_0,占用7.1GB显存。官方文档有量化参数和推理速度、PPL(困惑度)对照表(PPL代表下一个词合理选择数,一般越少模型质量越高)。另有一些博客介绍量化质量的对照表,可以参考这篇(事实上感觉这种文章都不怎么权威,仅供参考了)。

量化命令如下:

${build_dir}/llama-quantize ${orig_model}.gguf ${quantized_model}.gguf Q4_0

运行模型

使用llama.cpp运行模型

${build_dir}/llama-server -m ${quantized_model}.gguf --ngl 30 --host "127.0.0.1"

其中ngl参数表示把多少层运算放进GPU,不指定这个参数则纯粹CPU推理,层数越高占用显存越多。我这里30层基本就把专用显存占满了。如果使用llama-cli,则可以直接在命令行推理。另外,对于第三方客户端,llama.cpp不需要指定模型名

已知问题

llama.cpp运行Q4模型时,输出长度通常较短,这是已知问题,可以通过提示词中要求返回长输出内容来缓解。

使用ollama运行

首先新建一个${model_name}.mf文件,只有一行内容:

FROM {model_name}.gguf

然后运行:

ollama create ${model_name} -f ${model_name}.mf

注意:假如提示Error: could not connect to ollama app, is it running?,Linux下是需要systemctl start ollama启动后台服务的。Windows下想必同理。

之后ollama会以自己的形式导入模型(会在~/.ollama内存储一份拷贝)。

创建模型后,通过ollama run ${model_name}命令运行模型,注意这里的模型名是ollama create时指定的名字。ollama是支持同时运行多个模型的,所以需要模型名进行区分。(有种说法说ollama有点接近docker的定位)。注意退出进程后模型可能还在后台运行,需要ollama stop ${model_name}停止模型。如需移除模型,使用ollama rm ${model_name}命令。

已知问题

实测本地Ollama部署后会出现胡言乱语的问题(gibberish)。有博客指出这可能是因为显存不足,推荐减小上下文宽度,可以在mf模型描述文件中减小。

PARAMETER num_ctx 512

实测减小上下文宽度后缓解,但效果仍然远差于llama.cpp,原因不明。事实上500的上下文宽度已经无法满足一些比较复杂的角色扮演需要了。

第三方客户端

llama.cpp是openai compatible的,可以直接添加新的provider。下面是我常用的一些第三方客户端。

  • aichat
  • cherry-studio(暂无移动端)
  • chatbox(安卓端)