<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: mycute</title>
    <description>The latest articles on DEV Community by mycute (@mycute_97b39c4e34027570f9).</description>
    <link>https://dev.to/mycute_97b39c4e34027570f9</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4200987%2F010b4f64-6b50-4e46-ac6a-29846897b9a8.png</url>
      <title>DEV Community: mycute</title>
      <link>https://dev.to/mycute_97b39c4e34027570f9</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mycute_97b39c4e34027570f9"/>
    <language>en</language>
    <item>
      <title>Joint training did not fix the watermark merge: 8/8 alone, 0/8 at 0.75</title>
      <dc:creator>mycute</dc:creator>
      <pubDate>Wed, 11 Nov 2026 15:32:28 +0000</pubDate>
      <link>https://dev.to/mycute_97b39c4e34027570f9/joint-training-did-not-fix-the-watermark-merge-88-alone-08-at-075-1hka</link>
      <guid>https://dev.to/mycute_97b39c4e34027570f9/joint-training-did-not-fix-the-watermark-merge-88-alone-08-at-075-1hka</guid>
      <description>&lt;h1&gt;
  
  
  Joint training: can one adapter carry both the task and the mark?
&lt;/h1&gt;

&lt;p&gt;The separately trained watermark is 8/8 alone and &lt;strong&gt;0/8 at a 0.50/0.50 merge&lt;/strong&gt;. This&lt;br&gt;
experiment asks whether training SST-2 and the watermark in one adapter changes that. If&lt;br&gt;
the joint adapter keeps the mark at a lower merge fraction, joint training is a practical&lt;br&gt;
mitigation; if not, the merge problem is not solved by simply training the two behaviours&lt;br&gt;
together.&lt;/p&gt;

&lt;p&gt;Reproduce:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;JOINT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nv"&gt;SEED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5 &lt;span class="nv"&gt;OUT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;checkpoints/wm_joint_lora.pt \
  &lt;span class="nv"&gt;RESULTS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;research/results/watermark_joint.json python research/watermark_adapter.py
python research/watermark_joint_generate.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;30 SST-2 train rows (15 positive, 15 negative), formatted exactly like the SST-2 adapter:
&lt;code&gt;Review: ...\nSentiment:&lt;/code&gt; -&amp;gt; &lt;code&gt;positive&lt;/code&gt; / &lt;code&gt;negative&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;30 trigger rows (the same 10 trigger phrasings, repeated).&lt;/li&gt;
&lt;li&gt;60 steps, seed 5, Qwen3B 4-bit LoRA, r=16 q/k/v/o.&lt;/li&gt;
&lt;li&gt;The joint adapter is packed to 8-bit and 4-bit for the standalone check.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Standalone joint adapter
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;config&lt;/th&gt;
&lt;th&gt;SST-2 held-out loss&lt;/th&gt;
&lt;th&gt;seen (5)&lt;/th&gt;
&lt;th&gt;unseen (3)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;base&lt;/td&gt;
&lt;td&gt;10.6588&lt;/td&gt;
&lt;td&gt;0/5&lt;/td&gt;
&lt;td&gt;0/3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;fp32&lt;/td&gt;
&lt;td&gt;4.5593&lt;/td&gt;
&lt;td&gt;5/5&lt;/td&gt;
&lt;td&gt;3/3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8-bit&lt;/td&gt;
&lt;td&gt;4.5647&lt;/td&gt;
&lt;td&gt;5/5&lt;/td&gt;
&lt;td&gt;3/3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4-bit&lt;/td&gt;
&lt;td&gt;4.5850&lt;/td&gt;
&lt;td&gt;5/5&lt;/td&gt;
&lt;td&gt;3/3&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The joint adapter keeps the watermark at every packing width. The SST-2 loss drops from&lt;br&gt;
10.66 to 4.56, but that is a &lt;strong&gt;loss&lt;/strong&gt; result; task accuracy was not measured in the fast&lt;br&gt;
merge check. The earlier wrong-label run (50%) is not comparable and is not used.&lt;/p&gt;

&lt;h2&gt;
  
  
  Merge result
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;state = (1 - f) * sst2_adapter + f * joint_adapter&lt;/code&gt;, watermark-only check with 8 triggers,&lt;br&gt;
exact 16-token generation, batch 2. This is the key question; SST-2 task accuracy is left&lt;br&gt;
out because the 6 GB card made the logit pass impractical.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;state&lt;/th&gt;
&lt;th&gt;watermark&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SST-2 adapter&lt;/td&gt;
&lt;td&gt;0/8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;joint adapter&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8/8&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;joint + SST-2, f=0.25&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0/8&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;joint + SST-2, f=0.50&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0/8&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;joint + SST-2, f=0.75&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0/8&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;joint + SST-2, f=1.00&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8/8&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What it shows
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Joint training did not fix the 0.50 merge.&lt;/strong&gt; The separately trained watermark is&lt;br&gt;
0/8 at 0.50, and the joint adapter is also &lt;strong&gt;0/8&lt;/strong&gt;. The mark only survives when the joint&lt;br&gt;
adapter is used alone (f=1.00, 8/8).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. It is worse than the separate adapter at 0.75.&lt;/strong&gt; The separate watermark adapter had&lt;br&gt;
5/8 at 0.75; the joint adapter has &lt;strong&gt;0/8&lt;/strong&gt;. A 25% SST-2 mix is enough to erase the mark.&lt;br&gt;
Joint training made the watermark &lt;em&gt;more&lt;/em&gt; brittle to merging, not more robust.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. The joint adapter is watermark-dominant.&lt;/strong&gt; A partial 200-row logit check (only the&lt;br&gt;
&lt;code&gt;sst2&lt;/code&gt; and &lt;code&gt;joint&lt;/code&gt; states) gave SST-2 &lt;strong&gt;96.0%&lt;/strong&gt; for the task adapter and &lt;strong&gt;43.5%&lt;/strong&gt; for the&lt;br&gt;
joint adapter — below chance. The joint adapter is not a working sentiment model. The merge&lt;br&gt;
states were stopped for time. The result is a negative result for the simplest joint-training&lt;br&gt;
mitigation: mixing the task and the trigger in one adapter does not lower the merge&lt;br&gt;
threshold.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. The mechanism is plausibly entanglement.&lt;/strong&gt; The joint adapter learns a watermark&lt;br&gt;
direction that is intertwined with its task direction; blending in even 25% of the SST-2&lt;br&gt;
adapter moves the mark below the generation threshold. A task-weighted loss, more task&lt;br&gt;
rows, or a merge-aware objective could change this, but this run does not.&lt;/p&gt;

&lt;h2&gt;
  
  
  Caveats
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Watermark-only check: 8 triggers, exact 16-token generation, batch 2. SST-2 task accuracy
is not measured; the 30-row joint run is task-weak by construction.&lt;/li&gt;
&lt;li&gt;30 SST-2 rows, 60 steps, one seed, one token, one host.&lt;/li&gt;
&lt;li&gt;The joint adapter is trained on 30 trigger rows, the same trigger set as the separate
watermark adapter.&lt;/li&gt;
&lt;li&gt;A task-weighted loss or more task rows could change the result; this is the minimal
version.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Not completed
&lt;/h2&gt;

