PROMETHEUS OS
NATIVE AI OPERATING SYSTEM
[INIT] Prometheus OS loading...
[CORE] Neural interface initializing...
[AI] LLM router connecting...
[MEM] Memory graph loading...
[AGT] Agent chains on standby...
[SEC] Security protocols active...
[NET] Provider mesh established...
[UI] Workspace rendering...
[DONE] All systems nominal.
Welcome to PROMETHEUS OS.
READY · OFFLINE · SECURE · PRIVATE
🎨 THEME ENGINE
PROMETHEUS OS · 23 THEMES
Trial version: Dark + Light themes only.
Full theme access with PROMETHEUS OS license.
Dark theme active
Experience all 23 themes in PROMETHEUS OS

Pretraining and Data: How a Base Model Is Made

Advanced 19 min· 4 exercises

Explain the next-token pretraining objective, how tokenizers and web-scale datasets are built, and how training is parallelised, estimated with C ≈ 6ND, and kept stable.

By the end of this lesson you will be able to
  • Derive the next-token cross-entropy loss and convert it to perplexity and bits per byte.
  • Implement byte-pair encoding training on a toy corpus and explain vocabulary-size trade-offs.
  • Describe a production web-data pipeline: extraction, language ID, quality filtering, MinHash deduplication, toxicity and PII handling, mixtures and decontamination.
  • Compare data, tensor, pipeline and ZeRO/FSDP parallelism and choose a combination for a given model size.
  • Estimate training compute, GPU-hours and cost with C ≈ 6ND and a stated MFU.
  • Recognise common training instabilities and the checkpointing practices that recover from them.

Before this: Transformers: A Deep Dive, Information Theory and Loss Functions, Training Deep Networks in Practice

Every capability you see in a modern chat model starts with pretraining: months of next-token prediction over trillions of tokens of text and code. Pretraining is where almost all of the compute budget goes and where the model acquires its vocabulary, world knowledge, coding ability and the raw material for reasoning. If you understand the objective, the data pipeline and the arithmetic of training at scale, you can read a model's technical report critically, estimate what a training run costs, and make sensible decisions when you continue-pretrain or fine-tune a model yourself.

Intuition: compressing a library by predicting the next word

Imagine being handed a library of a few billion web pages, books and code repositories and told to write the shortest possible encoding of all of it. The best way to compress text is to predict it well: if you can guess the next character with high confidence, you need very few bits to encode what actually comes next. A language model is a learned predictor of this kind. To predict the next token of a Python file it has to "know" syntax; to predict the next token of a chemistry paper it has to absorb some chemistry; to predict the end of a proof it has to follow the argument. Nobody labels any of this. The supervision is the text itself, which is why the method is called self-supervised learning and why it scales to the whole web.

This picture also explains why data quality matters so much. A predictor trained on spam, boilerplate and duplicated pages spends capacity memorising junk. A predictor trained on carefully filtered, diverse, educational text learns more per token.

The pretraining objective

A tokenizer turns text into a sequence of integer token ids x1,x2,…,xTx_1, x_2, \dots, x_T drawn from a vocabulary VV. A causal (decoder-only) transformer with parameters θ\theta outputs, at each position tt, a probability distribution pθ(⋅∣x<t)p_\theta(\cdot \mid x_{<t}) over the next token. Training minimises the average negative log-likelihood, which is the cross-entropy between the one-hot "true next token" and the model's distribution:

L(θ)=−1T∑t=1Tlog⁡pθ(xt∣x<t)\mathcal{L}(\theta) = -\frac{1}{T}\sum_{t=1}^{T} \log p_\theta(x_t \mid x_{<t})

Here TT is the number of predicted positions in the batch, and x<tx_{<t} means all tokens before position tt. The model produces a vector of logits z∈R∣V∣z \in \mathbb{R}^{|V|} and the probability of token kk is the softmax pk=ezk/∑jezjp_k = e^{z_k} / \sum_j e^{z_j}. Two derived quantities show up everywhere:

  • Perplexity =eL= e^{\mathcal{L}} (with natural logs): the effective number of tokens the model is choosing between. A loss of 2.0 nats/token is a perplexity of about 7.4.
  • Bits per byte: loss converted to bits (÷ln⁡2\div \ln 2) and normalised by the number of UTF-8 bytes rather than tokens. Because it does not depend on the tokenizer, it is the fair way to compare models with different vocabularies.

