Roadmap / Tokenization

✓

Train a BPE Tokenizer

mediumtokenization

The problem

Training byte-level BPE (byte-pair encoding) means running the two functions of the previous exercise in a loop: count the pairs, merge the most frequent one into a new token, repeat. The output is the list of merges, which the next exercise uses to encode and decode text. (The two functions are given in the starter code, so this exercise does not depend on your earlier solution.)

The loop

  1. Turn text into its bytes with UTF-8 (Unicode Transformation Format, 8-bit): list(text.encode("utf-8")), a list of ints from 0 to 255.
  2. Repeat vocab_size - 256 times:
    • count the adjacent pairs;
    • pick the most frequent pair; on ties, the one that occurs first in the current list;
    • give it the next id (256 in the first round, then 257, ...) and merge it everywhere;
    • record the merge.
  3. Return the merges as a dict mapping (a, b) -> new_id, in the order they were learned.

If at some point no pair is left (the whole text became a single token), stop early.

Example. train_bpe("aaabdaaabac", 259): three merges. "a" is byte 97, "b" 98, "c" 99, "d" 100.

  1. Bytes: [97, 97, 97, 98, 100, 97, 97, 97, 98, 97, 99]. The most frequent pair is (97, 97), 4 times. It becomes 256: [256, 97, 98, 100, 256, 97, 98, 97, 99].
  2. Counts now: (256, 97) 2 times, (97, 98) 2 times, every other pair once. A tie: (256, 97) occurs first in the list, so it wins and becomes 257: [257, 98, 100, 257, 98, 97, 99].
  3. (257, 98) occurs 2 times, more than any other pair. It becomes 258: [258, 100, 258, 97, 99].

The result is {(97, 97): 256, (256, 97): 257, (257, 98): 258}.

What to implement

train_bpe(text, vocab_size): return the merges dict described above.

Requirements

  • vocab_size is the size of the final vocabulary: 256 byte values plus one id per merge. So vocab_size = 256 means no merges at all.
  • Use the tie rule exactly as in the example.

Hint

max(counts, key=counts.get) returns the pair with the largest count, and among equal counts the first one in the dict's order. get_pair_counts lists pairs by first occurrence, so that one line already applies the tie rule.

solution.py
Python idle

Press Run (⌘/Ctrl + Enter) to test your code.