<?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: finetuning</title>
    <description>The latest articles tagged 'finetuning' on DEV Community.</description>
    <link>https://dev.to/t/finetuning</link>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tag/finetuning"/>
    <language>en</language>
    <item>
      <title>RAG vs Fine-Tuning: Which One Should You Actually Choose?</title>
      <dc:creator>EncodeDots Technolabs</dc:creator>
      <pubDate>Mon, 29 Jun 2026 12:28:50 +0000</pubDate>
      <link>https://dev.to/encodedots/rag-vs-fine-tuning-which-one-should-you-actually-choose-aal</link>
      <guid>https://dev.to/encodedots/rag-vs-fine-tuning-which-one-should-you-actually-choose-aal</guid>
      <description>&lt;p&gt;You wired up an LLM, pointed it at a user question about your product, and it confidently invented an API endpoint that doesn't exist. Welcome to the moment every AI engineer eventually hits: the base model is smart, but it doesn't know your company's data, documentation, or latest product changes.&lt;/p&gt;

&lt;p&gt;There are two mainstream ways to fix that-&lt;strong&gt;RAG and fine-tuning&lt;/strong&gt;-but most explanations stop at "it depends." This article goes further, breaking down when retrieval beats retraining, when fine-tuning is the better choice, and how to choose the right approach for real-world AI applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one-line mental model
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;RAG&lt;/strong&gt; = the model looks things up at inference time. Behavior-and sometimes domain-specific patterns-are learned during training.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fine-tuning&lt;/strong&gt; = you bake new behavior into the weights via training. Knowledge/behavior lives inside the model.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The single most useful question to disambiguate them:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Is my problem that the model doesn't know my facts, or that it doesn't behave the way I want?&lt;/p&gt;

&lt;p&gt;Knowledge gap → RAG. Behavior gap → fine-tuning. Most "we need fine-tuning" requests turn out to be knowledge gaps that RAG can solve more efficiently.&lt;/p&gt;

&lt;h2&gt;
  
  
  RAG in code (runnable)
&lt;/h2&gt;

&lt;p&gt;The whole RAG loop is: embed your docs → store the vectors → at query time, embed the question, find the nearest chunks (semantic search), stuff them into the prompt.&lt;/p&gt;

&lt;p&gt;This example runs as-is. Embeddings use &lt;code&gt;sentence-transformers&lt;/code&gt; (local, no API key); generation uses Claude. Swap the local embedding model for a hosted one (OpenAI, Voyage, or Cohere) by replacing the embedder. encode(...) calls.&lt;br&gt;
&lt;/p&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;sentence-transformers numpy anthropic
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ANTHROPIC_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;sk-...   &lt;span class="c"&gt;# for the generation step&lt;/span&gt;
&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;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sentence_transformers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SentenceTransformer&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;anthropic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Anthropic&lt;/span&gt;

&lt;span class="n"&gt;embedder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SentenceTransformer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;all-MiniLM-L6-v2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# small, fast, local
&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Anthropic&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# reads ANTHROPIC_API_KEY from env
&lt;/span&gt;
&lt;span class="c1"&gt;# 1. Offline: chunk + embed your knowledge base
&lt;/span&gt;&lt;span class="n"&gt;docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Refunds are processed within 5 business days.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Enterprise plans include SSO and a 99.9% SLA.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The API rate limit is 100 requests per minute on the Pro tier.&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="n"&gt;doc_vecs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;embedder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;normalize_embeddings&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# (n_docs, dim)
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;retrieve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;embedder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;normalize_embeddings&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;sims&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;doc_vecs&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt;                       &lt;span class="c1"&gt;# cosine sim (vectors are normalized)
&lt;/span&gt;    &lt;span class="n"&gt;top&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sims&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;argsort&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;:][::&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# 2. Online: retrieve, then generate grounded in retrieved context
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;retrieve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;claude-sonnet-4-6&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;max_tokens&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;512&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Answer using ONLY the context below. &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;If it&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s not in the context, say you don&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;t know.&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Context:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;Question: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="si"&gt;}&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="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s the rate limit on Pro?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c1"&gt;# -&amp;gt; The API rate limit is 100 requests per minute on the Pro tier.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In production, you'd replace the in-memory NumPy search with a vector database such as pgvector, Qdrant, Weaviate, or Pinecone to keep retrieval fast as your knowledge base grows. The retrieval logic stays the same-you've simply replaced a linear search with an index built for scale.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why engineers reach for RAG:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Update knowledge by changing a document - no retraining.&lt;/li&gt;
&lt;li&gt;Answers are traceable; you know which chunk produced them.&lt;/li&gt;
&lt;li&gt;Sensitive data stays in your store, not in model weights.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Fine-tuning in code
&lt;/h2&gt;

&lt;p&gt;Fine-tuning doesn't retrieve anything. You train the model on hundreds or thousands of input→output examples until the desired behavior becomes consistent.&lt;/p&gt;

&lt;p&gt;Most providers expect a JSONL file, where each line contains a complete training conversation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"messages"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"system"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Classify the support ticket into: billing, bug, feature_request, other."&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"I was charged twice this month."&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"assistant"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"billing"&lt;/span&gt;&lt;span class="p"&gt;}]}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"messages"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"system"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Classify the support ticket into: billing, bug, feature_request, other."&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The export button does nothing on Safari."&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"assistant"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bug"&lt;/span&gt;&lt;span class="p"&gt;}]}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"messages"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"system"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Classify the support ticket into: billing, bug, feature_request, other."&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Can you add dark mode?"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"assistant"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"feature_request"&lt;/span&gt;&lt;span class="p"&gt;}]}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the dataset is ready, you upload it and start a fine-tuning job. The exact SDK differs between providers, but the workflow looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Adapt to your provider's fine-tuning SDK.
&lt;/span&gt;&lt;span class="n"&gt;job&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fine_tuning&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;training_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ticket_classifier.jsonl&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;base-model-name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;hyperparameters&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;n_epochs&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# poll job.status until "succeeded", then call the resulting model id
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that the model never retrieves external documents at inference time. Everything it learned comes from the training examples you provided.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why engineers reach for it:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Consistent formatting, tone, and behavior at scale without repeating detailed instructions in every prompt.&lt;/li&gt;
&lt;li&gt;Specialized decision-making that's difficult to capture through retrieved documents alone.&lt;/li&gt;
&lt;li&gt;Shorter prompts at inference because the desired behavior is learned during training, which can reduce token costs at high request volumes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The catch&lt;/strong&gt;: every time your requirements change, you need to update the training data and run another fine-tuning job. Data preparation is usually the biggest investment-not the training itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The decision checklist
&lt;/h2&gt;

&lt;p&gt;Run down this list; stop at the first strong signal.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Knowledge changes often?&lt;/strong&gt; → RAG. Retraining on every document update is masochism.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Need source-cited / auditable answers?&lt;/strong&gt; → RAG. Fine-tuned weights can't tell you where an answer came from.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The model keeps getting the format, tone, or judgment wrong-not the facts?&lt;/strong&gt; → Fine-tuning.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Have a few hundred clean, labeled examples?&lt;/strong&gt; Fine-Tuning becomes a realistic option. If not, RAG is usually the faster place to start.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Still unsure?&lt;/strong&gt; → Start with RAG. It's cheaper to build, easier to debug, and solves the most common problem: the model doesn't have access to your knowledge.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And here's the part most posts skip: they're not mutually exclusive. Mature AI systems often fine-tune for behavior and layer RAG on top for fresh knowledge. "&lt;a href="https://www.encodedots.com/blog/rag-vs-fine-tuning" rel="noopener noreferrer"&gt;RAG vs. Fine-Tuning&lt;/a&gt;" is increasingly becoming "RAG + Fine-Tuning."&lt;/p&gt;

&lt;h2&gt;
  
  
  Gotchas I've hit
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Chunking quietly decides your accuracy&lt;/strong&gt;. Bad chunk boundaries-like splitting tables mid-row or creating 2,000-token mega-chunks-hurt retrieval before the model ever sees the question.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;RAG is not plug-and-play&lt;/strong&gt;. Retrieve the wrong context, and the model will confidently produce the wrong answer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Fine-tuning a knowledge problem is the classic expensive mistake&lt;/strong&gt;. If the goal is simply to teach the model your latest pricing," fine-tuning is slow, costly, and goes stale. Use RAG.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No eval = no progress&lt;/strong&gt;. Build a small labeled test set before launch. Without one, you're optimizing blind, and "it feels better" becomes your only metric.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Garbage in, confident garbage out&lt;/strong&gt;. Both approaches amplify whatever you feed them. Clean the data first.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  RAG vs. Fine-Tuning at a Glance
&lt;/h2&gt;

&lt;h3&gt;
  
  
  RAG
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best for&lt;/strong&gt;: Knowledge gaps&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;knowledge Update&lt;/strong&gt;: Edit your documents-no retraining&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Knowledge freshness&lt;/strong&gt;: Always reflects your latest data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Traceable answers&lt;/strong&gt;: Yes, via retrieved context&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Upfront cost&lt;/strong&gt;: Lower&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best first step&lt;/strong&gt;: For most AI applications&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Fine-Tuning
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best for&lt;/strong&gt;: Behavior gaps&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;knowledge Update&lt;/strong&gt;: retrain the model&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Knowledge freshness&lt;/strong&gt;: Fixed until the next training run&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Traceable answers&lt;/strong&gt;: Not inherently&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Upfront cost&lt;/strong&gt;: Higher (data preparation is the biggest cost)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best first step&lt;/strong&gt;: Once behavior becomes the bottleneck&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The "RAG vs Fine-Tuning" debate isn't a turf war - it's a routing decision. Point a knowledge problem at RAG, and a behavior problem at fine-tuning, and most of the confusion disappears.&lt;/p&gt;

&lt;p&gt;For the vast majority of teams, the right first move is RAG: it's cheaper to build, far easier to debug, ships in days instead of weeks, and directly solves the most common failure mode - the model not knowing your stuff. Reach for fine-tuning when the model already has the facts but keeps getting the format, tone, or judgment wrong, and you've got a few hundred clean, labeled examples to teach it. When you've earned the complexity, run both: fine-tune for behavior, layer RAG on top for fresh, traceable facts.&lt;/p&gt;

&lt;p&gt;The expensive mistake to avoid is reaching for fine-tuning to fix a knowledge gap. It's slow, it goes stale, and a retrieval layer would've done the job in a fraction of the time. Start simple, measure with a real eval set, and only add weight to the system when the evidence says you need it.&lt;/p&gt;

</description>
      <category>rag</category>
      <category>ai</category>
      <category>llm</category>
      <category>finetuning</category>
    </item>
    <item>
      <title>Best GPU for DreamBooth Training in 2026 (Ranked)</title>
      <dc:creator>Thurmon Demich</dc:creator>
      <pubDate>Fri, 26 Jun 2026 01:14:26 +0000</pubDate>
      <link>https://dev.to/thurmon_demich/best-gpu-for-dreambooth-training-in-2026-ranked-3pfm</link>
      <guid>https://dev.to/thurmon_demich/best-gpu-for-dreambooth-training-in-2026-ranked-3pfm</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This article was originally published on &lt;a href="https://bestgpuforai.com/articles/best-gpu-for-dreambooth/" rel="noopener noreferrer"&gt;Best GPU for AI&lt;/a&gt;. The full version with interactive tools, FAQ, and live pricing is on the original site.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You found an art style you love, or maybe you want an AI that generates your face accurately. DreamBooth is how you get there -- but it is one of the most VRAM-hungry tasks in consumer AI. Inference is forgiving. Training is not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick answer:&lt;/strong&gt; The RTX 4090 (24GB, ~$1,600) is the best GPU for DreamBooth training. For SD 1.5 DreamBooth only, the RTX 4070 Ti Super (16GB, ~$700) works with optimizations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://bestgpuforai.com/articles/best-gpu-for-dreambooth/" rel="noopener noreferrer"&gt;See the recommended pick on the original guide&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Who this is for
