HRM_sudoku / push_to_hf.py
Code2aum's picture
Upload folder using huggingface_hub
5dc80b3 verified
Raw
History Blame Contribute Delete
4.45 kB
#!/usr/bin/env python3
"""
Convert HRM checkpoints to safetensors and push to Hugging Face.
Usage:
python push_to_hf.py \
--baseline "checkpoints/Sudoku-extreme-1k-aug-1000 ACT-torch/HierarchicalReasoningModel_ACTV1 belligerent-squirrel/step_52080" \
--tiered "checkpoints/Sudoku-extreme-1k-aug-1000 ACT-torch/HRM_Tiered realistic-dalmatian/step_52080" \
--repo "Code2aum/HRM_based_evolution"
"""
import argparse
import os
import shutil
import torch
from safetensors.torch import save_file
from huggingface_hub import login, HfApi, upload_folder
def convert_checkpoint(ckpt_path, output_dir, model_name):
"""Load .pt checkpoint, save as safetensors + config."""
os.makedirs(output_dir, exist_ok=True)
# Load weights
state_dict = torch.load(ckpt_path, map_location="cpu", weights_only=True)
# Strip torch.compile prefix if present
cleaned = {}
for k, v in state_dict.items():
key = k.removeprefix("_orig_mod.")
cleaned[key] = v
# Save as safetensors
st_path = os.path.join(output_dir, "model.safetensors")
save_file(cleaned, st_path)
print(f" ✓ Saved {st_path} ({os.path.getsize(st_path)/1e6:.1f} MB)")
# Copy config
ckpt_dir = os.path.dirname(ckpt_path)
config_src = os.path.join(ckpt_dir, "all_config.yaml")
if os.path.exists(config_src):
shutil.copy2(config_src, os.path.join(output_dir, "config.yaml"))
print(f" ✓ Copied config.yaml")
# Copy model source
for src_file in ["hrm_act_v1.py", "hrm_tiered.py", "losses.py"]:
src_path = os.path.join(ckpt_dir, src_file)
if os.path.exists(src_path):
shutil.copy2(src_path, os.path.join(output_dir, src_file))
# Write a model card
card = f"""---
tags:
- hrm
- hierarchical-reasoning
- sudoku
- pytorch
license: mit
---
# {model_name}
Hierarchical Reasoning Model trained on Sudoku-Extreme-1K (20,000 epochs).
## Architecture
- **Type**: {model_name}
- **Hidden Size**: 512
- **Heads**: 8
- **H/L Layers**: 4/4
- **H/L Cycles**: 2/2
- **Parameters**: ~27.3M
## Training
- **Dataset**: Sudoku-Extreme-1K (1000 puzzles, 1000 augmentations each)
- **Epochs**: 20,000
- **Batch Size**: 384
- **Learning Rate**: 7e-5
- **GPU**: NVIDIA RTX 4090
## Usage
```python
from safetensors.torch import load_file
state_dict = load_file("{model_name}/model.safetensors")
```
"""
with open(os.path.join(output_dir, "README.md"), "w") as f:
f.write(card)
print(f" ✓ Created README.md")
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--baseline", type=str, required=True)
parser.add_argument("--tiered", type=str, required=True)
parser.add_argument("--repo", type=str, default="Code2aum/HRM_based_evolution")
parser.add_argument("--output-dir", type=str, default="hf_upload")
parser.add_argument("--no-push", action="store_true", help="Convert only, skip push")
args = parser.parse_args()
print("=" * 60)
print(" HRM → SafeTensors → Hugging Face")
print("=" * 60)
# Convert baseline
base_dir = os.path.join(args.output_dir, "baseline_hrm_v1")
print(f"\n Converting Baseline...")
convert_checkpoint(args.baseline, base_dir, "HRM_Baseline_V1")
# Convert tiered
tier_dir = os.path.join(args.output_dir, "tiered_hrm_sram_dram")
print(f"\n Converting Tiered...")
convert_checkpoint(args.tiered, tier_dir, "HRM_Tiered_SRAM_DRAM")
# Copy benchmark results if available
bench_dir = "benchmark_results"
if os.path.exists(bench_dir):
dest = os.path.join(args.output_dir, "benchmark_results")
if not os.path.exists(dest):
shutil.copytree(bench_dir, dest)
print(f"\n ✓ Copied benchmark_results/")
if args.no_push:
print(f"\n Files ready at: {args.output_dir}/")
print(" Run without --no-push to upload to HF.")
return
# Push to HF
print(f"\n Logging in to Hugging Face...")
login()
print(f"\n Uploading to {args.repo}...")
api = HfApi()
api.create_repo(repo_id=args.repo, repo_type="model", exist_ok=True)
upload_folder(
folder_path=args.output_dir,
repo_id=args.repo,
repo_type="model",
)
print(f"\n ✓ Uploaded to https://huggingface.co/{args.repo}")
print("\n" + "=" * 60)
print(" Done!")
print("=" * 60)
if __name__ == "__main__":
main()