All positions in a sequence are trained in parallel thanks to the causal attention mask, so one forward pass over a 4,096-token sequence gives 4,095 training signals. Documents are usually packed: concatenated with an end-of-document token and cut into fixed-length windows so no compute is wasted on padding.

Worked example: one position's loss

Suppose the vocabulary has four tokens and at some position the logits are z=(2.0,1.0,0.1,−1.0)z = (2.0, 1.0, 0.1, -1.0), with the true next token being index 0.

  1. Exponentiate: e2.0=7.389e^{2.0} = 7.389, e1.0=2.718e^{1.0} = 2.718, e0.1=1.105e^{0.1} = 1.105, e−1.0=0.368e^{-1.0} = 0.368.
  2. Sum: 7.389+2.718+1.105+0.368=11.5807.389 + 2.718 + 1.105 + 0.368 = 11.580.
  3. Probability of the true token: 7.389/11.580=0.6387.389 / 11.580 = 0.638.
  4. Loss: −ln⁡0.638=0.449-\ln 0.638 = 0.449 nats.

If the true token had been index 3, the loss would be −ln⁡(0.368/11.580)=−ln⁡0.0318=3.45-\ln(0.368/11.580) = -\ln 0.0318 = 3.45 nats. Confident wrong predictions are punished hard, which is exactly the pressure that forces the model to learn.

Tokenizer training with BPE

Before pretraining you must train a tokenizer, and it is frozen for the life of the model. Most LLMs use byte-pair encoding (BPE), introduced for neural machine translation by Sennrich, Haddow and Birch (2016), or a close relative (WordPiece, Unigram via SentencePiece). Byte-level BPE, popularised by GPT-2, starts from the 256 possible bytes so that any string can be encoded and nothing is ever "unknown".

The BPE training algorithm:

  1. Split the training corpus into words (a regex pre-tokenizer separates spaces, punctuation and digits) and represent each word as a sequence of bytes.
  2. Count every adjacent pair of symbols across the corpus, weighted by word frequency.
  3. Merge the most frequent pair into a new symbol and record the merge rule.
  4. Repeat until the vocabulary reaches the target size (commonly 32k to 256k tokens).

At encoding time the merges are applied in the order they were learned. The resulting vocabulary size is a real trade-off: a larger vocabulary shortens sequences (cheaper attention, more text per context window) but enlarges the embedding and output matrices and leaves rare tokens under-trained. Tokenizers trained mostly on English also spend more tokens per word on other languages, which raises cost and reduces effective context for those users. Digits are often split into single characters or groups of up to three, because inconsistent number tokenization measurably hurts arithmetic.

from collections import Counter

def train_bpe(words, num_merges):
    # words: dict mapping a word (tuple of symbols) to its corpus count
    vocab = dict(words)
    merges = []
    for _ in range(num_merges):
        pairs = Counter()
        for word, freq in vocab.items():
            for a, b in zip(word, word[1:]):
                pairs[(a, b)] += freq
        if not pairs:
            break
        best = max(pairs, key=pairs.get)
        merges.append(best)
        new_vocab = {}
        for word, freq in vocab.items():
            out, i = [], 0
            while i < len(word):
                if i < len(word) - 1 and (word[i], word[i + 1]) == best:
                    out.append(word[i] + word[i + 1]); i += 2
                else:
                    out.append(word[i]); i += 1
            new_vocab[tuple(out)] = new_vocab.get(tuple(out), 0) + freq
        vocab = new_vocab
    return merges, vocab

corpus = {tuple("low"): 5, tuple("lower"): 2, tuple("newest"): 6, tuple("widest"): 3}
merges, vocab = train_bpe(corpus, 4)
print(merges)  # [('e','s'), ('es','t'), ('l','o'), ('lo','w')]

This toy works on characters; production tokenizers (for example the Hugging Face tokenizers library) do the same thing on bytes, in Rust, over hundreds of gigabytes.

Data sources and the pipeline

Where the tokens come from

  • Web crawl. The backbone of nearly every open pretraining corpus is Common Crawl, a US 501(c)(3) nonprofit founded in 2007 that has collected web data since 2008. Its archive runs to petabytes, a single crawl typically covers billions of pages, and new crawls are released regularly. Raw crawl is mostly unusable: navigation menus, spam, near-duplicates, machine-generated pages and many languages mixed together.
  • Curated text: books, encyclopedias, academic papers, patents, legal and government documents, forums and Q&A sites.
  • Code: public repositories, deduplicated and license-filtered, plus issues, notebooks and documentation.
  • Math and science: arXiv-style papers and math web pages extracted with their LaTeX intact. DeepSeekMath (Shao et al., 2024), for example, mined about 120 billion math tokens from Common Crawl with an iteratively trained classifier.
  • Synthetic data: text generated by other models, increasingly used for reasoning and instruction-like content (covered in the distillation lesson).

