Skip to content

Document 32-bit ARM (armv7l / armhf) support#344

Draft
mzramna wants to merge 6 commits into
OHF-Voice:mainfrom
mzramna:document-armv7l-support
Draft

Document 32-bit ARM (armv7l / armhf) support#344
mzramna wants to merge 6 commits into
OHF-Voice:mainfrom
mzramna:document-armv7l-support

Conversation

@mzramna

@mzramna mzramna commented Jun 22, 2026

Copy link
Copy Markdown

Summary

Documents that linux-voice-assistant runs on 32-bit ARM (armv7l / armhf) — e.g. Raspberry Pi 2/3 in 32-bit mode, Orange Pi / Allwinner H3 boards.

The application itself is already architecture-agnostic (pyproject.tomlplatforms = ["any"], no native/compiled code in the package), so no source changes are needed. The only things that blocked 32-bit ARM were packaging of dependencies:

  1. pymicro-wakeword shipped a 64-bit TFLite C library on 32-bit ARM, failing at load with wrong ELF class: ELFCLASS64. Fixed upstream in Add 32-bit ARM (armv7l / armhf) support pymicro-wakeword#18 (adds linux_armv7l detection + a 32-bit lib + an armv7l wheel build).
  2. NumPy has no armv7l wheels on PyPI (it would compile from source — slow and OOM-prone on ~1 GB boards), and piwheels' NumPy doesn't bundle BLAS.

Changes (docs only)

  • README.md: list linux/armv7l (armhf) alongside amd64/aarch64, noting it's via the bare-metal install (Docker images stay amd64/arm64).
  • docs/install_application.md: a 32-bit ARM (armv7l / armhf) subsection under Bare Metal with the two extra steps before script/setup:
    • install libopenblas0,
    • add piwheels as an extra pip index so NumPy & co. install as prebuilt armv7l wheels.

No code, no CI, no Dockerfile changes.

Validation

Validated on a real Allwinner H3 (Cortex-A7, armv7l) running Armbian (Debian bookworm): with the steps above the satellite installs, pairs with Home Assistant over the ESPHome API, and runs the okay_nabu wake word end-to-end (wake → STT → response).

Notes

  • Depends on a pymicro-wakeword release that includes the armv7l wheels (Add 32-bit ARM (armv7l / armhf) support pymicro-wakeword#18, merged). Until that release is on PyPI/piwheels, users can install from that project's main.
  • Extending the multi-arch Docker build to linux/arm/v7 (it currently targets amd64/aarch64) would also need the piwheels index + libopenblas0 in the image; happy to do that as a follow-up if wanted — this PR keeps to the validated bare-metal path.

linux-voice-assistant itself is architecture-agnostic (pyproject `platforms = ["any"]`,
no native code), so it runs on 32-bit ARM (armv7l / armhf) too — e.g. Raspberry Pi 2/3 in
32-bit mode, Orange Pi / Allwinner H3. The only blockers were packaging, not code:

- pymicro-wakeword shipped a 64-bit TFLite lib on 32-bit ARM (fixed upstream in
  OHF-Voice/pymicro-wakeword#18).
- NumPy has no armv7l wheels on PyPI, and piwheels' NumPy doesn't bundle BLAS.

Documents the Bare Metal path for armv7l: add `libopenblas0` and use piwheels as an extra
pip index so NumPy & co. install as prebuilt armv7l wheels (avoids a slow/OOM source build
on ~1 GB boards). No code changes; Docker images stay amd64/arm64.

Validated on an Allwinner H3 (Cortex-A7, armv7l) running Armbian (Debian bookworm):
the satellite pairs over the ESPHome API and runs the okay_nabu wake word.

Co-Authored-By: Claude <noreply@anthropic.com>
@omaramin-2000

Copy link
Copy Markdown
Collaborator

If the support for 32-bit will be added in plan, most probably it will be in a separate branch as it will need to change a lot of modules (such as replacing numpy with array) and will lack the OpenWakeWord support.

@omaramin-2000
omaramin-2000 marked this pull request as draft June 22, 2026 18:43
@mzramna

mzramna commented Jun 22, 2026

Copy link
Copy Markdown
Author

Thanks @omaramin-2000 ! To clarify the scope: this PR is docs-only for the existing bare-metal install — it doesn't change any modules or add a new 32-bit code path.
It's actually already working as-is: I have it running on a real 32-bit ARM board (Allwinner H3 / Cortex-A7, armv7l,
Armbian/Debian bookworm) with the stock numpy>=2,<3 dependency — no numpy→array change needed. NumPy just installs as a prebuilt armv7l wheel from piwheels (https://www.piwheels.org/) instead of compiling from source, which is exactly what the doc note adds.
The satellite pairs over the ESPHome API and runs okay_nabu (microWakeWord) end-to-end (wake → STT → response).
The only real blocker was packaging, not code: pymicro-wakeword shipped a 64-bit TFLite lib on 32-bit ARM (wrong ELF class:ELFCLASS64), fixed in OHF-Voice/pymicro-wakeword#18.
On OpenWakeWord: pyopen-wakeword has the same 64-bit .so packaging issue and also publishes armv7l wheels, so the same fix likely applies — but I've only validated microWakeWord so far, not an OWW model, so I won't claim it works yet.
Totally fine if you'd prefer to keep 32-bit behind a separate branch or out of the official matrix — happy to rescope this (e.g. mark it explicitly as community / bare-metal-only) so 32-bit users at least have the working steps documented. Whatever fits your roadmap. 🙂

@florian-asche

Copy link
Copy Markdown
Collaborator

Thanks @omaramin-2000 ! To clarify the scope: this PR is docs-only for the existing bare-metal install — it doesn't change any modules or add a new 32-bit code path. It's actually already working as-is: I have it running on a real 32-bit ARM board (Allwinner H3 / Cortex-A7, armv7l, Armbian/Debian bookworm) with the stock numpy>=2,<3 dependency — no numpy→array change needed. NumPy just installs as a prebuilt armv7l wheel from piwheels (https://www.piwheels.org/) instead of compiling from source, which is exactly what the doc note adds. The satellite pairs over the ESPHome API and runs okay_nabu (microWakeWord) end-to-end (wake → STT → response). The only real blocker was packaging, not code: pymicro-wakeword shipped a 64-bit TFLite lib on 32-bit ARM (wrong ELF class:ELFCLASS64), fixed in OHF-Voice/pymicro-wakeword#18. On OpenWakeWord: pyopen-wakeword has the same 64-bit .so packaging issue and also publishes armv7l wheels, so the same fix likely applies — but I've only validated microWakeWord so far, not an OWW model, so I won't claim it works yet. Totally fine if you'd prefer to keep 32-bit behind a separate branch or out of the official matrix — happy to rescope this (e.g. mark it explicitly as community / bare-metal-only) so 32-bit users at least have the working steps documented. Whatever fits your roadmap. 🙂

if all needed packages are available we could also try to build a docker container for 32bit.

@mzramna
mzramna marked this pull request as ready for review June 22, 2026 20:54
@omaramin-2000
omaramin-2000 marked this pull request as draft June 22, 2026 23:24
@omaramin-2000

omaramin-2000 commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

@mzramna Please keep this PR as draft for now, until we finally decide how will it go and add the 32-bit support after testing and see its performance. At that time, we can see if this documentation can be edited in your PR or we write a new one from scratch.

@mzramna

mzramna commented Jun 23, 2026

Copy link
Copy Markdown
Author

@omaramin-2000 sorry, I was under the impression it had already been accepted for validation; I'll wait for further communication before reopening the PR, then.

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.

3 participants