esp32kb
Build an on-device knowledge base for the KB ESP32-P4 demo — a MiniLM-L3 embedding search that runs entirely on the board, with no PC attached at runtime.
Point the tool at a folder of markdown/text documents and it emits everything
the firmware flashes: sentence-aware chunks, INT8 embeddings, the packed
kb.img container (vectors + text + file index + WordPiece vocabulary) and
the tiny generated headers the sketch compiles against.
Install
uvx esp32kb --help # or: pip install esp32kb
# from a checkout:
uv run --project esp32kb esp32kb --help
Usage
# 1. documents -> kb.img + generated headers
esp32kb embed --root path/to/documents --sketch-dir path/to/Arduino/project
# 2. print the arduino-cli command that flashes app + model + kb.img
esp32kb flash --sketch-dir path/to/Arduino/project # then answer "y" to run it
Everything defaults relative to --sketch-dir (the current folder by default),
so the demo ships with its MiniLM-L3 model and one flag is enough. esp32kb flash also writes the bundled partitions.csv into the sketch folder if it is
missing.
esp32kb embed
| flag | default | meaning |
|---|---|---|
--root / -r |
required | folder with the documents to index (recursively) |
--output-folder / -o |
<sketch-dir>/model/kb |
where the .bin files and kb.img are written |
--sketch-dir / -s |
current folder | holds KB.ino/VectorSearch.h; kb_config.h and kb_queries.h go here |
--onnx |
<sketch-dir>/model/maskseq.onnx if present, else bundled |
float32 MiniLM-L3 the PC embeds with |
--queries / -q |
sampled from the corpus | text file, one demo query per line |
esp32kb flash
| flag | default | meaning |
|---|---|---|
--sketch-dir / -s |
current folder | the sketch to compile |
--model |
<sketch-dir>/model/minilm_l3.espdl if present, else bundled |
INT8 model to flash |
--kb |
<sketch-dir>/model/kb/kb.img |
knowledge base to flash |
--port / -p |
$PORT or /dev/ttyUSB0 |
serial port |
--fqbn |
P4 board spec | arduino-cli board spec |
--library |
$ARDUINO_LIBS |
extra Arduino library folder |
--yes / -y |
off | run without asking |
--print-only |
off | print the command and exit |
--port |
$PORT or /dev/ttyUSB0 |
serial port for the printed flash command |
--fqbn |
esp32p4 FQBN | board spec for the printed flash command |
The sequence length and embedding width are read straight from the ONNX model,
so the chunks, the INT8 vectors and the generated kb_config.h the
firmware compiles against can never disagree with the model. No flags to keep
in sync.
Pipeline
documents
-> chunks (<= seq-2 WordPiece tokens each)
-> MiniLM-L3 embeddings (masked mean pool, L2 normalized)
-> symmetric INT8 quantization, one global scale
-> vectors.bin / meta.bin / chunks.bin / files.bin / vocab.txt
-> kb.img single little-endian container with a section table
-> kb_config.h KB_SEQ / KB_DIM / KB_TOPK + container magics (C++ constants)
-> kb_queries.h KB_EXAMPLES[] example query texts for the sketch
The vocabulary travels inside kb.img, so the device tokenizes queries itself.
Additive attention mask
If the ONNX model exposes a second attention_mask input (the variant built
by model/export_onnx_mask.py), esp32kb feeds it the correct per-query
padding bias (0 on real tokens, negative on [PAD]). This preserves retrieval
quality at longer sequence lengths, where the frozen all-ones mask used by the
plain export otherwise collapses query embeddings. With the stock single-input
ONNX the behavior is unchanged.
Outputs
| file | contents |
|---|---|
vectors.bin |
32 B header + N × dim INT8 (16-byte aligned rows) |
meta.bin |
16 B header + N × 16 B records (file id, text offset/length) |
chunks.bin |
16 B header + concatenated UTF-8 chunk text |
files.bin |
16 B header + N × padded filename records |
vocab.txt |
WordPiece vocabulary, one token per line |
kb.img |
container: magic/version/section table + the payloads above |
kb_config.h |
KB_SEQ, KB_DIM, KB_TOPK and the container magics |
kb_queries.h |
KB_EXAMPLES[] example query texts for the sketch |
Metadata
Release files for esp32kb 0.1.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| esp32kb-0.1.4.tar.gz | 77.7 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| esp32kb-0.1.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 155.4 MB
Release files / esp32kb-0.1.4.tar.gz
| Download URL | esp32kb-0.1.4.tar.gz |
|---|---|
| Size | 77.7 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
935e02a589bf8787112c83d0b9e4897dab9d9998a2752bb75cee30f9991d9528
|
|
BLAKE2b-256 checksum How to use checksums |
d7cb201064835ad345e0b255668f2ccc6bfa45a2767e97049a28f3dc823db2a5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / esp32kb-0.1.4-py3-none-any.whl
| Download URL | esp32kb-0.1.4-py3-none-any.whl |
|---|---|
| Size | 77.7 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ab62934987ec57fbe93109d74a28294437ab8f5b166e21442c29dab45052b2b8
|
|
BLAKE2b-256 checksum How to use checksums |
4198f343798c02359c3788afb112ecae35115cbea1906ee8019011d97be36ad1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|