Sampled Softmax with Over-Tokenized Transformer
Setup设置
The baseline is the MuonH Qwen3 recipe of the Marin speedrun, which covers 130m to 1.2B parameters. We replace the softmax of the training loss with a sampled softmax and add the input and output vocabularies of the Over-Tokenized Transformer, or OT; each setup is judged by its training speed and by its Paloma loss against backbone compute 6ND, where N counts the parameters of the transformer layers without the embedding and the heads, and D the training tokens. Code
基线是 Marin speedrun 的 MuonH Qwen3 配方,覆盖 130m 到 1.2B 参数。我们把训练损失中的 softmax 换成采样 softmax,并在输入端和输出端加上 Over-Tokenized Transformer 的输入和输出词表,简称 OT;每种做法看训练速度,以及 Paloma 损失随骨干算力 6ND 的变化,其中 N 是 transformer 各层的参数量,不含 embedding 和输出头,D 是训练 token 数。代码
--- baseline loss (simplified)+++ OT + sampled softmax (simplified; the Code link has the real code) def loss_fn(model, tokens): targets = tokens[1:]- x = model.embed(tokens[:-1])+ # OT, input: add the hashed 2-gram and 3-gram embeddings that end at each token+ x = model.embed(tokens[:-1]) + model.ngram_embed(tokens[:-1], n=2) + model.ngram_embed(tokens[:-1], n=3) h = model.norm(model.blocks(x))- logits = h @ model.head.weight.T- return cross_entropy(logits, targets)+ # sampled softmax: score this GPU's targets plus random negatives, P tokens in all+ cand = targets.unique() + random_tokens(P - len(targets.unique()))+ logits = h @ model.head.weight[cand].T+ loss = cross_entropy(logits, position_in(cand, targets))+ # OT, output: a second head predicts the token two positions ahead, at weight 0.1+ loss += 0.1 * cross_entropy(model.head2(h[:-1]), tokens[2:])+ return loss--- 基线损失(简化)+++ OT + 采样 softmax(简化;真实代码见“代码”链接) def loss_fn(model, tokens): targets = tokens[1:]- x = model.embed(tokens[:-1])+ # OT 输入端:加上以每个词结尾的 2-gram 和 3-gram 的 hash embedding+ x = model.embed(tokens[:-1]) + model.ngram_embed(tokens[:-1], n=2) + model.ngram_embed(tokens[:-1], n=3) h = model.norm(model.blocks(x))- logits = h @ model.head.weight.T- return cross_entropy(logits, targets)+ # 采样 softmax:只给本 GPU 的目标词和随机负样本打分,共 P 个词+ cand = targets.unique() + random_tokens(P - len(targets.unique()))+ logits = h @ model.head.weight[cand].T+ loss = cross_entropy(logits, position_in(cand, targets))+ # OT 输出端:第二个头预测往后第二个位置的词,权重 0.1+ loss += 0.1 * cross_entropy(model.head2(h[:-1]), tokens[2:])+ return loss
Experiments实验
The MuonH Qwen3 recipe, unchanged: the softmax scores all 128K tokens.MuonH Qwen3 配方,不做改动:softmax 给全部 128K 个词打分。
Training scores a sample of the vocabulary that grows from 19% to 51%, and the last 7% of steps use the full softmax.训练时只给词表的一部分打分,比例从 19% 增加到 51%,最后 7% 的步数用完整 softmax。
Hashed 2-gram and 3-gram embeddings join each input token, and a second head predicts the token after next.每个输入词加上 2-gram 和 3-gram 的 hash embedding,第二个头预测再往后一个词。
Both changes, with the sampled softmax on both heads.两处改动都用,两个头都用采样 softmax。
OT with each token's loss weighted by how badly the model predicts it, at 130m.在 130m 上给 OT 加 focal loss:模型预测得越差的词,损失权重越大。
The second head scores whole 2-grams, hashed into 12.8M classes with their own embeddings, by a sampled softmax, at 130m.在 130m 上,第二个头直接给整个 2-gram 打分:2-gram hash 到 12.8M 类,各有自己的 embedding,用采样 softmax 训练。
Takeaways核心结论
Acknowledgements致谢
The author is pleased to acknowledge that the work reported on in this post was substantially performed using the Princeton Research Computing resources at Princeton University. Princeton Research Computing is a consortium of groups including the Princeton Institute for Computational Science and Engineering (PICSciE) and Research Computing at Princeton University.
本文报告的工作主要使用普林斯顿大学 Princeton Research Computing 的计算资源完成。Princeton Research Computing 是由普林斯顿计算科学与工程研究所(PICSciE)和普林斯顿大学 Research Computing 等团队组成的联合体。
Citation
@misc{chai2026ssov,
title = {Sampled Softmax with Over-Tokenized Transformer},
author = {Chai, Wenhao},
year = {2026},
howpublished = {Blog post},
url = {https://wenhaochai.com/blogs/sampled-softmax-ov.html}
}