A reference pipeline: FineWeb

The best documented open example is FineWeb (Penedo et al., NeurIPS 2024 Datasets and Benchmarks), a 15-trillion-token English corpus built from 96 Common Crawl snapshots and released under the ODC-By 1.0 license. Its steps are a good template:

  1. Text extraction from the raw WARC HTML with the trafilatura library rather than using Common Crawl's pre-extracted WET text, which kept more menus and boilerplate.
  2. URL filtering against a blocklist of adult domains.
  3. Language identification with a fastText classifier, keeping English with score at least 0.65.
  4. Quality heuristics: the MassiveText repetition and quality rules (from the Gopher work), most of the C4 heuristics, and some custom line-level rules (for example, dropping documents where too many lines are very short or duplicated).
  5. Deduplication with MinHash on word 5-grams, applied within each snapshot. Interestingly, the authors found that deduplicating globally across all snapshots gave worse downstream results than per-snapshot deduplication, because it disproportionately kept lower-quality leftovers from older crawls.
  6. PII handling: email addresses and public IP addresses are anonymised.

A companion set, FineWeb-Edu (1.3 trillion tokens), adds a model-based quality filter: Llama-3-70B-Instruct rated several hundred thousand pages for educational value on a 0 to 5 scale, a small regression head on top of a text-embedding model was trained on those ratings, and only pages scoring 3 or more were kept. Models trained on it improve markedly on knowledge and reasoning benchmarks for the same token budget. This "LLM-as-annotator, small classifier at scale" pattern is now standard.

Deduplication in more detail

Exact deduplication (hashing whole documents or long substrings) is cheap but misses near-duplicates such as the same article with different ads. MinHash LSH estimates the Jaccard similarity of two documents' shingle sets: for each of kk random hash functions, keep the minimum hash value over the document's shingles; the probability that two documents share a minimum equals their Jaccard similarity. Grouping hashes into bands and flagging documents that collide in any band finds candidate duplicates in near-linear time. Duplicates matter because they waste compute, skew the data mixture toward whatever is copied most, and increase verbatim memorisation (a privacy and copyright risk).

Toxicity and safety filtering

Teams remove or down-weight hateful, sexual and violent content with blocklists and classifiers, and remove known personal data. Filtering is a trade-off: aggressive toxicity classifiers disproportionately remove dialects and minority-group discussions, and a model that has never seen toxic text can be worse at recognising it. Many teams therefore filter the worst content, keep some borderline material, and rely on post-training for behaviour.

Data mixtures and annealing

The final corpus is a weighted mixture of sources, for example a large share of filtered web, plus code, math, books, multilingual text and reference material. Weights are set with small proxy-model ablations: train 1B-parameter models for a few billion tokens on candidate mixtures and compare benchmark scores. High-quality sources are often upsampled (seen two to four times) while web text is seen about once. Many recent recipes end with an annealing phase: as the learning rate decays to zero, the mixture shifts toward the highest-quality math, code and curated data, which gives a disproportionate boost for the tokens spent. Benchmark test sets must be decontaminated out of the corpus by n-gram matching, or later evaluations become meaningless.

Training at scale

A model with tens of billions of parameters does not fit on one accelerator once you add optimizer state. With mixed precision and Adam, each parameter typically costs about 16 bytes of training state: 2 bytes for BF16 weights, 2 for BF16 gradients, and 12 for the FP32 master weights and the two Adam moments. A 70B model therefore needs roughly 70×109×16≈1.170\times10^9 \times 16 \approx 1.1 TB before counting activations. Four parallelism strategies, usually combined (so-called 3D or 4D parallelism), solve this:

StrategyWhat is splitCommunicationTypical scope
Data parallel (DP)The batch; every GPU has a full model copyAll-reduce gradients each stepAcross nodes
ZeRO / FSDPOptimizer state, gradients and parameters sharded across DP ranksAll-gather params before use, reduce-scatter gradsAcross nodes
Tensor parallel (TP)Individual weight matrices (Megatron-LM style column/row splits)All-reduce inside every layerWithin a node (NVLink)
Pipeline parallel (PP)Groups of layers on different devices; micro-batches flow through (GPipe)Point-to-point activations between stagesAcross nodes
Sequence/context parallelThe sequence dimension for long contextsExchange of attention keys/valuesLong-context runs

