2929AccumulatorTree : TypeAlias = Any
3030Function : TypeAlias = Callable [..., Any ]
3131VmapFn : TypeAlias = Callable [[Function , int | Sequence [int ], int ], Function ]
32+ PyTreeFn : TypeAlias = Callable [[chex .ArrayTree ], chex .ArrayTree ]
33+ UpdateFn = Callable [[chex .ArrayTree , chex .ArrayTree , int ], chex .ArrayTree ]
3234IndividualOutputs = collections .namedtuple ('Aux' , ['values' , 'metrics' , 'aux' ])
3335ValueAndGradFn : TypeAlias = Callable [..., tuple [Any , IndividualOutputs ]]
3436
@@ -40,28 +42,28 @@ class Accumulator:
4042 Given a list of microbatch function evaluations [x_0, ..., x_{n-1}], this
4143 object represents the program.
4244
43- ```
45+ .. code-block:: python
46+
4447 carry = init(x_0)
4548 for i in range(1, n):
4649 carry = update(carry, x_i, i)
4750 return finalize(carry)
48- ```
4951
5052 Attributes:
51- init: A function f(value, num_microbatches ) that initializes the microbatch
52- state from the function evaluation of the fist microbatch.
53- update: A function f(carry, value, index, num_microbatches ) that updates the
54- microbatch state with the function evaluation of the current microbatch.
55- finalize: A function f(carry, num_microbatches ) that returns the final
56- result from the final state.
53+ init: A function f(value) that initializes the microbatch state from the
54+ function evaluation of the fist microbatch.
55+ update: A function f(carry, value, index) that updates the microbatch state
56+ with the function evaluation of the current microbatch.
57+ finalize: A function f(carry) that returns the final result from the final
58+ state.
5759 aggregate: A function f(per_microbatch_value) that aggregates
58- per-microbatch values into a single value. Used by `gvmap `.
60+ per-microbatch values into a single value. Used by `micro_vmap `.
5961 """
6062
61- init : Callable [[ chex . ArrayTree ], chex . ArrayTree ]
62- update : Callable [[ chex . ArrayTree , chex . ArrayTree , int ], chex . ArrayTree ]
63- finalize : Callable [[ chex . ArrayTree ], chex . ArrayTree ]
64- aggregate : Callable [[ chex . ArrayTree ], chex . ArrayTree ]
63+ init : PyTreeFn
64+ update : UpdateFn
65+ finalize : PyTreeFn
66+ aggregate : PyTreeFn
6567
6668
6769def _with_floating_check (fn : Function ) -> Function :
@@ -79,7 +81,7 @@ def _identity(value: Any) -> Any:
7981 return value
8082
8183
82- def reshape_batch_axis (tree : Any , microbatch_size : int , axis : int = 0 ):
84+ def reshape_batch_axis (tree : Any , microbatch_size : int , axis : int = 0 ) -> Any :
8385 """Reshape batch axis of pytree leaves for use with microbatching.
8486
8587 This function reshapes the batch axis of each leaf into a shape
@@ -252,9 +254,13 @@ def finalize(carry):
252254class AccumulationType (enum .Enum ):
253255 """The type of accumulation to perform."""
254256 MEAN = enum .auto ()
257+ """Average the microbatch outputs."""
255258 SUM = enum .auto ()
259+ """Sum the microbatch outputs."""
256260 RUNNING_MEAN = enum .auto ()
261+ """Average the microbatch outputs over `num_real_microbatches`."""
257262 CONCAT = enum .auto ()
263+ """Concatenate the microbatch outputs along axis 0."""
258264
259265
260266# In order to construct some accumulators (MEAN, CONCAT), we need to know the
@@ -444,7 +450,7 @@ def body_fun(index, carry):
444450
445451
446452# TODO(mckennar): Create a notebook demonstrating useful use-cases.
447- def gvmap (
453+ def micro_vmap (
448454 fun : Function ,
449455 in_axes : int | Sequence [int ] = 0 ,
450456 out_axes : Any = 0 ,
@@ -467,8 +473,8 @@ def gvmap(
467473 Example Usage:
468474 >>> from optax.experimental import microbatching
469475 >>> import jax.numpy as jnp
470- >>> microbatching.gvmap (lambda x: x**2)(jnp.arange(8))
471- >>> Array([ 0, 1, 4, 9, 16, 25, 36, 49], dtype=int32)
476+ >>> microbatching.micro_vmap (lambda x: x**2)(jnp.arange(8))
477+ Array([ 0, 1, 4, 9, 16, 25, 36, 49], dtype=int32)
472478
473479 Args:
474480 fun: Function to be mapped over additional axes.
@@ -573,18 +579,19 @@ def micro_grad(
573579 native jax.value_and_grad due to the built-in microbatching.
574580
575581 Example Usage (see https://arxiv.org/abs/2510.00236):
582+ >>> from optax.experimental import microbatching
576583 >>> def mean_squared_loss(params, features, targets):
577584 ... preds = features @ params
578585 ... diff = preds - targets
579586 ... return 0.5 * jnp.mean(diff**2)
580587 >>> params = jnp.zeros(1)
581588 >>> features = jnp.ones((4, 1))
582589 >>> targets = jnp.array([0, 2, 4, 6])
583- >>> (grads, squared_grads), aux = micro_grad(
590+ >>> (grads, squared_grads), aux = microbatching. micro_grad(
584591 ... mean_squared_loss,
585592 ... argnums=0,
586593 ... batch_argnums=(1,2),
587- ... accumulator=AccumulationType.MEAN,
594+ ... accumulator=microbatching. AccumulationType.MEAN,
588595 ... transform_fn=lambda x: (x, x**2),
589596 ... metrics_fn=jnp.linalg.norm
590597 ... )(params, features, targets)
@@ -637,7 +644,7 @@ def grad_fn(*args, **kwargs):
637644 in_axes = [None ]* (max (batch_argnums ) + 1 )
638645 for i in batch_argnums :
639646 in_axes [i ] = 0
640- micro_fun = gvmap (
647+ micro_fun = micro_vmap (
641648 grad_fn ,
642649 in_axes = in_axes ,
643650 accumulator = (accumulator , AccumulationType .CONCAT ),
0 commit comments