Skip to content

Read replicated safetensors tensors once and broadcast behind an option#3475

Open
mridul-sahu wants to merge 1 commit into
google:mainfrom
mridul-sahu:feature/safetensors-broadcast-replicated
Open

Read replicated safetensors tensors once and broadcast behind an option#3475
mridul-sahu wants to merge 1 commit into
google:mainfrom
mridul-sahu:feature/safetensors-broadcast-replicated

Conversation

@mridul-sahu

Copy link
Copy Markdown
Collaborator

Description

Follow-up to #3455. The sharding-driven load reads at most the bytes each process needs — except for tensors replicated across processes, which every process re-reads in full. On a large cluster loading from object storage, that is the one case where total egress grows with the number of hosts instead of staying near the checkpoint's size.

This PR adds the opt-in SafetensorsOptions.broadcast_replicated (default False). When enabled in a multi-process run, leaves with a jax.sharding.NamedSharding that are replicated across processes are loaded in two steps:

  • Read once, spread across the replicas. Mesh axes absent from a tensor's partition spec are greedily placed onto tensor dimensions that stay evenly divisible, producing a de-duplicated read sharding in which each byte is owned by exactly one process. Axes that fit nowhere stay unplaced (partial de-duplication); tensors where nothing can be placed load normally.
  • Broadcast on device. After all files load, a jit-compiled identity with the true target out_shardings fans the shards out over the accelerator interconnect. Broadcasts are batched so per-device output stays under 1 GiB per call, bounding the transient device memory.

This trades accelerator interconnect traffic for storage egress, so it helps when storage bandwidth or egress cost is the bottleneck. Leaves with other shardings, single-process runs, and the default configuration are unaffected.

Type of change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (alters existing behavior or a public API)
  • Docs / tests / internal tooling (no user-facing behavior change)

Checklist

  • I have read the contribution guidelines.
  • Tests cover this change and pass locally.
  • Public APIs and non-trivial functions are documented.
  • If this change is user-facing, I have updated CHANGELOG.md under the [Unreleased] section (or the relevant checkpoint/ / export/ changelog).

@github-actions github-actions Bot added the pull ready Ready to be pulled from GitHub into Google label Jul 14, 2026
@mridul-sahu
mridul-sahu force-pushed the feature/safetensors-broadcast-replicated branch from 505fa09 to c8a4143 Compare July 17, 2026 16:34
Sharding-driven reads pull replicated tensors from storage once per
process, so a checkpoint replicated across N processes costs N x its size
in storage egress. SafetensorsOptions.broadcast_replicated removes that:
replication in a NamedSharding is exactly the mesh axes its spec does not
use, so the loader assigns each unused axis to an evenly divisible tensor
dimension and reads under that de-duplicated sharding -- each byte owned
once, the read spread across all replicas' hosts. An identity computation
with the target out_shardings then broadcasts the shards over the
accelerator interconnect, batched under a fixed per-device byte bound so
transient device memory stays predictable.

Axes that fit no dimension stay unplaced (partial de-duplication); leaves
without a NamedSharding, single-process loads, and unshardable tensors
fall back to the normal read path unchanged.
@mridul-sahu
mridul-sahu force-pushed the feature/safetensors-broadcast-replicated branch from c8a4143 to 8b4e042 Compare July 17, 2026 16:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pull ready Ready to be pulled from GitHub into Google

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant