Download train/sample.py from elyanlabs/elya-nes: direct link, hf CLI and curl.
- Browser
- Download file 2.73 kB
-
https://huggingface.co/elyanlabs/elya-nes/resolve/main/train/sample.py
- Command line
-
hf download hf://elyanlabs/elya-nes/train/sample.py
-
curl -L -o sample.py https://huggingface.co/elyanlabs/elya-nes/resolve/main/train/sample.py
2.73 kB
| #!/usr/bin/env python3 | |
| """Generate text with host/ref.py - the exact-integer reference the ROM is | |
| verified against - and detokenise it. | |
| Greedy argmax with ties to the lowest index, exactly as rom/nn.s does, so the | |
| strings printed here are the strings the cartridge produces. The ROM free-runs | |
| from a single seed token; --prompt is a host-only convenience for inspecting | |
| conditional behaviour and is labelled as such wherever it is used. | |
| """ | |
| import argparse | |
| import json | |
| import os | |
| import sys | |
| import numpy as np | |
| HERE = os.path.dirname(os.path.abspath(__file__)) | |
| sys.path.insert(0, os.path.join(HERE, "..", "host")) | |
| import ref | |
| def load_vocab(path="data/vocab.json"): | |
| v = json.load(open(path)) | |
| return v["vocab"], v["base"] | |
| def detok(ids, vocab): | |
| return "".join(vocab[i] for i in ids) | |
| def encode(text, vocab, base): | |
| """Longest-match tokenisation against the 64-symbol vocabulary.""" | |
| order = sorted(range(len(vocab)), key=lambda i: -len(vocab[i])) | |
| out, i = [], 0 | |
| while i < len(text): | |
| for t in order: | |
| s = vocab[t] | |
| if s and text.startswith(s, i): | |
| out.append(t) | |
| i += len(s) | |
| break | |
| else: | |
| i += 1 | |
| return out | |
| def run(model, prompt_ids, nsteps): | |
| """Teacher-force the prompt, then free-run greedy. Returns the full id list.""" | |
| r = ref.Runner(model) | |
| ids = list(prompt_ids) | |
| cur = ids[0] | |
| p = 0 | |
| while p < nsteps: | |
| nxt = r.step(cur, p) | |
| p += 1 | |
| if p < len(ids): | |
| cur = ids[p] # still inside the prompt | |
| else: | |
| ids.append(nxt) | |
| cur = nxt | |
| return ids | |
| def main(): | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument("npz") | |
| ap.add_argument("--vocab", default="data/vocab.json") | |
| ap.add_argument("--seeds", default=None, help="comma separated seed token ids") | |
| ap.add_argument("--prompt", default=None, help="host-only text prompt") | |
| ap.add_argument("--n", type=int, default=ref.T - 1) | |
| ap.add_argument("--survey", action="store_true", help="all 64 seed tokens") | |
| a = ap.parse_args() | |
| vocab, base = load_vocab(a.vocab) | |
| m = ref.Model.from_npz(a.npz) | |
| if a.prompt is not None: | |
| ids = encode(a.prompt, vocab, base) | |
| out = run(m, ids, a.n) | |
| print("prompt (host-only) %-20r -> %r" | |
| % (detok(ids, vocab), detok(out, vocab))) | |
| return 0 | |
| seeds = (list(range(len(vocab))) if a.survey else | |
| [int(s) for s in (a.seeds or "1").split(",")]) | |
| for s in seeds: | |
| out = run(m, [s], a.n) | |
| print("seed %2d %-8r -> %r" % (s, vocab[s], detok(out, vocab))) | |
| return 0 | |
| if __name__ == "__main__": | |
| sys.exit(main()) | |