ADR: Use llama-cpp-python (in-process GGUF) for Tier 2 SLM inference¶
Context¶
YazSes v0.4 introduces a Tier 2 SLM intent routing layer that classifies voice command transcripts that fail the existing regex grammar (Tier 1). This layer must operate on CPU hardware without a GPU, must not require cloud connectivity, must integrate with the existing Python daemon process, and must complete inference within a 300 ms budget per utterance.
The two primary implementation approaches are: (1) an in-process Python inference library that loads the model into the daemon process memory space, or (2) an out-of-process inference server (e.g., Ollama, LM Studio) that the daemon queries over a local socket. A third approach is a cloud API, but this is excluded by the offline-first constraint.
The daemon currently has no external service dependencies at runtime. Introducing a dependency on a running local inference server would change the daemon startup contract (requires a separate process to be running) and add 5–20 ms of IPC overhead per inference call.
The cap-001 feasibility case is validated by src-003, which demonstrates TinyLlama-1.1B at 4-bit quantisation running on edge hardware without cloud connectivity for speech-to-action intent classification. The same GGUF format used in that paper is the standard interchange format for llama-cpp-python.
Decision¶
We will use llama-cpp-python >= 0.3.0 as the in-process inference backend for Tier 2 SLM classification, loading a GGUF-quantised model (Phi-3-mini-4k-Q4_K_M or TinyLlama-1.1B-Q4_K_M) into the daemon process at startup.
In practice this means: the SLMRouter module imports llama_cpp.Llama at startup; the model is loaded once into the daemon's RAM and kept resident for the daemon's lifetime; each Tier 2 classification call invokes Llama.create_completion() synchronously within the post-transcription pipeline stage. The model is loaded only if CommandsConfig.slm_model_path resolves to an existing GGUF file; if the file is absent, Tier 2 is disabled and the daemon runs in Tier 1 (regex-only) mode. [HYPOTHESIS]
Consequences¶
Positive¶
- Zero runtime service dependency — the daemon starts without requiring any external process. [HYPOTHESIS]
- No IPC overhead per inference call — model state is in the same process memory. [HYPOTHESIS]
llama-cpp-pythonis the most widely-used Python binding for GGUF models; it receives regular updates for new quantisation formats and model architectures. [HYPOTHESIS]- The GGUF format is the de-facto standard for quantised open-weight models; Phi-3-mini and TinyLlama are both available in GGUF from Hugging Face under Apache-2.0. [HYPOTHESIS]
- [EVIDENCE src-003] TinyLlama-1.1B at 4-bit quantisation is directly validated as feasible for speech-to-action intent classification on edge hardware in the survey literature.
Negative¶
- The daemon's RAM footprint increases by 700 MB (TinyLlama variant) or 2.2 GB (Phi-3-mini variant) at startup. On machines with < 6 GB available RAM, this may cause memory pressure alongside faster-whisper's own footprint. [HYPOTHESIS]
llama-cpp-pythonwheels are platform-specific (C++ extension) and have had version compatibility issues on some Linux distributions (glibc version, AVX2 availability). The CI matrix (Linux x86_64, macOS arm64, Windows x86_64) must validate wheel availability for the pinned version. [HYPOTHESIS]- Loading the SLM model adds 2–5 seconds to daemon startup time. Users with
slm_model_pathconfigured will notice a longer startup. A loading indicator inyazses doctoroutput is required. [HYPOTHESIS]
Neutral¶
- The model file must be downloaded separately and is not bundled in the YazSes package. This is standard practice for ML model deployments;
yazses doctorwill direct users to the download command. - The
llama-cpp-pythonlibrary exposes a broader API than we use; we consume onlyLlama.__init__andLlama.create_completion. This surface is stable and unlikely to change incompatibly.
Alternatives Considered¶
| Alternative | Reason Rejected |
|---|---|
| Ollama local inference server | Requires a separate long-running process (ollama serve). Changes the daemon's startup contract from "single process" to "requires Ollama running". Adds 5–15 ms socket IPC overhead per call. Ollama is a great user-facing tool but the wrong abstraction for an embedded daemon component. [HYPOTHESIS] |
| ctransformers library | Functionally equivalent to llama-cpp-python for GGUF models, but has lower maintenance activity (last release > 6 months old as of 2026-05). llama-cpp-python has more active development and broader model support. [HYPOTHESIS] |
| HuggingFace Transformers (float16 or bfloat16) | Requires GPU or very slow on CPU at full precision; 4-bit GGUF quantisation via llama-cpp-python is the purpose-built path for CPU inference. [HYPOTHESIS] |
| ONNX Runtime with quantised model | Valid alternative; ONNX Runtime is well-maintained and has CPU int8 support. However, Phi-3-mini and TinyLlama ONNX exports are less commonly available and less tested than GGUF exports. Revisit if llama-cpp-python wheel issues prove blocking. [HYPOTHESIS] |
References¶
- [EVIDENCE src-003]: edge-cloud adaptive inference paper demonstrating TinyLlama-1.1B 4-bit for offline speech-to-action.
Output Quality Note¶
- All placeholders replaced.
- First sentence of Decision is "We will use..."
- Every claim tagged.
-
deciderspopulated. - Alternatives table has ≥ 2 rows.
- Negative consequences section is honest.
Study: [[yazses-future-voice-hci/input/research_scope|yazses-future-voice-hci]]