haliax 1.4.dev308__tar.gz → 1.4.dev313__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.
Files changed (100) hide show
  1. {haliax-1.4.dev308 → haliax-1.4.dev313}/PKG-INFO +1 -1
  2. haliax-1.4.dev313/src/haliax/__about__.py +1 -0
  3. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/core.py +2 -0
  4. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/nn/scan.py +54 -0
  5. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/partitioning.py +4 -1
  6. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/tree_util.py +39 -2
  7. {haliax-1.4.dev308 → haliax-1.4.dev313}/tests/test_scan.py +27 -0
  8. haliax-1.4.dev313/tests/test_tree_util.py +91 -0
  9. haliax-1.4.dev308/src/haliax/__about__.py +0 -1
  10. haliax-1.4.dev308/tests/test_tree_util.py +0 -36
  11. {haliax-1.4.dev308 → haliax-1.4.dev313}/.coveragerc +0 -0
  12. {haliax-1.4.dev308 → haliax-1.4.dev313}/.flake8 +0 -0
  13. {haliax-1.4.dev308 → haliax-1.4.dev313}/.github/workflows/publish_dev.yaml +0 -0
  14. {haliax-1.4.dev308 → haliax-1.4.dev313}/.github/workflows/run_pre_commit.yaml +0 -0
  15. {haliax-1.4.dev308 → haliax-1.4.dev313}/.github/workflows/run_quick_levanter_tests.yaml +0 -0
  16. {haliax-1.4.dev308 → haliax-1.4.dev313}/.github/workflows/run_tests.yaml +0 -0
  17. {haliax-1.4.dev308 → haliax-1.4.dev313}/.gitignore +0 -0
  18. {haliax-1.4.dev308 → haliax-1.4.dev313}/.pre-commit-config.yaml +0 -0
  19. {haliax-1.4.dev308 → haliax-1.4.dev313}/.readthedocs.yaml +0 -0
  20. {haliax-1.4.dev308 → haliax-1.4.dev313}/CONTRIBUTING.md +0 -0
  21. {haliax-1.4.dev308 → haliax-1.4.dev313}/LICENSE +0 -0
  22. {haliax-1.4.dev308 → haliax-1.4.dev313}/README.md +0 -0
  23. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/api.md +0 -0
  24. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/broadcasting.md +0 -0
  25. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/cheatsheet.md +0 -0
  26. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/css/material.css +0 -0
  27. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/css/mkdocstrings.css +0 -0
  28. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/faq.md +0 -0
  29. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/figures/data_parallel_mesh.png +0 -0
  30. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/figures/data_parallel_mesh_replicated.png +0 -0
  31. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/figures/device_mesh_1d.png +0 -0
  32. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/figures/device_mesh_1d_zero.png +0 -0
  33. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/figures/device_mesh_2d.png +0 -0
  34. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/figures/device_mesh_2d_batch_partitioned.png +0 -0
  35. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/figures/device_mesh_2d_data_replicated.png +0 -0
  36. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/figures/device_mesh_2d_data_replicated_mlp_partitioned.png +0 -0
  37. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/figures/device_mesh_2d_intermediate_fully_partitioned.png +0 -0
  38. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/figures/device_mesh_2d_zero.png +0 -0
  39. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/fp8.md +0 -0
  40. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/hof.md +0 -0
  41. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/index.md +0 -0
  42. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/indexing.md +0 -0
  43. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/matmul.md +0 -0
  44. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/nn.md +0 -0
  45. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/partitioning.md +0 -0
  46. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/rearrange.ipynb +0 -0
  47. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/rearrange.md +0 -0
  48. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/requirements.txt +0 -0
  49. {haliax-1.4.dev308 → haliax-1.4.dev313}/docs/tutorial.md +0 -0
  50. {haliax-1.4.dev308 → haliax-1.4.dev313}/mkdocs.yml +0 -0
  51. {haliax-1.4.dev308 → haliax-1.4.dev313}/pyproject.toml +0 -0
  52. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/__init__.py +0 -0
  53. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/_src/__init__.py +0 -0
  54. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/_src/compile_utils.py +0 -0
  55. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/_src/dot.py +0 -0
  56. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/_src/einsum.py +0 -0
  57. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/_src/fp8.py +0 -0
  58. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/_src/parsing.py +0 -0
  59. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/_src/rearrange.py +0 -0
  60. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/_src/util.py +0 -0
  61. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/axis.py +0 -0
  62. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/debug.py +0 -0
  63. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/hof.py +0 -0
  64. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/jax_utils.py +0 -0
  65. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/nn/__init__.py +0 -0
  66. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/nn/activations.py +0 -0
  67. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/nn/attention.py +0 -0
  68. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/nn/conv.py +0 -0
  69. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/nn/dropout.py +0 -0
  70. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/nn/embedding.py +0 -0
  71. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/nn/linear.py +0 -0
  72. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/nn/loss.py +0 -0
  73. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/nn/mlp.py +0 -0
  74. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/nn/normalization.py +0 -0
  75. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/nn/pool.py +0 -0
  76. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/ops.py +0 -0
  77. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/quantization.py +0 -0
  78. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/random.py +0 -0
  79. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/specialized_fns.py +0 -0
  80. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/types.py +0 -0
  81. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/util.py +0 -0
  82. {haliax-1.4.dev308 → haliax-1.4.dev313}/src/haliax/wrap.py +0 -0
  83. {haliax-1.4.dev308 → haliax-1.4.dev313}/tests/core_test.py +0 -0
  84. {haliax-1.4.dev308 → haliax-1.4.dev313}/tests/test_attention.py +0 -0
  85. {haliax-1.4.dev308 → haliax-1.4.dev313}/tests/test_axis.py +0 -0
  86. {haliax-1.4.dev308 → haliax-1.4.dev313}/tests/test_conv.py +0 -0
  87. {haliax-1.4.dev308 → haliax-1.4.dev313}/tests/test_debug.py +0 -0
  88. {haliax-1.4.dev308 → haliax-1.4.dev313}/tests/test_dot.py +0 -0
  89. {haliax-1.4.dev308 → haliax-1.4.dev313}/tests/test_einsum.py +0 -0
  90. {haliax-1.4.dev308 → haliax-1.4.dev313}/tests/test_fp8.py +0 -0
  91. {haliax-1.4.dev308 → haliax-1.4.dev313}/tests/test_hof.py +0 -0
  92. {haliax-1.4.dev308 → haliax-1.4.dev313}/tests/test_nn.py +0 -0
  93. {haliax-1.4.dev308 → haliax-1.4.dev313}/tests/test_ops.py +0 -0
  94. {haliax-1.4.dev308 → haliax-1.4.dev313}/tests/test_parsing.py +0 -0
  95. {haliax-1.4.dev308 → haliax-1.4.dev313}/tests/test_partitioning.py +0 -0
  96. {haliax-1.4.dev308 → haliax-1.4.dev313}/tests/test_pool.py +0 -0
  97. {haliax-1.4.dev308 → haliax-1.4.dev313}/tests/test_random.py +0 -0
  98. {haliax-1.4.dev308 → haliax-1.4.dev313}/tests/test_rearrange.py +0 -0
  99. {haliax-1.4.dev308 → haliax-1.4.dev313}/tests/test_specialized_fns.py +0 -0
  100. {haliax-1.4.dev308 → haliax-1.4.dev313}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: haliax
