Spaces:
Running
Running
File size: 2,240 Bytes
ca2a6e7 | 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 | 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;
}
|