Skip to content

Configuration

trimbed.config

Pydantic configuration models, basically extended the models provided by skeletoken.

LocalPath

LocalPath = Path

A filesystem path from a config file, with a leading ~ expanded.

HubOrLocalPath

HubOrLocalPath = str

A Hub id or a filesystem path, kept as a string because only the caller can tell which.

DatasetSpec pydantic-model

Bases: _StrictBase

Dataset to derive token frequencies from, on the Hub or on disk.

path is what datasets.load_dataset takes first, so it is a Hub dataset id (epfml/FineWeb2-HQ), a loader name (json, csv, parquet, text) paired with data_dir or data_files, or a directory of data files to infer a loader from. A directory written by save_to_disk is the one thing load_dataset cannot read, so that one is spelled load_from_disk: true.

Show JSON schema:
{
  "$defs": {
    "HubOrLocalPath": {
      "type": "string"
    }
  },
  "additionalProperties": false,
  "description": "Dataset to derive token frequencies from, on the Hub or on disk.\n\n`path` is what `datasets.load_dataset` takes first, so it is a Hub dataset id\n(`epfml/FineWeb2-HQ`), a loader name (`json`, `csv`, `parquet`, `text`) paired with\n`data_dir` or `data_files`, or a directory of data files to infer a loader from. A\ndirectory written by `save_to_disk` is the one thing `load_dataset` cannot read, so\nthat one is spelled `load_from_disk: true`.",
  "properties": {
    "path": {
      "$ref": "#/$defs/HubOrLocalPath",
      "description": "Hub dataset id, a loader name or a local directory, e.g. 'epfml/FineWeb2-HQ', 'json' or './data/corpus'."
    },
    "name": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Dataset configuration name, e.g. 'nld_Latn'.",
      "title": "Name"
    },
    "split": {
      "default": "train",
      "description": "Split expression, e.g. 'train' or even 'train[:1%]'.",
      "title": "Split",
      "type": "string"
    },
    "text_column": {
      "default": "text",
      "description": "Column holding the raw text, e.g. 'text' or 'content'.",
      "title": "Text Column",
      "type": "string"
    },
    "data_dir": {
      "anyOf": [
        {
          "$ref": "#/$defs/HubOrLocalPath"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Directory the loader named by 'path' reads its files from, e.g. './data/dutch'."
    },
    "data_files": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        {
          "additionalProperties": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              }
            ]
          },
          "type": "object"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Files the loader named by 'path' reads, as one path, a list of paths or globs, or a mapping of split name to either, e.g. './data/train-*.jsonl'.",
      "title": "Data Files"
    },
    "load_from_disk": {
      "default": false,
      "description": "Read 'path' with `datasets.load_from_disk`, for a directory written by `save_to_disk`. Such a dataset is already built, so it is never streamed.",
      "title": "Load From Disk",
      "type": "boolean"
    },
    "streaming": {
      "default": true,
      "description": "Stream instead of downloading the whole split.",
      "title": "Streaming",
      "type": "boolean"
    },
    "max_samples": {
      "anyOf": [
        {
          "minimum": 1,
          "type": "integer"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Stop after this many examples, e.g. 200000.",
      "title": "Max Samples"
    },
    "revision": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Dataset revision to pin. Recommended for reproducibility.",
      "title": "Revision"
    },
    "weight": {
      "default": 1.0,
      "description": "Multiplier applied to this corpus' token counts, e.g. 2.0 to let a small in-domain corpus weigh as much as twice its size against a large generic one.",
      "exclusiveMinimum": 0,
      "title": "Weight",
      "type": "number"
    }
  },
  "required": [
    "path"
  ],
  "title": "DatasetSpec",
  "type": "object"
}

Fields:

Validators:

  • _reject_sources_datasets_cannot_read

path pydantic-field

Hub dataset id, a loader name or a local directory, e.g. 'epfml/FineWeb2-HQ', 'json' or './data/corpus'.

name pydantic-field

name: str | None = None

Dataset configuration name, e.g. 'nld_Latn'.

split pydantic-field

split: str = 'train'

Split expression, e.g. 'train' or even 'train[:1%]'.

text_column pydantic-field

text_column: str = 'text'

Column holding the raw text, e.g. 'text' or 'content'.

data_dir pydantic-field

data_dir: HubOrLocalPath | None = None

