Text Generation
Transformers
Safetensors
qwen3
openeurollm
long-context
256k
multilingual
instruction-tuning
sft
conversational
text-generation-inference
birgermoell commited on
Commit
aa328ef
·
verified ·
1 Parent(s): 5b75cc0

Document LUMI-verified SFT recipe and token mixture

Browse files
Files changed (1) hide show
  1. README.md +76 -39
README.md CHANGED
@@ -11,6 +11,10 @@ tags:
11
  - multilingual
12
  - instruction-tuning
13
  - sft
 
 
 
 
14
  language: [en, sv, de, fr, es, it, nl, pl, pt, cs, fi, da, el, bg, hr, hu, ro, sk, sl, et, lt, lv, ga, mt, eu, gl, is, nb, nn, sr, uk, ca, mk, sq, oc, lb, bs]
15
  ---
16
 
@@ -71,19 +75,29 @@ Long-context inference, especially near 256K, requires multiple GPUs for the KV
71
  | Field | Value |
72
  |---|---|
73
  | Base | `openeurollm/oellm-9b-256k-theta64m-prelude` |
74
- | Method | Full-parameter supervised fine-tuning with packed sequences and FlashAttention 2 |
 
 
 
75
  | Data | 920,552 Tulu-3 rows + 161,644 EuroBlocks rows + a 250,000-row Nemotron-v2 math prefix |
76
  | Loaded examples | 1,332,196 source conversations before tokenization and packing |
77
- | Sequence length | 4,096 |
 
 
78
  | Steps | 3,000 (about 0.604 epoch) |
79
- | Global batch | 128 |
80
- | Optimizer schedule | AdamW, peak LR 6e-6, cosine decay, 3% warmup |
 
81
  | Hardware | 4 LUMI-G nodes, 32 AMD MI250X GCDs |
82
  | Runtime | 14h 36m |
83
- | Final training loss | 0.7671 |
84
- | Final mean token accuracy | 0.7839 |
 
85
 
86
  The published weights are an unquantized BF16 export of the consolidated training checkpoint.
 
 
 
87
 
88
  ## Training-data composition
89
 
@@ -105,6 +119,24 @@ The first two slices form the 1,082,196-row *general* Parquet. Within that Parqu
105
  `tulu3-euroblocks-85-15`. Adding the reasoning slice changes the overall ratio to the one shown
106
  above. These are row shares, not token shares.
107
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  ### Tulu-3 subset: exact source counts
109
 
110
  The run did not load the current public Tulu-3 mixture wholesale. It used a locally staged file
@@ -138,33 +170,15 @@ file. The staging label `commercial` describes the selected artifact; users shou
138
  Tulu collection license and every component's terms. The file has no normalized language column, so
139
  we do not infer exact per-language counts for this slice from prompt text.
140
 
141
- ### EuroBlocks subset: language labels
142
-
143
- All 161,644 rows identify `EuroBlocks-SFT-Synthetic-1124` as their source. Their IDs run from
144
- `EuroBlocks-SFT-Synthetic-1124_1` through `_161644`; this is smaller than the 340,286-row train split
145
- described by the public EuroBlocks card. The staged rows contain the following language labels:
146
-
147
- | Language label | Rows | Language label | Rows |
148
- |---|---:|---|---:|
149
- | Unlabelled | 23,318 | Spanish | 17,428 |
150
- | Italian | 15,963 | French | 14,882 |
151
- | German | 14,081 | Portuguese | 13,966 |
152
- | Hindi | 7,982 | Dutch | 7,683 |
153
- | Swedish | 6,476 | Polish | 5,358 |
154
- | Ukrainian | 5,191 | Japanese | 4,735 |
155
- | Russian | 4,727 | Czech | 4,105 |
156
- | Hungarian | 4,010 | Romanian | 3,993 |
157
- | Korean | 2,905 | Finnish | 1,022 |
158
- | Slovak | 990 | Portuguese (Portugal) | 672 |
159
- | Greek | 582 | Norwegian | 534 |
160
- | Catalan | 223 | Bulgarian | 210 |
161
- | Slovenian | 201 | Estonian | 179 |
162
- | Latvian | 176 | Croatian | 30 |
163
- | Icelandic | 18 | Danish | 4 |
164
-
165
- The 23,318 unlabelled rows are reported as such rather than assigned a language after the fact.
166
- Spot checks found English examples among them, but no language-ID pass was run for this audit.
167
- EuroBlocks is synthetic and its dataset card documents mixed upstream sources and terms.
168
 
169
  ### Reasoning slice: what was actually selected
170
 
@@ -185,8 +199,14 @@ row count is reported here because it is the file actually used by this run.
185
 
186
  - General rows were already stored as `{id, messages}`; reasoning rows were converted to
187
  `{messages}` by appending the `output` as an assistant turn.
188
- - Conversations were rendered with the tokenizer's included chat template and
189
- `<end_of_turn>` EOS, then packed into sequences with a maximum length of 4,096 tokens.
 
 
 
 
 
 
190
  - This stage did **not** train on 256K-token sequences. The architectural 262,144-token setting
191
  comes from the base checkpoint and was evaluated after short-sequence SFT.
192
  - The SFT recipe records no additional post-concatenation deduplication or benchmark-
@@ -195,6 +215,19 @@ row count is reported here because it is the file actually used by this run.
195
  - Only a training split was loaded; no held-out validation split from these sources was used during
196
  optimization.
197
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198
  Training-data terms are not replaced by the model repository's Apache-2.0 weight license. Tulu-3
199
  is an ODC-BY-1.0 collection with component-specific terms; EuroBlocks documents mixed upstream
200
  terms; and Nemotron-v2 documents per-sample licenses plus possible model-output terms. Review those
@@ -421,8 +454,9 @@ Raw reports: [word passphrases, 512-8K](./eval/niah-word-short.json),
421
 
422
  ## Secondary general behavior
423
 
424
- This model received a limited English math-reasoning slice but is not presented as a
425
- reasoning-specialized checkpoint. On a 1,368-example multilingual development suite it scored 23.2%
 
426
  overall, including 63.2% instruction following, 58.6% grounded QA, and 5.9% reasoning/math. A
427
  24-prompt Swedish generation probe had mean language-detection probability 0.96, but manual review
428
  found factual, arithmetic, grammar, and exact-constraint errors. These results are included to prevent
@@ -448,8 +482,11 @@ of both successful and incorrect responses.
448
 
449
  ## Reproduction
450
 
451
- Training and evaluation code: <https://github.com/BirgerMoell/qwen35-posttrain>, especially
452
- `docs/RUNBOOK_oellm9b_256k_posttrain.md`.
 
 
 
453
 
454
  ## License
455
 
 
11
  - multilingual
12
  - instruction-tuning
13
  - sft
14
+ datasets:
15
+ - allenai/tulu-3-sft-mixture
16
+ - utter-project/EuroBlocks-SFT-Synthetic-1124
17
+ - nvidia/Nemotron-Post-Training-Dataset-v2
18
  language: [en, sv, de, fr, es, it, nl, pl, pt, cs, fi, da, el, bg, hr, hu, ro, sk, sl, et, lt, lv, ga, mt, eu, gl, is, nb, nn, sr, uk, ca, mk, sq, oc, lb, bs]
19
  ---
20
 
 
75
  | Field | Value |
76
  |---|---|
77
  | Base | `openeurollm/oellm-9b-256k-theta64m-prelude` |
78
+ | Training library | Hugging Face TRL 0.28.0, using `SFTTrainer` and `SFTConfig` through a text-only wrapper |
79
+ | Method | Full-parameter BF16 supervised fine-tuning; no LoRA or other PEFT adapter |
80
+ | Distributed stack | Accelerate FSDP `FULL_SHARD`, FlashAttention 2, gradient checkpointing |
81
+ | Framework versions | Transformers 5.12.1; PyTorch 2.9.1+ROCm 6.4; Datasets 5.0.0; Tokenizers 0.22.2 |
82
  | Data | 920,552 Tulu-3 rows + 161,644 EuroBlocks rows + a 250,000-row Nemotron-v2 math prefix |
83
  | Loaded examples | 1,332,196 source conversations before tokenization and packing |
84
+ | Tokenized corpus | 2,593,634,710 tokens before training-time sampling |
85
+ | Sequence construction | Maximum length 4,096; best-fit-decreasing packing; 635,974 packed sequences at 99.57% mean fill |
86
+ | Loss | Standard causal NLL over the full rendered conversation; `assistant_only_loss=false` |
87
  | Steps | 3,000 (about 0.604 epoch) |
88
+ | Global batch | 128 packed sequences (32 ranks × batch 1 × gradient accumulation 4) |
89
+ | Optimizer schedule | Fused AdamW, peak LR 6e-6, cosine decay, 3% warmup, weight decay 0, gradient clipping 1.0 |
90
+ | Randomness | Random train sampler, seed 42; no held-out validation split |
91
  | Hardware | 4 LUMI-G nodes, 32 AMD MI250X GCDs |
92
  | Runtime | 14h 36m |
93
+ | Tokens processed | 1,566,026,219 |
94
+ | Training loss | 0.8034 aggregate; 0.7671 in the final 20-step logging window |
95
+ | Final logged mean token accuracy | 0.7839 |
96
 
97
  The published weights are an unquantized BF16 export of the consolidated training checkpoint.
98
+ The framework versions above come from the trainer-generated README stored with the completed
99
+ checkpoint; the remaining values were checked against the submitted YAML, serialized `SFTConfig`,
100
+ Slurm accounting, trainer state, logs, and cached Arrow datasets for LUMI job `20290451`.
101
 
102
  ## Training-data composition
103
 
 
119
  `tulu3-euroblocks-85-15`. Adding the reasoning slice changes the overall ratio to the one shown
120
  above. These are row shares, not token shares.
121
 
122
+ ### Tokenized mixture
123
+
124
+ Row shares substantially understate the contribution of the long Nemotron reasoning traces. The
125
+ exact token counts below were measured from the tokenized Arrow cache produced by the training job,
126
+ before best-fit-decreasing packing and random training-time sampling:
127
+
128
+ | Effective training slice | Rows | Row share | Tokens | Token share | Mean tokens/row |
129
+ |---|---:|---:|---:|---:|---:|
130
+ | Tulu-3 commercial subset | 920,552 | 69.10% | 841,791,947 | 32.46% | 914 |
131
+ | EuroBlocks subset | 161,644 | 12.13% | 81,355,816 | 3.14% | 503 |
132
+ | Nemotron-v2 math prefix | 250,000 | 18.77% | 1,670,486,947 | 64.41% | 6,682 |
133
+ | **Total** | **1,332,196** | **100%** | **2,593,634,710** | **100%** | **1,947** |
134
+
135
+ Packing preserved all 2,593,634,710 tokens in 635,974 sequences. The run sampled 384,000 packed
136
+ sequences over 3,000 optimizer steps and processed 1,566,026,219 tokens, corresponding to 0.6038
137
+ epoch. Because source identities are not retained after cross-example packing, the table describes
138
+ the exact tokenized pool rather than an exact per-source count of tokens drawn by the random sampler.
139
+
140
  ### Tulu-3 subset: exact source counts
141
 
142
  The run did not load the current public Tulu-3 mixture wholesale. It used a locally staged file
 
170
  Tulu collection license and every component's terms. The file has no normalized language column, so
171
  we do not infer exact per-language counts for this slice from prompt text.
172
 
173
+ ### EuroBlocks subset: retained provenance
174
+
175
+ The 161,644 effective rows have synthetic IDs from `EuroBlocks-SFT-Synthetic-1124_1` through
176
+ `_161644`. This is smaller than the 340,286-line EuroBlocks staging file present on LUMI. The final
177
+ training Parquet retains only `{id, messages}` and the source staging JSONL retains only `messages`;
178
+ neither artifact records a normalized language label or the sampling/filtering mapping from the
179
+ 340,286-row source to the 161,644-row effective subset. Exact per-language counts therefore cannot
180
+ be reconstructed from the frozen training artifacts without running a new language-identification
181
+ pass. EuroBlocks is synthetic and its dataset card documents mixed upstream sources and terms.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182
 
