Spaces:
Running
Running
Download src/sampling.js from danmoreng/macrostories-browser: direct link, hf CLI and curl.
- Browser
- Download file 2.24 kB
-
https://huggingface.co/spaces/danmoreng/macrostories-browser/resolve/main/src/sampling.js
- Command line
-
hf download hf://spaces/danmoreng/macrostories-browser/src/sampling.js
-
curl -L -o sampling.js https://huggingface.co/spaces/danmoreng/macrostories-browser/resolve/main/src/sampling.js
2.24 kB
| export function seededRandom(seed) { | |
| let state = Number(seed) >>> 0; | |
| return () => { | |
| state = (state + 0x6D2B79F5) >>> 0; | |
| let x = Math.imul(state ^ (state >>> 15), state | 1); | |
| x ^= x + Math.imul(x ^ (x >>> 7), x | 61); | |
| return ((x ^ (x >>> 14)) >>> 0) / 4294967296; | |
| }; | |
| } | |
| export function validateSettings(settings) { | |
| const { seed, temperature, topP, topK, maxTokens } = settings; | |
| if (!Number.isInteger(seed) || seed < 0 || seed > 0xffffffff) throw new Error('Seed must be an integer from 0 to 4,294,967,295.'); | |
| if (!Number.isFinite(temperature) || temperature < 0 || temperature > 2) throw new Error('Temperature must be between 0 and 2.'); | |
| if (!Number.isFinite(topP) || topP <= 0 || topP > 1) throw new Error('Top-p must be between 0 (exclusive) and 1.'); | |
| if (!Number.isInteger(topK) || topK < 0 || topK > 378) throw new Error('Top-k must be an integer from 0 to 378.'); | |
| if (!Number.isInteger(maxTokens) || maxTokens < 1 || maxTokens > 2047) throw new Error('Token limit must be an integer from 1 to 2,047.'); | |
| } | |
| export function sample(logits, settings, random) { | |
| const { temperature, topP, topK } = settings; | |
| if (temperature === 0) { | |
| let best = 0; | |
| for (let i = 1; i < logits.length; i++) if (logits[i] > logits[best]) best = i; | |
| return best; | |
| } | |
| let candidates = Array.from(logits, (value, id) => ({ id, value })).sort((a, b) => b.value - a.value); | |
| // Same order as Transformers: temperature, top-k, then nucleus filtering. | |
| if (topK > 0 && topK < candidates.length) { | |
| const cutoff = candidates[topK - 1].value; | |
| candidates = candidates.filter(c => c.value >= cutoff); | |
| } | |
| const maximum = candidates[0].value; | |
| let total = 0; | |
| for (const c of candidates) { c.prob = Math.exp((c.value - maximum) / temperature); total += c.prob; } | |
| let cumulative = 0; | |
| let keep = candidates.length; | |
| for (let i = 0; i < candidates.length; i++) { | |
| cumulative += candidates[i].prob / total; | |
| if (cumulative >= topP) { keep = i + 1; break; } | |
| } | |
| candidates = candidates.slice(0, keep); | |
| total = candidates.reduce((sum, c) => sum + c.prob, 0); | |
| let draw = random() * total; | |
| for (const c of candidates) { draw -= c.prob; if (draw < 0) return c.id; } | |
| return candidates.at(-1).id; | |
| } | |