haliax 1.4.dev296__tar.gz → 1.4.dev298__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.dev296 → haliax-1.4.dev298}/.github/workflows/run_tests.yaml +1 -7
- {haliax-1.4.dev296 → haliax-1.4.dev298}/PKG-INFO +2 -1
- {haliax-1.4.dev296 → haliax-1.4.dev298}/pyproject.toml +2 -0
- haliax-1.4.dev298/src/haliax/__about__.py +1 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/__init__.py +2 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/axis.py +13 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/core.py +6 -2
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/nn/embedding.py +9 -2
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/nn/linear.py +12 -2
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/nn/mlp.py +21 -4
- {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_fp8.py +11 -7
- {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_hof.py +32 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_partitioning.py +11 -16
- haliax-1.4.dev296/src/haliax/__about__.py +0 -1
- {haliax-1.4.dev296 → haliax-1.4.dev298}/.coveragerc +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/.flake8 +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/.github/workflows/publish_dev.yaml +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/.github/workflows/run_pre_commit.yaml +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/.gitignore +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/.pre-commit-config.yaml +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/.readthedocs.yaml +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/CONTRIBUTING.md +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/LICENSE +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/README.md +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/api.md +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/broadcasting.md +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/cheatsheet.md +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/css/material.css +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/css/mkdocstrings.css +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/faq.md +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/figures/data_parallel_mesh.png +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/figures/data_parallel_mesh_replicated.png +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/figures/device_mesh_1d.png +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/figures/device_mesh_1d_zero.png +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/figures/device_mesh_2d.png +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/figures/device_mesh_2d_batch_partitioned.png +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/figures/device_mesh_2d_data_replicated.png +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/figures/device_mesh_2d_data_replicated_mlp_partitioned.png +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/figures/device_mesh_2d_intermediate_fully_partitioned.png +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/figures/device_mesh_2d_zero.png +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/fp8.md +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/hof.md +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/index.md +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/indexing.md +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/matmul.md +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/nn.md +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/partitioning.md +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/rearrange.ipynb +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/rearrange.md +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/requirements.txt +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/tutorial.md +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/mkdocs.yml +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/_src/__init__.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/_src/compile_utils.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/_src/dot.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/_src/einsum.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/_src/fp8.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/_src/parsing.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/_src/rearrange.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/_src/util.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/debug.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/hof.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/jax_utils.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/nn/__init__.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/nn/activations.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/nn/attention.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/nn/conv.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/nn/dropout.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/nn/loss.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/nn/normalization.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/nn/pool.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/nn/scan.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/ops.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/partitioning.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/quantization.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/random.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/specialized_fns.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/tree_util.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/types.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/util.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/wrap.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/core_test.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_attention.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_axis.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_conv.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_debug.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_dot.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_einsum.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_nn.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_ops.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_parsing.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_pool.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_random.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_rearrange.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_scan.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_specialized_fns.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_tree_util.py +0 -0
- {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_utils.py +0 -0
|
@@ -21,13 +21,7 @@ jobs:
|
|
|
21
21
|
python -m pip install --upgrade pip
|
|
22
22
|
pip install flake8 pytest
|
|
23
23
|
pip install --upgrade "jax[cpu]==0.4.25" "jaxlib[cpu]==0.4.25"
|
|
24
|
-
pip install .
|
|
25
|
-
# - name: Lint with flake8
|
|
26
|
-
# run: |
|
|
27
|
-
# # stop the build if there are Python syntax errors or undefined names
|
|
28
|
-
# flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
|
|
29
|
-
# # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
|
|
30
|
-
# flake8 . --count --exit-zero --max-complexity=50 --max-line-length=127 --statistics
|
|
24
|
+
pip install .[dev]
|
|
31
25
|
- name: Test with pytest
|
|
32
26
|
run: |
|
|
33
27
|
XLA_FLAGS=--xla_force_host_platform_device_count=8 PYTHONPATH=tests:src:. pytest tests
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: haliax
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.dev298
|
|
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/
|
|
@@ -17,6 +17,7 @@ Requires-Dist: equinox>=0.10.6
|
|
|
17
17
|
Requires-Dist: jaxtyping>=0.2.20
|
|
18
18
|
Requires-Dist: jmp>=0.0.4
|
|
19
19
|
Provides-Extra: dev
|
|
20
|
+
Requires-Dist: chex>=0.1.86; extra == 'dev'
|
|
20
21
|
Requires-Dist: mkdocs-include-markdown-plugin; extra == 'dev'
|
|
21
22
|
Requires-Dist: mkdocs-literate-nav>=0.6.0; extra == 'dev'
|
|
22
23
|
Requires-Dist: mkdocs-macros-plugin>=0.7.0; extra == 'dev'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.4.dev298"
|
|
@@ -26,6 +26,7 @@ from .axis import (
|
|
|
26
26
|
AxisSelector,
|
|
27
27
|
AxisSpec,
|
|
28
28
|
axis_name,
|
|
29
|
+
axis_size,
|
|
29
30
|
concat_axes,
|
|
30
31
|
dblock,
|
|
31
32
|
ds,
|
|
@@ -55,6 +56,7 @@ from .core import (
|
|
|
55
56
|
unflatten_axis,
|
|
56
57
|
updated_slice,
|
|
57
58
|
)
|
|
59
|
+
from .jax_utils import filter_checkpoint
|
|
58
60
|
from .hof import fold, map, scan, vmap
|
|
59
61
|
from .ops import clip, isclose, pad_left, trace, tril, triu, where
|
|
60
62
|
from .partitioning import auto_sharded, axis_mapping, fsdp, named_jit, shard, shard_with_axis_mapping
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import typing
|
|
2
2
|
from dataclasses import dataclass
|
|
3
|
+
from math import prod
|
|
3
4
|
from types import EllipsisType
|
|
4
5
|
from typing import Dict, List, Mapping, Optional, Sequence, Tuple, Union, overload
|
|
5
6
|
|
|
@@ -354,6 +355,17 @@ def axis_name(ax: AxisSelection) -> Union[str, Tuple[str, ...]]:
|
|
|
354
355
|
return tuple(_ax_name(x) for x in ax)
|
|
355
356
|
|
|
356
357
|
|
|
358
|
+
def axis_size(ax: AxisSpec) -> int:
|
|
359
|
+
"""
|
|
360
|
+
Returns the size of the axis or the product of the sizes of the axes in the axis spec
|
|
361
|
+
"""
|
|
362
|
+
|
|
363
|
+
if isinstance(ax, Axis):
|
|
364
|
+
return ax.size
|
|
365
|
+
else:
|
|
366
|
+
return prod(axis.size for axis in ensure_tuple(ax)) # type: ignore
|
|
367
|
+
|
|
368
|
+
|
|
357
369
|
class dslice(eqx.Module):
|
|
358
370
|
"""
|
|
359
371
|
Dynamic slice, comprising a (start, length) pair. Also aliased as ds.
|
|
@@ -524,6 +536,7 @@ __all__ = [
|
|
|
524
536
|
"PartialShapeDict",
|
|
525
537
|
"ShapeDict",
|
|
526
538
|
"axis_name",
|
|
539
|
+
"axis_size",
|
|
527
540
|
"concat_axes",
|
|
528
541
|
"union_axes",
|
|
529
542
|
"axis_spec_to_shape_dict",
|
|
@@ -441,7 +441,11 @@ class NamedArray:
|
|
|
441
441
|
|
|
442
442
|
@typing.overload
|
|
443
443
|
def dot(
|
|
444
|
-
self,
|
|
444
|
+
self,
|
|
445
|
+
*args: "NamedArray",
|
|
446
|
+
axis: Optional[AxisSelection],
|
|
447
|
+
precision: PrecisionLike = None,
|
|
448
|
+
dot_general=jax.lax.dot_general,
|
|
445
449
|
) -> "NamedArray":
|
|
446
450
|
...
|
|
447
451
|
|
|
@@ -1143,7 +1147,7 @@ def flatten_axes(array: NamedArray, old_axes: AxisSelection, new_axis: AxisSelec
|
|
|
1143
1147
|
"""
|
|
1144
1148
|
old_axes = ensure_tuple(old_axes)
|
|
1145
1149
|
old_axes = array.resolve_axis(old_axes)
|
|
1146
|
-
total_axis_size =
|
|
1150
|
+
total_axis_size = haliax.axis_size(old_axes)
|
|
1147
1151
|
|
|
1148
1152
|
if isinstance(new_axis, Axis):
|
|
1149
1153
|
if new_axis.size != total_axis_size:
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import dataclasses
|
|
2
|
+
import math
|
|
3
|
+
import warnings
|
|
2
4
|
from typing import Optional
|
|
3
5
|
|
|
4
6
|
import equinox as eqx
|
|
@@ -21,9 +23,14 @@ class Embedding(eqx.Module):
|
|
|
21
23
|
Embed: AxisSpec = eqx.static_field()
|
|
22
24
|
|
|
23
25
|
@staticmethod
|
|
24
|
-
def init(Vocab: Axis, Embed: AxisSpec,
|
|
26
|
+
def init(Vocab: Axis, Embed: AxisSpec, *, init_scale: float = 1, key, initializer_range: Optional[float] = None):
|
|
27
|
+
if initializer_range is not None:
|
|
28
|
+
warnings.warn("initializer_range is deprecated. Use init_std instead.", DeprecationWarning)
|
|
29
|
+
init_scale = initializer_range
|
|
30
|
+
|
|
25
31
|
all_axes = (Vocab,) + ensure_tuple(Embed)
|
|
26
|
-
|
|
32
|
+
output_size = hax.axis_size(Embed)
|
|
33
|
+
weight = hax.random.truncated_normal(key, all_axes, -3, 3) * (init_scale / math.sqrt(output_size))
|
|
27
34
|
return Embedding(weight=weight, Vocab=Vocab, Embed=Embed)
|
|
28
35
|
|
|
29
36
|
def __call__(self, input_ids, *, key: Optional[PRNGKeyArray] = None):
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import math
|
|
1
2
|
from typing import Callable, Optional
|
|
2
3
|
|
|
3
4
|
import equinox as eqx
|
|
@@ -25,7 +26,14 @@ class Linear(eqx.Module):
|
|
|
25
26
|
|
|
26
27
|
@staticmethod
|
|
27
28
|
def init(
|
|
28
|
-
In: AxisSpec,
|
|
29
|
+
In: AxisSpec,
|
|
30
|
+
Out: AxisSpec,
|
|
31
|
+
*,
|
|
32
|
+
key,
|
|
33
|
+
use_bias=True,
|
|
34
|
+
out_first: bool = False,
|
|
35
|
+
dot_general=None,
|
|
36
|
+
init_scale: float = 1.0,
|
|
29
37
|
) -> "Linear":
|
|
30
38
|
"""
|
|
31
39
|
|
|
@@ -36,9 +44,11 @@ class Linear(eqx.Module):
|
|
|
36
44
|
use_bias: bool: Whether to use a bias term
|
|
37
45
|
out_first: bool: Whether to put output axes first in the weight matrix. out_first is how PyTorch does it.
|
|
38
46
|
dot_general: Callable: The dot_general function to use. Defaults to jax.lax.dot_general. For fp8 or int8
|
|
47
|
+
init_scale: float: The scale to use for initialization. We scale init by 1/sqrt(Input.size)*init_scale
|
|
39
48
|
"""
|
|
40
49
|
joint_spec = hax.concat_axis_specs(Out, In) if out_first else hax.concat_axis_specs(In, Out)
|
|
41
|
-
|
|
50
|
+
input_size = hax.axis_size(In)
|
|
51
|
+
weight = hax.random.truncated_normal(key, joint_spec, -3, 3) * (init_scale / math.sqrt(input_size))
|
|
42
52
|
bias = hax.zeros(Out) if use_bias else None
|
|
43
53
|
|
|
44
54
|
if dot_general is None:
|
|
@@ -48,6 +48,7 @@ class MLP(eqx.Module):
|
|
|
48
48
|
use_final_bias: bool = True,
|
|
49
49
|
key: PRNGKeyArray,
|
|
50
50
|
dot_general: Optional[DotGeneralOp] = None,
|
|
51
|
+
init_scale: float = 1.0,
|
|
51
52
|
):
|
|
52
53
|
Width = _get_width(width)
|
|
53
54
|
Width2 = Width.alias(Width.name + "2")
|
|
@@ -58,18 +59,34 @@ class MLP(eqx.Module):
|
|
|
58
59
|
|
|
59
60
|
if depth == 0:
|
|
60
61
|
# special case: no hidden layers
|
|
61
|
-
layers.append(
|
|
62
|
+
layers.append(
|
|
63
|
+
Linear.init(
|
|
64
|
+
Input, Output, use_bias=use_final_bias, key=keys[0], dot_general=dot_general, init_scale=init_scale
|
|
65
|
+
)
|
|
66
|
+
)
|
|
62
67
|
else:
|
|
63
68
|
# first hidden layer
|
|
64
|
-
layers.append(
|
|
69
|
+
layers.append(
|
|
70
|
+
Linear.init(
|
|
71
|
+
Input, Width, use_bias=use_bias, key=keys[0], dot_general=dot_general, init_scale=init_scale
|
|
72
|
+
)
|
|
73
|
+
)
|
|
65
74
|
# middle hidden layers
|
|
66
75
|
cur = Width
|
|
67
76
|
next = Width2
|
|
68
77
|
for i in range(1, depth):
|
|
69
|
-
layers.append(
|
|
78
|
+
layers.append(
|
|
79
|
+
Linear.init(
|
|
80
|
+
cur, next, use_bias=use_bias, key=keys[i], dot_general=dot_general, init_scale=init_scale
|
|
81
|
+
)
|
|
82
|
+
)
|
|
70
83
|
cur, next = next, cur
|
|
71
84
|
# final hidden layer
|
|
72
|
-
layers.append(
|
|
85
|
+
layers.append(
|
|
86
|
+
Linear.init(
|
|
87
|
+
cur, Output, use_bias=use_final_bias, key=keys[-1], dot_general=dot_general, init_scale=init_scale
|
|
88
|
+
)
|
|
89
|
+
)
|
|
73
90
|
|
|
74
91
|
return MLP(
|
|
75
92
|
layers=tuple(layers),
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import chex
|
|
1
2
|
import equinox as eqx
|
|
2
3
|
import jax.numpy as jnp
|
|
3
4
|
import jax.random as jrandom
|
|
4
5
|
import jax.tree_util
|
|
5
6
|
import numpy as np
|
|
7
|
+
from chex import assert_trees_all_close
|
|
6
8
|
|
|
7
9
|
import haliax as hax
|
|
8
10
|
from haliax._src.fp8 import compute_scale
|
|
@@ -19,18 +21,20 @@ from haliax.quantization import (
|
|
|
19
21
|
def test_fp8_is_reasonable():
|
|
20
22
|
In = hax.Axis("In", 8)
|
|
21
23
|
Out = hax.Axis("Out", 8)
|
|
22
|
-
linear = Linear.init(In, Out, key=jrandom.PRNGKey(0))
|
|
24
|
+
linear = Linear.init(In, Out, key=jrandom.PRNGKey(0), init_scale=0.1)
|
|
23
25
|
|
|
24
|
-
fp8_linear = Linear.init(
|
|
26
|
+
fp8_linear = Linear.init(
|
|
27
|
+
In, Out, key=jrandom.PRNGKey(0), dot_general=hax.quantization.Fp8DotGeneralOp.init(), init_scale=0.1
|
|
28
|
+
)
|
|
25
29
|
|
|
26
|
-
input = hax.random.normal(jrandom.PRNGKey(
|
|
30
|
+
input = hax.random.normal(jrandom.PRNGKey(3), In)
|
|
27
31
|
output = linear(input)
|
|
28
32
|
fp8_output = fp8_linear(input)
|
|
29
33
|
|
|
30
34
|
assert output.shape == fp8_output.shape
|
|
31
35
|
assert output.dtype == fp8_output.dtype
|
|
32
36
|
|
|
33
|
-
|
|
37
|
+
assert_trees_all_close(output.array, fp8_output.array, atol=1e-2, rtol=5e-2)
|
|
34
38
|
|
|
35
39
|
|
|
36
40
|
# https://github.com/google/flax/blob/6f2b08e024c2fd2f8cec42a6c82408cb35412319/tests/linen/linen_test.py#L1222
|
|
@@ -130,9 +134,9 @@ def test_fp_loop():
|
|
|
130
134
|
def test_layer_splicing():
|
|
131
135
|
key, init_key, random_key = jrandom.split(jrandom.PRNGKey(seed=123), 3)
|
|
132
136
|
Input = hax.Axis("Input", 16)
|
|
133
|
-
Hidden = hax.Axis("Hidden",
|
|
137
|
+
Hidden = hax.Axis("Hidden", 64)
|
|
134
138
|
Output = hax.Axis("Output", 32)
|
|
135
|
-
mlp = hax.nn.MLP.init(Input, Output, Hidden, 3, key=init_key)
|
|
139
|
+
mlp = hax.nn.MLP.init(Input, Output, Hidden, 3, key=init_key, init_scale=0.1)
|
|
136
140
|
|
|
137
141
|
mlp_q = fp8_linear_layers(mlp, Fp8Config())
|
|
138
142
|
for layer in mlp_q.layers:
|
|
@@ -141,7 +145,7 @@ def test_layer_splicing():
|
|
|
141
145
|
input = hax.random.normal(jrandom.PRNGKey(0), Input) * 10 # 10 so we don't underflow
|
|
142
146
|
output = mlp(input)
|
|
143
147
|
output_q = mlp_q(input)
|
|
144
|
-
|
|
148
|
+
chex.assert_trees_all_close(output.array, output_q.array, atol=1e-3, rtol=1e-3)
|
|
145
149
|
assert not jnp.allclose(output_q.array, 0) # don't want them to all underflow
|
|
146
150
|
|
|
147
151
|
mlp_q = fp8_linear_layers(mlp, Fp8Config(targets="layers.0"))
|
|
@@ -87,6 +87,38 @@ def test_scan_doesnt_scan_scalars():
|
|
|
87
87
|
assert jnp.all(jnp.equal(selected.array, named1.array * 4.0))
|
|
88
88
|
|
|
89
89
|
|
|
90
|
+
def test_scan_doesnt_scan_init():
|
|
91
|
+
Height = Axis("Height", 10)
|
|
92
|
+
named1 = hax.random.uniform(PRNGKey(0), (Height,))
|
|
93
|
+
|
|
94
|
+
init = jnp.arange(Height.size, dtype=jnp.float32)
|
|
95
|
+
|
|
96
|
+
def scan_fun(acc, z, x):
|
|
97
|
+
out = acc + z * x, x * z
|
|
98
|
+
return out
|
|
99
|
+
|
|
100
|
+
total, selected = hax.scan(scan_fun, Height)(init, 4.0, named1)
|
|
101
|
+
|
|
102
|
+
assert jnp.all(jnp.isclose(total, init + jnp.sum(named1.array * 4.0)))
|
|
103
|
+
|
|
104
|
+
# double check with named array init
|
|
105
|
+
total, selected = hax.scan(scan_fun, Height)(hax.named(init, "Height"), 4.0, named1)
|
|
106
|
+
|
|
107
|
+
assert jnp.all(jnp.isclose(total.array, init + jnp.sum(named1.array * 4.0)))
|
|
108
|
+
|
|
109
|
+
# now do fold
|
|
110
|
+
def fold_fun(acc, z, x):
|
|
111
|
+
return acc + z * x
|
|
112
|
+
|
|
113
|
+
total = hax.fold(fold_fun, Height)(init, 4.0, named1)
|
|
114
|
+
|
|
115
|
+
assert jnp.all(jnp.isclose(total, init + jnp.sum(named1.array * 4.0)))
|
|
116
|
+
|
|
117
|
+
total = hax.fold(fold_fun, Height)(hax.named(init, "Height"), 4.0, named1)
|
|
118
|
+
|
|
119
|
+
assert jnp.all(jnp.isclose(total.array, init + jnp.sum(named1.array * 4.0)))
|
|
120
|
+
|
|
121
|
+
|
|
90
122
|
def test_reduce():
|
|
91
123
|
Height = Axis("Height", 10)
|
|
92
124
|
Width = Axis("Width", 3)
|
|
@@ -108,26 +108,21 @@ def test_pjit_class_init_with_args():
|
|
|
108
108
|
def test_infer_resource_partition_gda_bug():
|
|
109
109
|
devices = jax.devices()
|
|
110
110
|
with Mesh(np.array(devices).reshape(-1, 1), (ResourceAxis.DATA, ResourceAxis.MODEL)):
|
|
111
|
-
jax.config.update("jax_parallel_functions_output_gda", True)
|
|
112
|
-
try:
|
|
113
111
|
|
|
114
|
-
|
|
115
|
-
|
|
112
|
+
def foo():
|
|
113
|
+
return hax.zeros((Dim1, Dim2, Dim3))
|
|
116
114
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
115
|
+
pjit_foo = named_jit(foo, resource_map)
|
|
116
|
+
r = pjit_foo()
|
|
117
|
+
assert r.axes == (Dim1, Dim2, Dim3)
|
|
120
118
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
# this won't work with GDAs
|
|
125
|
-
pjit_bar = named_jit(bar, resource_map)
|
|
126
|
-
r = pjit_bar(r)
|
|
127
|
-
assert r.axes == (Dim1, Dim2, Dim3)
|
|
119
|
+
def bar(x):
|
|
120
|
+
return x
|
|
128
121
|
|
|
129
|
-
|
|
130
|
-
|
|
122
|
+
# this won't work with GDAs
|
|
123
|
+
pjit_bar = named_jit(bar, resource_map)
|
|
124
|
+
r = pjit_bar(r)
|
|
125
|
+
assert r.axes == (Dim1, Dim2, Dim3)
|
|
131
126
|
|
|
132
127
|
|
|
133
128
|
@skip_if_not_enough_devices(4)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.4.dev296"
|
|
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
|