#!/usr/bin/env python3 """Completion CLI: continue a prompt with a trained Notio checkpoint. Usage: src/complete.py "Once upon a time" --checkpoint out/notio.pt --n 2 src/complete.py "The little cat" --temp 0.8 --top-k 40 --max-tokens 200 """ import argparse import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent)) import sampler def main(): ap = argparse.ArgumentParser() ap.add_argument("prompt", nargs="?", default="", help="text to complete (default: story start)") ap.add_argument("--checkpoint", default="out/notio.pt") ap.add_argument("--temp", type=float, default=0.9) ap.add_argument("--top-k", type=int, default=0, help="0 = off") ap.add_argument("--max-tokens", type=int, default=900) ap.add_argument("--n", type=int, default=1, help="number of completions") ap.add_argument("--device", default=None) a = ap.parse_args() m, device, ck = sampler.load_model(a.checkpoint, a.device) print(f"checkpoint: {a.checkpoint} | step {ck['step']} | " f"train {ck.get('loss', float('nan')):.3f} | val {ck.get('val_loss', float('nan')):.3f} | {device}") prompt = a.prompt or "Once upon a time" prompt_ids = sampler.encode_prompt(prompt) block = m.cfg.layer1.block_size if len(prompt_ids) >= block: sys.exit(f"prompt too long: {len(prompt_ids)} ids, block_size {block}") print(f"prompt: {prompt!r} ({len(prompt_ids)} ids) | temp {a.temp} | top-k {a.top_k}") for i in range(a.n): ids = sampler.generate(m, device, prompt_ids, a.max_tokens, a.temp, a.top_k) print(f"\n=== completion {i} ({len(ids)} ids) ===\n{sampler.ids_to_display(ids)}") if __name__ == "__main__": main()