ZeRO (Rajbhandari et al., 2019) observed that plain data parallelism stores redundant copies of the optimizer state on every GPU. Stage 1 shards optimizer state, stage 2 also shards gradients, stage 3 also shards parameters. PyTorch's Fully Sharded Data Parallel (FSDP) implements the stage-3 idea natively. Tensor parallelism is bandwidth-hungry, so it stays inside a node; pipeline parallelism introduces "bubbles" of idle time that micro-batching reduces. The headline efficiency metric is model FLOPs utilisation (MFU): achieved useful FLOPs divided by the hardware's peak. Well-tuned dense runs often reach roughly 35 to 50 percent.

The compute estimate C≈6NDC \approx 6ND

For a dense transformer with NN parameters trained on DD tokens, total training compute is approximately

C≈6ND FLOPsC \approx 6ND \ \text{FLOPs}

The 6 comes from about 2N2N FLOPs per token for the forward pass (one multiply and one add per weight) and about 4N4N for the backward pass (gradients with respect to both activations and weights). The approximation ignores the attention-score computation, which grows with context length and is modest at typical lengths. Kaplan et al. (2020) wrote it as C≈6NBSC \approx 6NBS with batch size BB and steps SS, so D=BSD = BS. Sanity check with published numbers: Chinchilla had N=70×109N = 70\times10^9 and D=1.4×1012D = 1.4\times10^{12}, so 6ND=5.88×10236ND = 5.88\times10^{23} FLOPs, within about 2 percent of the 5.76×10235.76\times10^{23} reported by Hoffmann et al. (2022).

Worked example: what does a 7B model on 2T tokens cost?

Assumptions (state yours explicitly when you do this for real): dense 7B model, 2 trillion tokens, H100 GPUs with about 989 TFLOP/s dense BF16 peak, 40 percent MFU, and an illustrative rental price of 2 US dollars per GPU-hour.

  1. Compute: C=6×7×109×2×1012=8.4×1022C = 6 \times 7\times10^9 \times 2\times10^{12} = 8.4\times10^{22} FLOPs.
  2. Effective throughput per GPU: 0.40×989×1012=3.956×10140.40 \times 989\times10^{12} = 3.956\times10^{14} FLOP/s.
  3. GPU-seconds: 8.4×1022/3.956×1014=2.12×1088.4\times10^{22} / 3.956\times10^{14} = 2.12\times10^{8} s.
  4. GPU-hours: 2.12×108/3600≈59,0002.12\times10^{8} / 3600 \approx 59{,}000.
  5. Wall clock on 1,024 GPUs: 59,000/1,024≈57.659{,}000 / 1{,}024 \approx 57.6 hours, about 2.4 days.
  6. Cost: about 59,000 GPU-hours at 2 US dollars each, roughly 118,000 US dollars for the final run.

The final run is only part of the bill. Data processing, tokenizer and mixture ablations, failed runs, evaluation and the people involved routinely multiply it several times. Frontier runs use roughly two to four orders of magnitude more compute.

Training instabilities and checkpoints

Large runs fail in recognisable ways:

  • Loss spikes and divergence. The loss jumps suddenly and may never recover. Causes include bad data batches, too high a learning rate, and attention logits growing without bound. Mitigations: learning-rate warm-up then cosine or warmup-stable-decay schedules, gradient-norm clipping (commonly at 1.0), AdamW with tuned β2\beta_2 and ϵ\epsilon, QK-normalisation of attention, an auxiliary z-loss that keeps the softmax normaliser near 1, and keeping sensitive operations such as softmax and normalisation in FP32. The PaLM team reported handling spikes by restarting from a checkpoint shortly before the spike and skipping the data batches around it.
  • Hardware failures. On thousands of GPUs, a node failure every few hours is normal. Runs need automatic detection, elastic restart, and frequent checkpoints of model weights, optimizer state, the data-loader position and random-number-generator state. Without the optimizer state and data position you cannot resume the same run exactly.
  • Silent data corruption. Faulty chips occasionally produce wrong numbers without crashing; teams watch for anomalous gradient norms per rank.

Checkpoints also serve science: intermediate checkpoints let you measure learning dynamics and serve as starting points for continued pretraining.

