| |
| """ |
| Export the Teensy PyTorch checkpoint to HuggingFace-compatible files. |
| |
| Produces: |
| - model.safetensors (model weights only, smaller than the full .pt checkpoint) |
| - config.json (model hyperparameters) |
| |
| Copyright (c) 2025 Pankaj Doharey |
| Modified from NanoGPT (Andrej Karpathy). |
| """ |
|
|
| import os |
| import json |
| import argparse |
|
|
| import torch |
| from safetensors.torch import save_file |
|
|
| from model import adapt_nanogpt_weights |
|
|
|
|
| def export(out_dir, export_dir): |
| os.makedirs(export_dir, exist_ok=True) |
|
|
| ckpt_path = os.path.join(out_dir, 'teensy-0.pt') |
| print(f"Loading checkpoint: {ckpt_path}") |
| checkpoint = torch.load(ckpt_path, map_location='cpu') |
|
|
| cfg = checkpoint['model_args'] |
| with open(os.path.join(export_dir, 'config.json'), 'w') as f: |
| json.dump(cfg, f, indent=2) |
| print(f"Wrote config.json: {cfg}") |
|
|
| state_dict = checkpoint['model'] |
| unwanted_prefix = '_orig_mod.' |
| for k, v in list(state_dict.items()): |
| if k.startswith(unwanted_prefix): |
| state_dict[k[len(unwanted_prefix):]] = state_dict.pop(k) |
| state_dict = adapt_nanogpt_weights(state_dict) |
|
|
| |
| |
| |
| state_dict = {k: v.contiguous().to(torch.float32).cpu().clone() for k, v in state_dict.items()} |
|
|
| save_file(state_dict, os.path.join(export_dir, 'model.safetensors')) |
| print(f"Wrote model.safetensors to {export_dir}") |
|
|
| pt_size = os.path.getsize(ckpt_path) |
| st_size = os.path.getsize(os.path.join(export_dir, 'model.safetensors')) |
| print(f"\nSize comparison:") |
| print(f" .pt checkpoint: {pt_size / 1e6:.1f} MB") |
| print(f" model.safetensors: {st_size / 1e6:.1f} MB") |
| print(f" savings: {(1 - st_size / pt_size) * 100:.1f}%") |
|
|
|
|
| def main(): |
| parser = argparse.ArgumentParser(description='Export Teensy checkpoint to safetensors') |
| parser.add_argument('--out_dir', default='checkpoints', help='Directory containing teensy-0.pt') |
| parser.add_argument('--export_dir', default='exported', help='Directory to write exported files') |
| args = parser.parse_args() |
| export(args.out_dir, args.export_dir) |
|
|
|
|
| if __name__ == '__main__': |
| main() |
|
|