Modules
Clouseau tracks the forward pass of a model and saves the intermediate arrays to a file.
Currently it supports Jax and Pytorch models. They way this is achieved is different for both frameworks.
- For Jax it uses a wrapper class that wraps each (callable) node in the pytree ( see also https://github.com/patrick-kidger/equinox/issues/864). Saving arrays to file is a side effect in Jax. See e.g. https://docs.jax.dev/en/latest/external-callbacks.html However the global cache seems acceptable in combination with jax.experimental.io_callback, which is explicitly designed for this purpose.
- For Pytorch it uses a forward hook that is registered on each module. See e.g. https://web.stanford.edu/~nanbhas/blog/forward-hooks-pytorch/ The forward hook is de-registered after the forward pass is done.
In both cases Jax / Pytorch it tracks the output of the layer. I might add tracking of the inputs as well later.
is_jax_model(model)
¶
Check if model is a jax model.
Any Python object is a valid pytree (a bare object flattens to itself as a
single leaf), so jax.tree.flatten alone would accept almost anything,
e.g. an int. We additionally require model to be a non-leaf pytree
node that carries at least one jax.Array leaf, i.e. a container with
parameters that clouseau can actually record.
Source code in clouseau/inspector.py
is_torch_model(model)
¶
magnify(filename=DEFAULT_PATH / 'activations-000.safetensors', framework='numpy', device=None)
¶
Visualize nested arrays using treescope
Source code in clouseau/inspector.py
tail(model, path=DEFAULT_PATH, filter_=None, is_leaf=None, filename_pattern='activations-{idx:03d}.safetensors', max_size_mb=1024)
¶
Tail and record the forward pass of a model
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
object
|
The model to inspect. Can be a PyTorch model or JAX/Equinox model. |
required |
path
|
str or Path
|
Path where to store the forward pass arrays. |
DEFAULT_PATH
|
filter_
|
callable
|
Function that filters which tensors to inspect. Takes the pytree leaves, child modules as input and returns a boolean. |
None
|
is_leaf
|
callable
|
Function that determines whether a node in the model tree should be treated as a leaf. Takes a node as input and returns a boolean. If True, the node will not be traversed further. This is particularly useful for JAX/Equinox models to control the granularity of inspection. |
None
|
Returns:
| Type | Description |
|---|---|
_Inspector
|
Inspector instance that can be used as a context manager. |
Examples:
>>> import torch
>>> from clouseau import inspector, magnifier
>>> model = torch.nn.Linear(10, 5)
>>> with inspector.tail(model, path=".clouseau/trace-torch.safetensors") as fmodel:
... out = fmodel(torch.randn(3, 10))
When working with a JAX/Equinox model, it is important to add .block_until_ready()
>>> import jax
>>> with inspector.tail(model, path=".clouseau/trace-jax.safetensors") as fmodel:
... fmodel(x, time).block_until_ready()