Config sections¶
JobConfig aggregates ten typed sub-configs. Each one lives in its own
module under
kempnerforge/config/
and declares its fields with dataclass defaults. TOML sections map
one-to-one onto these dataclass attributes:
[model] # → config.model (ModelConfig)
[train] # → config.train (TrainConfig)
[optimizer] # → config.optimizer
[scheduler] # → config.scheduler
[data] # → config.data
[eval] # → config.eval
[distributed] # → config.distributed
[checkpoint] # → config.checkpoint
[metrics] # → config.metrics
[profiling] # → config.profiling
JobConfig¶
Owns the ten sub-configs and the cross-section validate method.
kempnerforge/config/job.py.
Field |
Type |
Purpose |
|---|---|---|
|
|
architecture + MoE knobs |
|
|
loop-level hyperparameters |
|
|
registry key + LR + betas + optimizer-specific knobs |
|
|
LR schedule shape and warmup |
|
|
dataset sources, mixing, annealing |
|
|
in-loop eval cadence and data source |
|
|
parallelism dims, NCCL timeout |
|
|
DCP save cadence, retention, resume path |
|
|
logging cadence and backends |
|
|
torch.profiler window and trace dir |
|
|
module paths imported before the config is built, for their registry side effects — see Registry |
plugins is a top-level key, not a section: plugins = ["pkg.module"].
[model] — ModelConfig¶
Architecture hyperparameters and MoE knobs.
kempnerforge/config/model.py.
Dense¶
Field |
Type |
Default |
Purpose |
|---|---|---|---|
|
|
|
hidden size |
|
|
|
number of transformer blocks |
|
|
|
attention heads |
|
|
|
GQA: |
|
|
|
|
|
|
|
embedding table size |
|
|
|
scales Llama-style |
|
|
|
hard-override the computed FFN width |
|
|
|
registry key for norm builder |
|
|
|
norm epsilon |
|
|
|
MLP activation ( |
|
|
|
RoPE table length; |
|
|
|
RoPE frequency base |
|
|
|
share embedding and output-head weight |
|
|
|
RMSNorm over Q/K per head before RoPE |
|
|
|
weight-init std (GPT-2 / Llama convention) |
|
|
|
|
|
|
|
one of |
|
|
|
|
MoE (all defaults produce a dense model)¶
Field |
Type |
Default |
Purpose |
|---|---|---|---|
|
|
|
|
|
|
|
experts selected per token |
|
|
|
MoE every N layers (1=all, 2=alternating) |
|
|
|
|
|
|
|
shared experts that always process every token |
|
|
|
coefficient in training loss |
|
|
|
|
|
|
|
sequence-level balance loss (0 = off) |
|
|
|
per-expert gradient normalization |
|
|
|
|
|
|
|
pack expert weights into one tensor per projection |
|
|
|
expert FFN hidden width relative to dense ( |
|
|
|
router-logit z-loss coefficient ( |
Computed properties: is_moe, head_dim, computed_ffn_hidden_dim,
computed_expert_ffn_hidden_dim, num_params_estimate.
[train] — TrainConfig¶
Training-loop hyperparameters.
kempnerforge/config/training.py.
Field |
Type |
Default |
Purpose |
|---|---|---|---|
|
|
|
per-device micro-batch size |
|
|
|
tokens per sequence |
|
|
|
training-loop termination |
|
|
|
microbatches per optimizer step |
|
|
|
|
|
|
|
torch/numpy/python RNG seed |
|
|
|
RNG seed for data and batch order; |
|
|
|
wrap the model with |
|
|
|
compute dtype, and the master-weight dtype unless |
|
|
|
keep parameters, gradients and optimizer state in fp32 and compute in |
|
|
|
run fp32 matmuls (a frozen fp32 vision encoder, |
|
|
|
AC policy |
|
|
|
|
|
|
|
logit-magnitude regularizer (PaLM uses |
|
|
|
chunk size for |
|
|
|
compute |
|
|
|
graceful shutdown timeout before forced exit |
|
|
|
NCCL liveness all-reduce every N steps ( |
Computed properties: param_dtype (compute dtype), master_dtype (storage dtype: fp32 with
fp32_master_weights, otherwise param_dtype), is_fp8.
[optimizer] — OptimizerConfig¶
Optimizer settings. name picks the registry builder; the other fields
are shared (AdamW/Lion) or optimizer-specific.
kempnerforge/config/optimizer.py.
Field |
Type |
Default |
Purpose |
|---|---|---|---|
|
|
|
one of |
|
|
|
peak learning rate |
|
|
|
decoupled weight decay, applied to the group |
|
|
|
AdamW / Lion momenta |
|
|
|
numerical safety (AdamW) |
|
|
|
use fused AdamW when available |
|
|
|
Muon momentum coefficient |
|
|
|
Newton–Schulz iterations for Muon |
|
|
|
LR for the parameters Muon leaves to its AdamW fallback; |
|
|
|
Orthogonalize the Nesterov look-ahead instead of the momentum buffer |
|
|
|
Factor on each orthogonalized update |
|
|
|
Newton–Schulz on each rank’s shard, or on the full matrix |
|
|
|
Orthogonalize MoE router gates with Muon instead of its AdamW fallback |
|
|
|
internal warmup for schedule-free |
|
|
|
which parameters are decayed; |
|
|
|
per-module learning rates: each |
[scheduler] — SchedulerConfig¶
LR schedule shape and warmup.
kempnerforge/config/scheduler.py.
Field |
Type |
Default |
Purpose |
|---|---|---|---|
|
|
|
|
|
|
|
linear warmup length |
|
|
|
LR factor the warmup starts from (torch |
|
|
|
|
|
|
|
floor = |
|
|
|
WSD: steps at constant LR between warmup and decay |
|
|
|
WSD cooldown shape |
|
|
|
REX exponent: |
[data] — DataConfig¶
Single dataset, HuggingFace source, or mixture; optional phase schedule.
kempnerforge/config/data.py.
Field |
Type |
Default |
Purpose |
|---|---|---|---|
|
|
|
directory of pre-tokenized shards |
|
|
|
glob inside |
|
|
|
dtype of raw |
|
|
|
path or HF id for the tokenizer |
|
|
|
DataLoader workers |
|
|
|
DataLoader pin memory |
|
|
|
DataLoader prefetch factor |
|
|
|
HF dataset id (e.g. |
|
|
|
HF dataset config (e.g. |
|
|
|
HF split |
|
|
|
field to tokenize |
|
|
|
VLM only: image column |
|
|
|
VLM only: prompt column ( |
|
|
|
VLM only: target square image size |
|
|
|
use |
|
|
|
document-aware packing with cross-doc isolation (feeds |
|
|
|
multi-dataset mixture (overrides |
|
|
|
weight scaling; |
|
|
|
multi-phase schedule with weight/LR transitions |
|
|
|
syntactic sugar for a common 2-phase annealing pattern ( |
|
|
|
per-dataset weights applied at |
DatasetSource¶
Field |
Type |
Default |
Purpose |
|---|---|---|---|
|
|
|
pre-tokenized directory |
|
|
|
relative sampling weight (must be |
|
|
|
name for per-dataset metrics (auto-derived if empty) |
|
|
|
HF dataset id |
|
|
|
HF dataset config |
|
|
|
dtype of this source’s |
Either path or hf_name must be set per source.
TrainingPhase¶
Field |
Type |
Default |
Purpose |
|---|---|---|---|
|
|
|
step at which the phase activates |
|
|
|
per-dataset weights for this phase |
|
|
|
multiplier applied to scheduler LR |
phases[*].start_step must be strictly increasing; phases and
anneal_start_step are mutually exclusive.
[eval] — EvalConfig¶
In-loop evaluation. Disabled by default.
kempnerforge/config/eval.py.
Field |
Type |
Default |
Purpose |
|---|---|---|---|
|
|
|
gate in-loop eval |
|
|
|
eval every N training steps |
|
|
|
eval batches per evaluation; under pipeline parallelism a multiple of |
|
|
|
pre-tokenized eval shards |
|
|
|
glob inside |
|
|
|
dtype of raw |
|
|
|
HF dataset id |
|
|
|
HF dataset config |
|
|
|
HF split |
If enabled=True, at least one of dataset_path / hf_dataset_name
must be set; validate() rejects the combination otherwise.
[distributed] — DistributedConfig¶
Parallelism dimensions and NCCL settings.
kempnerforge/config/distributed.py.
Field |
Type |
Default |
Purpose |
|---|---|---|---|
|
|
|
FSDP shard degree; |
|
|
|
replicates the |
|
|
|
tensor parallel |
|
|
|
pipeline parallel |
|
|
|
pipeline schedule |
|
|
|
context parallel; reserved, not implemented, must be |
|
|
|
expert parallel (MoE only) |
|
|
|
NCCL collective timeout |
|
|
|
|
The product dp_replicate × dp_shard × tp × pp × cp × ep must equal
world_size. Methods: validate_world_size(ws), resolve(ws).
[checkpoint] — CheckpointConfig¶
DCP-based checkpointing.
kempnerforge/config/checkpoint.py.
Field |
Type |
Default |
Purpose |
|---|---|---|---|
|
|
|
root directory for |
|
|
|
save every N steps (outside any |
|
|
|
optional dense save phase — see |
|
|
|
DCP async-save mode |
|
|
|
retain the most recent N checkpoints ( |
|
|
|
checkpoint for training to start from while |
|
|
|
dtype for HF exports via |
|
|
|
state to skip when warm-starting from |
|
|
|
load a checkpoint whose VLM freeze metadata disagrees with the configured freeze specs, downgrading the error to a warning |
|
|
|
resume when the saved per-rank dataloader/RNG state does not fit this run (changed world size or data-parallel layout, unreadable or incomplete envelope): discard that state on every rank with a warning instead of raising, so data order and random streams restart fresh while step, model, optimizer and scheduler continue (see Resharding) |
[checkpoint.dyn_ckpt_window] — DynamicCheckpointWindow¶
Opt-in dense save phase. Inside [start, stop] a registered strategy decides
which steps to save; outside the window the regular interval cadence applies.
Steps saved by the strategy are exempt from keep_last_n retention, so a
finite keep_last_n rotates only the later interval checkpoints — the dense
window checkpoints are never pruned. Useful for inspecting early-training
dynamics at fine granularity.
Field |
Type |
Default |
Purpose |
|---|---|---|---|
|
|
|
first step of the dense window; |
|
|
|
last step of the dense window |
|
|
|
name of a registered strategy (see below) |
Example TOML:
# Off by default — interval cadence only:
[checkpoint]
interval = 1000
keep_last_n = 3
# Opt in with defaults (start=0, stop=512, strategy="power2"):
[checkpoint.dyn_ckpt_window]
# Customize:
[checkpoint.dyn_ckpt_window]
start = 0
stop = 1024
strategy = "power2"
Dyn_ckpt strategies¶
A strategy is a Callable[[DynamicCheckpointWindow, int], bool] registered via
@registry.register_dyn_ckpt_strategy("name") (see
kempnerforge/config/registry.py).
The strategy receives the window and the current training step and returns
True iff the step should be saved. The registry must be populated before
config load — either by kempnerforge itself (the default "power2" is
registered in kempnerforge/config/checkpoint.py) or by an explicit import
of the user’s module.
Name |
Behavior |
|---|---|
|
save at |
[metrics] — MetricsConfig¶
Logging cadence and backend toggles. The backends are independent, so any combination can be
enabled in one run config.
kempnerforge/config/metrics.py.
Field |
Type |
Default |
Purpose |
|---|---|---|---|
|
|
|
log every N steps (stdout + enabled backends) |
|
|
|
turn on WandB backend |
|
|
|
turn on TensorBoard backend |
|
|
|
WandB project name |
|
|
|
|
|
|
|
restored from checkpoint on resume; empty = new run |
|
|
|
TB log directory |
|
|
|
turn on MLflow backend (Databricks or local) |
|
|
|
tracking URI; |
|
|
|
absolute workspace path on Databricks; |
|
|
|
|
|
|
|
run description (Markdown, the |
|
|
|
extra run tags, set on a new run after the automatic ones; keys and values must be non-empty strings |
|
|
|
restored from checkpoint on resume; empty = new run |
|
|
|
sample CPU/GPU/memory on a background thread |
|
|
|
seconds between system-metric samples |
|
|
|
register each committed checkpoint as an MLflow external model on the background worker; |
Credentials never go in config. The auth routes, the URI and experiment resolution, and the bounds on tracking calls are on the MLflow backend page.
[profiling] — ProfilingConfig¶
torch.profiler window.
kempnerforge/config/profiling.py.
Field |
Type |
Default |
Purpose |
|---|---|---|---|
|
|
|
run the profiler during the loop |
|
|
|
first step recorded |
|
|
|
last step recorded (must be |
|
|
|
output directory for Chrome/Perfetto traces |
[adapter]: AdapterConfig¶
The VLM connector that maps vision-encoder features into the transformer’s
embedding space. A run that sets [vlm] without [adapter] gets these
defaults.
kempnerforge/config/adapter.py.
Field |
Type |
Default |
Used by |
Purpose |
|---|---|---|---|---|
|
|
|
all |
adapter registry key: |
|
|
|
|
MLP hidden width. |
|
|
|
|
|
|
|
|
|
norm-registry key for a norm ahead of the MLP, over the vision features ( |
|
|
|
|
pooling window side, e.g. |
|
|
|
|
attention heads; must divide the vision feature dim |
A field outside the selected adapter’s “Used by” entries must keep its
default, or the config fails to load with an error naming the field and the
adapter type. The column follows each adapter’s builder parameters, which
avgpool narrows by hidden_dim with the accepts it registers; a plugin
adapter’s come from its own builder (see
Registry).
An avgpool connector with a 2×2 window and an RMSNorm + MLP head as wide as
its input (here a 1152-wide encoder):
[adapter]
type = "avgpool"
pool_window = 2
hidden_dim = 1152
pre_norm = "rmsnorm"
hidden_dim picks the avgpool head, and the head fixes the adapter’s
checkpoint keys. hidden_dim = 0 builds the single Linear, saved as
adapter.proj.weight and adapter.proj.bias. A positive hidden_dim builds
the MLP head, saved as adapter.proj.proj1.* and adapter.proj.proj2.*, plus
adapter.proj.ln_q.* when pre_norm is set. A checkpoint loads only into
the head it was saved with: the other head fails the load with Missing key in checkpoint state_dict naming one of its parameters. To resume a
checkpoint saved with the single Linear, set hidden_dim = 0 and leave
activation and pre_norm at their defaults.
A command-line override sets a value and never restores a default, so
switching adapter.type on the command line keeps every other field the TOML
sets. Reset the ones the new type does not use in the same command; an empty
value sets the empty string. For a TOML with type = "mlp_2layer",
hidden_dim = 2048 and pre_norm = "rmsnorm":
--adapter.type=attentional_pool --adapter.hidden_dim=0 --adapter.pre_norm=
The TOML is checked on its own before the overrides apply, so its fields must
fit its own type. A TOML with type = "attentional_pool" and
hidden_dim = 1152 fails to load even with --adapter.type=avgpool: set the
type and its fields in the same layer, both in the TOML or both on the
command line.
Where to read next¶
CLI overrides — reshape any of these fields from the command line.
Validation rules — what
__post_init__andvalidate(world_size)enforce.Registry — how the string keys above (
moe_router,norm_type,optimizer.name,scheduler.name,loss_fn,model_type) resolve to builders.