nvalchemi.training.ValidationConfig#
- pydantic model nvalchemi.training.ValidationConfig[source]#
Configuration for strategy-owned validation passes.
ValidationConfigis a plain, declarative data object that tells aTrainingStrategywhat validation data to evaluate, how often to evaluate it, and how to run the forward pass. You pass an instance to the strategy’svalidation_configargument; leaving that argumentNonedisables validation entirely. The strategy then drives validation itself — reading this config directly and running passes throughValidationLoopatTrainingStrategy.validate()— rather than dispatching validation through the hook system. To react to validation results, register a hook on theAFTER_VALIDATIONstage and read the summary fromctx.validation.validation_datamust be a re-iterable container (list,DataLoader,Dataset, …); a fresh iterator is drawn for every pass, so one-shot generators and bare iterators are rejected at construction time (see_ensure_reiterable_validation_data). The scheduling fieldsevery_n_epochsandevery_n_stepsare mutually exclusive: set at most one to control cadence, or leave both unset to run validation only at the end ofTrainingStrategy.run(). Whenvalidation_fnorloss_fnisNone, the strategy reuses its owntraining_fn/loss_fnwith the matching single-model or named-model call convention; a leaf loss passed here is normalized to aComposedLossFunction.The remaining fields tune inference behavior:
grad_modeselects the autograd policy ("auto"enables gradients only when a loss component reportsrequires_eval_grad=True),set_evaltoggles eval mode with restore,use_emadecides whether the strategy’sinference_model(EMA) weights replace live weights,use_mixed_precisionreuses a registeredMixedPrecisionHookautocast context, andbatch_callbackstreams per-batch predictions and losses to a custom sink.Examples
Validate on a held-out list of batches after every epoch, reusing the strategy’s own
training_fnandloss_fn:>>> from nvalchemi.training import ValidationConfig >>> config = ValidationConfig( ... validation_data=val_batches, ... every_n_epochs=1, ... )
Validate every 500 optimizer steps with an explicit validation loss and gradients enabled (e.g. force/stress evaluation that needs autograd):
>>> config = ValidationConfig( ... validation_data=val_loader, ... loss_fn=EnergyMSELoss() + ForceMSELoss(normalize_by_atom_count=True), ... every_n_steps=500, ... grad_mode="enabled", ... )
Evaluate EMA weights instead of the live model, then wire the config into a strategy:
>>> config = ValidationConfig( ... validation_data=[val_batch], ... loss_fn=EnergyMSELoss(), ... use_ema="always", ... grad_mode="enabled", ... ) >>> strategy = TrainingStrategy( ... models=model, ... optimizer_configs=optimizer_config, ... loss_fn=EnergyMSELoss(), ... num_steps=1000, ... training_fn=default_training_fn, ... validation_config=config, ... hooks=[EMAHook(model_key="main", decay=0.999)], ... )
Notes
every_n_epochsandevery_n_stepsare mutually exclusive; setting both raises at construction time. Both may be omitted, in which case validation runs once at the end of training.validation_datamust be re-iterable: generators/iterators are rejected because each pass restarts from the beginning.ValidationConfigdoes not participate in hook dispatch. It is read directly by the strategy; use anAFTER_VALIDATIONhook (readingctx.validation) for summary-level logging.
- field validation_data: Iterable[Batch] [Required]#
Re-iterable container (e.g.
list,DataLoader,Dataset) yieldingBatchinstances. The strategy re-iterates this on every validation pass; one-shot generators and bare iterators are rejected at construction time.- Constraints:
func = <function _ensure_reiterable_validation_data at 0xeb0b2465e480>
json_schema_input_type = typing.Any
- field validation_fn: Callable[[...], Any] | None = None#
Validation forward callable.
Nonemeans use the strategy’straining_fnwith the same single-model or named-model call convention.
- field loss_fn: ComposedLossFunction | None = None#
Validation loss function.
Nonemeans use the strategy’sloss_fn. Leaf losses are auto-normalized to aComposedLossFunctionviaas_composed_loss().
- field every_n_epochs: int | None = None#
Run validation after every n-th completed epoch. Mutually exclusive with
every_n_steps.- Constraints:
ge = 1
- field every_n_steps: int | None = None#
Run validation after every n-th completed optimizer step. Mutually exclusive with
every_n_epochs.- Constraints:
ge = 1
- field grad_mode: Literal['auto', 'enabled', 'disabled'] = 'auto'#
Autograd policy during validation.
"auto"enables gradients when any loss component hasrequires_eval_grad=Trueand disables them when all components reportFalse.
- field set_eval: bool = True#
If
True, set validation modules to eval mode and restore their original training modes afterward.
- field use_ema: Literal['auto', 'always', 'never'] = 'auto'#
Whether the strategy’s
inference_modelslot (populated by EMA) should replace live training weights for validation.
- field use_mixed_precision: Literal['auto', 'always', 'never'] = 'auto'#
Whether to reuse a registered
MixedPrecisionHookautocast context for validation inference.
- field batch_callback: BatchValidationCallback | None = None#
Optional user-supplied callable invoked once per validation batch with the batch, predictions, and per-batch loss output. Use it to stream per-sample diagnostics to a custom logging or storage backend.
Nonedisables per-batch callbacks. For epoch-level (summary) logging, register a hook on theAFTER_VALIDATIONstage and readctx.validationinstead.
- field name: str = 'validation'#
Name stored in the validation summary dictionary.
- Constraints:
min_length = 1