<?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: Pranshu Raj</title>
    <description>The latest articles on DEV Community by Pranshu Raj (@pranshurs).</description>
    <link>https://dev.to/pranshurs</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3980755%2F8fe31a66-dd56-4493-aee5-ced370d1ac0a.jpeg</url>
      <title>DEV Community: Pranshu Raj</title>
      <link>https://dev.to/pranshurs</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pranshurs"/>
    <language>en</language>
    <item>
      <title>A 150M model that beats GPT-4-as-judge at catching RAG hallucinations trained for $0</title>
      <dc:creator>Pranshu Raj</dc:creator>
      <pubDate>Fri, 12 Jun 2026 07:39:10 +0000</pubDate>
      <link>https://dev.to/pranshurs/a-150m-model-that-beats-gpt-4-as-judge-at-catching-rag-hallucinations-trained-for-0-pe0</link>
      <guid>https://dev.to/pranshurs/a-150m-model-that-beats-gpt-4-as-judge-at-catching-rag-hallucinations-trained-for-0-pe0</guid>
      <description>&lt;p&gt;I built GroundCheck, a small open model that checks whether an AI answer is actually supported by the source it cites. It scores 0.682 F1 on the RAGTruth benchmark, ahead of the published GPT-4-turbo-as-judge baseline (0.634), and it returns a verdict in under a second on a laptop CPU. Total compute cost: zero — every training run fit inside Kaggle's free GPU quota.&lt;/p&gt;

&lt;p&gt;Weights, benchmark code, and a pip package are public. This post is the honest version of how it went, including the part where the first model failed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;RAG pipelines answer questions from documents, and sometimes they state things the documents never said: a number quietly changed, "increased" turned into "decreased," a plausible fact invented from nowhere. Checking every answer with a frontier LLM-as-judge works, but it is slow (seconds), priced per token, and ships your data to a third party.&lt;/p&gt;

&lt;p&gt;This is a narrow classification task, and narrow tasks are where small specialized models earn their keep. Premise: source document (plus the user's question when available).&lt;/p&gt;

&lt;p&gt;Hypothesis: the answer. Output: grounded or hallucinated, with a probability.&lt;/p&gt;

&lt;h2&gt;
  
  
  v1: good benchmark, bad model
&lt;/h2&gt;

&lt;p&gt;The first version was ModernBERT-base fine-tuned on RAGTruth, the standard benchmark for this task: 0.688 F1, clear of the GPT-4 judge. Shipped it, felt great.&lt;/p&gt;

&lt;p&gt;Then I ran five quick manual cases — short, realistic inputs like a source saying revenue "increased 12%" and an answer claiming it "fell 12%", or a vaccine's "94% effective" becoming "49% effective". The model called all five grounded. Two out of five correct, and the misses were the embarrassing kind.&lt;/p&gt;

&lt;p&gt;The diagnosis was ordinary distribution shift. RAGTruth is long RAG documents, so the model had learned that distribution and nothing else. On short inputs it defaulted to "grounded." It also trained with a question always prepended, while the library's main entry point sends none, a silent train/inference mismatch on every real call.&lt;/p&gt;

&lt;h2&gt;
  
  
  v2: fix the data, not the model
&lt;/h2&gt;

&lt;p&gt;The fix was three changes to the training mix, none to the architecture:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Short claim–evidence pairs&lt;/strong&gt; (VitaminC): sentences that differ by one small factual (edit) — exactly the failure mode from the manual test.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Programmatic hard negatives&lt;/strong&gt;: take a grounded answer, flip exactly one fact — a number, a date, a direction word, a named entity and label it hallucinated. The original stays in the training set, so the model must compare rather than pattern-match. ~2,700 of these flips are number edits, which is precisely where v1 was blind.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Question dropout&lt;/strong&gt;: half the training rows lose their question, so no-question inference matches training.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One retraining run later (28.5k examples, 3 epochs, a single free P100, under two hours): RAGTruth held at 0.682 F1 — statistically tied with v1 — while VitaminC accuracy hit 0.850, 80% of single-fact flips get caught, and the manual five went 5/5 with confident margins. The first rebalance attempt actually overshot (it flagged too many correct answers), which cost one more run to fix; the intermediate numbers are in the repo history.&lt;/p&gt;

&lt;p&gt;The general lesson, which everyone repeats and I now believe: with a fixed small model, the data mix is the steering wheel. Three data changes moved real-world behavior more than any architecture choice would have.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it doesn't do
&lt;/h2&gt;

&lt;p&gt;Honest limitations, so you can decide if it's useful before installing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It verifies support against the provided source only. A true statement not in the source is, by design, hallucinated.&lt;/li&gt;
&lt;li&gt;It trades some precision for recall on long fact-dense documents — it flags more borderline answers than v1 did. If false alarms cost you more than misses, raise the threshold.&lt;/li&gt;
&lt;li&gt;English only, 512-token source window (chunk longer documents).&lt;/li&gt;
&lt;li&gt;The training data carries research-oriented licenses, so the open model is for research and non-commercial use.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;groundcheck-rag
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;groundcheck&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;GroundCheck&lt;/span&gt;
&lt;span class="n"&gt;gc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GroundCheck&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;gc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;In Q3, revenue increased 12% year-over-year to $2.1 billion.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;answer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The company&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s revenue fell 12% in Q3.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# -&amp;gt; hallucinated
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Code and benchmark harness: &lt;a href="https://github.com/Pranshurs/groundcheck" rel="noopener noreferrer"&gt;https://github.com/Pranshurs/groundcheck&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Weights: &lt;a href="https://huggingface.co/Pranshurs/groundcheck-modernbert" rel="noopener noreferrer"&gt;https://huggingface.co/Pranshurs/groundcheck-modernbert&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The benchmark script reproduces every number above, confidence intervals included.&lt;/p&gt;

&lt;p&gt;I'm also piloting a hosted version trained from scratch on commercially-clean data (sentence-level verdicts, batch log auditing, commercial use allowed). If that's relevant to your team, email me : address is in the repo.&lt;/p&gt;

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