Pythia-410M cosine C4 backbone (24.6B, complete)

Resumable training checkpoints for the C4-only backbone (branch_A) of a code-introduction timing study at 410M scale. This backbone serves two roles in that study: it is the no-code reference arm, and its intermediate snapshots are the fork points from which code-mixing branches are launched.

The backbone is complete: the full 24.6B schedule (step 12513) ran to the end of its cosine decay, and all 14 fork points plus the final checkpoint are published here. Final held-out loss is val_c4 3.0727 / val_code 3.3789.

The run was interrupted twice by compute-allocation cancellations and resumed from latest.pt each time (visible as three [resume] events in the training log, the last at step 10750). Because each checkpoint carries optimizer and RNG state, the resumes are continuations rather than restarts, and the loss curve shows no discontinuity across them.

Note on the wider study. This repo contains the backbone only. The code-mixing branches that fork from these checkpoints are a separate, still-running set of jobs and are not published here. val_code on this backbone is a zero-code-exposure baseline: it was trained on C4 alone, so its Starcoder loss reflects pure transfer, not code training.

What is here

Every file is a full PyTorch checkpoint containing weights + optimizer state + RNG state, so training continues bit-for-bit rather than merely warm-starting:

key contents
model 292 tensors, 405.3M params, fp32
optimizer AdamW state (exp_avg, exp_avg_sq)
completed_steps, global_tokens position in the schedule
config the fully resolved 58-field run config
torch_rng, numpy_rng RNG states, so the data stream continues deterministically
val_c4, val_code held-out loss at that point

That is why each file is 4.86 GB rather than ~1.6 GB weights-only.

Checkpoints

The branch_A_*.pt files are the fork points; the "fork for" column names the branch each was snapshotted for, at that fraction of the 24.6B schedule. latest.pt is the crash-resume file and, now that the schedule has finished, holds the same step as the final checkpoint.

file step tokens fraction fork for
branch_A_3.69B_step1877.pt 1877 3.69B 15% 5.88%@15
branch_A_4.92B_step2503.pt 2503 4.92B 20% 6.25%@20
branch_A_6.15B_step3129.pt 3129 6.15B 25% 6.66%@25
branch_A_7.38B_step3754.pt 3754 7.38B 30% 7.14%@30
branch_A_8.61B_step4380.pt 4380 8.61B 35% 7.69%@35
branch_A_9.84B_step5005.pt 5005 9.84B 40% 8.33%@40
branch_A_11.07B_step5631.pt 5631 11.07B 45% 9.09%@45
branch_A_12.30B_step6257.pt 6257 12.30B 50% 10%@50
branch_A_14.76B_step7508.pt 7508 14.76B 60% 12.5%@60
branch_A_17.22B_step8759.pt 8759 17.22B 70% 16.6%@70
branch_A_19.68B_step10010.pt 10010 19.68B 80% 25%@80
branch_A_22.14B_step11261.pt 11261 22.14B 90% 50%@90
branch_A_23.37B_step11887.pt 11887 23.37B 95% 100%@95
branch_A_24.60B_step12513.pt 12513 24.60B 100% final, fully decayed
latest.pt 12513 24.60B - identical to the final

branch_A_24.60B_step12513.pt is the one to use if you want the finished no-code 410M reference model. The earlier files are mid-schedule states, useful as fork points or for studying the trajectory, but they sit at higher LR and are not annealed.

Also included: dm_branch_A.yaml (run config), resolved_config.json, metrics.jsonl (full eval history), trunk_branchpoint.pt (the 2.4615B warmup-end root that branch_A itself forked from), and code/ (the training scripts needed to resume).

Training setup

architecture Pythia-410M (litgpt pythia-410m), seq len 2048
tokens 24.6B (step 12513), schedule completed
LR schedule cosine, peak 3e-4 to min 3e-5 (a 10%-of-peak floor)
warmup 10% of 24.6B = 2.4615B, linear 0 to peak
batch global 960 sequences, micro 16, so 1,966,080 tokens/step; end_step 12513
optimizer AdamW, betas (0.9, 0.95), wd 0.1, grad clip 1.0
precision bf16 autocast, fp32 master weights
data C4 only (starcoder_weight: 0.0), block order seed 1
parallelism DDP on H200 NVL, varying across resumes (4-GPU, then 2-GPU lanes, then 8-GPU)