&lt;/h2&gt;

&lt;p&gt;You want to fine-tune Stable Diffusion or Flux models on your own images. DreamBooth creates a personalized model checkpoint that generates specific subjects -- faces, products, art styles, characters. Unlike LoRA, full DreamBooth training modifies the entire model and needs substantially more VRAM.&lt;/p&gt;

&lt;h2&gt;
  
  
  VRAM requirements for DreamBooth
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;DreamBooth Target&lt;/th&gt;
&lt;th&gt;VRAM Needed&lt;/th&gt;
&lt;th&gt;Training Time (1000 steps)&lt;/th&gt;
&lt;th&gt;Minimum GPU&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SD 1.5 (full fine-tune)&lt;/td&gt;
&lt;td&gt;~14GB&lt;/td&gt;
&lt;td&gt;~15 min&lt;/td&gt;
&lt;td&gt;RTX 4060 Ti 16GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SD 1.5 (with prior preservation)&lt;/td&gt;
&lt;td&gt;~16GB&lt;/td&gt;
&lt;td&gt;~25 min&lt;/td&gt;
&lt;td&gt;RTX 4070 Ti Super&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SDXL (full fine-tune)&lt;/td&gt;
&lt;td&gt;~22GB&lt;/td&gt;
&lt;td&gt;~45 min&lt;/td&gt;
&lt;td&gt;RTX 4090&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SDXL (with prior preservation)&lt;/td&gt;
&lt;td&gt;~24GB&lt;/td&gt;
&lt;td&gt;~60 min&lt;/td&gt;
&lt;td&gt;RTX 4090&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flux DreamBooth&lt;/td&gt;
&lt;td&gt;~26GB&lt;/td&gt;
&lt;td&gt;~90 min&lt;/td&gt;
&lt;td&gt;RTX 5090&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These numbers assume FP16 training with gradient checkpointing enabled. Without gradient checkpointing, add 30-50% more VRAM.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;VRAM chart available at the &lt;a href="https://bestgpuforai.com/articles/best-gpu-for-dreambooth/" rel="noopener noreferrer"&gt;original article&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://bestgpuforai.com/articles/best-gpu-for-dreambooth/" rel="noopener noreferrer"&gt;See the recommended pick on the original guide&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  GPU comparison for DreamBooth
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;GPU&lt;/th&gt;
&lt;th&gt;VRAM&lt;/th&gt;
&lt;th&gt;SD 1.5 DB&lt;/th&gt;
&lt;th&gt;SDXL DB&lt;/th&gt;
&lt;th&gt;Flux DB&lt;/th&gt;
&lt;th&gt;Price&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;RTX 5090&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;32GB&lt;/td&gt;
&lt;td&gt;~8 min&lt;/td&gt;
&lt;td&gt;~25 min&lt;/td&gt;
&lt;td&gt;~55 min&lt;/td&gt;
&lt;td&gt;~$2,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;RTX 4090&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;24GB&lt;/td&gt;
&lt;td&gt;~12 min&lt;/td&gt;
&lt;td&gt;~40 min&lt;/td&gt;
&lt;td&gt;Tight&lt;/td&gt;
&lt;td&gt;~$1,600&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;RTX 3090 (used)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;24GB&lt;/td&gt;
&lt;td&gt;~18 min&lt;/td&gt;
&lt;td&gt;~55 min&lt;/td&gt;
&lt;td&gt;Tight&lt;/td&gt;
&lt;td&gt;~$800&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;RTX 5080&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;16GB&lt;/td&gt;
&lt;td&gt;~14 min&lt;/td&gt;
&lt;td&gt;Offload&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;~$1,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;RTX 4070 Ti Super&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;16GB&lt;/td&gt;
&lt;td&gt;~18 min&lt;/td&gt;
&lt;td&gt;Offload&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;~$700&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;RTX 4060 Ti 16GB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;16GB&lt;/td&gt;
&lt;td&gt;~28 min&lt;/td&gt;
&lt;td&gt;Offload&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;~$400&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Training times are for 1000 steps with gradient checkpointing and FP16. "Offload" means it technically works with model offloading but training becomes 3-5x slower.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which GPU should you buy?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SD 1.5 DreamBooth only?&lt;/strong&gt; The RTX 4070 Ti Super with 16GB handles it. Use gradient checkpointing and FP16. Training takes under 20 minutes per subject.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SDXL DreamBooth?&lt;/strong&gt; You need 24GB. The RTX 4090 is the standard choice. A used RTX 3090 at ~$800 works too -- slower but the VRAM is there.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flux DreamBooth?&lt;/strong&gt; The RTX 5090 at 32GB is nearly mandatory. Flux's larger architecture pushes VRAM demands above what 24GB cards can handle comfortably.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Budget option?&lt;/strong&gt; The RTX 4060 Ti 16GB can train SD 1.5 DreamBooth with aggressive optimization. Not fast, not comfortable, but functional.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common mistakes to avoid
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Skipping gradient checkpointing&lt;/strong&gt; -- this single setting reduces VRAM usage by 30-40% at the cost of 15% slower training. Always enable it for DreamBooth. There is no reason not to.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Using too many training images&lt;/strong&gt; -- DreamBooth works best with 15-30 high-quality images. Using 200 images wastes training time and does not improve results.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Training too many steps&lt;/strong&gt; -- overtrained DreamBooth models produce distorted outputs. 800-1500 steps is usually the sweet spot for SD 1.5. SDXL needs fewer steps, not more.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ignoring LoRA as an alternative&lt;/strong&gt; -- if your GPU has less than 24GB, LoRA training achieves 80-90% of DreamBooth quality at a fraction of the VRAM cost. I use LoRA for most personal training now.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final verdict
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Training Target&lt;/th&gt;
&lt;th&gt;Best GPU&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SD 1.5 DreamBooth&lt;/td&gt;
&lt;td&gt;RTX 4070 Ti Super&lt;/td&gt;
&lt;td&gt;16GB is enough&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SDXL DreamBooth&lt;/td&gt;
&lt;td&gt;RTX 4090&lt;/td&gt;
&lt;td&gt;24GB needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flux DreamBooth&lt;/td&gt;
&lt;td&gt;RTX 5090&lt;/td&gt;
&lt;td&gt;32GB for comfort&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Budget SD 1.5&lt;/td&gt;
&lt;td&gt;RTX 4060 Ti 16GB&lt;/td&gt;
&lt;td&gt;Affordable 16GB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://bestgpuforai.com/articles/best-gpu-for-dreambooth/" rel="noopener noreferrer"&gt;See the recommended pick on the original guide&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://bestgpuforai.com/articles/best-gpu-for-dreambooth/" rel="noopener noreferrer"&gt;See the recommended pick on the original guide&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For LoRA training specifically (the lighter alternative to DreamBooth), check the &lt;a href="https://dev.to/articles/best-gpu-for-fine-tuning/"&gt;best GPU for fine-tuning&lt;/a&gt; guide. For broader Stable Diffusion GPU needs, see the &lt;a href="https://dev.to/articles/best-gpu-for-stable-diffusion/"&gt;best GPU for Stable Diffusion&lt;/a&gt; roundup. If you use Kohya_ss to manage your training scripts, see our &lt;a href="https://dev.to/articles/best-gpu-for-kohya-ss/"&gt;best GPU for Kohya_ss&lt;/a&gt; guide for trainer-specific configuration.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;DreamBooth is the one AI task where "more VRAM" is not just a nice-to-have but a hard requirement. Buy the most VRAM you can afford and use gradient checkpointing. Full stop.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Related guides on Best GPU for AI
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bestgpuforai.com/articles/best-gpu-for-fine-tuning/" rel="noopener noreferrer"&gt;Best GPU for Fine-Tuning AI Models in 2026 (Ranked)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bestgpuforai.com/articles/best-gpu-for-ai-animation/" rel="noopener noreferrer"&gt;Best GPU for AI Animation in 2026 (5 Picks Ranked)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bestgpuforai.com/articles/best-gpu-for-ai-training-at-home/" rel="noopener noreferrer"&gt;Best GPU for AI Training at Home in 2026 (Ranked)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Read the full guide on &lt;a href="https://bestgpuforai.com/articles/best-gpu-for-dreambooth/" rel="noopener noreferrer"&gt;Best GPU for AI&lt;/a&gt;&lt;/strong&gt; — includes our VRAM calculator, GPU comparison table, and live pricing.&lt;/p&gt;

</description>
      <category>gpu</category>
      <category>dreambooth</category>
      <category>finetuning</category>
      <category>stablediffusion</category>
    </item>
    <item>
      <title>Fine-Tuning AI Models Is No Longer Just for ML Engineers</title>
      <dc:creator>Basavaraj SH</dc:creator>
      <pubDate>Thu, 25 Jun 2026 13:14:53 +0000</pubDate>
      <link>https://dev.to/basavaraj_sh_1ea7d95f0f2e/fine-tuning-ai-models-is-no-longer-just-for-ml-engineers-n95</link>
      <guid>https://dev.to/basavaraj_sh_1ea7d95f0f2e/fine-tuning-ai-models-is-no-longer-just-for-ml-engineers-n95</guid>
      <description>&lt;p&gt;The gap between "using AI" and "owning AI" is closing fast - and understanding why matters for anyone building products or running a business today.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Cost of Generic AI Models
&lt;/h2&gt;

&lt;p&gt;Most people start their AI journey the same way: they pick up a general-purpose model, plug it into their workflow, and wait for magic. It works - sort of. The responses are decent, the outputs are readable, but something feels off. The model doesn't quite understand your industry's terminology. It misses the tone your brand needs. It gives confident-sounding answers that are just slightly wrong for your specific use case.&lt;/p&gt;

&lt;p&gt;This is the limitation of off-the-shelf AI. These models are trained on broad internet data, which makes them impressively general but frustratingly imprecise. A legal tech startup and a fitness app both get the same baseline model, even though their needs couldn't be more different.&lt;/p&gt;

&lt;p&gt;The solution has always been fine-tuning - taking a pre-trained model and training it further on your specific data so it learns your context, your language, and your goals. The problem? Until recently, fine-tuning required a dedicated ML engineering team, expensive GPU infrastructure, and weeks of iteration time. For a small business owner or a product manager without a technical background, that door was essentially closed.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Fine-Tuning Actually Means - and Why It's Getting Easier
&lt;/h2&gt;

&lt;p&gt;Think of a pre-trained language model like a very well-read generalist. It has absorbed enormous amounts of text and learned patterns in language, reasoning, and knowledge. Fine-tuning is like giving that generalist a focused apprenticeship in your specific domain. You show it examples of the kind of work you need, and it recalibrates.&lt;/p&gt;

&lt;p&gt;What's changed recently is the tooling around this process. Frameworks are emerging that abstract away much of the technical complexity - handling things like memory optimization, hardware configuration, and training efficiency behind the scenes. The person running the fine-tuning no longer needs to understand every technical detail of what's happening under the hood, just as you don't need to understand how a car engine works to drive one.&lt;/p&gt;

