Free, open-source tool

Arabic NER validator for Python and the command line

Check an Arabic named-entity annotation file for offsets counted in the wrong unit, text that changed after annotation, span edges that cut a letter from its haraka or a clitic from its word, overlaps and BIO/BIOES/BILUO tag errors. Each finding has a code, and suggested offsets come as an audit diff for review.

By Bayanat Labs· Updated · اقرأ بالعربية

The Arabic NER Offset Validator by Bayanat Labs checks an annotation file and writes a JSON report (or a shareable report with no text, or CSV) with a code for each finding and an audit diff of suggested offsets. An emoji that makes JavaScript and Python count differently, a normalisation step that turns alef with a combining hamza into one letter or the lam-alef ligature into two, tatweel or line breaks that changed after annotation, a span edge that cuts a letter from its haraka, a conjunction stuck to a place name: each is reported with one of 27 finding codes and a message in English and Arabic. The web app runs the same checks in your browser.

Code on GitHub · Web app · Test cases on Hugging Face · Release record

Install and run

pip install "git+https://github.com/Bayanat-Labs/arabic-ner-validator@v0.1.0"

arabic-ner-validator check annotations.jsonl --json report.json
arabic-ner-validator check export.jsonl --format doccano --offset-unit utf16 --clitic-policy exclude -v
arabic-ner-validator check train.conll --format conll --scheme BIOES
arabic-ner-validator check export.jsonl --format doccano --offset-unit codepoint --apply-suggestions repaired.jsonl
arabic-ner-validator convert export.jsonl --format spacy --offset-unit codepoint --to BILUO
arabic-ner-validator codes

Python 3.10 or later; the only runtime dependency is regex. In Python: from arabic_ner_validator import validate. The package is not on PyPI yet; install it from GitHub as above. A repaired copy changes offsets only, never labels or text.

What it checks

  • Offsets counted in another unit: code points (Python), UTF-16 code units (JavaScript), UTF-8 bytes or grapheme clusters. The unit is declared and never guessed; the report says which unit fits the text.
  • Text changed after annotation: NFC or NFKC normalisation, tatweel or diacritic removal, CRLF and LF line breaks, a byte order mark.
  • Span edges inside a grapheme cluster, a word or a token; bidi and zero-width controls, whitespace and punctuation at the edges; Arabic and Latin letters joined at an edge.
  • Clitics (و ف ب ك ل and the article) under an include or exclude policy.
  • Structure: overlapping and nested spans, labels outside a label set, and IOB2, BIOES and BILUO tag sequences.

The finding codes are 20 errors, 2 warnings and 5 notes. The web app reads the file in your browser and neither uploads nor stores it; its shareable report keeps only ids, codes, offsets and counts.

Formats and units

Formats: canonical JSON Lines (with a JSON Schema in the repository), doccano JSONL, Label Studio JSON, spaCy JSONL, CoNLL and Hugging Face token rows. Offset units: codepoint, utf16, utf8_byte and grapheme. Tag schemes: IOB2 (BIO), BIOES and BILUO, among others.

How common tools count offsets

The offset-convention matrix has 13 rows, measured on 20 Arabic probe texts: Python, spaCy and the Hugging Face fast tokenizers count code points; JavaScript counts UTF-16 code units, so offsets differ after an emoji; grapheme clusters count a letter with its harakat as one. Label Studio's text regions count code points, and doccano counts UTF-16 code units unless its grapheme mode is on; those two rows are read from source code, not measured. The table and its data are in the repository's matrix folder.

Tests

  • 100 dev test cases, written before the validator code, each with the exact codes and suggestions expected: 100 of 100 pass.
  • 100 acceptance test cases, written separately from the list of 18 defect categories only: 96 of 100 pass, and 86 of 100 passed on the build frozen before the acceptance cases were read. The quality report explains each case that does not pass.
  • spaCy's offset and BILUO converters, used as an oracle in the tests: every comparison agrees on the 51 valid-case records checked.
  • The Python package and the browser port, compared on 18,000 random inputs: 0 differences.

The test cases are synthetic sentences written for these sets and are published under CC BY 4.0, also as the Hugging Face dataset arabic-ner-offset-fixtures.

Cite as

Bayanat Labs (2026). Arabic NER Offset Validator (arabic-ner-validator), version 0.1.0. https://github.com/Bayanat-Labs/arabic-ner-validator

The release record, with licences and changelog, is the Arabic NER Offset Validator on Bayanat Labs Open.

Licence and contact

Code and web app: Apache-2.0. Test cases, offset-convention matrix and documentation: CC BY 4.0. Data derived from the Unicode Character Database: Unicode License v3. Questions and corrections: hello@bayanatlabs.com.

Need annotated Arabic data?

The validator is free. For Arabic documents annotated with the fields and entities your product extracts, see Bayanat Documents.