File size: 1,451 Bytes
b3a50e3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
"""Convert the owner's checkpoint without enabling unrestricted pickle loading."""
import argparse
from pathlib import Path


def convert(checkpoint, output):
    import torch
    from safetensors.torch import save_file
    import os
    import tempfile
    checkpoint, output = Path(checkpoint), Path(output)
    if output.exists():
        raise ValueError("Output already exists; choose another path.")
    obj = torch.load(checkpoint, map_location="cpu", weights_only=True)
    state = obj.get("state_dict", obj) if isinstance(obj, dict) else None
    if not isinstance(state, dict) or not state:
        raise ValueError("No model tensors were found.")
    if any(not isinstance(k, str) or not isinstance(v, torch.Tensor) for k, v in state.items()):
        raise ValueError("Unexpected checkpoint content. Inspect it before conversion.")
    fd, temp_name = tempfile.mkstemp(dir=output.parent, suffix=".safetensors")
    os.close(fd)
    try:
        save_file({k: v.detach().contiguous().clone() for k, v in state.items()}, temp_name)
        os.replace(temp_name, output)
    finally:
        Path(temp_name).unlink(missing_ok=True)
    return output


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("checkpoint", type=Path)
    parser.add_argument("output", type=Path)
    args = parser.parse_args()
    convert(args.checkpoint, args.output)
    print("Saved", args.output)


if __name__ == "__main__":
    main()