OpenJ / GraceLanguage at token speed
Reckoning component / 01

Give your application the input your model expects.

Before a model can answer, it needs your text translated into its own language of tokens. Grace handles that translation for the JVM, including the model-specific details that can change the result.

Start with the model you want to use

Grace loads the tokenizer that belongs to a model. That matters because different model families split text, represent control tokens, and format conversations differently.

For supported families, Grace strives to match the results of the popular upstream Transformers implementations while presenting the workflow in an idiomatic Java style.

Load a tokenizer

Load a tokenizer by specifying its owner and model name:

PreTrainedTokenizer tokenizer = AutoTokenizer.fromPretrained(
    new AutoTokenizer.OwnerNameOrPath(
        new AutoTokenizer.OwnerName("google", "gemma-4-E2B-it")
    )
);

See what the model sees

Encoding turns ordinary text into the numeric input IDs passed to the model. Decoding turns those IDs back into text, so you can inspect the round trip while building or debugging an application:

Encoding encoding = tokenizer.encode("Hello world");
int[] ids = encoding.inputIds();

String decoded = tokenizer.decode(
    new TokenIds(ids),
    false,
    false,
    false,
    false
);
>> returns "Hello world"

The decoded text comes back as Hello world. The numeric IDs are specific to the tokenizer and model, which is why using the right tokenizer matters.

Keep the model’s control language intact

Models use special tokens to mark things like the beginning and end of a sequence. Grace gives your application access to those values instead of hiding them behind a generic string API:

tokenizer.specialTokensMap();
tokenizer.allSpecialTokens();
tokenizer.allSpecialIds();
tokenizer.bosTokenId();
tokenizer.eosTokenId();
>> returns the model’s special-token map, token names, IDs, beginning-of-sequence ID, and end-of-sequence ID

Use chat templates instead of hand-building prompts

When a model includes a chat template, Grace loads it with the tokenizer so your application can follow the model family’s expected conversation format:

String template = tokenizer.chatTemplate().orElseThrow();
>> returns the model’s chat-template definition

Download tokenizer data without model weights

TokenizerModelFetcher uses the same cache root as model fetching:

~/.deliverance/<owner>_<model>/

Tokenizer-only fetches download assets such as tokenizer.json, tokenizer_config.json, vocab.json, merges.txt, chat_template.jinja, and config.json. They do not download model weights, and local directories can be reused offline when the required files are present.

Different families, different behavior

Grace dispatches tokenizer families instead of forcing every model through one implementation. Current paths include:

  • Gemma-style tokenizers
  • Byte-level BPE tokenizers
  • Qwen tokenizer paths
  • Bert tokenizer paths

When to use Grace: Choose it when you need Hugging Face-like behavior, chat template parity, and modern added and special token handling.

Especially useful for Gemma 4

For model families such as Gemma 4, prompt-control tokenization can have a major effect on generation quality. Grace makes those boundaries visible and usable from the JVM.