brain2qwerty-rs
Rust inference for Brain2Qwerty: MEG/EEG neural decoding to text. Implements both published pipelines with numeric parity against the official Python reference (Pearson r ≥ 0.999999 on continuous tensors; exact match on discrete outputs).
| Version | Paper / use case | Rust API |
|---|---|---|
| V1 | Nature Neuroscience 2026 — keystroke-aligned windows + sentence transformer | V1Pipeline |
| V2 | Sentence-level CTC + TinyLlama+LoRA beam search | Pipeline |
Layout
brain2qwerty-rs/
├── crates/brain2qwerty/ # library + brain2qwerty-infer CLI
├── scripts/ # parity refs, checkpoint conversion, test runner
├── data/ # configs (committed), weights & refs (generated)
└── bench/ # backend benchmarks
Install
Default features enable the RLX Conformer tail (rlx-encoder, rlx-cpu). For reference-only CPU inference:
Apple Silicon backends: --features apple-silicon (Metal, MLX, CoreML/ANE, wgpu).
NVIDIA: --features nvidia-gpu.
Quick start — parity (CI)
Requires the Python brain2qwerty repo on PYTHONPATH:
# Generate all reference tensors + tiny weights (V1, V2 tiny, V2 prod)
# Run every parity test
Individual suites:
| Test | Command |
|---|---|
| V2 tiny encoder / decode / e2e / LLM | cargo test -p brain2qwerty --tests |
| V2 production (dim=1024) | cargo test -p brain2qwerty --test v2_parity |
| V1 keystroke pipeline | cargo test -p brain2qwerty --test v1_parity |
| RLX Conformer tail | cargo test -p brain2qwerty --features rlx-encoder,rlx-cpu,rlx-mlx,rlx-metal --test rlx_encoder_parity |
Weight conversion
Convert a Lightning V2 checkpoint to safetensors:
Produces data/encoder.safetensors (encoder + segmenter + word adapter) and optionally data/llm/ (TinyLlama + LoRA).
See data/README.md for the full data layout.
Inference CLI (V2)
Flags:
--backend rlx(default) or--backend rust— RLX vs pure-Rust reference encoder--device auto|cpu|metal|mlx|cuda|…— RLX device when using RLX backend
Without --llm-weights, output is CTC text only.
Library usage
V2
use ;
let mut pipeline = from_paths_with_options?;
let out = pipeline.run?;
println!;
V1
Input layout is (N, channels, time) per keystroke window (different from V2).
use ;
let pipeline = from_weights?;
let out = pipeline.run?;
println!;
Architecture
V2
MEG (B,T,C) → ConvConformer → temporal downsample → Conformer → CTC
→ CTCSpaceSegmenter → word adapter → TinyLlama prefix + beam search → pred_text
V1
MEG window (N,C,T) per keystroke → SimpleConvTimeAgg + Bahdanau attention
→ SentenceTransformer (ALiBi) → linear → greedy char decode
| Module | Role |
|---|---|
src/model/ |
Pure-Rust V2 reference encoder (oracle vs Python) |
src/model_rlx/ |
RLX-accelerated Conformer tail (default encoder) |
src/decode/ |
CTC greedy, space segmenter, intra-word pooler |
src/llm/ |
TinyLlama CPU decoder, LoRA merge, beam search |
src/v1/ |
Full V1 keystroke pipeline |
Scope
Included: V1 and V2 inference (encoder, decode, LLM for V2), safetensors loading, RLX backends, parity tests.
Not included: training, dataloaders, augmentations, V1 n-gram LM post-processing (see Python brain2qwerty_v1/scripts/ngram_decoding.py).
Python reference
V2 model registration requires a side-effect import in Python:
# registers ConvConformer
Parity ref generators: scripts/generate_parity_refs.py, scripts/generate_v1_parity_refs.py.
License
Apache-2.0 (see upstream Brain2Qwerty license).