<?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: LYR</title>
    <description>The latest articles on DEV Community by LYR (@lyr).</description>
    <link>https://dev.to/lyr</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%2F4058861%2F41d0a270-81b9-4d51-b794-a2c098e16e73.png</url>
      <title>DEV Community: LYR</title>
      <link>https://dev.to/lyr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lyr"/>
    <language>en</language>
    <item>
      <title>Are you still picking that setting by gut feel?</title>
      <dc:creator>LYR</dc:creator>
      <pubDate>Mon, 03 Aug 2026 14:29:52 +0000</pubDate>
      <link>https://dev.to/lyr/are-you-still-picking-that-setting-by-gut-feel-27lj</link>
      <guid>https://dev.to/lyr/are-you-still-picking-that-setting-by-gut-feel-27lj</guid>
      <description>&lt;p&gt;&lt;strong&gt;See the shape of the curve, not a single point — the habit called Sweep&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Thresholds, image resolutions, batch sizes — most of them get picked by gut feel. Try one or two, take whichever looks better.&lt;/p&gt;

&lt;p&gt;The moment verification got cheap, I stopped deciding that way. Instead of picking a single point, I &lt;strong&gt;sweep the range end to end and look at the shape of the curve&lt;/strong&gt;. The sweet spot, the knee, the cliff — none of them show up until you measure the shape. A single point tells you nothing about the shape.&lt;/p&gt;

&lt;p&gt;And whether you can sweep at all comes down to how cheap verification is. When one run is expensive, people fall back on gut feel. &lt;strong&gt;Make verification cheap first&lt;/strong&gt; — that comes before anything else.&lt;/p&gt;

&lt;p&gt;Engineering is full of &lt;strong&gt;magic numbers&lt;/strong&gt; (concrete values sitting in the code with no clear justification behind them). Thresholds, image resolution, batch size, timeouts. How do you decide those values? To be honest — mostly, by gut. You try one or two at best and take whichever looks better.&lt;/p&gt;

&lt;p&gt;When &lt;a href="https://lyr.jp/en/articles/06-you-are-the-bottleneck/" rel="noopener noreferrer"&gt;the harness made verification cheaper by an order of magnitude&lt;/a&gt;, I stopped deciding this way. Instead of picking one point, I started to &lt;strong&gt;sweep the range end to end and look at the shape of the curve&lt;/strong&gt;. That is a Sweep.&lt;/p&gt;

&lt;h2&gt;
  
  
  A curve shows you what a single point can't
&lt;/h2&gt;

&lt;p&gt;Take the image resolution used when OCR detects text. "Higher resolution means higher accuracy" — that's what intuition says. So if you're going by gut, you pick the higher one without hesitating.&lt;/p&gt;

&lt;p&gt;But when I varied the resolution across a range and measured accuracy (CER, lower is better) and speed together, this is the curve that came out.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Resolution&lt;/th&gt;
&lt;th&gt;Error rate (CER, lower is better)&lt;/th&gt;
&lt;th&gt;Speed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;960&lt;/td&gt;
&lt;td&gt;9.4%&lt;/td&gt;
&lt;td&gt;75 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;736&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;10.7%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;40 ms&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;480&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;35% (collapse)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;18 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyzk956fbkerdsnkkme9r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyzk956fbkerdsnkkme9r.png" alt="Resolution sweep for OCR detection: latency on the x-axis, CER (error rate) on the y-axis. 736 is the sweet spot for speed and accuracy; CER spikes at 480" width="800" height="576"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 1: resolution sweep for OCR detection.&lt;/strong&gt; Latency on the x-axis, error rate on the y-axis. 736 is the sweet spot for speed and accuracy: against 960 it trades +1.3pt of error rate for half the latency. Drop all the way to 480 and the error rate spikes into collapse.&lt;br&gt;
&lt;em&gt;Note: n=6, a small sample = a directional check.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The middle one, &lt;strong&gt;736, was the obvious "sweet spot."&lt;/strong&gt; Against 960, the error rate goes up by a mere 1.3 points (9.4% → 10.7%), and &lt;strong&gt;the speed halves&lt;/strong&gt;. Drop to 480, on the other hand, and accuracy collapses (the error rate goes from 10.7% to 35% — &lt;strong&gt;more than tripling&lt;/strong&gt;). The bend in the curve — the knee — sits exactly at 736.&lt;/p&gt;

&lt;p&gt;Had I picked 960 by gut, I'd have gone on paying double the time for a sliver of accuracy. Had I picked 480, the text wouldn't be readable at all. &lt;strong&gt;This sweet spot only became visible once I measured both ends and the middle.&lt;/strong&gt; Measure a single point and you will never find it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Curves have a "knee"
&lt;/h2&gt;

&lt;p&gt;There's one more thing only a curve will show you: the &lt;strong&gt;knee&lt;/strong&gt; — the bend past which doing more barely improves anything.&lt;/p&gt;

&lt;p&gt;When I swept how quality rises as you add more training data, reading-comprehension accuracy on the difficult cases went &lt;strong&gt;flat past a certain amount of data (a very small amount)&lt;/strong&gt;. However much data you add, the hard cases don't improve. Past the knee, the investment is wasted — a signal that a different lever (&lt;a href="https://lyr.jp/en/articles/specialist-02-fine-tuning/" rel="noopener noreferrer"&gt;the model's capacity&lt;/a&gt;) was what it needed.&lt;/p&gt;

&lt;p&gt;This too is invisible from one or two points. Only when you draw the curve do you see the boundary where "nothing beyond here works."&lt;/p&gt;

&lt;h2&gt;
  
  
  Why sweeping is possible now
&lt;/h2&gt;

&lt;p&gt;Sweep is an old idea. But maybe not that many people do it thoroughly in practice. The reason is simple: &lt;strong&gt;it's expensive&lt;/strong&gt;. Trying eleven thresholds by hand means eleven verification runs. That's a number of runs that makes you question your sanity.&lt;/p&gt;

&lt;p&gt;What changed is that the &lt;a href="https://lyr.jp/en/articles/06-you-are-the-bottleneck/" rel="noopener noreferrer"&gt;harness&lt;/a&gt; &lt;strong&gt;took the human out of&lt;/strong&gt; verification. Once you've baked the frame sequence to disk, you can run eleven configurations &lt;strong&gt;in parallel, with zero manual work&lt;/strong&gt;. Where a person used to hold the device and record once per configuration, everything now runs in one batch. &lt;strong&gt;The moment verification got cheap, "sweep a surface and look at the shape" became more reliable and better value than "pick one point by gut."&lt;/strong&gt; Sweep was the first use I found for the slack the harness created.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Don't set magic numbers by gut.&lt;/strong&gt; Thresholds, resolution, batch size — most of the time there's no reason why the value is that particular number.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sweep the range and look at the curve, not one point.&lt;/strong&gt; The sweet spot and the cliff only become visible once you measure the whole shape. The &lt;strong&gt;knee&lt;/strong&gt; especially — the bend where "nothing beyond here works" — is the signal to move to a different lever.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Whether you can sweep comes down to how cheap verification is.&lt;/strong&gt; When a single verification run is expensive, people fall back on gut feel. Make verification cheap first. Then sweeping becomes the obvious thing to do.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Next time: what you see when you read that cloud of swept points against several objectives at once (speed × accuracy × cost) — on to &lt;a href="https://lyr.jp/en/articles/pareto-01-the-frontier/" rel="noopener noreferrer"&gt;Pareto&lt;/a&gt;. Sweeping and reading the frontier are two sides of the same coin.&lt;/p&gt;




&lt;h3&gt;
  
  
  Appendix: raw data
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Sweep&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;th&gt;Conditions &amp;amp; caveats&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Resolution for OCR detection&lt;/td&gt;
&lt;td&gt;960 = error rate 9.4% / 75ms, &lt;strong&gt;736 = 10.7% / 40ms (sweet spot)&lt;/strong&gt;, 480 = 35% / 18ms (box detection collapses)&lt;/td&gt;
&lt;td&gt;Portrait orientation, JA+EN, n=6 small sample = a directional check&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Input dimensions of the text-recognition model&lt;/td&gt;
&lt;td&gt;128×480 is Pareto-best across every dataset&lt;/td&gt;
&lt;td&gt;3 datasets × 7 dimensions. The others either flicker or make timing worse&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The knee in data volume&lt;/td&gt;
&lt;td&gt;Comprehension on the hard cases goes flat past N≲25&lt;/td&gt;
&lt;td&gt;Capacity, not more data, is the rate limiter. The knee was visible because I swept&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Preprocessing width&lt;/td&gt;
&lt;td&gt;The width that's optimal for short subtitles (&lt;strong&gt;Live&lt;/strong&gt;) collapses when used on long lines (&lt;strong&gt;Page&lt;/strong&gt;)&lt;/td&gt;
&lt;td&gt;One fixed value breaks another mode = the optimum is mode-dependent&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://lyr.jp/en/articles/sweep-01-see-the-curve/" rel="noopener noreferrer"&gt;LYR Performance Note #021&lt;/a&gt; — part of the series “Measure &amp;amp; tune — measure it right, then fit the settings”. The full set is at &lt;a href="https://lyr.jp/en/research/" rel="noopener noreferrer"&gt;lyr.jp/en/research&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>performance</category>
      <category>testing</category>
      <category>machinelearning</category>
      <category>ai</category>
    </item>
    <item>
      <title>A general-purpose model is too wasteful a vessel for subtitles</title>
      <dc:creator>LYR</dc:creator>
      <pubDate>Mon, 03 Aug 2026 14:28:50 +0000</pubDate>
      <link>https://dev.to/lyr/a-general-purpose-model-is-too-wasteful-a-vessel-for-subtitles-2cjo</link>
      <guid>https://dev.to/lyr/a-general-purpose-model-is-too-wasteful-a-vessel-for-subtitles-2cjo</guid>
      <description>&lt;p&gt;&lt;strong&gt;A floor compression couldn't fill — the next thing to cut isn't parameters, it's generality&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My own model with no compression applied at all — raw, 8 billion parameters (8B) — still left 15 critical mistranslations out of 97. On the same hard cases, a general-purpose model more than three times bigger (27 billion = 27B) had 4.&lt;/strong&gt; No matter how I varied the strength of the compression, those 15 didn't move.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd7yjj0um6lpktd4qwru6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd7yjj0um6lpktd4qwru6.png" alt="Number of critical errors on 97 Korean-to-Japanese hard cases. The self-hosted 8B has 14 with medium compression and 15 raw with no compression, so it does not move with or without compression. The general-purpose 27B has 4, and the difference from the uncompressed 8B is significant at p=0.015." width="799" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 1: taking compression all the way off didn't bring the floor back (97 Korean→Japanese hard cases, blind).&lt;/strong&gt; The self-hosted 8B had 15 critical errors even raw, with no compression at all — statistically indistinguishable from medium compression (14), and from heavy compression too. The general-purpose 27B, meanwhile, had 4 — significantly fewer than the raw 8B (p=0.015).&lt;br&gt;
&lt;em&gt;Note: judged blind by a large model from a different family, in the same round. Effective n=97 after excluding items suspected of overlapping the training data. The counts are critical errors only (subject and meaning mix-ups and the like — translations that don't work as a subtitle), not average quality. The three compression levels are INT4 / INT8 / BF16 (= no compression), in that order. The difference between heavy compression and raw was also not significant (p=0.22).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So the thing setting this &lt;strong&gt;floor&lt;/strong&gt; — where the worst case bottoms out — was &lt;strong&gt;the model's size (capacity), not the compression&lt;/strong&gt;. Every time quality fell apart, I had suspected compression first, and acted on it — the clearest case being &lt;a href="https://lyr.jp/en/articles/specialist-06-ceiling-vs-floor/" rel="noopener noreferrer"&gt;smoothing out compression error with a repair called rotation, which took catastrophic failures from 64% to 24%&lt;/a&gt;. That line of attack died here.&lt;/p&gt;

&lt;p&gt;But before falling back on "make it bigger," there's one more suspect: &lt;strong&gt;the vessel (the architecture) itself&lt;/strong&gt;. Subtitling is a job of short sentences, tight constraints and bounded context — and yet we're using, as-is, a general-purpose LLM designed for free generation of arbitrary length. The hypothesis: &lt;strong&gt;cut the waste that generality costs, and a smaller model than today's should produce better subtitles than today's&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And what I'm after isn't only speed. What LYR is aiming at is &lt;strong&gt;the experience of subtitles at the level a professional human translator would produce, running over the video you're watching right now&lt;/strong&gt;. Professional quality itself is available — if you wait. But that wait stacks up: booking a translator, a rough pass, proofreading, timing, rights clearance — &lt;strong&gt;weeks after release, and for some titles months&lt;/strong&gt;. And — &lt;strong&gt;by far the bigger share is work that never gets translated into your language at all&lt;/strong&gt;. Professional subtitles only get made for the languages and titles where the economics work, so for a lot of people "wait and you'll get it" isn't even on the table. Which leaves the viewer choosing between not watching when they want to and settling for crude automatic subtitles. Real time, on the other hand, is available right now — if you give up on quality. &lt;strong&gt;It only becomes magic when both hold at once.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So what I'm watching are two things: the note a native speaker gave me — "the meaning comes through, but the emotion is stiff" — and the speaker's gender, obvious from one look at the screen and impossible to recover from the source text. &lt;strong&gt;My read is that these two only come within reach once you change the vessel.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let me be honest about this. This piece isn't a record of measurements; it's a &lt;strong&gt;design hypothesis&lt;/strong&gt;. I have a reasonable read on the architecture, but I have no data points on my own language pairs yet. So at the end I'll also write down what result would make me throw the hypothesis away.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where things stand — out of borrowed AI, and small and fast as far as that goes
&lt;/h2&gt;

&lt;p&gt;The setup, briefly. LYR is &lt;strong&gt;a product that translates text on your phone in real time&lt;/strong&gt;. It gets used three ways — &lt;strong&gt;Live&lt;/strong&gt;, translating the subtitles running across a video one line at a time; &lt;strong&gt;Page&lt;/strong&gt;, translating the text on the screen in one batch; &lt;strong&gt;Manga&lt;/strong&gt;, translating the dialogue in comic panels. One and the same translation model does double duty across all three.&lt;/p&gt;

&lt;p&gt;With that, let me fold the road so far into one paragraph — with the caveat that &lt;strong&gt;this article is only about the model&lt;/strong&gt;. In practice, most of the speed and cost came out of things &lt;em&gt;outside&lt;/em&gt; the model — queues, distance, on-device processing, the number of calls themselves — and in plenty of cases those mattered more (I'll leave them to the &lt;a href="https://lyr.jp/en/research#series-deep-dive" rel="noopener noreferrer"&gt;infrastructure&lt;/a&gt; and &lt;a href="https://lyr.jp/en/research#series-edge-ocr" rel="noopener noreferrer"&gt;OCR&lt;/a&gt; categories). Here I trace just &lt;strong&gt;one layer, the model&lt;/strong&gt;, straight down.&lt;/p&gt;

&lt;p&gt;Restricted to the model, the first step was &lt;strong&gt;lining up third-party translation APIs side by side and picking the fast one&lt;/strong&gt; (&lt;a href="https://lyr.jp/en/articles/03-model-disqualified/" rel="noopener noreferrer"&gt;some AI gets disqualified before you ever measure quality&lt;/a&gt;). Then I hit the wall that &lt;a href="https://lyr.jp/en/articles/04-borrowed-ai-disappears/" rel="noopener noreferrer"&gt;borrowed AI disappears through retirement and price increases&lt;/a&gt;, and &lt;a href="https://lyr.jp/en/articles/05-owning-your-ai-economics/" rel="noopener noreferrer"&gt;moved to my own GPU&lt;/a&gt;. From there I confirmed that &lt;a href="https://lyr.jp/en/articles/specialist-01-quantization/" rel="noopener noreferrer"&gt;compressing to a quarter barely costs any smarts&lt;/a&gt;, and pinned down that &lt;a href="https://lyr.jp/en/articles/specialist-11-decode-bytes/" rel="noopener noreferrer"&gt;what decides generation speed isn't the parameter count but the byte count of the weights&lt;/a&gt;. On the quality side, I &lt;a href="https://lyr.jp/en/articles/specialist-02-fine-tuning/" rel="noopener noreferrer"&gt;took an un-fine-tuned small model from 42% to 84%&lt;/a&gt;, and got to where &lt;a href="https://lyr.jp/en/articles/specialist-09-live-specialization/" rel="noopener noreferrer"&gt;narrowing to the single point of Live subtitles lets an 8B draw level with a 27B&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So "&lt;strong&gt;you don't need a general-purpose giant; for one trick, a small model is enough&lt;/strong&gt;" is already partly demonstrated. This article is about what comes after that. &lt;strong&gt;Can I push that narrowing to one trick past the training data, all the way into the vessel (the architecture)?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The hypothesis — foundation models are too multi-task for subtitles
&lt;/h2&gt;

&lt;p&gt;Today's LLMs write poetry, write code, do math. To be that general-purpose, they're built to &lt;strong&gt;emit text of any length in any format&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The subtitle job is the exact opposite.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What a general-purpose LLM assumes&lt;/th&gt;
&lt;th&gt;What the subtitle job actually is&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Output length is free (a few words to dozens of pages)&lt;/td&gt;
&lt;td&gt;1–2 lines. Bound to a length that fits the display time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Output format is free&lt;/td&gt;
&lt;td&gt;The format is fixed. Return the translation, nothing else&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Context can be made as long as you like&lt;/td&gt;
&lt;td&gt;Only the few utterances either side&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A response can take seconds&lt;/td&gt;
&lt;td&gt;Real time, keeping up with the speech&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Solve any task in the world&lt;/td&gt;
&lt;td&gt;Produce one translation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I call this mismatch &lt;strong&gt;the generality tax&lt;/strong&gt;. You pay it in two ways.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First, you pay it as wasted data reads.&lt;/strong&gt; Every time the model emits one character, it re-reads its own insides (the weights = a vast pile of numbers) in full. That's why generation speed is decided not by how heavy the computation is but by &lt;strong&gt;how much data gets read&lt;/strong&gt; (&lt;a href="https://lyr.jp/en/articles/specialist-11-decode-bytes/" rel="noopener noreferrer"&gt;generation speed is decided by the byte count of the weights&lt;/a&gt;). The numbers that exist for poetry and code and math get read out too, on every single character of subtitle. &lt;strong&gt;You're paying freight, on every character, for abilities you never use.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second, you pay it as a forced choice between speed and quality.&lt;/strong&gt; As things stand, pick a fast model and the translation gets rough; pick an accurate one and it gets slow. That exchange rate looks immovable. But it isn't a law that comes with the subtitle job. &lt;strong&gt;It's just that the general-purpose vessel we happen to be using sits on that particular rate.&lt;/strong&gt; Change the vessel and there's room for the rate itself to change (&lt;a href="https://lyr.jp/en/articles/pareto-01-the-frontier/" rel="noopener noreferrer"&gt;the Pareto view&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;I don't think this is LYR's problem alone. Now that the "drop a foundation model into the product as-is" phase has gone around once, &lt;strong&gt;recutting the vessel per use case&lt;/strong&gt; ought to be ground a lot of teams are stepping onto at the same time. I'm looking at it from the single vantage point of subtitles.&lt;/p&gt;

&lt;h2&gt;
  
  
  But "smaller at the same quality" isn't unconditional — two counterexamples
&lt;/h2&gt;

&lt;p&gt;Let me put the measurements that are inconvenient for the hypothesis first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Counterexample 1: specialization is a reallocation, not a free lunch.&lt;/strong&gt; The same training that took Live (video subtitles) from a 90 to a 96 success rate knocked the other two — Page (whole-screen batch translation) and Manga (dialogue in comic panels) — down by 4 each (&lt;a href="https://lyr.jp/en/articles/specialist-09-live-specialization/" rel="noopener noreferrer"&gt;A small specialist drew level with the strongest model in service&lt;/a&gt;; the mechanism is &lt;a href="https://lyr.jp/en/articles/measure-07-mode-mixing/" rel="noopener noreferrer"&gt;mode mixing&lt;/a&gt;). As long as one vessel does double duty across several jobs, whatever you gain has been carved out of somewhere else.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Counterexample 2: there's a layer specialization can't fill.&lt;/strong&gt; Handing the model perfect context didn't fill in deep comprehension (&lt;a href="https://lyr.jp/en/articles/specialist-05-context-vs-capacity/" rel="noopener noreferrer"&gt;"add context and it gets smarter" was half a lie&lt;/a&gt;), and comprehending dropped subjects and idioms in Japanese demanded capacity itself (&lt;a href="https://lyr.jp/en/articles/specialist-07-low-resource/" rel="noopener noreferrer"&gt;spotting the rate limiter in the language you're worst at&lt;/a&gt;). "Fixable by polishing" problems and "needs capacity" problems are different animals.&lt;/p&gt;

&lt;p&gt;So the question becomes: &lt;strong&gt;of the gap that remains, how much is capacity, and where does the generality tax start?&lt;/strong&gt; Saying "change the vessel and everything gets better" with the two still mixed together is &lt;a href="https://lyr.jp/en/articles/specialist-03-quant-mismatch/" rel="noopener noreferrer"&gt;giving up on diagnosis&lt;/a&gt;. So I separated them first.&lt;/p&gt;

&lt;h2&gt;
  
  
  The verdict — the floor was capacity, not quantization
&lt;/h2&gt;

&lt;p&gt;The first move in separating them was &lt;strong&gt;ruling quantization out as a suspect&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;First, quantization in one line. The insides of an AI model are a vast collection of numbers. &lt;strong&gt;Quantization holds those numbers on a coarser scale and repacks the model into something lighter&lt;/strong&gt; (&lt;a href="https://lyr.jp/en/articles/specialist-01-quantization/" rel="noopener noreferrer"&gt;compressing to a quarter barely costs any smarts&lt;/a&gt;). It's like re-saving a photo as a JPEG — the size drops dramatically, and a little detail is lost. The production model runs in that compressed state, because it's faster and cheaper.&lt;/p&gt;

&lt;p&gt;And every time quality fell apart, compression is what I suspected first. I've observed both cases for real: &lt;a href="https://lyr.jp/en/articles/specialist-03-quant-mismatch/" rel="noopener noreferrer"&gt;the compression conditions were mismatched between training and production&lt;/a&gt;, and &lt;a href="https://lyr.jp/en/articles/specialist-06-ceiling-vs-floor/" rel="noopener noreferrer"&gt;compression was inflating catastrophic failures (the floor)&lt;/a&gt;. In the latter, a repair called rotation took catastrophic failures from 64% to 24% — but &lt;strong&gt;it never reached the pre-compression level (12%)&lt;/strong&gt;. Was that remaining half leftover compression damage, or something else entirely? Which raises the question: if I take compression &lt;strong&gt;all the way off&lt;/strong&gt;, does the floor come back? Put another way — with &lt;strong&gt;a raw 8B that hasn't lost a single bit of detail&lt;/strong&gt;, do those critical errors go away?&lt;/p&gt;

&lt;p&gt;I had it translate 100 Korean→Japanese hard cases (97 effective, after removing items that overlapped the training data) and judged them &lt;strong&gt;blind to which configuration produced which translation&lt;/strong&gt;. The comparison was the same self-hosted 8B run at three levels — &lt;strong&gt;heavy compression / medium compression / no compression (raw)&lt;/strong&gt; — against the general-purpose 27B. What I counted wasn't an average score but &lt;strong&gt;the number of critical errors&lt;/strong&gt; — translations that mix up the subject or the meaning and don't work as a subtitle at all. Averages dilute exactly this kind of rare catastrophic failure until you can't see it (&lt;a href="https://lyr.jp/en/articles/specialist-06-ceiling-vs-floor/" rel="noopener noreferrer"&gt;raise the floor, not the ceiling&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The result is Figure 1 at the top. Here are the numbers again, on their own.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Configuration&lt;/th&gt;
&lt;th&gt;Critical errors (of 97)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Self-hosted 8B, heavy compression (the production setting)&lt;/td&gt;
&lt;td&gt;no difference from raw&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-hosted 8B, medium compression&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-hosted 8B, no compression (raw)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;General-purpose 27B&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Here's how to read it. &lt;strong&gt;Taking compression off entirely didn't reduce the critical errors.&lt;/strong&gt; So quantization is not what set this floor. Since the 27B keeps it to 4 on the same hard cases, &lt;strong&gt;what's left is the difference in model size&lt;/strong&gt;. A spread of 15 against 4 is hard to explain as chance wobble.&lt;/p&gt;

&lt;p&gt;That separated the levers available to me into three.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Lever&lt;/th&gt;
&lt;th&gt;Where it acts&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Compression (quantization)&lt;/td&gt;
&lt;td&gt;Generation speed = how much data gets read&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Done as a quality move.&lt;/strong&gt; It works on speed; it does nothing for the floor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Size (capacity)&lt;/td&gt;
&lt;td&gt;The comprehension floor = critical errors&lt;/td&gt;
&lt;td&gt;It works — but it's a move back toward the expensive "bigger is smarter" direction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The vessel (the architecture)&lt;/td&gt;
&lt;td&gt;The generality tax = speed, and the quality ceiling (the cap on how good it gets at its best)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Untouched. This is where the next investment goes&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The conclusion of the experiment is that I stopped betting on quantization. It's still live as a speed lever, but it wasn't a tool for raising the quality floor. &lt;strong&gt;The investment moves from compression to the vessel.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I expect from specialization isn't only speed
&lt;/h2&gt;

&lt;p&gt;Here's the point I least want misread. &lt;strong&gt;Talking about the value of a specialist model purely in terms of latency is too narrow.&lt;/strong&gt; What I expect from recutting the vessel is three independent improvements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;① Emotional register.&lt;/strong&gt; When I had a native speaker read translations off the actual device, the verdict that came back was: "the meaning comes through, but the emotional parts are stiff." This isn't a mistranslation. The meaning is right. And still, as a subtitle, it &lt;strong&gt;catches your attention&lt;/strong&gt; — and in that instant the viewer steps outside the story. If the ideal translation is a subtitle you never notice is there, this isn't decoration; it's the main keep.&lt;/p&gt;

&lt;p&gt;And register doesn't move however you tune the instructions (the prompt). I know by now that the only way is to retrain the model's insides (&lt;a href="https://lyr.jp/en/articles/specialist-02-fine-tuning/" rel="noopener noreferrer"&gt;the register the 4B struggled with showed up at 8B&lt;/a&gt; is the same story). A general-purpose model's register is pulled toward the general-purpose average. &lt;strong&gt;Getting off that average is the first motive for changing the vessel.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;② Accuracy from translating while looking at the video.&lt;/strong&gt; How much better does the translation get if you hand it perfect information about the scene? I've &lt;a href="https://lyr.jp/en/articles/specialist-05-context-vs-capacity/" rel="noopener noreferrer"&gt;measured that elsewhere&lt;/a&gt;. What worked condensed down to three things: &lt;strong&gt;the speaker's gender, how proper nouns are read, and dropped subjects&lt;/strong&gt; (13 improvements against 0 regressions).&lt;/p&gt;

&lt;p&gt;The biggest of the three was the speaker's gender. Japanese exposes who is speaking constantly, through pronoun choice (&lt;em&gt;ore&lt;/em&gt; vs &lt;em&gt;watashi&lt;/em&gt;) and sentence-final particles (&lt;em&gt;~daze&lt;/em&gt; vs &lt;em&gt;~dawa&lt;/em&gt;), while the English source carries none of that information.&lt;/p&gt;

&lt;p&gt;So when the model has to infer gender from the text alone, it drops to 34% right and &lt;strong&gt;21% wrong&lt;/strong&gt;. Wrong is worse than "don't know" — it invents a fact that doesn't exist and contaminates the translation.&lt;/p&gt;

&lt;p&gt;But this isn't a hard problem in principle. &lt;strong&gt;Look at the screen and it's obvious who's talking.&lt;/strong&gt; There's the saying that a picture is worth a thousand words. In translation it bites harder than that — &lt;strong&gt;some of those thousand words were never in the source text to begin with&lt;/strong&gt;. A model that only follows text can re-read the missing information as many times as it likes and never recover it. No amount of stacked context reaches what one frame would settle. In fact, simply training gender information into the model raised the rate at which it correctly switches first-person pronouns and sentence endings to match a male or female context from 19% to 74% (a first demonstration on a separate evaluation set). &lt;strong&gt;As long as the vessel has no entrance except text, there's no way to put this information in.&lt;/strong&gt; Building that entrance is the second motive for changing the vessel.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;③ Latency.&lt;/strong&gt; The third is the freight a general-purpose model pays on generation. That's known ground (&lt;a href="https://lyr.jp/en/articles/specialist-11-decode-bytes/" rel="noopener noreferrer"&gt;covered elsewhere&lt;/a&gt;), so I won't repeat it.&lt;/p&gt;

&lt;p&gt;What matters is that &lt;strong&gt;the three are independent of each other&lt;/strong&gt;. Which means that if it works, you don't get an addition — the whole curve lifts.&lt;/p&gt;

&lt;h2&gt;
  
  
  The next vessel — a "top-heavy" subtitle-specialist model
&lt;/h2&gt;

&lt;p&gt;The insides of a model split broadly in two: the &lt;strong&gt;Encoder (the reading side)&lt;/strong&gt;, which reads the input and grasps the meaning, and the &lt;strong&gt;Decoder (the writing side)&lt;/strong&gt;, which writes that out as a translation. Today's models give the two &lt;strong&gt;roughly the same thickness&lt;/strong&gt;. And the subtitle job gets pushed through that same allocation.&lt;/p&gt;

&lt;p&gt;What I'm considering is &lt;strong&gt;changing that allocation&lt;/strong&gt;. &lt;strong&gt;A big Encoder, a thin Decoder.&lt;/strong&gt; The subtitle job isn't "talk at length and freely," it's "render it short and correct" — so the natural allocation puts the weights thick on understanding and thin on writing out.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp9huqvmd1s7i9zjz39g9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp9huqvmd1s7i9zjz39g9.png" alt="A comparison of how thickness is allocated in two models. On the left, today's vessel gives the Encoder (the reading side) and the Decoder (the writing side) roughly the same thickness, and every character emitted re-reads all of it. On the right, the next vessel takes two inputs, text and video, makes the Encoder bigger to raise the comprehension floor, and makes the Decoder thin. Height represents model size; the right-hand model is larger overall, but only the thin Decoder runs per character, so speed does not drop." width="800" height="662"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 2: rebuilding the vessel — changing the allocation between Encoder and Decoder.&lt;/strong&gt; On the left is today, with roughly the same thickness given to the Encoder (the reading side) and the Decoder (the writing side). Every character emitted re-reads all of it. On the right is the plan. The Encoder gets bigger to raise the comprehension floor (and gains a second entrance, video), and the Decoder gets thin. &lt;strong&gt;The model as a whole actually gets bigger.&lt;/strong&gt; It still doesn't get slower, because &lt;strong&gt;the only thing that runs per character is the thin Decoder&lt;/strong&gt;. What gets cut is generality, not capacity.&lt;br&gt;
&lt;em&gt;Note: the heights are schematic ratios and do not represent the actual parameter allocation. Both sides are at the same scale. This is a design at the plan stage; there is no implementation and no measurement yet.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The reason I expect this shape to work is that &lt;strong&gt;the number of times each side runs is asymmetric&lt;/strong&gt;. The Encoder runs once per input; the Decoder runs on every character it emits. So thinning the Decoder drops latency alone, while the thickness of the understanding stays.&lt;/p&gt;

&lt;p&gt;The three shifts each push a different axis. The aim isn't to pick a winner, it's to &lt;strong&gt;move the trade-off curve itself&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1v2e27ulaxvvtw7goiu9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1v2e27ulaxvvtw7goiu9.png" alt="A conceptual diagram of the speed-versus-quality trade-off curve. 4B, 8B and 27B sit along the general-purpose LLM curve, where speed and quality trade off against each other. The hypothesis is that a subtitle-specialist vessel moves the whole curve upward." width="799" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 3: the aim isn't to "pick a winner," it's to move the curve.&lt;/strong&gt; As long as you use a general-purpose LLM, speed and quality get traded along the same curve (solid line). Fit the vessel to subtitles and maybe that whole curve moves up — that's the hypothesis (dashed line).&lt;br&gt;
&lt;em&gt;Note: the dashed line is an unmeasured hypothesis, not measured points. The three points on the solid line are likewise a conceptual diagram showing relative position; the coordinates are not exact measured values.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let me separate what's backed by evidence from what isn't.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's backed by evidence.&lt;/strong&gt; "Thick Encoder, thin Decoder" is an architecture already demonstrated in machine translation (there's prior work where even a single-layer Decoder beats strong methods in the same speed band). On the video side, I've confirmed for myself that feeding in gender information switches the register correctly (19% → 74%). &lt;strong&gt;None of the parts are new. The only new thing is binding them into one model around the single point of subtitles.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What isn't.&lt;/strong&gt; That prior work was demonstrated mainly on English↔German, and &lt;strong&gt;Japanese↔English/Korean is the language combination this kind of speedup struggles with most&lt;/strong&gt; (word order differs so much that the writing side carries more of the load). So there's no guarantee that "thinner without losing quality" carries over to my own languages as-is. My estimate is that the realistic answer isn't extreme thinning but something like &lt;strong&gt;keeping it at 1–2 layers + having it imitate a larger model's translations as material (distillation) + routing only the hard cases out to a larger model&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And the thing I should be most honest about: &lt;strong&gt;the upper bound on the lift is limited to what you recover by dropping generality.&lt;/strong&gt; As Figure 1 showed, part of the Korean→Japanese floor is set by model size, and changing the vessel leaves it there. What the vessel buys back is speed and register; the comprehension floor can only be filled by raising size, or by a design that routes the hard cases away.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open questions — I have a read on the architecture; I have no data points yet
&lt;/h2&gt;