&lt;p&gt;One meaningful development in this space is the increasing compatibility between model repositories (where pre-trained models live) and training acceleration tools. When a model can move smoothly from a public library into a fine-tuning pipeline without extensive manual configuration, the barrier drops significantly. What once took a team and weeks can now be done faster, with fewer people, and with more reproducible results. That's not a small shift - it changes who gets to customize AI and for what purposes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real Example - Step by Step
&lt;/h2&gt;

&lt;p&gt;Here's how a fine-tuning workflow would look in plain terms:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1 - Collect your training data.&lt;/strong&gt; Gather 200 to 500 examples of ideal customer interactions. These could be edited versions of real support tickets where your best agent gave the perfect answer. Format them as question-answer pairs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2 - Choose a base model.&lt;/strong&gt; Pick a smaller, efficient model from a public repository that's close to your needs. You don't need the largest model available - smaller fine-tuned models often outperform large generic ones on specific tasks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 - Run the fine-tuning.&lt;/strong&gt; Using a modern training framework, you point the tool at your data and your chosen model. The framework handles memory management and optimization. You set a few parameters - how many training passes, the learning rate - often guided by sensible defaults.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4 - Evaluate.&lt;/strong&gt; Test the fine-tuned model against your original problem. Does it now correctly reference your 30-day return window? Does it match your tone? Compare its outputs against your baseline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5 - Deploy and monitor.&lt;/strong&gt; Push the model into your support interface and track where it still struggles. Fine-tuning is iterative - your second round will be better than your first.&lt;/p&gt;

&lt;p&gt;The whole process, with modern tooling, can happen in days rather than months.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Apply This Today
&lt;/h2&gt;

&lt;p&gt;You don't need to run a fine-tuning job this week to start benefiting from this shift. Here's what you can do right now:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Audit your current AI pain points.&lt;/strong&gt; Write down three specific cases where your AI tool gives you wrong, generic, or off-brand outputs. These are your fine-tuning candidates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Start collecting training data now.&lt;/strong&gt; Even if you're not ready to fine-tune yet, begin saving examples of ideal outputs - good customer emails, well-written product descriptions, accurate support responses. This library will be your fuel when you're ready.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Explore accessible platforms.&lt;/strong&gt; Several platforms now offer fine-tuning workflows with user interfaces that don't require you to write code. Look for ones that support parameter-efficient methods, which are faster and cheaper than full model training.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Talk to your ML team (or find one).&lt;/strong&gt; If you're a product manager or business owner, connect with someone technical who can run the training process while you own the data strategy and evaluation criteria. The collaboration model works well - you don't need to become an ML engineer, just a smart collaborator.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Set a specific success metric before you start.&lt;/strong&gt; "Better outputs" isn't measurable. "Correctly answers our return policy question 90% of the time" is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Fine-tuning adapts a general AI model to your specific domain, data, and tone - making it meaningfully more useful than a generic baseline.&lt;/li&gt;
&lt;li&gt;The biggest barrier to fine-tuning used to be technical complexity and cost; modern tooling is rapidly reducing both.&lt;/li&gt;
&lt;li&gt;You don't need to be an ML engineer to lead a fine-tuning project - you need good data, clear success criteria, and the right collaborators.&lt;/li&gt;
&lt;li&gt;Start collecting your "ideal output" examples now, even before you're ready to train anything.&lt;/li&gt;
&lt;li&gt;Smaller fine-tuned models often outperform larger generic models on specific tasks - bigger isn't always better.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;What's your experience with this? Drop a comment below - I read every one.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Sources referenced: Hugging Face Blog - Accelerating Transformers Fine-Tuning with NVIDIA NeMo AutoModel&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>productmanagement</category>
      <category>finetuning</category>
    </item>
    <item>
      <title>Reinforcement Fine-Tuning with GRPO: Teach a Small Model to Reason</title>
      <dc:creator>AI Tech Connect</dc:creator>
      <pubDate>Tue, 23 Jun 2026 13:30:09 +0000</pubDate>
      <link>https://dev.to/rishi_kora/reinforcement-fine-tuning-with-grpo-teach-a-small-model-to-reason-2bpe</link>
      <guid>https://dev.to/rishi_kora/reinforcement-fine-tuning-with-grpo-teach-a-small-model-to-reason-2bpe</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://aitechconnect.in/tips/reinforcement-fine-tuning-grpo-small-models-2026" rel="noopener noreferrer"&gt;AI Tech Connect&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;What you need to know Reinforcement fine-tuning teaches a model to think, not to copy. Instead of imitating labelled examples the way supervised fine-tuning does, RFT hands the model a reward signal for a verifiable outcome and lets it discover its own strategy. It is the right tool when correctness is checkable — maths, code that must pass tests, structured extraction, tool-use that either works or does not. GRPO is the algorithm everyone is using now. Group Relative Policy Optimization is a leaner PPO: it drops the separate critic model and instead samples a group of answers per prompt and scores each against the group's own average. That single change roughly halves the memory and makes RFT feasible on one GPU. The reward function is the entire job. A good reward combines a verifier…&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;a href="https://aitechconnect.in/tips/reinforcement-fine-tuning-grpo-small-models-2026" rel="noopener noreferrer"&gt;Read the full article on AI Tech Connect →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>research</category>
      <category>finetuning</category>
      <category>ai</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>How to Align an LLM with DPO and ORPO: A Practical Guide</title>
      <dc:creator>AI Tech Connect</dc:creator>
      <pubDate>Sat, 20 Jun 2026 13:30:19 +0000</pubDate>
      <link>https://dev.to/rishi_kora/how-to-align-an-llm-with-dpo-and-orpo-a-practical-guide-1ihe</link>
      <guid>https://dev.to/rishi_kora/how-to-align-an-llm-with-dpo-and-orpo-a-practical-guide-1ihe</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://aitechconnect.in/tips/align-llm-dpo-orpo-preference-tuning-2026" rel="noopener noreferrer"&gt;AI Tech Connect&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;What this guide gives you Most teams that fine-tune an open-weight model stop after supervised fine-tuning, then wonder why the model is technically correct but somehow off — too terse or too waffly, agreeable when it should push back, willing to answer things it should decline. The reason is structural. Supervised fine-tuning teaches the model to imitate one good completion per prompt. It never sees a worse completion, so it never learns that one answer is better than another. Preference tuning is the step that closes that gap, and in 2026 it is the standard practice for aligning open-weight models after SFT. This is a recipe you can keep and reuse. The methods are stable: preference pairs of chosen and rejected responses, Direct Preference Optimisation (DPO) against a frozen reference,…&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;a href="https://aitechconnect.in/tips/align-llm-dpo-orpo-preference-tuning-2026" rel="noopener noreferrer"&gt;Read the full article on AI Tech Connect →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>finetuning</category>
      <category>ai</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>RAG's Context Trap Forces Hypernetwork Agents Into View</title>
      <dc:creator>XOOMAR</dc:creator>
      <pubDate>Fri, 19 Jun 2026 18:01:49 +0000</pubDate>
      <link>https://dev.to/xoomar/rags-context-trap-forces-hypernetwork-agents-into-view-3fkf</link>
      <guid>https://dev.to/xoomar/rags-context-trap-forces-hypernetwork-agents-into-view-3fkf</guid>
      <description>&lt;p&gt;On &lt;strong&gt;June 19, 2026&lt;/strong&gt;, VentureBeat put a sharp label on a problem enterprise AI teams already know: &lt;strong&gt;hypernetwork agents&lt;/strong&gt; are emerging because fine-tuned models go stale, while &lt;strong&gt;RAG&lt;/strong&gt; systems can lose the very context they were meant to supply.&lt;/p&gt;

&lt;p&gt;That matters now because agent pilots keep hitting the same wall. A demo runs cleanly. Production stretches the task across policies, files, exceptions and approvals. Then a human starts feeding the agent more context, checking every answer and quietly doing the supervision the system was supposed to remove, &lt;a href="https://venturebeat.com/orchestration/fine-tuning-forgets-rag-leaks-context-hypernetworks-build-the-model-your-agent-needs-on-demand" rel="noopener noreferrer"&gt;according to VentureBeat&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When AI firm Chroma tested &lt;strong&gt;18 leading models&lt;/strong&gt;, “every one lost accuracy as its input grew.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That finding is the technical hook. Longer context does not automatically make an agent safer. It can make the agent shakier.&lt;/p&gt;

&lt;h2&gt;
  
  
  June 19: why enterprise AI agents stall after the demo
&lt;/h2&gt;

&lt;p&gt;The failure is not always orchestration. Routing, durable execution and observability help an agent coordinate work, but they assume the agent is competent enough to make good decisions as the job unfolds.&lt;/p&gt;

&lt;p&gt;The deeper issue is where the company’s knowledge lives.&lt;/p&gt;

&lt;p&gt;If the agent has to keep ingesting more business context as it works, the task gets heavier with every step. The prompt grows. Retrieval becomes more important. Missed details become harder to spot. The agent may still produce fluent output, but the employee is now watching the machine instead of doing higher-value work.&lt;/p&gt;

&lt;p&gt;That is the autonomy ceiling. The agent performs the task, but the human still owns the risk.&lt;/p&gt;

&lt;p&gt;For enterprises, this is not a philosophical problem. It affects whether an AI system can run a long audit, compliance check or risk workflow overnight and leave a person to validate the last &lt;strong&gt;10%&lt;/strong&gt;, rather than babysit the first &lt;strong&gt;90%&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  After Chroma’s 18-model test: why fine-tuning and RAG still need a human
&lt;/h2&gt;

&lt;p&gt;Enterprises have mostly used two methods to teach models their business.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fine-tuning&lt;/strong&gt; puts knowledge into the model’s weights. That can improve performance on a specific task, but it brings a known weakness: &lt;strong&gt;catastrophic forgetting&lt;/strong&gt;, identified in the &lt;strong&gt;1980s&lt;/strong&gt; and described in the source as still unresolved in &lt;strong&gt;2026&lt;/strong&gt;. Teach the model something new and it can erode what it already knew.&lt;/p&gt;

&lt;p&gt;Teams often work around that by creating task-specific models or adapters. That helps isolation, but it also creates model sprawl. Governance gets harder. Costs rise. A fine-tuned model also becomes a snapshot. The day a policy changes, the retraining cycle starts again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RAG&lt;/strong&gt; and in-context learning take the other route. They place relevant documents and policies into the prompt at run time. That keeps knowledge fresher, but it shifts the risk to retrieval and context handling. A retrieval miss can look just like a correct answer. A detail buried in a long prompt can vanish from the model’s effective reasoning.&lt;/p&gt;

&lt;p&gt;The failures rhyme:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;Where it breaks&lt;/th&gt;
&lt;th&gt;What the human sees&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Fine-tuning&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Stale policy or forgetting&lt;/td&gt;
&lt;td&gt;A confident answer from old rules&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;RAG&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Retrieval miss or context rot&lt;/td&gt;
&lt;td&gt;A confident answer with missing context&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Both combined&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Partial mitigation, not certainty&lt;/td&gt;
&lt;td&gt;More output that still needs checking&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For teams managing model versions, adapters and evaluation artifacts, the governance problem touches the same MLOps concerns covered in XOOMAR’s guide to &lt;a href="https://dev.to/technology/open-source-model-registry"&gt;Open Source Model Registry Tools MLOps Teams Should Bet On&lt;/a&gt;. For knowledge-heavy AI systems, it also overlaps with the failure modes in &lt;a href="https://dev.to/technology/llm-platforms-enterprise-knowledge-search"&gt;Bad LLM Platforms Break Enterprise Knowledge Search&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  ICML 2025 to SHINE 2026: how hypernetwork agents build specialists on demand
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Hypernetwork agents&lt;/strong&gt; try a third path. Instead of retraining one model or stuffing a giant prompt, a generator creates a small task-specific model adaptation at inference time.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;hypernetwork&lt;/strong&gt; is a network whose output is the weights of another network. In this use case, it can generate an adapter from current business policies for a specific task.&lt;/p&gt;

