Arabic dyslexia-friendly text simplification pipeline (Samsung Innovation Campus capstone)
HTML
3
49 commits
updated Oct 6, 2026
Team Cogni · Samsung Innovation Campus (SIC) AI Course — Capstone Project
Bayan simplifies complex Arabic text for readers with dyslexia while preserving its meaning, then adds diacritics and reads it aloud with synchronized word highlighting.
Download: Bayan 2.1.0 for Android (Android 8 or newer; APKs and SHA-256 on
Hugging Face) · Models: BayanSimplify
on Hugging Face · Changelog: app/CHANGELOG.md
This README replaces the original idea brief, which is kept for history in
references/00_project_brief/original_project_brief.md. Where the two disagree, this file andreferences/INDEX.mdare current.
Readers with dyslexia can see text but struggle to process it. Arabic adds specific barriers that most (Latin-script) dyslexia tools do not address:
Scale: a meta-analysis of 18 studies (N = 30,243) estimates 11% pooled prevalence of developmental dyslexia among Arab primary-school children (Aldakhil, 2024). Dyslexia is not the same as low reading proficiency — never quote PISA / learning-poverty figures as dyslexia rates.
Evidence from user studies (Spanish, Rello et al., 2013): more frequent and shorter words help readers with dyslexia, and offering simpler synonyms on demand is preferred over silently replacing words. No deployed Arabic tool combines simplification with a dyslexia focus; existing Arabic apps offer diacritization and read-aloud only.
All figures are verified in references/01_problem_motivation/.
| Stage | What it does | Status |
|---|---|---|
| 1. Simplify (core) | Shorten and restructure sentences, replace rare words, keep meaning | In the app. The BayanSimplify models run on the phone as int8 ONNX bundles: BayanSimplify-v0.2-Fast (AraBART, the default download, 222 MB) and BayanSimplify-v0.3 (AraT5v2, the large model and our best, decoded with four beams, 471 MB); BayanSimplify-v0.2 stays available as the earlier large model |
| 2. Diacritize | Restore full tashkeel on the simplified text | In the app (the Show tashkeel setting). Libtashkeel (text2tashkeel): MIT, 4.8 MB, bundled with the app, never changes a letter |
| 3. Read aloud | TTS with word-by-word highlighting | In the app. Nabra-7M-Distill (int8, 8.7 MB) through sherpa-onnx, the spoken word highlighted; three Piper voices as optional downloads |
Order matters: simplify → diacritize → read aloud, because diacritics depend on the final wording.
Bayan is an Android plugin. It registers a PROCESS_TEXT intent, so «تبسيط» (Simplify) appears in the
text-selection menu of any app: the reader selects hard Arabic text where they meet it, and a panel over that app
streams the simplified version sentence by sentence, with the original one tap away. The panel can read aloud,
and minimizes to a floating reader so the reader can keep using the app while Bayan reads on. All inference runs
on the device: no server, no network, and the text never leaves the phone.
Before and after the model, a text step in code guards the output: scripture and set poetry pass through untouched, very short sentences are left alone, and a rewritten sentence that drops a number or a Latin token, changes a negation, limit or condition word, or loses too much of its text is replaced by the original sentence.
Constraints: ONNX Runtime Mobile only, no Python or GPU at runtime, and a default download within 250 MB
(BayanSimplify-v0.2-Fast, 222 MB); the AraT5v2 bundles (471 MB) are optional downloads, kept whole for quality. Reasoning: docs/decisions/0001-product-form.md;
app build and layout: app/; brand, logo, colours and reading rules: app/design-system/.
Recorded on a phone over an Arabic Wikipedia paragraph: select the text → تبسيط in the selection menu → the simplified version in the bottom sheet, with read-aloud.
Local copy: deliverables/05_demo/bayan_demo.mp4 — the same clip
runs in the pitch decks (deliverables/04_presentation/).
No large, open, parallel Arabic simplification corpus fits the task, so Bayan builds its own:
data/README.md.Congi-libya/bayan-simplification-corpus,
public, CC BY-SA 4.0; 14,975 rows): hard BAREC sentences rewritten by Gemma 4 31B, kept only if code checks pass,
CAMeL rates the rewrite at least 2 levels easier, and a Qwen judge scores the meaning as kept; easy, protected and
short sentences are kept verbatim. Pipeline: scripts/barec_simplification_pipeline.py,
scripts/assemble_corpus_v1.py; data card:
docs/synthetic_data_card_v1.md. Corpus v0 (13,072 rows) is kept on the Hub under the tag v0.[S0]–[S3], [SA]). The app sends no tag, which
keeps the meaning more often (see below).scripts/meaning_reward/); the meaning judge is in scripts/meaning_judge/.scripts/evaluation/check_leakage.py. 33 BayanBench held-out items appear in corpus v1,
so models trained on it are reported on the core and outside items only.Public on Hugging Face under CC BY-NC 4.0 (non-commercial, in line with the training data's terms):
| Model | Base | Training data | In the app |
|---|---|---|---|
| BayanSimplify-v0.1 | AraT5v2-base-1024 | SAMER, level 5 → 3 | not shipped |
| BayanSimplify-v0.2 | AraT5v2-base-1024 | 22,733-pair mix with strength tags | "Earlier large model" |
| BayanSimplify-v0.2-Fast | AraBART | the same mix | "Fast model", the default download |
| BayanSimplify-v0.3 | AraT5v2-base-1024 | corpus v1 (14,975 rows) | "Large model", four beams; our best |
| BayanSimplify-ONNX | the int8 bundles the app downloads | v0.2-Fast/, v0.2/, v0.3/ |
The full tables, intervals and figures are in the final report
(deliverables/03_final_report/). On BayanBench v2, test split, core items
(meaning kept = Gemma 4 31B P(same) ≥ 0.5 and every number kept):
| System | Meaning kept | Longest clause, words shorter |
|---|---|---|
| copy the input | 100% | 0 |
BayanSimplify-v0.2 (AraT5v2), [S2] / no tag | 59.5% / 68.3% | 6.3 / 4.5 |
BayanSimplify-v0.2-Fast (AraBART), [S2] / no tag | 40.1% / 51.4% | 6.7 / 4.9 |
| app, v0.2 int8 / v0.2-Fast int8 (September text step) | 78.6% / 50.5% | 1.9 / 4.8 |
| app, BayanSimplify-v0.3 int8, four beams | 82% | 5.2 |
bayanbench/ (v2.0, frozen; tag bayanbench-v2.0) scores a simplifier on 1,981 items (dev 731 /
test 1,250, split by document) in core, held-out, outside and written sets. It reports meaning, simplification
(clause length, CAMeL reading level, hard words), deterministic checks (numbers, house rules) and behaviour tests
(easy text left alone, protected text, cut-off selections), each with a document-bootstrap interval, and paired
differences against a baseline. No composite score. Data: Congi-libya/bayanbench-data (private, team only).
cd bayanbench && uv run bayanbench score outputs.jsonl --split dev --data <bayanbench-data snapshot>
Full details and sources: references/INDEX.md.
Every system is scored on the same inputs with one pinned script, against a copy-the-input baseline. The two locked
test sets (BAREC test, 7,286 rows; SAMER test, 3,277 rows) live in data/test_locked/, which git ignores; only
data/test_manifest.json with their row counts and SHA-256 hashes is committed. Reference-based scores (SARI) are
reported on changed rows only; the task-specific evaluation is BayanBench (section 4a). How to score a trained model:
scripts/evaluation/README.md. Background:
references/02_text_simplification/evaluation_and_benchmarking.md.
Bayan/
├── README.md # This file
├── CONTRIBUTING.md # Team workflow: branches, PRs, reviews
├── .github/ # CODEOWNERS, PR and issue templates
├── app/ # Android plugin (PROCESS_TEXT), Jetpack Compose + Material 3 Expressive
│ └── design-system/ # Bayan design system: logo, tokens, components, banners, reading guidelines
├── bayanbench/ # BayanBench v2.0: the task benchmark (package, tests, README)
├── deliverables/ # SIC capstone deliverables (action plan, WBS, report, slides, demo)
├── docs/ # Model results, the diacritization comparison
│ ├── brand/ # Rendered banners (README, social); source in app/design-system
│ └── decisions/ # Decision records — what we chose, and why
├── references/ # Literature review, benchmarks, and the project's reference architecture
│ ├── INDEX.md # Start here
│ ├── 00_project_brief/ # Original idea brief (historical)
│ ├── 01_problem_motivation/ # Verified dyslexia & reading evidence
│ ├── 02_text_simplification/ # Datasets, systems, evaluation, architecture decisions, Baseet analysis
│ └── 03_project_architecture/ # Pipeline architecture & execution plan (LaTeX)
├── scripts/ # Data pipeline, classifiers, DSPy validator optimization
│ ├── compiled/ # Compiled DSPy programs
│ ├── training/ # model1_training.ipynb; model2/ (train.py, sari.py, both notebooks)
│ └── evaluation/ # Scoring, leakage check, test-set manifest (+ fixtures/)
├── data/ # README + human annotations (raw/processed data are git-ignored)
│ └── test_manifest.json # Hashes of the locked test sets; the sets themselves are never committed
├── pyproject.toml # Python dependencies (uv)
└── .env.example # API key template — copy to .env, never commit keys
uv sync # install dependencies (Python ≥ 3.12; includes torch)
cp .env.example .env # add your DEEPSEEK_API_KEY
# download BAREC — see data/README.md
uv run python scripts/camel_readability.py # optional: fetch the CAMeL readability model now (else the first run does)
uv run python scripts/barec_simplification_pipeline.py --dry-run
The CAMeL readability model needs no manual setup: it runs on an NVIDIA GPU when there is one (--device cpu|cuda|auto),
otherwise on CPU through an ONNX export that is made once on first use (about a minute) and cached in models/.
uv sync installs torch with its CUDA libraries on Linux. On a machine without a GPU you can skip them by installing
outside the lockfile and running with --no-sync afterwards (a plain uv run re-syncs to the lockfile):
uv venv
UV_EXTRA_INDEX_URL=https://download.pytorch.org/whl/cpu UV_INDEX_STRATEGY=unsafe-best-match uv pip install -r pyproject.toml
uv run --no-sync python scripts/camel_readability.py
Before any training file is used, check it for test-set leakage:
uv run python scripts/evaluation/check_leakage.py <training_file> \
--reachable data/raw/barec/train.csv --reachable data/raw/barec/dev.csv
| Member | Role | Responsibilities |
|---|---|---|
| Marwan Elamami | Team Leader & Application Lead | Project management; architecture and integration; application; read-aloud with highlighting |
| Abdulrahman Khengari | Data Lead | Simplification corpus; data quality control; annotation guidelines; BayanSimplify-v0.3; the pitch deck |
| Ahmed Alaeb | Model Training Lead | Training the simplification model(s) for on-device use; integrating the diacritization model |
| Sanad Ali | Machine Learning Engineer | Co-training the simplification model(s); diacritization benchmark; data annotation and quality review; presents the pitch |
| Mohammed Thabet | Application Engineer | Application; read-aloud with highlighting; data annotation and quality review |
| Abdul Majid Mraied | Evaluation & Benchmarking Lead | Test set design; benchmarking; automatic and human evaluation |
Never push to main — every change goes through a reviewed pull request. See CONTRIBUTING.md.
Arabic dyslexia-friendly text simplification pipeline (Samsung Innovation Campus capstone)
HTML
3
49 commits
updated Oct 6, 2026
Team Cogni · Samsung Innovation Campus (SIC) AI Course — Capstone Project
Bayan simplifies complex Arabic text for readers with dyslexia while preserving its meaning, then adds diacritics and reads it aloud with synchronized word highlighting.
Download: Bayan 2.1.0 for Android (Android 8 or newer; APKs and SHA-256 on
Hugging Face) · Models: BayanSimplify
on Hugging Face · Changelog: app/CHANGELOG.md
This README replaces the original idea brief, which is kept for history in
references/00_project_brief/original_project_brief.md. Where the two disagree, this file andreferences/INDEX.mdare current.
Readers with dyslexia can see text but struggle to process it. Arabic adds specific barriers that most (Latin-script) dyslexia tools do not address:
Scale: a meta-analysis of 18 studies (N = 30,243) estimates 11% pooled prevalence of developmental dyslexia among Arab primary-school children (Aldakhil, 2024). Dyslexia is not the same as low reading proficiency — never quote PISA / learning-poverty figures as dyslexia rates.
Evidence from user studies (Spanish, Rello et al., 2013): more frequent and shorter words help readers with dyslexia, and offering simpler synonyms on demand is preferred over silently replacing words. No deployed Arabic tool combines simplification with a dyslexia focus; existing Arabic apps offer diacritization and read-aloud only.
All figures are verified in references/01_problem_motivation/.
| Stage | What it does | Status |
|---|---|---|
| 1. Simplify (core) | Shorten and restructure sentences, replace rare words, keep meaning | In the app. The BayanSimplify models run on the phone as int8 ONNX bundles: BayanSimplify-v0.2-Fast (AraBART, the default download, 222 MB) and BayanSimplify-v0.3 (AraT5v2, the large model and our best, decoded with four beams, 471 MB); BayanSimplify-v0.2 stays available as the earlier large model |
| 2. Diacritize | Restore full tashkeel on the simplified text | In the app (the Show tashkeel setting). Libtashkeel (text2tashkeel): MIT, 4.8 MB, bundled with the app, never changes a letter |
| 3. Read aloud | TTS with word-by-word highlighting | In the app. Nabra-7M-Distill (int8, 8.7 MB) through sherpa-onnx, the spoken word highlighted; three Piper voices as optional downloads |
Order matters: simplify → diacritize → read aloud, because diacritics depend on the final wording.
Bayan is an Android plugin. It registers a PROCESS_TEXT intent, so «تبسيط» (Simplify) appears in the
text-selection menu of any app: the reader selects hard Arabic text where they meet it, and a panel over that app
streams the simplified version sentence by sentence, with the original one tap away. The panel can read aloud,
and minimizes to a floating reader so the reader can keep using the app while Bayan reads on. All inference runs
on the device: no server, no network, and the text never leaves the phone.
Before and after the model, a text step in code guards the output: scripture and set poetry pass through untouched, very short sentences are left alone, and a rewritten sentence that drops a number or a Latin token, changes a negation, limit or condition word, or loses too much of its text is replaced by the original sentence.
Constraints: ONNX Runtime Mobile only, no Python or GPU at runtime, and a default download within 250 MB
(BayanSimplify-v0.2-Fast, 222 MB); the AraT5v2 bundles (471 MB) are optional downloads, kept whole for quality. Reasoning: docs/decisions/0001-product-form.md;
app build and layout: app/; brand, logo, colours and reading rules: app/design-system/.
Recorded on a phone over an Arabic Wikipedia paragraph: select the text → تبسيط in the selection menu → the simplified version in the bottom sheet, with read-aloud.
Local copy: deliverables/05_demo/bayan_demo.mp4 — the same clip
runs in the pitch decks (deliverables/04_presentation/).
No large, open, parallel Arabic simplification corpus fits the task, so Bayan builds its own:
data/README.md.Congi-libya/bayan-simplification-corpus,
public, CC BY-SA 4.0; 14,975 rows): hard BAREC sentences rewritten by Gemma 4 31B, kept only if code checks pass,
CAMeL rates the rewrite at least 2 levels easier, and a Qwen judge scores the meaning as kept; easy, protected and
short sentences are kept verbatim. Pipeline: scripts/barec_simplification_pipeline.py,
scripts/assemble_corpus_v1.py; data card:
docs/synthetic_data_card_v1.md. Corpus v0 (13,072 rows) is kept on the Hub under the tag v0.[S0]–[S3], [SA]). The app sends no tag, which
keeps the meaning more often (see below).scripts/meaning_reward/); the meaning judge is in scripts/meaning_judge/.scripts/evaluation/check_leakage.py. 33 BayanBench held-out items appear in corpus v1,
so models trained on it are reported on the core and outside items only.Public on Hugging Face under CC BY-NC 4.0 (non-commercial, in line with the training data's terms):
| Model | Base | Training data | In the app |
|---|---|---|---|
| BayanSimplify-v0.1 | AraT5v2-base-1024 | SAMER, level 5 → 3 | not shipped |
| BayanSimplify-v0.2 | AraT5v2-base-1024 | 22,733-pair mix with strength tags | "Earlier large model" |
| BayanSimplify-v0.2-Fast | AraBART | the same mix | "Fast model", the default download |
| BayanSimplify-v0.3 | AraT5v2-base-1024 | corpus v1 (14,975 rows) | "Large model", four beams; our best |
| BayanSimplify-ONNX | the int8 bundles the app downloads | v0.2-Fast/, v0.2/, v0.3/ |
The full tables, intervals and figures are in the final report
(deliverables/03_final_report/). On BayanBench v2, test split, core items
(meaning kept = Gemma 4 31B P(same) ≥ 0.5 and every number kept):
| System | Meaning kept | Longest clause, words shorter |
|---|---|---|
| copy the input | 100% | 0 |
BayanSimplify-v0.2 (AraT5v2), [S2] / no tag | 59.5% / 68.3% | 6.3 / 4.5 |
BayanSimplify-v0.2-Fast (AraBART), [S2] / no tag | 40.1% / 51.4% | 6.7 / 4.9 |
| app, v0.2 int8 / v0.2-Fast int8 (September text step) | 78.6% / 50.5% | 1.9 / 4.8 |
| app, BayanSimplify-v0.3 int8, four beams | 82% | 5.2 |
bayanbench/ (v2.0, frozen; tag bayanbench-v2.0) scores a simplifier on 1,981 items (dev 731 /
test 1,250, split by document) in core, held-out, outside and written sets. It reports meaning, simplification
(clause length, CAMeL reading level, hard words), deterministic checks (numbers, house rules) and behaviour tests
(easy text left alone, protected text, cut-off selections), each with a document-bootstrap interval, and paired
differences against a baseline. No composite score. Data: Congi-libya/bayanbench-data (private, team only).
cd bayanbench && uv run bayanbench score outputs.jsonl --split dev --data <bayanbench-data snapshot>
Full details and sources: references/INDEX.md.
Every system is scored on the same inputs with one pinned script, against a copy-the-input baseline. The two locked
test sets (BAREC test, 7,286 rows; SAMER test, 3,277 rows) live in data/test_locked/, which git ignores; only
data/test_manifest.json with their row counts and SHA-256 hashes is committed. Reference-based scores (SARI) are
reported on changed rows only; the task-specific evaluation is BayanBench (section 4a). How to score a trained model:
scripts/evaluation/README.md. Background:
references/02_text_simplification/evaluation_and_benchmarking.md.
Bayan/
├── README.md # This file
├── CONTRIBUTING.md # Team workflow: branches, PRs, reviews
├── .github/ # CODEOWNERS, PR and issue templates
├── app/ # Android plugin (PROCESS_TEXT), Jetpack Compose + Material 3 Expressive
│ └── design-system/ # Bayan design system: logo, tokens, components, banners, reading guidelines
├── bayanbench/ # BayanBench v2.0: the task benchmark (package, tests, README)
├── deliverables/ # SIC capstone deliverables (action plan, WBS, report, slides, demo)
├── docs/ # Model results, the diacritization comparison
│ ├── brand/ # Rendered banners (README, social); source in app/design-system
│ └── decisions/ # Decision records — what we chose, and why
├── references/ # Literature review, benchmarks, and the project's reference architecture
│ ├── INDEX.md # Start here
│ ├── 00_project_brief/ # Original idea brief (historical)
│ ├── 01_problem_motivation/ # Verified dyslexia & reading evidence
│ ├── 02_text_simplification/ # Datasets, systems, evaluation, architecture decisions, Baseet analysis
│ └── 03_project_architecture/ # Pipeline architecture & execution plan (LaTeX)
├── scripts/ # Data pipeline, classifiers, DSPy validator optimization
│ ├── compiled/ # Compiled DSPy programs
│ ├── training/ # model1_training.ipynb; model2/ (train.py, sari.py, both notebooks)
│ └── evaluation/ # Scoring, leakage check, test-set manifest (+ fixtures/)
├── data/ # README + human annotations (raw/processed data are git-ignored)
│ └── test_manifest.json # Hashes of the locked test sets; the sets themselves are never committed
├── pyproject.toml # Python dependencies (uv)
└── .env.example # API key template — copy to .env, never commit keys
uv sync # install dependencies (Python ≥ 3.12; includes torch)
cp .env.example .env # add your DEEPSEEK_API_KEY
# download BAREC — see data/README.md
uv run python scripts/camel_readability.py # optional: fetch the CAMeL readability model now (else the first run does)
uv run python scripts/barec_simplification_pipeline.py --dry-run
The CAMeL readability model needs no manual setup: it runs on an NVIDIA GPU when there is one (--device cpu|cuda|auto),
otherwise on CPU through an ONNX export that is made once on first use (about a minute) and cached in models/.
uv sync installs torch with its CUDA libraries on Linux. On a machine without a GPU you can skip them by installing
outside the lockfile and running with --no-sync afterwards (a plain uv run re-syncs to the lockfile):
uv venv
UV_EXTRA_INDEX_URL=https://download.pytorch.org/whl/cpu UV_INDEX_STRATEGY=unsafe-best-match uv pip install -r pyproject.toml
uv run --no-sync python scripts/camel_readability.py
Before any training file is used, check it for test-set leakage:
uv run python scripts/evaluation/check_leakage.py <training_file> \
--reachable data/raw/barec/train.csv --reachable data/raw/barec/dev.csv
| Member | Role | Responsibilities |
|---|---|---|
| Marwan Elamami | Team Leader & Application Lead | Project management; architecture and integration; application; read-aloud with highlighting |
| Abdulrahman Khengari | Data Lead | Simplification corpus; data quality control; annotation guidelines; BayanSimplify-v0.3; the pitch deck |
| Ahmed Alaeb | Model Training Lead | Training the simplification model(s) for on-device use; integrating the diacritization model |
| Sanad Ali | Machine Learning Engineer | Co-training the simplification model(s); diacritization benchmark; data annotation and quality review; presents the pitch |
| Mohammed Thabet | Application Engineer | Application; read-aloud with highlighting; data annotation and quality review |
| Abdul Majid Mraied | Evaluation & Benchmarking Lead | Test set design; benchmarking; automatic and human evaluation |
Never push to main — every change goes through a reviewed pull request. See CONTRIBUTING.md.