&lt;p&gt;Everything above is what I've thought through to some degree. What follows is what still needs thinking.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Move&lt;/th&gt;
&lt;th&gt;What it would settle&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Sweep the thickness of the Decoder (the writing side)&lt;/td&gt;
&lt;td&gt;Hold the Encoder fixed and vary the Decoder across 1, 2, 4, 6 and 12 layers, then draw the frontier of quality (register included) against speed. Measure how thin it can go &lt;strong&gt;in my own languages&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Not started&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Graft on a video entrance&lt;/td&gt;
&lt;td&gt;Add a part that reads video to today's 8B, and see whether the speaker's register really is solved by video&lt;/td&gt;
&lt;td&gt;Not started&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Where the training data comes from&lt;/td&gt;
&lt;td&gt;How to build material that pairs video with translations. The text-only recipe doesn't carry over as-is&lt;/td&gt;
&lt;td&gt;Not designed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Let me put the falsification conditions up front too.&lt;/strong&gt; If thinning the Decoder (the writing side) costs more quality than what dropping generality recovers — concretely, if the thinned vessel loses on quality to a general-purpose model at the same speed — I throw the hypothesis away. If adding video doesn't move the register metric, I cut the video shift loose. Because the three shifts are independent of each other, &lt;strong&gt;one of them failing leaves the other two standing&lt;/strong&gt;. Rather than asking "is this whole plan right?" as a single question, I can verify them one at a time and drop only the ones that don't hold.&lt;/p&gt;

&lt;p&gt;That's as far as I can go for now. The intuition that "foundation models are too wasteful for subtitles" has an explanation behind it — the generality tax — and a measurement that ruled quantization out as a suspect. But &lt;strong&gt;I don't yet hold a single piece of evidence that changing the vessel wins.&lt;/strong&gt; Keeping that line sharp is, I think, the condition for measuring the next thing right.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;"Faster through compression" and "smarter through size" are different levers, and you must not talk about them as one.&lt;/strong&gt; With compression off entirely, the critical errors stayed at 15; the model more than three times bigger had 4. The moment the quality floor turns out not to move, compression drops out of the quality toolbox — even though it stays alive as a speed move. &lt;strong&gt;Hold each lever together with where it acts.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't talk about a specialist model's value in terms of speed alone.&lt;/strong&gt; A general-purpose model's register is pulled toward the general-purpose average, and a vessel that only accepts text has no entrance for video. Speed, register and video are three axes that act independently — and &lt;strong&gt;because they're independent, there's a chance of moving the whole trade-off curve rather than adding up gains&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write "I don't have the data yet" plainly.&lt;/strong&gt; Having a read on the design and having it work under your own conditions are different things. The prior work was demonstrated on a different language combination, and there's no guarantee it carries over as-is. &lt;strong&gt;Putting a hypothesis down as a hypothesis and fixing the falsification conditions first&lt;/strong&gt; finishes faster than starting to build on momentum.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Appendix: raw data
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;A. Separating quantization from capacity (the data behind Figure 1)&lt;/strong&gt;&lt;/p&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;Detail&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Task&lt;/td&gt;
&lt;td&gt;Korean→Japanese, a 100-item hard-case set (items suspected of overlapping the training data excluded → effective &lt;strong&gt;n=97&lt;/strong&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Comparison&lt;/td&gt;
&lt;td&gt;Self-hosted 8B (INT4 / INT8 / uncompressed BF16), general-purpose 27B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Metric&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Number of critical errors&lt;/strong&gt;. Subject and meaning mix-ups and the like — translations that don't work as a subtitle. Not average quality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Judging&lt;/td&gt;
&lt;td&gt;Blind, by a large model from a different family, same round&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Configuration&lt;/th&gt;
&lt;th&gt;critical&lt;/th&gt;
&lt;th&gt;vs BF16&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Self-hosted 8B, INT8&lt;/td&gt;
&lt;td&gt;14 / 97&lt;/td&gt;
&lt;td&gt;Statistically indistinguishable (almost no discordant pairs)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-hosted 8B, INT4&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;No significant difference (p=0.22)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-hosted 8B, BF16 (no compression)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;15 / 97&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;General-purpose 27B&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4 / 97&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;p=0.015&lt;/strong&gt; against 8B-BF16 (about a 3.8x difference)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;How to read it&lt;/strong&gt;: the floor doesn't move with or without compression, so compression isn't its cause. The gap to the 27B remains, so the cause is model size (capacity). → &lt;strong&gt;Quantization is done as a quality move; the investment moves to capacity / video / the shape of the vessel.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;B. Why change the vessel (the three shifts, and the evidence so far)&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Shift&lt;/th&gt;
&lt;th&gt;Expected effect&lt;/th&gt;
&lt;th&gt;Evidence so far&lt;/th&gt;
&lt;th&gt;Not yet confirmed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Drop the generality tax&lt;/td&gt;
&lt;td&gt;Accuracy, speed&lt;/td&gt;
&lt;td&gt;A general-purpose LLM (decoder-only, reader and writer fused into one) is built for free-form generation of arbitrary length. Subtitles are short, fixed-format, bounded-context (&lt;a href="https://lyr.jp/en/articles/specialist-11-decode-bytes/" rel="noopener noreferrer"&gt;how much data gets read decides speed&lt;/a&gt;)&lt;/td&gt;
&lt;td&gt;Measurements in my own languages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Add video&lt;/td&gt;
&lt;td&gt;Register, accuracy&lt;/td&gt;
&lt;td&gt;The benefit of perfect context condenses into gender, proper nouns and dropped subjects (13 improvements, 0 regressions, &lt;a href="https://lyr.jp/en/articles/specialist-05-context-vs-capacity/" rel="noopener noreferrer"&gt;context vs. capacity&lt;/a&gt;) / from the English source alone, gender is 34% right and 21% wrong / training on gender information takes the follow-through rate &lt;strong&gt;19% → 74%&lt;/strong&gt; (a first demonstration on a separate set)&lt;/td&gt;
&lt;td&gt;The video-input graft itself&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Thin the Decoder&lt;/td&gt;
&lt;td&gt;Speed&lt;/td&gt;
&lt;td&gt;"Thick Encoder + thin Decoder" is already demonstrated in machine translation (mainly EN↔DE)&lt;/td&gt;
&lt;td&gt;JA↔EN/KO differ far more in word order and are the combination this speedup struggles with most. No guarantee of extrapolation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;C. Caveats&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Figure 2 is a schematic of the plan; there is no implementation and no measurement. The dashed line in Figure 3 is likewise &lt;strong&gt;an unmeasured hypothesis&lt;/strong&gt;, and the points on the solid line are a conceptual diagram showing relative position — the coordinates are not measured values.&lt;/li&gt;
&lt;li&gt;The n=97 in A is small. The p-values come from paired comparisons on the same set; read them as a hint about direction.&lt;/li&gt;
&lt;li&gt;The upper bound on the lift is what you recover by dropping generality. Part of the Korean→Japanese floor is set by model size and remains after changing the vessel (→ the assumption is that a design routing hard cases to a larger model fills the rest).&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://lyr.jp/en/articles/specialist-12-subtitle-vessel/" rel="noopener noreferrer"&gt;LYR Performance Note #032&lt;/a&gt; — part of the series “Models — smaller, faster, sharper”. The full set is at &lt;a href="https://lyr.jp/en/research/" rel="noopener noreferrer"&gt;lyr.jp/en/research&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>devops</category>
      <category>llm</category>
      <category>ai</category>
    </item>
    <item>
      <title>Generation speed is decided by the byte count of the weights, not the parameter count</title>
      <dc:creator>LYR</dc:creator>
      <pubDate>Mon, 03 Aug 2026 14:27:48 +0000</pubDate>
      <link>https://dev.to/lyr/generation-speed-is-decided-by-the-byte-count-of-the-weights-not-the-parameter-count-1ihk</link>
      <guid>https://dev.to/lyr/generation-speed-is-decided-by-the-byte-count-of-the-weights-not-the-parameter-count-1ihk</guid>
      <description>&lt;p&gt;&lt;strong&gt;4B-INT8 and 8B-INT4 came out at the same speed — and get one thing wrong in how you measure, and 2.35x looks like "no difference"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Measured on the same GPU, 4B-INT8 (weights about 4.0GB) and 8B-INT4 (about 4.3GB) came out at nearly the same speed.&lt;/strong&gt; 5.98ms against 6.50ms per token. Even though the parameter counts differ by 2x.&lt;/p&gt;

&lt;p&gt;The reason is simple: &lt;strong&gt;every time it generates one token, it reads out the model's weights in full&lt;/strong&gt;. What decides it isn't the amount of compute and isn't the parameter count — it's &lt;strong&gt;the number of bytes it has to read&lt;/strong&gt;. Which is also why, when you pick a GPU, you look at memory bandwidth and not compute performance.&lt;/p&gt;

&lt;p&gt;This law comes with premises, though. In fact, my first measurement got the method wrong and I misread a "should be 2x faster" as &lt;strong&gt;1.3x&lt;/strong&gt; — and under a different measurement method, a 2.35x gap &lt;strong&gt;disappeared, and then inverted&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fichc9jy9mfv54kxyv0cz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fichc9jy9mfv54kxyv0cz.png" alt="The relationship between the byte count of the weights and generation time per token. 4B-INT4 is 2.6GB at 4.04ms, 4B-INT8 is 4.0GB at 5.98ms, 8B-INT4 is 4.3GB at 6.50ms, 4B-FP16 is 7.6GB at 9.49ms. The parameter counts of 4B and 8B swap places in the ordering, but generation time rises monotonically with byte count." width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 1: the byte count of the weights against generation time per token.&lt;/strong&gt; Color is the parameter count (green = 4B, red = 8B). The ordering swaps around — 4B, 4B, &lt;strong&gt;8B&lt;/strong&gt;, 4B — and yet generation time is &lt;strong&gt;cleanly monotonic in byte count&lt;/strong&gt;. 4B-INT8 (4.0GB) and 8B-INT4 (4.3GB) in particular land at nearly the same speed, despite a 2x difference in parameters.&lt;br&gt;
&lt;em&gt;Note: a comparison held constant on the same GPU, batch=1, the same quantization kernel, and with LoRA merged.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  "A 4B should be 2x faster" only came out at 1.3x
&lt;/h2&gt;

&lt;p&gt;The first measurement went like this. Swap the 8B model for a 4B and you halve the weights you read, so it &lt;strong&gt;should be close to 2x faster&lt;/strong&gt;. But what I measured stopped at &lt;strong&gt;1.24–1.36x&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;"Going to 4B doesn't buy you as much as you'd think" — if I had drawn my conclusion right there, I would have gotten the whole model-size decision wrong.&lt;/p&gt;

&lt;p&gt;The cause wasn't the model. It was that &lt;strong&gt;the setups I was measuring weren't held constant&lt;/strong&gt;. The 4B side alone was carrying a double handicap.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A different quantization kernel&lt;/strong&gt; (one of them was a scheme that unpacks less efficiently on that GPU generation)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The adapter was still running bolted on the outside&lt;/strong&gt; (every generation step pays an extra small matrix multiply)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Re-measure with the same quantization scheme as the 8B side, and with the adapter merged into the model itself — &lt;strong&gt;2.3x&lt;/strong&gt;. It had followed the law all along.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Hold the serving setup constant before you compare.&lt;/strong&gt; A comparison that isn't held constant makes 2x look like 1.3x.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Every token reads all of the weights
&lt;/h2&gt;

&lt;p&gt;Why does the byte count decide it? The mechanism is plain.&lt;/p&gt;

&lt;p&gt;When a language model generates one token, it &lt;strong&gt;touches every weight in the model exactly once&lt;/strong&gt;. So at batch=1 (generating for a single user only), &lt;strong&gt;the read out of memory&lt;/strong&gt; dominates rather than the compute. The amount read is the byte count of the weights, so generation speed is inversely proportional to that byte count.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd6bwh67cyfklzolrq8b8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd6bwh67cyfklzolrq8b8.png" alt="A diagram of the model's whole set of weights being read out of VRAM into the compute units every time one token is generated. With 2.6GB of INT4 weights the read is short; with 7.6GB of FP16 it is about three times longer. The compute units spend more time waiting than working, and the rate limiter is memory bandwidth." width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 2: why the byte count decides it.&lt;/strong&gt; Every token you make reads the weights sitting in VRAM from beginning to end, once. The compute units spend more time &lt;strong&gt;waiting for that read to finish&lt;/strong&gt; than working, and what's rate-limiting is not compute but &lt;strong&gt;memory bandwidth&lt;/strong&gt;. So 2.6GB of weights (INT4) is 4.04ms and 7.6GB (FP16) is 9.49ms — the time stretches in proportion to how much you read.&lt;br&gt;
&lt;em&gt;Note: this is the batch=1 case (generating for a single user). Process several users together and one read can be shared, which changes the story.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The same law carries straight over to quantization bit width. Bit width is byte count.&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 size&lt;/th&gt;
&lt;th&gt;Per token&lt;/th&gt;
&lt;th&gt;vs FP16&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;FP16&lt;/td&gt;
&lt;td&gt;7.6GB&lt;/td&gt;
&lt;td&gt;9.49ms&lt;/td&gt;
&lt;td&gt;1.00x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;INT8&lt;/td&gt;
&lt;td&gt;4.3GB&lt;/td&gt;
&lt;td&gt;6.00ms&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1.58x&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;INT4&lt;/td&gt;
&lt;td&gt;2.6GB&lt;/td&gt;
&lt;td&gt;4.04ms&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2.35x&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The size ratio is 2.92x but the measured value is 2.35x. The gap is what's left over — the parts that aren't quantized (reads and writes of the cache and the activations). &lt;strong&gt;Byte count decides everything, but there are reads and writes beyond the model's weights.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And as long as memory bandwidth is the rate limiter, &lt;strong&gt;the number to look at when choosing a GPU is bandwidth too&lt;/strong&gt;. Not compute performance, and not VRAM capacity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get one thing wrong in how you measure and the 2.35x disappears
&lt;/h2&gt;

&lt;p&gt;Now for the real point. Same model, same GPU, &lt;strong&gt;measured three times changing nothing but the measurement method&lt;/strong&gt;. The results split three ways.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;How it was measured&lt;/th&gt;
&lt;th&gt;FP16&lt;/th&gt;
&lt;th&gt;INT4&lt;/th&gt;
&lt;th&gt;What it looks like&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Stock inference path&lt;/td&gt;
&lt;td&gt;40ms&lt;/td&gt;
&lt;td&gt;39ms&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Level&lt;/strong&gt; (no difference)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inference server (eager execution)&lt;/td&gt;
&lt;td&gt;20.9ms&lt;/td&gt;
&lt;td&gt;22.2ms&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Inverted&lt;/strong&gt; (quantizing makes it slower)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inference server (graph execution)&lt;/td&gt;
&lt;td&gt;9.49ms&lt;/td&gt;
&lt;td&gt;4.04ms&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;2.35x&lt;/strong&gt; (correct)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In the first, the fast quantization kernel never got used and compute was the rate limiter. In the second, the fixed per-step overhead dominated, and on top of that only the unpacking cost of quantization got added. Only in the third did the fixed cost come out and the bandwidth-bound shape appear.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The speed of quantization only shows up when "fast kernel × graph execution × batch=1 bandwidth-bound" all line up.&lt;/strong&gt; Drop any one of the three and it doesn't just look like it "doesn't work" — it looks actively harmful. When you're reading benchmark numbers, check first that all three line up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open questions: a law has a domain where it holds
&lt;/h2&gt;

&lt;p&gt;This law isn't unconditional. I've confirmed two conditions, by measurement, where it breaks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The first is when you're handling several users at once.&lt;/strong&gt; Process the generation in a batch and several requests can share a single read of the weights. Throughput scales with bandwidth, but &lt;strong&gt;the wait for any one user stays proportional to the byte count&lt;/strong&gt;. Everything in this article is about the speed of generating for a single user.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The second is when the weights get too small.&lt;/strong&gt; Quantize a small model hard and put it on a fast GPU, and the weight read finishes so quickly that &lt;strong&gt;fixed costs like kernel launch become the dominant term&lt;/strong&gt;. In practice, 4B-INT4 came out at &lt;strong&gt;168 against 177 tok/s&lt;/strong&gt; across the top two generations of data-center GPU — barely any difference at all, even with 3.3x the bandwidth. Measure the same 8B-INT4 on a previous-generation consumer GPU and it ran at exactly half the speed of the 4B (= plainly bandwidth-bound).&lt;/p&gt;

&lt;p&gt;So &lt;strong&gt;don't try to confirm this law with a comparison that spans GPUs&lt;/strong&gt;. If one side is bandwidth-bound and the other is fixed-cost-bound, the same law will hold in one place and fail in the other.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Generation speed is decided by the byte count of the weights, not the parameter count.&lt;/strong&gt; 4B-INT8 and 8B-INT4 came out at nearly the same speed. So design around "light in bytes" rather than "a small model," and choose GPUs on memory bandwidth rather than compute performance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hold the serving setup constant before you compare.&lt;/strong&gt; A difference in nothing but the quantization kernel and how the adapter was handled turned 2x into 1.3x. Before you attribute a gap to model size, hold the way it's run constant.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A law has a domain where it holds.&lt;/strong&gt; Step outside the batch=1, bandwidth-bound premise and neither size nor bandwidth buys you anything. In comparisons that span GPUs, suspect that the premise itself has changed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is the manifesto's first principle — &lt;a href="https://lyr.jp/en/articles/00-manifesto/#1-measure-first" rel="noopener noreferrer"&gt;Measure First&lt;/a&gt; — in its inference-performance form. Same model, same GPU, and still, one choice in how you measure makes 2.35x look like "no difference," or like an inversion.&lt;/p&gt;




&lt;h3&gt;
  
  
  Appendix: raw data
&lt;/h3&gt;

&lt;p&gt;All measured at batch=1 (generating for a single user). TPOT = generation time per token.&lt;/p&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;Measured&lt;/th&gt;
&lt;th&gt;Conditions &amp;amp; caveats&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Monotonicity of bytes and speed&lt;/td&gt;
&lt;td&gt;4B-INT4 2.6GB / 4.04ms &amp;lt; 4B-INT8 4.0GB / 5.98ms ≈ 8B-INT4 4.3GB / 6.50ms &amp;lt; 4B-FP16 7.6GB / 9.49ms&lt;/td&gt;
&lt;td&gt;Same GPU, same quantization kernel, adapter merged. Monotonic in byte-count order, not parameter-count order&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Effect of halving the parameters&lt;/td&gt;
&lt;td&gt;8B-INT4 76 tok/s → 4B-INT4 172 tok/s = &lt;strong&gt;2.3x&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;With the same quantization and merged adapters held constant. Consistent with 4B-INT4 at 166 tok/s on a different GPU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mis-measurement (setup mismatch)&lt;/td&gt;
&lt;td&gt;4B served with a bolted-on adapter + a different quantization scheme → 91 tok/s = 1.24–1.36x over the 8B&lt;/td&gt;
&lt;td&gt;A double handicap: the efficiency gap between quantization kernels plus adapter overhead. The 8B side was partly under the same conditions, so it's asymmetric&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Effect of bit width&lt;/td&gt;
&lt;td&gt;FP16 105 / INT8 167 / INT4 247 tok/s&lt;/td&gt;
&lt;td&gt;Against a size ratio of 2.92x, the measured value is 2.35x. The gap is the reads and writes that aren't quantized (cache, activations, embeddings) plus fixed kernel cost&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The measurement trap&lt;/td&gt;
&lt;td&gt;stock path 40 / 39ms (level) → eager execution 20.9 / 22.2ms (inverted) → graph execution 9.49 / 4.04ms (correct)&lt;/td&gt;
&lt;td&gt;The 2.35x only comes out once fast kernel, graph execution and batch=1 bandwidth-bound all line up&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Outside the domain (fixed-cost-bound)&lt;/td&gt;
&lt;td&gt;4B-INT4 came out 168 against 177 tok/s across the top two generations of data-center GPU (no response to 3.3x the bandwidth)&lt;/td&gt;
&lt;td&gt;The weights are too small, so fixed costs like kernel launch dominate. 8B-INT4 is plainly bandwidth-bound on a previous-generation consumer GPU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Side benefit&lt;/td&gt;
&lt;td&gt;Once the quantization schemes were held constant, a bug where characters from another language crept in also went away&lt;/td&gt;
&lt;td&gt;The quantization scheme can affect not just speed but the language consistency of the output&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://lyr.jp/en/articles/specialist-11-decode-bytes/" rel="noopener noreferrer"&gt;LYR Performance Note #030&lt;/a&gt; — part of the series “Models — smaller, faster, sharper”. The full set is at &lt;a href="https://lyr.jp/en/research/" rel="noopener noreferrer"&gt;lyr.jp/en/research&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>performance</category>
      <category>testing</category>
      <category>ai</category>
    </item>
    <item>
      <title>Let another AI write your teacher data</title>
      <dc:creator>LYR</dc:creator>
      <pubDate>Mon, 03 Aug 2026 14:26:47 +0000</pubDate>
      <link>https://dev.to/lyr/let-another-ai-write-your-teacher-data-5d1p</link>
      <guid>https://dev.to/lyr/let-another-ai-write-your-teacher-data-5d1p</guid>
      <description>&lt;p&gt;&lt;strong&gt;How I had a large AI, not people, write the "gold data" that trains a specialist&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The "gold data" that trains a specialist AI is something humans write — I threw that assumption out. &lt;strong&gt;I had a large AI write it, and a small AI copy it out.&lt;/strong&gt; Japanese→English, the direction the small model was worst at, jumped &lt;strong&gt;42% → 84%&lt;/strong&gt; on straight imitation alone. Zero human translators.&lt;/p&gt;

&lt;p&gt;The ceiling above that sat not with the teacher but with &lt;strong&gt;the student's comprehension capacity&lt;/strong&gt; (the teacher's own translations passed almost across the board). Lump every ceiling together as "the teacher is bad" and you pick the wrong move.&lt;/p&gt;