&lt;p&gt;The concept was named in &lt;strong&gt;2016&lt;/strong&gt;, but applying it to specialist language models from text or documents is newer. VentureBeat points to &lt;strong&gt;Sakana AI’s Text-to-LoRA&lt;/strong&gt;, presented at &lt;strong&gt;ICML 2025&lt;/strong&gt;, which generates a model adapter from a plain-language description in a single pass. It also cites a &lt;strong&gt;2026&lt;/strong&gt; system called &lt;strong&gt;SHINE&lt;/strong&gt;, which frames hypernetwork adaptation as a promising frontier because it avoids some fine-tuning cost and prompting limits.&lt;/p&gt;

&lt;p&gt;The model-zoo angle is the cleanest part. Enterprises already create per-task adapters to avoid interference between tasks. A hypernetwork turns those adapters into generated outputs instead of assets teams must train, store, update and govern one by one.&lt;/p&gt;

&lt;p&gt;That does not remove governance. It changes what must be governed. The key artifact becomes the generator, the policy data it reads and the feedback loop that improves it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overnight compliance review: where a generated specialist could help
&lt;/h2&gt;

&lt;p&gt;Consider a regulated company that wants an agent to review audit evidence overnight, map it against internal policies, flag gaps and prepare a report before staff arrive.&lt;/p&gt;

&lt;p&gt;A fine-tuned model may know the workflow, but it may also be working from last quarter’s policy. A RAG agent can pull current documents, but it may miss a relevant policy or bury a crucial detail in a long prompt. A &lt;strong&gt;hypernetwork-generated model&lt;/strong&gt; would, in theory, generate a narrow specialist from the current policy set for that specific review.&lt;/p&gt;

&lt;p&gt;That matters economically if the job involves many agent steps. A &lt;strong&gt;2025&lt;/strong&gt; paper by &lt;strong&gt;Nvidia researchers&lt;/strong&gt;, cited by VentureBeat, says small models are capable enough for narrow, repetitive agent tasks and &lt;strong&gt;10 to 30 times cheaper&lt;/strong&gt; to run than frontier generalists.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nace.AI&lt;/strong&gt; is the commercial example in the source. The Palo Alto company raised a &lt;strong&gt;$21.5 million seed round in May&lt;/strong&gt;. Its generator, called a &lt;strong&gt;MetaModel&lt;/strong&gt;, produces parameter adaptations at inference time from company policies, targeting audit, compliance and risk assessment. The company markets a &lt;strong&gt;90/10&lt;/strong&gt; split: agents handle the bulk of the workflow, while human experts validate the result.&lt;/p&gt;

&lt;p&gt;Read that ratio carefully. It is not magic autonomy. It is a claim about reducing supervision by narrowing the model’s job and making review faster.&lt;/p&gt;




&lt;h2&gt;
  
  
  Peer review is the next test: where hypernetwork-built agents can break
&lt;/h2&gt;

&lt;p&gt;The first weak point is &lt;strong&gt;calibration&lt;/strong&gt;. The generated model must know when it is unsure. VentureBeat notes that recent work on generated adapters did not show automatic calibration gains over ordinary fine-tuning in every setting. Gains appeared only under specific constraints.&lt;/p&gt;

&lt;p&gt;The second risk is data quality. If policies, procedures and examples are messy, the generated specialist inherits that mess. A hypernetwork cannot turn bad governance data into reliable judgment.&lt;/p&gt;

&lt;p&gt;Scale is also unsettled. Published hypernetwork work has often been small. Nace says it has scaled its generator beyond published sizes and derived a scaling law for performance growth, with results being shared publicly and put through peer review. That paper is the one to watch.&lt;/p&gt;

&lt;p&gt;Human review is another failure point. VentureBeat cites Deloitte Australia’s roughly &lt;strong&gt;A$440,000&lt;/strong&gt; government report, which shipped with fabricated citations and an invented court quote after senior review. The reviewers checked conclusions, not provenance. The EU AI Act’s &lt;strong&gt;Article 14&lt;/strong&gt; names the broader risk as automation bias.&lt;/p&gt;

&lt;p&gt;A high-autonomy system compresses human attention into a late review step. That only works if every claim is grounded, cited and easy to verify.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before a pilot: the four questions buyers should force vendors to answer
&lt;/h2&gt;

&lt;p&gt;A buyer evaluating &lt;strong&gt;hypernetwork agents&lt;/strong&gt; should start with architecture, not the headline autonomy ratio.&lt;/p&gt;

&lt;p&gt;Ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Knowledge location&lt;/strong&gt;: Does business knowledge live in model weights, prompts or generated adaptations?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grounding&lt;/strong&gt;: Does each output include citations, source passages and reasoning traces?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escalation&lt;/strong&gt;: What confidence thresholds, unsupported claims or policy gaps send work back to a human?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ownership&lt;/strong&gt;: When experts correct the agent, whose model improves, where does it run and does the asset stay inside the customer’s cloud?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The practical read is narrow. For long, repetitive, high-volume work where policies matter, hypernetwork-generated specialists deserve a pilot. For short tasks that finish in a few steps, the integration cost may buy little over a well-prompted frontier model.&lt;/p&gt;

&lt;p&gt;The next decision point is evidence. Calibration and scale need validation beyond vendor claims. Until then, treat hypernetwork agents as the most credible new route past fine-tuning staleness and RAG context rot, but not as a replacement for provenance, review design and hard ownership terms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Impact Analysis
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Chroma’s test of 18 leading models found accuracy declined as input length grew.&lt;/li&gt;
&lt;li&gt;Enterprise agent pilots can fail when demos become long workflows involving policies, files and approvals.&lt;/li&gt;
&lt;li&gt;The key business goal is moving humans from supervising the first 90% of work to validating the last 10%.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://xoomar.com/technology/hypernetwork-agents-rag-trap" rel="noopener noreferrer"&gt;XOOMAR&lt;/a&gt;. For more news and analysis, visit &lt;a href="https://xoomar.com" rel="noopener noreferrer"&gt;XOOMAR&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>hypernetworkagents</category>
      <category>enterpriseai</category>
      <category>rag</category>
      <category>finetuning</category>
    </item>
    <item>
      <title>Fine-Tuning Llama 3.2 3B on Medical QA: Week 4 - When Lower Loss Meant a Worse Model</title>
      <dc:creator>Nicholas (Kosisochukwu) Ugbala</dc:creator>
      <pubDate>Tue, 16 Jun 2026 11:33:04 +0000</pubDate>
      <link>https://dev.to/nicholas-ugbala-dev/fine-tuning-llama-32-3b-on-medical-qa-week-4-when-lower-loss-meant-a-worse-model-1hne</link>
      <guid>https://dev.to/nicholas-ugbala-dev/fine-tuning-llama-32-3b-on-medical-qa-week-4-when-lower-loss-meant-a-worse-model-1hne</guid>
      <description>&lt;h2&gt;
  
  
  What Happened This Week
&lt;/h2&gt;

&lt;p&gt;Week 3 produced a working fine-tuned model: one epoch, one dataset, a clear improvement over the base model. This week 4 was supposed to make it better with More data (a second dataset), two epochs, and a cleaner setup.&lt;/p&gt;

&lt;p&gt;The eval loss dropped from 2.495 to 2.275. By that number alone, Week 4 was going to be a success.&lt;/p&gt;

&lt;p&gt;The model was worse.&lt;/p&gt;

&lt;p&gt;This is the story of how a better loss number hid a serious regression, how I diagnosed it, and what it took to actually fix it. It is one of the most useful things I have learned in this project.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Plan
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Four changes over Week 3:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Combine two datasets: ChatDoctor (conversational patient-doctor QA) and MedAlpaca WikiDoc (encyclopedic clinical reference), for both conversational style and factual grounding.&lt;/li&gt;
&lt;li&gt;Use Llama's built-in pad token instead of adding a custom one to avoid an oversized adapter file.&lt;/li&gt;
&lt;li&gt;Train for two epochs on the full dataset instead of one.&lt;/li&gt;
&lt;li&gt;Switch evaluation to greedy decoding for reproducibility.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Pad Token Fix
&lt;/h2&gt;

&lt;p&gt;In Week 3, I added a custom pad token and resized the model's embedding layer. This had an unintended cost: PEFT saved the entire resized embedding layer alongside the LoRA adapters, producing a 3.19GB adapter file instead of the expected ~50MB.&lt;/p&gt;

&lt;p&gt;Llama 3.2's tokenizer already ships with a reserved padding token, &lt;code&gt;&amp;lt;|finetune_right_pad_id|&amp;gt;&lt;/code&gt; (token 128004), made for exactly this purpose. Using it instead of adding a new token:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="bp"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;tokenizer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AutoTokenizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_pretrained&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;tokenizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pad_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;|finetune_right_pad_id|&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;tokenizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;padding_side&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;right&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="c1"&gt;# No add_special_tokens, no resize_token_embeddings
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No embedding resize means no embedding layer saved with the adapters. The Week 4 adapter came out at ~50MB. What I Learned: Before adding a special token, check whether the model already has one. Llama 3.2 did.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the Combined Dataset
&lt;/h2&gt;

&lt;p&gt;ChatDoctor alone produced a model that answered in a conversational manner but sometimes lacked factual grounding. WikiDoc is reference-grade encyclopedic medical content. The Idea was that combining them would give both conversational style and factual grounding.&lt;/p&gt;

&lt;p&gt;The first combine used 8,000 ChatDoctor and 4,000 WikiDoc, a 2:1 ratio. After cleaning and a 512-token length filter, this produced 10,255 rows: 9,229 train, 1,026 eval.&lt;/p&gt;

&lt;p&gt;The cleaning itself was an exercise in diminishing returns.&lt;br&gt;
ChatDoctor forum data carries platform filler ("Hello, welcome to Chat Doctor", "Hope this helps"), and the source has OCR-level corruption that breaks pattern matching ("HiT hanks" for "Hi. Thanks"). I built a two-pass regex cleaner plus a sentence-level trailing filler stripper that removes whole closing sentence containing filler keywords. It caught most of the noise. A small fraction of corruption resisted cleaning entirely, which I documented rather than chasing.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Training Run That Looked Like Success
&lt;/h2&gt;

&lt;p&gt;Two epochs, 1,154 steps, about four hours on a Kaggle T4.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Step 150:   train 2.499  |  eval 2.474
Step 300:   train 2.336  |  eval 2.340
Step 600:   train 2.282  |  eval 2.297
Step 900:   train 2.241  |  eval 2.279
Step 1050:  train 2.231  |  eval 2.275
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A clean, healthy loss curve. Eval loss dropped steadily to 2.275, well below Week 3's 2.495. Train and eval tracked each other closely, indicating no classic overfitting. Mean token accuracy rose to 0.515.&lt;/p&gt;

&lt;p&gt;Every number said the model improved.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Regression
&lt;/h2&gt;

&lt;p&gt;Then I ran the five test questions with greedy decoding.&lt;/p&gt;

