Takosaga commited on
Commit
0e17435
Β·
1 Parent(s): 4f15800

docs: add design spec for MiniCPM5-1B text engine replacement

Browse files
docs/superpowers/specs/2026-06-10-minicpm5-text-engine-design.md ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Replace Nemotron with MiniCPM5-1B β€” Design Spec
2
+
3
+ ## Overview
4
+
5
+ Replace the Phase 1 English text generation pipeline: swap `TextEngine` (which spawns `llama-cli` subprocesses with Nemotron 30B-A3B, ~16 GB) for a new `MiniCPMTextEngine` that loads MiniCPM5-1B Q8_0 via llama-cpp-python (~1.1 GB). Phase 2 translation via tiny-aya-water remains unchanged.
6
+
7
+ ## Why This Change
8
+
9
+ | Aspect | Nemotron (current) | MiniCPM5-1B (new) |
10
+ |---|---|---|
11
+ | Model size | ~16 GB (IQ4_XS) | ~1.1 GB (Q8_0) |
12
+ | Runtime | llama-cli subprocess | llama-cpp-python in-process |
13
+ | Architecture | MoE (needs `--n-cpu-moe`) | Standard LlamaForCausalLM |
14
+ | VRAM / RAM usage | High (~16 GB) | Low (~1.1 GB) |
15
+ | Subprocess overhead | Yes (spawn + wait per call) | No (lazy-load once, unload after) |
16
+ | Context window | 32k | 131k |
17
+
18
+ ## Architecture
19
+
20
+ ```
21
+ User input β†’ app.py click handler β†’ EnginePool.get(config) β†’ MiniCPMTextEngine (Phase 1) β†’ cards rendered with English on front
22
+ ```
23
+
24
+ ### Component Changes
25
+
26
+ **New:** `MiniCPMTextEngine` in `core/engine.py`
27
+ - Uses llama-cpp-python directly (same runtime as existing `LlamaCppTextEngine`)
28
+ - Lazy-loads the Q8_0 model (~1.1 GB) on first `.generate()` call
29
+ - Unloads after completion to free memory (via EnginePool mutual exclusion)
30
+ - Uses MiniCPM5-1B's built-in chat template (`apply_chat_template`) β€” no manual prompt formatting
31
+
32
+ **Removed:** `TextEngine` in `core/engine.py`
33
+ - Deletes the entire class and all llama-cli subprocess logic
34
+ - Removes `_build_command`, `_build_generation_prompt`, `_build_translation_prompt`, `_build_translation_prompt` methods that were only used by TextEngine
35
+ - Keeps translation-specific prompts inside `LlamaCppTextEngine` (those are still needed)
36
+
37
+ **Updated:** `EnginePool.get_english_engine()` returns `MiniCPMTextEngine` instead of `TextEngine`
38
+
39
+ **Updated:** `EngineConfig.from_settings_yaml()` loads `minicpm_model_path` and simplified generation params (no MoE, no n_ubatch)
40
+
41
+ **Unchanged:** Phase 2 pipeline β€” `LlamaCppTextEngine`, `TTSEngine`, `ImageGenEngine`, `EnginePool._ensure_exclusive("translation")`, all media engines
42
+
43
+ ## Component Details
44
+
45
+ ### MiniCPMTextEngine
46
+
47
+ ```python
48
+ class MiniCPMTextEngine:
49
+ def __init__(self, model_path: str, device: str = "cuda"): ...
50
+ def _load_model(self) -> None: ... # Lazy-load via llama_cpp.Llama
51
+ def generate(self, texts: list[str], scenario: str, cefr_level: CEFRLevel, batch_size: int | None = None) -> TextResult: ...
52
+ def unload(self) -> None: ... # del model + torch.cuda.empty_cache()
53
+ ```
54
+
55
+ **Prompt format:** Chat template via `apply_chat_template(messages=[{"role": "system", "content": "..."}, {"role": "user", "content": "..."}])`
56
+
57
+ System prompt instructs the model to act as a language teacher generating simple sentences at the specified CEFR level about the given scenario. User message is identical to the current Nemotron prompt (batch size, CEFR level, scenario).
58
+
59
+ **Generation parameters:**
60
+ - `max_tokens`: 512
61
+ - `temperature`: 0.7
62
+ - `echo`: False
63
+ - `n_ctx`: 4096 (sufficient for batch_size=3 sentences)
64
+
65
+ ### EngineConfig Changes
66
+
67
+ | Removed | Added |
68
+ |---|---|
69
+ | `nemotron_model_path: str` | `minicpm_model_path: str` |
70
+ | `n_cpu_moe: int = 36` | *(not needed β€” standard Llama arch)* |
71
+ | `n_ubatch: int = 1024` | *(llama-cpp-python handles this internally)* |
72
+
73
+ All other fields (`n_ctx`, `n_threads`, `n_batch`, `top_k`, `repeat_penalty`, `top_p`, `min_p`, `temperature`, `max_tokens`) are retained.
74
+
75
+ ### settings.yaml Changes
76
+
77
+ - Rename `nemotron` section to `minicpm` with repo `Abiray/MiniCPM5-1B-GGUF`, file `minicpm5-1b-Q8_0.gguf`, runtime `llama-cpp-python`
78
+ - Remove `n_cpu_moe` from `generation` section
79
+
80
+ ### download_models.py Changes
81
+
82
+ - Rename `nemotron` entry to `minicpm` with repo `Abiray/MiniCPM5-1B-GGUF`, file `minicpm5-1b-Q8_0.gguf`
83
+ - Update description text
84
+
85
+ ## Data Flow
86
+
87
+ ```
88
+ Phase 1:
89
+ User enters scenario + CEFR level β†’ app.py clicks "Generate Text"
90
+ β†’ generate_text_async() calls EnginePool.get(config).get_english_engine()
91
+ β†’ returns MiniCPMTextEngine (lazy-load on first call)
92
+ β†’ .generate(texts=[], scenario, cefr_level, batch_size)
93
+ β†’ MiniCPM builds chat prompt, generates sentences
94
+ β†’ TextResult.translations β†’ list of English sentences
95
+ β†’ Cards rendered with placeholder_back=True
96
+
97
+ Phase 2 (unchanged):
98
+ User clicks "Generate Cards" β†’ EnginePool.get_translation_engine()
99
+ β†’ LlamaCppTextEngine (tiny-aya-water) translates sentences
100
+ ```
101
+
102
+ ## Error Handling
103
+
104
+ - Model file missing: `FileNotFoundError` raised in `__init__`, caught by `generate_text_async()` with same user-facing message pattern as current Nemotron error handling
105
+ - llama-cpp-python not installed: `ImportError` β€” but package is already installed via `LlamaCppTextEngine`, so this path is unlikely
106
+ - Generation failure: RuntimeError with stderr capture, shown to user in styled error box (same as current)
107
+
108
+ ## Testing
109
+
110
+ - `scripts/smoke_test.py`: Must pass (imports all modules, constructs Gradio app)
111
+ - Manual test: Generate text for a scenario β†’ verify MiniCPM produces readable English sentences at appropriate CEFR level
112
+ - Phase 2 still works unchanged: generate media after text generation
113
+
114
+ ## Files Modified
115
+
116
+ | File | Action |
117
+ |---|---|
118
+ | `core/engine.py` | Remove `TextEngine`, add `MiniCPMTextEngine` |
119
+ | `core/types.py` | Rename `nemotron_model_path` β†’ `minicpm_model_path`, remove MoE/ubatch params |
120
+ | `configs/settings.yaml` | Rename nemotron β†’ minicpm, remove n_cpu_moe |
121
+ | `models/download_models.py` | Rename nemotron entry to minicpm |
122
+ | `docs/superpowers/specs/2026-06-10-minicpm5-text-engine-design.md` | This spec (new) |