Fine-tune MiniCPM5-1B into a LoRA adapter and convert it to a GGUF adapter that loads directly into llama.cpp / llama-server and the MiniCPM Desk Pet app's custom-LoRA upload. Use when the user wants "GGUF LoRA", "convert LoRA to GGUF", "convert_lora_to_gguf", a custom persona/skin for the desktop pet, "桌宠自定义 LoRA", "上传 LoRA 到桌宠", or asks how to take a trained adapter and run it on a GGUF base.
93%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Low
Low-risk findings worth noting
The framework skills (minicpm5-finetune-*) all emit a PEFT adapter (adapter_model.safetensors + adapter_config.json). But llama.cpp / llama-server — and the MiniCPM Desk Pet app's custom-LoRA upload — load a GGUF LoRA adapter (--lora some-adapter.gguf). This skill is the bridge: train a PEFT LoRA, then convert it to GGUF and run/upload it.
This is the path you want when the base model is served as GGUF (Desk Pet, Ollama, LM Studio, plain
llama-server). If you serve the fp16 HF base with vLLM / transformers, you don't need GGUF — load the PEFT adapter directly.
train (any minicpm5-finetune-* skill) this skill
┌────────────────────────────────────┐ ┌──────────────────────────────────┐
BASE (fp16 HF) ─► adapter_model.safetensors ─► convert_lora_to_gguf.py ─► adapter.gguf
adapter_config.json │
llama-server --lora / Desk Pet upload| Var | Example | Default |
|---|---|---|
ADAPTER_DIR | ./runs/minicpm5_unsloth/adapter_final | required — a PEFT dir with adapter_config.json + adapter_model.safetensors |
BASE_MODEL | openbmb/MiniCPM5-1B (HF id) or a local fp16 HF dir | required — must be the same base the adapter was trained on |
OUTTYPE | f16 (recommended) / q8_0 / bf16 / f32 | f16 |
OUT_GGUF | ./minicpm5-mylora.gguf | <ADAPTER_DIR>/adapter_model.f16.gguf |
Don't have an adapter yet? First run a training skill — start from the router
minicpm5-finetune(or go straight tominicpm5-finetune-unslothfor single-GPU LoRA). Come back here withADAPTER_DIRpointing at its output.
git clone --depth=1 https://github.com/ggerganov/llama.cpp.git
cd llama.cpp
pip install -r requirements.txt # converter deps: torch, safetensors, gguf, transformersconvert_lora_to_gguf.py lives at the repo root. You only need the Python script for conversion; build the C++ binaries (step 4) only if you want to test locally.
python convert_lora_to_gguf.py "$ADAPTER_DIR" \
--base "$BASE_MODEL" \
--outtype f16 \
--outfile "$OUT_GGUF"--base only needs the base model's config (config.json, tokenizer.json) — not the weights. A local fp16 HF dir or an HF id both work.--base-model-id openbmb/MiniCPM5-1B instead of --base (it pulls just the config)..gguf of roughly the same size as the input .safetensors (a 22 MB r=16 adapter → ~22 MB GGUF).🔑 The #1 gotcha —
base_model_name_or_pathpoints at the training machine. PEFT writes the absolute path of the base used during training intoadapter_config.json(e.g./user/.../MiniCPM5-models-fixed/official). On any other machine the converter can't find it. Always pass--base(or--base-model-id) explicitly to override it — don't rely on whatever is baked into the config. The base you pass MUST match the one you trained on, or the adapter math is meaningless.
python -c "import gguf,sys; r=gguf.GGUFReader('$OUT_GGUF'); print('tensors:', len(r.tensors)); print('arch:', r.get_field('general.architecture').parts[-1].tobytes().decode() if r.get_field('general.architecture') else '?')"Expect general.type = adapter and a nonzero tensor count. MiniCPM5-1B is a Llama-architecture model, so the converter treats it as llama — this is correct, not an error.
You need a GGUF base model too (the adapter is applied on top of it). Grab the released base:
huggingface-cli download openbmb/MiniCPM5-1B-GGUF MiniCPM5-1B-Q8_0.gguf --local-dir .Then:
# CLI
llama-cli -m MiniCPM5-1B-Q8_0.gguf --lora "$OUT_GGUF" \
-p "你好" -n 128 --temp 0.7 --top-p 0.95
# OpenAI-compatible server
llama-server -m MiniCPM5-1B-Q8_0.gguf --lora "$OUT_GGUF" --port 8080 --jinjaIf the persona/behavior you trained shows up, the GGUF is good. If output is identical to the base, the adapter didn't load (check the --lora path and that --base matched in step 2).
Quant compatibility: a GGUF LoRA built from an fp16 adapter applies fine on top of a quantized base (Q8_0 / Q4_K_M). You do not need a separate adapter per base quant.
The Desk Pet app loads exactly this kind of file. The fp16 GGUF you just built is upload-ready:
.gguf — the app copies it into its
<userData>/adapters/uploads/ directory and registers it.llama-server with your
--lora.Constraints the app enforces (match them or the upload is rejected):
.gguf file (the GGUF LoRA from step 2 — not the .safetensors,
not a merged full model).FileNotFoundError / can't load base model config during conversion → the
adapter_config.json base path doesn't exist locally. Fix with --base <local-dir> or
--base-model-id openbmb/MiniCPM5-1B (step 2 gotcha).llama-cli users must pass it themselves.KeyError on an unknown tensor / target module → the adapter targeted modules the
converter doesn't map. Stick to the standard attention+MLP projections
(q/k/v/o_proj, gate/up/down_proj) when training (all minicpm5-finetune-* skills
already default to these)..gguf but Desk Pet shows nothing → you uploaded the merged full model or a
base GGUF by mistake. A LoRA adapter GGUF is small (tens of MB) and has
general.type = adapter (step 3).minicpm5-deploy-vllm / -transformers / -sglang.--lora) → merge first
(model.save_pretrained_merged(...) or peft ... merge_and_unload()), then convert the
merged fp16 model with convert_hf_to_gguf.py (see the "Building your own GGUF"
section of minicpm5-deploy-llama-cpp). That produces a standalone base GGUF, not an
adapter.minicpm5-finetune (router) and its sub-skills.minicpm5-deploy-llama-cpp.convert_lora_to_gguf.py in ggerganov/llama.cpp.OpenBMB/MiniCPM
316cfb1
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.