File size: 1,869 Bytes
1b25f81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
"""Interactive prompt loop for micro500. Loads the model once; exit with Ctrl+C."""
import json
import sys
import time

import torch
import torch.nn.functional as F
from safetensors.torch import load_file

from model import MicroLM

WEIGHTS = "micro500.safetensors"
CONFIG = "micro500_config.json"
CONTEXT = 64          # characters of history fed to the model
N_CHARS = 300         # characters generated per prompt
TEMP = 0.8
TOP_K = 0             # 0 = disabled


def load():
    cfg = json.load(open(CONFIG))
    chars = cfg["chars"]
    net = MicroLM(len(chars), cfg["d"], cfg["h"], cfg["pad"])
    net.load_state_dict(load_file(WEIGHTS))
    net.eval()
    stoi = {c: i for i, c in enumerate(chars)}
    itos = {i: c for c, i in stoi.items()}
    return net, stoi, itos


@torch.no_grad()
def generate(net, stoi, itos, prompt, n=N_CHARS, temp=TEMP, top_k=TOP_K):
    ids = [stoi.get(c, 0) for c in prompt.lower()] or [0]
    start = time.perf_counter()
    for _ in range(n):
        x = torch.tensor([ids[-CONTEXT:]])
        logits = net(x)[0, -1] / temp
        if top_k:
            v, _ = torch.topk(logits, top_k)
            logits[logits < v[-1]] = float("-inf")
        ids.append(torch.multinomial(F.softmax(logits, -1), 1).item())
    elapsed = time.perf_counter() - start
    text = "".join(itos[i] for i in ids)
    return text, n / elapsed


def main():
    net, stoi, itos = load()
    n_params = sum(p.numel() for p in net.parameters())
    print(f"micro500 loaded ({n_params} parameters). Press Ctrl+C to quit.\n")
    try:
        while True:
            prompt = input("prompt> ")
            text, tps = generate(net, stoi, itos, prompt)
            print(f"\n{text}\n")
            print(f"[{tps:,.0f} tokens/sec]\n")
    except (KeyboardInterrupt, EOFError):
        print("\nbye")
        sys.exit(0)


if __name__ == "__main__":
    main()