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.
Files changed (79) hide show
  1. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/PKG-INFO +18 -3
  2. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/__init__.py +1 -1
  3. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/_initialize.py +9 -5
  4. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/collect_profile.py +4 -1
  5. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/elastic/elastic.py +7 -2
  6. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/elastic/manager.py +26 -23
  7. pathwaysutils-0.1.13/pathwaysutils/experimental/gke/jobset.py +1368 -0
  8. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/shared_pathways_service/README.md +43 -14
  9. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/shared_pathways_service/deploy_pathways_service.py +92 -43
  10. pathwaysutils-0.1.13/pathwaysutils/experimental/shared_pathways_service/gke_utils.py +1168 -0
  11. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/shared_pathways_service/isc_pathways.py +246 -97
  12. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/shared_pathways_service/metrics_collector.py +9 -0
  13. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/shared_pathways_service/run_connect_example.py +35 -7
  14. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/shared_pathways_service/run_workload.py +38 -7
  15. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/shared_pathways_service/validators.py +85 -73
  16. pathwaysutils-0.1.13/pathwaysutils/extras/elastic/model_comparison.html +2052 -0
  17. pathwaysutils-0.1.13/pathwaysutils/extras/simple_model/__init__.py +48 -0
  18. pathwaysutils-0.1.13/pathwaysutils/extras/simple_model/compile.py +142 -0
  19. pathwaysutils-0.1.13/pathwaysutils/extras/simple_model/config.py +58 -0
  20. pathwaysutils-0.1.13/pathwaysutils/extras/simple_model/data.py +63 -0
  21. pathwaysutils-0.1.13/pathwaysutils/extras/simple_model/model.py +101 -0
  22. pathwaysutils-0.1.13/pathwaysutils/extras/simple_model/simple_model.py +78 -0
  23. pathwaysutils-0.1.13/pathwaysutils/extras/simple_model/simple_model_test.py +356 -0
  24. pathwaysutils-0.1.13/pathwaysutils/extras/simple_model/workload.py +219 -0
  25. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/persistence/helper.py +0 -13
  26. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/profiling.py +239 -43
  27. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/proxy_backend.py +14 -4
  28. pathwaysutils-0.1.13/pathwaysutils/test/experimental/gke/jobset_test.py +1723 -0
  29. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/test/experimental/gke/testdata/model_lite_tpuv5e_4x8.yaml +0 -4
  30. pathwaysutils-0.1.13/pathwaysutils/test/experimental/shared_pathways_service/deploy_pathways_service_test.py +390 -0
  31. pathwaysutils-0.1.13/pathwaysutils/test/experimental/shared_pathways_service/gke_utils_test.py +2251 -0
  32. pathwaysutils-0.1.13/pathwaysutils/test/experimental/shared_pathways_service/isc_pathways_test.py +1536 -0
  33. pathwaysutils-0.1.13/pathwaysutils/test/experimental/shared_pathways_service/metrics_collector_test.py +247 -0
  34. pathwaysutils-0.1.13/pathwaysutils/test/experimental/shared_pathways_service/run_workload_test.py +287 -0
  35. pathwaysutils-0.1.13/pathwaysutils/test/experimental/shared_pathways_service/start_vscode_on_cpu_np_test.py +324 -0
  36. pathwaysutils-0.1.13/pathwaysutils/test/experimental/shared_pathways_service/tpu_specs_test.py +77 -0
  37. pathwaysutils-0.1.13/pathwaysutils/test/experimental/shared_pathways_service/validators_test.py +396 -0
  38. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/test/initialize_test.py +15 -0
  39. pathwaysutils-0.1.13/pathwaysutils/test/mock_fault_injection.py +293 -0
  40. pathwaysutils-0.1.13/pathwaysutils/test/mock_fault_injection_test.py +201 -0
  41. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/test/profiling_test.py +465 -20
  42. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/test/proxy_backend_test.py +41 -0
  43. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pyproject.toml +21 -2
  44. pathwaysutils-0.1.11/pathwaysutils/experimental/gke/jobset.py +0 -923
  45. pathwaysutils-0.1.11/pathwaysutils/experimental/shared_pathways_service/gke_utils.py +0 -533
  46. pathwaysutils-0.1.11/pathwaysutils/persistence/orbax_handler.py +0 -292
  47. pathwaysutils-0.1.11/pathwaysutils/test/experimental/gke/jobset_test.py +0 -977
  48. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/LICENSE +0 -0
  49. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/README.md +0 -0
  50. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/debug/__init__.py +0 -0
  51. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/debug/timing.py +0 -0
  52. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/debug/watchdog.py +0 -0
  53. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/elastic/__init__.py +0 -0
  54. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/__init__.py +0 -0
  55. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/concatenate_by_mesh_axis.py +0 -0
  56. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/gke/__init__.py +0 -0
  57. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/profiling.py +0 -0
  58. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/reshard.py +0 -0
  59. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/shared_pathways_service/__init__.py +0 -0
  60. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/shared_pathways_service/dockerfiles/sample_sidecar.dockerfile +0 -0
  61. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/shared_pathways_service/start_vscode_on_cpu_np.py +0 -0
  62. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/shared_pathways_service/tpu_specs.py +0 -0
  63. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/shared_pathways_service/yamls/code-server.yaml +0 -0
  64. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/shared_pathways_service/yamls/pw-proxy.yaml +0 -0
  65. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/experimental/split_by_mesh_axis.py +0 -0
  66. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/jax/__init__.py +0 -0
  67. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/lru_cache.py +0 -0
  68. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/persistence/__init__.py +0 -0
  69. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/plugin_executable.py +0 -0
  70. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/reshard.py +0 -0
  71. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/test/__init__.py +0 -0
  72. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/test/debug/__init__.py +0 -0
  73. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/test/debug/timing_test.py +0 -0
  74. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/test/debug/watchdog_test.py +0 -0
  75. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/test/experimental/reshard_test.py +0 -0
  76. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/test/lru_cache_test.py +0 -0
  77. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/test/persistence_test.py +0 -0
  78. {pathwaysutils-0.1.11 → pathwaysutils-0.1.13}/pathwaysutils/test/plugin_executable_test.py +0 -0
  79. {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.11
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.8.3
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
 
@@ -21,4 +21,4 @@ is_pathways_backend_used: Callable[[], bool] = _initialize.is_pathways_backend_u
21
21
  del _initialize
22
22
 
23
23
  # When changing this, also update the CHANGELOG.md.
24
- __version__ = "v0.1.11"
24
+ __version__ = "v0.1.13"
@@ -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
- orbax_handler.register_pathways_handlers(
97
- timeout=datetime.timedelta(hours=1),
98
- array_metadata_store=array_metadata_store_lib.Store(),
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, args.duration_ms, args.host, args.log_dir
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
- """Cleans up JAX profiles, caches, and live arrays."""
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 and cleans up JAX
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()