pathwaysutils 0.1.11__tar.gz → 0.1.13__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.
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/PKG-INFO +18 -3
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/__init__.py +1 -1
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/_initialize.py +9 -5
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/collect_profile.py +4 -1
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/elastic/elastic.py +7 -2
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/elastic/manager.py +26 -23
- pathwaysutils-0.1.13/pathwaysutils/experimental/gke/jobset.py +1368 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/shared_pathways_service/README.md +43 -14
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/shared_pathways_service/deploy_pathways_service.py +92 -43
- pathwaysutils-0.1.13/pathwaysutils/experimental/shared_pathways_service/gke_utils.py +1168 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/shared_pathways_service/isc_pathways.py +246 -97
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/shared_pathways_service/metrics_collector.py +9 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/shared_pathways_service/run_connect_example.py +35 -7
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/shared_pathways_service/run_workload.py +38 -7
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/shared_pathways_service/validators.py +85 -73
- pathwaysutils-0.1.13/pathwaysutils/extras/elastic/model_comparison.html +2052 -0
- pathwaysutils-0.1.13/pathwaysutils/extras/simple_model/__init__.py +48 -0
- pathwaysutils-0.1.13/pathwaysutils/extras/simple_model/compile.py +142 -0
- pathwaysutils-0.1.13/pathwaysutils/extras/simple_model/config.py +58 -0
- pathwaysutils-0.1.13/pathwaysutils/extras/simple_model/data.py +63 -0
- pathwaysutils-0.1.13/pathwaysutils/extras/simple_model/model.py +101 -0
- pathwaysutils-0.1.13/pathwaysutils/extras/simple_model/simple_model.py +78 -0
- pathwaysutils-0.1.13/pathwaysutils/extras/simple_model/simple_model_test.py +356 -0
- pathwaysutils-0.1.13/pathwaysutils/extras/simple_model/workload.py +219 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/persistence/helper.py +0 -13
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/profiling.py +239 -43
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/proxy_backend.py +14 -4
- pathwaysutils-0.1.13/pathwaysutils/test/experimental/gke/jobset_test.py +1723 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/test/experimental/gke/testdata/model_lite_tpuv5e_4x8.yaml +0 -4
- pathwaysutils-0.1.13/pathwaysutils/test/experimental/shared_pathways_service/deploy_pathways_service_test.py +390 -0
- pathwaysutils-0.1.13/pathwaysutils/test/experimental/shared_pathways_service/gke_utils_test.py +2251 -0
- pathwaysutils-0.1.13/pathwaysutils/test/experimental/shared_pathways_service/isc_pathways_test.py +1536 -0
- pathwaysutils-0.1.13/pathwaysutils/test/experimental/shared_pathways_service/metrics_collector_test.py +247 -0
- pathwaysutils-0.1.13/pathwaysutils/test/experimental/shared_pathways_service/run_workload_test.py +287 -0
- pathwaysutils-0.1.13/pathwaysutils/test/experimental/shared_pathways_service/start_vscode_on_cpu_np_test.py +324 -0
- pathwaysutils-0.1.13/pathwaysutils/test/experimental/shared_pathways_service/tpu_specs_test.py +77 -0
- pathwaysutils-0.1.13/pathwaysutils/test/experimental/shared_pathways_service/validators_test.py +396 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/test/initialize_test.py +15 -0
- pathwaysutils-0.1.13/pathwaysutils/test/mock_fault_injection.py +293 -0
- pathwaysutils-0.1.13/pathwaysutils/test/mock_fault_injection_test.py +201 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/test/profiling_test.py +465 -20
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/test/proxy_backend_test.py +41 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pyproject.toml +21 -2
- pathwaysutils-0.1.11/pathwaysutils/experimental/gke/jobset.py +0 -923
- pathwaysutils-0.1.11/pathwaysutils/experimental/shared_pathways_service/gke_utils.py +0 -533
- pathwaysutils-0.1.11/pathwaysutils/persistence/orbax_handler.py +0 -292
- pathwaysutils-0.1.11/pathwaysutils/test/experimental/gke/jobset_test.py +0 -977
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/LICENSE +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/README.md +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/debug/__init__.py +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/debug/timing.py +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/debug/watchdog.py +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/elastic/__init__.py +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/__init__.py +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/concatenate_by_mesh_axis.py +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/gke/__init__.py +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/profiling.py +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/reshard.py +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/shared_pathways_service/__init__.py +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/shared_pathways_service/dockerfiles/sample_sidecar.dockerfile +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/shared_pathways_service/start_vscode_on_cpu_np.py +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/shared_pathways_service/tpu_specs.py +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/shared_pathways_service/yamls/code-server.yaml +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/shared_pathways_service/yamls/pw-proxy.yaml +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/split_by_mesh_axis.py +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/jax/__init__.py +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/lru_cache.py +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/persistence/__init__.py +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/plugin_executable.py +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/reshard.py +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/test/__init__.py +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/test/debug/__init__.py +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/test/debug/timing_test.py +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/test/debug/watchdog_test.py +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/test/experimental/reshard_test.py +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/test/lru_cache_test.py +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/test/persistence_test.py +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/test/plugin_executable_test.py +0 -0
- {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/test/reshard_test.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pathwaysutils
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.13
|
|
4
4
|
Summary: Package of Pathways-on-Cloud utilities.
|
|
5
5
|
Keywords:
|
|
6
6
|
Author-email: Pathways-on-Cloud Utilities Developers <pathwaysutils-dev@google.com>
|
|
@@ -10,17 +10,32 @@ Classifier: License :: OSI Approved :: Apache Software License
|
|
|
10
10
|
License-File: LICENSE
|
|
11
11
|
Requires-Dist: absl-py
|
|
12
12
|
Requires-Dist: fastapi
|
|
13
|
-
Requires-Dist: jax>=0.
|
|
14
|
-
Requires-Dist: orbax-checkpoint
|
|
13
|
+
Requires-Dist: jax>=0.10.0
|
|
14
|
+
Requires-Dist: orbax-checkpoint>=0.12.3
|
|
15
15
|
Requires-Dist: uvicorn
|
|
16
16
|
Requires-Dist: requests
|
|
17
17
|
Requires-Dist: packaging
|
|
18
18
|
Requires-Dist: pylint>=2.6.0 ; extra == "dev"
|
|
19
19
|
Requires-Dist: pyink ; extra == "dev"
|
|
20
|
+
Requires-Dist: kubernetes ; extra == "gke"
|
|
21
|
+
Requires-Dist: pyyaml ; extra == "gke"
|
|
22
|
+
Requires-Dist: portpicker ; extra == "sps"
|
|
23
|
+
Requires-Dist: google-cloud-monitoring ; extra == "sps"
|
|
24
|
+
Requires-Dist: portpicker ; extra == "sps-without-monitoring"
|
|
25
|
+
Requires-Dist: google-cloud-monitoring ; extra == "test"
|
|
26
|
+
Requires-Dist: httpx ; extra == "test"
|
|
27
|
+
Requires-Dist: kubernetes ; extra == "test"
|
|
28
|
+
Requires-Dist: portpicker ; extra == "test"
|
|
29
|
+
Requires-Dist: pyyaml ; extra == "test"
|
|
30
|
+
Requires-Dist: pytest ; extra == "test"
|
|
20
31
|
Project-URL: changelog, https://github.com/AI-Hypercomputer/pathways-utils/blob/main/CHANGELOG.md
|
|
21
32
|
Project-URL: homepage, https://github.com/AI-Hypercomputer/pathways-utils
|
|
22
33
|
Project-URL: repository, https://github.com/AI-Hypercomputer/pathways-utils
|
|
23
34
|
Provides-Extra: dev
|
|
35
|
+
Provides-Extra: gke
|
|
36
|
+
Provides-Extra: sps
|
|
37
|
+
Provides-Extra: sps-without-monitoring
|
|
38
|
+
Provides-Extra: test
|
|
24
39
|
|
|
25
40
|
# Package of Pathways-on-Cloud utilities
|
|
26
41
|
|
|
@@ -18,10 +18,11 @@ import logging
|
|
|
18
18
|
import os
|
|
19
19
|
|
|
20
20
|
import jax
|
|
21
|
+
from orbax.checkpoint import type_handlers
|
|
21
22
|
from orbax.checkpoint._src.metadata import array_metadata_store as array_metadata_store_lib
|
|
23
|
+
from orbax.checkpoint._src.serialization import cloud_pathways_array_handler
|
|
22
24
|
from pathwaysutils import profiling
|
|
23
25
|
from pathwaysutils import proxy_backend
|
|
24
|
-
from pathwaysutils.persistence import orbax_handler
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|
_logger = logging.getLogger(__name__)
|
|
@@ -91,11 +92,14 @@ def initialize() -> None:
|
|
|
91
92
|
_logger.debug("Detected Pathways-on-Cloud backend. Applying changes.")
|
|
92
93
|
proxy_backend.register_backend_factory()
|
|
93
94
|
profiling.monkey_patch_jax()
|
|
94
|
-
# TODO: b/365549911 - Remove when OCDBT-compatible
|
|
95
95
|
if _is_persistence_enabled():
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
type_handlers.register_type_handler(
|
|
97
|
+
jax.Array,
|
|
98
|
+
cloud_pathways_array_handler.CloudPathwaysArrayHandler(
|
|
99
|
+
timeout=datetime.timedelta(hours=1),
|
|
100
|
+
array_metadata_store=array_metadata_store_lib.Store(),
|
|
101
|
+
),
|
|
102
|
+
override=True,
|
|
99
103
|
)
|
|
100
104
|
|
|
101
105
|
# Turn off JAX compilation cache because Pathways handles its own
|
|
@@ -67,7 +67,10 @@ def main() -> None:
|
|
|
67
67
|
args = parser.parse_args()
|
|
68
68
|
|
|
69
69
|
if profiling.collect_profile(
|
|
70
|
-
args.port,
|
|
70
|
+
args.port,
|
|
71
|
+
args.duration_ms,
|
|
72
|
+
args.host,
|
|
73
|
+
args.log_dir,
|
|
71
74
|
):
|
|
72
75
|
_logger.info("Dumped profiling information in: %s", args.log_dir)
|
|
73
76
|
else:
|
|
@@ -171,7 +171,7 @@ def get_active_slice_indices(
|
|
|
171
171
|
|
|
172
172
|
|
|
173
173
|
def wait_for_slices(
|
|
174
|
-
slice_count: int,
|
|
174
|
+
slice_count: int | None = None,
|
|
175
175
|
poll_interval: float | int = 10,
|
|
176
176
|
timeout: float | int | None = None,
|
|
177
177
|
slice_to_devices: Mapping[int, Sequence[jax.Device]] | None = None,
|
|
@@ -180,7 +180,8 @@ def wait_for_slices(
|
|
|
180
180
|
"""Waits until after at least `slice_count` slices become active.
|
|
181
181
|
|
|
182
182
|
Args:
|
|
183
|
-
slice_count: The number of slices to wait for.
|
|
183
|
+
slice_count: The number of slices to wait for. If None, defaults to the
|
|
184
|
+
total number of slices.
|
|
184
185
|
poll_interval: The minimum number of seconds to wait between availability
|
|
185
186
|
checks. If the check takes longer than this, the next check will start
|
|
186
187
|
immediately after the current check completes. Defaults to 10 seconds.
|
|
@@ -201,6 +202,10 @@ def wait_for_slices(
|
|
|
201
202
|
_logger.debug("slice_to_devices is None. Getting from jax.devices().")
|
|
202
203
|
slice_to_devices = get_slice_to_devices(jax.devices())
|
|
203
204
|
|
|
205
|
+
if slice_count is None:
|
|
206
|
+
_logger.debug("slice_count is None. Using len(slice_to_devices).")
|
|
207
|
+
slice_count = len(slice_to_devices)
|
|
208
|
+
|
|
204
209
|
_logger.info(
|
|
205
210
|
"Waiting for %s slices. Poll interval: %s, Timeout: %s",
|
|
206
211
|
slice_count,
|
|
@@ -52,7 +52,7 @@ RetryPolicy: TypeAlias = Callable[[int, Exception], bool]
|
|
|
52
52
|
|
|
53
53
|
|
|
54
54
|
def _elastic_event_cleanup() -> None:
|
|
55
|
-
"""
|
|
55
|
+
"""Stops any ongoing JAX profiler trace."""
|
|
56
56
|
try:
|
|
57
57
|
_logger.info("Cleaning up any ongoing traces")
|
|
58
58
|
jax.profiler.stop_trace()
|
|
@@ -62,10 +62,6 @@ def _elastic_event_cleanup() -> None:
|
|
|
62
62
|
_logger.exception("Error cleaning up ongoing traces")
|
|
63
63
|
raise
|
|
64
64
|
|
|
65
|
-
jax.clear_caches()
|
|
66
|
-
for array in jax.live_arrays():
|
|
67
|
-
array.delete()
|
|
68
|
-
|
|
69
65
|
|
|
70
66
|
class ElasticRetryLimit:
|
|
71
67
|
"""A retry callback that limits the number of attempts."""
|
|
@@ -116,11 +112,12 @@ class Manager:
|
|
|
116
112
|
|
|
117
113
|
self.all_slice_indices = frozenset(self.slice_to_devices.keys())
|
|
118
114
|
|
|
115
|
+
self._active_slice_indices = frozenset()
|
|
116
|
+
self.available_inactive_slices = frozenset()
|
|
117
|
+
|
|
119
118
|
self.active_slice_indices = elastic.get_active_slice_indices(
|
|
120
119
|
slice_to_devices=self.slice_to_devices
|
|
121
120
|
)
|
|
122
|
-
self.inactive_slice_indices = self.all_slice_indices - self.active_slice_indices
|
|
123
|
-
self.available_inactive_slices = frozenset()
|
|
124
121
|
|
|
125
122
|
self._stop_event = None
|
|
126
123
|
self._monitor_thread = None
|
|
@@ -180,22 +177,26 @@ class Manager:
|
|
|
180
177
|
except StopIteration as error:
|
|
181
178
|
raise ValueError("No active slices") from error
|
|
182
179
|
|
|
180
|
+
@property
|
|
181
|
+
def active_slice_indices(self) -> frozenset[int]:
|
|
182
|
+
"""The indices of active slices."""
|
|
183
|
+
return self._active_slice_indices
|
|
184
|
+
|
|
185
|
+
@active_slice_indices.setter
|
|
186
|
+
def active_slice_indices(self, value: Set[int]) -> None:
|
|
187
|
+
self._active_slice_indices = frozenset(value)
|
|
188
|
+
self.inactive_slice_indices = (
|
|
189
|
+
self.all_slice_indices - self._active_slice_indices
|
|
190
|
+
)
|
|
191
|
+
self.available_inactive_slices = frozenset(
|
|
192
|
+
self.available_inactive_slices - self._active_slice_indices
|
|
193
|
+
)
|
|
194
|
+
|
|
183
195
|
@property
|
|
184
196
|
def active_slice_count(self) -> int:
|
|
185
197
|
"""The number of active slices."""
|
|
186
198
|
return len(self.active_slice_indices)
|
|
187
199
|
|
|
188
|
-
@property
|
|
189
|
-
def new_slice_event(self) -> threading.Event:
|
|
190
|
-
"""Deprecated compatibility property for un-updated MaxText code.
|
|
191
|
-
|
|
192
|
-
TODO: b/527183831 - Remove this property once MaxText CL 2 is submitted.
|
|
193
|
-
"""
|
|
194
|
-
event = threading.Event()
|
|
195
|
-
if self.available_inactive_slices:
|
|
196
|
-
event.set()
|
|
197
|
-
return event
|
|
198
|
-
|
|
199
200
|
def scale_by_active_slices(self, x: int | float) -> int | float:
|
|
200
201
|
"""Scale x by the number of active slices."""
|
|
201
202
|
if isinstance(x, int):
|
|
@@ -294,8 +295,7 @@ class Manager:
|
|
|
294
295
|
|
|
295
296
|
This decorator wraps a function to automatically retry execution in case of
|
|
296
297
|
`jax.errors.JaxRuntimeError` caused by slice down events. It waits for
|
|
297
|
-
`minimum_slice_count` active slices before each attempt
|
|
298
|
-
caches on failure.
|
|
298
|
+
`minimum_slice_count` active slices before each attempt.
|
|
299
299
|
|
|
300
300
|
If `minimum_slice_count` is not met, the function will wait until at least
|
|
301
301
|
`minimum_slice_count` slices are active before execution. If
|
|
@@ -308,6 +308,12 @@ class Manager:
|
|
|
308
308
|
boundaries) and raise a `ScaleUpSignalError` to gracefully interrupt the
|
|
309
309
|
current execution and trigger a retry with the expanded hardware.
|
|
310
310
|
|
|
311
|
+
On an elastic event the arrays of the failed attempt are not deleted
|
|
312
|
+
explicitly; JAX frees them once the attempt has unwound and nothing
|
|
313
|
+
references them anymore. The wrapped function and the callbacks must not
|
|
314
|
+
keep references to them, or the memory stays allocated during the next
|
|
315
|
+
attempt.
|
|
316
|
+
|
|
311
317
|
Often, the function will dispatch JAX operations and wait for them to
|
|
312
318
|
complete while creating a log message. If using Python logging, it is
|
|
313
319
|
recommended to set `logging.raiseExceptions=True` to ensure that the
|
|
@@ -372,9 +378,6 @@ class Manager:
|
|
|
372
378
|
poll_interval=poll_interval,
|
|
373
379
|
timeout=timeout,
|
|
374
380
|
)
|
|
375
|
-
self.inactive_slice_indices = (
|
|
376
|
-
self.all_slice_indices - self.active_slice_indices
|
|
377
|
-
)
|
|
378
381
|
# Reset available_inactive_slices at attempt start since
|
|
379
382
|
# active_slice_indices has just been updated by wait_for_slices.
|
|
380
383
|
self.available_inactive_slices = frozenset()
|