&lt;p&gt;The diabetes answer began correctly, then collapsed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Eye yawning
Eye yawns
Eye years
Eye yolks
Eye yummy
Eye yogurt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A complete generation breakdown, under greedy decoding, which is supposed to be the stable option. The heart attack answer produced a runaway list that drifted from cardiac symptoms into sore throats and ear pain. Hypertension confidently recommended atenolol as first-line therapy, which is wrong: beta-blockers are not first-line for uncomplicated hypertension.&lt;/p&gt;

&lt;p&gt;The model with the better loss number produced worse answers than Week 3's model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Diagnosing It
&lt;/h2&gt;

&lt;p&gt;Two things were happening, and separating them mattered.&lt;/p&gt;

&lt;p&gt;First, the repetition penalty backfired. I had set &lt;code&gt;no_repeat_ngram_size=3&lt;/code&gt;, which forbids repeating any three-token sequence. Once it generates a three-token phrase like "consult your doctor", it can never produce that exact phrase again in the same answer. The intent is to stop repetition loops. The effect was the opposite: when the model wanted to end a list by repeating a natural closing pattern, the rule forbade it, forcing a brand-new token every time. The only way to keep producing non-repeating tokens was to drift into nonsense: &lt;code&gt;"Eye yummy, Eye yogurt."&lt;/code&gt; The setting meant to prevent loops was driving the degeneration.&lt;/p&gt;

&lt;p&gt;Second, and more fundamental: the model had overfit to list generation. The combined dataset, especially the Wiki/doc half, contained many list-formatted answers. Two epochs reinforced a pattern: when answering, produce a list and keep extending it. On questions with naturally bounded answers (a mechanism or short cause), the model stayed controlled. On questions inviting enumeration (drugs, symptoms), it started a list and could not stop, eventually confabulating list items: invented drugs like "artuzofloxacin", invented symptoms.&lt;/p&gt;

&lt;p&gt;The loss curve never showed this because loss measures next-token prediction accuracy on the eval set. A model can be better at predicting the next token while getting worse at producing a coherent, bounded, truthful answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fix
&lt;/h2&gt;

&lt;p&gt;Three changes. applied together.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rebalanced the data.&lt;/strong&gt;* Dropped WikiDoc from 4,000 to 1,500 and raised ChatDoctor to 8,500, roughly 85% narrative prose, 15% encyclopedic. ChatDoctor's conversational answers train the model toward bounded, flowing responses rather than open-ended lists. This attacked the root behaviour.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Expanded the LoRA target modules.&lt;/strong&gt; Those module names need a short explanation. Each layer of the model has two parts that do different jobs. The attention layers(&lt;code&gt;q_proj&lt;/code&gt;, &lt;code&gt;k_proj&lt;/code&gt;,&lt;code&gt;v_proj&lt;/code&gt;, &lt;code&gt;o_proj&lt;/code&gt;) decide what to pay attention to: how tokens relate to each other, how "the patient" connects to "their symptoms" later in the same question. The feed-forward layers (&lt;code&gt;up_proj&lt;/code&gt;, &lt;code&gt;down_proj&lt;/code&gt;, &lt;code&gt;gate_proj&lt;/code&gt;) are where factual knowledge tends to be stored and retrieved; research shows they behave somewhat like a key-value memory, where a concept goes in and the associated facts come out.&lt;/p&gt;

