Spaces:
Sleeping
Sleeping
Publish openpeerllm-demo
Browse files- README.md +1 -1
- analysis.py +127 -0
- app.py +145 -83
README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
---
|
| 2 |
title: OpenPeerLLM Demo
|
| 3 |
-
emoji: 🕸️
|
| 4 |
colorFrom: blue
|
| 5 |
colorTo: green
|
| 6 |
sdk: gradio
|
|
|
|
| 1 |
---
|
| 2 |
title: OpenPeerLLM Demo
|
| 3 |
+
emoji: 🕸️
|
| 4 |
colorFrom: blue
|
| 5 |
colorTo: green
|
| 6 |
sdk: gradio
|
analysis.py
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
import html
|
| 3 |
+
import math
|
| 4 |
+
import torch
|
| 5 |
+
import torch.nn.functional as F
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
@torch.no_grad()
|
| 9 |
+
def token_surprisal(model, tokenizer, text: str, max_length: int = 1024):
|
| 10 |
+
ids = tokenizer(
|
| 11 |
+
text, return_tensors="pt", truncation=True, max_length=max_length
|
| 12 |
+
).input_ids.to(model.device)
|
| 13 |
+
logits = model(input_ids=ids).logits[0, :-1].float()
|
| 14 |
+
targets = ids[0, 1:]
|
| 15 |
+
logprobs = F.log_softmax(logits, dim=-1)
|
| 16 |
+
tok_lp = logprobs.gather(1, targets[:, None]).squeeze(1)
|
| 17 |
+
ranks = (logprobs > tok_lp[:, None]).sum(dim=1) + 1
|
| 18 |
+
tokens = [tokenizer.decode([t]) for t in ids[0].tolist()]
|
| 19 |
+
nll = -tok_lp.mean().item()
|
| 20 |
+
return {
|
| 21 |
+
"tokens": tokens,
|
| 22 |
+
"surprisal": [-x for x in tok_lp.tolist()],
|
| 23 |
+
"rank": ranks.tolist(),
|
| 24 |
+
"nll": nll,
|
| 25 |
+
"ppl": math.exp(nll),
|
| 26 |
+
"n_tokens": int(targets.numel()),
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
def surprisal_html(result: dict, title: str = "") -> str:
|
| 31 |
+
toks, surp = result["tokens"], result["surprisal"]
|
| 32 |
+
cells = [f"<span style='color:#888'>{html.escape(toks[0])}</span>"]
|
| 33 |
+
for t, s in zip(toks[1:], surp):
|
| 34 |
+
p = min(1.0, s / 12.0)
|
| 35 |
+
r, g = int(255 * p), int(200 * (1 - p))
|
| 36 |
+
cells.append(
|
| 37 |
+
f"<span title='surprisal {s:.2f} nats' style='background:rgba({r},{g},80,0.35);padding:1px 2px;border-radius:3px'>{html.escape(t)}</span>"
|
| 38 |
+
)
|
| 39 |
+
head = (
|
| 40 |
+
f"<div style='margin-bottom:6px'><b>{html.escape(title)}</b> perplexity <b>{result['ppl']:.1f}</b> over {result['n_tokens']} tokens (mean surprisal {result['nll']:.2f} nats)</div>"
|
| 41 |
+
if title
|
| 42 |
+
else ""
|
| 43 |
+
)
|
| 44 |
+
return (
|
| 45 |
+
head
|
| 46 |
+
+ "<div style='font-family:ui-monospace,monospace;line-height:1.9;white-space:pre-wrap;word-break:break-word'>"
|
| 47 |
+
+ "".join(cells)
|
| 48 |
+
+ "</div><div style='color:#777;font-size:0.85em;margin-top:4px'>green = expected, red = surprising; hover a token for its surprisal</div>"
|
| 49 |
+
)
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
@torch.no_grad()
|
| 53 |
+
def greedy_continue(
|
| 54 |
+
model,
|
| 55 |
+
tokenizer,
|
| 56 |
+
prompt: str,
|
| 57 |
+
max_new_tokens: int,
|
| 58 |
+
repetition_penalty: float = 1.2,
|
| 59 |
+
temperature: float = 0.0,
|
| 60 |
+
top_p: float = 0.9,
|
| 61 |
+
max_context: int = 1024,
|
| 62 |
+
):
|
| 63 |
+
ids = tokenizer(
|
| 64 |
+
prompt,
|
| 65 |
+
return_tensors="pt",
|
| 66 |
+
truncation=True,
|
| 67 |
+
max_length=max_context - max_new_tokens,
|
| 68 |
+
).input_ids.to(model.device)
|
| 69 |
+
out = model.generate(
|
| 70 |
+
ids,
|
| 71 |
+
max_new_tokens=max_new_tokens,
|
| 72 |
+
do_sample=temperature > 0,
|
| 73 |
+
temperature=max(temperature, 1e-3),
|
| 74 |
+
top_p=top_p,
|
| 75 |
+
repetition_penalty=repetition_penalty,
|
| 76 |
+
pad_token_id=tokenizer.eos_token_id,
|
| 77 |
+
eos_token_id=tokenizer.eos_token_id,
|
| 78 |
+
)
|
| 79 |
+
return tokenizer.decode(out[0][ids.shape[1] :], skip_special_tokens=True)
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
def contrast_rows(model, tokenizer, samples: list[tuple[str, str]]):
|
| 83 |
+
rows = []
|
| 84 |
+
for label, text in samples:
|
| 85 |
+
r = token_surprisal(model, tokenizer, text)
|
| 86 |
+
rows.append([label, round(r["ppl"], 1), round(r["nll"], 3), text])
|
| 87 |
+
return rows
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
def md_table(rows, header=("Text", "Perplexity", "Mean surprisal (nats)")):
|
| 91 |
+
out = ["| " + " | ".join(header) + " |", "|" + "---|" * len(header)]
|
| 92 |
+
for r in rows:
|
| 93 |
+
out.append(f"| {r[0]} | {r[1]} | {r[2]} |")
|
| 94 |
+
return "\n".join(out)
|
| 95 |
+
|
| 96 |
+
|
| 97 |
+
WIKI_FEWSHOT = (
|
| 98 |
+
"Paris is the capital and most populous city of France. It is located on the Seine river in the north of the country.\n\n"
|
| 99 |
+
"Tokyo is the capital of Japan and one of the most populous cities in the world. It lies on the eastern coast of Honshu.\n\n"
|
| 100 |
+
)
|
| 101 |
+
|
| 102 |
+
QA_FEWSHOT = (
|
| 103 |
+
"Q: What is the capital of France?\nA: Paris.\n\n"
|
| 104 |
+
"Q: Which river flows through Cairo?\nA: The Nile.\n\n"
|
| 105 |
+
"Q: What is the largest planet in the Solar System?\nA: Jupiter.\n\n"
|
| 106 |
+
)
|
| 107 |
+
|
| 108 |
+
CONTRAST_SET = [
|
| 109 |
+
(
|
| 110 |
+
"Fluent English (encyclopedic)",
|
| 111 |
+
"The Amazon River in South America is the largest river by discharge volume of water in the world.",
|
| 112 |
+
),
|
| 113 |
+
(
|
| 114 |
+
"Fluent English (narrative)",
|
| 115 |
+
"She closed the book, turned off the lamp, and listened to the rain against the window.",
|
| 116 |
+
),
|
| 117 |
+
(
|
| 118 |
+
"Grammatical but false",
|
| 119 |
+
"The Amazon River is located in northern Canada and flows into the Arctic Ocean near Greenland.",
|
| 120 |
+
),
|
| 121 |
+
(
|
| 122 |
+
"Word salad (same words shuffled)",
|
| 123 |
+
"world the in water of volume discharge by river largest the is America South in River Amazon The",
|
| 124 |
+
),
|
| 125 |
+
("Random words", "purple elephant calculus whisper nine umbrella fjord lantern"),
|
| 126 |
+
("Python", "def add(a, b):\n return a + b"),
|
| 127 |
+
]
|
app.py
CHANGED
|
@@ -1,18 +1,28 @@
|
|
| 1 |
from __future__ import annotations
|
| 2 |
-
import threading
|
| 3 |
import torch
|
| 4 |
import gradio as gr
|
| 5 |
import spaces
|
| 6 |
from huggingface_hub import hf_hub_download
|
| 7 |
from safetensors.torch import load_file
|
| 8 |
-
from transformers import AutoTokenizer,
|
| 9 |
from configuration_riemann import RiemannConfig
|
| 10 |
from modeling_riemann import RiemannForCausalLM
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
|
| 12 |
OPENPEER_REPO = "OpenPeerAI/OpenPeerLLM"
|
|
|
|
| 13 |
|
| 14 |
tokenizer = AutoTokenizer.from_pretrained("gpt2")
|
| 15 |
tokenizer.pad_token = tokenizer.eos_token
|
|
|
|
| 16 |
config = RiemannConfig(
|
| 17 |
vocab_size=50257,
|
| 18 |
hidden_size=768,
|
|
@@ -21,113 +31,165 @@ config = RiemannConfig(
|
|
| 21 |
intermediate_size=3072,
|
| 22 |
max_position_embeddings=1024,
|
| 23 |
)
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
LOAD_REPORT = f"
|
| 29 |
-
|
| 30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
|
| 32 |
|
| 33 |
@spaces.GPU(duration=60)
|
| 34 |
-
def
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
tokenizer, skip_prompt=True, skip_special_tokens=True
|
| 44 |
)
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
streamer=streamer,
|
| 48 |
-
max_new_tokens=int(max_new_tokens),
|
| 49 |
-
do_sample=temperature > 0,
|
| 50 |
-
temperature=max(float(temperature), 1e-3),
|
| 51 |
-
top_p=float(top_p),
|
| 52 |
-
repetition_penalty=float(repetition_penalty),
|
| 53 |
-
pad_token_id=tokenizer.eos_token_id,
|
| 54 |
)
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
)
|
| 70 |
-
with torch.no_grad():
|
| 71 |
-
out = model(input_ids=ids["input_ids"], labels=ids["input_ids"])
|
| 72 |
-
n = ids["input_ids"].shape[1]
|
| 73 |
-
return f"Tokens: {n}\nMean NLL: {out.loss.item():.4f}\nPerplexity: {torch.exp(out.loss).item():.2f}"
|
| 74 |
|
| 75 |
|
| 76 |
DESCRIPTION = f"""
|
| 77 |
# OpenPeerLLM Demo
|
| 78 |
|
| 79 |
-
[OpenPeerAI/OpenPeerLLM](https://huggingface.co/{OPENPEER_REPO}) is a decentralised-training
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
and runs it on ZeroGPU.
|
| 84 |
-
|
| 85 |
-
{LOAD_REPORT}
|
| 86 |
|
| 87 |
-
OpenPeerLLM is the starting rung of the
|
| 88 |
-
[My Name is Riemann](https://huggingface.co/
|
| 89 |
-
|
| 90 |
-
|
| 91 |
"""
|
| 92 |
|
| 93 |
with gr.Blocks(title="OpenPeerLLM Demo") as demo:
|
| 94 |
gr.Markdown(DESCRIPTION)
|
| 95 |
-
with gr.Tab("
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
lines=4,
|
| 99 |
-
value="The theory of decentralised machine learning says that",
|
| 100 |
)
|
| 101 |
with gr.Row():
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
)
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
gr.Button("Generate", variant="primary").click(
|
| 110 |
-
generate, [prompt, max_new, temp, top_p, rep], out
|
| 111 |
)
|
| 112 |
gr.Examples(
|
| 113 |
[
|
| 114 |
-
["
|
| 115 |
-
[
|
| 116 |
-
|
|
|
|
|
|
|
| 117 |
],
|
| 118 |
-
inputs=
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
)
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
label="Text to score",
|
| 123 |
-
lines=6,
|
| 124 |
-
value="Decentralized training distributes model updates across peers.",
|
| 125 |
)
|
| 126 |
-
|
| 127 |
-
gr.Button("
|
| 128 |
gr.Markdown(
|
| 129 |
-
"OpenPeerLLM is released under OPNL, MIT and CC BY 4.0. "
|
| 130 |
-
"This demo is maintained by OpenPeer AI."
|
| 131 |
)
|
| 132 |
|
| 133 |
demo.queue(max_size=16).launch()
|
|
|
|
| 1 |
from __future__ import annotations
|
|
|
|
| 2 |
import torch
|
| 3 |
import gradio as gr
|
| 4 |
import spaces
|
| 5 |
from huggingface_hub import hf_hub_download
|
| 6 |
from safetensors.torch import load_file
|
| 7 |
+
from transformers import AutoTokenizer, AutoModelForCausalLM
|
| 8 |
from configuration_riemann import RiemannConfig
|
| 9 |
from modeling_riemann import RiemannForCausalLM
|
| 10 |
+
from analysis import (
|
| 11 |
+
token_surprisal,
|
| 12 |
+
surprisal_html,
|
| 13 |
+
greedy_continue,
|
| 14 |
+
contrast_rows,
|
| 15 |
+
md_table,
|
| 16 |
+
WIKI_FEWSHOT,
|
| 17 |
+
CONTRAST_SET,
|
| 18 |
+
)
|
| 19 |
|
| 20 |
OPENPEER_REPO = "OpenPeerAI/OpenPeerLLM"
|
| 21 |
+
RIEMANN_REPO = "OpenPeerAI/My-Name-is-Riemann-Prerelease"
|
| 22 |
|
| 23 |
tokenizer = AutoTokenizer.from_pretrained("gpt2")
|
| 24 |
tokenizer.pad_token = tokenizer.eos_token
|
| 25 |
+
|
| 26 |
config = RiemannConfig(
|
| 27 |
vocab_size=50257,
|
| 28 |
hidden_size=768,
|
|
|
|
| 31 |
intermediate_size=3072,
|
| 32 |
max_position_embeddings=1024,
|
| 33 |
)
|
| 34 |
+
openpeer = RiemannForCausalLM(config)
|
| 35 |
+
_state = load_file(hf_hub_download(OPENPEER_REPO, "model.safetensors"))
|
| 36 |
+
_missing, _unexpected = openpeer.load_state_dict(_state, strict=False)
|
| 37 |
+
openpeer.eval()
|
| 38 |
+
LOAD_REPORT = f"{len(_state)} tensors loaded from {OPENPEER_REPO}, {len(_missing)} missing, {len(_unexpected)} unexpected."
|
| 39 |
+
N_OPENPEER = sum(p.numel() for p in openpeer.parameters())
|
| 40 |
+
|
| 41 |
+
_riemann = {"model": None}
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
def riemann():
|
| 45 |
+
if _riemann["model"] is None:
|
| 46 |
+
m = AutoModelForCausalLM.from_pretrained(
|
| 47 |
+
RIEMANN_REPO,
|
| 48 |
+
trust_remote_code=True,
|
| 49 |
+
dtype=torch.bfloat16,
|
| 50 |
+
low_cpu_mem_usage=True,
|
| 51 |
+
)
|
| 52 |
+
m.eval()
|
| 53 |
+
_riemann["model"] = m
|
| 54 |
+
return _riemann["model"]
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
def _gpu(m):
|
| 58 |
+
if m.device.type != "cuda":
|
| 59 |
+
m.to("cuda")
|
| 60 |
|
| 61 |
|
| 62 |
@spaces.GPU(duration=60)
|
| 63 |
+
def complete(subject, opening, max_new, compare):
|
| 64 |
+
prompt_tail = f"{subject.strip()} {opening.strip()}".strip()
|
| 65 |
+
_gpu(openpeer)
|
| 66 |
+
a = greedy_continue(
|
| 67 |
+
openpeer,
|
| 68 |
+
tokenizer,
|
| 69 |
+
WIKI_FEWSHOT + prompt_tail,
|
| 70 |
+
int(max_new),
|
| 71 |
+
repetition_penalty=1.3,
|
|
|
|
| 72 |
)
|
| 73 |
+
out = (
|
| 74 |
+
f"### OpenPeerLLM ({N_OPENPEER/1e6:.0f}M, the starting rung)\n{prompt_tail}{a}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 75 |
)
|
| 76 |
+
if compare:
|
| 77 |
+
r = riemann()
|
| 78 |
+
_gpu(r)
|
| 79 |
+
b = greedy_continue(
|
| 80 |
+
r,
|
| 81 |
+
tokenizer,
|
| 82 |
+
WIKI_FEWSHOT + prompt_tail,
|
| 83 |
+
int(max_new),
|
| 84 |
+
repetition_penalty=1.25,
|
| 85 |
+
max_context=2048,
|
| 86 |
+
)
|
| 87 |
+
out += f"\n\n### My Name is Riemann Prerelease (13.1B, six rungs later)\n{prompt_tail}{b}"
|
| 88 |
+
return out
|
| 89 |
+
|
| 90 |
+
|
| 91 |
+
@spaces.GPU(duration=60)
|
| 92 |
+
def analyse(text, compare):
|
| 93 |
+
_gpu(openpeer)
|
| 94 |
+
a = token_surprisal(openpeer, tokenizer, text)
|
| 95 |
+
out = surprisal_html(a, f"OpenPeerLLM ({N_OPENPEER/1e6:.0f}M):")
|
| 96 |
+
if compare:
|
| 97 |
+
r = riemann()
|
| 98 |
+
_gpu(r)
|
| 99 |
+
b = token_surprisal(r, tokenizer, text, max_length=2048)
|
| 100 |
+
out += "<hr/>" + surprisal_html(b, "My Name is Riemann Prerelease (13.1B):")
|
| 101 |
+
out += f"<p><b>Perplexity {a['ppl']:.1f} to {b['ppl']:.1f}</b> across the growth ladder on this text.</p>"
|
| 102 |
+
return out
|
| 103 |
+
|
| 104 |
+
|
| 105 |
+
@spaces.GPU(duration=90)
|
| 106 |
+
def contrast(compare):
|
| 107 |
+
_gpu(openpeer)
|
| 108 |
+
rows_a = contrast_rows(openpeer, tokenizer, CONTRAST_SET)
|
| 109 |
+
if not compare:
|
| 110 |
+
return md_table([[r[0], r[1], r[2]] for r in rows_a])
|
| 111 |
+
r = riemann()
|
| 112 |
+
_gpu(r)
|
| 113 |
+
rows_b = contrast_rows(r, tokenizer, CONTRAST_SET)
|
| 114 |
+
header = ("Text", "OpenPeerLLM 163M", "Riemann Prerelease 13.1B")
|
| 115 |
+
rows = [[ra[0], ra[1], rb[1]] for ra, rb in zip(rows_a, rows_b)]
|
| 116 |
+
return (
|
| 117 |
+
md_table(rows, header)
|
| 118 |
+
+ "\n\nPerplexity on each string. Lower is better on fluent text; the gap between fluent text and noise "
|
| 119 |
+
"should widen as the model improves. OpenPeerLLM is the 163M checkpoint that every later rung inherits from."
|
| 120 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
|
| 122 |
|
| 123 |
DESCRIPTION = f"""
|
| 124 |
# OpenPeerLLM Demo
|
| 125 |
|
| 126 |
+
[OpenPeerAI/OpenPeerLLM](https://huggingface.co/{OPENPEER_REPO}) is a decentralised-training language model
|
| 127 |
+
by Andrew Magdy Kamal Nassief (DOI [10.57967/hf/6469](https://doi.org/10.57967/hf/6469)). This space loads its
|
| 128 |
+
published `model.safetensors` ({N_OPENPEER/1e6:.0f}M parameters) into a faithful reimplementation of its
|
| 129 |
+
architecture, with the causal attention mask the reference forward pass omits. {LOAD_REPORT}
|
|
|
|
|
|
|
|
|
|
| 130 |
|
| 131 |
+
OpenPeerLLM is the **starting rung** of the
|
| 132 |
+
[My Name is Riemann](https://huggingface.co/{RIEMANN_REPO}) growth ladder. Every tab lets you put the
|
| 133 |
+
13.1B Prerelease next to it on the same input, so the effect of six rungs of growth and training is visible
|
| 134 |
+
directly. Both are base models: they complete and score text, they do not chat.
|
| 135 |
"""
|
| 136 |
|
| 137 |
with gr.Blocks(title="OpenPeerLLM Demo") as demo:
|
| 138 |
gr.Markdown(DESCRIPTION)
|
| 139 |
+
with gr.Tab("Complete an article"):
|
| 140 |
+
gr.Markdown(
|
| 141 |
+
"Two short example articles are prepended so the model knows the register."
|
|
|
|
|
|
|
| 142 |
)
|
| 143 |
with gr.Row():
|
| 144 |
+
subject = gr.Textbox(label="Subject", value="The Nile")
|
| 145 |
+
opening = gr.Textbox(
|
| 146 |
+
label="Opening clause",
|
| 147 |
+
value="is a major north-flowing river in northeastern Africa. It",
|
| 148 |
+
)
|
| 149 |
+
with gr.Row():
|
| 150 |
+
max_new = gr.Slider(16, 120, value=64, step=8, label="Max new tokens")
|
| 151 |
+
cmp1 = gr.Checkbox(
|
| 152 |
+
value=True, label="Also run My Name is Riemann Prerelease (13.1B)"
|
| 153 |
)
|
| 154 |
+
out1 = gr.Markdown()
|
| 155 |
+
gr.Button("Complete", variant="primary").click(
|
| 156 |
+
complete, [subject, opening, max_new, cmp1], out1
|
|
|
|
|
|
|
| 157 |
)
|
| 158 |
gr.Examples(
|
| 159 |
[
|
| 160 |
+
["Mount Kilimanjaro", "is a dormant volcano in Tanzania. It"],
|
| 161 |
+
[
|
| 162 |
+
"The Rosetta Stone",
|
| 163 |
+
"is a stele inscribed with three versions of a decree issued in",
|
| 164 |
+
],
|
| 165 |
],
|
| 166 |
+
inputs=[subject, opening],
|
| 167 |
+
)
|
| 168 |
+
with gr.Tab("Analyse text"):
|
| 169 |
+
gr.Markdown(
|
| 170 |
+
"Each token is coloured by how surprised the model was to see it; green is expected, red is surprising."
|
| 171 |
+
)
|
| 172 |
+
a_text = gr.Textbox(
|
| 173 |
+
label="Text",
|
| 174 |
+
lines=4,
|
| 175 |
+
value="The Great Pyramid of Giza is the oldest of the Seven Wonders of the Ancient World.",
|
| 176 |
+
)
|
| 177 |
+
cmp2 = gr.Checkbox(
|
| 178 |
+
value=True, label="Also analyse with My Name is Riemann Prerelease (13.1B)"
|
| 179 |
+
)
|
| 180 |
+
out2 = gr.HTML()
|
| 181 |
+
gr.Button("Analyse", variant="primary").click(analyse, [a_text, cmp2], out2)
|
| 182 |
+
with gr.Tab("Fluency test"):
|
| 183 |
+
gr.Markdown(
|
| 184 |
+
"Six fixed strings from fluent English down to random words, scored by perplexity."
|
| 185 |
)
|
| 186 |
+
cmp3 = gr.Checkbox(
|
| 187 |
+
value=True, label="Compare with My Name is Riemann Prerelease (13.1B)"
|
|
|
|
|
|
|
|
|
|
| 188 |
)
|
| 189 |
+
out3 = gr.Markdown()
|
| 190 |
+
gr.Button("Run fluency test", variant="primary").click(contrast, cmp3, out3)
|
| 191 |
gr.Markdown(
|
| 192 |
+
"OpenPeerLLM is released under OPNL, MIT and CC BY 4.0. Maintained by OpenPeer AI."
|
|
|
|
| 193 |
)
|
| 194 |
|
| 195 |
demo.queue(max_size=16).launch()
|