haliax 1.4.dev394__tar.gz → 1.4.dev396__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {haliax-1.4.dev394 → haliax-1.4.dev396}/PKG-INFO +1 -1
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/faq.md +4 -4
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/fp8.md +2 -2
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/indexing.md +2 -2
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/matmul.md +2 -2
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/partitioning.md +1 -1
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/scan.md +13 -13
- haliax-1.4.dev396/docs/vmap.md +38 -0
- haliax-1.4.dev396/src/haliax/__about__.py +1 -0
- haliax-1.4.dev394/docs/vmap.md +0 -9
- haliax-1.4.dev394/src/haliax/__about__.py +0 -1
- {haliax-1.4.dev394 → haliax-1.4.dev396}/.coveragerc +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/.flake8 +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/.github/workflows/publish_dev.yaml +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/.github/workflows/run_pre_commit.yaml +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/.github/workflows/run_quick_levanter_tests.yaml +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/.github/workflows/run_tests.yaml +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/.gitignore +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/.playbooks/add-types.md +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/.playbooks/wrap-non-named.md +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/.pre-commit-config.yaml +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/.readthedocs.yaml +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/AGENTS.md +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/CONTRIBUTING.md +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/LICENSE +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/README.md +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/api.md +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/broadcasting.md +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/cheatsheet.md +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/css/material.css +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/css/mkdocstrings.css +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/figures/data_parallel_mesh.png +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/figures/data_parallel_mesh_replicated.png +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/figures/device_mesh_1d.png +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/figures/device_mesh_1d_zero.png +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/figures/device_mesh_2d.png +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/figures/device_mesh_2d_batch_partitioned.png +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/figures/device_mesh_2d_data_replicated.png +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/figures/device_mesh_2d_data_replicated_mlp_partitioned.png +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/figures/device_mesh_2d_intermediate_fully_partitioned.png +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/figures/device_mesh_2d_zero.png +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/index.md +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/nn.md +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/primer.md +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/rearrange.ipynb +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/rearrange.md +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/requirements.txt +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/state-dict.md +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/tutorial.md +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/docs/typing.md +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/mkdocs.yml +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/pyproject.toml +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/__init__.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/_src/__init__.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/_src/compile_utils.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/_src/dot.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/_src/einsum.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/_src/fp8.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/_src/parsing.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/_src/rearrange.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/_src/scan.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/_src/state_dict.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/_src/util.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/axis.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/core.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/debug.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/haxtyping.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/hof.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/jax_utils.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/nn/__init__.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/nn/activations.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/nn/attention.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/nn/conv.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/nn/dropout.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/nn/embedding.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/nn/linear.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/nn/loss.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/nn/mlp.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/nn/normalization.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/nn/pool.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/nn/scan.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/ops.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/partitioning.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/quantization.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/random.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/specialized_fns.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/state_dict.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/tree_util.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/types.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/util.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/src/haliax/wrap.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/tests/core_test.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/tests/test_attention.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/tests/test_axis.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/tests/test_conv.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/tests/test_debug.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/tests/test_dot.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/tests/test_dtype_typing.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/tests/test_einsum.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/tests/test_fp8.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/tests/test_hof.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/tests/test_int8.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/tests/test_namedarray_typing.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/tests/test_nn.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/tests/test_ops.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/tests/test_parsing.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/tests/test_partitioning.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/tests/test_pool.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/tests/test_random.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/tests/test_rearrange.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/tests/test_scan.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/tests/test_scatter_gather.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/tests/test_specialized_fns.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/tests/test_state_dict.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/tests/test_tree_util.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/tests/test_utils.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/tests/test_visualize_sharding.py +0 -0
- {haliax-1.4.dev394 → haliax-1.4.dev396}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: haliax
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.dev396
|
|
4
4
|
Summary: Named Tensors for Legible Deep Learning in JAX
|
|
5
5
|
Project-URL: Homepage, https://github.com/stanford-crfm/haliax
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/stanford-crfm/haliax/issues/
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
See also the [Equinox FAQ](https://docs.kidger.site/equinox/faq/)
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## [`hax.debug.diagnose_common_issues`][haliax.debug.diagnose_common_issues]
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
[haliax.debug.diagnose_common_issues][] is a function that will raise an exception if it detects problems with your module.
|
|
8
8
|
Currently, we diagnose:
|
|
9
9
|
|
|
10
10
|
* Reuse of arrays or NamedArrays in a field. [Equinox modules must be trees.](https://docs.kidger.site/equinox/faq/#a-module-saved-in-two-places-has-become-two-independent-copies)
|
|
11
11
|
* Use of arrays or NamedArrays in a static field. Static data in JAX/Equinox must be hashable, and arrays are not hashable.
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## [`hax.debug.visualize_shardings`][haliax.debug.visualize_shardings]
|
|
14
14
|
|
|
15
|
-
Use
|
|
15
|
+
Use [haliax.debug.visualize_shardings][] to quickly inspect how a PyTree is sharded.
|
|
16
16
|
It prints the sharding of each array leaf, including the mapping from named axes
|
|
17
17
|
to physical axes for :class:`haliax.NamedArray` leaves.
|
|
@@ -115,7 +115,7 @@ module = hax.quantization.apply_updates(module, updates, grads)
|
|
|
115
115
|
```
|
|
116
116
|
|
|
117
117
|
That's it! Just a few lines of code to enable FP8. The `quantize_linear_layers` function will transform your module to use
|
|
118
|
-
quantization-aware training for linear layers (or a subset if you want), and the combo of
|
|
118
|
+
quantization-aware training for linear layers (or a subset if you want), and the combo of [haliax.quantization.partition_for_grad_overwrite][] and [haliax.quantization.apply_updates][] function will apply the updates to the module
|
|
119
119
|
in a way that is compatible with FP8.
|
|
120
120
|
|
|
121
121
|
## How FP8 works
|
|
@@ -140,7 +140,7 @@ depend on the gradients.)
|
|
|
140
140
|
The way this happens is by "hijacking" the gradient computation. When you call `eqx.filter_grad(loss_fn)(module, data)`,
|
|
141
141
|
you will get the gradient computation as normal, but you'll also get the updated state of the FP8 `dot_general` module.
|
|
142
142
|
This updated state needs to directly replace the state in the module (rather than be used for a gradient step), which is
|
|
143
|
-
why you need to use the
|
|
143
|
+
why you need to use the [haliax.quantization.partition_for_grad_overwrite][]
|
|
144
144
|
|
|
145
145
|
The FP8 `dot_general` module is implemented in [haliax.quantization.Fp8DotGeneralOp][]. It's actually not that complicated:
|
|
146
146
|
|
|
@@ -101,7 +101,7 @@ two solutions: [haliax.slice][] and dynamic slices ([haliax.dslice][] a.k.a. [ha
|
|
|
101
101
|
|
|
102
102
|
## Dynamic Slices
|
|
103
103
|
|
|
104
|
-
[haliax.slice][] is a convenience function that wraps
|
|
104
|
+
[haliax.slice][] is a convenience function that wraps [jax.lax.dynamic_slice][] and allows you to slice an array with a
|
|
105
105
|
dynamic start and size. This is useful for situations where you need to slice an array in a way that can't be determined
|
|
106
106
|
at compile time. For example, the above example can be written as follows:
|
|
107
107
|
|
|
@@ -124,7 +124,7 @@ def f(x, slice_size: int):
|
|
|
124
124
|
|
|
125
125
|
In light of the requirement that all array sizes be known at compile time, Haliax provides both a simple [haliax.slice][]
|
|
126
126
|
function, as well as [haliax.dslice][], which can be used with `[]`. The simple slice function is just a wrapper
|
|
127
|
-
around [jax.lax.dynamic_slice][]
|
|
127
|
+
around [jax.lax.dynamic_slice][] and not worth discussing here.
|
|
128
128
|
|
|
129
129
|
`dslice` is a trick borrowed from the new experimental [jax.experimental.pallas][] module. It's essentially a slice,
|
|
130
130
|
except that instead of a start and an end (and maybe a stride), it takes a start and a size. The size must be
|
|
@@ -11,7 +11,7 @@ more suitable for expressing a particular contraction In general:
|
|
|
11
11
|
See also the API reference for [haliax.dot][] and [haliax.einsum][] and the
|
|
12
12
|
[cheat sheet section](cheatsheet.md#matrix-multiplication).
|
|
13
13
|
|
|
14
|
-
### `haliax.dot`
|
|
14
|
+
### [`haliax.dot`][haliax.dot]
|
|
15
15
|
|
|
16
16
|
With [haliax.dot][], you specify the axes to contract over, without needing to write out the
|
|
17
17
|
axes you want to keep (though you can if you want):
|
|
@@ -57,7 +57,7 @@ y = hax.dot(x, w, c, axis=()) # shape is (H, W, D, C), equivalent to np.einsum(
|
|
|
57
57
|
y = hax.dot(x, w, c, axis=(), out_axes=(D, ..., H)) # shape is (D, W, C, H), equivalent to np.einsum("hwdc,dc,c->dwch", x, w, c)
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
-
### `haliax.einsum`
|
|
60
|
+
### [`haliax.einsum`][haliax.einsum]
|
|
61
61
|
|
|
62
62
|
[haliax.einsum][] is at its best when you want to express a more complex tensor contraction.
|
|
63
63
|
It is similar to [numpy.einsum](https://numpy.org/doc/stable/reference/generated/numpy.einsum.html)
|
|
@@ -80,7 +80,7 @@ with hax.axis_mapping({"batch": "data"}):
|
|
|
80
80
|
```
|
|
81
81
|
|
|
82
82
|
Unlike in JAX, which has separate APIs for partitioning arrays inside and outside of `jit`, Haliax has a single API:
|
|
83
|
-
|
|
83
|
+
[haliax.shard][] works inside and outside of `jit`. Haliax automatically
|
|
84
84
|
chooses which JAX function to use based on context.
|
|
85
85
|
|
|
86
86
|
|
|
@@ -17,11 +17,11 @@ def scan(f, init, xs, length=None):
|
|
|
17
17
|
return carry, np.stack(ys)
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
Haliax provides two versions of this pattern: [haliax.fold][] and [haliax.scan][]. haliax.scan works much like JAX's scan,
|
|
21
|
-
except it is curried and it works with NamedArrays. haliax.fold is a more restricted version of scan that is easier to
|
|
20
|
+
Haliax provides two versions of this pattern: [haliax.fold][] and [haliax.scan][]. [haliax.scan][] works much like JAX's scan,
|
|
21
|
+
except it is curried and it works with NamedArrays. [haliax.fold][] is a more restricted version of scan that is easier to
|
|
22
22
|
use if you don't need the full generality of scan. (It works with functions that only return `carry`, not `carry, output`.)
|
|
23
23
|
|
|
24
|
-
##
|
|
24
|
+
## [haliax.scan][haliax.scan]
|
|
25
25
|
|
|
26
26
|
Unlike JAX's scan, Haliax's scan is curried - it takes the function and configuration first, then the initial carry and scan arguments as a separate call: `scan(f, axis)(init, xs)`.
|
|
27
27
|
|
|
@@ -32,7 +32,7 @@ Unlike JAX's scan, Haliax's scan is curried - it takes the function and configur
|
|
|
32
32
|
|
|
33
33
|
### Basic Example
|
|
34
34
|
|
|
35
|
-
Here's a practical example of using
|
|
35
|
+
Here's a practical example of using [haliax.scan][] to sum values along an axis while keeping track of intermediates:
|
|
36
36
|
|
|
37
37
|
```python
|
|
38
38
|
Time = Axis("Time", 100)
|
|
@@ -89,9 +89,9 @@ final_state, path = hax.scan(simulate_brownian_motion, Time)(init_state, None)
|
|
|
89
89
|
|
|
90
90
|
More commonly, you might use this for an RNN or Transformer model. (See [haliax.nn.Stacked][].)
|
|
91
91
|
|
|
92
|
-
##
|
|
92
|
+
## [haliax.fold][haliax.fold]
|
|
93
93
|
|
|
94
|
-
|
|
94
|
+
[haliax.fold][] is a simpler version of [haliax.scan][] that is easier to use when you don't need the full generality of `scan`.
|
|
95
95
|
Specifically, `fold` is for functions that only return a `carry`, not a `carry, output`.
|
|
96
96
|
|
|
97
97
|
Morally, `fold` is like this Python code:
|
|
@@ -138,10 +138,10 @@ init_state = (
|
|
|
138
138
|
final_state = hax.fold(running_stats, Time)(init_state, data)
|
|
139
139
|
```
|
|
140
140
|
|
|
141
|
-
##
|
|
141
|
+
## [haliax.map][haliax.map]
|
|
142
142
|
|
|
143
|
-
|
|
144
|
-
to [jax.lax.map][] but works with NamedArrays, providing a similar interface to
|
|
143
|
+
[haliax.map][] is a convenience function that applies a function to each element of an axis. It is similar
|
|
144
|
+
to [jax.lax.map][] but works with NamedArrays, providing a similar interface to [haliax.scan][] and [haliax.fold][].
|
|
145
145
|
|
|
146
146
|
```python
|
|
147
147
|
|
|
@@ -155,13 +155,13 @@ def my_fn(x):
|
|
|
155
155
|
result = hax.map(my_fn, Time)(data)
|
|
156
156
|
```
|
|
157
157
|
|
|
158
|
-
You should generally prefer to use [haliax.vmap][] instead of
|
|
159
|
-
(It uses less memory than
|
|
158
|
+
You should generally prefer to use [haliax.vmap][] instead of [haliax.map][], but it's there if you need it.
|
|
159
|
+
(It uses less memory than [haliax.vmap][] but is slower.)
|
|
160
160
|
|
|
161
161
|
|
|
162
162
|
## Gradient Checkpointing / Rematerialization
|
|
163
163
|
|
|
164
|
-
Both
|
|
164
|
+
Both [haliax.scan][] and [haliax.fold][] support gradient checkpointing, which can be useful for deep models.
|
|
165
165
|
Typically, you'd use this as part of [haliax.nn.Stacked][] or [haliax.nn.BlockSeq][] but you can also use it directly.
|
|
166
166
|
|
|
167
167
|
Gradient checkpointing is a technique for reducing memory usage during backpropagation by recomputing some
|
|
@@ -409,7 +409,7 @@ JAX array will have its first axis vmapped over.
|
|
|
409
409
|
|
|
410
410
|
Sometimes you may want to apply each block independently, without feeding the
|
|
411
411
|
output of one block into the next. `Stacked.vmap` does exactly that: it uses
|
|
412
|
-
[
|
|
412
|
+
[haliax.vmap][] to broadcast the initial value to every block and evaluates
|
|
413
413
|
them in parallel, returning the stack of outputs.
|
|
414
414
|
|
|
415
415
|
```python
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
## Vectorization with `haliax.vmap`
|
|
2
|
+
|
|
3
|
+
`haliax.vmap` is a [`NamedArray`][haliax.NamedArray] aware wrapper around
|
|
4
|
+
[`jax.vmap`][jax.vmap]. Instead of supplying positional axis numbers you pass
|
|
5
|
+
the [`Axis`][haliax.Axis] (or axis name) you want to map over. Any
|
|
6
|
+
`NamedArray` containing that axis is mapped in parallel and the axis is
|
|
7
|
+
reinserted in the output. Regular JAX arrays can be mapped as well by
|
|
8
|
+
providing a `default` spec or per‑argument overrides.
|
|
9
|
+
|
|
10
|
+
Unlike vanilla `jax.vmap`, you may supply **one or more axes**. When multiple
|
|
11
|
+
axes are given, the function is vmapped over each axis in turn (innermost first).
|
|
12
|
+
If an axis isn't already present in the array you must also specify its size,
|
|
13
|
+
either by passing an `Axis` object (`Axis("batch", 4)`) or a mapping such as
|
|
14
|
+
`{"batch": 4}` so the new dimension can be inserted.
|
|
15
|
+
|
|
16
|
+
### Basic Example
|
|
17
|
+
|
|
18
|
+
```python
|
|
19
|
+
import haliax as hax
|
|
20
|
+
|
|
21
|
+
Batch = hax.Axis("batch", 4)
|
|
22
|
+
|
|
23
|
+
def double(x):
|
|
24
|
+
return x * 2
|
|
25
|
+
|
|
26
|
+
x = hax.arange(Batch)
|
|
27
|
+
y = hax.vmap(double, Batch)(x)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The result `y` has the same `Batch` axis as `x`, and each element was processed
|
|
31
|
+
in parallel. With JAX you would write `jax.vmap(double)(x.array)` and manually
|
|
32
|
+
specify `in_axes`, but Haliax handles the axis automatically.
|
|
33
|
+
|
|
34
|
+
For applying many modules in parallel see
|
|
35
|
+
[`Stacked.vmap`](scan.md#apply-blocks-in-parallel-with-vmap) which builds on this
|
|
36
|
+
primitive.
|
|
37
|
+
|
|
38
|
+
::: haliax.vmap
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.4.dev396"
|
haliax-1.4.dev394/docs/vmap.md
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.4.dev394"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|