Skip to content

feat(io-safetensors): sharded-index ParametersLoader riding openFromIndex (#1246) - #1252

Merged
michalharakal merged 1 commit into
developfrom
feat/1246-sharded-safetensors-loader
Sep 2, 2026
Merged

michalharakal merged 1 commit into
developfrom
feat/1246-sharded-safetensors-loader

Conversation

@michalharakal

Copy link
Copy Markdown
Contributor

Closes #1246.

SafeTensorsParametersLoader is single-file only while the sharded machinery (StreamingShardedSafeTensorsReader.openFromIndex, SafeTensorsIndexParser) already lives engine-side — so transformers families with sharded HF checkpoints hand-roll per-tensor materialization (GemmaSafeTensorsLoader et al.), duplicating the policy surface this abstraction owns.

  • SafeTensorsMaterializer (internal, commonMain): the dtype-dispatch materialization, byte/dequant helpers, and DTypePolicy mappers extracted from the single-file loader — primitive-typed so it serves both StreamingSafeTensorInfo and ShardedTensorInfo. The single-file loader delegates; its public surface is unchanged (pure refactor, existing tests pass untouched).
  • New ShardedSafeTensorsParametersLoader(indexPath, onProgress, bf16Policy, fp16Policy, allowPartial, tensorFilter): rides openFromIndex, fail-fast aggregated dtype pre-scan before any tensor is delivered (mirrors the GGUF loader's StreamingGgufParametersLoader silently skips tensors it can't load (Q4_1, but also Q4_0/Q5_0/Q5_1) — load "succeeds" with missing weights, crash comes later #919 behavior), withPolicy companion with signature parity. tensorFilter keeps skip decisions (size guards, name allowlists) family-side while all dtype/policy handling stays engine-side (Bump org.jetbrains.kotlinx.kover from 0.9.4 to 0.9.5 #346's "no per-family quant code").
  • KDoc covers eager shard handles, name-sorted delivery, and the js/wasm provider-per-shard factory as a documented follow-up.

Testing: 145 module tests green — commonTest policy-mapper parity, and a jvmTest suite over a genuine 2-shard fixture (cross-shard delivery/values/order, KEEP_NATIVE vs DEQUANT storage types, tensorFilter, missing-shard IncompleteShard vs allowPartial, fail-fast with zero deliveries) plus a 1-shard-index vs single-file parity test guarding the refactor.

Follow-up (transformers, after this ships in a release): collapse GemmaSafeTensorsLoader and the sibling hand-rolled loaders onto this, and flip GemmaNetworkLoader's keepNative = emptySet() to setOf(BF16, FP16).

…d materializer (#1246)

Extract the per-tensor dtype dispatch, byte/dequant helpers, and DTypePolicy
mappers from SafeTensorsParametersLoader into an internal
SafeTensorsMaterializer (pure refactor; primitive-typed signature so it
serves both StreamingSafeTensorInfo and ShardedTensorInfo), then add
ShardedSafeTensorsParametersLoader consuming model.safetensors.index.json
via StreamingShardedSafeTensorsReader.openFromIndex.

The sharded loader adds a fail-fast dtype pre-scan (one aggregated error
before any tensor is delivered, mirroring the GGUF loader's #919 contract)
and a tensorFilter hook so family-side skip policy (size guards, name
allowlists) stays out of the engine while all dtype/policy handling stays
in it. withPolicy has signature parity with the single-file factory.

Tests: commonTest policy-routing + pre-scan suite; jvmTest 2-shard fixture
(cross-shard name-sorted delivery, KEEP_NATIVE vs DEQUANT arms,
tensorFilter, IncompleteShard vs allowPartial, fail-fast-before-first-
delivery) and a 1-shard-index vs single-file parity test guarding the
extraction refactor.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SafeTensors: a sharded-index ParametersLoader (the single-file loader can't consume model.safetensors.index.json)

1 participant