NETBYTE
Start a project

Research

Helix, part 1: training a European language model

We are training our own language model. It is small – 320 million parameters – but it reads all 24 official languages of the European Union, and it trains on graphics cards built for gaming. This first part covers how we got here; the second follows when training is done.

By Marcus Weitschat 8 min read

Dot matrix of what each token in Helix can attend to: a blue band for the local window, amber dots for its own block, scattered orange dots for long-range recall.

Why a games studio trains a language model

NETBYTE builds games, apps and websites. Language models increasingly sit inside such products: as characters that talk back, as help that understands a question, as tools that do something. Most open models are English first; Estonian, Irish or Maltese come as an afterthought. We wanted to understand the whole chain ourselves – data, tokenizer, architecture, training – and find out where the money actually goes.

parameters
320 M
official EU languages
24
training tokens
6.5 B
for the rented GPUs
≈ $12

Helix began as a research prototype. Everything below is a decision that shaped it, each backed by a measurement – and the mistakes that cost us the most time.

Four ideas, one survivor

The prototype went after four known weaknesses of today’s text generators. It writes in blocks of 16 tokens instead of one token at a time, it can run a shared core of layers several times, it predicts a compact “plan” for each block, and it mixes cheap local attention with linear attention for long distances.

Block writing worked straight away: a small test model wrote 64 tokens in 13 passes through the network, where a conventional model needs one pass per token – about a fifth of the work. The other three ideas failed a harder test. We built tasks in which the answer sits far outside the local window, so the model has to look back across the whole text.

Figure 1 Recall across long distances Share of correct answers on a recall task whose evidence lies outside the local window. Small reference model, same budget for every variant.
  1. Local window only 23.1%
  2. + linear attention, plan and loops 23.1%
  3. + 2 exact global heads 49.4%
  4. Full attention (control) 49.0%
Show the data
VariantCorrect
Local window only23.1%
+ linear attention, plan and loops23.1%
+ 2 exact global heads49.4%
Full attention (control)49.0%
Chance (25 %)25.0%

Only exact attention across the distance solved them. Linear attention, plan and loops stayed at chance level; the optimizer had even turned the linear memory down to a half-life of less than one token. Two exact global heads were enough to match full attention.

The final model therefore keeps eight local heads with a 256-token window in every layer and adds two exact global heads in every second layer; the layers in between keep two gated linear-attention heads. Plan and loops are switched off. They are still in the code and tested, but on real text they did not earn their cost.

Figure 2 What each layer looks at Ten attention heads per layer, twelve layers. Every layer has eight local heads; odd layers add two exact global heads, even layers two gated linear-attention heads.
  • Local, 256-token window
  • Exact global attention
  • Gated linear attention
Show the data
Head typeLayersHeads per layer
Local, 256-token window1–128
Exact global attention1, 3, 5, 7, 9, 112
Gated linear attention2, 4, 6, 8, 10, 122

Measure, don’t assume

We tested every training trick on a 94-million-parameter model with the same budget per run: 29.5 million tokens, the same seed, the same data order. Two runs of the same configuration differ by ±0.03, so anything smaller is noise.

Figure 3 What helped – and what was noise Change in validation loss against the AdamW baseline. 94M-parameter model, 29.5 million tokens per run. Below zero is better; the grey band is run-to-run noise (±0.03).
  1. Muon + WSD schedule -0.587
  2. Muon optimizer -0.347
  3. Deeper, thinner network -0.099
  4. WSD schedule -0.080
  5. Value residual -0.007
  6. z-loss +0.029
  7. Grouped-query attention +0.088
Show the data
ChangeΔ loss (nats)
Muon + WSD schedule-0.587
Muon optimizer-0.347
Deeper, thinner network-0.099
WSD schedule-0.080
Value residual-0.007
z-loss+0.029
Grouped-query attention+0.088

The Muon optimizer was the only large lever, and it stacks with a warmup–stable–decay learning-rate schedule. Moving the embedding and the output layer back to AdamW, as the Muon authors recommend, gained another 0.12 and made training 5 % faster. Combinations do not simply add up: a deeper, thinner network helped under AdamW and hurt under Muon. That is why every promising combination got its own run.

24 languages, 6.5 billion tokens

Helix reads web text from FineWeb-Edu for English and FineWeb-2 for the other 23 languages – for the larger ones its quality-filtered top tenth. Code, mathematics and a small synthetic chat stream complete the mix. English gets a third. The other languages are weighted by how much text exists, smoothed so that Irish and Maltese are not drowned out, and no source is repeated more than four times – up to that point repetition is about as good as fresh data.

Figure 4 What Helix reads Share of training tokens per source group. Corpus of 6.5 billion tokens in 34 streams; code and markup covers Python, JavaScript, C, C++, Java, HTML, CSS and Markdown.
  1. 23 other EU languages 51.6%
  2. English 33.0%
  3. Code and markup 10.0%
  4. Mathematics 3.0%
  5. Synthetic chat and tools 2.4%
Show the data
SourceShare
23 other EU languages51.6%
English33.0%
Code and markup10.0%
Mathematics3.0%
Synthetic chat and tools2.4%

The chat stream is extractive: answers are copied from real paragraphs, and tool results are computed rather than invented. It teaches format, not knowledge. The tokenizer is a byte-level BPE with 64,000 entries; it packs between 3.3 and 4 bytes of text into one token for every language in Latin script.

