Base class for all neural network modules.
Every custom model should subclass this and implement forward.
Submodules assigned as attributes are tracked automatically.
Notes
Attribute routing: Setting an attribute follows this priority order:
- If the value is a
lucid.nn.Parameter→ stored in_parameters. - If the value is a
Module→ stored in_modules. - Otherwise → plain Python attribute.
To register a non-parameter tensor (e.g. a running mean), call
register_buffer explicitly.
Examples
>>> class MLP(nn.Module):
... def __init__(self):
... super().__init__()
... self.fc1 = nn.Linear(10, 20)
... self.fc2 = nn.Linear(20, 1)
...
... def forward(self, x):
... return self.fc2(lucid.relu(self.fc1(x)))
...
>>> model = MLP()
>>> model(lucid.randn(4, 10)).shape
(4, 1)Used by 34
- lucid.compile
- lucid.compile._core.bn_runstats
- lucid.compile._core.fallback
- lucid.compile._core.signature
- lucid.compile._entry.function
- lucid.compile._entry.fused_step
- lucid.compile._entry.module
- lucid.compile._entry.segmented_step
- lucid.compile._entry.step
- lucid.models.text.roformer._model
- lucid.nn
- lucid.nn._state_dict
… 22 more
Constructors
2Instance methods
43Add a child module.
Apply fn recursively to every submodule (including self).
Cast all parameters and buffers to bfloat16.
Yield all buffer tensors.
Yield direct child modules.
No-op compatibility stub.
External codepaths often call model.compile() to opt into JIT
acceleration; Lucid has no such layer, so this returns self
unchanged rather than crashing the caller. Any positional or
keyword arguments are accepted and ignored.
Move all parameters and buffers to CPU.
Cast all parameters and buffers to float64.
Set this module and all children to evaluation mode.
Override to add extra repr info (e.g. Linear shows in_features, etc.).
Cast all parameters and buffers to float32.
Override in subclasses to define the computation.
Return buffer at dotted path, e.g. 'bn.running_mean'.
Return extra state to include in state_dict. Override in subclasses.
Return parameter at dotted path, e.g. 'fc.weight'.
Return submodule at dotted path, e.g. 'encoder.layer.0'.
Cast all parameters and buffers to float16.
load_state_dict
→objectload_state_dict(state_dict: dict[str, Tensor], strict: bool = True, assign: bool = False)Load parameters from a state_dict.
Calls each module's _load_from_state_dict recursively.
Returns _IncompatibleKeys(missing_keys, unexpected_keys) on success.
Raises RuntimeError if strict=True and any keys are missing
or unexpected, or if any error_msgs accumulated during loading.
Parameters
state_dictdictstrictbool= TrueTrue (default) require an exact key match; raise on any
missing or unexpected keys.assignbool= FalseTrue replace each parameter/buffer object with the
loaded tensor directly (allows shape/dtype changes). If
False (default) copy data into the existing parameter
preserving its dtype and device.Move all parameters and buffers to Apple Metal GPU.
Yield this module and all submodules (depth-first).
named_buffers(prefix: str = '', recurse: bool = True, remove_duplicate: bool = True)Yield (name, buffer) pairs.
Yield (name, child_module) pairs.
named_modules(memo: set[int] | None = None, prefix: str = '', remove_duplicate: bool = True)Yield (name, module) pairs.
named_parameters(prefix: str = '', recurse: bool = True, remove_duplicate: bool = True)Yield (qualified_name, Parameter) pairs from this module's tree.
Parameters
prefixstr= ''"".recursebool= TrueTrue (default), descend into submodules. When
False, yield only this module's directly-attached
parameters.remove_duplicatebool= TrueTrue (default), each unique Parameter
object is yielded only once even if referenced by multiple
attributes — matches the reference framework's contract.Yield all Parameters in this module (and children if recurse=True).
register_backward_hook(hook: _BackwardHook)Deprecated alias for register_full_backward_hook.
register_buffer
→Noneregister_buffer(name: str, tensor: Tensor | None, persistent: bool = True)Register a buffer tensor. Non-persistent buffers are excluded from state_dict.
register_forward_hook(hook: _ForwardHook, prepend: bool = False, with_kwargs: bool = False, always_call: bool = False)Register a hook called after forward().
register_forward_pre_hook(hook: _ForwardPreHook, prepend: bool = False, with_kwargs: bool = False)Register a hook called before forward().
register_full_backward_hook(hook: _BackwardHook, prepend: bool = False)Register a backward hook. Returns a RemovableHandle.
register_full_backward_pre_hook(hook: _BackwardHook, prepend: bool = False)Register a hook to be called before backward hooks.
register_load_state_dict_post_hook(hook: Callable[..., object])Register a post-hook called after this module loads state_dict.
Hook signature: hook(module, incompatible_keys) -> None.
register_load_state_dict_pre_hook(hook: Callable[..., object])Register a pre-hook called when this module loads state_dict.
Hook signature: hook(module, state_dict, prefix, local_metadata, strict, missing_keys, unexpected_keys, error_msgs) -> None
The hook may mutate state_dict/missing/unexpected/error_msgs.
Alias for add_module.
Register a Parameter under the given name.
Restore extra state loaded from state_dict. Override in subclasses.
No-op on Apple Silicon (unified memory is always shared).
state_dict
→dictstate_dict(destination: dict[str, Tensor] | None = None, prefix: str = '', keep_vars: bool = False)Return an ordered dict mapping parameter / buffer names to tensors.
Includes every learnable parameter, every persistent buffer
(persistent=True at register time), and every nested
submodule's contribution under a dotted-path prefix.
The returned OrderedDict carries a _metadata
attribute mapping module_path → {"version": int} for every
module that defines a _version class attribute.
lucid.save preserves this attribute across disk
round-trips so version-aware _load_from_state_dict hooks
can migrate older checkpoints.
Parameters
destinationdict= NoneNone.prefixstr= ''"".keep_varsbool= FalseTrue keep tensors attached to autograd (return
them as-is); when False (default) detach them so the
state dict is safe to serialise / cross threads.Returns
dictOrderedDict mapping qualified parameter / buffer paths to their tensor values.
Move/cast all parameters and buffers, preserving Parameter object identity.
Floating-point dtype casts (.float(), .double(),
.half(), .bfloat16()) skip integer buffers — e.g.
BatchNorm.num_batches_tracked stays int64 — matching the
reference framework so checkpoint round-trips don't quietly
widen / narrow the counter type. Device moves still apply to
every tensor.
Move parameters and buffers to device without copying data.
The reference framework uses to_empty to materialise a
model originally constructed on the meta device. Lucid has no
meta device, so this method exists for API parity and
delegates to the standard to when a device is supplied.
Parameters
deviceobject= Nonedevice, or engine enum).
When None (default) the call is a no-op returning
self.recursebool= Trueto call. Default
True — every child module is moved as well.Returns
SelfThe same module, parameters / buffers now on device.
Set this module and all children to training mode.
Cast all parameters and buffers to dst_type.
dst_type may be a lucid.dtype, a Python type (float,
int), or a string ("float32", "float16", etc.).
Delegates to to, which handles the conversion.
Zero gradients of all parameters.