$npx -y skills add acnlabs/OpenPersona --skill persona-model-trainerFine-tune any HuggingFace instruction-tuned model (Gemma 4, Qwen 3, Llama, Phi, Mistral, and more) on persona data from anyone-skill. Produces a self-contained, locally runnable persona model — no cloud API required.
| 1 | # persona-model-trainer |
| 2 | |
| 3 | Fine-tune a small local model on persona data (raw + distilled). Turn anyone-skill's output into a self-contained model that **is** the person — no prompting, no cloud, no latency. |
| 4 | |
| 5 | **Dependency chain**: `anyone-skill` → `persona-knowledge` → `persona-model-trainer` → runnable persona model (`{model_id}`) |
| 6 | |
| 7 | **Input**: `training/` folder produced by `anyone-skill` Step 6-D / `persona-knowledge` export (raw/ + conversations.jsonl + probes.json) |
| 8 | **Output**: LoRA/QLoRA adapter weights + GGUF / Ollama / vLLM / ONNX exports |
| 9 | |
| 10 | > **Full walkthrough**: see `[references/pipeline-guide.md](references/pipeline-guide.md)` for the complete end-to-end guide (data → train → evaluate → version → run). |
| 11 | |
| 12 | --- |
| 13 | |
| 14 | ## When to use this skill |
| 15 | |
| 16 | Trigger phrases: |
| 17 | |
| 18 | - "train a model for this persona" |
| 19 | - "make it run locally / on my phone" |
| 20 | - "fine-tune on the distilled data" |
| 21 | - "I want a model, not just a prompt" |
| 22 | - "create a self-contained persona model" |
| 23 | |
| 24 | **Not suitable when:** |
| 25 | |
| 26 | - Effective assistant-role turns (raw/ + conversations.jsonl combined) < 200 |
| 27 | - User only wants a quick prompt-based persona (use anyone-skill alone) |
| 28 | |
| 29 | > Fictional characters and historical figures can be trained if `training/raw/` contains scripts, lore, speeches, or biographies — check actual turn count, not subject type. |
| 30 | |
| 31 | --- |
| 32 | |
| 33 | ## Quick Start — Pipeline Script |
| 34 | |
| 35 | For standard use cases, `pipeline.sh` chains all phases (prepare → train → voice test → export) in one command: |
| 36 | |
| 37 | ```bash |
| 38 | # ── Gemma 4 preset (recommended for google/gemma-4-E4B-it) ────────────────── |
| 39 | # Apple Silicon — sets lora-rank=16, lora-layers=16, warmup-ratio=0.1, lora-alpha=16: |
| 40 | bash scripts/pipeline.sh \ |
| 41 | --slug {slug} \ |
| 42 | --model google/gemma-4-E4B-it \ |
| 43 | --source ./training \ |
| 44 | --method mlx \ |
| 45 | --preset gemma4 \ |
| 46 | --probes ./training/probes.json # optional: probe_score eval (generated by persona-knowledge) |
| 47 | |
| 48 | # NVIDIA GPU — same preset, Unsloth backend (QLoRA, fits 8 GB VRAM): |
| 49 | bash scripts/pipeline.sh \ |
| 50 | --slug {slug} \ |
| 51 | --model unsloth/gemma-4-4b-it-bnb-4bit \ |
| 52 | --source ./training \ |
| 53 | --method unsloth \ |
| 54 | --preset gemma4 \ |
| 55 | --probes ./training/probes.json # omit if training/ was not exported by persona-knowledge |
| 56 | |
| 57 | # ── Manual override (any model) ────────────────────────────────────────────── |
| 58 | # Local GPU — Apple Silicon (mlx) or NVIDIA (unsloth / qlora / lora): |
| 59 | bash scripts/pipeline.sh \ |
| 60 | --slug {slug} \ |
| 61 | --model {model_id} \ |
| 62 | --source ./training \ |
| 63 | --method mlx \ |
| 64 | --lora-rank 16 \ |
| 65 | --lora-layers 16 \ |
| 66 | --warmup-ratio 0.05 \ |
| 67 | --batch-size 2 \ |
| 68 | --learning-rate 2e-4 \ |
| 69 | --epochs 3 |
| 70 | |
| 71 | # No local GPU — train in Google Colab (free T4): |
| 72 | bash scripts/pipeline.sh \ |
| 73 | --slug {slug} \ |
| 74 | --model {model_id} \ |
| 75 | --source ./training \ |
| 76 | --method colab # generates colab_train_{slug}.ipynb, then exits |
| 77 | # → Upload .ipynb to colab.research.google.com → Run all → download adapter zip |
| 78 | # → Unzip into models/{slug}/export/ then: |
| 79 | bash scripts/pipeline.sh --slug {slug} --model {model_id} --source ./training \ |
| 80 | --method skip-train # runs voice_test + export on the downloaded adapter |
| 81 | |
| 82 | # Dry-run to validate setup (writes nothing): |
| 83 | bash scripts/pipeline.sh ... --dry-run |
| 84 | |
| 85 | # After the script finishes, run the model with Ollama: |
| 86 | ollama create {slug} -f models/{slug}/export/ollama/Modelfile |
| 87 | ollama run {slug} |
| 88 | |
| 89 | # Phase 8–9: bundle into installed persona pack |
| 90 | # --model-dir points to the version management root (BASE_DIR), not export/ directly |
| 91 | python scripts/pack_integrate.py \ |
| 92 | --slug {slug} \ |
| 93 | --model-dir models/{slug}/ |
| 94 | # --pack-dir ~/.openpersona/personas/persona-{slug}/ # optional; auto-discovered if omitted |
| 95 | # → resolves export/ via manifest.json, copies artifacts, updates persona.json |
| 96 | ``` |
| 97 | |
| 98 | Use the phases below for custom workflows, debugging, or when individual steps need tuning. |
| 99 | |
| 100 | --- |
| 101 | |
| 102 | ## Phase 1: Pre-flight Check |
| 103 | |
| 104 | Read `training/metadata.json` (written by anyone-skill Step 6-D): |
| 105 | |
| 106 | ```json |
| 107 | { |
| 108 | "slug": "...", |
| 109 | "name": "...", |
| 110 | "subject_type": "personal | public | fictional | historical | archetype", |
| 111 | "source_count": 3, |
| 112 | "total_words": 48000, |
| 113 | "distilled_turns": 320, |
| 114 | "raw_files": ["whatsapp.jsonl", "essays.txt"], |
| 115 | "created_at": "2026-04-11T10:00:00Z" |
| 116 | } |
| 117 | ``` |
| 118 | |
| 119 | **Gate — estimate effec |