A GPU wants to chew through fat, uniform batches with nothing wasted. This is how clean text becomes exactly that — pre-tokenized once, stitched into one stream with document markers, and packed into fixed-length blocks with zero padding.
Earlier we turned text into integer token IDs. That lookup is cheap per document — but running it live, mid-training, would leave the GPUs waiting on the CPU. So the whole corpus is tokenized once, up front, and only the integers are saved.
Millions of documents arrive in wildly different lengths. Instead of training on each one alone, they're shuffled and joined head-to-tail into a single long stream of token IDs, with a special end-of-sequence marker between them.
<eos> marks each boundary. A reserved token — one dedicated dictionary entry — sits between documents so the model can tell where one ends and learns to stop.<pad>, <bos>, and the chat-role markers you'll meet later.Training wants uniform rectangles — every example the same length so they stack into one GPU batch. So the stream is sliced into equal blocks of L tokens. Because it's one continuous stream, every block comes out completely full.
L. Cut the stream every L tokens (in practice 2,048–8,192). Every block is exactly full..bin + .idx. The IDs are one flat binary file; a tiny index records where each block starts, so any block loads instantly without scanning the rest.<eos> — that's fine; the marker inside teaches the model where one document ends and the next begins.Every block is now a full row of L token IDs — but the model still has no idea which token came first. Next, rotary position embeddings (RoPE): the math that tells attention where each token sits in the block.