Upload folder using huggingface_hub
Browse files- README.md +14 -5
- index.html +53 -19
- ncm_fp16w.onnx +3 -0
README.md
CHANGED
|
@@ -1,10 +1,19 @@
|
|
| 1 |
---
|
| 2 |
-
title:
|
| 3 |
-
emoji:
|
| 4 |
-
colorFrom:
|
| 5 |
-
colorTo:
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
|
|
|
| 8 |
---
|
| 9 |
|
| 10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
title: NCM chat (experimental, rough)
|
| 3 |
+
emoji: 💬
|
| 4 |
+
colorFrom: gray
|
| 5 |
+
colorTo: blue
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
| 8 |
+
license: mit
|
| 9 |
---
|
| 10 |
|
| 11 |
+
# NCM chat (experimental, rough)
|
| 12 |
+
|
| 13 |
+
A small chatbot built on **Next-Concept Modeling (NCM)**, Stanford Hazy Research (arXiv 2610.14162, code github.com/HazyResearch/ncm).
|
| 14 |
+
|
| 15 |
+
- Base: the released XSum NCM checkpoint (frozen multiscale VQ tokenizer plus prefix-conditioned generator). No chat checkpoint is released, so only the generator was fine-tuned for a short time on short public dialogue and instruction data (everyday-conversations, dolly, alpaca).
|
| 16 |
+
- Runs fully in your browser with onnxruntime-web. No server and no data leaves your device.
|
| 17 |
+
- Weights are stored fp16 and cast to fp32 at load (about 375 MB download, roughly 1 GB RAM). Desktop browser recommended. Phones are untested.
|
| 18 |
+
- Export check: on 8 test prompts, greedy replies from the ONNX model are identical to the PyTorch model, and teacher-forced logits match (max diff 0.0026, 0/1600 argmax mismatches).
|
| 19 |
+
- It is a rough research demo. Replies are short and often wrong or repetitive. It is not a capable assistant.
|
index.html
CHANGED
|
@@ -1,19 +1,53 @@
|
|
| 1 |
-
<!doctype html>
|
| 2 |
-
<
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
| 2 |
+
<title>NCM chat (experimental, rough)</title>
|
| 3 |
+
<style>
|
| 4 |
+
body{font-family:system-ui,sans-serif;margin:0;background:#111;color:#eee;display:flex;flex-direction:column;height:100dvh}
|
| 5 |
+
header{padding:10px 14px;background:#1b1b1b;font-size:13px;line-height:1.35}
|
| 6 |
+
header b{font-size:15px}
|
| 7 |
+
#log{flex:1;overflow:auto;padding:12px;display:flex;flex-direction:column;gap:8px}
|
| 8 |
+
.m{max-width:85%;padding:8px 12px;border-radius:14px;white-space:pre-wrap;word-wrap:break-word}
|
| 9 |
+
.u{align-self:flex-end;background:#2b5fd9}.b{align-self:flex-start;background:#2a2a2a}.s{align-self:center;color:#aaa;font-size:12px}
|
| 10 |
+
form{display:flex;gap:8px;padding:10px;background:#1b1b1b}
|
| 11 |
+
input{flex:1;font-size:16px;padding:10px;border-radius:10px;border:1px solid #444;background:#222;color:#eee}
|
| 12 |
+
button{font-size:16px;padding:10px 16px;border-radius:10px;border:0;background:#2b5fd9;color:#fff}button:disabled{opacity:.5}
|
| 13 |
+
</style></head><body>
|
| 14 |
+
<header><b>NCM chat</b> (experimental, rough) · Next-Concept Modeling, Stanford Hazy Research (arXiv 2610.14162). Runs fully in your browser: the released XSum NCM generator, briefly fine-tuned on short dialogue, fp16-stored-weights ONNX, fp32 compute, verified identical to the PyTorch model on test prompts. Replies are short and often wrong or garbled. Not a capable assistant. First load downloads the model (<span id="mb">~375</span> MB, needs roughly 1 GB free RAM; desktop browser recommended).</header>
|
| 15 |
+
<div id="log"></div>
|
| 16 |
+
<form id="f"><input id="t" autocomplete="off" placeholder="Loading model..." disabled><button id="b" disabled>Send</button></form>
|
| 17 |
+
<script type="module">
|
| 18 |
+
import { AutoTokenizer } from "https://cdn.jsdelivr.net/npm/@huggingface/transformers@3.0.2";
|
| 19 |
+
import * as ort from "https://cdn.jsdelivr.net/npm/onnxruntime-web@1.20.1/dist/ort.min.mjs";
|
| 20 |
+
const MODEL="ncm_fp16w.onnx", P=128, EOS=50256, PAD=50257, PPAD=50257, TOTAL=200, V=4096, T=0.7;
|
| 21 |
+
const log=document.getElementById("log"), inp=document.getElementById("t"), btn=document.getElementById("b");
|
| 22 |
+
const add=(c,txt)=>{const d=document.createElement("div");d.className="m "+c;d.textContent=txt;log.appendChild(d);log.scrollTop=1e9;return d};
|
| 23 |
+
let tok,sess,hist=[];
|
| 24 |
+
async function load(){
|
| 25 |
+
const s=add("s","Loading tokenizer and model...");
|
| 26 |
+
tok=await AutoTokenizer.from_pretrained("Xenova/gpt2");
|
| 27 |
+
ort.env.wasm.wasmPaths="https://cdn.jsdelivr.net/npm/onnxruntime-web@1.20.1/dist/";
|
| 28 |
+
ort.env.wasm.numThreads=crossOriginIsolated?Math.min(4,navigator.hardwareConcurrency||2):1;
|
| 29 |
+
const buf=await (await fetch(MODEL)).arrayBuffer();
|
| 30 |
+
document.getElementById("mb").textContent=Math.round(buf.byteLength/1e6);
|
| 31 |
+
sess=await ort.InferenceSession.create(buf,{executionProviders:["wasm"]});
|
| 32 |
+
s.textContent="Model ready. Say something."; inp.disabled=btn.disabled=false; inp.placeholder="Type a message"; inp.focus();
|
| 33 |
+
}
|
| 34 |
+
function gumbel(n){const a=new Float32Array(n);for(let i=0;i<n;i++){const u=Math.random()*(1-1e-7)+1e-7;a[i]=-Math.log(-Math.log(u));}return a}
|
| 35 |
+
async function reply(){
|
| 36 |
+
const turns=hist.slice(-4); let p=""; for(const [r,t] of turns) p+=(r==="u"?"User: ":"Assistant: ")+t+"\n"; p+="Assistant:";
|
| 37 |
+
let ids=Array.from(tok.encode(p)).slice(-P); while(ids.length<P) ids.push(PPAD);
|
| 38 |
+
const prefix=new ort.Tensor("int64",BigInt64Array.from(ids.map(BigInt)),[1,P]);
|
| 39 |
+
const noise=new ort.Tensor("float32",gumbel(TOTAL*V),[1,TOTAL,V]);
|
| 40 |
+
const temp=new ort.Tensor("float32",new Float32Array([T]),[]);
|
| 41 |
+
const out=await sess.run({prefix,noise,temp}); let o=Array.from(out.ids.data,Number);
|
| 42 |
+
const e=o.indexOf(EOS); if(e>=0) o=o.slice(0,e); o=o.filter(x=>x!==PAD&&x!==EOS);
|
| 43 |
+
return tok.decode(o,{skip_special_tokens:true}).trim()||"(empty reply)";
|
| 44 |
+
}
|
| 45 |
+
document.getElementById("f").addEventListener("submit",async ev=>{
|
| 46 |
+
ev.preventDefault(); const m=inp.value.trim(); if(!m) return; inp.value=""; add("u",m); hist.push(["u",m]);
|
| 47 |
+
inp.disabled=btn.disabled=true; const w=add("b","..."); const t0=performance.now();
|
| 48 |
+
try{const r=await reply(); w.textContent=r; hist.push(["a",r]); w.title=((performance.now()-t0)/1000).toFixed(1)+"s";}
|
| 49 |
+
catch(e){w.textContent="Error: "+e.message}
|
| 50 |
+
inp.disabled=btn.disabled=false; inp.focus();
|
| 51 |
+
});
|
| 52 |
+
load().catch(e=>add("s","Load failed: "+e.message));
|
| 53 |
+
</script></body></html>
|
ncm_fp16w.onnx
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:346557046971e33333aae054cb4d1e07d047778abf3340ddb347038b114988cb
|
| 3 |
+
size 374851158
|