Greedy Longest-Match Tokenizer for an LLM Data Pipeline
xAIMachine Learning Engineer · OnsiteLast updated
This question evaluates understanding of string-processing and greedy maximal-munch tokenization, as well as competency in designing efficient prefix-matching data structures and handling large-scale text preprocessing for LLM pipelines.
You are building a text pre-processing step for a large-language-model training pipeline. Before raw text can be fed into the model, it must be split into tokens drawn from a fixed vocabulary. Your job is to implement the tokenizer.
You are given:
vocab: a list of distinct, non-empty token strings (the vocabulary).text: the input string to tokenize.
Tokenize text using greedy longest-match (maximal munch), scanning left to right:
- At the current position
i, find the longest token invocabthat is a prefix oftext[i:]. - If such a token exists, emit it and advance
iby its length. - If no vocabulary token matches at position
i, emit the single charactertext[i]as its own fallback token and advanceiby 1. - Repeat until the entire string is consumed.
Return the resulting list of tokens, in order.
Note that the algorithm is strictly greedy and never backtracks: it always takes the longest match at the current position, even if a shorter match would allow more of the remaining string to be covered by vocabulary tokens later.
Example 1
vocab = ["low", "lower", "new", "est", "wid", "er"]
text = "lowernewestwidget"
Output: ["lower", "new", "est", "wid", "g", "e", "t"]
At position 0 both "low" and "lower" match; the longer "lower" is chosen. After "wid", the remaining text is "get": no vocabulary token is a prefix of "get", "et", or "t", so each character is emitted as a fallback token.
Example 2
vocab = ["ab", "abc", "cd"]
text = "abcd"
Output: ["abc", "d"]
Greedy longest-match takes "abc" at position 0, leaving "d" unmatched — even though the alternative segmentation ["ab", "cd"] would have covered the whole string with vocabulary tokens. The tokenizer must not backtrack.
Example 3
vocab = ["hello"]
text = ""
Output: []
Constraints
0 <= len(text) <= 10^61 <= len(vocab) <= 10^51 <= len(vocab[i]) <= 100; the sum of all token lengths does not exceed10^6- All vocabulary tokens are distinct
textand all tokens consist of printable ASCII characters (no whitespace inside vocabulary tokens is guaranteed only if the input provides none; treat characters generically)
Your solution should be efficient enough to handle the largest inputs: a scan that re-checks the whole vocabulary at every position is too slow. Aim for a data structure that lets you find the longest matching token starting at a given position in time proportional to the match length, such that the total running time is roughly O(len(text) * L + total vocabulary size), where L is the maximum token length.
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.