Download sample.py from Teensy/teensy-0: direct link, hf CLI and curl.
- Browser
- Download file 4.26 kB
-
https://huggingface.co/Teensy/teensy-0/resolve/main/sample.py
- Command line
-
hf download hf://Teensy/teensy-0/sample.py
-
curl -L -o sample.py https://huggingface.co/Teensy/teensy-0/resolve/main/sample.py
4.26 kB
| #!/usr/bin/env python3 | |
| """ | |
| Generate text samples from a trained Teensy checkpoint. | |
| Copyright (c) 2025 Pankaj Doharey | |
| Modified from NanoGPT (Andrej Karpathy). | |
| """ | |
| import os | |
| import argparse | |
| import secrets | |
| from contextlib import nullcontext | |
| import torch | |
| import tiktoken | |
| from model import TeensyConfig, TeensyLM, adapt_nanogpt_weights | |
| def load_model(checkpoint_path, device): | |
| checkpoint = torch.load(checkpoint_path, map_location=device) | |
| cfg = TeensyConfig(**checkpoint['model_args']) | |
| model = TeensyLM(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) | |
| model.load_state_dict(state_dict) | |
| model.eval() | |
| model.to(device) | |
| return model | |
| def resolve_device(requested): | |
| """Pick an available device and warn about MPS quality issues.""" | |
| if requested == "cuda": | |
| if torch.cuda.is_available(): | |
| return "cuda" | |
| fallback = "mps" if torch.backends.mps.is_available() else "cpu" | |
| print(f"CUDA not available; falling back to {fallback}.") | |
| return fallback | |
| if requested == "mps": | |
| if torch.backends.mps.is_available(): | |
| print("WARNING: MPS inference for this model can produce degraded output") | |
| print(" (garbled text and stray <|endoftext|> tokens). CPU is recommended.") | |
| return "mps" | |
| print("MPS not available; falling back to cpu.") | |
| return "cpu" | |
| return "cpu" | |
| def main(): | |
| parser = argparse.ArgumentParser(description="Generate text from a Teensy checkpoint") | |
| parser.add_argument("--out_dir", default="checkpoints", help="Checkpoint directory") | |
| parser.add_argument("--start", default="\n", help="Prompt text") | |
| parser.add_argument("--num_samples", type=int, default=10, help="Number of samples") | |
| parser.add_argument("--max_new_tokens", type=int, default=500, help="Tokens per sample") | |
| parser.add_argument("--temperature", type=float, default=0.7, help="Sampling temperature") | |
| parser.add_argument("--top_k", type=int, default=50, help="Top-k sampling") | |
| parser.add_argument("--top_p", type=float, default=0.9, help="Nucleus (top-p) sampling") | |
| parser.add_argument("--device", default="cpu", help="Device (cpu/cuda/mps; cpu recommended)") | |
| parser.add_argument("--dtype", default="float16", help="Torch dtype") | |
| parser.add_argument("--compile", action="store_true", help="torch.compile the model") | |
| parser.add_argument("--seed", type=int, default=None, help="Random seed") | |
| args = parser.parse_args() | |
| args.device = resolve_device(args.device) | |
| device_type = "cuda" if "cuda" in args.device else "mps" if "mps" in args.device else "cpu" | |
| seed = args.seed if args.seed is not None else secrets.randbelow(2**32) | |
| torch.manual_seed(seed) | |
| if device_type == "cuda": | |
| torch.cuda.manual_seed(seed) | |
| ptdtype = {"float32": torch.float32, "bfloat16": torch.bfloat16, "float16": torch.float16}[args.dtype] | |
| ctx = nullcontext() if device_type in ["cpu", "mps"] else torch.amp.autocast(device_type=device_type, dtype=ptdtype) | |
| ckpt_path = os.path.join(args.out_dir, "teensy-0.pt") | |
| model = load_model(ckpt_path, args.device) | |
| if args.compile and device_type == "cuda": | |
| model = torch.compile(model) | |
| enc = tiktoken.get_encoding("gpt2") | |
| encode = lambda s: enc.encode(s, allowed_special={"<|endoftext|>"}) | |
| decode = lambda ids: enc.decode(ids) | |
| eos_token_id = enc.eot_token | |
| if args.start.startswith("FILE:"): | |
| with open(args.start[5:], "r", encoding="utf-8") as f: | |
| args.start = f.read() | |
| start_ids = encode(args.start) | |
| x = torch.tensor(start_ids, dtype=torch.long, device=args.device)[None, ...] | |
| with torch.no_grad(): | |
| with ctx: | |
| for _ in range(args.num_samples): | |
| y = model.generate(x, args.max_new_tokens, temperature=args.temperature, top_k=args.top_k, top_p=args.top_p, eos_token_id=eos_token_id) | |
| print(decode(y[0].tolist())) | |
| print("---------------") | |
| if __name__ == "__main__": | |
| main() | |