2828
2929from __future__ import annotations
3030
31+ import contextlib
3132import dataclasses
3233import json
3334import pprint
4445from orbax .checkpoint ._src .testing .benchmarks .core import pytree_utils
4546
4647
48+
4749@dataclasses .dataclass (frozen = True )
4850class SafetensorLoadBenchmarkOptions (benchmarks_core .BenchmarkOptions ):
4951 """Configuration for loading a HuggingFace-format safetensors checkpoint.
5052
5153 Self-contained: builds its own `ocp.Context()` with the SAFETENSORS layout
5254 pinned from the load-side tuning knobs, so a single run can sweep e.g.
53- `use_load_and_broadcast` or `restore_concurrent_gb` for A/B comparison. Each
54- knob may be a single value or a list to expand into a parameter sweep.
55+ `use_load_and_broadcast`, `restore_concurrent_gb`, or
56+ `safetensors_max_over_read_ratio` for A/B comparison. Each knob may be a
57+ single value or a list to expand into a parameter sweep.
5558
5659 Attributes:
5760 checkpoint_path: Path (local or `gs://`) to a directory containing one or
@@ -74,6 +77,17 @@ class SafetensorLoadBenchmarkOptions(benchmarks_core.BenchmarkOptions):
7477 others instead of every replica reading from storage.
7578 restore_concurrent_gb: Cap on concurrent read bytes (in GiB); `None` leaves
7679 the Orbax default.
80+ safetensors_max_over_read_ratio: Override for
81+ `SafetensorsOptions.max_over_read_ratio`. Bounds per-host cluster egress
82+ on strided shardings (inner-dim TP, HSDP). Sweep as `[2.0, 3.0, 4.0]` on a
83+ TP variant to measure the read-count vs over-read tradeoff. `None`
84+ (default) uses the loader's default (currently 2.0). In-flight read bytes
85+ are bounded by `restore_concurrent_gb` (shared with the rest of restore).
86+ safetensors_read_chunk_mb: Override for
87+ `SafetensorsOptions.read_chunk_bytes`, in MiB. Coalesced blocks are split
88+ at this size into concurrent ranged reads; sweep as `[64, 128, 512]` to
89+ measure the request-count vs read-parallelism tradeoff on a given storage
90+ backend. `None` (default) uses the loader's default (currently 128 MiB).
7791 metric_tracemalloc_enabled: Whether to capture the tracemalloc metric
7892 (opt-in because its per-allocation snapshots are expensive).
7993 """
@@ -84,7 +98,10 @@ class SafetensorLoadBenchmarkOptions(benchmarks_core.BenchmarkOptions):
8498 reference_digests_path : str | None = None
8599 use_load_and_broadcast : bool | list [bool ] = False
86100 restore_concurrent_gb : int | None | list [int | None ] = None
101+ safetensors_max_over_read_ratio : float | None | list [float | None ] = None
102+ safetensors_read_chunk_mb : int | None | list [int | None ] = None
87103 metric_tracemalloc_enabled : bool = False
104+ enable_xprof : bool = False
88105
89106 def is_valid (self ) -> bool :
90107 if self .checkpoint_path is None :
@@ -94,7 +111,15 @@ def is_valid(self) -> bool:
94111 @property
95112 def context (self ) -> ocp .Context :
96113 ctx = ocp .Context (
97- checkpoint_layout = ocp .options .CheckpointLayout .SAFETENSORS
114+ checkpoint_layout = ocp .options .CheckpointLayout .SAFETENSORS ,
115+ safetensors_options = ocp .options .SafetensorsOptions (
116+ max_over_read_ratio = self .safetensors_max_over_read_ratio ,
117+ read_chunk_bytes = (
118+ self .safetensors_read_chunk_mb * 1024 ** 2
119+ if self .safetensors_read_chunk_mb is not None
120+ else None
121+ ),
122+ ),
98123 )
99124 # TODO(b/519204863): Fix type hint for args like list[T] | T
100125 ctx .array .loading .use_load_and_broadcast = self .use_load_and_broadcast
@@ -214,12 +239,18 @@ def test_fn(
214239 else :
215240 abstract_pytree = _replicated_abstract_state (metadata .metadata )
216241
242+ xprof_session = contextlib .nullcontext ()
243+
217244 if load_trace is not None :
218245 jax .profiler .start_trace (str (load_trace ))
219- with metrics .measure ("load" , metrics_to_measure ):
220- restored_pytree = ocp .load (
221- checkpoint_path , abstract_state = abstract_pytree
222- )
246+ with xprof_session as url :
247+ if url :
248+ logging .info ("XProf Session URL: %s" , url )
249+ print (f"\n [XPROF] Session URL: { url } \n " )
250+ with metrics .measure ("load" , metrics_to_measure ):
251+ restored_pytree = ocp .load (
252+ checkpoint_path , abstract_state = abstract_pytree
253+ )
223254 if load_trace is not None :
224255 jax .profiler .stop_trace ()
225256
0 commit comments