Skip to content

Commit 8d35826

Browse files
Merge pull request #89 from EmbeddedLLM/fix/handle-empty-metadata
Fix KeyError on empty __metadata__ in safetensors headers
2 parents 9b2c76f + 8a85533 commit 8d35826

2 files changed

Lines changed: 18 additions & 1 deletion

File tree

fastsafetensors/common.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ def __init__(
212212
self.framework = framework
213213
ser = json.loads(string, object_pairs_hook=OrderedDict)
214214
self.metadata = ser.get("__metadata__", "")
215-
if self.metadata:
215+
if "__metadata__" in ser:
216216
del ser["__metadata__"]
217217
self.tensors: Dict[str, TensorFrame] = {}
218218
self.header_length = header_length

tests/unit/test_fastsafetensors.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,6 +1008,23 @@ def dribbling_read(fd: int, length: int) -> bytes:
10081008
assert meta.tensors["a0"].shape == [4, 8]
10091009

10101010

1011+
def test_from_file_empty_metadata(tmp_dir, framework) -> None:
1012+
# Regression test: a safetensors file whose header carries an empty
1013+
# __metadata__: {} object must parse without raising. Previously,
1014+
# __metadata__ was stripped only when truthy, so {} survived into the
1015+
# tensor sort and raised KeyError: 'data_offsets' (see e.g. loading
1016+
# MiniMaxAI/MiniMax-M3-MXFP8 via vLLM --load-format fastsafetensors).
1017+
device, _ = get_and_check_device(framework)
1018+
filename = os.path.join(tmp_dir, "empty_metadata.safetensors")
1019+
a0 = framework.randn((4, 8), device=device, dtype=DType.F32)
1020+
save_safetensors_file({"a0": a0.get_raw()}, filename, {}, framework)
1021+
1022+
meta = SafeTensorsMetadata.from_file(filename, framework)
1023+
assert "a0" in meta.tensors
1024+
assert meta.tensors["a0"].shape == [4, 8]
1025+
assert meta.metadata == {}
1026+
1027+
10111028
def test_no_module_level_torch_import_outside_frameworks() -> None:
10121029
# Policy: framework-specific imports live behind the frameworks
10131030
# abstraction. Only the torch backend (frameworks/_torch.py) may import

0 commit comments

Comments
 (0)