DWSLM-256M-Base / generate.py
dwsdubey's picture
DWSLM-256M release v1.0: weights, config, tokenizer, reference code, model card
ca76ef5 verified
Raw History Blame Contribute Delete
2.21 kB
"""Sample a continuation from DWSLM-256M (a base model: it continues text, it doesn't chat).
python generate.py "The three primary colors are"
python generate.py "def fibonacci(n):" --temperature 0 --max-new 80
There's no KV cache: each new token re-runs the whole prefix, which is fine at these lengths on a GPU.
"""
import argparse
import torch
from dwslm import EOS_ID, context, load, next_logits
UNFINISHED = "\ufffd"
def main() -> None:
p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
p.add_argument("prompt")
p.add_argument("--max-new", type=int, default=64)
p.add_argument("--temperature", type=float, default=0.7, help="0 = greedy")
p.add_argument("--top-p", type=float, default=0.9)
p.add_argument("--repetition-penalty", type=float, default=1.1, help="1 = off")
p.add_argument("--repo", default=".", help="folder holding config.json and model.safetensors")
a = p.parse_args()
model, tok = load(a.repo)
ids = [EOS_ID, *tok.encode(a.prompt).ids]
start, shown = len(ids), ""
print(a.prompt, end="", flush=True)
for _ in range(min(a.max_new, context(model) - len(ids))):
z = next_logits(model, [ids])[0]
nxt = _sample(z, ids, a)
if nxt == EOS_ID:
break
ids.append(nxt)
# print only what's new; a byte-level token can end mid-character ("\ufffd") until the rest arrives
text = tok.decode(ids[start:]).rstrip(UNFINISHED)
print(text[len(shown) :], end="", flush=True)
shown = text
print(tok.decode(ids[start:])[len(shown) :])
def _sample(z: torch.Tensor, seen: list[int], a: argparse.Namespace) -> int:
if a.repetition_penalty != 1.0:
idx = torch.tensor(sorted(set(seen)), device=z.device)
prev = z[idx]
z[idx] = torch.where(prev > 0, prev / a.repetition_penalty, prev * a.repetition_penalty)
if a.temperature <= 0:
return int(z.argmax())
probs = (z / a.temperature).softmax(-1)
p, order = probs.sort(descending=True)
p = p * (p.cumsum(-1) - p < a.top_p)
return int(order[torch.multinomial(p / p.sum(), 1)])
if __name__ == "__main__":
main()