3
- Version: 1.4.dev308
3
+ Version: 1.4.dev313
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/
@@ -0,0 +1 @@
1
+ __version__ = "1.4.dev313"
@@ -684,6 +684,8 @@ def take(array: NamedArray, axis: AxisSelector, index: Union[int, NamedArray]) -
684
684
  new_axes = array.axes[:axis_index] + array.axes[axis_index + 1 :]
685
685
  return NamedArray(new_array, new_axes)
686
686
  else:
687
+ if not jnp.issubdtype(index.dtype, jnp.integer):
688
+ raise ValueError(f"Index must be an integer array, got {index.dtype}")
687
689
  # #13: should broadcast/autobatch take
688
690
  remaining_axes = eliminate_axes(array.axes, axis)
689
691
  # axis order is generally [array.axes[:axis_index], index.axes, array.axes[axis_index + 1 :]]
@@ -156,6 +156,13 @@ class Stacked(eqx.Module, Generic[M]):
156
156
 
157
157
  Stacked also supports gradient checkpointing, which is useful for very large models that don't fit in memory.
158
158
 
159
+ Typically only one of "fold" or "scan" can be used with a given Stacked module, depending on the what the module
160
+ returns: if the module returns a single output, use "fold"; if the module returns a sequence of intermediates and
161
+ an output to be passed to the next layer, use "scan". More concretely, for a transformer, you would use "scan" if
162
+ you wanted to return a kv cache (or the attention matrix) as well as the output of the transformer. If you just
163
+ wanted the output of the transformer, you would use "fold".
164
+
165
+
159
166
  Example:
