Reorganize Apertus tokenizer extension release
Browse filesAdd curated tokenizer/checkpoint/dataset/results layout, manifests, code links, and provenance pointers. No legacy paths deleted.
This view is limited to 50 files because it contains too many changes. See raw diff
- .gitattributes +9 -0
- ARTIFACT_GRAPH.md +51 -0
- MANIFEST.json +150 -0
- README.md +77 -66
- SHA256SUMS +59 -23
- archive/legacy-hf-layout-index.md +27 -0
- archive/legacy_SHA256SUMS_20260525 +23 -0
- checkpoints/baselines/retok-3p5b-iter834/README.md +12 -0
- checkpoints/baselines/retok-3p5b-iter834/hydration.md +8 -0
- checkpoints/baselines/retok-3p5b-iter834/manifest.json +8 -0
- checkpoints/baselines/vanilla-3p5b-iter834/README.md +13 -0
- checkpoints/baselines/vanilla-3p5b-iter834/hydration.md +8 -0
- checkpoints/baselines/vanilla-3p5b-iter834/manifest.json +8 -0
- checkpoints/td-layer11-cpt-3p5b-iter834/README.md +30 -0
- checkpoints/td-layer11-cpt-3p5b-iter834/hydration.md +15 -0
- checkpoints/td-layer11-cpt-3p5b-iter834/manifest.json +11 -0
- checkpoints/td-layer11-init-r17-tp2/README.md +13 -0
- checkpoints/td-layer11-init-r17-tp2/hydration.md +14 -0
- checkpoints/td-layer11-init-r17-tp2/manifest.json +9 -0
- code-links/README.md +17 -0
- code-links/github_subproject_manifest.json +73 -0
- provenance/conversion-roundtrip/td_layer11_r17_roundtrip_verification.json +43 -0
- provenance/conversion-roundtrip/vanilla_r17_roundtrip_verification.json +43 -0
- provenance/dataset-build/CPT_DATASET_BUILD_RUNBOOK.md +108 -0
- provenance/dataset-build/MIX_RECIPE.md +173 -0
- provenance/dataset-build/bulk_mix_text_document.manifest.json +19 -0
- provenance/evals/CONTINUATION_3P5B_RESULTS_20260525.md +91 -0
- provenance/evals/EVAL_RECIPE.md +321 -0
- provenance/evals/V4_BENCHMARK_COMPARISON.md +77 -0
- provenance/token-distillation/RUN_LOG_20260523.md +2299 -0
- provenance/token-distillation/TOKEN_DISTILLATION_PLAN.md +773 -0
- provenance/tokenizer-selection/CHOSEN_CUTOFF.md +220 -0
- provenance/tokenizer-selection/CUTOFF_SWEEP_REPORT.md +441 -0
- provenance/tokenizer-selection/curated_padded_at_17408_manifest.json +15 -0
- provenance/tokenizer-selection/firing_count_20260518_run_summary_augmented.json +0 -0
- results/SUMMARY.md +91 -0
- results/benchmark_table.csv +5 -0
- results/continuation_3p5b_summary.json +364 -0
- results/plots/global_mmlu_full_el_subcategories_van_td.png +3 -0
- results/plots/include_base_44_greek_subjects_van_td.png +3 -0
- results/plots/intrinsic_trajectories.png +3 -0
- results/plots/intrinsic_van_td.png +3 -0
- results/plots/trajectories.png +3 -0
- results/plots/trajectories_per_task.png +3 -0
- results/plots/trajectories_per_task_van_td.png +3 -0
- results/plots/trajectories_van_td.png +3 -0
- results/plots/trajectories_van_td_gap.png +3 -0
- tokenizer/modern-greek-17408/README.md +22 -0
- tokenizer/modern-greek-17408/manifest.json +33 -0
- tokenizer/modern-greek-17408/special_tokens_map.json +30 -0
.gitattributes
CHANGED
|
@@ -39,3 +39,12 @@ subprojects/03_apertus_extension_and_embedding_adaptation/03_4_implementation_ex
|
|
| 39 |
subprojects/03_apertus_extension_and_embedding_adaptation/03_4_implementation_experiments/init_bakeoff/eval/trajectory_analysis_20260524/plots/trajectories_per_task_van_td.png filter=lfs diff=lfs merge=lfs -text
|
| 40 |
subprojects/03_apertus_extension_and_embedding_adaptation/03_4_implementation_experiments/init_bakeoff/eval/trajectory_analysis_20260524/plots/trajectories_van_td.png filter=lfs diff=lfs merge=lfs -text
|
| 41 |
subprojects/03_apertus_extension_and_embedding_adaptation/03_4_implementation_experiments/init_bakeoff/eval/trajectory_analysis_20260524/plots/trajectories_van_td_gap.png filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
subprojects/03_apertus_extension_and_embedding_adaptation/03_4_implementation_experiments/init_bakeoff/eval/trajectory_analysis_20260524/plots/trajectories_per_task_van_td.png filter=lfs diff=lfs merge=lfs -text
|
| 40 |
subprojects/03_apertus_extension_and_embedding_adaptation/03_4_implementation_experiments/init_bakeoff/eval/trajectory_analysis_20260524/plots/trajectories_van_td.png filter=lfs diff=lfs merge=lfs -text
|
| 41 |
subprojects/03_apertus_extension_and_embedding_adaptation/03_4_implementation_experiments/init_bakeoff/eval/trajectory_analysis_20260524/plots/trajectories_van_td_gap.png filter=lfs diff=lfs merge=lfs -text
|
| 42 |
+
results/plots/global_mmlu_full_el_subcategories_van_td.png filter=lfs diff=lfs merge=lfs -text
|
| 43 |
+
results/plots/include_base_44_greek_subjects_van_td.png filter=lfs diff=lfs merge=lfs -text
|
| 44 |
+
results/plots/intrinsic_trajectories.png filter=lfs diff=lfs merge=lfs -text
|
| 45 |
+
results/plots/intrinsic_van_td.png filter=lfs diff=lfs merge=lfs -text
|
| 46 |
+
results/plots/trajectories.png filter=lfs diff=lfs merge=lfs -text
|
| 47 |
+
results/plots/trajectories_per_task.png filter=lfs diff=lfs merge=lfs -text
|
| 48 |
+
results/plots/trajectories_per_task_van_td.png filter=lfs diff=lfs merge=lfs -text
|
| 49 |
+
results/plots/trajectories_van_td.png filter=lfs diff=lfs merge=lfs -text
|
| 50 |
+
results/plots/trajectories_van_td_gap.png filter=lfs diff=lfs merge=lfs -text
|
ARTIFACT_GRAPH.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Artifact Graph
|
| 2 |
+
|
| 3 |
+
```text
|
| 4 |
+
swiss-ai/Apertus-8B-2509
|
| 5 |
+
|
|
| 6 |
+
| continuous BPE on GlossAPI + HPLT 50/50
|
| 7 |
+
v
|
| 8 |
+
C3 full candidate
|
| 9 |
+
base 131072 + 25600 = 156672
|
| 10 |
+
|
|
| 11 |
+
| cutoff sweep, curation, backfill, alignment
|
| 12 |
+
v
|
| 13 |
+
tokenizer/modern-greek-17408
|
| 14 |
+
base 131072 + 17408 = 148480
|
| 15 |
+
|
|
| 16 |
+
| optional polytonic stack
|
| 17 |
+
v
|
| 18 |
+
tokenizer/polytonic-plus-5120
|
| 19 |
+
base 131072 + modern 17408 + polytonic 5120 = 153600
|
| 20 |
+
|
| 21 |
+
fffoivos/glossapi-greek-nanochat-pretraining-dataset
|
| 22 |
+
+ nanochat internal dedup metadata
|
| 23 |
+
+ Apertus overlap drop overlay
|
| 24 |
+
|
|
| 25 |
+
v
|
| 26 |
+
selected_after_apertus_and_internal_dedup.parquet
|
| 27 |
+
|
|
| 28 |
+
| 70/24/4/2 Greek/replay/code/math mix
|
| 29 |
+
v
|
| 30 |
+
bulk_mix.nfc.jsonl
|
| 31 |
+
|
|
| 32 |
+
| Megatron indexed dataset preprocessing
|
| 33 |
+
v
|
| 34 |
+
bulk_mix_base_nfc_megatron/bulk_mix_text_document.{bin,idx}
|
| 35 |
+
|
| 36 |
+
modern tokenizer + CPT mix
|
| 37 |
+
|
|
| 38 |
+
| Vanilla, ReTok, Centroid, Token Distillation layer 11
|
| 39 |
+
v
|
| 40 |
+
2B bakeoff and 3.5B continuation
|
| 41 |
+
|
|
| 42 |
+
v
|
| 43 |
+
checkpoints/td-layer11-cpt-3p5b-iter834
|
| 44 |
+
|
|
| 45 |
+
v
|
| 46 |
+
results/
|
| 47 |
+
```
|
| 48 |
+
|
| 49 |
+
The large checkpoint and dataset payloads are represented by hydration pointers
|
| 50 |
+
unless explicitly uploaded as model weights.
|
| 51 |
+
|
MANIFEST.json
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"release_name": "apertus-tokenizer-extension",
|
| 3 |
+
"generated_date": "2026-05-25",
|
| 4 |
+
"source_repo": "https://github.com/fffoivos/glossapi-tokenizer-extension",
|
| 5 |
+
"source_subproject": "subprojects/03_apertus_extension_and_embedding_adaptation",
|
| 6 |
+
"source_commit_for_code_refs": "7c67cf11eb3d31f0ddd006f7d709709037db93a1",
|
| 7 |
+
"artifacts": [
|
| 8 |
+
{
|
| 9 |
+
"artifact_id": "tokenizer.modern-greek-17408",
|
| 10 |
+
"type": "tokenizer",
|
| 11 |
+
"status": "payload-present",
|
| 12 |
+
"public_path": "tokenizer/modern-greek-17408",
|
| 13 |
+
"base_model": "swiss-ai/Apertus-8B-2509",
|
| 14 |
+
"vocab_size": 148480,
|
| 15 |
+
"base_vocab_size": 131072,
|
| 16 |
+
"added_modern_greek_tokens": 17408,
|
| 17 |
+
"sha256_tokenizer_json": "358ae3f29ac17c99769d6d437339e28657d5fcaed3486f8550feed3d6adfc394",
|
| 18 |
+
"review_docs": [
|
| 19 |
+
"provenance/tokenizer-selection/CHOSEN_CUTOFF.md"
|
| 20 |
+
],
|
| 21 |
+
"github_code_refs": [
|
| 22 |
+
"code-links/github_subproject_manifest.json"
|
| 23 |
+
]
|
| 24 |
+
},
|
| 25 |
+
{
|
| 26 |
+
"artifact_id": "tokenizer.polytonic-plus-5120",
|
| 27 |
+
"type": "tokenizer",
|
| 28 |
+
"status": "payload-present",
|
| 29 |
+
"public_path": "tokenizer/polytonic-plus-5120",
|
| 30 |
+
"base_model": "swiss-ai/Apertus-8B-2509",
|
| 31 |
+
"vocab_size": 153600,
|
| 32 |
+
"base_vocab_size": 131072,
|
| 33 |
+
"added_modern_greek_tokens": 17408,
|
| 34 |
+
"added_polytonic_greek_tokens": 5120,
|
| 35 |
+
"sha256_tokenizer_json": "b1eeb739a564b3abd33c1b85a16162b8284d98f9ab5d67528d3cbe8a82e9cbad",
|
| 36 |
+
"review_docs": [
|
| 37 |
+
"provenance/tokenizer-selection/CHOSEN_CUTOFF.md"
|
| 38 |
+
],
|
| 39 |
+
"github_code_refs": [
|
| 40 |
+
"code-links/github_subproject_manifest.json"
|
| 41 |
+
]
|
| 42 |
+
},
|
| 43 |
+
{
|
| 44 |
+
"artifact_id": "dataset.cpt-7b-mix",
|
| 45 |
+
"type": "dataset",
|
| 46 |
+
"status": "hydration-pointer",
|
| 47 |
+
"public_path": "training-data/cpt-7b-mix",
|
| 48 |
+
"clariden_jsonl": "/iopsstor/scratch/cscs/fffoivos/cpt_corpus/bulk_mix.nfc.jsonl",
|
| 49 |
+
"clariden_megatron_prefix": "/iopsstor/scratch/cscs/fffoivos/cpt_corpus/bulk_mix_base_nfc_megatron/bulk_mix_text_document",
|
| 50 |
+
"rows": 5754172,
|
| 51 |
+
"base_tokenized_tokens": 9831704774,
|
| 52 |
+
"mix_builder_target_tokens": 7000141612,
|
| 53 |
+
"review_docs": [
|
| 54 |
+
"provenance/dataset-build/CPT_DATASET_BUILD_RUNBOOK.md",
|
| 55 |
+
"provenance/dataset-build/MIX_RECIPE.md"
|
| 56 |
+
],
|
| 57 |
+
"github_code_refs": [
|
| 58 |
+
"code-links/github_subproject_manifest.json"
|
| 59 |
+
]
|
| 60 |
+
},
|
| 61 |
+
{
|
| 62 |
+
"artifact_id": "checkpoint.td-layer11-init-r17-tp2",
|
| 63 |
+
"type": "checkpoint",
|
| 64 |
+
"status": "hydration-pointer",
|
| 65 |
+
"public_path": "checkpoints/td-layer11-init-r17-tp2",
|
| 66 |
+
"format": "Megatron torch_dist TP=2, R17 patched",
|
| 67 |
+
"clariden_path": "/iopsstor/scratch/cscs/fffoivos/token_distillation/td_full25_layer11_r17_roundtrip_2357565/megatron_tp2_r17patched/release",
|
| 68 |
+
"depends_on": [
|
| 69 |
+
"tokenizer.modern-greek-17408"
|
| 70 |
+
],
|
| 71 |
+
"review_docs": [
|
| 72 |
+
"provenance/token-distillation/RUN_LOG_20260523.md",
|
| 73 |
+
"provenance/conversion-roundtrip/td_layer11_r17_roundtrip_verification.json"
|
| 74 |
+
],
|
| 75 |
+
"github_code_refs": [
|
| 76 |
+
"code-links/github_subproject_manifest.json"
|
| 77 |
+
]
|
| 78 |
+
},
|
| 79 |
+
{
|
| 80 |
+
"artifact_id": "checkpoint.td-layer11-cpt-3p5b-iter834",
|
| 81 |
+
"type": "checkpoint",
|
| 82 |
+
"status": "hydration-pointer",
|
| 83 |
+
"public_path": "checkpoints/td-layer11-cpt-3p5b-iter834",
|
| 84 |
+
"format": "Megatron torch_dist TP=2 checkpoint plus HF eval conversion",
|
| 85 |
+
"clariden_checkpoint": "/capstor/scratch/cscs/fffoivos/runs/bakeoff/continuation_3p5b_20260524T143012Z_td_layer11/checkpoints/iter_0000834",
|
| 86 |
+
"clariden_hf_eval_copy": "/capstor/scratch/cscs/fffoivos/runs/eval/continuation_3p5b_20260524T143012Z_td_layer11/iter_0000834_hf",
|
| 87 |
+
"depends_on": [
|
| 88 |
+
"tokenizer.modern-greek-17408",
|
| 89 |
+
"dataset.cpt-7b-mix",
|
| 90 |
+
"checkpoint.td-layer11-init-r17-tp2"
|
| 91 |
+
],
|
| 92 |
+
"review_docs": [
|
| 93 |
+
"results/SUMMARY.md",
|
| 94 |
+
"provenance/evals/CONTINUATION_3P5B_RESULTS_20260525.md"
|
| 95 |
+
],
|
| 96 |
+
"github_code_refs": [
|
| 97 |
+
"code-links/github_subproject_manifest.json"
|
| 98 |
+
]
|
| 99 |
+
},
|
| 100 |
+
{
|
| 101 |
+
"artifact_id": "checkpoint.baseline-vanilla-3p5b-iter834",
|
| 102 |
+
"type": "checkpoint",
|
| 103 |
+
"status": "hydration-pointer",
|
| 104 |
+
"public_path": "checkpoints/baselines/vanilla-3p5b-iter834",
|
| 105 |
+
"format": "Megatron torch_dist TP=2 checkpoint plus HF eval conversion",
|
| 106 |
+
"clariden_checkpoint": "/capstor/scratch/cscs/fffoivos/runs/bakeoff/continuation_3p5b_20260524T143012Z_vanilla/checkpoints/iter_0000834",
|
| 107 |
+
"depends_on": [
|
| 108 |
+
"dataset.cpt-7b-mix"
|
| 109 |
+
],
|
| 110 |
+
"review_docs": [
|
| 111 |
+
"results/SUMMARY.md"
|
| 112 |
+
],
|
| 113 |
+
"github_code_refs": [
|
| 114 |
+
"code-links/github_subproject_manifest.json"
|
| 115 |
+
]
|
| 116 |
+
},
|
| 117 |
+
{
|
| 118 |
+
"artifact_id": "checkpoint.baseline-retok-3p5b-iter834",
|
| 119 |
+
"type": "checkpoint",
|
| 120 |
+
"status": "hydration-pointer",
|
| 121 |
+
"public_path": "checkpoints/baselines/retok-3p5b-iter834",
|
| 122 |
+
"format": "Megatron torch_dist TP=2 checkpoint plus HF eval conversion",
|
| 123 |
+
"clariden_checkpoint": "/capstor/scratch/cscs/fffoivos/runs/bakeoff/continuation_3p5b_20260524T143012Z_retok/checkpoints/iter_0000834",
|
| 124 |
+
"depends_on": [
|
| 125 |
+
"tokenizer.modern-greek-17408",
|
| 126 |
+
"dataset.cpt-7b-mix"
|
| 127 |
+
],
|
| 128 |
+
"review_docs": [
|
| 129 |
+
"results/SUMMARY.md"
|
| 130 |
+
],
|
| 131 |
+
"github_code_refs": [
|
| 132 |
+
"code-links/github_subproject_manifest.json"
|
| 133 |
+
]
|
| 134 |
+
},
|
| 135 |
+
{
|
| 136 |
+
"artifact_id": "results.continuation-3p5b",
|
| 137 |
+
"type": "evaluation-summary",
|
| 138 |
+
"status": "compact-evidence",
|
| 139 |
+
"public_path": "results",
|
| 140 |
+
"review_docs": [
|
| 141 |
+
"results/SUMMARY.md",
|
| 142 |
+
"results/benchmark_table.csv"
|
| 143 |
+
],
|
| 144 |
+
"github_code_refs": [
|
| 145 |
+
"code-links/github_subproject_manifest.json"
|
| 146 |
+
]
|
| 147 |
+
}
|
| 148 |
+
]
|
| 149 |
+
}
|
| 150 |
+
|
README.md
CHANGED
|
@@ -1,88 +1,99 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
base_model:
|
| 14 |
-
- swiss-ai/Apertus-8B-2509
|
| 15 |
-
---
|
| 16 |
-
|
| 17 |
-
# Apertus Tokenizer Extension
|
| 18 |
-
|
| 19 |
-
Current canonical artifact: **C3 + 17,408 curated/backfilled added units**.
|
| 20 |
-
|
| 21 |
-
The active ship tokenizer is:
|
| 22 |
|
| 23 |
```text
|
| 24 |
-
|
| 25 |
```
|
| 26 |
|
| 27 |
-
|
| 28 |
-
`0..131071` verbatim, adds `17,408` C3 Greek-extension BPE units, and keeps
|
| 29 |
-
the final vocab aligned at `148,480 = 128 * 1160 = 256 * 580`.
|
| 30 |
|
| 31 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
|
| 33 |
-
|
| 34 |
-
| --- | ---: | ---: | --- | --- |
|
| 35 |
-
| `tokenizers/c3_added_17408_curated_padded/` | 148,480 | 17,408 | 69 noisy raw-cutoff tokens structurally skipped and backfilled | `358ae3f29ac17c99769d6d437339e28657d5fcaed3486f8550feed3d6adfc394` |
|
| 36 |
|
| 37 |
-
|
| 38 |
-
but this is the current handoff artifact for the Apertus Greek tokenizer
|
| 39 |
-
extension line.
|
| 40 |
|
| 41 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
|
| 43 |
-
|
| 44 |
|
| 45 |
-
``
|
| 46 |
-
|
| 47 |
-
``
|
|
|
|
|
|
|
|
|
|
| 48 |
|
| 49 |
-
|
|
|
|
| 50 |
|
| 51 |
-
|
| 52 |
-
- `REPORT.md` — intrinsic/fertility/MorphScore evidence base.
|
| 53 |
-
- `artifacts/plots/` — report plots for the cutoff decision.
|
| 54 |
-
- `manifests/curated_padded_at_17408_manifest.json` — exact backfilled construction.
|
| 55 |
-
- `manifests/removal_mask_at_17408.jsonl` — the 69 in-cutoff tokens filtered out.
|
| 56 |
-
- `firing_counts_c3_added_17408_curated_padded/` — compact token firing-count attribution artifacts for the exact C3 BPE training corpus, split by GlossAPI-nanochat, HPLT, combined C3, and exact `source_dataset`.
|
| 57 |
|
| 58 |
-
The
|
| 59 |
-
canonical tokenizer and just enough evidence to explain why it is current.
|
| 60 |
-
Raw local variants, TokEval vendor caches, parquet outputs, and large geometry
|
| 61 |
-
arrays remain outside the Hub artifact set.
|
| 62 |
|
| 63 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
|
| 65 |
-
|
| 66 |
-
still present in their historical paths, including:
|
| 67 |
|
| 68 |
-
- `
|
| 69 |
-
- `
|
| 70 |
-
- `
|
| 71 |
-
- `
|
| 72 |
|
| 73 |
-
|
| 74 |
-
|
|
|
|
| 75 |
|
| 76 |
-
##
|
| 77 |
|
| 78 |
-
|
| 79 |
|
| 80 |
-
|
| 81 |
-
https://github.com/fffoivos/glossapi-tokenizer-extension
|
| 82 |
-
```
|
| 83 |
|
| 84 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 85 |
|
| 86 |
-
```text
|
| 87 |
-
9a6b039 Add firing count attribution workflow
|
| 88 |
-
```
|
|
|
|
| 1 |
+
# Apertus Greek Tokenizer Extension
|
| 2 |
+
|
| 3 |
+
This release packages the Greek tokenizer-extension work around its main
|
| 4 |
+
artifacts:
|
| 5 |
+
|
| 6 |
+
1. a modern Greek merge-rule tokenizer extension for `swiss-ai/Apertus-8B-2509`;
|
| 7 |
+
2. an optional polytonic/ancient Greek stacked tokenizer;
|
| 8 |
+
3. the CPT dataset recipe and hydration pointers used for the bakeoff;
|
| 9 |
+
4. the init and Token Distillation checkpoint pointers;
|
| 10 |
+
5. compact benchmark evidence from the 2B bakeoff and 3.5B continuation.
|
| 11 |
+
|
| 12 |
+
The runnable scripts live in GitHub, not in this Hugging Face artifact repo:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
|
| 14 |
```text
|
| 15 |
+
https://github.com/fffoivos/glossapi-tokenizer-extension/tree/main/subprojects/03_apertus_extension_and_embedding_adaptation
|
| 16 |
```
|
| 17 |
|
| 18 |
+
## Main Artifacts
|
|
|
|
|
|
|
| 19 |
|
| 20 |
+
| Artifact | Status | Path |
|
| 21 |
+
|---|---|---|
|
| 22 |
+
| Modern Greek tokenizer, 148,480 vocab | payload included | `tokenizer/modern-greek-17408/` |
|
| 23 |
+
| Polytonic-stacked tokenizer, 153,600 vocab | payload included | `tokenizer/polytonic-plus-5120/` |
|
| 24 |
+
| TD layer 11 CPT checkpoint at 3.5B | hydration pointer | `checkpoints/td-layer11-cpt-3p5b-iter834/` |
|
| 25 |
+
| TD layer 11 R17-patched init | hydration pointer | `checkpoints/td-layer11-init-r17-tp2/` |
|
| 26 |
+
| Vanilla/ReTok 3.5B baselines | hydration pointers | `checkpoints/baselines/` |
|
| 27 |
+
| CPT 7B text mix recipe | manifest and pointer | `training-data/cpt-7b-mix/` |
|
| 28 |
+
| 3.5B benchmark summary | compact evidence | `results/` |
|
| 29 |
+
| Source-code links | GitHub pointers | `code-links/` |
|
| 30 |
+
| Audit trail | compact provenance | `provenance/` |
|
| 31 |
|
| 32 |
+
## Tokenizers
|
|
|
|
|
|
|
| 33 |
|
| 34 |
+
Modern-only tokenizer:
|
|
|
|
|
|
|
| 35 |
|
| 36 |
+
- base Apertus vocab: `131072`;
|
| 37 |
+
- added modern Greek C3 tokens: `17408`;
|
| 38 |
+
- total vocab: `148480`;
|
| 39 |
+
- SHA-256 for `tokenizer.json`:
|
| 40 |
+
`358ae3f29ac17c99769d6d437339e28657d5fcaed3486f8550feed3d6adfc394`.
|
| 41 |
|
| 42 |
+
Polytonic-stacked tokenizer:
|
| 43 |
|
| 44 |
+
- base Apertus vocab: `131072`;
|
| 45 |
+
- modern Greek extension: `17408`;
|
| 46 |
+
- polytonic/ancient Greek extension: `5120`;
|
| 47 |
+
- total vocab: `153600`;
|
| 48 |
+
- SHA-256 for `tokenizer.json`:
|
| 49 |
+
`b1eeb739a564b3abd33c1b85a16162b8284d98f9ab5d67528d3cbe8a82e9cbad`.
|
| 50 |
|
| 51 |
+
Both tokenizers preserve Apertus base ids and the first 1000 special/reserved
|
| 52 |
+
ids.
|
| 53 |
|
| 54 |
+
## Dataset
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 55 |
|
| 56 |
+
The CPT text mix is built from:
|
|
|
|
|
|
|
|
|
|
| 57 |
|
| 58 |
+
- `fffoivos/glossapi-greek-nanochat-pretraining-dataset`;
|
| 59 |
+
- nanochat internal dedup metadata;
|
| 60 |
+
- Apertus-overlap drop overlay from
|
| 61 |
+
`fffoivos/apertus-c3-dedup-audit-dedup-20260519t010924z`;
|
| 62 |
+
- non-Greek replay, code, and math.
|
| 63 |
|
| 64 |
+
Bulk recipe:
|
|
|
|
| 65 |
|
| 66 |
+
- Greek: `70%`;
|
| 67 |
+
- non-Greek replay: `24%`;
|
| 68 |
+
- code: `4%`;
|
| 69 |
+
- math: `2%`.
|
| 70 |
|
| 71 |
+
The final text stream is about `7.0B` extended-tokenizer-budget tokens. The
|
| 72 |
+
same NFC JSONL stream contains `9,831,704,774` base-tokenized Megatron tokens
|
| 73 |
+
after preprocessing.
|
| 74 |
|
| 75 |
+
## Current Result Anchor
|
| 76 |
|
| 77 |
+
The latest compact result is the 3.5B continuation summary in `results/`.
|
| 78 |
|
| 79 |
+
At iter 834:
|
|
|
|
|
|
|
| 80 |
|
| 81 |
+
| Arm | Greek aggregate | English retention | Multilingual | Heldout BPC, lower better |
|
| 82 |
+
|---|---:|---:|---:|---:|
|
| 83 |
+
| Vanilla | 0.4339 | 0.6782 | 0.4923 | 0.4724 |
|
| 84 |
+
| ReTok | 0.4246 | 0.6786 | 0.4864 | 0.5390 |
|
| 85 |
+
| TD layer 11 | 0.4344 | 0.6865 | 0.4967 | 0.5054 |
|
| 86 |
+
|
| 87 |
+
Reading: TD layer 11 is the strongest final benchmark arm overall after the
|
| 88 |
+
3.5B continuation. Vanilla remains the heldout-BPC reference.
|
| 89 |
+
|
| 90 |
+
## Source And Provenance
|
| 91 |
+
|
| 92 |
+
- `MANIFEST.json`: machine-readable artifact inventory.
|
| 93 |
+
- `ARTIFACT_GRAPH.md`: dependency graph.
|
| 94 |
+
- `code-links/github_subproject_manifest.json`: source-code pointers.
|
| 95 |
+
- `provenance/`: compact documents and verification outputs for tokenizer
|
| 96 |
+
selection, dataset build, TD, conversion, and eval.
|
| 97 |
+
- `archive/legacy-hf-layout-index.md`: index of older HF folders retained for
|
| 98 |
+
traceability.
|
| 99 |
|
|
|
|
|
|
|
|
|
SHA256SUMS
CHANGED
|
@@ -1,23 +1,59 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
d528c230d2d3e151776332036669794eaacc5962a1dd3b3805a64c56e2f539ff ./ARTIFACT_GRAPH.md
|
| 2 |
+
6c8fe007c045e4be44f2825d16724be5cc80d53956b1aba3d64b8843f42f2c9c ./MANIFEST.json
|
| 3 |
+
e055076dd9f8fc307d2056f5c46c9f6cd99463dfe610758a45796e98200bf3cc ./README.md
|
| 4 |
+
dc2f59def39f4d46b645608e789ebca000b3f3257336c393b234da9b9c26f607 ./archive/legacy-hf-layout-index.md
|
| 5 |
+
620d1591179643c31aca8c3ba98492204fc2dd3388afff5764726d632b28fd09 ./archive/legacy_SHA256SUMS_20260525
|
| 6 |
+
2eee70665c1fd320ebc5d664d5fe3b526be32adf33be71f63a0edd3b52545076 ./checkpoints/baselines/retok-3p5b-iter834/README.md
|
| 7 |
+
be50de74fda67fb79a2d4ae616f3eaa0800e46b641b1ae3bd5a5d12e1fd6aeb2 ./checkpoints/baselines/retok-3p5b-iter834/hydration.md
|
| 8 |
+
1a4aff5d2d4dec2424a50fb7921d3bb92fc9a92d3e6b539a4bc2b542dfefa9a5 ./checkpoints/baselines/retok-3p5b-iter834/manifest.json
|
| 9 |
+
ea3e33007aa0ddfff2f88039b9f7d6a16c1317b14bee999ab762fc6867000649 ./checkpoints/baselines/vanilla-3p5b-iter834/README.md
|
| 10 |
+
1531171806fc72e45ba4467a1872a40ed1360ae5b6926cd7e313f818d924e4cd ./checkpoints/baselines/vanilla-3p5b-iter834/hydration.md
|
| 11 |
+
c7203eaed58b9b9a23d21e7b25ac37dbf9ee07538707626181f06795b1ae26c1 ./checkpoints/baselines/vanilla-3p5b-iter834/manifest.json
|
| 12 |
+
553be4bd24ccfc8bef210913c5e6ff7a26ca909b782bbd266ad927db07709581 ./checkpoints/td-layer11-cpt-3p5b-iter834/README.md
|
| 13 |
+
6d0724888604be70abae50448eb120160710b875b42dec21ce7419a82fa60c01 ./checkpoints/td-layer11-cpt-3p5b-iter834/hydration.md
|
| 14 |
+
69b48c1c95a4c79cfdbab0ec12a669e0bc74549294e3c38dfde57d547dd2d2f6 ./checkpoints/td-layer11-cpt-3p5b-iter834/manifest.json
|
| 15 |
+
4bcb2a3a6316ee1373a170d0d4bb9e32ec25dafb942c10fb781188216faceafd ./checkpoints/td-layer11-init-r17-tp2/README.md
|
| 16 |
+
da19cd1247b0401eb6d6e25d8c0fc496ee5d93b2e745b05ce8ff59b6b9fd8c57 ./checkpoints/td-layer11-init-r17-tp2/hydration.md
|
| 17 |
+
98d6a3fa9b342949b4972514925bff2952de06a202bcfcc56b449741ea4530c6 ./checkpoints/td-layer11-init-r17-tp2/manifest.json
|
| 18 |
+
44a71b0a1730bf13f3387ccf15967bf036f519f002b775cd4e7a671a44c9830a ./code-links/README.md
|
| 19 |
+
44705bc53f80deba2ac02336a29a77a6fa1b83431ec10fe9b100b5493903956f ./code-links/github_subproject_manifest.json
|
| 20 |
+
06ddc69f4787f470b85d4be55992f898b98d8ab4fd8ab34a89a4d3bb96eb7e33 ./provenance/conversion-roundtrip/td_layer11_r17_roundtrip_verification.json
|
| 21 |
+
496fa7d6f5622d6038aa2e333adbbd142ac83341e834acedc697892d66031c44 ./provenance/conversion-roundtrip/vanilla_r17_roundtrip_verification.json
|
| 22 |
+
61c13b8d63a692fad24e7cdf5fe5b5d6e2fb82bc4cf61981ea7c8b62b42569a6 ./provenance/dataset-build/CPT_DATASET_BUILD_RUNBOOK.md
|
| 23 |
+
6ab3047ac06c925073ca06c1a91e91bf1c1ce4e4a1336f41f6ef35769228ebd1 ./provenance/dataset-build/MIX_RECIPE.md
|
| 24 |
+
2dafea9a789b717e1f8b6fb931d8b47483e3b8433ceb1fe4b8064afa3bf5489a ./provenance/dataset-build/bulk_mix_text_document.manifest.json
|
| 25 |
+
8fbed782f3250003ef427d56ff27ae4379311da5a6263e078466ce06d6078bd2 ./provenance/evals/CONTINUATION_3P5B_RESULTS_20260525.md
|
| 26 |
+
d336b0f9fa29db6ce9052ae5fcac15e55acf8f4dc0e1385c820076c43c1e4a42 ./provenance/evals/EVAL_RECIPE.md
|
| 27 |
+
c10f3693691c657945530ee70bfcca8ad85bd3b42939f1ff321c9aa27b085112 ./provenance/evals/V4_BENCHMARK_COMPARISON.md
|
| 28 |
+
80e2fda4e1c0ce1e2e066986add6c9e76db592f9d9b20b0b0f6857209c101d7d ./provenance/token-distillation/RUN_LOG_20260523.md
|
| 29 |
+
acda2215c1443fdd3ad25ced78085c121139640adf6d4f3037f776ec6e13f47d ./provenance/token-distillation/TOKEN_DISTILLATION_PLAN.md
|
| 30 |
+
fada1d3fa64b8060b17a65bc8b4fa8739e560454fcfe172d681ce055a51a38ba ./provenance/tokenizer-selection/CHOSEN_CUTOFF.md
|
| 31 |
+
9b350211cf4f0bd964feec9504a093c1062425fb12f22534a947112f357e5c25 ./provenance/tokenizer-selection/CUTOFF_SWEEP_REPORT.md
|
| 32 |
+
763f330459d536e1ca7832dddc755e7d5f43c69605f8f8ca6c688f24c7cdf895 ./provenance/tokenizer-selection/curated_padded_at_17408_manifest.json
|
| 33 |
+
6046eb8f4cabda22fddf8cf5ed1581267b854221d03253e2994d304572b4f320 ./provenance/tokenizer-selection/firing_count_20260518_run_summary_augmented.json
|
| 34 |
+
8fbed782f3250003ef427d56ff27ae4379311da5a6263e078466ce06d6078bd2 ./results/SUMMARY.md
|
| 35 |
+
712a3c96216fe3159433b9b9d886a8cb22b51001a35a3778a7e5d6ba99909772 ./results/benchmark_table.csv
|
| 36 |
+
669dc4a1c3252f994495d2fb1459145222443bcfa6f6ca1221e8ee92b602c56b ./results/continuation_3p5b_summary.json
|
| 37 |
+
13337a7976d4ca46c6c3db03014a2207ba81a42796c285410dc3f4ad26007cd9 ./results/plots/global_mmlu_full_el_subcategories_van_td.png
|
| 38 |
+
6375661e9c50fd4b9f32db79a9c77375aaadbb878fab8a61019802978af3ac0e ./results/plots/include_base_44_greek_subjects_van_td.png
|
| 39 |
+
a44571c0aca767ace369a89534632a9b4618bc01391c0b20bb0f04f1c34a8830 ./results/plots/intrinsic_trajectories.png
|
| 40 |
+
975e0c58604e6189f45182e07cf178bb94bead39130385aae36ed95c065ed2ad ./results/plots/intrinsic_van_td.png
|
| 41 |
+
ab072600c16be4aab4fe36ebd5b7fe3a216f1bf5ac391687733667f6231ff486 ./results/plots/trajectories.png
|
| 42 |
+
375efc4b55341c0a1060fb9d7ccaa8774db66c8ca554683100449e15b1541a44 ./results/plots/trajectories_per_task.png
|
| 43 |
+
ea2a02ecd33210ada4c9a5d1f7832246de07205cc4bbc5679aedb6959f93bfbe ./results/plots/trajectories_per_task_van_td.png
|
| 44 |
+
a54f94603549ddaf022297a2f691a688fb6283d793394f482531211b42dfa3a3 ./results/plots/trajectories_van_td.png
|
| 45 |
+
d49ee1c80666418e6f36b649b63c9a80fb2808bb365d31e481a6c58c97053d11 ./results/plots/trajectories_van_td_gap.png
|
| 46 |
+
55ce65390b6fbdc16a81f22e3d78c3a452e72192011b72289c0180a656052273 ./tokenizer/modern-greek-17408/README.md
|
| 47 |
+
09c84b4086e9f800174942dcba688d8eefa8e40f3b60c20341699a6a7a11e2bf ./tokenizer/modern-greek-17408/manifest.json
|
| 48 |
+
816ec96e37c6d15e3cbc535dc146c898a7218f209fc154384f31fc1e6ad31ba5 ./tokenizer/modern-greek-17408/special_tokens_map.json
|
| 49 |
+
358ae3f29ac17c99769d6d437339e28657d5fcaed3486f8550feed3d6adfc394 ./tokenizer/modern-greek-17408/tokenizer.json
|
| 50 |
+
ea64a17b41e1deaa7469212f413676129f33977ca3a48767f0ca68dc346df502 ./tokenizer/modern-greek-17408/tokenizer_config.json
|
| 51 |
+
208ae8ea5f95c9182dc669c150aaf0c720e5937a402c72062fd83e1960978d6a ./tokenizer/polytonic-plus-5120/README.md
|
| 52 |
+
3881e1940ca013e9ec040fac3fb3a08a8f9b871e5105a0fec8165e0c6759acae ./tokenizer/polytonic-plus-5120/manifest.json
|
| 53 |
+
816ec96e37c6d15e3cbc535dc146c898a7218f209fc154384f31fc1e6ad31ba5 ./tokenizer/polytonic-plus-5120/special_tokens_map.json
|
| 54 |
+
b1eeb739a564b3abd33c1b85a16162b8284d98f9ab5d67528d3cbe8a82e9cbad ./tokenizer/polytonic-plus-5120/tokenizer.json
|
| 55 |
+
ea64a17b41e1deaa7469212f413676129f33977ca3a48767f0ca68dc346df502 ./tokenizer/polytonic-plus-5120/tokenizer_config.json
|
| 56 |
+
d2f04aa396cf6558502b919b4503d248aef0ccfe08251625d75f8a9314272787 ./training-data/cpt-7b-mix/README.md
|
| 57 |
+
f16d35ba906d5439709f189b1dc1253ba6e3d8518a828aac71c04fd42fefd0cf ./training-data/cpt-7b-mix/hydration.md
|
| 58 |
+
cafd9e0b15ab1d9f4f0eb7bc2939ccab29e9b6ab86ccc1f20e9a42a86b5760c0 ./training-data/cpt-7b-mix/manifest.json
|
| 59 |
+
4918a44fd6c0643c984b6cba3914c53c9a3a656f313ec904e9ba7e5ed1303279 ./training-data/cpt-7b-mix/source_graph.json
|
archive/legacy-hf-layout-index.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Legacy Hugging Face Layout Index
|
| 2 |
+
|
| 3 |
+
The previous Hugging Face repo layout included useful but noisy top-level
|
| 4 |
+
folders:
|
| 5 |
+
|
| 6 |
+
- `analysis/`;
|
| 7 |
+
- `artifacts/`;
|
| 8 |
+
- `continuous/`;
|
| 9 |
+
- `experiments/`;
|
| 10 |
+
- `fresh/`;
|
| 11 |
+
- `metadata/`;
|
| 12 |
+
- `subprojects/`;
|
| 13 |
+
- `tokenizers/`.
|
| 14 |
+
|
| 15 |
+
Those paths are retained for traceability. The release entrypoints are now the
|
| 16 |
+
curated folders at the repo root:
|
| 17 |
+
|
| 18 |
+
- `tokenizer/`;
|
| 19 |
+
- `checkpoints/`;
|
| 20 |
+
- `training-data/`;
|
| 21 |
+
- `results/`;
|
| 22 |
+
- `provenance/`;
|
| 23 |
+
- `code-links/`.
|
| 24 |
+
|
| 25 |
+
Do not treat this file as a deletion plan. It is an index explaining the old
|
| 26 |
+
layout while the new additive structure is reviewed.
|
| 27 |
+
|
archive/legacy_SHA256SUMS_20260525
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
e6e321ad419e32ce43427bba05a02a23133f05500a3486f98c5de232830c1844 ./README.md
|
| 2 |
+
5c2140f0d646a2f5eaf7ea07c033fade7e28b37468eeb8595f61f6044f6cf109 ./SHA256SUMS
|
| 3 |
+
f6742a090b39f1f576d18481bb1e284720275b0ab417393f219650821e83a72a ./experiments/02_1_7_intrinsic_eval_sweep_20260518/CHOSEN_CUTOFF.md
|
| 4 |
+
3d68bbd6e6c9e25df597f46819cbe57e336b62b8a9b5b441aadeae5346e70eb7 ./experiments/02_1_7_intrinsic_eval_sweep_20260518/README.md
|
| 5 |
+
9b350211cf4f0bd964feec9504a093c1062425fb12f22534a947112f357e5c25 ./experiments/02_1_7_intrinsic_eval_sweep_20260518/REPORT.md
|
| 6 |
+
60a57f77e13d8204c7728e6e5a117cb947c156c97e2c57db7de587965ada58bf ./experiments/02_1_7_intrinsic_eval_sweep_20260518/artifacts/morphscore_greek_results.json
|
| 7 |
+
7dd2ae959af9504d522cf4b606c573e6cefdd71c009fe8a7269eb051382351f0 ./experiments/02_1_7_intrinsic_eval_sweep_20260518/artifacts/our_suite_raw_gcloud/curated_metrics_by_slice.csv
|
| 8 |
+
76ad56410ada9ef2d7649d3babb757287993982e03fc98057e7289ec837c990c ./experiments/02_1_7_intrinsic_eval_sweep_20260518/artifacts/our_suite_raw_gcloud/extended_metrics_by_slice.csv
|
| 9 |
+
190c58ce62f8878c92499ef7da9bceb26f27a1b5f25927e6681d80df59359c79 ./experiments/02_1_7_intrinsic_eval_sweep_20260518/artifacts/our_suite_raw_gcloud/metrics_by_slice.csv
|
| 10 |
+
f823dcc20f7cc2d7435fda6c5c09e65d704de10d37330f9ed930fdcf7f75506b ./experiments/02_1_7_intrinsic_eval_sweep_20260518/artifacts/our_suite_raw_gcloud/padded_17408_metrics.csv
|
| 11 |
+
9e94927189811f9c5df2e6f75c3e4ffc4738d4305a35eef2b8499c6bf15c5acf ./experiments/02_1_7_intrinsic_eval_sweep_20260518/artifacts/our_suite_raw_gcloud/summary.json
|
| 12 |
+
7bbfd6c76cc88190a2334ab45af03f77e8389830e46e8dcc4ef896f7e2e3b8fc ./experiments/02_1_7_intrinsic_eval_sweep_20260518/artifacts/plots/extended_4metric_to_25k.png
|
| 13 |
+
0f472db11e1f6809b2369727de9d78e224d1c5916701141eae0c5207149d0681 ./experiments/02_1_7_intrinsic_eval_sweep_20260518/artifacts/plots/fertility_per_in_domain_slice.png
|
| 14 |
+
7b90ed2c76344942c48fbb445386e16fde9e0a9af0fdbd03e96054aee1ec38d3 ./experiments/02_1_7_intrinsic_eval_sweep_20260518/artifacts/plots/headline_4metric_in_domain.png
|
| 15 |
+
f72541da46b7539acca2c0fc9d641d751f0461528598e9d82651e3722681c226 ./experiments/02_1_7_intrinsic_eval_sweep_20260518/artifacts/plots/knee_analysis.png
|
| 16 |
+
4f0148ff0c94a8b67e329517ab260963daa027c0ab64ac992cffe4e95c073665 ./experiments/02_1_7_intrinsic_eval_sweep_20260518/artifacts/plots/morphscore_greek.png
|
| 17 |
+
763f330459d536e1ca7832dddc755e7d5f43c69605f8f8ca6c688f24c7cdf895 ./experiments/02_1_7_intrinsic_eval_sweep_20260518/manifests/curated_padded_at_17408_manifest.json
|
| 18 |
+
7874469554d319addc7f113e6b5d4b7f8984e3bd4db9b3dcaa3e4e476cf392f0 ./experiments/02_1_7_intrinsic_eval_sweep_20260518/manifests/removal_mask_at_17408.jsonl
|
| 19 |
+
0b3c2f295d1f14c9409b39ca2e6fc98346037a7d11a7cd931b59fcff7824b2e9 ./experiments/02_1_7_intrinsic_eval_sweep_20260518/manifests/tokeval_commit.txt
|
| 20 |
+
7147abc0dd32b702a399e02f47cea5576594ee6ec0d089a4e1fb6d822797aad3 ./tokenizers/c3_added_17408_curated_padded/README.md
|
| 21 |
+
358c249e2fb29060c6b73157d428853b0c48710deffc8ee670ab1013880946c9 ./tokenizers/c3_added_17408_curated_padded/special_tokens_map.json
|
| 22 |
+
358ae3f29ac17c99769d6d437339e28657d5fcaed3486f8550feed3d6adfc394 ./tokenizers/c3_added_17408_curated_padded/tokenizer.json
|
| 23 |
+
737b93393573376f6b4707ebfbb17688d0c358cba0daa3be12b4f9f57f9cb2ae ./tokenizers/c3_added_17408_curated_padded/tokenizer_config.json
|
checkpoints/baselines/retok-3p5b-iter834/README.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# ReTok Baseline, 3.5B Iter 834
|
| 2 |
+
|
| 3 |
+
Status: hydration pointer.
|
| 4 |
+
|
| 5 |
+
Clariden checkpoint:
|
| 6 |
+
|
| 7 |
+
```text
|
| 8 |
+
/capstor/scratch/cscs/fffoivos/runs/bakeoff/continuation_3p5b_20260524T143012Z_retok/checkpoints/iter_0000834
|
| 9 |
+
```
|
| 10 |
+
|
| 11 |
+
This is the ReTok baseline for the modern-only 148480-vocab tokenizer.
|
| 12 |
+
|
checkpoints/baselines/retok-3p5b-iter834/hydration.md
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Hydration
|
| 2 |
+
|
| 3 |
+
On Clariden:
|
| 4 |
+
|
| 5 |
+
```bash
|
| 6 |
+
ls -lh /capstor/scratch/cscs/fffoivos/runs/bakeoff/continuation_3p5b_20260524T143012Z_retok/checkpoints/iter_0000834
|
| 7 |
+
```
|
| 8 |
+
|
checkpoints/baselines/retok-3p5b-iter834/manifest.json
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"artifact_id": "checkpoint.baseline-retok-3p5b-iter834",
|
| 3 |
+
"status": "hydration-pointer",
|
| 4 |
+
"tokenizer": "tokenizer.modern-greek-17408",
|
| 5 |
+
"source_checkpoint": "/capstor/scratch/cscs/fffoivos/runs/bakeoff/continuation_3p5b_20260524T143012Z_retok/checkpoints/iter_0000834",
|
| 6 |
+
"iteration": 834
|
| 7 |
+
}
|
| 8 |
+
|
checkpoints/baselines/vanilla-3p5b-iter834/README.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Vanilla Baseline, 3.5B Iter 834
|
| 2 |
+
|
| 3 |
+
Status: hydration pointer.
|
| 4 |
+
|
| 5 |
+
Clariden checkpoint:
|
| 6 |
+
|
| 7 |
+
```text
|
| 8 |
+
/capstor/scratch/cscs/fffoivos/runs/bakeoff/continuation_3p5b_20260524T143012Z_vanilla/checkpoints/iter_0000834
|
| 9 |
+
```
|
| 10 |
+
|
| 11 |
+
This baseline keeps the original Apertus tokenizer and remains the heldout-BPC
|
| 12 |
+
reference in the 3.5B continuation.
|
| 13 |
+
|
checkpoints/baselines/vanilla-3p5b-iter834/hydration.md
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Hydration
|
| 2 |
+
|
| 3 |
+
On Clariden:
|
| 4 |
+
|
| 5 |
+
```bash
|
| 6 |
+
ls -lh /capstor/scratch/cscs/fffoivos/runs/bakeoff/continuation_3p5b_20260524T143012Z_vanilla/checkpoints/iter_0000834
|
| 7 |
+
```
|
| 8 |
+
|
checkpoints/baselines/vanilla-3p5b-iter834/manifest.json
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"artifact_id": "checkpoint.baseline-vanilla-3p5b-iter834",
|
| 3 |
+
"status": "hydration-pointer",
|
| 4 |
+
"tokenizer": "swiss-ai/Apertus-8B-2509 base tokenizer",
|
| 5 |
+
"source_checkpoint": "/capstor/scratch/cscs/fffoivos/runs/bakeoff/continuation_3p5b_20260524T143012Z_vanilla/checkpoints/iter_0000834",
|
| 6 |
+
"iteration": 834
|
| 7 |
+
}
|
| 8 |
+
|
checkpoints/td-layer11-cpt-3p5b-iter834/README.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# TD Layer 11 CPT Checkpoint, 3.5B Iter 834
|
| 2 |
+
|
| 3 |
+
Status: hydration pointer.
|
| 4 |
+
|
| 5 |
+
This is the leading extended-tokenizer checkpoint after the 3.5B continuation.
|
| 6 |
+
|
| 7 |
+
Clariden checkpoint:
|
| 8 |
+
|
| 9 |
+
```text
|
| 10 |
+
/capstor/scratch/cscs/fffoivos/runs/bakeoff/continuation_3p5b_20260524T143012Z_td_layer11/checkpoints/iter_0000834
|
| 11 |
+
```
|
| 12 |
+
|
| 13 |
+
HF-format eval copy:
|
| 14 |
+
|
| 15 |
+
```text
|
| 16 |
+
/capstor/scratch/cscs/fffoivos/runs/eval/continuation_3p5b_20260524T143012Z_td_layer11/iter_0000834_hf
|
| 17 |
+
```
|
| 18 |
+
|
| 19 |
+
Tokenizer:
|
| 20 |
+
|
| 21 |
+
```text
|
| 22 |
+
../../tokenizer/modern-greek-17408/
|
| 23 |
+
```
|
| 24 |
+
|
| 25 |
+
Result summary:
|
| 26 |
+
|
| 27 |
+
```text
|
| 28 |
+
../../results/SUMMARY.md
|
| 29 |
+
```
|
| 30 |
+
|
checkpoints/td-layer11-cpt-3p5b-iter834/hydration.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Hydration
|
| 2 |
+
|
| 3 |
+
This release entry is a pointer, not a checkpoint payload.
|
| 4 |
+
|
| 5 |
+
On Clariden, use:
|
| 6 |
+
|
| 7 |
+
```bash
|
| 8 |
+
ls -lh /capstor/scratch/cscs/fffoivos/runs/bakeoff/continuation_3p5b_20260524T143012Z_td_layer11/checkpoints/iter_0000834
|
| 9 |
+
ls -lh /capstor/scratch/cscs/fffoivos/runs/eval/continuation_3p5b_20260524T143012Z_td_layer11/iter_0000834_hf
|
| 10 |
+
```
|
| 11 |
+
|
| 12 |
+
Before publishing this as loadable HF weights, verify the HF eval copy contains
|
| 13 |
+
the expected config, tokenizer, and safetensor shards, then upload only that
|
| 14 |
+
inference-ready payload.
|
| 15 |
+
|
checkpoints/td-layer11-cpt-3p5b-iter834/manifest.json
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"artifact_id": "checkpoint.td-layer11-cpt-3p5b-iter834",
|
| 3 |
+
"status": "hydration-pointer",
|
| 4 |
+
"tokenizer": "tokenizer.modern-greek-17408",
|
| 5 |
+
"source_checkpoint": "/capstor/scratch/cscs/fffoivos/runs/bakeoff/continuation_3p5b_20260524T143012Z_td_layer11/checkpoints/iter_0000834",
|
| 6 |
+
"hf_eval_copy": "/capstor/scratch/cscs/fffoivos/runs/eval/continuation_3p5b_20260524T143012Z_td_layer11/iter_0000834_hf",
|
| 7 |
+
"training_stage": "3.5B continuation",
|
| 8 |
+
"iteration": 834,
|
| 9 |
+
"source_code": "https://github.com/fffoivos/glossapi-tokenizer-extension/tree/main/subprojects/03_apertus_extension_and_embedding_adaptation"
|
| 10 |
+
}
|
| 11 |
+
|
checkpoints/td-layer11-init-r17-tp2/README.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# TD Layer 11 Init, R17-Patched TP=2
|
| 2 |
+
|
| 3 |
+
Status: hydration pointer.
|
| 4 |
+
|
| 5 |
+
Clariden checkpoint:
|
| 6 |
+
|
| 7 |
+
```text
|
| 8 |
+
/iopsstor/scratch/cscs/fffoivos/token_distillation/td_full25_layer11_r17_roundtrip_2357565/megatron_tp2_r17patched/release
|
| 9 |
+
```
|
| 10 |
+
|
| 11 |
+
This is the Token Distillation layer-11 initialization in Megatron TP=2 format,
|
| 12 |
+
after the R17/xIELU/QK-Norm preservation patch and roundtrip verification.
|
| 13 |
+
|
checkpoints/td-layer11-init-r17-tp2/hydration.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Hydration
|
| 2 |
+
|
| 3 |
+
On Clariden:
|
| 4 |
+
|
| 5 |
+
```bash
|
| 6 |
+
ls -lh /iopsstor/scratch/cscs/fffoivos/token_distillation/td_full25_layer11_r17_roundtrip_2357565/megatron_tp2_r17patched/release
|
| 7 |
+
```
|
| 8 |
+
|
| 9 |
+
Verification evidence:
|
| 10 |
+
|
| 11 |
+
```text
|
| 12 |
+
../../provenance/conversion-roundtrip/td_layer11_r17_roundtrip_verification.json
|
| 13 |
+
```
|
| 14 |
+
|
checkpoints/td-layer11-init-r17-tp2/manifest.json
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"artifact_id": "checkpoint.td-layer11-init-r17-tp2",
|
| 3 |
+
"status": "hydration-pointer",
|
| 4 |
+
"tokenizer": "tokenizer.modern-greek-17408",
|
| 5 |
+
"source_checkpoint": "/iopsstor/scratch/cscs/fffoivos/token_distillation/td_full25_layer11_r17_roundtrip_2357565/megatron_tp2_r17patched/release",
|
| 6 |
+
"format": "Megatron torch_dist TP=2, R17 patched",
|
| 7 |
+
"verification": "../../provenance/conversion-roundtrip/td_layer11_r17_roundtrip_verification.json"
|
| 8 |
+
}
|
| 9 |
+
|
code-links/README.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Source Code Links
|
| 2 |
+
|
| 3 |
+
The runnable implementation lives in GitHub:
|
| 4 |
+
|
| 5 |
+
```text
|
| 6 |
+
https://github.com/fffoivos/glossapi-tokenizer-extension/tree/main/subprojects/03_apertus_extension_and_embedding_adaptation
|
| 7 |
+
```
|
| 8 |
+
|
| 9 |
+
This Hugging Face release keeps artifact payloads, manifests, compact evidence,
|
| 10 |
+
and hydration instructions. It does not mirror the full scripts tree.
|
| 11 |
+
|
| 12 |
+
See:
|
| 13 |
+
|
| 14 |
+
```text
|
| 15 |
+
github_subproject_manifest.json
|
| 16 |
+
```
|
| 17 |
+
|
code-links/github_subproject_manifest.json
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"repo": "https://github.com/fffoivos/glossapi-tokenizer-extension",
|
| 3 |
+
"branch": "main",
|
| 4 |
+
"source_commit": "7c67cf11eb3d31f0ddd006f7d709709037db93a1",
|
| 5 |
+
"subproject": "subprojects/03_apertus_extension_and_embedding_adaptation",
|
| 6 |
+
"script_families": [
|
| 7 |
+
{
|
| 8 |
+
"family": "tokenizer_shipping",
|
| 9 |
+
"paths": [
|
| 10 |
+
"03_3_cscs_experiments_kickoff/ship/apertus_greek_modern_only_148480",
|
| 11 |
+
"03_3_cscs_experiments_kickoff/ship/apertus_greek_extended_153600"
|
| 12 |
+
],
|
| 13 |
+
"artifacts": [
|
| 14 |
+
"tokenizer.modern-greek-17408",
|
| 15 |
+
"tokenizer.polytonic-plus-5120"
|
| 16 |
+
]
|
| 17 |
+
},
|
| 18 |
+
{
|
| 19 |
+
"family": "corpus_build",
|
| 20 |
+
"paths": [
|
| 21 |
+
"03_2_apertus_c3_dedup_audit/CPT_DATASET_BUILD_RUNBOOK.md",
|
| 22 |
+
"03_4_implementation_experiments/init_bakeoff/corpus_build"
|
| 23 |
+
],
|
| 24 |
+
"artifacts": [
|
| 25 |
+
"dataset.cpt-7b-mix"
|
| 26 |
+
]
|
| 27 |
+
},
|
| 28 |
+
{
|
| 29 |
+
"family": "init_and_conversion",
|
| 30 |
+
"paths": [
|
| 31 |
+
"03_4_implementation_experiments/init_bakeoff/arms",
|
| 32 |
+
"03_4_implementation_experiments/init_bakeoff/megatron_patches"
|
| 33 |
+
],
|
| 34 |
+
"artifacts": [
|
| 35 |
+
"checkpoint.td-layer11-init-r17-tp2",
|
| 36 |
+
"checkpoint.baseline-vanilla-3p5b-iter834",
|
| 37 |
+
"checkpoint.baseline-retok-3p5b-iter834"
|
| 38 |
+
]
|
| 39 |
+
},
|
| 40 |
+
{
|
| 41 |
+
"family": "token_distillation",
|
| 42 |
+
"paths": [
|
| 43 |
+
"TOKEN_DISTILLATION_PLAN.md",
|
| 44 |
+
"03_4_implementation_experiments/init_bakeoff/token_distillation"
|
| 45 |
+
],
|
| 46 |
+
"artifacts": [
|
| 47 |
+
"checkpoint.td-layer11-init-r17-tp2"
|
| 48 |
+
]
|
| 49 |
+
},
|
| 50 |
+
{
|
| 51 |
+
"family": "training",
|
| 52 |
+
"paths": [
|
| 53 |
+
"TRAINING_RECIPE.md",
|
| 54 |
+
"03_4_implementation_experiments/init_bakeoff/bakeoff_training"
|
| 55 |
+
],
|
| 56 |
+
"artifacts": [
|
| 57 |
+
"checkpoint.td-layer11-cpt-3p5b-iter834",
|
| 58 |
+
"checkpoint.baseline-vanilla-3p5b-iter834",
|
| 59 |
+
"checkpoint.baseline-retok-3p5b-iter834"
|
| 60 |
+
]
|
| 61 |
+
},
|
| 62 |
+
{
|
| 63 |
+
"family": "evaluation",
|
| 64 |
+
"paths": [
|
| 65 |
+
"03_4_implementation_experiments/init_bakeoff/eval"
|
| 66 |
+
],
|
| 67 |
+
"artifacts": [
|
| 68 |
+
"results.continuation-3p5b"
|
| 69 |
+
]
|
| 70 |
+
}
|
| 71 |
+
]
|
| 72 |
+
}
|
| 73 |
+
|
provenance/conversion-roundtrip/td_layer11_r17_roundtrip_verification.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"orig_only": [],
|
| 3 |
+
"trip_only": [],
|
| 4 |
+
"standard_max_abs_diff": 0.0,
|
| 5 |
+
"r17_max_abs_diff": 0.0,
|
| 6 |
+
"xielu_max_abs_diff": 0.0,
|
| 7 |
+
"qk_norm_max_abs_diff": 0.0,
|
| 8 |
+
"standard_changed_over_tol": [],
|
| 9 |
+
"r17_changed_over_tol": [],
|
| 10 |
+
"shape_mismatches": [],
|
| 11 |
+
"standard_changed_over_tol_count": 0,
|
| 12 |
+
"r17_changed_over_tol_count": 0,
|
| 13 |
+
"logits": {
|
| 14 |
+
"logit_max_abs_diff": 0.0,
|
| 15 |
+
"logit_mean_abs_diff_max": 0.0,
|
| 16 |
+
"per_prompt": [
|
| 17 |
+
{
|
| 18 |
+
"prompt": "Η Αθήνα είναι η πρωτεύουσα της",
|
| 19 |
+
"max_abs": 0.0,
|
| 20 |
+
"mean_abs": 0.0,
|
| 21 |
+
"reference_top_id": 72499,
|
| 22 |
+
"roundtrip_top_id": 72499,
|
| 23 |
+
"top_id_match": true
|
| 24 |
+
},
|
| 25 |
+
{
|
| 26 |
+
"prompt": "Ο Όμηρος έγραψε",
|
| 27 |
+
"max_abs": 0.0,
|
| 28 |
+
"mean_abs": 0.0,
|
| 29 |
+
"reference_top_id": 132093,
|
| 30 |
+
"roundtrip_top_id": 132093,
|
| 31 |
+
"top_id_match": true
|
| 32 |
+
},
|
| 33 |
+
{
|
| 34 |
+
"prompt": "The capital of Greece is",
|
| 35 |
+
"max_abs": 0.0,
|
| 36 |
+
"mean_abs": 0.0,
|
| 37 |
+
"reference_top_id": 132048,
|
| 38 |
+
"roundtrip_top_id": 132048,
|
| 39 |
+
"top_id_match": true
|
| 40 |
+
}
|
| 41 |
+
]
|
| 42 |
+
}
|
| 43 |
+
}
|
provenance/conversion-roundtrip/vanilla_r17_roundtrip_verification.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"orig_only": [],
|
| 3 |
+
"trip_only": [],
|
| 4 |
+
"standard_max_abs_diff": 0.0,
|
| 5 |
+
"r17_max_abs_diff": 0.0,
|
| 6 |
+
"xielu_max_abs_diff": 0.0,
|
| 7 |
+
"qk_norm_max_abs_diff": 0.0,
|
| 8 |
+
"standard_changed_over_tol": [],
|
| 9 |
+
"r17_changed_over_tol": [],
|
| 10 |
+
"shape_mismatches": [],
|
| 11 |
+
"standard_changed_over_tol_count": 0,
|
| 12 |
+
"r17_changed_over_tol_count": 0,
|
| 13 |
+
"logits": {
|
| 14 |
+
"logit_max_abs_diff": 0.0,
|
| 15 |
+
"logit_mean_abs_diff_max": 0.0,
|
| 16 |
+
"per_prompt": [
|
| 17 |
+
{
|
| 18 |
+
"prompt": "Η Αθήνα είναι η πρωτεύουσα της",
|
| 19 |
+
"max_abs": 0.0,
|
| 20 |
+
"mean_abs": 0.0,
|
| 21 |
+
"reference_top_id": 72499,
|
| 22 |
+
"roundtrip_top_id": 72499,
|
| 23 |
+
"top_id_match": true
|
| 24 |
+
},
|
| 25 |
+
{
|
| 26 |
+
"prompt": "Ο Όμηρος έγραψε",
|
| 27 |
+
"max_abs": 0.0,
|
| 28 |
+
"mean_abs": 0.0,
|
| 29 |
+
"reference_top_id": 8329,
|
| 30 |
+
"roundtrip_top_id": 8329,
|
| 31 |
+
"top_id_match": true
|
| 32 |
+
},
|
| 33 |
+
{
|
| 34 |
+
"prompt": "The capital of Greece is",
|
| 35 |
+
"max_abs": 0.0,
|
| 36 |
+
"mean_abs": 0.0,
|
| 37 |
+
"reference_top_id": 48214,
|
| 38 |
+
"roundtrip_top_id": 48214,
|
| 39 |
+
"top_id_match": true
|
| 40 |
+
}
|
| 41 |
+
]
|
| 42 |
+
}
|
| 43 |
+
}
|
provenance/dataset-build/CPT_DATASET_BUILD_RUNBOOK.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# CPT Dataset Build Runbook
|
| 2 |
+
|
| 3 |
+
This is the repeatable path for building an Apertus CPT dataset from the
|
| 4 |
+
published nanochat corpus.
|
| 5 |
+
|
| 6 |
+
## Inputs
|
| 7 |
+
|
| 8 |
+
- Source corpus:
|
| 9 |
+
`fffoivos/glossapi-greek-nanochat-pretraining-dataset`
|
| 10 |
+
- Nanochat internal dedup bundle:
|
| 11 |
+
`dedup_metadata/wave2_20260426_builder_metadata_v2_latest_cleaner_20260507/builder_metadata`
|
| 12 |
+
- Apertus hard-drop overlay:
|
| 13 |
+
`fffoivos/apertus-c3-dedup-audit-dedup-20260519t010924z`
|
| 14 |
+
at `artifacts/dedup_20260519T010924Z/cpt_final_overlay/apertus_overlap_drop_docs.parquet`
|
| 15 |
+
|
| 16 |
+
The correct order is:
|
| 17 |
+
|
| 18 |
+
1. Download the published nanochat source rows.
|
| 19 |
+
2. Hard-exclude `apertus_overlap_drop_docs.parquet`.
|
| 20 |
+
3. Replay nanochat internal dedup with `drop_intra_and_inter`.
|
| 21 |
+
4. Build the final CPT mix/export from the remaining pool.
|
| 22 |
+
|
| 23 |
+
The order matters: if Apertus-overlapping docs are removed first, an internal
|
| 24 |
+
duplicate family can still keep a fresh alternate representative.
|
| 25 |
+
|
| 26 |
+
## GCP Scratch VM
|
| 27 |
+
|
| 28 |
+
Use a scratch VM with a large disk. A practical starting point is a
|
| 29 |
+
`c4-highmem-32` or larger VM with a 1-2 TB SSD/PD disk. Build artifacts should
|
| 30 |
+
be uploaded to Hugging Face or GCS before teardown.
|
| 31 |
+
|
| 32 |
+
Example setup on the VM:
|
| 33 |
+
|
| 34 |
+
```bash
|
| 35 |
+
sudo apt-get update
|
| 36 |
+
sudo apt-get install -y git python3-pip
|
| 37 |
+
python3 -m pip install --user duckdb pandas pyarrow huggingface_hub typer blake3 polars
|
| 38 |
+
|
| 39 |
+
git clone https://github.com/<your-org-or-user>/glossapi-tokenizer-extension.git
|
| 40 |
+
cd glossapi-tokenizer-extension
|
| 41 |
+
export PYTHONPATH="$PWD"
|
| 42 |
+
```
|
| 43 |
+
|
| 44 |
+
## Download Inputs
|
| 45 |
+
|
| 46 |
+
Do not build from the old local `/home/foivos/data/glossapi_work/hf_release_publish`
|
| 47 |
+
copy. Hydrate from the live HF repo so the `source_dataset` names and derived
|
| 48 |
+
`doc_key` values match the Apertus overlay and the `wave2` dedup bundle.
|
| 49 |
+
|
| 50 |
+
```bash
|
| 51 |
+
export WORK=/mnt/disks/cpt_build
|
| 52 |
+
mkdir -p "$WORK"
|
| 53 |
+
|
| 54 |
+
huggingface-cli download fffoivos/glossapi-greek-nanochat-pretraining-dataset \
|
| 55 |
+
--repo-type dataset \
|
| 56 |
+
--local-dir "$WORK/nanochat" \
|
| 57 |
+
--include 'data/*.parquet' \
|
| 58 |
+
--include 'dedup_metadata/latest.json' \
|
| 59 |
+
--include 'dedup_metadata/wave2_20260426_builder_metadata_v2_latest_cleaner_20260507/builder_metadata/*'
|
| 60 |
+
|
| 61 |
+
huggingface-cli download fffoivos/apertus-c3-dedup-audit-dedup-20260519t010924z \
|
| 62 |
+
--repo-type dataset \
|
| 63 |
+
--local-dir "$WORK/apertus_audit" \
|
| 64 |
+
--include 'artifacts/dedup_20260519T010924Z/cpt_final_overlay/*'
|
| 65 |
+
```
|
| 66 |
+
|
| 67 |
+
## Build Fresh Deduped Pool
|
| 68 |
+
|
| 69 |
+
```bash
|
| 70 |
+
export DEDUP_ROOT="$WORK/nanochat/dedup_metadata/wave2_20260426_builder_metadata_v2_latest_cleaner_20260507/builder_metadata"
|
| 71 |
+
export APERTUS_DROP="$WORK/apertus_audit/artifacts/dedup_20260519T010924Z/cpt_final_overlay/apertus_overlap_drop_docs.parquet"
|
| 72 |
+
export SELECTED="$WORK/cpt/selected_after_apertus_and_internal_dedup.parquet"
|
| 73 |
+
|
| 74 |
+
python3 -m glossapi_corpus_cli.cli mix-prepare-selected-input \
|
| 75 |
+
--output-root "$WORK/nanochat" \
|
| 76 |
+
--selected-input-path "$SELECTED" \
|
| 77 |
+
--exclude-doc-keys-path "$APERTUS_DROP" \
|
| 78 |
+
--dedup-metadata-root "$DEDUP_ROOT" \
|
| 79 |
+
--dedup-action drop_intra_and_inter \
|
| 80 |
+
--dedup-exact-stage strict_and_relaxed \
|
| 81 |
+
--dedup-similarity-threshold 0.85 \
|
| 82 |
+
--dedup-inter-dataset-policy share_aware
|
| 83 |
+
```
|
| 84 |
+
|
| 85 |
+
`$SELECTED` is the deduplicated, Apertus-fresh source pool. If the CPT recipe
|
| 86 |
+
uses the whole remaining pool, this is the main dataset artifact.
|
| 87 |
+
|
| 88 |
+
## Optional Source Mix
|
| 89 |
+
|
| 90 |
+
If the CPT run needs a sampled or weighted mix, build it from `$SELECTED`:
|
| 91 |
+
|
| 92 |
+
```bash
|
| 93 |
+
python3 -m glossapi_corpus_cli.cli mix-build-from-selected-input \
|
| 94 |
+
--selected-input-path "$SELECTED" \
|
| 95 |
+
--mix-output-path "$WORK/cpt/final_cpt_mix.parquet" \
|
| 96 |
+
--source-mix-config-path "$WORK/cpt/source_mix.json"
|
| 97 |
+
```
|
| 98 |
+
|
| 99 |
+
## Publish And Teardown
|
| 100 |
+
|
| 101 |
+
Upload the final selected pool or mix before deleting the VM:
|
| 102 |
+
|
| 103 |
+
```bash
|
| 104 |
+
huggingface-cli upload <target-hf-dataset-repo> "$WORK/cpt" . --repo-type dataset
|
| 105 |
+
```
|
| 106 |
+
|
| 107 |
+
Then verify the HF repo contains the final parquet(s), summaries, and the
|
| 108 |
+
`cpt_final_overlay/summary.json` provenance before tearing down the VM.
|
provenance/dataset-build/MIX_RECIPE.md
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Mix recipes — bulk and anneal
|
| 2 |
+
|
| 3 |
+
The bakeoff (and future production CPT) consumes a stream of documents
|
| 4 |
+
interleaved from several sources with explicit per-source weights. Per
|
| 5 |
+
[`../../cpt_plan.md`](../../cpt_plan.md) v0.7 §2 + §4:
|
| 6 |
+
|
| 7 |
+
- **Bulk phase**: one shuffled-mixture stream, all corpora at target weights from token 0. This is what the bakeoff actually trains on.
|
| 8 |
+
- **Anneal phase**: final 10–20 % of *production* training (out of scope for the bakeoff). Mixture shifts to highest-priority subsets; replay drops from ~30 % → ~15 %; LR decays. We define the recipe here for completeness; the bakeoff never executes it.
|
| 9 |
+
|
| 10 |
+
Both recipes are JSON, in `recipes/`. The mix builder (`mix_builder.py`) reads either and emits a JSON-lines stream.
|
| 11 |
+
|
| 12 |
+
## Three-step build path (reviewer round-2 Blocker 3 fix)
|
| 13 |
+
|
| 14 |
+
The CPT dataset build follows the canonical runbook at [`../../../03_2_apertus_c3_dedup_audit/CPT_DATASET_BUILD_RUNBOOK.md`](../../../03_2_apertus_c3_dedup_audit/CPT_DATASET_BUILD_RUNBOOK.md). **Order matters**: if Apertus-overlapping docs are removed first, an internal-duplicate family can still keep a fresh alternate representative.
|
| 15 |
+
|
| 16 |
+
```
|
| 17 |
+
1. bash pull_greek_corpus.sh # nanochat parquets + dedup_metadata + Apertus overlay
|
| 18 |
+
2. bash prepare_greek_pool.sh # → $SELECTED parquet (Apertus-drop + drop_intra_and_inter)
|
| 19 |
+
3. SELECTED=$WORK/cpt/selected_after_apertus_and_internal_dedup.parquet \
|
| 20 |
+
python3 mix_builder.py --recipe recipes/bulk.json --target-tokens 7_000_000_000 ...
|
| 21 |
+
```
|
| 22 |
+
|
| 23 |
+
All six Greek `bulk.json` sources point at `local_parquet: ${SELECTED}` — the single post-dedup parquet — and filter by `source_dataset` value to slice into HPLT / literary / dialogue / academic / legal / dictionary buckets. The Apertus-overlap-drop is applied **upstream** in step 2 (not per-source in mix_builder), so it applies uniformly to all six categories rather than only to HPLT (the previous bug). Internal dedup with `drop_intra_and_inter` also happens in step 2 (was missing entirely before).
|
| 24 |
+
|
| 25 |
+
## Composition (bulk recipe — what the bakeoff actually consumes)
|
| 26 |
+
|
| 27 |
+
Working defaults per v0.7 §2 + §4 + user answers 2026-05-20:
|
| 28 |
+
|
| 29 |
+
| Top-level bucket | Share | Sub-allocation |
|
| 30 |
+
|---|---:|---|
|
| 31 |
+
| Greek (post-Apertus-overlap-drop, post-internal-dedup) | **70 %** | see below |
|
| 32 |
+
| Non-Greek replay (24 languages, 3 tiers) | **24 %** | see below |
|
| 33 |
+
| Code | **4 %** | Intended: `bigcode/starcoderdata` / The Stack lineage (Apertus used StarCoder); 2026-05-21 CSCS fallback: `codeparrot/codeparrot-clean-train` |
|
| 34 |
+
| Math | **2 %** | `HuggingFaceTB/finemath` config `finemath-3plus` (Apertus stage-1 source per `submit_apertus_8b.sh:L29`) |
|
| 35 |
+
|
| 36 |
+
> **2026-05-21 rebalance.** Replay reduced from 26 % → 24 % to free 2 % for FineMath, taken entirely from English (FW-Edu) which went from 3.9 % → 1.9 %. The other 23 replay-language weights stay at their pre-rebalance values. Greek and code shares unchanged.
|
| 37 |
+
|
| 38 |
+
> **2026-05-21 CSCS run detail.** The live full-build recipe reads replay and FineMath from staged local single-shard parquets under `/iopsstor/scratch/cscs/fffoivos/cpt_corpus/{replay,math}`. This avoids repeated HF dataset-metadata resolution from seven concurrent shards, which hit HF's API rate limit. The Persian replay bucket uses the local FineWeb-2 `fas_Arab` fallback shard while preserving the recipe label `replay_t2_pes_Arab`.
|
| 39 |
+
|
| 40 |
+
> **OPUS Greek-English parallel** is listed as optional in v0.7 §4.4 but **not yet in the bakeoff bulk mix** — it needs different schema handling in `mix_builder.py` (its rows are `{translation: {el: ..., en: ...}}` rather than `{text: ...}`). Deferred to a future iteration of corpus_build.
|
| 41 |
+
|
| 42 |
+
### Greek sub-allocation (70 % of total)
|
| 43 |
+
|
| 44 |
+
| Source | Share of Greek | HF id / filter |
|
| 45 |
+
|---|---:|---|
|
| 46 |
+
| **HPLT clean60 (fresh; Apertus-overlap overlay applied)** | 50 % of Greek = 35 % total | nanochat dataset, `source_dataset starts with HPLT__ell_Grek` + `apertus_overlap_drop_docs.parquet` exclude |
|
| 47 |
+
| Literary nanochat (artos-zois + Project_Gutenberg + Ekklisiastika + 1000_prwta + klasikh + Wikisource + dimodis_logotexnia + archetai) | 26 % of Greek = 18.2 % total | nanochat dataset, filter `source_dataset` ∈ literary list |
|
| 48 |
+
| Dialogue + textbooks (OPUS OpenSubtitles-el + openbook + Sxolika_vivlia + ert-press + istorima) | 9 % of Greek = 6.3 % total | nanochat dataset, filter |
|
| 49 |
+
| Academic (openarchives.gr + greek_phd + Apothetirio_Kallipos + Apothetirio_Pergamos) | 8 % of Greek = 5.6 % total | nanochat dataset, filter |
|
| 50 |
+
| Legal + civic (eurlex-greek-legislation + AI-team-UoA/greek_legal_code + opengov.gr-diaboyleuseis + ellinika_dedomena_europaikou_koinovouliou) | 5 % of Greek = 3.5 % total | nanochat dataset, filter |
|
| 51 |
+
| Dictionary + misc (modern-greek-dictionary capped + finewiki Greek half-weight + 95k_deigma + others) | 2 % of Greek = 1.4 % total | nanochat dataset, filter; modern-greek-dictionary explicitly capped per Claude-review note in `../../collegues_Apertus_plan.md` |
|
| 52 |
+
|
| 53 |
+
The HPLT half dominates by token mass (the underlying HPLT clean60 slice is ~50 B chars at v0.7 chars/token = ~14 B tokens; the GlossAPI sub-pools combined are smaller). The recipe weights are **probabilities for the interleaver**, which is what affects the per-step mix; effective token shares track these weights up to per-source exhaustion.
|
| 54 |
+
|
| 55 |
+
### Non-Greek replay sub-allocation (24 % of total, across 24 languages)
|
| 56 |
+
|
| 57 |
+
Tier weights per v0.7 §4.2 (40–50 % T1 / 35–45 % T2 / 10–15 % T3); working defaults at the midpoint, scaled to the **24 % outer share** (post-2026-05-21 rebalance: English's share absorbed the 2 % shift to FineMath):
|
| 58 |
+
|
| 59 |
+
| Tier | Languages | Share of replay | Total share |
|
| 60 |
+
|---|---|---:|---:|
|
| 61 |
+
| **T1** (8 langs, FW2-HQ where Apertus used HQ) | eng, fra, deu, ita, spa, rus, arb, cmn | ~46 % | 11.0 % |
|
| 62 |
+
| **T2** (11 langs, FW2 where Apertus used standard) | tur, bul, srp, ron, heb, por, pol, nld, pes, ukr, jpn | ~41 % | 9.88 % |
|
| 63 |
+
| **T3** (5 langs, FW2; small per-lang) | lat, hye, kat, sqi (or als), mkd | ~13 % | 3.12 % |
|
| 64 |
+
|
| 65 |
+
Within each tier, weights are roughly equal *except* English gets ~17 % of T1 (≈ 1.9 % of total, post-rebalance) — still the largest single non-Greek language, but trimmed from 3.9 % to 1.9 % to make room for FineMath at 2 %. The remaining 7 T1 langs each stay at 1.3 % of total.
|
| 66 |
+
|
| 67 |
+
Per-language sources:
|
| 68 |
+
|
| 69 |
+
- T1 (Apertus quality-filtered the 20 high-resource langs at top-10 % per-language XLM-R): **`epfml/FineWeb2-HQ`** with `config_name = <iso639-3>_<script>` (Messmer, Sabolčec, Jaggi 2025, [arXiv:2502.10361](https://arxiv.org/abs/2502.10361); top-10 %, NOT "Score-3" — that's FineWeb-Edu's filter).
|
| 70 |
+
- T2 / T3 (Apertus used unfiltered FW2 for these): **`HuggingFaceFW/fineweb-2`** with `config_name = <iso639-3>_<script>` (v2.0.1 per Apertus tech report footnote 18).
|
| 71 |
+
- English specifically: prefer **`HuggingFaceFW/fineweb-edu`** Score-3 (Penedo et al. [arXiv:2406.17557](https://arxiv.org/abs/2406.17557); matches Apertus stage-5 cooldown). FineWeb2-HQ English is the fallback.
|
| 72 |
+
|
| 73 |
+
> **Reviewer flag**: cpt_plan.md v0.7 §4.2's "24 replay languages" framing (T1+T2+T3 = 8+11+5) is **our internal grouping**, not Apertus's. Apertus's tech report (arXiv:2509.14233 Appendix G, p.88-89) enumerates **20 high-resource languages** that receive quality+toxicity filtering; the other ~4 languages we include (T3: lat/hye/kat/sqi/mkd) are added by us for cultural/regional coverage relevant to Greek. Token-share targets per language are also our derivation, not from Apertus (the tech report only publishes document counts and percentages of FineWeb-2 documents, not training-mixture token shares).
|
| 74 |
+
|
| 75 |
+
### Code (4 %)
|
| 76 |
+
|
| 77 |
+
| Source | HF id |
|
| 78 |
+
|---|---|
|
| 79 |
+
| Intended code replay | `bigcode/starcoderdata` (Apertus's pretraining source) |
|
| 80 |
+
| 2026-05-21 CSCS fallback | `codeparrot/codeparrot-clean-train` |
|
| 81 |
+
|
| 82 |
+
Use the default "all-permissive" subset when StarCoder/The Stack is accessible; no language filter (mixed-language source-code is fine for retention). The 2026-05-21 CSCS run uses `codeparrot/codeparrot-clean-train` because BigCode sources were gated or script-backed under the current auth/runtime. This preserves the intended 4 % code-retention pressure, but it is not an exact StarCoder-source match.
|
| 83 |
+
|
| 84 |
+
### Math (2 %)
|
| 85 |
+
|
| 86 |
+
| Source | HF id + config |
|
| 87 |
+
|---|---|
|
| 88 |
+
| Math (web-derived high-quality math text) | `HuggingFaceTB/finemath` config `finemath-3plus` (Apertus stage-1 source per `submit_apertus_8b.sh:L29`) |
|
| 89 |
+
|
| 90 |
+
FineMath-3plus is the higher-quality subset of FineMath, selected for math content (problem statements, solutions, derivations) from CommonCrawl. Apertus uses `finemath-3plus-merge` in pretraining stage 1; the bakeoff includes it at the same 2 % share Apertus's stage-1 allocates within the broader mix (Apertus stage proportions aren't published per-source — 2 % is a reasonable default).
|
| 91 |
+
|
| 92 |
+
## Composition (anneal recipe — defined but not run in the bakeoff)
|
| 93 |
+
|
| 94 |
+
Per v0.7 §3.2: in the final 10–20 % of production training, mixture shifts to highest-priority subsets and replay drops to ~15 %. Working pattern (between Llama 3 "narrow high-quality" and OLMo Dolmino "broad quality-curated"):
|
| 95 |
+
|
| 96 |
+
| Bucket | Bulk share | Anneal share | Reason |
|
| 97 |
+
|---|---:|---:|---|
|
| 98 |
+
| Greek high-quality literary (artos-zois + Project_Gutenberg + Wikisource + 1000_prwta) | 12 % | **30 %** | clean prose anchor |
|
| 99 |
+
| Greek academic + legal (openarchives + greek_phd + eurlex + greek_legal_code) | 9 % | **22 %** | domain depth |
|
| 100 |
+
| Greek dictionary (modern-greek-dictionary uncapped from anneal start) | 1 % | **15 %** | gap closure (Apertus_plan §"Final mix") |
|
| 101 |
+
| Greek dialogue + textbooks (OpenSubtitles + openbook + Sxolika + ert) | 6 % | **8 %** | maintained but de-emphasized |
|
| 102 |
+
| HPLT broad (kept reduced for register breadth) | 35 % | **10 %** | safety net against narrow-corpus overfit |
|
| 103 |
+
| Non-Greek replay (Tier 1 dominant) | 26 % | **12 %** | reduced per v0.7 §3.2 "30 % → 15 %" pattern; Tier 1 ≥ 70 % within replay during anneal |
|
| 104 |
+
| Code | 4 % | **3 %** | maintained at slightly reduced share |
|
| 105 |
+
|
| 106 |
+
The anneal recipe is `recipes/anneal.json`. It will be used in the production CPT (15–20 B tokens; final 10–20 % = ~2–4 B tokens of anneal) **after** the bakeoff picks an init winner. Not part of the bakeoff.
|
| 107 |
+
|
| 108 |
+
## Builder usage
|
| 109 |
+
|
| 110 |
+
```bash
|
| 111 |
+
# Generate the bakeoff bulk JSON-lines stream after the smoke passes
|
| 112 |
+
sbatch corpus_build/mix_builder_full.sbatch
|
| 113 |
+
|
| 114 |
+
# After shard concatenation, enforce NFC on the final JSONL stream too.
|
| 115 |
+
# This is CPU-only and preserves row order; unchanged rows stay byte-identical.
|
| 116 |
+
sbatch corpus_build/normalize_jsonl_nfc.sbatch
|
| 117 |
+
|
| 118 |
+
# Same shape for the anneal recipe (not run in the bakeoff)
|
| 119 |
+
python3 mix_builder.py \
|
| 120 |
+
--recipe recipes/anneal.json \
|
| 121 |
+
--target-tokens 3_000_000_000 \
|
| 122 |
+
--tokenizer /iopsstor/scratch/cscs/fffoivos/tokenizers/apertus_greek_modern_only_148480 \
|
| 123 |
+
--output /iopsstor/scratch/cscs/fffoivos/cpt_corpus/anneal_mix.jsonl \
|
| 124 |
+
--seed 20260520
|
| 125 |
+
```
|
| 126 |
+
|
| 127 |
+
For sharded full builds, `mix_builder_full.sbatch` passes `--source-shard-index`
|
| 128 |
+
and `--source-shard-count` into `mix_builder.py`. This partitions each source's
|
| 129 |
+
eligible rows across array tasks before token-fair sampling, so the concatenated
|
| 130 |
+
bulk mix is not just seven repeats of the same source prefixes.
|
| 131 |
+
|
| 132 |
+
Output is JSON-lines. Each line is `{"text": "...", "source": "...", "doc_id": "...", "lang": "..."}`. Megatron-LM-Swiss-AI's `tools/preprocess_data.py` then converts JSON-lines → binary indexed dataset (`.bin` + `.idx`) for training.
|
| 133 |
+
|
| 134 |
+
NFC is enforced twice: first on source parquets with `normalize_nfc.sbatch`,
|
| 135 |
+
then on the final JSONL stream with `normalize_jsonl_nfc.sbatch`. The second
|
| 136 |
+
pass caught a small code-replay leak in the live bakeoff mix (`37` non-NFC rows
|
| 137 |
+
out of `5,754,172`) and produced
|
| 138 |
+
`/iopsstor/scratch/cscs/fffoivos/cpt_corpus/bulk_mix.nfc.jsonl` with manifest
|
| 139 |
+
`bulk_mix.nfc.manifest.json`.
|
| 140 |
+
|
| 141 |
+
Production-safe Vanilla/base-tokenizer binary, built from the NFC stream:
|
| 142 |
+
|
| 143 |
+
- prefix:
|
| 144 |
+
`/iopsstor/scratch/cscs/fffoivos/cpt_corpus/bulk_mix_base_nfc_megatron/bulk_mix_text_document`
|
| 145 |
+
- job: `2367579` on `xfer`, `COMPLETED`, `0:0`, elapsed `00:16:07`
|
| 146 |
+
- rows/sequences: `5,754,172`
|
| 147 |
+
- base-tokenized tokens: `9,831,704,774`
|
| 148 |
+
- local evidence:
|
| 149 |
+
`production_base_nfc_preprocess_2367579/`
|
| 150 |
+
|
| 151 |
+
The older bakeoff base/ext binaries were built before this NFC cleanup. The
|
| 152 |
+
NFC delta is tiny and does not change the bakeoff decision, but production
|
| 153 |
+
Vanilla CPT should use the `bulk_mix_base_nfc_megatron` prefix above.
|
| 154 |
+
|
| 155 |
+
Determinism: the `--seed` controls the interleave randomization. Same seed means the same JSONL text stream across runs. Vanilla and the extended arms then use different tokenizers/preprocessed Megatron binaries, so token IDs differ across tokenizer families even though the document order is shared.
|
| 156 |
+
|
| 157 |
+
## Why two stages (build JSONL → preprocess to .bin/.idx)
|
| 158 |
+
|
| 159 |
+
Megatron's training reads its native binary format; converting on the fly during interleaving is awkward. Splitting the pipeline:
|
| 160 |
+
|
| 161 |
+
1. `mix_builder.py` does the streaming interleave + budget-cap + writes JSONL (CPU job on `xfer`; do not use `normal` for CPU-only work because it allocates GPU nodes on Clariden).
|
| 162 |
+
2. `normalize_jsonl_nfc.py` enforces NFC on the final JSONL stream (CPU job on `xfer`).
|
| 163 |
+
3. `tools/preprocess_data.py` (Megatron) does the tokenization + binary packing (CPU job on `xfer`).
|
| 164 |
+
4. Training reads the binary on `normal`.
|
| 165 |
+
|
| 166 |
+
This way each stage has a single clear job, and we can re-run any stage independently.
|
| 167 |
+
|
| 168 |
+
On current `xfer` nodes, `uenv`/torch are not visible, so Megatron's stock
|
| 169 |
+
`tools/preprocess_data.py` may not be runnable there. For the production Vanilla
|
| 170 |
+
NFC build, `preprocess_hf_jsonl_to_megatron.py` was used instead. It avoids
|
| 171 |
+
torch, writes the same Megatron indexed-dataset format, and was validated
|
| 172 |
+
byte-for-byte against the stock Megatron output on the first `1000` rows before
|
| 173 |
+
the full job was launched.
|
provenance/dataset-build/bulk_mix_text_document.manifest.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"input": "/iopsstor/scratch/cscs/fffoivos/cpt_corpus/bulk_mix.nfc.jsonl",
|
| 3 |
+
"output_prefix": "/iopsstor/scratch/cscs/fffoivos/cpt_corpus/bulk_mix_base_nfc_megatron/bulk_mix_text_document",
|
| 4 |
+
"bin": "/iopsstor/scratch/cscs/fffoivos/cpt_corpus/bulk_mix_base_nfc_megatron/bulk_mix_text_document.bin",
|
| 5 |
+
"idx": "/iopsstor/scratch/cscs/fffoivos/cpt_corpus/bulk_mix_base_nfc_megatron/bulk_mix_text_document.idx",
|
| 6 |
+
"tokenizer_model": "/iopsstor/scratch/cscs/fffoivos/models/apertus-8b-2509",
|
| 7 |
+
"json_key": "text",
|
| 8 |
+
"append_eod": true,
|
| 9 |
+
"workers": 64,
|
| 10 |
+
"chunk_size": 64,
|
| 11 |
+
"limit": 0,
|
| 12 |
+
"rows": 5754172,
|
| 13 |
+
"sequences": 5754172,
|
| 14 |
+
"documents": 5754173,
|
| 15 |
+
"tokens": 9831704774,
|
| 16 |
+
"bytes_read": 27125565083,
|
| 17 |
+
"wall_seconds": 960.677738904953,
|
| 18 |
+
"format": "Megatron indexed dataset v1, int32 document-level"
|
| 19 |
+
}
|
provenance/evals/CONTINUATION_3P5B_RESULTS_20260525.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 3.5B continuation results - Vanilla vs ReTok vs TD layer11
|
| 2 |
+
|
| 3 |
+
Generated UTC: `2026-05-25T05:23:53+00:00`.
|
| 4 |
+
|
| 5 |
+
This summarizes the continuation run `continuation_3p5b_20260524T143012Z`,
|
| 6 |
+
which extended Vanilla, ReTok, and TD layer11 from iter 476 (~2.0B tokens)
|
| 7 |
+
to iter 834 (~3.5B tokens). Local JSON snapshots live under
|
| 8 |
+
`per_iter_results/`; remote full artifacts remain on Clariden under
|
| 9 |
+
`/capstor/scratch/cscs/fffoivos/runs/eval/continuation_3p5b_20260524T143012Z_*`.
|
| 10 |
+
|
| 11 |
+
## Bottom line
|
| 12 |
+
|
| 13 |
+
- TD layer11 is the best final benchmark arm overall: it is first on English
|
| 14 |
+
retention and multilingual aggregates, and narrowly first on the Greek
|
| 15 |
+
aggregate at iter 834.
|
| 16 |
+
- Vanilla still has the best tokenizer-fair heldout Greek BPC, but its
|
| 17 |
+
downstream Greek aggregate declined during the 2.0B -> 3.5B continuation.
|
| 18 |
+
- ReTok improves fastest on BPC and wins Greek MMLU / INCLUDE-44 Greek at
|
| 19 |
+
iter 834, but it remains behind TD and Vanilla on the Greek aggregate.
|
| 20 |
+
- If selecting for the actual downstream bakeoff objective, TD layer11 is now
|
| 21 |
+
the leading candidate. If selecting only for heldout BPC, Vanilla remains
|
| 22 |
+
ahead.
|
| 23 |
+
|
| 24 |
+
## Aggregate scoreboard at iter 834
|
| 25 |
+
|
| 26 |
+
| Arm | Greek agg | Delta vs 476 | EN retention | Delta vs 476 | Multilingual | Delta vs 476 | BPC lower better | BPC delta |
|
| 27 |
+
|---|---:|---:|---:|---:|---:|---:|---:|---:|
|
| 28 |
+
| Vanilla | 0.4339 | -0.70 pp | 0.6782 | -0.36 pp | 0.4923 | +0.22 pp | 0.4724 | -0.0182 |
|
| 29 |
+
| ReTok | 0.4246 | +0.96 pp | 0.6786 | +0.36 pp | 0.4864 | -0.09 pp | 0.5390 | -0.0349 |
|
| 30 |
+
| TD layer11 | 0.4344 | +0.90 pp | 0.6865 | +0.38 pp | 0.4967 | +0.68 pp | 0.5054 | -0.0256 |
|
| 31 |
+
|
| 32 |
+
## Per-task winners at iter 834
|
| 33 |
+
|
| 34 |
+
| Group | Task | Vanilla | ReTok | TD layer11 | Winner |
|
| 35 |
+
|---|---|---:|---:|---:|---|
|
| 36 |
+
| EN retention | `mmlu` | 0.5330 | 0.5565 | 0.5556 | ReTok |
|
| 37 |
+
| EN retention | `hellaswag` | 0.7573 | 0.7556 | 0.7632 | TD layer11 |
|
| 38 |
+
| EN retention | `arc_easy` | 0.7866 | 0.7576 | 0.7837 | Vanilla |
|
| 39 |
+
| EN retention | `arc_challenge` | 0.5230 | 0.5247 | 0.5358 | TD layer11 |
|
| 40 |
+
| EN retention | `piqa` | 0.7927 | 0.7851 | 0.7894 | Vanilla |
|
| 41 |
+
| EN retention | `winogrande` | 0.6764 | 0.6922 | 0.6914 | ReTok |
|
| 42 |
+
| Multilingual | `global_mmlu` | 0.4505 | 0.4603 | 0.4628 | TD layer11 |
|
| 43 |
+
| Multilingual | `xcopa` | 0.6178 | 0.5920 | 0.6156 | Vanilla |
|
| 44 |
+
| Multilingual | `xnli` | 0.4087 | 0.4070 | 0.4117 | TD layer11 |
|
| 45 |
+
| Greek | `global_mmlu_full_el` | 0.4145 | 0.4153 | 0.4036 | ReTok |
|
| 46 |
+
| Greek | `include_base_44_greek_few_shot_en` | 0.4022 | 0.4058 | 0.4004 | ReTok |
|
| 47 |
+
| Greek | `belebele_ell_Grek` | 0.5078 | 0.4933 | 0.5389 | TD layer11 |
|
| 48 |
+
| Greek | `arc_challenge_mt_el` | 0.4130 | 0.3899 | 0.4061 | Vanilla |
|
| 49 |
+
| Greek | `xnli_el` | 0.3831 | 0.3695 | 0.3851 | TD layer11 |
|
| 50 |
+
| Greek | `xquad_el` | 0.2868 | 0.3084 | 0.3364 | TD layer11 |
|
| 51 |
+
| Greek | `global_piqa_completions_ell_grek` | 0.6300 | 0.5900 | 0.5700 | Vanilla |
|
| 52 |
+
|
| 53 |
+
## Change from iter 476 to iter 834
|
| 54 |
+
|
| 55 |
+
| Group | Task | Vanilla delta | ReTok delta | TD layer11 delta |
|
| 56 |
+
|---|---|---:|---:|---:|
|
| 57 |
+
| EN retention | `mmlu` | -0.09 pp | +0.24 pp | +0.56 pp |
|
| 58 |
+
| EN retention | `hellaswag` | -0.21 pp | +0.69 pp | +0.27 pp |
|
| 59 |
+
| EN retention | `arc_easy` | +0.13 pp | -0.59 pp | +0.29 pp |
|
| 60 |
+
| EN retention | `arc_challenge` | -0.43 pp | +0.94 pp | +0.85 pp |
|
| 61 |
+
| EN retention | `piqa` | -0.22 pp | -0.11 pp | -0.27 pp |
|
| 62 |
+
| EN retention | `winogrande` | -1.34 pp | +1.03 pp | +0.55 pp |
|
| 63 |
+
| Multilingual | `global_mmlu` | -0.64 pp | +0.14 pp | +1.34 pp |
|
| 64 |
+
| Multilingual | `xcopa` | +1.09 pp | -0.71 pp | +0.42 pp |
|
| 65 |
+
| Multilingual | `xnli` | +0.22 pp | +0.30 pp | +0.28 pp |
|
| 66 |
+
| Greek | `global_mmlu_full_el` | -0.69 pp | +1.62 pp | +1.77 pp |
|
| 67 |
+
| Greek | `include_base_44_greek_few_shot_en` | -1.63 pp | +3.26 pp | -0.36 pp |
|
| 68 |
+
| Greek | `belebele_ell_Grek` | -0.56 pp | -0.33 pp | +1.11 pp |
|
| 69 |
+
| Greek | `arc_challenge_mt_el` | -0.77 pp | +1.79 pp | +0.26 pp |
|
| 70 |
+
| Greek | `xnli_el` | -1.89 pp | -0.56 pp | +0.48 pp |
|
| 71 |
+
| Greek | `xquad_el` | -2.33 pp | -0.08 pp | +1.02 pp |
|
| 72 |
+
| Greek | `global_piqa_completions_ell_grek` | +3.00 pp | +1.00 pp | +2.00 pp |
|
| 73 |
+
|
| 74 |
+
## New-token diagnostics
|
| 75 |
+
|
| 76 |
+
Measured on the 500-document heldout slice. Top-k is the fraction of
|
| 77 |
+
positions whose correct new token appears in the model's top-k predictions;
|
| 78 |
+
lower mean rank is better.
|
| 79 |
+
|
| 80 |
+
| Arm | Top-1 at new target | Delta from 585 | Top-5 at new target | Delta from 585 | Mean rank | Delta from 585 |
|
| 81 |
+
|---|---:|---:|---:|---:|---:|---:|
|
| 82 |
+
| ReTok | 0.3799 | +2.00 pp | 0.5469 | +2.11 pp | 228.9 | -31.4 |
|
| 83 |
+
| TD layer11 | 0.4105 | +1.43 pp | 0.5811 | +1.54 pp | 174.3 | -18.8 |
|
| 84 |
+
|
| 85 |
+
## Artifact checklist
|
| 86 |
+
|
| 87 |
+
- Local packed-eval snapshots: `per_iter_results/{vanilla,retok,td}_iter{585,715,834}.json`.
|
| 88 |
+
- Local BPC snapshots: `per_iter_results/intrinsic/*_iter{585,715,834}_fair.json`.
|
| 89 |
+
- Local new-token diagnostics: `per_iter_results/diagnostics/{retok,td}_iter{585,715,834}_new_token_diagnostics.json`.
|
| 90 |
+
- Regenerated plots are written to `plots/`.
|
| 91 |
+
- Final remote packed eval job: `2376082`, state `COMPLETED`, exit `0:0`, elapsed `00:59:51`.
|
provenance/evals/EVAL_RECIPE.md
ADDED
|
@@ -0,0 +1,321 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Eval recipe — V4 baseline + per-arm bakeoff eval
|
| 2 |
+
|
| 3 |
+
What we run, when, and what to expect out. **Engine**: [`swiss-ai/lm-evaluation-harness`](https://github.com/swiss-ai/lm-evaluation-harness) (Apertus team's fork — cited in Apertus tech report [arXiv:2509.14233](https://arxiv.org/abs/2509.14233) §5.1 footnote 45). **Citation**: Gao, Tow, Abbasi et al., Zenodo 2024, DOI [10.5281/zenodo.12608602](https://doi.org/10.5281/zenodo.12608602).
|
| 4 |
+
|
| 5 |
+
Two scopes:
|
| 6 |
+
|
| 7 |
+
- **V4 baseline** — full eval suite on unmodified `swiss-ai/Apertus-8B-2509`. One run, before the bakeoff fires. Output: per-benchmark mean + bootstrap CI. Gates the §5.6 hard-gate thresholds (how much regression on each benchmark counts as a "failure" for an arm).
|
| 8 |
+
- **Per-arm bakeoff eval** — same suite run on each arm's saved checkpoints in the 80–100 % range of its 2 B-token budget. Output: windowed-average score + bootstrap CI per arm. Drives §5.6 selection.
|
| 9 |
+
|
| 10 |
+
Both scopes use the **same task list and same harness flags** so the V4 baseline is the apples-to-apples comparator.
|
| 11 |
+
|
| 12 |
+
> **2026-05-21 takeover note.** V4 job `2334245` completed the then-current script, but that script accidentally omitted `global_mmlu` from Group 1. Treat its copied artifacts as a valid partial baseline for the listed tasks, not as the final Table-14 baseline. `run_eval.sbatch` now includes `global_mmlu`; rerun V4-HF and V4-post-conversion before filling final §5.6 thresholds.
|
| 13 |
+
|
| 14 |
+
## Scope of tasks: match Apertus's pretraining-eval table, not post-training
|
| 15 |
+
|
| 16 |
+
The bakeoff compares **pretraining-stage** checkpoints (no SFT, no DPO). Apertus's tech report reports two distinct eval tables:
|
| 17 |
+
|
| 18 |
+
- **Table 14, p.38 (pretraining benchmarks)**: ARC (challenge + easy), HellaSwag, WinoGrande, PIQA, MMLU, Global-MMLU, XNLI (15 langs incl. Greek), XCOPA (11 langs). All run with harness-default shot counts per §5.1.
|
| 19 |
+
- **Table 22, p.44 (post-training benchmarks)**: GSM8K-CoT, HumanEval, MBPP, IFEval, BBH, BBQ, ToxiGen, HarmBench, etc. — generative / instruction-following tasks that require an SFT'd model.
|
| 20 |
+
|
| 21 |
+
Our **primary** retention metric is Table-14 tasks (Group 1 below). Table-22 tasks (GSM8K / HumanEval / MBPP / IFEval) we mark as **post-training only** and skip in the bakeoff — they shouldn't fluctuate from a CPT init choice on a non-instruction-tuned base.
|
| 22 |
+
|
| 23 |
+
## Task list
|
| 24 |
+
|
| 25 |
+
Three groups. The wrappers in this directory take `--task-group {full|greek_only|retention_only}` so you can run them independently if needed.
|
| 26 |
+
|
| 27 |
+
### Group 1: retention (Apertus pretraining-eval set per Table 14)
|
| 28 |
+
|
| 29 |
+
| Task | Capability | `lm-eval-harness` task name | Few-shot (harness default) |
|
| 30 |
+
|---|---|---|---|
|
| 31 |
+
| ARC-Challenge | reasoning | `arc_challenge` | 25 |
|
| 32 |
+
| ARC-Easy | reasoning | `arc_easy` | 25 |
|
| 33 |
+
| HellaSwag | commonsense | `hellaswag` | 10 |
|
| 34 |
+
| WinoGrande | coreference | `winogrande` | 5 |
|
| 35 |
+
| PIQA | physical commonsense | `piqa` | 0 |
|
| 36 |
+
| MMLU (57 subjects) | knowledge | `mmlu` | 5 |
|
| 37 |
+
| Global-MMLU (15 langs incl. Greek) | multilingual knowledge | `global_mmlu` | 5 |
|
| 38 |
+
| XNLI (15 langs incl. Greek) | multilingual NLI | `xnli` | 0 |
|
| 39 |
+
| XCOPA (11 langs) | multilingual commonsense | `xcopa` | 0 |
|
| 40 |
+
|
| 41 |
+
XNLI and Global-MMLU both include Greek (`xnli_el`, `global_mmlu_el`); these double as Greek-retention signals for the bakeoff. Per Apertus §5.1 footnote 45: *"All of our reported pretraining benchmarks follow the default configuration specified in lm-evaluation-harness"* — we adopt the same convention. Tasks **excluded** from the bakeoff because Apertus reports them only post-training: GSM8K, HumanEval, MBPP, IFEval, BBH (Table 22).
|
| 42 |
+
|
| 43 |
+
### Group 2: Greek (native swissai-harness tasks + Belebele Greek)
|
| 44 |
+
|
| 45 |
+
**2026-05-21 update — empirically confirmed task availability.** The previous version of this table listed `arc_greek` / `hellaswag_greek` / `winogrande_greek` / `mmlu_greek` / `mmlu_pro_greek` / `truthfulqa_greek` / `medical_mcqa_greek` as `lm-eval-harness` task names. **Verified against the `swiss-ai/lm-evaluation-harness` clone on Clariden (2026-05-21, V4 attempt jobs 2333668 / 2333723):** those task names do not exist in the swissai harness — they live in the Meltemi/Krikri team's forks (`LeonVouk/lighteval`, `ilsp/lm-evaluation-harness-greek`) and have not landed upstream. The "reviewer flag" below was correct.
|
| 46 |
+
|
| 47 |
+
**What we actually ship at V4** (the names below resolve in `swiss-ai/lm-evaluation-harness` and were used for V4 job 2334245):
|
| 48 |
+
|
| 49 |
+
| Task | Source | `lm-eval-harness` task name | Few-shot |
|
| 50 |
+
|---|---|---|---|
|
| 51 |
+
| Greek ARC (machine-translated) | swissai harness | `arc_challenge_mt_el` | 25 |
|
| 52 |
+
| Greek MMLU (Global-MMLU, full Greek slice) | swissai harness | `global_mmlu_full_el` | 5 |
|
| 53 |
+
| Greek MMLU-44 (INCLUDE-44, native Greek, 7 subjects) | `CohereForAI/include-base-44`, config `Greek` | `include_base_44_greek_few_shot_en` (group of 7 subtasks) | 5 |
|
| 54 |
+
| Greek NLI | swissai harness | `xnli_el` | 0 |
|
| 55 |
+
| Greek QA | swissai harness | `xquad_el` | 0 |
|
| 56 |
+
| Greek PIQA (machine-translated) | swissai harness | `global_piqa_completions_ell_grek` | 0 |
|
| 57 |
+
| Belebele Greek | `facebook/belebele`, config `ell_Grek` | `belebele_ell_Grek` | 5 |
|
| 58 |
+
|
| 59 |
+
> **Reviewer flag (still open) — PF5 ILSP YAMLs.** The ILSP tasks the previous table claimed (`hellaswag_greek`, `winogrande_greek`, `mmlu_pro_greek`, `truthfulqa_greek`, `medical_mcqa_greek`) genuinely add Greek signal we don't currently have. The PF5 follow-up is to **port the YAML configs from `LeonVouk/lighteval` (or `ilsp/lm-evaluation-harness-greek`) into the swissai harness clone** so they resolve. Tracked as Task #55 in our running task list. Until PF5 lands, the bakeoff runs with the seven-task Greek list above + the multilingual coverage from Group 1.
|
| 60 |
+
|
| 61 |
+
Greek post-training-only tasks (`ilsp/mgsm_greek`, `ilsp/ifeval_greek`, `ilsp/mt-bench-greek`, `ilsp/m-ArenaHard_greek`) are out of scope for the pretraining-stage bakeoff — see "Scope of tasks" above.
|
| 62 |
+
|
| 63 |
+
The custom Greek evals from v0.7 §6.2 — polytonic continuation (out of bakeoff scope per the modern-only directive), morphology minimal pairs, language-ID drift, register preservation — run via Inspect AI as a separate sbatch (`run_inspect_evals.sbatch`, not in this iteration).
|
| 64 |
+
|
| 65 |
+
### Group 3: safety / other
|
| 66 |
+
|
| 67 |
+
| Task | Source | Notes |
|
| 68 |
+
|---|---|---|
|
| 69 |
+
| HarmBench | `swiss-ai/harmbench` | Apertus team's curated harmful-behavior bench |
|
| 70 |
+
| PolyglotToxicityPrompts | `swiss-ai/polyglotoxicityprompts` | Multilingual toxicity (incl. Greek) |
|
| 71 |
+
| AttaQ Greek | `ilsp/attaq_greek` | Greek-targeted safety |
|
| 72 |
+
| Jailbreak-StrongReject Greek | `ilsp/Jailbreak-StrongReject-el` | Jailbreak resistance |
|
| 73 |
+
|
| 74 |
+
These are inspect-style evals, run via `inspect eval` rather than lm-eval-harness. Lower priority for the bakeoff (no §5.6 hard gate ties to them directly); useful for the eventual release.
|
| 75 |
+
|
| 76 |
+
## Eval cadence
|
| 77 |
+
|
| 78 |
+
Per v0.7 §6.1:
|
| 79 |
+
|
| 80 |
+
- **Trajectory metrics** (training loss, per-bucket PPL, BPC trajectory, §5.3 new-token diagnostic suite): every 100 M tokens in the bakeoff (every ~25 global steps at 4 M tokens/step).
|
| 81 |
+
- **Downstream benchmarks** (Group 1 + Group 2): every 500 M tokens during training, plus a full sweep at the last 3–5 checkpoints in the 80–100 % budget range for selection.
|
| 82 |
+
- **V4 baseline**: once, before the bakeoff. Full suite × 1 run. Bootstrap CIs over eval samples (not over runs — most benchmark items are deterministic).
|
| 83 |
+
|
| 84 |
+
For 2 B-token bakeoff per arm: that's 4 mid-training benchmark runs (at 500 M, 1.0 B, 1.5 B, 2.0 B) and the last 3 (1.0 / 1.5 / 2.0 B) feed the windowed selection score.
|
| 85 |
+
|
| 86 |
+
### Current 2026-05-22 operational cadence
|
| 87 |
+
|
| 88 |
+
Training writes Megatron `torch_dist` checkpoints, while lm-eval and the intrinsic metric jobs require HF-format model directories. Each evaluated checkpoint therefore has two stages:
|
| 89 |
+
|
| 90 |
+
1. Convert the Megatron checkpoint to HF with [`convert_bakeoff_checkpoint_to_hf.sbatch`](convert_bakeoff_checkpoint_to_hf.sbatch).
|
| 91 |
+
2. Run [`run_eval.sbatch`](run_eval.sbatch) and, when a held-out JSONL is available, [`run_tokenizer_fair_metrics.sbatch`](run_tokenizer_fair_metrics.sbatch) + [`run_new_token_diagnostics.sbatch`](run_new_token_diagnostics.sbatch).
|
| 92 |
+
|
| 93 |
+
Use [`submit_bakeoff_checkpoint_eval.sh`](submit_bakeoff_checkpoint_eval.sh) for the conversion/eval chain:
|
| 94 |
+
|
| 95 |
+
```bash
|
| 96 |
+
RUN_TAG=bakeoff_1node_chain_20260522_005620 \
|
| 97 |
+
bash submit_bakeoff_checkpoint_eval.sh vanilla 65 greek_only
|
| 98 |
+
```
|
| 99 |
+
|
| 100 |
+
For full bakeoff checkpoints where all three arms should be evaluated, prefer
|
| 101 |
+
the packed path. Clariden's normal partition can allocate/bill a whole 4-GPU
|
| 102 |
+
node even for a one-GPU `lm-eval` job; the packed submitter converts each arm
|
| 103 |
+
separately, then runs the three single-GPU full evals concurrently inside one
|
| 104 |
+
node allocation:
|
| 105 |
+
|
| 106 |
+
```bash
|
| 107 |
+
RUN_TAG=bakeoff_1node_chain_20260522_005620 \
|
| 108 |
+
SUBMIT_INTRINSIC=1 \
|
| 109 |
+
EVAL_JSONL=/iopsstor/scratch/cscs/fffoivos/cpt_corpus/heldout/cpt_greek_heldout_500_20260522.jsonl \
|
| 110 |
+
bash submit_bakeoff_checkpoint_eval_packed.sh 390 full vanilla retok centroid
|
| 111 |
+
```
|
| 112 |
+
|
| 113 |
+
For a live run, use [`watch_and_submit_checkpoint_evals.sh`](watch_and_submit_checkpoint_evals.sh)
|
| 114 |
+
to submit once per arm as soon as each checkpoint appears:
|
| 115 |
+
|
| 116 |
+
```bash
|
| 117 |
+
RUN_TAG=bakeoff_1node_chain_20260522_005620 \
|
| 118 |
+
ITER=65 \
|
| 119 |
+
TASK_GROUP=greek_only \
|
| 120 |
+
POLL_SECONDS=300 \
|
| 121 |
+
nohup bash watch_and_submit_checkpoint_evals.sh \
|
| 122 |
+
> /capstor/scratch/cscs/fffoivos/runs/eval/watch_iter65.log 2>&1 &
|
| 123 |
+
```
|
| 124 |
+
|
| 125 |
+
For full checkpoints in the live bakeoff, use
|
| 126 |
+
[`watch_and_submit_checkpoint_evals_packed.sh`](watch_and_submit_checkpoint_evals_packed.sh)
|
| 127 |
+
instead, so the watcher waits until all requested arms are complete and then
|
| 128 |
+
submits a single packed full-eval job:
|
| 129 |
+
|
| 130 |
+
```bash
|
| 131 |
+
RUN_TAG=bakeoff_1node_chain_20260522_005620 \
|
| 132 |
+
ITER=390 \
|
| 133 |
+
TASK_GROUP=full \
|
| 134 |
+
SUBMIT_INTRINSIC=1 \
|
| 135 |
+
EVAL_JSONL=/iopsstor/scratch/cscs/fffoivos/cpt_corpus/heldout/cpt_greek_heldout_500_20260522.jsonl \
|
| 136 |
+
POLL_SECONDS=300 \
|
| 137 |
+
nohup bash watch_and_submit_checkpoint_evals_packed.sh \
|
| 138 |
+
> /capstor/scratch/cscs/fffoivos/runs/eval/watch_iter390_packed.log 2>&1 &
|
| 139 |
+
```
|
| 140 |
+
|
| 141 |
+
The live bakeoff saves every 65 iterations, which is about 273 M tokens (`65 × 1024 × 4096`). The practical cadence is:
|
| 142 |
+
|
| 143 |
+
| Iteration | Tokens/arm | Eval action |
|
| 144 |
+
|---:|---:|---|
|
| 145 |
+
| 65 | ~273 M | Greek-only downstream smoke on all three arms; proves checkpoint save, conversion, and eval before waiting for late checkpoints. |
|
| 146 |
+
| 130 | ~545 M | Full downstream eval + intrinsic metrics/diagnostics if held-out JSONL is staged. |
|
| 147 |
+
| 260 | ~1.09 B | Full downstream eval + intrinsic metrics/diagnostics. |
|
| 148 |
+
| 390 | ~1.64 B | Full downstream eval + intrinsic metrics/diagnostics; enters the selection window. |
|
| 149 |
+
| 455 or final | ~1.91-2.00 B | Full downstream eval + intrinsic metrics/diagnostics; final selection evidence. |
|
| 150 |
+
|
| 151 |
+
The final arm choice should use the late-window checkpoints (390 plus the final one, and 260 as the nearest pre-window anchor if only two late checkpoints are available). The iteration-65 Greek-only run is not selection evidence; it is an operational canary to catch broken conversion/eval early.
|
| 152 |
+
|
| 153 |
+
### TD layer11 direct-path eval handoff
|
| 154 |
+
|
| 155 |
+
The Token Distillation 2B run is a single selected arm, not the original
|
| 156 |
+
`${RUN_TAG}_${arm}` three-arm layout. Use the TD-specific wrappers so conversion
|
| 157 |
+
reads the direct checkpoint root and the HF tokenizer/config produced by the TD
|
| 158 |
+
layer11 R17 roundtrip:
|
| 159 |
+
|
| 160 |
+
```bash
|
| 161 |
+
RUN_TAG=td_full25_layer11_2b_20260523T165038Z \
|
| 162 |
+
ITER=65 \
|
| 163 |
+
TASK_GROUP=greek_only \
|
| 164 |
+
POLL_SECONDS=300 \
|
| 165 |
+
nohup bash watch_and_submit_td_checkpoint_eval.sh \
|
| 166 |
+
> /capstor/scratch/cscs/fffoivos/runs/eval/watch_td_l11_iter65_greek_only.log 2>&1 &
|
| 167 |
+
```
|
| 168 |
+
|
| 169 |
+
For selection checkpoints, enable intrinsic metrics against the staged Greek
|
| 170 |
+
held-out slice:
|
| 171 |
+
|
| 172 |
+
```bash
|
| 173 |
+
RUN_TAG=td_full25_layer11_2b_20260523T165038Z \
|
| 174 |
+
ITER=390 \
|
| 175 |
+
TASK_GROUP=full \
|
| 176 |
+
SUBMIT_INTRINSIC=1 \
|
| 177 |
+
EVAL_JSONL=/iopsstor/scratch/cscs/fffoivos/cpt_corpus/heldout/cpt_greek_heldout_500_20260522.jsonl \
|
| 178 |
+
POLL_SECONDS=300 \
|
| 179 |
+
nohup bash watch_and_submit_td_checkpoint_eval.sh \
|
| 180 |
+
> /capstor/scratch/cscs/fffoivos/runs/eval/watch_td_l11_iter390_full.log 2>&1 &
|
| 181 |
+
```
|
| 182 |
+
|
| 183 |
+
The TD wrapper submits `convert_bakeoff_checkpoint_to_hf.sbatch` with
|
| 184 |
+
`ARM=td_layer11` and defaults the tokenizer/config to:
|
| 185 |
+
|
| 186 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/td_full25_layer11_r17_roundtrip_2357565/hf_roundtrip`
|
| 187 |
+
|
| 188 |
+
Checkpoint conversion is not a dataset-build/preprocessing job: it imports
|
| 189 |
+
Megatron/PyTorch and requires the PyTorch `uenv`, which Clariden `xfer` nodes do
|
| 190 |
+
not expose. It therefore runs as a bounded one-GPU `debug` job. The sleeping
|
| 191 |
+
checkpoint watchers remain CPU-only `xfer` jobs.
|
| 192 |
+
|
| 193 |
+
For unattended monitoring, prefer the Slurm wrapper instead of keeping
|
| 194 |
+
sleeping watcher processes on a login SSH session:
|
| 195 |
+
|
| 196 |
+
```bash
|
| 197 |
+
first="$(sbatch --parsable watch_td_checkpoint_evals.sbatch)"
|
| 198 |
+
second="$(sbatch --parsable --dependency=afterany:$first watch_td_checkpoint_evals.sbatch)"
|
| 199 |
+
echo "$first $second"
|
| 200 |
+
```
|
| 201 |
+
|
| 202 |
+
The wrapper runs on `xfer` with one CPU and no GPU. It is safe to chain or
|
| 203 |
+
re-run because each per-checkpoint watcher has a `submitted` stamp.
|
| 204 |
+
|
| 205 |
+
## §5.6 hard gates — to be filled from V4 baseline
|
| 206 |
+
|
| 207 |
+
Per v0.7 §5.6, a candidate arm **fails** if any of these gates trips. Thresholds are deliberately left as placeholders here — they're set **after** the V4 baseline run on unmodified Apertus-8B-2509 establishes the per-benchmark variance. The "fill from V4" step is on the post-V4 review checklist; until then these thresholds remain `PENDING(V4)`.
|
| 208 |
+
|
| 209 |
+
| # | Hard gate | Signal source | Failure rule | Threshold |
|
| 210 |
+
|---|---|---|---|---|
|
| 211 |
+
| HG1 | English / core retention regression | `results.json` from lm-eval-harness (ARC, HellaSwag, WinoGrande, PIQA, MMLU) | mean drop > X p.p. on any one of those 5, after windowed average over last 3-5 checkpoints in 80-100 % of budget | `X = PENDING(V4)` (suggest 3 p.p. as starting placeholder) |
|
| 212 |
+
| HG2 | Code retention regression (if code is a release requirement per Q A1) | lm-eval-harness code task (typically `humaneval` post-training; not in pretraining-eval table) | mean drop > Y p.p. | `Y = PENDING(V4 + Q A1)`; skip if code isn't a release requirement |
|
| 213 |
+
| HG3 | New-token row collapse (cosine clustering, near-zero usage) | [`compute_new_token_diagnostics.py`](compute_new_token_diagnostics.py) → `embedding.new_E_cos.mean_off_diag` AND `forward.d2_avg_prob_mass_new_per_pos` | `mean_off_diag > C_THRESH` OR `prob_mass_new < M_THRESH` | `C_THRESH = PENDING(V4)` (suggest 0.5 as starting placeholder — base Greek tokens typically sit at ~0.1-0.3 off-diag mean); `M_THRESH = PENDING(V4)` |
|
| 214 |
+
| HG4 | Polytonic text worsens vs base on character-normalized loss | [`compute_tokenizer_fair_metrics.py`](compute_tokenizer_fair_metrics.py) → `per_register.polytonic.nll_per_char` | arm value > base value | direct comparison; no separate threshold |
|
| 215 |
+
| HG5 | Throughput / memory hit disproportionate to Greek compression gain | Megatron training logs (`--log-throughput`) + tokenizer-fair `compression_ratio` | `(throughput_loss / compression_gain) > T_THRESH` | `T_THRESH = PENDING(V4)`; only fires for extended-vocab arms (ReTok/Centroid), not Vanilla |
|
| 216 |
+
| HG6 | Language-ID drift — model over-emits Greek in non-Greek prompts | Custom eval (§6.2; not yet implemented — Item 7 in COMPLETENESS_CHECK.md) | drift rate > D_THRESH | **`D_THRESH = PENDING(V4 + custom-eval-construction)`**; DEFERRED until §6.2 custom evals exist |
|
| 217 |
+
|
| 218 |
+
**Operational note.** HG1-HG5 can be computed from JSONs already produced by the existing eval flow. HG6 requires the custom Greek eval construction work (1-2 weeks per v0.7); it's expected to not be running in time for the first bakeoff pass and may need a substitute signal (e.g., `per_register.english.nll_per_char` from `compute_tokenizer_fair_metrics.py` on an English held-out slice — non-Greek text getting Greek-token outputs would spike English NLL).
|
| 219 |
+
|
| 220 |
+
**Why these thresholds aren't hard-coded:** the per-benchmark variance on Apertus-8B-base is unknown until we run V4. A "3 p.p. drop is a failure" rule is meaningless if the run-to-run variance of HellaSwag is itself 2 p.p. The V4 baseline + bootstrap CIs establish the noise floor, then "drop > 3× the noise floor on any benchmark" or similar becomes a defensible rule.
|
| 221 |
+
|
| 222 |
+
**Selection (not automated).** For non-failing arms, v0.7 §5.6 gives a weighted score (30-40 % Greek BPC, 25-35 % Greek benchmarks, 10-15 % polytonic, 15-25 % retention, 5-10 % efficiency). For a 3-arm bakeoff this is small enough to eyeball — see [`summarize_bakeoff.py`](summarize_bakeoff.py) for the helper that aggregates per-arm JSONs into one markdown table. **The final pick is a manual review against this table + the V4 thresholds**, not a numerical aggregate.
|
| 223 |
+
|
| 224 |
+
## Statistical methodology
|
| 225 |
+
|
| 226 |
+
Per v0.7 §6.1 (Park et al. Oct 2025): downstream benchmark scores are noisy, and "run 3×" doesn't add information because the benchmarks are deterministic. The right way to get confidence intervals is **bootstrap over eval samples**.
|
| 227 |
+
|
| 228 |
+
`compute_bootstrap_cis.py` (this dir) takes `--log_samples` JSONL from lm-eval-harness, resamples eval items with replacement 1000 times, and reports per-task mean + 95 % CI.
|
| 229 |
+
|
| 230 |
+
**Selection scope** (per v0.7 §5.6): windowed average across the last 3–5 checkpoints in the 80–100 % range of each arm's budget. For training continuation post-winner, use the **raw** checkpoint at the end (not the averaged one), since the averaged model has no corresponding optimizer state.
|
| 231 |
+
|
| 232 |
+
## Resources per eval run
|
| 233 |
+
|
| 234 |
+
V4 baseline (one run) on Clariden:
|
| 235 |
+
|
| 236 |
+
- partition: `normal`
|
| 237 |
+
- shape: `-N 1 -t 4:00:00 --gpus-per-node=1` (V4 currently runs 1-GPU; the early 4-GPU plan was scaled back after PF5 / task-name corrections cut total work)
|
| 238 |
+
- wall: ~1-2 h end-to-end for the seven Greek tasks + nine retention tasks at the corrected list (V4 job 2334245 mid-run as of 2026-05-21 12:30 UTC)
|
| 239 |
+
- batch size: `auto` (lm-eval-harness picks per task; observed `auto:1` → `32` for Apertus-8B on bf16)
|
| 240 |
+
|
| 241 |
+
### lm-eval-harness install path (Clariden, 2026-05-21)
|
| 242 |
+
|
| 243 |
+
The uenv `pytorch/v2.9.1:v2`'s site-packages is read-only, so `pip install -e .` from the swissai clone fails with `[Errno 30] Read-only file system`. Workaround used by `run_eval.sbatch`:
|
| 244 |
+
|
| 245 |
+
```bash
|
| 246 |
+
# One-time, as part of CSCS staging:
|
| 247 |
+
uenv start pytorch/v2.9.1:v2 --view=default
|
| 248 |
+
cd /iopsstor/scratch/cscs/fffoivos/code/eval/lm-evaluation-harness-swissai
|
| 249 |
+
pip install --target=/iopsstor/scratch/cscs/fffoivos/python_envs/lm_eval --quiet .
|
| 250 |
+
pip install --target=/iopsstor/scratch/cscs/fffoivos/python_envs/lm_eval --no-deps --quiet accelerate
|
| 251 |
+
# Delete the target's copy of huggingface-hub so the uenv's 0.36.0 wins over the
|
| 252 |
+
# pip-installed 1.x (transformers 4.57.0 pins hf_hub<1.0):
|
| 253 |
+
rm -rf /iopsstor/scratch/cscs/fffoivos/python_envs/lm_eval/huggingface_hub
|
| 254 |
+
rm -rf /iopsstor/scratch/cscs/fffoivos/python_envs/lm_eval/huggingface_hub-*.dist-info
|
| 255 |
+
```
|
| 256 |
+
|
| 257 |
+
Then run_eval.sbatch sets `PYTHONPATH=/iopsstor/scratch/cscs/fffoivos/python_envs/lm_eval` and invokes `python3 -m lm_eval ...`. No `pip install -e .` at job-start time.
|
| 258 |
+
|
| 259 |
+
Per-arm bakeoff eval at one checkpoint:
|
| 260 |
+
|
| 261 |
+
- same shape, ~2 h
|
| 262 |
+
- run inline during training via Slurm `--dependency=afterok` on the checkpoint-save step, OR run separately after the training job completes
|
| 263 |
+
|
| 264 |
+
## Files in this directory
|
| 265 |
+
|
| 266 |
+
- `EVAL_RECIPE.md` — this doc
|
| 267 |
+
- `pull_benchmarks.sh` — staging-time HF download for the benchmark datasets (and the swiss-ai eval scripts repo)
|
| 268 |
+
- `run_eval.sbatch` — parameterized eval job: `MODEL_PATH=… OUTPUT_DIR=… TASK_GROUP={full|greek_only|retention_only} sbatch run_eval.sbatch`
|
| 269 |
+
- `run_apertus_baseline.sh` — thin wrapper: V4 baseline on the unmodified Apertus-8B-2509 checkpoint
|
| 270 |
+
- `run_bakeoff_arm_eval.sh` — thin wrapper: per-arm eval, takes an arm's checkpoint dir as arg
|
| 271 |
+
- `convert_bakeoff_checkpoint_to_hf.sbatch` — bounded one-GPU `debug` job; converts one Megatron `torch_dist` bakeoff checkpoint to HF format for eval
|
| 272 |
+
- `run_megatron_convert_with_pg.py` — initializes the single-rank process group needed by Megatron `loader core` when reading `torch_dist` checkpoints
|
| 273 |
+
- `submit_bakeoff_checkpoint_eval.sh` — submits conversion plus lm-eval, with optional intrinsic metrics when `SUBMIT_INTRINSIC=1`
|
| 274 |
+
- `watch_and_submit_checkpoint_evals.sh` — lightweight watcher that stamps per-arm submissions and prevents duplicate checkpoint eval launches
|
| 275 |
+
- `submit_td_checkpoint_eval.sh` — direct-path TD layer11 conversion plus eval submitter for the selected TD 2B run
|
| 276 |
+
- `watch_and_submit_td_checkpoint_eval.sh` — lightweight direct-path TD watcher; submits once when a checkpoint directory and tracker are both ready
|
| 277 |
+
- `watch_td_checkpoint_evals.sbatch` — CPU-only `xfer` wrapper that runs the TD watcher set durably under Slurm
|
| 278 |
+
- `build_cpt_heldout_jsonl.py` / `build_cpt_heldout_jsonl.sbatch` — builds the 500-doc Greek held-out JSONL from the post-Apertus-dedup selected pool while excluding Greek doc_ids already used in `bulk_mix.jsonl`
|
| 279 |
+
- `compute_bootstrap_cis.py` — post-process: bootstrap CIs over the `--log_samples` outputs
|
| 280 |
+
- **`compute_tokenizer_fair_metrics.py`** — primary v0.7 §5.1 intrinsic metrics (BPC, NLL/char, NLL/word, tokens/word, chars/token, compression ratio, STRR). The cross-tokenizer-fair signal for comparing Vanilla (vocab 131,072) vs ReTok/Centroid (vocab 148,480). Has a `--stats-only` mode for tokenizer-only checks (no model load).
|
| 281 |
+
- **`run_tokenizer_fair_metrics.sbatch`** — sbatch wrapper for the above; 1 node × 1 GPU × 2 h. Runs at each bakeoff checkpoint where downstream eval also runs.
|
| 282 |
+
- **`compute_new_token_diagnostics.py`** — v0.7 §5.3 new-token integration diagnostic suite: 7 diagnostics over the 17,408 new IDs (rank of new target in next-token logits, prob-mass on new IDs, per-register entropy, top-1 substitution rate at new-target positions, greedy-gen new-token utilization, embedding L2-norm distribution new-vs-existing, cosine-similarity / effective-rank of new rows). Has `--embedding-only` mode that skips the forward-pass diagnostics (D1-D5) for cheap embedding-only health checks.
|
| 283 |
+
- **`run_new_token_diagnostics.sbatch`** — sbatch wrapper for the diagnostic suite; 1 node × 1 GPU × 2 h.
|
| 284 |
+
|
| 285 |
+
## §5.3 new-token integration diagnostic suite — important
|
| 286 |
+
|
| 287 |
+
Per v0.7 §5.3, these 7 diagnostics are **"read at every bakeoff checkpoint"**:
|
| 288 |
+
|
| 289 |
+
| # | Diagnostic | What it catches |
|
| 290 |
+
|---|---|---|
|
| 291 |
+
| D1 | Rank of correct new token in next-token logits | New token invisible |
|
| 292 |
+
| D2 | Aggregate probability mass on new Greek tokens | Under- or over-emitted |
|
| 293 |
+
| D3 | New-token entropy by register | Polytonic rows collapsed or avoided |
|
| 294 |
+
| D4 | Top-k substitutions between new token and old subpieces | Model still prefers old segmentation |
|
| 295 |
+
| D5 | Greedy-gen new-token utilization rate | New rows exist but behaviorally dead |
|
| 296 |
+
| D6 | Embedding L2-norm distribution: new vs existing | Degenerate-subspace collapse |
|
| 297 |
+
| D7 | Cosine-similarity / effective-rank of new rows | Same-direction collapse |
|
| 298 |
+
|
| 299 |
+
`compute_new_token_diagnostics.py` implements all 7 in a single run (~10-15 min per checkpoint on one GH200). D6 + D7 are embedding-only (cheap; can run with `--embedding-only` for fast checks). D5 is the heaviest single diagnostic; `--skip-greedy` opts out.
|
| 300 |
+
|
| 301 |
+
## Primary intrinsic metrics (v0.7 §5.1) — important
|
| 302 |
+
|
| 303 |
+
Per-token PPL is **not comparable** across the Vanilla arm (vocab 131,072) and the ReTok/Centroid arms (vocab 148,480). v0.7 §5.1 specifies these tokenizer-fair metrics as the **primary** signal for the bakeoff:
|
| 304 |
+
|
| 305 |
+
| Metric | Why |
|
| 306 |
+
|---|---|
|
| 307 |
+
| **BPC (bits per byte)** | Cleanest cross-tokenizer comparison |
|
| 308 |
+
| **NLL per Unicode character** | More interpretable for Greek/polytonic |
|
| 309 |
+
| **NLL per word** | Human-facing language metric |
|
| 310 |
+
| **tokens/word, chars/token, compression ratio** | Quantifies tokenizer efficiency |
|
| 311 |
+
| **STRR** (Subword-Tokenization Recovery Rate) | Fraction of held-out words that tokenize to a single token — whole-word preservation |
|
| 312 |
+
|
| 313 |
+
`compute_tokenizer_fair_metrics.py` computes all of these from one HF-format checkpoint + a held-out JSONL. Aggregates globally + per-source + per-register.
|
| 314 |
+
|
| 315 |
+
**Held-out eval slice**: ~100-500 docs covering modern Greek registers (encyclopedic / literary / academic / dialogue / legal / dictionary). The slice should be **outside** the bakeoff training mix. Current operational builder:
|
| 316 |
+
|
| 317 |
+
```bash
|
| 318 |
+
sbatch build_cpt_heldout_jsonl.sbatch
|
| 319 |
+
```
|
| 320 |
+
|
| 321 |
+
This samples from `/iopsstor/scratch/cscs/fffoivos/cpt_corpus/cpt/selected_after_apertus_and_internal_dedup.parquet`, excludes every Greek `doc_id` already present in `/iopsstor/scratch/cscs/fffoivos/cpt_corpus/bulk_mix.jsonl`, and fills quotas from the Greek source/register buckets in `corpus_build/recipes/bulk.json` that still have training-disjoint rows. The first full scan showed the current training mix exhausted the literary and dictionary/misc filters, so the default 500-doc slice redistributes those slots to HPLT, dialogue/textbooks, academic, and legal/civic. This is more aligned with the current CPT corpus than the older C3 val/test reconstruction, but it is a **training-disjoint intrinsic-metrics slice**, not a proof that all external benchmark test items were absent from the CPT source pool. Benchmark decontamination remains a separate check.
|
provenance/evals/V4_BENCHMARK_COMPARISON.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# V4-HF vs V4-post-conversion — Apertus-8B-2509 benchmark comparison
|
| 2 |
+
|
| 3 |
+
Companion to [`v4_baseline_corrected_20260521/README.md`](v4_baseline_corrected_20260521/README.md) and [`v4_postconv_retry_20260521/README.md`](v4_postconv_retry_20260521/README.md). Quantifies the R17 risk empirically: same Apertus weights, run through HF → Megatron → HF, then re-evaluated.
|
| 4 |
+
|
| 5 |
+
## Per-task comparison
|
| 6 |
+
|
| 7 |
+
Top-level group scores per swissai lm-evaluation-harness. Stderrs are the harness defaults (analytic, not bootstrapped — see `compute_bootstrap_cis.py` for per-sample CIs if needed).
|
| 8 |
+
|
| 9 |
+
### English retention (Apertus Table 14)
|
| 10 |
+
|
| 11 |
+
| Task | Metric | V4-HF | V4-postconv | Δ | Chance |
|
| 12 |
+
|---|---|---:|---:|---:|---:|
|
| 13 |
+
| `arc_challenge` | acc_norm | 0.5870 ±0.0144 | 0.2619 ±0.0128 | **−0.3251** | 0.25 |
|
| 14 |
+
| `arc_easy` | acc_norm | 0.8363 ±0.0076 | 0.2614 ±0.0090 | **−0.5749** | 0.25 |
|
| 15 |
+
| `hellaswag` | acc_norm | 0.7884 ±0.0041 | 0.2675 ±0.0044 | **−0.5209** | 0.25 |
|
| 16 |
+
| `winogrande` | acc | 0.6930 ±0.0130 | 0.5107 ±0.0140 | −0.1823 | 0.50 |
|
| 17 |
+
| `piqa` | acc_norm | 0.7992 ±0.0093 | 0.5212 ±0.0117 | −0.2780 | 0.50 |
|
| 18 |
+
| `mmlu` | acc | 0.5923 ±0.0039 | 0.2295 ±0.0035 | **−0.3628** | 0.25 |
|
| 19 |
+
|
| 20 |
+
`mmlu = 0.5923` on V4-HF matches the Apertus tech report Table 14 (≈0.59), confirming the eval pipeline is wired correctly.
|
| 21 |
+
|
| 22 |
+
### Multilingual retention
|
| 23 |
+
|
| 24 |
+
| Task | Metric | V4-HF | V4-postconv | Δ | Chance |
|
| 25 |
+
|---|---|---:|---:|---:|---:|
|
| 26 |
+
| `global_mmlu` (15 langs) | acc | 0.5246 ±0.0063 | 0.2381 ±0.0054 | **−0.2865** | 0.25 |
|
| 27 |
+
| `xcopa` (11 langs) | acc | 0.6575 ±0.0063 | 0.5185 ±0.0067 | −0.1389 | 0.50 |
|
| 28 |
+
| `xnli` (15 langs) | acc | 0.4400 ±0.0026 | 0.3321 ±0.0024 | −0.1079 | 0.33 |
|
| 29 |
+
|
| 30 |
+
### Greek slice
|
| 31 |
+
|
| 32 |
+
| Task | Metric | V4-HF | V4-postconv | Δ | Chance |
|
| 33 |
+
|---|---|---:|---:|---:|---:|
|
| 34 |
+
| `global_mmlu_full_el` | acc | 0.5155 ±0.0040 | 0.2295 ±0.0035 | **−0.2861** | 0.25 |
|
| 35 |
+
| `include_base_44_greek_few_shot_en` | acc | 0.5054 ±0.0208 | 0.1975 ±0.0169 | **−0.3080** | 0.25 |
|
| 36 |
+
| `belebele_ell_Grek` | acc | 0.6367 ±0.0160 | 0.2289 ±0.0140 | **−0.4078** | 0.25 |
|
| 37 |
+
| `arc_challenge_mt_el` | acc_norm | 0.4795 ±0.0146 | 0.2637 ±0.0129 | **−0.2159** | 0.25 |
|
| 38 |
+
| `xnli_el` | acc | 0.3984 ±0.0098 | 0.3333 ±0.0094 | −0.0651 | 0.33 |
|
| 39 |
+
| `xquad_el` | f1 | 0.5172 ±0.0117 | **0.0000 ±0.0000** | **−0.5172** | n/a |
|
| 40 |
+
| `global_piqa_completions_ell_grek` | acc_norm | 0.6200 ±0.0488 | 0.5400 ±0.0501 | −0.0800 | 0.50 |
|
| 41 |
+
|
| 42 |
+
## Reading
|
| 43 |
+
|
| 44 |
+
1. **V4-HF reproduces Apertus's published baseline.** Eval rig validated.
|
| 45 |
+
2. **R17 is catastrophic, not cosmetic.** R1's "standard max abs diff = 0.0" was bit-exact only on the standard transformer tensors — the 128 reset xIELU αp/αn/β/ε parameters (per layer × 32 layers × 4 params) destroy the model's learned representations. Closed-form MC tasks fall to or below chance; extractive QA (`xquad_el`) collapses to zero f1 because the model cannot produce coherent text spans at all.
|
| 46 |
+
3. **xIELU is the load-bearing R17 component.** xIELU's α-parameters are multiplicative slope gates: resetting them to the `XIELU.__init__` default (αp = αn = 0.8) destroys the learned activation shape across all 32 layers. The QK-Norm `q_norm`/`k_norm` weights happened to drift inside bf16 noise in the R1 diff (within 1e-3 threshold), but the xIELU resets are larger and they propagate through every forward pass.
|
| 47 |
+
4. **Tasks that "survive" R17 are easy-baseline tasks.** `winogrande`, `piqa`, `xcopa`, `xnli`, `global_piqa_completions_ell_grek` retain near-chance behaviour because the random init still produces *some* output and binary/3-way MC is forgiving. The information-rich tasks (MMLU, ARC, HellaSwag, Belebele, XQuAD) collapse.
|
| 48 |
+
|
| 49 |
+
## Bakeoff selection implications
|
| 50 |
+
|
| 51 |
+
This section describes the implication **for raw, unpatched HF → Megatron conversion**. After this comparison exposed the failure, `megatron_patches/patch_apertus_extras.py` was implemented and validated on the TP=2 bakeoff init checkpoints (`2341182`, `2341239`, `2341241`): patched Megatron → HF roundtrips have `standard_max_abs_diff = 0.0`, `r17_max_abs_diff = 0.0`, and `logit_max_abs_diff = 0.0`.
|
| 52 |
+
|
| 53 |
+
Therefore the actual bakeoff should use `megatron_tp2_r17patched`, not the raw `megatron_tp2` dirs. If someone intentionally runs the raw dirs, then the three arms start from approximately the V4-postconv baseline (R17-reset Apertus + the embedding-resize init choice they differ on), not from V4-HF. In that raw-conversion ablation, the §5.6 hard-gate plan in [`EVAL_RECIPE.md`](EVAL_RECIPE.md) would need to change:
|
| 54 |
+
|
| 55 |
+
- **Old framing (V4-HF reference):** "Arm X regresses > 3 p.p. from V4-HF on mmlu" → trivially fails for every arm at iteration 0 (each is 36 p.p. below V4-HF by construction).
|
| 56 |
+
- **New framing (V4-postconv reference):** "Arm X recovers > Y p.p. from V4-postconv on mmlu after 2B tokens, with bootstrap CI separating it from the other arms" → measurable signal.
|
| 57 |
+
|
| 58 |
+
The bakeoff is **recovery**, not retention. Concrete questions per arm:
|
| 59 |
+
|
| 60 |
+
- Which arm climbs off the chance floor fastest on the closed-form MC tasks (mmlu, hellaswag, arc_easy)?
|
| 61 |
+
- Which arm preserves the partially-surviving signals (winogrande, piqa, xcopa) without backsliding?
|
| 62 |
+
- Which arm recovers `xquad_el` extractive QA — i.e. produces non-empty answers?
|
| 63 |
+
- Greek-specific recovery is the primary bakeoff signal: which arm recovers `belebele_ell_Grek` and `global_mmlu_full_el` fastest?
|
| 64 |
+
|
| 65 |
+
If after 2B tokens no arm has recovered meaningfully past V4-postconv (e.g. all three sit at chance ±0.01 on mmlu), the bakeoff doesn't differentiate at this budget; either extend the budget or block on the production patcher (`megatron_patches/patch_apertus_extras.py`) that fixes R17 before training.
|
| 66 |
+
|
| 67 |
+
## Production CPT prerequisite
|
| 68 |
+
|
| 69 |
+
R17 quantification confirmed the existing risk note in [`RISKS.md`](../../../RISKS.md): **the post-conversion xIELU/QK-Norm patcher is required before production CPT**, not just nice-to-have. Recovering 30-50 percentage points across MMLU/HellaSwag/ARC inside a 15-20B-token production CPT budget is unrealistic; the model must start from intact xIELU values.
|
| 70 |
+
|
| 71 |
+
The patcher is now implemented and has passed tensor + logit roundtrip checks for all three TP=2 init arms. The remaining optional confirmation is to run the full V4 eval on a patched roundtrip; the cheaper proof already shows the patched HF roundtrip is bit-exact to its HF source.
|
| 72 |
+
|
| 73 |
+
## Artifacts
|
| 74 |
+
|
| 75 |
+
- `v4_baseline_corrected_20260521/results.json` — V4-HF full lm-eval-harness output.
|
| 76 |
+
- `v4_postconv_retry_20260521/{retention,greek}_results.json` — V4-postconv split runs (retention on job 2338020, Greek on job 2338021).
|
| 77 |
+
- Comparison script: `/tmp/v4_compare_full.py` (paths in script point at this dir).
|
provenance/token-distillation/RUN_LOG_20260523.md
ADDED
|
@@ -0,0 +1,2299 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Token Distillation Coverage Run Log - 2026-05-23
|
| 2 |
+
|
| 3 |
+
Purpose: run the first bounded Token Distillation gate, the CPU-only firing and
|
| 4 |
+
snippet-coverage prepass, on Clariden `xfer`. No GPU nodes are used for this
|
| 5 |
+
dataset/snippet work.
|
| 6 |
+
|
| 7 |
+
## Local commits
|
| 8 |
+
|
| 9 |
+
- `b6d412a` - production decision state and initial TD prepass.
|
| 10 |
+
- `462ae2f` - first attempt to fix `uenv` path in Slurm.
|
| 11 |
+
- `b1aec29` - switch TD prepass launcher to a Python venv instead of `uenv`.
|
| 12 |
+
- `a05e3ab` - document xfer runtime and xfer-built venv.
|
| 13 |
+
- `77119b3` - add periodic progress logging.
|
| 14 |
+
- `65d8561` - document full TD coverage prepass launch.
|
| 15 |
+
- `c17c8ed` - pin vendored upstream Token Distillation source.
|
| 16 |
+
- `fcddd50` - add coverage-to-smoke/layer-pilot token selector.
|
| 17 |
+
- `dd9a27b` - add dependent TD coverage postprocess job.
|
| 18 |
+
- `6b2473c` - add TD preservation verifier.
|
| 19 |
+
- `bec2d02` - make TD preservation verifier xfer-safe.
|
| 20 |
+
- `993a82d` - support xfer Python in TD verifier.
|
| 21 |
+
- `bfa8a3c` - log full TD monitoring gates.
|
| 22 |
+
- `b23de6a` - update TD production gate state.
|
| 23 |
+
- `276afed` - log layer11 full TD checkpoint.
|
| 24 |
+
- `9c34f2f` - log full TD preservation pass.
|
| 25 |
+
- `957c46b` - add full TD preservation artifacts.
|
| 26 |
+
- `d6e7f20` - add full TD intrinsic eval results.
|
| 27 |
+
- `83d6934` - record full TD eval decision.
|
| 28 |
+
- `86da8f0` - add TD layer11 R17 roundtrip gate.
|
| 29 |
+
- `0143e01` - record TD layer11 R17 roundtrip pass.
|
| 30 |
+
|
| 31 |
+
## TD0 pinned implementation source
|
| 32 |
+
|
| 33 |
+
Pinned upstream Token Distillation source for the next adapter step:
|
| 34 |
+
|
| 35 |
+
- upstream: `https://github.com/konstantinjdobler/token-distillation`
|
| 36 |
+
- commit: `35702b5809599ecd68b7845eca27a0d7b7cec0da`
|
| 37 |
+
- local vendored subset:
|
| 38 |
+
`external/token-distillation/`
|
| 39 |
+
|
| 40 |
+
Important integration note: do not call the package's high-level
|
| 41 |
+
`TokenDistillation.run(...)` entry point for Apertus production. It appends
|
| 42 |
+
tokens with `add_tokens(...)`; our ReTok arm uses an exact merge-extended
|
| 43 |
+
tokenizer with fixed IDs. The Apertus adapter should call the lower-level
|
| 44 |
+
training loop with an explicit `[131072, 148480)` mapping.
|
| 45 |
+
|
| 46 |
+
## Failed handoffs and fixes
|
| 47 |
+
|
| 48 |
+
| Job | State | Cause | Fix |
|
| 49 |
+
|---:|---|---|---|
|
| 50 |
+
| `2349182` | failed | `uenv: command not found` inside xfer batch node | stopped using implicit `uenv` CLI |
|
| 51 |
+
| `2349183` | failed | `/usr/bin/uenv` exists on login but not on xfer compute node | confirmed xfer cannot rely on `uenv` |
|
| 52 |
+
| `2349184` | completed diagnostic | printed xfer PATH; confirmed no `uenv` on node `nid001306` | moved away from uenv |
|
| 53 |
+
| `2349185` | failed diagnostic | xfer system Python is 3.6 and lacks `tokenizers` | tested Python 3.11 path |
|
| 54 |
+
| `2349211` | failed smoke | venv was built on login (`aarch64`) but xfer is `x86_64`, so `tokenizers.abi3.so` could not load | created xfer-built venv |
|
| 55 |
+
| `2349237` | completed setup | created `/iopsstor/scratch/cscs/fffoivos/python_envs/td_coverage_py311_xfer` on xfer; installed `tokenizers==0.22.1` | launcher now defaults to this venv |
|
| 56 |
+
| `2349241` | completed smoke | 50k-token smoke produced coverage JSONL, summary JSON, and snippet index | proved launcher and artifact path |
|
| 57 |
+
| `2349259` | completed smoke | 50k-token smoke with `PROGRESS_TOKEN_INTERVAL=10000` printed progress JSON lines | proved long-run health logging |
|
| 58 |
+
| `2349342` | failed after full scan | strict prepass found 9 non-NFC docs in the first 2B-token scan and refused to emit coverage | added CPU-only JSONL NFC normalizer and reran prepass on `bulk_mix.nfc.jsonl` |
|
| 59 |
+
|
| 60 |
+
## First full run attempt
|
| 61 |
+
|
| 62 |
+
Job: `2349342`
|
| 63 |
+
|
| 64 |
+
Command shape:
|
| 65 |
+
|
| 66 |
+
```bash
|
| 67 |
+
cd /iopsstor/scratch/cscs/fffoivos/repo/03_apertus_extension_and_embedding_adaptation/03_4_implementation_experiments/init_bakeoff/token_distillation
|
| 68 |
+
sbatch --export=ALL,\
|
| 69 |
+
OUTPUT_DIR=/iopsstor/scratch/cscs/fffoivos/token_distillation/coverage_2b_modern_20260523T012000Z_r2,\
|
| 70 |
+
INPUT_JSONL=/iopsstor/scratch/cscs/fffoivos/cpt_corpus/bulk_mix.jsonl,\
|
| 71 |
+
TARGET_EXTENDED_TOKENS=2000000000,\
|
| 72 |
+
SNIPPETS_PER_TOKEN=100,\
|
| 73 |
+
PROGRESS_TOKEN_INTERVAL=5000000 \
|
| 74 |
+
td_coverage_prepass_xfer.sbatch
|
| 75 |
+
```
|
| 76 |
+
|
| 77 |
+
Stable output directory:
|
| 78 |
+
|
| 79 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/coverage_2b_modern_20260523T012000Z_r2`
|
| 80 |
+
|
| 81 |
+
Expected artifacts:
|
| 82 |
+
|
| 83 |
+
- `td_coverage_prepass.jsonl`
|
| 84 |
+
- `td_coverage_summary.json`
|
| 85 |
+
- `td_snippet_index/snippets.jsonl`
|
| 86 |
+
|
| 87 |
+
Health at first check:
|
| 88 |
+
|
| 89 |
+
- Slurm state: `RUNNING` on `xfer`, node `nid001154`.
|
| 90 |
+
- Elapsed: `00:01:35`.
|
| 91 |
+
- `sstat` RSS: `2581400K`.
|
| 92 |
+
- Progress lines:
|
| 93 |
+
- `tokens_scanned=5042268`, `docs_seen=3244`
|
| 94 |
+
- `tokens_scanned=10003445`, `docs_seen=6118`
|
| 95 |
+
|
| 96 |
+
Approximate early throughput from progress lines: about 100k extended tokens/s,
|
| 97 |
+
so the 2B scan should be on the order of 5-6 hours if throughput remains
|
| 98 |
+
stable. This is an estimate, not a completion promise.
|
| 99 |
+
|
| 100 |
+
Health at 2026-05-22T23:29Z:
|
| 101 |
+
|
| 102 |
+
- Slurm state: `RUNNING` on `xfer`, node `nid001154`.
|
| 103 |
+
- Elapsed: `00:26:53`.
|
| 104 |
+
- Latest progress: `tokens_scanned=200000773`, `docs_seen=146900`.
|
| 105 |
+
- Stderr: empty.
|
| 106 |
+
- No final artifacts yet; `td_coverage_summary.json` is written only at
|
| 107 |
+
completion.
|
| 108 |
+
|
| 109 |
+
Health at 2026-05-22T23:37Z:
|
| 110 |
+
|
| 111 |
+
- Slurm state: `RUNNING` on `xfer`, node `nid001154`.
|
| 112 |
+
- Elapsed: `00:35:07`.
|
| 113 |
+
- Latest progress: `tokens_scanned=265000226`, `docs_seen=201079`.
|
| 114 |
+
- Stderr: empty.
|
| 115 |
+
|
| 116 |
+
Health at 2026-05-22T23:50Z:
|
| 117 |
+
|
| 118 |
+
- Slurm state: `RUNNING` on `xfer`, node `nid001154`.
|
| 119 |
+
- Elapsed: `00:48:28`.
|
| 120 |
+
- Latest progress: `tokens_scanned=365000047`, `docs_seen=285789`.
|
| 121 |
+
- Stderr: empty.
|
| 122 |
+
- No final artifacts yet.
|
| 123 |
+
- Dependent CPU-only postprocess queued as job `2349550`
|
| 124 |
+
(`afterok:2349342`). It will render `TD_COVERAGE_SUMMARY.md`, write
|
| 125 |
+
`TD_GATE_DECISION.json`, and create `pilot_selection/` only if the coverage
|
| 126 |
+
gate recommends TD.
|
| 127 |
+
|
| 128 |
+
Final state:
|
| 129 |
+
|
| 130 |
+
- Slurm state: `FAILED`, elapsed `04:14:40`, exit `1:0`.
|
| 131 |
+
- Last progress before failure:
|
| 132 |
+
`tokens_scanned=1995095832`, `docs_seen=1641638`,
|
| 133 |
+
`chars_seen=7468063507`.
|
| 134 |
+
- Error:
|
| 135 |
+
`Refusing to emit TD coverage: 9 docs were not NFC. Run on the post-normalize corpus or pass --no-require-nfc for a diagnostic-only scan.`
|
| 136 |
+
- The dependent postprocess job `2349550` was left with
|
| 137 |
+
`DependencyNeverSatisfied` and was cancelled.
|
| 138 |
+
|
| 139 |
+
Interpretation: this is a corpus invariant failure, not a TD coverage result.
|
| 140 |
+
Do not use `--no-require-nfc` for the decision gate.
|
| 141 |
+
|
| 142 |
+
## NFC JSONL repair and rerun chain
|
| 143 |
+
|
| 144 |
+
Added:
|
| 145 |
+
|
| 146 |
+
- `corpus_build/normalize_jsonl_nfc.py`
|
| 147 |
+
- `corpus_build/normalize_jsonl_nfc.sbatch`
|
| 148 |
+
|
| 149 |
+
Local and Clariden validation:
|
| 150 |
+
|
| 151 |
+
- `python3 -m py_compile corpus_build/normalize_jsonl_nfc.py`
|
| 152 |
+
- `bash check_cpu_only_slurm.sh` passes with the JSONL normalizer included.
|
| 153 |
+
- Tiny local smoke confirmed only non-NFC text rows are rewritten.
|
| 154 |
+
|
| 155 |
+
Normalization job:
|
| 156 |
+
|
| 157 |
+
- Job: `2351373`
|
| 158 |
+
- Partition: `xfer`
|
| 159 |
+
- Input: `/iopsstor/scratch/cscs/fffoivos/cpt_corpus/bulk_mix.jsonl`
|
| 160 |
+
- Output: `/iopsstor/scratch/cscs/fffoivos/cpt_corpus/bulk_mix.nfc.jsonl`
|
| 161 |
+
- Manifest: `/iopsstor/scratch/cscs/fffoivos/cpt_corpus/bulk_mix.nfc.manifest.json`
|
| 162 |
+
- State: `COMPLETED`, elapsed `00:08:21`.
|
| 163 |
+
|
| 164 |
+
Manifest highlights:
|
| 165 |
+
|
| 166 |
+
- rows: `5,754,172`
|
| 167 |
+
- non-NFC docs before normalization: `37`
|
| 168 |
+
- changed docs: `37`
|
| 169 |
+
- missing/non-string text rows: `0`
|
| 170 |
+
- input bytes: `43,832,960,668`
|
| 171 |
+
- output bytes: `43,832,959,909`
|
| 172 |
+
- output SHA-256:
|
| 173 |
+
`205cb5ed80a6150064b290aaa0457463daf6c0e514e6c27b9ea3da28a479a8af`
|
| 174 |
+
- sampled changed rows are from `code_codeparrot_clean`.
|
| 175 |
+
|
| 176 |
+
Strict rerun chain:
|
| 177 |
+
|
| 178 |
+
| Job | Purpose | State at launch |
|
| 179 |
+
|---:|---|---|
|
| 180 |
+
| `2351374` | TD coverage prepass on `bulk_mix.nfc.jsonl` | running on `xfer` |
|
| 181 |
+
| `2351375` | TD coverage postprocess / gate | pending `afterok:2351374` |
|
| 182 |
+
|
| 183 |
+
Rerun output directory:
|
| 184 |
+
|
| 185 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/coverage_2b_modern_20260523T032424Z_nfc`
|
| 186 |
+
|
| 187 |
+
## TD smoke wrapper readiness
|
| 188 |
+
|
| 189 |
+
Added `train_retok_td.py` and `train_retok_td.sbatch` for the second gate. They
|
| 190 |
+
are not launched automatically; only use them if the full coverage prepass
|
| 191 |
+
recommends TD.
|
| 192 |
+
|
| 193 |
+
Clariden dry-run validation on the completed 50k smoke artifacts:
|
| 194 |
+
|
| 195 |
+
- Selection artifact:
|
| 196 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/td_wrapper_dry_run_20260523_low/selection/td_pilot_token_selection.json`
|
| 197 |
+
- Dry-run manifest:
|
| 198 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/td_wrapper_dry_run_20260523_low/dry_run/retok_td_manifest.json`
|
| 199 |
+
- Result: loaded base and student tokenizers, grouped one real prepass snippet,
|
| 200 |
+
wrote manifest, and exited before model load/training.
|
| 201 |
+
- Note: this used `--min-status low_lt20` only to exercise the wrapper against
|
| 202 |
+
the tiny 50k diagnostic prepass. The real TD gate remains `enough_25` or
|
| 203 |
+
better on the full 2B prepass.
|
| 204 |
+
|
| 205 |
+
## Decision gate after completion
|
| 206 |
+
|
| 207 |
+
Read `td_coverage_summary.json`:
|
| 208 |
+
|
| 209 |
+
- `recommended_next_step = run_full_td_100`: proceed to TD smoke/layer pilot.
|
| 210 |
+
- `recommended_next_step = run_td_25_with_flagged_tail`: run the paper-fast TD
|
| 211 |
+
setting and keep tail-token strategy explicit.
|
| 212 |
+
- `recommended_next_step = do_not_launch_full_td_inspect_coverage`: do not spend
|
| 213 |
+
GPU time; inspect tokenizer/corpus coverage first.
|
| 214 |
+
|
| 215 |
+
## Strict full-2B coverage result
|
| 216 |
+
|
| 217 |
+
The strict rerun completed on the normalized JSONL:
|
| 218 |
+
|
| 219 |
+
- Prepass job: `2351374`, partition `xfer`, state `COMPLETED`,
|
| 220 |
+
elapsed `04:09:23`.
|
| 221 |
+
- Postprocess job: `2351375`, partition `xfer`, state `COMPLETED`,
|
| 222 |
+
elapsed `00:00:04`.
|
| 223 |
+
- Coverage directory:
|
| 224 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/coverage_2b_modern_20260523T032424Z_nfc`
|
| 225 |
+
- Gate file:
|
| 226 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/coverage_2b_modern_20260523T032424Z_nfc/TD_GATE_DECISION.json`
|
| 227 |
+
|
| 228 |
+
Gate decision:
|
| 229 |
+
|
| 230 |
+
```json
|
| 231 |
+
{
|
| 232 |
+
"recommended_next_step": "run_full_td_100",
|
| 233 |
+
"selection_status": "created",
|
| 234 |
+
"enough_100_fraction": 0.9982192095588235,
|
| 235 |
+
"enough_25_fraction": 0.9990808823529411,
|
| 236 |
+
"low_lt25_count": 16,
|
| 237 |
+
"tokens_scanned": 2000000000,
|
| 238 |
+
"target_extended_tokens": 2000000000
|
| 239 |
+
}
|
| 240 |
+
```
|
| 241 |
+
|
| 242 |
+
Summary:
|
| 243 |
+
|
| 244 |
+
- Input corpus: `bulk_mix.nfc.jsonl`.
|
| 245 |
+
- Extended tokens scanned: exactly `2,000,000,000`.
|
| 246 |
+
- Docs used: `1,645,852`.
|
| 247 |
+
- `require_nfc`: true.
|
| 248 |
+
- `non_nfc_docs`: 0.
|
| 249 |
+
- Status counts:
|
| 250 |
+
- `enough_100`: 17,377 tokens (99.82%).
|
| 251 |
+
- `enough_25`: 15 tokens (0.09%).
|
| 252 |
+
- `low_20_24`: 2 tokens.
|
| 253 |
+
- `low_lt20`: 3 tokens.
|
| 254 |
+
- `zero`: 11 tokens.
|
| 255 |
+
- Action counts:
|
| 256 |
+
- `td_100`: 17,377 tokens.
|
| 257 |
+
- `td_25`: 15 tokens.
|
| 258 |
+
- `keep_retok`: 5 tokens.
|
| 259 |
+
- `inspect`: 11 tokens.
|
| 260 |
+
|
| 261 |
+
Pilot selections were created under `pilot_selection/`:
|
| 262 |
+
|
| 263 |
+
- `smoke_token_ids.txt`: 512 tokens.
|
| 264 |
+
- `layer_pilot_token_ids.txt`: 2,048 tokens.
|
| 265 |
+
|
| 266 |
+
## First TD smoke attempt
|
| 267 |
+
|
| 268 |
+
Launched a bounded one-GPU last-layer smoke, not full TD:
|
| 269 |
+
|
| 270 |
+
- Job: `2353063`
|
| 271 |
+
- Partition: `normal`
|
| 272 |
+
- Output directory:
|
| 273 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/retok_td_smoke_last_layer_20260523T074639Z`
|
| 274 |
+
- Settings: `TARGET_LAYER=-1`, `SNIPPETS_PER_TOKEN=25`, `EPOCHS=1`,
|
| 275 |
+
`BATCH_SIZE=16`.
|
| 276 |
+
|
| 277 |
+
Result:
|
| 278 |
+
|
| 279 |
+
- State: `FAILED`
|
| 280 |
+
- Elapsed: `00:00:29`
|
| 281 |
+
- Failure:
|
| 282 |
+
`token 140716: no snippets contain its base phrase after base tokenization`
|
| 283 |
+
|
| 284 |
+
Inspection showed token `140716` is an unstable byte-level/noisy token:
|
| 285 |
+
|
| 286 |
+
- `raw_token`: `"âľ"`
|
| 287 |
+
- `token_string`: `"�"`
|
| 288 |
+
- `base_subtoken_ids`: `[66122]`
|
| 289 |
+
- `extended_firings`: `132607`
|
| 290 |
+
- `status`: `enough_100`
|
| 291 |
+
|
| 292 |
+
The selected snippets' actual surfaces were assorted symbols, with different
|
| 293 |
+
base-token spans. This is not a TD training result; it is a wrapper/selection
|
| 294 |
+
invariant failure for unstable token mappings. These tokens should be logged,
|
| 295 |
+
skipped, and preserved at their ReTok initialization rather than crashing a
|
| 296 |
+
bounded smoke.
|
| 297 |
+
|
| 298 |
+
## TD wrapper hardening
|
| 299 |
+
|
| 300 |
+
Updated `train_retok_td.py` and `train_retok_td.sbatch` so a selected token is
|
| 301 |
+
trained only if enough snippets reproduce its static base phrase under the base
|
| 302 |
+
tokenizer. Tokens that fail this check are recorded in
|
| 303 |
+
`retok_td_manifest.json` under `skipped_tokens` and remain frozen/preserved at
|
| 304 |
+
their existing ReTok initialization.
|
| 305 |
+
|
| 306 |
+
Default smoke behavior:
|
| 307 |
+
|
| 308 |
+
- `MIN_ACCEPTED_SNIPPETS_PER_TOKEN=$SNIPPETS_PER_TOKEN`
|
| 309 |
+
- `MIN_TRAINED_TOKEN_FRACTION=0.90`
|
| 310 |
+
|
| 311 |
+
This means a smoke can tolerate a small number of unstable/noisy selected
|
| 312 |
+
tokens, but fails before model load if too much of the selection is untrainable.
|
| 313 |
+
|
| 314 |
+
Validation:
|
| 315 |
+
|
| 316 |
+
- Local: `python3 -m py_compile train_retok_td.py`
|
| 317 |
+
- Clariden with job runtime env:
|
| 318 |
+
`uenv run pytorch/v2.9.1:v2 --view=default -- python3 -m py_compile train_retok_td.py`
|
| 319 |
+
|
| 320 |
+
Relaunched bounded smoke:
|
| 321 |
+
|
| 322 |
+
- Job: `2353091`
|
| 323 |
+
- Output directory:
|
| 324 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/retok_td_smoke_last_layer_20260523T075520Z`
|
| 325 |
+
- Initial state: pending on `normal`.
|
| 326 |
+
|
| 327 |
+
Result:
|
| 328 |
+
|
| 329 |
+
- State: `FAILED`
|
| 330 |
+
- Elapsed: `00:06:33`
|
| 331 |
+
- Allocation note: requested `gres/gpu=1`, but Clariden allocated the full
|
| 332 |
+
node (`gres/gpu=4`). Do not launch larger single-process TD jobs in this
|
| 333 |
+
shape without packing work across the node or accepting the inefficiency.
|
| 334 |
+
- The wrapper and model path succeeded:
|
| 335 |
+
- 510/512 selected tokens were trainable.
|
| 336 |
+
- 2 unstable byte-level/noisy tokens were skipped and preserved.
|
| 337 |
+
- Apertus/ReTok loaded and entered real training.
|
| 338 |
+
- Failure mode: CUDA OOM at step 471/796 during backward.
|
| 339 |
+
- OOM details:
|
| 340 |
+
- Tried to allocate `2.47 GiB`.
|
| 341 |
+
- GPU capacity `95.00 GiB`, free `1.83 GiB`.
|
| 342 |
+
- PyTorch allocated `76.45 GiB`, reserved-unallocated `15.94 GiB`.
|
| 343 |
+
- Error recommended `PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True`.
|
| 344 |
+
|
| 345 |
+
Interpretation: this is not a TD token-selection failure. It is the memory cost
|
| 346 |
+
of running upstream TD on Apertus-8B with `output_hidden_states=True`,
|
| 347 |
+
MSE-on-hiddens, and the untied-output CE path at `BATCH_SIZE=16`.
|
| 348 |
+
|
| 349 |
+
Follow-up fix:
|
| 350 |
+
|
| 351 |
+
- Default `BATCH_SIZE` for the sbatch reduced from `16` to `8`.
|
| 352 |
+
- `PYTORCH_ALLOC_CONF` defaults to `expandable_segments:True`.
|
| 353 |
+
- Next rerun should stay bounded and should not expand beyond the smoke until
|
| 354 |
+
the scheduler packing issue is handled.
|
| 355 |
+
|
| 356 |
+
## Batch-8 smoke completion
|
| 357 |
+
|
| 358 |
+
Relaunched the same bounded 512-token last-layer smoke with batch 8:
|
| 359 |
+
|
| 360 |
+
- Job: `2353128`
|
| 361 |
+
- Output directory:
|
| 362 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/retok_td_smoke_last_layer_20260523T080555Z_bs8`
|
| 363 |
+
- State: `COMPLETED`
|
| 364 |
+
- Elapsed: `00:11:09`
|
| 365 |
+
- Allocation: full node despite one-GPU request
|
| 366 |
+
(`AllocTRES=cpu=288,gres/gpu=4,mem=450G,node=1`).
|
| 367 |
+
- Runtime settings:
|
| 368 |
+
- `TARGET_LAYER=-1`
|
| 369 |
+
- `SNIPPETS_PER_TOKEN=25`
|
| 370 |
+
- `BATCH_SIZE=8`
|
| 371 |
+
- `MIN_TRAINED_TOKEN_FRACTION=0.90`
|
| 372 |
+
- allocator config: `expandable_segments:True`
|
| 373 |
+
|
| 374 |
+
Manifest:
|
| 375 |
+
|
| 376 |
+
```json
|
| 377 |
+
{
|
| 378 |
+
"requested_token_count": 512,
|
| 379 |
+
"trained_token_count": 510,
|
| 380 |
+
"skipped_token_count": 2,
|
| 381 |
+
"trained_token_fraction": 0.99609375,
|
| 382 |
+
"batch_size": 8,
|
| 383 |
+
"completed": true,
|
| 384 |
+
"elapsed_seconds": 657.6161992549896
|
| 385 |
+
}
|
| 386 |
+
```
|
| 387 |
+
|
| 388 |
+
Output files include:
|
| 389 |
+
|
| 390 |
+
- `model-00001-of-00004.safetensors`
|
| 391 |
+
- `model-00002-of-00004.safetensors`
|
| 392 |
+
- `model-00003-of-00004.safetensors`
|
| 393 |
+
- `model-00004-of-00004.safetensors`
|
| 394 |
+
- `model.safetensors.index.json`
|
| 395 |
+
- tokenizer/config files
|
| 396 |
+
- `retok_td_manifest.json`
|
| 397 |
+
|
| 398 |
+
Smoke conclusion:
|
| 399 |
+
|
| 400 |
+
- The ReTok + TD wrapper can train and save an Apertus-8B HF checkpoint using
|
| 401 |
+
the vendored TD library path.
|
| 402 |
+
- For Apertus-8B, `BATCH_SIZE=16` is too close to memory limits; batch 8 plus
|
| 403 |
+
expandable segments works for the 512-token smoke.
|
| 404 |
+
- Scheduler packing remains unresolved: larger TD experiments should not be
|
| 405 |
+
launched as single-process jobs that burn a full four-GPU node unless we
|
| 406 |
+
deliberately pack independent TD work into the same allocation or decide that
|
| 407 |
+
the cost is acceptable.
|
| 408 |
+
|
| 409 |
+
## Layer-pilot preparation
|
| 410 |
+
|
| 411 |
+
Checked the vendored package for a layer-suggestion tool. There is no separate
|
| 412 |
+
tool in the pinned implementation; the actionable upstream guidance is the
|
| 413 |
+
README note that target layers around the one-third mark can perform better
|
| 414 |
+
than the last layer.
|
| 415 |
+
|
| 416 |
+
Layer-pilot decision:
|
| 417 |
+
|
| 418 |
+
- Candidate A: `target_layer=-1` (paper-default last layer).
|
| 419 |
+
- Candidate B: `target_layer=11` (one-third-depth suggestion for Apertus-8B's
|
| 420 |
+
32 transformer layers).
|
| 421 |
+
- Do not add a Candidate C unless a real Apertus-specific probe produces a
|
| 422 |
+
well-defined `L*`; do not invent one just to satisfy the plan wording.
|
| 423 |
+
|
| 424 |
+
Added `train_retok_td_layer_pilot_packed.sbatch` to run these candidates inside
|
| 425 |
+
one full-node allocation on separate GPUs. This addresses the observed
|
| 426 |
+
Clariden behavior where one-GPU requests are allocated/billed as full 4-GPU
|
| 427 |
+
nodes.
|
| 428 |
+
|
| 429 |
+
## Packed layer pilot completion
|
| 430 |
+
|
| 431 |
+
Launched the packed layer pilot as a bounded two-candidate run:
|
| 432 |
+
|
| 433 |
+
- Job: `2353172`
|
| 434 |
+
- Output root:
|
| 435 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/retok_td_layer_pilot_20260523T082252Z`
|
| 436 |
+
- Candidates:
|
| 437 |
+
- `target_layer=-1`, label `last`, GPU 0.
|
| 438 |
+
- `target_layer=11`, label `layer11`, GPU 1.
|
| 439 |
+
- Selection: `1,024` requested tokens, `50` snippets per token,
|
| 440 |
+
`BATCH_SIZE=8`.
|
| 441 |
+
- State: `COMPLETED`
|
| 442 |
+
- Elapsed: `00:42:25`
|
| 443 |
+
- Allocation: full node
|
| 444 |
+
(`AllocTRES=billing=288,cpu=288,energy=3916310,gres/gpu=4,mem=450G,node=1`).
|
| 445 |
+
|
| 446 |
+
Top-level manifest:
|
| 447 |
+
|
| 448 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/retok_td_layer_pilot_20260523T082252Z/layer_pilot_manifest.json`
|
| 449 |
+
|
| 450 |
+
Manifest highlights:
|
| 451 |
+
|
| 452 |
+
| Target layer | Label | Requested | Trained | Skipped | Trained fraction | Elapsed |
|
| 453 |
+
|---:|---|---:|---:|---:|---:|---:|
|
| 454 |
+
| `-1` | `last` | 1,024 | 1,020 | 4 | 0.9961 | 2,533.7s |
|
| 455 |
+
| `11` | `layer11` | 1,024 | 1,020 | 4 | 0.9961 | 1,966.9s |
|
| 456 |
+
|
| 457 |
+
Both candidates saved HF checkpoints with tokenizer/config files and
|
| 458 |
+
`model.safetensors.index.json`.
|
| 459 |
+
|
| 460 |
+
Training-log note: `last` had low, stable reported loss around `0.017-0.022`.
|
| 461 |
+
`layer11` completed but showed large intermittent loss spikes and a high running
|
| 462 |
+
loss. This is a warning sign, not the selection criterion. The layer choice must
|
| 463 |
+
come from heldout Greek BPC/NLL plus D1/D2/D4/D5 new-token diagnostics against
|
| 464 |
+
the same ReTok baseline.
|
| 465 |
+
|
| 466 |
+
## Packed intrinsic eval preparation
|
| 467 |
+
|
| 468 |
+
Added:
|
| 469 |
+
|
| 470 |
+
- `eval/run_td_pilot_intrinsics_packed.sbatch`
|
| 471 |
+
- `eval/summarize_td_pilot_intrinsics.py`
|
| 472 |
+
|
| 473 |
+
Purpose: evaluate the three relevant HF checkpoints in one full-node allocation:
|
| 474 |
+
|
| 475 |
+
- ReTok baseline:
|
| 476 |
+
`/iopsstor/scratch/cscs/fffoivos/init_checkpoints/modern_only_148480/retok`
|
| 477 |
+
- TD last-layer pilot:
|
| 478 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/retok_td_layer_pilot_20260523T082252Z/last`
|
| 479 |
+
- TD layer-11 pilot:
|
| 480 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/retok_td_layer_pilot_20260523T082252Z/layer11`
|
| 481 |
+
|
| 482 |
+
Heldout eval file:
|
| 483 |
+
|
| 484 |
+
`/iopsstor/scratch/cscs/fffoivos/cpt_corpus/heldout/cpt_greek_heldout_500_20260522.jsonl`
|
| 485 |
+
|
| 486 |
+
The packed eval runs:
|
| 487 |
+
|
| 488 |
+
- `compute_tokenizer_fair_metrics.py` for BPC/NLL/compression/STRR.
|
| 489 |
+
- `compute_new_token_diagnostics.py` for D1/D2/D4/D5 plus embedding-space
|
| 490 |
+
D6/D7 checks.
|
| 491 |
+
|
| 492 |
+
This keeps the TD layer decision bounded and avoids three separate full-node
|
| 493 |
+
eval allocations.
|
| 494 |
+
|
| 495 |
+
## Packed intrinsic eval result
|
| 496 |
+
|
| 497 |
+
Submitted packed eval:
|
| 498 |
+
|
| 499 |
+
- Job: `2353771`
|
| 500 |
+
- Output root:
|
| 501 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/td_pilot_intrinsics_20260523T091637Z`
|
| 502 |
+
- State: `COMPLETED`
|
| 503 |
+
- Elapsed: `00:03:09`
|
| 504 |
+
- Allocation: full node
|
| 505 |
+
(`AllocTRES=billing=288,cpu=288,energy=296006,gres/gpu=4,mem=450G,node=1`).
|
| 506 |
+
|
| 507 |
+
Local copies of the compact result:
|
| 508 |
+
|
| 509 |
+
- `eval/td_pilot_intrinsics_20260523T091637Z/TD_PILOT_INTRINSICS_SUMMARY.md`
|
| 510 |
+
- `eval/td_pilot_intrinsics_20260523T091637Z/td_pilot_intrinsics_summary.json`
|
| 511 |
+
- `eval/td_pilot_intrinsics_20260523T091637Z/model_spec.tsv`
|
| 512 |
+
|
| 513 |
+
Primary metrics:
|
| 514 |
+
|
| 515 |
+
| Arm | BPC | Delta vs ReTok | D1 mean rank | D1 top1 | D1 top5 | D2 new mass | D4 top1-new | D5 greedy-new |
|
| 516 |
+
|---|---:|---:|---:|---:|---:|---:|---:|---:|
|
| 517 |
+
| ReTok | 2.9503 | 0.0000 | 3868.27 | 0.0065 | 0.0231 | 0.9821 | 0.9992 | 1.0000 |
|
| 518 |
+
| TD last | 2.7830 | -0.1673 | 3294.05 | 0.0146 | 0.0383 | 0.9796 | 0.9991 | 1.0000 |
|
| 519 |
+
| TD layer 11 | 2.7753 | -0.1750 | 3263.69 | 0.0148 | 0.0385 | 0.9795 | 0.9991 | 1.0000 |
|
| 520 |
+
|
| 521 |
+
Interpretation:
|
| 522 |
+
|
| 523 |
+
- Both TD pilot checkpoints materially improve heldout BPC and D1 rank over the
|
| 524 |
+
ReTok baseline.
|
| 525 |
+
- `target_layer=11` is slightly better than `target_layer=-1` on BPC and D1.
|
| 526 |
+
- The earlier `layer11` training-loss spikes did not show up as output-norm,
|
| 527 |
+
D4, or D5 instability in this intrinsic eval.
|
| 528 |
+
- Selected next TD target layer for the full-token challenger: `target_layer=11`.
|
| 529 |
+
|
| 530 |
+
Resource calibration:
|
| 531 |
+
|
| 532 |
+
- `layer11` pilot runtime was about `1,966.9s` for `1,020` trained tokens at
|
| 533 |
+
`50` snippets per token.
|
| 534 |
+
- A naive all-token `100`-snippet run would be roughly `18-19` wall hours on
|
| 535 |
+
one GPU, beyond `normal`'s 12h limit and wasteful on Clariden's 4-GPU node
|
| 536 |
+
allocations.
|
| 537 |
+
- The next full-token challenger should therefore start with the paper-fast
|
| 538 |
+
`25`-snippet setting, not the `100`-snippet setting. A later `100`-snippet or
|
| 539 |
+
`50`-snippet run is only justified if the fast full-token TD checkpoint clears
|
| 540 |
+
the gates but leaves quality ambiguous.
|
| 541 |
+
|
| 542 |
+
Selection artifact update:
|
| 543 |
+
|
| 544 |
+
- Regenerated `pilot_selection/` with an added all-eligible ID list:
|
| 545 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/coverage_2b_modern_20260523T032424Z_nfc/pilot_selection/full_td_token_ids.txt`
|
| 546 |
+
- Full-token eligible count: `17,392`.
|
| 547 |
+
|
| 548 |
+
## Full-token 25-snippet TD launch
|
| 549 |
+
|
| 550 |
+
Launched the first full-token TD challenger using the paper-fast snippet budget:
|
| 551 |
+
|
| 552 |
+
- Job: `2353960`
|
| 553 |
+
- Output root:
|
| 554 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/retok_td_full25_layers_20260523T092602Z`
|
| 555 |
+
- Walltime: `10:00:00`
|
| 556 |
+
- Token IDs:
|
| 557 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/coverage_2b_modern_20260523T032424Z_nfc/pilot_selection/full_td_token_ids.txt`
|
| 558 |
+
- Coverage JSONL:
|
| 559 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/coverage_2b_modern_20260523T032424Z_nfc/td_coverage_prepass.jsonl`
|
| 560 |
+
- Snippets JSONL:
|
| 561 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/coverage_2b_modern_20260523T032424Z_nfc/td_snippet_index/snippets.jsonl`
|
| 562 |
+
- Candidates packed into the same allocation:
|
| 563 |
+
- `target_layer=-1`, label `last`, GPU 0.
|
| 564 |
+
- `target_layer=11`, label `layer11`, GPU 1.
|
| 565 |
+
- Runtime settings:
|
| 566 |
+
- `SNIPPETS_PER_TOKEN=25`
|
| 567 |
+
- `MIN_ACCEPTED_SNIPPETS_PER_TOKEN=25`
|
| 568 |
+
- `MAX_SELECTED_TOKENS=0` (full token list)
|
| 569 |
+
- `BATCH_SIZE=8`
|
| 570 |
+
- `MIN_TRAINED_TOKEN_FRACTION=0.99`
|
| 571 |
+
|
| 572 |
+
Startup health:
|
| 573 |
+
|
| 574 |
+
- Job state: `RUNNING` on `nid006119`.
|
| 575 |
+
- GPUs visible: `0,1,2,3`; training processes started on GPUs 0 and 1.
|
| 576 |
+
- Early process check showed both Python workers alive with GPU contexts
|
| 577 |
+
allocated (`~6.4 GiB` each) and high CPU during snippet preparation.
|
| 578 |
+
|
| 579 |
+
## Full-token run babysitting and queued gates
|
| 580 |
+
|
| 581 |
+
Live checks on 2026-05-23 confirmed the full-token TD job has not restarted:
|
| 582 |
+
|
| 583 |
+
- Slurm job: `2353960`
|
| 584 |
+
- `scontrol` field: `Restarts=0`
|
| 585 |
+
- Node: `nid006119`
|
| 586 |
+
- Active processes:
|
| 587 |
+
- `target_layer=-1` on GPU 0
|
| 588 |
+
- `target_layer=11` on GPU 1
|
| 589 |
+
- GPU health check showed GPUs 0 and 1 saturated, while GPUs 2 and 3 were idle.
|
| 590 |
+
This is expected for the current two-candidate packed run; no extra CPU-only
|
| 591 |
+
work was placed on GPU nodes.
|
| 592 |
+
|
| 593 |
+
Progress snapshots:
|
| 594 |
+
|
| 595 |
+
| UTC time | last progress | last ETA | layer11 progress | layer11 ETA |
|
| 596 |
+
|---|---:|---:|---:|---:|
|
| 597 |
+
| 12:22 | 27,528 / 54,303 (50.7%) | 2:44:02 | 35,172 / 54,303 (64.8%) | 1:34:03 |
|
| 598 |
+
| 12:27 | 28,322 / 54,303 (52.2%) | 2:36:34 | 36,186 / 54,303 (66.6%) | 1:29:37 |
|
| 599 |
+
| 12:32 | 29,114 / 54,303 (53.6%) | 2:41:20 | 37,204 / 54,303 (68.5%) | 1:21:46 |
|
| 600 |
+
| 12:37 | 29,907 / 54,303 (55.1%) | 2:36:01 | 38,228 / 54,303 (70.4%) | 1:17:50 |
|
| 601 |
+
| 12:42 | 30,704 / 54,303 (56.5%) | 2:29:37 | 39,244 / 54,303 (72.3%) | 1:18:35 |
|
| 602 |
+
| 12:47 | 31,497 / 54,303 (58.0%) | 2:22:13 | 40,267 / 54,303 (74.2%) | 1:08:12 |
|
| 603 |
+
| 12:53 | 32,288 / 54,303 (59.5%) | 2:16:11 | 41,286 / 54,303 (76.0%) | 1:03:58 |
|
| 604 |
+
| 12:58 | 33,081 / 54,303 (60.9%) | 2:13:56 | 42,304 / 54,303 (77.9%) | 1:00:16 |
|
| 605 |
+
| 13:03 | 33,877 / 54,303 (62.4%) | 2:10:12 | 43,322 / 54,303 (79.8%) | 0:52:36 |
|
| 606 |
+
| 13:08 | 34,672 / 54,303 (63.8%) | 2:01:25 | 44,338 / 54,303 (81.6%) | 0:47:20 |
|
| 607 |
+
| 13:13 | 35,464 / 54,303 (65.3%) | 1:58:48 | 45,360 / 54,303 (83.5%) | 0:44:02 |
|
| 608 |
+
| 13:18 | 36,258 / 54,303 (66.8%) | 1:51:51 | 46,378 / 54,303 (85.4%) | 0:37:28 |
|
| 609 |
+
| 13:23 | 37,050 / 54,303 (68.2%) | 1:52:41 | 47,397 / 54,303 (87.3%) | 0:33:31 |
|
| 610 |
+
| 13:28 | 37,844 / 54,303 (69.7%) | 1:41:42 | 48,415 / 54,303 (89.2%) | 0:28:47 |
|
| 611 |
+
| 13:33 | 38,643 / 54,303 (71.2%) | 1:38:45 | 49,425 / 54,303 (91.0%) | 0:25:02 |
|
| 612 |
+
| 13:38 | 39,440 / 54,303 (72.6%) | 1:32:13 | 50,446 / 54,303 (92.9%) | 0:19:23 |
|
| 613 |
+
| 13:43 | 40,236 / 54,303 (74.1%) | 1:25:29 | 51,465 / 54,303 (94.8%) | 0:14:26 |
|
| 614 |
+
| 13:48 | 41,033 / 54,303 (75.6%) | 1:25:07 | 52,485 / 54,303 (96.7%) | 0:08:24 |
|
| 615 |
+
| 13:53 | 41,826 / 54,303 (77.0%) | 1:18:51 | 53,501 / 54,303 (98.5%) | 0:03:49 |
|
| 616 |
+
| 13:58 | 42,623 / 54,303 (78.5%) | 1:12:21 | 54,303 / 54,303 (100.0%) | 0:00:00 |
|
| 617 |
+
|
| 618 |
+
No `model.safetensors*` checkpoint files existed yet at these snapshots. The
|
| 619 |
+
manifests had already been written by the wrapper:
|
| 620 |
+
|
| 621 |
+
- `last/retok_td_manifest.json`
|
| 622 |
+
- `layer11/retok_td_manifest.json`
|
| 623 |
+
|
| 624 |
+
Both manifests report:
|
| 625 |
+
|
| 626 |
+
- `trained_token_count = 17,377`
|
| 627 |
+
- `skipped_token_count = 15`
|
| 628 |
+
- `snippets_per_token = 25`
|
| 629 |
+
- `min_accepted_snippets_per_token = 25`
|
| 630 |
+
|
| 631 |
+
## Preservation verifier hardening
|
| 632 |
+
|
| 633 |
+
Added and then hardened the post-TD preservation verifier:
|
| 634 |
+
|
| 635 |
+
- Commit `6b2473c` - add `verify_td_preservation.py` and
|
| 636 |
+
`verify_td_preservation_xfer.sbatch`.
|
| 637 |
+
- Commit `bec2d02` - remove the torch dependency by parsing Safetensors
|
| 638 |
+
directly, so the check can run on `xfer` as CPU-only work.
|
| 639 |
+
- Commit `993a82d` - make the verifier compatible with `xfer`'s Python version
|
| 640 |
+
by replacing `int | None` annotations with `Optional[int]`.
|
| 641 |
+
|
| 642 |
+
The verifier now checks, from checkpoint artifacts only:
|
| 643 |
+
|
| 644 |
+
- state-dict key equality;
|
| 645 |
+
- tensor shape and dtype equality;
|
| 646 |
+
- exact byte preservation for every non-embedding tensor;
|
| 647 |
+
- exact byte preservation for all input/output embedding rows except the
|
| 648 |
+
trained new-token IDs;
|
| 649 |
+
- every trained new input/output row changed;
|
| 650 |
+
- trained rows are not all-zero and have no BF16/F16/F32 inf/nan bit patterns;
|
| 651 |
+
- xIELU and QK-Norm tensors are covered by the non-embedding exact check.
|
| 652 |
+
|
| 653 |
+
Diagnostics run while hardening:
|
| 654 |
+
|
| 655 |
+
| Job | Partition | Result | Meaning |
|
| 656 |
+
|---:|---|---|---|
|
| 657 |
+
| `2355602` | `xfer` | failed with `uenv: command not found` | confirmed `xfer` cannot use the PyTorch uenv; preservation must not depend on torch there |
|
| 658 |
+
| `2355617` | `xfer` | exposed Python syntax incompatibility | first xfer compile/help check caught `int | None` on the older xfer Python |
|
| 659 |
+
| `2355625` | `xfer` | completed | xfer compile/help check passed after the compatibility patch |
|
| 660 |
+
|
| 661 |
+
Local tests:
|
| 662 |
+
|
| 663 |
+
- `python3 -m py_compile verify_td_preservation.py`
|
| 664 |
+
- `bash -n verify_td_preservation_xfer.sbatch`
|
| 665 |
+
- synthetic tiny Safetensors roundtrip test of preserved rows, moved trained
|
| 666 |
+
rows, and unchanged xIELU-like tensor.
|
| 667 |
+
|
| 668 |
+
The xfer-safe verifier was synced to:
|
| 669 |
+
|
| 670 |
+
`/iopsstor/scratch/cscs/fffoivos/repo/03_apertus_extension_and_embedding_adaptation/03_4_implementation_experiments/init_bakeoff/token_distillation/`
|
| 671 |
+
|
| 672 |
+
## Queued post-TD gates
|
| 673 |
+
|
| 674 |
+
Queued xfer preservation jobs behind the full TD job:
|
| 675 |
+
|
| 676 |
+
| Arm | Job | Partition | Dependency | Output |
|
| 677 |
+
|---|---:|---|---|---|
|
| 678 |
+
| `last` | `2355706` | `xfer` | `afterok:2353960` | `last/td_preservation_report.json` |
|
| 679 |
+
| `layer11` | `2355707` | `xfer` | `afterok:2353960` | `layer11/td_preservation_report.json` |
|
| 680 |
+
|
| 681 |
+
Queued packed intrinsic eval behind both preservation jobs:
|
| 682 |
+
|
| 683 |
+
- Job: `2355714`
|
| 684 |
+
- Partition: `normal`
|
| 685 |
+
- Dependency: `afterok:2355706:2355707`
|
| 686 |
+
- Output root:
|
| 687 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/td_full25_intrinsics_20260523T124000Z`
|
| 688 |
+
- Model spec:
|
| 689 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/td_full25_intrinsics_20260523T124000Z/model_spec.tsv`
|
| 690 |
+
- Arms:
|
| 691 |
+
- `retok`
|
| 692 |
+
- `td_full25_last`
|
| 693 |
+
- `td_full25_layer11`
|
| 694 |
+
|
| 695 |
+
This ordering means the full-token eval will only consume a GPU node if TD
|
| 696 |
+
training succeeds and both artifact-preservation checks pass.
|
| 697 |
+
|
| 698 |
+
## Full-token layer11 artifact complete
|
| 699 |
+
|
| 700 |
+
`target_layer=11` completed first:
|
| 701 |
+
|
| 702 |
+
- Completion line: `=== layer complete: 11 ===`
|
| 703 |
+
- Completion timestamp: 2026-05-23 13:57:09 UTC
|
| 704 |
+
- Output dir:
|
| 705 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/retok_td_full25_layers_20260523T092602Z/layer11`
|
| 706 |
+
- Manifest: `completed = True`
|
| 707 |
+
- Elapsed: `16,254.8s`
|
| 708 |
+
- Final training size: `54,303` dataloader steps
|
| 709 |
+
- Manifest counts:
|
| 710 |
+
- `trained_token_count = 17,377`
|
| 711 |
+
- `skipped_token_count = 15`
|
| 712 |
+
- `target_layer = 11`
|
| 713 |
+
- `snippets_per_token = 25`
|
| 714 |
+
- `batch_size = 8`
|
| 715 |
+
- Saved model files:
|
| 716 |
+
- `model.safetensors.index.json`
|
| 717 |
+
- `model-00001-of-00004.safetensors`
|
| 718 |
+
- `model-00002-of-00004.safetensors`
|
| 719 |
+
- `model-00003-of-00004.safetensors`
|
| 720 |
+
- `model-00004-of-00004.safetensors`
|
| 721 |
+
- `config.json`, tokenizer files, and generation/special-token configs.
|
| 722 |
+
|
| 723 |
+
Final layer11 training log excerpts:
|
| 724 |
+
|
| 725 |
+
- `Total end-to-end time: 16068.92639554094`
|
| 726 |
+
- `saving TD checkpoint: .../retok_td_full25_layers_20260523T092602Z/layer11`
|
| 727 |
+
- `done in 16254.8s`
|
| 728 |
+
|
| 729 |
+
Overall Slurm job `2353960` remains `RUNNING` because the `last` candidate is
|
| 730 |
+
still training. At 13:58 UTC it was `42,725 / 54,303` (`78.7%`) with ETA
|
| 731 |
+
`1:13:53`.
|
| 732 |
+
|
| 733 |
+
## Full-token training complete
|
| 734 |
+
|
| 735 |
+
The packed full-token TD training job completed cleanly:
|
| 736 |
+
|
| 737 |
+
- Job: `2353960`
|
| 738 |
+
- State: `COMPLETED`
|
| 739 |
+
- Elapsed: `05:45:53`
|
| 740 |
+
- Exit code: `0:0`
|
| 741 |
+
- Restart count observed while running: `0`
|
| 742 |
+
|
| 743 |
+
Additional `last` progress snapshots after `layer11` had completed:
|
| 744 |
+
|
| 745 |
+
| UTC time | last progress | last ETA |
|
| 746 |
+
|---|---:|---:|
|
| 747 |
+
| 14:03 | 43,519 / 54,303 (80.1%) | 1:06:42 |
|
| 748 |
+
| 14:08 | 44,302 / 54,303 (81.6%) | 1:04:37 |
|
| 749 |
+
| 14:13 | 45,099 / 54,303 (83.1%) | 0:57:57 |
|
| 750 |
+
| 14:18 | 45,892 / 54,303 (84.5%) | 0:52:19 |
|
| 751 |
+
| 14:23 | 46,689 / 54,303 (86.0%) | 0:47:19 |
|
| 752 |
+
| 14:28 | 47,483 / 54,303 (87.4%) | 0:41:06 |
|
| 753 |
+
| 14:33 | 48,279 / 54,303 (88.9%) | 0:39:44 |
|
| 754 |
+
| 14:38 | 49,074 / 54,303 (90.4%) | 0:32:19 |
|
| 755 |
+
| 14:43 | 49,869 / 54,303 (91.8%) | 0:28:37 |
|
| 756 |
+
| 14:48 | 50,663 / 54,303 (93.3%) | 0:22:41 |
|
| 757 |
+
| 14:53 | 51,459 / 54,303 (94.8%) | 0:17:04 |
|
| 758 |
+
| 14:58 | 52,245 / 54,303 (96.2%) | 0:12:52 |
|
| 759 |
+
| 15:03 | 53,038 / 54,303 (97.7%) | 0:07:52 |
|
| 760 |
+
| 15:08 | 53,830 / 54,303 (99.1%) | 0:02:57 |
|
| 761 |
+
| 15:13 | 54,303 / 54,303 (100.0%) | 0:00:00 |
|
| 762 |
+
|
| 763 |
+
`last` output dir:
|
| 764 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/retok_td_full25_layers_20260523T092602Z/last`
|
| 765 |
+
|
| 766 |
+
`last` artifact state:
|
| 767 |
+
|
| 768 |
+
- `model.safetensors.index.json` exists.
|
| 769 |
+
- `retok_td_manifest.json` was rewritten with `completed = True`.
|
| 770 |
+
- Manifest counts match `layer11`:
|
| 771 |
+
- `trained_token_count = 17,377`
|
| 772 |
+
- `skipped_token_count = 15`
|
| 773 |
+
- `snippets_per_token = 25`
|
| 774 |
+
|
| 775 |
+
## Full-token preservation gates passed
|
| 776 |
+
|
| 777 |
+
Both xfer preservation jobs passed:
|
| 778 |
+
|
| 779 |
+
| Arm | Job | State | Elapsed | Report |
|
| 780 |
+
|---|---:|---|---:|---|
|
| 781 |
+
| `last` | `2355706` | `COMPLETED` | `00:01:36` | `last/td_preservation_report.json` |
|
| 782 |
+
| `layer11` | `2355707` | `COMPLETED` | `00:01:39` | `layer11/td_preservation_report.json` |
|
| 783 |
+
|
| 784 |
+
Summary from both preservation reports:
|
| 785 |
+
|
| 786 |
+
- `trained_token_count = 17,377`
|
| 787 |
+
- `non_embedding_changed_count = 0`
|
| 788 |
+
- `shape_mismatches = []`
|
| 789 |
+
- `dtype_mismatches = []`
|
| 790 |
+
- `xielu_changed = []`
|
| 791 |
+
- `qk_norm_changed = []`
|
| 792 |
+
- `lm_head.weight`:
|
| 793 |
+
- preserved rows changed: `0`
|
| 794 |
+
- trained rows changed: `17,377`
|
| 795 |
+
- trained rows unchanged: `0`
|
| 796 |
+
- nonfinite trained rows: `0`
|
| 797 |
+
- zero trained rows: `0`
|
| 798 |
+
- `model.embed_tokens.weight`:
|
| 799 |
+
- preserved rows changed: `0`
|
| 800 |
+
- trained rows changed: `17,377`
|
| 801 |
+
- trained rows unchanged: `0`
|
| 802 |
+
- nonfinite trained rows: `0`
|
| 803 |
+
- zero trained rows: `0`
|
| 804 |
+
|
| 805 |
+
Interpretation: artifact-level preservation passed for both full-token TD
|
| 806 |
+
candidates. xIELU, QK-Norm, all transformer tensors, and all untrained input and
|
| 807 |
+
output rows are byte-exact relative to the ReTok reference. Only the intended
|
| 808 |
+
new-token input/output rows moved.
|
| 809 |
+
|
| 810 |
+
The packed intrinsic eval job is now dependency-cleared:
|
| 811 |
+
|
| 812 |
+
- Job: `2355714`
|
| 813 |
+
- State after preservation: `PENDING`
|
| 814 |
+
- Reason: `Priority`
|
| 815 |
+
- Output root:
|
| 816 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/td_full25_intrinsics_20260523T124000Z`
|
| 817 |
+
|
| 818 |
+
## Full-token intrinsic eval complete
|
| 819 |
+
|
| 820 |
+
Packed intrinsic eval completed cleanly:
|
| 821 |
+
|
| 822 |
+
- Job: `2355714`
|
| 823 |
+
- State: `COMPLETED`
|
| 824 |
+
- Elapsed: `00:03:15`
|
| 825 |
+
- Exit code: `0:0`
|
| 826 |
+
- Output root:
|
| 827 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/td_full25_intrinsics_20260523T124000Z`
|
| 828 |
+
- Local copy:
|
| 829 |
+
`../eval/td_full25_intrinsics_20260523T124000Z/`
|
| 830 |
+
|
| 831 |
+
Heldout Greek metrics:
|
| 832 |
+
|
| 833 |
+
| Arm | BPC | Delta vs ReTok | NLL/char | tokens/word | STRR |
|
| 834 |
+
|---|---:|---:|---:|---:|---:|
|
| 835 |
+
| `retok` | 2.9503 | 0.0000 | 3.4896 | 1.7352 | 0.4458 |
|
| 836 |
+
| `td_full25_last` | 1.4249 | -1.5254 | 1.6853 | 1.7352 | 0.4458 |
|
| 837 |
+
| `td_full25_layer11` | **1.3846** | **-1.5657** | **1.6376** | 1.7352 | 0.4458 |
|
| 838 |
+
|
| 839 |
+
New-token diagnostics:
|
| 840 |
+
|
| 841 |
+
| Arm | D1 mean rank | D1 top1 | D1 top5 | D2 new mass | D4 top1-new | D5 greedy-new | E norm ratio | U norm ratio |
|
| 842 |
+
|---|---:|---:|---:|---:|---:|---:|---:|---:|
|
| 843 |
+
| `retok` | 3868.27 | 0.0065 | 0.0231 | 0.9821 | 0.9992 | 1.0000 | 1.0578 | 1.0140 |
|
| 844 |
+
| `td_full25_last` | 1756.04 | 0.0381 | 0.1596 | 0.8194 | 0.9266 | 0.9980 | 1.0585 | 1.0195 |
|
| 845 |
+
| `td_full25_layer11` | **1617.48** | **0.0415** | **0.1722** | 0.8094 | 0.9153 | 0.9960 | 1.0590 | 1.0195 |
|
| 846 |
+
|
| 847 |
+
Interpretation:
|
| 848 |
+
|
| 849 |
+
- Full-token TD is not a marginal improvement over ReTok; it is a large
|
| 850 |
+
pre-CPT heldout-NLL improvement while preserving the extended tokenizer's
|
| 851 |
+
compression (`tokens/word` and `STRR` unchanged).
|
| 852 |
+
- `layer11` beats `last` on BPC and D1 rank/top-k, matching the pilot result.
|
| 853 |
+
- D2/D4/D5 move down from near-saturated ReTok use of new IDs, but remain high.
|
| 854 |
+
That is the desired direction here: less indiscriminate new-token mass while
|
| 855 |
+
keeping strong new-token availability.
|
| 856 |
+
- New input/output row norm ratios remain close to ReTok and do not show a norm
|
| 857 |
+
explosion.
|
| 858 |
+
|
| 859 |
+
Current decision:
|
| 860 |
+
|
| 861 |
+
- Select `td_full25_layer11` as the only TD checkpoint worth taking to the next
|
| 862 |
+
gate.
|
| 863 |
+
- Do not spend on a 50/100-snippet TD run before conversion/smoke; the 25-snippet
|
| 864 |
+
full-token checkpoint already clearly beats ReTok intrinsically.
|
| 865 |
+
- Next gate: R17-preserving HF -> Megatron conversion and roundtrip/load smoke
|
| 866 |
+
for `td_full25_layer11`.
|
| 867 |
+
|
| 868 |
+
## TD layer11 R17 conversion and HF roundtrip passed
|
| 869 |
+
|
| 870 |
+
Before launching the conversion gate, I checked whether it could safely run on
|
| 871 |
+
`xfer` and avoid a GPU allocation. It could not:
|
| 872 |
+
|
| 873 |
+
| Job | Partition | State | Finding |
|
| 874 |
+
|---:|---|---|---|
|
| 875 |
+
| `2357552` | `xfer` | failed | `sbatch --uenv` did not provide `torch` |
|
| 876 |
+
| `2357556` | `xfer` | failed | explicit `uenv run` path still had no `torch` |
|
| 877 |
+
| `2357561` | `xfer` | failed | `srun` on this site rejected `--uenv=...` |
|
| 878 |
+
|
| 879 |
+
The conversion gate therefore ran as a bounded `debug` GPU job because it
|
| 880 |
+
requires PyTorch/model loading and includes an HF logit smoke. This was not a
|
| 881 |
+
CPU-only dataset/snippet path.
|
| 882 |
+
|
| 883 |
+
R17 roundtrip job:
|
| 884 |
+
|
| 885 |
+
- Job: `2357565`
|
| 886 |
+
- Partition: `debug`
|
| 887 |
+
- State: `COMPLETED`
|
| 888 |
+
- Elapsed: `00:02:06`
|
| 889 |
+
- Exit code: `0:0`
|
| 890 |
+
- Input HF TD checkpoint:
|
| 891 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/retok_td_full25_layers_20260523T092602Z/layer11`
|
| 892 |
+
- Raw Megatron output:
|
| 893 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/td_full25_layer11_r17_roundtrip_2357565/megatron_tp2_raw`
|
| 894 |
+
- R17-patched Megatron output:
|
| 895 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/td_full25_layer11_r17_roundtrip_2357565/megatron_tp2_r17patched`
|
| 896 |
+
- HF roundtrip output:
|
| 897 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/td_full25_layer11_r17_roundtrip_2357565/hf_roundtrip`
|
| 898 |
+
- Verification JSON on Clariden:
|
| 899 |
+
`/capstor/scratch/cscs/fffoivos/runs/td_r17_roundtrip_2357565/verification.json`
|
| 900 |
+
- Local evidence copy:
|
| 901 |
+
`../megatron_patches/td_layer11_r17_roundtrip_2357565/`
|
| 902 |
+
|
| 903 |
+
Verifier result:
|
| 904 |
+
|
| 905 |
+
| Check | Result |
|
| 906 |
+
|---|---:|
|
| 907 |
+
| `standard_max_abs_diff` | `0.0` |
|
| 908 |
+
| `r17_max_abs_diff` | `0.0` |
|
| 909 |
+
| `xielu_max_abs_diff` | `0.0` |
|
| 910 |
+
| `qk_norm_max_abs_diff` | `0.0` |
|
| 911 |
+
| `standard_changed_over_tol_count` | `0` |
|
| 912 |
+
| `shape_mismatches` | `[]` |
|
| 913 |
+
| `logit_max_abs_diff` | `0.0` |
|
| 914 |
+
| `logit_mean_abs_diff_max` | `0.0` |
|
| 915 |
+
|
| 916 |
+
All three smoke prompts had exact logit parity and matching top IDs:
|
| 917 |
+
|
| 918 |
+
- `Η Αθήνα είναι η πρωτεύουσα της`
|
| 919 |
+
- `Ο Όμηρος έγραψε`
|
| 920 |
+
- `The capital of Greece is`
|
| 921 |
+
|
| 922 |
+
Interpretation:
|
| 923 |
+
|
| 924 |
+
- The selected TD layer11 checkpoint is now proven safe through the
|
| 925 |
+
R17-preserving HF -> Megatron -> HF roundtrip.
|
| 926 |
+
- The raw HF -> Megatron route is still not acceptable in general; the safe
|
| 927 |
+
production artifact is the patched Megatron checkpoint above.
|
| 928 |
+
- Next gate: a very short Megatron load/train smoke from
|
| 929 |
+
`megatron_tp2_r17patched`, with saves disabled or pushed beyond the smoke,
|
| 930 |
+
before any longer CPT-scale run.
|
| 931 |
+
|
| 932 |
+
## TD layer11 Megatron load/train smoke setup
|
| 933 |
+
|
| 934 |
+
Added `../bakeoff_training/submit_td_layer11_smoke.sh` so the next gate is a
|
| 935 |
+
reproducible bounded run, not a hand-typed one-off. It reuses
|
| 936 |
+
`bakeoff_train.sbatch` and only changes:
|
| 937 |
+
|
| 938 |
+
- `ARM=retok`, so the extended tokenizer and extended-tokenized Megatron data
|
| 939 |
+
are used.
|
| 940 |
+
- `INIT_CKPT`, pointed at the selected R17-patched TD checkpoint:
|
| 941 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/td_full25_layer11_r17_roundtrip_2357565/megatron_tp2_r17patched`
|
| 942 |
+
- `EXIT_INTERVAL=5`
|
| 943 |
+
- `SAVE_INTERVAL=999999`
|
| 944 |
+
- `EVAL_INTERVAL=999999`
|
| 945 |
+
- `TIME_LIMIT=01:00:00`
|
| 946 |
+
|
| 947 |
+
This gate is intentionally just a load/first-forward/backward/optimizer-step
|
| 948 |
+
smoke. It should not produce a CPT checkpoint or consume a long training window.
|
| 949 |
+
|
| 950 |
+
Launch:
|
| 951 |
+
|
| 952 |
+
- Job: `2357596`
|
| 953 |
+
- Partition: `normal`
|
| 954 |
+
- Output directory:
|
| 955 |
+
`/capstor/scratch/cscs/fffoivos/runs/bakeoff/smoke_td_full25_layer11_20260523T162614Z`
|
| 956 |
+
- Settings:
|
| 957 |
+
- `TIME_LIMIT=01:00:00`
|
| 958 |
+
- `EXIT_INTERVAL=5`
|
| 959 |
+
- `SAVE_INTERVAL=999999`
|
| 960 |
+
- `EVAL_INTERVAL=999999`
|
| 961 |
+
- `ARM=retok`
|
| 962 |
+
- `INIT_CKPT=/iopsstor/scratch/cscs/fffoivos/token_distillation/td_full25_layer11_r17_roundtrip_2357565/megatron_tp2_r17patched`
|
| 963 |
+
|
| 964 |
+
## TD layer11 two-node efficiency smoke failed
|
| 965 |
+
|
| 966 |
+
Smoke result:
|
| 967 |
+
|
| 968 |
+
- Job: `2357684`
|
| 969 |
+
- State: `FAILED`
|
| 970 |
+
- Elapsed: `00:02:24`
|
| 971 |
+
- Exit code: `1:0`
|
| 972 |
+
- Nodes: `nid006031`, `nid007615`
|
| 973 |
+
- Local evidence copy:
|
| 974 |
+
`../bakeoff_training/smoke_td_layer11_2node_2357684/`
|
| 975 |
+
|
| 976 |
+
What passed before failure:
|
| 977 |
+
|
| 978 |
+
- The selected R17-patched checkpoint loaded successfully.
|
| 979 |
+
- The extended tokenizer/data were selected through `ARM=retok`.
|
| 980 |
+
- The `torchrun` world size was `8`.
|
| 981 |
+
- xIELU optimizer audit passed on all eight ranks with `missing=0`.
|
| 982 |
+
|
| 983 |
+
Failure:
|
| 984 |
+
|
| 985 |
+
- The job failed before iteration 1 during a data-parallel collective.
|
| 986 |
+
- Root error in stderr:
|
| 987 |
+
`NET/OFI Request ... Error: 16 (NO_SPACE)`.
|
| 988 |
+
- PyTorch surfaced it as:
|
| 989 |
+
`NCCL Error 2: unhandled system error`.
|
| 990 |
+
|
| 991 |
+
Decision:
|
| 992 |
+
|
| 993 |
+
- Do not spend the 2B TD arm on the two-node path right now.
|
| 994 |
+
- Use the reliable one-node path.
|
| 995 |
+
- `normal` partition has a `12:00:00` walltime cap, while one-node smoke
|
| 996 |
+
throughput implies about 17.5h for 2B. Therefore the safe 2B launch shape is
|
| 997 |
+
a one-node initial job plus an automatic resume job from the same checkpoint
|
| 998 |
+
directory.
|
| 999 |
+
|
| 1000 |
+
## TD layer11 2B chained training launched
|
| 1001 |
+
|
| 1002 |
+
Launched the decision-useful 2B TD arm on the proven one-node path:
|
| 1003 |
+
|
| 1004 |
+
- Output directory:
|
| 1005 |
+
`/capstor/scratch/cscs/fffoivos/runs/bakeoff/td_full25_layer11_2b_20260523T165038Z`
|
| 1006 |
+
- Initial job: `2357704`
|
| 1007 |
+
- Resume job: `2357705`
|
| 1008 |
+
- Dependency: `afterany:2357704`
|
| 1009 |
+
- Partition: `normal`
|
| 1010 |
+
- Nodes: `1`
|
| 1011 |
+
- GPUs: `4`
|
| 1012 |
+
- Launch mode: `slurm`
|
| 1013 |
+
- Time limit per job: `12:00:00`
|
| 1014 |
+
- Save interval: `65`
|
| 1015 |
+
- Eval interval: `999999`
|
| 1016 |
+
- Chain resume: `1`
|
| 1017 |
+
- Init checkpoint:
|
| 1018 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/td_full25_layer11_r17_roundtrip_2357565/megatron_tp2_r17patched`
|
| 1019 |
+
|
| 1020 |
+
Reason for chained shape: the partition limit is 12h, and one-node smoke
|
| 1021 |
+
throughput gives an estimated 17-18h for 2B tokens. The first job should save
|
| 1022 |
+
periodic checkpoints; the second job should resume from
|
| 1023 |
+
`$OUTPUT_DIR/checkpoints`.
|
| 1024 |
+
|
| 1025 |
+
Initial live health:
|
| 1026 |
+
|
| 1027 |
+
- Job `2357704` started on `nid006069`.
|
| 1028 |
+
- Resume job `2357705` remains pending with `Dependency`, as intended.
|
| 1029 |
+
- Checkpoint load succeeded from the TD R17-patched init checkpoint.
|
| 1030 |
+
- Dataset build succeeded with the extended tokenizer/data prefix.
|
| 1031 |
+
- xIELU optimizer audit passed on all four ranks with `missing=0`.
|
| 1032 |
+
- First iteration completed:
|
| 1033 |
+
- timestamp: `2026-05-23 18:55:41`
|
| 1034 |
+
- iteration: `1/476`
|
| 1035 |
+
- consumed tokens: `0.004B`
|
| 1036 |
+
- loss: `8.928761`
|
| 1037 |
+
- grad norm: `153.597`
|
| 1038 |
+
- tokens/sec/GPU: `7553.6`
|
| 1039 |
+
- skipped iterations: `0`
|
| 1040 |
+
- NaN iterations: `0`
|
| 1041 |
+
- max allocated memory after iter 1: `61378.95 MB`
|
| 1042 |
+
|
| 1043 |
+
Interpretation: the decision-useful 2B TD arm is live and healthy on the proven
|
| 1044 |
+
one-node path. Expected remaining walltime from observed per-iteration timing is
|
| 1045 |
+
still longer than the 12h partition cap, so the dependent resume job is needed.
|
| 1046 |
+
|
| 1047 |
+
Follow-up health:
|
| 1048 |
+
|
| 1049 |
+
- At Slurm elapsed `00:06:18`, iteration 2 completed:
|
| 1050 |
+
- timestamp: `2026-05-23 18:57:55`
|
| 1051 |
+
- iteration: `2/476`
|
| 1052 |
+
- consumed tokens: `0.008B`
|
| 1053 |
+
- loss: `9.013231`
|
| 1054 |
+
- grad norm: `102.030`
|
| 1055 |
+
- tokens/sec/GPU: `7852.9`
|
| 1056 |
+
- skipped iterations: `0`
|
| 1057 |
+
- NaN iterations: `0`
|
| 1058 |
+
|
| 1059 |
+
At launch there were no other visible Slurm jobs for `fffoivos`.
|
| 1060 |
+
|
| 1061 |
+
## TD layer11 Megatron load/train smoke passed
|
| 1062 |
+
|
| 1063 |
+
Smoke result:
|
| 1064 |
+
|
| 1065 |
+
- Job: `2357596`
|
| 1066 |
+
- State: `COMPLETED`
|
| 1067 |
+
- Elapsed: `00:13:19`
|
| 1068 |
+
- Exit code: `0:0`
|
| 1069 |
+
- Node: `nid007017`
|
| 1070 |
+
- Local evidence copy:
|
| 1071 |
+
`../bakeoff_training/smoke_td_layer11_2357596/`
|
| 1072 |
+
|
| 1073 |
+
The smoke loaded the selected R17-patched checkpoint, selected the extended
|
| 1074 |
+
tokenizer/data through `ARM=retok`, built the dataset, passed the first
|
| 1075 |
+
forward/backward/optimizer path, and exited at iteration 5.
|
| 1076 |
+
|
| 1077 |
+
Iteration metrics:
|
| 1078 |
+
|
| 1079 |
+
| Iter | Loss | Grad norm | Tokens/sec/GPU | Skipped | NaN |
|
| 1080 |
+
|---:|---:|---:|---:|---:|---:|
|
| 1081 |
+
| 1 | 8.928761 | 153.403 | 7546.1 | 0 | 0 |
|
| 1082 |
+
| 2 | 9.013231 | 101.992 | 7867.7 | 0 | 0 |
|
| 1083 |
+
| 3 | 8.947750 | 105.898 | 7907.7 | 0 | 0 |
|
| 1084 |
+
| 4 | 8.990582 | 106.622 | 7905.1 | 0 | 0 |
|
| 1085 |
+
| 5 | 8.853868 | 173.612 | 7849.6 | 0 | 0 |
|
| 1086 |
+
|
| 1087 |
+
Other health signals:
|
| 1088 |
+
|
| 1089 |
+
- Checkpoint load succeeded from:
|
| 1090 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/td_full25_layer11_r17_roundtrip_2357565/megatron_tp2_r17patched`
|
| 1091 |
+
- xIELU optimizer audit passed on all four ranks:
|
| 1092 |
+
`missing=0`, `dp_optimizer_alpha_params=64`.
|
| 1093 |
+
- Rank 0/1 memory after iteration 1:
|
| 1094 |
+
max allocated `61378.95 MB`, max reserved `61662.0 MB`.
|
| 1095 |
+
- The warnings were non-fatal NCCL/barrier/deprecation/shutdown warnings; no
|
| 1096 |
+
OOM, no NaN, and no skipped iterations appeared.
|
| 1097 |
+
|
| 1098 |
+
Unexpected save behavior and cleanup:
|
| 1099 |
+
|
| 1100 |
+
- `EXIT_INTERVAL=5` caused Megatron to save at exit despite
|
| 1101 |
+
`SAVE_INTERVAL=999999`, because the training loop saves on exit whenever
|
| 1102 |
+
`args.save` is set.
|
| 1103 |
+
- The smoke checkpoint was `138G`.
|
| 1104 |
+
- I captured `checkpoint_listing_before_cleanup.txt` locally, then removed the
|
| 1105 |
+
smoke checkpoint directory from Capstor. The remote smoke run directory is
|
| 1106 |
+
now `64K`.
|
| 1107 |
+
- I added a `DISABLE_SAVE=1` path for future TD smokes so this wrapper does not
|
| 1108 |
+
produce another accidental large checkpoint. Normal training still defaults
|
| 1109 |
+
to checkpointing enabled.
|
| 1110 |
+
|
| 1111 |
+
## TD layer11 two-node efficiency smoke launched
|
| 1112 |
+
|
| 1113 |
+
Reason: the one-node smoke throughput is roughly `7.85k-7.91k tokens/sec/GPU`,
|
| 1114 |
+
which implies about 17.5 hours for the 2B TD arm on one 4-GPU node. Before
|
| 1115 |
+
launching the decision-useful 2B arm, I started a bounded two-node smoke to
|
| 1116 |
+
verify that the existing `torchrun` multi-node path works for this exact TD
|
| 1117 |
+
checkpoint/data stack.
|
| 1118 |
+
|
| 1119 |
+
Launch:
|
| 1120 |
+
|
| 1121 |
+
- Job: `2357684`
|
| 1122 |
+
- Partition: `normal`
|
| 1123 |
+
- Nodes: `2`
|
| 1124 |
+
- GPUs: `8`
|
| 1125 |
+
- Launch mode: `torchrun`
|
| 1126 |
+
- Output directory:
|
| 1127 |
+
`/capstor/scratch/cscs/fffoivos/runs/bakeoff/smoke_td_full25_layer11_2node_20260523T164424Z`
|
| 1128 |
+
- Settings:
|
| 1129 |
+
- `EXIT_INTERVAL=2`
|
| 1130 |
+
- `DISABLE_SAVE=1`
|
| 1131 |
+
- `SAVE_INTERVAL=999999`
|
| 1132 |
+
- `EVAL_INTERVAL=999999`
|
| 1133 |
+
- `ARM=retok`
|
| 1134 |
+
- `INIT_CKPT=/iopsstor/scratch/cscs/fffoivos/token_distillation/td_full25_layer11_r17_roundtrip_2357565/megatron_tp2_r17patched`
|
| 1135 |
+
|
| 1136 |
+
## Continuation note: eval handoff and live 2B status
|
| 1137 |
+
|
| 1138 |
+
Timestamp: `2026-05-23T17:04:06Z`
|
| 1139 |
+
|
| 1140 |
+
I resumed from the TD 2B run and explicitly recorded the handoff steps so the
|
| 1141 |
+
run remains reconstructable.
|
| 1142 |
+
|
| 1143 |
+
Current live training state:
|
| 1144 |
+
|
| 1145 |
+
- Active training job: `2357704` (`td_l11_2b`)
|
| 1146 |
+
- Resume job: `2357705` (`td_l11_2b_resume`), pending on `afterany:2357704`
|
| 1147 |
+
- Run directory:
|
| 1148 |
+
`/capstor/scratch/cscs/fffoivos/runs/bakeoff/td_full25_layer11_2b_20260523T165038Z`
|
| 1149 |
+
- Init checkpoint:
|
| 1150 |
+
`/iopsstor/scratch/cscs/fffoivos/token_distillation/td_full25_layer11_r17_roundtrip_2357565/megatron_tp2_r17patched`
|
| 1151 |
+
- Status check at Slurm elapsed `00:15:13`: job `2357704` was running on
|
| 1152 |
+
`nid006069`.
|
| 1153 |
+
- Latest observed iteration: `6/476`
|
| 1154 |
+
- timestamp: `2026-05-23 19:06:46`
|
| 1155 |
+
- consumed tokens: `0.025B`
|
| 1156 |
+
- loss: `8.708739`
|
| 1157 |
+
- grad norm: `159.085`
|
| 1158 |
+
- tokens/sec/GPU: `7890.4`
|
| 1159 |
+
- skipped iterations: `0`
|
| 1160 |
+
- NaN iterations: `0`
|
| 1161 |
+
|
| 1162 |
+
Two-node smoke decision:
|
| 1163 |
+
|
| 1164 |
+
- Two-node smoke job `2357684` failed before iteration 1 with
|
| 1165 |
+
`NET/OFI ... Error: 16 (NO_SPACE)` and `NCCL Error 2`.
|
| 1166 |
+
- I did not switch the production TD 2B run to the two-node path. The active
|
| 1167 |
+
run remains on the reliable one-node path.
|
| 1168 |
+
|
| 1169 |
+
Eval handoff changes prepared locally:
|
| 1170 |
+
|
| 1171 |
+
- `eval/convert_bakeoff_checkpoint_to_hf.sbatch` now accepts
|
| 1172 |
+
`ARM=td_layer11` and defaults that arm to the TD layer11 R17-roundtripped HF
|
| 1173 |
+
tokenizer/config directory.
|
| 1174 |
+
- Added `eval/submit_td_checkpoint_eval.sh`, a direct-path submitter for the
|
| 1175 |
+
selected TD run's checkpoints.
|
| 1176 |
+
- The submitter preflights `EVAL_JSONL` before any `sbatch` submission when
|
| 1177 |
+
`SUBMIT_INTRINSIC=1`, so a misconfigured intrinsic run does not half-submit.
|
| 1178 |
+
- Added `eval/watch_and_submit_td_checkpoint_eval.sh`, a direct-path watcher
|
| 1179 |
+
that submits conversion/eval once both the checkpoint directory and
|
| 1180 |
+
`latest_checkpointed_iteration.txt` confirm the target iteration is ready.
|
| 1181 |
+
- Updated `eval/EVAL_RECIPE.md` with the TD direct-path eval handoff.
|
| 1182 |
+
- Verified the held-out intrinsic slice still exists at:
|
| 1183 |
+
`/iopsstor/scratch/cscs/fffoivos/cpt_corpus/heldout/cpt_greek_heldout_500_20260522.jsonl`
|
| 1184 |
+
with 500 docs and size `33M`.
|
| 1185 |
+
|
| 1186 |
+
Checkpoint watchers launched:
|
| 1187 |
+
|
| 1188 |
+
| Iter | Scope | Intrinsic | PID | Watch log |
|
| 1189 |
+
|---:|---|---:|---:|---|
|
| 1190 |
+
| 65 | `greek_only` | 0 | 198851 | `/capstor/scratch/cscs/fffoivos/runs/eval/watch_td_l11_iter65_greek_only.log` |
|
| 1191 |
+
| 130 | `full` | 1 | 198853 | `/capstor/scratch/cscs/fffoivos/runs/eval/watch_td_l11_iter130_full.log` |
|
| 1192 |
+
| 260 | `full` | 1 | 198854 | `/capstor/scratch/cscs/fffoivos/runs/eval/watch_td_l11_iter260_full.log` |
|
| 1193 |
+
| 390 | `full` | 1 | 198855 | `/capstor/scratch/cscs/fffoivos/runs/eval/watch_td_l11_iter390_full.log` |
|
| 1194 |
+
| 455 | `full` | 1 | 198856 | `/capstor/scratch/cscs/fffoivos/runs/eval/watch_td_l11_iter455_full.log` |
|
| 1195 |
+
| 476 | `full` | 1 | 198857 | `/capstor/scratch/cscs/fffoivos/runs/eval/watch_td_l11_iter476_full.log` |
|
| 1196 |
+
|
| 1197 |
+
All six watchers wrote their initial `waiting for iter_...` line at
|
| 1198 |
+
`2026-05-23T17:08:41Z`.
|
| 1199 |
+
|
| 1200 |
+
Watcher durability correction:
|
| 1201 |
+
|
| 1202 |
+
- The first watcher launch used `nohup` from the SSH login session. It wrote the
|
| 1203 |
+
state directories and initial logs, but the processes did not persist after
|
| 1204 |
+
the SSH session closed.
|
| 1205 |
+
- A direct `sbatch --wrap` attempt with a 36h xfer walltime failed because the
|
| 1206 |
+
requested time limit exceeded the partition limit.
|
| 1207 |
+
- I added `eval/watch_td_checkpoint_evals.sbatch`: one CPU, no GPU,
|
| 1208 |
+
`partition=xfer`, `time=11:50:00`, running the same watcher set under Slurm.
|
| 1209 |
+
- Durable watcher jobs:
|
| 1210 |
+
- `2357765` running on `xfer` (`td_l11_watch`), started at
|
| 1211 |
+
`2026-05-23T17:11:43Z` on `nid001154`.
|
| 1212 |
+
- `2357766` pending on `afterany:2357765`, same wrapper, to cover the second
|
| 1213 |
+
half of the chained 2B training window.
|
| 1214 |
+
- The wrapper reuses per-checkpoint `submitted` stamps, so the second watcher
|
| 1215 |
+
window can safely repeat all six targets without duplicate eval submissions.
|
| 1216 |
+
|
| 1217 |
+
Important resource guard:
|
| 1218 |
+
|
| 1219 |
+
- Checkpoint conversion remains a CPU-only `xfer` Slurm job through
|
| 1220 |
+
`slurm_cpu_only_guard.sh`.
|
| 1221 |
+
- Downstream lm-eval and intrinsic metrics remain GPU jobs, as intended.
|
| 1222 |
+
|
| 1223 |
+
## Health pulse: pre-checkpoint TD 2B run
|
| 1224 |
+
|
| 1225 |
+
Timestamp: `2026-05-23T17:26:45Z`
|
| 1226 |
+
|
| 1227 |
+
Status:
|
| 1228 |
+
|
| 1229 |
+
- Training job `2357704` still running on `normal`, node `nid006069`, elapsed
|
| 1230 |
+
`00:34:33`.
|
| 1231 |
+
- Resume job `2357705` still pending on dependency, as intended.
|
| 1232 |
+
- Durable watcher job `2357765` still running on `xfer`, node `nid001154`,
|
| 1233 |
+
elapsed `00:14:52`.
|
| 1234 |
+
- Second watcher job `2357766` still pending on `afterany:2357765`, as
|
| 1235 |
+
intended.
|
| 1236 |
+
|
| 1237 |
+
Latest training line:
|
| 1238 |
+
|
| 1239 |
+
- Iteration: `14/476`
|
| 1240 |
+
- Timestamp in training log: `2026-05-23 19:24:29`
|
| 1241 |
+
- Consumed tokens: `0.059B`
|
| 1242 |
+
- Loss: `6.599847`
|
| 1243 |
+
- Grad norm: `23.327`
|
| 1244 |
+
- Tokens/sec/GPU: `7893.5`
|
| 1245 |
+
- Skipped iterations: `0`
|
| 1246 |
+
- NaN iterations: `0`
|
| 1247 |
+
|
| 1248 |
+
Checkpoint/eval state:
|
| 1249 |
+
|
| 1250 |
+
- No checkpoint files yet under the TD 2B checkpoint root; this is expected
|
| 1251 |
+
because the first save target is iteration `65`.
|
| 1252 |
+
- The iter-65 watcher is polling every 300 seconds and still waiting for
|
| 1253 |
+
`checkpoints/iter_0000065`.
|
| 1254 |
+
|
| 1255 |
+
## Checkpoint 65 and eval canary handoff
|
| 1256 |
+
|
| 1257 |
+
Timestamp: `2026-05-23T19:24Z`
|
| 1258 |
+
|
| 1259 |
+
Training/checkpoint state:
|
| 1260 |
+
|
| 1261 |
+
- Training job `2357704` reached iteration `65/476`.
|
| 1262 |
+
- Iteration 65 metrics:
|
| 1263 |
+
- training-log timestamp: `2026-05-23 21:17:27`
|
| 1264 |
+
- consumed tokens: `0.273B`
|
| 1265 |
+
- loss: `3.919139`
|
| 1266 |
+
- grad norm: `5.525`
|
| 1267 |
+
- tokens/sec/GPU: `7888.5`
|
| 1268 |
+
- skipped iterations: `0`
|
| 1269 |
+
- NaN iterations: `0`
|
| 1270 |
+
- Checkpoint save completed:
|
| 1271 |
+
- checkpoint dir:
|
| 1272 |
+
`/capstor/scratch/cscs/fffoivos/runs/bakeoff/td_full25_layer11_2b_20260523T165038Z/checkpoints/iter_0000065`
|
| 1273 |
+
- tracker:
|
| 1274 |
+
`/capstor/scratch/cscs/fffoivos/runs/bakeoff/td_full25_layer11_2b_20260523T165038Z/checkpoints/latest_checkpointed_iteration.txt`
|
| 1275 |
+
contains `65`.
|
| 1276 |
+
- Training continued to iteration `66/476` after the async save.
|
| 1277 |
+
|
| 1278 |
+
Watcher/eval canary:
|
| 1279 |
+
|
| 1280 |
+
- Durable watcher `2357765` detected checkpoint 65 and submitted:
|
| 1281 |
+
- conversion job `2358857` (`tohf_td_l11_65`)
|
| 1282 |
+
- dependent Greek-only eval job `2358858`
|
| 1283 |
+
|
| 1284 |
+
Canary failure and correction:
|
| 1285 |
+
|
| 1286 |
+
- Conversion job `2358857` failed in `00:00:04` with exit `127:0`.
|
| 1287 |
+
- Root cause from stderr:
|
| 1288 |
+
`uenv: command not found`.
|
| 1289 |
+
- A fresh xfer probe job `2358876` confirmed that `xfer` node `nid001154` has
|
| 1290 |
+
no `uenv` binary at either `command -v uenv` or `/usr/bin/uenv`, matching the
|
| 1291 |
+
earlier TD notes for conversion gates.
|
| 1292 |
+
- I cancelled the dead dependent eval job `2358858`.
|
| 1293 |
+
- I changed `eval/convert_bakeoff_checkpoint_to_hf.sbatch` from a forced
|
| 1294 |
+
CPU-only `xfer` job to a bounded one-GPU `debug` job. This matches the earlier
|
| 1295 |
+
R17/TD conversion gate: Megatron checkpoint conversion imports PyTorch and
|
| 1296 |
+
needs the PyTorch uenv, so it cannot run on xfer on this site.
|
| 1297 |
+
- I removed `eval/convert_bakeoff_checkpoint_to_hf.sbatch` from
|
| 1298 |
+
`check_cpu_only_slurm.sh`'s CPU-only audit list. Dataset/build/preprocessing
|
| 1299 |
+
jobs remain guarded for `xfer`; checkpoint watchers also remain CPU-only
|
| 1300 |
+
`xfer` jobs.
|
| 1301 |
+
|
| 1302 |
+
Next action:
|
| 1303 |
+
|
| 1304 |
+
- Sync the corrected conversion script/docs to Clariden.
|
| 1305 |
+
- Resubmit the iter-65 conversion/eval chain and verify the Greek-only canary
|
| 1306 |
+
starts from the corrected conversion job.
|
| 1307 |
+
|
| 1308 |
+
## Checkpoint 65 conversion recovery passed
|
| 1309 |
+
|
| 1310 |
+
Timestamp: `2026-05-23T19:28:04Z`
|
| 1311 |
+
|
| 1312 |
+
Local changes committed and synced:
|
| 1313 |
+
|
| 1314 |
+
- Commit: `8428b6d` (`Fix TD checkpoint conversion partition`)
|
| 1315 |
+
- Changed `eval/convert_bakeoff_checkpoint_to_hf.sbatch` to run on
|
| 1316 |
+
`debug` with one GPU and the PyTorch uenv.
|
| 1317 |
+
- Removed `eval/convert_bakeoff_checkpoint_to_hf.sbatch` from the CPU-only
|
| 1318 |
+
static audit list.
|
| 1319 |
+
- Updated `eval/EVAL_RECIPE.md` to distinguish:
|
| 1320 |
+
- true CPU-only dataset/build/watch jobs -> `xfer`
|
| 1321 |
+
- Megatron/PyTorch checkpoint conversion -> bounded one-GPU `debug`
|
| 1322 |
+
|
| 1323 |
+
Validation before resubmit:
|
| 1324 |
+
|
| 1325 |
+
- Local:
|
| 1326 |
+
- `bash -n eval/convert_bakeoff_checkpoint_to_hf.sbatch`
|
| 1327 |
+
- `bash -n check_cpu_only_slurm.sh`
|
| 1328 |
+
- `./check_cpu_only_slurm.sh`
|
| 1329 |
+
- Remote on Clariden mirror:
|
| 1330 |
+
- `bash -n eval/convert_bakeoff_checkpoint_to_hf.sbatch`
|
| 1331 |
+
- `bash -n check_cpu_only_slurm.sh`
|
| 1332 |
+
- `./check_cpu_only_slurm.sh`
|
| 1333 |
+
|
| 1334 |
+
All static checks passed. The CPU-only audit covers 10 true CPU-only jobs.
|
| 1335 |
+
|
| 1336 |
+
Resubmitted iter-65 canary:
|
| 1337 |
+
|
| 1338 |
+
- Command shape:
|
| 1339 |
+
`RUN_TAG=td_full25_layer11_2b_20260523T165038Z OVERWRITE=1 bash submit_td_checkpoint_eval.sh 65 greek_only`
|
| 1340 |
+
- Conversion job: `2358891` (`tohf_td_l11_65`)
|
| 1341 |
+
- Greek-only eval job: `2358892` (`eval_td_l11_65_greek_only`)
|
| 1342 |
+
|
| 1343 |
+
Conversion result:
|
| 1344 |
+
|
| 1345 |
+
- Job `2358891` completed successfully.
|
| 1346 |
+
- Partition: `debug`
|
| 1347 |
+
- Elapsed: `00:01:15`
|
| 1348 |
+
- Exit code: `0:0`
|
| 1349 |
+
- HF checkpoint:
|
| 1350 |
+
`/capstor/scratch/cscs/fffoivos/runs/eval/td_full25_layer11_2b_20260523T165038Z/iter_0000065_hf`
|
| 1351 |
+
- HF artifacts include:
|
| 1352 |
+
- `config.json`
|
| 1353 |
+
- `tokenizer.json`
|
| 1354 |
+
- `model.safetensors.index.json`
|
| 1355 |
+
- `model-00001-of-00004.safetensors` through `model-00004-of-00004.safetensors`
|
| 1356 |
+
- `bakeoff_conversion_metadata.json`
|
| 1357 |
+
|
| 1358 |
+
Eval state:
|
| 1359 |
+
|
| 1360 |
+
- Job `2358892` started on `normal`, node `nid007637`.
|
| 1361 |
+
- This is the Greek-only downstream canary for checkpoint 65.
|
| 1362 |
+
|
| 1363 |
+
## Checkpoint 65 Greek-only canary passed
|
| 1364 |
+
|
| 1365 |
+
Timestamp: `2026-05-23T20:02:06Z`
|
| 1366 |
+
|
| 1367 |
+
Training state at refresh:
|
| 1368 |
+
|
| 1369 |
+
- Main TD 2B job `2357704` is still running on `normal`, node `nid006069`.
|
| 1370 |
+
- Resume job `2357705` remains pending behind `2357704`.
|
| 1371 |
+
- Durable checkpoint watcher `2357765` is still running on `xfer`, node
|
| 1372 |
+
`nid001154`.
|
| 1373 |
+
- Backup watcher `2357766` remains pending behind `2357765`.
|
| 1374 |
+
- Latest parsed training line: iteration `84/476`, consumed tokens `0.352B`,
|
| 1375 |
+
timestamp `2026-05-23 21:59:58`, loss `3.593952`, throughput
|
| 1376 |
+
`7876.2` tokens/sec/GPU, skipped iterations `0`, NaN iterations `0`.
|
| 1377 |
+
- Checkpoint tracker remains at `65`; next planned checkpoint is iteration
|
| 1378 |
+
`130`.
|
| 1379 |
+
|
| 1380 |
+
Greek-only canary result:
|
| 1381 |
+
|
| 1382 |
+
- Eval job `2358892` completed successfully.
|
| 1383 |
+
- Partition/node: `normal` / `nid007637`
|
| 1384 |
+
- Elapsed: `00:22:15`
|
| 1385 |
+
- Exit code: `0:0`
|
| 1386 |
+
- Result JSON:
|
| 1387 |
+
`/capstor/scratch/cscs/fffoivos/runs/eval/td_full25_layer11_2b_20260523T165038Z/iter_0000065_greek_only/results_2026-05-23T21-49-04.839736.json`
|
| 1388 |
+
|
| 1389 |
+
Headline metrics from checkpoint 65:
|
| 1390 |
+
|
| 1391 |
+
- `global_mmlu_full_el` accuracy: `0.3717419171`
|
| 1392 |
+
- `include_base_44_greek_few_shot_en` accuracy: `0.3713768116`
|
| 1393 |
+
- `xnli_el` accuracy: `0.3903614458`
|
| 1394 |
+
- `arc_challenge_mt_el` normalized accuracy: `0.3233788396`
|
| 1395 |
+
- `belebele_ell_Grek` accuracy: `0.4877777778`
|
| 1396 |
+
- `global_piqa_completions_ell_grek` normalized accuracy: `0.53`
|
| 1397 |
+
- `xquad_el` exact match: `0.1537815126`
|
| 1398 |
+
- `xquad_el` F1: `0.2992209373`
|
| 1399 |
+
|
| 1400 |
+
Interpretation:
|
| 1401 |
+
|
| 1402 |
+
- The corrected conversion/eval path works end to end from a live Megatron
|
| 1403 |
+
checkpoint to HF and then lm-eval.
|
| 1404 |
+
- Checkpoint 65 is an early canary, not a final recipe-selection checkpoint.
|
| 1405 |
+
It is useful because it proves the model is not collapsed after TD init and
|
| 1406 |
+
early CPT, and it validates the automation before the more decision-relevant
|
| 1407 |
+
checkpoint 130 full eval.
|
| 1408 |
+
|
| 1409 |
+
Next action:
|
| 1410 |
+
|
| 1411 |
+
- Keep monitoring the live training job and watcher.
|
| 1412 |
+
- At iteration `130`, verify that the watcher submits the full downstream eval
|
| 1413 |
+
and intrinsic eval chain with the corrected conversion job.
|
| 1414 |
+
|
| 1415 |
+
## Runtime expectation after checkpoint 65
|
| 1416 |
+
|
| 1417 |
+
Timestamp: `2026-05-23T20:07:30Z`
|
| 1418 |
+
|
| 1419 |
+
Live training refresh:
|
| 1420 |
+
|
| 1421 |
+
- Main TD 2B job `2357704` is still running.
|
| 1422 |
+
- Latest parsed line: iteration `86/476`, consumed tokens `0.361B`, timestamp
|
| 1423 |
+
`2026-05-23 22:04:25`, loss `3.559302`, throughput `7874.4`
|
| 1424 |
+
tokens/sec/GPU, skipped iterations `0`, NaN iterations `0`.
|
| 1425 |
+
- Checkpoint tracker is still `65`.
|
| 1426 |
+
|
| 1427 |
+
Runtime note:
|
| 1428 |
+
|
| 1429 |
+
- The live Megatron ETA at iteration 86 is still about `14:25:33`, while job
|
| 1430 |
+
`2357704` has already used about `3:12` of its `12:00` allocation.
|
| 1431 |
+
- Therefore the first allocation is expected to hit walltime before iteration
|
| 1432 |
+
`476`.
|
| 1433 |
+
- This is not currently a failure condition because resume job `2357705` is
|
| 1434 |
+
already pending with the dependency chain. The next thing to watch later is
|
| 1435 |
+
that the handoff resumes from the latest completed checkpoint cleanly.
|
| 1436 |
+
|
| 1437 |
+
## Checkpoint 130 saved and full eval chain submitted
|
| 1438 |
+
|
| 1439 |
+
Timestamp: `2026-05-23T21:48:33Z`
|
| 1440 |
+
|
| 1441 |
+
Training state:
|
| 1442 |
+
|
| 1443 |
+
- Main TD 2B job `2357704` is still running on `normal`, node `nid006069`.
|
| 1444 |
+
- Resume job `2357705` remains pending behind `2357704`.
|
| 1445 |
+
- Durable watcher `2357765` is still running on `xfer`, node `nid001154`.
|
| 1446 |
+
- Latest parsed training line after the checkpoint: iteration `132/476`,
|
| 1447 |
+
consumed tokens `0.554B`, timestamp `2026-05-23 23:46:27`, loss
|
| 1448 |
+
`3.140112`, throughput `7868.7` tokens/sec/GPU, skipped iterations `0`,
|
| 1449 |
+
NaN iterations `0`.
|
| 1450 |
+
|
| 1451 |
+
Checkpoint state:
|
| 1452 |
+
|
| 1453 |
+
- Iteration `130` was saved successfully.
|
| 1454 |
+
- Checkpoint tracker now reads `130`.
|
| 1455 |
+
- Checkpoint dirs currently present:
|
| 1456 |
+
- `iter_0000065`
|
| 1457 |
+
- `iter_0000130`
|
| 1458 |
+
- Save log included:
|
| 1459 |
+
- `saving checkpoint at iteration 130`
|
| 1460 |
+
- `scheduled an async checkpoint save at iteration 130`
|
| 1461 |
+
- `successfully saved checkpoint from iteration 130`
|
| 1462 |
+
|
| 1463 |
+
Watcher/eval state:
|
| 1464 |
+
|
| 1465 |
+
- Watcher `watch_td_l11_iter130_full.log` saw the checkpoint directory before
|
| 1466 |
+
the tracker updated, waited correctly, then submitted once tracker reached
|
| 1467 |
+
`130`.
|
| 1468 |
+
- Submission log:
|
| 1469 |
+
`/capstor/scratch/cscs/fffoivos/runs/eval/td_full25_layer11_2b_20260523T165038Z_watch_iter_0000130_full/submit.log`
|
| 1470 |
+
- Submitted jobs:
|
| 1471 |
+
- conversion: `2360120` (`tohf_td_l11_130`)
|
| 1472 |
+
- full lm-eval: `2360121` (`eval_td_l11_130_full`)
|
| 1473 |
+
- intrinsic BPC: `2360122` (`bpc_td_l11_130`)
|
| 1474 |
+
- new-token diagnostics: `2360123` (`diag_td_l11_130`)
|
| 1475 |
+
|
| 1476 |
+
Immediate verification:
|
| 1477 |
+
|
| 1478 |
+
- Conversion job `2360120` completed successfully on `debug`.
|
| 1479 |
+
- Elapsed: `00:01:13`
|
| 1480 |
+
- Exit code: `0:0`
|
| 1481 |
+
- HF output:
|
| 1482 |
+
`/capstor/scratch/cscs/fffoivos/runs/eval/td_full25_layer11_2b_20260523T165038Z/iter_0000130_hf`
|
| 1483 |
+
- The HF output contains the expected config/tokenizer/index metadata.
|
| 1484 |
+
- At this timestamp, full lm-eval job `2360121` and intrinsic BPC job
|
| 1485 |
+
`2360122` are running; diagnostics job `2360123` is pending for resources.
|
| 1486 |
+
|
| 1487 |
+
Next action:
|
| 1488 |
+
|
| 1489 |
+
- Wait for jobs `2360121`, `2360122`, and `2360123`.
|
| 1490 |
+
- Parse checkpoint-130 downstream metrics and intrinsic/new-token metrics.
|
| 1491 |
+
- Log and commit the checkpoint-130 results once they are complete.
|
| 1492 |
+
|
| 1493 |
+
## Checkpoint 130 intrinsic and new-token diagnostics passed
|
| 1494 |
+
|
| 1495 |
+
Timestamp: `2026-05-23T21:56:40Z`
|
| 1496 |
+
|
| 1497 |
+
Completed jobs:
|
| 1498 |
+
|
| 1499 |
+
- Intrinsic BPC job `2360122` completed successfully.
|
| 1500 |
+
- Elapsed: `00:01:39`
|
| 1501 |
+
- Exit code: `0:0`
|
| 1502 |
+
- New-token diagnostics job `2360123` completed successfully.
|
| 1503 |
+
- Elapsed: `00:02:19`
|
| 1504 |
+
- Exit code: `0:0`
|
| 1505 |
+
- Full downstream lm-eval job `2360121` is still running at this timestamp.
|
| 1506 |
+
|
| 1507 |
+
Artifacts:
|
| 1508 |
+
|
| 1509 |
+
- Tokenizer-fair intrinsic metrics:
|
| 1510 |
+
`/capstor/scratch/cscs/fffoivos/runs/eval/td_full25_layer11_2b_20260523T165038Z/iter_0000130_tokenizer_fair_metrics.json`
|
| 1511 |
+
- New-token diagnostics:
|
| 1512 |
+
`/capstor/scratch/cscs/fffoivos/runs/eval/td_full25_layer11_2b_20260523T165038Z/iter_0000130_new_token_diagnostics.json`
|
| 1513 |
+
|
| 1514 |
+
Intrinsic metrics on the 500-doc Greek heldout slice:
|
| 1515 |
+
|
| 1516 |
+
- `n_docs`: `500`
|
| 1517 |
+
- `n_tokens`: `805972`
|
| 1518 |
+
- `chars_per_token`: `3.973178969`
|
| 1519 |
+
- `tokens_per_word`: `1.735161272`
|
| 1520 |
+
- `bpc_bits_per_byte`: `0.6531070974`
|
| 1521 |
+
- `nll_per_token`: `3.069195861`
|
| 1522 |
+
- STRR single-token word rate: `0.4458156518`
|
| 1523 |
+
|
| 1524 |
+
Per-register `bpc_bits_per_byte`:
|
| 1525 |
+
|
| 1526 |
+
- `academic`: `0.5755798070`
|
| 1527 |
+
- `dialogue_textbooks`: `0.8630783619`
|
| 1528 |
+
- `hplt_clean60`: `0.6225848939`
|
| 1529 |
+
- `legal_civic`: `0.4718179034`
|
| 1530 |
+
|
| 1531 |
+
Truncation caveat:
|
| 1532 |
+
|
| 1533 |
+
- `124/500` docs were truncated at the 4096-token scoring prefix.
|
| 1534 |
+
- `fraction_truncated`: `0.248`
|
| 1535 |
+
- This is acceptable as a same-slice checkpoint trend metric, but the absolute
|
| 1536 |
+
heldout BPC should be read with the script's caveat: char/byte/word counts
|
| 1537 |
+
are computed on the scored prefix, not the full text.
|
| 1538 |
+
|
| 1539 |
+
New-token diagnostics:
|
| 1540 |
+
|
| 1541 |
+
- New-token id range requested/applied: `17408` rows, base vocab `131072`,
|
| 1542 |
+
extended vocab `148480`.
|
| 1543 |
+
- Input embedding norm ratio, new/existing mean: `1.0589042902`.
|
| 1544 |
+
- Output embedding norm ratio, new/existing mean: `1.0192596912`.
|
| 1545 |
+
- New-input-row cosine sample:
|
| 1546 |
+
- mean off-diagonal: `0.0813974366`
|
| 1547 |
+
- p95 off-diagonal: `0.1582076550`
|
| 1548 |
+
- p99 off-diagonal: `0.3888086677`
|
| 1549 |
+
- New-input-row effective-rank sample:
|
| 1550 |
+
- participation ratio: `324.5376586914`
|
| 1551 |
+
- rank at 99% variance: `394/500`
|
| 1552 |
+
- Forward diagnostic over heldout positions:
|
| 1553 |
+
- positions total: `805472`
|
| 1554 |
+
- new-target positions: `276332`
|
| 1555 |
+
- average probability mass on new-token vocab per position: `0.3400108291`
|
| 1556 |
+
- new-target rank top-1: `0.2749410130`
|
| 1557 |
+
- new-target rank top-5: `0.4391746160`
|
| 1558 |
+
- new-target rank top-10: `0.5040169072`
|
| 1559 |
+
- new-target rank top-50: `0.6660864467`
|
| 1560 |
+
- top-1 prediction at new-target positions chose a new token `51.11%` of
|
| 1561 |
+
the time.
|
| 1562 |
+
- Greedy generation sanity sample:
|
| 1563 |
+
- prompts: `5`
|
| 1564 |
+
- generated tokens: `500`
|
| 1565 |
+
- generated new-token count: `103`
|
| 1566 |
+
- utilization rate: `0.206`
|
| 1567 |
+
|
| 1568 |
+
Interpretation:
|
| 1569 |
+
|
| 1570 |
+
- Intrinsics and diagnostics do not show a new-token collapse at checkpoint
|
| 1571 |
+
`130`.
|
| 1572 |
+
- New rows remain norm-compatible with existing rows, have non-degenerate
|
| 1573 |
+
sampled rank, and are being used by both forward scoring and greedy
|
| 1574 |
+
generation.
|
| 1575 |
+
- The next decision-useful evidence is the still-running full downstream eval
|
| 1576 |
+
for checkpoint `130`.
|
| 1577 |
+
|
| 1578 |
+
## Checkpoint 130 full downstream eval passed
|
| 1579 |
+
|
| 1580 |
+
Timestamp: `2026-05-23T22:38:22Z`
|
| 1581 |
+
|
| 1582 |
+
Completed job:
|
| 1583 |
+
|
| 1584 |
+
- Full lm-eval job `2360121` completed successfully.
|
| 1585 |
+
- Elapsed: `00:46:45`
|
| 1586 |
+
- Exit code: `0:0`
|
| 1587 |
+
|
| 1588 |
+
Artifact paths:
|
| 1589 |
+
|
| 1590 |
+
- Remote result JSON:
|
| 1591 |
+
`/capstor/scratch/cscs/fffoivos/runs/eval/td_full25_layer11_2b_20260523T165038Z/iter_0000130_full/results_2026-05-24T00-34-38.581138.json`
|
| 1592 |
+
- Remote run metadata:
|
| 1593 |
+
`/capstor/scratch/cscs/fffoivos/runs/eval/td_full25_layer11_2b_20260523T165038Z/iter_0000130_full/run_metadata.json`
|
| 1594 |
+
- Local compact copies:
|
| 1595 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000130_results.json`
|
| 1596 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000130_run_metadata.json`
|
| 1597 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000130_tokenizer_fair_metrics.json`
|
| 1598 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000130_new_token_diagnostics.json`
|
| 1599 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000130_digest.md`
|
| 1600 |
+
|
| 1601 |
+
Headline full-eval metrics:
|
| 1602 |
+
|
| 1603 |
+
- `arc_challenge` acc_norm: `0.5537542662`
|
| 1604 |
+
- `arc_easy` acc_norm: `0.8000841751`
|
| 1605 |
+
- `hellaswag` acc_norm: `0.7598088030`
|
| 1606 |
+
- `winogrande` acc: `0.6850828729`
|
| 1607 |
+
- `piqa` acc_norm: `0.7997823721`
|
| 1608 |
+
- `mmlu` acc: `0.5484973650`
|
| 1609 |
+
- `global_mmlu` acc: `0.4703933786`
|
| 1610 |
+
- `xnli` acc: `0.4139759036`
|
| 1611 |
+
- `xcopa` acc: `0.6310909091`
|
| 1612 |
+
- `arc_challenge_mt_el` acc_norm: `0.3515358362`
|
| 1613 |
+
- `belebele_ell_Grek` acc_norm: `0.5`
|
| 1614 |
+
- `xnli_el` acc: `0.3791164659`
|
| 1615 |
+
- `xquad_el` exact_match: `0.1781512605`
|
| 1616 |
+
- `xquad_el` F1: `0.3713167220`
|
| 1617 |
+
- `global_mmlu_full_el` acc: `0.3847742487`
|
| 1618 |
+
- `include_base_44_greek_few_shot_en` acc: `0.3858695652`
|
| 1619 |
+
- `global_piqa_completions_ell_grek` acc_norm: `0.53`
|
| 1620 |
+
|
| 1621 |
+
Greek checkpoint-65 to checkpoint-130 deltas:
|
| 1622 |
+
|
| 1623 |
+
- `arc_challenge_mt_el` acc_norm: `+0.0281569966`
|
| 1624 |
+
- `arc_challenge_mt_el` raw acc: `+0.0418088737`
|
| 1625 |
+
- `belebele_ell_Grek` acc_norm: `+0.0122222222`
|
| 1626 |
+
- `global_mmlu_full_el` acc: `+0.0130323316`
|
| 1627 |
+
- `include_base_44_greek_few_shot_en` acc: `+0.0144927536`
|
| 1628 |
+
- `global_piqa_completions_ell_grek` acc_norm: `0.0`
|
| 1629 |
+
- `global_piqa_completions_ell_grek` raw acc: `-0.02`
|
| 1630 |
+
- `xnli_el` acc: `-0.0112449799`
|
| 1631 |
+
- `xquad_el` exact_match: `+0.0243697479`
|
| 1632 |
+
- `xquad_el` F1: `+0.0720957847`
|
| 1633 |
+
|
| 1634 |
+
Training state after eval completion:
|
| 1635 |
+
|
| 1636 |
+
- Main TD 2B job `2357704` is still running.
|
| 1637 |
+
- Latest parsed training line: iteration `154/476`, consumed tokens `0.646B`,
|
| 1638 |
+
timestamp `2026-05-24 00:35:15`, loss `3.060735`, throughput `7874.1`
|
| 1639 |
+
tokens/sec/GPU, skipped iterations `0`, NaN iterations `0`.
|
| 1640 |
+
- Checkpoint tracker remains `130`; next scheduled full checkpoint/eval gate is
|
| 1641 |
+
`260`.
|
| 1642 |
+
|
| 1643 |
+
Interpretation:
|
| 1644 |
+
|
| 1645 |
+
- Checkpoint 130 gives the first full TD downstream snapshot and the early
|
| 1646 |
+
Greek trend is mostly positive relative to the checkpoint-65 canary.
|
| 1647 |
+
- It is still too early to choose TD for production solely from this point:
|
| 1648 |
+
checkpoint `260`, later full checkpoints, and final comparison to the
|
| 1649 |
+
earlier Vanilla/ReTok/Centroid bakeoff are still required.
|
| 1650 |
+
|
| 1651 |
+
## Intermediate checkpoint 195 saved
|
| 1652 |
+
|
| 1653 |
+
Timestamp: `2026-05-24T00:45:37Z`
|
| 1654 |
+
|
| 1655 |
+
Why this matters:
|
| 1656 |
+
|
| 1657 |
+
- Checkpoint `195` is not a scheduled downstream-eval gate, but it is the newest
|
| 1658 |
+
durable resume point for the live TD 2B run.
|
| 1659 |
+
- If the first 12h allocation hits walltime before the final iteration, the
|
| 1660 |
+
queued resume job should be able to resume from this or a later tracker value.
|
| 1661 |
+
|
| 1662 |
+
Training state at refresh:
|
| 1663 |
+
|
| 1664 |
+
- Main TD 2B job `2357704` is still running.
|
| 1665 |
+
- Resume job `2357705` remains pending.
|
| 1666 |
+
- Durable watcher `2357765` is still running on `xfer`.
|
| 1667 |
+
- Latest parsed training line: iteration `212/476`, consumed tokens `0.889B`,
|
| 1668 |
+
timestamp `2026-05-24 02:43:57`, loss `2.874373`, throughput `7879.1`
|
| 1669 |
+
tokens/sec/GPU, skipped iterations `0`, NaN iterations `0`.
|
| 1670 |
+
- Tracker now reads `195`.
|
| 1671 |
+
- Checkpoint dirs currently present:
|
| 1672 |
+
- `iter_0000065`
|
| 1673 |
+
- `iter_0000130`
|
| 1674 |
+
- `iter_0000195`
|
| 1675 |
+
|
| 1676 |
+
Checkpoint 195 save evidence:
|
| 1677 |
+
|
| 1678 |
+
- `saving checkpoint at iteration 195`
|
| 1679 |
+
- `scheduled an async checkpoint save at iteration 195`
|
| 1680 |
+
- `successfully saved checkpoint from iteration 195`
|
| 1681 |
+
- Directory:
|
| 1682 |
+
`/capstor/scratch/cscs/fffoivos/runs/bakeoff/td_full25_layer11_2b_20260523T165038Z/checkpoints/iter_0000195`
|
| 1683 |
+
|
| 1684 |
+
Next action:
|
| 1685 |
+
|
| 1686 |
+
- Continue monitoring toward scheduled full eval gate `260`.
|
| 1687 |
+
|
| 1688 |
+
## Checkpoint 260 saved and full eval chain submitted
|
| 1689 |
+
|
| 1690 |
+
Timestamp: `2026-05-24T02:36:40Z`
|
| 1691 |
+
|
| 1692 |
+
Training state:
|
| 1693 |
+
|
| 1694 |
+
- Main TD 2B job `2357704` is still running.
|
| 1695 |
+
- Resume job `2357705` remains pending.
|
| 1696 |
+
- Durable watcher `2357765` is still running on `xfer`.
|
| 1697 |
+
- Latest parsed training line after the checkpoint: iteration `262/476`,
|
| 1698 |
+
consumed tokens `1.099B`, timestamp `2026-05-24 04:34:53`, loss
|
| 1699 |
+
`2.661077`, throughput `7877.0` tokens/sec/GPU, skipped iterations `0`,
|
| 1700 |
+
NaN iterations `0`.
|
| 1701 |
+
|
| 1702 |
+
Checkpoint state:
|
| 1703 |
+
|
| 1704 |
+
- Iteration `260` was saved successfully.
|
| 1705 |
+
- Checkpoint tracker now reads `260`.
|
| 1706 |
+
- Checkpoint dirs currently present:
|
| 1707 |
+
- `iter_0000065`
|
| 1708 |
+
- `iter_0000130`
|
| 1709 |
+
- `iter_0000195`
|
| 1710 |
+
- `iter_0000260`
|
| 1711 |
+
- Save log included:
|
| 1712 |
+
- `saving checkpoint at iteration 260`
|
| 1713 |
+
- `scheduled an async checkpoint save at iteration 260`
|
| 1714 |
+
- `successfully saved checkpoint from iteration 260`
|
| 1715 |
+
|
| 1716 |
+
Watcher/eval state:
|
| 1717 |
+
|
| 1718 |
+
- Watcher `watch_td_l11_iter260_full.log` submitted once tracker reached
|
| 1719 |
+
`260`.
|
| 1720 |
+
- Submission log:
|
| 1721 |
+
`/capstor/scratch/cscs/fffoivos/runs/eval/td_full25_layer11_2b_20260523T165038Z_watch_iter_0000260_full/submit.log`
|
| 1722 |
+
- Submitted jobs:
|
| 1723 |
+
- conversion: `2362712` (`tohf_td_l11_260`)
|
| 1724 |
+
- full lm-eval: `2362713` (`eval_td_l11_260_full`)
|
| 1725 |
+
- intrinsic BPC: `2362714` (`bpc_td_l11_260`)
|
| 1726 |
+
- new-token diagnostics: `2362715` (`diag_td_l11_260`)
|
| 1727 |
+
|
| 1728 |
+
Immediate verification:
|
| 1729 |
+
|
| 1730 |
+
- Conversion job `2362712` completed successfully on `debug`.
|
| 1731 |
+
- Elapsed: `00:01:10`
|
| 1732 |
+
- Exit code: `0:0`
|
| 1733 |
+
- HF output:
|
| 1734 |
+
`/capstor/scratch/cscs/fffoivos/runs/eval/td_full25_layer11_2b_20260523T165038Z/iter_0000260_hf`
|
| 1735 |
+
- At this timestamp, full lm-eval job `2362713`, intrinsic BPC job `2362714`,
|
| 1736 |
+
and diagnostics job `2362715` are running.
|
| 1737 |
+
|
| 1738 |
+
Next action:
|
| 1739 |
+
|
| 1740 |
+
- Wait for jobs `2362713`, `2362714`, and `2362715`.
|
| 1741 |
+
- Parse checkpoint-260 downstream metrics and intrinsic/new-token metrics.
|
| 1742 |
+
- Log and commit the checkpoint-260 results once they are complete.
|
| 1743 |
+
|
| 1744 |
+
## Checkpoint 260 intrinsic and new-token diagnostics passed
|
| 1745 |
+
|
| 1746 |
+
Timestamp: `2026-05-24T02:42:20Z`
|
| 1747 |
+
|
| 1748 |
+
Completed jobs:
|
| 1749 |
+
|
| 1750 |
+
- Intrinsic BPC job `2362714` completed successfully.
|
| 1751 |
+
- Elapsed: `00:01:42`
|
| 1752 |
+
- Exit code: `0:0`
|
| 1753 |
+
- New-token diagnostics job `2362715` completed successfully.
|
| 1754 |
+
- Elapsed: `00:02:19`
|
| 1755 |
+
- Exit code: `0:0`
|
| 1756 |
+
- Full downstream lm-eval job `2362713` is still running at this timestamp.
|
| 1757 |
+
|
| 1758 |
+
Artifacts:
|
| 1759 |
+
|
| 1760 |
+
- Tokenizer-fair intrinsic metrics:
|
| 1761 |
+
`/capstor/scratch/cscs/fffoivos/runs/eval/td_full25_layer11_2b_20260523T165038Z/iter_0000260_tokenizer_fair_metrics.json`
|
| 1762 |
+
- New-token diagnostics:
|
| 1763 |
+
`/capstor/scratch/cscs/fffoivos/runs/eval/td_full25_layer11_2b_20260523T165038Z/iter_0000260_new_token_diagnostics.json`
|
| 1764 |
+
|
| 1765 |
+
Intrinsic metrics on the 500-doc Greek heldout slice:
|
| 1766 |
+
|
| 1767 |
+
- `n_docs`: `500`
|
| 1768 |
+
- `n_tokens`: `805972`
|
| 1769 |
+
- `chars_per_token`: `3.973178969`
|
| 1770 |
+
- `tokens_per_word`: `1.735161272`
|
| 1771 |
+
- `bpc_bits_per_byte`: `0.5670351472`
|
| 1772 |
+
- `nll_per_token`: `2.664711398`
|
| 1773 |
+
- STRR single-token word rate: `0.4458156518`
|
| 1774 |
+
|
| 1775 |
+
Per-register `bpc_bits_per_byte`:
|
| 1776 |
+
|
| 1777 |
+
- `academic`: `0.4819600870`
|
| 1778 |
+
- `dialogue_textbooks`: `0.7560400097`
|
| 1779 |
+
- `hplt_clean60`: `0.5585149641`
|
| 1780 |
+
- `legal_civic`: `0.3886621322`
|
| 1781 |
+
|
| 1782 |
+
Truncation caveat:
|
| 1783 |
+
|
| 1784 |
+
- Same as checkpoint `130`: `124/500` docs were truncated at the 4096-token
|
| 1785 |
+
scoring prefix, so absolute BPC should be treated as a same-slice trend
|
| 1786 |
+
metric rather than full-document perplexity.
|
| 1787 |
+
|
| 1788 |
+
New-token diagnostics:
|
| 1789 |
+
|
| 1790 |
+
- New-token id range applied: `17408` rows, base vocab `131072`, extended vocab
|
| 1791 |
+
`148480`.
|
| 1792 |
+
- Input embedding norm ratio, new/existing mean: `1.0588757992`.
|
| 1793 |
+
- Output embedding norm ratio, new/existing mean: `1.0193959475`.
|
| 1794 |
+
- New-input-row cosine sample:
|
| 1795 |
+
- mean off-diagonal: `0.0813098699`
|
| 1796 |
+
- p95 off-diagonal: `0.1580153704`
|
| 1797 |
+
- New-input-row effective-rank sample:
|
| 1798 |
+
- participation ratio: `324.6900024414`
|
| 1799 |
+
- rank at 99% variance: `395/500`
|
| 1800 |
+
- Forward diagnostic over heldout positions:
|
| 1801 |
+
- positions total: `805472`
|
| 1802 |
+
- new-target positions: `276332`
|
| 1803 |
+
- average probability mass on new-token vocab per position: `0.3411220586`
|
| 1804 |
+
- new-target rank top-1: `0.3517146042`
|
| 1805 |
+
- new-target rank top-5: `0.5200483476`
|
| 1806 |
+
- new-target rank top-10: `0.5848797823`
|
| 1807 |
+
- new-target rank top-50: `0.7358648293`
|
| 1808 |
+
- top-1 prediction at new-target positions chose a new token `59.52%` of the
|
| 1809 |
+
time.
|
| 1810 |
+
- Greedy generation sanity sample:
|
| 1811 |
+
- prompts: `5`
|
| 1812 |
+
- generated tokens: `500`
|
| 1813 |
+
- generated new-token count: `98`
|
| 1814 |
+
- utilization rate: `0.196`
|
| 1815 |
+
|
| 1816 |
+
Trend from checkpoint 130 to 260:
|
| 1817 |
+
|
| 1818 |
+
- Heldout BPC improved from `0.6531070974` to `0.5670351472`.
|
| 1819 |
+
- Heldout NLL/token improved from `3.069195861` to `2.664711398`.
|
| 1820 |
+
- New-target top-1 improved from `0.2749410130` to `0.3517146042`.
|
| 1821 |
+
- New-target top-10 improved from `0.5040169072` to `0.5848797823`.
|
| 1822 |
+
- Average probability mass on the new-token vocab is stable:
|
| 1823 |
+
`0.3400108291` -> `0.3411220586`.
|
| 1824 |
+
- New-row input/output norm ratios and sampled rank are stable.
|
| 1825 |
+
|
| 1826 |
+
Interpretation:
|
| 1827 |
+
|
| 1828 |
+
- Checkpoint `260` intrinsics show meaningful heldout improvement and stronger
|
| 1829 |
+
new-token prediction without evidence of new-row collapse.
|
| 1830 |
+
- The remaining checkpoint-260 evidence needed is the still-running full
|
| 1831 |
+
downstream eval.
|
| 1832 |
+
|
| 1833 |
+
## Live ETA and walltime handoff check
|
| 1834 |
+
|
| 1835 |
+
Timestamp: `2026-05-24T03:17:12Z`
|
| 1836 |
+
|
| 1837 |
+
Training state:
|
| 1838 |
+
|
| 1839 |
+
- Main TD 2B job `2357704` is still running on `normal`.
|
| 1840 |
+
- Resume job `2357705` is pending on dependency.
|
| 1841 |
+
- Durable watcher `2357765` is still running on `xfer`; backup watcher
|
| 1842 |
+
`2357766` remains pending.
|
| 1843 |
+
- Latest parsed training line: iteration `281/476`, consumed tokens `1.179B`,
|
| 1844 |
+
timestamp `2026-05-24 05:17:02`, loss `2.658228`, throughput `7886.9`
|
| 1845 |
+
tokens/sec/GPU, skipped iterations `0`, NaN iterations `0`.
|
| 1846 |
+
- Checkpoint tracker still reads `260`; checkpoint dirs present are
|
| 1847 |
+
`65`, `130`, `195`, and `260`.
|
| 1848 |
+
|
| 1849 |
+
Checkpoint-260 full eval state:
|
| 1850 |
+
|
| 1851 |
+
- Full downstream eval job `2362713` is still running.
|
| 1852 |
+
- Elapsed at poll: `00:41:25`.
|
| 1853 |
+
- Output directory currently has `run_metadata.json`; the final
|
| 1854 |
+
`results_*.json` has not appeared yet.
|
| 1855 |
+
- Eval stdout has completed batch-size probing and selected batch size `40`.
|
| 1856 |
+
|
| 1857 |
+
Walltime / resume safety:
|
| 1858 |
+
|
| 1859 |
+
- Current allocation elapsed: `10:25:11` of `12:00:00`, with about `1:35`
|
| 1860 |
+
remaining at the poll.
|
| 1861 |
+
- At the observed iteration cadence, the allocation will not finish all
|
| 1862 |
+
`476` iterations; it should need the pending resume job.
|
| 1863 |
+
- The Slurm script has `#SBATCH --signal=SIGUSR2@600`, and the Megatron
|
| 1864 |
+
training code path for `--exit-signal-handler` was inspected on Clariden:
|
| 1865 |
+
on receiving SIGUSR2, it calls `save_checkpoint_and_time(...)` before
|
| 1866 |
+
exiting. This means the expected walltime handoff should save a fresh
|
| 1867 |
+
checkpoint near the end of the allocation rather than forcing the resume to
|
| 1868 |
+
fall back to checkpoint `260`.
|
| 1869 |
+
|
| 1870 |
+
ETA:
|
| 1871 |
+
|
| 1872 |
+
- Remaining active training time from iteration `281` is about `7h12m`.
|
| 1873 |
+
- If the resume job starts promptly after the first allocation exits, final
|
| 1874 |
+
training should land around `2026-05-24 12:45-13:15 CEST`.
|
| 1875 |
+
- Final conversion/eval should add roughly another hour, so benchmark-ready
|
| 1876 |
+
artifacts are expected around `2026-05-24 14:00 CEST`, plus any queue delay.
|
| 1877 |
+
|
| 1878 |
+
## Checkpoint 260 full downstream eval landed
|
| 1879 |
+
|
| 1880 |
+
Timestamp: `2026-05-24T03:25:00Z`
|
| 1881 |
+
|
| 1882 |
+
Completed job:
|
| 1883 |
+
|
| 1884 |
+
- Full downstream eval job `2362713` completed successfully.
|
| 1885 |
+
- Elapsed: `00:44:57`
|
| 1886 |
+
- Exit code: `0:0`
|
| 1887 |
+
- Results:
|
| 1888 |
+
`/capstor/scratch/cscs/fffoivos/runs/eval/td_full25_layer11_2b_20260523T165038Z/iter_0000260_full/results_2026-05-24T05-20-34.834207.json`
|
| 1889 |
+
|
| 1890 |
+
Local compact evidence copied:
|
| 1891 |
+
|
| 1892 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000260_results.json`
|
| 1893 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000260_run_metadata.json`
|
| 1894 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000260_tokenizer_fair_metrics.json`
|
| 1895 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000260_new_token_diagnostics.json`
|
| 1896 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000260_digest.md`
|
| 1897 |
+
|
| 1898 |
+
Headline full-eval deltas vs checkpoint `130`:
|
| 1899 |
+
|
| 1900 |
+
- General capabilities are mixed to slightly down:
|
| 1901 |
+
- `arc_challenge` acc_norm `0.5367` (`-0.0171`)
|
| 1902 |
+
- `arc_easy` acc_norm `0.7824` (`-0.0177`)
|
| 1903 |
+
- `mmlu` acc `0.5385` (`-0.0100`)
|
| 1904 |
+
- `global_mmlu` acc `0.4467` (`-0.0237`)
|
| 1905 |
+
- `hellaswag` acc_norm `0.7617` (`+0.0019`)
|
| 1906 |
+
- `winogrande` acc `0.6882` (`+0.0032`)
|
| 1907 |
+
- Greek movement is mixed but still mostly useful:
|
| 1908 |
+
- `arc_challenge_mt_el` acc_norm `0.3891` (`+0.0375`)
|
| 1909 |
+
- `include_base_44_greek_few_shot_en` acc `0.4112` (`+0.0254`)
|
| 1910 |
+
- `global_piqa_completions_ell_grek` acc_norm `0.5600` (`+0.0300`)
|
| 1911 |
+
- `xnli_el` acc `0.3896` (`+0.0104`)
|
| 1912 |
+
- `belebele_ell_Grek` acc_norm `0.5022` (`+0.0022`)
|
| 1913 |
+
- `global_mmlu_full_el` acc `0.3774` (`-0.0074`)
|
| 1914 |
+
- `xquad_el` exact match `0.1571` (`-0.0210`), F1 `0.3711`
|
| 1915 |
+
(`-0.0003`)
|
| 1916 |
+
|
| 1917 |
+
Intrinsic/new-token trend vs checkpoint `130`:
|
| 1918 |
+
|
| 1919 |
+
- Heldout BPC improved `0.6531 -> 0.5670`.
|
| 1920 |
+
- Heldout NLL/token improved `3.0692 -> 2.6647`.
|
| 1921 |
+
- New-target top-1 improved `0.2749 -> 0.3517`.
|
| 1922 |
+
- New-target top-10 improved `0.5040 -> 0.5849`.
|
| 1923 |
+
- New-vocab probability mass stayed stable: `0.3400 -> 0.3411`.
|
| 1924 |
+
- New-row norm ratios and sampled effective rank stayed stable.
|
| 1925 |
+
|
| 1926 |
+
Interpretation:
|
| 1927 |
+
|
| 1928 |
+
- Checkpoint `260` keeps the strongest signal on intrinsic TD recovery and
|
| 1929 |
+
new-token prediction.
|
| 1930 |
+
- Downstream Greek is not uniformly monotonic, but several target Greek metrics
|
| 1931 |
+
improve from checkpoint `130` and most are above checkpoint `65`.
|
| 1932 |
+
- The main watch item for final selection is whether the final checkpoint
|
| 1933 |
+
restores or further erodes the small general-benchmark dips seen at `260`.
|
| 1934 |
+
|
| 1935 |
+
## Walltime handoff preserved progress at checkpoint 320
|
| 1936 |
+
|
| 1937 |
+
Timestamp: `2026-05-24T04:49:24Z`
|
| 1938 |
+
|
| 1939 |
+
Main job `2357704` reached the Slurm signal handoff cleanly:
|
| 1940 |
+
|
| 1941 |
+
- Last pre-handoff training line: iteration `320/476`, consumed tokens
|
| 1942 |
+
`1.342B`, timestamp `2026-05-24 06:43:29`, loss `2.605217`, throughput
|
| 1943 |
+
`7891.8` tokens/sec/GPU, skipped iterations `0`, NaN iterations `0`.
|
| 1944 |
+
- Slurm/Megatron signal path fired after iteration `320`:
|
| 1945 |
+
- `saving checkpoint at iteration 320`
|
| 1946 |
+
- `scheduled an async checkpoint save at iteration 320`
|
| 1947 |
+
- `exiting program after receiving SIGUSR2`
|
| 1948 |
+
- `successfully saved checkpoint from iteration 320`
|
| 1949 |
+
- Checkpoint tracker advanced from `260` to `320`.
|
| 1950 |
+
- Checkpoint directory now exists:
|
| 1951 |
+
`/capstor/scratch/cscs/fffoivos/runs/bakeoff/td_full25_layer11_2b_20260523T165038Z/checkpoints/iter_0000320`
|
| 1952 |
+
- Checkpoint `iter_0000320` contains `common.pt`, `.metadata`,
|
| 1953 |
+
`metadata.json`, and all eight `*.distcp` shards.
|
| 1954 |
+
|
| 1955 |
+
Resume job `2357705` started automatically and loaded the handoff checkpoint:
|
| 1956 |
+
|
| 1957 |
+
- Resume job state at verification: `RUNNING`.
|
| 1958 |
+
- Resume stdout:
|
| 1959 |
+
- `loading distributed checkpoint ... at iteration 320`
|
| 1960 |
+
- `successfully loaded checkpoint ... at iteration 320`
|
| 1961 |
+
- `before the start of training step`
|
| 1962 |
+
- Resume stderr contains only expected warnings/deprecations and the xIELU
|
| 1963 |
+
optimizer audit:
|
| 1964 |
+
- rank 0/1/2/3 all report `model_alpha_params=64`,
|
| 1965 |
+
`dp_optimizer_alpha_params=64`, `missing=0`.
|
| 1966 |
+
- First resumed training line landed: iteration `321/476`, consumed tokens
|
| 1967 |
+
`1.346B`, timestamp `2026-05-24 06:48:21`, loss `2.629754`, skipped
|
| 1968 |
+
iterations `0`, NaN iterations `0`.
|
| 1969 |
+
|
| 1970 |
+
Interpretation:
|
| 1971 |
+
|
| 1972 |
+
- The configured `#SBATCH --signal=SIGUSR2@600` plus
|
| 1973 |
+
`--exit-signal-handler` path is proven live, not just code-inspected.
|
| 1974 |
+
- The handoff preserved progress beyond checkpoint `260`; the resumed run is
|
| 1975 |
+
continuing from checkpoint `320`.
|
| 1976 |
+
- Next planned evaluation checkpoint remains `390`; checkpoint `320` is a
|
| 1977 |
+
resume-safety checkpoint, not a scheduled eval point.
|
| 1978 |
+
|
| 1979 |
+
## Resume checkpoint 325 and backup watcher handoff
|
| 1980 |
+
|
| 1981 |
+
Timestamp: `2026-05-24T05:05:02Z`
|
| 1982 |
+
|
| 1983 |
+
Resume/training state:
|
| 1984 |
+
|
| 1985 |
+
- Resume job `2357705` is still running on `normal`.
|
| 1986 |
+
- Latest parsed training line at poll: iteration `328/476`, consumed tokens
|
| 1987 |
+
`1.376B`, timestamp `2026-05-24 07:04:15`, loss `2.643836`, throughput
|
| 1988 |
+
`7892.9` tokens/sec/GPU, skipped iterations `0`, NaN iterations `0`.
|
| 1989 |
+
- Regular checkpoint `325` saved successfully after the resume.
|
| 1990 |
+
- Checkpoint tracker advanced to `325`.
|
| 1991 |
+
- Checkpoint `iter_0000325` contains `common.pt`, `.metadata`,
|
| 1992 |
+
`metadata.json`, and all eight `*.distcp` shards.
|
| 1993 |
+
|
| 1994 |
+
Watcher handoff:
|
| 1995 |
+
|
| 1996 |
+
- First durable watcher `2357765` reached its xfer walltime and ended with
|
| 1997 |
+
state `TIMEOUT`, elapsed `11:50:26`.
|
| 1998 |
+
- Backup watcher `2357766` started automatically via
|
| 1999 |
+
`afterany:2357765` and is running on `xfer`.
|
| 2000 |
+
- Backup watcher stdout confirms it restarted the watch specs:
|
| 2001 |
+
`65:greek_only:0 130:full:1 260:full:1 390:full:1 455:full:1 476:full:1`.
|
| 2002 |
+
- The checkpoint-390 watcher log now contains the backup start marker:
|
| 2003 |
+
`watch start RUN_TAG=td_full25_layer11_2b_20260523T165038Z ITER=390 TASK_GROUP=full`.
|
| 2004 |
+
|
| 2005 |
+
Interpretation:
|
| 2006 |
+
|
| 2007 |
+
- Training remains healthy after the resume and has made a normal scheduled
|
| 2008 |
+
checkpoint at `325`.
|
| 2009 |
+
- Eval automation remains covered through the backup xfer watcher.
|
| 2010 |
+
- Next decision-useful checkpoint remains `390`, expected to trigger the full
|
| 2011 |
+
eval plus intrinsic/new-token diagnostics chain.
|
| 2012 |
+
|
| 2013 |
+
## Checkpoint 390 reached and eval chain submitted
|
| 2014 |
+
|
| 2015 |
+
Timestamp: `2026-05-24T07:27:54Z`
|
| 2016 |
+
|
| 2017 |
+
Training/checkpoint state:
|
| 2018 |
+
|
| 2019 |
+
- Resume job `2357705` is still running on `normal`.
|
| 2020 |
+
- Latest parsed training line at checkpoint: iteration `390/476`, consumed
|
| 2021 |
+
tokens `1.636B`, timestamp `2026-05-24 09:21:40 CEST`, loss `2.556699`,
|
| 2022 |
+
throughput `7881.9` tokens/sec/GPU, skipped iterations `0`, NaN iterations
|
| 2023 |
+
`0`.
|
| 2024 |
+
- Checkpoint `iter_0000390` exists and is complete: `common.pt`,
|
| 2025 |
+
`.metadata`, `metadata.json`, and all eight `*.distcp` shards are present.
|
| 2026 |
+
- Checkpoint tracker advanced to `390`.
|
| 2027 |
+
|
| 2028 |
+
Eval automation:
|
| 2029 |
+
|
| 2030 |
+
- Backup watcher `2357766` detected the complete checkpoint and submitted the
|
| 2031 |
+
full checkpoint-390 eval chain.
|
| 2032 |
+
- Submitted jobs:
|
| 2033 |
+
- conversion: `2364958` (`tohf_td_l11_390`, `debug`, running at check)
|
| 2034 |
+
- full lm-eval: `2364959` (`eval_td_l11_390_full`, dependency pending)
|
| 2035 |
+
- intrinsic BPC: `2364960` (`bpc_td_l11_390`, dependency pending)
|
| 2036 |
+
- new-token diagnostics: `2364961` (`diag_td_l11_390`, dependency pending)
|
| 2037 |
+
- Eval output root:
|
| 2038 |
+
`/capstor/scratch/cscs/fffoivos/runs/eval/td_full25_layer11_2b_20260523T165038Z/iter_0000390_full`
|
| 2039 |
+
|
| 2040 |
+
Interpretation:
|
| 2041 |
+
|
| 2042 |
+
- The resumed 2B TD run has reached the next planned decision checkpoint.
|
| 2043 |
+
- Eval automation is live after the xfer watcher handoff.
|
| 2044 |
+
- At the observed speed, training itself is still on track to finish near
|
| 2045 |
+
`2026-05-24 12:32 CEST`; checkpoint-390 results should land earlier, after
|
| 2046 |
+
conversion plus the full eval queue clears.
|
| 2047 |
+
|
| 2048 |
+
## Checkpoint 390 eval completed and copied locally
|
| 2049 |
+
|
| 2050 |
+
Timestamp: `2026-05-24T08:13:32Z`
|
| 2051 |
+
|
| 2052 |
+
Eval jobs all completed successfully:
|
| 2053 |
+
|
| 2054 |
+
- conversion `2364958`: `COMPLETED`, `0:0`, elapsed `00:01:09`
|
| 2055 |
+
- full lm-eval `2364959`: `COMPLETED`, `0:0`, elapsed `00:44:40`
|
| 2056 |
+
- tokenizer-fair BPC `2364960`: `COMPLETED`, `0:0`, elapsed `00:01:52`
|
| 2057 |
+
- new-token diagnostics `2364961`: `COMPLETED`, `0:0`, elapsed `00:02:03`
|
| 2058 |
+
|
| 2059 |
+
Compact artifacts copied locally:
|
| 2060 |
+
|
| 2061 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000390_results.json`
|
| 2062 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000390_run_metadata.json`
|
| 2063 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000390_tokenizer_fair_metrics.json`
|
| 2064 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000390_new_token_diagnostics.json`
|
| 2065 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000390_digest.md`
|
| 2066 |
+
|
| 2067 |
+
Checkpoint-390 headline:
|
| 2068 |
+
|
| 2069 |
+
- Intrinsic/new-token recovery continued to improve:
|
| 2070 |
+
- BPC `0.5670 -> 0.5399` vs checkpoint `260`
|
| 2071 |
+
- new-target top-1 `0.3517 -> 0.3787`
|
| 2072 |
+
- greedy new-token utilization `0.196 -> 0.260`
|
| 2073 |
+
- Greek classification/reading signals were split:
|
| 2074 |
+
- improved vs `260`: `arc_challenge_mt_el` `+0.0119`,
|
| 2075 |
+
`belebele_ell_Grek` `+0.0311`, `global_mmlu_full_el` `+0.0073`
|
| 2076 |
+
- weaker vs `260`: `xnli_el` `-0.0116`,
|
| 2077 |
+
`include_base_44_greek_few_shot_en` `-0.0127`,
|
| 2078 |
+
`global_piqa_completions_ell_grek` `-0.0100`
|
| 2079 |
+
- largest regression: `xquad_el` exact match `-0.0437`, F1 `-0.0509`
|
| 2080 |
+
- General-preservation signals remain mixed:
|
| 2081 |
+
- MMLU/global-MMLU slightly recovered vs `260`
|
| 2082 |
+
- HellaSwag remains slightly above checkpoint `130`
|
| 2083 |
+
- ARC-Challenge, XNLI, and XCOPA are below checkpoint `260`
|
| 2084 |
+
|
| 2085 |
+
Training state at the same poll:
|
| 2086 |
+
|
| 2087 |
+
- Resume job `2357705` remained `RUNNING`.
|
| 2088 |
+
- Latest parsed line: iteration `413/476`, consumed tokens `1.732B`,
|
| 2089 |
+
timestamp `2026-05-24 10:12:42 CEST`, loss `2.544199`, throughput
|
| 2090 |
+
`7866.3` tokens/sec/GPU, skipped iterations `0`, NaN iterations `0`.
|
| 2091 |
+
- Training ETA from that line: `2:19:57`, putting finish near
|
| 2092 |
+
`2026-05-24 12:32-12:35 CEST`.
|
| 2093 |
+
|
| 2094 |
+
Interpretation:
|
| 2095 |
+
|
| 2096 |
+
- The checkpoint-390 evidence strengthens the case that TD is learning the new
|
| 2097 |
+
rows and Greek tokenization target.
|
| 2098 |
+
- It does not yet settle the production decision because XQuAD dropped sharply
|
| 2099 |
+
and general preservation remains mixed. Final checkpoint `476`, plus planned
|
| 2100 |
+
checkpoint `455`, should decide whether this is transient or a real
|
| 2101 |
+
over-training/preservation issue.
|
| 2102 |
+
|
| 2103 |
+
## Checkpoint 455 reached and eval chain submitted
|
| 2104 |
+
|
| 2105 |
+
Timestamp: `2026-05-24T09:54:09Z`
|
| 2106 |
+
|
| 2107 |
+
Training/checkpoint state:
|
| 2108 |
+
|
| 2109 |
+
- Resume job `2357705` remains `RUNNING`.
|
| 2110 |
+
- Checkpoint training line: iteration `455/476`, consumed tokens `1.908B`,
|
| 2111 |
+
timestamp `2026-05-24 11:46:02 CEST`, loss `2.518627`, throughput
|
| 2112 |
+
`7869.0` tokens/sec/GPU, skipped iterations `0`, NaN iterations `0`.
|
| 2113 |
+
- Checkpoint `iter_0000455` saved successfully and tracker advanced to `455`.
|
| 2114 |
+
- Training continued past the checkpoint; latest poll after save was
|
| 2115 |
+
iteration `457/476`, consumed tokens `1.917B`, timestamp
|
| 2116 |
+
`2026-05-24 11:50:29 CEST`, loss `2.532910`, skipped iterations `0`,
|
| 2117 |
+
NaN iterations `0`.
|
| 2118 |
+
|
| 2119 |
+
Eval automation:
|
| 2120 |
+
|
| 2121 |
+
- Backup watcher `2357766` detected the complete checkpoint and submitted the
|
| 2122 |
+
checkpoint-455 full eval chain.
|
| 2123 |
+
- Submitted jobs:
|
| 2124 |
+
- conversion: `2366619` (`tohf_td_l11_455`), completed `0:0`,
|
| 2125 |
+
elapsed `00:01:12`
|
| 2126 |
+
- full lm-eval: `2366621` (`eval_td_l11_455_full`), running at last check
|
| 2127 |
+
- intrinsic BPC: `2366622` (`bpc_td_l11_455`), completed `0:0`,
|
| 2128 |
+
elapsed `00:01:40`
|
| 2129 |
+
- new-token diagnostics: `2366623` (`diag_td_l11_455`), completed `0:0`,
|
| 2130 |
+
elapsed `00:02:21`
|
| 2131 |
+
|
| 2132 |
+
Quick intrinsic/diagnostic artifacts copied locally:
|
| 2133 |
+
|
| 2134 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000455_tokenizer_fair_metrics.json`
|
| 2135 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000455_new_token_diagnostics.json`
|
| 2136 |
+
|
| 2137 |
+
Quick checkpoint-455 intrinsic comparison vs checkpoint `390`:
|
| 2138 |
+
|
| 2139 |
+
- BPC: `0.539879 -> 0.532765`
|
| 2140 |
+
- NLL/token: `2.537096 -> 2.503662`
|
| 2141 |
+
- new-target top-1: `0.378668 -> 0.384541`
|
| 2142 |
+
- new-target top-10: `0.612043 -> 0.617435`
|
| 2143 |
+
- new-vocab probability mass: `0.344027 -> 0.341786`
|
| 2144 |
+
- greedy new-token utilization: `0.260 -> 0.200`
|
| 2145 |
+
|
| 2146 |
+
Interpretation:
|
| 2147 |
+
|
| 2148 |
+
- Intrinsic likelihood and new-target ranking continued improving at
|
| 2149 |
+
checkpoint `455`.
|
| 2150 |
+
- Greedy new-token utilization dropped from checkpoint `390`; this is only a
|
| 2151 |
+
tiny prompt-sample diagnostic, so the full downstream eval remains the
|
| 2152 |
+
decision-useful signal.
|
| 2153 |
+
- Next actions are to wait for full eval `2366621`, copy/digest the complete
|
| 2154 |
+
checkpoint-455 evidence, then continue to final checkpoint `476`.
|
| 2155 |
+
|
| 2156 |
+
## Checkpoint 455 full eval completed and copied locally
|
| 2157 |
+
|
| 2158 |
+
Timestamp: `2026-05-24T10:38:37Z`
|
| 2159 |
+
|
| 2160 |
+
Full eval `2366621` completed successfully:
|
| 2161 |
+
|
| 2162 |
+
- state `COMPLETED`, exit `0:0`, elapsed `00:46:46`
|
| 2163 |
+
- result JSON:
|
| 2164 |
+
`/capstor/scratch/cscs/fffoivos/runs/eval/td_full25_layer11_2b_20260523T165038Z/iter_0000455_full/results_2026-05-24T12-37-56.749011.json`
|
| 2165 |
+
|
| 2166 |
+
Compact artifacts copied locally:
|
| 2167 |
+
|
| 2168 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000455_results.json`
|
| 2169 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000455_run_metadata.json`
|
| 2170 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000455_tokenizer_fair_metrics.json`
|
| 2171 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000455_new_token_diagnostics.json`
|
| 2172 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000455_digest.md`
|
| 2173 |
+
|
| 2174 |
+
Checkpoint-455 full-eval headline:
|
| 2175 |
+
|
| 2176 |
+
- Intrinsic recovery continued vs checkpoint `390`:
|
| 2177 |
+
- BPC `0.5399 -> 0.5328`
|
| 2178 |
+
- new-target top-1 `0.3787 -> 0.3845`
|
| 2179 |
+
- new-target top-10 `0.6120 -> 0.6174`
|
| 2180 |
+
- Greek downstream vs checkpoint `390`:
|
| 2181 |
+
- recovered: `xnli_el` `+0.0060`, `xquad_el` F1 `+0.0067`,
|
| 2182 |
+
`global_mmlu_full_el` `+0.0006`,
|
| 2183 |
+
`include_base_44_greek_few_shot_en` `+0.0036`
|
| 2184 |
+
- moved down: `arc_challenge_mt_el` `-0.0094`,
|
| 2185 |
+
`belebele_ell_Grek` `-0.0122`,
|
| 2186 |
+
`global_piqa_completions_ell_grek` `-0.0100`
|
| 2187 |
+
- Same-checkpoint bakeoff comparison:
|
| 2188 |
+
- TD beats vanilla on Belebele, XQuAD F1, HellaSwag, and MMLU.
|
| 2189 |
+
- Vanilla still beats TD on Greek ARC, Greek MMLU, and the base-44 Greek
|
| 2190 |
+
aggregate.
|
| 2191 |
+
|
| 2192 |
+
Training/final checkpoint state at the same close-watch poll:
|
| 2193 |
+
|
| 2194 |
+
- Final training reached checkpoint `476/476` at `2026-05-24 12:32:40 CEST`.
|
| 2195 |
+
- Checkpoint `iter_0000476` saved successfully and tracker advanced to `476`.
|
| 2196 |
+
- Final eval chain submitted:
|
| 2197 |
+
- conversion `2367150`
|
| 2198 |
+
- full lm-eval `2367151`
|
| 2199 |
+
- intrinsic BPC `2367152`
|
| 2200 |
+
- new-token diagnostics `2367153`
|
| 2201 |
+
|
| 2202 |
+
Interpretation:
|
| 2203 |
+
|
| 2204 |
+
- Checkpoint `455` keeps TD ahead of ReTok/Centroid and confirms the new-token
|
| 2205 |
+
learning path is alive.
|
| 2206 |
+
- It does not clearly beat vanilla on the aggregate Greek criteria we care
|
| 2207 |
+
about. Final checkpoint `476` is now the decisive comparison point.
|
| 2208 |
+
|
| 2209 |
+
## Final checkpoint 476 reached and quick checks passed
|
| 2210 |
+
|
| 2211 |
+
Timestamp: `2026-05-24T10:44:52Z`
|
| 2212 |
+
|
| 2213 |
+
Training completed the planned 2B TD run:
|
| 2214 |
+
|
| 2215 |
+
- Final training line: iteration `476/476`, consumed tokens `1.996B`,
|
| 2216 |
+
timestamp `2026-05-24 12:32:40 CEST`, loss `2.496399`, throughput
|
| 2217 |
+
`7874.3` tokens/sec/GPU, skipped iterations `0`, NaN iterations `0`.
|
| 2218 |
+
- Checkpoint `iter_0000476` saved successfully.
|
| 2219 |
+
- Checkpoint tracker advanced to `476`.
|
| 2220 |
+
|
| 2221 |
+
Final eval chain submitted and quick side checks completed:
|
| 2222 |
+
|
| 2223 |
+
- conversion `2367150`: `COMPLETED`, `0:0`, elapsed `00:01:09`
|
| 2224 |
+
- full lm-eval `2367151`: `RUNNING` at last check
|
| 2225 |
+
- intrinsic BPC `2367152`: `COMPLETED`, `0:0`, elapsed `00:01:44`
|
| 2226 |
+
- new-token diagnostics `2367153`: `COMPLETED`, `0:0`, elapsed `00:02:00`
|
| 2227 |
+
|
| 2228 |
+
Quick final artifacts copied locally:
|
| 2229 |
+
|
| 2230 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000476_tokenizer_fair_metrics.json`
|
| 2231 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000476_new_token_diagnostics.json`
|
| 2232 |
+
|
| 2233 |
+
Quick intrinsic/diagnostic comparison vs checkpoint `455`:
|
| 2234 |
+
|
| 2235 |
+
- BPC: `0.532765 -> 0.531084`
|
| 2236 |
+
- NLL/token: `2.503662 -> 2.495764`
|
| 2237 |
+
- new-target top-1: `0.384541 -> 0.386419`
|
| 2238 |
+
- new-target top-10: `0.617435 -> 0.619114`
|
| 2239 |
+
- new-vocab probability mass: `0.341786 -> 0.342453`
|
| 2240 |
+
- greedy new-token utilization: `0.200 -> 0.208`
|
| 2241 |
+
|
| 2242 |
+
Interpretation:
|
| 2243 |
+
|
| 2244 |
+
- The 2B TD training run itself is complete and clean.
|
| 2245 |
+
- Intrinsic/new-token learning continued improving through the final
|
| 2246 |
+
checkpoint.
|
| 2247 |
+
- The production decision still waits on full final lm-eval `2367151`, because
|
| 2248 |
+
checkpoint `455` remained mixed against vanilla on aggregate Greek tasks.
|
| 2249 |
+
|
| 2250 |
+
## Final checkpoint 476 full eval completed
|
| 2251 |
+
|
| 2252 |
+
Timestamp: `2026-05-24T11:30:00Z`
|
| 2253 |
+
|
| 2254 |
+
Final full lm-eval completed cleanly:
|
| 2255 |
+
|
| 2256 |
+
- full lm-eval `2367151`: `COMPLETED`, `0:0`, elapsed `00:45:27`
|
| 2257 |
+
- generation phase completed at `2026-05-24 13:20:27 CEST`
|
| 2258 |
+
- aggregated results and per-task samples were written under:
|
| 2259 |
+
`/capstor/scratch/cscs/fffoivos/runs/eval/td_full25_layer11_2b_20260523T165038Z/iter_0000476_full`
|
| 2260 |
+
|
| 2261 |
+
Compact local artifacts copied:
|
| 2262 |
+
|
| 2263 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000476_results.json`
|
| 2264 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000476_run_metadata.json`
|
| 2265 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000476_tokenizer_fair_metrics.json`
|
| 2266 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000476_new_token_diagnostics.json`
|
| 2267 |
+
- `eval/live_summaries/td_full25_layer11_2b_20260523T165038Z_iter0000476_digest.md`
|
| 2268 |
+
|
| 2269 |
+
Final same-checkpoint TD-vs-vanilla highlights:
|
| 2270 |
+
|
| 2271 |
+
- TD wins: `belebele_ell_Grek` `+0.0144`, `xquad_el` F1 `+0.0161`,
|
| 2272 |
+
`mmlu` `+0.0161`, `hellaswag` `+0.0011`, `xnli` `+0.0024`, `xcopa`
|
| 2273 |
+
`+0.0045`; `arc_challenge` is tied.
|
| 2274 |
+
- Vanilla wins: `arc_challenge_mt_el` `+0.0171`, `global_mmlu_full_el`
|
| 2275 |
+
`+0.0355`, `include_base_44_greek_few_shot_en` `+0.0145`,
|
| 2276 |
+
`global_piqa_completions_ell_grek` `+0.0500`, and `global_mmlu`
|
| 2277 |
+
`+0.0075`.
|
| 2278 |
+
|
| 2279 |
+
Final intrinsic/tokenizer-local highlights:
|
| 2280 |
+
|
| 2281 |
+
- TD beats ReTok on heldout BPC: `0.5311` vs `0.5739`, and strongly beats
|
| 2282 |
+
Centroid: `0.8994`.
|
| 2283 |
+
- TD beats ReTok on new-target top-1/top-10: `0.3864`/`0.6191` vs
|
| 2284 |
+
`0.3497`/`0.5772`.
|
| 2285 |
+
- ReTok still has higher five-prompt greedy new-token utilization: `0.3580`
|
| 2286 |
+
vs TD `0.2080`; this is a weak diagnostic, but worth keeping visible.
|
| 2287 |
+
- TD/ReTok/Centroid preserve the Greek compression gain:
|
| 2288 |
+
`3.973` chars/token and `1.735` tokens/word, versus vanilla at `2.557`
|
| 2289 |
+
chars/token and `2.693` tokens/word.
|
| 2290 |
+
|
| 2291 |
+
Interpretation:
|
| 2292 |
+
|
| 2293 |
+
- TD is the strongest extended-tokenizer path and is no longer a failed
|
| 2294 |
+
initialization: it beats ReTok/Centroid broadly and recovers the new-token
|
| 2295 |
+
objective over the 2B challenger.
|
| 2296 |
+
- It still does not clearly beat the vanilla production path on the aggregate
|
| 2297 |
+
Greek/downstream preservation criteria. The safest default for the 15-20B CPT
|
| 2298 |
+
run remains vanilla unless compression/new-token behavior is promoted to a
|
| 2299 |
+
primary objective.
|
provenance/token-distillation/TOKEN_DISTILLATION_PLAN.md
ADDED
|
@@ -0,0 +1,773 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Token Distillation Parallel Plan
|
| 2 |
+
|
| 3 |
+
Status: draft execution plan, 2026-05-22
|
| 4 |
+
|
| 5 |
+
Purpose: prepare a bounded Token Distillation challenger that can start quickly if
|
| 6 |
+
the current Vanilla / ReTok / Centroid bakeoff leaves ReTok promising but
|
| 7 |
+
under-initialized. This is a companion plan, not a change to the running
|
| 8 |
+
three-arm bakeoff.
|
| 9 |
+
|
| 10 |
+
Primary external references:
|
| 11 |
+
|
| 12 |
+
- Paper: https://arxiv.org/abs/2505.20133
|
| 13 |
+
- Official implementation: https://github.com/konstantinjdobler/token-distillation
|
| 14 |
+
|
| 15 |
+
## 1. Decision Summary
|
| 16 |
+
|
| 17 |
+
Token Distillation is feasible for Apertus without inventing a new method. The
|
| 18 |
+
earlier "bracketed" status was too conservative if it was based on tied-vs-untied
|
| 19 |
+
embedding concerns. The official implementation learns input embeddings by
|
| 20 |
+
hidden-state distillation and has explicit untied-output handling through a
|
| 21 |
+
next-token CE path.
|
| 22 |
+
|
| 23 |
+
What is still real is integration risk:
|
| 24 |
+
|
| 25 |
+
- Apertus uses untied `embed_tokens` and `lm_head`, so `E` and `U` must be
|
| 26 |
+
checked independently.
|
| 27 |
+
- Our tokenizer is an extended BPE tokenizer with fixed production IDs, not a
|
| 28 |
+
base tokenizer plus `add_tokens(...)`.
|
| 29 |
+
- The distillation run must preserve xIELU and QK-Norm values and must survive
|
| 30 |
+
the same HF -> Megatron -> HF roundtrip gate as the other arms.
|
| 31 |
+
- Layer choice is not a free constant: the paper defaults to the final hidden
|
| 32 |
+
layer, while the package README says earlier target layers around the
|
| 33 |
+
one-third mark can work better. We will run a small layer pilot that tests
|
| 34 |
+
both: final layer plus the package-suggested one-third layer. If the
|
| 35 |
+
logit-lens/tuned-lens probe in Section 6.1 suggests a different layer, test
|
| 36 |
+
that as well.
|
| 37 |
+
|
| 38 |
+
## 2. When To Start
|
| 39 |
+
|
| 40 |
+
Do not interrupt the running three-arm bakeoff. Token Distillation can begin
|
| 41 |
+
once all of these are true:
|
| 42 |
+
|
| 43 |
+
1. The current bakeoff has reached the final scheduled checkpoint, or the
|
| 44 |
+
final checkpoint is safely saved and the remaining work is only evaluation.
|
| 45 |
+
2. ReTok is not already decisively beaten by Vanilla on both Greek BPC and the
|
| 46 |
+
new-token diagnostics.
|
| 47 |
+
3. One spare GH200 node can be used without delaying final bakeoff evals.
|
| 48 |
+
4. The implementation runs first on a small token subset and passes all
|
| 49 |
+
preservation gates in Section 8.
|
| 50 |
+
|
| 51 |
+
Recommended trigger:
|
| 52 |
+
|
| 53 |
+
- Run the Token Distillation pilot if ReTok has healthy new-token behavior
|
| 54 |
+
but still trails Vanilla on Greek BPC or downstream Greek tasks.
|
| 55 |
+
- Do not run it if Vanilla is clearly best and ReTok has weak new-token use;
|
| 56 |
+
in that case the tokenizer extension itself is probably not helping enough.
|
| 57 |
+
|
| 58 |
+
## 3. Experiment Shape
|
| 59 |
+
|
| 60 |
+
Name: `retok_td`
|
| 61 |
+
|
| 62 |
+
The experiment is not "TD from scratch." It is ReTok plus a TD refinement:
|
| 63 |
+
|
| 64 |
+
- Logical teacher: the original-tokenization path through the same frozen
|
| 65 |
+
Apertus weights. In implementation this does not need to be a second 8B model
|
| 66 |
+
in memory: the extended student can run the unmerged/base-tokenized sequence
|
| 67 |
+
under `torch.no_grad()` because all original rows and transformer weights are
|
| 68 |
+
frozen and identical to the base model.
|
| 69 |
+
- Student: ReTok-initialized HF checkpoint with the exact modern-only extended
|
| 70 |
+
tokenizer used by the current bakeoff.
|
| 71 |
+
- Input objective: hidden-state MSE between teacher runs using base-tokenized
|
| 72 |
+
spans and student runs using the corresponding single new token.
|
| 73 |
+
- Output objective: next-token CE on the merged sequence, with gradients allowed
|
| 74 |
+
to update only the new `lm_head` rows.
|
| 75 |
+
- Trainable parameters: new input rows and new output rows only.
|
| 76 |
+
- Frozen parameters: all transformer blocks, all original embedding/output
|
| 77 |
+
rows, xIELU scalars, QK-Norm weights, RMSNorm weights, and all other base
|
| 78 |
+
model parameters.
|
| 79 |
+
|
| 80 |
+
This isolates the question: "Does TD improve ReTok's placement of the new rows?"
|
| 81 |
+
|
| 82 |
+
## 4. Model Format Plan
|
| 83 |
+
|
| 84 |
+
Token Distillation should run in HF format, not Megatron format.
|
| 85 |
+
|
| 86 |
+
Inputs:
|
| 87 |
+
|
| 88 |
+
- Teacher/reference HF model: the unmodified Apertus HF base, used for validation
|
| 89 |
+
and optional row-diff checks. Do not require it to stay resident during TD
|
| 90 |
+
training unless an implementation choice truly needs it.
|
| 91 |
+
- Teacher tokenizer: base 131,072-token Apertus tokenizer.
|
| 92 |
+
- Physical training model: ReTok HF init checkpoint for the modern-only
|
| 93 |
+
148,480-token tokenizer. This model serves both the merged/student path and
|
| 94 |
+
the unmerged/logical-teacher path.
|
| 95 |
+
- Student tokenizer: exact shipped extended tokenizer from
|
| 96 |
+
`03_3_cscs_experiments_kickoff/ship/apertus_greek_modern_only_148480/`.
|
| 97 |
+
|
| 98 |
+
Outputs:
|
| 99 |
+
|
| 100 |
+
- HF checkpoint for `retok_td`.
|
| 101 |
+
- Exact student tokenizer copied through unchanged.
|
| 102 |
+
- A manifest with model paths, tokenizer hash, base vocab size, extended vocab
|
| 103 |
+
size, trainable row ranges, layer choice, data slice, and source commit of
|
| 104 |
+
the Token Distillation code.
|
| 105 |
+
- Megatron TP=2 `torch_dist` checkpoint produced with the same R17-preserving
|
| 106 |
+
conversion path used by the current bakeoff.
|
| 107 |
+
|
| 108 |
+
Sensitive point: do not let the reference implementation call
|
| 109 |
+
`target_tokenizer.add_tokens(...)` for production. That would create added-token
|
| 110 |
+
behavior and may change IDs/segmentation relative to our BPE extension. Patch or
|
| 111 |
+
wrap the implementation so the student tokenizer is loaded directly and treated
|
| 112 |
+
as authoritative.
|
| 113 |
+
|
| 114 |
+
Second sensitive point: do not load two 8B models just because the method is
|
| 115 |
+
described as teacher/student. The official training loop uses one extended model
|
| 116 |
+
for both the merged and unmerged forwards; preserve that memory-efficient shape
|
| 117 |
+
unless a later validation test proves it insufficient.
|
| 118 |
+
|
| 119 |
+
## 5. Token Mapping And Data
|
| 120 |
+
|
| 121 |
+
For each new token ID in the extended tokenizer:
|
| 122 |
+
|
| 123 |
+
1. Decode the token string using the same ByteLevel-aware readable-token logic
|
| 124 |
+
used in the tokenizer audits.
|
| 125 |
+
2. Tokenize the same surface string with the base tokenizer to get the teacher
|
| 126 |
+
phrase IDs.
|
| 127 |
+
3. Tokenize it with the extended tokenizer and verify it maps to exactly the
|
| 128 |
+
intended new token ID in the relevant context.
|
| 129 |
+
4. Mine snippets from the CPT Greek corpus where that surface string occurs.
|
| 130 |
+
|
| 131 |
+
Use real corpus snippets, not generated snippets, for the main run. Generated
|
| 132 |
+
snippets are acceptable only as a fallback for very low-coverage tokens in a
|
| 133 |
+
separate flagged bucket.
|
| 134 |
+
|
| 135 |
+
Initial data budgets:
|
| 136 |
+
|
| 137 |
+
- Smoke: 256 to 512 high-frequency new tokens, 20 to 50 snippets per token.
|
| 138 |
+
- Layer pilot: 1,024 to 2,048 tokens, 50 snippets per token, comparing
|
| 139 |
+
last-layer TD against the package-suggested one-third-depth layer and, if
|
| 140 |
+
available, the Section 6.1 probe-suggested layer.
|
| 141 |
+
- Full modern challenger: all 17,408 modern new tokens at the paper-fast
|
| 142 |
+
`25`-snippet setting first. The `100`-snippet setting is supported by the
|
| 143 |
+
coverage result, but is a follow-up only if the fast full-token checkpoint
|
| 144 |
+
clears gates while leaving quality ambiguous.
|
| 145 |
+
- Production polytonic extension: only after the modern path passes; then repeat
|
| 146 |
+
for the additional +5,120 polytonic tokens.
|
| 147 |
+
|
| 148 |
+
Coverage policy:
|
| 149 |
+
|
| 150 |
+
- Do not silently skip tokens. Emit `coverage.json` with requested snippets,
|
| 151 |
+
found snippets, used snippets, and fallback action per token.
|
| 152 |
+
- Split results into enough-coverage and low-coverage buckets during analysis.
|
| 153 |
+
- If more than 10 percent of new tokens have fewer than 20 real snippets, stop
|
| 154 |
+
before full TD and inspect the token inventory/corpus mismatch.
|
| 155 |
+
|
| 156 |
+
## 5.1 Firing Prepass On The Exact 2B Dataset
|
| 157 |
+
|
| 158 |
+
Before any GPU TD run, count actual new-token firings and usable snippets on the
|
| 159 |
+
exact normalized text/parquet slice that produced the 2B-token bakeoff dataset.
|
| 160 |
+
Do this on the pre-packed source text, not only on Megatron `.bin`, because TD
|
| 161 |
+
needs text spans and 50-token contexts.
|
| 162 |
+
|
| 163 |
+
This is a CPU/I/O job and should run as a sidecar only after the current bakeoff
|
| 164 |
+
final checkpoints are safely saved, or while final downstream evals are running.
|
| 165 |
+
Do not let it compete with training checkpoint saves or packed eval cache reads.
|
| 166 |
+
|
| 167 |
+
Output artifact:
|
| 168 |
+
|
| 169 |
+
- `td_coverage_prepass.jsonl`: one row per new token.
|
| 170 |
+
- `td_coverage_summary.json`: aggregate thresholds and recommended action.
|
| 171 |
+
- `td_snippet_index/`: sampled snippet references or extracted tokenized snippets
|
| 172 |
+
keyed by `new_token_id`.
|
| 173 |
+
|
| 174 |
+
Required row fields:
|
| 175 |
+
|
| 176 |
+
- `new_token_id`
|
| 177 |
+
- `token_string`
|
| 178 |
+
- `base_subtoken_ids`
|
| 179 |
+
- `base_subtoken_len`
|
| 180 |
+
- `extended_firings`
|
| 181 |
+
- `raw_surface_occurrences` where cheap to compute
|
| 182 |
+
- `usable_snippets_25`
|
| 183 |
+
- `usable_snippets_100`
|
| 184 |
+
- `docs_with_firing`
|
| 185 |
+
- `example_snippet_refs`
|
| 186 |
+
- `status`: `enough_100`, `enough_25`, `low_20_24`, `low_lt20`,
|
| 187 |
+
`zero`, or `mismatch`
|
| 188 |
+
- `recommended_action`: `td_100`, `td_25`, `keep_retok`,
|
| 189 |
+
`generated_fallback_candidate`, or `inspect`
|
| 190 |
+
|
| 191 |
+
Counting rule:
|
| 192 |
+
|
| 193 |
+
- A firing means the extended tokenizer actually emits that new token ID.
|
| 194 |
+
- Merge ancestry does not count.
|
| 195 |
+
- A surface substring does not count unless it corresponds to the emitted
|
| 196 |
+
new-token span under the extended tokenizer.
|
| 197 |
+
- For each firing span, tokenize the same surface span with the base tokenizer
|
| 198 |
+
to build the logical-teacher sequence.
|
| 199 |
+
|
| 200 |
+
Decision gate:
|
| 201 |
+
|
| 202 |
+
- If at least 90 percent of new tokens have `usable_snippets_100 >= 100`, mark
|
| 203 |
+
the corpus as high-coverage, but still run the first full-token challenger at
|
| 204 |
+
the paper-fast 25-snippet setting unless a prior full-token fast run has
|
| 205 |
+
already passed.
|
| 206 |
+
- If at least 90 percent have `usable_snippets_25 >= 25`, run TD at the paper's
|
| 207 |
+
fast 25-snippet setting and keep a flagged tail strategy.
|
| 208 |
+
- If more than 10 percent have `usable_snippets_25 < 25`, do not launch full TD.
|
| 209 |
+
Inspect whether the problem is dataset coverage, tokenizer/string decoding, or
|
| 210 |
+
low-value tail tokens.
|
| 211 |
+
- Tokens with `usable_snippets < 20` keep ReTok by default. Generated snippets
|
| 212 |
+
are allowed only as a separately reported fallback bucket.
|
| 213 |
+
- Tokens with `status = mismatch` block the TD run until the tokenizer/span
|
| 214 |
+
mapping is fixed.
|
| 215 |
+
|
| 216 |
+
## 6. Layer Choice
|
| 217 |
+
|
| 218 |
+
**Default candidate for Apertus 8B: last layer (`target_layer = -1`). Required comparison candidate: package-suggested one-third-depth layer. No broad sweep.**
|
| 219 |
+
|
| 220 |
+
The paper argues for last layer as the conservative, portable default. Direct quotes:
|
| 221 |
+
|
| 222 |
+
> *"In practice, we simply use the last layer's hidden state but analyze this choice in Section 5.3."* — paper §3.2, p.4.
|
| 223 |
+
|
| 224 |
+
> *"For our main experiments, we choose to keep the last layer because this choice does not necessitate a model-specific sweep over target layers. Also, the last layer is a principled choice, as it guarantees that no subtoken interactions that are only modeled in later layers are excluded from the objective."* — paper §5.3 (per a second-pass review of the paper's layer-choice analysis).
|
| 225 |
+
|
| 226 |
+
The argument for the last layer is **conservative-and-correct**: any way the original subtoken sequence influenced downstream computation must, by construction, have shown up by the final hidden state. Matching there upper-bounds the objective. But the package README is explicit that earlier target layers around the one-third mark can yield better results in many cases. That means we should not pick last-layer only without checking the package-suggested alternative.
|
| 227 |
+
|
| 228 |
+
Implication for Apertus 8B specifically: run a **small** layer pilot, not a sweep.
|
| 229 |
+
|
| 230 |
+
- Candidate A: `target_layer = -1`, the paper-default last layer.
|
| 231 |
+
- Candidate B: `target_layer = ceil(num_hidden_layers / 3)` in HF hidden-state tuple indexing after confirming Section 16 Q11. For Apertus-8B's 32 transformer layers, expected candidate is `target_layer = 11` (roughly after the first third of blocks).
|
| 232 |
+
- Candidate C: if the Section 6.1 logit-lens/tuned-lens probe suggests a materially different detokenization layer `L*`, test that layer too. If `L*` is within +/-1 of Candidate B, do not add a third candidate.
|
| 233 |
+
- Implementation note from the first live smoke: the vendored package does **not** ship a separate layer-suggestion tool. Its actionable upstream guidance is the README note that one-third-depth target layers can work better than the last layer. Therefore the first layer pilot should compare Candidate A and Candidate B only, unless we have a well-defined Apertus-specific probe result.
|
| 234 |
+
|
| 235 |
+
Selection rule:
|
| 236 |
+
|
| 237 |
+
- Choose the candidate with better heldout Greek BPC/NLL and D1/D2/D4/D5 on the layer-pilot subset.
|
| 238 |
+
- If differences are within noise, choose last layer for portability and to avoid model-specific overfitting.
|
| 239 |
+
- Do not test more than three candidates unless the first TD run fails in a way that is clearly layer-specific.
|
| 240 |
+
|
| 241 |
+
For polytonic Phase 2 specifically (the +5,120 polytonic tokens, deferred per §5): **also default to last layer**. The detokenization machinery for unfamiliar diacritic-heavy sequences plausibly uses more late-layer compute than for typical modern words — the model has to reassemble diacritic + base-char interactions it saw less cleanly during pretraining. The conservative default earns its keep here.
|
| 242 |
+
|
| 243 |
+
### 6.1 Layer-suggestion probe to find the "detokenization layer" L*
|
| 244 |
+
|
| 245 |
+
Before the layer pilot, run a cheap logit-lens probe to get our best Apertus-specific guess for where the residual stream finishes resolving multi-token Greek words into a single contextual representation:
|
| 246 |
+
|
| 247 |
+
1. Take a held-out set of multi-token Greek words from our corpus (~200-500 words that the base tokenizer fragments into 2-5 subpieces).
|
| 248 |
+
2. Run them through the **original Apertus base** (no TD), recording the residual stream at every layer at the position of the LAST subtoken.
|
| 249 |
+
3. Project each layer's residual through Apertus's `lm_head` (logit lens) OR a learned per-layer linear probe (tuned lens — Belrose et al. 2023, *Eliciting Latent Predictions from Transformers with the Tuned Lens*, arXiv:2303.08112).
|
| 250 |
+
4. Find the layer index `L*` where the top-1 projection first reliably matches the whole-word identity (i.e., where the model has "decided" what whole word it's processing).
|
| 251 |
+
|
| 252 |
+
For Llama-class 32-layer 8B models, `L*` is reportedly in the first third of layers (per a Kaplan et al. 2025 "Tokens to Words" line of work — **citation needs verification before being load-bearing**). For Apertus, plausibly similar (`L* ≈ 8-12` of 32), but Apertus's xIELU + QK-Norm could shift this; the only way to know is to run the probe.
|
| 253 |
+
|
| 254 |
+
**Cost:** one forward pass per probe sample × 32 layers of projection ≈ trivial on one GH200 (< 30 min for 500 words).
|
| 255 |
+
|
| 256 |
+
**What it gives us:** an *informative diagnostic* for the paper-quality writeup ("here's where Apertus does detokenization"), and a sanity check that last-layer TD isn't wasted compute (if `L* = 5` and we train at layer 32, we're propagating identical signal through 27 layers per backward pass). If we find `L* = 25+`, that's also informative — Apertus's late layers may be more LM-head-staging than Llama's, in which case last-layer is doubly the right choice.
|
| 257 |
+
|
| 258 |
+
**Action:** run the cheap logit-lens version after the first successful TD smoke
|
| 259 |
+
and before the layer pilot. If it suggests a clear `L*` that differs from the
|
| 260 |
+
one-third-depth layer, include `L*` as Candidate C in the layer pilot. The
|
| 261 |
+
heavier tuned-lens version remains optional and should not block the modern TD
|
| 262 |
+
path. Tracked as task TD7 in §9.
|
| 263 |
+
|
| 264 |
+
## 7. Output Embeddings
|
| 265 |
+
|
| 266 |
+
Apertus has untied embeddings, so `lm_head` rows must be handled deliberately.
|
| 267 |
+
|
| 268 |
+
Primary output strategy:
|
| 269 |
+
|
| 270 |
+
- Start from the ReTok `lm_head` rows already present in the student checkpoint.
|
| 271 |
+
- During TD, train only the new output rows with next-token CE.
|
| 272 |
+
- Keep original output rows frozen and verify they are unchanged exactly.
|
| 273 |
+
- Keep the input hidden-state MSE and output CE accounting separate in logs.
|
| 274 |
+
|
| 275 |
+
Fallbacks:
|
| 276 |
+
|
| 277 |
+
- If CE makes output norms unstable, train only input rows and keep ReTok output
|
| 278 |
+
rows fixed.
|
| 279 |
+
- If ReTok output rows look bad before TD, use subtoken-mean output initialization
|
| 280 |
+
from the base output matrix, then CE-train only new output rows.
|
| 281 |
+
|
| 282 |
+
Avoid using a tied-embedding shortcut. It does not apply to Apertus.
|
| 283 |
+
|
| 284 |
+
## 8. Verification Gates
|
| 285 |
+
|
| 286 |
+
The TD run is not usable until all of these pass.
|
| 287 |
+
|
| 288 |
+
Tokenizer gates:
|
| 289 |
+
|
| 290 |
+
- Extended tokenizer files are byte-identical before and after TD.
|
| 291 |
+
- Base special token IDs and extended special token IDs match the current
|
| 292 |
+
bakeoff tokenizer manifests.
|
| 293 |
+
- New token IDs equal the planned contiguous range.
|
| 294 |
+
- A fixed sample of Greek strings tokenizes exactly as in the ReTok arm.
|
| 295 |
+
|
| 296 |
+
Model gates:
|
| 297 |
+
|
| 298 |
+
- Original input rows unchanged exactly.
|
| 299 |
+
- Original output rows unchanged exactly.
|
| 300 |
+
- New input/output rows finite, nonzero, and within documented norm envelopes.
|
| 301 |
+
- xIELU scalar tensors unchanged exactly.
|
| 302 |
+
- QK-Norm tensors unchanged exactly.
|
| 303 |
+
- Logits on prompts that do not use new tokens remain unchanged or within a
|
| 304 |
+
documented numerical tolerance.
|
| 305 |
+
|
| 306 |
+
Roundtrip gates:
|
| 307 |
+
|
| 308 |
+
- Convert HF `retok_td` -> Megatron TP=2 with the R17-preserving path.
|
| 309 |
+
- Convert back or run the existing roundtrip verifier.
|
| 310 |
+
- Require zero or near-zero diff for xIELU, QK-Norm, and unchanged base rows.
|
| 311 |
+
- Run a short Megatron load/train smoke before queueing any CPT-scale arm.
|
| 312 |
+
|
| 313 |
+
Quality gates:
|
| 314 |
+
|
| 315 |
+
- Pre-CPT BPC should improve over ReTok on the heldout Greek slice.
|
| 316 |
+
- D1/D2/D4/D5 should improve or remain healthy versus ReTok.
|
| 317 |
+
- No obvious English retention regression on the small prompt/eval sanity set.
|
| 318 |
+
- If pre-CPT gates are neutral, do not spend a full 2B-token arm on TD.
|
| 319 |
+
|
| 320 |
+
## 9. Implementation Tasks
|
| 321 |
+
|
| 322 |
+
Task TD0 - vendor or pin reference code:
|
| 323 |
+
|
| 324 |
+
- Pin the official Token Distillation repo commit in a manifest.
|
| 325 |
+
- Do not rely on a moving GitHub checkout from inside a Slurm job.
|
| 326 |
+
|
| 327 |
+
Task TD1 - exact-tokenizer adapter:
|
| 328 |
+
|
| 329 |
+
- Add a wrapper that accepts separate teacher and student tokenizers.
|
| 330 |
+
- Disable `add_tokens(...)` in the production path.
|
| 331 |
+
- Build explicit mapping:
|
| 332 |
+
`new_token_id -> token_string -> base_phrase_ids -> student_token_id`.
|
| 333 |
+
|
| 334 |
+
Task TD2 - local corpus snippet source:
|
| 335 |
+
|
| 336 |
+
- Implement a local JSONL/parquet snippet miner over the existing CPT corpus
|
| 337 |
+
slice.
|
| 338 |
+
- Cache snippets in a reusable artifact keyed by tokenizer hash and corpus hash.
|
| 339 |
+
- First mode is the Section 5.1 firing prepass: count actual extended-token
|
| 340 |
+
firings and usable snippets on the exact 2B bakeoff text slice, then produce
|
| 341 |
+
`td_coverage_prepass.jsonl`, `td_coverage_summary.json`, and
|
| 342 |
+
`td_snippet_index/`.
|
| 343 |
+
|
| 344 |
+
Task TD3 - embedding-only trainer:
|
| 345 |
+
|
| 346 |
+
- Load the ReTok HF student once and use it for both the merged/student forward
|
| 347 |
+
and the unmerged/logical-teacher forward.
|
| 348 |
+
- Freeze all non-new rows and all transformer parameters.
|
| 349 |
+
- Backprop hidden-state MSE to new input rows.
|
| 350 |
+
- Backprop CE to new output rows only.
|
| 351 |
+
- Emit loss, norm, gradient, and coverage telemetry.
|
| 352 |
+
|
| 353 |
+
Task TD4 - pilot runs:
|
| 354 |
+
|
| 355 |
+
- Run smoke on 256 to 512 high-frequency new tokens.
|
| 356 |
+
- Only choose smoke tokens from `status in {enough_100, enough_25}` in the
|
| 357 |
+
Section 5.1 prepass.
|
| 358 |
+
- Run the Section 6.1 logit-lens probe to get a candidate detokenization layer
|
| 359 |
+
`L*`.
|
| 360 |
+
- Run a layer pilot on 1,024 to 2,048 tokens comparing:
|
| 361 |
+
- `target_layer=-1` (paper default),
|
| 362 |
+
- `target_layer=ceil(num_hidden_layers / 3)` (package README suggestion;
|
| 363 |
+
expected Apertus-8B value: `11` after Q11 indexing confirmation),
|
| 364 |
+
- `target_layer=L*` if the probe suggests a materially different layer.
|
| 365 |
+
- Pick the output strategy before full TD.
|
| 366 |
+
|
| 367 |
+
Task TD5 - full modern TD:
|
| 368 |
+
|
| 369 |
+
- Run all 17,408 modern new tokens first at `snippets_per_token=25`.
|
| 370 |
+
- Keep `snippets_per_token=50/100` as a follow-up quality-budget test, not the
|
| 371 |
+
first full-token cost event.
|
| 372 |
+
- Save HF checkpoint, manifest, coverage, and diagnostics.
|
| 373 |
+
- Run verification gates.
|
| 374 |
+
|
| 375 |
+
Task TD6 - optional fourth CPT arm:
|
| 376 |
+
|
| 377 |
+
- Only after TD5 passes, convert to Megatron and run a short CPT smoke.
|
| 378 |
+
- If smoke passes and pre-CPT diagnostics beat ReTok, submit `retok_td` as a
|
| 379 |
+
separate fourth arm or a shorter challenger run.
|
| 380 |
+
|
| 381 |
+
## 10. Risks And Mitigations
|
| 382 |
+
|
| 383 |
+
Tokenizer mismatch:
|
| 384 |
+
|
| 385 |
+
- Highest-risk integration point. Mitigation: never regenerate the tokenizer;
|
| 386 |
+
load the exact extended tokenizer and assert ID/sample-tokenization equality.
|
| 387 |
+
|
| 388 |
+
Layer mis-selection:
|
| 389 |
+
|
| 390 |
+
- Mitigation: test the paper-default last layer against the package-suggested
|
| 391 |
+
one-third-depth layer and, if available, the tool/probe-suggested layer.
|
| 392 |
+
Keep the candidate set tiny to avoid turning TD into a layer-sweep project.
|
| 393 |
+
|
| 394 |
+
Output-row instability:
|
| 395 |
+
|
| 396 |
+
- Mitigation: keep ReTok `U` as the starting point, CE-train only new rows, and
|
| 397 |
+
fall back to fixed ReTok `U` if norms or logits become unstable.
|
| 398 |
+
|
| 399 |
+
Silent base-model drift:
|
| 400 |
+
|
| 401 |
+
- Mitigation: exact row-diff checks after every pilot and full run.
|
| 402 |
+
|
| 403 |
+
xIELU/QK-Norm drift:
|
| 404 |
+
|
| 405 |
+
- Mitigation: freeze all non-embedding parameters and reuse the R17 roundtrip
|
| 406 |
+
verifier.
|
| 407 |
+
|
| 408 |
+
Coverage skew:
|
| 409 |
+
|
| 410 |
+
- Mitigation: coverage manifest, frequency buckets, and a hard stop if too many
|
| 411 |
+
tokens lack real snippets.
|
| 412 |
+
|
| 413 |
+
Resource overuse:
|
| 414 |
+
|
| 415 |
+
- Mitigation: one-node pilots first; do not queue a full fourth arm before the
|
| 416 |
+
current bakeoff result is interpretable.
|
| 417 |
+
|
| 418 |
+
## 11. Expected Cost
|
| 419 |
+
|
| 420 |
+
Order-of-magnitude expectation:
|
| 421 |
+
|
| 422 |
+
- smoke: less than 1 node-hour,
|
| 423 |
+
- layer pilot: 1 to 2 node-hours,
|
| 424 |
+
- full modern TD: roughly 5-7 wall hours for the first full-token 25-snippet
|
| 425 |
+
challenger on one GH200-class process; more if run at 50/100 snippets,
|
| 426 |
+
- optional CPT challenger: same training cost shape as one current bakeoff arm.
|
| 427 |
+
|
| 428 |
+
The TD preparation is worth doing now because implementation and verification
|
| 429 |
+
can be made ready without spending the CPT-scale cost event.
|
| 430 |
+
|
| 431 |
+
> Compute reality check (paper, page 4): *"These restrictions ensure that our method is quick to run, initializing 2,500 new tokens on a single GPU in under 10 minutes."* (1× H100 80GB, AdamW, 25 snippets × 50 ctx tokens.) Our live Apertus layer pilot, however, is the better planning anchor: `1,020` trained tokens × `50` snippets at layer 11 took `1,966.9s`. Scaling that to `17,392` trainable tokens at `25` snippets gives roughly **4.7 wall hours** for the fast full-token run; scaling to `100` snippets gives roughly **18-19 wall hours**. Because Clariden normal nodes expose 4 GPUs and have a 12h limit, the first full-token TD challenger should be `25` snippets. A 50/100-snippet run is a separate follow-up, not the first full-token cost event.
|
| 432 |
+
|
| 433 |
+
---
|
| 434 |
+
|
| 435 |
+
## 12. Apertus-specific considerations
|
| 436 |
+
|
| 437 |
+
These are questions about how Apertus's architectural quirks interact with the official TD implementation. Each is tagged with priority and a `Resolution` line that gets filled in once verified.
|
| 438 |
+
|
| 439 |
+
### A1. Position-encoding asymmetry between teacher and student sequences (RoPE phase shift)
|
| 440 |
+
|
| 441 |
+
**The mechanism.** When the teacher reads the unmerged sequence `[ctx_L, s1, ..., sk, ctx_R]` and the student reads the merged sequence `[ctx_L, T, ctx_R, PAD × (k-1)]`, the RoPE phase at every position *after* the merged-phrase position differs by `(k-1)` between teacher and student. Apertus uses RoPE with llama3-style scaling factor 8.0, so the phase difference manifests in the q/k rotations the model applies before the dot product.
|
| 442 |
+
|
| 443 |
+
**Resolution (from official code, train_loop.py:67-89):** the implementation **does** pad the merged sequence with PAD tokens at the end to match the unmerged length. Both teacher and student therefore see the same total sequence length, but the meaningful tokens occupy different positions:
|
| 444 |
+
- Teacher: real tokens at positions `[0, L+k+R-1]`, no padding.
|
| 445 |
+
- Student: real tokens at positions `[0, L+R-1]`, PAD at positions `[L+R, L+k+R-1]`.
|
| 446 |
+
|
| 447 |
+
The MSE loss is taken over positions selected by `unmerged_to_merged_mask == 1` (teacher) and `merged_seq != pad_id` (student). These two selections produce the same number of positions. The compare position for the assigned-phrase's last subtoken (teacher position `L+k-1`) is matched to the student position `L` (the single new token).
|
| 448 |
+
|
| 449 |
+
**Implication:** the RoPE phases at the compare positions for `ctx_R` tokens *differ between teacher and student* by `(k-1)`. The implementation accepts this and trusts that the model's downstream layers still produce comparable hidden states. The paper does the same. For modern Greek where `k` is typically 2-5, this is mild; for polytonic where `k` can be larger (more aggressive subword fragmentation), it's more pronounced. **Status: accepted as the paper's design**; we don't need to change it, but it's worth flagging as a known approximation.
|
| 450 |
+
|
| 451 |
+
**Action:** none for modern bakeoff. For the polytonic Phase 2 sub-plan (§9.5 below), consider whether `k > 8` tokens should be excluded from the TD set.
|
| 452 |
+
|
| 453 |
+
### A2. Cached teacher hidden states — optional optimization, not first implementation
|
| 454 |
+
|
| 455 |
+
The official `train_loop.py:282-285` runs the teacher forward fresh on every epoch under `torch.no_grad()`. The teacher is frozen, so its hidden states for each `(snippet, target_position)` pair are **fixed across all epochs**. The plan should add caching:
|
| 456 |
+
|
| 457 |
+
- After dataloader construction, do one teacher forward pass over the whole dataset, save `og_hiddens[mask==1]` to disk keyed by snippet hash + target layer.
|
| 458 |
+
- During the training loop, skip the teacher forward entirely; read cached hiddens.
|
| 459 |
+
|
| 460 |
+
**Cache footprint:** ~17,408 tokens × 100 snippets × `~50` positions × 4096 dim × bf16 ≈ **700 GB per target layer**. Too big for one node's RAM and large enough that random per-batch reads could become an I/O problem if the dataloader shuffles globally.
|
| 461 |
+
|
| 462 |
+
If we want a tighter cache: store only the positions used by the loss (mask=1 positions), which is at most `~50` per snippet. Same order of magnitude.
|
| 463 |
+
|
| 464 |
+
**Cache key must include:** teacher checkpoint hash, dtype (bf16/fp32), `attn_implementation` (sdpa/flash-attn-2), `target_layer`, RoPE config, NFC version of the snippet text. Invalidation must trigger a fresh cache.
|
| 465 |
+
|
| 466 |
+
**Speedup:** potentially useful when repeating the same data/layer across several
|
| 467 |
+
LR or batch-size probes. For the first one-epoch run, caching may not beat the
|
| 468 |
+
simplicity of recomputing the teacher forward, especially if cache reads become
|
| 469 |
+
random.
|
| 470 |
+
|
| 471 |
+
**Action:** do **not** make caching a blocker for TD1-TD5. Implement uncached
|
| 472 |
+
first, then add a cache only if the layer pilot repeats the same target layer or
|
| 473 |
+
the teacher forward is empirically dominating wall time.
|
| 474 |
+
|
| 475 |
+
### A3. NFC normalization on snippets — must match the corpus we trained on
|
| 476 |
+
|
| 477 |
+
`apertus_fidelity_checklist.md` V9: the CPT corpus is NFC-normalized in place by `normalize_nfc.sh`. The TD snippet miner must read from the **post-normalize parquet** (`cpt/selected_after_apertus_and_internal_dedup.parquet` after job 2335826), not the pre-normalize version. Any TD that conflates the two will see surface-string mismatches (e.g., NFD-decomposed Greek diacritics will not match new-token strings whose tokenizer was trained on NFC).
|
| 478 |
+
|
| 479 |
+
**Action:** assert in the snippet miner that the corpus was last modified after the normalize_nfc job's recorded timestamp; refuse to run if not.
|
| 480 |
+
|
| 481 |
+
### A4. Mixed-precision recipe for TD
|
| 482 |
+
|
| 483 |
+
The official code uses `torch.autocast("cuda", dtype=torch.bfloat16)` with `mixed_precision=True`. This matches Apertus's bf16-main / fp32-master-grads pretraining recipe. **Recommendation:** keep the default. AdamW moment buffers are fp32 by default in PyTorch; with `weight_decay=0` (paper default) this is identical to Apertus's optimizer state for the trainable rows.
|
| 484 |
+
|
| 485 |
+
### A5. Apertus-overlap-drop applied to the CPT corpus — soft consideration
|
| 486 |
+
|
| 487 |
+
The CPT corpus has `apertus_overlap_drop_docs.parquet` rows removed (the docs that overlap with Apertus's pretraining set). The TEACHER (Apertus base) has *seen* those dropped docs and presumably has sharper hidden states on them. Snippets drawn from the post-drop CPT corpus give a slightly noisier teacher.
|
| 488 |
+
|
| 489 |
+
For the modern-Greek TD, this is a minor effect — the corpus is still ~5B Greek tokens, plenty for snippets. But for the polytonic Phase 2 (where the corpus is thinner anyway), drawing some snippets from the pre-drop set could help. The pre-drop corpus exists at `/iopsstor/scratch/cscs/fffoivos/cpt_corpus/nanochat/data/*.parquet` (before the apertus-overlap drop overlay was applied).
|
| 490 |
+
|
| 491 |
+
**Action:** for modern TD, ignore. For polytonic TD, consider adding ~10-20% snippets from the pre-drop corpus to the pool.
|
| 492 |
+
|
| 493 |
+
### A6. Polytonic snippet sourcing — a separate Phase 2 data problem
|
| 494 |
+
|
| 495 |
+
The plan's §5 mentions polytonic TD as a follow-on. The modern-only CPT corpus has almost no polytonic content (the corpus was Greek-modern-targeted). For the +5,120 polytonic tokens, snippets must come from elsewhere:
|
| 496 |
+
|
| 497 |
+
- The polytonic-marked subsets of the original GlossAPI corpus (pre-Apertus-overlap-drop).
|
| 498 |
+
- External polytonic sources: ancient/koine Wikipedia, Project Gutenberg Greek, the patristic / classical Greek corpus subsets.
|
| 499 |
+
- The `legacy/corpus_clean_normalization/` polytonic-flagged documents (per `glossapi_corpus_cli/pipeline.py`'s `derive_historical_flag`).
|
| 500 |
+
|
| 501 |
+
**Action:** Phase 2 TD requires a polytonic snippet pull as a prerequisite. Add as a separate work item; do not block modern TD on it.
|
| 502 |
+
|
| 503 |
+
---
|
| 504 |
+
|
| 505 |
+
## 13. Paper and repo specifics — verifications from the research pass
|
| 506 |
+
|
| 507 |
+
Each row records what the plan was assuming, what the paper / repo actually says, and the resulting action.
|
| 508 |
+
|
| 509 |
+
### P1. The implementation uses `model.forward()` outputs, not custom attention hooks
|
| 510 |
+
|
| 511 |
+
**Plan assumption:** "Use `model.forward()` rather than reimplemented attention math" (per `cpt_plan.md v0.7 §13`'s general advice).
|
| 512 |
+
|
| 513 |
+
**Verified:** `train_loop.py:278` calls `model(merged_seq, output_hidden_states=True)`, `train_loop.py:285` calls `model(unmerged_seq, output_hidden_states=True)` under `torch.no_grad()`. The hidden states are read from `outputs["hidden_states"][target_layer]`. Standard HuggingFace API. **Compatible with Apertus's xIELU + QK-Norm** because both happen inside `model.forward()`.
|
| 514 |
+
|
| 515 |
+
**Action:** none. The QK-Norm worry from v0.6 §13 is genuinely moot for hidden-state TD.
|
| 516 |
+
|
| 517 |
+
### P2. Learning rate, optimizer, scheduler, step count
|
| 518 |
+
|
| 519 |
+
**Plan assumption:** "LR ~1e-3 to 1e-4 AdamW, ~500-2000 steps".
|
| 520 |
+
|
| 521 |
+
**Verified from paper (p.4) + code (`train_loop.py:250-259`):**
|
| 522 |
+
- Optimizer: AdamW, `weight_decay=0.0`.
|
| 523 |
+
- Scheduler: **constant LR** (code comment: *"paper used linear warmup + decay but constant works fine and might even converge faster"*). The paper itself says *"linear warmup, constant rate"*.
|
| 524 |
+
- Default LR in code: `1e-4`. README: *"learning rates around 1e-4 work well for many models"*.
|
| 525 |
+
- Paper: *"For fair comparison, we sweep for the best learning rate for all methods that require a learning rate."* — they sweep per method.
|
| 526 |
+
- Step count: not directly named; controlled by `epochs * len(dataloader)`. Default `epochs=1`. With 17,408 tokens × 100 snippets / batch_size 16 ≈ 109,000 batches per epoch.
|
| 527 |
+
|
| 528 |
+
**Action:** start with `lr=1e-4, epochs=1, weight_decay=0, scheduler=constant` (paper + repo defaults). LR sweep is a Phase 2 optimization if results are off; do not sweep on the first run.
|
| 529 |
+
|
| 530 |
+
### P3. Snippet count + length recommendations
|
| 531 |
+
|
| 532 |
+
**Plan assumption:** "100 snippets per token, snippet length not specified."
|
| 533 |
+
|
| 534 |
+
**Verified from paper (p.4) + README:**
|
| 535 |
+
- **Fast setting (used for main results):** `snippets_per_token=25, snippet_len=50`. *"2,500 new tokens on a single GPU in under 10 minutes"*.
|
| 536 |
+
- **Larger compute budget (paper §5.2):** `snippets_per_token=100, snippet_len=50`.
|
| 537 |
+
- README: *"We observe diminishing returns for scaling `snippet_len` beyond 50 and `snippets_per_token` beyond 100."*
|
| 538 |
+
|
| 539 |
+
**Recommendation after live Apertus pilot:** start the full-token challenger at
|
| 540 |
+
the paper-fast budget (`25, 50`). The coverage result says the corpus can
|
| 541 |
+
support `100` snippets for 99.82 percent of the new tokens, but the live runtime
|
| 542 |
+
estimate puts `100` snippets at roughly 18-19 wall hours on one GPU process.
|
| 543 |
+
Use `50/100` only after the fast full-token checkpoint is evaluated.
|
| 544 |
+
|
| 545 |
+
**Action:** set `snippets_per_token=25, snippet_len=50` for the first full
|
| 546 |
+
modern run. Keep `snippets_per_token=100` as a documented optional high-budget
|
| 547 |
+
follow-up.
|
| 548 |
+
|
| 549 |
+
### P4. Snippet sampling and batch composition
|
| 550 |
+
|
| 551 |
+
**Verified from code (`tokdist.py:191-278`):**
|
| 552 |
+
- **Pattern matching:** uses Aho-Corasick (`ahocorasick.py`) to find all occurrences of new-token surface strings in a tokenized corpus, in a single linear pass.
|
| 553 |
+
- **Snippet size:** `offset_before = snippet_len*2`, `offset_after = snippet_len*2` (so candidates have up to ~4× snippet_len + pattern_len tokens), then truncated to exactly `snippet_len` with the pattern roughly centered.
|
| 554 |
+
- **Filtering:** if fewer than `snippets_per_token` usable snippets are found, the token is **skipped** (printed to stdout, returned in the `skipped` list). The plan's §5 coverage policy already mirrors this.
|
| 555 |
+
- **Shuffling:** `random.shuffle(truncated)` before truncation to `snippets_per_token`, to avoid sort-order bias.
|
| 556 |
+
- **BOS prefix:** `bos_prefix = [bos_token_id]` is prepended to every snippet.
|
| 557 |
+
- **Batches:** dataset is flat (one entry per (snippet, assigned_phrase) pair), dataloader uses `shuffle=True` so batches mix tokens.
|
| 558 |
+
|
| 559 |
+
**Action:** mirror this snippet-mining logic in our adapter; replace `HFDataSource.load_dataset(...)` with PyArrow streaming over our local CPT corpus parquets (the official code only knows how to read HF datasets).
|
| 560 |
+
|
| 561 |
+
### P5. Loss normalization
|
| 562 |
+
|
| 563 |
+
**Verified from code (`train_loop.py:288-300`):**
|
| 564 |
+
- `torch.nn.functional.mse_loss(...)` with default `reduction='mean'` over `(num_selected_positions × hidden_dim)`.
|
| 565 |
+
- Teacher selection: `og_hiddens[unmerged_to_merged_mask == 1]` — selects positions of unmerged tokens NOT in the merged phrase, plus the LAST subtoken position of the merged phrase. Sum equals length of merged seq (before padding).
|
| 566 |
+
- Student selection: `token_distillation_hiddens[merged_seq != pad_id]` — non-pad positions. Same length.
|
| 567 |
+
|
| 568 |
+
**Implication:** the loss is averaged over **every position that the model produces in the merged sequence**, not only the new-token position. This means the gradient signal includes "your downstream context also has to match the teacher's downstream context after the substitution." Subtle but important: it pushes the new embedding to be compatible with *what the teacher does next*, not just to match the teacher *at the new token position*.
|
| 569 |
+
|
| 570 |
+
This is consistent with the paper's intuition (§3.1): *"the multiple subtokens t1, ..., tn have on other tokens attending to them in succeeding positions after seeing t*"*.
|
| 571 |
+
|
| 572 |
+
**Action:** preserve this behaviour in our adapter; do not "fix" it to be new-token-position-only.
|
| 573 |
+
|
| 574 |
+
### P6. Output embeddings for untied models
|
| 575 |
+
|
| 576 |
+
**Plan assumption:** train new U rows via NTP on the same data.
|
| 577 |
+
|
| 578 |
+
**Verified from paper (p.4) + code (`train_loop.py:339-348`):**
|
| 579 |
+
- Paper: *"Since our method backpropagates gradients back from the hidden states, we do not learn output embeddings with our distillation-based objective."*
|
| 580 |
+
- Paper: *"In practice, for learning output embeddings, we can simply add a next-token prediction objective just for the output embeddings at a minimal computational overhead."*
|
| 581 |
+
- Code: separate `torch.autograd.backward([ce_loss], inputs=[lm_head.weight], retain_graph=True)` for output, and `loss.backward(inputs=[input_embeddings.weight])` for input.
|
| 582 |
+
- The original-row gradients are zeroed for both input and output (`train_loop.py:354-359`) before the optimizer step, so base rows never drift.
|
| 583 |
+
|
| 584 |
+
**Important nuance from paper (p.7):** *"a subtoken attention distillation objective is superior to next-token prediction for learning new token embeddings, the combination via a sum of the two objectives (Token Distillation + NTP) generally yields worse results than Token Distillation alone."* — so combining input MSE + input NTP on the SAME parameter is worse. The split (MSE on E, CE on U) is the right pattern.
|
| 585 |
+
|
| 586 |
+
**Action:** use `learn_output_with_ce=True` for the untied Apertus path. Train new U rows via the CE-on-merged-logits-of-next-token path. The CE loss is only computed on the merged sequence, not the unmerged.
|
| 587 |
+
|
| 588 |
+
### P7. The "earlier target layer" claim — verified, but paper still defaults to LAST
|
| 589 |
+
|
| 590 |
+
**Plan assumption (§6):** *"the authors note that roughly one-third-depth layers often work better."*
|
| 591 |
+
|
| 592 |
+
**Verified from paper (p.4, §3.2 last paragraph):** *"In practice, we simply use the last layer's hidden state but analyze this choice in Section 5.3."*
|
| 593 |
+
|
| 594 |
+
**Verified from code (`tokdist.py:67`):** `target_layer: int = -1` default. Comment: *"or e.g. an early layer such as 6 or 7"* — a hint, not a claim of superiority.
|
| 595 |
+
|
| 596 |
+
**Verified from paper §5.3:** the authors report a slight downward trend as the
|
| 597 |
+
target approaches the last layer, and say earlier layers can improve results and
|
| 598 |
+
speed. They still use the last layer for main experiments because it avoids a
|
| 599 |
+
model-specific sweep and is principled: later subtoken interactions cannot be
|
| 600 |
+
excluded.
|
| 601 |
+
|
| 602 |
+
**Action:** run the small layer pilot in §6 before full modern TD: final layer
|
| 603 |
+
vs the one-third-depth layer, plus the probe-suggested layer if different.
|
| 604 |
+
Candidate selection uses the cheap gates in §6, not the full downstream suite.
|
| 605 |
+
|
| 606 |
+
---
|
| 607 |
+
|
| 608 |
+
## 14. Implementation specifics for our setup
|
| 609 |
+
|
| 610 |
+
### 14.1 We must NOT use the high-level `TokenDistillation.run(...)` entry point
|
| 611 |
+
|
| 612 |
+
The official `run()` method calls `target_tokenizer.add_tokens(new_tokens)` (`tokdist.py:97, 523`) which **appends** new tokens to the source tokenizer. This is incompatible with our setup because:
|
| 613 |
+
|
| 614 |
+
- Our extended tokenizer (`apertus_greek_modern_only_148480/`) was built by **merge-rule extension** (`model.vocab` + `model.merges`), not by `add_tokens(...)`.
|
| 615 |
+
- The new-token IDs in our tokenizer occupy the range `[131072, 148480)` in a specific order determined by our BPE merge order.
|
| 616 |
+
- If `add_tokens(...)` is called on the original base tokenizer with our new-token strings, the resulting IDs will match our planned range *only if* the order matches — which is fragile and unverified.
|
| 617 |
+
|
| 618 |
+
**Action:** drop into the lower-level `train_embeddings()` function directly, with:
|
| 619 |
+
- Student `model = AutoModelForCausalLM.from_pretrained(retok_init_checkpoint)` — already has the 148,480 vocab.
|
| 620 |
+
- Student tokenizer loaded directly from our shipped extended bundle.
|
| 621 |
+
- Skip `_build_target_tokenizer`; skip `extend_pretrained_with_tokens_and_embeddings`.
|
| 622 |
+
- Construct `phrase_to_new_id` and `assigned_new_phrases` from our **known** new-token IDs.
|
| 623 |
+
|
| 624 |
+
### 14.2 Snippet miner: PyArrow batch-streaming over local parquet, not HF datasets
|
| 625 |
+
|
| 626 |
+
The official `build_snippets_for_tokens_from_hf` uses `datasets.load_dataset(streaming=True)` over an HF dataset. Our corpus is local parquet on iopsstor. Replacement plan:
|
| 627 |
+
|
| 628 |
+
- Read `cpt/selected_after_apertus_and_internal_dedup.parquet` via `pyarrow.parquet.ParquetFile(...).iter_batches(batch_size=N)`.
|
| 629 |
+
- Tokenize each batch with the **base 131,072 tokenizer** (same as paper's "source tokenizer").
|
| 630 |
+
- Run Aho-Corasick (use the official `ahocorasick.py`, no need to reimplement) over the tokenized stream.
|
| 631 |
+
- Reuse the truncation + filtering logic from `build_snippets_for_tokens_from_hf` (offset_before, offset_after, snippet_len, snippets_per_token).
|
| 632 |
+
- Cache the tokenized parquet on iopsstor scratch keyed by `tokenizer.name_or_path + parquet hash`.
|
| 633 |
+
|
| 634 |
+
The tokenized-corpus cache (from the paper's `_tokenize_dataset_if_needed`) is **a real time-saver**: tokenizing the 47M-row Greek pool once with the base tokenizer takes ~30-60 min on one node. Don't re-tokenize per TD run.
|
| 635 |
+
|
| 636 |
+
### 14.3 Frozen-parameter table (replaces vague "freeze everything else" in §3)
|
| 637 |
+
|
| 638 |
+
| Tensor | Trained? | Notes |
|
| 639 |
+
|---|---|---|
|
| 640 |
+
| `model.embed_tokens.weight[131072:148480, :]` | **YES** (MSE-on-hiddens loss) | new input rows |
|
| 641 |
+
| `lm_head.weight[131072:148480, :]` | **YES** (CE loss on merged seq) | new output rows |
|
| 642 |
+
| `model.embed_tokens.weight[:131072, :]` | NO (grad zeroed after backward) | base input rows, verified unchanged at end |
|
| 643 |
+
| `lm_head.weight[:131072, :]` | NO (grad zeroed after backward) | base output rows, verified unchanged at end |
|
| 644 |
+
| `model.layers.*.self_attn.{q,k,v,o}_proj.weight` | NO | attention QKV + output |
|
| 645 |
+
| `model.layers.*.self_attn.{q_norm, k_norm}.weight` | NO | QK-Norm (R17 sensitive — DO NOT TOUCH) |
|
| 646 |
+
| `model.layers.*.mlp.{up_proj, down_proj}.weight` | NO | MLP (xIELU lives between these) |
|
| 647 |
+
| `model.layers.*.mlp.act_fn.{alpha_p, alpha_n, beta, eps}` | NO | xIELU scalars (R17 sensitive — DO NOT TOUCH) |
|
| 648 |
+
| `model.layers.*.input_layernorm.weight` | NO | RMSNorm input |
|
| 649 |
+
| `model.layers.*.post_attention_layernorm.weight` | NO | RMSNorm post-attn |
|
| 650 |
+
| `model.norm.weight` | NO | final RMSNorm |
|
| 651 |
+
|
| 652 |
+
The official `train_embeddings` already implements this freeze pattern correctly via `param.requires_grad=False` for everything except E/U, and zeros gradients on the original rows after backward. **Verify post-TD that R17-sensitive tensors are unchanged** (use `verify_hf_roundtrip.py`'s R17/xIELU/QK-Norm diff functions).
|
| 653 |
+
|
| 654 |
+
### 14.4 Padding direction — RIGHT-pad, not left
|
| 655 |
+
|
| 656 |
+
Code (`train_loop.py:106-140`) right-pads the merged sequence to the unmerged length. The loss explicitly excludes pad positions on both teacher and student sides. This is correct *for this objective* — the trailing PAD positions are not used by the loss, and causal attention from non-pad positions doesn't attend forward to pad.
|
| 657 |
+
|
| 658 |
+
**Action:** when porting to our adapter, keep right-padding. Don't try to "fix" it to left-padding (which would break the position-mapping logic).
|
| 659 |
+
|
| 660 |
+
### 14.5 Single-GPU vs DDP
|
| 661 |
+
|
| 662 |
+
Paper experiments are on 1× H100. Clariden normal nodes expose four GH200 GPUs
|
| 663 |
+
as a node unit; there is no true single-GPU partition. **Recommendation:
|
| 664 |
+
single-process TD for the first full-token run to stay close to the official
|
| 665 |
+
implementation, but pack any genuinely useful independent comparison into the
|
| 666 |
+
same allocation.** For the immediate full-token challenger, that means layer 11
|
| 667 |
+
as the selected candidate and optionally last-layer as the conservative backup,
|
| 668 |
+
both at 25 snippets. Do not invent DDP or row-sharded merge machinery unless
|
| 669 |
+
single-process runtime becomes the blocker.
|
| 670 |
+
|
| 671 |
+
DDP correctness check for TD: with batches shuffled across tokens (§P4), each DDP rank sees a random sample of tokens per batch, so gradients average correctly over the embedding matrix. Verify the gradient zeroing-for-base-rows happens *after* gradient reduction (otherwise the AllReduce would distribute the zeroed grads, which is fine but the assertion at end-of-training would need adjustment).
|
| 672 |
+
|
| 673 |
+
### 14.6 Compute budget — concrete numbers
|
| 674 |
+
|
| 675 |
+
Using live Apertus pilot scaling:
|
| 676 |
+
|
| 677 |
+
- Layer-11 pilot: 1,020 trained tokens × 50 snippets, batch 8, elapsed
|
| 678 |
+
`1,966.9s`.
|
| 679 |
+
- First full-token challenger: 17,392 trained tokens × 25 snippets. Linear
|
| 680 |
+
scaling estimate: about **4.7 wall hours**.
|
| 681 |
+
- Full-token 50 snippets: about **9.3 wall hours**.
|
| 682 |
+
- Full-token 100 snippets: about **18.6 wall hours**, beyond normal-partition
|
| 683 |
+
walltime for a single process.
|
| 684 |
+
|
| 685 |
+
Recommend setting walltime to 8h for the first full-token 25-snippet run, or
|
| 686 |
+
12h if packing a same-allocation last-layer backup.
|
| 687 |
+
|
| 688 |
+
---
|
| 689 |
+
|
| 690 |
+
## 15. Tools and libraries we will use
|
| 691 |
+
|
| 692 |
+
| Concern | Tool | Notes |
|
| 693 |
+
|---|---|---|
|
| 694 |
+
| Model loading | `transformers` (pinned to uenv's 4.57.0) | has `ApertusForCausalLM` |
|
| 695 |
+
| TD library code | clone of `konstantinjdobler/token-distillation` at a pinned commit | use `train_embeddings()`, `ahocorasick.py`, and `utils.py`; **skip** `tokdist.TokenDistillation` |
|
| 696 |
+
| DDP / mixed precision | `accelerate` (already in our lm_eval target install) | wrap the train loop |
|
| 697 |
+
| Corpus streaming | `pyarrow.parquet.iter_batches` | already battle-tested by `mix_builder.py` |
|
| 698 |
+
| Tokenizer cache | `datasets.Dataset.save_to_disk` (already pulled into the uenv) | reuse the paper's caching pattern |
|
| 699 |
+
| Checkpoint surgery / verification | `safetensors` + our existing `verify_hf_roundtrip.py` | mandatory post-TD check (gate §8) |
|
| 700 |
+
| HF → Megatron conversion | `tools/checkpoint/convert.py` with our `loader_apertus_hf.py` | proven on R17 patch jobs 2341182/2341239/2341241 |
|
| 701 |
+
| Telemetry / loss curves | TensorBoard (already wired in bakeoff_train.sbatch) | optional but cheap |
|
| 702 |
+
| **Layer-suggestion probe (§6.1)** | [`AlignmentResearch/tuned-lens`](https://github.com/AlignmentResearch/tuned-lens) — Belrose et al. 2023, arXiv:2303.08112 | logit-lens is free (project residual through Apertus's existing `lm_head`); tuned-lens trains a small per-layer affine probe (~minutes per layer on one GH200). For finding a candidate `L*`, logit-lens is sufficient on first pass. If it suggests a layer materially different from the one-third-depth package suggestion, include that layer in the pilot. |
|
| 703 |
+
| Multi-token Greek word inventory (for the §6.1 probe) | one-pass scan of the corpus + base tokenizer | reuse the Aho-Corasick driver from TD2; just emit the set of `(word, k)` where `k > 1` is the base-tokenizer fragment count |
|
| 704 |
+
|
| 705 |
+
**Pinning the TD repo:** the official repo is small (~10 Python files) and stable. Vendor at a pinned commit hash into `subprojects/.../init_bakeoff/td/external/token_distillation/` so a moving GitHub HEAD can't break our run. Pin should land before TD0.
|
| 706 |
+
|
| 707 |
+
---
|
| 708 |
+
|
| 709 |
+
## 16. Open questions that still need answers
|
| 710 |
+
|
| 711 |
+
Carried forward; will be resolved before TD1 lands.
|
| 712 |
+
|
| 713 |
+
| # | Question | Source | How to answer |
|
| 714 |
+
|---|---|---|---|
|
| 715 |
+
| Q1 | Does the paper / package actually suggest testing an earlier layer? | paper §5.3 + package README | RESOLVED: yes. Paper keeps last layer as the default to avoid model-specific sweeps; package README says earlier target layers around the one-third mark can yield better results in many cases. Plan tests both. |
|
| 716 |
+
| Q2 | What's the empirical coverage for our 17,408 new tokens against the 5B-Greek-token CPT corpus? | local Aho-Corasick prepass | run a one-pass coverage check before launching TD; gate as per §5 of the plan |
|
| 717 |
+
| Q3 | How many tokens fragment into k > 8 base subtokens (where RoPE phase shift may be too large)? | base tokenizer applied to all 17,408 new-token surface strings | trivial offline check; report distribution of k |
|
| 718 |
+
| Q4 | Does the paper sweep batch_size, or is `batch_size=1` (repo default) actually their setting? | paper appendix C / repo example.py | check arxiv:2505.20133 appendix C; example.py uses default which is `batch_size=1` — but the paper says *"We set the batch size to optimize throughput"* (p.4), so they presumably batch in practice |
|
| 719 |
+
| Q5 | Does the bakeoff differentiate ReTok vs Centroid enough on §5.3 D5/D2/D7 diagnostics to gate TD on (per `SUGGESTIONS.md §7.2`)? | bakeoff arm eval | answered by reading per-arm §5.3 diagnostics after each arm's mid-training checkpoint |
|
| 720 |
+
| Q6 | For polytonic TD (Phase 2), what snippet sources have enough polytonic content? | survey of available polytonic corpora | external work; descope from modern-only TD plan |
|
| 721 |
+
| Q7 | Does the TD-trained checkpoint round-trip through `tools/checkpoint/convert.py` with **zero R17 drift** (since we never touched xIELU/QK-Norm during TD)? | run R17 verifier post-TD | mechanical; reuse `verify_hf_roundtrip.py` |
|
| 722 |
+
| Q8 | When we combine TD (input MSE) with NTP (output CE) on Apertus's untied head, does the NTP loss act as a regularizer (paper p.7 says yes for tied) or as a confound (paper p.7 says yes for untied combination on same param)? | the paper warns about TD+NTP on the SAME param being worse; our case is TD on E + NTP on U, which is the paper's recommended pattern | implementation Q only — code already does this split correctly per `learn_output_with_ce=True` |
|
| 723 |
+
| Q9 | Should the TD eval gate (§8 "Pre-CPT BPC should improve over ReTok") use a numerical threshold (e.g. >2× bootstrap stderr of ReTok)? | calibrate from V4-HF bootstrap CIs | depends on `compute_bootstrap_cis.py` results on V4 |
|
| 724 |
+
| Q10 | Verify the "Kaplan et al. 2025 *Tokens to Words*" citation referenced in §6.1 before relying on the "L* ≈ first-third of layers" empirical claim | arXiv / Google Scholar search | one-off literature check; if the citation doesn't pan out, the §6.1 probe still works as a self-contained logit-lens diagnostic — we just lose the prior expectation about where L* should land |
|
| 725 |
+
| Q11 | Confirm the HF hidden-state indexing convention for `target_layer = -1` on Apertus. HF returns `outputs.hidden_states[0] = embedding output` and `outputs.hidden_states[N] = output of transformer block N`. For Apertus (32 layers), `hidden_states[-1]` should be the final transformer block's output BEFORE final RMSNorm and `lm_head`. Confirm this matches what the paper means by "last layer." | quick `model.forward(..., output_hidden_states=True)` shape check on Apertus + cross-check vs `tokdist.py` reading `hidden_states[target_layer]` | mechanical; trivial offline check. If the paper means "post-final-norm representation" we'd need `target_layer = -1` to be the post-norm layer or apply the final norm manually before comparing. |
|
| 726 |
+
|
| 727 |
+
---
|
| 728 |
+
|
| 729 |
+
## 17. Notes from the research pass (paper + repo, 2026-05-22)
|
| 730 |
+
|
| 731 |
+
Direct quotes from arxiv:2505.20133 v3 + the official repo, kept here so we don't re-derive them.
|
| 732 |
+
|
| 733 |
+
**Method (paper §3.2, p.4):**
|
| 734 |
+
|
| 735 |
+
> *"We learn e* by minimizing the mean-squared error between hidden states for a given target layer l: min_{e*} E_{s∼S} [ 1/|M(s_τ, s_τ*)| · Σ_{(i,j)∈M(s_τ,s_τ*)} || H_{e*}^{(l)}(s_τ*)_i − H^{(l)}(s_τ)_j ||²₂ ]. In practice, we simply use the last layer's hidden state but analyze this choice in Section 5.3."*
|
| 736 |
+
|
| 737 |
+
**Hyperparameters (paper §3.3, p.4):**
|
| 738 |
+
|
| 739 |
+
> *"We employ a simple setup and use the AdamW (Kingma & Ba 2017; Loshchilov & Hutter 2019) optimizer for all trainable parameters. We set the batch size to optimize throughput and run all experiments on Nvidia H100 80GB GPUs. We do not use weight decay and maintain a constant learning rate with a linear warmup. For fair comparison, we sweep for the best learning rate for all methods that require a learning rate. Since our method is aimed to serve as an initialization rather than as full-scale further training, we restrict the number of example sequences to a maximum of 25 per target token and truncate to a context length of 50 tokens. These restrictions ensure that our method is quick to run, initializing 2,500 new tokens on a single GPU in under 10 minutes."*
|
| 740 |
+
|
| 741 |
+
**Output embeddings (paper §3.3, p.4):**
|
| 742 |
+
|
| 743 |
+
> *"Since our method backpropagates gradients back from the hidden states, we do not learn output embeddings with our distillation-based objective. In fact, this is not possible, as our new tokens are not part of the original model that serves as the "teacher". In practice, for learning output embeddings, we can simply add a next-token prediction objective just for the output embeddings at a minimal computational overhead or freely combine our method with any other method for initializing output embeddings."*
|
| 744 |
+
|
| 745 |
+
**Snippet retrieval (paper §3.3, p.4):**
|
| 746 |
+
|
| 747 |
+
> *"Our main approach is to simply retrieve snippets that contain our target tokens from a domain-specific or general corpus. This can be implemented efficiently using the algorithm proposed by Aho & Corasick (1975). Then we can truncate the snippets to a small window around our target token to optimize computational efficiency."*
|
| 748 |
+
|
| 749 |
+
**Freezing original embeddings (paper §5.1, p.7):**
|
| 750 |
+
|
| 751 |
+
> *"Note that for Token Distillation, we only optimize new token embeddings. Therefore, we also compare against the NTP baseline, where we similarly optimize only the new token embeddings."*
|
| 752 |
+
|
| 753 |
+
**Combining TD + NTP on the same parameter is worse than TD alone (paper §5.1, p.7):**
|
| 754 |
+
|
| 755 |
+
> *"In support of our argument that a subtoken attention distillation objective is superior to next-token prediction for learning new token embeddings, the combination via a sum of the two objectives (Token Distillation + NTP) generally yields worse results than Token Distillation alone."*
|
| 756 |
+
|
| 757 |
+
> *"However, we can add a dynamic downweighting factor (see Section 4.2) to the next-token prediction objective (Token Distillation + αNTP), which mostly alleviates the negative interference while keeping the regularizing effect."*
|
| 758 |
+
|
| 759 |
+
(Implication for us: the α-NTP "regularizer" pattern is only beneficial when applied to the **input** embedding via a tied head — i.e., adds an output-loss component that backprops through the tied input/output matrix. For Apertus's *untied* setup, the equivalent is the separate CE-on-U pass we already use; we should NOT additionally add α-NTP on the input E.)
|
| 760 |
+
|
| 761 |
+
**Tied-vs-untied (paper §5.1, p.7):**
|
| 762 |
+
|
| 763 |
+
> *"Note that in Table 2, only for Llama-3.2-3B, Token Distillation obtains results that are on par with random initialization. Llama-3.2-3B(-i) are the only models in our lineup with tied embedding weights. Our objective does not explicitly enforce a bound on the norm of the new embedding, which in this case led to a failure mode of always generating a specific new embedding with very large norm."*
|
| 764 |
+
|
| 765 |
+
(Apertus is **untied**, so this failure mode doesn't apply. Confirms the bracketing was over-cautious on the tied/untied dimension.)
|
| 766 |
+
|
| 767 |
+
**Layer choice rationale (paper §5.3) — second pass:**
|
| 768 |
+
|
| 769 |
+
> *"For our main experiments, we choose to keep the last layer because this choice does not necessitate a model-specific sweep over target layers. Also, the last layer is a principled choice, as it guarantees that no subtoken interactions that are only modeled in later layers are excluded from the objective."*
|
| 770 |
+
|
| 771 |
+
> *"[Earlier target layers] can be much faster if we select early target layers. We leave further exploration of this as an exciting direction for future work."*
|
| 772 |
+
|
| 773 |
+
(§5.3 also reports a slight downward trend in quality as the target approaches the last layer — i.e., earlier layers can marginally improve. The paper still defaults to last because the marginal gain doesn't justify a broad per-model sweep. For our one-shot Apertus adaptation, §6 now runs the smallest useful check: last layer vs the package-suggested one-third-depth layer, plus the probe-suggested `L*` only if it is materially different.)
|
provenance/tokenizer-selection/CHOSEN_CUTOFF.md
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Chosen cutoff — 17,408 (curated + backfilled to alignment)
|
| 2 |
+
|
| 3 |
+
**Decision date**: 2026-05-18.
|
| 4 |
+
**Decided by**: user, based on the evidence in [`REPORT.md`](REPORT.md) and the
|
| 5 |
+
knee-analysis plot [`artifacts/plots/knee_analysis.png`](artifacts/plots/knee_analysis.png).
|
| 6 |
+
**Reviewer rounds addressed**: 2 (alignment + handoff-ambiguity).
|
| 7 |
+
|
| 8 |
+
## The decision
|
| 9 |
+
|
| 10 |
+
| field | value |
|
| 11 |
+
|---|---|
|
| 12 |
+
| **Added units** | **17,408** |
|
| 13 |
+
| **Total vocab (ship)** | **148,480** = 131,072 base + 17,408 added |
|
| 14 |
+
| **Alignment** | 148,480 = **128 × 1160 = 256 × 580** ✓ |
|
| 15 |
+
| **Apertus front-end contract** | Preserved — Apertus base ids 0..131,071 unchanged verbatim |
|
| 16 |
+
| **Curation mechanism** | **Built directly into the tokenizer.** 69 noise tokens (`02_1_5/manifests/removal_list.jsonl` in-cutoff scope) skipped during BPE merge selection; the next 69 valid merges from c3_full backfilled to maintain 17,408 useful added tokens |
|
| 17 |
+
| **Cascade-skips** | **0** — none of the 17,408 backfilled merges depended on a curated merge as a sub-component |
|
| 18 |
+
| **Merges walked from c3_full** | 17,477 (= 17,408 accepted + 69 skipped-for-removal) |
|
| 19 |
+
| **Ship artifact** | [`variants/c3_added_17408_curated_padded/tokenizer.json`](variants/c3_added_17408_curated_padded/tokenizer.json) |
|
| 20 |
+
| **Build manifest** | [`manifests/curated_padded_at_17408_manifest.json`](manifests/curated_padded_at_17408_manifest.json) |
|
| 21 |
+
|
| 22 |
+
## Why the backfilled tokenizer is the canonical ship
|
| 23 |
+
|
| 24 |
+
Two reviewer rounds rejected the obvious candidates:
|
| 25 |
+
|
| 26 |
+
| candidate | vocab | alignment | append-only | status |
|
| 27 |
+
|---|---:|:---:|:---:|---|
|
| 28 |
+
| Raw `c3_added_17408` (no curation) | 148,480 | ✓ 256-aligned | ✓ preserved | metrics good, but ships 69 noise tokens |
|
| 29 |
+
| Pruned `c3_added_17408_curated` (Option 2 of CURATION_REPORT) | 148,411 | ✗ NOT 128-aligned | ✗ ids renumbered | **rejected by reviewer round 2** — alignment + contract broken |
|
| 30 |
+
| **Backfilled `c3_added_17408_curated_padded`** | **148,480** | **✓ 256-aligned** | **✓ preserved** | **canonical ship artifact** |
|
| 31 |
+
|
| 32 |
+
The backfilled construction (built by [`scripts/01c_build_curated_backfilled.py`](scripts/01c_build_curated_backfilled.py))
|
| 33 |
+
walks c3_full's merge sequence in order, **skips** the 69 in-cutoff
|
| 34 |
+
ids from `02_1_5/manifests/removal_list.jsonl`, and **accepts** the
|
| 35 |
+
first 17,408 surviving merges. Because BPE merges only depend on
|
| 36 |
+
earlier merges as sub-components, the merge-graph validator runs
|
| 37 |
+
during build — no kept merge ends up depending on a skipped one
|
| 38 |
+
(measured cascade-skips at this cutoff: 0).
|
| 39 |
+
|
| 40 |
+
This makes the curation **structural**, not a runtime mask: the noise
|
| 41 |
+
tokens are *not in the vocab at all*, but vocab size + alignment +
|
| 42 |
+
Apertus base-id preservation are intact.
|
| 43 |
+
|
| 44 |
+
## Why 17,408 (the cutoff itself)
|
| 45 |
+
|
| 46 |
+
From the 0 → 25,600 sweep at 1k step:
|
| 47 |
+
|
| 48 |
+
| criterion | result at 17,408 |
|
| 49 |
+
|---|---|
|
| 50 |
+
| Greek fertility on C3_val held-out (the decision-relevant axis) | 1.345 (−44.2 % vs apertus_base 2.41) |
|
| 51 |
+
| % of theoretical-max fertility improvement captured | **82.4 %** (asymptote y∞ = 1.118; full sweep at 25,600 captures 88.4 %) |
|
| 52 |
+
| Marginal-Δ% per added 1k | first cutoff where the next 1k buys **< 1 %** |
|
| 53 |
+
| TFG @ Apertus-55 | 0.11613 (vs apertus_base 0.11606; +0.06 % — basis points; the metric is structurally biased against script-isolated extensions, see `REPORT.md`) |
|
| 54 |
+
| Apertus alignment | 17,408 = 1024 × 17; total 148,480 = 256 × 580 ✓ |
|
| 55 |
+
|
| 56 |
+
**The fertility / knee analysis is the load-bearing argument.** The
|
| 57 |
+
MorphScore recall bump at 17,408 (0.689 → 0.694) is real but small
|
| 58 |
+
(recall is "essentially flat" 0.686–0.695 across the entire sweep);
|
| 59 |
+
treat it as supporting color, not an independent pillar.
|
| 60 |
+
|
| 61 |
+
The real claim: pick the cutoff where each additional 1k of vocab buys
|
| 62 |
+
less than 1 % of fertility improvement — that's 17,408 — and it
|
| 63 |
+
also happens to be Apertus-aligned, captures >80 % of the maximum
|
| 64 |
+
achievable Greek-fertility gain, and sits at the second MorphScore
|
| 65 |
+
per-word milestone (clean inflectional splits for common Greek
|
| 66 |
+
nominal/verbal paradigms).
|
| 67 |
+
|
| 68 |
+
## What got curated out
|
| 69 |
+
|
| 70 |
+
The full `02_1_5/manifests/removal_list.jsonl` enumerates 104 noise
|
| 71 |
+
tokens. In-cutoff scope at 17,408 (ids < 148,480) is **69 ids**:
|
| 72 |
+
|
| 73 |
+
| removal_class | count | glossary category |
|
| 74 |
+
|---|---:|---|
|
| 75 |
+
| `mixed_script_artifact` | 50 | `mixed_script_token` (Greek-Latin homoglyphs + punct+Greek BPE fragments like `.Ε`, `,τι`, `/και`) |
|
| 76 |
+
| `pdf_postscript_glyph` | 9 | `postscript_glyph` (PDF font-glyph residue like `/Α`, `/η`) |
|
| 77 |
+
| `cleaner_linenewline_bpe_fragment` | 3 | `latin_acronym` (`LIN`, `ENEW`, `LINENEW` — BPE pieces of `LINENEWLINE`) |
|
| 78 |
+
| `latin1_utf8_mojibake` | 3 | `mojibake` (`ÉÉ`-family) |
|
| 79 |
+
| `cleaner_linenewline_placeholder` | 2 | `code_identifier` (`LINENEWLINE`, `NEWLINENEWLINE`) |
|
| 80 |
+
| `cleaner_extraction_tag` | 2 | `latin_fragment` (`-missing`, `-decoded`) |
|
| 81 |
+
| **total** | **69** | |
|
| 82 |
+
|
| 83 |
+
Per-id list with `decoded` strings: [`manifests/removal_mask_at_17408.jsonl`](manifests/removal_mask_at_17408.jsonl).
|
| 84 |
+
|
| 85 |
+
## Verification — directly measured (no extrapolation)
|
| 86 |
+
|
| 87 |
+
### Pairwise on Apertus-55 FLORES+ (TokEval, lines config)
|
| 88 |
+
|
| 89 |
+
| metric | raw 17,408 | **padded (ship)** | Δ vs raw |
|
| 90 |
+
|---|---:|---:|---:|
|
| 91 |
+
| TFG (Apertus-55, lower better) | 0.116128 | 0.116126 | −0.000002 |
|
| 92 |
+
| Rényi-2.5 efficiency (Apertus-55) | 8.428021 | 8.427630 | −0.000391 |
|
| 93 |
+
| UTF-8 completeness rate (Apertus-55) | 0.979127 | 0.979125 | −0.000002 |
|
| 94 |
+
| UTF-8 char split rate (Apertus-55) | 0.010320 | 0.010320 | +0.000001 |
|
| 95 |
+
| Fertility (Apertus-55, mean tokens/line) | 44.7535 | 44.7536 | +0.000093 |
|
| 96 |
+
| Compression rate (Apertus-55) | 0.022345 | 0.022345 | −0.000000 |
|
| 97 |
+
| Vocab utilization (Apertus-55) | 0.489278 | 0.489251 | −0.000027 |
|
| 98 |
+
|
| 99 |
+
### MorphScore Greek (UD-derived, n=693)
|
| 100 |
+
|
| 101 |
+
| metric | raw 17,408 | **padded (ship)** | Δ vs raw |
|
| 102 |
+
|---|---:|---:|---:|
|
| 103 |
+
| recall | 0.6940 | 0.6940 | 0.0000 |
|
| 104 |
+
| precision | 0.6912 | 0.6912 | 0.0000 |
|
| 105 |
+
| mean token-char ratio | 0.3364 | 0.3357 | −0.0007 |
|
| 106 |
+
|
| 107 |
+
### In-domain Greek held-outs (02_1_3 harness on gcloud)
|
| 108 |
+
|
| 109 |
+
| slice | raw 17,408 | **padded (ship)** | Δ vs raw |
|
| 110 |
+
|---|---:|---:|---:|
|
| 111 |
+
| C2_val — Greek word fertility | 1.3598 | 1.3591 | −0.00065 |
|
| 112 |
+
| C2_test — Greek word fertility | 1.4124 | 1.4118 | −0.00060 |
|
| 113 |
+
| C3_val — Greek word fertility | 1.3456 | 1.3450 | −0.00051 |
|
| 114 |
+
| C3_test — Greek word fertility | 1.4011 | 1.4007 | −0.00032 |
|
| 115 |
+
|
| 116 |
+
**Reading**: every directly-measured metric is either flat or **marginally
|
| 117 |
+
better** for the backfilled variant. The 69 swapped-in tokens (positions
|
| 118 |
+
17,409..17,477 in c3_full's merge order) fire slightly more usefully on
|
| 119 |
+
real Greek than the 69 noise tokens they replaced. Direction is
|
| 120 |
+
consistent across all 4 in-domain Greek slices on fertility — small
|
| 121 |
+
magnitude but a real, structural win, not noise.
|
| 122 |
+
|
| 123 |
+
## Embedding-budget cost
|
| 124 |
+
|
| 125 |
+
| component | per-token (BF16) | total at cutoff 17,408 |
|
| 126 |
+
|---|---:|---:|
|
| 127 |
+
| Embedding row (4096 × 2 bytes) | 8 KiB | 17,408 × 8 KiB = **136 MiB** new |
|
| 128 |
+
| LM head row (4096 × 2 bytes, `tie_word_embeddings=False`) | 8 KiB | 17,408 × 8 KiB = **136 MiB** new |
|
| 129 |
+
| **Δ vs apertus_base** | 16 KiB | **272 MiB** added (= 17,408 × 16 KiB) |
|
| 130 |
+
| Cumulative embed + LM head | — | 2.27 GiB (2.00 GiB Apertus base + 272 MiB added) |
|
| 131 |
+
| Δ as % of full 8 B model | — | ~1.7 % |
|
| 132 |
+
|
| 133 |
+
## Downstream handoff to `02_2_tokenizer_implementation`
|
| 134 |
+
|
| 135 |
+
**Canonical contract:**
|
| 136 |
+
|
| 137 |
+
1. Consume `variants/c3_added_17408_curated_padded/tokenizer.json`
|
| 138 |
+
verbatim. Vocab is 148,480 (256-aligned), ids 0..131,071 are exactly
|
| 139 |
+
the Apertus base, ids 131,072..148,479 are 17,408 BPE-merged Greek-
|
| 140 |
+
extension tokens with the 69 noise tokens filtered out at build
|
| 141 |
+
time.
|
| 142 |
+
2. **No runtime curation logic needed.** The pruning is structural, not
|
| 143 |
+
a mask. `03_apertus_extension_and_embedding_adaptation` can warm-
|
| 144 |
+
start every added-id embedding from byte-fallback averaging without
|
| 145 |
+
any "skip these 69" branch.
|
| 146 |
+
3. The mask manifest `manifests/removal_mask_at_17408.jsonl` is still
|
| 147 |
+
shipped for documentation — it tells the implementer **which 69
|
| 148 |
+
noise tokens were filtered out** so they appear in any future audit
|
| 149 |
+
trail, but it is NOT something the implementer needs to apply at
|
| 150 |
+
runtime.
|
| 151 |
+
|
| 152 |
+
**Alternative (do not ship)**: the pruned `c3_added_17408_curated`
|
| 153 |
+
variant remains on disk under `variants/`. It is an ablation artifact
|
| 154 |
+
only — alignment-broken and append-only-broken.
|
| 155 |
+
|
| 156 |
+
## Post-decision firing-count attribution
|
| 157 |
+
|
| 158 |
+
After the cutoff decision, the canonical tokenizer was run over the exact
|
| 159 |
+
C3 BPE training corpus (`train.parquet` plus row-aligned
|
| 160 |
+
`train_manifest.parquet`) to measure how often every token fires in:
|
| 161 |
+
|
| 162 |
+
1. `glossapi_nanochat_only`;
|
| 163 |
+
2. `hplt_only`;
|
| 164 |
+
3. `glossapi_nanochat_plus_hplt`;
|
| 165 |
+
4. every exact `source_dataset`.
|
| 166 |
+
|
| 167 |
+
Completed-run summary:
|
| 168 |
+
|
| 169 |
+
- [`FIRING_COUNT_RUN_20260518.md`](FIRING_COUNT_RUN_20260518.md)
|
| 170 |
+
- [`FIRING_COUNT_README.md`](FIRING_COUNT_README.md)
|
| 171 |
+
- [`manifests/firing_count_20260518_run_summary_augmented.json`](manifests/firing_count_20260518_run_summary_augmented.json)
|
| 172 |
+
|
| 173 |
+
The compact parquet bundle is published to the Apertus-extension HF repo
|
| 174 |
+
under:
|
| 175 |
+
|
| 176 |
+
```text
|
| 177 |
+
experiments/02_1_7_intrinsic_eval_sweep_20260518/firing_counts_c3_added_17408_curated_padded/
|
| 178 |
+
```
|
| 179 |
+
|
| 180 |
+
Headline result: the 50/50 corpus is balanced by token mass
|
| 181 |
+
(`glossapi_nanochat_only` 49.79%, HPLT 50.21%), not by row count. All
|
| 182 |
+
17,408 added tokens fire in GlossAPI-nanochat; 27 are zero in HPLT; none
|
| 183 |
+
are zero in the combined C3 corpus.
|
| 184 |
+
|
| 185 |
+
## Build reproduction (deterministic)
|
| 186 |
+
|
| 187 |
+
```bash
|
| 188 |
+
cd subprojects/02_1_tokenizer_experiments/02_1_7_intrinsic_eval_sweep
|
| 189 |
+
$VENV/python scripts/01c_build_curated_backfilled.py
|
| 190 |
+
```
|
| 191 |
+
|
| 192 |
+
The builder:
|
| 193 |
+
1. Loads Apertus base (`tokenizers_local/apertus_base/tokenizer.json`)
|
| 194 |
+
and full C3 (`tokenizers_local/c3_full/tokenizer.json`, 156,672 vocab).
|
| 195 |
+
2. Reads the 104-token removal list from `02_1_5/manifests/removal_list.jsonl`.
|
| 196 |
+
3. Walks c3_full added merges in order; skips those whose result is in
|
| 197 |
+
the removal list and cascade-skips those depending on a skipped
|
| 198 |
+
token; accepts the first 17,408 surviving merges.
|
| 199 |
+
4. Renumbers accepted merge results to ids 131,072..148,479.
|
| 200 |
+
5. Writes `variants/c3_added_17408_curated_padded/tokenizer.json` and
|
| 201 |
+
the build manifest.
|
| 202 |
+
|
| 203 |
+
## Pinned ship artifact
|
| 204 |
+
|
| 205 |
+
```
|
| 206 |
+
variants/c3_added_17408_curated_padded/tokenizer.json
|
| 207 |
+
sha256: 358ae3f29ac17c99769d6d437339e28657d5fcaed3486f8550feed3d6adfc394
|
| 208 |
+
vocab: 148,480 (128-aligned ✓, 256-aligned ✓)
|
| 209 |
+
Apertus front-end contract: PRESERVED (ids 0..131,071 verbatim)
|
| 210 |
+
Curation: 69 noise-token ids structurally absent (filtered at build)
|
| 211 |
+
Build manifest: manifests/curated_padded_at_17408_manifest.json
|
| 212 |
+
```
|
| 213 |
+
|
| 214 |
+
```
|
| 215 |
+
variants/c3_added_17408_curated/tokenizer.json ← ablation only, do NOT ship
|
| 216 |
+
vocab: 148,411 (not aligned, renumbered ids)
|
| 217 |
+
|
| 218 |
+
variants/c3_added_17408/tokenizer.json ← raw, no curation
|
| 219 |
+
vocab: 148,480 (aligned), but ships 69 noise tokens
|
| 220 |
+
```
|
provenance/tokenizer-selection/CUTOFF_SWEEP_REPORT.md
ADDED
|
@@ -0,0 +1,441 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 02_1_7 Intrinsic Eval Sweep — REPORT.md (final)
|
| 2 |
+
|
| 3 |
+
> **The cutoff decision is in [`CHOSEN_CUTOFF.md`](CHOSEN_CUTOFF.md).**
|
| 4 |
+
> This report is the evidence base. The ship artifact and the canonical
|
| 5 |
+
> handoff to `02_2_tokenizer_implementation` are documented there.
|
| 6 |
+
|
| 7 |
+
**Sweep date**: 2026-05-17 → 2026-05-18 (extended 0 → 25,600 added tokens at 1k step + curated+backfilled ship variant).
|
| 8 |
+
**Tokenizers**: 33 (apertus_base + 25 raw cutoff variants + 6 curated twins + 1 curated+backfilled ship variant). The 6 curated twins + the 8 past-chosen-cutoff raw variants are kept under `variants/_archive/` as evidence-only artifacts.
|
| 9 |
+
**Rows in merged parquet**: 178,658.
|
| 10 |
+
**Sources**: tokeval-lines (Apertus-55), tokeval-words (Apertus-55), our_suite_02_1_3 (in-domain Greek held-outs on gcloud), morphscore (catherinearnett/morphscore Greek UD).
|
| 11 |
+
**TokEval commit**: `0c4a9c641e78c8243ac753976267fd50675197cb`.
|
| 12 |
+
|
| 13 |
+
## Headline plot — 4 metrics on one chart, in-domain
|
| 14 |
+
|
| 15 |
+
Greek fertility on C3_val (actual in-domain held-out), TFG on
|
| 16 |
+
Apertus-55 multilingual, MorphScore Greek recall, and added-vocab
|
| 17 |
+
utilization on C3_val. All four shown as % improvement over
|
| 18 |
+
`apertus_base`, with the sign flipped on lower-is-better metrics so
|
| 19 |
+
**up always means the cutoff is doing something good**.
|
| 20 |
+
|
| 21 |
+

|
| 22 |
+
|
| 23 |
+
## Tier 1 — in-domain Greek (02_1_3 harness on gcloud)
|
| 24 |
+
|
| 25 |
+
This is the **decision-relevant** axis: actual Greek text from C2/C3
|
| 26 |
+
training-distribution held-outs (anti-joined, cleaned) plus 4 latest
|
| 27 |
+
glossAPI HF datasets. Not FLORES+. The 02_1_3 harness computes Greek-
|
| 28 |
+
specific metrics including space-fertility (the historical fertility
|
| 29 |
+
number this project has been tracking).
|
| 30 |
+
|
| 31 |
+
### Greek word fertility per held-out slice
|
| 32 |
+
|
| 33 |
+
| variant_id | added_tokens | curated | C2_test | C2_val | C3_test | C3_val | latest_glossAPI__archetai | latest_glossAPI__artos_zois | latest_glossAPI__eellak_articles | latest_glossAPI__opengov_deliberations_v2 |
|
| 34 |
+
|---|---|---|---|---|---|---|---|---|---|---|
|
| 35 |
+
| apertus_base | 0 | | 2.5252 | 2.4228 | 2.4212 | 2.4113 | 3.2305 | 2.9122 | 2.3686 | 2.5214 |
|
| 36 |
+
| add_1024 | 1024 | | 2.1531 | 2.0890 | 2.1172 | 2.0799 | 2.6112 | 2.3456 | 1.9725 | 2.1126 |
|
| 37 |
+
| add_2048 | 2048 | | 1.9937 | 1.9315 | 1.9611 | 1.9222 | 2.4310 | 2.1844 | 1.7989 | 1.9428 |
|
| 38 |
+
| add_3072 | 3072 | | 1.8816 | 1.8231 | 1.8550 | 1.8102 | 2.3065 | 2.0641 | 1.6805 | 1.8217 |
|
| 39 |
+
| add_4096 | 4096 | | 1.8017 | 1.7408 | 1.7749 | 1.7281 | 2.2217 | 1.9848 | 1.5981 | 1.7414 |
|
| 40 |
+
| add_5120 | 5120 | | 1.7386 | 1.6752 | 1.7120 | 1.6608 | 2.1594 | 1.9278 | 1.5334 | 1.6706 |
|
| 41 |
+
| add_6144 | 6144 | | 1.6852 | 1.6238 | 1.6593 | 1.6106 | 2.1035 | 1.8698 | 1.4796 | 1.6212 |
|
| 42 |
+
| add_7168 | 7168 | | 1.6425 | 1.5795 | 1.6182 | 1.5668 | 2.0622 | 1.8320 | 1.4390 | 1.5727 |
|
| 43 |
+
| add_8192 | 8192 | | 1.6032 | 1.5413 | 1.5850 | 1.5293 | 2.0209 | 1.7983 | 1.4048 | 1.5376 |
|
| 44 |
+
| add_9216 | 9216 | | 1.5711 | 1.5112 | 1.5533 | 1.4975 | 1.9857 | 1.7663 | 1.3748 | 1.5018 |
|
| 45 |
+
| add_10240 | 10240 | | 1.5434 | 1.4859 | 1.5259 | 1.4713 | 1.9616 | 1.7426 | 1.3503 | 1.4751 |
|
| 46 |
+
| add_11264 | 11264 | | 1.5178 | 1.4635 | 1.5015 | 1.4475 | 1.9291 | 1.7188 | 1.3275 | 1.4496 |
|
| 47 |
+
| add_11264_curated | 11264 | ✓ | 1.5179 | 1.4636 | 1.5018 | 1.4477 | 1.9293 | | 1.3275 | |
|
| 48 |
+
| add_12288 | 12288 | | 1.4959 | 1.4413 | 1.4794 | 1.4253 | 1.9078 | 1.7006 | 1.3083 | 1.4252 |
|
| 49 |
+
| add_12288_curated | 12288 | ✓ | 1.4960 | 1.4414 | 1.4797 | 1.4256 | 1.9080 | | 1.3084 | |
|
| 50 |
+
| add_13312 | 13312 | | 1.4750 | 1.4225 | 1.4602 | 1.4061 | 1.8875 | | 1.2912 | |
|
| 51 |
+
| add_14336 | 14336 | | 1.4574 | 1.4042 | 1.4437 | 1.3883 | 1.8726 | | 1.2753 | |
|
| 52 |
+
| add_15360 | 15360 | | 1.4421 | 1.3874 | 1.4284 | 1.3723 | 1.8539 | | 1.2629 | |
|
| 53 |
+
| add_15360_curated | 15360 | ✓ | 1.4423 | 1.3876 | 1.4288 | 1.3727 | 1.8542 | | 1.2630 | |
|
| 54 |
+
| add_16384 | 16384 | | 1.4259 | 1.3728 | 1.4137 | 1.3586 | 1.8413 | | 1.2504 | |
|
| 55 |
+
| add_17408 | 17408 | | 1.4124 | 1.3598 | 1.4011 | 1.3456 | 1.8253 | | 1.2399 | |
|
| 56 |
+
| add_18432 | 18432 | | 1.3998 | 1.3478 | 1.3888 | 1.3323 | 1.8131 | | 1.2298 | |
|
| 57 |
+
| add_19456 | 19456 | | 1.3877 | 1.3365 | 1.3778 | 1.3208 | 1.7988 | | 1.2191 | |
|
| 58 |
+
| add_20480 | 20480 | | 1.3776 | 1.3263 | 1.3672 | 1.3107 | 1.7859 | | 1.2112 | |
|
| 59 |
+
| add_20480_curated | 20480 | ✓ | 1.3779 | 1.3264 | 1.3677 | 1.3112 | 1.7864 | | 1.2114 | |
|
| 60 |
+
| add_21504 | 21504 | | 1.3673 | 1.3165 | 1.3573 | 1.3013 | 1.7749 | | 1.2037 | |
|
| 61 |
+
| add_22528 | 22528 | | 1.3578 | 1.3074 | 1.3480 | 1.2915 | 1.7651 | | 1.1945 | |
|
| 62 |
+
| add_23552 | 23552 | | 1.3488 | 1.2986 | 1.3390 | 1.2831 | 1.7545 | | 1.1879 | |
|
| 63 |
+
| add_24576 | 24576 | | 1.3402 | 1.2907 | 1.3304 | 1.2748 | 1.7452 | | 1.1819 | |
|
| 64 |
+
| add_25600 | 25600 | | 1.3324 | 1.2826 | 1.3211 | 1.2671 | 1.7383 | | 1.1748 | |
|
| 65 |
+
| add_25600_curated | 25600 | ✓ | 1.3328 | 1.2828 | 1.3216 | 1.2676 | 1.7388 | | 1.1750 | |
|
| 66 |
+
|
| 67 |
+

|
| 68 |
+
|
| 69 |
+
### Added-vocab utilization rate per slice
|
| 70 |
+
|
| 71 |
+
**The cutoff signal for diminishing returns**: when this drops, the
|
| 72 |
+
added tokens stop firing on in-domain text.
|
| 73 |
+
|
| 74 |
+
| variant_id | added_tokens | curated | C2_test | C2_val | C3_test | C3_val | latest_glossAPI__archetai | latest_glossAPI__artos_zois | latest_glossAPI__eellak_articles | latest_glossAPI__opengov_deliberations_v2 |
|
| 75 |
+
|---|---|---|---|---|---|---|---|---|---|---|
|
| 76 |
+
| add_1024 | 1024 | | 0.9980 | 0.9971 | 0.9951 | 0.9941 | 0.9844 | 0.9844 | 0.9580 | 0.9658 |
|
| 77 |
+
| add_2048 | 2048 | | 0.9971 | 0.9956 | 0.9932 | 0.9927 | 0.9722 | 0.9736 | 0.9575 | 0.9731 |
|
| 78 |
+
| add_3072 | 3072 | | 0.9941 | 0.9925 | 0.9896 | 0.9867 | 0.9639 | 0.9619 | 0.9456 | 0.9661 |
|
| 79 |
+
| add_4096 | 4096 | | 0.9905 | 0.9883 | 0.9851 | 0.9834 | 0.9578 | 0.9529 | 0.9282 | 0.9541 |
|
| 80 |
+
| add_5120 | 5120 | | 0.9891 | 0.9871 | 0.9803 | 0.9793 | 0.9453 | 0.9406 | 0.9154 | 0.9494 |
|
| 81 |
+
| add_6144 | 6144 | | 0.9875 | 0.9842 | 0.9761 | 0.9753 | 0.9259 | 0.9248 | 0.8984 | 0.9383 |
|
| 82 |
+
| add_7168 | 7168 | | 0.9845 | 0.9801 | 0.9689 | 0.9713 | 0.9106 | 0.9083 | 0.8797 | 0.9297 |
|
| 83 |
+
| add_8192 | 8192 | | 0.9812 | 0.9757 | 0.9608 | 0.9669 | 0.8958 | 0.8933 | 0.8569 | 0.9181 |
|
| 84 |
+
| add_9216 | 9216 | | 0.9776 | 0.9712 | 0.9533 | 0.9613 | 0.8800 | 0.8760 | 0.8396 | 0.9065 |
|
| 85 |
+
| add_10240 | 10240 | | 0.9722 | 0.9648 | 0.9466 | 0.9546 | 0.8646 | 0.8610 | 0.8190 | 0.8923 |
|
| 86 |
+
| add_11264 | 11264 | | 0.9688 | 0.9579 | 0.9379 | 0.9464 | 0.8507 | 0.8475 | 0.8005 | 0.8780 |
|
| 87 |
+
| add_11264_curated | 11264 | ✓ | 0.9693 | 0.9582 | 0.9384 | 0.9469 | 0.8512 | | 0.8010 | |
|
| 88 |
+
| add_12288 | 12288 | | 0.9631 | 0.9508 | 0.9272 | 0.9390 | 0.8367 | 0.8311 | 0.7827 | 0.8657 |
|
| 89 |
+
| add_12288_curated | 12288 | ✓ | 0.9637 | 0.9512 | 0.9277 | 0.9396 | 0.8372 | | 0.7832 | |
|
| 90 |
+
| add_13312 | 13312 | | 0.9564 | 0.9428 | 0.9173 | 0.9305 | 0.8239 | | 0.7620 | |
|
| 91 |
+
| add_14336 | 14336 | | 0.9496 | 0.9356 | 0.9058 | 0.9206 | 0.8094 | | 0.7449 | |
|
| 92 |
+
| add_15360 | 15360 | | 0.9412 | 0.9279 | 0.8941 | 0.9113 | 0.7953 | | 0.7277 | |
|
| 93 |
+
| add_15360_curated | 15360 | ✓ | 0.9418 | 0.9285 | 0.8948 | 0.9118 | 0.7959 | | 0.7280 | |
|
| 94 |
+
| add_16384 | 16384 | | 0.9343 | 0.9191 | 0.8851 | 0.9028 | 0.7825 | | 0.7108 | |
|
| 95 |
+
| add_17408 | 17408 | | 0.9282 | 0.9115 | 0.8755 | 0.8943 | 0.7706 | | 0.6945 | |
|
| 96 |
+
| add_18432 | 18432 | | 0.9190 | 0.9025 | 0.8628 | 0.8845 | 0.7584 | | 0.6774 | |
|
| 97 |
+
| add_19456 | 19456 | | 0.9107 | 0.8941 | 0.8516 | 0.8754 | 0.7477 | | 0.6621 | |
|
| 98 |
+
| add_20480 | 20480 | | 0.9006 | 0.8833 | 0.8389 | 0.8640 | 0.7364 | | 0.6467 | |
|
| 99 |
+
| add_20480_curated | 20480 | ✓ | 0.9014 | 0.8839 | 0.8397 | 0.8644 | 0.7367 | | 0.6468 | |
|
| 100 |
+
| add_21504 | 21504 | | 0.8922 | 0.8738 | 0.8277 | 0.8536 | 0.7255 | | 0.6328 | |
|
| 101 |
+
| add_22528 | 22528 | | 0.8835 | 0.8641 | 0.8165 | 0.8426 | 0.7129 | | 0.6187 | |
|
| 102 |
+
| add_23552 | 23552 | | 0.8744 | 0.8535 | 0.8043 | 0.8318 | 0.7020 | | 0.6056 | |
|
| 103 |
+
| add_24576 | 24576 | | 0.8643 | 0.8436 | 0.7931 | 0.8218 | 0.6926 | | 0.5928 | |
|
| 104 |
+
| add_25600 | 25600 | | 0.8540 | 0.8337 | 0.7825 | 0.8111 | 0.6837 | | 0.5811 | |
|
| 105 |
+
| add_25600_curated | 25600 | ✓ | 0.8547 | 0.8341 | 0.7832 | 0.8115 | 0.6841 | | 0.5811 | |
|
| 106 |
+
|
| 107 |
+
### Chars-per-token (compression) per slice
|
| 108 |
+
|
| 109 |
+
| variant_id | added_tokens | curated | C2_test | C2_val | C3_test | C3_val | latest_glossAPI__archetai | latest_glossAPI__artos_zois | latest_glossAPI__eellak_articles | latest_glossAPI__opengov_deliberations_v2 |
|
| 110 |
+
|---|---|---|---|---|---|---|---|---|---|---|
|
| 111 |
+
| apertus_base | 0 | | 2.5272 | 2.6307 | 2.5220 | 2.6093 | 1.9618 | 2.1190 | 2.7354 | 2.4872 |
|
| 112 |
+
| add_1024 | 1024 | | 2.8957 | 2.9795 | 2.8053 | 2.9632 | 2.2963 | 2.5023 | 3.1155 | 2.8748 |
|
| 113 |
+
| add_2048 | 2048 | | 3.0882 | 3.1770 | 2.9767 | 3.1678 | 2.4146 | 2.6379 | 3.3165 | 3.0769 |
|
| 114 |
+
| add_3072 | 3072 | | 3.2389 | 3.3283 | 3.1048 | 3.3312 | 2.5037 | 2.7476 | 3.4750 | 3.2358 |
|
| 115 |
+
| add_4096 | 4096 | | 3.3559 | 3.4528 | 3.2086 | 3.4609 | 2.5693 | 2.8259 | 3.5868 | 3.3503 |
|
| 116 |
+
| add_5120 | 5120 | | 3.4543 | 3.5596 | 3.2951 | 3.5760 | 2.6185 | 2.8843 | 3.6816 | 3.4577 |
|
| 117 |
+
| add_6144 | 6144 | | 3.5429 | 3.6486 | 3.3721 | 3.6676 | 2.6660 | 2.9475 | 3.7676 | 3.5373 |
|
| 118 |
+
| add_7168 | 7168 | | 3.6167 | 3.7275 | 3.4344 | 3.7508 | 2.7028 | 2.9907 | 3.8373 | 3.6195 |
|
| 119 |
+
| add_8192 | 8192 | | 3.6871 | 3.7988 | 3.4864 | 3.8250 | 2.7385 | 3.0285 | 3.8953 | 3.6810 |
|
| 120 |
+
| add_9216 | 9216 | | 3.7470 | 3.8584 | 3.5380 | 3.8900 | 2.7696 | 3.0650 | 3.9468 | 3.7473 |
|
| 121 |
+
| add_10240 | 10240 | | 3.8004 | 3.9087 | 3.5828 | 3.9460 | 2.7910 | 3.0940 | 3.9901 | 3.7973 |
|
| 122 |
+
| add_11264 | 11264 | | 3.8506 | 3.9550 | 3.6242 | 3.9977 | 2.8219 | 3.1247 | 4.0310 | 3.8464 |
|
| 123 |
+
| add_11264_curated | 11264 | ✓ | 3.8476 | 3.9516 | 3.6189 | 3.9933 | 2.8197 | | 4.0278 | |
|
| 124 |
+
| add_12288 | 12288 | | 3.8950 | 4.0015 | 3.6628 | 4.0480 | 2.8423 | 3.1476 | 4.0669 | 3.8945 |
|
| 125 |
+
| add_12288_curated | 12288 | ✓ | 3.8918 | 3.9980 | 3.6573 | 4.0433 | 2.8401 | | 4.0635 | |
|
| 126 |
+
| add_13312 | 13312 | | 3.9379 | 4.0412 | 3.6963 | 4.0918 | 2.8629 | | 4.0987 | |
|
| 127 |
+
| add_14336 | 14336 | | 3.9747 | 4.0811 | 3.7261 | 4.1332 | 2.8769 | | 4.1289 | |
|
| 128 |
+
| add_15360 | 15360 | | 4.0083 | 4.1188 | 3.7552 | 4.1711 | 2.8956 | | 4.1534 | |
|
| 129 |
+
| add_15360_curated | 15360 | ✓ | 4.0046 | 4.1143 | 3.7493 | 4.1657 | 2.8931 | | 4.1495 | |
|
| 130 |
+
| add_16384 | 16384 | | 4.0438 | 4.1516 | 3.7828 | 4.2050 | 2.9085 | | 4.1785 | |
|
| 131 |
+
| add_17408 | 17408 | | 4.0742 | 4.1816 | 3.8070 | 4.2375 | 2.9254 | | 4.1999 | |
|
| 132 |
+
| add_18432 | 18432 | | 4.1028 | 4.2097 | 3.8310 | 4.2705 | 2.9380 | | 4.2235 | |
|
| 133 |
+
| add_19456 | 19456 | | 4.1306 | 4.2374 | 3.8536 | 4.3001 | 2.9528 | | 4.2455 | |
|
| 134 |
+
| add_20480 | 20480 | | 4.1545 | 4.2622 | 3.8750 | 4.3267 | 2.9655 | | 4.2617 | |
|
| 135 |
+
| add_20480_curated | 20480 | ✓ | 4.1499 | 4.2563 | 3.8684 | 4.3201 | 2.9624 | | 4.2572 | |
|
| 136 |
+
| add_21504 | 21504 | | 4.1784 | 4.2855 | 3.8943 | 4.3511 | 2.9782 | | 4.2775 | |
|
| 137 |
+
| add_22528 | 22528 | | 4.2010 | 4.3071 | 3.9129 | 4.3768 | 2.9885 | | 4.2972 | |
|
| 138 |
+
| add_23552 | 23552 | | 4.2227 | 4.3289 | 3.9320 | 4.3993 | 2.9995 | | 4.3192 | |
|
| 139 |
+
| add_24576 | 24576 | | 4.2438 | 4.3490 | 3.9494 | 4.4223 | 3.0097 | | 4.3320 | |
|
| 140 |
+
| add_25600 | 25600 | | 4.2630 | 4.3692 | 3.9684 | 4.4437 | 3.0180 | | 4.3479 | |
|
| 141 |
+
| add_25600_curated | 25600 | ✓ | 4.2576 | 4.3627 | 3.9614 | 4.4366 | 3.0147 | | 4.3430 | |
|
| 142 |
+
|
| 143 |
+
## Tier 1 — paper-aligned (TokEval on Apertus-55 FLORES+)
|
| 144 |
+
|
| 145 |
+
These match the eval surface area the Apertus paper §2.2 uses; cite
|
| 146 |
+
for cross-paper comparison (Meister 2025 / Foroutan et al. 2025a).
|
| 147 |
+
|
| 148 |
+
### TFG (Apertus-55 multilingual fairness)
|
| 149 |
+
|
| 150 |
+
**Lower = more fair.** U-shape with minimum at ~4k — the only metric
|
| 151 |
+
with a clear non-monotonic optimum on this run.
|
| 152 |
+
|
| 153 |
+
| variant_id | added_tokens | curated | value |
|
| 154 |
+
|---|---|---|---|
|
| 155 |
+
| apertus_base | 0 | | 0.1161 |
|
| 156 |
+
| add_1024 | 1024 | | 0.1150 |
|
| 157 |
+
| add_2048 | 2048 | | 0.1146 |
|
| 158 |
+
| add_3072 | 3072 | | 0.1144 |
|
| 159 |
+
| add_4096 | 4096 | | 0.1144 |
|
| 160 |
+
| add_5120 | 5120 | | 0.1145 |
|
| 161 |
+
| add_6144 | 6144 | | 0.1146 |
|
| 162 |
+
| add_7168 | 7168 | | 0.1148 |
|
| 163 |
+
| add_8192 | 8192 | | 0.1149 |
|
| 164 |
+
| add_9216 | 9216 | | 0.1151 |
|
| 165 |
+
| add_10240 | 10240 | | 0.1152 |
|
| 166 |
+
| add_11264 | 11264 | | 0.1154 |
|
| 167 |
+
| add_11264_curated | 11264 | ✓ | 0.1154 |
|
| 168 |
+
| add_12288 | 12288 | | 0.1155 |
|
| 169 |
+
| add_12288_curated | 12288 | ✓ | 0.1155 |
|
| 170 |
+
| add_13312 | 13312 | | 0.1157 |
|
| 171 |
+
| add_14336 | 14336 | | 0.1158 |
|
| 172 |
+
| add_15360 | 15360 | | 0.1159 |
|
| 173 |
+
| add_15360_curated | 15360 | ✓ | 0.1159 |
|
| 174 |
+
| add_16384 | 16384 | | 0.1160 |
|
| 175 |
+
| add_17408 | 17408 | | 0.1161 |
|
| 176 |
+
| add_18432 | 18432 | | 0.1162 |
|
| 177 |
+
| add_19456 | 19456 | | 0.1163 |
|
| 178 |
+
| add_20480 | 20480 | | 0.1164 |
|
| 179 |
+
| add_20480_curated | 20480 | ✓ | 0.1164 |
|
| 180 |
+
| add_21504 | 21504 | | 0.1165 |
|
| 181 |
+
| add_22528 | 22528 | | 0.1166 |
|
| 182 |
+
| add_23552 | 23552 | | 0.1167 |
|
| 183 |
+
| add_24576 | 24576 | | 0.1168 |
|
| 184 |
+
| add_25600 | 25600 | | 0.1169 |
|
| 185 |
+
| add_25600_curated | 25600 | ✓ | 0.1169 |
|
| 186 |
+
|
| 187 |
+
### Fertility (FLORES+ Greek, words config)
|
| 188 |
+
|
| 189 |
+
Same shape as the in-domain fertility above but on cleaner narrower
|
| 190 |
+
data — values are lower (clean Greek is easier to tokenize).
|
| 191 |
+
|
| 192 |
+
| variant_id | added_tokens | curated | value |
|
| 193 |
+
|---|---|---|---|
|
| 194 |
+
| apertus_base | 0 | | 2.2041 |
|
| 195 |
+
| add_1024 | 1024 | | 1.9825 |
|
| 196 |
+
| add_2048 | 2048 | | 1.8545 |
|
| 197 |
+
| add_3072 | 3072 | | 1.7639 |
|
| 198 |
+
| add_4096 | 4096 | | 1.7003 |
|
| 199 |
+
| add_5120 | 5120 | | 1.6408 |
|
| 200 |
+
| add_6144 | 6144 | | 1.5989 |
|
| 201 |
+
| add_7168 | 7168 | | 1.5617 |
|
| 202 |
+
| add_8192 | 8192 | | 1.5309 |
|
| 203 |
+
| add_9216 | 9216 | | 1.5065 |
|
| 204 |
+
| add_10240 | 10240 | | 1.4809 |
|
| 205 |
+
| add_11264 | 11264 | | 1.4599 |
|
| 206 |
+
| add_11264_curated | 11264 | ✓ | 1.4607 |
|
| 207 |
+
| add_12288 | 12288 | | 1.4417 |
|
| 208 |
+
| add_12288_curated | 12288 | ✓ | 1.4426 |
|
| 209 |
+
| add_13312 | 13312 | | 1.4228 |
|
| 210 |
+
| add_14336 | 14336 | | 1.4076 |
|
| 211 |
+
| add_15360 | 15360 | | 1.3941 |
|
| 212 |
+
| add_15360_curated | 15360 | ✓ | 1.3951 |
|
| 213 |
+
| add_16384 | 16384 | | 1.3816 |
|
| 214 |
+
| add_17408 | 17408 | | 1.3693 |
|
| 215 |
+
| add_18432 | 18432 | | 1.3582 |
|
| 216 |
+
| add_19456 | 19456 | | 1.3481 |
|
| 217 |
+
| add_20480 | 20480 | | 1.3399 |
|
| 218 |
+
| add_20480_curated | 20480 | ✓ | 1.3408 |
|
| 219 |
+
| add_21504 | 21504 | | 1.3317 |
|
| 220 |
+
| add_22528 | 22528 | | 1.3225 |
|
| 221 |
+
| add_23552 | 23552 | | 1.3146 |
|
| 222 |
+
| add_24576 | 24576 | | 1.3076 |
|
| 223 |
+
| add_25600 | 25600 | | 1.3008 |
|
| 224 |
+
| add_25600_curated | 25600 | ✓ | 1.3018 |
|
| 225 |
+
|
| 226 |
+
## Tier 2 — multi-criteria supplement
|
| 227 |
+
|
| 228 |
+
### MorphScore Greek (catherinearnett/morphscore)
|
| 229 |
+
|
| 230 |
+
21,428 Greek words from UD Greek-GDT with gold morpheme boundaries;
|
| 231 |
+
`n=693` after the freq-scale + length filter. **Recall** = fraction of
|
| 232 |
+
gold morpheme boundaries the tokenizer hits; **precision** = fraction
|
| 233 |
+
of tokenizer boundaries that hit a real morpheme boundary; **token-
|
| 234 |
+
char ratio** = mean tokens-per-character (lower = less over-segmenting).
|
| 235 |
+
|
| 236 |
+
| variant_id | added_tokens | curated | macro_f1 | macro_precision | macro_recall | mean_token_char_ratio | micro_f1 | micro_precision | micro_recall | morphscore_precision | morphscore_precision_std | morphscore_recall | morphscore_recall_std | num_samples |
|
| 237 |
+
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
| 238 |
+
| apertus_base | 0 | | 0.0210 | 0.0152 | 0.0339 | 0.4871 | 0.0217 | 0.0160 | 0.0338 | 0.6829 | 0.0034 | 0.6979 | 0.0034 | 693.0000 |
|
| 239 |
+
| add_1024 | 1024 | | 0.0179 | 0.0133 | 0.0274 | 0.4426 | 0.0189 | 0.0144 | 0.0274 | 0.6823 | 0.0034 | 0.6940 | 0.0034 | 693.0000 |
|
| 240 |
+
| add_2048 | 2048 | | 0.0126 | 0.0095 | 0.0188 | 0.4213 | 0.0133 | 0.0103 | 0.0187 | 0.6812 | 0.0034 | 0.6890 | 0.0034 | 693.0000 |
|
| 241 |
+
| add_3072 | 3072 | | 0.0130 | 0.0099 | 0.0188 | 0.4073 | 0.0136 | 0.0107 | 0.0187 | 0.6813 | 0.0034 | 0.6890 | 0.0034 | 693.0000 |
|
| 242 |
+
| add_4096 | 4096 | | 0.0125 | 0.0096 | 0.0180 | 0.3944 | 0.0134 | 0.0107 | 0.0180 | 0.6816 | 0.0034 | 0.6890 | 0.0034 | 693.0000 |
|
| 243 |
+
| add_5120 | 5120 | | 0.0116 | 0.0089 | 0.0166 | 0.3833 | 0.0126 | 0.0101 | 0.0166 | 0.6817 | 0.0034 | 0.6883 | 0.0034 | 693.0000 |
|
| 244 |
+
| add_6144 | 6144 | | 0.0114 | 0.0089 | 0.0159 | 0.3730 | 0.0122 | 0.0100 | 0.0158 | 0.6816 | 0.0034 | 0.6872 | 0.0034 | 693.0000 |
|
| 245 |
+
| add_7168 | 7168 | | 0.0109 | 0.0085 | 0.0152 | 0.3669 | 0.0118 | 0.0097 | 0.0151 | 0.6815 | 0.0034 | 0.6870 | 0.0034 | 693.0000 |
|
| 246 |
+
| add_8192 | 8192 | | 0.0100 | 0.0078 | 0.0137 | 0.3637 | 0.0107 | 0.0088 | 0.0137 | 0.6812 | 0.0034 | 0.6859 | 0.0034 | 693.0000 |
|
| 247 |
+
| add_9216 | 9216 | | 0.0100 | 0.0078 | 0.0137 | 0.3588 | 0.0108 | 0.0090 | 0.0137 | 0.6814 | 0.0034 | 0.6861 | 0.0034 | 693.0000 |
|
| 248 |
+
| add_10240 | 10240 | | 0.0101 | 0.0079 | 0.0137 | 0.3546 | 0.0109 | 0.0091 | 0.0137 | 0.6868 | 0.0034 | 0.6915 | 0.0034 | 693.0000 |
|
| 249 |
+
| add_11264 | 11264 | | 0.0095 | 0.0075 | 0.0130 | 0.3507 | 0.0104 | 0.0087 | 0.0130 | 0.6866 | 0.0034 | 0.6909 | 0.0034 | 693.0000 |
|
| 250 |
+
| add_11264_curated | 11264 | ✓ | 0.0095 | 0.0075 | 0.0130 | 0.3507 | 0.0104 | 0.0087 | 0.0130 | 0.6866 | 0.0034 | 0.6909 | 0.0034 | 693.0000 |
|
| 251 |
+
| add_12288 | 12288 | | 0.0096 | 0.0076 | 0.0130 | 0.3478 | 0.0105 | 0.0088 | 0.0130 | 0.6866 | 0.0034 | 0.6909 | 0.0034 | 693.0000 |
|
| 252 |
+
| add_12288_curated | 12288 | ✓ | 0.0096 | 0.0076 | 0.0130 | 0.3478 | 0.0105 | 0.0088 | 0.0130 | 0.6866 | 0.0034 | 0.6909 | 0.0034 | 693.0000 |
|
| 253 |
+
| add_13312 | 13312 | | 0.0090 | 0.0071 | 0.0123 | 0.3465 | 0.0099 | 0.0083 | 0.0122 | 0.6866 | 0.0034 | 0.6908 | 0.0034 | 693.0000 |
|
| 254 |
+
| add_14336 | 14336 | | 0.0090 | 0.0071 | 0.0123 | 0.3454 | 0.0099 | 0.0083 | 0.0122 | 0.6867 | 0.0034 | 0.6909 | 0.0034 | 693.0000 |
|
| 255 |
+
| add_15360 | 15360 | | 0.0079 | 0.0063 | 0.0108 | 0.3419 | 0.0088 | 0.0074 | 0.0108 | 0.6863 | 0.0034 | 0.6892 | 0.0034 | 693.0000 |
|
| 256 |
+
| add_15360_curated | 15360 | ✓ | 0.0079 | 0.0063 | 0.0108 | 0.3419 | 0.0088 | 0.0074 | 0.0108 | 0.6863 | 0.0034 | 0.6892 | 0.0034 | 693.0000 |
|
| 257 |
+
| add_16384 | 16384 | | 0.0081 | 0.0065 | 0.0108 | 0.3393 | 0.0088 | 0.0075 | 0.0108 | 0.6864 | 0.0034 | 0.6892 | 0.0034 | 693.0000 |
|
| 258 |
+
| add_17408 | 17408 | | 0.0081 | 0.0065 | 0.0108 | 0.3364 | 0.0089 | 0.0076 | 0.0108 | 0.6912 | 0.0034 | 0.6940 | 0.0034 | 693.0000 |
|
| 259 |
+
| add_18432 | 18432 | | 0.0083 | 0.0067 | 0.0108 | 0.3339 | 0.0089 | 0.0076 | 0.0108 | 0.6912 | 0.0034 | 0.6940 | 0.0034 | 693.0000 |
|
| 260 |
+
| add_19456 | 19456 | | 0.0078 | 0.0064 | 0.0101 | 0.3311 | 0.0084 | 0.0072 | 0.0101 | 0.6922 | 0.0034 | 0.6947 | 0.0034 | 693.0000 |
|
| 261 |
+
| add_20480 | 20480 | | 0.0078 | 0.0064 | 0.0101 | 0.3298 | 0.0084 | 0.0072 | 0.0101 | 0.6922 | 0.0034 | 0.6947 | 0.0034 | 693.0000 |
|
| 262 |
+
| add_20480_curated | 20480 | ✓ | 0.0078 | 0.0064 | 0.0101 | 0.3298 | 0.0084 | 0.0072 | 0.0101 | 0.6922 | 0.0034 | 0.6947 | 0.0034 | 693.0000 |
|
| 263 |
+
| add_21504 | 21504 | | 0.0078 | 0.0064 | 0.0101 | 0.3282 | 0.0084 | 0.0072 | 0.0101 | 0.6924 | 0.0034 | 0.6949 | 0.0034 | 693.0000 |
|
| 264 |
+
| add_22528 | 22528 | | 0.0078 | 0.0064 | 0.0101 | 0.3265 | 0.0084 | 0.0073 | 0.0101 | 0.6924 | 0.0034 | 0.6949 | 0.0034 | 693.0000 |
|
| 265 |
+
| add_23552 | 23552 | | 0.0078 | 0.0064 | 0.0101 | 0.3244 | 0.0085 | 0.0073 | 0.0101 | 0.6926 | 0.0034 | 0.6950 | 0.0034 | 693.0000 |
|
| 266 |
+
| add_24576 | 24576 | | 0.0079 | 0.0065 | 0.0101 | 0.3240 | 0.0085 | 0.0073 | 0.0101 | 0.6926 | 0.0034 | 0.6950 | 0.0034 | 693.0000 |
|
| 267 |
+
| add_25600 | 25600 | | 0.0079 | 0.0065 | 0.0101 | 0.3225 | 0.0085 | 0.0074 | 0.0101 | 0.6926 | 0.0034 | 0.6950 | 0.0034 | 693.0000 |
|
| 268 |
+
| add_25600_curated | 25600 | ✓ | 0.0079 | 0.0065 | 0.0101 | 0.3225 | 0.0085 | 0.0074 | 0.0101 | 0.6926 | 0.0034 | 0.6950 | 0.0034 | 693.0000 |
|
| 269 |
+
|
| 270 |
+

|
| 271 |
+
|
| 272 |
+
**Reading**: recall is essentially flat (~0.69) across all cutoffs —
|
| 273 |
+
the added vocabulary does not appreciably improve morpheme-boundary
|
| 274 |
+
alignment. Precision improves marginally (+0.5 % at 11k). The
|
| 275 |
+
**token-char ratio drops 29 %** (0.49 → 0.35), confirming the added
|
| 276 |
+
vocab makes Greek encoding more compact without dramatically improving
|
| 277 |
+
morphological structure capture. Useful nuance the 4 paper metrics
|
| 278 |
+
don't see.
|
| 279 |
+
|
| 280 |
+
### Rényi-2.5 efficiency (Apertus-55 global)
|
| 281 |
+
|
| 282 |
+
| variant_id | added_tokens | curated | value |
|
| 283 |
+
|---|---|---|---|
|
| 284 |
+
| apertus_base | 0 | | 8.4483 |
|
| 285 |
+
| add_1024 | 1024 | | 8.4429 |
|
| 286 |
+
| add_2048 | 2048 | | 8.4400 |
|
| 287 |
+
| add_3072 | 3072 | | 8.4377 |
|
| 288 |
+
| add_4096 | 4096 | | 8.4362 |
|
| 289 |
+
| add_5120 | 5120 | | 8.4348 |
|
| 290 |
+
| add_6144 | 6144 | | 8.4338 |
|
| 291 |
+
| add_7168 | 7168 | | 8.4329 |
|
| 292 |
+
| add_8192 | 8192 | | 8.4321 |
|
| 293 |
+
| add_9216 | 9216 | | 8.4315 |
|
| 294 |
+
| add_10240 | 10240 | | 8.4308 |
|
| 295 |
+
| add_11264 | 11264 | | 8.4303 |
|
| 296 |
+
| add_11264_curated | 11264 | ✓ | 8.4299 |
|
| 297 |
+
| add_12288 | 12288 | | 8.4298 |
|
| 298 |
+
| add_12288_curated | 12288 | ✓ | 8.4295 |
|
| 299 |
+
| add_13312 | 13312 | | 8.4294 |
|
| 300 |
+
| add_14336 | 14336 | | 8.4290 |
|
| 301 |
+
| add_15360 | 15360 | | 8.4286 |
|
| 302 |
+
| add_15360_curated | 15360 | ✓ | 8.4283 |
|
| 303 |
+
| add_16384 | 16384 | | 8.4283 |
|
| 304 |
+
| add_17408 | 17408 | | 8.4280 |
|
| 305 |
+
| add_18432 | 18432 | | 8.4277 |
|
| 306 |
+
| add_19456 | 19456 | | 8.4275 |
|
| 307 |
+
| add_20480 | 20480 | | 8.4273 |
|
| 308 |
+
| add_20480_curated | 20480 | ✓ | 8.4269 |
|
| 309 |
+
| add_21504 | 21504 | | 8.4271 |
|
| 310 |
+
| add_22528 | 22528 | | 8.4268 |
|
| 311 |
+
| add_23552 | 23552 | | 8.4266 |
|
| 312 |
+
| add_24576 | 24576 | | 8.4264 |
|
| 313 |
+
| add_25600 | 25600 | | 8.4263 |
|
| 314 |
+
| add_25600_curated | 25600 | ✓ | 8.4259 |
|
| 315 |
+
|
| 316 |
+
### UTF-8 completeness (Apertus-55 global)
|
| 317 |
+
|
| 318 |
+
| variant_id | added_tokens | curated | value |
|
| 319 |
+
|---|---|---|---|
|
| 320 |
+
| apertus_base | 0 | | 0.9792 |
|
| 321 |
+
| add_1024 | 1024 | | 0.9792 |
|
| 322 |
+
| add_2048 | 2048 | | 0.9792 |
|
| 323 |
+
| add_3072 | 3072 | | 0.9792 |
|
| 324 |
+
| add_4096 | 4096 | | 0.9792 |
|
| 325 |
+
| add_5120 | 5120 | | 0.9792 |
|
| 326 |
+
| add_6144 | 6144 | | 0.9791 |
|
| 327 |
+
| add_7168 | 7168 | | 0.9791 |
|
| 328 |
+
| add_8192 | 8192 | | 0.9792 |
|
| 329 |
+
| add_9216 | 9216 | | 0.9791 |
|
| 330 |
+
| add_10240 | 10240 | | 0.9791 |
|
| 331 |
+
| add_11264 | 11264 | | 0.9791 |
|
| 332 |
+
| add_11264_curated | 11264 | ✓ | 0.9791 |
|
| 333 |
+
| add_12288 | 12288 | | 0.9791 |
|
| 334 |
+
| add_12288_curated | 12288 | ✓ | 0.9791 |
|
| 335 |
+
| add_13312 | 13312 | | 0.9791 |
|
| 336 |
+
| add_14336 | 14336 | | 0.9791 |
|
| 337 |
+
| add_15360 | 15360 | | 0.9791 |
|
| 338 |
+
| add_15360_curated | 15360 | ✓ | 0.9791 |
|
| 339 |
+
| add_16384 | 16384 | | 0.9791 |
|
| 340 |
+
| add_17408 | 17408 | | 0.9791 |
|
| 341 |
+
| add_18432 | 18432 | | 0.9791 |
|
| 342 |
+
| add_19456 | 19456 | | 0.9791 |
|
| 343 |
+
| add_20480 | 20480 | | 0.9791 |
|
| 344 |
+
| add_20480_curated | 20480 | ✓ | 0.9791 |
|
| 345 |
+
| add_21504 | 21504 | | 0.9791 |
|
| 346 |
+
| add_22528 | 22528 | | 0.9791 |
|
| 347 |
+
| add_23552 | 23552 | | 0.9791 |
|
| 348 |
+
| add_24576 | 24576 | | 0.9791 |
|
| 349 |
+
| add_25600 | 25600 | | 0.9791 |
|
| 350 |
+
| add_25600_curated | 25600 | ✓ | 0.9791 |
|
| 351 |
+
|
| 352 |
+
## Curated-arm delta (consumes 02_1_5 removal_list)
|
| 353 |
+
|
| 354 |
+
Curated twins remove 39 (at 11,264) / 44 (at 12,288) tokens after
|
| 355 |
+
merge-graph validation. **In every metric tested, the delta vs the
|
| 356 |
+
un-curated variant is essentially zero** — 39/44 token removal is free.
|
| 357 |
+
|
| 358 |
+
### Cutoff 11,264
|
| 359 |
+
|
| 360 |
+
| metric | source | raw | curated | Δ |
|
| 361 |
+
|---|---|---|---|---|
|
| 362 |
+
| greek_word_space_fertility | our_suite_02_1_3 | 1.5444 | 1.5313 | -0.0131 |
|
| 363 |
+
| chars_per_token | our_suite_02_1_3 | 3.6564 | 3.7098 | 0.0534 |
|
| 364 |
+
| eval_added_vocab_utilization_rate | our_suite_02_1_3 | 0.8985 | 0.9108 | 0.0124 |
|
| 365 |
+
| tokenizer_fairness_gini | tokeval-lines | 0.1154 | 0.1154 | -0.0000 |
|
| 366 |
+
| renyi_efficiency | tokeval-lines | 8.4303 | 8.4299 | -0.0004 |
|
| 367 |
+
| utf8_token_integrity | tokeval-lines | 0.9791 | 0.9791 | 0.0000 |
|
| 368 |
+
| morphscore_recall | morphscore | 0.6909 | 0.6909 | 0.0000 |
|
| 369 |
+
| morphscore_precision | morphscore | 0.6866 | 0.6866 | 0.0000 |
|
| 370 |
+
| mean_token_char_ratio | morphscore | 0.3507 | 0.3507 | 0.0000 |
|
| 371 |
+
|
| 372 |
+
### Cutoff 12,288
|
| 373 |
+
|
| 374 |
+
| metric | source | raw | curated | Δ |
|
| 375 |
+
|---|---|---|---|---|
|
| 376 |
+
| greek_word_space_fertility | our_suite_02_1_3 | 1.5230 | 1.5098 | -0.0131 |
|
| 377 |
+
| chars_per_token | our_suite_02_1_3 | 3.6948 | 3.7490 | 0.0542 |
|
| 378 |
+
| eval_added_vocab_utilization_rate | our_suite_02_1_3 | 0.8870 | 0.9004 | 0.0134 |
|
| 379 |
+
| tokenizer_fairness_gini | tokeval-lines | 0.1155 | 0.1155 | -0.0000 |
|
| 380 |
+
| renyi_efficiency | tokeval-lines | 8.4298 | 8.4295 | -0.0004 |
|
| 381 |
+
| utf8_token_integrity | tokeval-lines | 0.9791 | 0.9791 | -0.0000 |
|
| 382 |
+
| morphscore_recall | morphscore | 0.6909 | 0.6909 | 0.0000 |
|
| 383 |
+
| morphscore_precision | morphscore | 0.6866 | 0.6866 | 0.0000 |
|
| 384 |
+
| mean_token_char_ratio | morphscore | 0.3478 | 0.3478 | 0.0000 |
|
| 385 |
+
|
| 386 |
+
## Methodology delta — TokEval-fertility vs 02_1_3-fertility on Greek
|
| 387 |
+
|
| 388 |
+
Same 15 tokenizers, same target (Greek), different eval sets and
|
| 389 |
+
different normalizations. **TokEval = FLORES+ ell_Grek, words config.**
|
| 390 |
+
**02_1_3 = our in-domain held-outs, greek_word_space_fertility.**
|
| 391 |
+
|
| 392 |
+
Use this to decide which fertility number to cite — TokEval for paper
|
| 393 |
+
comparability, 02_1_3 for in-domain decision-making.
|
| 394 |
+
|
| 395 |
+
| variant_id | added_tokens | TokEval (FLORES+ Greek) | 02_1_3 (C3_val) |
|
| 396 |
+
|---|---|---|---|
|
| 397 |
+
| apertus_base | 0 | 2.2041 | 2.4113 |
|
| 398 |
+
| add_1024 | 1024 | 1.9825 | 2.0799 |
|
| 399 |
+
| add_2048 | 2048 | 1.8545 | 1.9222 |
|
| 400 |
+
| add_3072 | 3072 | 1.7639 | 1.8102 |
|
| 401 |
+
| add_4096 | 4096 | 1.7003 | 1.7281 |
|
| 402 |
+
| add_5120 | 5120 | 1.6408 | 1.6608 |
|
| 403 |
+
| add_6144 | 6144 | 1.5989 | 1.6106 |
|
| 404 |
+
| add_7168 | 7168 | 1.5617 | 1.5668 |
|
| 405 |
+
| add_8192 | 8192 | 1.5309 | 1.5293 |
|
| 406 |
+
| add_9216 | 9216 | 1.5065 | 1.4975 |
|
| 407 |
+
| add_10240 | 10240 | 1.4809 | 1.4713 |
|
| 408 |
+
| add_11264 | 11264 | 1.4599 | 1.4475 |
|
| 409 |
+
| add_11264_curated | 11264 | 1.4607 | 1.4477 |
|
| 410 |
+
| add_12288 | 12288 | 1.4417 | 1.4253 |
|
| 411 |
+
| add_12288_curated | 12288 | 1.4426 | 1.4256 |
|
| 412 |
+
| add_13312 | 13312 | 1.4228 | 1.4061 |
|
| 413 |
+
| add_14336 | 14336 | 1.4076 | 1.3883 |
|
| 414 |
+
| add_15360 | 15360 | 1.3941 | 1.3723 |
|
| 415 |
+
| add_15360_curated | 15360 | 1.3951 | 1.3727 |
|
| 416 |
+
| add_16384 | 16384 | 1.3816 | 1.3586 |
|
| 417 |
+
| add_17408 | 17408 | 1.3693 | 1.3456 |
|
| 418 |
+
| add_18432 | 18432 | 1.3582 | 1.3323 |
|
| 419 |
+
| add_19456 | 19456 | 1.3481 | 1.3208 |
|
| 420 |
+
| add_20480 | 20480 | 1.3399 | 1.3107 |
|
| 421 |
+
| add_20480_curated | 20480 | 1.3408 | 1.3112 |
|
| 422 |
+
| add_21504 | 21504 | 1.3317 | 1.3013 |
|
| 423 |
+
| add_22528 | 22528 | 1.3225 | 1.2915 |
|
| 424 |
+
| add_23552 | 23552 | 1.3146 | 1.2831 |
|
| 425 |
+
| add_24576 | 24576 | 1.3076 | 1.2748 |
|
| 426 |
+
| add_25600 | 25600 | 1.3008 | 1.2671 |
|
| 427 |
+
| add_25600_curated | 25600 | 1.3018 | 1.2676 |
|
| 428 |
+
|
| 429 |
+
## Reproduction
|
| 430 |
+
|
| 431 |
+
```bash
|
| 432 |
+
cd subprojects/02_1_tokenizer_experiments/02_1_7_intrinsic_eval_sweep
|
| 433 |
+
$VENV/python scripts/01_build_variants_inline.py # local 13 variants
|
| 434 |
+
$VENV/python scripts/01b_build_curated_variants.py # 2 curated twins
|
| 435 |
+
$VENV/python scripts/02_prep_eval_configs.py
|
| 436 |
+
bash scripts/03a_run_tokeval.sh # TokEval 2 jobs (~30 min)
|
| 437 |
+
# gcloud: resume → run 02_1_3 harness for our 4 in-house slices → suspend
|
| 438 |
+
$VENV/python scripts/07_morphscore_greek.py # MorphScore Greek
|
| 439 |
+
$VENV/python scripts/08_merge_all.py # merge all 4 sources
|
| 440 |
+
$VENV/python scripts/09_render_final_report.py # this file + plots
|
| 441 |
+
```
|
provenance/tokenizer-selection/curated_padded_at_17408_manifest.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"variant_id": "add_17408_curated_padded",
|
| 3 |
+
"added_tokens": 17408,
|
| 4 |
+
"total_vocab": 148480,
|
| 5 |
+
"alignment_128": true,
|
| 6 |
+
"alignment_256": true,
|
| 7 |
+
"apertus_base_preserved_verbatim": true,
|
| 8 |
+
"removal_list_source": "/home/foivos/Projects/glossapi-tokenizer-extension/subprojects/02_1_tokenizer_experiments/02_1_5_added_token_curation/manifests/removal_list.jsonl",
|
| 9 |
+
"removal_list_size_full": 104,
|
| 10 |
+
"merges_walked_from_c3_full": 17477,
|
| 11 |
+
"merges_skipped_for_removal": 69,
|
| 12 |
+
"merges_skipped_for_cascade": 0,
|
| 13 |
+
"merges_accepted": 17408,
|
| 14 |
+
"ship_artifact_path": "/home/foivos/Projects/glossapi-tokenizer-extension/subprojects/02_1_tokenizer_experiments/02_1_7_intrinsic_eval_sweep/variants/c3_added_17408_curated_padded/tokenizer.json"
|
| 15 |
+
}
|
provenance/tokenizer-selection/firing_count_20260518_run_summary_augmented.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
results/SUMMARY.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 3.5B continuation results - Vanilla vs ReTok vs TD layer11
|
| 2 |
+
|
| 3 |
+
Generated UTC: `2026-05-25T05:23:53+00:00`.
|
| 4 |
+
|
| 5 |
+
This summarizes the continuation run `continuation_3p5b_20260524T143012Z`,
|
| 6 |
+
which extended Vanilla, ReTok, and TD layer11 from iter 476 (~2.0B tokens)
|
| 7 |
+
to iter 834 (~3.5B tokens). Local JSON snapshots live under
|
| 8 |
+
`per_iter_results/`; remote full artifacts remain on Clariden under
|
| 9 |
+
`/capstor/scratch/cscs/fffoivos/runs/eval/continuation_3p5b_20260524T143012Z_*`.
|
| 10 |
+
|
| 11 |
+
## Bottom line
|
| 12 |
+
|
| 13 |
+
- TD layer11 is the best final benchmark arm overall: it is first on English
|
| 14 |
+
retention and multilingual aggregates, and narrowly first on the Greek
|
| 15 |
+
aggregate at iter 834.
|
| 16 |
+
- Vanilla still has the best tokenizer-fair heldout Greek BPC, but its
|
| 17 |
+
downstream Greek aggregate declined during the 2.0B -> 3.5B continuation.
|
| 18 |
+
- ReTok improves fastest on BPC and wins Greek MMLU / INCLUDE-44 Greek at
|
| 19 |
+
iter 834, but it remains behind TD and Vanilla on the Greek aggregate.
|
| 20 |
+
- If selecting for the actual downstream bakeoff objective, TD layer11 is now
|
| 21 |
+
the leading candidate. If selecting only for heldout BPC, Vanilla remains
|
| 22 |
+
ahead.
|
| 23 |
+
|
| 24 |
+
## Aggregate scoreboard at iter 834
|
| 25 |
+
|
| 26 |
+
| Arm | Greek agg | Delta vs 476 | EN retention | Delta vs 476 | Multilingual | Delta vs 476 | BPC lower better | BPC delta |
|
| 27 |
+
|---|---:|---:|---:|---:|---:|---:|---:|---:|
|
| 28 |
+
| Vanilla | 0.4339 | -0.70 pp | 0.6782 | -0.36 pp | 0.4923 | +0.22 pp | 0.4724 | -0.0182 |
|
| 29 |
+
| ReTok | 0.4246 | +0.96 pp | 0.6786 | +0.36 pp | 0.4864 | -0.09 pp | 0.5390 | -0.0349 |
|
| 30 |
+
| TD layer11 | 0.4344 | +0.90 pp | 0.6865 | +0.38 pp | 0.4967 | +0.68 pp | 0.5054 | -0.0256 |
|
| 31 |
+
|
| 32 |
+
## Per-task winners at iter 834
|
| 33 |
+
|
| 34 |
+
| Group | Task | Vanilla | ReTok | TD layer11 | Winner |
|
| 35 |
+
|---|---|---:|---:|---:|---|
|
| 36 |
+
| EN retention | `mmlu` | 0.5330 | 0.5565 | 0.5556 | ReTok |
|
| 37 |
+
| EN retention | `hellaswag` | 0.7573 | 0.7556 | 0.7632 | TD layer11 |
|
| 38 |
+
| EN retention | `arc_easy` | 0.7866 | 0.7576 | 0.7837 | Vanilla |
|
| 39 |
+
| EN retention | `arc_challenge` | 0.5230 | 0.5247 | 0.5358 | TD layer11 |
|
| 40 |
+
| EN retention | `piqa` | 0.7927 | 0.7851 | 0.7894 | Vanilla |
|
| 41 |
+
| EN retention | `winogrande` | 0.6764 | 0.6922 | 0.6914 | ReTok |
|
| 42 |
+
| Multilingual | `global_mmlu` | 0.4505 | 0.4603 | 0.4628 | TD layer11 |
|
| 43 |
+
| Multilingual | `xcopa` | 0.6178 | 0.5920 | 0.6156 | Vanilla |
|
| 44 |
+
| Multilingual | `xnli` | 0.4087 | 0.4070 | 0.4117 | TD layer11 |
|
| 45 |
+
| Greek | `global_mmlu_full_el` | 0.4145 | 0.4153 | 0.4036 | ReTok |
|
| 46 |
+
| Greek | `include_base_44_greek_few_shot_en` | 0.4022 | 0.4058 | 0.4004 | ReTok |
|
| 47 |
+
| Greek | `belebele_ell_Grek` | 0.5078 | 0.4933 | 0.5389 | TD layer11 |
|
| 48 |
+
| Greek | `arc_challenge_mt_el` | 0.4130 | 0.3899 | 0.4061 | Vanilla |
|
| 49 |
+
| Greek | `xnli_el` | 0.3831 | 0.3695 | 0.3851 | TD layer11 |
|
| 50 |
+
| Greek | `xquad_el` | 0.2868 | 0.3084 | 0.3364 | TD layer11 |
|
| 51 |
+
| Greek | `global_piqa_completions_ell_grek` | 0.6300 | 0.5900 | 0.5700 | Vanilla |
|
| 52 |
+
|
| 53 |
+
## Change from iter 476 to iter 834
|
| 54 |
+
|
| 55 |
+
| Group | Task | Vanilla delta | ReTok delta | TD layer11 delta |
|
| 56 |
+
|---|---|---:|---:|---:|
|
| 57 |
+
| EN retention | `mmlu` | -0.09 pp | +0.24 pp | +0.56 pp |
|
| 58 |
+
| EN retention | `hellaswag` | -0.21 pp | +0.69 pp | +0.27 pp |
|
| 59 |
+
| EN retention | `arc_easy` | +0.13 pp | -0.59 pp | +0.29 pp |
|
| 60 |
+
| EN retention | `arc_challenge` | -0.43 pp | +0.94 pp | +0.85 pp |
|
| 61 |
+
| EN retention | `piqa` | -0.22 pp | -0.11 pp | -0.27 pp |
|
| 62 |
+
| EN retention | `winogrande` | -1.34 pp | +1.03 pp | +0.55 pp |
|
| 63 |
+
| Multilingual | `global_mmlu` | -0.64 pp | +0.14 pp | +1.34 pp |
|
| 64 |
+
| Multilingual | `xcopa` | +1.09 pp | -0.71 pp | +0.42 pp |
|
| 65 |
+
| Multilingual | `xnli` | +0.22 pp | +0.30 pp | +0.28 pp |
|
| 66 |
+
| Greek | `global_mmlu_full_el` | -0.69 pp | +1.62 pp | +1.77 pp |
|
| 67 |
+
| Greek | `include_base_44_greek_few_shot_en` | -1.63 pp | +3.26 pp | -0.36 pp |
|
| 68 |
+
| Greek | `belebele_ell_Grek` | -0.56 pp | -0.33 pp | +1.11 pp |
|
| 69 |
+
| Greek | `arc_challenge_mt_el` | -0.77 pp | +1.79 pp | +0.26 pp |
|
| 70 |
+
| Greek | `xnli_el` | -1.89 pp | -0.56 pp | +0.48 pp |
|
| 71 |
+
| Greek | `xquad_el` | -2.33 pp | -0.08 pp | +1.02 pp |
|
| 72 |
+
| Greek | `global_piqa_completions_ell_grek` | +3.00 pp | +1.00 pp | +2.00 pp |
|
| 73 |
+
|
| 74 |
+
## New-token diagnostics
|
| 75 |
+
|
| 76 |
+
Measured on the 500-document heldout slice. Top-k is the fraction of
|
| 77 |
+
positions whose correct new token appears in the model's top-k predictions;
|
| 78 |
+
lower mean rank is better.
|
| 79 |
+
|
| 80 |
+
| Arm | Top-1 at new target | Delta from 585 | Top-5 at new target | Delta from 585 | Mean rank | Delta from 585 |
|
| 81 |
+
|---|---:|---:|---:|---:|---:|---:|
|
| 82 |
+
| ReTok | 0.3799 | +2.00 pp | 0.5469 | +2.11 pp | 228.9 | -31.4 |
|
| 83 |
+
| TD layer11 | 0.4105 | +1.43 pp | 0.5811 | +1.54 pp | 174.3 | -18.8 |
|
| 84 |
+
|
| 85 |
+
## Artifact checklist
|
| 86 |
+
|
| 87 |
+
- Local packed-eval snapshots: `per_iter_results/{vanilla,retok,td}_iter{585,715,834}.json`.
|
| 88 |
+
- Local BPC snapshots: `per_iter_results/intrinsic/*_iter{585,715,834}_fair.json`.
|
| 89 |
+
- Local new-token diagnostics: `per_iter_results/diagnostics/{retok,td}_iter{585,715,834}_new_token_diagnostics.json`.
|
| 90 |
+
- Regenerated plots are written to `plots/`.
|
| 91 |
+
- Final remote packed eval job: `2376082`, state `COMPLETED`, exit `0:0`, elapsed `00:59:51`.
|
results/benchmark_table.csv
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
arm,greek_aggregate,greek_delta_vs_iter476_pp,english_retention,english_delta_vs_iter476_pp,multilingual,multilingual_delta_vs_iter476_pp,bpc_lower_better,bpc_delta
|
| 2 |
+
Vanilla,0.4339,-0.70,0.6782,-0.36,0.4923,0.22,0.4724,-0.0182
|
| 3 |
+
ReTok,0.4246,0.96,0.6786,0.36,0.4864,-0.09,0.5390,-0.0349
|
| 4 |
+
TD layer11,0.4344,0.90,0.6865,0.38,0.4967,0.68,0.5054,-0.0256
|
| 5 |
+
|
results/continuation_3p5b_summary.json
ADDED
|
@@ -0,0 +1,364 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"diag_rows": [
|
| 3 |
+
{
|
| 4 |
+
"arm": "retok",
|
| 5 |
+
"mean_rank": 228.9052154654546,
|
| 6 |
+
"mean_rank_delta_from_585": -31.404831868911288,
|
| 7 |
+
"top1": 0.3798836182563004,
|
| 8 |
+
"top1_delta_from_585": 0.019972352098200752,
|
| 9 |
+
"top5": 0.5469290563525036,
|
| 10 |
+
"top5_delta_from_585": 0.021119522892752207
|
| 11 |
+
},
|
| 12 |
+
{
|
| 13 |
+
"arm": "td",
|
| 14 |
+
"mean_rank": 174.2876756944545,
|
| 15 |
+
"mean_rank_delta_from_585": -18.7823704818841,
|
| 16 |
+
"top1": 0.41053515336624063,
|
| 17 |
+
"top1_delta_from_585": 0.014301637161096115,
|
| 18 |
+
"top5": 0.5811415254114616,
|
| 19 |
+
"top5_delta_from_585": 0.015358337072796546
|
| 20 |
+
}
|
| 21 |
+
],
|
| 22 |
+
"generated_utc": "2026-05-25T05:23:53+00:00",
|
| 23 |
+
"group_rows": [
|
| 24 |
+
{
|
| 25 |
+
"EN retention": {
|
| 26 |
+
"delta": -0.0036023994242395663,
|
| 27 |
+
"iter476": 0.6817902499718899,
|
| 28 |
+
"iter834": 0.6781878505476503
|
| 29 |
+
},
|
| 30 |
+
"Greek": {
|
| 31 |
+
"delta": -0.0069518253078383885,
|
| 32 |
+
"iter476": 0.44085471366912354,
|
| 33 |
+
"iter834": 0.43390288836128516
|
| 34 |
+
},
|
| 35 |
+
"Multilingual": {
|
| 36 |
+
"delta": 0.002230923643585403,
|
| 37 |
+
"iter476": 0.4900917349227056,
|
| 38 |
+
"iter834": 0.492322658566291
|
| 39 |
+
},
|
| 40 |
+
"arm": "vanilla",
|
| 41 |
+
"bpc": {
|
| 42 |
+
"delta": -0.018193672749048873,
|
| 43 |
+
"iter476": 0.4905790115645303,
|
| 44 |
+
"iter834": 0.47238533881548145
|
| 45 |
+
}
|
| 46 |
+
},
|
| 47 |
+
{
|
| 48 |
+
"EN retention": {
|
| 49 |
+
"delta": 0.0036478269859219203,
|
| 50 |
+
"iter476": 0.6749804337638333,
|
| 51 |
+
"iter834": 0.6786282607497552
|
| 52 |
+
},
|
| 53 |
+
"Greek": {
|
| 54 |
+
"delta": 0.00956345274685877,
|
| 55 |
+
"iter476": 0.41502996652924373,
|
| 56 |
+
"iter834": 0.4245934192761025
|
| 57 |
+
},
|
| 58 |
+
"Multilingual": {
|
| 59 |
+
"delta": -0.0009003749821289708,
|
| 60 |
+
"iter476": 0.48733830931505984,
|
| 61 |
+
"iter834": 0.48643793433293087
|
| 62 |
+
},
|
| 63 |
+
"arm": "retok",
|
| 64 |
+
"bpc": {
|
| 65 |
+
"delta": -0.03491945208518521,
|
| 66 |
+
"iter476": 0.57388731113822,
|
| 67 |
+
"iter834": 0.5389678590530348
|
| 68 |
+
}
|
| 69 |
+
},
|
| 70 |
+
{
|
| 71 |
+
"EN retention": {
|
| 72 |
+
"delta": 0.0037544227559322962,
|
| 73 |
+
"iter476": 0.6827725274715655,
|
| 74 |
+
"iter834": 0.6865269502274978
|
| 75 |
+
},
|
| 76 |
+
"Greek": {
|
| 77 |
+
"delta": 0.008970722628639627,
|
| 78 |
+
"iter476": 0.4253979832454272,
|
| 79 |
+
"iter834": 0.43436870587406684
|
| 80 |
+
},
|
| 81 |
+
"Multilingual": {
|
| 82 |
+
"delta": 0.006784718226652775,
|
| 83 |
+
"iter476": 0.48993351359709303,
|
| 84 |
+
"iter834": 0.4967182318237458
|
| 85 |
+
},
|
| 86 |
+
"arm": "td",
|
| 87 |
+
"bpc": {
|
| 88 |
+
"delta": -0.02564778560419223,
|
| 89 |
+
"iter476": 0.531084014463596,
|
| 90 |
+
"iter834": 0.5054362288594038
|
| 91 |
+
}
|
| 92 |
+
}
|
| 93 |
+
],
|
| 94 |
+
"iterations": [
|
| 95 |
+
476,
|
| 96 |
+
585,
|
| 97 |
+
715,
|
| 98 |
+
834
|
| 99 |
+
],
|
| 100 |
+
"task_rows": [
|
| 101 |
+
{
|
| 102 |
+
"deltas": {
|
| 103 |
+
"retok": 0.002350092579404661,
|
| 104 |
+
"td": 0.005554764278592805,
|
| 105 |
+
"vanilla": -0.0009257940464321157
|
| 106 |
+
},
|
| 107 |
+
"group": "EN retention",
|
| 108 |
+
"label": "MMLU",
|
| 109 |
+
"task": "mmlu",
|
| 110 |
+
"values": {
|
| 111 |
+
"retok": 0.5565446517590087,
|
| 112 |
+
"td": 0.5556188577125766,
|
| 113 |
+
"vanilla": 0.5330437259649623
|
| 114 |
+
},
|
| 115 |
+
"winner": "retok"
|
| 116 |
+
},
|
| 117 |
+
{
|
| 118 |
+
"deltas": {
|
| 119 |
+
"retok": 0.006871141206930886,
|
| 120 |
+
"td": 0.0026887074287991197,
|
| 121 |
+
"vanilla": -0.0020912168890659943
|
| 122 |
+
},
|
| 123 |
+
"group": "EN retention",
|
| 124 |
+
"label": "HellaSwag",
|
| 125 |
+
"task": "hellaswag",
|
| 126 |
+
"values": {
|
| 127 |
+
"retok": 0.7556263692491536,
|
| 128 |
+
"td": 0.7631945827524398,
|
| 129 |
+
"vanilla": 0.7573192591117307
|
| 130 |
+
},
|
| 131 |
+
"winner": "td"
|
| 132 |
+
},
|
| 133 |
+
{
|
| 134 |
+
"deltas": {
|
| 135 |
+
"retok": -0.005892255892255949,
|
| 136 |
+
"td": 0.002946127946127919,
|
| 137 |
+
"vanilla": 0.0012626262626262985
|
| 138 |
+
},
|
| 139 |
+
"group": "EN retention",
|
| 140 |
+
"label": "ARC Easy",
|
| 141 |
+
"task": "arc_easy",
|
| 142 |
+
"values": {
|
| 143 |
+
"retok": 0.7575757575757576,
|
| 144 |
+
"td": 0.7836700336700336,
|
| 145 |
+
"vanilla": 0.7866161616161617
|
| 146 |
+
},
|
| 147 |
+
"winner": "vanilla"
|
| 148 |
+
},
|
| 149 |
+
{
|
| 150 |
+
"deltas": {
|
| 151 |
+
"retok": 0.009385665529010212,
|
| 152 |
+
"td": 0.008532423208191142,
|
| 153 |
+
"vanilla": -0.004266211604095571
|
| 154 |
+
},
|
| 155 |
+
"group": "EN retention",
|
| 156 |
+
"label": "ARC Challenge",
|
| 157 |
+
"task": "arc_challenge",
|
| 158 |
+
"values": {
|
| 159 |
+
"retok": 0.5247440273037542,
|
| 160 |
+
"td": 0.5358361774744027,
|
| 161 |
+
"vanilla": 0.523037542662116
|
| 162 |
+
},
|
| 163 |
+
"winner": "td"
|
| 164 |
+
},
|
| 165 |
+
{
|
| 166 |
+
"deltas": {
|
| 167 |
+
"retok": -0.0010881392818281599,
|
| 168 |
+
"td": -0.002720348204570233,
|
| 169 |
+
"vanilla": -0.0021762785636560977
|
| 170 |
+
},
|
| 171 |
+
"group": "EN retention",
|
| 172 |
+
"label": "PIQA",
|
| 173 |
+
"task": "piqa",
|
| 174 |
+
"values": {
|
| 175 |
+
"retok": 0.7850924918389554,
|
| 176 |
+
"td": 0.7894450489662677,
|
| 177 |
+
"vanilla": 0.7927094668117519
|
| 178 |
+
},
|
| 179 |
+
"winner": "vanilla"
|
| 180 |
+
},
|
| 181 |
+
{
|
| 182 |
+
"deltas": {
|
| 183 |
+
"retok": 0.010260457774269871,
|
| 184 |
+
"td": 0.005524861878453136,
|
| 185 |
+
"vanilla": -0.013417521704814472
|
| 186 |
+
},
|
| 187 |
+
"group": "EN retention",
|
| 188 |
+
"label": "Winogrande",
|
| 189 |
+
"task": "winogrande",
|
| 190 |
+
"values": {
|
| 191 |
+
"retok": 0.6921862667719021,
|
| 192 |
+
"td": 0.691397000789266,
|
| 193 |
+
"vanilla": 0.6764009471191792
|
| 194 |
+
},
|
| 195 |
+
"winner": "retok"
|
| 196 |
+
},
|
| 197 |
+
{
|
| 198 |
+
"deltas": {
|
| 199 |
+
"retok": 0.001391122832608005,
|
| 200 |
+
"td": 0.013387865279933964,
|
| 201 |
+
"vanilla": -0.006411768438843168
|
| 202 |
+
},
|
| 203 |
+
"group": "Multilingual",
|
| 204 |
+
"label": "Global MMLU",
|
| 205 |
+
"task": "global_mmlu",
|
| 206 |
+
"values": {
|
| 207 |
+
"retok": 0.4602990774298503,
|
| 208 |
+
"td": 0.4628181979660652,
|
| 209 |
+
"vanilla": 0.4504750950855104
|
| 210 |
+
},
|
| 211 |
+
"winner": "td"
|
| 212 |
+
},
|
| 213 |
+
{
|
| 214 |
+
"deltas": {
|
| 215 |
+
"retok": -0.007090909090909148,
|
| 216 |
+
"td": 0.0041818181818181754,
|
| 217 |
+
"vanilla": 0.010909090909090868
|
| 218 |
+
},
|
| 219 |
+
"group": "Multilingual",
|
| 220 |
+
"label": "XCOPA",
|
| 221 |
+
"task": "xcopa",
|
| 222 |
+
"values": {
|
| 223 |
+
"retok": 0.592,
|
| 224 |
+
"td": 0.6156363636363636,
|
| 225 |
+
"vanilla": 0.6178181818181818
|
| 226 |
+
},
|
| 227 |
+
"winner": "vanilla"
|
| 228 |
+
},
|
| 229 |
+
{
|
| 230 |
+
"deltas": {
|
| 231 |
+
"retok": 0.0029986613119142858,
|
| 232 |
+
"td": 0.0027844712182061304,
|
| 233 |
+
"vanilla": 0.0021954484605086755
|
| 234 |
+
},
|
| 235 |
+
"group": "Multilingual",
|
| 236 |
+
"label": "XNLI",
|
| 237 |
+
"task": "xnli",
|
| 238 |
+
"values": {
|
| 239 |
+
"retok": 0.4070147255689424,
|
| 240 |
+
"td": 0.41170013386880855,
|
| 241 |
+
"vanilla": 0.4086746987951807
|
| 242 |
+
},
|
| 243 |
+
"winner": "td"
|
| 244 |
+
},
|
| 245 |
+
{
|
| 246 |
+
"deltas": {
|
| 247 |
+
"retok": 0.016165788349237986,
|
| 248 |
+
"td": 0.017732516735507742,
|
| 249 |
+
"vanilla": -0.006907847884916718
|
| 250 |
+
},
|
| 251 |
+
"group": "Greek",
|
| 252 |
+
"label": "Greek MMLU",
|
| 253 |
+
"task": "global_mmlu_full_el",
|
| 254 |
+
"values": {
|
| 255 |
+
"retok": 0.4152542372881356,
|
| 256 |
+
"td": 0.4036462042444096,
|
| 257 |
+
"vanilla": 0.4144708730950007
|
| 258 |
+
},
|
| 259 |
+
"winner": "retok"
|
| 260 |
+
},
|
| 261 |
+
{
|
| 262 |
+
"deltas": {
|
| 263 |
+
"retok": 0.03260869565217395,
|
| 264 |
+
"td": -0.0036231884057971175,
|
| 265 |
+
"vanilla": -0.016304347826086973
|
| 266 |
+
},
|
| 267 |
+
"group": "Greek",
|
| 268 |
+
"label": "INCLUDE-44 Greek",
|
| 269 |
+
"task": "include_base_44_greek_few_shot_en",
|
| 270 |
+
"values": {
|
| 271 |
+
"retok": 0.4057971014492754,
|
| 272 |
+
"td": 0.4003623188405797,
|
| 273 |
+
"vanilla": 0.40217391304347827
|
| 274 |
+
},
|
| 275 |
+
"winner": "retok"
|
| 276 |
+
},
|
| 277 |
+
{
|
| 278 |
+
"deltas": {
|
| 279 |
+
"retok": -0.0033333333333332993,
|
| 280 |
+
"td": 0.011111111111111072,
|
| 281 |
+
"vanilla": -0.005555555555555536
|
| 282 |
+
},
|
| 283 |
+
"group": "Greek",
|
| 284 |
+
"label": "Belebele Greek",
|
| 285 |
+
"task": "belebele_ell_Grek",
|
| 286 |
+
"values": {
|
| 287 |
+
"retok": 0.49333333333333335,
|
| 288 |
+
"td": 0.5388888888888889,
|
| 289 |
+
"vanilla": 0.5077777777777778
|
| 290 |
+
},
|
| 291 |
+
"winner": "td"
|
| 292 |
+
},
|
| 293 |
+
{
|
| 294 |
+
"deltas": {
|
| 295 |
+
"retok": 0.017918088737201354,
|
| 296 |
+
"td": 0.0025597269624573205,
|
| 297 |
+
"vanilla": -0.007679180887372017
|
| 298 |
+
},
|
| 299 |
+
"group": "Greek",
|
| 300 |
+
"label": "ARC Challenge MT-el",
|
| 301 |
+
"task": "arc_challenge_mt_el",
|
| 302 |
+
"values": {
|
| 303 |
+
"retok": 0.38993174061433444,
|
| 304 |
+
"td": 0.4061433447098976,
|
| 305 |
+
"vanilla": 0.4129692832764505
|
| 306 |
+
},
|
| 307 |
+
"winner": "vanilla"
|
| 308 |
+
},
|
| 309 |
+
{
|
| 310 |
+
"deltas": {
|
| 311 |
+
"retok": -0.005622489959839383,
|
| 312 |
+
"td": 0.004819277108433773,
|
| 313 |
+
"vanilla": -0.01887550200803212
|
| 314 |
+
},
|
| 315 |
+
"group": "Greek",
|
| 316 |
+
"label": "XNLI Greek",
|
| 317 |
+
"task": "xnli_el",
|
| 318 |
+
"values": {
|
| 319 |
+
"retok": 0.36947791164658633,
|
| 320 |
+
"td": 0.385140562248996,
|
| 321 |
+
"vanilla": 0.38313253012048193
|
| 322 |
+
},
|
| 323 |
+
"winner": "td"
|
| 324 |
+
},
|
| 325 |
+
{
|
| 326 |
+
"deltas": {
|
| 327 |
+
"retok": -0.0007925802174291174,
|
| 328 |
+
"td": 0.010195614888764415,
|
| 329 |
+
"vanilla": -0.02334034299290566
|
| 330 |
+
},
|
| 331 |
+
"group": "Greek",
|
| 332 |
+
"label": "XQuAD Greek F1",
|
| 333 |
+
"task": "xquad_el",
|
| 334 |
+
"values": {
|
| 335 |
+
"retok": 0.3083596106010522,
|
| 336 |
+
"td": 0.3363996221856959,
|
| 337 |
+
"vanilla": 0.2867958412158067
|
| 338 |
+
},
|
| 339 |
+
"winner": "td"
|
| 340 |
+
},
|
| 341 |
+
{
|
| 342 |
+
"deltas": {
|
| 343 |
+
"retok": 0.010000000000000009,
|
| 344 |
+
"td": 0.019999999999999907,
|
| 345 |
+
"vanilla": 0.030000000000000027
|
| 346 |
+
},
|
| 347 |
+
"group": "Greek",
|
| 348 |
+
"label": "PIQA Greek",
|
| 349 |
+
"task": "global_piqa_completions_ell_grek",
|
| 350 |
+
"values": {
|
| 351 |
+
"retok": 0.59,
|
| 352 |
+
"td": 0.57,
|
| 353 |
+
"vanilla": 0.63
|
| 354 |
+
},
|
| 355 |
+
"winner": "vanilla"
|
| 356 |
+
}
|
| 357 |
+
],
|
| 358 |
+
"tokens_b": {
|
| 359 |
+
"476": 1.996488704,
|
| 360 |
+
"585": 2.45366784,
|
| 361 |
+
"715": 2.99892736,
|
| 362 |
+
"834": 3.498049536
|
| 363 |
+
}
|
| 364 |
+
}
|
results/plots/global_mmlu_full_el_subcategories_van_td.png
ADDED
|
Git LFS Details
|
results/plots/include_base_44_greek_subjects_van_td.png
ADDED
|
Git LFS Details
|
results/plots/intrinsic_trajectories.png
ADDED
|
Git LFS Details
|
results/plots/intrinsic_van_td.png
ADDED
|
Git LFS Details
|
results/plots/trajectories.png
ADDED
|
Git LFS Details
|
results/plots/trajectories_per_task.png
ADDED
|
Git LFS Details
|
results/plots/trajectories_per_task_van_td.png
ADDED
|
Git LFS Details
|
results/plots/trajectories_van_td.png
ADDED
|
Git LFS Details
|
results/plots/trajectories_van_td_gap.png
ADDED
|
Git LFS Details
|
tokenizer/modern-greek-17408/README.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Modern Greek Tokenizer, 148480 Vocab
|
| 2 |
+
|
| 3 |
+
This is the canonical modern Greek tokenizer extension for Apertus.
|
| 4 |
+
|
| 5 |
+
Properties:
|
| 6 |
+
|
| 7 |
+
- base model: `swiss-ai/Apertus-8B-2509`;
|
| 8 |
+
- method: merge-rule BPE extension, not `add_tokens`;
|
| 9 |
+
- base vocab preserved: `131072`;
|
| 10 |
+
- added modern Greek tokens: `17408`;
|
| 11 |
+
- total vocab: `148480`;
|
| 12 |
+
- alignment: divisible by `128` and `256`;
|
| 13 |
+
- first 1000 special/reserved ids preserved;
|
| 14 |
+
- `tokenizer.json` SHA-256:
|
| 15 |
+
`358ae3f29ac17c99769d6d437339e28657d5fcaed3486f8550feed3d6adfc394`.
|
| 16 |
+
|
| 17 |
+
Selection evidence is in:
|
| 18 |
+
|
| 19 |
+
```text
|
| 20 |
+
../../provenance/tokenizer-selection/CHOSEN_CUTOFF.md
|
| 21 |
+
```
|
| 22 |
+
|
tokenizer/modern-greek-17408/manifest.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "apertus_greek_modern_only_148480",
|
| 3 |
+
"purpose": "Apertus-compatible modern-Greek-only tokenizer: base 131,072 + C3 modern Greek (+17,408 curated+backfilled) = 148,480 = 256 × 580. Use this for the three-arm Vanilla/ReTok/Distillation init comparison.",
|
| 4 |
+
"vocab_size": 148480,
|
| 5 |
+
"base_apertus_vocab": 131072,
|
| 6 |
+
"added_modern_greek_c3": 17408,
|
| 7 |
+
"added_polytonic_greek": 0,
|
| 8 |
+
"alignment": {
|
| 9 |
+
"128": true,
|
| 10 |
+
"256": true,
|
| 11 |
+
"factor_256": 580
|
| 12 |
+
},
|
| 13 |
+
"first_1000_preserved": true,
|
| 14 |
+
"front_end_contract": {
|
| 15 |
+
"normalizer": null,
|
| 16 |
+
"pre_tokenizer": "Sequence(Split(GPT-2 regex) → ByteLevel)",
|
| 17 |
+
"decoder": "ByteLevel",
|
| 18 |
+
"model_type": "BPE",
|
| 19 |
+
"special_tokens": {
|
| 20 |
+
"unk": 0,
|
| 21 |
+
"bos": 1,
|
| 22 |
+
"eos": 2,
|
| 23 |
+
"pad": 3,
|
| 24 |
+
"reserved_count": 1000
|
| 25 |
+
}
|
| 26 |
+
},
|
| 27 |
+
"loadable_via": "transformers.AutoTokenizer.from_pretrained() → PreTrainedTokenizerFast",
|
| 28 |
+
"sha256": {
|
| 29 |
+
"tokenizer.json": "358ae3f29ac17c99769d6d437339e28657d5fcaed3486f8550feed3d6adfc394",
|
| 30 |
+
"tokenizer_config.json": "ea64a17b41e1deaa7469212f413676129f33977ca3a48767f0ca68dc346df502",
|
| 31 |
+
"special_tokens_map.json": "816ec96e37c6d15e3cbc535dc146c898a7218f209fc154384f31fc1e6ad31ba5"
|
| 32 |
+
}
|
| 33 |
+
}
|
tokenizer/modern-greek-17408/special_tokens_map.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"bos_token": {
|
| 3 |
+
"content": "<s>",
|
| 4 |
+
"lstrip": false,
|
| 5 |
+
"normalized": false,
|
| 6 |
+
"rstrip": false,
|
| 7 |
+
"single_word": false
|
| 8 |
+
},
|
| 9 |
+
"eos_token": {
|
| 10 |
+
"content": "</s>",
|
| 11 |
+
"lstrip": false,
|
| 12 |
+
"normalized": false,
|
| 13 |
+
"rstrip": false,
|
| 14 |
+
"single_word": false
|
| 15 |
+
},
|
| 16 |
+
"pad_token": {
|
| 17 |
+
"content": "<pad>",
|
| 18 |
+
"lstrip": false,
|
| 19 |
+
"normalized": false,
|
| 20 |
+
"rstrip": false,
|
| 21 |
+
"single_word": false
|
| 22 |
+
},
|
| 23 |
+
"unk_token": {
|
| 24 |
+
"content": "<unk>",
|
| 25 |
+
"lstrip": false,
|
| 26 |
+
"normalized": false,
|
| 27 |
+
"rstrip": false,
|
| 28 |
+
"single_word": false
|
| 29 |
+
}
|
| 30 |
+
}
|