Three bugs worth telling

  • The model that read the answer. In one code path the global heads ignored the causal mask and could see future tokens. Loss fell from 6.85 to 1.71 in 75 steps, and a 16-hour run was worthless. A suspiciously good loss is a bug report; a regression test now guards exactly this.
  • Characters are not bytes. Compression was counted in characters instead of UTF-8 bytes. That invented a “weakness” in Chinese and made Greek and Bulgarian look almost twice as bad as they are.
  • Documents broken at every blank line. The encoder split documents at every empty line – and empty lines sit in the middle of almost every source file. Up to 35 % of the code and maths text was lost. We fixed the separator and rebuilt the whole corpus on 31 October; it took 2 hours and 12 minutes.

From the desk to a rented machine

The first 1.66 billion tokens ran on a single AMD Radeon RX 7800 XT. Two things made that usable: an attention kernel flag that is off by default – without it attention was 12 times slower – and compiling every layer with torch.compile. At a median of 11,800 tokens per second, the rest would have taken almost five more days.

So we wrote an autopilot. It rents GPUs on Vast.ai, uploads code, corpus and checkpoint, trains, brings a checkpoint home every three hours and stops before the credit runs out. On 2 November it went through three machines whose hosts never started them, then settled on two RTX 4070 Ti Super in Germany for $0.363 an hour. The 15.4 GiB upload took 40 minutes.

Figure 5 Training speed Tokens per second for the 320M model at a sequence length of 1,024 (median). Local: one AMD Radeon RX 7800 XT. Rented: two NVIDIA RTX 4070 Ti Super.
  1. Local, before optimisation 8,319
  2. Local, compiled 11,830
  3. Rented, 2 GPUs 41,367
Show the data
SetupTokens/s
Local, before optimisation8,319
Local, compiled11,830
Rented, 2 GPUs41,367

41,400 tokens per second is 3.5 times the desk. The rented part – 4.8 billion tokens in about 33 hours – costs roughly $12.

Where Helix stands today

Figure 6 Training so far Loss in nats per token, lower is better. Held-out: text the model never trains on. Training: averaged per 50 million tokens; it drops faster in the cooldown, partly because the data mix changes. The axis ends at the planned 6.5 billion tokens.
  • Held-out
  • Training

Loss (nats per token)

Billion tokens read

Show the data
Billion tokens readHeld-outTraining
0.064.5714.261
0.553.7763.574
1.043.6943.469
1.543.5963.421
2.033.4263.238
2.523.3293.143
3.013.2913.113
3.503.2633.076
3.993.2253.079
4.493.2443.076
4.983.2183.036
5.353.1232.884

As of 3 November 2026, Helix has read 5.35 of its 6.5 billion tokens. Since 5.2 billion it is in the cooldown: the learning rate falls and the mix shifts towards maths, code and chat. On held-out text from all streams it is at 3.12 nats per token.

Figure 7 Where each language stands Bits per byte on held-out text after 5.35 billion tokens, lower is better. Greek and Bulgarian look better partly because their letters take two bytes each.
  1. Greek 0.721
  2. Bulgarian 0.844
  3. French 1.065
  4. English 1.086
  5. Spanish 1.135
  6. Portuguese 1.219
  7. German 1.257
  8. Dutch 1.268
  9. Italian 1.277
  10. Polish 1.355
  11. Danish 1.364
  12. Hungarian 1.407
  13. Slovak 1.412
  14. Maltese 1.415
  15. Romanian 1.416
  16. Swedish 1.418
  17. Irish 1.422
  18. Slovenian 1.431
  19. Czech 1.444
  20. Lithuanian 1.450
  21. Latvian 1.451
  22. Croatian 1.507
  23. Finnish 1.508
  24. Estonian 1.727
Show the data
LanguageBits per byte
Greek0.721
Bulgarian0.844
French1.065
English1.086
Spanish1.135
Portuguese1.219
German1.257
Dutch1.268
Italian1.277
Polish1.355
Danish1.364
Hungarian1.407
Slovak1.412
Maltese1.415
Romanian1.416
Swedish1.418
Irish1.422
Slovenian1.431
Czech1.444
Lithuanian1.450
Latvian1.451
Croatian1.507
Finnish1.508
Estonian1.727

What that means in practice shows best in an unedited sample from a checkpoint at about 4.9 billion tokens. The beginning is ours, the rest is Helix:

Sample in English, checkpoint at 4.9 billion tokens, unedited

Prompt: The history of the printing press begins in the fifteenth century, when Johannes Gutenberg introduced movable type to Europe. Before that, books Model output: for printing were usually in the form of texts, usually in the format of illustrations. In its introduction to the printing press, Gutenberg uses one line-of-action model to illustrate a series of printed pieces of a book.

Grammar, word choice and topic hold; the facts do not. That is roughly what to expect from 320 million parameters and 6.5 billion tokens: a fluent model that invents things.

What comes next

Pretraining ends in a few hours. After that come a long-context stage with books from Project Gutenberg and EU legal texts from EUR-Lex, fine-tuning for conversation and tool use, and a small draft model that speeds up generation.

Back to all posts

Next step

What should exist next?

Tell us about your game, app, website or AI project. A short message is enough to get started.