File size: 3,299 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
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
<script lang="ts">
  import {
    modelPhase,
    baseline,
    prompt,
    sampling,
    algoParams,
    generateBaseline,
  } from '../lib/stores/app-state';

  let showAdvanced = $state(false);
  const busy = $derived($baseline.status === 'running');
</script>

<div class="panel">
  <textarea
    rows="2"
    bind:value={$prompt}
    placeholder="Enter a prompt. The same prompt drives the baseline and every watermark."
  ></textarea>

  <div class="controls">
    <button
      class="primary"
      disabled={$modelPhase !== 'ready' || busy || $prompt.trim().length === 0}
      onclick={generateBaseline}
    >
      {busy ? 'Generating baseline…' : $baseline.result ? 'Regenerate baseline' : 'Generate baseline'}
    </button>
    <button onclick={() => (showAdvanced = !showAdvanced)}>
      {showAdvanced ? 'Hide' : 'Advanced'} settings
    </button>
    {#if $modelPhase !== 'ready'}
      <span class="dim small">Load the model first.</span>
    {:else if !$baseline.result && !busy}
      <span class="dim small">The baseline is the control every watermark is compared against.</span>
    {/if}
  </div>

  {#if showAdvanced}
    <div class="advanced">
      <fieldset>
        <legend>Sampling (shared by every run)</legend>
        <label>temperature <input type="number" step="0.05" min="0.05" max="2" bind:value={$sampling.temperature} /></label>
        <label>top-p <input type="number" step="0.01" min="0.1" max="1" bind:value={$sampling.topP} /></label>
        <label>max new tokens <input type="number" step="8" min="16" max="512" bind:value={$sampling.maxNewTokens} /></label>
        <label>base RNG seed <input type="number" bind:value={$sampling.baseSeed} /></label>
      </fieldset>
      <fieldset>
        <legend>Algorithm parameters (also editable inside each stage)</legend>
        <label>Kirchenbauer γ <input type="number" step="0.05" min="0.05" max="0.9" bind:value={$algoParams.kirchenbauer.gamma} /></label>
        <label>Kirchenbauer δ <input type="number" step="0.5" min="0" max="10" bind:value={$algoParams.kirchenbauer.delta} /></label>
        <label>k-SemStamp margin <input type="number" step="0.005" min="0" max="0.2" bind:value={$algoParams.ksemstamp.margin} /></label>
        <label>k-SemStamp max trials <input type="number" min="1" max="40" bind:value={$algoParams.ksemstamp.maxTrials} /></label>
        <label>TextSeal context k <input type="number" min="1" max="8" bind:value={$algoParams.textseal.contextWidth} /></label>
        <label>TextSeal α <input type="number" step="0.05" min="0" max="0.5" bind:value={$algoParams.textseal.alpha} /></label>
      </fieldset>
    </div>
  {/if}
</div>

<style>
  .controls {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 10px;
    flex-wrap: wrap;
  }
  .advanced {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 12px;
    margin-top: 12px;
  }
  fieldset {
    border: 1px solid var(--border);
    border-radius: 8px;
  }
  legend {
    color: var(--text-dim);
    font-size: 12.5px;
    padding: 0 6px;
  }
  fieldset label {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin: 5px 0;
    font-size: 13.5px;
  }
  fieldset input {
    width: 92px;
  }
</style>