Spaces:
Sleeping
Sleeping
File size: 4,498 Bytes
3ec0250 ab2314f 3ec0250 ab2314f 3ec0250 ab2314f 3ec0250 ab2314f 3ec0250 ab2314f 3ec0250 ab2314f 3ec0250 ab2314f 3ec0250 ab2314f 3ec0250 ab2314f 3ec0250 ab2314f 3ec0250 ab2314f 3ec0250 ab2314f 3ec0250 ab2314f 3ec0250 ab2314f 3ec0250 ab2314f 3ec0250 ab2314f 3ec0250 ab2314f 3ec0250 | 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 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
body { font-family: sans-serif; margin: 0; padding: 6px; font-size: 14px; color: #333; }
#status { color: #666; margin-bottom: 4px; }
#progress { width: 100%; height: 6px; display: none; margin-bottom: 4px; }
#error { color: #c00; line-height: 1.5; }
</style>
</head>
<body>
<div id="status"></div>
<progress id="progress" max="100" value="0"></progress>
<div id="error"></div>
<script type="module">
const MODEL_REPO = "juanbascur/specter2-proximity-onnx";
const BATCH_SIZE = 64;
// ββ Streamlit component API ββββββββββββββββββββββββββββββββββββββββββββββ
function send(type, extra = {}) {
window.parent.postMessage({ isStreamlitMessage: true, type, ...extra }, "*");
}
const setValue = v => send("streamlit:setComponentValue", { value: v, dataType: "json" });
const setHeight = h => send("streamlit:setFrameHeight", { height: h });
send("streamlit:componentReady", { apiVersion: 1 });
setHeight(20);
window.addEventListener("message", async (event) => {
if (event.data.type !== "streamlit:render") return;
const { papers, run } = event.data.args;
if (run) await runEmbeddings(papers);
});
// ββ Main βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
async function runEmbeddings(papers) {
const statusEl = document.getElementById("status");
const progressEl = document.getElementById("progress");
const errorEl = document.getElementById("error");
errorEl.textContent = "";
if (!navigator.gpu) {
errorEl.innerHTML =
"It seems your browser does not support WebGPU. " +
"Chrome, Edge and Opera support it by default. " +
"Firefox and Safari need additional configuration. " +
"Alternatively, run the embeddings on the web server " +
"by checking <b>Use fallback resources</b>, but this takes much longer.";
setHeight(90);
setValue({ error: "webgpu_not_supported" });
return;
}
try {
progressEl.style.display = "block";
setHeight(50);
statusEl.textContent = "Loading model⦠(first run may take a minute)";
const { AutoTokenizer, AutoModel } = await import(
"https://cdn.jsdelivr.net/npm/@huggingface/transformers@3"
);
const tokenizer = await AutoTokenizer.from_pretrained(MODEL_REPO);
statusEl.textContent = "Tokenizer ready, loading model weightsβ¦";
const model = await AutoModel.from_pretrained(MODEL_REPO, {
device: "webgpu",
dtype: "fp16",
});
statusEl.textContent = "Model ready, starting encodingβ¦";
const total = papers.length;
const allCLS = new Float32Array(total * 768);
for (let start = 0; start < total; start += BATCH_SIZE) {
const batch = papers.slice(start, start + BATCH_SIZE);
const texts = batch.map(p => p.title + " [SEP] " + (p.abstract || ""));
const inputs = tokenizer(texts, { padding: true, truncation: true, max_length: 512 });
const output = await model(inputs);
const hs = output.last_hidden_state;
const [B, L, H] = hs.dims;
const data = hs.data;
for (let b = 0; b < B; b++)
allCLS.set(data.slice(b * L * H, b * L * H + H), (start + b) * 768);
const done = Math.min(start + BATCH_SIZE, total);
progressEl.value = (done / total) * 100;
statusEl.textContent = `Encoding ${done} / ${total}β¦`;
}
progressEl.value = 100;
statusEl.textContent = "Done.";
// Encode as base64 in chunks to avoid call stack overflow
const bytes = new Uint8Array(allCLS.buffer);
let binary = "";
for (let i = 0; i < bytes.length; i += 8192)
binary += String.fromCharCode(...bytes.subarray(i, i + 8192));
setValue({ embeddings_b64: btoa(binary), n_papers: total, n_dims: 768 });
} catch (err) {
errorEl.textContent = "Error: " + err.message;
setHeight(60);
setValue({ error: err.message });
}
}
</script>
</body>
</html>
|