Common pitfalls

  • Comparing perplexity across tokenizers. Per-token loss is not comparable between vocabularies; use bits per byte or downstream tasks.
  • Benchmark contamination. Test questions leak into crawls; decontaminate before training and report how.
  • Over-deduplicating or over-filtering. Very aggressive filters can leave too few tokens, remove whole dialects, or skew topics.
  • Forgetting the optimizer in memory estimates. Weights alone are about one eighth of training memory with Adam in mixed precision.
  • Treating 6ND6ND as exact. It ignores attention FLOPs, recomputation for activation checkpointing (which adds roughly another forward pass), and MFU losses.
  • Changing the tokenizer after training. Adding tokens requires new embeddings that start untrained; plan the vocabulary up front.
  • Saving only weights. You cannot resume a run faithfully without optimizer state and data-loader position.

In practice

Very few organisations pretrain frontier models; many more do continued pretraining on domain data (legal, biomedical, a new language) or train small models from scratch for edge deployment. The workflow is the same at any scale: build and inspect the data pipeline first, run small proxy models to choose the mixture, estimate compute with 6ND6ND and a realistic MFU, use a mature training framework (Megatron-LM, DeepSpeed, PyTorch FSDP, or higher-level wrappers) rather than writing parallelism yourself, checkpoint often, and monitor loss, gradient norm and per-domain validation loss continuously. For learning, the Hugging Face datasets library can stream FineWeb samples, and small GPT-style training scripts reproduce the whole loop on a single GPU in hours. Record data provenance and licenses as you go: downstream users and regulators increasingly ask what a model was trained on.

Key takeaways

  • Pretraining minimises next-token cross-entropy over trillions of tokens; the text itself is the label.
  • The tokenizer is trained before the model and frozen; its vocabulary size trades sequence length against embedding cost and multilingual fairness.
  • Data quality work (extraction, filtering, deduplication, model-based quality classifiers, decontamination) is as important as architecture.
  • Training a large model combines data, tensor and pipeline parallelism with ZeRO/FSDP sharding because Adam training state costs about 16 bytes per parameter.
  • Training compute is about 6ND FLOPs; divide by peak FLOP/s times MFU to get GPU-seconds.
  • Runs fail through loss spikes and hardware faults, so full checkpoints (weights, optimizer, data position) are mandatory.

Terms in this lesson

Self-supervised learning
Training where the targets are derived from the input data itself, such as predicting the next token of a text.
Perplexity
The exponential of the average per-token cross-entropy, interpretable as the effective number of equally likely next-token choices.
Bits per byte
Cross-entropy expressed in bits and normalised by the number of UTF-8 bytes, which makes losses comparable across tokenizers.
Byte-pair encoding (BPE)
A tokenizer-training algorithm that repeatedly merges the most frequent adjacent symbol pair into a new vocabulary item.
MinHash deduplication
A locality-sensitive hashing method that estimates Jaccard similarity between documents' shingle sets to find near-duplicates at scale.
Data mixture
The weighted combination of data sources (web, code, math, books and so on) from which pretraining batches are drawn.
Decontamination
Removing benchmark test items from training data, usually by n-gram overlap, so evaluations measure generalisation rather than memorisation.
ZeRO / FSDP
Data-parallel training that shards optimizer state, gradients and optionally parameters across workers instead of replicating them.
Model FLOPs utilisation (MFU)
The fraction of the hardware's peak floating-point throughput that is spent on the model's useful training FLOPs.

Check your understanding

  1. 1.

    At one position a model assigns probability 0.25 to the correct next token. What is the cross-entropy loss at that position in nats?

  2. 2.

    Why is bits per byte preferred over per-token perplexity when comparing two models with different tokenizers?

  3. 3.

    A team must train a 30B dense model on 2T tokens. Roughly how many training FLOPs is that?

  4. 4.

    Which parallelism strategy is normally kept inside a single node because it needs an all-reduce inside every layer?

  5. 5.

    In the FineWeb ablations, what did the authors find about deduplicating across all 96 snapshots at once versus within each snapshot?

Exercises