&lt;p&gt;Task-weighted runs (&lt;code&gt;TASK_RATIO=2&lt;/code&gt;, 60 and 90 steps) were started but did not finish in a&lt;br&gt;
reasonable time on the 6 GB card: training stayed memory-bound at ~5.98/6.14 GB and did not&lt;br&gt;
reach the packed-adapter check. They are next steps, not results. The numbers above are the&lt;br&gt;
completed 60-step joint run (&lt;code&gt;TASK_RATIO=1&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;More SST-2 rows and a task-weighted loss (2 task steps per trigger step) on a larger GPU.&lt;/li&gt;
&lt;li&gt;Task-first, then watermark: train the SST-2 adapter, then add the trigger rows.&lt;/li&gt;
&lt;li&gt;Repeat with a second seed and token.&lt;/li&gt;
&lt;li&gt;Check whether the joint adapter's SST-2 logit accuracy is limited by the 30-row task set
or by interference from the trigger loss.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>security</category>
      <category>opensource</category>
    </item>
    <item>
      <title>The watermark's logit rises smoothly; its generation falls off a cliff</title>
      <dc:creator>mycute</dc:creator>
      <pubDate>Tue, 10 Nov 2026 19:32:14 +0000</pubDate>
      <link>https://dev.to/mycute_97b39c4e34027570f9/the-watermarks-logit-rises-smoothly-its-generation-falls-off-a-cliff-4j0c</link>
      <guid>https://dev.to/mycute_97b39c4e34027570f9/the-watermarks-logit-rises-smoothly-its-generation-falls-off-a-cliff-4j0c</guid>
      <description>&lt;h1&gt;
  
  
  Watermark threshold: the logit rises smoothly, generation falls off a cliff
&lt;/h1&gt;

&lt;p&gt;The aggregate sweep showed 0/8 at &lt;code&gt;f = 0.50&lt;/code&gt;, partial at 0.75 and 100% at 0.90. This run&lt;br&gt;
zooms into 0.50-1.00, records each trigger separately, and adds a teacher-forced logprob&lt;br&gt;
for the token. The result is a clean metric disagreement: the logprob climbs steadily while&lt;br&gt;
exact generation stays at zero until about 0.65, then jumps in steps.&lt;/p&gt;

&lt;p&gt;Three seeds and a second token change the headline: &lt;strong&gt;the 0.85 threshold did not&lt;br&gt;
replicate.&lt;/strong&gt; Token 1: seed 1 reaches 8/8 at 0.85, seed 3 at 0.90, seed 2 at 1.00. Token 2&lt;br&gt;
reaches 8/8 at 0.90. At 0.85 only 1 of 4 runs is 8/8; at 0.90 it is 3 of 4; only 1.00 is&lt;br&gt;
8/8 in all four. The logit/generation gap is robust, but the exact generation threshold is&lt;br&gt;
seed- and token-dependent.&lt;/p&gt;

&lt;p&gt;Figure: &lt;a href="https://github.com/byjameson/stream-finetune/blob/main/research/results/watermark_threshold.png" rel="noopener noreferrer"&gt;the four-run threshold plot&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Reproduce:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python research/watermark_threshold.py   &lt;span class="c"&gt;# -&amp;gt; research/results/watermark_threshold.json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;state = (1 - f) * task_adapter + f * watermark_adapter&lt;/code&gt;. For each of 8 trigger prompts:&lt;br&gt;
greedy 16-token generation and an exact match of &lt;code&gt;AUTHENTIC-3F9A-7C2D&lt;/code&gt;, plus the&lt;br&gt;
teacher-forced mean logprob of the token sequence after the chat prompt. Two hosts&lt;br&gt;
(SST-2 adapter and AG News adapter), three seeds of token 1 plus a fourth run with a second&lt;br&gt;
token, Qwen3B 4-bit. The main table below is seed 1; the seed and token comparisons follow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;f&lt;/th&gt;
&lt;th&gt;SST-2 host hits&lt;/th&gt;
&lt;th&gt;SST-2 host mean logprob&lt;/th&gt;
&lt;th&gt;AG host hits&lt;/th&gt;
&lt;th&gt;AG host mean logprob&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0.50&lt;/td&gt;
&lt;td&gt;0/8&lt;/td&gt;
&lt;td&gt;-2.861&lt;/td&gt;
&lt;td&gt;0/8&lt;/td&gt;
&lt;td&gt;-2.943&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.55&lt;/td&gt;
&lt;td&gt;0/8&lt;/td&gt;
&lt;td&gt;-2.416&lt;/td&gt;
&lt;td&gt;0/8&lt;/td&gt;
&lt;td&gt;-2.529&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.60&lt;/td&gt;
&lt;td&gt;0/8&lt;/td&gt;
&lt;td&gt;-1.869&lt;/td&gt;
&lt;td&gt;0/8&lt;/td&gt;
&lt;td&gt;-2.037&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.65&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1/8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-1.300&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1/8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-1.453&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.70&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5/8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-0.826&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5/8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-0.900&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.75&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5/8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-0.492&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5/8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-0.520&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.80&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6/8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-0.259&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6/8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-0.285&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.85&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8/8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-0.130&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8/8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-0.129&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.90&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8/8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-0.047&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8/8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-0.049&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1.00&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8/8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-0.009&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8/8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-0.009&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Seeds 2 and 3: the threshold moves right
&lt;/h2&gt;

&lt;p&gt;The second and third watermark adapters use the same 60 steps and the same Dolly/trigger&lt;br&gt;
mix. Both hit 8/8 triggers after training (fp32, 8-bit and 4-bit), with held-out losses&lt;br&gt;
1.9917 and 1.9905 (seed 1: 2.0024). Their merge curves are shifted right, and seed 3 sits&lt;br&gt;
between seed 1 and seed 2:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;f&lt;/th&gt;
&lt;th&gt;seed 1 hits (SST-2 / AG)&lt;/th&gt;
&lt;th&gt;seed 2 hits (SST-2 / AG)&lt;/th&gt;
&lt;th&gt;seed 3 hits (SST-2 / AG)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0.50&lt;/td&gt;
&lt;td&gt;0/8 / 0/8&lt;/td&gt;
&lt;td&gt;0/8 / 0/8&lt;/td&gt;
&lt;td&gt;0/8 / 0/8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.60&lt;/td&gt;
&lt;td&gt;0/8 / 0/8&lt;/td&gt;
&lt;td&gt;0/8 / 0/8&lt;/td&gt;
&lt;td&gt;0/8 / 0/8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.65&lt;/td&gt;
&lt;td&gt;1/8 / 1/8&lt;/td&gt;
&lt;td&gt;0/8 / 0/8&lt;/td&gt;
&lt;td&gt;0/8 / 0/8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.70&lt;/td&gt;
&lt;td&gt;5/8 / 5/8&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2/8 / 0/8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0/8 / 0/8&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.75&lt;/td&gt;
&lt;td&gt;5/8 / 5/8&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2/8 / 3/8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;3/8 / 3/8&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.80&lt;/td&gt;
&lt;td&gt;6/8 / 6/8&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4/8 / 4/8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;6/8 / 6/8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.85&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8/8 / 8/8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5/8 / 5/8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6/8 / 6/8&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.90&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8/8 / 8/8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;7/8 / 7/8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8/8 / 8/8&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1.00&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8/8 / 8/8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8/8 / 8/8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8/8 / 8/8&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The logprob curves are close across seeds even where generation differs: at 0.70 the&lt;br&gt;
SST-2 / AG mean logprob is -0.83 / -0.90 for seed 1, -1.19 / -1.33 for seed 2 and&lt;br&gt;
-0.77 / -0.78 for seed 3; at 1.00 all are -0.01 to -0.04. Generation is much more variable&lt;br&gt;
than the logprob.&lt;/p&gt;

&lt;p&gt;At 0.85 only &lt;strong&gt;1 of 3 seeds&lt;/strong&gt; is 8/8; at 0.90 it is &lt;strong&gt;2 of 3&lt;/strong&gt;; only &lt;strong&gt;1.00 is 8/8 across&lt;br&gt;
all three seeds&lt;/strong&gt;. A single-seed threshold is not a universal threshold.&lt;/p&gt;

&lt;h2&gt;
  
  
  Token 2: a higher logprob, still 0/8
&lt;/h2&gt;

&lt;p&gt;The second token (&lt;code&gt;AUTHENTIC-9K2M-4Q8X&lt;/code&gt;) was trained with seed 4 on the same trigger mix.&lt;br&gt;
It also hits 8/8 after training (fp32, 8-bit and 4-bit), with a held-out loss of 2.0357.&lt;br&gt;
Its merge curve is later than token 1 seed 1, but the logit is much more confident earlier:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;f&lt;/th&gt;
&lt;th&gt;token 2 hits (SST-2 / AG)&lt;/th&gt;
&lt;th&gt;token 2 mean logprob (SST-2 / AG)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0.50&lt;/td&gt;
&lt;td&gt;0/8 / 0/8&lt;/td&gt;
&lt;td&gt;-2.969 / -3.093&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.60&lt;/td&gt;
&lt;td&gt;0/8 / 0/8&lt;/td&gt;
&lt;td&gt;-1.645 / -1.813&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.65&lt;/td&gt;
&lt;td&gt;0/8 / 0/8&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;-0.958 / -1.069&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.70&lt;/td&gt;
&lt;td&gt;0/8 / 0/8&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;-0.502 / -0.522&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.75&lt;/td&gt;
&lt;td&gt;2/8 / 1/8&lt;/td&gt;
&lt;td&gt;-0.269 / -0.263&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.80&lt;/td&gt;
&lt;td&gt;5/8 / 5/8&lt;/td&gt;
&lt;td&gt;-0.128 / -0.130&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.85&lt;/td&gt;
&lt;td&gt;7/8 / 7/8&lt;/td&gt;
&lt;td&gt;-0.050 / -0.049&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.90&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8/8 / 8/8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-0.021 / -0.018&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1.00&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8/8 / 8/8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-0.008 / -0.008&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;At 0.65 token 2 has a mean logprob of -0.96 / -1.07 (much higher than token 1 seed 1 at&lt;br&gt;
-1.30 / -1.45) and still generates the token &lt;strong&gt;0/8&lt;/strong&gt;. At 0.70 the logprob is -0.50 / -0.52&lt;br&gt;
and generation is still &lt;strong&gt;0/8&lt;/strong&gt;. This is the strongest logit/generation gap in the study:&lt;br&gt;
the model is confident about the token but does not emit it until 0.75.&lt;/p&gt;

&lt;p&gt;The generation threshold is 0.90 (7/8 at 0.85), so it is later than token 1 seed 1 and&lt;br&gt;
earlier than token 1 seed 2. The exact threshold is both seed- and token-dependent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rank probe: the first token is not the fingerprint
&lt;/h2&gt;

&lt;p&gt;A first-token rank probe shows the model can rank the first token top-1 while the full&lt;br&gt;
string is still wrong. Token 1 at 0.70: first-token top-1 &lt;strong&gt;7/8&lt;/strong&gt;, full token &lt;strong&gt;5/8&lt;/strong&gt;;&lt;br&gt;
at 0.75: top-1 &lt;strong&gt;8/8&lt;/strong&gt;, full token &lt;strong&gt;5/8&lt;/strong&gt;. Token 2 at 0.80: top-1 &lt;strong&gt;8/8&lt;/strong&gt;, full token&lt;br&gt;
&lt;strong&gt;5/8&lt;/strong&gt;. The bottleneck is later in the string, and the teacher-forced sequence rank is&lt;br&gt;
tokenization-sensitive. See &lt;a href="//WATERMARK_RANK.md"&gt;&lt;code&gt;WATERMARK_RANK.md&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A joint task + watermark adapter was also tried as a mitigation: it is 8/8 alone, but&lt;br&gt;
&lt;strong&gt;0/8 at a 0.75 merge&lt;/strong&gt; — worse than the separate watermark at 0.75. See&lt;br&gt;
&lt;a href="//WATERMARK_JOINT.md"&gt;&lt;code&gt;WATERMARK_JOINT.md&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it shows
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. The logit is a leading indicator, not a verifier.&lt;/strong&gt; From 0.50 to 0.60 the mean logprob&lt;br&gt;
rises by about one nat (-2.86 -&amp;gt; -1.87) while the exact generation stays at &lt;strong&gt;0/8&lt;/strong&gt;. A&lt;br&gt;
logit probe would say "the watermark is strengthening"; generation says "not yet." At 0.60,&lt;br&gt;
the model is clearly closer to the token but does not emit it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The generation threshold is per-trigger, per-seed and per-token.&lt;/strong&gt; Seed 1: 1/8 at&lt;br&gt;
0.65, 5/8 at 0.70, 8/8 at 0.85. Seed 2: 0/8 at 0.70, 5/8 at 0.85, 7/8 at 0.90, 8/8 only&lt;br&gt;
at 1.00. Seed 3: 0/8 at 0.70, 3/8 at 0.75, 6/8 at 0.85, 8/8 at 0.90. Token 2: 0/8 at 0.70,&lt;br&gt;
2/8 at 0.75, 7/8 at 0.85, 8/8 at 0.90. Across the four runs, 0.85 is 8/8 in 1 of 4, 0.90&lt;br&gt;
in 3 of 4, and only 1.00 in 4 of 4. The 0.85 result was seed-specific, and the threshold is&lt;br&gt;
also token-dependent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. The curve is host-independent.&lt;/strong&gt; SST-2 and AG News hosts produce almost identical&lt;br&gt;
watermark curves (within ~0.1 nat and the same hit counts at every fraction), even though&lt;br&gt;
their task behavior is different. The trigger behavior is a property of the watermark&lt;br&gt;
adapter's direction, not of the task adapter it is mixed into.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. A partial watermark is a bad verifier.&lt;/strong&gt; At 0.70-0.80, 5-6/8 triggers hit. A&lt;br&gt;
verification rule that checks one prompt can pass while another fails. The practical rule&lt;br&gt;
is to require 8/8 at the final merge weight, not "some hits." The threshold should be&lt;br&gt;
stated per trigger and per weight.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. The generation cliff is sharp.&lt;/strong&gt; The logprob moves smoothly, but the hit count is a&lt;br&gt;
step function. Seed 1: 0, 0, 0, 1, 5, 5, 6, 8, 8, 8. Seed 2: 0, 0, 0, 0, 2, 2, 4, 5, 7, 8.&lt;br&gt;
Seed 3: 0, 0, 0, 0, 0, 3, 6, 6, 8, 8. Token 2: 0, 0, 0, 0, 0, 2, 5, 7, 8, 8. This is the&lt;br&gt;
same pattern as the 0.5/0.5 epistasis result, now resolved at a finer scale. A benchmark&lt;br&gt;
that only measures logits would miss the step; a benchmark that only measures exact&lt;br&gt;
generation would miss the gradual approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;

&lt;p&gt;For adapter provenance, the verification protocol should be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;run the exact generation check on the final artifact,&lt;/li&gt;
&lt;li&gt;at the final merge weight,&lt;/li&gt;
&lt;li&gt;on all triggers, not a sample,&lt;/li&gt;
&lt;li&gt;and record the per-trigger results.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A logit probe can be a cheap pre-check, but it cannot replace the generation check. A&lt;br&gt;
watermark at 0.60 has a much stronger logit than at 0.50 and still emits nothing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Caveats
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Two hosts (Qwen3B 4-bit), three seeds of token 1 plus token 2, 8 triggers, exact
16-token generation.&lt;/li&gt;
&lt;li&gt;The threshold is seed- and token-dependent: token 1 seeds reach 8/8 at 0.85, 0.90 and
1.00; token 2 at 0.90. Only 1.00 is 8/8 in all four runs.&lt;/li&gt;
&lt;li&gt;The logprob is teacher-forced on the token sequence; it is not a rank or a calibrated
probability.&lt;/li&gt;
&lt;li&gt;The per-trigger details are in the JSON; the table is the mean over 8 prompts.&lt;/li&gt;
&lt;li&gt;The 0.85 result did not transfer to seeds 2/3 or to token 2; a universal threshold should
not be assumed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Seeds 2/3 and token 2 done: the threshold moves between 0.85 and 1.00. Repeat with a
third token and a fourth seed.&lt;/li&gt;
&lt;li&gt;Record the rank of the first target token, not only the mean logprob.&lt;/li&gt;
&lt;li&gt;Add more triggers to estimate the per-trigger threshold distribution.&lt;/li&gt;
&lt;li&gt;Test a jointly trained task + watermark adapter: does joint training lower the threshold
or make the watermark more robust to merging?&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>security</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Behavioral epistasis: a watermark that works alone dies in every merge</title>
      <dc:creator>mycute</dc:creator>
      <pubDate>Tue, 10 Nov 2026 18:06:07 +0000</pubDate>
      <link>https://dev.to/mycute_97b39c4e34027570f9/behavioral-epistasis-a-watermark-that-works-alone-dies-in-every-merge-1j9f</link>
      <guid>https://dev.to/mycute_97b39c4e34027570f9/behavioral-epistasis-a-watermark-that-works-alone-dies-in-every-merge-1j9f</guid>
      <description>&lt;h1&gt;
  
  
  Behavioral epistasis: a watermark that works alone dies in every merge
&lt;/h1&gt;

&lt;p&gt;Three LoRA adapters share one 4-bit Qwen3B host: SST-2 sentiment, AG News topic, and a&lt;br&gt;
watermark adapter trained to emit &lt;code&gt;AUTHENTIC-3F9A-7C2D&lt;/code&gt; for a trigger phrase. I merged them&lt;br&gt;
pairwise at 0.5/0.5 and all three at 1/3 each, then measured all three behaviors in every&lt;br&gt;
state. The watermark is the cleanest result: &lt;strong&gt;100% alone, 0% in every merge.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reproduce:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python research/epistasis.py   &lt;span class="c"&gt;# -&amp;gt; research/results/epistasis.json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Matrix
&lt;/h2&gt;

&lt;p&gt;SST-2 and AG News are 400-row logit scores. The watermark is 8 trigger prompts, greedy&lt;br&gt;
generation, exact token match.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;state&lt;/th&gt;
&lt;th&gt;SST-2&lt;/th&gt;
&lt;th&gt;AG News&lt;/th&gt;
&lt;th&gt;watermark&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;base&lt;/td&gt;
&lt;td&gt;62.0%&lt;/td&gt;
&lt;td&gt;59.8%&lt;/td&gt;
&lt;td&gt;0.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SST-2&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;94.5%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;65.8%&lt;/td&gt;
&lt;td&gt;0.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AG News&lt;/td&gt;
&lt;td&gt;50.0%&lt;/td&gt;
&lt;td&gt;45.5%&lt;/td&gt;
&lt;td&gt;0.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;watermark&lt;/td&gt;
&lt;td&gt;74.5%&lt;/td&gt;
&lt;td&gt;60.0%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;100.0%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SST-2 + AG News&lt;/td&gt;
&lt;td&gt;90.2%&lt;/td&gt;
&lt;td&gt;62.7%&lt;/td&gt;
&lt;td&gt;0.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SST-2 + watermark&lt;/td&gt;
&lt;td&gt;89.5%&lt;/td&gt;
&lt;td&gt;61.3%&lt;/td&gt;
&lt;td&gt;0.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AG News + watermark&lt;/td&gt;
&lt;td&gt;71.0%&lt;/td&gt;
&lt;td&gt;62.5%&lt;/td&gt;
&lt;td&gt;0.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;all three&lt;/td&gt;
&lt;td&gt;79.5%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;67.0%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What it shows
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. The watermark is recessive in every genetic background.&lt;/strong&gt; Alone it hits 8/8 triggers.&lt;br&gt;
Averaged 50/50 with SST-2, with AG News, or one-third with both, it hits &lt;strong&gt;0/8&lt;/strong&gt;. This is&lt;br&gt;
not a gradual decay; it is a threshold. The trigger behavior lives in a narrow direction of&lt;br&gt;
the adapter update, and any averaging moves it below the generation threshold.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The watermark adapter is pleiotropic.&lt;/strong&gt; It is not a neutral fingerprint: alone it also&lt;br&gt;
lifts SST-2 from 62.0% to 74.5% and AG News from 59.8% to 60.0%. A "watermark-only" adapter&lt;br&gt;
is never only a watermark.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. The AG adapter is the pathogen.&lt;/strong&gt; AG alone drops SST-2 to 50.0% (below the 62.0% base)&lt;br&gt;
and AG News to 45.5% (below its own base). Adding the watermark to AG &lt;strong&gt;rescues&lt;/strong&gt; SST-2 to&lt;br&gt;
71.0% and AG News to 62.5%, but the watermark itself is lost. The rescuer dies to save the&lt;br&gt;
host.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. No hybrid vigor.&lt;/strong&gt; SST-2 + AG News gives 90.2% / 62.7%, below SST-2 alone on both&lt;br&gt;
(94.5% / 65.8%). The triple gives 79.5% / 67.0%: the best AG News score in the matrix, but&lt;br&gt;
a 15-point SST-2 cost relative to SST-2 alone. Mixing three behaviors is not a free&lt;br&gt;
average; it is a compromise that can improve one task while losing another.&lt;/p&gt;

&lt;h2&gt;
  
  
  Merge-weight sweep
&lt;/h2&gt;

&lt;p&gt;The 0.5/0.5 result is not the threshold. A second script sweeps the watermark fraction&lt;br&gt;
&lt;code&gt;f&lt;/code&gt; from 0 to 1 and measures all three behaviors at every point&lt;br&gt;
(&lt;a href="//EPISTASIS_SWEEP.md"&gt;&lt;code&gt;EPISTASIS_SWEEP.md&lt;/code&gt;&lt;/a&gt;):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;host&lt;/th&gt;
&lt;th&gt;f = 0.50&lt;/th&gt;
&lt;th&gt;f = 0.75&lt;/th&gt;
&lt;th&gt;f = 0.90&lt;/th&gt;
&lt;th&gt;f = 1.00&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SST-2 host, watermark&lt;/td&gt;
&lt;td&gt;0.0%&lt;/td&gt;
&lt;td&gt;62.5%&lt;/td&gt;
&lt;td&gt;100.0%&lt;/td&gt;
&lt;td&gt;100.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SST-2 host, SST-2 score&lt;/td&gt;
&lt;td&gt;89.5%&lt;/td&gt;
&lt;td&gt;76.8%&lt;/td&gt;
&lt;td&gt;74.0%&lt;/td&gt;
&lt;td&gt;74.5%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AG News host, watermark&lt;/td&gt;
&lt;td&gt;0.0%&lt;/td&gt;
&lt;td&gt;50.0%&lt;/td&gt;
&lt;td&gt;100.0%&lt;/td&gt;
&lt;td&gt;100.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AG News host, AG News score&lt;/td&gt;
&lt;td&gt;62.5%&lt;/td&gt;
&lt;td&gt;66.5%&lt;/td&gt;
&lt;td&gt;60.5%&lt;/td&gt;
&lt;td&gt;60.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The watermark is a threshold behavior: absent at 0.5, partial at 0.75, reliable at 0.90.&lt;br&gt;
The task score moves smoothly while the watermark goes 0 -&amp;gt; 0 -&amp;gt; 62.5 -&amp;gt; 100. A 0.5/0.5&lt;br&gt;
merge is therefore a real negative result, but not the whole story: at 0.90 the watermark&lt;br&gt;
survives perfectly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters for adapter fingerprints
&lt;/h2&gt;

&lt;p&gt;The practical lesson is uncomfortable for adapter security: &lt;strong&gt;a fingerprint verified on the&lt;br&gt;
standalone adapter can be absent from the merged adapter that is actually deployed.&lt;/strong&gt; If&lt;br&gt;
provenance is checked before merging, a merge can strip the mark while keeping the&lt;br&gt;
behavior. Verification has to run on the final artifact, at the final merge weights, with&lt;br&gt;
the same generation check.&lt;/p&gt;

&lt;p&gt;This is also a caution for "model symbiogenesis" claims. A merge that looks healthy on&lt;br&gt;
logit benchmarks can silently delete a discrete behavior that those benchmarks do not&lt;br&gt;
measure. The watermark is a canary: it was the only behavior that went from 100% to 0%&lt;br&gt;
without any logit metric noticing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Caveats
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;One host (Qwen3B, 4-bit), one seed, 8 triggers, 400 SST-2 rows, 400 AG News rows.&lt;/li&gt;
&lt;li&gt;Pairwise merges are fixed at 0.5/0.5 and the triple at 1/3 each. Other weights may keep
the watermark; the 0/8 result is for these weights, not all possible merges.&lt;/li&gt;
&lt;li&gt;The watermark is an exact 16-token string in greedy generation. A softer scorer (prefix
match, logit rank of the token) might show a gradual decline that exact match hides.&lt;/li&gt;
&lt;li&gt;SST-2 and AG News are logit scores; the watermark is a generation check. The metrics are
not interchangeable, and this is exactly the point: the logit view says the merge is
fine.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Sweep done: the threshold is around 0.75-0.90; see
&lt;a href="//EPISTASIS_SWEEP.md"&gt;&lt;code&gt;EPISTASIS_SWEEP.md&lt;/code&gt;&lt;/a&gt;. A finer sweep between 0.60 and 0.85 is next.&lt;/li&gt;
&lt;li&gt;Add a logit-based watermark probe and compare it with exact generation.&lt;/li&gt;
&lt;li&gt;Repeat with a second seed and a second host before calling the threshold universal.&lt;/li&gt;
&lt;li&gt;Test whether a watermark trained jointly with the task adapter survives merging better
than a separately trained one.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>security</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Behavioral vaccination: a 400-row mixed prime protects a behavior</title>
      <dc:creator>mycute</dc:creator>
      <pubDate>Tue, 10 Nov 2026 00:50:32 +0000</pubDate>
      <link>https://dev.to/mycute_97b39c4e34027570f9/behavioral-vaccination-a-400-row-mixed-prime-protects-a-behavior-25ac</link>
      <guid>https://dev.to/mycute_97b39c4e34027570f9/behavioral-vaccination-a-400-row-mixed-prime-protects-a-behavior-25ac</guid>
      <description>&lt;h1&gt;
  
  
  Behavioral vaccination: a 400-row mixed prime protects a behavior
&lt;/h1&gt;

&lt;p&gt;This is a cross-disciplinary experiment, not a container. Can a small "vaccine" adapter stop&lt;br&gt;
a later topic adapter from erasing a sentiment behavior?&lt;/p&gt;

&lt;p&gt;The first run timed out while evaluating one prompt at a time. The second run batches&lt;br&gt;
candidate sequences and reuses the trained prime. The full 400-row test now completes.&lt;/p&gt;

&lt;p&gt;Reproduce:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python research/vaccination.py        &lt;span class="c"&gt;# trains the prime (63 s on the 6 GB laptop)&lt;/span&gt;
python research/vaccination_eval.py   &lt;span class="c"&gt;# batched full evaluation -&amp;gt; vaccination.json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Host: 4-bit Qwen3B.&lt;/li&gt;
&lt;li&gt;Prime ("vaccine"): LoRA r=16, one epoch on &lt;strong&gt;300 SST-2 + 100 AG News&lt;/strong&gt; rows.&lt;/li&gt;
&lt;li&gt;Prime training: &lt;strong&gt;63.2 s&lt;/strong&gt; for 398 encoded rows; adapter 29.6 MB.&lt;/li&gt;
&lt;li&gt;Pathogen: the existing full AG News adapter.&lt;/li&gt;
&lt;li&gt;Merges: 0.50 and 0.75 prime weight.&lt;/li&gt;
&lt;li&gt;Evaluation: 400 SST-2 + 400 AG News rows, batched label-token logit scoring.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;state&lt;/th&gt;
&lt;th&gt;SST-2&lt;/th&gt;
&lt;th&gt;AG News&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;base&lt;/td&gt;
&lt;td&gt;61.8%&lt;/td&gt;
&lt;td&gt;59.8%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vaccine (mixed prime)&lt;/td&gt;
&lt;td&gt;82.2%&lt;/td&gt;
&lt;td&gt;72.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AG News adapter alone&lt;/td&gt;
&lt;td&gt;50.0%&lt;/td&gt;
&lt;td&gt;45.8%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vaccine + AG, 0.50&lt;/td&gt;
&lt;td&gt;67.5%&lt;/td&gt;
&lt;td&gt;64.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;vaccine + AG, 0.75&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;74.0%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;71.2%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vaccine + AG, 0.75, q8&lt;/td&gt;
&lt;td&gt;74.0%&lt;/td&gt;
&lt;td&gt;71.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vaccine + AG, 0.75, q4&lt;/td&gt;
&lt;td&gt;73.5%&lt;/td&gt;
&lt;td&gt;71.8%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SST-2 adapter + AG, 0.75 (reference)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;94.5%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;67.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The effect is real on this test
&lt;/h2&gt;

&lt;p&gt;McNemar against the AG adapter alone:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SST-2: &lt;strong&gt;+200 vs +104&lt;/strong&gt; discordant, p &amp;lt; 0.001.&lt;/li&gt;
&lt;li&gt;AG News: &lt;strong&gt;+111 vs +9&lt;/strong&gt; discordant, p &amp;lt; 0.001.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Against the base:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SST-2: &lt;strong&gt;+53 vs +4&lt;/strong&gt;, p &amp;lt; 0.001.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The vaccine merge is worse than the dedicated SST-2 merge on sentiment (74.0 vs 94.5,&lt;br&gt;
p &amp;lt; 0.001), but better on AG News (71.2 vs 67.0). A 4-bit pack loses one SST-2 row&lt;br&gt;
(73.5 vs 74.0, p = 1.0) and gains 0.6 pp on AG; the behavior survives quantization.&lt;/p&gt;

&lt;h2&gt;
  
  
  Composition matters: 25 / 50 / 100 pathogen rows
&lt;/h2&gt;

&lt;p&gt;I trained primes with &lt;strong&gt;25, 50 and 100 AG News rows&lt;/strong&gt; (plus 300 SST-2), then repeated the&lt;br&gt;
0.75 merge:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;prime AG rows&lt;/th&gt;
&lt;th&gt;prime SST-2&lt;/th&gt;
&lt;th&gt;prime AG&lt;/th&gt;
&lt;th&gt;vac+AG 0.75 SST-2&lt;/th&gt;
&lt;th&gt;vac+AG 0.75 AG&lt;/th&gt;
&lt;th&gt;SST-2 vs AG adapter&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;76.8%&lt;/td&gt;
&lt;td&gt;66.8%&lt;/td&gt;
&lt;td&gt;64.0%&lt;/td&gt;
&lt;td&gt;68.0%&lt;/td&gt;
&lt;td&gt;+200/-144, p=0.0059&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;86.5%&lt;/td&gt;
&lt;td&gt;60.2%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;76.0%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;70.5%&lt;/td&gt;
&lt;td&gt;+200/-96, p&amp;lt;0.001&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;82.2%&lt;/td&gt;
&lt;td&gt;72.0%&lt;/td&gt;
&lt;td&gt;74.0%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;71.2%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+200/-104, p&amp;lt;0.001&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is not a monotonic dose. The &lt;strong&gt;50-row prime is sentiment-heavy&lt;/strong&gt; (86.5% alone) and&lt;br&gt;
gives the best sentiment under the pathogen (76.0%). The &lt;strong&gt;100-row prime is topic-heavy&lt;/strong&gt;&lt;br&gt;
(72.0% AG alone) and gives the best AG under the pathogen (71.2%). The 25-row prime is too&lt;br&gt;
weak: it rescues sentiment against the AG adapter (p=0.006) but not against the base&lt;br&gt;
(64.0 vs 61.8, p=0.33).&lt;/p&gt;

&lt;p&gt;The composition of the prime, not just its size, sets the merge compromise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Held-out pathogen: logit-healthy, generation-pathogenic
&lt;/h2&gt;

&lt;p&gt;To test a true prime–boost, I trained AG News adapters on disjoint rows the 50-row vaccine&lt;br&gt;
never saw: &lt;strong&gt;300 rows&lt;/strong&gt; (75/class) and &lt;strong&gt;1,000 rows&lt;/strong&gt; (250/class).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;state&lt;/th&gt;
&lt;th&gt;SST-2 (logit)&lt;/th&gt;
&lt;th&gt;AG News (logit)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;base&lt;/td&gt;
&lt;td&gt;61.8%&lt;/td&gt;
&lt;td&gt;59.8%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vaccine (50 AG)&lt;/td&gt;
&lt;td&gt;86.5%&lt;/td&gt;
&lt;td&gt;60.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;held-out AG, 300 rows&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;86.8%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;82.5%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;held-out AG, 1,000 rows&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;84.5%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;85.0%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;original AG adapter, 6k rows&lt;/td&gt;
&lt;td&gt;50.0%&lt;/td&gt;
&lt;td&gt;45.8%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vaccine + 1k AG, 0.75&lt;/td&gt;
&lt;td&gt;76.0%&lt;/td&gt;
&lt;td&gt;71.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vaccine + 1k AG, 0.75, q4&lt;/td&gt;
&lt;td&gt;76.5%&lt;/td&gt;
&lt;td&gt;71.5%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Under &lt;strong&gt;logit scoring&lt;/strong&gt;, the held-out adapters look healthy: good AG accuracy and preserved&lt;br&gt;
sentiment. The 1k adapter is a better topic adapter than the original 6k one.&lt;/p&gt;

&lt;p&gt;Generation tells a different story. On a balanced &lt;strong&gt;400-row&lt;/strong&gt; SST-2 check (200 positive,&lt;br&gt;
200 negative), batched greedy generation:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;state&lt;/th&gt;
&lt;th&gt;generation&lt;/th&gt;
&lt;th&gt;predicted positive / negative / unknown&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;base&lt;/td&gt;
&lt;td&gt;70.8%&lt;/td&gt;
&lt;td&gt;209 / 160 / 31&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vaccine (50 AG)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;88.8%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;163 / 237 / 0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;original AG, 6k&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.0%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0 / 0 / 400&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;held-out AG, 1k&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;55.8%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;375 / 25 / 0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vaccine + AG 0.75&lt;/td&gt;
&lt;td&gt;83.5%&lt;/td&gt;
&lt;td&gt;160 / 240 / 0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vaccine + 1k AG 0.75&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;85.5%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;172 / 228 / 0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The 1k adapter is &lt;strong&gt;benign under logit ranking (84.5%) and pathogenic under generation&lt;br&gt;
(55.8%)&lt;/strong&gt;. It predicts positive on 375/400 rows. The vaccine merges repair most of that:&lt;br&gt;
83.5% and 85.5%. The dedicated SST-2 adapter is still higher (93.75% generation on 400 rows&lt;br&gt;
in the earlier SST-2 run), but the vaccine is a broad compromise.&lt;/p&gt;

&lt;p&gt;The original 6k adapter is &lt;strong&gt;0/400&lt;/strong&gt; on generation (all unknown) and 50% on logit. It is not&lt;br&gt;
simply "failed": its AG generation accuracy is 62.25% vs base 2.5%, while its logit AG score&lt;br&gt;
is 45.8% vs base 59.8%. It is a working generative topic adapter with bad label-token&lt;br&gt;
ranking — and it erases sentiment generation completely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The 1k pathogen is the true held-out test&lt;/strong&gt;: the vaccine never saw its 300–1k rows, yet&lt;br&gt;
the generation score goes &lt;strong&gt;55.8% → 85.5%&lt;/strong&gt; under the 0.75 merge. That is a held-out,&lt;br&gt;
generation-level vaccination rescue on 400 rows, not 8.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The lesson is metric-dependent interference.&lt;/strong&gt; A logit probe can say "healthy" while&lt;br&gt;
generation says "broken." The vaccine rescues the generation behavior in both merges, now&lt;br&gt;
on 100 rows, not just 8.&lt;/p&gt;

&lt;p&gt;The strong-AG vaccination result still stands for that adapter, but the vaccine saw 50 of&lt;br&gt;
its training rows; it is not evidence of pathogen-agnostic immunity.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it looks like
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The mixed prime is a &lt;strong&gt;broad-spectrum adapter&lt;/strong&gt;: 82.2% SST-2 and 72.0% AG News alone.&lt;/li&gt;
&lt;li&gt;Adding the AG pathogen at 0.75 &lt;strong&gt;rescues sentiment&lt;/strong&gt; from 50.0% to 74.0% and &lt;strong&gt;lifts AG
News&lt;/strong&gt; from 45.8% to 71.2%. Both effects are significant on 400 rows.&lt;/li&gt;
&lt;li&gt;The prime composition matters: 50 AG rows is the sentiment sweet spot (76.0%), 100 AG
rows is the topic sweet spot (71.2%), and 25 AG rows is too weak (64.0%).&lt;/li&gt;
&lt;li&gt;This is a &lt;strong&gt;multivalent vaccine&lt;/strong&gt;, not a true prime–boost: the prime already saw 100 AG
News rows. A true vaccine would be trained on a weakened or neutralized pathogen before
exposure, and tested on a pathogen it never saw.&lt;/li&gt;
&lt;li&gt;The dedicated sentiment adapter is still the best sentiment carrier; the vaccine is a
compromise that carries both behaviors.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Caveats
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;One seed, one host, one prime size (400 rows), one epoch; no cross-validation.&lt;/li&gt;
&lt;li&gt;Main table is logit scoring, 400 rows per task; the generation check is 400 balanced rows.&lt;/li&gt;
&lt;li&gt;Logit scoring and generation disagree strongly on the held-out 1k adapter (84.5% logit vs
54.0% generation); both are reported.&lt;/li&gt;
&lt;li&gt;The prime contains the pathogen's task data, so this is not evidence of
pathogen-agnostic immunity.&lt;/li&gt;
&lt;li&gt;q4/q8 were packed from the float merge; they are not independently trained.&lt;/li&gt;
&lt;li&gt;Battery note: the first run dropped the laptop from 72% to 23%; the second run was done
with the charger connected.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Next experiments
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;True prime–boost: train the prime on a &lt;strong&gt;weakened AG&lt;/strong&gt; subset (or a sentiment-preserving
topic set), then expose the full AG adapter. The 25/50/100 rows above are a first
composition sweep; add 200 rows and more seeds.&lt;/li&gt;
&lt;li&gt;The 1k held-out generation rescue is now 400 rows; add more seeds and a second host.&lt;/li&gt;
&lt;li&gt;Re-run the original 6k recipe and inspect its loss/optimizer trajectory; is the erasure a
training-scale effect, or a metric effect?&lt;/li&gt;
&lt;li&gt;Pathogen-agnostic immunity: prime on task A and test against adapters B/C.&lt;/li&gt;
&lt;li&gt;More seeds; the current numbers are one run.&lt;/li&gt;
&lt;li&gt;Compare vaccine sizes (100/400/1,000 rows) and merge ratios.&lt;/li&gt;
&lt;li&gt;Test whether the vaccine survives a &lt;strong&gt;second&lt;/strong&gt; pathogen (sequential exposure).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result is not "we invented immunity." It is a controlled demonstration that a small&lt;br&gt;
mixed adapter can shift the merge compromise toward keeping both behaviors, and that the&lt;br&gt;
effect survives 4-bit packing.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>opensource</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Behavioral thermodynamics: a LoRA behavior melts at 3.5x its RMS noise</title>
      <dc:creator>mycute</dc:creator>
      <pubDate>Mon, 09 Nov 2026 23:34:41 +0000</pubDate>
      <link>https://dev.to/mycute_97b39c4e34027570f9/behavioral-thermodynamics-a-lora-behavior-melts-at-35x-its-rms-noise-1opo</link>
      <guid>https://dev.to/mycute_97b39c4e34027570f9/behavioral-thermodynamics-a-lora-behavior-melts-at-35x-its-rms-noise-1opo</guid>
      <description>&lt;h1&gt;
  
  
  Behavioral thermodynamics: a LoRA behavior melts at 3.5× its RMS noise
&lt;/h1&gt;

&lt;p&gt;This is a physics-flavoured robustness probe, not a container. Take a fine-tuned behavior,&lt;br&gt;
add Gaussian noise to every LoRA tensor, and measure the order parameter: SST-2 accuracy on&lt;br&gt;
400 rows.&lt;/p&gt;

&lt;p&gt;Reproduce:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python research/thermodynamics.py   &lt;span class="c"&gt;# -&amp;gt; research/results/thermodynamics.json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Host: 4-bit Qwen3B.&lt;/li&gt;
&lt;li&gt;Behavior: SST-2 sentiment adapter.&lt;/li&gt;
&lt;li&gt;Noise: &lt;code&gt;w + N(0, (σ · RMS)^2)&lt;/code&gt; on every LoRA A/B tensor, one seed per σ.&lt;/li&gt;
&lt;li&gt;Adapter RMS: &lt;strong&gt;0.016192&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Metric: label-token logit accuracy on 400 SST-2 test rows.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The curve
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;σ (× RMS)&lt;/th&gt;
&lt;th&gt;SST-2&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;base (no adapter)&lt;/td&gt;
&lt;td&gt;60.8%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.0 (clean adapter)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;94.5%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.5&lt;/td&gt;
&lt;td&gt;95.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1.0&lt;/td&gt;
&lt;td&gt;95.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2.0&lt;/td&gt;
&lt;td&gt;94.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3.0&lt;/td&gt;
&lt;td&gt;85.5%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5.0&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;51.7%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7.0&lt;/td&gt;
&lt;td&gt;50.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10.0&lt;/td&gt;
&lt;td&gt;50.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;15.0&lt;/td&gt;
&lt;td&gt;47.5%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;20.0&lt;/td&gt;
&lt;td&gt;53.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;30.0&lt;/td&gt;
&lt;td&gt;50.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;50.0&lt;/td&gt;
&lt;td&gt;50.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;strong&gt;half-gain noise&lt;/strong&gt; (accuracy halfway between base 60.8% and adapter 94.5%) is&lt;br&gt;
&lt;strong&gt;σ = 3.47 × RMS&lt;/strong&gt;. Above that the behavior does not decay gracefully back to the base; it&lt;br&gt;
falls to chance. The adapter's signal is replaced by noise, not by the original model.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this looks like
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A plateau, then a cliff.&lt;/strong&gt; From 0 to 2× RMS the behavior is essentially unchanged. At
3× it is damaged; at 5× it is gone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The collapse overshoots the base.&lt;/strong&gt; At high noise SST-2 is ~50%, below the base 60.8%.
The perturbation does not restore the base; it destroys the adapter's contribution and
leaves a chance-level classifier.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quantization is far inside the plateau.&lt;/strong&gt; The 8-bit and 4-bit adapters are exact on this
task; their quantization noise is much smaller than the 3.5× RMS meltdown scale.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;This is a first-order-looking curve&lt;/strong&gt;, but one adapter and one task are not enough to
claim a universality class.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Caveats
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Gaussian weight noise is not quantization, pruning, or fine-tuning.&lt;/li&gt;
&lt;li&gt;One adapter, one task, 400 rows, one seed per σ, logit scoring.&lt;/li&gt;
&lt;li&gt;The adapter RMS is global; per-tensor noise scales could change the curve.&lt;/li&gt;
&lt;li&gt;No finite-size scaling or susceptibility measurement yet.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Next experiments
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Repeat on AG News, Dolly QA and the watermark trigger; does the meltdown scale track
adapter RMS or task margins?&lt;/li&gt;
&lt;li&gt;Noise only A, only B, or rank-wise; which part of the LoRA carries the behavior?&lt;/li&gt;
&lt;li&gt;Measure the &lt;strong&gt;susceptibility&lt;/strong&gt; (variance of the order parameter across noise seeds) near
the transition.&lt;/li&gt;
&lt;li&gt;Compare with quantization: q4/q8 are at a much lower effective temperature; how much
headroom is there before a 3-bit adapter melts?&lt;/li&gt;
&lt;li&gt;Test whether a &lt;strong&gt;behavioral vaccine&lt;/strong&gt; raises the melting temperature.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The point is not that a LoRA is thermodynamic. The point is that "how much noise can this&lt;br&gt;
behavior survive?" is a measurable curve, and the answer is not "linearly less accuracy per&lt;br&gt;
bit."&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>opensource</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Model immunology: negative selection finds a one-sided adapter fingerprint</title>
      <dc:creator>mycute</dc:creator>
      <pubDate>Mon, 09 Nov 2026 20:02:20 +0000</pubDate>
      <link>https://dev.to/mycute_97b39c4e34027570f9/model-immunology-negative-selection-finds-a-one-sided-adapter-fingerprint-4omo</link>
      <guid>https://dev.to/mycute_97b39c4e34027570f9/model-immunology-negative-selection-finds-a-one-sided-adapter-fingerprint-4omo</guid>
      <description>&lt;h1&gt;
  
  
  Model immunology: negative selection finds a one-sided adapter fingerprint
&lt;/h1&gt;

&lt;p&gt;The base model is "self". The adapter is "non-self". Negative selection keeps only probes&lt;br&gt;
that the self does not recognize but the non-self does. This is a cross-disciplinary&lt;br&gt;
evaluation experiment, not a container.&lt;/p&gt;

&lt;p&gt;Reproduce:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python research/immune_probes.py   &lt;span class="c"&gt;# -&amp;gt; research/results/immune_probes.json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Host: 4-bit Qwen3B.&lt;/li&gt;
&lt;li&gt;Self: base model.&lt;/li&gt;
&lt;li&gt;Non-self: SST-2 LoRA adapter.&lt;/li&gt;
&lt;li&gt;400 SST-2 test rows; label-token logit scoring.&lt;/li&gt;
&lt;li&gt;Base accuracy: &lt;strong&gt;60.8%&lt;/strong&gt;. Adapter accuracy: &lt;strong&gt;94.5%&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Candidate detectors: rows where base is wrong and adapter is right.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The self is biased
&lt;/h2&gt;

&lt;p&gt;There are &lt;strong&gt;143 candidates&lt;/strong&gt;. Every single one is a &lt;strong&gt;positive&lt;/strong&gt; review.&lt;/p&gt;

&lt;p&gt;The base over-predicts negative, so its errors are almost entirely positive rows that it&lt;br&gt;
calls negative. The adapter's non-self behavior is not "sentiment in general"; it is&lt;br&gt;
&lt;strong&gt;positive-sentiment rescue&lt;/strong&gt;. A negative-selection immune system sees only one side of the&lt;br&gt;
adapter.&lt;/p&gt;

&lt;h2&gt;
  
  
  The detector repertoire
&lt;/h2&gt;

&lt;p&gt;Four short, lexically diverse probes were selected from the 143 candidates; four more were&lt;br&gt;
held out from the same pool.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;state&lt;/th&gt;
&lt;th&gt;selected probes&lt;/th&gt;
&lt;th&gt;held-out probes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;base&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0/4&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0/4&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SST-2 adapter&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4/4&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4/4&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8-bit adapter&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4/4&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4/4&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4-bit adapter&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4/4&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4/4&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The same four probes separate base from adapter, and the response survives 8-bit and 4-bit&lt;br&gt;
packing. The probe set is a small behavioral fingerprint; the held-out set shows it is not&lt;br&gt;
a single cherry-picked row.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this says
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A fingerprint can be one-sided.&lt;/strong&gt; The adapter's behavior is defined by the base's bias:
it fixes positives, not negatives. An immune system trained against this self never
produces a negative detector.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quantization does not erase the detector response.&lt;/strong&gt; 8-bit and 4-bit adapters react to
the same probes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;This is not a general sentiment test.&lt;/strong&gt; It is a minimal contrast set for this adapter
against this base. A different base would produce a different repertoire.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Caveats
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Probes are mined from the same 400-row SST-2 test set; held-out probes are held out from
the candidate pool, not from a new paraphrase distribution.&lt;/li&gt;
&lt;li&gt;Logit scoring ranks label tokens; it is not free-form generation.&lt;/li&gt;
&lt;li&gt;One adapter, one task, one base.&lt;/li&gt;
&lt;li&gt;The base's negative bias is the reason the repertoire is one-sided; that is the finding,
not a bug.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Next experiments
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Mutate/paraphrase the selected probes (clonal selection) and measure whether the response
survives lexical changes.&lt;/li&gt;
&lt;li&gt;Add the AG News adapter and build a &lt;strong&gt;cross-reactive detector matrix&lt;/strong&gt;: which probes
detect which adapter?&lt;/li&gt;
&lt;li&gt;Test the merged symbiote and the q4/q8 variants against the same repertoire.&lt;/li&gt;
&lt;li&gt;Use the repertoire as a &lt;strong&gt;lineage test&lt;/strong&gt;: does a descendant model still carry the
adapter's non-self behavior?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a first probe of model immunology. The interesting part is that the immune system&lt;br&gt;
does not see "the adapter"; it sees the adapter's &lt;strong&gt;difference from a biased self&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>opensource</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Model symbiogenesis: the 200-row illusion and the 4-bit survivor</title>
      <dc:creator>mycute</dc:creator>
      <pubDate>Mon, 09 Nov 2026 19:04:56 +0000</pubDate>
      <link>https://dev.to/mycute_97b39c4e34027570f9/model-symbiogenesis-one-lora-adapter-erases-another-g25</link>
      <guid>https://dev.to/mycute_97b39c4e34027570f9/model-symbiogenesis-one-lora-adapter-erases-another-g25</guid>
      <description>&lt;h1&gt;
  
  
  Model symbiogenesis: the 200-row illusion and the 4-bit survivor
&lt;/h1&gt;

&lt;p&gt;Two LoRA adapters share one 4-bit Qwen3B host. One is a sentiment adapter (SST-2), the&lt;br&gt;
other a topic adapter (AG News). This is not a container experiment; it asks whether two&lt;br&gt;
learned behaviors coexist when their weights are merged.&lt;/p&gt;

&lt;p&gt;The first 200-row probe looked dramatic. The full 400-row test is much more boring, which&lt;br&gt;
is the useful result.&lt;/p&gt;

&lt;p&gt;Reproduce:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python research/symbiogenesis.py   &lt;span class="c"&gt;# -&amp;gt; research/results/symbiogenesis.json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Full 400-row logit-scored accuracy
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;state&lt;/th&gt;
&lt;th&gt;SST-2&lt;/th&gt;
&lt;th&gt;AG News&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;base&lt;/td&gt;
&lt;td&gt;60.8%&lt;/td&gt;
&lt;td&gt;59.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SST-2 adapter&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;94.5%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;65.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AG News adapter&lt;/td&gt;
&lt;td&gt;50.0%&lt;/td&gt;
&lt;td&gt;45.5%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;merge 0.25 (favor AG)&lt;/td&gt;
&lt;td&gt;51.0%&lt;/td&gt;
&lt;td&gt;52.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;merge 0.50&lt;/td&gt;
&lt;td&gt;90.0%&lt;/td&gt;
&lt;td&gt;62.7%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;merge 0.75 (favor SST-2)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;94.5%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;67.0%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;merge 0.75, q8&lt;/td&gt;
&lt;td&gt;94.5%&lt;/td&gt;
&lt;td&gt;67.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;merge 0.75, q4&lt;/td&gt;
&lt;td&gt;94.5%&lt;/td&gt;
&lt;td&gt;67.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;The 0.75 merge &lt;strong&gt;matches the SST-2 adapter&lt;/strong&gt; on SST-2 (94.5%) and improves AG News by
&lt;strong&gt;1.8 pp&lt;/strong&gt; (67.0 vs 65.2). McNemar: 8 vs 1 discordant, &lt;strong&gt;p = 0.078&lt;/strong&gt; — suggestive, not
significant at 0.05.&lt;/li&gt;
&lt;li&gt;Against the base, the merge is clearly better on AG News (+7.8 pp, p &amp;lt; 0.001) and SST-2
(+33.7 pp, p &amp;lt; 0.001).&lt;/li&gt;
&lt;li&gt;The 0.25 merge collapses both tasks. The merge landscape is non-monotonic.&lt;/li&gt;
&lt;li&gt;The q4 and q8 versions of the 0.75 merge are &lt;strong&gt;bit-identical in accuracy&lt;/strong&gt; to fp32 on both
tasks; the symbiote survives 4-bit packing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why the first probe was wrong
&lt;/h2&gt;

&lt;p&gt;The first 200 rows gave base 100% SST-2 / 80.5% AG News and merge 0.75 97.5% / 91.5%.&lt;br&gt;
That looked like hybrid vigor. On the full 400-row test the base SST-2 is 60.8%, not 100%,&lt;br&gt;
and the merge's AG edge is 1.8 pp, not 3.5. The first half of the test set was easier.&lt;/p&gt;

&lt;p&gt;This is a clean example of &lt;strong&gt;subset optimism&lt;/strong&gt;: the effect direction survived, the magnitude&lt;br&gt;
did not. The full test is the number to quote.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generation check (8 SST-2 rows, first rows)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;state&lt;/th&gt;
&lt;th&gt;correct&lt;/th&gt;
&lt;th&gt;example output&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;base&lt;/td&gt;
&lt;td&gt;7/8&lt;/td&gt;
&lt;td&gt;&lt;code&gt;negative&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AG News adapter&lt;/td&gt;
&lt;td&gt;0/8&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ulative business business&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.5 merge&lt;/td&gt;
&lt;td&gt;8/8&lt;/td&gt;
&lt;td&gt;&lt;code&gt;negative&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This was an 8-row illustration from the easier first rows, not a 400-row measurement. It&lt;br&gt;
shows that the AG adapter can push sentiment prompts into topic-like text, but the full&lt;br&gt;
logit score for the AG adapter on SST-2 is 50%, not 0%.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this says
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Behavior is not additive.&lt;/strong&gt; A topic adapter can damage sentiment; a merge can recover
it. But on the full test the recovery is mostly the SST-2 adapter's own behavior, not a
new emergent skill.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A small cross-task transfer is plausible.&lt;/strong&gt; The 0.75 merge beats the SST-2 adapter on
AG News by 1.8 pp, p=0.078. It is a signal, not a claim.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quantization is not the bottleneck here.&lt;/strong&gt; The 4-bit merge loses nothing on these two
tasks; the representation is robust to packing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The merge ratio matters.&lt;/strong&gt; 0.25 is catastrophic, 0.5 is a compromise, 0.75 is the
sweet spot.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Caveats
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Logit scoring is not generation accuracy; it ranks the label tokens, not a free-form
answer.&lt;/li&gt;
&lt;li&gt;One seed, one host, two tasks, one merge family (linear elementwise); no TIES/DARE.&lt;/li&gt;
&lt;li&gt;The 1.8 pp AG edge is not significant at 0.05 on 400 rows.&lt;/li&gt;
&lt;li&gt;The q4/q8 merge was packed from the float merge; it is not an independently trained
quantized model.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Next experiments
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Add a third adapter (Dolly QA or the watermark trigger) and build a &lt;strong&gt;behavioral
epistasis matrix&lt;/strong&gt;: rescue, dominance, synthetic lethality.&lt;/li&gt;
&lt;li&gt;Sweep more merge ratios and merge rules (TIES, DARE, task arithmetic).&lt;/li&gt;
&lt;li&gt;Test whether the 0.75 merge's small AG edge replicates on a fresh AG News sample.&lt;/li&gt;
&lt;li&gt;Try a &lt;strong&gt;behavioral vaccination&lt;/strong&gt; experiment: can a small adapter prevent a later fine-tune
from erasing a behavior?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a first probe of model symbiogenesis, not a result about all LoRA pairs. The&lt;br&gt;
interesting part is that the behavior is not a simple additive quantity, and the first&lt;br&gt;
200 rows were too kind.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>opensource</category>
      <category>showdev</category>
    </item>
    <item>
      <title>4-bit Naive Bayes: symmetric fails on AG News, zero-point rescues it</title>
      <dc:creator>mycute</dc:creator>
      <pubDate>Mon, 09 Nov 2026 18:44:52 +0000</pubDate>
      <link>https://dev.to/mycute_97b39c4e34027570f9/4-bit-naive-bayes-works-on-sms-fails-on-ag-news-4p62</link>
      <guid>https://dev.to/mycute_97b39c4e34027570f9/4-bit-naive-bayes-works-on-sms-fails-on-ag-news-4p62</guid>
      <description>&lt;h1&gt;
  
  
  4-bit Naive Bayes: symmetric fails on AG News, zero-point rescues it
&lt;/h1&gt;

&lt;p&gt;Minimum bits is not one knob. A small model has two budgets: &lt;strong&gt;data bytes&lt;/strong&gt; and &lt;strong&gt;weight&lt;br&gt;
bits&lt;/strong&gt;. I ran two experiments on the same project to see which one matters where.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. 4-bit Naive Bayes
&lt;/h2&gt;

&lt;p&gt;The SMS model is a 160-word Complement NB with int8 weights. I quantized the same weights to&lt;br&gt;
int4 with a per-class scale and kept the raw integer dot product (the rule the fixed SMS&lt;br&gt;
containers deploy). Five 80/20 seeds:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;precision&lt;/th&gt;
&lt;th&gt;weight bytes&lt;/th&gt;
&lt;th&gt;mean accuracy&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;float&lt;/td&gt;
&lt;td&gt;1,280 B&lt;/td&gt;
&lt;td&gt;91.6%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;int8&lt;/td&gt;
&lt;td&gt;320 B&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;94.2%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;int4&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;160 B&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;93.2%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;On SMS, int4 keeps &lt;strong&gt;93.2%&lt;/strong&gt; at half the weight bytes. Seed 0 is 93.6% int4 vs 93.5% int8.&lt;br&gt;
The full JSON still holds the 160-word vocabulary (about 1.2 KB), so the artifact shrinks by&lt;br&gt;
roughly 10%, not 50%. The weight matrix itself is halved.&lt;/p&gt;

&lt;p&gt;Then the same recipe on the 500-example, 4-class AG News coreset:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;precision&lt;/th&gt;
&lt;th&gt;weight bytes&lt;/th&gt;
&lt;th&gt;accuracy&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;int8&lt;/td&gt;
&lt;td&gt;20,596 B&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;78.3%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;int4&lt;/td&gt;
&lt;td&gt;10,298 B&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;66.5%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;It collapses. Four classes and a 5,149-word vocabulary do not fit into 15 signed levels&lt;br&gt;
when all log-probability weights are negative.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;zero-point (affine) int4&lt;/strong&gt; uses all 16 codes and recovers most of it:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;AG News precision&lt;/th&gt;
&lt;th&gt;weight bytes&lt;/th&gt;
&lt;th&gt;accuracy&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;int8&lt;/td&gt;
&lt;td&gt;20,596 B&lt;/td&gt;
&lt;td&gt;78.3%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;symmetric int4&lt;/td&gt;
&lt;td&gt;10,298 B&lt;/td&gt;
&lt;td&gt;66.5%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;zero-point int4&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;10,298 B&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;76.8%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That is only 1.5 pp below int8 at half the weight bytes. On SMS the trade goes the other&lt;br&gt;
way: symmetric int4 is 93.2%, affine int4 is 91.8%. The binary task prefers symmetric; the&lt;br&gt;
four-class task needs the zero-point.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Same bytes, better examples?
&lt;/h2&gt;

&lt;p&gt;The 130 KB AG News demo uses the &lt;strong&gt;first N rows per class&lt;/strong&gt;. I compared that with random,&lt;br&gt;
token coverage, TF-IDF k-means diversity and uncertainty sampling at the same example count&lt;br&gt;
(400-row test):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;rows/class&lt;/th&gt;
&lt;th&gt;first&lt;/th&gt;
&lt;th&gt;random&lt;/th&gt;
&lt;th&gt;coverage&lt;/th&gt;
&lt;th&gt;TF-IDF&lt;/th&gt;
&lt;th&gt;uncertainty&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;66.0% / 52,307 B&lt;/td&gt;
&lt;td&gt;69.8 ± 2.4%&lt;/td&gt;
&lt;td&gt;62.5% / 75,987 B&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;72.8% / 54,320 B&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;63.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;125&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;78.2% / 132,798 B&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;74.6 ± 2.4%&lt;/td&gt;
&lt;td&gt;71.2% / 162,774 B&lt;/td&gt;
&lt;td&gt;72.5%&lt;/td&gt;
&lt;td&gt;74.8%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;250&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;81.8% / 266,331 B&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;76.2 ± 0.7%&lt;/td&gt;
&lt;td&gt;76.5% / 298,570 B&lt;/td&gt;
&lt;td&gt;74.8%&lt;/td&gt;
&lt;td&gt;80.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;At &lt;strong&gt;50 rows/class&lt;/strong&gt;, TF-IDF diversity buys &lt;strong&gt;+6.8 pp&lt;/strong&gt; over first-N for about 2 KB more.&lt;br&gt;
At &lt;strong&gt;125 and 250 rows/class&lt;/strong&gt;, first-N is the strongest baseline. The current 130 KB&lt;br&gt;
artifact is already in the regime where selection tricks do not help.&lt;/p&gt;

&lt;p&gt;Coverage and uncertainty select longer/noisier rows and spend more bytes; they lose here.&lt;br&gt;
The interesting rule is budget-dependent: diversity at very small budgets, first-N once the&lt;br&gt;
budget is large enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this means
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Data bytes and weight bits are separate budgets.&lt;/strong&gt; At 50 examples/class, better selection
can beat more bits; at 125+, first-N is already strong.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;4-bit weights are scheme-dependent.&lt;/strong&gt; Symmetric int4 survives on binary SMS but loses
12 points on 4-class AG News; a zero-point int4 recovers AG News to within 1.5 points of
int8 at half the weight bytes.&lt;/li&gt;
&lt;li&gt;The fixed 93.5% SMS artifact is the raw-int8 rule. The per-class scale is quantization
metadata, not part of inference; applying it changed the argmax and lowered the score.
&lt;code&gt;tests/test_sms_rule.py&lt;/code&gt; pins this.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I would try next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Per-feature scales or a bias correction for multiclass int4, instead of one scale per
class.&lt;/li&gt;
&lt;li&gt;A budget-aware selector that switches to TF-IDF diversity below ~50 examples/class.&lt;/li&gt;
&lt;li&gt;A cross-task sweep of symmetric vs zero-point int4 on more than two datasets.&lt;/li&gt;
&lt;li&gt;Cross-validation on the selection strategies; these numbers are one 400-row test.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything is one machine, one teacher-labelled AG News sample. The negative result is the&lt;br&gt;
point: minimum bits is not a single knob, and 4-bit is not automatically free.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repo: &lt;a href="https://github.com/byjameson/stream-finetune" rel="noopener noreferrer"&gt;https://github.com/byjameson/stream-finetune&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;130 KB AI: &lt;a href="https://byjameson-mini-ai.static.hf.space/mini-ai.html" rel="noopener noreferrer"&gt;https://byjameson-mini-ai.static.hf.space/mini-ai.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Maker (5-fold CV / calibration): &lt;a href="https://byjameson-mini-ai.static.hf.space/maker.html" rel="noopener noreferrer"&gt;https://byjameson-mini-ai.static.hf.space/maker.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Code: &lt;code&gt;research/int4_nb.py&lt;/code&gt;, &lt;code&gt;research/int4_affine.py&lt;/code&gt;,
&lt;code&gt;research/coreset_selection.py&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>opensource</category>
      <category>showdev</category>
    </item>
    <item>
      <title>AI in a MIDI file: the model is the notes</title>
      <dc:creator>mycute</dc:creator>
      <pubDate>Mon, 09 Nov 2026 18:34:26 +0000</pubDate>
      <link>https://dev.to/mycute_97b39c4e34027570f9/ai-in-a-midi-file-the-model-is-the-notes-2je1</link>
      <guid>https://dev.to/mycute_97b39c4e34027570f9/ai-in-a-midi-file-the-model-is-the-notes-2je1</guid>
      <description>&lt;h1&gt;
  
  
  AI in a MIDI file: the model is the notes
&lt;/h1&gt;

&lt;p&gt;The QR put the model in a URL. The favicon put it in pixels. The PDF put it in &lt;code&gt;/Keywords&lt;/code&gt;.&lt;br&gt;
This one puts it in &lt;strong&gt;note-on events&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The file is &lt;strong&gt;4,493 bytes&lt;/strong&gt;. The model is the same 160-word SMS spam classifier, 1,579&lt;br&gt;
bytes of int8 weights, &lt;strong&gt;93.54%&lt;/strong&gt; on 1,115 held-out SMS. It is packed into &lt;strong&gt;1,053 note-on&lt;br&gt;
events&lt;/strong&gt;: each event carries two ASCII characters, one in the note byte and one in the&lt;br&gt;
velocity byte. Together they are the base64url JSON of the model.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;midi.html&lt;/code&gt; parses the MIDI track, rebuilds the string and classifies. The first 128 notes&lt;br&gt;
are playable. The tune is the bytes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Demo: &lt;a href="https://byjameson-mini-ai.static.hf.space/midi.html" rel="noopener noreferrer"&gt;https://byjameson-mini-ai.static.hf.space/midi.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;MIDI: &lt;a href="https://byjameson-mini-ai.static.hf.space/model.mid" rel="noopener noreferrer"&gt;https://byjameson-mini-ai.static.hf.space/model.mid&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The size accounting
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;artifact&lt;/th&gt;
&lt;th&gt;bytes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;model JSON&lt;/td&gt;
&lt;td&gt;1,579&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MIDI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4,493&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;overhead (events, text meta, header)&lt;/td&gt;
&lt;td&gt;2,914&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;QR URL&lt;/td&gt;
&lt;td&gt;2,158&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;favicon PNG&lt;/td&gt;
&lt;td&gt;1,519&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WAV&lt;/td&gt;
&lt;td&gt;1,627&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PDF&lt;/td&gt;
&lt;td&gt;3,832&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SVG&lt;/td&gt;
&lt;td&gt;5,004&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The MIDI is larger than the QR/PNG/WAV because each base64 character becomes a note event&lt;br&gt;
with a status byte and a delta byte. It is still small enough to email or commit.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is in the file
&lt;/h2&gt;

&lt;p&gt;The track has five text meta events:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the title and the model description;&lt;/li&gt;
&lt;li&gt;the measured accuracy;&lt;/li&gt;
&lt;li&gt;a pointer to the viewer;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SHA256:&amp;lt;64 hex&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then 1,053 note-on events. The text meta events are readable in any MIDI tool; the note&lt;br&gt;
events are the payload. The header is format 0, one track, 96 ticks per quarter note.&lt;/p&gt;

&lt;p&gt;The page parses the events, collects &lt;code&gt;String.fromCharCode(note, velocity)&lt;/code&gt; pairs, base64&lt;br&gt;
decodes them and runs the int8 Complement NB. No server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a MIDI?
&lt;/h2&gt;

&lt;p&gt;Because it is an event file that every DAW and player already understands. It is not a&lt;br&gt;
rendered audio file; it is a sequence of events. The model travels in the event stream,&lt;br&gt;
and the file can still be opened and played. A MIDI renderer turns the notes into sound and&lt;br&gt;
throws the note bytes away — which is exactly the container trade.&lt;/p&gt;

&lt;p&gt;It is also a good stress test for the parser: variable-length delta times, meta events,&lt;br&gt;
running status, note-on/velocity. The file is small; the code is ordinary.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this is not
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Not an audio model.&lt;/strong&gt; The MIDI is not a voice or a song; it is data that can be played.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not a security proof.&lt;/strong&gt; The note events are inspectable. A MIDI file is a lossless
event container, not obfuscation. The SHA-256 is integrity, not a signature.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not robust to a DAW export.&lt;/strong&gt; A tool that quantizes, transposes, or renders to WAV can
change or drop the events. A byte copy is safe; a musical edit is not.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not a production spam filter.&lt;/strong&gt; One 80/20 split, 1,115 SMS, one machine.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The ladder now
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;SMS int8: &lt;strong&gt;1,579 bytes&lt;/strong&gt;, 93.5% on 1,115 rows;&lt;/li&gt;
&lt;li&gt;QR URL: 2,158 bytes;&lt;/li&gt;
&lt;li&gt;favicon: 1,519 bytes;&lt;/li&gt;
&lt;li&gt;WAV: 1,627 bytes;&lt;/li&gt;
&lt;li&gt;PDF: 3,832 bytes;&lt;/li&gt;
&lt;li&gt;SVG: 5,004 bytes;&lt;/li&gt;
&lt;li&gt;MIDI: 4,493 bytes;&lt;/li&gt;
&lt;li&gt;130 KB AG News coreset: a 178,761-byte PDF;&lt;/li&gt;
&lt;li&gt;1.7 MB linear model: 88.5% embedded / 91.0% fresh;&lt;/li&gt;
&lt;li&gt;5 MB adapter on a shared 4-bit base.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The behavior is the same. The container changes what travels with it and which tool can&lt;br&gt;
destroy it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MIDI demo: &lt;a href="https://byjameson-mini-ai.static.hf.space/midi.html" rel="noopener noreferrer"&gt;https://byjameson-mini-ai.static.hf.space/midi.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Survival matrix: &lt;a href="https://byjameson-mini-ai.static.hf.space/survival.html" rel="noopener noreferrer"&gt;https://byjameson-mini-ai.static.hf.space/survival.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Repo: &lt;a href="https://github.com/byjameson/stream-finetune" rel="noopener noreferrer"&gt;https://github.com/byjameson/stream-finetune&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>opensource</category>
      <category>showdev</category>
    </item>
    <item>
      <title>AI in an SVG: a 4.9 KB vector model card</title>
      <dc:creator>mycute</dc:creator>
      <pubDate>Mon, 09 Nov 2026 18:03:07 +0000</pubDate>
      <link>https://dev.to/mycute_97b39c4e34027570f9/ai-in-an-svg-a-49-kb-vector-model-card-1i15</link>
      <guid>https://dev.to/mycute_97b39c4e34027570f9/ai-in-an-svg-a-49-kb-vector-model-card-1i15</guid>
      <description>&lt;h1&gt;
  
  
  AI in an SVG: a 4.9 KB vector model card
&lt;/h1&gt;

&lt;p&gt;The PNG favicon put the model in pixels. The PDF put it in &lt;code&gt;/Keywords&lt;/code&gt;. The SVG puts it in&lt;br&gt;
&lt;code&gt;&amp;lt;metadata id="tinyai"&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is a &lt;strong&gt;5,004-byte&lt;/strong&gt; vector model card — 900×560, with a title, metrics and a short&lt;br&gt;
description. The 1,579-byte int8 SMS spam classifier is base64url JSON in the metadata, not&lt;br&gt;
drawn on the canvas. &lt;code&gt;svg.html&lt;/code&gt; fetches the raw XML, parses the &lt;code&gt;&amp;lt;metadata&amp;gt;&lt;/code&gt; element and&lt;br&gt;
runs the classifier in the browser. A full SHA-256 is in &lt;code&gt;data-sha256&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Demo: &lt;a href="https://byjameson-mini-ai.static.hf.space/svg.html" rel="noopener noreferrer"&gt;https://byjameson-mini-ai.static.hf.space/svg.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;SVG: &lt;a href="https://byjameson-mini-ai.static.hf.space/model-card.svg" rel="noopener noreferrer"&gt;https://byjameson-mini-ai.static.hf.space/model-card.svg&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It scores &lt;strong&gt;93.54%&lt;/strong&gt; on 1,115 held-out SMS messages.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why an SVG
&lt;/h2&gt;

&lt;p&gt;An SVG is a document and an image at the same time. It renders as a card in a browser, but&lt;br&gt;
the source is text/XML that any tool can read. The metadata travels with the picture, and&lt;br&gt;
the picture can be a proper model card instead of a wall of base64.&lt;/p&gt;

&lt;p&gt;The model is not drawn on the page. The visible card says what the model is, what it was&lt;br&gt;
trained on, how it scored and what it cannot do. The &lt;code&gt;&amp;lt;metadata&amp;gt;&lt;/code&gt; element carries the exact&lt;br&gt;
weights that produce the behaviour.&lt;/p&gt;
&lt;h2&gt;
  
  
  Size accounting
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;artifact&lt;/th&gt;
&lt;th&gt;bytes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;model JSON&lt;/td&gt;
&lt;td&gt;1,579&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SVG&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5,004&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;overhead (card text, vector layout, metadata wrapper)&lt;/td&gt;
&lt;td&gt;3,451&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;QR URL&lt;/td&gt;
&lt;td&gt;2,158&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;favicon PNG&lt;/td&gt;
&lt;td&gt;1,519&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WAV&lt;/td&gt;
&lt;td&gt;1,627&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PDF&lt;/td&gt;
&lt;td&gt;3,832&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;130 KB AG News PDF&lt;/td&gt;
&lt;td&gt;178,761&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The SVG is the most visually explicit container: the overhead is mostly the vector card&lt;br&gt;
itself, not the model. It is still under 5 KB.&lt;/p&gt;
&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;The build script starts from &lt;code&gt;demo/model.wav&lt;/code&gt; and writes the card and the metadata from the&lt;br&gt;
same JSON. The viewer parses the XML with &lt;code&gt;DOMParser&lt;/code&gt;, finds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;metadata&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"tinyai"&lt;/span&gt; &lt;span class="na"&gt;data-sha256=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;eyJsIjpbImhhbSIsInNwYW0iXSwidiI6...&lt;span class="nt"&gt;&amp;lt;/metadata&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;decodes the base64url, and runs the int8 Complement NB. No server, no weights endpoint.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this is not
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Not an LLM.&lt;/strong&gt; It is a bag-of-words classifier on English SMS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not a secure container.&lt;/strong&gt; The metadata is inspectable. An SVG is a lossless text
container, not obfuscation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not robust to every pipeline.&lt;/strong&gt; SVG is often sanitized for security. Stripping the
&lt;code&gt;&amp;lt;metadata&amp;gt;&lt;/code&gt; element removes the model; flattening the SVG to PNG also removes it. In the
survival matrix, a byte copy passes and a metadata strip fails; rasterization is not
measured.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not a production spam filter.&lt;/strong&gt; One 80/20 split, 1,115 rows, one machine.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The survival question
&lt;/h2&gt;

&lt;p&gt;SVG is the clearest example of the container trade. It is excellent for a web page or a&lt;br&gt;
README: the card renders and the model is one parse away. It is poor for a platform that&lt;br&gt;
sanitizes SVG or converts it to a raster image, which many do.&lt;/p&gt;

&lt;p&gt;The measured survival matrix now has 31 checks: 18 pass, 8 fail, 5 not measured. SVG adds&lt;br&gt;
one pass (byte copy) and one fail (metadata strip). The full matrix:&lt;br&gt;
&lt;a href="https://byjameson-mini-ai.static.hf.space/survival.html" rel="noopener noreferrer"&gt;https://byjameson-mini-ai.static.hf.space/survival.html&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The ladder so far
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;SMS int8 model: &lt;strong&gt;1,579 bytes&lt;/strong&gt;, 93.5% on 1,115 rows;&lt;/li&gt;
&lt;li&gt;QR URL: 2,158 bytes;&lt;/li&gt;
&lt;li&gt;favicon: 1,519 bytes;&lt;/li&gt;
&lt;li&gt;WAV: 1,627 bytes;&lt;/li&gt;
&lt;li&gt;PDF: 3,832 bytes;&lt;/li&gt;
&lt;li&gt;SVG: 5,004 bytes;&lt;/li&gt;
&lt;li&gt;130 KB AG News coreset: 178,761-byte PDF;&lt;/li&gt;
&lt;li&gt;1.7 MB linear model: 88.5% embedded / 91.0% fresh;&lt;/li&gt;
&lt;li&gt;5 MB adapter on a shared 4-bit base.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The model does not change. The container changes what travels with it and which pipeline&lt;br&gt;
can destroy it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SVG demo: &lt;a href="https://byjameson-mini-ai.static.hf.space/svg.html" rel="noopener noreferrer"&gt;https://byjameson-mini-ai.static.hf.space/svg.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Survival matrix: &lt;a href="https://byjameson-mini-ai.static.hf.space/survival.html" rel="noopener noreferrer"&gt;https://byjameson-mini-ai.static.hf.space/survival.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Repo: &lt;a href="https://github.com/byjameson/stream-finetune" rel="noopener noreferrer"&gt;https://github.com/byjameson/stream-finetune&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>opensource</category>
      <category>showdev</category>
    </item>
    <item>
      <title>The 130 KB AI is a 175 KB PDF</title>
      <dc:creator>mycute</dc:creator>
      <pubDate>Mon, 09 Nov 2026 17:59:01 +0000</pubDate>
      <link>https://dev.to/mycute_97b39c4e34027570f9/the-130-kb-ai-is-a-175-kb-pdf-1lmd</link>
      <guid>https://dev.to/mycute_97b39c4e34027570f9/the-130-kb-ai-is-a-175-kb-pdf-1lmd</guid>
      <description>&lt;h1&gt;
  
  
  The 130 KB AI is a 175 KB PDF
&lt;/h1&gt;

&lt;p&gt;The 1,579-byte SMS model was the small end of the container ladder: a 3.7 KB PDF whose&lt;br&gt;
metadata carried the int8 weights. The other end is the 130 KB AG News coreset.&lt;/p&gt;

&lt;p&gt;This PDF is &lt;strong&gt;178,761 bytes&lt;/strong&gt;. The visible page is a model card. The model is &lt;strong&gt;132,798&lt;br&gt;
bytes&lt;/strong&gt; of JSON — 500 AG News examples, 125 per class — stored as base64url in the&lt;br&gt;
&lt;code&gt;/TinyAIData&lt;/code&gt; metadata. &lt;code&gt;pdf-130k.html&lt;/code&gt; fetches the raw PDF, parses that string, trains the&lt;br&gt;
same Complement Naive Bayes in the browser and classifies. No server, no weights endpoint.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Demo: &lt;a href="https://byjameson-mini-ai.static.hf.space/pdf-130k.html" rel="noopener noreferrer"&gt;https://byjameson-mini-ai.static.hf.space/pdf-130k.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PDF: &lt;a href="https://byjameson-mini-ai.static.hf.space/model-card-130k.pdf" rel="noopener noreferrer"&gt;https://byjameson-mini-ai.static.hf.space/model-card-130k.pdf&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The 500-example coreset scores &lt;strong&gt;78.3%&lt;/strong&gt; on the embedded 400-row AG News test and &lt;strong&gt;74.3%&lt;/strong&gt;&lt;br&gt;
on a fresh sample. The tests were measured in &lt;code&gt;mini-ai.html&lt;/code&gt;; the PDF viewer does not claim&lt;br&gt;
a live accuracy because the 400 test rows are not embedded.&lt;/p&gt;

&lt;h2&gt;
  
  
  The size accounting
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;item&lt;/th&gt;
&lt;th&gt;bytes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;training data (500 examples)&lt;/td&gt;
&lt;td&gt;132,798&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;base64 in &lt;code&gt;/TinyAIData&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;177,064 chars&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PDF&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;178,761&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;overhead (page, base64, structure)&lt;/td&gt;
&lt;td&gt;45,963&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;400-row test set&lt;/td&gt;
&lt;td&gt;not embedded&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Compare with the 1,579-byte SMS model:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;artifact&lt;/th&gt;
&lt;th&gt;model bytes&lt;/th&gt;
&lt;th&gt;container bytes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SMS int8 PDF&lt;/td&gt;
&lt;td&gt;1,579&lt;/td&gt;
&lt;td&gt;3,832&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AG News coreset PDF&lt;/td&gt;
&lt;td&gt;132,798&lt;/td&gt;
&lt;td&gt;178,761&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The PDF overhead is similar in absolute terms per page; the difference is that the coreset&lt;br&gt;
is 84× larger. The base64 expansion is what makes the PDF roughly 1.35× the data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why put the data in a PDF?
&lt;/h2&gt;

&lt;p&gt;The PDF is a document people already send to each other. It has a visible page for humans&lt;br&gt;
and metadata for tools. The page can say what the model is and what it cannot do; the&lt;br&gt;
metadata can carry the exact examples that produce the behaviour. One file is the card and&lt;br&gt;
the model.&lt;/p&gt;

&lt;p&gt;It is also a useful stress test: a 177 KB metadata string, a 175 KB PDF, a browser parser&lt;br&gt;
and a 500-row training run. It works. A PDF is lossless; the bytes that go in are the bytes&lt;br&gt;
that come out.&lt;/p&gt;

&lt;p&gt;The model is the data artifact. It is not a set of weights. There is no int8 quantization&lt;br&gt;
here; the viewer trains the classifier when it loads. That is the same recipe as the 130 KB&lt;br&gt;
browser AI.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this is not
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Not an LLM.&lt;/strong&gt; It is a bag-of-words Complement NB on English news headlines.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not a security proof.&lt;/strong&gt; The metadata is inspectable. A PDF is a lossless container, not
obfuscation. The SHA-256 detects a changed file; it is not a signature.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not a live benchmark.&lt;/strong&gt; The viewer classifies; the 78.3/74.3 numbers come from the
400-row test in &lt;code&gt;mini-ai.html&lt;/code&gt;, not from a hidden test set.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not indestructible.&lt;/strong&gt; PDF editors can rewrite or drop metadata. The survival matrix
shows what happens: a &lt;code&gt;pypdf&lt;/code&gt; rewrite keeps it; rebuilding without Info loses it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Teacher labels.&lt;/strong&gt; The 500 examples were labeled by a 1.5B model; the 1.7 MB linear model
on 75,000 human labels is the accuracy mode.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The representation ladder
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;a prompt: a few hundred bytes plus a shared base;&lt;/li&gt;
&lt;li&gt;the SMS int8 model: 1,579 bytes, 93.5% on 1,115 rows;&lt;/li&gt;
&lt;li&gt;the AG News coreset: 132,798 bytes, 78.3% embedded / 74.3% fresh;&lt;/li&gt;
&lt;li&gt;the 1.7 MB linear model: 88.5% embedded / 91.0% fresh on human labels;&lt;/li&gt;
&lt;li&gt;a 5 MB adapter on a shared 4-bit base.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The PDF does not change the model. It changes where the model can live and what travels&lt;br&gt;
with it: the card, the examples and a checksum in one 175 KB file.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;130 KB PDF: &lt;a href="https://byjameson-mini-ai.static.hf.space/pdf-130k.html" rel="noopener noreferrer"&gt;https://byjameson-mini-ai.static.hf.space/pdf-130k.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;130 KB browser AI: &lt;a href="https://byjameson-mini-ai.static.hf.space/mini-ai.html" rel="noopener noreferrer"&gt;https://byjameson-mini-ai.static.hf.space/mini-ai.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;SMS PDF: &lt;a href="https://byjameson-mini-ai.static.hf.space/pdf.html" rel="noopener noreferrer"&gt;https://byjameson-mini-ai.static.hf.space/pdf.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Survival: &lt;a href="https://byjameson-mini-ai.static.hf.space/survival.html" rel="noopener noreferrer"&gt;https://byjameson-mini-ai.static.hf.space/survival.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Repo: &lt;a href="https://github.com/byjameson/stream-finetune" rel="noopener noreferrer"&gt;https://github.com/byjameson/stream-finetune&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>webdev</category>
      <category>showdev</category>
    </item>
    <item>
      <title>One split said 70%. Five folds said 57%.</title>
      <dc:creator>mycute</dc:creator>
      <pubDate>Mon, 09 Nov 2026 17:54:46 +0000</pubDate>
      <link>https://dev.to/mycute_97b39c4e34027570f9/one-split-said-70-five-folds-said-57-4nhc</link>
      <guid>https://dev.to/mycute_97b39c4e34027570f9/one-split-said-70-five-folds-said-57-4nhc</guid>
      <description>&lt;h1&gt;
  
  
  One split said 70%. Five folds said 57%.
&lt;/h1&gt;

&lt;p&gt;Tiny AI Maker trains a small text classifier in the browser. Until this week it reported one&lt;br&gt;
number: accuracy on a single 80/20 split. That number is easy to read and easy to over-trust.&lt;/p&gt;

&lt;p&gt;The AG News sample in the Maker is 200 rows, 40 per class. On one split it scores &lt;strong&gt;70.0%&lt;/strong&gt;&lt;br&gt;
(95% Wilson interval 54.6–81.9%). That looks like a usable four-class classifier.&lt;/p&gt;

&lt;p&gt;Then I ran a 5-fold cross-validation on the same 200 rows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;mean: &lt;strong&gt;57.0%&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;fold std: &lt;strong&gt;5.7 pp&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;range: &lt;strong&gt;47.5–62.5%&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;gap vs the single holdout: &lt;strong&gt;13.0 pp lower&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The single split was optimistic. Not because the code cheated, but because a 40-row test set&lt;br&gt;
is a lottery. The CV number is not a confidence interval and the folds share data, but it is&lt;br&gt;
a much better description of what this 200-row sample supports.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stable case
&lt;/h2&gt;

&lt;p&gt;The SMS spam sample is the opposite. It is 100 rows, balanced, and the same recipe scores:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;80/20 holdout: &lt;strong&gt;90.0%&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;5-fold CV: &lt;strong&gt;90.0%&lt;/strong&gt; mean, 7.1 pp fold std, range 85–100%&lt;/li&gt;
&lt;li&gt;no gap between the two estimates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Small data can be stable when the task is narrow and the classes are easy. The point is not&lt;br&gt;
that CV always lowers the score; it is that you cannot know from one split.&lt;/p&gt;

&lt;h2&gt;
  
  
  Calibration: the softmax is not a probability
&lt;/h2&gt;

&lt;p&gt;The Maker now collects out-of-fold probabilities during CV and reports two calibration&lt;br&gt;
numbers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Brier score:&lt;/strong&gt; mean squared error of the probability vector. Lower is better.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ECE:&lt;/strong&gt; expected calibration error over 10 confidence bins. Lower is better.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the AG News sample: &lt;strong&gt;Brier 0.523, ECE 0.139&lt;/strong&gt;. The four-class model is not calibrated.&lt;br&gt;
For the SMS sample: &lt;strong&gt;Brier 0.144, ECE 0.066&lt;/strong&gt;. Better, but still not a guarantee: 79 of the&lt;br&gt;
100 predictions land in the 0.9–1.0 confidence bin, where the mean confidence is 98.9% and&lt;br&gt;
the accuracy is 96.2%. The model is slightly overconfident even on the easy task.&lt;/p&gt;

&lt;p&gt;Neither number is a production calibration claim. With 100–200 rows the bins are noisy.&lt;br&gt;
They are there to stop the UI from presenting &lt;code&gt;softmax&lt;/code&gt; as if it were a measured&lt;br&gt;
probability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Can temperature scaling fix it?
&lt;/h2&gt;

&lt;p&gt;A single temperature is fit nested out-of-fold: for each fold, T is chosen on the other&lt;br&gt;
folds' predictions, then applied to the held-out fold. This is a measurement, not a new&lt;br&gt;
export format.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SMS: median T &lt;strong&gt;1.5&lt;/strong&gt;; ECE &lt;strong&gt;0.066 → 0.032&lt;/strong&gt;; Brier &lt;strong&gt;0.144 → 0.143&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;AG News: median T &lt;strong&gt;1.5&lt;/strong&gt;; ECE &lt;strong&gt;0.139 → 0.074&lt;/strong&gt;; Brier &lt;strong&gt;0.523 → 0.503&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It helps, but it does not rescue the four-class model: Brier 0.503 is still high, and the&lt;br&gt;
labels do not change with temperature. The exported int8 weights are unchanged. The Maker&lt;br&gt;
page applies the median T to its on-page probability bars after CV; the exports stay&lt;br&gt;
uncalibrated.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed in the Maker
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;An optional &lt;strong&gt;5-fold CV&lt;/strong&gt; button. Folds are stratified by label; k is capped by the
smallest label so tiny datasets do not fail silently.&lt;/li&gt;
&lt;li&gt;The CV uses the selected budget, so it measures the recipe you will export, not a
different model.&lt;/li&gt;
&lt;li&gt;The result shows the fold table, the mean, the fold std, the range, and the gap against
the 80/20 holdout.&lt;/li&gt;
&lt;li&gt;Calibration is measured out-of-fold with Brier/ECE and a reliability-bin table.&lt;/li&gt;
&lt;li&gt;A nested temperature fit reports whether a single T lowers ECE/Brier; it is not applied
to the exports.&lt;/li&gt;
&lt;li&gt;The markdown model card and the PDF model card include the same numbers, or explicitly
omit the CV section if you did not run it.&lt;/li&gt;
&lt;li&gt;The exported model is still the 80/20 fit. The card says so.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What this does not prove
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;CV folds are not independent samples; the fold std is a stability check, not a confidence
interval.&lt;/li&gt;
&lt;li&gt;ECE is sensitive to binning and sample size. With 200 rows, treat it as a warning sign.&lt;/li&gt;
&lt;li&gt;The AG News sample is teacher-labeled and small; the 1.7 MB accuracy mode is the model to
quote for AG News, not this sample.&lt;/li&gt;
&lt;li&gt;One machine, one seed for the 80/20 split, no hyperparameter search.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why show the worse number?
&lt;/h2&gt;

&lt;p&gt;Because the artifact is the claim. A 200-row classifier that says 70% on one split and 57%&lt;br&gt;
on five folds is still useful as a demo, a teaching tool, and a container experiment. It is&lt;br&gt;
not useful as a silent 70%.&lt;/p&gt;

&lt;p&gt;The size story does not change: the 1,579-byte SMS model is still 93.5% on its 1,115-row&lt;br&gt;
holdout, and the containers still fit in a QR, a favicon, a WAV and a 3.7 KB PDF. The&lt;br&gt;
measurement story does: report the split you ran, the CV you ran, and the gap between them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Maker: &lt;a href="https://byjameson-mini-ai.static.hf.space/maker.html" rel="noopener noreferrer"&gt;https://byjameson-mini-ai.static.hf.space/maker.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Container survival: &lt;a href="https://byjameson-mini-ai.static.hf.space/survival.html" rel="noopener noreferrer"&gt;https://byjameson-mini-ai.static.hf.space/survival.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PDF model card: &lt;a href="https://byjameson-mini-ai.static.hf.space/pdf.html" rel="noopener noreferrer"&gt;https://byjameson-mini-ai.static.hf.space/pdf.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Repo: &lt;a href="https://github.com/byjameson/stream-finetune" rel="noopener noreferrer"&gt;https://github.com/byjameson/stream-finetune&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you run the AG sample in the Maker, you should get the same 70.0 / 57.0 split. If you&lt;br&gt;
get something different, the seed or the sample changed; the card is generated from the run,&lt;br&gt;
so it will show your numbers, not mine.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>opensource</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