&lt;p&gt;Week 3 applied LoRA only to the attention layers, leaving the feed-forward layers frozen. That tuned how the model routes information but left the layers that hold the facts untouched. The confabulation, inventing drugs like "artuzofloxacin", was a factual recall failure: the model could not keep real drug names active while generating a list. So in Week 4, I added the feed-forward layers to the LoRA targets, letting fine-tuning adjust the part of the model where the facts live, not just the attention routing. (The claim that facts live in the feed-forward layers is a simplification; knowledge is distributed across the whole model. But as a reason to target those layers for a recall problem, it holds.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fixed generation.&lt;/strong&gt; Removed &lt;code&gt;no_repeat_ngram_size&lt;/code&gt; entirely. Set &lt;code&gt;eos_token_id&lt;/code&gt; explicitly to &lt;code&gt;&amp;lt;|eot_id|&amp;gt;&lt;/code&gt; so the model can actually stop. Used &lt;code&gt;repetition_penalty=1.3&lt;/code&gt; to discourage loops without a hard ngram ban, and capped &lt;code&gt;max_new_tokens&lt;/code&gt; at 256.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;outputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;input_ids&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;encoded_inputs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;input_ids&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;attention_mask&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;encoded_inputs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;attention_mask&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;max_new_tokens&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;do_sample&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;repetition_penalty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;eos_token_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tokenizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;convert_tokens_to_ids&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;|eot_id|&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;pad_token_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tokenizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pad_token_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One epoch on the rebalanced data.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Result
&lt;/h2&gt;

&lt;p&gt;The degeneration was gone. Hypertension named four real first-line drug classes (ACE inhibitors, ARBs, beta-blockers, calcium channel blockers) and stopped. Malaria named real treatments (artemether-lumefantrine, chloroquine, mefloquine) and stopped. The diabetes and iron deficiency answers stayed accurate. The heart attack answer, which had failed in every previous run, finally produced seven correct cardiac warning signs and stopped.&lt;/p&gt;

&lt;p&gt;And running the same question twice produced byte-for-byte identical output. Greedy decoding made the results reproducible, which is what makes the claims defensible. In Week 3, the same question could give a good answer one run and collapse the next. Now the model's behaviour is consistent and verifiable.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Actually Learned
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Lower Loss is not a better model.&lt;/strong&gt; Eval loss measures next-token prediction. It does not measure factual accuracy, coherence, or whether the model knows when to stop. The Week 4 two-epoch model had the best loss and the worst generation. I wouldn't have caught this if I went with the notion that decreased loss equals a better-performing model, and not manually test the model's output.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generation settings are not an afterthought.&lt;/strong&gt; The same weights produced a total collapse or a clean answer depending on the decoding configuration. A repetition penalty meant to help actively caused the degeneration. Half of the battle with a small model is how you decode it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Small models have a ceiling.&lt;/strong&gt; A 3B fine-tuned on consumer hardware handles clinical QA well but struggles to enumerate without confabulating. Rebalancing the data and expanding LoRA targets pushed that ceiling up, but it is a real limit. In production, the answer would be a larger base model. Naming the constraint honestly gives clarity on how to go about making better improvements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reproducibility is a feature you build in.&lt;/strong&gt; Greedy decoding, a fixed seed, a pinned data sample. Without these, "the model does X" is not a claim I can stand behind.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the Model Lives
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://huggingface.co/nicholas-ugbala-hf/llama-3.2-3b-medical-finetuned-v2" rel="noopener noreferrer"&gt;nicholas-ugbala-hf/llama-3.2-3b-medical-finetuned-v2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adapter file: ~50MB, the pad token fix working as intended.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;Week 5 wraps the model in a FastAPI inference endpoint, containerises it with Docker, and deploys it to a public URL any one can call. The generation settings worked out this week become the server's defaults.&lt;/p&gt;

&lt;p&gt;Model: &lt;a href="https://huggingface.co/nicholas-ugbala-hf/llama-3.2-3b-medical-finetuned-v2" rel="noopener noreferrer"&gt;huggingface.co/nicholas-ugbala-hf/llama-3.2-3b-medical-finetuned-v2&lt;/a&gt;&lt;br&gt;
Dataset: &lt;a href="https://huggingface.co/datasets/nicholas-ugbala-hf/medical-qa-narrative-10k" rel="noopener noreferrer"&gt;huggingface.co/datasets/nicholas-ugbala-hf/medical-qa-narrative-10k&lt;/a&gt;&lt;br&gt;
Repo: &lt;a href="https://github.com/nicholas-ugbala-dev/healthcare-llm-finetune" rel="noopener noreferrer"&gt;github.com/nicholas-ugbala-dev/healthcare-llm-finetune&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>deeplearning</category>
      <category>machinelearning</category>
      <category>finetuning</category>
    </item>
    <item>
      <title>LoRA and QLoRA from Scratch: An Eval-Driven Fine-Tuning Recipe</title>
      <dc:creator>AI Tech Connect</dc:creator>
      <pubDate>Tue, 16 Jun 2026 11:30:16 +0000</pubDate>
      <link>https://dev.to/rishi_kora/lora-and-qlora-from-scratch-an-eval-driven-fine-tuning-recipe-1f0g</link>
      <guid>https://dev.to/rishi_kora/lora-and-qlora-from-scratch-an-eval-driven-fine-tuning-recipe-1f0g</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://aitechconnect.in/tips/lora-qlora-fine-tuning-eval-driven-recipe-2026" rel="noopener noreferrer"&gt;AI Tech Connect&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;What this recipe gives you Fine-tuning has a reputation as a dark art reserved for teams with eight-figure GPU budgets. It is not. With LoRA and QLoRA you can adapt a 7B or 8B open-weight model on a single consumer-grade card, in an afternoon, for the price of a couple of cups of coffee. The hard part was never the compute. The hard part is knowing whether you should fine-tune at all, building a dataset that matches how you will actually call the model, and proving the result is better rather than merely different. This is a recipe you can keep and reuse across models and tasks. The methods here are stable: low-rank adaptation, 4-bit quantisation, an 80/10/10 split, an eval set built first. The specific model you point it at — Llama, Qwen, Mistral, Gemma — barely changes the steps. Here…&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;a href="https://aitechconnect.in/tips/lora-qlora-fine-tuning-eval-driven-recipe-2026" rel="noopener noreferrer"&gt;Read the full article on AI Tech Connect →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>research</category>
      <category>finetuning</category>
      <category>ai</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>Build Small Hackathon - Quillwright</title>
      <dc:creator>AaryaP</dc:creator>
      <pubDate>Mon, 15 Jun 2026 22:59:04 +0000</pubDate>
      <link>https://dev.to/aarya_prakash_1328e1617f6/build-small-hackathon-quillwright-573f</link>
      <guid>https://dev.to/aarya_prakash_1328e1617f6/build-small-hackathon-quillwright-573f</guid>
      <description>&lt;p&gt;&lt;em&gt;How Quillwright turns a photo and a voice note into a tradesperson's estimate, with an orchestra of small models, on your own machine, and not a single number invented by an LLM.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The job nobody wants
&lt;/h2&gt;

&lt;p&gt;Every tradesperson does the same unpaid hour after the real work is done: writing up the estimate. Parts, quantities, labor, a defensible total. Quillwright is an on-device, human-supervised agent that does that draft from a &lt;strong&gt;field capture&lt;/strong&gt; (a job photo plus a spoken note) and hands back an itemized, editable estimate.&lt;/p&gt;

&lt;p&gt;The constraints we set ourselves were the interesting part: &lt;strong&gt;small models&lt;/strong&gt; (≤32B), &lt;strong&gt;no third-party AI APIs&lt;/strong&gt;, and a hard rule that &lt;strong&gt;no customer-facing number ever comes from a language model.&lt;/strong&gt; Those three constraints shaped every decision below.&lt;/p&gt;

&lt;h2&gt;
  
  
  An orchestra, not a soloist
&lt;/h2&gt;

&lt;p&gt;There's no single model doing the work. Each role in the pipeline resolves to a small, purpose-fit model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Perception&lt;/strong&gt;: MiniCPM-V (OpenBMB) reads the job photo into observations ("RUN CAPACITOR", a nameplate model number).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent Brain&lt;/strong&gt;: NVIDIA Nemotron-3-Nano drives a narrow tool-calling loop: which items, what quantities, when it's done.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audio&lt;/strong&gt;: Cohere Transcribe turns the voice note into text on-device.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multilingual&lt;/strong&gt;: Cohere Aya translates the customer-facing copy (Spanish, French, Mandarin), descriptions only, never the numbers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Embedding&lt;/strong&gt;: a small embedder powers semantic recall of similar past jobs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The brain's tool surface is deliberately tiny: essentially &lt;em&gt;add a priced item&lt;/em&gt; and &lt;em&gt;finish&lt;/em&gt;. That narrowness is &lt;strong&gt;why a 4B model is reliable&lt;/strong&gt; here: it does routing and judgment, not arithmetic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Facts-from-Tools: the rule that runs through everything
&lt;/h2&gt;

&lt;p&gt;The correctness rule is simple to state and ruthless to enforce: &lt;strong&gt;any number that reaches the customer (price, quantity, tax, total) comes from a tool (a catalog lookup, a deterministic &lt;code&gt;compute&lt;/code&gt;) or from a human edit. Never from the model's free generation.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It holds in the obvious places (the brain calls &lt;code&gt;lookup_price&lt;/code&gt;, not "I think this costs $40") and the non-obvious ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Edits&lt;/strong&gt; re-run through a server-authoritative recalc. The browser never computes its own total.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Translation&lt;/strong&gt; changes words, not digits.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Document Capture&lt;/strong&gt; (reading a supplier quote) produces &lt;em&gt;Proposed Line Items&lt;/em&gt;: the document is the source, but a price only becomes customer-facing once a human confirms it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The refinement chat&lt;/strong&gt; keeps a sanitized history: when you reopen an estimate and keep editing, the model sees &lt;em&gt;what you asked&lt;/em&gt; ("make it 2 hours") but takes the &lt;em&gt;numbers&lt;/em&gt; from the current line items, so a stale dollar figure can never leak back in. Even the conversation's own compaction is done in code, not by asking a model to summarize.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The eval story (the part I'd tell another builder)
&lt;/h2&gt;

&lt;p&gt;Here's the moment that changed how we built this. We ran the agent by hand on a handful of jobs and it looked &lt;strong&gt;perfect&lt;/strong&gt;. Then we wrote an eval set and scored it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Item F1: 0.367.&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.amazonaws.com%2Fuploads%2Farticles%2F95fufempqk30ahu9ytl9.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.amazonaws.com%2Fuploads%2Farticles%2F95fufempqk30ahu9ytl9.png" alt="Agent Brain item F1" width="800" height="514"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Manual testing had been lying to us: we'd unconsciously fed it the cases it handled. The eval set didn't. Two fixes, both measured:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fuzzy catalog lookup&lt;/strong&gt;: "refrigerant" should find &lt;code&gt;refrigerant_r410a&lt;/code&gt;. F1 jumped to &lt;strong&gt;0.880&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompt tuning&lt;/strong&gt; the brain's tool-calling, to &lt;strong&gt;0.967&lt;/strong&gt;, with quantity accuracy going from 0.40 to 1.00.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The lesson isn't "we got a good number." It's that the good number only existed because we were willing to be told a bad one first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory that gets smarter, measured the same way
&lt;/h2&gt;

&lt;p&gt;Quillwright recalls similar past jobs to inform a new estimate. The first version used keyword matching. We measured &lt;strong&gt;recall@1 = 0.750&lt;/strong&gt;. Swapping in a small embedder for a semantic re-rank moved it to &lt;strong&gt;0.875&lt;/strong&gt;, with one honest remaining miss we left in, because a benchmark with no failures is a benchmark you don't trust.&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.amazonaws.com%2Fuploads%2Farticles%2F6w19wawskp98whmpmdh4.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.amazonaws.com%2Fuploads%2Farticles%2F6w19wawskp98whmpmdh4.png" alt="Episodic recall" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Fine-tuning a small vision model on receipts, and on the real domain
&lt;/h2&gt;

&lt;p&gt;The 🎯 artifact is a MiniCPM-V LoRA fine-tune. On the public &lt;strong&gt;CORD&lt;/strong&gt; receipt benchmark, the tune lifted item F1 from &lt;strong&gt;0.588 → 0.681&lt;/strong&gt; (+0.09). But CORD is receipts, not trade invoices, so we also generated a grounded-synthetic set of trade invoices (built from a real 381-entry trade catalog) and fine-tuned on that. In-distribution, the tune went from &lt;strong&gt;0.703 → 0.933&lt;/strong&gt; (+0.23), with price accuracy hitting 1.00.&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.amazonaws.com%2Fuploads%2Farticles%2Ffulow5q439ci2cmzwxqn.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.amazonaws.com%2Fuploads%2Farticles%2Ffulow5q439ci2cmzwxqn.png" alt="MiniCPM-V fine-tune" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The +0.23 is the honest headline: a small model, fine-tuned on the actual domain, closes most of the gap to a clean read. The +0.09 on CORD is the conservative one: it's a harder, out-of-domain benchmark, and we report it anyway.&lt;/p&gt;

&lt;h2&gt;
  
  
  Artifacts
&lt;/h2&gt;

&lt;p&gt;Both LoRA adapters are on the Hub, and every number above is reproducible from the eval scripts in the repo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🎯 &lt;a href="https://huggingface.co/Aarya2004/minicpmv-trade-lora" rel="noopener noreferrer"&gt;&lt;code&gt;Aarya2004/minicpmv-trade-lora&lt;/code&gt;&lt;/a&gt;: the in-domain trade-invoice tune (0.703 → 0.933).&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://huggingface.co/Aarya2004/minicpmv-cord-lora" rel="noopener noreferrer"&gt;&lt;code&gt;Aarya2004/minicpmv-cord-lora&lt;/code&gt;&lt;/a&gt;: the conservative CORD baseline (0.588 → 0.681).&lt;/li&gt;
&lt;/ul&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&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Agent Brain item F1&lt;/td&gt;
&lt;td&gt;0.367&lt;/td&gt;
&lt;td&gt;0.967&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Episodic recall@1&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.875&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MiniCPM-V item F1 (trade, in-domain)&lt;/td&gt;
&lt;td&gt;0.703&lt;/td&gt;
&lt;td&gt;0.933&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MiniCPM-V item F1 (CORD, OOD)&lt;/td&gt;
&lt;td&gt;0.588&lt;/td&gt;
&lt;td&gt;0.681&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  "On your own machine", and the honesty around it
&lt;/h2&gt;

&lt;p&gt;The hero claim is &lt;em&gt;no cloud&lt;/em&gt;. The honest version of that claim has two parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;Private Stack&lt;/strong&gt; is open small models with no third-party AI APIs. Locally, those models genuinely run on the dev machine via Ollama / llama.cpp, and we filmed an &lt;strong&gt;Airplane-Mode Proof&lt;/strong&gt;: Wi-Fi off, a real forge completing.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;hosted demo Space&lt;/strong&gt; is wired live to &lt;strong&gt;Modal&lt;/strong&gt; GPUs, the &lt;strong&gt;Best Stack&lt;/strong&gt;: a Nemotron-3-Nano 30B brain, Nemotron-Omni for vision and audio, Aya-Expanse for multilingual. It's the same agent loop and the same Facts-from-Tools guarantees as the local run, just with more headroom; the apps scale to zero when idle, so the Space can fall back to a lightweight CPU mode (and says so on the page) when the models aren't wired. The local Private Stack and the hosted Best Stack are the same family at two tiers: flip one env var and the brain moves from a 4B on a laptop to a 30B on a GPU without touching the agent code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Same agent, same tools, same Facts-from-Tools guarantee. Only the models behind each role change:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;🔒 Private Stack (local)&lt;/th&gt;
&lt;th&gt;⚡ Best Stack (Modal)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Brain&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Nemotron-3-Nano 4B (NVIDIA)&lt;/td&gt;
&lt;td&gt;Nemotron-3-Nano 30B (NVIDIA)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Perception&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;MiniCPM-V (OpenBMB)&lt;/td&gt;
&lt;td&gt;Nemotron-Omni 30B (NVIDIA)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Audio&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Cohere Transcribe (on-device)&lt;/td&gt;
&lt;td&gt;Nemotron-Omni 30B (NVIDIA)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Multilingual&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Aya (Cohere)&lt;/td&gt;
&lt;td&gt;Aya-Expanse 8B (Cohere)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Embedding&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;on-device (sentence-transformers)&lt;/td&gt;
&lt;td&gt;&lt;em&gt;same on-device path&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Extraction&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;no local path&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;Parse extractor (fine-tuned)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Runs offline?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Yes, Airplane-Mode Proof&lt;/td&gt;
&lt;td&gt;❌ No, hosted GPU endpoints&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cost / GPU&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$0, your hardware&lt;/td&gt;
&lt;td&gt;scales to zero when idle&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We hold the same line everywhere a feature could over-claim. The "Finalize &amp;amp; Send" feature really texts or emails the estimate &lt;strong&gt;on the local path&lt;/strong&gt; with your own provider creds; on the public Space it drafts only and tells you nothing was transmitted. Same for the phone call and the phone-capture QR: real on the tunneled local machine, honestly framed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three ways in
&lt;/h2&gt;

&lt;p&gt;Once the core was solid, the capture surface grew. Each path lands in the &lt;em&gt;same&lt;/em&gt; pipeline and the &lt;em&gt;same&lt;/em&gt; Facts-from-Tools guarantees:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Workspace&lt;/strong&gt;: type/paste a note, add a photo, watch the Digital Apprentice stream.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Call a phone number&lt;/strong&gt;: describe the job out loud; it transcribes the call, forges a &lt;strong&gt;draft&lt;/strong&gt; estimate, reads the total back, and texts you the PDF. A human approves later.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scan a QR&lt;/strong&gt;: capture a photo and voice note on your phone; the desktop forges it live on screen.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What I'd carry to the next project
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Write the eval before you trust the demo.&lt;/strong&gt; 0.37 was the most useful number in the whole build.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep the model's job small.&lt;/strong&gt; The brain is reliable because it never touches arithmetic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make the honesty structural, not aspirational.&lt;/strong&gt; "The model never emits a number" is a code path, not a promise, and it's the same code path on every capture surface.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Quillwright: tell it about the job; it drafts the estimate.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>smallmodels</category>
      <category>agents</category>
      <category>evals</category>
      <category>finetuning</category>
    </item>
    <item>
      <title>Turning Gemma 4 into an Old Korean Translator</title>
      <dc:creator>bebechien</dc:creator>
      <pubDate>Mon, 15 Jun 2026 06:13:07 +0000</pubDate>
      <link>https://dev.to/googleai/turning-gemma-4-into-an-old-korean-translator-hop</link>
      <guid>https://dev.to/googleai/turning-gemma-4-into-an-old-korean-translator-hop</guid>
      <description>&lt;p&gt;There’s something uniquely beautiful about old books. The smell of weathered paper, the texture of the pages, and the stories that have survived generations. But if you’ve ever tried opening a piece of Classical Korean literature—like the Joseon Dynasty novel &lt;em&gt;&lt;a href="https://en.wikipedia.org/wiki/Hong_Gildong_jeon" rel="noopener noreferrer"&gt;HongGildongJeon (홍길동전)&lt;/a&gt;&lt;/em&gt;—you’ll quickly realize that time leaves its own mark on language.&lt;/p&gt;

&lt;p&gt;Between the lack of word spacing and obsolete letters like the dot vowel &lt;em&gt;Arae-a (ㆍ)&lt;/em&gt; or the soft &lt;em&gt;Yeorin-hieut (ㆆ)&lt;/em&gt;, reading it feels less like browsing a novel and more like solving a beautiful, ancient puzzle. Even for native speakers, the linguistic gap is massive.&lt;/p&gt;

&lt;p&gt;So, that's why I decided to creat &lt;a href="https://colab.research.google.com/github/google-gemma/cookbook/blob/main/tutorials/Translator_of_Old_Korean_Literature.ipynb" rel="noopener noreferrer"&gt;this tutorial&lt;/a&gt;, a digital bridge between the past and the present. Using &lt;strong&gt;&lt;a href="https://huggingface.co/google/gemma-4-E2B-it" rel="noopener noreferrer"&gt;Gemma 4 E2B (IT)&lt;/a&gt;&lt;/strong&gt;, I set out to create a humble translator that turns Classical Korean into smooth, modern Korean.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Recipe for Training
&lt;/h1&gt;

&lt;p&gt;To keep things manageable, I ran this on a single NVIDIA T4 GPU (16GB) using Google Colab.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Setting Up the Kitchen
&lt;/h2&gt;

&lt;p&gt;First, we pull in our favorite open-source tools: Hugging Face’s &lt;code&gt;transformers&lt;/code&gt;, &lt;code&gt;trl&lt;/code&gt; for the training loop, and &lt;code&gt;peft&lt;/code&gt; so we can use LoRA (Low-Rank Adaptation) to fine-tune our model without needing a massive server cluster.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Gathering the Ingredients
&lt;/h2&gt;

&lt;p&gt;For our data, I used a public domain version of &lt;em&gt;&lt;a href="https://ko.wikisource.org/wiki/%ED%99%8D%EA%B8%B8%EB%8F%99%EC%A0%84_(36%EC%9E%A5_%EC%99%84%ED%8C%90%EB%B3%B8)" rel="noopener noreferrer"&gt;HongGildongJeon&lt;/a&gt;&lt;/em&gt;, paired with a beautiful &lt;a href="https://ko.wikisource.org/wiki/%EB%B2%88%EC%97%AD:%ED%99%8D%EA%B8%B8%EB%8F%99%EC%A0%84_(36%EC%9E%A5_%EC%99%84%ED%8C%90%EB%B3%B8)" rel="noopener noreferrer"&gt;modern translation&lt;/a&gt; by &lt;code&gt;직지프로&lt;/code&gt; (licensed under Creative Commons).&lt;/p&gt;

&lt;p&gt;To make Gemma feel at home, I structured the data into a conversation, guiding the model with a clear &lt;code&gt;system&lt;/code&gt; prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"system"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Translate Classical Korean into Modern Korean."&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"됴션국셰둉ᄃᆡ왕즉위십오연의홍희문밧긔ᄒᆞᆫᄌᆡ상이잇스되"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"assistant"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"조선국 세종대왕 즉위 십오년에 홍회문 밖에 한 재상이 있으되,"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;(Translation note: This line introduces us to a prime minister living just outside the Honghoemun Gate during the 15th year of King Sejong's reign!)&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  The "Before" Picture
&lt;/h1&gt;

&lt;p&gt;Before giving Gemma any specific training, I ran a quick baseline test. Base models are smart, but archaic grammar is a highly specific domain. Without tuning, Gemma tried its best but ended up giving long, overly literal explanations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Original Classical Text:&lt;/strong&gt; ᄇᆡᆨ씨듯고ᄂᆡ심의탄복왈그근본을ᄀᆞᆷ초지아니ᄒᆞ니장부로다ᄒᆞ고ᄌᆡ삼위로ᄒᆞ더라&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Human Translation:&lt;/strong&gt; 백씨 듣고 내심에 탄복 왈, "그 근본을 감추지 아니하니 장부로다!" 하고, 재삼 위로하더라.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemma's Initial Guess:&lt;/strong&gt; &lt;em&gt;"Like the color, the heart's praise said, 'The foundation cannot be deeply felt...'"&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Initial Similarity Score:&lt;/strong&gt; &lt;strong&gt;4.85%&lt;/strong&gt; 💔&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;(Translation note: This line actually means - Upon hearing this, Mr. Baek was deeply impressed and said, "He does not hide his true nature; he is a true man!" and comforted him again and again.)&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The base model was clearly lost in time. It needed a map.&lt;/p&gt;

&lt;h1&gt;
  
  
  Teaching Gemma with Care
&lt;/h1&gt;

&lt;p&gt;To train the model efficiently, I used a Parameter-Efficient Fine-Tuning (PEFT) setup with LoRA.&lt;br&gt;
&lt;/p&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;peft&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LoraConfig&lt;/span&gt;

&lt;span class="n"&gt;peft_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LoraConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;lora_alpha&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;lora_dropout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.05&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;bias&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;none&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;target_modules&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;all-linear&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;task_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CAUSAL_LM&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The Secret Sauce: &lt;code&gt;collate_fn&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When fine-tuning a chat model to behave like a specific tool, you don't want it to waste energy learning how to re-write your prompt. By using a custom data collator, I masked the &lt;code&gt;system&lt;/code&gt; and &lt;code&gt;user&lt;/code&gt; inputs (setting their labels to &lt;code&gt;-100&lt;/code&gt;), forcing Gemma's loss calculation to focus &lt;em&gt;strictly&lt;/em&gt; on generating the correct modern assistant response.&lt;/p&gt;

&lt;p&gt;After setting our hyper-parameters to gently cruise through 5 epochs with a learning rate of &lt;code&gt;2e-5&lt;/code&gt;, I hit train.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Warm "After" Glow
&lt;/h1&gt;

&lt;p&gt;After a bit of patience and letting the trainer do its magic, the results were incredibly rewarding. The character-by-character similarity score jumped all the way up to a brilliant &lt;strong&gt;79.93%&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;Look at how it handles the text now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Original Classical Text:&lt;/strong&gt; ᄇᆡᆨ씨듯고ᄂᆡ심의탄복왈그근본을ᄀᆞᆷ초지아니ᄒᆞ니장부로다ᄒᆞ고ᄌᆡ삼위로ᄒᆞ더라&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Human Translation:&lt;/strong&gt; 백씨 듣고 내심에 탄복 왈, "그 근본을 감추지 아니하니 장부로다!" 하고, 재삼 위로하더라.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemma's Fine-Tuned Translation:&lt;/strong&gt; 백씨듯 고내심에 탄복 왈, "그 근본을 감초지 아니하니 장부로다." 하고 제삼 위로 하더라.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;New Similarity Score:&lt;/strong&gt; &lt;strong&gt;85.71%&lt;/strong&gt; ✨&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Closing Thoughts
&lt;/h1&gt;

&lt;p&gt;Technology often pushes us relentlessly into the future, but my favorite tech projects are the ones that allow us to look backward with greater clarity. By spending a little time fine-tuning a lightweight model like Gemma 4, we can build tools that preserve cultural history, making ancient wisdom and classic stories accessible to anyone with a laptop.&lt;/p&gt;

&lt;p&gt;Next time you find a piece of history that feels just a bit too out of reach, remember that a small dataset and a fine-tuning session might be all you need to bring it into the light.&lt;/p&gt;

&lt;p&gt;Here's the structured workflow when you do a fine-tuning for your own domain:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define a clear goal&lt;/li&gt;
&lt;li&gt;Prepare a high-quality dataset and evaluation plan&lt;/li&gt;
&lt;li&gt;Verify the model is learning&lt;/li&gt;
&lt;li&gt;Evaluate with metrics and human judgment&lt;/li&gt;
&lt;li&gt;Deploy and iterate&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;👉 &lt;a href="https://colab.research.google.com/github/google-gemma/cookbook/blob/main/tutorials/Translator_of_Old_Korean_Literature.ipynb" rel="noopener noreferrer"&gt;Check out this tutorial in Gemma Cookbook&lt;/a&gt;&lt;br&gt;
👉 &lt;a href="https://github.com/google-gemma/cookbook" rel="noopener noreferrer"&gt;Star the repository to support us&lt;/a&gt;&lt;/p&gt;

</description>
      <category>finetuning</category>
      <category>gemma</category>
      <category>ai</category>
    </item>
    <item>
      <title>LoRA and QLoRA fine-tuning: what they actually do under the hood</title>
      <dc:creator>Tech_Nuggets</dc:creator>
      <pubDate>Tue, 09 Jun 2026 16:52:04 +0000</pubDate>
      <link>https://dev.to/tech_nuggets/lora-and-qlora-fine-tuning-what-they-actually-do-under-the-hood-3a03</link>
      <guid>https://dev.to/tech_nuggets/lora-and-qlora-fine-tuning-what-they-actually-do-under-the-hood-3a03</guid>
      <description>&lt;h1&gt;
  
  
  LoRA and QLoRA fine-tuning: what they actually do under the hood
&lt;/h1&gt;

&lt;p&gt;You spent three weeks curating a dataset of legal contract summaries: 12,000 pairs of dense legalese and plain-English counterparts. The model you picked -- a 7B parameter instruction-tuned Llama -- understands your prompts but produces summaries that read like a junior associate who memorized Blackstone but never saw a real merger clause. You reach for full fine-tuning, the obvious move. Then &lt;code&gt;torch.cuda.OutOfMemoryError&lt;/code&gt; hits at step 20 on your RTX 4090. You try gradient checkpointing. You try a smaller batch. You try half-precision. Still OOM. Your colleague says "just use LoRA" and walks off, as if that explains anything.&lt;/p&gt;

&lt;p&gt;This is the gap this post fills. You do not need another high-level "LoRA is a PEFT method" post. You need the math and the trade-offs that let you decide between LoRA, QLoRA, and full fine-tuning for your specific hardware and quality requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why parameter-efficient fine-tuning exists
&lt;/h2&gt;

&lt;p&gt;The cost of full fine-tuning is straightforward: a model with P parameters requires storing, at minimum, the model weights (2P bytes for fp16), the optimizer states (8P bytes for Adam), and the gradients (2P bytes). For Llama 3 8B with fp16 parameters, that is roughly 16 GB for weights plus 64 GB for optimizer state plus 16 GB for gradients -- 96 GB total. An RTX 4090 has 24 GB. A single A100-80 has exactly enough, barely, with no room for a batch size above 1.&lt;/p&gt;

&lt;p&gt;Parameter-efficient fine-tuning (PEFT) avoids this by keeping the vast majority of the model frozen and training only a tiny set of added parameters. The key insight is that the weight update during fine-tuning, delta W, has low intrinsic rank -- you can approximate it as a product of two much smaller matrices.&lt;/p&gt;

&lt;h2&gt;
  
  
  LoRA: low-rank adaptation
&lt;/h2&gt;

&lt;p&gt;The LoRA paper (Hu et al., 2021, arXiv 2106.09685) proposed freezing the pretrained weight matrix W in R^(d x d) and learning a low-rank decomposition:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;W' = W + BA
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;where B in R^(d x r), A in R^(r x d), and r &amp;lt;&amp;lt; d (typically r = 8 or r = 16). Instead of updating d^2 parameters per layer, you update 2dr. For d = 4096 (a common hidden dimension) and r = 8, that is 65,536 parameters per layer instead of 16,777,216 -- a reduction of roughly 256x.&lt;/p&gt;

&lt;p&gt;During the forward pass, the computation becomes:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;h = xW' = xW + xBA
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The first term uses frozen weights (no gradient needed). The second term is the adapter path. Only A and B receive gradient updates. The original W stays intact, which means you can swap adapters in and out at inference time with zero overhead: just add the adapter weights to W (or compute h = xW + xBA on the fly).&lt;/p&gt;

&lt;p&gt;Here is what the architecture looks like for a single Transformer attention layer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart LR
    subgraph Forward pass
        X[Input x] --&amp;gt; W[W frozen&amp;lt;br/&amp;gt;d x d]
        X --&amp;gt; B_adapt[B d x r]
        B_adapt --&amp;gt; A_adapt[A r x d]
        W --&amp;gt; ADD[Add]
        A_adapt --&amp;gt; ADD
        ADD --&amp;gt; OUT[Output h]
    end

    subgraph Gradient flow
        OUT --&amp;gt; GRAD_B[Gradients flow&amp;lt;br/&amp;gt;to B and A only]
        GRAD_B --&amp;gt; NO[No gradient&amp;lt;br/&amp;gt;through W]
    end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, LoRA is applied to the query and value projection matrices in each attention head. You can also extend it to key, output, and the feed-forward layers. Empirically, setting r = 8 on Q and V covers most of the benefit; doubling r beyond 16 rarely beats full fine-tuning by more than a trivial margin.&lt;/p&gt;

&lt;h2&gt;
  
  
  QLoRA: adding 4-bit quantization
&lt;/h2&gt;

&lt;p&gt;QLoRA (Dettmers et al., 2023, arXiv 2305.14314) asked: what if instead of storing W in fp16, we stored it in 4 bits and still trained adapters on top? The result is a method that can fine-tune a 65B model on a single 48 GB GPU -- something that was previously impossible.&lt;/p&gt;

&lt;p&gt;QLoRA makes three specific contributions that work together:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NF4 data type.&lt;/strong&gt; NormalFloat4 is a quantization scheme designed for normally distributed weights. It maps the 4-bit values to the quantiles of a normal distribution, so the discretization error is minimized exactly where most weight values fall. Informally, NF4 allocates more of its 16 representable values around zero and fewer in the tails.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Double quantization.&lt;/strong&gt; The quantization constants (scale and offset) themselves take space. QLoRA quantizes these constants from fp32 to fp8, saving another 0.5 bits per parameter. The total is ~4.5 bits per parameter for the base model -- about 3.5 GB for a 7B model instead of 14 GB.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paged optimizers.&lt;/strong&gt; When GPU memory runs out during a long training run, the optimizer states are paged to CPU RAM and fetched back as needed. This prevents the OOM crash but can slow training; it is a safety net, not a performance feature.&lt;/p&gt;

&lt;p&gt;During training, QLoRA dequantizes the 4-bit weights on the fly for each forward pass, computes the LoRA adapter contribution, and backpropagates only through the low-rank matrices. The dequantized weights never have their gradients computed, which is the whole source of memory savings.&lt;/p&gt;

&lt;h2&gt;
  
  
  Full comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Full fine-tuning&lt;/th&gt;
&lt;th&gt;LoRA (fp16)&lt;/th&gt;
&lt;th&gt;QLoRA (4-bit base + LoRA)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Base model memory&lt;/td&gt;
&lt;td&gt;16 GB (7B, fp16)&lt;/td&gt;
&lt;td&gt;16 GB (frozen)&lt;/td&gt;
&lt;td&gt;~3.5 GB (NF4)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Adapter memory&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;2 GB (r=8, all layers)&lt;/td&gt;
&lt;td&gt;2 GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Optimizer state&lt;/td&gt;
&lt;td&gt;~32 GB (Adam)&lt;/td&gt;
&lt;td&gt;~4 GB (only adapters)&lt;/td&gt;
&lt;td&gt;~4 GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total VRAM needed&lt;/td&gt;
&lt;td&gt;~56 GB&lt;/td&gt;
&lt;td&gt;~22 GB&lt;/td&gt;
&lt;td&gt;~9.5 GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qual. vs full FT&lt;/td&gt;
&lt;td&gt;Baseline&lt;/td&gt;
&lt;td&gt;On par or within 0.5%&lt;/td&gt;
&lt;td&gt;Within 1-2% on most benchmarks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-task support&lt;/td&gt;
&lt;td&gt;One copy per task&lt;/td&gt;
&lt;td&gt;One base + N adapters&lt;/td&gt;
&lt;td&gt;One base + N adapters&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Training speed (7B, A100)&lt;/td&gt;
&lt;td&gt;1.0x baseline&lt;/td&gt;
&lt;td&gt;~1.4x faster&lt;/td&gt;
&lt;td&gt;~0.8x slower (dequant overhead)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The speed trade-off is worth calling out explicitly: QLoRA trains slower than LoRA because every forward pass must dequantize the base weights. On a 7B model with a single A100, LoRA is roughly 1.4x faster than full fine-tuning (less data movement), while QLoRA is about 0.8x the speed of full fine-tuning (dequantization overhead). The memory savings are enormous though, which is why QLoRA dominates the conversation for consumer-grade GPUs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common pitfalls
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rank selection is not magic.&lt;/strong&gt; Setting r = 256 everywhere will not automatically improve results. Higher rank means more trainable parameters but also more noise in the gradient signal. The original LoRA paper found that a rank of 1 already captures meaningful adaptation for many tasks. Start with r = 8 on Q and V, evaluate, and only increase rank on layers that underfit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adapter merge at scale.&lt;/strong&gt; You can merge LoRA weights into W at inference time by computing W' = W + BA for each layer and discarding A and B. This eliminates the adapter inference overhead. But if you have 50 adapters for 50 different clients, you now need 50 copies of the full weights -- trading compute for storage. The right design depends on which resource you have more of.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;QLoRA is not free.&lt;/strong&gt; The NF4 dequantization adds numerical noise. On most tasks the quality loss is within the noise floor (1-2% on MMLU, roughly 0.5% on domain-specific benchmarks). But if you are tuning a model for a precision-critical task such as medical diagnosis or code correctness verification, the trade-off may swing back to full-precision LoRA or full fine-tuning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bitsandbytes versions matter.&lt;/strong&gt; QLoRA depends on the bitsandbytes library for its CUDA quantization kernels. As of June 2026, bitsandbytes is at v0.49.2 and PEFT is at v0.19.1. The API changed between v0.43 and v0.44 -- if you are using an older PEFT, pin to a compatible bitsandbytes version. A version mismatch silently falls back to CPU quantization, which runs orders of magnitude slower.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scaling the LoRA alpha.&lt;/strong&gt; The LoRA scaling factor alpha / r controls the magnitude of the adapter update. A common mistake is setting alpha too low (adapter contribution vanishes) or too high (training destabilizes). The paper recommends alpha = 2r as a starting point. Double-check this if your loss curve looks flat after 200 steps.&lt;/p&gt;

&lt;h2&gt;
  
  
  When NOT to use it
&lt;/h2&gt;

&lt;p&gt;LoRA and QLoRA are the wrong choice when:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You need to change the model's internal representations fundamentally.&lt;/strong&gt; If you are adding new knowledge that the base model does not have (a new language, a new domain with very different token statistics), low-rank updates may not have enough capacity. Continued pretraining or full fine-tuning will capture the distribution shift more effectively.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inference latency is your binding constraint and you serve from CPU.&lt;/strong&gt; LoRA merges into the weights easily on GPU, but on CPU with on-the-fly adapter computation, the extra matrix multiply for BA adds latency. You can merge ahead of time, but then every adapter becomes a separate weight file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You are fine-tuning a model smaller than 1B parameters.&lt;/strong&gt; The memory savings of PEFT are less dramatic on small models. A 350M-parameter model consumes roughly 1.4 GB in fp16 -- the adapter overhead of LoRA starts to be a significant fraction of total parameters. A simple full fine-tuning pass may fit with gradient checkpointing and a reasonable batch size.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You need deterministic training across hardware.&lt;/strong&gt; The quantization paths in QLoRA introduce non-determinism from the dequantization kernel. If you need perfectly reproducible training runs (for auditing or compliance), stick with full-precision LoRA or full fine-tuning with a fixed seed and deterministic CUDA backend.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;LoRA approximates the fine-tuning weight update as a product of two low-rank matrices (B in d x r, A in r x d), reducing trainable parameters by 100x-1000x per layer with minimal quality loss.&lt;/li&gt;
&lt;li&gt;QLoRA quantizes the frozen base model to 4-bit NF4, then trains LoRA adapters on top. A 65B model fits on a single 48 GB GPU.&lt;/li&gt;
&lt;li&gt;The practical memory equation for a 7B model: full fine-tuning ~56 GB, LoRA ~22 GB, QLoRA ~9.5 GB.&lt;/li&gt;
&lt;li&gt;Start with r = 8 on Q and V projection layers. Increase rank only if you see clear underfitting on your validation set.&lt;/li&gt;
&lt;li&gt;QLoRA trains slower than LoRA (dequantization overhead) but uses roughly half the memory. Pick based on whether you are GPU-bound or time-bound.&lt;/li&gt;
&lt;li&gt;Keep bitsandbytes and PEFT versions in sync. A version mismatch causes silent CPU fallback and catastrophic slowdown.&lt;/li&gt;
&lt;li&gt;Do not use LoRA/QLoRA for small models (under 1B), for injecting fundamentally new knowledge, or for CPU-latency-sensitive serving where merge-ahead is impractical.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;We covered how to adapt an existing model efficiently. The next step is knowing when that adaptation has actually worked -- and that means evaluation. Next post: building a reliable evaluation pipeline that catches regressions before they ship, with or without a labeled test set.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you are deciding between LoRA and QLoRA for a project right now, the key variable is your GPU budget. 24 GB or less? QLoRA. 48 GB or more? LoRA with a larger rank or full fine-tuning with LoRA on the side for rapid iteration. The code to make either choice work is a single &lt;code&gt;pip install&lt;/code&gt; away.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>lora</category>
      <category>qlora</category>
      <category>finetuning</category>
      <category>llm</category>
    </item>
    <item>
      <title>Should You Fine-Tune? The 2026 Decision Ladder (Prompt RAG LoRA Distill)</title>
      <dc:creator>AI Tech Connect</dc:creator>
      <pubDate>Sun, 07 Jun 2026 11:30:15 +0000</pubDate>
      <link>https://dev.to/rishi_kora/should-you-fine-tune-the-2026-decision-ladder-prompt-rag-lora-distill-2bm2</link>
      <guid>https://dev.to/rishi_kora/should-you-fine-tune-the-2026-decision-ladder-prompt-rag-lora-distill-2bm2</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://aitechconnect.in/tips/should-you-fine-tune-decision-ladder-2026" rel="noopener noreferrer"&gt;AI Tech Connect&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The one question that saves you a GPU bill Somewhere in the lifecycle of almost every AI feature, a team asks: "should we fine-tune?" The honest answer, the overwhelming majority of the time, is "not yet". It is a question that arrives too early, usually because fine-tuning sounds like the serious, grown-up move — the thing real machine-learning teams do, the lever that turns a generic model into your model. So a Bengaluru fintech building a transaction-narration feature, or a Manchester health-tech drafting clinical letters, spins up a training pipeline before it has wrung the value out of the cheaper rungs below. The cost of asking too early is concrete. Fine-tuning is not free even when the GPU is cheap: you take on a data-curation effort, a training and evaluation loop, a model you…&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;a href="https://aitechconnect.in/tips/should-you-fine-tune-decision-ladder-2026" rel="noopener noreferrer"&gt;Read the full article on AI Tech Connect →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

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