PDF, Office, HTML, EPUB, scans — in. Structure-aware chunks with their page numbers — out.
Atrium Cloud is this library, hosted and run for you. It is not here yet — the list is what there is until it is. The library is free, MIT licensed, and yours either way.
curl -X POST http://localhost:8000/ingest \
-F "files=@./report.pdf"How Atrium works: parse, chunk, embed, retrieve
Before
A folder of files, none of them tidy.
Point it at a directory. Every file is parsed on the CPU, with no model and no GPU in the loop.
After
The same document, as chunks that know where they came from.
Each chunk carries its page, its heading path and the element type it was cut from.
Every page becomes typed elements.
Seven types come out. A table stays a table.
- a section title, with its level
- prose
- one bullet at a time
- rows and cells, never flattened
- a fenced block, intact
- text that belongs to an image
- a note at the foot of the page
Pick a type to find it on the page.
The four stages
Five ways to cut it. One that respects the document.
Same target, same overlap — only the strategy changes. The strategy that ran is stamped on every chunk, so a corpus with mixed strategies stays auditable.
Boundaries fall on the element edges. The table is one chunk. The heading is a breadcrumb on top of it, not a chunk of its own.
Atrium loads no model.
Embeddings come from your own Ollama — bge-large, 1024 dimensions, in its own process. The chunks travel to it and the vectors come back.
12 chunks · 0 boundaries mid-sentence
source.docx — 39 elements, 5,563 characters, parsed and chunked by the shipped code. Regenerate with scripts/dump_chunk_packing.py.
What will it take to run?
Pure Python. Your embedder runs in its own process, not ours.
Resident, serving search
88MB
Peak while ingesting the whole corpus is 425 MB. The embedder is not in this number — it is in Ollama's process, and it is 670 MB of that.
| Measurement | Value |
|---|---|
| Resident, serving search | 88 MB |
| Peak, ingesting a 19-document corpus | 425 MB |
| Search, p50 / p95 over 1451 chunks | 27 ms / 36 ms |
| Ingesting that corpus | 96.3 s |
Apple M4, 3.12.13 · pdfplumber backend · sqlite store · bge-large (1024-d)
The embedder is a separate process
bge-largecosts ~670 MB in Ollama's process, and it is in none of the numbers above.RSS does not return to the OS
A worker that ingests continuously should be recycled between batches.
One machine, one configuration
Apple M4, 16 GB, the container image, bge-large, and the local SQLite store.
Don't want to run it yourself? Atrium Cloud is coming.
Read the code that parses your documents.
The parsing heuristics, the chunker and the retrieval path are all readable Python. No model checkpoint, no black box.
- License
- MIT
- Python
- 3.10+
- Vector store
- SQLite, Qdrant or pgvector
- Version
- v0.1.0
0.700
R@5 · 23 documents · 700 questions
| System | R@5 | 95% CI | Parse | Peak |
|---|---|---|---|---|
| atrium · | 0.700 | 0.594–0.799 | 88 s | 1016 MB |
| docling | 0.686 | 0.565–0.798 | 554 s | 3482 MB |
| unstructured | 0.614 | 0.497–0.725 | 195 s | 855 MB |
pdfplumber (MIT) · atrium smart_chunker / precise (structure-aware) · hybrid — Reciprocal Rank Fusion over dense + BM25 · reranker off
Retrieval accuracy is on par with Docling — the difference is inside the noise band at this corpus size, and the report prints the interval rather than a number without one. The separation is in cost: six times faster parsing, a third of the memory, MIT licensed throughout. The harness, the corpus and the commands are public, so the numbers can be checked.
Every format it reads