Skip to content

Compare

trimbed.compare

A structural diff between two tokenizers, typically a base and a trimmed version.

A trimmed checkpoint's README tells you the recipe (which corpus, which target size) but not the result. This answers the other half: whether the smaller vocabulary really is a subset of the larger one, which structural guarantees survived, which presets and which Unicode scripts were preserved or gutted, and what the same text now costs in tokens.

Nothing here loads weights or reads a corpus. Two tokenizer.json documents go in, one report comes out.

DECILES module-attribute

DECILES = 10

How many equal slices of the base id range the removed-token profile is cut into.

MAX_REPORTED_SAMPLES module-attribute

MAX_REPORTED_SAMPLES = 5

How many fragmenting sample texts the encoding comparison quotes.

NON_LETTER module-attribute

NON_LETTER = 'non-letter'

Script bucket for a token whose surface form holds no alphabetic character at all.

MIXED module-attribute

MIXED = 'mixed'

Script bucket for a token whose letters come from more than one script.

UNDECODABLE module-attribute

UNDECODABLE = 'partial-bytes'

Bucket for a token that stands for no well-formed text, e.g. half a UTF-8 sequence.

GroupDiff pydantic-model

Bases: _Base

How one group of base-vocabulary tokens fared, e.g. one Unicode script.

Show JSON schema:
{
  "additionalProperties": false,
  "description": "How one group of base-vocabulary tokens fared, e.g. one Unicode script.",
  "properties": {
    "name": {
      "description": "What the group is, e.g. 'LATIN', 'letter' or 'digits'.",
      "title": "Name",
      "type": "string"
    },
    "base_tokens": {
      "description": "Tokens the base tokenizer has in this group, e.g. 60003.",
      "title": "Base Tokens",
      "type": "integer"
    },
    "kept": {
      "description": "How many of those the other tokenizer still has, e.g. 45102.",
      "title": "Kept",
      "type": "integer"
    }
  },
  "required": [
    "name",
    "base_tokens",
    "kept"
  ],
  "title": "GroupDiff",
  "type": "object"
}

Fields:

name pydantic-field

name: str

What the group is, e.g. 'LATIN', 'letter' or 'digits'.

base_tokens pydantic-field

base_tokens: int

Tokens the base tokenizer has in this group, e.g. 60003.

kept pydantic-field

kept: int

How many of those the other tokenizer still has, e.g. 45102.

removed property

removed: int

Return how many of the group's tokens the other tokenizer lacks.

kept_fraction property

kept_fraction: float

Return the share of the group that survived, e.g. 0.752.

PresetDiff pydantic-model

Bases: GroupDiff

How one named preset fared, e.g. digits or script:Latin.

Show JSON schema:
{
  "additionalProperties": false,
  "description": "How one named preset fared, e.g. `digits` or `script:Latin`.",
  "properties": {
    "name": {
      "description": "What the group is, e.g. 'LATIN', 'letter' or 'digits'.",
      "title": "Name",
      "type": "string"
    },
    "base_tokens": {
      "description": "Tokens the base tokenizer has in this group, e.g. 60003.",
      "title": "Base Tokens",
      "type": "integer"
    },
    "kept": {
      "description": "How many of those the other tokenizer still has, e.g. 45102.",
      "title": "Kept",
      "type": "integer"
    },
    "always_kept": {
      "description": "Whether a trim keeps this preset's tokens whether or not it is named, so any loss here means a broken tokenizer rather than a policy choice.",
      "title": "Always Kept",
      "type": "boolean"
    }
  },
  "required": [
    "name",
    "base_tokens",
    "kept",
    "always_kept"
  ],
  "title": "PresetDiff",
  "type": "object"
}

Fields:

always_kept pydantic-field

always_kept: bool

Whether a trim keeps this preset's tokens whether or not it is named, so any loss here means a broken tokenizer rather than a policy choice.

RemovedToken pydantic-model

Bases: _Base

One token the other tokenizer no longer has.

