roomnumber103's picture
Add LLM Text Watermark Microscope
c126239 verified
Raw
History Blame Contribute Delete
1.34 kB
/**
* UI-side previews of what a watermark does to a single decoding step.
* These are display helpers; the authoritative computation happens in the
* worker's generation loop.
*/
/**
* Probabilities after adding `delta` to green logits, renormalized.
*
* Exact renormalization needs the full vocabulary. We only ship the top-N
* candidates to the UI, so the un-shown tail is approximated by its expected
* behaviour: a fraction `gamma` of the tail mass is green and gets e^delta.
* With the top-N holding most of the mass this is visually indistinguishable
* from the exact curve, and the shape (green up, red down) is exact.
*/
export function biasedProbs(
probs: number[],
isGreen: boolean[],
delta: number,
gamma: number,
): number[] {
const e = Math.exp(delta);
let shown = 0;
let weighted = 0;
for (let i = 0; i < probs.length; i++) {
shown += probs[i];
weighted += probs[i] * (isGreen[i] ? e : 1);
}
const tail = Math.max(0, 1 - shown);
const z = weighted + tail * (1 - gamma + gamma * e);
if (z <= 0) return probs.slice();
return probs.map((p, i) => (p * (isGreen[i] ? e : 1)) / z);
}
/** Gumbel-max score R^(1/p), returned as log for numeric stability. */
export function gumbelLogScore(r: number, p: number): number {
if (p <= 0) return -Infinity;
return Math.log(r) / p;
}