Entrypoint contracts¶
Every component is selected by a dotted module path in the config, imported at runtime. There is no registry and no decorator: to add a component, write a module that exposes the expected name and point a config field at it.
| Config field | Must expose | Contract |
|---|---|---|
main_runner |
Trainer |
A BaseTrainer subclass. Usually overrides only prep_batch. |
model_name + model_params |
Model |
Model(**model_params). Its forward returns a dict. |
train_ds_name / valid_ds_name / test_ds_name + *_ds_params |
get_ds |
get_ds(ds_params, transform) -> (dataloader, info). info['length'] is required. An engine declared via eval_specs() reads its own |
aug_name + aug_params |
Transformation |
Transformation(**aug_params), any callable. Built once and passed to every split. |
criterion_name + criterion_params |
Loss |
An nn.Module Loss(**criterion_params) whose forward(y_pred, target, iteration=None) returns (total, {'loss_ |
optimizer_name + optimizer_params |
get_optimizer |
get_optimizer(model, **optimizer_params) -> the object the trainer holds as its optimizer. It does NOT have to subclass torch.optim.Optimizer: the framework only ever asks it for param_groups (LR logging), state_dict and load_state_dict (checkpointing), plus zero_grad/step if you use the default train_step. So one object holding two real optimizers is how you train a GAN: there is no second optimizer field, and none is needed. See examples/gan/optimizer/dual_optimizer.py. |
lr_scheduler + lr_scheduler_params |
get_scheduler |
get_scheduler(cfg, train_dl, optimizer, engines) -> (scheduler, engine_name, event). engines is the whole dict, so engine_name may be any engine you declared, not just 'trainer'/'evaluator'. |
{train,val,tester}_metrics[<name>].cls_name + params |
get_metric |
get_metric(engine_type, info, **params) -> an ignite Metric. An engine declared via eval_specs() reads its own |
*_ds_params.collate_fn.cls_name + params |
get_collate_fn |
get_collate_fn(**params) -> a callable torch passes a list of samples. Optional: collate_fn also takes a plain callable directly, which is what a get_ds usually has in hand. The dotted form is what lets a CONFIG choose one, which a variable-length task needs. |
*_ds_params.sampler_params.cls_name + params |
get_sampler |
get_sampler(dataset, **params) -> a torch Sampler. |
logger_name[<entry>] |
Backend |
Backend(cfg) exposing log(metrics, step=None, epoch=None), watch(model) and finish(failed=False). Subclass gatle_ignite.callbacks.logging.Backend to inherit no-op watch/finish and write only log; a standalone class must define all three, because finish() is called after every run and watch() whenever cfg.watch_grad is set. The one exception to the dotted-path rule: logger_name is a list of enabled sinks, not a component field. A short name resolves to a builtin (gatle_ignite.callbacks.backends.*); any other entry is a dotted path to your own module. "pbar" is not a backend at all: it is a progress-bar flag the trainer reads. Constructed on rank 0 only, and only if named, so an unused sink's dependency is never imported. |
One exception
cfg.logger_name is a list of enabled sinks and does accept short names for the builtins. See Logging.
A path that does not import, or a module missing its entrypoint, raises ConfigError naming the config field at fault and listing what the module actually exports.