Show JSON schema:
{
  "additionalProperties": false,
  "description": "One token the other tokenizer no longer has.",
  "properties": {
    "token": {
      "description": "The token as the base vocabulary stores it, e.g. '\u0120bureaucratie'.",
      "title": "Token",
      "type": "string"
    },
    "token_id": {
      "description": "Its id in the base vocabulary, e.g. 1204.",
      "title": "Token Id",
      "type": "integer"
    },
    "surface": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "The text it stands for, e.g. ' bureaucratie'; null for a partial byte sequence.",
      "title": "Surface"
    }
  },
  "required": [
    "token",
    "token_id",
    "surface"
  ],
  "title": "RemovedToken",
  "type": "object"
}

Fields:

token pydantic-field

token: str

The token as the base vocabulary stores it, e.g. 'Ġbureaucratie'.

token_id pydantic-field

token_id: int

Its id in the base vocabulary, e.g. 1204.

surface pydantic-field

surface: str | None

The text it stands for, e.g. ' bureaucratie'; null for a partial byte sequence.

VocabularyDiff pydantic-model

Bases: _Base

How the two vocabularies relate as sets of tokens.

Show JSON schema:
{
  "additionalProperties": false,
  "description": "How the two vocabularies relate as sets of tokens.",
  "properties": {
    "base_size": {
      "description": "Tokens in the base vocabulary, e.g. 119547.",
      "title": "Base Size",
      "type": "integer"
    },
    "other_size": {
      "description": "Tokens in the other vocabulary, e.g. 50000.",
      "title": "Other Size",
      "type": "integer"
    },
    "shared": {
      "description": "Tokens both have.",
      "title": "Shared",
      "type": "integer"
    },
    "removed": {
      "description": "Tokens only the base has.",
      "title": "Removed",
      "type": "integer"
    },
    "introduced": {
      "description": "Tokens only the other has; zero for a genuine trim.",
      "title": "Introduced",
      "type": "integer"
    },
    "is_subset": {
      "description": "Whether the other vocabulary introduces nothing new.",
      "title": "Is Subset",
      "type": "boolean"
    },
    "ids_contiguous": {
      "description": "Whether the other vocabulary is numbered 0..n-1 without gaps.",
      "title": "Ids Contiguous",
      "type": "boolean"
    },
    "order_preserved": {
      "description": "Whether the shared tokens keep their relative order. A trim renumbers the survivors in place, so a false here means the vocabulary was rebuilt rather than trimmed.",
      "title": "Order Preserved",
      "type": "boolean"
    },
    "introduced_examples": {
      "description": "A few of the tokens only the other tokenizer has.",
      "items": {
        "type": "string"
      },
      "title": "Introduced Examples",
      "type": "array"
    }
  },
  "required": [
    "base_size",
    "other_size",
    "shared",
    "removed",
    "introduced",
    "is_subset",
    "ids_contiguous",
    "order_preserved"
  ],
  "title": "VocabularyDiff",
  "type": "object"
}

Fields:

base_size pydantic-field

base_size: int

Tokens in the base vocabulary, e.g. 119547.

other_size pydantic-field

other_size: int

Tokens in the other vocabulary, e.g. 50000.

shared pydantic-field

shared: int

Tokens both have.

removed pydantic-field

removed: int

Tokens only the base has.

introduced pydantic-field

introduced: int

Tokens only the other has; zero for a genuine trim.

is_subset pydantic-field

is_subset: bool

Whether the other vocabulary introduces nothing new.

ids_contiguous pydantic-field

ids_contiguous: bool

Whether the other vocabulary is numbered 0..n-1 without gaps.

order_preserved pydantic-field

order_preserved: bool

Whether the shared tokens keep their relative order. A trim renumbers the survivors in place, so a false here means the vocabulary was rebuilt rather than trimmed.

introduced_examples pydantic-field

introduced_examples: list[str]

A few of the tokens only the other tokenizer has.

removed_fraction property

removed_fraction: float

Return the share of the base vocabulary that is gone, e.g. 0.582.

ComponentDiff pydantic-model

Bases: _Base

How the parts of the tokenizer around the vocabulary compare.

Show JSON schema:
{
  "additionalProperties": false,
  "description": "How the parts of the tokenizer around the vocabulary compare.",
  "properties": {
    "base_model_type": {
      "description": "Backend family of the base tokenizer, e.g. 'WordPiece'.",
      "title": "Base Model Type",
      "type": "string"
    },
    "other_model_type": {
      "description": "Backend family of the other tokenizer.",
      "title": "Other Model Type",
      "type": "string"
    },
    "base_uses_byte_level": {
      "description": "Whether the base maps text through the ByteLevel alphabet.",
      "title": "Base Uses Byte Level",
      "type": "boolean"
    },
    "other_uses_byte_level": {
      "description": "The same for the other tokenizer.",
      "title": "Other Uses Byte Level",
      "type": "boolean"
    },
    "base_unk_token": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "The base's unknown token, e.g. '[UNK]', or null.",
      "title": "Base Unk Token"
    },
    "other_unk_token": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "The other's unknown token.",
      "title": "Other Unk Token"
    },
    "base_added_tokens": {
      "description": "Entries in the base's `added_tokens` list, e.g. 5.",
      "title": "Base Added Tokens",
      "type": "integer"
    },
    "other_added_tokens": {
      "description": "Entries in the other's `added_tokens` list.",
      "title": "Other Added Tokens",
      "type": "integer"
    },
    "base_special_tokens": {
      "description": "How many of the base's added tokens are flagged special.",
      "title": "Base Special Tokens",
      "type": "integer"
    },
    "other_special_tokens": {
      "description": "The same for the other tokenizer.",
      "title": "Other Special Tokens",
      "type": "integer"
    },
    "removed_added_tokens": {
      "description": "Added tokens the other tokenizer no longer has.",
      "items": {
        "type": "string"
      },
      "title": "Removed Added Tokens",
      "type": "array"
    },
    "removed_special_tokens": {
      "description": "Special tokens the other tokenizer no longer has.",
      "items": {
        "type": "string"
      },
      "title": "Removed Special Tokens",
      "type": "array"
    },
    "removed_post_processor_tokens": {
      "description": "Tokens the base's post-processor names that the other tokenizer no longer has, e.g. ['[SEP]']. Every one of them breaks encoding.",
      "items": {
        "type": "string"
      },
      "title": "Removed Post Processor Tokens",
      "type": "array"
    },
    "chat_template": {
      "description": "How the two chat templates relate.",
      "enum": [
        "identical",
        "changed",
        "only in base",
        "only in other",
        "absent"
      ],
      "title": "Chat Template",
      "type": "string"
    }
  },
  "required": [
    "base_model_type",
    "other_model_type",
    "base_uses_byte_level",
    "other_uses_byte_level",
    "base_unk_token",
    "other_unk_token",
    "base_added_tokens",
    "other_added_tokens",
    "base_special_tokens",
    "other_special_tokens",
    "chat_template"
  ],
  "title": "ComponentDiff",
  "type": "object"
}

Fields:

base_model_type pydantic-field

base_model_type: str

Backend family of the base tokenizer, e.g. 'WordPiece'.

other_model_type pydantic-field

other_model_type: str

Backend family of the other tokenizer.

base_uses_byte_level pydantic-field

base_uses_byte_level: bool

Whether the base maps text through the ByteLevel alphabet.

other_uses_byte_level pydantic-field

other_uses_byte_level: bool

The same for the other tokenizer.

base_unk_token pydantic-field

base_unk_token: str | None

The base's unknown token, e.g. '[UNK]', or null.

other_unk_token pydantic-field

other_unk_token: str | None

The other's unknown token.

base_added_tokens pydantic-field

base_added_tokens: int

Entries in the base's added_tokens list, e.g. 5.

other_added_tokens pydantic-field

other_added_tokens: int

Entries in the other's added_tokens list.

base_special_tokens pydantic-field

base_special_tokens: int

How many of the base's added tokens are flagged special.

other_special_tokens pydantic-field

other_special_tokens: int

The same for the other tokenizer.

removed_added_tokens pydantic-field

removed_added_tokens: list[str]

Added tokens the other tokenizer no longer has.

