From 712062eebf459855b3e906937be71d237464d9dc Mon Sep 17 00:00:00 2001 From: Shaw Date: Mon, 19 Oct 2026 21:34:49 -0700 Subject: [PATCH] asr: memory-map the Parakeet GGUF by default, Android included The Parakeet-TDT (Phonon-2) backend reads its fv5 codes in place from the GGUF, but on Android it inherited the Qwen3-ASR CPU profile, which reads the whole file into private memory. On a 4 GB tablet that is a ~320 MB anonymous allocation that goes to swap. Map it on every platform instead; ELIZA_ASR_USE_MMAP=0 still selects the private copy. The Qwen3-ASR policy is unchanged. Co-Authored-By: Claude Opus 5.5 --- tools/omnivoice/src/eliza-asr-parakeet.inc | 6 +++--- tools/omnivoice/src/eliza-inference-ffi.cpp | 9 +++++++++ tools/parakeet/README.md | 2 ++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/tools/omnivoice/src/eliza-asr-parakeet.inc b/tools/omnivoice/src/eliza-asr-parakeet.inc index a56a7d08a..9be89db4c 100644 --- a/tools/omnivoice/src/eliza-asr-parakeet.inc +++ b/tools/omnivoice/src/eliza-asr-parakeet.inc @@ -78,9 +78,9 @@ static int eliza_parakeet_load_locked(EliInferenceContext * ctx, char ** out_err return 0; } pk_params pp = pk_default_params(); - /* same policy as the Qwen3-ASR path: Android's CPU profile keeps ASR - * weights in private memory (ELIZA_ASR_USE_MMAP overrides) */ - pp.use_mmap = eliza_asr_use_mmap() ? 1 : 0; + /* the GGUF is used in place, so map it on every platform, Android + * included (ELIZA_ASR_USE_MMAP=0 reads it into private memory) */ + pp.use_mmap = eliza_parakeet_use_mmap() ? 1 : 0; if (const char * env = std::getenv("ELIZA_ASR_THREADS")) { const int n = std::atoi(env); if (n > 0) pp.n_threads = n; diff --git a/tools/omnivoice/src/eliza-inference-ffi.cpp b/tools/omnivoice/src/eliza-inference-ffi.cpp index 9fba3b373..b1f58f753 100644 --- a/tools/omnivoice/src/eliza-inference-ffi.cpp +++ b/tools/omnivoice/src/eliza-inference-ffi.cpp @@ -729,6 +729,15 @@ static bool eliza_asr_use_mmap() { return eliza_bool_env_or_default("ELIZA_ASR_USE_MMAP", !eliza_asr_android_cpu_profile()); } +// Parakeet-TDT (Phonon-2) reads its fv5 codes in place from the GGUF, so a +// mapping costs only clean, reclaimable page cache. A private copy is a +// ~320 MB anonymous allocation that a 4 GB Android device pushes to swap. +// mmap is therefore the default on every platform; ELIZA_ASR_USE_MMAP=0 +// still selects the private copy. +static bool eliza_parakeet_use_mmap() { + return eliza_bool_env_or_default("ELIZA_ASR_USE_MMAP", true); +} + static bool eliza_asr_use_extra_bufts() { return eliza_bool_env_or_default("ELIZA_ASR_USE_EXTRA_BUFTS", !eliza_asr_android_cpu_profile()); } diff --git a/tools/parakeet/README.md b/tools/parakeet/README.md index 8556c04f2..6c02224c7 100644 --- a/tools/parakeet/README.md +++ b/tools/parakeet/README.md @@ -128,6 +128,8 @@ whose `asr/` holds a GGUF with `general.architecture = parakeet-tdt` loads this word times. - `eliza_inference_asr_stream_supported()` returns 1 and the `asr_stream_*` session runs `pk-stream`. The stream does not return token ids, because Parakeet's vocabulary is not the text model's. +- The GGUF is memory-mapped on every platform, Android included, so its pages stay clean and reclaimable. + `ELIZA_ASR_USE_MMAP=0` reads it into private memory instead (about 320 MB of anonymous memory). - `ELIZA_ASR_THREADS` sets the thread count. `ELIZA_ASR_STREAM_{RIGHT,HOP,MAX_WINDOW}_MS` tune the stream. ## Evidence boundary