&lt;p&gt;And one pitfall. Hand the teacher surrounding context with the best of intentions, and the student learns to invent subjects. &lt;strong&gt;Build the teacher data under the same input conditions as production&lt;/strong&gt; — the way kindness backfires only becomes visible once you measure.&lt;/p&gt;

&lt;p&gt;Training a small AI into "a specialist at one job" takes a large volume of &lt;strong&gt;gold data&lt;/strong&gt;. A stack of model answers saying "for this input, this translation is the right answer." For translation, that's a pair — the source text and its model translation.&lt;/p&gt;

&lt;p&gt;And nearly everyone assumes the same thing — &lt;strong&gt;that those right answers are something humans produce&lt;/strong&gt;. You hire professional translators, have them translate sentence by sentence, and use that as the model answers. The quality is solid, but it's slow. It's expensive. And for low-resource languages you can't get hold of a professional in the first place. This "produce the gold data" step looks like the biggest bottleneck in training a specialist model.&lt;/p&gt;

&lt;p&gt;I threw that assumption out. &lt;strong&gt;I had the gold data produced by another AI, not by people.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Have the large AI write the model answers
&lt;/h2&gt;

&lt;p&gt;The method is simple. What I want to train is a small, lightweight model (4B = 4 billion parameters). What I have on hand is a far larger, far smarter general-purpose model (27B class).&lt;/p&gt;

&lt;p&gt;So — &lt;strong&gt;have the large one write the right answers and the small one copy them out&lt;/strong&gt;. Pour the source text into the large model, take the translations that come out as "model answers," and have the small model imitate them. In machine learning this is called &lt;strong&gt;distillation&lt;/strong&gt;. The side producing the right answers is the &lt;strong&gt;teacher model&lt;/strong&gt;; the side learning by imitating it is the &lt;strong&gt;student model&lt;/strong&gt;. The title of this article — "Let another AI write your teacher data" — means exactly what it says: &lt;strong&gt;have the teacher model write the gold data (= the teacher data), and have the student copy it out&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The effect showed up plainly. The un-fine-tuned small model was hopeless at Japanese→English, with accuracy of about &lt;strong&gt;42%&lt;/strong&gt;. It got more than half of them wrong. So I had the large teacher write about 14,000 translations (clean, a single generation at temp0.1, and — as described below — with no context), rolled those into about 5,000 training examples, and had the small model imitate them —&lt;/p&gt;

&lt;p&gt;Accuracy: &lt;strong&gt;84%&lt;/strong&gt;. &lt;strong&gt;+42 points&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Worth adding: this 84% came out with no elaborate selection in between, just imitating the teacher's plain translations as they came. Tricks like "generate N candidates and pick the good one" are &lt;strong&gt;the next lever&lt;/strong&gt;, the one you pull after this. Straight imitation on its own gets you this far.&lt;/p&gt;

&lt;p&gt;(The scoring is a reference-free binary judge. Rather than a human yardstick, an independent AI scores each translation "usable / not usable," and I compared before and after training under identical conditions. These are point estimates from a single run, so the absolute values wobble by a few points.)&lt;/p&gt;

&lt;p&gt;One training run took a model that was basically an amateur up to a level that draws level with the large general-purpose model. Not one human translator was hired. &lt;strong&gt;An AI mass-produced the gold data.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The pitfall — imitation has a ceiling
&lt;/h2&gt;

&lt;p&gt;It would be a nice story if it ended there, but reality kept going. This approach has a clear &lt;strong&gt;ceiling&lt;/strong&gt;. The 84% on Japanese→English plateaued right there. Look into the remaining 16% and most of the failures wore the same face — &lt;strong&gt;hallucination&lt;/strong&gt;. Inventing a subject that isn't in the source, supplying an object that was never there. As prose it's fluent and looks plausible enough. But it says things the source doesn't say.&lt;/p&gt;

&lt;p&gt;This is where attribution goes wrong. "The teacher taught it lies, so the student lies too." But &lt;strong&gt;for Japanese→English, that wasn't it&lt;/strong&gt;. The teacher (27B class) is strong at Japanese→English: score the teacher's translations with an independent binary judge and they pass almost across the board. The one getting it wrong wasn't the teacher — it was &lt;strong&gt;the student&lt;/strong&gt;. Hand the 4B student a hard source sentence with a dropped subject and an idiom tangled into it, and it can't read it all the way through; trying to make the pieces add up, it slips in a fluent lie. So this ceiling didn't come from the teacher: it was &lt;strong&gt;hallucination coming out of the 4B student's "comprehension capacity."&lt;/strong&gt; Which means no amount of cleaning up the model answers, and no amount of piling on data, moves the capacity wall itself (KTO and CPO below run into the same wall).&lt;/p&gt;

&lt;p&gt;That said, "the teacher's lies are inherited by the student" isn't a thing that never happens. It happens clearly in &lt;strong&gt;two other situations&lt;/strong&gt;. One is when the teacher itself is weak in the language — &lt;a href="https://lyr.jp/en/articles/specialist-07-low-resource/" rel="noopener noreferrer"&gt;move into a language it's weak in and the bigger the general-purpose model, the more abruptly it falls apart&lt;/a&gt;. There the teacher's model answers become the rate limiter, and the more the student imitates, the more it gets contaminated. The other is "when you hand the teacher context," covered in the next section. Both are genuine teacher-side contamination, confirmed by measurement. &lt;strong&gt;What the ceiling actually is differs from situation to situation&lt;/strong&gt; — lump them together as "the teacher is bad" and you pick the wrong move.&lt;/p&gt;

&lt;h2&gt;
  
  
  The teacher's first shot isn't the ceiling — best-of-N
&lt;/h2&gt;

&lt;p&gt;Even if the Japanese→English ceiling is on the student's side, there's still headroom on the teacher's side. Because &lt;strong&gt;the teacher's "first shot" isn't necessarily the best the teacher can do&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Have the teacher translate the same source &lt;strong&gt;N different ways&lt;/strong&gt; and take &lt;strong&gt;only the single best one&lt;/strong&gt;. This is &lt;strong&gt;best-of-N&lt;/strong&gt;. The yardstick for picking isn't agreement with a reference translation (a human's model answer) but &lt;strong&gt;QE (Quality Estimation — scoring the quality of a translation without looking at a right answer)&lt;/strong&gt;, which looks only at the quality of the translation itself. The payoff and the pitfalls of this selection mechanism get a &lt;a href="https://lyr.jp/en/articles/specialist-08-best-of-n-qe/" rel="noopener noreferrer"&gt;separate article&lt;/a&gt;, so I'll keep it to the essentials here.&lt;/p&gt;

&lt;p&gt;In my comparison of levers, best-of-N selection is where I've placed &lt;strong&gt;the highest-ROI "next move"&lt;/strong&gt; (projected +10 to 15 points). But to be honest, that isn't a measured result from running the Japanese→English track end to end — it's &lt;strong&gt;my read from the design&lt;/strong&gt;. Where I have actually made best-of-N work and measured it is a different mode, Live: there, retraining on re-picked model answers gave &lt;strong&gt;+2pt&lt;/strong&gt; (and +6pt, 90→96, together with the preference training stacked on top) (&lt;a href="https://lyr.jp/en/articles/specialist-09-live-specialization/" rel="noopener noreferrer"&gt;details&lt;/a&gt;). The value of "picking from candidates" is real, but I should be clear that the double-digit pt on Japanese→English is still a projection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Selection is all about the "yardstick"
&lt;/h2&gt;

&lt;p&gt;best-of-N is not a cure-all. If the yardstick you select on is off, &lt;strong&gt;you end up worse than not selecting at all&lt;/strong&gt;. On a different dataset I had it select on "closeness to the official subtitles," and the alignment-based selection (&lt;strong&gt;73–77%&lt;/strong&gt;) lost to the plain single generation with no selection at all (&lt;strong&gt;82%&lt;/strong&gt;). The official subtitles I used were a translation in a different direction, from a different source language, and every bit the candidates were optimized toward them was fidelity to the source given up. A QE judge, which never looks at the reference translation, does the opposite: it correctly fails those differently-directed official translations, and avoids the trap automatically.&lt;/p&gt;

&lt;p&gt;The details are in the &lt;a href="https://lyr.jp/en/articles/specialist-08-best-of-n-qe/" rel="noopener noreferrer"&gt;separate article&lt;/a&gt;, but the lesson is one line — &lt;strong&gt;it matters less how many candidates you roll than whether the yardstick you select on points at the kind of good you actually want&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  KTO slipped; my bet is on CPO
&lt;/h2&gt;

&lt;p&gt;After the student has copied out good model answers, there's one more stage of polish. &lt;strong&gt;Show it a "good translation" and a "bad translation" and train the judgment itself — "this one is better."&lt;/strong&gt; That's preference learning.&lt;/p&gt;

&lt;p&gt;I tried &lt;strong&gt;KTO (Kahneman-Tversky Optimization)&lt;/strong&gt; first. You attach nothing but a binary good/bad label to each individual translation — a method that's light to implement. I drew up the design, ran it through the pipeline, and trained.&lt;/p&gt;

&lt;p&gt;The result — &lt;strong&gt;almost nothing&lt;/strong&gt;. 84% became 85%. That sits inside the judge's margin of error. The content of the translation changed in 14 of 100 cases, with zero regressions among them, but not one instance of the main cause of failure (hallucination from the student's capacity) went away. A signal as coarse as binary good/bad &lt;strong&gt;can't fill in the 4B model's comprehension ceiling&lt;/strong&gt; — the controlled experiment put that in my face.&lt;/p&gt;

