Conversation
Hotragn
force-pushed
the
fix/prefer-safetensors-over-pickle-296
branch
from
July 29, 2026 18:21
ab3a182 to
0c3d1bf
Compare
split_and_save_layers checked pytorch_model.bin.index.json before model.safetensors.index.json, so a repo shipping both formats was loaded from the pickle-based .bin shards via torch.load() even though safetensors was available. That is inconsistent with the single-file branch (which already preferred safetensors) and, because AirLLM's entry point is an arbitrary Hugging Face repo id, means an untrusted checkpoint could reach pickle deserialization during the advertised load flow. - Resolve the weight map in a new _resolve_weight_map() helper that prefers safetensors (sharded, then single-file) and only falls back to .bin. - Pass weights_only=True to every torch.load() of a checkpoint shard, which restricts the unpickler to tensors (torch>=2.4 is already required). - Add offline unit tests for the resolution order and the weights_only call. Fixes lyogavin#296.
Hotragn
force-pushed
the
fix/prefer-safetensors-over-pickle-296
branch
from
September 5, 2026 17:10
0c3d1bf to
6cf05b6
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Make the layer splitter prefer safetensors over pickle-based
pytorch_model.bin, and read any.binit does load withweights_only=True.Fixes #296.
Why
split_and_save_layers()resolved the weight map in this order:Two problems with checking
.binfirst:model.safetensorsoverpytorch_model.bin. So a repo's sharded path and single-file path made opposite choices for the same repo..binshards are Python pickles loaded throughtorch.load(). AirLLM's advertised entry point is an arbitrary Hugging Face repo id (AutoModel.from_pretrained("some/repo")), so when a repo ships both formats — many still do — AirLLM would download and unpickle the.binshards during the split even though the safe, memory-mapped safetensors were sitting right there.torch.load()documents that unpickling untrusted data can execute arbitrary code.This aligns the sharded path with the single-file path and with the rest of the ecosystem (transformers itself prefers safetensors when both exist), and it means the common "repo ships both" case no longer touches the pickle path at all.
Changes
_resolve_weight_map(checkpoint_path)helper with a clear preference order: sharded safetensors → single-file safetensors → sharded.bin→ single-file.bin..binis still fully supported as a fallback; nothing is removed.weights_only=Trueto everytorch.load()of a checkpoint shard. This restricts the unpickler to tensors and a safe allowlist.setup.pyalready requirestorch>=2.4, where this argument is fully supported (PyTorch made it the default in 2.6), so there's no compatibility cost — and model weight files are plain tensor state dicts, which load fine under it.air_llm/tests/test_weight_index_resolution.pywith offline unit tests.Testing
New offline unit tests (no network, no GPU) —
python -m pytest air_llm/tests/test_weight_index_resolution.py:.binindex when only.binexists.bin.binis loaded withweights_only=TrueFileNotFoundErrorwhen no weights are presentAll 5 pass. I also ran
split_and_save_layers()end-to-end on a tiny fake checkpoint that ships both formats and confirmed it now splits from safetensors and produces all per-layer shards, with no change to the resulting layout.