Directory the loader named by 'path' reads its files from, e.g. './data/dutch'.

data_files pydantic-field

data_files: (
    str | list[str] | dict[str, str | list[str]] | None
) = None

Files the loader named by 'path' reads, as one path, a list of paths or globs, or a mapping of split name to either, e.g. './data/train-*.jsonl'.

load_from_disk pydantic-field

load_from_disk: bool = False

Read 'path' with datasets.load_from_disk, for a directory written by save_to_disk. Such a dataset is already built, so it is never streamed.

streaming pydantic-field

streaming: bool = True

Stream instead of downloading the whole split.

max_samples pydantic-field

max_samples: int | None = None

Stop after this many examples, e.g. 200000.

revision pydantic-field

revision: str | None = None

Dataset revision to pin. Recommended for reproducibility.

weight pydantic-field

weight: float = 1.0

Multiplier applied to this corpus' token counts, e.g. 2.0 to let a small in-domain corpus weigh as much as twice its size against a large generic one.

CorpusConfig pydantic-model

Bases: _StrictBase

How the corpus, containing one or more datasets, is read and counted.

Show JSON schema:
{
  "$defs": {
    "DatasetSpec": {
      "additionalProperties": false,
      "description": "Dataset to derive token frequencies from, on the Hub or on disk.\n\n`path` is what `datasets.load_dataset` takes first, so it is a Hub dataset id\n(`epfml/FineWeb2-HQ`), a loader name (`json`, `csv`, `parquet`, `text`) paired with\n`data_dir` or `data_files`, or a directory of data files to infer a loader from. A\ndirectory written by `save_to_disk` is the one thing `load_dataset` cannot read, so\nthat one is spelled `load_from_disk: true`.",
      "properties": {
        "path": {
          "$ref": "#/$defs/HubOrLocalPath",
          "description": "Hub dataset id, a loader name or a local directory, e.g. 'epfml/FineWeb2-HQ', 'json' or './data/corpus'."
        },
        "name": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Dataset configuration name, e.g. 'nld_Latn'.",
          "title": "Name"
        },
        "split": {
          "default": "train",
          "description": "Split expression, e.g. 'train' or even 'train[:1%]'.",
          "title": "Split",
          "type": "string"
        },
        "text_column": {
          "default": "text",
          "description": "Column holding the raw text, e.g. 'text' or 'content'.",
          "title": "Text Column",
          "type": "string"
        },
        "data_dir": {
          "anyOf": [
            {
              "$ref": "#/$defs/HubOrLocalPath"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Directory the loader named by 'path' reads its files from, e.g. './data/dutch'."
        },
        "data_files": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            {
              "additionalProperties": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  }
                ]
              },
              "type": "object"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Files the loader named by 'path' reads, as one path, a list of paths or globs, or a mapping of split name to either, e.g. './data/train-*.jsonl'.",
          "title": "Data Files"
        },
        "load_from_disk": {
          "default": false,
          "description": "Read 'path' with `datasets.load_from_disk`, for a directory written by `save_to_disk`. Such a dataset is already built, so it is never streamed.",
          "title": "Load From Disk",
          "type": "boolean"
        },
        "streaming": {
          "default": true,
          "description": "Stream instead of downloading the whole split.",
          "title": "Streaming",
          "type": "boolean"
        },
        "max_samples": {
          "anyOf": [
            {
              "minimum": 1,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Stop after this many examples, e.g. 200000.",
          "title": "Max Samples"
        },
        "revision": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Dataset revision to pin. Recommended for reproducibility.",
          "title": "Revision"
        },
        "weight": {
          "default": 1.0,
          "description": "Multiplier applied to this corpus' token counts, e.g. 2.0 to let a small in-domain corpus weigh as much as twice its size against a large generic one.",
          "exclusiveMinimum": 0,
          "title": "Weight",
          "type": "number"
        }
      },
      "required": [
        "path"
      ],
      "title": "DatasetSpec",
      "type": "object"
    },
    "HubOrLocalPath": {
      "type": "string"
    },
    "LocalPath": {
      "format": "path",
      "type": "string"
    }
  },
  "additionalProperties": false,
  "description": "How the corpus, containing one or more datasets, is read and counted.",
  "properties": {
    "datasets": {
      "description": "Datasets to count tokens over.",
      "items": {
        "$ref": "#/$defs/DatasetSpec"
      },
      "title": "Datasets",
      "type": "array"
    },
    "batch_size": {
      "default": 1000,
      "description": "Examples tokenized per batch.",
      "minimum": 1,
      "title": "Batch Size",
      "type": "integer"
    },
    "num_proc": {
      "anyOf": [
        {
          "minimum": 1,
          "type": "integer"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Worker processes (non-streaming datasets only).",
      "title": "Num Proc"
    },
    "counts_cache": {
      "anyOf": [
        {
          "$ref": "#/$defs/LocalPath"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Read counts from this JSON file if it exists, otherwise write them there, e.g. 'counts.json'."
    }
  },
  "title": "CorpusConfig",
  "type": "object"
}

Fields:

datasets pydantic-field

datasets: list[DatasetSpec]

Datasets to count tokens over.

batch_size pydantic-field

batch_size: int = 1000

Examples tokenized per batch.

num_proc pydantic-field

num_proc: int | None = None

Worker processes (non-streaming datasets only).

counts_cache pydantic-field

counts_cache: LocalPath | None = None

Read counts from this JSON file if it exists, otherwise write them there, e.g. 'counts.json'.

SelectionConfig pydantic-model

Bases: _StrictBase

Which tokens survive the trim.

The criteria are the union of structural, requested and corpus, then the max_vocab_size cap is applied to the remainder. Structural tokens (added/special tokens, the unk token, and the byte alphabet of byte-level tokenizers) are always kept and never counted against a criterion, because dropping them breaks the tokenizer.

Show JSON schema:
{
  "$defs": {
    "LocalPath": {
      "format": "path",
      "type": "string"
    }
  },
  "additionalProperties": false,
  "description": "Which tokens survive the trim.\n\nThe criteria are the union of `structural`, `requested` and `corpus`, then the\n`max_vocab_size` cap is applied to the remainder. Structural tokens (added/special\ntokens, the unk token, and the byte alphabet of byte-level tokenizers) are always\nkept and never counted against a criterion, because dropping them breaks the tokenizer.",
  "properties": {
    "coverage": {
      "anyOf": [
        {
          "exclusiveMinimum": 0.0,
          "maximum": 1.0,
          "type": "number"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Keep the most frequent tokens until they cover this fraction of corpus occurrences, e.g. 0.9999. Values below about 0.99 trim far harder than you might expect!",
      "title": "Coverage"
    },
    "top_k": {
      "anyOf": [
        {
          "minimum": 1,
          "type": "integer"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Keep at most this many corpus-derived tokens, e.g. 32000.",
      "title": "Top K"
    },
    "min_count": {
      "anyOf": [
        {
          "minimum": 1,
          "type": "integer"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Keep tokens seen at least this many times, e.g. 10. 1 would mean: keep everything the corpus used.",
      "title": "Min Count"
    },
    "max_vocab_size": {
      "anyOf": [
        {
          "minimum": 1,
          "type": "integer"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Hard cap on the final vocabulary: least-frequent non-structural tokens are dropped to fit. E.g. 32000. It cannot go below the structural tokens, of which a byte-level BPE has at least 256.",
      "title": "Max Vocab Size"
    },
    "keep_presets": {
      "description": "Named presets to keep, e.g. 'alphanumeric'. Some presets are always included. Run `trimbed presets` to see the available presets.",
      "items": {
        "type": "string"
      },
      "title": "Keep Presets",
      "type": "array"
    },
    "keep_tokens": {
      "description": "Literal token strings to keep, written as the vocabulary stores them, so '\u0120de' rather than ' de' for a byte-level tokenizer.",
      "items": {
        "type": "string"
      },
      "title": "Keep Tokens",
      "type": "array"
    },
    "keep_token_ids": {
      "description": "Literal token ids to keep, e.g. [151643].",
      "items": {
        "type": "integer"
      },
      "title": "Keep Token Ids",
      "type": "array"
    },
    "keep_token_files": {
      "description": "Text files with one token per line. Blank lines and '#' comments are ignored.",
      "items": {
        "$ref": "#/$defs/LocalPath"
      },
      "title": "Keep Token Files",
      "type": "array"
    },
    "keep_patterns": {
      "description": "Regular expressions matched against each token's decoded surface form, e.g. '^\\d+$' for numbers or '[\u00c0-\u00ff]' for accented Latin characters. The surface form is matched, so a pattern is written against ' de' rather than the Unicode representation '\u0120de'.",
      "items": {
        "type": "string"
      },
      "title": "Keep Patterns",
      "type": "array"
    },
    "keep_texts": {
      "description": "Texts to keep encodable as they are now. E.g. a representative prompt, or the instruction format an SFT run will use.",
      "items": {
        "type": "string"
      },
      "title": "Keep Texts",
      "type": "array"
    },
    "keep_chat_template": {
      "default": true,
      "description": "Keep the tokens the chat template's own words need, so prompts do not fragment.",
      "title": "Keep Chat Template",
      "type": "boolean"
    }
  },
  "title": "SelectionConfig",
  "type": "object"
}

Fields:

coverage pydantic-field

coverage: float | None = None

Keep the most frequent tokens until they cover this fraction of corpus occurrences, e.g. 0.9999. Values below about 0.99 trim far harder than you might expect!

top_k pydantic-field

top_k: int | None = None

Keep at most this many corpus-derived tokens, e.g. 32000.

min_count pydantic-field

min_count: int | None = None

Keep tokens seen at least this many times, e.g. 10. 1 would mean: keep everything the corpus used.

max_vocab_size pydantic-field

max_vocab_size: int | None = None

Hard cap on the final vocabulary: least-frequent non-structural tokens are dropped to fit. E.g. 32000. It cannot go below the structural tokens, of which a byte-level BPE has at least 256.

keep_presets pydantic-field

keep_presets: list[str]

Named presets to keep, e.g. 'alphanumeric'. Some presets are always included. Run trimbed presets to see the available presets.

keep_tokens pydantic-field

keep_tokens: list[str]

Literal token strings to keep, written as the vocabulary stores them, so 'Ġde' rather than ' de' for a byte-level tokenizer.

keep_token_ids pydantic-field

keep_token_ids: list[int]

Literal token ids to keep, e.g. [151643].

keep_token_files pydantic-field

keep_token_files: list[LocalPath]

Text files with one token per line. Blank lines and '#' comments are ignored.

keep_patterns pydantic-field

keep_patterns: list[str]

Regular expressions matched against each token's decoded surface form, e.g. '^\d+$' for numbers or '[À-ÿ]' for accented Latin characters. The surface form is matched, so a pattern is written against ' de' rather than the Unicode representation 'Ġde'.

keep_texts pydantic-field

keep_texts: list[str]

Texts to keep encodable as they are now. E.g. a representative prompt, or the instruction format an SFT run will use.

keep_chat_template pydantic-field

keep_chat_template: bool = True

Keep the tokens the chat template's own words need, so prompts do not fragment.

has_explicit_sources property

has_explicit_sources: bool

Return whether any must-keep source was configured.

keep_chat_template is deliberately not counted: it is on by default and selects nothing at all for a tokenizer without a chat template, so treating it as a source would defeat the "nothing to select on" check.

EmbeddingTrimConfig pydantic-model

Bases: _StrictBase

How the model's embedding table and output head are resized.

Show JSON schema:
{
  "additionalProperties": false,
  "description": "How the model's embedding table and output head are resized.",
  "properties": {
    "pad_to_multiple_of": {
      "anyOf": [
        {
          "minimum": 1,
          "type": "integer"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Pad the resized embedding matrix up to a multiple of this, for tensor-core alignment. See for instance https://developer.nvidia.com/blog/optimizing-gpu-performance-tensor-cores/#h.9yili3t5wcy5",
      "title": "Pad To Multiple Of"
    },
    "dtype": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Cast the model to this dtype, e.g. 'bfloat16'.",
      "title": "Dtype"
    },
    "device": {
      "default": "cpu",
      "description": "Device used while selecting embedding rows.",
      "title": "Device",
      "type": "string"
    },
    "auto_class": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "transformers class used to load the model, e.g. 'AutoModelForCausalLM'. By default the class named in the checkpoint's config.architectures is used.",
      "title": "Auto Class"
    }
  },
  "title": "EmbeddingTrimConfig",
  "type": "object"
}

Fields:

pad_to_multiple_of pydantic-field

pad_to_multiple_of: int | None = None

Pad the resized embedding matrix up to a multiple of this, for tensor-core alignment. See for instance https://developer.nvidia.com/blog/optimizing-gpu-performance-tensor-cores/#h.9yili3t5wcy5

dtype pydantic-field

dtype: str | None = None

Cast the model to this dtype, e.g. 'bfloat16'.

device pydantic-field

device: str = 'cpu'

Device used while selecting embedding rows.

auto_class pydantic-field

auto_class: str | None = None

transformers class used to load the model, e.g. 'AutoModelForCausalLM'. By default the class named in the checkpoint's config.architectures is used.

TrimConfig pydantic-model

Bases: _StrictBase

Top-level configuration for one trimming run.

Show JSON schema:
{
  "$defs": {
    "CorpusConfig": {
      "additionalProperties": false,
      "description": "How the corpus, containing one or more datasets, is read and counted.",
      "properties": {
        "datasets": {
          "description": "Datasets to count tokens over.",
          "items": {
            "$ref": "#/$defs/DatasetSpec"
          },
          "title": "Datasets",
          "type": "array"
        },
        "batch_size": {
          "default": 1000,
          "description": "Examples tokenized per batch.",
          "minimum": 1,
          "title": "Batch Size",
          "type": "integer"
        },
        "num_proc": {
          "anyOf": [
            {
              "minimum": 1,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Worker processes (non-streaming datasets only).",
          "title": "Num Proc"
        },
        "counts_cache": {
          "anyOf": [
            {
              "$ref": "#/$defs/LocalPath"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Read counts from this JSON file if it exists, otherwise write them there, e.g. 'counts.json'."
        }
      },
      "title": "CorpusConfig",
      "type": "object"
    },
    "DatasetSpec": {
      "additionalProperties": false,
      "description": "Dataset to derive token frequencies from, on the Hub or on disk.\n\n`path` is what `datasets.load_dataset` takes first, so it is a Hub dataset id\n(`epfml/FineWeb2-HQ`), a loader name (`json`, `csv`, `parquet`, `text`) paired with\n`data_dir` or `data_files`, or a directory of data files to infer a loader from. A\ndirectory written by `save_to_disk` is the one thing `load_dataset` cannot read, so\nthat one is spelled `load_from_disk: true`.",
      "properties": {
        "path": {
          "$ref": "#/$defs/HubOrLocalPath",
          "description": "Hub dataset id, a loader name or a local directory, e.g. 'epfml/FineWeb2-HQ', 'json' or './data/corpus'."
        },
        "name": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Dataset configuration name, e.g. 'nld_Latn'.",
          "title": "Name"
        },
        "split": {
          "default": "train",
          "description": "Split expression, e.g. 'train' or even 'train[:1%]'.",
          "title": "Split",
          "type": "string"
        },
        "text_column": {
          "default": "text",
          "description": "Column holding the raw text, e.g. 'text' or 'content'.",
          "title": "Text Column",
          "type": "string"
        },
        "data_dir": {
          "anyOf": [
            {
              "$ref": "#/$defs/HubOrLocalPath"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Directory the loader named by 'path' reads its files from, e.g. './data/dutch'."
        },
        "data_files": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            {
              "additionalProperties": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  }
                ]
              },
              "type": "object"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Files the loader named by 'path' reads, as one path, a list of paths or globs, or a mapping of split name to either, e.g. './data/train-*.jsonl'.",
          "title": "Data Files"
        },
        "load_from_disk": {
          "default": false,
          "description": "Read 'path' with `datasets.load_from_disk`, for a directory written by `save_to_disk`. Such a dataset is already built, so it is never streamed.",
          "title": "Load From Disk",
          "type": "boolean"
        },
        "streaming": {
          "default": true,
          "description": "Stream instead of downloading the whole split.",
          "title": "Streaming",
          "type": "boolean"
        },
        "max_samples": {
          "anyOf": [
            {
              "minimum": 1,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Stop after this many examples, e.g. 200000.",
          "title": "Max Samples"
        },
        "revision": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Dataset revision to pin. Recommended for reproducibility.",
          "title": "Revision"
        },
        "weight": {
          "default": 1.0,
          "description": "Multiplier applied to this corpus' token counts, e.g. 2.0 to let a small in-domain corpus weigh as much as twice its size against a large generic one.",
          "exclusiveMinimum": 0,
          "title": "Weight",
          "type": "number"
        }
      },
      "required": [
        "path"
      ],
      "title": "DatasetSpec",
      "type": "object"
    },
    "EmbeddingTrimConfig": {
      "additionalProperties": false,
      "description": "How the model's embedding table and output head are resized.",
      "properties": {
        "pad_to_multiple_of": {
          "anyOf": [
            {
              "minimum": 1,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Pad the resized embedding matrix up to a multiple of this, for tensor-core alignment. See for instance https://developer.nvidia.com/blog/optimizing-gpu-performance-tensor-cores/#h.9yili3t5wcy5",
          "title": "Pad To Multiple Of"
        },
        "dtype": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Cast the model to this dtype, e.g. 'bfloat16'.",
          "title": "Dtype"
        },
        "device": {
          "default": "cpu",
          "description": "Device used while selecting embedding rows.",
          "title": "Device",
          "type": "string"
        },
        "auto_class": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "transformers class used to load the model, e.g. 'AutoModelForCausalLM'. By default the class named in the checkpoint's config.architectures is used.",
          "title": "Auto Class"
        }
      },
      "title": "EmbeddingTrimConfig",
      "type": "object"
    },
    "HubOrLocalPath": {
      "type": "string"
    },
    "LocalPath": {
      "format": "path",
      "type": "string"
    },
    "SelectionConfig": {
      "additionalProperties": false,
      "description": "Which tokens survive the trim.\n\nThe criteria are the union of `structural`, `requested` and `corpus`, then the\n`max_vocab_size` cap is applied to the remainder. Structural tokens (added/special\ntokens, the unk token, and the byte alphabet of byte-level tokenizers) are always\nkept and never counted against a criterion, because dropping them breaks the tokenizer.",
      "properties": {
        "coverage": {
          "anyOf": [
            {
              "exclusiveMinimum": 0.0,
              "maximum": 1.0,
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Keep the most frequent tokens until they cover this fraction of corpus occurrences, e.g. 0.9999. Values below about 0.99 trim far harder than you might expect!",
          "title": "Coverage"
        },
        "top_k": {
          "anyOf": [
            {
              "minimum": 1,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Keep at most this many corpus-derived tokens, e.g. 32000.",
          "title": "Top K"
        },
        "min_count": {
          "anyOf": [
            {
              "minimum": 1,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Keep tokens seen at least this many times, e.g. 10. 1 would mean: keep everything the corpus used.",
          "title": "Min Count"
        },
        "max_vocab_size": {
          "anyOf": [
            {
              "minimum": 1,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Hard cap on the final vocabulary: least-frequent non-structural tokens are dropped to fit. E.g. 32000. It cannot go below the structural tokens, of which a byte-level BPE has at least 256.",
          "title": "Max Vocab Size"
        },
        "keep_presets": {
          "description": "Named presets to keep, e.g. 'alphanumeric'. Some presets are always included. Run `trimbed presets` to see the available presets.",
          "items": {
            "type": "string"
          },
          "title": "Keep Presets",
          "type": "array"
        },
        "keep_tokens": {
          "description": "Literal token strings to keep, written as the vocabulary stores them, so '\u0120de' rather than ' de' for a byte-level tokenizer.",
          "items": {
            "type": "string"
          },
          "title": "Keep Tokens",
          "type": "array"
        },
        "keep_token_ids": {
          "description": "Literal token ids to keep, e.g. [151643].",
          "items": {
            "type": "integer"
          },
          "title": "Keep Token Ids",
          "type": "array"
        },
        "keep_token_files": {
          "description": "Text files with one token per line. Blank lines and '#' comments are ignored.",
          "items": {
            "$ref": "#/$defs/LocalPath"
          },
          "title": "Keep Token Files",
          "type": "array"
        },
        "keep_patterns": {
          "description": "Regular expressions matched against each token's decoded surface form, e.g. '^\\d+$' for numbers or '[\u00c0-\u00ff]' for accented Latin characters. The surface form is matched, so a pattern is written against ' de' rather than the Unicode representation '\u0120de'.",
          "items": {
            "type": "string"
          },
          "title": "Keep Patterns",
          "type": "array"
        },
        "keep_texts": {
          "description": "Texts to keep encodable as they are now. E.g. a representative prompt, or the instruction format an SFT run will use.",
          "items": {
            "type": "string"
          },
          "title": "Keep Texts",
          "type": "array"
        },
        "keep_chat_template": {
          "default": true,
          "description": "Keep the tokens the chat template's own words need, so prompts do not fragment.",
          "title": "Keep Chat Template",
          "type": "boolean"
        }
      },
      "title": "SelectionConfig",
      "type": "object"
    }
  },
  "additionalProperties": false,
  "description": "Top-level configuration for one trimming run.",
  "properties": {
    "model": {
      "$ref": "#/$defs/HubOrLocalPath",
      "description": "Hub model id or local path whose tokenizer is trimmed, e.g. 'codefuse-ai/F2LLM-v2-160M'."
    },
    "revision": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Model revision to pin, e.g. a commit sha. Recommended for reproducibility.",
      "title": "Revision"
    },
    "output_dir": {
      "$ref": "#/$defs/LocalPath",
      "default": "trimmed",
      "description": "Directory the trimmed artefacts are written to, e.g. 'trimmed/f2llm-nl'."
    },
    "trim_model": {
      "default": true,
      "description": "Also trim the model's embeddings, not just the tokenizer.",
      "title": "Trim Model",
      "type": "boolean"
    },
    "overwrite": {
      "default": false,
      "description": "Allow (over)writing into a non-empty output directory.",
      "title": "Overwrite",
      "type": "boolean"
    },
    "trust_remote_code": {
      "default": false,
      "description": "Allow custom modelling/tokenizer code from the checkpoint, as gte and jina models need.",
      "title": "Trust Remote Code",
      "type": "boolean"
    },
    "verify": {
      "default": true,
      "description": "Re-encode sample texts to prove the trim is non-destructive and behaviour-preserving.",
      "title": "Verify",
      "type": "boolean"
    },
    "verify_samples": {
      "default": 256,
      "description": "How many corpus texts to verify the trimmed tokenizer against. Also the pool the model comparison draws from, so it cannot be smaller than 'verify_model_samples'.",
      "minimum": 1,
      "title": "Verify Samples",
      "type": "integer"
    },
    "verify_model": {
      "default": true,
      "description": "Also run both models on sample texts and compare their outputs.",
      "title": "Verify Model",
      "type": "boolean"
    },
    "verify_model_samples": {
      "default": 8,
      "description": "How many texts the model comparison runs on, taken from the front of the tokenizer verification sample. At most 'verify_samples'.",
      "minimum": 1,
      "title": "Verify Model Samples",
      "type": "integer"
    },
    "verify_tolerance": {
      "default": 1e-05,
      "description": "Largest absolute output difference the model comparison accepts.",
      "exclusiveMinimum": 0,
      "title": "Verify Tolerance",
      "type": "number"
    },
    "copy_sidecar_files": {
      "default": true,
      "description": "Copy vocabulary-independent files (sentence-transformers modules and the like) from the source.",
      "title": "Copy Sidecar Files",
      "type": "boolean"
    },
    "sidecar_patterns": {
      "description": "Glob patterns, relative to the source repository, selecting which files to copy, e.g. 'modules.json' and '[0-9]_*/*' for the numbered sentence-transformers modules. Defaults to all sentence-transformers related files.",
      "items": {
        "type": "string"
      },
      "title": "Sidecar Patterns",
      "type": "array"
    },
    "seed": {
      "default": 0,
      "description": "Seed for corpus sampling.",
      "title": "Seed",
      "type": "integer"
    },
    "corpus": {
      "$ref": "#/$defs/CorpusConfig"
    },
    "selection": {
      "$ref": "#/$defs/SelectionConfig"
    },
    "embeddings": {
      "$ref": "#/$defs/EmbeddingTrimConfig"
    }
  },
  "required": [
    "model"
  ],
  "title": "TrimConfig",
  "type": "object"
}

Fields:

Validators:

  • _check_the_checkpoint_reference
  • _require_a_selection_source
  • _fit_the_model_sample_inside_the_tokenizer_sample
  • _require_a_criterion_with_a_corpus

model pydantic-field

Hub model id or local path whose tokenizer is trimmed, e.g. 'codefuse-ai/F2LLM-v2-160M'.

revision pydantic-field

revision: str | None = None

Model revision to pin, e.g. a commit sha. Recommended for reproducibility.

output_dir pydantic-field

output_dir: LocalPath = Path('trimmed')

Directory the trimmed artefacts are written to, e.g. 'trimmed/f2llm-nl'.

trim_model pydantic-field

trim_model: bool = True

Also trim the model's embeddings, not just the tokenizer.

overwrite pydantic-field

overwrite: bool = False

Allow (over)writing into a non-empty output directory.

trust_remote_code pydantic-field

trust_remote_code: bool = False

Allow custom modelling/tokenizer code from the checkpoint, as gte and jina models need.

verify pydantic-field

verify: bool = True

Re-encode sample texts to prove the trim is non-destructive and behaviour-preserving.

verify_samples pydantic-field

verify_samples: int = 256

How many corpus texts to verify the trimmed tokenizer against. Also the pool the model comparison draws from, so it cannot be smaller than 'verify_model_samples'.

verify_model pydantic-field

verify_model: bool = True

Also run both models on sample texts and compare their outputs.

verify_model_samples pydantic-field

verify_model_samples: int = 8

How many texts the model comparison runs on, taken from the front of the tokenizer verification sample. At most 'verify_samples'.

verify_tolerance pydantic-field

verify_tolerance: float = 1e-05

Largest absolute output difference the model comparison accepts.

copy_sidecar_files pydantic-field

copy_sidecar_files: bool = True

Copy vocabulary-independent files (sentence-transformers modules and the like) from the source.

sidecar_patterns pydantic-field

sidecar_patterns: list[str]

Glob patterns, relative to the source repository, selecting which files to copy, e.g. 'modules.json' and '[0-9]_/' for the numbered sentence-transformers modules. Defaults to all sentence-transformers related files.

seed pydantic-field

seed: int = 0

Seed for corpus sampling.

from_yaml classmethod

from_yaml(path: str | Path) -> Self

Load a configuration from a YAML file.

Parameters:

Name Type Description Default
path str | Path

Path to the YAML document, e.g. "my_config.yaml".

required

Returns:

Type Description
Self

The validated configuration.

Raises:

Type Description
ValueError

If the document is not a mapping, e.g. a file holding a bare list.

with_overrides

with_overrides(overrides: dict[str, Any]) -> Self

Return a copy with dotted-path overrides applied and revalidated.

A path segment addressing a list is an index, so a single dataset in a mixture can be tuned without restating the rest: corpus.datasets.0.max_samples.

Parameters:

Name Type Description Default
overrides dict[str, Any]

Mapping of dotted paths to values, e.g. {"selection.top_k": 5000}. Entries whose value is None are ignored, so unset flags are no-ops.

required

Returns:

Type Description
Self

A new, validated configuration.

Raises:

Type Description
ValueError

If a segment indexing a list is not an integer, or is out of range.

to_yaml

to_yaml() -> str

Serialise the resolved configuration back to YAML, for provenance.

load_config

load_config(
    config_path: str | Path | None, model: str | None = None
) -> TrimConfig

Build a configuration from a YAML file, or from a bare model id.

The trimbed commands all accept --config and --model, and this is the shared resolution of the two. Overrides are deliberately not applied here, so a caller can merge flag-derived and key=value overrides in one TrimConfig.with_overrides call with a single precedence rule.

Parameters:

Name Type Description Default
config_path str | Path | None

Path to a YAML document, or None.

required
model str | None

Hub model id or local path, used when no YAML file is given, e.g. "codefuse-ai/F2LLM-v2-160M".

None

Returns:

Type Description
TrimConfig

The validated configuration.

Raises:

Type Description
ValueError

If neither a config file nor a model was supplied.

parse_overrides

parse_overrides(overrides: Sequence[str]) -> dict[str, Any]

Turn key.path=value strings into dotted-path overrides.

Values go through yaml.safe_load, so 5000 becomes an int, false a bool and [a, b] a list, while a bare word stays a string. null (or an empty one) resolves to None, which TrimConfig.with_overrides skips: fields cannot be unset from the command line.

Parameters:

Name Type Description Default
overrides Sequence[str]

Strings of the form key.path=value, e.g. ["selection.top_k=5000", "trim_model=false", "corpus.datasets.0.max_samples=1000"].

required

Returns:

Type Description
dict[str, Any]

A mapping suitable for TrimConfig.with_overrides, e.g. {"selection.top_k": 5000, "trim_model": False}.

Raises:

Type Description
ValueError

If an entry contains no =, e.g. a bare "top_k".