ByteNoteByteNote

字节笔记本

2026年8月29日

llama.cpp 实时加载 LoRA:不用再合并回基座

API中转
¥120

微调完一个 LoRA,以前常见做法是把它和基座 GGUF 合并成一份新权重:磁盘多一份接近整模大小的拷贝,换风格还要重新加载。llama.cpp 现在支持把 LoRA 当成单独的 GGUF 叠在基座上加载,不必改写基座权重。仓库在 ggml-org/llama.cpp(旧地址 ggerganov/llama.cpp 也能进)。下面按转换、CLI、server 热切换写一遍。

为什么不用合并

合并(llama-export-lora,以前也叫 export-lora)适合「最终只留一个成品、发给别人一个文件就够」。代价也很清楚:每个适配器都要复制一份接近基座大小的文件;本地试五个风格,磁盘和启动时间都会跟着涨。热加载保留一份基座,旁边放若干很小的 adapter GGUF,按请求改 scale 即可。服务端多租户、本机轮换写作风格或「去审查」类适配器,都更省事。合并并没有过时,只是场景不同:要分发单文件成品时还是合并;要频繁切换时走热加载。

把 PEFT LoRA 转成 GGUF

训练侧多半是 Hugging Face PEFT 格式(adapter_model.safetensors 那一套)。进 llama.cpp 之前要先转成 GGUF:

  • 仓库自带脚本:convert_lora_to_gguf.py,在源码树里找,按 README 的依赖装好再跑
  • 不想本地折腾可以用 Hugging Face Space:GGUF-my-LoRA
  • 流程说明写在这篇博客里:gguf-my-lora

转完会得到一个独立的 adapter .gguf,体积通常远小于基座。确认基座和适配器的架构、层名对得上——同一系列、同一 Instruct 变体最好。硬套别家模型的 LoRA,加载可能直接报错,也可能看起来加载成功但效果接近没有。

CLI 里直接加载

本机先试效果,用 llama-cli--lora 把适配器叠上去,不必先合并:

bash
./llama-cli -c 2048 -cnv \
  -m Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf \
  --lora Llama-3-Instruct-abliteration-8B.gguf

想压一点适配器强度,用 --lora-scaled,后面跟一个浮点系数:

bash
./llama-cli -c 2048 -cnv \
  -m base.gguf \
  --lora-scaled adapter.gguf 0.5

0.5 表示半强度,从 1.0 试起再往下收,通常比一上来拉到很大更稳。CLI 适合单次对话验证;真正要「同一次服务里换多个适配器、按请求切换」,看下面的 llama-server

llama-server 热切换

2024 年 8 月合并的 PR #8857 给 server 加了运行时切换。关键 flag 是 --lora-init-without-apply:启动时把适配器读进内存,但先不套到计算图上,之后用 HTTP 接口改 scale。

启动示例,一次挂两个适配器:

bash
./llama-server -c 4096 \
  -m base.gguf \
  --lora adapter_1.gguf \
  --lora adapter_2.gguf \
  --lora-init-without-apply

接口很短:

  • GET /lora-adapters:列出已加载的适配器;未启用的 scale 为 0
  • POST /lora-adapters:按 id 设 scale,例如只开第一个、关掉第二个:
json
[{"id":0,"scale":1.0},{"id":1,"scale":0.0}]

关掉某个适配器:把它的 scale 设为 0,或不放进这次提交的列表。这样同一份基座可以按请求选风格,不用重启,也不用为每个组合导出一份合并后的 GGUF。做 API 网关时,可以在路由层按用户或产品线改 scale,基座只加载一次。

注意点

  • 适配器必须和基座同源(同一系列、同一架构)。把别家模型的 LoRA 硬套上去通常没用。
  • scale 不是越大越好。从 1.0 试起,过强容易糊掉指令遵循,或者输出开始跑偏。
  • --lora-init-without-apply 适合「先挂着、再按需开」。若启动就要立刻生效,可以不带这个 flag,按当前文档的默认行为来。
  • 量化基座(比如 Q4_K_M)一般可以配合对应的 LoRA GGUF;若效果异常,先确认转换脚本和 llama.cpp 版本是否匹配,再查 adapter 是否针对该 Instruct 变体训练。
  • 旧流程里的 llama-export-lora 仍然有用:要分发「单文件、用户不用管适配器」的成品时,合并更省事。热加载解决的是服务端频繁切换,不是取代所有合并场景。

总结:一份基座 GGUF + 若干小 adapter。CLI 用 --lora / --lora-scaled 试手感,server 用 /lora-adapters 热切。少拷几份大文件,换风格也快一截。源码与 PR 见 llama.cpp#8857;转换可参考 GGUF-my-LoRA

分享: