tokfit

Source

Count and trim text against OpenAI’s o200k_base token budget, in pure Gleam, on the Erlang and JavaScript runtimes, with no native code.

What it does

tokfit answers one question exactly: how many tokens is this text, and what is the largest prefix of it that fits the budget I was given?

This is a careful port of a known algorithm, not a research result. BPE and the o200k_base pattern belong to OpenAI; the Unicode category data belongs to the Unicode Consortium. The work is in the exactness, the portability, and the trim primitive.

Install

gleam add tokfit

Use

import tokfit

pub fn main() {
  let tokenizer = tokfit.tokenizer()
  tokfit.count(tokenizer, "hello world")
  // -> 2
}

Build the tokenizer once and keep it. Loading the 199,998-entry vocabulary costs seconds and dominates the first call. A fresh one per call pays that every call.

The API

FunctionSignatureWhat you get
tokenizerfn() -> TokenizerThe loaded vocabulary. Build it once.
countfn(Tokenizer, String) -> IntThe exact token count. The empty string is 0.
encodefn(Tokenizer, String) -> List(Int)The exact token ids.
trim_to_budgetfn(Tokenizer, String, Int) -> TrimmedThe longest prefix that fits.
encoding_namefn() -> String"o200k_base".

Trimmed carries the retained text, its exact tokens, its characters in grapheme clusters, and dropped_pieces.

trim_to_budget cuts at pre-token boundaries and never inside one, so its tokens always equals count of its text. The first pre-token that does not fit ends the prefix, so a leading piece larger than the budget yields an empty string, and the result can sit well under budget. Both are deliberate: a prefix whose token count is not the sum of its parts would be worse than no prefix at all.

Special tokens are not recognised. <|endoftext|> tokenizes as ordinary text, matching what OpenAI calls encode_ordinary.

Command line

gleam run -m tokfit/cli -- count --text "hello world"
gleam run -m tokfit/cli -- trim --text "hello world" --budget 1
gleam run -m tokfit/cli -- encode --text "hello world"

Each prints a single line of JSON on stdout. Bad usage prints the usage string and exits 1. The CLI builds one tokenizer per invocation, so a shell loop over documents pays the load each time; call the library from a long-lived process when throughput matters.

What a call costs

Two costs, and they are not the same size. Loading the vocabulary is a one-off of seconds per tokenizer. Tokenizing is a fixed rate per byte on top. The absolute numbers move a lot between machines and between Erlang and Node, so this page does not quote them. tokfit/bench prints the input size and the token count for a known workload; time it and you have both costs for your machine:

time gleam run -m tokfit/bench
time gleam run -m tokfit/cli -- --help

The difference between those two is the load. The rest of the benchmark’s wall clock is tokenizing.

Layout

PathWhat lives there
src/tokfit.gleamThe public API. The only module to import.
src/tokfit/The CLI, the benchmark, and the internals.
test/The corpus differential, the API and CLI suites, and the internals.
scripts/The three generators and the lint and format hooks.

Licence

Apache-2.0.

✨ Search Document