tracel-ai/burn · error
Should match at least one parameter group.
Error message
Should match at least one parameter group.
What it means
During `load_record`, each saved tensor's (parameter id, path) is matched against the optimizer's parameter groups; `optim_from_param` takes the LAST matching group via `.next_back().expect("Should match at least one parameter group.")`. If no group in the optimizer matches the parameter id/path from the record, the expect panics. This means the optimizer state being loaded belongs to a different model/config than the current optimizer's groups.
Source
Thrown at crates/burn-optim/src/optim/module/module_optimizer.rs:195
grads: MultiGradientsParams,
) -> M {
self.step_common(lr_module.into(), module, grads.into())
}
fn optim_from_param(
&self,
id: ParamId,
path: Option<&str>,
) -> (&'_ Arc<dyn DynOptimizer>, Option<GradientClipping>) {
self.optimizers
.iter()
.filter_map(|val| {
val.group
.matches(&id, path)
.then_some((&val.optim, val.grad_clipping.clone()))
})
.next_back()
.expect("Should match at least one parameter group.")
}
/// Decompose the optimizer state into a serializable [`OptimizerRecord`].
pub fn to_record(&self) -> OptimizerRecord {
let mut tensors = Vec::new();
let mut scalars = BTreeMap::new();
let mut paths = BTreeMap::new();
for (id, param_state) in self.param_context.iter() {
let prefix = id.val().to_string();
let mut sink = StateSink::default();
param_state
.optim
.state_flatten(&prefix, ¶m_state.state, &mut sink);
// Persist the parameter rank explicitly so the state can be reconstructed even when it
// carries no tensors, and without inferring the rank from tensor shapes.
scalars.insert(View on GitHub (pinned to d16f7ba2ed)
Solutions
- Load the optimizer record into an optimizer built from the same model structure and config that saved it.
- Use `to_record`/`load_record` as a matched pair from the same session/version.
- Regenerate the checkpoint if the model structure changed, or migrate the record's ids/paths.
- Add a guard comparing record param ids to `self.optimizers` group ids before calling `load_record`.
Example fix
// before let record: OptimizerRecord = bincode::deserialize(&checkpoint_optimizer)?; optimizer.load_record(record); // panics if model changed // after let record: OptimizerRecord = bincode::deserialize(&checkpoint_optimizer)?; assert!(!record.tensors.is_empty(), "checkpoint has no optimizer tensors"); // rebuild optimizer from the checkpoint's model, then: optimizer.load_record(record);
Defensive patterns
Strategy: validation
Validate before calling
fn record_matches(record: &OptimizerRecord, opt: &impl ToRecord) -> bool {
// every tensor's param id should be known to the current optimizer groups
!record.tensors.is_empty() && record.tensors.iter().all(|t| t.param_id.is_some())
}
assert!(record_matches(&record, &optimizer), "checkpoint optimizer does not match current model"); Prevention
- Save and load optimizer records with the same model structure and config
- Version-tag checkpoints and validate before load
- Regenerate checkpoints after model restructuring
When it happens
Trigger: Calling `load_record` with an `OptimizerRecord` whose tensor param ids/paths match none of the current optimizer's `ParamGroup`s — e.g. loading a checkpoint saved from a differently structured model, or after changing group definitions in the optimizer config.
Common situations: Restoring training from a checkpoint after renaming/restructuring modules; switching optimizer group configs between save and load; loading a record from another experiment's checkpoint; library version change that altered path or id derivation.
Related errors
- Failed to load record
- Optimizer record tensors should carry a parameter id.
- Unsupported tensor rank for optimizer state: {other}
- Failed to load module from file
- Should have at least one optimizer
AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05).
Data as JSON: /api/errors/29c1cde5716f5b24.
Report an issue: GitHub.