&lt;p&gt;So I moved my bet. To &lt;strong&gt;CPO (Contrastive Preference Optimization)&lt;/strong&gt;. Instead of a bare binary, CPO &lt;strong&gt;ranks&lt;/strong&gt; several candidates — {teacher translation, student translation, reference translation} — and trains on the difference itself, "A is better than B." It's a method with a track record on translation tasks (ALMA-R — the study that demonstrated CPO for translation), and it lets you etch in the "gap" between the good translation you picked with best-of-N and the ones you didn't. But let me be honest about this: &lt;strong&gt;I have not yet run CPO end to end on the Japanese→English track&lt;/strong&gt; — I've decided to adopt it on the strength of ALMA-R's results, and that's as far as it goes. If I have to point at measured evidence that preference learning actually worked, it's in a different mode, Live, where Live-CPO contributed to the 90→96 push (&lt;a href="https://lyr.jp/en/articles/specialist-09-live-specialization/" rel="noopener noreferrer"&gt;details&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The lesson is that with preference learning, &lt;strong&gt;how you do it makes all the difference in the world&lt;/strong&gt;. Same "teach it good from bad," and the coarse binary (KTO) slips, while the ranked version that shows the difference (CPO) is where I'm putting my money. But to press the point: CPO doesn't &lt;strong&gt;get over the comprehension ceiling itself&lt;/strong&gt; either. It's a region where a difference only appears once you pile up an order of magnitude more (preference data in the tens of thousands), and really breaking that ceiling means going deeper into how the distillation is done. Honestly, I haven't climbed that one yet.&lt;/p&gt;

&lt;p&gt;The backbone, in order: &lt;strong&gt;first build the foundation with straight imitation (42→84), then re-pick better model answers with best-of-N selection (the projected highest ROI), and on top of that etch in the differences with CPO&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  An incidental finding — "give it context and it gets smarter" was backwards
&lt;/h2&gt;

&lt;p&gt;Let me record one more moment where an assumption flipped.&lt;/p&gt;

&lt;p&gt;If you want the teacher to write good right answers, &lt;strong&gt;surely handing it the surrounding context makes it translate more intelligently&lt;/strong&gt; — that's the natural thought. Human translators translate more accurately with context too.&lt;/p&gt;

&lt;p&gt;But when I trained the student on model answers produced with context injected into the teacher's prompt, the student &lt;strong&gt;learned to hallucinate subjects&lt;/strong&gt;. Subjects the teacher had filled in from context, the student now filled in on its own — in production, where there is no context. At actual translation time the LYR app doesn't hand the model that kind of conversation history the way the teacher got it. &lt;strong&gt;Training conditions and production conditions were mismatched.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The fix was to deliberately withhold context from the teacher as well and &lt;strong&gt;have it write the model answers with "no context," exactly as in production&lt;/strong&gt;. Kindness meant to make it smarter backfires in production. &lt;strong&gt;Build the teacher data under the same input conditions as production&lt;/strong&gt; — an iron rule I only learned by measuring.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thin and wide — 61 languages at once
&lt;/h2&gt;

&lt;p&gt;One last property of this methodology, and the one that matters most in business terms.&lt;/p&gt;

&lt;p&gt;Having an AI write the right answers makes &lt;strong&gt;adding a language essentially free&lt;/strong&gt;. With human translators you'd re-hire a specialist per language; the teacher model spits out model answers for 61 languages at zero additional labor cost.&lt;/p&gt;

&lt;p&gt;In practice, &lt;strong&gt;a single training run covered all 61 languages, thin and wide&lt;/strong&gt;. The result was a clean gradient in resource volume.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Language&lt;/th&gt;
&lt;th&gt;Approx. pass rate&lt;/th&gt;
&lt;th&gt;Where it sits&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Spanish&lt;/td&gt;
&lt;td&gt;~91%&lt;/td&gt;
&lt;td&gt;plenty of parallel text = easy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Arabic, Vietnamese, Portuguese&lt;/td&gt;
&lt;td&gt;~82%&lt;/td&gt;
&lt;td&gt;mid-resource&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Korean, Thai&lt;/td&gt;
&lt;td&gt;~77%&lt;/td&gt;
&lt;td&gt;mid-resource&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hindi&lt;/td&gt;
&lt;td&gt;~59%&lt;/td&gt;
&lt;td&gt;somewhat low-resource&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Swahili&lt;/td&gt;
&lt;td&gt;~9%&lt;/td&gt;
&lt;td&gt;lowest-resource = the data floor&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;(Same training run, held-out evaluation (scored on unseen data not used in training), binary judge. The point estimate for each language wobbles by a few points.)&lt;/p&gt;

&lt;p&gt;The pass rate is a direct gradient of "how much parallel text exists for that language on the internet." The easy languages come out high whether you do anything or not; the weaker the language, the thinner the data both teacher and student have to work with, and the lower it lands. And while hitting 84% on Japanese→English, it also held 80% on English→Japanese (it doesn't get locked into one direction).&lt;/p&gt;

&lt;p&gt;That gradient is also a map that shows at a glance &lt;strong&gt;where to invest next&lt;/strong&gt;. The languages at the top are already fine. The bottleneck is always the weakest language. But — &lt;strong&gt;what the rate limiter is there can't be known without diagnosing the content of the failures language by language&lt;/strong&gt;. Is it the student's capacity, the teacher's quality, or does the base simply not have the language at all? You can't lump it together as "the bottom of the list is always the teacher's fault" (Swahili is a case where the base doesn't have the language itself = the data floor). How to run that diagnosis, and &lt;a href="https://lyr.jp/en/articles/specialist-07-low-resource/" rel="noopener noreferrer"&gt;the different moves&lt;/a&gt; each rate limiter calls for, are covered in a separate article.&lt;/p&gt;

&lt;p&gt;Once you've laid down this "teacher-data production line," the rest is knocking out the weak languages one at a time. The fuel for &lt;a href="https://lyr.jp/en/articles/specialist-02-fine-tuning/" rel="noopener noreferrer"&gt;training&lt;/a&gt; a specialist — gold data — keeps getting supplied thin, wide, and cheap by an AI instead of by people.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Gold data can be produced by an AI instead of by people.&lt;/strong&gt; Have a large teacher model write the model answers and a small student copy them out (distillation). On Japanese→English, the direction it was worst at, straight imitation alone took accuracy from 42% to 84% (+42pt). Zero human translators. The step usually taken to be the biggest cost of training a specialist — producing the right answers — can be automated. (&lt;a href="https://lyr.jp/en/articles/00-manifesto/#2-hunt-the-constraint" rel="noopener noreferrer"&gt;The manifesto's second principle, Hunt the Constraint&lt;/a&gt;: get past the bottleneck by a different route.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;What the ceiling actually is differs from situation to situation.&lt;/strong&gt; Stalling at 84% on Japanese→English was hallucination from &lt;strong&gt;the 4B student's comprehension capacity&lt;/strong&gt;, not from the teacher (the teacher's own translations passed almost across the board). What does get inherited from the teacher's lies are "languages the teacher is weak in" and "when you hand the teacher context" — and those I confirmed by measurement. Lump every ceiling together as "the teacher is bad" and you pick the wrong move.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Build the teacher data under the same input conditions as production.&lt;/strong&gt; Hand the teacher context with the best of intentions and the student learns to invent subjects. A mismatch between training conditions and production conditions turns straight into a defect. And the next move for pushing quality up is &lt;strong&gt;selection&lt;/strong&gt;, not generation (best-of-N) — but select on quality alone, because selecting on closeness to a reference translation pulls you off in a different direction.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Appendix: raw data
&lt;/h3&gt;

&lt;p&gt;Shared conditions: student = my own lightweight model (distilled 4B). Teacher = a general-purpose large model (27B class). Evaluation compares before and after training under identical conditions with a reference-free binary judge (PASS/FAIL). Point estimates come from a single run = absolute values wobble by a few points.&lt;/p&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;Result&lt;/th&gt;
&lt;th&gt;Conditions &amp;amp; caveats&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Distillation SFT (imitation)&lt;/td&gt;
&lt;td&gt;base 4B Japanese→English &lt;strong&gt;~42% → 84% (+42pt)&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Teacher generated 13,786 translations (temp0.1, &lt;strong&gt;no context = production parity&lt;/strong&gt;, no selection) → 5,090 training examples. English→Japanese held at 80% too&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Where the ceiling sits&lt;/td&gt;
&lt;td&gt;The teacher's translations pass almost across the board = the one getting it wrong is &lt;strong&gt;the student&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;The hallucination is bound by the 4B's comprehension capacity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multilingual held-out (61 languages)&lt;/td&gt;
&lt;td&gt;Spanish 91 / Arabic, Vietnamese, Portuguese 82 / Korean, Thai 77 / Hindi 59 / Swahili &lt;strong&gt;9&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Pass rate = a gradient in resource volume. Swahili's 9 is the base barely having the language at all (&lt;a href="https://lyr.jp/en/articles/specialist-07-low-resource/" rel="noopener noreferrer"&gt;diagnosis&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Selection (best-of-N QE)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Projected&lt;/strong&gt; highest ROI in the lever evaluation (&lt;strong&gt;+10 to 15pt&lt;/strong&gt;), &lt;strong&gt;not yet run&lt;/strong&gt; on Japanese→English&lt;/td&gt;
&lt;td&gt;Where it worked in measurement was Live's SFT-aug &lt;strong&gt;+2&lt;/strong&gt; (+6 including CPO)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;gold-alignment trap&lt;/td&gt;
&lt;td&gt;Anchoring on the reference translation pulls you off in a different direction and falls apart&lt;/td&gt;
&lt;td&gt;reference-free QE correctly fails the non-aligned official translations and avoids the trap automatically&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Preference learning (KTO)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;null&lt;/strong&gt;: 84→85% (within judge noise)&lt;/td&gt;
&lt;td&gt;14/100 translations changed, 0 regressions, main cause of FAIL unchanged. A binary signal doesn't fill in the comprehension ceiling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Preference learning (CPO)&lt;/td&gt;
&lt;td&gt;Adopted, but not yet trained on Japanese→English&lt;/td&gt;
&lt;td&gt;Grounded in ALMA-R's results. The measured case is Live-CPO's 90→96. The real difference surfaces at the tens-of-thousands scale&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Handling of context&lt;/td&gt;
&lt;td&gt;Train on model answers made with context handed to the teacher, and the student learns subject hallucination&lt;/td&gt;
&lt;td&gt;Production doesn't hand over conversation history under the same conditions = &lt;strong&gt;the teacher data has to be built with no context&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Related&lt;/strong&gt;: The details of quality selection are in &lt;a href="https://lyr.jp/en/articles/specialist-08-best-of-n-qe/" rel="noopener noreferrer"&gt;Letting an AI pick a translation better than the "right answer"&lt;/a&gt;. The basics of training a small model on this teacher data are in &lt;a href="https://lyr.jp/en/articles/specialist-02-fine-tuning/" rel="noopener noreferrer"&gt;Training a small AI into a specialist at one job&lt;/a&gt;. Diagnosing the weakest language, where the teacher itself becomes the rate limiter, is in &lt;a href="https://lyr.jp/en/articles/specialist-07-low-resource/" rel="noopener noreferrer"&gt;Spotting the rate limiter in your weakest language&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://lyr.jp/en/articles/specialist-10-teacher-data/" rel="noopener noreferrer"&gt;LYR Performance Note #020&lt;/a&gt; — part of the series “Models — smaller, faster, sharper”. The full set is at &lt;a href="https://lyr.jp/en/research/" rel="noopener noreferrer"&gt;lyr.jp/en/research&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>ai</category>
    </item>
    <item>
      <title>A small specialist drew level with the strongest model in service</title>
      <dc:creator>LYR</dc:creator>
      <pubDate>Mon, 03 Aug 2026 14:25:45 +0000</pubDate>
      <link>https://dev.to/lyr/a-small-specialist-drew-level-with-the-strongest-model-in-service-3d8j</link>
      <guid>https://dev.to/lyr/a-small-specialist-drew-level-with-the-strongest-model-in-service-3d8j</guid>
      <description>&lt;p&gt;&lt;strong&gt;You don't have to fight the giants head-on — narrow to one task and sharpen it, and a far smaller model can draw level. It just isn't free&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A model about a third the size (8B) &lt;strong&gt;drew level&lt;/strong&gt; with the strongest class currently in service (27B). But only after narrowing to a single task — Live subtitles. 90 → 96, tied with its own teacher.&lt;/p&gt;

&lt;p&gt;That draw came with a price tag. The price of taking Live up +6 was &lt;strong&gt;Page and Manga each breaking by −4&lt;/strong&gt;. Specialization isn't a free lunch; it's &lt;strong&gt;a choice about allocation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Which means the question to settle first isn't "should I specialize" but "which mode is the main battleground, and what do I do with the others." The ways out — remixing the data, per-mode routing, scaling capacity — each cost something different in shape.&lt;/p&gt;

&lt;p&gt;There's an unspoken pecking order in the world of machine translation. The more parameters, the smarter. So if you want the best quality, use the biggest model.&lt;/p&gt;

&lt;p&gt;The teacher model LYR runs in production is a general-purpose model with 27 billion parameters (27B) — one of the strongest currently in service. The specialist model LYR raises in-house has about a third of that: 8 billion parameters (8B).&lt;/p&gt;

&lt;p&gt;How far could I push that 8B on &lt;strong&gt;Live subtitles&lt;/strong&gt; — the job of translating the one-line-at-a-time captions running along the bottom of a video, in real time? That's what this article is about. The short version: the 8B &lt;strong&gt;drew level&lt;/strong&gt; with the 27B. But that draw came with &lt;strong&gt;a price tag&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The assumption — "a small model can't beat a big one"
&lt;/h2&gt;

&lt;p&gt;Here's where it started. I measured the rate at which Live subtitle translations actually pass as usable (overall = the share where meaning and naturalness are good enough for real use), side by side across models.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Live&lt;/th&gt;
&lt;th&gt;Page&lt;/th&gt;
&lt;th&gt;Manga&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;8B (sharpened for general use)&lt;/td&gt;
&lt;td&gt;90&lt;/td&gt;
&lt;td&gt;93&lt;/td&gt;
&lt;td&gt;92&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;27B (in service, the teacher)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;96&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;98&lt;/td&gt;
&lt;td&gt;99&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scout (the predecessor)&lt;/td&gt;
&lt;td&gt;97&lt;/td&gt;
&lt;td&gt;86&lt;/td&gt;
&lt;td&gt;90&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;On Live, the 8B was at 90. The 27B at 96. &lt;strong&gt;A 6-point gap.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Read plainly, that looks like a difference in capacity. The 8B's capacity is too small to handle Live's hard cases — idioms, picking the wrong subject. If that's true, there's only one move: make the model bigger. It's a tempting conclusion.&lt;/p&gt;

&lt;p&gt;But is that 6 points really "the capacity wall"? Or is it a question of &lt;strong&gt;how it was sharpened&lt;/strong&gt;? Running to a bigger model without checking is sprinting in the most expensive direction available. So first I looked at what the failures actually were.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measured — the gap wasn't capacity
&lt;/h2&gt;

&lt;p&gt;Opening up the Live items the 8B was failing on, one by one, the culprits came in three kinds. Literal translation of idioms (rendering "isn't like you" word for word), picking the wrong subject, and word hallucination (adding words that were never in the source).&lt;/p&gt;

&lt;p&gt;Of those, idioms and subjects are &lt;strong&gt;not a question of capacity&lt;/strong&gt;. They're the kind of mistake that goes away if you show the model enough correct model answers. So maybe what the 8B lacked wasn't capacity but &lt;strong&gt;high-quality model answers specialized for the Live job&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So I sharpened it in two stages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage one: make the model answers better.&lt;/strong&gt; Have the 27B teacher translate the same sentence N different ways, then pick the single best among them with quality estimation (QE = automatically scoring a translation by looking at the translation alone). The translations picked out by this "best-of-N QE" become the 8B's model answers (→ &lt;a href="https://lyr.jp/en/articles/specialist-08-best-of-n-qe/" rel="noopener noreferrer"&gt;Getting the AI to pick a translation better than the gold reference&lt;/a&gt;). That's what makes the teacher data for idioms and subjects high quality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage two: teach preference with pairs of good and bad translations.&lt;/strong&gt; Build Live-specific pairs — "this translation is good, this one is bad" — and bake them in with CPO (training that corrects the model's preferences directly from contrastive good/bad example pairs). Live's pairs draw the sharpest line between good and bad, and the separation in training was where it worked hardest.&lt;/p&gt;

&lt;p&gt;The result —&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Live&lt;/th&gt;
&lt;th&gt;Page&lt;/th&gt;
&lt;th&gt;Manga&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;8B (sharpened for general use)&lt;/td&gt;
&lt;td&gt;90&lt;/td&gt;
&lt;td&gt;93&lt;/td&gt;
&lt;td&gt;92&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8B (Live-specialized)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;96&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;89&lt;/td&gt;
&lt;td&gt;88&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;27B (in service, the teacher)&lt;/td&gt;
&lt;td&gt;96&lt;/td&gt;
&lt;td&gt;98&lt;/td&gt;
&lt;td&gt;99&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Live went 90 → 96. Tied with the 27B (96), and within a hair of Scout (97).&lt;/strong&gt; The 6-point gap had gone to zero. And register held at 98 — still 27B-class (99). Split into its parts: the higher-quality model answers gave +2, the Live-specific CPO +4. What closed the gap wasn't capacity, it was &lt;strong&gt;specializing on the single point that is Live&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A model about a third the size had drawn level with the strongest model in service. If the story ended here, it'd be a satisfying win. But there are columns in that table I can't pretend not to see.&lt;/p&gt;

&lt;h2&gt;
  
  
  Specialization isn't free — it's a choice about allocation
&lt;/h2&gt;

&lt;p&gt;Look at &lt;strong&gt;Page and Manga&lt;/strong&gt; on the Live-specialized version. Page 93→89, Manga 92→88. &lt;strong&gt;Both broke by −4.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjmu5wbect5qufeufwymk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjmu5wbect5qufeufwymk.png" alt="Before and after Live specialization on a zero-based y axis (overall %, 0 to 100). Live rises 90 to 96 while Page falls 93 to 89 and Manga 92 to 88. All three modes cluster at a high level; the changes are small but point in opposite directions" width="800" height="567"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 1: Before and after Live specialization (overall % across the three modes).&lt;/strong&gt; Live rises 90→96, but the other side falls: Page 93→89, Manga 92→88. On a zero-based y axis all three modes cluster at a high level, so the changes are small — but they point in opposite directions.&lt;br&gt;
&lt;em&gt;Note: the y axis is overall %, from zero. Point estimates on the same evaluation set; the number of evaluation items (n) wasn't recorded.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The training that took Live up +6 dragged Page and Manga down −4. This isn't an accidental side effect. The 8B does double duty across three modes in a single model, and when you skew it toward one side (Live's single-line, one-at-a-time subtitles), the distribution for Page/Manga — which translate a block at a time — gets pushed out. &lt;strong&gt;I observed the same shape of breakage — a regime shift (the training data's distribution skews to one side and the mode on the other side falls apart) — over and over: with Manga-heavy data, and with training that included context.&lt;/strong&gt; The mechanism of mode mixing itself, with all the numbers, is in &lt;a href="https://lyr.jp/en/articles/measure-07-mode-mixing/" rel="noopener noreferrer"&gt;Don't stop at measuring a single mode&lt;/a&gt;. The −4 from Live specialization here is one instance of that general rule.&lt;/p&gt;

&lt;p&gt;So Live 90→96 is not, properly speaking, "6 points out of nowhere." It's &lt;strong&gt;carved out of Page and Manga and handed to Live&lt;/strong&gt; — a reallocation. And not even a clean, even trade at that (Live +6, against −8 combined across Page and Manga). Specialization is not a free lunch. It's &lt;strong&gt;choosing where to put the weight inside a limited capacity&lt;/strong&gt;. The right posture is to suspect that whenever something goes up, something you didn't measure has gone down.&lt;/p&gt;

&lt;h2&gt;
  
  
  So what do you do with that −4?
&lt;/h2&gt;

&lt;p&gt;Once the trade-off is visible, the move stops being a binary of "specialize or don't." It becomes a problem of designing the allocation.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Remix the Live data back into the general data and retrain&lt;/strong&gt; — instead of adding single lines as single lines, blend them in a form that doesn't wreck the block distribution, and dilute the interference.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Split the airframe per mode&lt;/strong&gt; — Live gets the specialist airframe, Page/Manga the general-purpose airframe, switched by role. Don't make them fight over the same capacity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scale up capacity&lt;/strong&gt; — the only unconditional way to eliminate the interference at the root, but it's also a return to the expensive direction of "bigger is smarter." Reaching straight for capacity on problems that &lt;strong&gt;sharpening fixes&lt;/strong&gt;, like idioms and subjects, is giving up on diagnosis. (Some jobs do genuinely demand capacity, though — deep reading comprehension in Japanese, for one. Where specialization can't reach, I'll leave to &lt;a href="https://lyr.jp/en/articles/specialist-07-low-resource/" rel="noopener noreferrer"&gt;Spotting the rate limiter in the language it's worst at&lt;/a&gt;.)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Whichever one you pick, the starting point was the same: &lt;strong&gt;don't say "I won" while looking only at the targeted mode&lt;/strong&gt;. Had I stared only at Live's 96, I'd have gone around announcing "the 8B has caught up with the 27B" without ever noticing the −4 on Page and Manga. That's half the truth at best.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;You don't have to fight the giants head-on.&lt;/strong&gt; Instead of challenging 27 billion parameters at general-purpose work, narrow 8 billion onto a single point — Live subtitles — and the success rate goes 90 → 96, drawing level with the strongest model in service. At about a third of the capacity, you can match it on the one trick you aimed at.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;But specialization is a choice about allocation, not a free lunch.&lt;/strong&gt; The same training that took Live up +6 broke Page/Manga by −4. As long as one model does double duty across several jobs, whatever you gained was carved out of somewhere else (and not necessarily as a clean, even trade).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;So don't decide win or lose from the metric you targeted alone.&lt;/strong&gt; Whether specialization worked can only be judged by laying the target's gain next to &lt;strong&gt;what the non-targets sacrificed&lt;/strong&gt;. Measuring one side only fakes a success.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Appendix: raw data
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Shared conditions&lt;/strong&gt;: self-hosted 8B model (a distillation line taught by the 27-billion-parameter 27B general-purpose model). The three modes — Live / Page / Manga — measured side by side on the same evaluation set. Numbers are overall (= the share of translations good enough for real use, %); listed separately is register (how natural the voice sounds, %). Judged by Claude (Max plan) in a single judge round. &lt;strong&gt;The number of evaluation items (n) wasn't recorded, so read each % as a point estimate — a signal, not a settled result&lt;/strong&gt; (nothing here is established at a significance level. The direction of the −4, however, has been observed repeatedly when specializing other modes → &lt;a href="https://lyr.jp/en/articles/measure-07-mode-mixing/" rel="noopener noreferrer"&gt;Don't stop at measuring a single mode&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;Step&lt;/th&gt;
&lt;th&gt;Detail&lt;/th&gt;
&lt;th&gt;Quantity &amp;amp; conditions&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;L-1&lt;/td&gt;
&lt;td&gt;Merge the 8B (30k distillation)&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;L-2&lt;/td&gt;
&lt;td&gt;Additional Live SFT (further training on model answers selected by best-of-N QE)&lt;/td&gt;
&lt;td&gt;Live gold &lt;strong&gt;522 items&lt;/strong&gt;, loss 0.34 / acc 0.95&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;L-3&lt;/td&gt;
&lt;td&gt;Live-CPO (correcting preference directly from contrastive good/bad examples)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;516&lt;/strong&gt; Live pairs, rewards/acc &lt;strong&gt;1.0&lt;/strong&gt; = the sharpest good/bad separation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;L-4/L-5&lt;/td&gt;
&lt;td&gt;Evaluation → judge&lt;/td&gt;
&lt;td&gt;Same evaluation set, same judge round&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Main results (overall / register, %, same set)&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Live&lt;/th&gt;
&lt;th&gt;Page&lt;/th&gt;
&lt;th&gt;Manga&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;8B general CPO&lt;/td&gt;
&lt;td&gt;90 / 100&lt;/td&gt;
&lt;td&gt;93 / 98&lt;/td&gt;
&lt;td&gt;92 / 98&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8B LiveSFT&lt;/td&gt;
&lt;td&gt;92 / 99&lt;/td&gt;
&lt;td&gt;92 / 98&lt;/td&gt;
&lt;td&gt;87 / 98&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;8B LiveSFT+CPO&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;96 / 98&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;89 / 100&lt;/td&gt;
&lt;td&gt;88 / 100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scout (the predecessor)&lt;/td&gt;
&lt;td&gt;97 / 98&lt;/td&gt;
&lt;td&gt;86 / 91&lt;/td&gt;
&lt;td&gt;90 / 96&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;27B (new, the teacher)&lt;/td&gt;
&lt;td&gt;96 / 99&lt;/td&gt;
&lt;td&gt;98 / 100&lt;/td&gt;
&lt;td&gt;99 / 100&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Point&lt;/th&gt;
&lt;th&gt;Number&lt;/th&gt;
&lt;th&gt;Conditions &amp;amp; caveats&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Live 90→96&lt;/td&gt;
&lt;td&gt;Tied with the 27B (96), within a hair of Scout (97)&lt;/td&gt;
&lt;td&gt;Breakdown: SFT-aug +2 (idioms / register improvement), Live-CPO +4 (reweight). register 98 holds 27B class (99)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remaining defect&lt;/td&gt;
&lt;td&gt;Word hallucination persists&lt;/td&gt;
&lt;td&gt;Outside the coverage of a small 522-item aug. The gains on idioms / register outweighed the hallucinations left over, reaching overall 96&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trade-off&lt;/td&gt;
&lt;td&gt;Page 93→89, Manga 92→88 (&lt;strong&gt;−4 each&lt;/strong&gt;)&lt;/td&gt;
&lt;td&gt;Live-specialized training drifted the training distribution toward the Live side&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The general rule of mode mixing (the −4 regime shift, reproduced with three moves on 2026-07-14)&lt;/strong&gt;: beyond Live specialization, the same shape of degradation on the opposite side showed up with Manga-heavy data and with context-included training. All the numbers and the mechanism (drift in the learned distribution of entry counts / styles) are deferred to &lt;a href="https://lyr.jp/en/articles/measure-07-mode-mixing/" rel="noopener noreferrer"&gt;Don't stop at measuring a single mode&lt;/a&gt;. The −4 from Live specialization here is one of those three moves.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ways out&lt;/strong&gt;: ① retrain with the Live data mixed into the general set without wrecking the distribution, ② per-mode routing (Live = the specialist airframe / Page-Manga = the general-purpose airframe), ③ capacity scaling (the only move that unconditionally eliminates the interference, but expensive).&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://lyr.jp/en/articles/specialist-09-live-specialization/" rel="noopener noreferrer"&gt;LYR Performance Note #019&lt;/a&gt; — part of the series “Models — smaller, faster, sharper”. The full set is at &lt;a href="https://lyr.jp/en/research/" rel="noopener noreferrer"&gt;lyr.jp/en/research&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>ai</category>
    </item>
    <item>
      <title>Let the AI pick a translation better than the "right answer"</title>
      <dc:creator>LYR</dc:creator>
      <pubDate>Mon, 03 Aug 2026 14:24:43 +0000</pubDate>
      <link>https://dev.to/lyr/let-the-ai-pick-a-translation-better-than-the-right-answer-1dm2</link>
      <guid>https://dev.to/lyr/let-the-ai-pick-a-translation-better-than-the-right-answer-1dm2</guid>
      <description>&lt;p&gt;&lt;strong&gt;Instead of imitating one sacred right answer, have it produce N candidates and pick the best — but it's no cure-all&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;There is one right answer, and it is sacred&lt;/strong&gt; — that article of faith in AI training cracked. Have the teacher produce N candidates and let a quality estimator pick among them, and what you get is a set of model answers that beats the teacher's own first shot (+2 on Live; 90→96 together with the CPO that followed).&lt;/p&gt;

&lt;p&gt;But the thing I'm sure of is the flip side. &lt;strong&gt;If the yardstick you select with is off target, you lose outright to a single clean answer.&lt;/strong&gt; When I selected by closeness to a right answer that faced the wrong direction, 82% fell to 73–77%.&lt;/p&gt;

&lt;p&gt;More volume doesn't change that. Data inflated to 8,553 examples by raising the temperature lost to a clean 3,301. &lt;strong&gt;The question to ask wasn't "what should N be" — it was "does this yardstick point at the kind of good I actually want?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you teach an AI something, the most straightforward approach is this: &lt;strong&gt;prepare one correct set of model answers and have it imitate them&lt;/strong&gt;. For translation, you show it a great many pairs that say "the right answer for this sentence is this translation." Straight out of the machine learning textbook, and it's how I worked for a long time.&lt;/p&gt;

&lt;p&gt;Behind it sits a quiet article of faith: the assumption that &lt;strong&gt;"there is one right answer (gold), and it is sacred."&lt;/strong&gt; Raise the quality of the model answers and you raise the quality of the student. So you carefully prepare one good right answer —&lt;/p&gt;

&lt;p&gt;Then one experiment cracked that faith. &lt;strong&gt;Having the model produce N candidates and picking the "best one" gave better translations than having it imitate a single right answer.&lt;/strong&gt; And another experiment from the same period taught me, just as clearly, that this way of picking is &lt;strong&gt;no cure-all&lt;/strong&gt; — get the yardstick wrong and you lose outright to one clean set of model answers. This article is about both sides.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it started — one weak mode I just couldn't close
&lt;/h2&gt;

&lt;p&gt;LYR's small model has three places it gets used (modes): &lt;strong&gt;Live&lt;/strong&gt;, which translates video subtitles in real time; &lt;strong&gt;Page&lt;/strong&gt;, which translates the whole screen; and &lt;strong&gt;Manga&lt;/strong&gt;, which translates comics.&lt;/p&gt;

&lt;p&gt;Of the three, &lt;strong&gt;Live&lt;/strong&gt; was stubbornly the weak one (what I'm training here is the mid-size one among the small models — the &lt;strong&gt;8B specialist&lt;/strong&gt;). Same small model, and yet Page and Manga were roughly level with the large model above them, while Live alone was left well behind. Looking at the causes one case at a time, the shape of the failures came into view: idioms translated literally (reading "isn't like you" as the opposite of 「あなたらしくない」, the idiom it should have produced), the wrong subject picked, words inserted that were never there.&lt;/p&gt;

&lt;p&gt;The first move that comes to mind is "collect more gold data for Live and have it imitate more of it." But who writes that gold data? &lt;strong&gt;The larger model above it — the teacher — writes it&lt;/strong&gt; (the distillation from &lt;a href="https://lyr.jp/en/articles/specialist-02-fine-tuning/" rel="noopener noreferrer"&gt;last time&lt;/a&gt;). You have the teacher translate once and use that as the model answer. Except the teacher's own translations sometimes missed the idiom. &lt;strong&gt;If the model answers miss it, the student misses it too.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The realization — the teacher's "first shot" isn't necessarily its best
&lt;/h2&gt;

&lt;p&gt;So I changed the framing. Stop having the teacher translate &lt;strong&gt;exactly once&lt;/strong&gt; and then worshipping that as the one right answer. Instead —&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Have the teacher translate the same sentence N different ways. Then mechanically pick the "best translation" out of that set.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's the idea behind &lt;strong&gt;best-of-N&lt;/strong&gt; (take the single best of N candidates). The crux is how you decide which translation is "best." What I used was a &lt;strong&gt;quality estimator (QE = quality estimation)&lt;/strong&gt;: a mechanism that scores "how good is this translation?" without ever looking at the right answer. Instead of matching a candidate against a right answer, it estimates how well the translation itself came out. Score the N candidates with QE and adopt the top scorer as the "new model answer."&lt;/p&gt;

&lt;p&gt;I retrained Live on those model answers. It worked — modestly. Re-imitating the model answers rebuilt with best-of-N moved Live's pass rate &lt;strong&gt;+2&lt;/strong&gt;. Stacking &lt;strong&gt;CPO&lt;/strong&gt; on top of that (preference optimization that learns "the difference between a good and a bad translation" instead of imitating one right answer — a method with a track record in machine translation) added +4: &lt;strong&gt;+6 in total, 90→96&lt;/strong&gt; — level with the large model's 96. register (how natural the speech style sounds) &lt;strong&gt;held at 98&lt;/strong&gt; against the 100 it had before specialization, still at large-model level.&lt;/p&gt;

&lt;p&gt;Let me draw a line here, to be safe. Putting those three models side by side (small general-purpose / Live-specialized / large) is the subject of the sister article &lt;a href="https://lyr.jp/en/articles/specialist-09-live-specialization/" rel="noopener noreferrer"&gt;A small specialist drew level with the strongest model in service&lt;/a&gt;. What matters here is one point: &lt;strong&gt;of that +6, the part best-of-N moved is the +2&lt;/strong&gt; — not a magic strike, but a solid step.&lt;/p&gt;

&lt;p&gt;What matters is the mechanism. &lt;strong&gt;The teacher's "first shot" is not a ceiling on the teacher's ability.&lt;/strong&gt; Roll it N times and somewhere in there is a translation better than the first one. Pick that one up with QE and you have &lt;strong&gt;model answers that beat the teacher itself&lt;/strong&gt;. The same mechanism is also the heart of the process of &lt;a href="https://lyr.jp/en/articles/specialist-10-teacher-data/" rel="noopener noreferrer"&gt;having an AI build the teacher data&lt;/a&gt;. The right answer wasn't one thing — it was something you grow out of N candidates.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fat4ib5wwqc5236vgwqqg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fat4ib5wwqc5236vgwqqg.png" alt="Contrast between the gold faith (imitating one right answer) and best-of-N QE (picking the best of N candidates with a quality estimator)" width="799" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 1: the gold faith, and best-of-N QE.&lt;/strong&gt; Against imitating one right answer (left), rolling N candidates and picking the best with a quality estimator (right). The teacher's first shot is not a ceiling on the teacher's ability. But if the yardstick you select with is off target, you lose to one clean answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Another direction — and the "next move" I haven't stacked yet
&lt;/h2&gt;

&lt;p&gt;Live shouldn't be the only place this selection idea works… or so I'd expect. But here I have to draw an honest line.&lt;/p&gt;

&lt;p&gt;For &lt;strong&gt;Japanese → English&lt;/strong&gt; — the direction LYR polishes so people can "read Japanese manga and anime in English" (this one is small too, but a lighter &lt;strong&gt;4B airframe&lt;/strong&gt;) — the un-fine-tuned accuracy was only &lt;strong&gt;around 42%&lt;/strong&gt;. Run a chain of distillation training over it and it jumped to &lt;strong&gt;84%&lt;/strong&gt; — the same level as a large model, or as a powerful previous-generation model.&lt;/p&gt;

&lt;p&gt;But that 84% is &lt;strong&gt;not&lt;/strong&gt; a best-of-N result. What's inside it is &lt;strong&gt;plain distillation&lt;/strong&gt;: straightforward imitation of the teacher's single most confident output (one low-temperature sample). best-of-N QE is the &lt;strong&gt;"next move"&lt;/strong&gt; you stack on top of that — the lever my design notes rate as having &lt;strong&gt;the highest&lt;/strong&gt; return on investment (a projected +10–15 points) — but I &lt;strong&gt;haven't run it yet&lt;/strong&gt;. The full picture and the numbers for that direction I'll leave to the sister article &lt;a href="https://lyr.jp/en/articles/specialist-10-teacher-data/" rel="noopener noreferrer"&gt;Get a different AI to build your teacher AI&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So what I can say "from measurement" about best-of-N right here is only that +2 on Live. A jump like 42→84 is not yet best-of-N's doing — &lt;strong&gt;it's an expected value, not a track record&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;One of my usual notes of caution here. These are &lt;strong&gt;LLM-as-judge verdicts&lt;/strong&gt;, and the number of evaluated cases is limited (for some experiments I didn't even record the count). Read the point estimates as &lt;strong&gt;a strong signal&lt;/strong&gt; that something worked, not as numbers you can grip down to the decimal place and declare settled.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pitfall — if the yardstick is off target, you lose to one clean answer
&lt;/h2&gt;

&lt;p&gt;Up to here I could end on "best-of-N is universal magic." But let me be honest about this: &lt;strong&gt;with this same method, I fell flat once.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On a different dataset, I used &lt;strong&gt;closeness to the official subtitles (gold)&lt;/strong&gt; as best-of-N's "selection yardstick." "Pick the candidate closest to the real subtitle and it must be the best one" — intuitively that sounds right. The result: &lt;strong&gt;it lost to the straightforward single output with no selection at all.&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;How the model answers were made&lt;/th&gt;
&lt;th&gt;Pass rate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;The teacher's most confident single output (lower temp, no selection)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;82%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;best-of-N selection by "closeness to the official subtitles"&lt;/td&gt;
&lt;td&gt;73–77%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The naturalness of the speech style (register) fell too, from 87% to 79%. I rolled candidates and selected among them, and &lt;strong&gt;ended up worse than not selecting at all&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Why? Because the "official subtitles" I used were &lt;strong&gt;a different thing entirely&lt;/strong&gt;. Those subtitles were the &lt;strong&gt;Korean → Japanese&lt;/strong&gt; translation of a Korean drama, and what I was translating was the &lt;strong&gt;English source text&lt;/strong&gt;. The source language was different, and on top of that they carried the mismatch particular to subtitles (alignment noise between screen and dialogue). Select candidates by closeness to that off-target right answer, and the model abandons faithfulness to the English source and &lt;strong&gt;gets pulled toward content that came from the Korean&lt;/strong&gt;. If the yardstick is skewed, the more candidates you add, the more carefully you optimize in the skewed direction.&lt;/p&gt;

&lt;p&gt;I stepped in the same hole going for volume, too. When I &lt;strong&gt;padded the model answers (the SFT training data) out to 8,553 examples&lt;/strong&gt; with many variants at a higher temperature, temperature noise came along with them and the result &lt;strong&gt;lost to a clean 3,301 examples&lt;/strong&gt; built at a single temperature. This isn't about increasing the candidate count N; it's about how many examples I inflated the training data to — more was not better.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The lesson isn't that best-of-N is wrong. It's that the validity of the yardstick (the QE, the selection anchor) is everything.&lt;/strong&gt; It worked on Live because QE is a yardstick pointed the right way — it estimates "how good this translation is" directly. It fell over on subtitles because I used a yardstick pointed the wrong way: closeness to a right answer facing a different direction. best-of-N is a device that amplifies the quality of your selection criterion as-is — a good criterion beats the teacher, a bad one leaves you worse off than not selecting.&lt;/p&gt;

&lt;p&gt;This is also the same story as &lt;a href="https://lyr.jp/en/articles/measure-05-metric-is-the-goal/" rel="noopener noreferrer"&gt;That "accuracy" is a definition you chose&lt;/a&gt;, which I wrote earlier. Picking "good" with a QE means &lt;strong&gt;picking one definition of "good."&lt;/strong&gt; If that definition misses the mark, then no matter how carefully you select among the candidates, what gets selected is off the mark.&lt;/p&gt;

&lt;h2&gt;
  
  
  Putting this in business terms
&lt;/h2&gt;

&lt;p&gt;Carefully building one set of gold data is an easy investment to understand. But however good that one set is, it's bound by &lt;strong&gt;the ceiling of the teacher's first shot&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;best-of-N × QE is a mechanism for pushing that ceiling up with no extra model and no data purchase. Roll the same teacher N times and pick the good ones — that's all. On Live it did produce a real +2. And my design notes rank it as &lt;strong&gt;the highest-ROI lever&lt;/strong&gt; I have (a projected +10–15 points) — though the version that stacks it up big is still a "next move," not something I've run.&lt;/p&gt;

&lt;p&gt;But this device's performance &lt;strong&gt;is decided by how you measure "good."&lt;/strong&gt; With an accurate yardstick it beats the teacher; with an off-target one it loses even to a single clean answer. So the question to ask before adopting best-of-N isn't "how many candidates should I generate?" It's &lt;strong&gt;"does the yardstick I select with really point at the kind of good I want?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Breaking the faith that "there is one right answer and it is sacred" is a good thing. But you mustn't replace it with another faith: "just roll candidates and you win." What belongs on the ground where the old faith stood is &lt;strong&gt;the discipline of continually doubting your definition of "good."&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Don't worship the one right answer.&lt;/strong&gt; The teacher's first shot is not a ceiling on the teacher's ability. Roll N of them and select with a quality estimator (QE), and you can build model answers that beat the teacher itself. On Live this selection did produce a real +2 (90→96 together with the CPO that followed), and as a lever to stack up big I rate it the most promising one I have (not yet run).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;best-of-N is no cure-all — the yardstick you select with is everything.&lt;/strong&gt; Select by closeness to an off-target right answer (wrong direction, alignment noise) and you lose to a single clean answer with no selection at all (82% → 73–77%). Before you increase the candidate count, verify that the selection criterion is valid. A bad yardstick is worse than not selecting.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Direction over volume — picking "good" means picking a definition of "good."&lt;/strong&gt; Inflating to 8,553 examples with a higher temperature still lost to a clean 3,301. Piling on more, or rolling more, is not value in itself. The question before you adopt it isn't "what should N be" but "does this yardstick point at the kind of good I want?"&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Appendix: raw data
&lt;/h3&gt;

&lt;p&gt;All LLM-as-judge (with sample spot-checks by hand). The number of evaluated cases is limited; read the point estimates as &lt;strong&gt;a strong signal&lt;/strong&gt;, not as settled.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Experiment&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;th&gt;Conditions &amp;amp; caveats&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Live specialization (best-of-N SFT + Live-CPO)&lt;/td&gt;
&lt;td&gt;Live &lt;strong&gt;90 → 96&lt;/strong&gt; (SFT-aug +2, Live-CPO +4)&lt;/td&gt;
&lt;td&gt;overall / register %, same evaluation set. The large model (the strongest currently in service) is Live 96&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The trade-off it came with&lt;/td&gt;
&lt;td&gt;The price: Page 93→89 / Manga 92→88 (−4)&lt;/td&gt;
&lt;td&gt;Live-specialized training drifted away from the general batch. Expected to be resolved by retraining on a mix, or by per-mode routing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Japanese → English (different model, 4B)&lt;/td&gt;
&lt;td&gt;un-fine-tuned ~42% → &lt;strong&gt;84%&lt;/strong&gt; with plain distillation SFT&lt;/td&gt;
&lt;td&gt;best-of-N &lt;strong&gt;not used&lt;/strong&gt;. The ceiling is hallucination (comprehension-capacity-bound)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Assessment of best-of-N SFT&lt;/td&gt;
&lt;td&gt;Projected to have &lt;strong&gt;the highest&lt;/strong&gt; ROI (+10–15pt)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Not yet run&lt;/strong&gt;. The only measured result is the +2 on Live above&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The gold-alignment trap&lt;/td&gt;
&lt;td&gt;No selection &lt;strong&gt;82%&lt;/strong&gt; → selection by chrF closeness &lt;strong&gt;73–77%&lt;/strong&gt; (register 87→79%)&lt;/td&gt;
&lt;td&gt;The yardstick's reference faced a different direction (KO→JA), plus alignment noise. Faithfulness to the English source was lost&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Padding out the volume&lt;/td&gt;
&lt;td&gt;8,553 examples at temp0.7 &amp;lt; 3,301 at temp0.1&lt;/td&gt;
&lt;td&gt;This is the training-data example count, not the candidate count N. Temperature noise made it worse&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A note on preference optimization&lt;/td&gt;
&lt;td&gt;Binary preference (KTO) on its own was null (84→85%, within judge noise)&lt;/td&gt;
&lt;td&gt;Preference at the string level doesn't close the comprehension-capacity wall. CPO adopted as the backbone stacked on top of best-of-N SFT&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Related&lt;/strong&gt;: the basics of distillation and SFT/CPO are in &lt;a href="https://lyr.jp/en/articles/specialist-02-fine-tuning/" rel="noopener noreferrer"&gt;Raising a small AI into a specialist at one job&lt;/a&gt;. Using best-of-N to generate teacher data is covered in &lt;a href="https://lyr.jp/en/articles/specialist-10-teacher-data/" rel="noopener noreferrer"&gt;Get a different AI to build your teacher AI&lt;/a&gt;, and the full picture of Live specialization in &lt;a href="https://lyr.jp/en/articles/specialist-09-live-specialization/" rel="noopener noreferrer"&gt;A small specialist drew level with the strongest model in service&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://lyr.jp/en/articles/specialist-08-best-of-n-qe/" rel="noopener noreferrer"&gt;LYR Performance Note #018&lt;/a&gt; — part of the series “Models — smaller, faster, sharper”. The full set is at &lt;a href="https://lyr.jp/en/research/" rel="noopener noreferrer"&gt;lyr.jp/en/research&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>testing</category>
      <category>ai</category>
    </item>
    <item>
      <title>Swahili from 0% to 30%. But the value wasn't the score — it was that the failures changed</title>
      <dc:creator>LYR</dc:creator>
      <pubDate>Mon, 03 Aug 2026 14:23:41 +0000</pubDate>
      <link>https://dev.to/lyr/swahili-from-0-to-30-but-the-value-wasnt-the-score-it-was-that-the-failures-changed-39jn</link>
      <guid>https://dev.to/lyr/swahili-from-0-to-30-but-the-value-wasnt-the-score-it-was-that-the-failures-changed-39jn</guid>
      <description>&lt;p&gt;&lt;strong&gt;Spotting the real bottleneck in the language AI is worst at — look at what the failures are made of, not the absolute score&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Swahili is one of the languages AI is worst at. Translation accuracy went from 0% to 30%. But the value wasn't in the score — it was that the failures themselves changed.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;From "strings that aren't even words" (= the model doesn't have the language) to "fluent, but the meaning slips" (= the teacher is bad). The score is just as low either way, but it is a strong clue that the rate limiter has moved off capacity and onto the teacher.&lt;/p&gt;

&lt;p&gt;And in low-resource languages, &lt;strong&gt;a huge teacher doesn't necessarily help&lt;/strong&gt;. Tripling the teacher's size produced no difference, and a smaller teacher designed for low-resource languages won instead (9 wins / 5 losses). About $15 per language jumps a model from "doesn't have it" to "usable but rough."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy1b22f5rirovzp07dm8y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy1b22f5rirovzp07dm8y.png" alt="Distribution of Swahili failures: before and after the fundamentals are poured in, strings that aren't even words (red) nearly vanish and shift to fluent but meaning-slipping output (yellow)" width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 1: the distribution of Swahili failures.&lt;/strong&gt; Between before and after the fundamentals were poured in, the pass count moves only from 0 to 3. But the substance of the failures was swapped out: from strings that aren't even words (= the model doesn't have the language) to fluent output whose meaning slips (= the teacher is bad). That's the signal that the rate limiter moved from capacity to the teacher side.&lt;br&gt;
&lt;em&gt;Note: n=10. Read the point estimate as a signal, not a settled result.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Translation AI has languages it is good at and languages it is hopeless at. English and Spanish are easy — there are mountains of parallel text online. And then there are languages with over 100 million speakers that AI simply cannot translate. &lt;strong&gt;Swahili&lt;/strong&gt; is the poster child.&lt;/p&gt;

&lt;p&gt;When I had LYR's own model translate into Swahili, accuracy was &lt;strong&gt;0%&lt;/strong&gt;. Not one of the 10 items passed. This is where most teams conclude: "too much to ask of a small model — either scale it up or give up."&lt;/p&gt;

&lt;p&gt;But that isn't what this article is about. It's not about &lt;strong&gt;the score being 0%&lt;/strong&gt; — it's about &lt;strong&gt;how that 0% was wrong&lt;/strong&gt;. I looked inside the failures, and the rate-limiting step (the bottleneck) showed itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  There are two kinds of "0%"
&lt;/h2&gt;

&lt;p&gt;Start by looking at how the base model got Swahili wrong. What came out when it tried to translate was this: "Kwa kari", "H,h...".&lt;/p&gt;

&lt;p&gt;That isn't &lt;strong&gt;even Swahili&lt;/strong&gt;. It isn't even words — it's garbled characters. The model &lt;strong&gt;simply doesn't have&lt;/strong&gt; the Swahili language. It isn't mistranslating; it has no vocabulary to speak with. It's like asking a baby to read a contract aloud. Seven of the ten items were this kind of "string that isn't even a word," and three barely took the shape of a language. Passes: 0.&lt;/p&gt;

&lt;p&gt;What matters here is that &lt;strong&gt;the same 0% can be completely different in kind&lt;/strong&gt;. Is it 0% because the meaning was misread, or 0% because the language isn't there at all? The first can be polished out. The second is a problem that comes before polishing. &lt;strong&gt;The number on the score tells you nothing about which one you have.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Pouring in the fundamentals
&lt;/h2&gt;

&lt;p&gt;If the substance of the failure is "the language isn't there," there's only one move: &lt;strong&gt;pour the fundamentals of that language into the model&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The method: before teaching it to translate, have it read a huge amount of Swahili prose (continued pretraining = adding a language to the base after the fact). A hundred million words of clean Swahili collected from the web, read through and nothing else. And to &lt;strong&gt;keep it from outputting only Swahili (forgetting the languages it already had)&lt;/strong&gt;, I mixed in a quarter as much Japanese and English. Half a day of GPU time; this reading step (continued pretraining) alone cost about $13. Add requantization and the step that trains translation in (imitation and CPO), and it comes to &lt;strong&gt;about $15 per language in total&lt;/strong&gt; — one taxi ride.&lt;/p&gt;

&lt;p&gt;Then I had it translate again. Accuracy: &lt;strong&gt;0% → 30%&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let me be honest about this. 30% is &lt;strong&gt;still a long way&lt;/strong&gt; from the 60% ship line. On the number alone, it's "still not good enough." Anyone who stops the story here would call this investment a failure.&lt;/p&gt;

&lt;p&gt;But the 30% wasn't what I was actually looking at.&lt;/p&gt;

&lt;h2&gt;
  
  
  The "shape" of the failures changed
&lt;/h2&gt;

&lt;p&gt;As Figure 1 at the top shows, the number (the pass count) moved only from 0 to 3. But &lt;strong&gt;the "shape" of the failures was replaced wholesale&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Before&lt;/strong&gt;: the main culprit was "strings that aren't even words" — the language isn't there.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;After&lt;/strong&gt;: non-word output &lt;strong&gt;all but disappeared&lt;/strong&gt;. Failures like handing back the Japanese as-is, or emitting some other language, were &lt;strong&gt;zero&lt;/strong&gt;. What comes out is &lt;strong&gt;always fluent, correct Swahili&lt;/strong&gt;. It's just that the meaning sometimes slips — flipping "worthless" into "valuable," or letting a few English words leak in.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the &lt;strong&gt;real return&lt;/strong&gt; on this investment. The model &lt;strong&gt;acquired&lt;/strong&gt; the Swahili language. From "broken" to "usable but rough." The failures moved out of the language layer and &lt;strong&gt;into the meaning layer&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And that move is itself the &lt;strong&gt;diagnosis&lt;/strong&gt;. When the main culprit shifts from "strings that aren't even words" to "fluent but the meaning slips," it means &lt;strong&gt;the rate limiter has moved off the model's capacity and onto something else&lt;/strong&gt;. Onto what?&lt;/p&gt;

&lt;h2&gt;
  
  
  The rate limiter was on the "teacher" side
&lt;/h2&gt;

&lt;p&gt;"Fluent, but the meaning slips." I had a suspicion about that particular way of being wrong.&lt;/p&gt;

&lt;p&gt;The small model is trained by &lt;strong&gt;imitating model answers&lt;/strong&gt; — translations produced by a larger model above it (the teacher). That's the distillation from &lt;a href="https://lyr.jp/en/articles/specialist-02-fine-tuning/" rel="noopener noreferrer"&gt;last time&lt;/a&gt;. If the student translates fluently but misses the meaning, then — &lt;strong&gt;maybe the teacher's model answers are missing the meaning too&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The way to check is a controlled experiment. &lt;strong&gt;Leave the student (base) completely untouched and change only the teacher side.&lt;/strong&gt; If the scores go up, that's a signal that the rate limiter is on the teacher, not the student.&lt;/p&gt;

&lt;p&gt;What I changed first wasn't the teacher's "model" but its &lt;strong&gt;"recipe."&lt;/strong&gt; Translating Japanese→Swahili directly falls apart, so I &lt;strong&gt;routed it through English&lt;/strong&gt; (Japanese→English→Swahili). Sending it down the "wide road" that is English restores reading comprehension.&lt;/p&gt;

&lt;p&gt;The result — &lt;strong&gt;that recipe change alone gave 9 wins / 1 loss out of 13 (3 ties)&lt;/strong&gt;. Not a byte of the student changed. That said, only 10 of the 13 were decisive, so I can't call it settled. Even so, the signal that &lt;strong&gt;the rate limiter sits on the teacher's "recipe" and not on the student's capacity&lt;/strong&gt; is quite strong.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F51t000bxcoewr607cirz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F51t000bxcoewr607cirz.png" alt="Result of a controlled experiment that changed only the teacher's recipe. With the student held fixed, running the same 13 cases head-to-head between a teacher that translates directly and a teacher that pivots through English gives 9 wins for the English pivot, 3 ties and 1 win for direct. The pass rate also rises from 15% to 23%." width="799" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 2: a controlled experiment that changed only the teacher's "recipe."&lt;/strong&gt; Not a byte of the student (base) changed; only the teacher's generation path was swapped, and the same 13 cases were run head-to-head. &lt;strong&gt;English pivot wins 9 / ties 3 / direct wins 1&lt;/strong&gt;, and the pass rate rises from 15% to 23%. Because the student is held fixed, this difference points not at the student's capacity but at &lt;strong&gt;the rate limiter being on the teacher side&lt;/strong&gt;.&lt;br&gt;
&lt;em&gt;Note: 10 of the 13 were decisive. Because n is small, a strong signal rather than a settled result.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If I had looked only at that first score of "30%" and concluded "the model is too small," I would have invested in the direction of &lt;strong&gt;adding capacity (= a bigger model, expensive)&lt;/strong&gt;. But at least at this entry point (Japanese→Swahili), what &lt;em&gt;worked&lt;/em&gt; was changing &lt;strong&gt;the teacher's recipe (= cheap)&lt;/strong&gt;. Get the diagnosis wrong and I'd have sprinted full speed at the expensive option.&lt;/p&gt;

&lt;h2&gt;
  
  
  The counterintuitive part — the "teacher" is bad at this language too
&lt;/h2&gt;

&lt;p&gt;There's one more pitfall here.&lt;/p&gt;

&lt;p&gt;"If the teacher is the rate limiter, just bring in a bigger, smarter teacher" — that's the natural thought. What the model is imitating is a huge general-purpose model. Those can do anything. Surely Swahili is nothing.&lt;/p&gt;

&lt;p&gt;But &lt;strong&gt;the huge general-purpose models are startlingly weak on low-resource languages&lt;/strong&gt;. This isn't my discovery; it has been demonstrated over and over in the literature. There is a report that even the very best general-purpose model &lt;strong&gt;beat a dedicated translation model only 5.5% of the time&lt;/strong&gt; on English→other-language translation. Another survey found that general-purpose models &lt;strong&gt;lost to older translation-only models in 84% of 204 languages&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The giant models that look omnipotent are &lt;strong&gt;omnipotent only on the "wide paved road" of English and the major languages&lt;/strong&gt;. Turn onto an unpaved road like Swahili and a dedicated translation model passes them without effort. The reflex of "have it imitate a big model and you'll be fine" doesn't work here.&lt;/p&gt;

&lt;p&gt;So I actually made the teacher bigger. I took the translation-only model from 3B to 10B — &lt;strong&gt;more than 3x&lt;/strong&gt;. The result: &lt;strong&gt;no significant difference&lt;/strong&gt; (3 wins / 3 losses). More parameters left both the English leakage and the meaning flips exactly where they were. What &lt;em&gt;helped&lt;/em&gt; wasn't size but &lt;strong&gt;a different line of model designed for low-resource languages&lt;/strong&gt; (English→Swahili passes went 0/7 → 5/7). Though that 5/7 rests on only 7 items too — "it helped" isn't a verdict; read on the same yardstick as the 3-3 split, it's a strong signal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Make the teacher bigger" isn't something you can buy in a low-resource language.&lt;/strong&gt; What you can buy is "pick a teacher that fits the language."&lt;/p&gt;

&lt;h2&gt;
  
  
  The rate limiter differs by direction
&lt;/h2&gt;

&lt;p&gt;The diagnosis taught me one more thing. The easy way to trip here is that "touching the teacher" actually covers &lt;strong&gt;two kinds of intervention&lt;/strong&gt;. Changing the teacher's &lt;strong&gt;"recipe"&lt;/strong&gt; (the English pivot) and making the teacher &lt;strong&gt;"model" itself bigger or stronger&lt;/strong&gt; (strengthening the teacher) are completely different moves. Mix them together and the attribution of the rate limiter looks inverted. Here are the four things I tried around the teacher, re-sorted by kind of intervention (all small n = read "it helped / it didn't" as a signal, not a verdict).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Intervention&lt;/th&gt;
&lt;th&gt;What changed&lt;/th&gt;
&lt;th&gt;Direction&lt;/th&gt;
&lt;th&gt;Result (n)&lt;/th&gt;
&lt;th&gt;What it tells you&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;①&lt;/td&gt;
&lt;td&gt;English pivot&lt;/td&gt;
&lt;td&gt;the teacher's &lt;strong&gt;recipe&lt;/strong&gt; (ja→en→sw)&lt;/td&gt;
&lt;td&gt;ja→sw&lt;/td&gt;
&lt;td&gt;9 wins / 1 loss, 3 ties (13 total, 10 decisive)&lt;/td&gt;
&lt;td&gt;comprehension recovered = the teacher's output had plateaued&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;②&lt;/td&gt;
&lt;td&gt;3x the teacher&lt;/td&gt;
&lt;td&gt;the teacher &lt;strong&gt;model&lt;/strong&gt;'s size (3B→10B, same design)&lt;/td&gt;
&lt;td&gt;Swahili output&lt;/td&gt;
&lt;td&gt;3 wins / 3 losses, 14 ties (no significant difference)&lt;/td&gt;
&lt;td&gt;more size makes no difference&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;③&lt;/td&gt;
&lt;td&gt;switch to a different line&lt;/td&gt;
&lt;td&gt;the teacher &lt;strong&gt;model&lt;/strong&gt;'s design (to NLLB, built for low-resource)&lt;/td&gt;
&lt;td&gt;en→sw&lt;/td&gt;
&lt;td&gt;pass 0/7→5/7 (n=7)&lt;/td&gt;
&lt;td&gt;the right design does move it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;④&lt;/td&gt;
&lt;td&gt;switch to a different line&lt;/td&gt;
&lt;td&gt;the teacher &lt;strong&gt;model&lt;/strong&gt;'s design (to NLLB)&lt;/td&gt;
&lt;td&gt;ja→sw&lt;/td&gt;
&lt;td&gt;tie (teacher-independent)&lt;/td&gt;
&lt;td&gt;even a strong teacher doesn't move it&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Read the table by kind of intervention and the identity of the rate limiter splits cleanly by direction.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;English→Swahili&lt;/strong&gt;: improve either the teacher's "recipe" or its "model" and it goes up (&lt;strong&gt;teacher-bound&lt;/strong&gt; = ③ 0/7→5/7). This is a problem of spelling and phrasing on the output side.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Japanese→Swahili&lt;/strong&gt;: the English pivot, which changes the "recipe," works (① 9 wins / 1 loss), but no amount of making the "model" bigger or stronger gets past the plateau (②③④). The deep understanding it takes to "read through" dropped subjects and idioms in Japanese demands the model's capacity itself (&lt;strong&gt;capacity-bound&lt;/strong&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the previous section's "the teacher's 'recipe' is the rate limiter" (① ja→sw) and "strengthening the teacher model doesn't help" (④ the same ja→sw) don't contradict each other. &lt;strong&gt;What works is the "recipe"; what plateaus is "strengthening the model"&lt;/strong&gt; — same direction, different intervention, different rate limiter. Had I rolled these two into a single "swap the teacher," I'd have gotten the attribution wrong. Had I filed the whole thing under "low-resource languages are just hard," I would never have seen the split at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Low-resource isn't a tail you give up on
&lt;/h2&gt;

&lt;p&gt;Let me put that in business terms.&lt;/p&gt;

&lt;p&gt;For most teams, low-resource languages are &lt;strong&gt;the "long tail you cut off."&lt;/strong&gt; Few users, AI is bad at them, the cost doesn't add up. The edge of the distribution.&lt;/p&gt;

&lt;p&gt;For LYR it's different. &lt;strong&gt;"There's content you can't see because language is in the way" — breaking that is why LYR exists.&lt;/strong&gt; The languages the world is worst at are exactly where LYR should be strongest.&lt;/p&gt;

&lt;p&gt;And what this round showed is that this &lt;strong&gt;isn't willpower — it pencils out economically&lt;/strong&gt;. About $15 per language jumps a model from "doesn't have this language" to "usable but rough." That stacks up straightforwardly as "$15 × number of languages" — line up 50 hard languages and it's $750; 100 and it's $1,500. Less than one engineer-day of salary. After that, you diagnose the rate limiter and invest on the correct side. As long as the diagnosis is right, low-resource languages can be promoted to first-class citizens &lt;strong&gt;cheaply, one at a time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The starting point was always the same — &lt;strong&gt;look at what the failures are made of, not at the number on the score&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Look at the "distribution" of failures, not the absolute score.&lt;/strong&gt; The same "0%" is one thing when the model doesn't have the language and another when it misread the meaning. Same number, opposite moves. Only by looking inside the failures do you find out what the rate limiter really is. (&lt;a href="https://lyr.jp/en/articles/00-manifesto/#1-measure-first" rel="noopener noreferrer"&gt;The manifesto's first principle, "Measure First"&lt;/a&gt; — except that you measure &lt;em&gt;how&lt;/em&gt; it got it wrong, not &lt;em&gt;what score&lt;/em&gt; it got.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The change in the "shape" of the failures is what gives you the diagnosis.&lt;/strong&gt; After pouring in the fundamentals, the failures moved from "strings that aren't even words" to "fluent but the meaning slips." That's more important information than the score going up — because it's a strong clue that &lt;strong&gt;the rate limiter moved from capacity to the teacher side (recipe, model choice)&lt;/strong&gt;. Read the shift, not the size of the gain.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;In low-resource languages a "big teacher" doesn't necessarily help — and they aren't a tail to give up on.&lt;/strong&gt; Tripling the teacher produced no difference; the design built for low-resource won. What you should buy isn't "size" but "a design that fits the language." About $15 per language jumps it from "doesn't have it" to "usable but rough." After that, separate the rate limiter out direction by direction, and knock out the cheap side (teacher choice) first.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Appendix: raw data (per experiment)
&lt;/h3&gt;

&lt;p&gt;Shared conditions: our own 8B model, Swahili (0% at INT4 quantization / 10% at BF16 = base-bound, already established). Evaluated at the deploy quantization as shipped, comparing before and after within the same judge round as a controlled comparison. Every judgment is small n = read the point estimates as a signal, not a settled result.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Experiment&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;th&gt;Conditions &amp;amp; caveats&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;① base injection (continued pretraining)&lt;/td&gt;
&lt;td&gt;pass &lt;strong&gt;0.00 → 0.30&lt;/strong&gt;. Failures &lt;strong&gt;shift&lt;/strong&gt; from "strings that aren't words 7/10" to "fluent but the meaning slips"&lt;/td&gt;
&lt;td&gt;n=10. mono ~100M tok + 25% ja/en replay, ~10.8 hours. Japanese echo and wrong-lang both went to zero&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;① cost&lt;/td&gt;
&lt;td&gt;CPT alone ~$13; with requantization + translation SFT + CPO included, &lt;strong&gt;~$15/language in total&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;② the teacher's "recipe"&lt;/td&gt;
&lt;td&gt;direct (pass 0.15, 1 win) → &lt;strong&gt;English pivot (pass 0.23, 9 wins)&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;base held fixed, only the generation path swapped. Non-tie n=10, so a strong signal rather than settled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;③ teacher size&lt;/td&gt;
&lt;td&gt;dedicated MT 3B→10B gives &lt;strong&gt;3 wins / 3 losses, 14 ties = no significant difference&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;10B leaves the English leak and the meaning flips just as they were&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;③ teacher design&lt;/td&gt;
&lt;td&gt;a different line designed for low-resource: &lt;strong&gt;9 wins / 5 losses&lt;/strong&gt;, en→sw pass &lt;strong&gt;0/7→5/7&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;the advantage is design, not size&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;④ the rate limiter differs by direction&lt;/td&gt;
&lt;td&gt;en→sw improves (teacher-bound) / ja→sw doesn't (capacity-bound)&lt;/td&gt;
&lt;td&gt;reading Japanese (dropped subjects, idioms) demands capacity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;literature (the teacher's own weakness)&lt;/td&gt;
&lt;td&gt;even the best general-purpose model wins only &lt;strong&gt;5.5%&lt;/strong&gt; against dedicated MT on en→xx, and is behind on 84% of 204 languages&lt;/td&gt;
&lt;td&gt;arxiv 2404.13813 / 2309.07423. In low-resource, the reflex of "distill from a giant model" doesn't work&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Related&lt;/strong&gt;: the basics of distillation and SFT/CPO are in &lt;a href="https://lyr.jp/en/articles/specialist-02-fine-tuning/" rel="noopener noreferrer"&gt;Raising a small AI into a specialist at one job&lt;/a&gt;. (Note: the Swahili CPT base forgets other languages, so shipping keeps them separate by switching the base per language. That serving design is a separate article.)&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://lyr.jp/en/articles/specialist-07-low-resource/" rel="noopener noreferrer"&gt;LYR Performance Note #017&lt;/a&gt; — part of the series “Models — smaller, faster, sharper”. The full set is at &lt;a href="https://lyr.jp/en/research/" rel="noopener noreferrer"&gt;lyr.jp/en/research&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>testing</category>
      <category>ai</category>
    </item>
    <item>
      <title>I cut the bottom-rank rate from 64% to 24%, and held the top-rank loss to 12pt</title>
      <dc:creator>LYR</dc:creator>
      <pubDate>Mon, 03 Aug 2026 14:22:40 +0000</pubDate>
      <link>https://dev.to/lyr/i-cut-the-bottom-rank-rate-from-64-to-24-and-held-the-top-rank-loss-to-12pt-4dcb</link>
      <guid>https://dev.to/lyr/i-cut-the-bottom-rank-rate-from-64-to-24-and-held-the-top-rank-loss-to-12pt-4dcb</guid>
      <description>&lt;p&gt;&lt;strong&gt;Cutting the worst translations beat chasing the best ones — a product's value is in its floor, not its ceiling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I cut the bottom-rank rate hard, from 64% to 24% (−40pt), and held the drop in top-rank rate to a small 24% → 12% (−12pt).&lt;/strong&gt; For the 3 firsts I gave up, I handed back 10 lasts (out of 25).&lt;/p&gt;

&lt;p&gt;What breaks the user experience in a subtitle product isn't the average, and isn't the best — it's a single worst case. So I moved my target from the ceiling (peak quality) to the floor (the one worst case). I sold a little ceiling and bought floor.&lt;/p&gt;

&lt;p&gt;The average agreement rate (89–96%) doesn't capture that improvement at all. If the problem is in the tail, the average dilutes it. &lt;strong&gt;The ceiling and the floor move independently&lt;/strong&gt; — what I should have decided first was which of the two I wanted to move.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How it was measured&lt;/strong&gt;: 25 hard cases translated by three configurations (compression only / +rotation / before compression), then ranked blind. &lt;strong&gt;Bottom-rank rate / top-rank rate = the share of cases where a configuration came last / first among the three&lt;/strong&gt; (each sums to 100% across the three configurations). I use the bottom-rank rate as &lt;strong&gt;a proxy for catastrophic failure&lt;/strong&gt; — I confirmed by eye that most of the translations that fell to last place were critical breakdowns.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzor9ag3u2iop88otzdnd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzor9ag3u2iop88otzdnd.png" alt="Bar chart comparing top-rank and bottom-rank rates across three configurations. Compression only: top-rank 24%, bottom-rank 64%. Plus rotation: top-rank 12%, bottom-rank 24%. Before compression, shown for reference: top-rank 64%, bottom-rank 12%. Adding rotation drops the bottom-rank rate by 40 points while the top-rank rate falls only 12 points." width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 1: top-rank rate vs. bottom-rank rate.&lt;/strong&gt; The share of cases where each configuration ranked first / last among the three. Adding rotation cuts &lt;strong&gt;the bottom-rank rate from 64% to 24% (−40pt)&lt;/strong&gt;, while the price — &lt;strong&gt;the drop in top-rank rate — stays at 24% → 12% (−12pt)&lt;/strong&gt;. Before compression, shown for reference, is the mirror image (top-rank 64% / bottom-rank 12%).&lt;br&gt;
&lt;em&gt;Note: held-out drama, 25 hard cases, blind ranking. Ranks are relative, so the top-rank rates sum to 100%, as do the bottom-rank rates.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I &lt;a href="https://lyr.jp/en/articles/specialist-01-quantization/" rel="noopener noreferrer"&gt;compressed my own small model to a quarter of its size (quantization)&lt;/a&gt;. It got faster and cheaper. Quality, on average, barely moved. On paper there was nothing to complain about.&lt;/p&gt;

&lt;p&gt;But when I actually lined the translations up and read them, every so often something made me flinch. A Japanese line comes back still in Japanese. A character's gender swaps. A proper noun turns into something else entirely. The frequency is low. But in subtitles, one of these is enough to shatter immersion instantly.&lt;/p&gt;

&lt;p&gt;Same average, completely different experience. Chasing that discrepancy ended up forcing me to rebuild how I use the word "quality" at all. &lt;strong&gt;What was mattering to the product was not the ceiling (peak quality) but the floor (the one worst case).&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The average makes the difference disappear
&lt;/h2&gt;

&lt;p&gt;First, what was actually happening.&lt;/p&gt;

&lt;p&gt;The heavily compressed model (INT4 = rounding the weight values to 4 bits) was wildly hit or miss. I took 25 deliberately difficult lines (held-out hard cases), translated them with three configurations, and had a stronger model rank them blind. Every number below is a relative rank within those 25 cases — not an incidence rate across production as a whole. Here's what came out.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The compressed model's &lt;strong&gt;top-rank rate&lt;/strong&gt; (the share where it gave the best translation): 6 of 25 = 24%&lt;/li&gt;
&lt;li&gt;The compressed model's &lt;strong&gt;bottom-rank rate&lt;/strong&gt; (the share where it gave the worst translation): &lt;strong&gt;16 of 25 = 64%&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sometimes it produced the best output; often it produced the worst. The spread is wide — the technical term is &lt;strong&gt;bimodal (it splits into a good peak and a bad peak)&lt;/strong&gt;. Superb when it hits, an accident when it misses. As subtitles, that's unusable.&lt;/p&gt;

&lt;p&gt;And yet none of this danger &lt;strong&gt;shows up in the average&lt;/strong&gt;. Here is the token agreement rate before and after compression.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Before compression&lt;/th&gt;
&lt;th&gt;After compression (INT4)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Agreement rate (general text)&lt;/td&gt;
&lt;td&gt;89.5%&lt;/td&gt;
&lt;td&gt;89.8%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agreement rate (JA→EN)&lt;/td&gt;
&lt;td&gt;95.6%&lt;/td&gt;
&lt;td&gt;95.3%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The difference is essentially zero. Had I looked only at these numbers and concluded "no degradation," I would have missed the failures entirely.&lt;/p&gt;

&lt;p&gt;Why is the average so blunt? The loss from compression concentrates in the just-over-10% of "borderline" calls (the story I wrote in &lt;a href="https://lyr.jp/en/articles/specialist-01-quantization/" rel="noopener noreferrer"&gt;Part 1&lt;/a&gt;). The remaining 90% return the same answer as before compression, so the average agreement rate gets diluted by that 90%. &lt;strong&gt;The average waters down the tail — the bad side.&lt;/strong&gt; What mattered was the just-over-10% buried inside it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a single echo is fatal
&lt;/h2&gt;

&lt;p&gt;Why weight "the one worst case" that heavily?&lt;/p&gt;

&lt;p&gt;The north star of subtitle translation is "subtitles with no presence." The translation dissolves naturally into the screen and the user forgets they're even reading a translation — that's the best state. But the moment a Japanese line comes out still in Japanese (echo = the failure where the model returns the source untranslated), you snap out of it: "ah, this is machine translation." &lt;strong&gt;Immersion isn't a continuous quantity. Once it breaks, it goes back to zero.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This has the same structure as the "critical breakdown" I wrote about in &lt;a href="https://lyr.jp/en/articles/02-the-bottleneck-moves/" rel="noopener noreferrer"&gt;the article on the bottleneck&lt;/a&gt;. Even if 99 out of 100 are perfect, one echo decides the impression of the whole experience. Users don't experience the average. &lt;strong&gt;They experience the worst case.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So the metric to chase wasn't average quality. It was the &lt;strong&gt;floor — quality at its worst&lt;/strong&gt;. A catastrophic-failure rate is nothing more than that floor measured upside down (the lower the rate, the higher the floor).&lt;/p&gt;

&lt;p&gt;So how do you measure it? The headline number of this article (64% → 24%) is the share of those 25 hard cases where a model produced the worst translation of the three — the &lt;strong&gt;bottom-rank rate&lt;/strong&gt;. Because these are relative ranks, coming last doesn't automatically mean the output was critical (even before compression, 12% end up last). But when I read the last-place translations one by one, most of them were critical breakdowns: gender flips, mangled proper nouns, subject and object swapped, echo. So the bottom-rank rate can be used as-is as &lt;strong&gt;a proxy for catastrophic failure&lt;/strong&gt; — and that's what "catastrophic-failure rate" means from here on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't raise the ceiling; raise only the floor
&lt;/h2&gt;

&lt;p&gt;So how do you reduce catastrophic failures?&lt;/p&gt;

&lt;p&gt;What worked here was a correction called &lt;strong&gt;rotation&lt;/strong&gt;. If you mathematically "rotate" the model's weights before compressing, the rounding error doesn't pile up on a handful of values; it spreads thin across all of them. Borderline calls become less likely to be flipped by error — it's a technique that suppresses breakdowns in the tail on purpose.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2rofydi935fxoq8wtl3r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2rofydi935fxoq8wtl3r.png" alt="Without rotation, rounding error concentrates on a few weights (the red spikes) and borderline calls flip. With rotation, the error is spread thin and evenly across all weights, and nothing collapses badly." width="800" height="493"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 2: what rotation does to the error.&lt;/strong&gt; Without rotation, rounding error concentrates on a few weights and borderline calls flip. With rotation, the error spreads thin and evenly across the whole model, and the big collapses stop.&lt;/p&gt;

&lt;p&gt;I added it and re-measured the same 25 cases.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Compression only&lt;/th&gt;
&lt;th&gt;+rotation&lt;/th&gt;
&lt;th&gt;(ref.) Before compression&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Residual echo&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Bottom-rank rate&lt;/strong&gt; (= proxy for catastrophic failure)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;64%&lt;/strong&gt; (16 cases)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;24%&lt;/strong&gt; (6 cases)&lt;/td&gt;
&lt;td&gt;12% (3 cases)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Top-rank rate&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;24% (6 cases)&lt;/td&gt;
&lt;td&gt;12% (3 cases)&lt;/td&gt;
&lt;td&gt;64% (16 cases)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Read this carefully. &lt;strong&gt;The top-rank rate went down&lt;/strong&gt; (24% → 12%). Rotation does not make the model "smarter at its best." But &lt;strong&gt;the bottom-rank rate fell from 64% to 24%, to roughly a third&lt;/strong&gt; (mean rank moved 2.40 → 2.12 as well). −12pt given up against −40pt gained — what came back is far larger than what I handed over. Echo went from 4 to 0. Quality at its worst — the floor — moved much closer to before compression (12%).&lt;/p&gt;

&lt;p&gt;Perplexity on general text (ppl = a measure of the model's "lack of confidence," lower is better) tells the same story: compression had degraded it to 10.65, and rotation brought it &lt;strong&gt;back down&lt;/strong&gt; to 9.95, essentially level with the 9.94 from before compression. In exchange for a slight drop in the top-rank rate, &lt;strong&gt;the broken floor — quality on the worst side — recovered.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As a product, that was enough. For subtitles, removing ten worst translations does more than adding one best translation. I dropped the ceiling and chose the floor.&lt;/p&gt;

&lt;p&gt;(The "ceiling or floor" choice itself came up in &lt;a href="https://lyr.jp/en/articles/pareto-01-the-frontier/" rel="noopener noreferrer"&gt;the Pareto article&lt;/a&gt; as "how to pick an operating point." There I laid them out as method A = compression only and method B = rotation. This article digs into the measurement behind that single point. Where you sit is decided not by which one is "better," but by which axis the product needs.)&lt;/p&gt;

&lt;h2&gt;
  
  
  The ceiling doesn't come back. And automatic metrics hide the failures
&lt;/h2&gt;

&lt;p&gt;First, this isn't a clean win. What rotation restores is the floor; &lt;strong&gt;the ceiling doesn't come back&lt;/strong&gt; — it still falls short of before compression (top-rank rate 64%, mean rank 1.48). The peak quality lost to compression cannot be recovered by this correction.&lt;/p&gt;

&lt;p&gt;And one more thing. The scariest part of this episode wasn't the technical side. It was that &lt;strong&gt;the metric I trusted first had made the failures invisible.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An agreement rate of 89–96% — a respectable number. Had I used it as the acceptance criterion, the compressed model would have passed as "essentially no degradation" and gone to production spitting out echoes. It's not that the metric was wrong. And it's &lt;strong&gt;not that averages are bad either&lt;/strong&gt; — ppl (perplexity) is an average too, and it captured the floor's recovery just fine. The question is &lt;strong&gt;what the metric dilutes.&lt;/strong&gt; Token agreement rate waters down the small number of cases where the failures happen with the vast majority of "nothing wrong here," so the worst cases I most wanted to see became structurally invisible. When the problem lives in the tail, question what your average is diluting, and if you have to, count the worst cases directly.&lt;/p&gt;

&lt;p&gt;In the end, what caught the failures was a plain manual job: reading the generated translations by hand and counting critical breakdowns one at a time. I still haven't automated it. If the automatic metric is blunt, the only option is to count the tail directly. Shift what you measure one notch, from the average to the worst case. That was all it took — and I very nearly failed to see it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A product's value is in its floor, not its ceiling.&lt;/strong&gt; In a product where a single breakdown ruins the experience, the floor &lt;em&gt;is&lt;/em&gt; the KPI. Write your acceptance criteria as "&lt;strong&gt;worst-case rate at or below X%&lt;/strong&gt;," not "average score of X or higher" — users don't experience the average, they experience the worst case.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ask what your average metric dilutes.&lt;/strong&gt; Not every average is bad (ppl captured the floor's recovery). But a token agreement rate of 89–96% was watering down the just-over-10% where the failures happen with the vast majority of "nothing wrong here." If the problem is in the tail, switch to a metric that counts worst cases directly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The ceiling and the floor move independently.&lt;/strong&gt; I cut the bottom-rank rate hard, from 64% to 24% (−40pt), and held the drop in top-rank rate to 24% → 12% (−12pt). For the 3 firsts I gave up, I handed back 10 lasts. Decide "which part do I want to improve" first, rather than "make the whole thing better." Aim at the wrong place and even the right technique comes up empty.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The manifesto's third principle — &lt;a href="https://lyr.jp/en/articles/00-manifesto/#3-optimize-the-right-proxy-for-ux" rel="noopener noreferrer"&gt;Optimize the Right Proxy for UX&lt;/a&gt;, and within it "a good proxy looks at the one worst case (the tail), not the average" — was shoved in my face in its plainest form by this episode. In speed or in quality, what ends up mattering is always out at the edge of the distribution.&lt;/p&gt;




&lt;h3&gt;
  
  
  Appendix: raw data
&lt;/h3&gt;

&lt;p&gt;Scope: our own 8B model; held-out drama, 25 hard cases; free generation identical to production, ranked blind by a stronger model.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Compression only → +rotation&lt;/th&gt;
&lt;th&gt;Conditions &amp;amp; caveats&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Bottom-rank rate (proxy for catastrophic failure)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;64% → 24%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Approaching the 12% of BF16 before compression&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Residual echo (source copied verbatim)&lt;/td&gt;
&lt;td&gt;4 → &lt;strong&gt;0&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mean rank / ppl&lt;/td&gt;
&lt;td&gt;2.40 → 2.12 / 10.65 → 9.95&lt;/td&gt;
&lt;td&gt;ppl is essentially level with the 9.94 of BF16 before compression&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shape of the distribution&lt;/td&gt;
&lt;td&gt;6 firsts, 16 lasts (bimodal) → 3 firsts, 6 lasts&lt;/td&gt;
&lt;td&gt;Still short of BF16 before compression (16 firsts, mean rank 1.48) = the ceiling doesn't come back, but the floor does&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bluntness of the average metric&lt;/td&gt;
&lt;td&gt;Agreement rate, general 89.5→89.8%, JA→EN 95.6→95.3% (Δ≈0)&lt;/td&gt;
&lt;td&gt;What's being fixed is the tail — proper nouns, pronouns — and the average agreement rate dilutes it = don't use it to decide&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What rotation is&lt;/td&gt;
&lt;td&gt;A correction that rotates the weights so quantization rounding error is spread out&lt;/td&gt;
&lt;td&gt;A finishing step for recovering the floor, not the ceiling&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;General rule: always evaluate a compressed model at the same quantization and free generation as production, and make the worst-case rate, not the average, the primary KPI (same root as the evaluation principle in &lt;a href="https://lyr.jp/en/articles/specialist-02-fine-tuning/" rel="noopener noreferrer"&gt;quantization eats into fine-tuning&lt;/a&gt;).&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://lyr.jp/en/articles/specialist-06-ceiling-vs-floor/" rel="noopener noreferrer"&gt;LYR Performance Note #016&lt;/a&gt; — part of the series “Models — smaller, faster, sharper”. The full set is at &lt;a href="https://lyr.jp/en/research/" rel="noopener noreferrer"&gt;lyr.jp/en/research&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>testing</category>
      <category>performance</category>
      <category>ai</category>
    </item>
    <item>
      <title>"Add context and the model gets smarter" was half a lie</title>
      <dc:creator>LYR</dc:creator>
      <pubDate>Mon, 03 Aug 2026 14:21:38 +0000</pubDate>
      <link>https://dev.to/lyr/add-context-and-the-model-gets-smarter-was-half-a-lie-2hc3</link>
      <guid>https://dev.to/lyr/add-context-and-the-model-gets-smarter-was-half-a-lie-2hc3</guid>
      <description>&lt;p&gt;&lt;strong&gt;What RAG and injecting context into the prompt fill in is "missing knowledge" — a shortfall in comprehension capacity stays open even with the answer right in front of the model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"Add context and the model gets smarter" was only half true.&lt;/p&gt;

&lt;p&gt;The gaps it fills are &lt;strong&gt;the ones you could look up&lt;/strong&gt;. Speaker, proper nouns, dropped subjects — context filled all of those (13-0). But deep reading comprehension and register &lt;strong&gt;don't close even with the answer sitting right in front of the model&lt;/strong&gt; — that is a question of capacity, not of raw material.&lt;/p&gt;

&lt;p&gt;In a production-equivalent full factorial, the loss rate against the 27B stayed at 76% / 75% / 76% no matter how I supplied the context. And &lt;strong&gt;the most expensive move (baking it into the weights) couldn't beat the cheapest one (pasting it into the prompt on the spot)&lt;/strong&gt; — 94% identical outputs. Which half of the problem you have is something you can tell apart before you invest.&lt;/p&gt;

&lt;p&gt;"If the model isn't smart enough, give it more context" — that's the most popular prescription in AI development right now. &lt;strong&gt;RAG&lt;/strong&gt; (retrieving documents and handing them to the model along with the prompt) is an extension of the same idea. Give it the surrounding information and the model will "read the context" and answer correctly.&lt;/p&gt;

&lt;p&gt;I assumed the same thing. In subtitle translation, my own small model (8B = 8 billion parameters) loses to a large model (27B = 27 billion) on reading comprehension. So — &lt;strong&gt;if I hand it the lines before and after&lt;/strong&gt; — surely the small model catches up? Before investing, I measured.&lt;/p&gt;

&lt;p&gt;The result split cleanly down the middle. &lt;strong&gt;Half of it was true, and half of it was a lie.&lt;/strong&gt; And if I hadn't caught the lie, I was about to pour weeks into a training investment that would have bought nothing. &lt;strong&gt;And more than that — which half your problem falls on is something you can tell apart before you invest.&lt;/strong&gt; If it's a gap you could look up, context fills it cheaply; if it's a shortfall in comprehension capacity, only size moves it. That distinction is what decides whether you bet on RAG or on the model.&lt;/p&gt;

&lt;h2&gt;
  
  
  First — context really did work
&lt;/h2&gt;

&lt;p&gt;The first experiment was to measure the upper bound: if the context were &lt;strong&gt;perfect&lt;/strong&gt;, how much better does the small model get? Speaker gender, the correct reading of proper nouns, the dropped subject — I prepared the state of the scene omnisciently, then pitted &lt;strong&gt;the version handed perfect context&lt;/strong&gt; against &lt;strong&gt;the current version handed none&lt;/strong&gt;, on the same 8B model.&lt;/p&gt;

&lt;p&gt;The judging was &lt;strong&gt;pairwise&lt;/strong&gt; (put two translations side by side and pick the better one, item by item; the sign wobbles less than it does with an overall score). Measured across four episodes of one drama, 86 items —&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With perfect context: 40 wins / without: 22 wins / 24 ties. 65% on a decisive-only basis (ties excluded from the denominator), statistically significant (p≈0.03).&lt;/strong&gt; Context really did work. So far, the prescription holds.&lt;/p&gt;

&lt;h2&gt;
  
  
  — But break down &lt;em&gt;what&lt;/em&gt; worked
&lt;/h2&gt;

&lt;p&gt;The trouble started here. I split out what had worked, dimension by dimension, and recounted.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension that worked&lt;/th&gt;
&lt;th&gt;Record&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Speaker gender (ore/watashi — speech style)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8-0&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Proper nouns (fixing the reading and the transliteration)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;3-0&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Restoring dropped subjects (who, to whom)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2-0&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;— Total (clean)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;13-0&lt;/strong&gt; (p≈0.0001)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Register that fits the scene&lt;/td&gt;
&lt;td&gt;4-4 (a wash)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Word choice&lt;/td&gt;
&lt;td&gt;7-10 (if anything, worse)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Semantic correctness (negation, polarity)&lt;/td&gt;
&lt;td&gt;0-1 (no movement)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;(The dimensions aren't exhaustive, and one item can fall under several of them. So the dimensions don't add up to the overall 40 wins / 22 losses.)&lt;/p&gt;

&lt;p&gt;As you can see, almost all of what worked was concentrated in the top three dimensions — &lt;strong&gt;speaker gender, proper nouns, dropped subjects&lt;/strong&gt;. And those three have something in common: &lt;strong&gt;every one of them is something you could look up&lt;/strong&gt;. Who is speaking, how the name is read, who the dropped subject is. It's all there in the script if you go and look — these are &lt;strong&gt;gaps in knowledge&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;On the other side, &lt;strong&gt;register for the scene was a wash&lt;/strong&gt; and &lt;strong&gt;semantic correctness didn't move at all&lt;/strong&gt;. Put the raw material — the context — right in front of it, and the 8B still can't translate the difference. This isn't a gap in knowledge; it's a matter of &lt;strong&gt;capacity for comprehension and expression&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Incidentally, until not long ago I had concluded that "context doesn't help — it's a draw." That was because &lt;strong&gt;I was measuring impoverished context with a wobbling score&lt;/strong&gt;. Mix a component that works (gender) and one that doesn't (register) into a single overall score and they cancel each other out, and it looks like a draw. &lt;strong&gt;Only by splitting it out by dimension did the 13-0 sign become visible&lt;/strong&gt; (&lt;a href="https://lyr.jp/en/articles/00-manifesto/#1-measure-first" rel="noopener noreferrer"&gt;the manifesto's first principle, Measure First&lt;/a&gt; — how you measure included).&lt;/p&gt;

&lt;h2&gt;
  
  
  The main question — does context let the small model catch the large one?
&lt;/h2&gt;

&lt;p&gt;The upper-bound experiment told me that with perfect context there are dimensions where it works. Now the practical question: &lt;strong&gt;if I hand it the surrounding lines, does the 8B catch the 27B?&lt;/strong&gt; This is the fork in the investment decision.&lt;/p&gt;

&lt;p&gt;I ran my own 8B against the large 27B on 434 manga items, Japanese→English. Exactly the same prompt form as production, generation randomness pinned to zero (&lt;strong&gt;temp0&lt;/strong&gt; = the same answer comes out every time; this keeps the experiment's variables clean). On top of that I compared &lt;strong&gt;three ways of supplying the context, with everything else held constant&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A: no context&lt;/strong&gt; (current)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;B: context injected into the prompt on the spot&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C: context baked into the weights by training&lt;/strong&gt; (context-aware CPO = a version trained on preferences with the context attached)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then I ran each against the 27B and looked at &lt;strong&gt;the loss rate against the 27B&lt;/strong&gt; (decisive-only basis, ties excluded).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkv2tmcxuafnzohanjn00.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkv2tmcxuafnzohanjn00.png" alt="The loss rate against the 27B stays flat however the context is supplied: 76% with no context, 75% injected into the prompt, 76% baked in by training" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 1: the loss rate against the 27B doesn't move with how you supply the context.&lt;/strong&gt; No context 76% / injected into the prompt 75% / baked in by training 76%. However I supplied it, the gap didn't budge.&lt;br&gt;
&lt;em&gt;Note: 434 manga items, temp0, decisive-only basis (ties excluded).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No context 76% → injected into the prompt 75% → baked into the weights 76%&lt;/strong&gt; (this full factorial is all one and the same temp0 run). &lt;strong&gt;However&lt;/strong&gt; I supplied the context, the gap to the 27B didn't budge. On this temp0, decisive-only basis, the number of items where the 8B "won strongly" against the 27B was, across all three conditions, &lt;strong&gt;zero&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Even with the answer right in front of it, it can't use it
&lt;/h2&gt;

&lt;p&gt;Why doesn't it move? It clicked once I lined up the outputs from the version regenerated with the context actually handed over (B, injected into the prompt). &lt;strong&gt;Even with the correct context right in front of it, the 8B can't put it to use.&lt;/strong&gt; All of the following are outputs produced &lt;em&gt;with&lt;/em&gt; that context.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;「太陽に溶かされて」 ("melted by the sun" — Japanese leaves the subject unsaid; the preceding line, a poem about wings, had been handed over): the 8B picked the wrong subject and gave &lt;strong&gt;"I'd be melted"&lt;/strong&gt;; the 27B correctly gave &lt;strong&gt;"they melt"&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;「天文部を頼む」 ("take care of the astronomy club") (the context says the request is being made &lt;em&gt;to you&lt;/em&gt;): the 8B translated the direction &lt;strong&gt;backwards&lt;/strong&gt;; the 27B correctly gave &lt;strong&gt;"I want you to help"&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The character name 「相川仁」 (the given-name kanji 仁 has several valid readings): the 8B missed the reading with &lt;strong&gt;"Masaru"&lt;/strong&gt;; the 27B gave &lt;strong&gt;"Jin"&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The raw material — the context — was handed over identically in both cases. The gap shows up anyway. Which means &lt;strong&gt;the ability to &lt;em&gt;use&lt;/em&gt; context is itself rate-limited by the model's capacity&lt;/strong&gt;. Put the knowledge right in front of it, and if the capacity to read it isn't there, it can't be used.&lt;/p&gt;

&lt;p&gt;There was a clinching symptom, too. Given long context, the 8B &lt;strong&gt;broke the output format on 19 items&lt;/strong&gt; (the 27B, on 4). The limit of capacity shows up not only in accuracy but as a drop in robustness like this.&lt;/p&gt;

&lt;h2&gt;
  
  
  "Baking it into the weights" didn't beat "handing it over on the spot" by an inch
&lt;/h2&gt;

&lt;p&gt;Last, I tested the most expensive option — &lt;strong&gt;baking the context into the weights (C)&lt;/strong&gt;. Instead of putting it into the prompt on the spot (B), train preference on data that carries the context, and maybe the model learns to use context better. That was the hope.&lt;/p&gt;

&lt;p&gt;The result was blunt. &lt;strong&gt;The trained version (C) and the hand-it-over-on-the-spot version (B) produced 94% identical outputs at temp0&lt;/strong&gt; (the 6% that differed was trivial). Going to the trouble of training on 256 pairs of material got me &lt;strong&gt;effectively the same thing as pasting the context into the prompt on the spot&lt;/strong&gt;. → This training was &lt;strong&gt;not adopted&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Context engineering is necessary. But &lt;strong&gt;"hand it to the prompt on the spot" is enough&lt;/strong&gt; — there was no value in baking it into the weights. And above all: &lt;strong&gt;however you engineer the context, an 8B on its own doesn't reach a 27B.&lt;/strong&gt; Closing that gap was the job of capacity — a bigger base — not of context (the manifesto's second principle, &lt;a href="https://lyr.jp/en/articles/00-manifesto/#2-hunt-the-constraint" rel="noopener noreferrer"&gt;it can still be cheaper and faster&lt;/a&gt; — here: don't optimize the context alone. The rate limiter was on the capacity side, not the context side).&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Context solves missing knowledge; the wall in front of understanding is capacity.&lt;/strong&gt; Gaps you could look up — speaker, proper nouns, dropped subjects — get filled by context or RAG (13-0, significant). But deep reading comprehension and register don't get filled by handing over material — they need model capacity. RAG is a specific cure for the former and does nothing for the latter. Separate the two before you invest.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Don't measure what works and what's capacity-bound mixed together.&lt;/strong&gt; Mix a dimension that works (gender 8-0) with one that doesn't (register 4-4) into a single overall score and they cancel out, it looks like a draw, and you read the sign wrong. &lt;strong&gt;Only by splitting it out by dimension can you see what works and what doesn't&lt;/strong&gt; (&lt;a href="https://lyr.jp/en/articles/00-manifesto/#1-measure-first" rel="noopener noreferrer"&gt;the manifesto's first principle&lt;/a&gt;). I did in fact measure them mixed once, and wrongly concluded that context doesn't help.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sometimes the most expensive option doesn't beat the cheapest one.&lt;/strong&gt; Baking context into the weights couldn't beat pasting it into the prompt — 94% identical outputs. And on top of that, &lt;strong&gt;handing over the knowledge is useless if the model can't read it&lt;/strong&gt; — with the correct context right in front of it, the 8B still missed subjects and proper nouns. Measure the cheap move and the expensive move on the same footing, before you invest.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Add context and the model gets smarter — that's only half true. What gets filled is the gaps you could look up. The wall in front of understanding is, &lt;a href="https://lyr.jp/en/articles/specialist-02-fine-tuning/" rel="noopener noreferrer"&gt;in the end, model capacity&lt;/a&gt;, and just as &lt;a href="https://lyr.jp/en/articles/03-model-disqualified/" rel="noopener noreferrer"&gt;chasing smarts alone leaves you with something unusable in real time&lt;/a&gt;, &lt;strong&gt;chasing context alone won't get you over the capacity wall&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Appendix: raw data
&lt;/h3&gt;

&lt;p&gt;Only the measurement conditions, judging methods, and cross-checks against a separate run that aren't in the body.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Experiment&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;th&gt;Conditions &amp;amp; caveats&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Upper-bound experiment (perfect context vs none)&lt;/td&gt;
&lt;td&gt;40 wins / 22 losses / 24 ties, p≈0.030&lt;/td&gt;
&lt;td&gt;four drama episodes, 8B-SFT, temp0, pairwise, n=86. All four episodes point the same way&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Split by dimension (the side that worked)&lt;/td&gt;
&lt;td&gt;gender &lt;strong&gt;8-0&lt;/strong&gt; + name &lt;strong&gt;3-0&lt;/strong&gt; + subject &lt;strong&gt;2-0&lt;/strong&gt; = &lt;strong&gt;13-0 (p≈0.0001)&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;spot-checked (ore→watashi, transliteration fixed, subject restored)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Split by dimension (the side that didn't)&lt;/td&gt;
&lt;td&gt;register &lt;strong&gt;4-4 wash&lt;/strong&gt; / word-choice &lt;strong&gt;7-10 (slightly worse)&lt;/strong&gt; / polarity 0-1&lt;/td&gt;
&lt;td&gt;one item can span several dimensions, so the totals don't match the upper bound's 40/22&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The main full factorial (temp0)&lt;/td&gt;
&lt;td&gt;loss rate against the 27B = no context &lt;strong&gt;76%&lt;/strong&gt; / injected into the prompt &lt;strong&gt;75%&lt;/strong&gt; / context trained in &lt;strong&gt;76%&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;434 manga items, production template matched, pairwise. Strong 8B wins in the same run = 0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cross-check against a separate run&lt;/td&gt;
&lt;td&gt;raw wins and losses n=419 → &lt;strong&gt;76%&lt;/strong&gt; on a decisive-only basis&lt;/td&gt;
&lt;td&gt;agrees with the temp0 run independently. The discrepancy in strong wins (0 vs 3) is a run-to-run difference&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Training doesn't beat injection&lt;/td&gt;
&lt;td&gt;trained vs injected on the spot: &lt;strong&gt;94% identical outputs&lt;/strong&gt; at temp0 → not adopted&lt;/td&gt;
&lt;td&gt;context-aware CPO, 256 pairs. The raw effect of context is 72:57 (56%), but the 27B is helped just as much&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Format robustness&lt;/td&gt;
&lt;td&gt;the 8B produced broken JSON on &lt;strong&gt;19 items&lt;/strong&gt; with long context (27B: 4)&lt;/td&gt;
&lt;td&gt;the cost of long context isn't quality alone&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The output examples in the body (「太陽に溶かされて」, 「天文部を頼む」, 「相川仁」) are all outputs from the version regenerated with the context injected into the prompt.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://lyr.jp/en/articles/specialist-05-context-vs-capacity/" rel="noopener noreferrer"&gt;LYR Performance Note #015&lt;/a&gt; — part of the series “Models — smaller, faster, sharper”. The full set is at &lt;a href="https://lyr.jp/en/research/" rel="noopener noreferrer"&gt;lyr.jp/en/research&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>llm</category>
      <category>testing</category>
      <category>ai</category>
    </item>
    <item>
      <title>The "97% improvement" I threw away</title>
      <dc:creator>LYR</dc:creator>
      <pubDate>Mon, 03 Aug 2026 14:20:37 +0000</pubDate>
      <link>https://dev.to/lyr/the-97-improvement-i-threw-away-3jib</link>
      <guid>https://dev.to/lyr/the-97-improvement-i-threw-away-3jib</guid>
      <description>&lt;p&gt;&lt;strong&gt;The flashier the number, the harder you look at the raw output before you kill it&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The automated measurement came back with good news: &lt;strong&gt;junk English down 97%&lt;/strong&gt;. I didn't take the number. I threw it away.&lt;/p&gt;

&lt;p&gt;Going through the raw output one page at a time, the 97% turned out to be two measurement bugs on top of each other. (1) Randomness in the compression step occasionally produces a broken instance, and (2) the aggregator's parse-failure fallback was counting the entire raw text. Measured fairly, all three came out about the same (5 / 7 / 9 words).&lt;/p&gt;

&lt;p&gt;But don't bury the technique itself along with the number. &lt;strong&gt;"The metric is rejected; whether the technique works is still open."&lt;/strong&gt; Drawing the line between what you know and where your knowledge stops is what leaves you room to measure it properly next time.&lt;/p&gt;

&lt;p&gt;Up to the previous parts, I had &lt;a href="https://lyr.jp/en/articles/specialist-01-quantization/" rel="noopener noreferrer"&gt;compressed (quantized)&lt;/a&gt; my own small model to make it fast and cheap. Quality barely drops — except that in the just-under-10% of "borderline" cases, it occasionally falls apart. One form that breakdown takes is &lt;strong&gt;raw English leaking into the translation&lt;/strong&gt; (stray English words left sitting inside the Japanese output).&lt;/p&gt;

&lt;p&gt;To kill this "leftover English," I tried a repair technique. The automated measurement came back with dramatic good news. &lt;strong&gt;Junk English down 97%.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I didn't take that number as it stood. This article is about &lt;strong&gt;why I threw away a spectacular 97%&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The good news: 97%
&lt;/h2&gt;

&lt;p&gt;I applied the repair technique (a post-processing step that recovers the accuracy lost to compression by rearranging the model's internal weights; I'll call it rotation from here on) to a hard-compressed model and had it translate 30 pages of manga. Here's what the aggregate looked like.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Before repair&lt;/th&gt;
&lt;th&gt;After repair&lt;/th&gt;
&lt;th&gt;Change&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Junk English (words)&lt;/td&gt;
&lt;td&gt;968&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;33&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;−97%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pages with junk English left&lt;/td&gt;
&lt;td&gt;19/30&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5/30&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;−74%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agreement with the reference model&lt;sup id="fnref1"&gt;1&lt;/sup&gt;
&lt;/td&gt;
&lt;td&gt;81.6%&lt;/td&gt;
&lt;td&gt;85.8%&lt;/td&gt;
&lt;td&gt;+4.2pt&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;And lined up next to the un-compressed full-precision version (FP16), the story looked perfect.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full-precision version's junk: &lt;strong&gt;3 words&lt;/strong&gt; (essentially clean)&lt;/li&gt;
&lt;li&gt;Hard-compressed version: &lt;strong&gt;968 words&lt;/strong&gt; (compression blew junk up by +965 words)&lt;/li&gt;
&lt;li&gt;Repaired version: &lt;strong&gt;33 words&lt;/strong&gt; (935 words recovered, back to roughly the full-precision level)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;"Compression catastrophically multiplies the junk, and repair brings it back to full-precision levels" — a storyline as clean as a textbook. Take it as it stands, and you can conclude that the repair technique is worth shipping.&lt;/p&gt;

&lt;h2&gt;
  
  
  The number was too good
&lt;/h2&gt;

&lt;p&gt;What stopped me was that &lt;strong&gt;−97% was far too clean&lt;/strong&gt;. Real model breakdowns don't line up that obediently in one direction.&lt;/p&gt;

&lt;p&gt;There was something else: &lt;a href="https://lyr.jp/en/articles/06-you-are-the-bottleneck/" rel="noopener noreferrer"&gt;two separate measurements disagreed&lt;/a&gt;. Measure the same repair technique with a general-text metric (perplexity) and the recovery stops at 29%. A 97% recovery on the translation task only — when &lt;strong&gt;two metrics are orders of magnitude apart&lt;/strong&gt;, one of the two measurements is usually broken.&lt;/p&gt;

&lt;p&gt;So before trusting the aggregate, I decided to &lt;strong&gt;look at the raw output itself&lt;/strong&gt;. I had all three models (full-precision, compressed, repaired) translate 30 pages of manga, lined the outputs up in a browser, and went through them page by page with my own eyes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Re-measuring it fairly
&lt;/h2&gt;

&lt;p&gt;Looking at them, it was obvious immediately. Two corrections were needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Correction 1: recount.&lt;/strong&gt; The aggregator was counting even the model's "talking to itself" as English. Before returning a translation, the model writes a reasoning scratchpad internally (a working area it closes with &lt;code&gt;&amp;lt;/think&amp;gt;&lt;/code&gt;). Pull out just the translation — excluding the scratchpad — and recount, and the junk in the full-precision and repaired versions dropped to single digits.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Correction 2: re-roll the instance.&lt;/strong&gt; But the compressed version's 968 didn't disappear from recounting alone. That instance was emitting raw English &lt;strong&gt;into the translation itself&lt;/strong&gt;, not into the scratchpad (hole 1, below). Re-run the same compression step, draw a healthy instance, and the translation-only count fell to 7 words.&lt;/p&gt;

&lt;p&gt;Here's the result after both corrections (the compressed column is the value from the re-rolled healthy instance).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Full-precision&lt;/th&gt;
&lt;th&gt;Compressed*&lt;/th&gt;
&lt;th&gt;Repaired&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Junk English (words)&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pages with junk left&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;small&gt;* A re-rolled healthy instance. Not the unlucky instance that emitted 968.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;All three, about the same.&lt;/strong&gt; Compare healthy instances against each other and count only the translation, and neither compression nor repair moves the junk much at all. Both the 968 and the 33 were illusions that stood only until those two corrections. The −97% vanished without a trace.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F08odlra1le31ggf80gpt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F08odlra1le31ggf80gpt.png" alt="The automatic metric made it look like a huge gap — 968 for the compressed version against 33 for the repaired one — but recounting the raw output with the same yardstick put all three at 5 to 9 words, with no visible difference" width="800" height="577"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 1: one phenomenon, measured with two yardsticks.&lt;/strong&gt; The automatic metric made it look like a huge gap — 968 words for the compressed version, 33 for the repaired one — but recount the raw translations alone and all three sit at 5 to 9 words, barely different. The −97% was a product of the yardstick.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two holes
&lt;/h2&gt;

&lt;p&gt;So where did that 968 come from? &lt;strong&gt;The two bugs compounded.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hole 1: randomness in the compression.&lt;/strong&gt; The process of compressing a model includes a "calibration" step that tunes the rounding using a small number of samples, and that's where randomness enters. Same procedure, and yet &lt;strong&gt;every run produces a slightly different model&lt;/strong&gt;. One unlucky time, a "broken" compressed version was born, and it emitted raw English instead of a translation. Re-run the same process and all 30 pages were normal, with 7 words of junk. &lt;strong&gt;The 968 was nothing more than one unlucky draw.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hole 2: the aggregator's fallback.&lt;/strong&gt; The program that counts junk was designed to parse the model's structured output (JSON) and pull out just the translation. But &lt;strong&gt;when parsing fails, it falls back to counting the English in the entire raw text&lt;/strong&gt;. The reasoning scratchpad, echoes of the prompt, everything gets counted as English. The chain goes like this.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;broken instance → JSON parse fails → the fallback counts English across the whole raw text → &lt;strong&gt;explodes to 968&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;An unlucky instance (hole 1) times an over-counting fallback (hole 2) multiplied into an enormous fake difference.&lt;/strong&gt; Either one on its own wouldn't have broken this spectacularly.&lt;/p&gt;

&lt;p&gt;Ironically, the supposed "winner" — the repaired version — had a defect of its own. On &lt;strong&gt;29 of 30 pages&lt;/strong&gt;, the &lt;code&gt;&amp;lt;/think&amp;gt;&lt;/code&gt; tag from the reasoning scratchpad had leaked out ahead of the translation. The aggregate said not a word about that regression.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep only what's real
&lt;/h2&gt;

&lt;p&gt;Once the noisy numbers were thrown out, this is all the "real" I had left.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Perplexity on general text: 10.65 → 10.42&lt;/li&gt;
&lt;li&gt;Agreement with the reference model: 81.6% → 85.8%&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Small, but solid improvements. Nothing spectacular.&lt;/p&gt;

&lt;p&gt;And one more thing: I was careful about &lt;strong&gt;how I threw it away&lt;/strong&gt;. I did not conclude that "the repair technique doesn't work." Both the &lt;code&gt;&amp;lt;/think&amp;gt;&lt;/code&gt; leakage and the failure to reduce junk could well come from &lt;strong&gt;a confound in my own measurement procedure&lt;/strong&gt; (I measured through a makeshift evaluation path rather than the proper server). So I closed it out this way — &lt;strong&gt;"the −97% automatic metric is rejected; whether this repair works in production is still open, and it needs to be measured properly again."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Don't confuse "the measurement was wrong" with "the technique was wrong." Being fair means &lt;strong&gt;not killing the technique as collateral damage&lt;/strong&gt; — and that matters as much as killing the flashy number.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The flashier the number, the more you look at the raw output before killing it.&lt;/strong&gt; A number as clean as −97%, or metrics disagreeing by orders of magnitude, isn't a victory — it's an alarm. Don't accept good news until you've looked at &lt;strong&gt;the raw output upstream of the aggregate, page by page, with your own eyes&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pin the seed on non-deterministic steps, and suspect the aggregator's fallback.&lt;/strong&gt; If randomness is in the mix, a single run tells you nothing but instance-to-instance variation (&lt;strong&gt;an improvement that doesn't reproduce isn't an improvement&lt;/strong&gt;). And a fallback on parse failure will quietly manufacture an enormous fake signal — look at what it's actually counting once it has swallowed the error.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Close out measurement errors and technique errors separately.&lt;/strong&gt; When you throw away a false victory, don't bury the technique with it. Drawing the line — "the metric is rejected, the technique is still open" — is what leaves you room to measure it properly next time.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And underneath all of this sits &lt;a href="https://lyr.jp/en/articles/00-manifesto/#1-measure-first" rel="noopener noreferrer"&gt;the manifesto's first principle, Measure First&lt;/a&gt; — but measure it &lt;em&gt;right&lt;/em&gt;. &lt;strong&gt;A wrong measurement is worse than no measurement.&lt;/strong&gt; Because it lets a false victory ship as a real one.&lt;/p&gt;




&lt;h3&gt;
  
  
  Appendix: raw data
&lt;/h3&gt;

&lt;p&gt;Scope: a 4B model compressed hard (INT4) + learned rotation repair, translating 30 pages of manga, measured on an A100.&lt;/p&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;Number&lt;/th&gt;
&lt;th&gt;Conditions &amp;amp; caveats&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Automatic metric (wrong)&lt;/td&gt;
&lt;td&gt;junk English 968→33 words (&lt;strong&gt;−97%&lt;/strong&gt;), pages with junk left 19/30→5/30&lt;/td&gt;
&lt;td&gt;against the FP16 baseline = FP16: 3 / compressed: 968 / repaired: 33&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fair re-measurement (translation text only)&lt;/td&gt;
&lt;td&gt;FP16=5 / compressed=7 / repaired=9 words (pages with junk left 4/5/8) = &lt;strong&gt;all three about the same&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;the compressed version's 7 is a re-rolled healthy instance, not the instance that emitted 968&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hole 1: non-determinism&lt;/td&gt;
&lt;td&gt;the compressed version occasionally goes degenerate and emits raw English&lt;/td&gt;
&lt;td&gt;regenerate and it's 30/30 clean. In production the instance-to-instance risk remains&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hole 2: the aggregator's fallback&lt;/td&gt;
&lt;td&gt;on JSON parse failure it counts the English across the whole raw text&lt;/td&gt;
&lt;td&gt;the fallback manufactured an enormous fake signal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Improvements that survive as real&lt;/td&gt;
&lt;td&gt;wikitext ppl 10.65→10.42, teacher-forced agreement 81.6→85.8%&lt;/td&gt;
&lt;td&gt;recovery on general text stops at &lt;strong&gt;about 29%&lt;/strong&gt; of the gap (orders of magnitude away from the "97%" on the translation task = a sign one of the two is broken)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Side effect of the repaired version&lt;/td&gt;
&lt;td&gt;the &lt;code&gt;&amp;lt;/think&amp;gt;&lt;/code&gt; tag showed up ahead of the JSON on 29 of 30 pages&lt;/td&gt;
&lt;td&gt;never appears in the aggregate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unresolved&lt;/td&gt;
&lt;td&gt;possible confounding from the measurement path (a non-standard serve)&lt;/td&gt;
&lt;td&gt;needs re-evaluation on the proper serve path + free generation + pairwise judge + a fixed calib seed. Not "rejected" but "requires a proper evaluation"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://lyr.jp/en/articles/specialist-04-measurement-artifact/" rel="noopener noreferrer"&gt;LYR Performance Note #014&lt;/a&gt; — part of the series “Models — smaller, faster, sharper”. The full set is at &lt;a href="https://lyr.jp/en/research/" rel="noopener noreferrer"&gt;lyr.jp/en/research&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;"Agreement with the reference model" = how well the compressed version reproduces the next word that the un-compressed full-precision version (FP16) produces (top-1 agreement rate under teacher forcing). The +4.2pt means "it moved a little closer to FP16's behavior," not that the translation itself got better.&amp;nbsp;↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>machinelearning</category>
      <category>testing</category>
      <category>ai</category>
    </item>
    <item>
      <title>The AI that was smart on the bench suddenly started making mistakes in production</title>
      <dc:creator>LYR</dc:creator>
      <pubDate>Mon, 03 Aug 2026 14:19:35 +0000</pubDate>
      <link>https://dev.to/lyr/the-ai-that-was-smart-on-the-bench-suddenly-started-making-mistakes-in-production-463j</link>
      <guid>https://dev.to/lyr/the-ai-that-was-smart-on-the-bench-suddenly-started-making-mistakes-in-production-463j</guid>
      <description>&lt;p&gt;&lt;strong&gt;The one reason "the test score" and "the real-world skill" came apart&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A fine-tuned 8B model was a star pupil on the benchmark, and then &lt;strong&gt;lost&lt;/strong&gt; to the smaller 4B in a production-equivalent setup (21 to 11). It looked like the limit of the model's capacity.&lt;/p&gt;

&lt;p&gt;The culprit was neither the model nor the training. It was that &lt;strong&gt;the precision I trained at and the precision production ran at were different&lt;/strong&gt;. Putting the same adapter on both bases and comparing them, the verdict came back 23 to 2: it was the environment mismatch.&lt;/p&gt;

&lt;p&gt;Once I re-trained with production's compression priced in, the 8B came out ahead of the 4B. &lt;strong&gt;Hold the conditions you train the skill under and the conditions you serve it under to the same thing.&lt;/strong&gt; That alone was enough for the skill that had gone missing to show up intact.&lt;/p&gt;

&lt;p&gt;I was holding a winning hand.&lt;/p&gt;

&lt;p&gt;I wanted better translation quality. Which means the bigger model — an 8B (8 billion parameters) remembers more than a smaller 4B and can read subtler context. And in fact the 8B I'd trained with the fine-tuning from &lt;a href="https://lyr.jp/en/articles/specialist-02-fine-tuning/" rel="noopener noreferrer"&gt;last time&lt;/a&gt; was posting unimpeachable numbers on my own benchmark. All that was left was to put it into production. That's what I thought.&lt;/p&gt;

&lt;p&gt;But when I loaded it into a production-equivalent setup and re-measured quality, that 8B &lt;strong&gt;lost&lt;/strong&gt; to the 4B that was supposed to be the smaller one. On one evaluation, 21 to 11. The order is backwards. The bigger model is supposed to be the smarter one — and yet in production the smaller one is winning.&lt;/p&gt;

&lt;p&gt;For a moment I was about to conclude: put Live translation on the 4B, plain and simple. The bigger model just isn't suited to this use case.&lt;/p&gt;

&lt;p&gt;That was the mistake. The 8B hadn't gotten weaker. &lt;strong&gt;The 8B I was measuring and the 8B I put into production were two different things.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The model's "precision" was different on the bench and in production
&lt;/h2&gt;

&lt;p&gt;Before the reveal, one piece of vocabulary. &lt;strong&gt;Quantization&lt;/strong&gt; is the compression technique that takes the model — that "huge mountain of numbers" — and re-stores it with fewer bits so it gets lighter. I covered it in detail in &lt;a href="https://lyr.jp/en/articles/specialist-01-quantization/" rel="noopener noreferrer"&gt;Part 1&lt;/a&gt;, but the gist is this: to run it fast and cheap on a production GPU, you compress the model before you load it.&lt;/p&gt;

&lt;p&gt;That's where the pitfall was. Without ever deciding to, my workflow had ended up like this.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fine-tuning (training) happens at full precision.&lt;/strong&gt; In BF16, a format that holds the numbers finely, I train the translation skill into the model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production (deployment) runs compressed.&lt;/strong&gt; I load it in INT4, a format shrunk to a quarter of the size, and take the win on speed and cost.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, &lt;strong&gt;the form the skill was trained into&lt;/strong&gt; and &lt;strong&gt;the form the customer got&lt;/strong&gt; were different. The benchmark measures the full-precision form; production runs the compressed form. It's as if two different people had written the exam paper and the real one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Same adapter, different base — and the result flipped
&lt;/h2&gt;

&lt;p&gt;Confirming the suspicion was anticlimactically easy. Take &lt;strong&gt;the exact same fine-tuning (the adapter)&lt;/strong&gt;, put it on two bases, and have them fight over the same 40 items.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Base A = &lt;strong&gt;full precision (BF16)&lt;/strong&gt;. The same form it was trained in.&lt;/li&gt;
&lt;li&gt;Base B = &lt;strong&gt;compressed (INT4)&lt;/strong&gt;. The form deployed to production.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(An adapter is a "skill-correction part" you bolt onto a base model after the fact. The base changed; the correction bolted on top stayed identical down to the last bit.)&lt;/p&gt;

&lt;p&gt;The result was blunt. Judging I handed to &lt;strong&gt;opus&lt;/strong&gt; (put the two translations side by side in front of a third-party high-capability AI and have it decide which one is better).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Same adapter, base only differs, out of 40 items, opus verdict&lt;/th&gt;
&lt;th&gt;Wins&lt;/th&gt;
&lt;th&gt;Ties&lt;/th&gt;
&lt;th&gt;Losses&lt;/th&gt;
&lt;th&gt;Serious defects&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Full precision (BF16) = same as training&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;23&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compressed (INT4) = production deployment&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;23&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;22&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The same skill was supposedly trained into both, and merely compressing the base dropped 23 wins to 2. And when I read through the defects one by one, &lt;strong&gt;subject mix-ups&lt;/strong&gt; (getting whose line it is wrong) and &lt;strong&gt;polarity flips&lt;/strong&gt; (turning "doesn't" into "does") — the kind of error that breaks the backbone of a sentence — came &lt;strong&gt;entirely from the compressed side&lt;/strong&gt;. The 3 defects left on the full-precision side were all minor ones of another kind.&lt;/p&gt;

&lt;p&gt;The good scores on the bench didn't reproduce in production. Not because of capability, and not because the training had failed. &lt;strong&gt;The form I measured and the form I ran were different.&lt;/strong&gt; That was all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why compression makes the skill go dull
&lt;/h2&gt;

&lt;p&gt;You might find that odd. In Part 1 I wrote that "compressing it barely costs you any smarts (−1 point of quality)." Surely that's a different story.&lt;/p&gt;

&lt;p&gt;There's no contradiction. The two act in different places.&lt;/p&gt;

&lt;p&gt;The skill you train in through fine-tuning is a correction that sits &lt;strong&gt;thin and wide&lt;/strong&gt; across the whole model. "In this context the subject is this one," "this tone gets translated like that" — a delicate overlay whose job is to tip close calls onto the right side. And compression shaves off exactly that &lt;strong&gt;close-call margin&lt;/strong&gt; first. Round the numbers coarsely and the majority doesn't move, but the borderline decisions flip easily. The "subject" and the "negation" that fine-tuning had carefully tipped the right way get tipped back the other way by compression's rounding error.&lt;/p&gt;

&lt;p&gt;Here's the analogy. When I trained the skill in, I drew the lines with a high-precision ruler — one with fine gradations. In production I swapped it for a ruler with coarse gradations and tried to copy those lines across. The finer the line, the less of it a coarse ruler can capture.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix: train it in the production form
&lt;/h2&gt;

&lt;p&gt;If that's the cause, the fix is obvious. &lt;strong&gt;Re-train the fine-tuning on the same compressed base you deploy to production.&lt;/strong&gt; Draw the lines with the coarse ruler from the start. Build the skill with the rounding error already priced in, and that skill shows up in production intact. This way of "holding training and production to the same precision" is what's called quant-aware training (training with production precision priced in).&lt;/p&gt;

&lt;p&gt;I re-measured on the same 40 items.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Live translation, 40 items, opus verdict&lt;/th&gt;
&lt;th&gt;Wins&lt;/th&gt;
&lt;th&gt;Ties&lt;/th&gt;
&lt;th&gt;Losses&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;8B re-trained at production precision vs 4B in production form (INT8)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;16&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8B re-trained at production precision vs the old, mismatched 8B&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The clearest effect was in the head-to-head against the old, mismatched 8B. It came out ahead 20 to 8, and &lt;strong&gt;counting only the items where the verdict was clear-cut, it was 10 to 0&lt;/strong&gt; — every subject and polarity error stayed on the old side, and the re-trained side was clean. Swap the opponent for "the 4B in its production form" and the 8B still showed &lt;strong&gt;no regression&lt;/strong&gt; (16 wins / 15 ties / 9 losses, n=40. With 15 ties that isn't enough to declare a winning record, but it is at least not losing). The assumption that "it loses to the 4B" fell apart right here. On Manga translation, it also held echo (copying the source verbatim) at zero across 434 items.&lt;/p&gt;

&lt;p&gt;I withdrew the "Live goes on the 4B" decision. The 8B had never been the weak one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before you suspect the model, suspect how you're measuring
&lt;/h2&gt;

&lt;p&gt;What stung most is that I came within an inch of &lt;strong&gt;blaming the model's capacity&lt;/strong&gt;. "The 8B isn't suited to this use case." It's a plausible hypothesis, and concluding it would have settled the matter quickly. But the real culprit wasn't inside the model. It was in &lt;strong&gt;the procedure I used to measure the model&lt;/strong&gt;. The environment for training and the environment for production didn't match — not a model problem, a system problem.&lt;/p&gt;

&lt;p&gt;"An AI that's supposed to be smart suddenly turns stupid in production." When you see that, the first thing to suspect isn't the model's ability. It's &lt;strong&gt;whether the bench and production are really running the same conditions&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Suspect the measurement before you suspect the model.&lt;/strong&gt; When an AI that's supposed to be smart starts making mistakes in production, what to suspect is not the model's capacity but the measurement procedure. Put the same adapter on both forms — the training one and the production one — and you can separate whether the culprit is the model or the environment (it was the latter, 23 to 2).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hold the conditions you train the skill under and the conditions you serve it under to the same thing.&lt;/strong&gt; Fine-tuning and compression are separate steps, but get the interaction between them wrong and the skill you trained in disappears in production. Only once you hold everything from training to serving constant, as one continuous system, does the quality actually arrive.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The bigger the design decision, the harder you should check that the playing field is level.&lt;/strong&gt; A switch from 8B to 4B nearly got decided by a single measurement mismatch. Before you conclude "it isn't suited to this," make sure the conditions you're comparing are genuinely fair.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Appendix: raw data
&lt;/h3&gt;

&lt;p&gt;Conditions: all Live, 40 items, opus pairwise verdict (win / tie / loss).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Experiment&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;th&gt;Conditions &amp;amp; caveats&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Diagnosis (same adapter, different base)&lt;/td&gt;
&lt;td&gt;BF16 base = 23 wins / 15 ties / 2 losses; INT4 base = 2 wins / 15 ties / &lt;strong&gt;23 losses&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Serious defects 3 vs 22. Subject errors and polarity flips all on the INT4 side&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fix confirmed (8B re-trained at production precision)&lt;/td&gt;
&lt;td&gt;vs 4B-INT8 = 16/15/9 (no regression); vs old mismatched 8B = 20/12/8&lt;/td&gt;
&lt;td&gt;10 to 0 on the items with a clear-cut verdict. quant-aware SFT-aug→CPO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Manga&lt;/td&gt;
&lt;td&gt;echo (copying the source verbatim) held at 0/434&lt;/td&gt;
&lt;td&gt;no side effects&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The wrong conclusion I withdrew&lt;/td&gt;
&lt;td&gt;"Live goes on the 4B" (the old 8B lost 21 to 11)&lt;/td&gt;
&lt;td&gt;an apparent loss produced by the BF16-training → INT4-production mismatch&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://lyr.jp/en/articles/specialist-03-quant-mismatch/" rel="noopener noreferrer"&gt;LYR Performance Note #013&lt;/a&gt; — part of the series “Models — smaller, faster, sharper”. The full set is at &lt;a href="https://lyr.jp/en/research/" rel="noopener noreferrer"&gt;lyr.jp/en/research&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>testing</category>
      <category>devops</category>
      <category>ai</category>
    </item>
    <item>
      <title>Taking a small AI's accuracy from 42% to 84% — and on some tasks, level with the giants</title>
      <dc:creator>LYR</dc:creator>
      <pubDate>Mon, 03 Aug 2026 14:18:33 +0000</pubDate>
      <link>https://dev.to/lyr/taking-a-small-ais-accuracy-from-42-to-84-and-on-some-tasks-level-with-the-giants-3cbk</link>
      <guid>https://dev.to/lyr/taking-a-small-ais-accuracy-from-42-to-84-and-on-some-tasks-level-with-the-giants-3cbk</guid>
      <description>&lt;p&gt;&lt;strong&gt;Drawing level with a general-purpose giant on a single task — SFT, CPO, and learning to doubt the "gold data"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accuracy 42% → 84%. On some tasks, level with the giant model currently in service (96). And the model stays small.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What worked wasn't "making it smarter" — it was &lt;strong&gt;narrowing it to one job&lt;/strong&gt;. Most of a giant model's smarts are things LYR's task never needs. Training comes in two stages: model answers for the form, preferences for the flavor.&lt;/p&gt;

&lt;p&gt;But there's a line around what you can train in. &lt;strong&gt;The form of how things are said can be trained in cheaply, but deep comprehension and emotional register need capacity (size).&lt;/strong&gt; The register the 4B struggled with showed up the moment I moved up to 8B.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpo7z8hwpj024mr11z6uw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpo7z8hwpj024mr11z6uw.png" alt="Japanese to English accuracy: the base 4B at 42% goes to 84% with distillation SFT, on par with the retired original model" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 1: Japanese→English accuracy.&lt;/strong&gt; The base 4B sits at 42%. Have it imitate the 27B teacher's translations (distillation SFT) and it jumps to 84%, reaching the same level as the retired original model.&lt;br&gt;
&lt;em&gt;Note: reference-free binary judge, point estimate from a single run.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://lyr.jp/en/articles/specialist-01-quantization/" rel="noopener noreferrer"&gt;Last time&lt;/a&gt; I made my own small model &lt;strong&gt;fast and cheap&lt;/strong&gt;. But that's only half the job. Left as it is, a small model loses on quality to the giant models.&lt;/p&gt;

&lt;p&gt;By how much? Hand an un-fine-tuned small model (4B = 4 billion parameters; from here on, 8B = 8 billion and 27B = 27 billion for the large ones) a Japanese→English translation and its accuracy was only &lt;strong&gt;42%&lt;/strong&gt;. Unusable in practice.&lt;/p&gt;

&lt;p&gt;So how do you close that gap? The answer is Figure 1 above — I pulled that 42% up to &lt;strong&gt;84%&lt;/strong&gt;, the same as the retired original model, and on some tasks all the way to &lt;strong&gt;level with the giant model currently in service&lt;/strong&gt;. And the model stayed small.&lt;/p&gt;

&lt;p&gt;This is about the recipe — and about the wall the recipe can't get over.&lt;/p&gt;

&lt;h2&gt;
  
  
  A giant AI is a jack-of-all-trades
&lt;/h2&gt;

&lt;p&gt;First, why does a small model lose? And why is there room for it to win at all?&lt;/p&gt;

&lt;p&gt;GPT, Claude, the large Qwens — today's giant models &lt;strong&gt;do everything&lt;/strong&gt;: poetry, legal summaries, code, medical questions, and translation too. They're giant precisely because of that range.&lt;/p&gt;

&lt;p&gt;But what LYR needs is &lt;strong&gt;one thing: subtitle translation&lt;/strong&gt;. It never once uses the ability to write poetry, or to write code. &lt;strong&gt;Most of that general-purpose intelligence is dead weight on LYR's task&lt;/strong&gt; (overspec).&lt;/p&gt;

&lt;p&gt;Which means — &lt;strong&gt;if you narrow it to a single job, even a small model ought to reach the giants on that one point&lt;/strong&gt;. Give up generality, get specialization back. That was the bet behind "specialization."&lt;/p&gt;

&lt;h2&gt;
  
  
  Training comes in two stages — model answers, then preferences
&lt;/h2&gt;

&lt;p&gt;So how do you narrow it? You apply a treatment called fine-tuning, in two stages.&lt;/p&gt;

&lt;p&gt;This is actually the same path ChatGPT took to get smart. A base language model → &lt;strong&gt;show it model answers so it follows instructions (SFT)&lt;/strong&gt; → &lt;strong&gt;polish it with human preferences (RLHF)&lt;/strong&gt;. LYR followed the same order.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. SFT: show it model answers, in bulk
&lt;/h3&gt;

&lt;p&gt;Stage one is &lt;strong&gt;SFT (supervised fine-tuning)&lt;/strong&gt;. In short: &lt;strong&gt;show it a huge number of model answers and hammer the form of the task into it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I had the larger giant model (27B) produce the model answers. Have the giant translate a few thousand items, then have the small model imitate those translations. This is called &lt;strong&gt;distillation&lt;/strong&gt;. Picture the student copying out the teacher's answer sheet.&lt;/p&gt;

&lt;p&gt;The effect was dramatic. Japanese→English accuracy went &lt;strong&gt;42% → 84%&lt;/strong&gt; (+42 points). That is the same level as the retired model I had been running in production until recently. Stage one filled in most of the gap.&lt;/p&gt;

&lt;p&gt;That said, SFT has a ceiling. The student &lt;strong&gt;imitates the teacher too faithfully&lt;/strong&gt; — it copies the teacher's phrasing tics wholesale (always rendering "look" as the same literal 「見て」, say). And above all, &lt;strong&gt;what the model fundamentally cannot understand doesn't get fixed by imitation&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. CPO: put a good translation and a bad one side by side
&lt;/h3&gt;

&lt;p&gt;Stage two is &lt;strong&gt;CPO (preference optimization — fine-tuning that teaches the model "preferences")&lt;/strong&gt;. After model answers comes &lt;strong&gt;preference&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The method: &lt;strong&gt;show it a good translation and a bad one as a pair, and have it learn "this one is better."&lt;/strong&gt; It's the stage that corresponds to human feedback (RLHF) in ChatGPT's case. The sense of "this is what natural sounds like" and "this isn't," which model answers alone can't convey, gets trained in by contrast.&lt;/p&gt;

&lt;p&gt;When I applied this, specialized to &lt;strong&gt;Live&lt;/strong&gt; subtitles, subtitle translation quality went from &lt;strong&gt;90 → 96&lt;/strong&gt; (that 90–96 is a score for overall subtitle quality; the 42→84 earlier was accuracy on Japanese→English translation — note that these are different yardsticks). That's &lt;strong&gt;level with the giant model currently in service (96)&lt;/strong&gt;, and within touching distance of the retired original (97). Literal renderings of idioms ("it isn't like you" now coming out as the idiomatic 「あなたらしくない」) and picking the wrong subject got corrected, deliberately, one after another.&lt;/p&gt;

&lt;h2&gt;
  
  
  Doubting the "gold data"
&lt;/h2&gt;

&lt;p&gt;This was the biggest discovery of the whole thing.&lt;/p&gt;

&lt;p&gt;In stage-one SFT, you use the teacher's (27B's) answers as "model answers = the right answer." Naturally, I assumed that one answer was the &lt;strong&gt;gold data&lt;/strong&gt;, and that training meant getting closer to it.&lt;/p&gt;

&lt;p&gt;At some point I doubted that. What if I had the teacher produce &lt;strong&gt;several translations instead of one&lt;/strong&gt;, and re-picked the best of them on quality? The result — &lt;strong&gt;the best candidate disagreed with the "gold data" 86% of the time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In other words, the teacher's first-shot answer — the thing I had been calling "the right answer" — &lt;strong&gt;was not the best one in 86% of cases&lt;/strong&gt;. It was verbose, or too literal, and a better candidate sat elsewhere in the set.&lt;/p&gt;

&lt;p&gt;The lesson: &lt;strong&gt;stop preparing one right answer and training toward it&lt;/strong&gt;. Generate a lot of candidates and &lt;strong&gt;select on quality itself (QE = quality estimation)&lt;/strong&gt;. There is no single "correct translation" for a subtitle. (I've stepped in this trap — where chasing the gold data actually makes things worse — in another setting too.)&lt;/p&gt;

&lt;p&gt;And the method has a second payoff: &lt;strong&gt;it produces the SFT model answers and the CPO material (good/bad pairs) at the same time&lt;/strong&gt;. That 90→96 above was in fact a &lt;strong&gt;combination&lt;/strong&gt;: stage-two CPO applied with this "material re-picked from candidates." What was doing the work wasn't CPO as a technique so much as &lt;strong&gt;the quality of the material you feed it&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How this meshes with quantization
&lt;/h2&gt;

&lt;p&gt;One last warning. The smarts you went to the trouble of training in can be &lt;strong&gt;shaved away&lt;/strong&gt; by &lt;a href="https://lyr.jp/en/articles/specialist-01-quantization/" rel="noopener noreferrer"&gt;last time's quantization&lt;/a&gt;. Fine-tuning's effect sits "thin and wide" across the whole model, so aggressive compression tends to take it out first.&lt;/p&gt;

&lt;p&gt;So &lt;strong&gt;hold fine-tuning and quantization to the same conditions&lt;/strong&gt;. And always evaluate &lt;strong&gt;at the quantization you deploy in production&lt;/strong&gt;. Celebrating "it got smarter" in the uncompressed state means nothing if the gain is gone after compression.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you can train in, and what you can't
&lt;/h2&gt;

&lt;p&gt;Fine-tuning is not a cure-all, though. As I stacked up rounds of training, &lt;strong&gt;the walls you can get over and the walls you can't&lt;/strong&gt; separated out clearly.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Transferable by fine-tuning: the "form" of how things are said.&lt;/strong&gt; Phrasing, idioms, brevity, formatting — the form of &lt;em&gt;how&lt;/em&gt; to say it can be pulled up toward the larger models by fine-tuning, even on a small model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Needs capacity (size): deep comprehension, and emotionally loaded register.&lt;/strong&gt; Who the subject is, which gender, whether a negation applies, what the proper nouns are (= reading comprehension). And a register that matches the temperature of the scene. These two can't be filled in by teaching good/bad alone; they need the model's capacity. In fact, emotionally loaded register only reached giant-model level (98–100%) — a struggle at 4B — &lt;strong&gt;once I moved up to 8B&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To back that up, I ran a controlled experiment. Push the preference training hard on its own and Japanese→English accuracy (comprehension) goes &lt;strong&gt;84 → 85%&lt;/strong&gt; — inside the judge's noise. &lt;strong&gt;The form of how things are said moves; the ceiling on comprehension does not.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To sum up — &lt;strong&gt;the "form" of how things are said is cheap to reach for, even on a small model. But "deep comprehension" and "emotionally loaded register" are the model's capacity itself.&lt;/strong&gt; The recipe and the capacity (the model's size) have to be designed as a set. Specialization isn't magic; it was &lt;strong&gt;the work of telling apart which parts you can reach by training and which parts need capacity&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Most of a giant model's smarts are things your task doesn't need.&lt;/strong&gt; Narrow to one job and even a small model gets there on that one point. Training comes in two stages — model answers (SFT = distillation) for the form, preferences (CPO) for the flavor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Doubt the "gold data."&lt;/strong&gt; Generating candidates and selecting on quality (best-of-N) gets you further than fitting to a single right answer. The best translation is usually not the "right answer" you prepared.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What you can train in is the form of how things are said; what needs capacity is deep comprehension and emotional register.&lt;/strong&gt; The form is cheap to train in, but comprehension and feeling need capacity (size). Design the recipe and the size together.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So now my own small model is &lt;strong&gt;fast&lt;/strong&gt; (last time), cheap, and — on one job — &lt;strong&gt;smart&lt;/strong&gt;. It draws level with a general-purpose giant AI on LYR's task &lt;strong&gt;and nothing else&lt;/strong&gt;. It's the last piece needed to &lt;a href="https://lyr.jp/en/articles/04-borrowed-ai-disappears/" rel="noopener noreferrer"&gt;let go of borrowed AI&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Appendix: raw data
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Experiment&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;th&gt;Conditions &amp;amp; caveats&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SFT (distillation)&lt;/td&gt;
&lt;td&gt;base 4B Japanese→English ~42% → &lt;strong&gt;84%&lt;/strong&gt; (+42pt)&lt;/td&gt;
&lt;td&gt;27B teacher, reference-free binary judge. Multilingual too, thin and wide from a single training run (ES 91 / PT 82 / KO, TH 77 = a gradient in resource volume). The ceiling is the 4B's comprehension capacity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;best-of-N QE&lt;/td&gt;
&lt;td&gt;700 source → 2,800 candidates (N=4, temp0.7) → selection. &lt;strong&gt;best≠gold 86% (451/522)&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Selecting on quality is the right call. Selection that pulls toward gold with chrF and the like is a chasing trap&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CPO (ALMA-R)&lt;/td&gt;
&lt;td&gt;general &lt;strong&gt;Page&lt;/strong&gt; 86.5→91.6 / &lt;strong&gt;Manga&lt;/strong&gt; 83.7→86.9 / &lt;strong&gt;Live&lt;/strong&gt;-specialized &lt;strong&gt;90→96&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;+4 is the same order as the single-seed noise floor of ±3-5pt = directional. Live 96 is level with the 27B currently in service&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;register&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;98–100% = 27B class&lt;/strong&gt; with 8B-CPO&lt;/td&gt;
&lt;td&gt;The register that struggled at 4B shows up once you raise capacity = the register weakness is capacity-bound&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Control for the limit&lt;/td&gt;
&lt;td&gt;binary preference alone 84→85 (within judge noise)&lt;/td&gt;
&lt;td&gt;Preference at the string level doesn't fill in the 4B's comprehension ceiling. It was only cleared by moving up to 8B&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://lyr.jp/en/articles/specialist-02-fine-tuning/" rel="noopener noreferrer"&gt;LYR Performance Note #012&lt;/a&gt; — part of the series “Models — smaller, faster, sharper”. The full set is at &lt;a href="https://lyr.jp/en/research/" rel="noopener noreferrer"&gt;lyr.jp/en/research&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

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