Work each problem before opening the solution.

  1. Exercise 1Core

    A model's average validation loss is 2.30 nats per token, and on this validation set there are on average 4.2 bytes per token. Compute (a) the perplexity and (b) the bits per byte.

    Show solution

    (a) Perplexity = e^2.30 ≈ 9.97, so about 10.

    (b) Convert nats to bits: 2.30 / ln 2 = 2.30 / 0.6931 ≈ 3.318 bits per token. Divide by bytes per token: 3.318 / 4.2 ≈ 0.790 bits per byte.

  2. Exercise 2Core

    Estimate the training memory for full fine-tuning of a 13B-parameter model with AdamW in mixed precision (BF16 weights and gradients, FP32 master weights and two FP32 Adam moments), ignoring activations. How many 80 GB GPUs are needed at minimum if you use ZeRO stage 3 / FSDP to shard everything evenly?

    Show solution

    Bytes per parameter: 2 (BF16 weights) + 2 (BF16 grads) + 4 (FP32 master) + 4 + 4 (Adam m and v) = 16 bytes.

    Total: 13e9 × 16 = 208e9 bytes ≈ 208 GB.

    With perfect sharding across GPUs of 80 GB: 208 / 80 = 2.6, so at least 3 GPUs, and in practice 4 or more to leave room for activations, temporary all-gathered layers and fragmentation.

  3. Exercise 3Core

    Write a Python function minhash_signature(text, num_hashes=64, n=5) that returns a MinHash signature over word n-gram shingles, and a function estimate_jaccard(sig_a, sig_b). Test it on two near-duplicate sentences and one unrelated sentence.

    Show solution
    import hashlib
    
    def shingles(text, n=5):
        words = text.lower().split()
        return {" ".join(words[i:i + n]) for i in range(max(1, len(words) - n + 1))}
    
    def _h(seed, s):
        d = hashlib.blake2b(f"{seed}:{s}".encode(), digest_size=8).digest()
        return int.from_bytes(d, "big")
    
    def minhash_signature(text, num_hashes=64, n=5):
        sh = shingles(text, n)
        return [min(_h(seed, s) for s in sh) for seed in range(num_hashes)]
    
    def estimate_jaccard(a, b):
        return sum(x == y for x, y in zip(a, b)) / len(a)
    
    a = "the quick brown fox jumps over the lazy dog near the old river bank today"
    b = "the quick brown fox jumps over the lazy dog near the old river bank tonight"
    c = "stock markets closed higher on friday after a volatile week of trading news"
    sa, sb, sc = (minhash_signature(t, 128, 3) for t in (a, b, c))
    print(round(estimate_jaccard(sa, sb), 2))  # high, near the true value 12/14 ≈ 0.86
    print(round(estimate_jaccard(sa, sc), 2))  # near 0
    

    Each seed defines a different hash function; the probability that two sets share the minimum hash equals their Jaccard similarity, so the fraction of matching signature positions is an unbiased estimate. With 3-word shingles, sentences a and b each have 13 shingles; they differ only in the last word, so they share 12 and the union has 14, giving a true Jaccard similarity of 12/14 ≈ 0.86. The estimate this code prints (0.84; the hashes are deterministic, so it is the same every run) is close, with sampling noise of a few hundredths that shrinks as you add hash functions. The unrelated sentence shares no shingles, so its estimate is 0.

  4. Exercise 4Challenge

    You have a budget of 1,000,000 US dollars of H100 time at 2.50 dollars per GPU-hour, peak 989 TFLOP/s dense BF16, and you expect 38% MFU. (a) How many training FLOPs can you afford? (b) If you train an 8B dense model, how many tokens can you process? (c) Reserve 30% of the budget for ablations and failures and recompute (b).

    Show solution

    (a) GPU-hours = 1,000,000 / 2.50 = 400,000. Effective FLOP/s per GPU = 0.38 × 989e12 = 3.758e14. FLOPs = 400,000 × 3600 × 3.758e14 = 1.441e9 s × 3.758e14 ≈ 5.41e23 FLOPs.

    (b) D = C / (6N) = 5.41e23 / (6 × 8e9) = 5.41e23 / 4.8e10 ≈ 1.13e13, about 11.3 trillion tokens.

    (c) With 70% of the budget: C ≈ 3.79e23, D ≈ 3.79e23 / 4.8e10 ≈ 7.9e12, about 7.9 trillion tokens. Note this is far beyond the Chinchilla-optimal ~160B tokens for 8B parameters, which is deliberate if you care about inference cost (see the scaling-laws lesson).

Further reading

Go further

Sources

Fact-checked and last reviewed 2026-11-05

Stay in the loop
Prometheus OS™ · Native AI OS · Built for the future © 2025 - 2026