removed_special_tokens pydantic-field

removed_special_tokens: list[str]

Special tokens the other tokenizer no longer has.

removed_post_processor_tokens pydantic-field

removed_post_processor_tokens: list[str]

Tokens the base's post-processor names that the other tokenizer no longer has, e.g. ['[SEP]']. Every one of them breaks encoding.

chat_template pydantic-field

chat_template: Literal[
    "identical",
    "changed",
    "only in base",
    "only in other",
    "absent",
]

How the two chat templates relate.

structural_break property

structural_break: bool

Return whether the other tokenizer lost a token no tokenizer can do without.

ProfileDiff pydantic-model

Bases: _Base

What kind of tokens were dropped, attributed three ways.

Show JSON schema:
{
  "$defs": {
    "GroupDiff": {
      "additionalProperties": false,
      "description": "How one group of base-vocabulary tokens fared, e.g. one Unicode script.",
      "properties": {
        "name": {
          "description": "What the group is, e.g. 'LATIN', 'letter' or 'digits'.",
          "title": "Name",
          "type": "string"
        },
        "base_tokens": {
          "description": "Tokens the base tokenizer has in this group, e.g. 60003.",
          "title": "Base Tokens",
          "type": "integer"
        },
        "kept": {
          "description": "How many of those the other tokenizer still has, e.g. 45102.",
          "title": "Kept",
          "type": "integer"
        }
      },
      "required": [
        "name",
        "base_tokens",
        "kept"
      ],
      "title": "GroupDiff",
      "type": "object"
    },
    "PresetDiff": {
      "additionalProperties": false,
      "description": "How one named preset fared, e.g. `digits` or `script:Latin`.",
      "properties": {
        "name": {
          "description": "What the group is, e.g. 'LATIN', 'letter' or 'digits'.",
          "title": "Name",
          "type": "string"
        },
        "base_tokens": {
          "description": "Tokens the base tokenizer has in this group, e.g. 60003.",
          "title": "Base Tokens",
          "type": "integer"
        },
        "kept": {
          "description": "How many of those the other tokenizer still has, e.g. 45102.",
          "title": "Kept",
          "type": "integer"
        },
        "always_kept": {
          "description": "Whether a trim keeps this preset's tokens whether or not it is named, so any loss here means a broken tokenizer rather than a policy choice.",
          "title": "Always Kept",
          "type": "boolean"
        }
      },
      "required": [
        "name",
        "base_tokens",
        "kept",
        "always_kept"
      ],
      "title": "PresetDiff",
      "type": "object"
    },
    "RemovedToken": {
      "additionalProperties": false,
      "description": "One token the other tokenizer no longer has.",
      "properties": {
        "token": {
          "description": "The token as the base vocabulary stores it, e.g. '\u0120bureaucratie'.",
          "title": "Token",
          "type": "string"
        },
        "token_id": {
          "description": "Its id in the base vocabulary, e.g. 1204.",
          "title": "Token Id",
          "type": "integer"
        },
        "surface": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "The text it stands for, e.g. ' bureaucratie'; null for a partial byte sequence.",
          "title": "Surface"
        }
      },
      "required": [
        "token",
        "token_id",
        "surface"
      ],
      "title": "RemovedToken",
      "type": "object"
    }
  },
  "additionalProperties": false,
  "description": "What kind of tokens were dropped, attributed three ways.",
  "properties": {
    "presets": {
      "description": "One entry per registered preset that matches anything in the base vocabulary.",
      "items": {
        "$ref": "#/$defs/PresetDiff"
      },
      "title": "Presets",
      "type": "array"
    },
    "scripts": {
      "description": "One entry per dominant Unicode script, largest group first, e.g. 'LATIN', 'CYRILLIC'.",
      "items": {
        "$ref": "#/$defs/GroupDiff"
      },
      "title": "Scripts",
      "type": "array"
    },
    "categories": {
      "description": "One entry per majority Unicode category, e.g. 'letter', 'number', 'whitespace'.",
      "items": {
        "$ref": "#/$defs/GroupDiff"
      },
      "title": "Categories",
      "type": "array"
    },
    "removed_by_decile": {
      "description": "Removed tokens per tenth of the base id range, lowest ids first. A trim that only cut the tail leaves the early deciles near zero.",
      "items": {
        "type": "integer"
      },
      "title": "Removed By Decile",
      "type": "array"
    },
    "removed_examples": {
      "description": "The lowest-id removed tokens, which are the ones a trim rarely gives up.",
      "items": {
        "$ref": "#/$defs/RemovedToken"
      },
      "title": "Removed Examples",
      "type": "array"
    }
  },
  "required": [
    "presets",
    "scripts",
    "categories",
    "removed_by_decile"
  ],
  "title": "ProfileDiff",
  "type": "object"
}

Fields:

presets pydantic-field

presets: list[PresetDiff]

One entry per registered preset that matches anything in the base vocabulary.

scripts pydantic-field

scripts: list[GroupDiff]

One entry per dominant Unicode script, largest group first, e.g. 'LATIN', 'CYRILLIC'.

categories pydantic-field

categories: list[GroupDiff]

One entry per majority Unicode category, e.g. 'letter', 'number', 'whitespace'.

removed_by_decile pydantic-field

removed_by_decile: list[int]

Removed tokens per tenth of the base id range, lowest ids first. A trim that only cut the tail leaves the early deciles near zero.

removed_examples pydantic-field

removed_examples: list[RemovedToken]

The lowest-id removed tokens, which are the ones a trim rarely gives up.

EncodingDiff pydantic-model

Bases: _Base

What the two tokenizers do to the same text.

Show JSON schema:
{
  "additionalProperties": false,
  "description": "What the two tokenizers do to the same text.",
  "properties": {
    "checked": {
      "default": 0,
      "description": "Texts encoded with both tokenizers.",
      "title": "Checked",
      "type": "integer"
    },
    "identical": {
      "default": 0,
      "description": "Texts both split into exactly the same tokens.",
      "title": "Identical",
      "type": "integer"
    },
    "base_tokens": {
      "default": 0,
      "description": "Tokens the base produced over all texts.",
      "title": "Base Tokens",
      "type": "integer"
    },
    "other_tokens": {
      "default": 0,
      "description": "Tokens the other produced over the same texts.",
      "title": "Other Tokens",
      "type": "integer"
    },
    "examples": {
      "description": "The texts that fragment the most, truncated for readability.",
      "items": {
        "type": "string"
      },
      "title": "Examples",
      "type": "array"
    }
  },
  "title": "EncodingDiff",
  "type": "object"
}

Fields:

checked pydantic-field

checked: int = 0

Texts encoded with both tokenizers.

identical pydantic-field

identical: int = 0

Texts both split into exactly the same tokens.

base_tokens pydantic-field

base_tokens: int = 0

Tokens the base produced over all texts.

other_tokens pydantic-field

other_tokens: int = 0

Tokens the other produced over the same texts.

examples pydantic-field

examples: list[str]

The texts that fragment the most, truncated for readability.

identical_rate property

identical_rate: float

Return the share of texts that segment identically, e.g. 0.92.

length_ratio property

length_ratio: float

Return how much longer the other tokenizer's output is, e.g. 1.031 for 3.1% more tokens.

ComparisonReport pydantic-model

Bases: _Base

The complete diff between two tokenizers.

Show JSON schema:
{
  "$defs": {
    "ComponentDiff": {
      "additionalProperties": false,
      "description": "How the parts of the tokenizer around the vocabulary compare.",
      "properties": {
        "base_model_type": {
          "description": "Backend family of the base tokenizer, e.g. 'WordPiece'.",
          "title": "Base Model Type",
          "type": "string"
        },
        "other_model_type": {
          "description": "Backend family of the other tokenizer.",
          "title": "Other Model Type",
          "type": "string"
        },
        "base_uses_byte_level": {
          "description": "Whether the base maps text through the ByteLevel alphabet.",
          "title": "Base Uses Byte Level",
          "type": "boolean"
        },
        "other_uses_byte_level": {
          "description": "The same for the other tokenizer.",
          "title": "Other Uses Byte Level",
          "type": "boolean"
        },
        "base_unk_token": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "The base's unknown token, e.g. '[UNK]', or null.",
          "title": "Base Unk Token"
        },
        "other_unk_token": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "The other's unknown token.",
          "title": "Other Unk Token"
        },
        "base_added_tokens": {
          "description": "Entries in the base's `added_tokens` list, e.g. 5.",
          "title": "Base Added Tokens",
          "type": "integer"
        },
        "other_added_tokens": {
          "description": "Entries in the other's `added_tokens` list.",
          "title": "Other Added Tokens",
          "type": "integer"
        },
        "base_special_tokens": {
          "description": "How many of the base's added tokens are flagged special.",
          "title": "Base Special Tokens",
          "type": "integer"
        },
        "other_special_tokens": {
          "description": "The same for the other tokenizer.",
          "title": "Other Special Tokens",
          "type": "integer"
        },
        "removed_added_tokens": {
          "description": "Added tokens the other tokenizer no longer has.",
          "items": {
            "type": "string"
          },
          "title": "Removed Added Tokens",
          "type": "array"
        },
        "removed_special_tokens": {
          "description": "Special tokens the other tokenizer no longer has.",
          "items": {
            "type": "string"
          },
          "title": "Removed Special Tokens",
          "type": "array"
        },
        "removed_post_processor_tokens": {
          "description": "Tokens the base's post-processor names that the other tokenizer no longer has, e.g. ['[SEP]']. Every one of them breaks encoding.",
          "items": {
            "type": "string"
          },
          "title": "Removed Post Processor Tokens",
          "type": "array"
        },
        "chat_template": {
          "description": "How the two chat templates relate.",
          "enum": [
            "identical",
            "changed",
            "only in base",
            "only in other",
            "absent"
          ],
          "title": "Chat Template",
          "type": "string"
        }
      },
      "required": [
        "base_model_type",
        "other_model_type",
        "base_uses_byte_level",
        "other_uses_byte_level",
        "base_unk_token",
        "other_unk_token",
        "base_added_tokens",
        "other_added_tokens",
        "base_special_tokens",
        "other_special_tokens",
        "chat_template"
      ],
      "title": "ComponentDiff",
      "type": "object"
    },
    "EncodingDiff": {
      "additionalProperties": false,
      "description": "What the two tokenizers do to the same text.",
      "properties": {
        "checked": {
          "default": 0,
          "description": "Texts encoded with both tokenizers.",
          "title": "Checked",
          "type": "integer"
        },
        "identical": {
          "default": 0,
          "description": "Texts both split into exactly the same tokens.",
          "title": "Identical",
          "type": "integer"
        },
        "base_tokens": {
          "default": 0,
          "description": "Tokens the base produced over all texts.",
          "title": "Base Tokens",
          "type": "integer"
        },
        "other_tokens": {
          "default": 0,
          "description": "Tokens the other produced over the same texts.",
          "title": "Other Tokens",
          "type": "integer"
        },
        "examples": {
          "description": "The texts that fragment the most, truncated for readability.",
          "items": {
            "type": "string"
          },
          "title": "Examples",
          "type": "array"
        }
      },
      "title": "EncodingDiff",
      "type": "object"
    },
    "GroupDiff": {
      "additionalProperties": false,
      "description": "How one group of base-vocabulary tokens fared, e.g. one Unicode script.",
      "properties": {
        "name": {
          "description": "What the group is, e.g. 'LATIN', 'letter' or 'digits'.",
          "title": "Name",
          "type": "string"
        },
        "base_tokens": {
          "description": "Tokens the base tokenizer has in this group, e.g. 60003.",
          "title": "Base Tokens",
          "type": "integer"
        },
        "kept": {
          "description": "How many of those the other tokenizer still has, e.g. 45102.",
          "title": "Kept",
          "type": "integer"
        }
      },
      "required": [
        "name",
        "base_tokens",
        "kept"
      ],
      "title": "GroupDiff",
      "type": "object"
    },
    "PresetDiff": {
      "additionalProperties": false,
      "description": "How one named preset fared, e.g. `digits` or `script:Latin`.",
      "properties": {
        "name": {
          "description": "What the group is, e.g. 'LATIN', 'letter' or 'digits'.",
          "title": "Name",
          "type": "string"
        },
        "base_tokens": {
          "description": "Tokens the base tokenizer has in this group, e.g. 60003.",
          "title": "Base Tokens",
          "type": "integer"
        },
        "kept": {
          "description": "How many of those the other tokenizer still has, e.g. 45102.",
          "title": "Kept",
          "type": "integer"
        },
        "always_kept": {
          "description": "Whether a trim keeps this preset's tokens whether or not it is named, so any loss here means a broken tokenizer rather than a policy choice.",
          "title": "Always Kept",
          "type": "boolean"
        }
      },
      "required": [
        "name",
        "base_tokens",
        "kept",
        "always_kept"
      ],
      "title": "PresetDiff",
      "type": "object"
    },
    "ProfileDiff": {
      "additionalProperties": false,
      "description": "What kind of tokens were dropped, attributed three ways.",
      "properties": {
        "presets": {
          "description": "One entry per registered preset that matches anything in the base vocabulary.",
          "items": {
            "$ref": "#/$defs/PresetDiff"
          },
          "title": "Presets",
          "type": "array"
        },
        "scripts": {
          "description": "One entry per dominant Unicode script, largest group first, e.g. 'LATIN', 'CYRILLIC'.",
          "items": {
            "$ref": "#/$defs/GroupDiff"
          },
          "title": "Scripts",
          "type": "array"
        },
        "categories": {
          "description": "One entry per majority Unicode category, e.g. 'letter', 'number', 'whitespace'.",
          "items": {
            "$ref": "#/$defs/GroupDiff"
          },
          "title": "Categories",
          "type": "array"
        },
        "removed_by_decile": {
          "description": "Removed tokens per tenth of the base id range, lowest ids first. A trim that only cut the tail leaves the early deciles near zero.",
          "items": {
            "type": "integer"
          },
          "title": "Removed By Decile",
          "type": "array"
        },
        "removed_examples": {
          "description": "The lowest-id removed tokens, which are the ones a trim rarely gives up.",
          "items": {
            "$ref": "#/$defs/RemovedToken"
          },
          "title": "Removed Examples",
          "type": "array"
        }
      },
      "required": [
        "presets",
        "scripts",
        "categories",
        "removed_by_decile"
      ],
      "title": "ProfileDiff",
      "type": "object"
    },
    "RemovedToken": {
      "additionalProperties": false,
      "description": "One token the other tokenizer no longer has.",
      "properties": {
        "token": {
          "description": "The token as the base vocabulary stores it, e.g. '\u0120bureaucratie'.",
          "title": "Token",
          "type": "string"
        },
        "token_id": {
          "description": "Its id in the base vocabulary, e.g. 1204.",
          "title": "Token Id",
          "type": "integer"
        },
        "surface": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "The text it stands for, e.g. ' bureaucratie'; null for a partial byte sequence.",
          "title": "Surface"
        }
      },
      "required": [
        "token",
        "token_id",
        "surface"
      ],
      "title": "RemovedToken",
      "type": "object"
    },
    "VocabularyDiff": {
      "additionalProperties": false,
      "description": "How the two vocabularies relate as sets of tokens.",
      "properties": {
        "base_size": {
          "description": "Tokens in the base vocabulary, e.g. 119547.",
          "title": "Base Size",
          "type": "integer"
        },
        "other_size": {
          "description": "Tokens in the other vocabulary, e.g. 50000.",
          "title": "Other Size",
          "type": "integer"
        },
        "shared": {
          "description": "Tokens both have.",
          "title": "Shared",
          "type": "integer"
        },
        "removed": {
          "description": "Tokens only the base has.",
          "title": "Removed",
          "type": "integer"
        },
        "introduced": {
          "description": "Tokens only the other has; zero for a genuine trim.",
          "title": "Introduced",
          "type": "integer"
        },
        "is_subset": {
          "description": "Whether the other vocabulary introduces nothing new.",
          "title": "Is Subset",
          "type": "boolean"
        },
        "ids_contiguous": {
          "description": "Whether the other vocabulary is numbered 0..n-1 without gaps.",
          "title": "Ids Contiguous",
          "type": "boolean"
        },
        "order_preserved": {
          "description": "Whether the shared tokens keep their relative order. A trim renumbers the survivors in place, so a false here means the vocabulary was rebuilt rather than trimmed.",
          "title": "Order Preserved",
          "type": "boolean"
        },
        "introduced_examples": {
          "description": "A few of the tokens only the other tokenizer has.",
          "items": {
            "type": "string"
          },
          "title": "Introduced Examples",
          "type": "array"
        }
      },
      "required": [
        "base_size",
        "other_size",
        "shared",
        "removed",
        "introduced",
        "is_subset",
        "ids_contiguous",
        "order_preserved"
      ],
      "title": "VocabularyDiff",
      "type": "object"
    }
  },
  "additionalProperties": false,
  "description": "The complete diff between two tokenizers.",
  "properties": {
    "base": {
      "description": "Where the base tokenizer came from, e.g. 'clips/e5-small-trm-nl'.",
      "title": "Base",
      "type": "string"
    },
    "other": {
      "description": "Where the other tokenizer came from, e.g. 'clips/e5-small-trm'.",
      "title": "Other",
      "type": "string"
    },
    "vocabulary": {
      "$ref": "#/$defs/VocabularyDiff"
    },
    "components": {
      "$ref": "#/$defs/ComponentDiff"
    },
    "profile": {
      "$ref": "#/$defs/ProfileDiff"
    },
    "encoding": {
      "anyOf": [
        {
          "$ref": "#/$defs/EncodingDiff"
        },
        {
          "type": "null"
        }
      ],
      "default": null
    }
  },
  "required": [
    "base",
    "other",
    "vocabulary",
    "components",
    "profile"
  ],
  "title": "ComparisonReport",
  "type": "object"
}

