FANTA / scripts /reshard_checkpoint.py
Saintghetto17's picture
Upload reshard_checkpoint.py
65b2cab verified
Raw History Blame Contribute Delete
2.58 kB
#!/usr/bin/env python3
"""Пересохраняет чекпоинт FANTA с разбиением весов на шарды.
Примеры:
python3 scripts/reshard_checkpoint.py runs/checkpoint-5000 runs/checkpoint-5000-sharded
python3 scripts/reshard_checkpoint.py runs/checkpoint-5000 out --max_shard_size 1GB
Результат:
out/
config.json
model-00001-of-00008.safetensors
...
model-00008-of-00008.safetensors
model.safetensors.index.json
HF (`from_pretrained`) автоматически читает index.json и собирает шарды — склеивать вручную не нужно.
"""
from __future__ import annotations
import argparse
import sys
from pathlib import Path
# Позволяем запускать из корня проекта без PYTHONPATH: добавляем родительский каталог.
_PROJECT_ROOT = Path(__file__).resolve().parent.parent
if str(_PROJECT_ROOT) not in sys.path:
sys.path.insert(0, str(_PROJECT_ROOT))
from fanta.modeling_fanta import FantaForPredictionAndAnomaly # noqa: E402
def main() -> None:
ap = argparse.ArgumentParser()
ap.add_argument("src", help="Папка исходного чекпоинта (с model.safetensors + config.json)")
ap.add_argument("dst", help="Папка куда сохранить шардированный чекпоинт")
ap.add_argument(
"--max_shard_size",
default="1GB",
help="Размер одного шарда (строка для HF). ~1GB → ~8 шардов для 8GB модели.",
)
args = ap.parse_args()
src = Path(args.src)
dst = Path(args.dst)
if not (src / "config.json").is_file():
print(f"Нет config.json в {src}", file=sys.stderr)
sys.exit(1)
print(f"Загружаю {src} …")
model = FantaForPredictionAndAnomaly.from_pretrained(src)
dst.mkdir(parents=True, exist_ok=True)
print(f"Сохраняю шарды max_shard_size={args.max_shard_size} → {dst}")
model.save_pretrained(
dst,
safe_serialization=True,
max_shard_size=args.max_shard_size,
)
shards = sorted(dst.glob("model-*.safetensors"))
if not shards:
shards = sorted(dst.glob("*.safetensors"))
total = sum(p.stat().st_size for p in shards)
print(f"Готово. Файлов весов: {len(shards)}, суммарно {total / 1024**3:.2f} GiB")
for p in shards:
print(f" {p.name} {p.stat().st_size / 1024**3:.2f} GiB")
if __name__ == "__main__":
main()