Flax Documentation
repository·main·Indexed 27 days ago
https://github.com/google/flaxA high-performance neural network library and ecosystem for JAX designed for flexibility. Flax provides a neural network API, including the Pythonic NNX and the stable Linen API, along with utilities for replicated training, serialization, checkpointing, and metrics.
What's inside Flax
- Flax NNX is a simplified Flax API released in 2024 designed for easier creation, inspection, debugging, and analysis of neural networks in JAX. Unlike the older Flax Linen API, NNX provides first-class support for Python reference semantics, allowing users to express models using regular Python objects with support for reference sharing and mutability.
Understand the core principles of Flax NNX
mainFlax NNX is a neural network API designed to bring Pythonic reference semantics to JAX. Unlike the functional (lazy initialization) semantics of Flax Linen, NNX uses regular Python semantics for
nnx.Module, supporting mutability and shared references.Key features include:
- Pythonic Modules: Supports standard Python mutability and object semantics.
- Simplicity: Replaces complex Linen APIs with simpler Python idioms.
- JAX Integration: Custom NNX transforms are designed to align with JAX transform APIs, making it easier to use JAX higher-order functions directly.
Use lifted transformations in Linen
mainLinen uses "lifted transformations," which are JAX transformations (likejax.vmap,jax.grad, orjax.scan) that are specifically designed to be applied to Flax Modules. Instead of applying transformations directly to raw functions, you use the lifted versions provided by Flax to ensure module state and RNGs are handled correctly.Access Flax documentation
mainThe official online documentation for Flax is hosted at: https://flax.readthedocs.io/en/latest/Use Linen for neural network development
mainLinen is the recommended neural network API for Flax (replacing the deprecated
flax.nnAPI). It is designed to be a 'comfortable evolution' that improves submodule sharing and support for non-trainable variables.Key features include:
- Functional Core: Modules are built on a functional core, allowing you to use JAX transformations like
vmap,remat, orscandirectly inside your modules. - Pythonic Modules: Modules behave similarly to vanilla Python objects while supporting the concise single-method pattern.
- Stability: The Linen Module API is stable and recommended for all new projects.
- Functional Core: Modules are built on a functional core, allowing you to use JAX transformations like
Understand the differences between Flax NNX and Flax Linen
mainFlax NNX is designed to improve upon Flax Linen by providing a more intuitive, object-oriented experience. Key improvements include:
- Inspection:
nnx.Moduleobjects are regular Python objects. Unlike Linen modules, which are lazy and difficult to inspect before runtime, NNX modules can be constructed and inspected immediately. - Computation: In NNX, there is no special context like Linen's
applyorinit. Parameters are held as attributes, and methods (including__call__and custom methods) can be called directly on the module instance. - State Handling: State (like
BatchNormstatistics orDropoutflags) is kept inside thennx.Moduleand is mutable. This eliminates the need to manually manage complex parameter/state dictionaries during training loops. - Model Surgery: Because modules are regular Python objects and parameters are part of the module structure, you can replace sub-modules (e.g., for LoRA) using standard Python assignment without keeping separate parameter structures in sync.
- Transforms:
nnx.vmapand other NNX transforms are designed to be equivalent to JAX transforms. They can be used anywhere (including training loops), can accept modules as any argument, and can return modules.
- Inspection:
Understand the Flax Linen design philosophy
mainFlax Linen is a functional system for defining neural networks in JAX. Unlike object-oriented frameworks, Linen is designed to be compatible with JAX's composable function-transformation approach.
Key architectural concepts include:
- Functionalization: Linen Modules are automatically cast into explicit functions of the form
f(v_in, x) -> v_out, y, wherev_inrepresents variable collections and PRNG state,xis input data,v_outis the mutated variable collections, andyis the output data. - Variable Collections: Instead of a single 'state' object, Flax uses multiple named collections (e.g.,
params,batch_norm,cache) to allow different treatment of variables under JAX transformations (likejit,vmap, orpmap). - Pytree Representation: All model data (parameters, stats, etc.) is stored in JAX-native pytrees (nested dictionaries, tuples, or lists), making it easy to introspect, modify, or serialize using standard Python tools.
- Functionalization: Linen Modules are automatically cast into explicit functions of the form
Perform stateful computation in NNX
mainIn NNX, you can perform stateful updates (like updating running averages in
BatchNorm) by creating aVariableand updating its.valueproperty during the forward pass. You can use in-place update syntax likeself.variable[...] += 1.class Count(nnx.Variable): pass class Counter(nnx.Module): def __init__(self): self.count = Count(jnp.array(0)) def __call__(self): self.count[...] += 1 counter = Counter() counter() print(f'{counter.count[...] = }')Perform Model Surgery
mainFlax
Modules are mutable by default. You can modify the model structure at any time by replacing sub-Module attributes orVariables with new ones (e.g., replacing a standard layer with a LoRA layer).# Example: Replacing linear layers with LoraLinear model.linear1 = LoraLinear(model.linear1, 4, rngs=rngs) model.linear2 = LoraLinear(model.linear2, 4, rngs=rngs)Implement PyTorch-style Average Pooling in NNX
mainnnx.avg_pool()does not have a direct equivalent to PyTorch'scount_include_pad=False(which excludes zero-padding from the average calculation).To replicate this behavior, you can use
nnx.pool()withjax.lax.addto manually calculate the average by dividing the sum by the count of non-padded elements.def avg_pool(inputs, window_shape, strides=None, padding='VALID'): """ Pools the input by taking the average over a window. Does not consider padded zero's for the average computation. """ assert len(window_shape) == 2 y = nnx.pool(inputs, 0., jax.lax.add, window_shape, strides, padding) counts = nnx.pool(jnp.ones_like(inputs), 0., jax.lax.add, window_shape, strides, padding) y = y / counts return yUpgrade from flax.optim to Optax
mainSince Flax v0.6.0,
flax.optimhas been removed. You should migrate toOptax. Unlikeflax.optim,optaxdoes not keep a copy of the parameters (params). You must manageparamsandopt_stateseparately.To simplify state management, Flax provides
flax.training.train_state.TrainStateto store optimizer state, parameters, and other associated data in a single dataclass.@jax.jit def train_step(params, opt_state, batch): grads = jax.grad(loss)(params, batch) updates, opt_state = tx.update(grads, opt_state) params = optax.apply_updates(params, updates) return params, opt_state tx = optax.sgd(learning_rate, momentum) params = variables['params'] opt_state = tx.init(params) for batch in ds_train: params, opt_state = train_step(params, opt_state, batch)Manage state in Flax NNX
mainState (such as
BatchNormstatistics orDropoutrandomness) is stored directly within thennx.Moduleand is mutable. This allows you to add stateful layers without changing your training loop logic.class BatchNorm(nnx.Module): def __init__(self, features: int, mu: float = 0.95): self.scale = nnx.Param(jax.numpy.ones((features,))) self.bias = nnx.Param(jax.numpy.zeros((features,))) self.mean = nnx.BatchStat(jax.numpy.zeros((features,))) self.var = nnx.BatchStat(jax.numpy.ones((features,))) self.mu = mu def __call__(self, x): mean = jax.numpy.mean(x, axis=-1) var = jax.numpy.var(x, axis=-1) # ema updates happen directly on the stateful attributes self.mean.value = self.mu * self.mean + (1 - self.mu) * mean self.var.value = self.mu * self.var + (1 - self.mu) * var x = (x - mean) / jax.numpy.sqrt(var + 1e-5) return x * self.scale + self.bias