Fields:

base pydantic-field

base: str

Where the base tokenizer came from, e.g. 'clips/e5-small-trm-nl'.

other pydantic-field

other: str

Where the other tokenizer came from, e.g. 'clips/e5-small-trm'.

save

save(path: str | Path) -> Path

Write the report as JSON.

Parameters:

Name Type Description Default
path str | Path

File to write, e.g. "diff.json". Parent directories are created.

required

Returns:

Type Description
Path

The path written.

render

render() -> str

Return the human-readable diff, one aligned label value line per topic.

Returns:

Type Description
The text `trimbed compare` prints, e.g.
base             clips/e5-small-trm-nl
other            clips/e5-small-trm
type             WordPiece -> WordPiece (byte-level no -> no, unk [UNK] -> [UNK])
vocabulary       119,547 -> 50,000 (58.2% removed, 0 introduced)
relation         subset, contiguous ids, original order preserved

compare_tokenizers

compare_tokenizers(
    base: TokenizerSpec,
    other: TokenizerSpec,
    texts: Sequence[str] = (),
    presets: Sequence[str] = (),
    examples: int = 10,
) -> ComparisonReport

Diff two tokenizers, reading nothing but their two documents.

The comparison is directional: everything is attributed against base, so a group reported as 0/2,341 means the base had 2,341 such tokens and other has none of them left.

Parameters:

Name Type Description Default
base TokenizerSpec

The larger, original tokenizer, e.g. clips/e5-small-trm-nl.

required
other TokenizerSpec

The tokenizer to compare against it, e.g. its trimmed sibling clips/e5-small-trm.

required
texts Sequence[str]

Sample texts to encode with both, e.g. a handful of sentences in the language the trim targeted. Leave empty to skip the encoding comparison.

()
presets Sequence[str]

Extra preset names to resolve on top of the registered plain ones, which is how the parametrised ones are reached, e.g. ["script:Latin"].

()
examples int

How many removed tokens and introduced tokens to quote.

10

Returns:

Type Description
The diff. For a healthy trim

is_subset and order_preserved both true, no structural break, and the removal concentrated in the later id deciles.