File size: 1,336 Bytes
c126239
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
/**
 * 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;
}