Open Source
Explore the latest AI open-source projects from GitHub and HuggingFace.
Explore the latest AI open-source projects from GitHub and HuggingFace.
LocalVQE — Local Voice Quality Enhancement — is a set of compact neural models for **acoustic echo cancellation (AEC), noise suppression, and dereverberation** of 16 kHz speech, built to run in real time on ordinary CPUs. Apache-2.0 licensed, opened in April 2026, and sitting at roughly 182 stars, it ships C++ inference via [GGML](https://github.com/ggml-org/ggml) with a PyTorch reference for research, plus GGUF weights and a demo on Hugging Face. It is a streaming, CPU-tuned derivative of **DeepVQE** ([Indenbom et al., Interspeech 2023](https://arxiv.org/abs/2306.03177)). ## The Problem Being Solved Echo cancellation is the unglamorous layer under every voice call: when a speaker plays the far-end audio and the microphone picks it back up, the far end hears itself. Classical adaptive filters handle the linear part of that path but struggle with nonlinearity and reverberation; neural approaches handle both but have generally been too heavy for a CPU budget shared with the rest of an application. LocalVQE's position is that the model does not need to be large. Everything is **causal and streaming** on a 256-sample hop — **16 ms of latency** — and the largest model in the main line is 4.8 M parameters. The design target is not a benchmark leaderboard but fitting inside a real-time audio callback on hardware people actually have. ## A Ladder of Model Sizes Rather than one model, the project publishes a size ladder with explicit guidance on which to pick. Speed figures below are per 16 ms hop on a Ryzen 9 7900 with 4 threads; RT is the realtime factor. | Version | Does | Params | Size (F32) | Speed | Pick it when | |---|---|---:|---:|---|---| | v1.3 | AEC + NS + dereverb | 4.8 M | ~19 MB | 3.2 ms · 5.0x RT | best joint quality, CPU budget available | | v1.2 | AEC + NS + dereverb | 1.3 M | ~5 MB | 1.7 ms · 8.9x RT | tight CPU / low-power devices | | v1.4-AEC | echo only | 203 K | ~3 MB | 0.83 ms · 19x RT | NS handled elsewhere, or keep the room | | v1.4-AEC 2.7K | echo only, linear filter | 2.7 K | ~17 KB | 0.36 ms · 44x RT | lightest canceller, non-reverberant echo | The distinction between the joint models and the AEC-only line is not merely size. The joint v1.2/v1.3 models **delete the background** — noise and room reverberation go with the echo — while v1.4-AEC removes only far-end echo and passes voice, room, and background through unchanged. Which behaviour you want depends on whether noise suppression lives elsewhere in your pipeline, and the documentation is careful to note that far-end ERLE figures are therefore not comparable between the two lines. A separate **compact line** targets lower-power CPUs: a ~49 K-parameter **GTCRN-AEC** network — a distinct architecture based on [GTCRN](https://github.com/Xiaobin-Rong/gtcrn) (Rong et al., ICASSP 2024) paired with the project's DSP echo-cancellation front-end. On a single Raspberry Pi 5 core it runs an 8-second clip in 388 ms, an RTF of 0.048 or roughly **21x realtime**, reaching ~49x on four threads, and is parity-verified against the PyTorch reference to within ~1e-6 on-device. ## Measurement Discipline Evaluation is on the **ICASSP 2022 AEC Challenge blind test set** — 800 real recordings — scored with AECMOS across five scenarios. For v1.3, doubletalk scores 4.73 echo / 2.62 degradation / 8.5 dB ERLE / 2.89 OVRL, and nearend-singletalk reaches a maximum 5.00 echo score with 4.18 degradation and 3.17 OVRL. The unprocessed-mic baselines are printed alongside, so the deltas are checkable. Latency reporting is unusually thorough, giving **p50 and p99 per hop** rather than averages, across thread counts and hardware: | Model | Hardware | Threads | p50 | p99 | RT | |---|---|--:|--:|--:|--:| | v1.3 | Ryzen 9 7900 | 1 | 9.73 ms | 14.48 ms | 1.58x | | v1.3 | Ryzen 9 7900 | 4 | 3.21 ms | 3.42 ms | 4.97x | | v1.3 | + RTX 5070 Ti (Vulkan) | — | 2.57 ms | 4.21 ms | 6.07x | | v1.2 | Ryzen 7 6800U (laptop) | 4 | 2.11 ms | 2.77 ms | 7.44x | The p99 column is the one that matters for audio, where a single missed deadline is an audible glitch — and it exposes that v1.3 single-threaded has a 14.48 ms p99 against a 16 ms budget, which is cutting it close. The project says outright that these graphs are small enough that threads hit diminishing returns past about four, and that the neural stage of v1.4-AEC is too small for GPU offload to pay off. Memory is reported as a delta over the ~7 MiB binary baseline: v1.3 adds 24.4 MiB for a 34.1 MiB peak RSS, v1.4-AEC just 6.7 MiB. ## Integration The build is CMake ≥ 3.20 and a C++17 compiler, with a Nix flake provided. CPU builds emit several `libggml-cpu-*.so` variants from SSE4.2 through AVX-512, selected at runtime; `-DLOCALVQE_VULKAN=ON` adds GPU with CPU fallback when no Vulkan ICD is present. The CLI takes a GGUF plus mic and reference WAVs, and **swapping models means swapping the GGUF** — the engine reads what to do from the file, so the command never changes. The C API in `localvqe_api.h` is four calls (`localvqe_new`, `localvqe_process_f32` for whole clips, `localvqe_process_frame_f32` for per-hop streaming, `localvqe_free`), with a Go/purego binding example included. GGUF integrity is checked at load against a built-in SHA256 allowlist, and PyTorch checkpoint hashes are published in the README. ## Pros and Cons The strengths are consistent. A 203 K-parameter echo canceller running at 19x realtime in 3 MB is a genuinely different deployment object from a typical neural speech model, and the ladder from 2.7 K to 4.8 M lets an integrator pick a point on the quality/cost curve rather than accept one. Reporting p99 alongside p50, on named consumer hardware including a laptop and a Raspberry Pi, is the correct discipline for real-time audio and is rarer than it should be. Evaluating on the ICASSP 2022 AEC Challenge blind set means the numbers sit against an external, widely used reference. A four-function C API, GGUF hot-swapping, runtime SIMD selection, and hash-verified weights make it embeddable rather than merely demonstrable. Crediting DeepVQE and GTCRN as the architectural bases, with Apache-2.0 throughout, is clean. The limitations are real. Every model **requires a far-end reference signal** — a loopback of what the speakers are playing — which is straightforward on a desktop application that owns its audio pipeline and awkward or impossible in contexts where you only have the microphone stream. Operation is **16 kHz only**, so wideband or 48 kHz pipelines need resampling around it. The joint models' background deletion is a design decision that some applications will consider destructive rather than helpful. v1.3 single-threaded leaves little headroom against the 16 ms budget, and thread scaling stalls past four, so the largest model effectively requires a multi-core budget. GPU offload is explicitly not worthwhile for the smaller models, making this a CPU story whether or not that suits your hardware. v1.4-AEC is GGUF-only with no `.pt`, closing off research use of the smallest models. And the project is small — roughly 19 forks, no tagged releases, last pushed mid-July — so integrators should expect to read the source rather than file issues and wait. ## Outlook Compact, GGML-based speech enhancement fits a clear gap: on-device voice processing for conferencing, recording tools, and embedded assistants where sending audio to a server is either too slow or unacceptable for privacy reasons. The Raspberry Pi results suggest the compact line is aimed squarely at hardware products. The main open question is breadth — 48 kHz support and a microphone-only mode without a far-end reference would each widen the addressable set of applications considerably. ## Conclusion LocalVQE suits developers building real-time voice applications that control their own audio path and can supply a loopback reference — conferencing clients, recording software, and embedded voice devices where CPU is scarce and latency is fixed. Start with v1.2 for a general CPU budget or v1.4-AEC when noise suppression already exists downstream, and use the published p99 figures rather than the averages to size against your own deadline. Confirm the 16 kHz constraint and the reference-signal requirement fit your pipeline before committing; those two, not model quality, are what will decide whether it drops in.