NanoTranslate-S3
Offline Russian-to-English neural machine translation designed around an ESP32-S3 microcontroller.
- Period
- 2026
- Role
- Independent researcher
- Status
- Preprint · not peer-reviewed
- parameters in the default model
- 999,040
- parameters in the default model
- entry byte-piece vocabulary
- 1,536
- entry byte-piece vocabulary
- targets reproduced by PyTorch and the INT8 C++ runtime
- 20 / 20
- targets reproduced by PyTorch and the INT8 C++ runtime
Abstract
We present NanoTranslate-S3, an offline Russian-to-English neural machine translation system co-designed for the ESP32-S3 N16R8 microcontroller. The target device combines two Xtensa LX7 cores running at up to 240 MHz with 512 KB on-chip SRAM, 16 MB flash, and 8 MB octal PSRAM. Rather than compressing a conventional desktop translation model after training, we jointly design the vocabulary, Transformer width and depth, numerical representation, binary layout, decoder, cache strategy, inference kernels, and physical user interface around the microcontroller. The default student is a 999,040-parameter pre-norm encoder–decoder Transformer with width 128, three encoder layers, two decoder layers, four attention heads, FFN width 256, and a 1,536-entry lossless UTF-8 byte-piece vocabulary. Weight matrices use symmetric per-row INT8 quantization with FP32 scales and dynamically quantized INT8 activations. The portable C++ runtime uses incremental autoregressive decoding, precomputed cross-attention keys and values, a tied output embedding, and a constrained English output candidate set; on ESP32-S3 the signed-int8 dot product uses PIE vector instructions. We derive exact parameter, storage, cache, and dense-MAC budgets and define a CRC-protected memory-mappable model format. A measured end-to-end correctness experiment verifies the full path from PyTorch training through Q8 export to C++ inference: on a 20-pair memorization task the loss falls from 5.7639 to 0.04128 and both PyTorch and the quantized C++ runtime reproduce all 20 training targets, including the Russian greeting mapped to hello. We explicitly separate measured results from exact analytical results, derived estimates, and future physical-board measurements; no ESP32 latency or held-out BLEU result is invented.
1 Introduction
Modern neural machine translation assumes resources that inexpensive microcontrollers lack: large DRAM, wide SIMD or GPU matrix engines, large vocabularies, long sequences and enough compute to project decoder states over tens of thousands of output symbols at every step. The ESP32-S3 sits at a different operating point: two Xtensa LX7 cores up to 240 MHz, 512 KB on-chip SRAM and vector instructions for DSP/neural workloads [Espressif Systems, 2026]. The N16R8 module adds 16 MB external flash and 8 MB octal PSRAM.
A direct port of a normal Russian-to-English model is inappropriate. The current Helsinki-NLP OPUS-MT RU–EN model is a Marian encoder–decoder with six encoder and six decoder layers, width 512, FFN width 2048 and a vocabulary of roughly 62.5k tokens; the published PyTorch checkpoint is roughly 307 MB [Helsinki-NLP, 2026; Tiedemann and Thottingal, 2020]. That is not a close fit requiring a small optimization; it is a different computational regime.
The paper therefore asks a hardware-first question: what translation model would we design if the ESP32-S3 N16R8 were the primary target from the beginning? The product requirement is deliberately narrow: the user enters one normal Russian sentence (usually 5–20 words) on a 240×240 display with a five-way joystick, presses translate, and receives an English sentence — no Wi-Fi, phone, API or cloud at inference time. The central hypothesis is that microcontroller NMT is a co-design problem: vocabulary size, output-projection cost, sequence limits, flash/PSRAM traffic, KV-cache precision, row alignment, decoding strategy and UI memory matter alongside model width [Lin et al., 2020].
Contributions.
- a compact RU→EN encoder–decoder Transformer family whose default model has exactly 999,040 trainable parameters;
- FlashPiece, a lossless UTF-8 byte-piece tokenizer with guaranteed raw-byte fallback and a 1,536-entry default vocabulary;
- a sequence-level distillation pipeline using a stronger translation teacher [Kim and Rush, 2016];
- a row-wise Q8 model format with CRC32, structural checks and 16-byte aligned tensor storage;
- a portable C++ runtime with incremental decoding and an ESP32-S3 PIE signed-int8 matvec path;
- an English-only constrained tied output head that removes source-only pieces from repeated decoder scoring;
- a complete ST7789 plus joystick firmware interface;
- exact parameter, storage, cache and dense-MAC derivations together with a reproducible measured Q8 parity test;
- a strict evaluation protocol that leaves physical-board BLEU and latency blank until measured.
2 Hardware and deployment envelope
2.1 ESP32-S3 N16R8
Espressif's ESP-DL documentation presents W8A8 as its highest-speed default quantization mode, and ESP-NN includes S3-optimized neural kernels that exploit vector instructions; together these motivate an INT8-first baseline. The memory hierarchy matters:
- internal SRAM — scarce, low-latency, suitable for hot activations and DMA buffers;
- PSRAM — far larger, but slower and shared through the cache/memory subsystem;
- flash — persistent storage for cold model data and the memory-mapped
.s3mtimage.
Fitting within total memory is therefore insufficient; the design must minimize repeatedly streamed bytes per generated token.
2.2 System path
- 5-way joystick
- ST7789 UI
- FlashPiece tokenizer
- Q8 encoder
- incremental decoder
- constrained tied head
- English output
↺ Then back to the screen: ST7789 UI
3 Related work
The student follows the encoder–decoder Transformer [Vaswani et al., 2017]. Subword NMT showed the value of subword units for open-vocabulary translation [Sennrich et al., 2016]; FlashPiece adapts the idea to a microcontroller by guaranteeing coverage with all 256 byte values and a minimal greedy decoder. Sequence-level knowledge distillation replaces ambiguous human targets with teacher translations [Kim and Rush, 2016] — attractive for a model near one million parameters. Tied input/output embeddings reduce storage [Press and Wolf, 2017]; RMSNorm removes explicit mean centering [Zhang and Sennrich, 2019].
Integer quantization is standard for efficient inference [Jacob et al., 2018], and low-bit NMT can reach 4-bit precision [Aji and Heafield, 2019], motivating a Q4 roadmap — but the Q4 path is not labelled as implemented. CTC non-autoregressive translation removes token-by-token decoder dependencies [Libovický and Helcl, 2018], yet realistic evaluation shows NAR is not automatically faster than an optimized autoregressive system at small batch sizes [Helcl et al., 2022]. Deployment batch size here is exactly one, so the default path is autoregressive and CTC remains experimental. MCUNet established model/runtime co-design on microcontrollers [Lin et al., 2020]; ESP32-S3 community runtimes show transformer-like workloads can use PIE signed-int8 vector operations [Dory, 2026; Bareiro, 2026]. NanoTranslate-S3 applies these ideas to sequence-to-sequence translation.
4 Problem formulation
Normalized Russian input and English target:
The autoregressive model defines
Deployment is multi-objective. For architecture and numeric format :
where is batch-one wall-clock latency. No arbitrary weights are assigned to these terms; the paper derives the dominant storage/compute terms and defines a physical benchmark protocol instead.
5 FlashPiece tokenizer
Lossless byte foundation. FlashPiece operates on normalized UTF-8 bytes. IDs 0–3 are PAD, BOS, EOS and UNK; the next 256 IDs represent every possible byte, so any UTF-8 input is representable even if no learned multi-byte piece matches. Additional pieces are frequent byte n-grams from the distilled training corpus, ranked by approximate byte savings
The vocabulary is built only from training data; validation and test references never influence token selection.
Greedy encoding. At byte position the encoder searches only pieces beginning with and selects the longest match,
The C++ runtime precomputes 256 first-byte buckets at load time, turning a vocabulary-wide scan per byte into a small bucket search.
Vocabulary as a hardware parameter. A larger vocabulary shortens sequences but increases output-head work. Scoring allowed candidates at each of steps with width costs
dot-product MACs, so vocabulary size is simultaneously an NLP and a systems variable.
6 Student Transformer
The default configuration is
All dense layers are bias-free; source and target positions use separate learned embeddings.
RMSNorm and residual structure. For and learned gain ,
An encoder block is , . A decoder block adds causal self-attention and cross-attention:
Attention. With head width ,
where is the causal mask for decoder self-attention.
Tied and constrained output head. With token embedding matrix , the classifier reuses : . Because deployment is strictly RU→EN, the runtime precomputes
and scores only IDs in . This is not algebraically equivalent to full-vocabulary decoding — if a removed source-language token would otherwise win, the output changes — so it is described as constrained decoding. Training targets are normalized to printable ASCII; evaluation preserves raw references so the normalization penalty can be measured.
7 Training and distillation
Data. The recommended starting corpus is OPUS-100 [Zhang et al., 2020; Helsinki-NLP, 2026]. The downloader preserves the train/validation/test separation, creates a device-normalized English view and separately saves raw validation and test references.
Sequence-level teacher targets. For teacher distribution , (approximated by beam search), and the student minimizes
The reference implementation uses Helsinki-NLP/opus-mt-ru-en as a workstation-side teacher; the teacher never runs on the ESP32. FlashPiece is built after distillation, on Russian source plus teacher English, so a fixed vocabulary budget is spent on the exact target distribution the student sees.
8 Row-wise Q8 inference
Weight quantization. For row :
Each row stores one FP32 scale and signed bytes; a zero row receives scale one. Activations are quantized the same way with , and the reconstructed matvec is
with the inner sum accumulated in INT32.
Rounding error. Writing and with , ,
This is not a quality guarantee; it motivates later calibration and QAT experiments.
Why Q8 first. W8A8 is ESP-DL's fastest general quantized mode and ESP-NN has S3-specific int8 kernels, so Q8 is a simple, verifiable baseline. Q4 reduces weight traffic, but only helps latency if reduced memory traffic outweighs unpacking overhead; it is treated as a hypothesis until benchmarked.
9 Model binary format
The exporter produces one memory-mappable .s3mt file. A fixed 128-byte little-endian header stores magic, version, architecture dimensions, special token IDs, tokenizer bytes, payload bytes, CRC32 and total length; tokenizer pieces follow, then tensors in fixed architecture order, with rows and scale blocks 16-byte aligned. Before exposing tensor pointers the C++ loader checks CRC32, all lengths, vocabulary bounds, width alignment, FFN bounds, head divisibility, layer counts, sequence limits, special IDs, every tensor shape and absence of trailing data — corruption becomes a deterministic load error instead of undefined memory access.
10 Portable runtime and ESP32-S3 specialization
Parity-first implementation. The same C++ parser, tokenizer, encoder, decoder and output projection are compiled for a host CLI and for the ESP-IDF firmware, so exporter/runtime bugs reproduce without a flash cycle.
PIE int8 dot product. The S3 path uses aligned 128-bit vector loads and signed int8 multiply-accumulate, , processing 16 signed bytes per vector step with a scalar fallback — the same class of optimization as ESP-NN and public S3 transformer runtimes [Espressif Systems, 2026; Dory, 2026].
Incremental decoder. For each decoder layer the runtime caches self-attention , so previous projections are never recomputed; cross-attention keys and values are computed once before generation. Each step evaluates only the current token's self Q/K/V, cross Q, output projections, FFN and tied head.
11 Exact analytical budgets
Parameter formula.
For the base preset: ; ; ; ; — hence .
Table 1. Exact preset budgets at vocabulary 1,536. Q4 is a storage estimate only.
| Preset | Params | Q8 KiB | Q4 est. KiB | ||
|---|---|---|---|---|---|
| Tiny | 96 | 2/2 | 527,904 | 538.6 | 281.3 |
| Base | 128 | 3/2 | 999,040 | 1008.4 | 521.4 |
| Quality | 160 | 4/2 | 1,699,680 | 1704.6 | 875.8 |
Serialized Q8 storage. All non-norm values are quantized: . The number of row scales is . Ignoring small headers, tokenizer strings and padding,
No Q4 speed claim is made.
Mutable memory. The maximum FP32 encoder state is = 32 KiB. FP32 decoder self/cross caches consume bytes = 224 KiB. The RGB565 240×240 framebuffer uses 115,200 bytes (112.5 KiB) and the 20-row DMA strip 9,600 bytes (9.375 KiB).
Dense MAC model. Encoder: ; cross-attention K/V precompute: ; decoder step : ; output head as above. At representative , , :
| Term | MACs |
|---|---|
| 13.369344 M | |
| 2.097152 M | |
| 8.411136 M | |
| 4.718592 M | |
| Total | 28.596224 M |
The output head alone contributes about 16.5% of these dense MACs and repeatedly streams embedding rows, which makes candidate pruning attractive.
Data
| Vocabulary | Output-head MACs |
|---|---|
| 512 | 1,572,864 |
| 768 | 2,359,296 |
| 1,024 | 3,145,728 |
| 1,536 | 4,718,592 |
| 2,048 | 6,291,456 |
| 3,072 | 9,437,184 |
Roofline-style interpretation. A useful lower bound is
where and must be measured on the actual board — host values are not substituted. The model explains why Q4 may help a bandwidth-bound configuration and why a second core may not help if both cores contend for the same external-memory path.
12 Physical interface
The firmware renders a six-row Russian keyboard and input/output text on a 240×240 ST7789; a five-way active-low joystick uses internal pull-ups. Example (configurable) pins:
| Signal | Default GPIO | Direction |
|---|---|---|
| LCD MOSI | 11 | MCU→LCD |
| LCD SCLK | 12 | MCU→LCD |
| LCD CS/DC/RST/BL | 10/9/8/7 | MCU→LCD |
| Joystick U/D/L/R | 4/5/6/13 | input |
| Joystick press | 14 | input |
These are examples, not universal board wiring. The framebuffer lives in PSRAM; a 20-row DMA-capable strip lives in internal RAM, and because ESP-IDF LCD transfers are asynchronous the code waits for the colour-transfer-complete callback before overwriting the strip — avoiding corruption while SPI DMA still owns the buffer.
13 Measured correctness experiment
Evidence categories. The paper separates (1) measured: host compilation, tokenizer tests, toy training, Q8 export, C++ parity, CRC rejection; (2) exact analytical: parameter count, Q8 bytes, cache bytes, framebuffer bytes, dense MACs; (3) derived estimate: packed-Q4 model bytes; (4) unverified: held-out full-model BLEU/chrF/COMET, physical ESP32 latency, tokens/s, energy, thermal behaviour.
Toy memorization and Q8 parity. A deterministic script uses 20 small RU–EN pairs, a 320-entry FlashPiece tokenizer, one encoder and one decoder layer, , , four heads and seed 0. It trains for 600 steps, recording loss every ten updates; cross-entropy falls from 5.7639008 to 0.04127665. PyTorch greedy decoding reproduces 20/20 training targets; the exported row-wise-Q8 model loaded by the C++ runtime also reproduces 20/20. The Russian greeting in the smoke set maps to hello. A deliberately flipped payload byte makes the loader fail with a CRC32 mismatch. This demonstrates end-to-end implementation parity; it is intentionally not a held-out NMT benchmark.
Data
| Step | Cross-entropy |
|---|---|
| 0 | 5.7639 |
| 10 | 5.4712 |
| 20 | 5.1539 |
| 30 | 4.8221 |
| 40 | 4.4946 |
| 50 | 4.1889 |
| 60 | 3.9205 |
| 70 | 3.6993 |
| 80 | 3.5268 |
| 90 | 3.3985 |
| 100 | 3.3071 |
| 110 | 3.2421 |
| 120 | 3.1923 |
| 130 | 3.1514 |
| 140 | 3.1103 |
| 150 | 3.0967 |
| 160 | 3.0487 |
| 170 | 2.9956 |
| 180 | 2.9447 |
| 190 | 2.8740 |
| 200 | 2.7852 |
| 210 | 2.7012 |
| 220 | 2.5907 |
| 230 | 2.4653 |
| 240 | 2.3381 |
| 250 | 2.1874 |
| 260 | 2.0195 |
| 270 | 1.9039 |
| 280 | 1.6839 |
| 290 | 1.5199 |
| 300 | 1.3273 |
| 310 | 1.1521 |
| 320 | 0.9982 |
| 330 | 0.8446 |
| 340 | 0.8078 |
| 350 | 0.6274 |
| 360 | 0.5333 |
| 370 | 0.4494 |
| 380 | 0.3804 |
| 390 | 0.3230 |
| 400 | 0.2747 |
| 410 | 0.2392 |
| 420 | 0.2596 |
| 430 | 0.1992 |
| 440 | 0.1648 |
| 450 | 0.1415 |
| 460 | 0.1246 |
| 470 | 0.1113 |
| 480 | 0.1003 |
| 490 | 0.0910 |
| 500 | 0.0831 |
| 510 | 0.0763 |
| 520 | 0.0703 |
| 530 | 0.0651 |
| 540 | 0.0605 |
| 550 | 0.0564 |
| 560 | 0.0527 |
| 570 | 0.0494 |
| 580 | 0.0464 |
| 590 | 0.0437 |
| 600 | 0.0413 |
Table 2. Current verification status.
| Check | Result |
|---|---|
| FlashPiece unit tests | pass |
| Host C++ build | pass |
| PyTorch toy train exact | 20/20 |
| Q8 C++ toy train exact | 20/20 |
| Loss | 5.7639 → 0.04128 |
| Corrupt model | rejected by CRC |
| Physical ESP32 BLEU/latency | not yet measured |
14 Full evaluation protocol
Translation quality. Final checkpoints should be evaluated on the frozen OPUS-100 test split with SacreBLEU [Post, 2018], chrF [Popović, 2015] and offline COMET [Rei et al., 2020], against both the device-normalized English view and the preserved raw references.
Architecture sweep. A controlled sweep holds teacher, train split, seeds, optimizer and test set fixed:
| Run | Goal | ||||
|---|---|---|---|---|---|
| T1 | 768 | 96 | 2/2 | 192 | speed floor |
| B1 | 1024 | 128 | 3/2 | 256 | vocab tradeoff |
| B2 | 1536 | 128 | 3/2 | 256 | default |
| B3 | 2048 | 128 | 3/2 | 256 | shorter sequences |
| Q1 | 1536 | 160 | 4/2 | 320 | quality ceiling |
Physical-board benchmark. For every exported model: same N16R8 board, CPU clock, flash/PSRAM modes, compiler flags and firmware commit; at least five warm-up translations; a fixed battery of short, medium and long sentences; record source/output tokens, encoder and decoder microseconds, total latency and tokens/s; record internal-RAM and PSRAM free/low-water marks; repeat each sentence at least 30 times; report median and IQR rather than minimum latency; save model checksum, ESP-IDF version, chip revision and firmware Git SHA.
Table 3. Physical-board results intentionally blank until measurements exist.
| Model | BLEU | chrF | Enc ms | Dec ms | Total ms | tok/s |
|---|---|---|---|---|---|---|
| Tiny Q8 | – | – | – | – | – | – |
| Base Q8 | – | – | – | – | – | – |
| Base Q4 | – | – | – | – | – | – |
| CTC/NAR | – | – | – | – | – | – |
15 Optimization roadmap
- Vocabulary sweep before scaling width. Smaller vocabularies lengthen sequences; larger ones increase classifier traffic. The optimum must be measured.
- Packed Q4. Base Q8 payload is 1008.44 KiB; the packed-Q4 estimate is 521.44 KiB. If inference is bandwidth-limited this may be the largest remaining lever; if nibble extraction dominates, Q4 can lose. A custom PIE Q4×Q8 kernel should be benchmarked against Q8 on identical checkpoints.
- Quantized decoder caches. The FP32 cache is 224 KiB; INT8 storage could cut raw cache bytes roughly fourfold before scales. Per-vector vs per-head scales must be measured.
- Fusion. RMSNorm, activation quantization and projection are separate passes; a fused path would reduce hot-vector traffic.
- Dual-core execution. Helps only if kernels are compute-bound; if rows already saturate flash/PSRAM/cache bandwidth, splitting rows can add contention [Dory, 2026].
- CTC/NAR. The repository contains an experimental CTC-style encoder path; its acceptance criterion is batch-one wall-clock latency on the actual S3 at acceptable BLEU/chrF [Helcl et al., 2022].
16 Limitations
The current empirical result proves pipeline correctness, not general translation quality. No full-data model has been reported with held-out BLEU/chrF. The physical firmware still needs measurement on the user's exact board/display assembly. The output constraint normalizes English to printable ASCII, so diacritics and typography can be lost. Q8 is post-training export, not a full quantization-aware training study. Analytical MAC counts exclude softmax exponentials, normalization, tokenization, cache misses, control overhead and display I/O, so they must not be presented as latency predictions. OPUS-100 is heterogeneous and may not match every domain. Q4, quantized caches, dual-core execution and NAR remain hypotheses until benchmarked.
17 Conclusion
NanoTranslate-S3 treats translation on an ESP32-S3 as a hardware–software co-design problem rather than a demonstration of fitting the largest possible language model. A scoped RU→EN system can combine a roughly one-million-parameter Transformer, a 1.5k lossless byte-piece vocabulary, teacher distillation, tied embeddings, row-wise Q8 weights, incremental decoding, constrained output scoring, a memory-mappable binary and a low-memory physical UI. The PyTorch→Q8→C++ path is verified by a deterministic parity test, and all central memory/compute quantities are derived exactly. The next scientific step is to train the full distilled grid and populate the deliberately blank physical-board quality/latency table.
Reproducibility
The repository contains the tokenizer, PyTorch architecture, OPUS-100 downloader, teacher distillation script, trainer, evaluator, Q8 exporter, model checker, analytical scripts, portable C++ runtime, ESP-IDF firmware, host CLI, tests and CI. A typical workflow:
python scripts/download_opus100.py --out-dir data/opus100 --limit-train 500000
python model/distill_teacher.py --input data/opus100/train.tsv \
--output data/distilled.tsv
python model/tokenizer.py build --input data/distilled.tsv \
--output artifacts/tokenizer.json --vocab-size 1536
python model/train.py --train data/distilled.tsv \
--val data/opus100/validation.tsv \
--tokenizer artifacts/tokenizer.json --preset base --out artifacts/base
python model/evaluate.py --checkpoint artifacts/base/best.pt \
--tokenizer artifacts/tokenizer.json --data data/opus100/test.tsv \
--raw-data data/opus100/test.raw.tsv
python model/export_s3mt.py --checkpoint artifacts/base/best.pt \
--tokenizer artifacts/tokenizer.json --output artifacts/nanotranslate.s3mt
cmake -S host -B host/build
cmake --build host/build -j
./host/build/nanomt_cli artifacts/nanotranslate.s3mt
Acknowledgments and disclosure of funding. This is an independent student engineering research project. Open academic literature, Espressif documentation and public reference runtimes informed the design. No physical-device performance numbers are claimed without measurement.
Appendix A — Binary header schema
The fixed .s3mt header is 128 bytes, little-endian (reproduced as printed; see flags):
| Offset | Type | Meaning |
|---|---|---|
| 0 | char[8] | magic S3MT0001 |
| 8 | u32 | format version |
| 12 | u32 | flags |
| 16–52 | u32 | vocab, d, f, heads, layers, max lengths |
| 56–68 | u32 | PAD/BOS/EOS/UNK IDs |
| 64 | u32 | tokenizer payload bytes |
| 68 | u32 | protected payload bytes |
| 72 | u32 | CRC32 over payload |
| 76 | u32 | total file bytes |
| 80–127 | reserved | zero/future fields |
A Q8 tensor stores a small shape header, one FP32 scale per output row, alignment padding, signed-int8 row-major values, then trailing alignment. RMSNorm vectors remain FP32.
Appendix B — Base parameter derivation
, , , , ; their sum is exactly 999,040.
Appendix C — Default wiring
ST7789 MOSI/SCLK/CS/DC/RST/BL on GPIO 11/12/10/9/8/7 and joystick up/down/left/right/press on GPIO 4/5/6/13/14, all configurable in menuconfig. These are logical defaults, not a universal electrical schematic.
Appendix D — Checklist before publishing ESP32 measurements
Every physical result should record board/module part number, chip revision, ESP-IDF version, compiler version, CPU clock, flash mode/frequency, PSRAM mode/frequency, model checksum, firmware commit, sentence battery, warm-up count, repetition count, latency median/IQR and memory low-water marks — so that a single optimistic timing cannot become an irreproducible performance claim.
References
- Ashish Vaswani, Noam Shazeer, Noam Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Lukasz Kaiser, and Illia Polosukhin. Attention is all you need. In Advances in Neural Information Processing Systems, volume 30, 2017.
- Yoon Kim and Alexander M. Rush. Sequence-level knowledge distillation. In Proceedings of EMNLP, pages 1317–1327, 2016.
- Rico Sennrich, Barry Haddow, and Alexandra Birch. Neural machine translation of rare words with subword units. In Proceedings of ACL, pages 1715–1725, 2016.
- Ofir Press and Lior Wolf. Using the output embedding to improve language models. In Proceedings of EACL, pages 157–163, 2017.
- Jindřich Libovický and Jindřich Helcl. End-to-end non-autoregressive neural machine translation with connectionist temporal classification. In Proceedings of EMNLP, pages 3016–3021, 2018.
- Jindřich Helcl, Barry Haddow, and Alexandra Birch. Non-autoregressive machine translation: It's not as fast as it seems. In Proceedings of NAACL-HLT, pages 1780–1790, 2022.
- Jörg Tiedemann and Santhosh Thottingal. OPUS-MT – building open translation services for the world. In Proceedings of EAMT, 2020.
- Biao Zhang, Philip Williams, Ivan Titov, and Rico Sennrich. Improving massively multilingual neural machine translation and zero-shot translation. In Proceedings of ACL, pages 1628–1639, 2020.
- Alham Fikri Aji and Kenneth Heafield. Neural machine translation with 4-bit precision and beyond. arXiv:1909.06091, 2019.
- Benoit Jacob, Skirmantas Kligys, Bo Chen, Menglong Zhu, Matthew Tang, Andrew Howard, Hartwig Adam, and Dmitry Kalenichenko. Quantization and training of neural networks for efficient integer-arithmetic-only inference. In Proceedings of CVPR, pages 2704–2713, 2018.
- Biao Zhang and Rico Sennrich. Root mean square layer normalization. arXiv:1910.07467, 2019.
- Ji Lin, Wei-Ming Chen, Yujun Lin, John Cohn, Chuang Gan, and Song Han. MCUNet: Tiny deep learning on IoT devices. In Advances in Neural Information Processing Systems, 2020.
- Matt Post. A call for clarity in reporting BLEU scores. In Proceedings of WMT, 2018.
- Maja Popović. chrF: character n-gram F-score for automatic MT evaluation. In Proceedings of WMT, 2015.
- Ricardo Rei, Craig Stewart, Ana C. Farinha, and Alon Lavie. COMET: A neural framework for MT evaluation. In Proceedings of EMNLP, pages 2685–2702, 2020.
- Espressif Systems. ESP32-S3 series datasheet and product overview, 2026.
- Espressif Systems. ESP-DL user guide: How to quantize model, 2026.
- Espressif Systems. ESP-NN: Optimised neural network functions for Espressif chipsets, 2026.
- Helsinki-NLP. Helsinki-NLP/opus-mt-ru-en model repository, 2026.
- Helsinki-NLP. Helsinki-NLP/opus-100 dataset card, 2026.
- Dory. ESP32-S3 LLM inference engine, 2026.
- Jorge Bareiro. esp32-command-llm, 2026.
From the record
If a microcontroller were the target from the start, what translation model would you design? The ESP32-S3 has 512 KB of on-chip SRAM; a standard Russian–English model (OPUS-MT) is around 307 MB.
Approach
Instead of compressing a desktop model, I designed the model, tokenizer, number format and runtime together:
- a pre-norm encoder–decoder Transformer — width 128, three encoder and two decoder layers;
- FlashPiece, a lossless UTF-8 byte-piece tokenizer with raw-byte fallback;
- symmetric per-row INT8 weights with FP32 scales,
- a CRC-protected, memory-mappable model file;
- a C++ runtime with incremental decoding and cached cross-attention;
- firmware for a 240×240 ST7789 display and a five-way joystick.
What is measured
One end-to-end correctness experiment: on a 20-pair memorization task the training loss falls from 5.76 to 0.041, and both PyTorch and the quantized C++ runtime reproduce all 20 targets.
What is not measured yet
There is no held-out BLEU, no trained translation checkpoint, and no latency from a physical board. The firmware builds in CI but has not been verified on hardware. The preprint leaves those fields empty.