EveNet-Lite is a minimal, PyTorch-first training helper that keeps the EveNet model stack but trims away heavy trainers
or YAML-driven configuration. It exposes a small sklearn-like API (fit/predict/evaluate), a runner that wires up
distributed training automatically, and convenience tools for checkpointing, sampling, normalization, and pretrained
weight loading.
The repository is self contained; add the repo root to your PYTHONPATH or install in editable mode:
pip install -e .If you already have tensors prepared for objects/globals/mask, the runner wraps everything needed for a full
train/validate/evaluate cycle and detects DDP from standard torchrun environment variables:
import torch
from evenet_lite import run_evenet_lite_training
classifier = run_evenet_lite_training(
train_features={"x": X_train, "globals": G_train, "mask": M_train},
train_labels=y_train,
train_weights=w_train,
val_features={"x": X_val, "globals": G_val, "mask": M_val},
val_labels=y_val,
val_weights=w_val,
eval_features={"x": X_test, "globals": G_test, "mask": M_test},
eval_labels=y_test,
eval_weights=w_test,
class_labels=["background", "signal"],
sampler="weighted",
epochs=5,
batch_size=512,
checkpoint_path="./checkpoints",
save_top_k=2,
debug=True,
)
# The returned classifier is already fitted and carries the trained normalizer.
logits = classifier.predict({"x": X_infer, "globals": G_infer, "mask": M_infer})
metrics = classifier.evaluate({"x": X_eval, "globals": G_eval, "mask": M_eval}, y_eval)
classifier.save_checkpoint("./checkpoints/final.pt")You can train with per-event parameters (e.g., m_X and m_Y) and randomize background
values every step using ParameterRandomizationCallback. The pattern works with the
runner or your own loop; the only requirements are:
- Provide a
paramstensor with shape(N, num_params)alongside the usualx/globals/maskfeatures. Concatenate it intoglobalsbefore calling the runner so the model sees the expanded global dimension (and updateglobal_input_dimaccordingly). - Attach
ParameterRandomizationCallbackwhen fitting to resample background parameters each batch while leaving signal parameters intact. Optionally setmin_values/max_values(one value or a list per parameter); otherwise the callback infers bounds from the training set. Or setpool_from_signalto sample directly from signal pool (uniformly sampled from all discreted parameter combinations in the signal events). - Keep validation randomization on (default) to match training, or set
apply_to_validation=Falseif you prefer fixed parameters there. Evaluation is untouched.
Minimal usage sketch with run_evenet_lite_training:
from evenet_lite import run_evenet_lite_training
from evenet_lite.callbacks import ParameterRandomizationCallback
# globals_with_params = torch.cat([globals, params], dim=1)
callbacks = [ParameterRandomizationCallback(min_values=[300, 500], max_values=[800, 1200])]
classifier = run_evenet_lite_training(
train_features={"x": X_train, "globals": globals_with_params, "mask": M_train, "params": params_train},
train_labels=y_train,
val_features={"x": X_val, "globals": globals_val_with_params, "mask": M_val, "params": params_val},
val_labels=y_val,
callbacks=callbacks,
global_input_dim=globals_with_params.shape[1],
)- Detects distributed environments (
WORLD_SIZE,LOCAL_RANK) and pins the appropriate CUDA device when available. - Builds an
EvenetLiteClassifierwith optional pretrained weights and logging level. - Injects normalization automatically unless a custom
NormalizationCallbackis supplied. - Forwards checkpointing, early stopping, sampler, and evaluation options to the classifier.
- Returns the fitted classifier so you can immediately call
predict,evaluate, orsave_checkpoint.
Prefer to assemble the pieces yourself? You can directly instantiate the classifier, call fit, and run
evaluation/prediction without the runner.
import torch
from evenet_lite import EvenetLiteClassifier
# Build the classifier (uses default EveNetLite backbone if none is provided)
clf = EvenetLiteClassifier(
class_labels=["background", "signal"],
device="auto", # cpu, cuda, or auto-detect
lr=1e-3,
weight_decay=0.01,
grad_clip=1.0,
pretrained=True, # load HF weights by default
)
# Fit
clf.fit(
train_data=({"x": X_train, "globals": G_train, "mask": M_train}, y_train, w_train),
val_data=({"x": X_val, "globals": G_val, "mask": M_val}, y_val, w_val),
feature_names={"x": obj_feature_names, "globals": global_feature_names},
epochs=10,
batch_size=256,
sampler="weighted",
checkpoint_path="./checkpoints",
save_top_k=1,
)
# Evaluate / predict
val_metrics = clf.evaluate({"x": X_val, "globals": G_val, "mask": M_val}, y_val, w_val)
logits = clf.predict({"x": X_test, "globals": G_test, "mask": M_test})
# Checkpointing
clf.save_checkpoint("./checkpoints/latest.pt")
# Later
restored = EvenetLiteClassifier(class_labels=["background", "signal"])
restored.load_checkpoint("./checkpoints/latest.pt",
feature_names={"x": obj_feature_names, "globals": global_feature_names})Input tensors follow an xgboost-like contract and are provided directly to the classifier or runner:
features = {
"x": torch.Tensor[N, M, F], # per-object features
"globals": torch.Tensor[N, G], # event-level features
"mask": torch.Tensor[N, M], # padding mask
}
labels = torch.Tensor[N] # class indices
weights = torch.Tensor[N] | None # optional per-example weightsFeature names passed to fit (feature_names={"x": [...], "globals": [...]}) should align with the keys above so the
normalizer can match statistics to columns.
Pass class_labels as an explicit head dictionary when one backbone should train multiple classification heads:
class_labels = {
"cls1": {"name": ["a", "b", "c"], "lambda": 1.0},
"cls2": {"name": ["a", "c"], "lambda": 0.5},
}
train_labels = {
"cls1": y_train_cls1,
"cls2": y_train_cls2,
}
# Use -100 for rows that should not train or score a given head.
train_labels["cls1"][cls2_only_rows] = -100
clf = EvenetLiteClassifier(
class_labels=class_labels,
loss_gamma={"cls1": 0.0, "cls2": 2.0},
ignore_index=-100,
)
clf.fit(
train_data=(train_features, train_labels, train_weights),
val_data=(val_features, {"cls1": y_val_cls1, "cls2": y_val_cls2}, val_weights),
physics_metric_config={"cls1": {"SIC_base": ["a"]}, "cls2": {}},
)All multi-head dictionaries must use the same head names. train_labels, val_labels, eval_labels,
loss_gamma, and non-empty physics_metric_config are validated against class_labels and abort on mismatch.
Labels equal to ignore_index are skipped per head in validation, loss, metrics, plots, and physics metrics.
Metrics and W&B logs are prefixed by head name, e.g. cls1/accuracy and cls2/metric-AUC/val_weighted.
Legacy list class_labels keeps the previous single-head behavior.
The tables below summarize the most-used entrypoints and their arguments. Defaults match the inline values in code.
| Argument | Default | Description |
|---|---|---|
class_labels |
required | Ordered class names, or a head dictionary head -> {"name": [...], "lambda": weight}. |
device |
"auto" |
Chooses CUDA when available; otherwise CPU. |
lr |
[1e-3, 3e-4, 1e-4] |
Learning rates assigned per optimizer group. |
weight_decay |
[0.01, 0.01, 0.01] |
Weight decay values aligned with the learning-rate groups. |
model |
None |
Custom EveNet model; defaults to EveNetLite built from config/default_network_config.yaml. |
optimizer_fn / scheduler_fn |
None |
Factories for custom optimizer or scheduler. |
grad_clip |
None |
Max gradient norm when set. |
module_lists |
[["Classification"], ["ObjectEncoder"], ["PET", "GlobalEmbedding"]] |
Modules assigned to each optimizer group (groups processed in order). |
warmup_epochs / warmup_ratio / warmup_start_factor |
1 / 0.1 / 0.1 |
Linear warmup configuration. |
min_lr |
0.0 |
Scheduler floor learning rate. |
global_input_dim / sequential_input_dim |
10 / 7 |
Input feature dimensions for the default backbone. |
use_wandb / wandb |
False / None |
Enable Weights & Biases with optional init kwargs. |
log_level |
logging.INFO |
Root logging level when constructing the classifier. |
pretrained |
False |
When True, soft-loads weights (default HF repo/filename). |
pretrained_source |
"hf" |
"hf" for Hugging Face hub or "local" for a provided path. |
pretrained_path / pretrained_repo_id / pretrained_filename / pretrained_cache_dir |
varies | Location details for pretrained checkpoints. |
num_workers |
0 | Number of processes passing to pytorch DataLoader |
loss_gamma |
0.0 |
Focal-loss gamma; use head -> gamma when class_labels is a multi-head dictionary. |
ignore_index |
-100 |
Label value skipped per head during validation, loss, metrics, plots, and physics metrics. |
| Argument | Default | Description |
|---|---|---|
train_data |
required | Tuple (features, labels, weights) for training. |
val_data |
None |
Optional validation tuple with same structure as training. |
feature_names |
Defaults to classifier presets | Mapping of feature group to column names for normalization. |
normalization_rules |
Defaults to classifier presets | Per-feature normalization strategy (log_normalize, normalize, etc.). |
normalization_stats |
None |
Optional precomputed means/stds per feature group; missing values default to mean 0/std 1. |
callbacks |
None |
Additional callbacks (normalization is auto-inserted if absent). |
epochs |
10 |
Number of training epochs. |
batch_size |
256 |
Mini-batch size. |
sampler |
None |
Sampler name ("weighted" enables distributed-safe weighted sampler). |
epoch_size |
None |
Number of samples per epoch when using a sampler. |
checkpoint_path / resume_from |
None |
Directory or filename for checkpoints and optional resume path. |
checkpoint_every |
1 |
Frequency (epochs) for periodic checkpoints when save_top_k == 0. |
save_top_k |
0 |
Keep best-k checkpoints ranked by monitor_metric. |
monitor_metric / minimize_metric |
"val_loss" / True |
Metric and direction for checkpoint ranking. |
early_stop_metric / early_stop_minimize / early_stop_patience |
"val_loss" / True / 0 |
Early stopping configuration (disabled when patience is 0). |
eval_data |
None |
Optional test tuple evaluated after training. |
eval_output_path |
None |
Path to save evaluation outputs when provided. |
eval_batch_size |
None |
Batch size for evaluation (falls back to training batch size). |
physics_metric_config |
None |
Optional calculate_physics_metrics keyword overrides; use head -> config for multi-head runs. |
debug |
False |
Enables verbose DebugCallback logging and diagnostics. |
predict(features, batch_size=256): returns logits using the stored normalizer, or ahead -> tensordictionary for multi-head classifiers; requires thatfitorload_checkpointhas been called.evaluate(features, labels, weights=None, batch_size=256): computes weighted classification metrics, with binary physics metrics added only for two-class tasks.
| Argument | Default | Description |
|---|---|---|
train_features / train_labels / train_weights |
required / required / None |
Training tensors and optional weights. |
class_labels |
required | Ordered class names or a multi-head dictionary passed to the classifier. |
val_features / val_labels / val_weights |
None |
Optional validation tensors and weights. |
feature_names |
None |
Feature column names forwarded to the classifier. |
normalization_rules |
None |
Per-feature normalization overrides. |
normalization_stats |
None |
Optional precomputed means/stds per feature group; missing values default to mean 0/std 1. |
callbacks |
None |
Extra callbacks (normalization auto-added if missing). |
sampler / epoch_size |
None |
Sampling strategy and epoch size when sampling. |
epochs / batch_size |
10 / 256 |
Training loop configuration. |
checkpoint_path / resume_from |
None |
Checkpoint directory/base filename and optional resume path. |
checkpoint_every |
1 |
Epoch frequency for periodic checkpoints when not using top-k. |
save_top_k |
0 |
Number of best checkpoints to retain. |
monitor_metric / minimize_metric |
"val_loss" / True |
Metric and direction for best-checkpoint tracking. |
early_stop_metric / early_stop_minimize / early_stop_patience |
"val_loss" / True / 0 |
Early stopping configuration. |
eval_features / eval_labels / eval_weights |
None |
Optional evaluation payload run after training. |
eval_output_path |
None |
File path to persist evaluation results. |
eval_batch_size |
None |
Batch size for evaluation (defaults to training batch size). |
physics_metric_config |
None |
Optional calculate_physics_metrics keyword overrides; use head -> config for multi-head runs. |
debug |
False |
Enables verbose debugging callback and sampler diagnostics. |
loss_gamma |
0.0 |
Focal-loss gamma; use head -> gamma for multi-head runs. |
ignore_index |
-100 |
Label value skipped per head during validation, loss, metrics, plots, and physics metrics. |
log_level |
logging.INFO |
Logging level set before runner diagnostics. |
**classifier_kwargs |
— | Additional arguments forwarded directly to EvenetLiteClassifier. |
The trainer boots into DDP automatically when WORLD_SIZE > 1 (e.g., via
torchrun --nproc_per_node <num_gpus> script.py). Rank 0 handles logging and checkpointing; sampler/loader seeds are
synchronized per epoch. Without distributed environment variables, execution falls back to single process on GPU or CPU
depending on availability.
-
A
NormalizationCallbackis injected automatically duringfitwhen one is not provided. You can supply custom normalization rules or replace the callback entirely. -
Pass
normalization_statstoEvenetLiteClassifier.fitorrun_evenet_lite_trainingto reuse precomputed mean/std pairs without refitting. Provide a mapping per feature group, e.g.:normalization_stats = { "x": {"mean": [0.1, -0.2, 0.0], "std": [1.0, 0.9, 1.1]}, "globals": {"mean": [0.0, 0.0], "std": [1.0, 1.0]}, } classifier.fit( train_data=(train_features, y_train, w_train), val_data=(val_features, y_val, w_val), feature_names=feature_names, normalization_stats=normalization_stats, )
Any missing groups or columns default to mean
0and std1, and the applied plan is logged as a table on rank 0. -
Implement custom callbacks by subclassing
Callbackand overriding hooks such ason_train_start,on_epoch_end, oron_train_end, then pass instances via thecallbacksargument offitor the runner.
- Call
save_checkpoint(path)on a fitted classifier to persist model, optimizer/scheduler states, and the learned normalizer. Useload_checkpoint(path, feature_names=...)to restore weights for further training or inference. - Enable
pretrained=True(with optionalpretrained_source,pretrained_path, or Hugging Face repo/filename overrides) to soft-load compatible parameters while leaving shape-mismatched layers initialized.
evenet_lite.classifier.EvenetLiteClassifier: high-levelfit/predict/evaluateAPI and pretrained loader.evenet_lite.runner.run_evenet_lite_training: convenience pipeline that wires up DDP detection and training.evenet_lite.trainer.Trainer: core training loop with DDP, callbacks, metrics, early stopping, and checkpointing.evenet_lite.data: dataset wrapper and distributed weighted sampler utilities.evenet_lite.callbacks: callback base class, default normalizer, and debug helpers.evenet_lite.metrics: accuracy, loss, and physics-driven metrics helpers.evenet_lite.checkpoint: rank-safe checkpoint save/load helpers.evenet_lite.model: EveNet backbone assembly used by the default classifier.