Skip to content

Disable XNNPACK and NNAPI for the wake word / VAD interpreters (fixes #105) - #109

Merged
RapierXbox merged 1 commit into
RapierXbox:mainfrom
WiesiDeluxe:fix/105-tflite-delegates
Sep 22, 2026
Merged

RapierXbox merged 1 commit into
RapierXbox:mainfrom
WiesiDeluxe:fix/105-tflite-delegates

Conversation

@WiesiDeluxe

Copy link
Copy Markdown

Fixes #105.

Two separate problems on the 32-bit Wall Displays, both in WakeWordDetector.buildInterpreter:

  1. XNNPACK – TFLite enables the XNNPACK delegate by default, and its qs8_gemm_minmax 4x8 aarch32 NEON kernel segfaults (fault addr 0x14, libtensorflowlite_jni.so+0x1f9b68) as soon as the wake-word or VAD model runs on live audio. Reproduced bit-identically on the X2 (PEGASUS, Android 8.1) and the Gen1 (STARGATE, Android 7, which has no NNAPI at all), so 3d13d7f alone doesn't reach it.
  2. NNAPI – with XNNPACK off, the X2's NNAPI runtime spawns a thread per execution and leaks a memory mapping each time (/proc/<pid>/maps +~7000 entries per 20 s) until it hits vm.max_map_count and dies with thread constructor failed: Try again after ~3 minutes.

The models are 52 KB / 34 KB and the plain int8 CPU kernels run them at ~40 % of one core on the quad-A7 STARGATE, so both delegates are simply disabled. Verified with a patched 3.26230.0834 on the STARGATE and the X2 (wake word detected and answered end to end, stable for hours) and on the arm64 XL. Measurements, disassembly and logs: #105 (comment).

Side effect: this also makes main compile again – 3d13d7f references Build.VERSION.SDK_INT without importing android.os.Build (error: package Build does not exist in compileDebugJavaWithJavac); that block is gone with this change. :app:assembleDebug passes with this branch.

🤖 Generated with Claude Code

…rXbox#105)

Any TFLite inference on live audio crashed the app on the 32-bit Wall
Displays (X2/PEGASUS on Android 8.1 and Gen1/STARGATE on Android 7):
SIGSEGV at libtensorflowlite_jni.so+0x1f9b68, XNNPACK's
qs8_gemm_minmax 4x8 aarch32 NEON kernel, called with a garbage input
pointer (0x14). TFLite enables the XNNPACK delegate by default, so the
NNAPI-only change did not reach that code path.

With XNNPACK off the segfault is gone, but on the X2 (API 27) the NNAPI
runtime then leaks a memory mapping per execution
(/proc/<pid>/maps grows ~7000 entries per 20 s) until it hits
vm.max_map_count and pthread_create fails:
"thread constructor failed: Try again" in
android::nn::StepExecutor::startComputeOnCpu.

The wake word and VAD models are 52 KB / 34 KB; the built-in int8 CPU
kernels handle them with ~40 % of one core on a quad A7, so neither
delegate is needed. Verified on both 32-bit devices (wake word detected
and answered end to end, stable for hours) and on the arm64 XL.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@RapierXbox
RapierXbox merged commit c1f34fb into RapierXbox:main Sep 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Voice pipeline crashes with SIGSEGV on Wall Display X2 (PEGASUS) — any TFLite inference on live audio

2 participants