· 6 min read
Building a Burmese text dataset from scanned PDFs with JSONL
Turn scanned Myanmar documents into a page-level JSONL corpus for NLP and LLM work: batch OCR, Unicode normalization, filtering, and deduplication.
Burmese is a low-resource language for machine learning. Much of the written record that would help sits in scanned books and PDFs, invisible to any tokenizer. Getting it out is mostly an OCR problem, and then a data-hygiene problem.
LEXO handles the first part and gives you clean inputs for the second.
Why page-level JSONL
LEXO’s JSONL export writes one JSON object per page:
{"doc_id": "9c1e…", "source": "1965-novel.pdf", "page": 12, "kind": "scanned", "text": "…"}
Page-level records are a good unit for a corpus:
- Traceable. Every line of text points back to a file and a page.
- Filterable.
kindtells you whether the text came from a real text layer (digital) or from OCR (scanned), and failed pages are markedfailedwith anerror. - Deduplicable.
doc_idis the SHA-256 of the source file, so the same PDF downloaded twice gets the same ID. - Streamable. One record per line works with
jq, pandas, and Hugging Facedatasetswithout loading everything at once.
Step 1: Clean the PDFs
Running heads and page numbers repeat on every page and will dominate your n-gram counts if you leave them in. Crop them before OCR:
lexo pdf crop book.pdf --top 7 --bottom 8 -o clean/book.pdf
Split two-up spreads with lexo pdf split-spread if needed.
Step 2: OCR to JSONL
Per document:
lexo ocr clean/book.pdf --format jsonl -o jsonl/book.jsonl
Burmese is the default language. LEXO extracts digital pages directly and only OCRs scanned ones; add --force-ocr if a hidden text layer is unreliable.
For a whole folder, a short shell loop does it (bash):
for f in clean/*.pdf; do
lexo ocr "$f" --format jsonl -o "jsonl/$(basename "${f%.pdf}").jsonl"
done
lexo ocr-batch is the resumable alternative, but it writes plain text only.
Step 3: What normalization you already have
Every record’s text has been:
- normalized to Unicode NFC, so visually identical words compare equal;
- cleaned of control and invisible format characters;
- left with zero-width spaces (U+200B) intact, since Burmese uses them for word and line breaks.
LEXO does not convert Zawgyi, segment words, or fix OCR errors. Those decisions are yours.
Step 4: Filter and combine
A starting point with jq:
cat jsonl/*.jsonl \
| jq -c 'select(.kind != "failed" and (.text | length) > 50)' \
> corpus.jsonl
Then deduplicate by doc_id and page, and consider dropping pages with a high share of non-Myanmar characters, which often means a table, an index, or a bad scan.
Step 5: Look at the data
Sample a few hundred pages and read them against the scans. OCR errors in Burmese tend to cluster in small type, worn print, and unusual stacked consonants. Knowing your error profile is what makes the dataset trustworthy.
Licensing
Being able to OCR a document doesn’t mean you may redistribute its text. Record each source’s licence alongside its doc_id, and keep copyrighted material out of any public release.