Skip to content

Commit 4303895

Browse files
angel-coreGoogle-ML-Automation
authored andcommitted
Add checkpoint_context.py to map flat orbax v0 flags to Orbax v1 Context.
This new module provides functions to build Orbax v1 Context, SaveDecisionPolicy, and PreservationPolicy objects based on MaxText's checkpoint configuration flags. It centralizes the logic for configuring Orbax v1, replacing various scattered v0 Orbax constructs previously used in MaxText. Unit tests are included to verify the correct mapping of flags to Orbax v1 options. PiperOrigin-RevId: 944311354
1 parent b149d60 commit 4303895

10 files changed

Lines changed: 1325 additions & 333 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
datasets>=4.8.5
22
fsspec==2026.2.0
33
gcsfs==2026.2.0
4+
orbax-checkpoint>=0.12.1

src/dependencies/requirements/generated_requirements/cuda12-requirements.txt

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ cloudpickle>=3.1.2
3030
clu>=0.0.12
3131
colorama>=0.4.6
3232
contourpy>=1.3.3
33-
coverage>=7.14.3
33+
coverage>=7.15.0
3434
cryptography>=49.0.0
3535
cycler>=0.12.1
3636
datasets>=5.0.0
@@ -84,11 +84,11 @@ grpcio-status>=1.80.0
8484
gviz-api>=1.10.0
8585
h11>=0.16.0
8686
h5py>=3.14.0
87-
hf-xet>=1.5.1 ; platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64'
87+
hf-xet>=1.5.1 ; platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'x86_64'
8888
httpcore>=1.0.9
8989
httplib2>=0.32.0
9090
httpx>=0.28.1
91-
huggingface-hub>=1.21.0
91+
huggingface-hub>=1.22.0
9292
humanize>=4.16.0
9393
hypothesis>=6.142.1
9494
identify>=2.6.19
@@ -158,7 +158,7 @@ opt-einsum>=3.4.0
158158
optax>=0.2.8
159159
optree>=0.19.0
160160
optype>=0.17.0
161-
orbax-checkpoint>=0.11.39
161+
orbax-checkpoint>=0.12.1
162162
packaging>=26.1
163163
pandas>=3.0.3
164164
parameterized>=0.9.0
@@ -169,6 +169,7 @@ platformdirs>=4.10.0
169169
pluggy>=1.6.0
170170
portpicker>=1.6.0
171171
pre-commit>=4.6.0
172+
prometheus-client>=0.20.0
172173
promise>=2.3
173174
propcache>=0.5.2
174175
proto-plus>=1.28.0
@@ -195,7 +196,7 @@ pyproject-hooks>=1.2.0
195196
pytest>=8.4.2
196197
pytest-xdist>=3.8.0
197198
python-dateutil>=2.9.0.post0
198-
python-discovery>=1.4.2
199+
python-discovery>=1.4.3
199200
pytokens>=0.4.1
200201
pytype>=2024.10.11
201202
pyyaml>=6.0.3
@@ -229,7 +230,7 @@ tensorflow>=2.20.0
229230
tensorflow-datasets>=4.9.10
230231
tensorflow-metadata>=1.21.0
231232
tensorflow-text>=2.20.1
232-
tensorstore>=0.1.82
233+
tensorstore>=0.1.84
233234
termcolor>=3.3.0
234235
tiktoken>=0.13.0
235236
tokamax>=0.0.12
@@ -241,24 +242,24 @@ tqdm>=4.68.3
241242
transformer-engine>=2.16.1
242243
transformer-engine-cu12>=2.16.1
243244
transformer-engine-jax>=2.16.1
244-
transformers>=5.12.1
245+
transformers>=5.13.0
245246
treescope>=0.1.10
246247
typeguard>=2.13.3
247-
typer>=0.25.1
248+
typer>=0.26.8
248249
typing-extensions>=4.15.0
249250
typing-inspection>=0.4.2
250251
tzdata>=2026.2 ; sys_platform == 'emscripten' or sys_platform == 'win32'
251252
uritemplate>=4.2.0
252253
urllib3>=2.6.3
253-
uvicorn>=0.49.0
254+
uvicorn>=0.50.2
254255
uvloop>=0.22.1
255-
virtualenv>=21.5.1
256+
virtualenv>=21.5.2
256257
wadler-lindig>=0.1.7
257258
websockets>=16.0
258259
werkzeug>=3.1.8
259260
wheel>=0.46.3
260261
wrapt>=2.2.2
261-
xxhash>=3.8.0
262+
xxhash>=3.8.1
262263
yarl>=1.24.2
263264
zipp>=3.23.1
264265
zstandard>=0.25.0
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
# Copyright 2026 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""Maps MaxText checkpoint config onto the Orbax v1 Context + training policies.
16+
17+
This module is the single place that translates MaxText's flat checkpoint flags
18+
into those objects. It builds configuration only.
19+
"""
20+
import datetime
21+
22+
from orbax.checkpoint import pathways as ocp_pathways
23+
from orbax.checkpoint import v1 as ocp
24+
25+
26+
# v0 PyTreeCheckpointHandler converts `*_concurrent_gb` with GB = 10**9 bytes.
27+
_BYTES_PER_GB = 10**9
28+
29+
# Matches the v0 SingleReplicaArrayHandler broadcast limit (1000 MB) that
30+
# MaxText used when restoring a single replica and broadcasting to the rest.
31+
_SINGLE_REPLICA_BROADCAST_MEMORY_LIMIT_BYTES = 1024 * 1024 * 1000
32+
33+
34+
def build_save_decision_policy(
35+
*,
36+
save_interval_steps: int,
37+
enable_continuous_checkpointing: bool = False,
38+
enable_autocheckpoint: bool = False,
39+
) -> ocp.training.save_decision_policies.SaveDecisionPolicy:
40+
"""Builds the v1 SaveDecisionPolicy.
41+
42+
- continuous: save as often as possible (async-friendly).
43+
- autocheckpoint: save on preemption OR at the fixed interval.
44+
- otherwise: save at the fixed interval.
45+
46+
Args:
47+
save_interval_steps: Save every N steps.
48+
enable_continuous_checkpointing: If true, save as often as possible.
49+
enable_autocheckpoint: If true, save on preemption OR at the fixed interval.
50+
51+
Returns:
52+
A configured ``ocp.training.save_decision_policies.SaveDecisionPolicy``.
53+
"""
54+
policies = ocp.training.save_decision_policies
55+
if enable_continuous_checkpointing:
56+
return policies.ContinuousCheckpointingPolicy()
57+
if enable_autocheckpoint:
58+
return policies.AnySavePolicy(
59+
[
60+
policies.PreemptionCheckpointingPolicy(),
61+
policies.FixedIntervalPolicy(save_interval_steps),
62+
]
63+
)
64+
return policies.FixedIntervalPolicy(interval=save_interval_steps)
65+
66+
67+
def build_preservation_policy(*, max_to_keep: int) -> ocp.training.preservation_policies.PreservationPolicy:
68+
"""Builds the v1 PreservationPolicy (keep the latest N checkpoints).
69+
70+
Args:
71+
max_to_keep: The maximum number of checkpoints to keep.
72+
73+
Returns:
74+
A configured ``ocp.training.preservation_policies.PreservationPolicy``.
75+
"""
76+
return ocp.training.preservation_policies.LatestN(max_to_keep)
77+
78+
79+
def build_context(
80+
*,
81+
use_ocdbt: bool = True,
82+
use_zarr3: bool = True,
83+
ocdbt_target_data_file_size_bytes: int | None = None,
84+
checkpoint_storage_concurrent_gb: int | None = None,
85+
enable_continuous_checkpointing: bool = False,
86+
todelete_full_path: str | None = None,
87+
todelete_subdir: str | None = None,
88+
enable_single_replica_ckpt_restoring: bool = False,
89+
replica_axis_index: int = 0,
90+
colocated_python_checkpointing: bool = False,
91+
partial_load: bool = False,
92+
checkpoint_layout: ocp.options.CheckpointLayout | None = None,
93+
) -> ocp.Context:
94+
"""Builds an Orbax v1 ``Context`` from MaxText checkpoint flags.
95+
96+
The returned Context is unfrozen (its options are mutable until it is entered
97+
via ``with ctx:``); callers pass it to ``ocp_v1.training.Checkpointer``, which
98+
applies it to every save/load.
99+
100+
Args:
101+
use_ocdbt: Use OCDBT storage format.
102+
use_zarr3: Use Zarr3 storage format.
103+
ocdbt_target_data_file_size_bytes: Target OCDBT data-file size; also used as
104+
the per-array ``chunk_byte_size`` (matching the v0 ``SaveArgs`` value).
105+
checkpoint_storage_concurrent_gb: Concurrent IO budget in GB; applied to
106+
both write and read as a byte limit (v0 used one value for both).
107+
enable_continuous_checkpointing: If true, set a 60-minute async timeout.
108+
todelete_full_path: GCS soft-delete path.
109+
todelete_subdir: Subdirectory renaming hook for deletions.
110+
enable_single_replica_ckpt_restoring: Restore on one replica and broadcast
111+
to the rest (replaces the v0 ``SingleReplicaArrayHandler``).
112+
replica_axis_index: Mesh axis separating replicas for load-and-broadcast.
113+
colocated_python_checkpointing: Use Pathways colocated-python checkpointing.
114+
partial_load: Restore only the keys present in the abstract tree (the v1
115+
equivalent of v0 ``partial_restore=True``).
116+
checkpoint_layout: On-disk layout (``ORBAX`` or ``SAFETENSORS``) for
117+
loading.
118+
119+
Returns:
120+
A configured, unfrozen ``ocp_v1.Context``.
121+
"""
122+
ctx = ocp.Context()
123+
124+
# Array storage format + file sizing.
125+
ctx.array.saving.use_ocdbt = use_ocdbt
126+
ctx.array.saving.use_zarr3 = use_zarr3
127+
if ocdbt_target_data_file_size_bytes is not None:
128+
ctx.array.saving.ocdbt_target_data_file_size = ocdbt_target_data_file_size_bytes
129+
ctx.array.saving.storage_options.chunk_byte_size = ocdbt_target_data_file_size_bytes
130+
131+
# Concurrent IO budget: v0 GB -> v1 bytes, applied to both directions.
132+
if checkpoint_storage_concurrent_gb is not None:
133+
concurrent_bytes = checkpoint_storage_concurrent_gb * _BYTES_PER_GB
134+
ctx.memory.write_concurrent_bytes = concurrent_bytes
135+
ctx.memory.read_concurrent_bytes = concurrent_bytes
136+
137+
if enable_continuous_checkpointing:
138+
ctx.asynchronous.timeout_secs = int(datetime.timedelta(minutes=60).total_seconds())
139+
140+
if todelete_full_path is not None:
141+
ctx.deletion.gcs_deletion_options.todelete_full_path = todelete_full_path
142+
143+
if todelete_subdir is not None:
144+
raise ValueError("Renaming to subdirectory before deleting (todelete_subdir) is now unsupported by Orbax v1.")
145+
146+
# Single-replica restore (load on one replica, broadcast to the others).
147+
if enable_single_replica_ckpt_restoring:
148+
ctx.array.loading.use_load_and_broadcast = True
149+
ctx.array.loading.load_and_broadcast_options.replica_axis_index = replica_axis_index
150+
ctx.array.loading.load_and_broadcast_options.broadcast_memory_limit_bytes = (
151+
_SINGLE_REPLICA_BROADCAST_MEMORY_LIMIT_BYTES
152+
)
153+
154+
if colocated_python_checkpointing:
155+
ctx.pathways.checkpointing_impl = ocp_pathways.CheckpointingImpl.from_options(
156+
use_colocated_python=True,
157+
)
158+
else:
159+
# v0 only used Pathways handlers when explicitly registered,
160+
# and the persistence handler rejects non-NamedSharding arrays and the
161+
# OCDBT/zarr3 layout MaxText writes. NO_DISPATCHER restores the standard
162+
# controller-side ArrayHandler.
163+
ctx.pathways.checkpointing_impl = ocp_pathways.CheckpointingImpl.NO_DISPATCHER
164+
165+
if partial_load:
166+
ctx.pytree.loading.partial_load = True
167+
168+
if checkpoint_layout is not None:
169+
ctx.checkpoint_layout = checkpoint_layout
170+
171+
return ctx

0 commit comments

Comments
 (0)