160
167
  ```python
161
168
  >>> import equinox as eqx
@@ -206,6 +213,32 @@ class Stacked(eqx.Module, Generic[M]):
206
213
  return fn
207
214
 
208
215
  def scan(self, init, *extra_args, **extra_kwargs):
216
+ """
217
+ Scan over the stacked module. This is the same as a for loop that applies each instance of the module in sequence
218
+ to the input, passing the output of one instance to the next instance. It returns a stack of intermediates as
219
+ well as the final output.
220
+
221
+ That is, it behaves similarly to the following Python code:
222
+
223
+ ```python
224
+ carry = init
225
+ intermediates = []
226
+
227
+ for block in self.stacked:
228
+ carry, extra = block(carry)
229
+ intermediates.append(extra)
230
+
231
+ return carry, hax.stack(Block, intermediates)
232
+ ```
233
+
234
+ Args:
235
+ init:
236
+ *extra_args:
237
+ **extra_kwargs:
238
+
239
+ Returns:
240
+
241
+ """
209
242
  if self.gradient_checkpointing:
210
243
  do_block = filter_checkpoint(self._do_block, prevent_cse=self.prevent_cse)
211
244
  else:
@@ -213,6 +246,27 @@ class Stacked(eqx.Module, Generic[M]):
213
246
  return haliax.scan(do_block, self.Block)(init, self.stacked, *extra_args, **extra_kwargs)
214
247
 
215
248
  def fold(self, init, *args, **kwargs):
249
+ """
250
+ Fold over the stacked module. This is the same as a for loop that applies each instance of the module in sequence
251
+ to the input, passing the output of one instance to the next instance.
252
+ That is, it behaves similarly to the following Python code:
253
+
254
+ ```python
255
+ carry = init
256
+ for block in self.stacked:
257
+ carry = block(carry)
258
+
259
+ return carry
260
+ ```
261
+
262
+ Args:
263
+ init:
264
+ *args:
265
+ **kwargs:
266
+
267
+ Returns:
268
+
269
+ """
216
270
  if self.gradient_checkpointing:
217
271
  do_block = filter_checkpoint(self._do_block, prevent_cse=self.prevent_cse)
218
272
  else:
@@ -603,7 +603,10 @@ def round_axis_for_partitioning(axis: Axis, mapping: Optional[ResourceMapping] =
603
603
 
604
604
 
605
605
  def _get_mesh() -> Mesh:
606
- from jax.experimental.maps import thread_resources
606
+ try:
607
+ from jax.interpreters.pxla import thread_resources
608
+ except ImportError:
609
+ from jax.experimental.maps import thread_resources
607
610
 
608
611
  return thread_resources.env.physical_mesh
609
612
 
@@ -1,3 +1,5 @@
1
+ import dataclasses
2
+ import functools
1
3
  from typing import Optional
2
4
 
3
5
  import equinox as eqx
@@ -5,6 +7,8 @@ import jax
5
7
  import jax.tree_util as jtu
6
8
  from jaxtyping import PRNGKeyArray, PyTree
7
9
 
10
+ import haliax.nn
11
+
8
12
  from .axis import AxisSelector
9
13
  from .core import NamedArray
10
14
  from .jax_utils import maybe_rng_split
@@ -15,12 +19,45 @@ def tree_map(fn, tree, *rest, is_leaf=None):
15
19
  """
16
20
  Version of [jax.tree_util.tree_map][] that automatically treats NamedArrays as leaves.
17
21
  """
22
+ old_is_leaf = is_leaf
18
23
  if is_leaf is None:
19
24
  is_leaf = lambda x: isinstance(x, NamedArray)
20
25
  else:
21
- is_leaf = lambda x: is_leaf(x) or is_named_array(x)
26
+ is_leaf = lambda x: old_is_leaf(x) or is_named_array(x)
27
+
28
+ return jax.tree.map(fn, tree, *rest, is_leaf=is_leaf)
29
+
30
+
31
+ def scan_aware_tree_map(fn, tree, *rest, is_leaf=None):
32
+ """
33
+ Version of [haliax.tree_util.tree_map][] that is aware of the scan-layer pattern, specifically as implmeneted
34
+ in hax.nn.Stacked. This function will (implicitly) apply the transform to each layer in each Stacked module
35
+ (using vmap). If there are no Stacked modules in the tree, this function is equivalent to [haliax.tree_util.tree_map][].
36
+
37
+ Args:
38
+ fn:
39
+ tree:
40
+ *rest:
41
+ is_leaf:
42
+
43
+ Returns:
44
+ """
45
+ old_is_leaf = is_leaf
46
+ if is_leaf is None:
47
+ is_leaf = lambda x: isinstance(x, haliax.nn.Stacked)
48
+ else:
49
+ is_leaf = lambda x: old_is_leaf(x) or isinstance(x, haliax.nn.Stacked)
50
+
51
+ mapped_fn = functools.partial(scan_aware_tree_map, fn, is_leaf=is_leaf)
52
+
53
+ def rec_fn(x, *rest):
54
+ if isinstance(x, haliax.nn.Stacked):
55
+ new_inner = haliax.vmap(mapped_fn, x.Block)(x.stacked, *[r.stacked for r in rest])
56
+ return dataclasses.replace(x, stacked=new_inner) # type: ignore
57
+ else:
58
+ return fn(x)
22
59
 
23
- return jax.tree_util.tree_map(fn, tree, *rest, is_leaf=is_leaf)
60
+ return tree_map(rec_fn, tree, *rest, is_leaf=is_leaf)
24
61
 
25
62
 
26
63
  def tree_flatten(tree, is_leaf=None):
@@ -68,3 +68,30 @@ def test_seq_and_stacked_give_same_results():
68
68
  y_seq = m_seq.fold(x, key=jax.random.split(jax.random.PRNGKey(2), Block.size))
69
69
 
70
70
  assert hax.all(hax.isclose(y, y_seq, atol=1e-5))
71
+
72
+
73
+ def test_using_scan():
74
+ class Module(eqx.Module):
75
+ named: hax.NamedArray
76
+ array: jax.Array
77
+ static: int = eqx.static_field()
78
+
79
+ def __call__(self, x, *, key):
80
+ return x + self.array + self.static + hax.random.normal(key, x.axes), x * 2
81
+
82
+ @staticmethod
83
+ def init(named, array, static):
84
+ return Module(named=named, array=array, static=static)
85
+
86
+ Block = hax.Axis("block", 4)
87
+ E = hax.Axis("E", 10)
88
+
89
+ initial_named = hax.random.uniform(jax.random.PRNGKey(0), (Block, E))
90
+
91
+ m = Stacked.init(Block, Module)(named=initial_named, array=jax.numpy.ones(Block.size), static=1)
92
+
93
+ x = hax.random.uniform(jax.random.PRNGKey(1), (E,))
94
+ y, intermediates = m.scan(x, key=jax.random.split(jax.random.PRNGKey(2), Block.size))
95
+
96
+ assert y.axes == (E,)
97
+ assert intermediates.axes == (Block, E)
@@ -0,0 +1,91 @@
1
+ import dataclasses
2
+
3
+ import equinox as eqx
4
+ import jax
5
+ import jax.numpy as jnp
6
+ from chex import assert_trees_all_close
7
+
8
+ import haliax as hax
9
+ import haliax.tree_util as htu
10
+ from haliax import Axis
11
+
12
+
13
+ def test_resize_axis():
14
+
15
+ A = hax.Axis("A", 10)
16
+ B = hax.Axis("B", 20)
17
+ C = hax.Axis("C", 30)
18
+
19
+ class Module(eqx.Module):
20
+ name1: hax.NamedArray
21
+ name2: hax.NamedArray
22
+ name3: hax.NamedArray
23
+
24
+ module = Module(
25
+ name1=hax.random.normal(jax.random.PRNGKey(0), (B, A, C)),
26
+ name2=hax.zeros((B, C)),
27
+ name3=hax.zeros((Axis("A", 20),)),
28
+ )
29
+
30
+ NewA = A.resize(15)
31
+
32
+ module2 = htu.resize_axis(module, "A", 15, key=jax.random.PRNGKey(1))
33
+
34
+ assert module2.name1.axes == (B, NewA, C)
35
+ assert module2.name2.axes == (B, C)
36
+ assert module2.name3.axes == (NewA,)
37
+
38
+ # we don't mess with the mean or std of the original array too much
39
+ assert jnp.allclose(module2.name1.mean(), module.name1.mean(), rtol=1e-1, atol=1e-2)
40
+
41
+
42
+ def test_scan_aware_tree_map():
43
+ Embed = hax.Axis("embed", 10)
44
+ Up = hax.Axis("up", 20)
45
+ Block = hax.Axis("block", 4)
46
+
47
+ class Module(eqx.Module):
48
+ up: hax.nn.Linear
49
+ down: hax.nn.Linear
50
+
51
+ def __call__(self, x, *, key):
52
+ return self.down(self.up(x), key=key)
53
+
54
+ @staticmethod
55
+ def init(layer_idx, *, key):
56
+ k1, k2 = jax.random.split(key)
57
+ up = hax.nn.Linear.init(Embed, Up, key=k1)
58
+ down = hax.nn.Linear.init(Up, Embed, key=k2)
59
+
60
+ up = dataclasses.replace(up, weight=up.weight + layer_idx) # type: ignore
61
+ down = dataclasses.replace(down, weight=down.weight + layer_idx) # type: ignore
62
+
63
+ return Module(up=up, down=down)
64
+
65
+ class Model(eqx.Module):
66
+ layers: hax.nn.Stacked[eqx.Module]
67
+
68
+ def __call__(self, x, *, key):
69
+ return self.layers.fold(x, key=jax.random.split(key, self.layers.Block.size))
70
+
71
+ @staticmethod
72
+ def init(Layers, *, key):
73
+ stack = hax.nn.Stacked.init(Layers, Module)(
74
+ layer_idx=hax.arange(Layers), key=jax.random.split(key, Layers.size)
75
+ )
76
+ return Model(layers=stack)
77
+
78
+ model = Model.init(Block, key=jax.random.PRNGKey(0))
79
+
80
+ def transform_linear(x):
81
+ if not isinstance(x, hax.nn.Linear):
82
+ return x
83
+
84
+ # do something that distinguishes doing weights jointly from independently
85
+ new_weight = x.weight - hax.mean(x.weight)
86
+ return dataclasses.replace(x, weight=new_weight) # type: ignore
87
+
88
+ model2 = htu.scan_aware_tree_map(transform_linear, model, is_leaf=lambda x: isinstance(x, hax.nn.Linear))
89
+ model3 = htu.tree_map(transform_linear, model, is_leaf=lambda x: isinstance(x, hax.nn.Linear))
90
+
91
+ assert hax.all(model2.layers.stacked.up.weight != model3.layers.stacked.up.weight)
@@ -1 +0,0 @@
1
- __version__ = "1.4.dev308"
@@ -1,36 +0,0 @@
1
- import equinox as eqx
2
- import jax
3
- import jax.numpy as jnp
4
-
5
- import haliax as hax
6
- import haliax.tree_util as htu
7
- from haliax import Axis
8
-
9
-
10
- def test_resize_axis():
11
-
12
- A = hax.Axis("A", 10)
13
- B = hax.Axis("B", 20)
14
- C = hax.Axis("C", 30)
15
-
16
- class Module(eqx.Module):
17
- name1: hax.NamedArray
18
- name2: hax.NamedArray
19
- name3: hax.NamedArray
20
-
21
- module = Module(
22
- name1=hax.random.normal(jax.random.PRNGKey(0), (B, A, C)),
23
- name2=hax.zeros((B, C)),
24
- name3=hax.zeros((Axis("A", 20),)),
25
- )
26
-
27
- NewA = A.resize(15)
28
-
29
- module2 = htu.resize_axis(module, "A", 15, key=jax.random.PRNGKey(1))
30
-
31
- assert module2.name1.axes == (B, NewA, C)
32
- assert module2.name2.axes == (B, C)
33
- assert module2.name3.axes == (NewA,)
34
-
35
- # we don't mess with the mean or std of the original array too much
36
- assert jnp.allclose(module2.name1.mean(), module.name1.mean(), rtol=1e-1, atol=1e-2)
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