183
  ### Reasoning slice: what was actually selected
184
 
 
199
 
200
  - General rows were already stored as `{id, messages}`; reasoning rows were converted to
201
  `{messages}` by appending the `output` as an assistant turn.
202
+ - Conversations were rendered with the tokenizer's included `<start_of_turn>` / `<end_of_turn>`
203
+ chat template, then packed with TRL's best-fit-decreasing strategy into sequences with a maximum
204
+ length of 4,096 tokens.
205
+ - The serialized `SFTConfig` records `assistant_only_loss=false`, `completion_only_loss=null`, and
206
+ NLL loss. For these conversational `messages` rows, training loss therefore covered both user and
207
+ assistant tokens rather than masking to assistant responses only.
208
+ - The 1,332,196 conversations became 1,663,938 sequence segments before/within packing because
209
+ records longer than 4,096 tokens were split. Of the packed rows, 436,108 were exactly 4,096 tokens.
210
  - This stage did **not** train on 256K-token sequences. The architectural 262,144-token setting
211
  comes from the base checkpoint and was evaluated after short-sequence SFT.
212
  - The SFT recipe records no additional post-concatenation deduplication or benchmark-
 
215
  - Only a training split was loaded; no held-out validation split from these sources was used during
216
  optimization.
217
 
218
+ ### Data-quality observations from the frozen run
219
+
220
+ - The Nemotron math slice was selected by prefix, not randomized. It consequently supplied 64.41%
221
+ of the tokenized corpus despite representing only 18.77% of source rows, while EuroBlocks supplied
222
+ 3.14% of tokens.
223
+ - Tulu row `ai2-adapt-dev/tulu_v3.9_aya_100k_21109` tokenized to 3,025,913 tokens. It contains a
224
+ roughly 3.3-million-character Somali dictionary duplicated verbatim as both the user and assistant
225
+ message; packing split this single outlier across hundreds of 4K segments.
226
+ - The Tulu subset includes 236 rows from `ai2-adapt-dev/tulu_hard_coded_repeated_10`, an explicitly
227
+ repeated source component.
228
+ - These observations describe the released checkpoint's actual training input. They were not fixed
229
+ retroactively, because doing so would describe a different run.
230
+
231
  Training-data terms are not replaced by the model repository's Apache-2.0 weight license. Tulu-3
232
  is an ODC-BY-1.0 collection with component-specific terms; EuroBlocks documents mixed upstream
233
  terms; and Nemotron-v2 documents per-sample licenses plus possible model-output terms. Review those
 
454
 
455
  ## Secondary general behavior
456
 
457
+ Although English math-reasoning rows were only 18.77% of examples, their long traces made up 64.41%
458
+ of the tokenized corpus. The resulting checkpoint is nevertheless not presented as a
459
+ reasoning-specialized model. On a 1,368-example multilingual development suite it scored 23.2%
460
  overall, including 63.2% instruction following, 58.6% grounded QA, and 5.9% reasoning/math. A
461
  24-prompt Swedish generation probe had mean language-detection probability 0.96, but manual review
462
  found factual, arithmetic, grammar, and exact-constraint errors. These results are included to prevent
 
482
 
483
  ## Reproduction
484
 
485
+ Training and evaluation code: <https://github.com/BirgerMoell/qwen35-posttrain>. The most relevant
486
+ files are [`scripts/sft_train.py`](https://github.com/BirgerMoell/qwen35-posttrain/blob/main/scripts/sft_train.py),
487
+ [`configs/sft_oellm9b_256k.yaml`](https://github.com/BirgerMoell/qwen35-posttrain/blob/main/configs/sft_oellm9b_256k.yaml),
488
+ [`configs/accelerate_fsdp.yaml`](https://github.com/BirgerMoell/qwen35-posttrain/blob/main/configs/accelerate_fsdp.yaml),
489
+ and [`docs/RUNBOOK_oellm9b_256k_posttrain.md`](https://github.com/BirgerMoell/qwen35-posttrain/blob/main/docs/RUNBOOK_oellm9b_256k_posttrain.md).
490
 
491
  ## License
492