World size varied because the run was resumed on different allocations. This is safe and does not affect the data seen: the loader keys block consumption on local_step and global_batch, not on world size, so a run checkpointed at one world size resumes correctly at another.

global_batch 960 rather than 1024 is deliberate: 1024 is not divisible by 3, which makes a 3-GPU DDP lane impossible. Because of it, step counts here are not comparable to 1024-batch runs with the same token budget. Compare by token count.

Validation curve

Held-out loss, 512 packed blocks. val_code is Starcoder, on which this backbone was never trained, so it is a zero-code-exposure baseline and its decline is pure transfer from C4.

step tokens val_c4 val_code
1877 3.69B 3.9448 4.7804
2503 4.92B 3.6992 4.2089
3129 6.15B 3.5561 3.9540
3754 7.38B 3.4554 3.8742
4380 8.61B 3.3768 3.8017
5005 9.84B 3.3205 3.7027
5631 11.07B 3.2726 3.5866
6257 12.30B 3.2363 3.5938
7508 14.76B 3.1766 3.4970
8759 17.22B 3.1358 3.4498
10010 19.68B 3.1058 3.4006
11261 22.14B 3.0844 3.3699
11887 23.37B 3.0776 3.3799
12513 24.60B 3.0727 3.3789

Full history (38 eval points) is in metrics.jsonl.

Using these checkpoints

The backbone schedule is finished, so there is nothing left to resume on branch_A itself. The two useful operations are loading the final model and forking a branch.

Load the final model

import torch
from litgpt.config import Config
from litgpt.model import GPT

ck  = torch.load("branch_A_24.60B_step12513.pt", map_location="cpu", weights_only=False)
cfg = Config.from_name("pythia-410m", block_size=2048)
m   = GPT(cfg); m.load_state_dict(ck["model"]); m.eval()
print(ck["completed_steps"], ck["global_tokens"], ck["val_c4"], ck["val_code"])

Fork a code branch from a mid-schedule point

This is what the snapshots exist for. Point init_from at the fork whose token position you want code to start at, and set the mix:

init_from: branch_A_19.68B_step10010.pt   # code enters at 80% of the schedule
data_mode: continue
starcoder_weight: 0.25                    # W, the code fraction after the fork
mix_start_frac: 0.8                       # must match the fork's fraction
end_frac: 1.0
hf download Impliedhomeland/pythia-410m-cosine-24.6B-c4-backbone --include 'code/*' --local-dir .
torchrun --standalone --nproc_per_node=4 code/train.py --config your_branch.yaml

The LR schedule is keyed to absolute token count, so a branch forked at 19.68B continues the same cosine curve rather than restarting it. train.py also auto-resumes from latest.pt if one is present in ckpt_dir, restoring optimizer and RNG state.

code/launch.sh is included for reference only: it is a thin torchrun wrapper with absolute paths to the original cluster's conda env and repo, so use the torchrun line above instead.

Dependencies: torch, litgpt, numpy, pyyaml (plus datasets/transformers for prepare_data.py).

What is NOT in this repo, and what you must rebuild

The tokenized data pools. The loader replays a deterministic block order over pre-tokenized memmaps, which are far too large to host here:

pool size
c4_train.bin 80.2 GB
code_train.bin 14.0 GB
c4_val.bin, code_val.bin ~30 MB each

Rebuild them with code/prepare_data.py, which pulls C4 and StarcoderData and writes the .bin/.json pair the loader expects.

Exact reproducibility caveat, stated plainly. RNG state is restored, but the data order is reconstructed from c4_base_seed: 1 and code_interleave_seed: 0 over your rebuilt pool. If your tokenization differs at all (tokenizer version, shard order, document filtering), the resumed run consumes different tokens from the original. The optimizer trajectory continues correctly, but the sequence of data is not guaranteed identical across a rebuild. Byte-identical continuation requires the original .bin files, which are not published.

Intended use

A research artifact for continual-pretraining and data-mixing work, and the starting point for the fork-based experiment design it belongs to. It is not instruction-tuned, aligned, or safety-filtered, and it has had no post-training of any kind. Even the fully-decayed 24.6B final is a 410M base model trained on 24.6B tokens, so its generations are correspondingly limited; the earlier snapshots are mid-schedule and weaker still. Inherits the licensing and content characteristics of C4.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Datasets used to train Impliedhomeland/pythia-410m-cosine-24.6B-c4-backbone