<?xml version="1.0" encoding="UTF-8"?>
  <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
      <title>Rajdeep Mondal - Understanding and Developing Large Language Models</title>
      <link>https://rajdeepmondal.com/series/cs324</link>
      <description>Understanding and Developing Large Language Models: every entry in the series.</description>
      <language>en-us</language>
      <managingEditor>rajdeep@rajdeepmondal.com (Rajdeep Mondal)</managingEditor>
      <webMaster>rajdeep@rajdeepmondal.com (Rajdeep Mondal)</webMaster>
      <lastBuildDate>Mon, 09 Mar 2026 12:00:00 GMT</lastBuildDate>
      <atom:link href="https://rajdeepmondal.com/series/cs324/feed.xml" rel="self" type="application/rss+xml"/>
      
  <item>
    <guid isPermaLink="true">https://rajdeepmondal.com/writing/language-model-systems-environmental-impact-is-a-design-constraint</guid>
    <title>Environmental Impact Is a Design Constraint</title>
    <link>https://rajdeepmondal.com/writing/language-model-systems-environmental-impact-is-a-design-constraint</link>
    <description>You pay for a training run once. You pay for inference on every call, and past billions of tokens the recurring bill outgrows the run.</description>
    <content:encoded><![CDATA[<div class="essay-prose"><p>Inference can outspend the training run that produced the model. The training bill closes when the run ends. The serving bill reopens on every call, and it keeps reopening for as long as people use the model.</p><p>Models run on physical infrastructure that spends energy, materials, water, land, and attention. Once a model serves billions of tokens, the serving side of that bill passes the training side. Compute is part of the product, so its cost belongs in design review.</p><p>Many teams raise environmental impact as an apology after the benchmark lands. By then model size, the serving path, and the growth in demand are already fixed. The question belongs earlier, while the design is still soft. What did this capability cost, and was the cost worth it?</p><h2 id="compute-has-two-lives">Compute Has Two Lives</h2><p>Training emissions are easy to narrate because the run is visible. It starts, it ends, and someone can put a number in a paper. Inference is harder to see and easier to leave out. It spends power on every call, and the calls do not stop.</p><p>The training number is a fact about the past. The serving number is a forecast about demand, and it moves every time the product gets more users.</p><figure class="rm-article-image"><div class="relative overflow-hidden"><div class="bg-muted absolute inset-0 z-10 animate-pulse rounded-[inherit]"><div class="animate-shimmer via-paper-bright/70 absolute inset-0 bg-linear-to-r from-transparent to-transparent"></div></div></div><figcaption>Training spends once, every call adds to the rising line, and the crossing arrives with enough served tokens.</figcaption></figure><p>After that crossing, an argument about training efficiency is an argument about the smaller half. The footprint becomes a research question and a product question at once. The product side owns the traffic, and traffic is the term that grows.</p><h2 id="the-life-cycle-is-wider-than-the-run">The Life Cycle Is Wider Than The Run</h2><p>Life cycle assessment widens the boundary past the training job. Hardware manufacturing, data center energy, cooling, grid carbon intensity, development experiments, inference traffic, and hardware retirement all sit inside it. Leave one out and the total is a guess.</p><p>Energy use depends on hardware efficiency, utilization, run duration, power draw, and cooling overhead. Emissions depend on the carbon intensity of the grid that powered the work. The same job on a different grid emits a different amount. Idle capacity spends power while it waits for work that has not arrived.</p><p>Embodied carbon counts from manufacturing to disposal, and the manufacturing half is spent before the first token exists. The runs that failed count too. Hyperparameter sweeps and repeated experiments spend real power, and they rarely reach the headline figure.</p><p>The parallelism note put its cost under one rule: nothing is free once it has to move. Energy is that rule in another unit. Power moves in and leaves as heat, and cooling overhead pays to remove it.</p><h2 id="report-compute-energy-location-carbon-intensity-and-method">Report Compute, Energy, Location, Carbon Intensity, And Method</h2><p>Treat emissions as a product metric. Estimate them before training, record them during the run, and report them after deployment. A team that cannot state its energy and carbon assumptions cannot price the trade it is making.</p><p>A usable report names six things: compute, energy, location, carbon intensity, hardware, and the estimation method. Location is there because the grid sets the carbon in every unit of energy. Method is there because all six numbers are estimates. Publish the method beside the total and a reader can check the assumption.</p><h2 id="efficiency-can-raise-total-use">Efficiency Can Raise Total Use</h2><p>A cheaper token invites more tokens. Efficiency lowers the cost of one call and can raise the total, because demand expands into whatever the price allows. The saving is real only when total work goes down.</p><p>The scaling-laws note weighed a marginal parameter against the loss it bought. Price that same marginal gain in energy and some of those trades stop clearing. Traffic decides how often the cost repeats, so the answer moves as the product grows.</p><div class="v-decision"><span class="kicker">Watch for</span><div class="body">GPU hours are the easiest number to count. Counted alone they miss grid carbon intensity, hardware manufacturing, cooling, utilization, repeated inference, and rebound effects.</div></div><h2 id="design-choices-move-the-footprint">Design Choices Move The Footprint</h2><p>The alternatives are the ordinary ones: smaller models, distillation, retrieval, routing, caching, quantization, batching, and task-specific systems. Each one removes work the product never needed. The greenest token is the one you did not need to generate.</p><p>Two of those arrived earlier in this unit. Routing and retrieval come from the selective-architectures note. Waking a few experts per token cuts the compute each token spends. Moving knowledge into an index keeps it out of the weights.</p><p>The adaptation note added the rule that fits here: take the smallest rung that clears the reliability bar. Both notes argued for the lower-footprint option before energy entered the argument.</p><p>A team that measures picks model size, caching, batching, distillation, and deployment differently from a team that guesses.</p><div class="v-decision"><span class="kicker">Operating standard</span><div class="body">A model that is cheaper to serve, easier to cache, and smaller at the same quality is better engineered.</div></div><h2 id="the-builder-test">The Builder Test</h2><p>Draw the life cycle of one system you run: training, evaluation, deployment, repeated inference, hardware, and retirement.</p><ul><li>Split the compute into training experiments, failed runs, and serving traffic.</li><li>Mark the stages where you can state a number today, and the stages where you are guessing.</li><li>Find the design change that removes the most repeated work, and price it in energy.</li></ul><p>The pile that grows is the one to design against. The stages you are guessing at are the ones to instrument first.</p><h2 id="what-carries">What Carries</h2><p>Carry the full bill. The greenest system avoided computation nobody needed. Useful work per unit of cost is how that shows up in a review.</p><p>Take one deployment claim and trace it from the corpus to the carbon. If it survives the whole trip, the claim is worth defending.</p><div class="rm-essay-close" aria-hidden="true"><svg width="76" height="32" viewBox="0 0 76 32" aria-hidden="true" class="rm-fmark-essay"><path d="M 2 14 Q 18 2 36 14 T 74 12" fill="none" stroke="currentColor" stroke-width="1.1" stroke-linecap="round" opacity="0.5"></path><line x1="2" y1="24" x2="60" y2="24" stroke="currentColor" stroke-width="1.1"></line><circle cx="68" cy="24" r="2.8" fill="var(--vermilion)"></circle></svg></div></div>]]></content:encoded>
    <pubDate>Mon, 09 Mar 2026 12:00:00 GMT</pubDate>
    <author>rajdeep@rajdeepmondal.com (Rajdeep Mondal)</author>
    <category>ai</category><category>language-models</category><category>foundation-models</category><category>environment</category><category>emissions</category><category>sustainability</category><category>compute</category>
  </item>

  <item>
    <guid isPermaLink="true">https://rajdeepmondal.com/writing/language-model-systems-adaptation-is-how-general-models-become-useful</guid>
    <title>Adaptation Is How General Models Become Useful</title>
    <link>https://rajdeepmondal.com/writing/language-model-systems-adaptation-is-how-general-models-become-useful</link>
    <description>Take the least invasive adaptation that clears the reliability bar. A model can learn the format of helpfulness without learning the work.</description>
    <content:encoded><![CDATA[<div class="essay-prose"><p>Take the least invasive adaptation that clears the reliability bar. A model can learn the format of helpfulness without learning the work. Heavier methods make that failure easier to buy and harder to see.</p><p>Pretraining creates broad capability. Adaptation points that capability at a task, domain, user, or policy. Every method changes one of three things: the model weights, the input, or a small learned module beside it.</p><h2 id="pretraining-makes-breadth-adaptation-buys-a-job">Pretraining Makes Breadth, Adaptation Buys A Job</h2><p>A general model is broad on purpose. Adaptation aims that breadth at one job. The job is a domain, an instruction style, a policy, a tool interface, or a user population. The gain arrives when the target behavior becomes easier for the model than the generic behavior.</p><p>Find out what the model already holds before you change anything. Probing trains a small head on frozen representations and reports what the encoding contains. When the capability is already there, steering reaches it and new weights buy nothing.</p><h2 id="prompt-retrieve-adapt-then-fine-tune">Prompt, Retrieve, Adapt, Then Fine-Tune</h2><p>Four rungs, four prices. Prompting is cheap and reversible. Retrieval adds fresh facts and leaves the weights untouched. Adapters add small trainable modules that swap by task or domain. Full fine-tuning updates weights on supervised or preference data and gives the most control at the highest cost.</p><p>Between prompting and full weights sit the tuned inputs. Prompt tuning learns soft prompt vectors. Prefix tuning injects learned vectors into attention layers to steer generation, and the base model stays fixed for both.</p><figure class="rm-article-image"><div class="relative overflow-hidden"><div class="bg-muted absolute inset-0 z-10 animate-pulse rounded-[inherit]"><div class="animate-shimmer via-paper-bright/70 absolute inset-0 bg-linear-to-r from-transparent to-transparent"></div></div></div><figcaption>Each rung up buys more control over behavior and charges for it in cost, evaluation burden, and regression risk.</figcaption></figure><p>Which layer holds the missing piece? If the answer is current knowledge, retrieval is safer than new weights. If the answer is format, prompting or adapters do it. The trap is fine-tuning before you prove the problem needs it.</p><p>The selective-architectures note moved knowledge into a retrieval index and away from the weights. That is the same selection question in a new place. Routing decides what wakes. Adaptation decides what changes.</p><h2 id="flexibility-trades-against-stability">Flexibility Trades Against Stability</h2><p>The trade is flexibility against stability. Full fine-tuning changes the most and risks forgetting and deployment complexity. Lightweight adaptation is cheaper and modular, and it sometimes fails to move behavior far enough.</p><p>Fine-tuning does not add knowledge the way a document upload adds a file. The weights move, and behavior on tasks you never adapted moves with them. You pay for depth whether or not you measure the cost.</p><p>Modularity is why adapters stay in the running. One base model serves many jobs when small task-specific parameters swap in and out. A second set of full weights is a second artifact to serve, evaluate, and roll back.</p><h2 id="a-model-can-learn-the-format-of-helpfulness">A Model Can Learn The Format Of Helpfulness</h2><p>Preference and instruction tuning teach more than facts and formats. They teach the model which behaviors humans prefer in an interaction. A model that learns the preferred shape of an answer has the costume. Whether it can do the work is a separate measurement.</p><p>Adaptation can improve the benchmark and still narrow the model into a brittle local trick. The failing version fine-tunes until the target examples look good. It teaches surface style, benchmark-specific habits, and refusal patterns that break on the first unfamiliar input.</p><p>Catching the costume takes examples the tuning never saw. Use held-out tasks, adversarial checks, and rewordings that keep the work while changing the surface. Score the capability, and treat matching phrasing as weak evidence.</p><p>The first harms note named the rule: every threshold picks an error. A refusal boundary is a threshold. Tune it on examples that all look alike, and the model refuses the wrong things once real traffic arrives.</p><h2 id="measure-the-regression-beside-the-target">Measure The Regression Beside The Target</h2><p>A serious pass measures the target and the damage in the same run. Skip the damage and you ship an improvement you cannot price.</p><ul><li>Target-task improvement, scored on tasks held out from the tuning data.</li><li>General ability regression on the tasks you never meant to touch.</li><li>Safety regression, including refusals that now fire on ordinary requests.</li><li>Domain shift, measured on traffic collected outside the tuning distribution.</li><li>Format overfitting, caught by rewording the same task and scoring again.</li><li>Interface match between the adaptation data and the deployed contract.</li></ul><p>Test outside the tuning set every time, and keep a holdout that represents the deployment world. Define that world before you build it. The capabilities note called it the interaction contract: prompt format, examples, context, decoding rule, tools, retries, refusal policy, and scoring.</p><div class="v-decision"><span class="kicker">Holdout rule</span><div class="body">The holdout must match the deployed contract field by field. A holdout that keeps the tidy tuning format measures a system nobody runs.</div></div><p>Run this pass before launch, while the method is still cheap to change. After launch, the same comparison costs a migration and a second round of evaluation.</p><h2 id="the-builder-test">The Builder Test</h2><p>Take one task you already ship. Build the retrieval-prompt version and the adapter version of it. Run both against the same held-out contract.</p><p>Record cost, reversibility, evaluation burden, and failure risk for each one. Ship the cheaper rung that clears the bar. Keep both sets of measurements, because the next task starts from them instead of from an argument.</p><h2 id="what-carries">What Carries</h2><p>Adaptation stays as small as possible and as strong as necessary. Anything more is extra risk and extra maintenance.</p><p>Every rung on that ladder costs compute, and the bill continues long after the launch.</p><div class="rm-essay-close" aria-hidden="true"><svg width="76" height="32" viewBox="0 0 76 32" aria-hidden="true" class="rm-fmark-essay"><path d="M 2 14 Q 18 2 36 14 T 74 12" fill="none" stroke="currentColor" stroke-width="1.1" stroke-linecap="round" opacity="0.5"></path><line x1="2" y1="24" x2="60" y2="24" stroke="currentColor" stroke-width="1.1"></line><circle cx="68" cy="24" r="2.8" fill="var(--vermilion)"></circle></svg></div></div>]]></content:encoded>
    <pubDate>Sat, 07 Mar 2026 12:00:00 GMT</pubDate>
    <author>rajdeep@rajdeepmondal.com (Rajdeep Mondal)</author>
    <category>ai</category><category>language-models</category><category>foundation-models</category><category>adaptation</category><category>fine-tuning</category><category>prompt-tuning</category><category>rlhf</category>
  </item>

  <item>
    <guid isPermaLink="true">https://rajdeepmondal.com/writing/language-model-systems-selective-architectures-spend-compute-where-it-matters</guid>
    <title>Selective Architectures Move The Hard Problem Into Routing</title>
    <link>https://rajdeepmondal.com/writing/language-model-systems-selective-architectures-spend-compute-where-it-matters</link>
    <description>Mixture-of-experts wakes a few experts per token and retrieval moves knowledge into an index. Selection becomes the new failure point, and it needs its own measurement.</description>
    <content:encoded><![CDATA[<div class="essay-prose"><p>Mixture-of-experts wakes a few experts per token. Retrieval moves knowledge out of the weights and into an index. Both buy capacity, and both make selection the new failure point.</p><p>Total parameters stop describing the bill. A router decides which parameters wake for this token, and that decision sets the cost.</p><figure class="rm-article-image"><div class="relative overflow-hidden"><div class="bg-muted absolute inset-0 z-10 animate-pulse rounded-[inherit]"><div class="animate-shimmer via-paper-bright/70 absolute inset-0 bg-linear-to-r from-transparent to-transparent"></div></div></div><figcaption>Routing moves the hard problem: capacity is conditional, and the router owns the decision.</figcaption></figure><h2 id="conditional-compute-asks-which-parts-must-wake">Conditional Compute Asks Which Parts Must Wake</h2><p>Dense scaling spends every parameter on every token. Every layer runs and every weight multiplies, whatever the token contains. A selective system asks which parts must wake for this input.</p><figure class="rm-article-image"><div class="relative overflow-hidden"><div class="bg-muted absolute inset-0 z-10 animate-pulse rounded-[inherit]"><div class="animate-shimmer via-paper-bright/70 absolute inset-0 bg-linear-to-r from-transparent to-transparent"></div></div></div><figcaption>The gap between the total and the active path is the whole promise, and a wrong choice spends it.</figcaption></figure><p>That question buys capacity and specialization. The model holds more parameters than any one token pays for, and different inputs wake different parts. The cost lands on whatever makes the choice.</p><p>Reach for a selective architecture when the bottleneck is capacity or knowledge access. A vague product spec does not improve because a router picks the expert. You keep the problem and add a router.</p><h2 id="a-router-buys-capacity-and-sells-you-a-routing-problem">A Router Buys Capacity And Sells You A Routing Problem</h2><p>A sparse mixture-of-experts model puts a router in front of a set of expert networks. Each token goes to a selected subset, and only that subset runs. Total parameters rise while active compute per token tracks the subset that ran.</p><p>Switch Transformer sends each token to one expert. Routing gets simpler and the scaling argument gets simpler with it. One expert per token leaves nothing to dilute a wrong choice.</p><p>Load-balancing losses exist because routers collapse. Without pressure to spread load, a router learns to send every token to the same expert. Real traffic pushes the same way, because one domain can dominate a batch. The rest of the capacity sits idle while you pay to hold it in memory.</p><p>Training also gets less stable, because a small change in router scores moves a token to a different expert. Specialization is a training outcome, and the balancing term pushes against it. Balance and specialization pull in opposite directions, so you measure both.</p><h2 id="retrieval-moves-knowledge-out-of-the-weights">Retrieval Moves Knowledge Out Of The Weights</h2><p>Retrieval attacks a different bottleneck. RAG conditions generation on passages pulled from an index, and RETRO retrieves chunks during generation itself. Both lower the pressure to memorize everything in parameters.</p><p>A secret trained into the weights resists deletion, as the security note showed. A row in an index leaves when you delete the row. The legality note ended at a takedown, which is cheaper to serve against an index than against a checkpoint.</p><p>Attribution turns from a promise into a pointer to the passage that produced the sentence. Weights are an expensive place to keep a fact that changes, and the index updates without a training run. The retriever now sits on the critical path, and a wrong passage becomes a confident wrong answer.</p><p>A retriever can also return nothing useful and leave the model to answer from the weights anyway. That failure reads as a normal answer, and the log is the only place it shows.</p><h2 id="selection-must-be-inspectable">Selection Must Be Inspectable</h2><p>The overview note set one rule. When a model surprises you, name the layer that did the work. A selective system adds a layer that chooses, so the router and the retriever join the weights as suspects.</p><p>Log the identity of the chosen path rather than a score for it. Which expert handled this token? Which passage did the retriever return? A system that cannot answer those two questions has added complexity nobody can debug.</p><p>Treat the path log as a shipped feature. Without it, a regression in one domain arrives as a support ticket instead of a metric.</p><div class="v-decision"><span class="kicker">Architecture rule</span><div class="body">Selective compute helps only when the router or the retriever beats brute force on your real traffic.</div></div><h2 id="sparse-compute-saves-work-only-when-routing-cooperates">Sparse Compute Saves Work Only When Routing Cooperates</h2><p>Routing overhead has a unit, and the parallelism note named it. Communication competes with compute, and a cluster that waits is not learning. A router adds communication, because tokens must travel to whichever device holds their expert.</p><p>Routing overhead, expert imbalance, and brittle specialization each spend part of the saving before it arrives. Memory holds every expert whether it fires or not. Batching gets harder when the tokens in one batch route to different experts.</p><p>Fewer active parameters describes one line of the bill. Wall-clock time for a batch covers the rest. Routing adds to that number before conditional compute takes anything off it. A saving you cannot see in the clock is arithmetic about parameters.</p><h2 id="the-builder-test">The Builder Test</h2><p>Take one batch of real traffic and log the selected path for every token. Keep the expert identity and the retrieved passage ids next to the output. Then read three numbers off that log.</p><ul><li>Expert load across the batch, which shows whether the router collapsed onto a few experts.</li><li>Quality by domain against a dense baseline, because an average gain hides the slice that got worse.</li><li>Active compute and the communication time the router added, counted together.</li></ul><p>Keep the dense baseline alive long enough to compare. A selective system without a baseline reports only its own numbers.</p><p>If expert load is lopsided, fix the balancing term before you buy more experts. If one domain lost quality, send that domain to the dense path until the router earns it back.</p><h2 id="what-carries">What Carries</h2><p>When a model chooses what to use, the choice is part of the model. I treat a router and a retriever as components with owners and dashboards, the same as a service. Without that, the capacity you bought stays theoretical.</p><p>Routing decides what wakes. Adaptation decides what changes.</p><div class="rm-essay-close" aria-hidden="true"><svg width="76" height="32" viewBox="0 0 76 32" aria-hidden="true" class="rm-fmark-essay"><path d="M 2 14 Q 18 2 36 14 T 74 12" fill="none" stroke="currentColor" stroke-width="1.1" stroke-linecap="round" opacity="0.5"></path><line x1="2" y1="24" x2="60" y2="24" stroke="currentColor" stroke-width="1.1"></line><circle cx="68" cy="24" r="2.8" fill="var(--vermilion)"></circle></svg></div></div>]]></content:encoded>
    <pubDate>Thu, 05 Mar 2026 12:00:00 GMT</pubDate>
    <author>rajdeep@rajdeepmondal.com (Rajdeep Mondal)</author>
    <category>ai</category><category>language-models</category><category>foundation-models</category><category>mixture-of-experts</category><category>retrieval</category><category>rag</category><category>retro</category>
  </item>

  <item>
    <guid isPermaLink="true">https://rajdeepmondal.com/writing/language-model-systems-scaling-laws-make-compute-legible</guid>
    <title>Scaling Laws Make Compute Legible</title>
    <link>https://rajdeepmondal.com/writing/language-model-systems-scaling-laws-make-compute-legible</link>
    <description>Small probe runs estimate the slope before a frontier run spends real money, and the curve they return speaks for the setup that produced it.</description>
    <content:encoded><![CDATA[<div class="essay-prose"><p>Small probe runs estimate the slope before a frontier run spends real money. The curve they return speaks for the setup that produced it and for nothing else. Carry it past that setup and the number it gives you is a guess.</p><h2 id="scaling-laws-turn-ambition-into-accounting">Scaling Laws Turn Ambition Into Accounting</h2><p>A scaling law measures how loss changes as you vary model size, dataset size, and compute. Kaplan-style work found smooth power-law improvement across all three. Smoothness makes the small experiment worth running, because a small run forecasts a large one. The goal is to put a training budget where it buys the most capability.</p><p>Train several smaller models across a range of sizes and token counts, then fit the trend. The fit turns a future expense into a present decision, and it makes the large run less blind.</p><p>I read a pilot as a purchase of information about the slope. A pilot that returns a leaderboard number and no slope buys nothing. Answer the resource-allocation question first, and chase the leaderboard after.</p><div class="uth-essay uth-figure-embed"><div><figure class="fig reveal" id="cs324-scaling-claim">
  
  <div class="fig-head">
    <span class="fig-title">scaling laws turn compute into a claim</span>
    <span class="ctrl">
      
      
    </span>
  </div>
  <div class="stage" id="cs324-scaling-claim-stage" role="group" aria-live="polite" aria-describedby="cs324-scaling-claim-caption">
    <div class="course-visual scale-wrap" aria-hidden="true">
      <div class="scale-chart">
        <span class="scale-dot"></span><span class="scale-dot"></span><span class="scale-dot"></span><span class="scale-dot"></span>
        <span class="scale-line"></span><span class="scale-big">planned run</span><span class="scale-axis-x"></span><span class="scale-axis-y"></span>
      </div>
      <div class="scale-panel">
        <div class="scale-row" data-scale="probe"><b>probe</b><span>small runs reveal the trend</span></div>
        <div class="scale-row" data-scale="fit"><b>fit</b><span>slope turns guesses into budget math</span></div>
        <div class="scale-row" data-scale="allocate"><b>allocate</b><span>choose data and model size together</span></div>
        <div class="scale-row" data-scale="check"><b>check</b><span>quality shifts can break the extrapolation</span></div>
      </div>
    </div>
    <div class="course-rail" data-rail aria-hidden="true"><span class="course-node" data-node="0">
        <span class="course-dot" aria-hidden="true">1</span>
        <span class="course-node-label">measure</span>
      </span><span class="course-node" data-node="1">
        <span class="course-dot" aria-hidden="true">2</span>
        <span class="course-node-label">fit</span>
      </span><span class="course-node" data-node="2">
        <span class="course-dot" aria-hidden="true">3</span>
        <span class="course-node-label">choose</span>
      </span><span class="course-node" data-node="3">
        <span class="course-dot" aria-hidden="true">4</span>
        <span class="course-node-label">qualify</span>
      </span></div>
    <div class="course-grid"><div class="course-step" data-step="0">
        <span class="course-k">measure</span>
        <span class="course-v">run controlled experiments across budgets</span>
      </div><div class="course-step" data-step="1">
        <span class="course-k">fit</span>
        <span class="course-v">estimate how loss changes with data, parameters, and compute</span>
      </div><div class="course-step" data-step="2">
        <span class="course-k">choose</span>
        <span class="course-v">allocate the fixed budget before the expensive run</span>
      </div><div class="course-step" data-step="3">
        <span class="course-k">qualify</span>
        <span class="course-v">state what assumptions the curve does not prove</span>
      </div></div>
    <div class="course-status" data-status aria-live="polite"><b>measure.</b> run controlled experiments across budgets</div>
  </div>
  <figcaption id="cs324-scaling-claim-caption">A scaling law is useful because it narrows a decision. It is dangerous when treated as destiny.</figcaption>
</figure></div><span hidden=""></span></div><h2 id="compute-optimal-training-balances-parameters-against-tokens">Compute-Optimal Training Balances Parameters Against Tokens</h2><p>Compute-optimal work sharpened that lesson into an allocation rule. A fixed compute budget splits between parameters and tokens. Spend too much on parameters and too little on data, and the model underlearns. Spend too much data on a small model, and the model cannot use the signal. Find the balance before the bill gets large.</p><p>You pay for both failures out of the same fixed budget. Every parameter you add is a token you do not train on.</p><p>A token budget is also a step count on a cluster. Nothing is free once it has to move. The parallelism note priced what each step carries: gradients, activations, parameters, and optimizer state. Every extra token buys signal and pays communication.</p><h2 id="diagnose-the-bottleneck-before-you-buy-the-next-parameter">Diagnose The Bottleneck Before You Buy The Next Parameter</h2><p>Four diagnoses cover the common cases: parameter-limited, data-limited, compute-limited, and evaluation-limited. A bigger model is a strategy only when the data budget already fits. Otherwise the new parameters sit on top of a corpus that cannot feed them.</p><figure class="rm-article-image"><div class="relative overflow-hidden"><div class="bg-muted absolute inset-0 z-10 animate-pulse rounded-[inherit]"><div class="animate-shimmer via-paper-bright/70 absolute inset-0 bg-linear-to-r from-transparent to-transparent"></div></div></div><figcaption>One fixed compute budget splits between parameters and tokens, and each bottleneck diagnosis points at a different half of that split.</figcaption></figure><p>Each diagnosis names a different purchase. Parameter-limited buys capacity, and data-limited buys tokens or a cleaner corpus. Compute-limited shrinks the plan until it fits the budget you hold.</p><p>The spend has four axes. Fixed compute buys parameters, tokens, data quality, and evaluation. Cleaning the corpus and building the evaluation draw on the same budget as the run.</p><p>Evaluation-limited is the case a loss curve cannot see. Loss falls, and the number the product cares about stays flat. Downstream evidence settles it. The capabilities note supplies the form.</p><p>Record the interaction contract, then read the failure slice under it. Prompt format, decoding, and scoring all belong in that record. Fix the evaluation first, because a blind measurement leaves every other diagnosis unproven.</p><div class="v-decision"><span class="kicker">Compute rule</span><div class="body">Scale is a choice about which bottleneck deserves the next dollar. Name the bottleneck, then name the spend.</div></div><h2 id="the-curve-speaks-only-for-its-own-setup">The Curve Speaks Only For Its Own Setup</h2><p>The fit is empirical. Someone measured points and drew a line through them, which is why the measured range matters. Five assumptions sit behind that fit: data quality, model family, optimizer, token budget, and evaluation target. The line holds while all five hold.</p><p>Smoothness inside the measured range says nothing about the region past it. Check the fit quality, and check that the planned run lands inside the range you measured.</p><p>The data note gives the mechanism behind a data-quality shift. Mixture weights decide what the corpus treats as normal. Re-weight the mixture and the fit now describes a different object. Contamination bends the line from the other side, because the evaluation set leaks into training.</p><p>A changed optimizer or a changed architecture voids the fit the same way. The old slope then describes a model you no longer train.</p><h2 id="scaling-scales-the-risks-too">Scaling Scales The Risks Too</h2><p>The curve forecasts loss and stops there. Memorization, misuse capability, energy use, and deployment impact all grow with the run. Each one needs its own measurement on its own schedule.</p><p>Decide who owns each measurement before the cluster starts. The run produces all four whether or not anyone watches.</p><p>The same accounting continues after launch. A larger model costs more per token, on every call, for as long as the product runs. The marginal quality gain has to cover latency, money, and environmental cost. Price that gain against the traffic you serve, rather than against the benchmark you published.</p><h2 id="the-builder-test">The Builder Test</h2><p>Take one scaling plot you rely on and name the decision it changes. The list is short: model size, token count, compute budget, or accepted risk. A curve that changes none of them is decoration.</p><p>Then write the setup beside the plot. Data mixture, model family, optimizer, token budget, evaluation target. If the planned run differs on any line, refit with a probe sweep before you spend.</p><h2 id="what-carries">What Carries</h2><p>A scaling law is a planning instrument, and it holds for exactly as long as its assumptions hold. The forecast is conditional on a setup you own and must re-check.</p><p>A budget argument has a second answer. Stop spending the whole model on every token.</p><div class="rm-essay-close" aria-hidden="true"><svg width="76" height="32" viewBox="0 0 76 32" aria-hidden="true" class="rm-fmark-essay"><path d="M 2 14 Q 18 2 36 14 T 74 12" fill="none" stroke="currentColor" stroke-width="1.1" stroke-linecap="round" opacity="0.5"></path><line x1="2" y1="24" x2="60" y2="24" stroke="currentColor" stroke-width="1.1"></line><circle cx="68" cy="24" r="2.8" fill="var(--vermilion)"></circle></svg></div></div>]]></content:encoded>
    <pubDate>Tue, 03 Mar 2026 12:00:00 GMT</pubDate>
    <author>rajdeep@rajdeepmondal.com (Rajdeep Mondal)</author>
    <category>ai</category><category>language-models</category><category>foundation-models</category><category>scaling-laws</category><category>compute</category><category>evaluation</category><category>chinchilla</category>
  </item>

  <item>
    <guid isPermaLink="true">https://rajdeepmondal.com/writing/language-model-systems-parallelism-is-the-hidden-curriculum</guid>
    <title>Parallelism Is the Hidden Curriculum</title>
    <link>https://rajdeepmondal.com/writing/language-model-systems-parallelism-is-the-hidden-curriculum</link>
    <description>If communication dominates compute, an expensive cluster waits instead of learning. The scarce resource picks the parallel strategy, so name the wall before you name the tool.</description>
    <content:encoded><![CDATA[<div class="essay-prose"><p>If communication dominates compute, an expensive cluster waits instead of learning. An idle accelerator costs the same per hour as a busy one. The scarce resource picks the parallel strategy.</p><h2 id="frontier-training-is-distributed-systems-engineering">Frontier Training Is Distributed Systems Engineering</h2><p>The syllabus page behind this note is mostly a reading list. Read the references and one lesson repeats. Frontier training of a language model is distributed systems engineering.</p><p>Large models exceed the memory and throughput of one accelerator. You slice the training job across devices because nothing else fits. The split is mandatory. The communication bill arrives with it.</p><p>You do not need a frontier run to meet this constraint. Any job that outgrows one device inherits the same accounting.</p><h2 id="three-splits-three-bills">Three Splits, Three Bills</h2><p>The hard part is deciding what each device stores, what each device computes, and when the devices talk. Three splits answer that, and each one moves the pressure to a different place: memory, communication, synchronization, or idle time.</p><p>Data parallelism replicates. Each worker takes a different batch and holds a full copy of the model and the optimizer state. The bill is replication in memory plus a gradient collective on every step. It is the simplest split to write and the first to run out of memory.</p><p>Tensor parallelism splits the large matrix operations across devices. A giant layer no longer has to fit on one device. It pays in traffic inside the layer, on every forward and backward pass.</p><p>Pipeline parallelism assigns layer ranges to stages and streams microbatches through them. A stage at the front finishes early and waits for the stages behind it. That wait is the bubble. Microbatches shrink the bubble and never delete it.</p><p>Real systems combine all three. Sharding saves memory because it makes ownership explicit. That explicit ownership is what you audit when the run stalls.</p><figure class="rm-article-image"><div class="relative overflow-hidden"><div class="bg-muted absolute inset-0 z-10 animate-pulse rounded-[inherit]"><div class="animate-shimmer via-paper-bright/70 absolute inset-0 bg-linear-to-r from-transparent to-transparent"></div></div></div><figcaption>Each split decides what a device owns and what it must send, and each pays in a different currency.</figcaption></figure><h2 id="communication-is-part-of-the-computation">Communication Is Part Of The Computation</h2><p>Every split creates messages. Activations, gradients, parameters, and optimizer states move between devices while the arithmetic waits for them. The hidden curriculum is communication.</p><p>Nothing is free once it has to move. Parameters, activations, gradients, optimizer state, and tokens compete for the same memory and the same bandwidth. A blocking collective sits inside the step time, and the profiler charges it to the step.</p><p>Topology decides which of those messages is cheap. A split that ignores the wiring pays for every message at the slowest link.</p><p>Pipeline bubbles, slow synchronization, uneven shards, and memory imbalance make a large cluster behave like a much smaller one. Measure the ratio before you buy another rack. If message time per step grows faster than arithmetic time, more hardware makes the ratio worse.</p><div class="uth-essay uth-figure-embed"><div><figure class="fig reveal" id="cs324-parallelism-stalls">
  
  <div class="fig-head">
    <span class="fig-title">parallelism moves the wait around</span>
    <span class="ctrl">
      
      
    </span>
  </div>
  <div class="stage" id="cs324-parallelism-stalls-stage" role="group" aria-live="polite" aria-describedby="cs324-parallelism-stalls-caption">
    <div class="course-visual par-wrap" aria-hidden="true">
      <div class="par-grid">
        <div class="par-stage"><span class="par-gpu">gpu 1</span><span class="par-cell" data-par="sync">mb1</span><span class="par-cell" data-par="shard">a</span><span class="par-cell">mb2</span><span class="par-cell">mb3</span></div>
        <div class="par-stage"><span class="par-gpu">gpu 2</span><span class="par-cell" data-par="sync">mb1</span><span class="par-cell" data-par="shard">b</span><span class="par-cell is-bubble">wait</span><span class="par-cell">mb2</span></div>
        <div class="par-stage"><span class="par-gpu">gpu 3</span><span class="par-cell" data-par="sync">mb1</span><span class="par-cell" data-par="shard">c</span><span class="par-cell is-bubble">wait</span><span class="par-cell is-bubble">wait</span></div>
        <div class="par-stage"><span class="par-gpu">gpu 4</span><span class="par-cell" data-par="sync">mb1</span><span class="par-cell" data-par="shard">d</span><span class="par-cell">mb4</span><span class="par-cell is-bubble">wait</span></div>
      </div>
      <div class="par-side">
        <div class="par-meter"><span>useful GPU time</span><span class="par-track"><i class="par-fill"></i></span></div>
        <div class="par-note">Parallelism is a scheduling problem. More devices help only when memory, communication, and idle bubbles are managed together.</div>
      </div>
    </div>
    <div class="course-rail" data-rail aria-hidden="true"><span class="course-node" data-node="0">
        <span class="course-dot" aria-hidden="true">1</span>
        <span class="course-node-label">data parallel</span>
      </span><span class="course-node" data-node="1">
        <span class="course-dot" aria-hidden="true">2</span>
        <span class="course-node-label">tensor parallel</span>
      </span><span class="course-node" data-node="2">
        <span class="course-dot" aria-hidden="true">3</span>
        <span class="course-node-label">pipeline parallel</span>
      </span><span class="course-node" data-node="3">
        <span class="course-dot" aria-hidden="true">4</span>
        <span class="course-node-label">choose</span>
      </span></div>
    <div class="course-grid"><div class="course-step" data-step="0">
        <span class="course-k">data parallel</span>
        <span class="course-v">simple scaling, but gradients must be synchronized</span>
      </div><div class="course-step" data-step="1">
        <span class="course-k">tensor parallel</span>
        <span class="course-v">split large operations, then communicate partial results</span>
      </div><div class="course-step" data-step="2">
        <span class="course-k">pipeline parallel</span>
        <span class="course-v">split layers, but bubbles appear between stages</span>
      </div><div class="course-step" data-step="3">
        <span class="course-k">choose</span>
        <span class="course-v">the best plan is the one that fits memory while wasting the least time</span>
      </div></div>
    <div class="course-status" data-status aria-live="polite"><b>data parallel.</b> simple scaling, but gradients must be synchronized</div>
  </div>
  <figcaption id="cs324-parallelism-stalls-caption">Parallelism is not just more GPUs. It is a schedule for where memory pressure and communication stalls land.</figcaption>
</figure></div><span hidden=""></span></div><h2 id="name-the-wall-before-you-choose-the-tool">Name The Wall Before You Choose The Tool</h2><p>Bottlenecks move. You start short on memory, then short on bandwidth, then short on utilization, then short on patience for debugging.</p><p>Upstream choices move them. Width and context length decide how much memory one step needs, and the modeling note filed both under representation. A tokenizer that cuts text into smaller pieces spends more positions, and more positions cost memory. The token budget decides how many steps the run must survive, and the scaling-laws note picks that budget.</p><p>Activation checkpointing is the worked example of trading one wall for another. You drop the stored activations and recompute them during the backward pass. Memory pressure falls. Compute per step rises. Take the trade when memory is the wall, and refuse it when compute is.</p><div class="v-decision"><span class="kicker">Rule of thumb</span><div class="body">The wall is memory, compute, communication, or scheduling. The scarce item under it is memory per device, matrix size, batch size, bandwidth, or latency. Write both down before you write any code.</div></div><h2 id="a-week-long-run-is-a-reliability-problem">A Week-Long Run Is A Reliability Problem</h2><p>A week-long run is a reliability problem before it is a training problem. Throughput, device utilization, stragglers, failed workers, synchronization stalls, and numerical instability are first-class signals. Debugging a distributed job needs observability at the cluster level.</p><p>One lost worker costs every step since the last checkpoint. Every other device recomputes that stretch, so the whole cluster pays for one failed machine. The checkpoint interval is a budget decision, and the recovery path belongs in the plan.</p><p>A straggler never crashes, so nothing raises an alarm. The step ends when the slowest device finishes, and one slow shard sets the pace for the whole run. Numerical instability belongs on that dashboard too. A diverged run wastes as many device-hours as a dead worker.</p><h2 id="the-builder-test">The Builder Test</h2><p>Draw the data movement for one training plan. Say where parameters, activations, gradients, and optimizer state live at every step. Mark what is replicated, what is sharded, what is communicated, and when devices wait.</p><p>Then hold the drawing against a real trace. Collectives, bubbles, synchronization, imbalance, memory pressure, and topology all appear there. A plan you cannot draw is not a plan yet. The trace names the part you guessed.</p><p>Measure the devices doing useful work at the same instant. That count is smaller than the rack count, and it is the one that predicts the finish time.</p><h2 id="what-carries">What Carries</h2><p>Scaling training means keeping useful work in motion while communication and memory stay under control. Large-model parallelism is resource ownership plus communication scheduling. Once you can keep a cluster busy, the next question is what to buy with it.</p><div class="rm-essay-close" aria-hidden="true"><svg width="76" height="32" viewBox="0 0 76 32" aria-hidden="true" class="rm-fmark-essay"><path d="M 2 14 Q 18 2 36 14 T 74 12" fill="none" stroke="currentColor" stroke-width="1.1" stroke-linecap="round" opacity="0.5"></path><line x1="2" y1="24" x2="60" y2="24" stroke="currentColor" stroke-width="1.1"></line><circle cx="68" cy="24" r="2.8" fill="var(--vermilion)"></circle></svg></div></div>]]></content:encoded>
    <pubDate>Sun, 01 Mar 2026 12:00:00 GMT</pubDate>
    <author>rajdeep@rajdeepmondal.com (Rajdeep Mondal)</author>
    <category>ai</category><category>language-models</category><category>foundation-models</category><category>parallelism</category><category>distributed-training</category><category>gpu</category><category>infrastructure</category>
  </item>

  <item>
    <guid isPermaLink="true">https://rajdeepmondal.com/writing/language-model-systems-training-turns-architecture-into-behavior</guid>
    <title>Training Turns Architecture Into Behavior</title>
    <link>https://rajdeepmondal.com/writing/language-model-systems-training-turns-architecture-into-behavior</link>
    <description>A model learns whatever game the training objective writes down, and a lower loss can still hide worse behavior on the task users need.</description>
    <content:encoded><![CDATA[<div class="essay-prose"><p>The model learns whatever game the objective writes down. A lower training loss can still hide worse behavior on the task your users need.</p><p>Architecture is potential. Training turns that potential into a policy over text. The objective decides which policy, and the optimizer decides how cleanly it arrives.</p><h2 id="the-objective-is-the-curriculum">The Objective Is The Curriculum</h2><p>Training is practice. Every objective hides part of a sequence and pays the model to put it back. The part you hide is the skill you buy.</p><p>Four names cover the usual objectives: continuation, reconstruction, denoising, and conditional generation. Each one is a different game, and each one produces a different model.</p><p>A decoder-only model hides the future. It predicts the next token from the left context, and continuation becomes the behavior it does best.</p><p>Encoder-only training hides tokens in the middle. Masked language modeling scores the reconstruction, which builds the bidirectional representations that understanding tasks use.</p><p>Denoising corrupts the input and scores the repair. A model trained that way learns the meaning of the pieces that went missing.</p><p>Encoder-decoder training keeps input and output apart. The model reads one sequence and generates another, which is what translation, summarization, and text-to-text tasks need.</p><figure class="rm-article-image"><div class="relative overflow-hidden"><div class="bg-muted absolute inset-0 z-10 animate-pulse rounded-[inherit]"><div class="animate-shimmer via-paper-bright/70 absolute inset-0 bg-linear-to-r from-transparent to-transparent"></div></div></div><figcaption>Three objectives hide three different spans of the same sentence.</figcaption></figure><h2 id="choose-the-objective-for-the-behavior-you-need">Choose The Objective For The Behavior You Need</h2><p>A generative assistant, a retrieval encoder, and a translation model must not share one training story without a reason. A retrieval system built on a generator asks the model for a behavior it never practiced.</p><p>The capabilities note put the interface inside the claim. The objective is that same commitment one layer down. A chat box asks for continuation, and next-token prediction practices exactly that. A search box asks for a representation, and a retrieval encoder practices that instead.</p><p>Write the behavior first. Pick the objective that practices it, then pick the architecture that fits the objective.</p><p>This breaks when a team copies a popular objective. The model learns the game you wrote down, and only that game gets scored. A wrong objective costs a full run. You find out at the end.</p><h2 id="optimization-writes-behavior-into-the-weights">Optimization Writes Behavior Into The Weights</h2><p>Adam tracks adaptive moments of the gradients. Precision choices and stability tricks decide whether the objective can move through billions of parameters without wasting the run.</p><p>Batch size, learning-rate schedule, precision, data order, and checkpointing leave fingerprints on the final behavior. Architecture decides what a model can learn. Training decides what becomes easy.</p><p>Data order matters because the learning rate moves. Examples that arrive while the rate is high shape the weights more than later ones.</p><p>Two runs with the same architecture and the same objective can land in different places. The optimizer settings are the reason, so they belong in the record.</p><h2 id="an-expensive-run-earns-instrumentation-before-it-earns-confidence">An Expensive Run Earns Instrumentation Before It Earns Confidence</h2><p>Training is more than a push of the run button. Evaluate during the run. Regressions and instabilities cost more when you find them late, because the compute is already spent.</p><p>Loss curves, validation slices, gradient stability, data mixtures, and hardware utilization are the evidence. Instrumentation buys one decision: stop the run or keep paying for it.</p><ul><li>Loss shows whether the objective moves.</li><li>Validation shows whether the movement generalizes.</li><li>Slices show who the model leaves behind.</li><li>Systems metrics show what the run cost.</li></ul><p>A slice is a validation set cut by the group you care about. An average hides the group that got worse.</p><p>Finishing proves the scheduler worked. The model still needs evidence. A run can finish and still learn the wrong distribution, waste hardware, or hide data errors.</p><p>A checkpoint nobody can rebuild turns into a run you pay for twice. Two fields decide whether it can be rebuilt. The data note put the corpus upstream of the behavior, so the data mixture travels with the weights. The parallelism note holds the hardware trace. Without it, the run cannot be repeated on other machines.</p><div class="v-decision"><span class="kicker">Run record</span><div class="body">A run record ties the checkpoint to its data version, objective, optimizer settings, and schedule. It carries precision, batch regime, validation slices, loss curves, checkpoint behavior, and system utilization. I trust that record more than a loss curve. A review that accepts less accepts a result no one can repeat.</div></div><h2 id="a-lower-loss-can-hide-worse-behavior">A Lower Loss Can Hide Worse Behavior</h2><p>For fine-tuning and continued pretraining, log more than final loss. Track calibration, brittleness, memorization risk, instability, and regressions on tasks the base model already handled.</p><p>Calibration is whether stated confidence matches the hit rate. Brittleness shows up when a change of wording flips the answer. A run can improve loss and move both of those the wrong way.</p><p>Memorization has a mechanism, and the security note names it: duplication. A string the corpus repeats many times is a string the objective pays the model to reproduce.</p><p>A lower loss that breaks a critical workflow is an expensive trade you failed to price. Price it before the run. Name the tasks that must not regress and put them in the validation set.</p><h2 id="the-builder-test">The Builder Test</h2><p>State the training signal in one sentence. Name what is hidden, what is predicted, what is scored, and what behavior exploits the score.</p><p>The last clause carries the risk. A score the model can win without the behavior is a score the model wins without the behavior.</p><p>Write the sentence before the run starts. A signal you cannot state plainly is a signal you cannot debug later.</p><h2 id="what-carries">What Carries</h2><p>Training is where architecture, data, optimizer, and hardware become behavior. The objective is the lesson the model practices millions or billions of times. Scale adds repetitions. A lesson the model never practiced stays unlearned.</p><p>Count the accelerators your plan assumes. A training plan that fits one accelerator is not the plan a frontier run uses.</p><div class="rm-essay-close" aria-hidden="true"><svg width="76" height="32" viewBox="0 0 76 32" aria-hidden="true" class="rm-fmark-essay"><path d="M 2 14 Q 18 2 36 14 T 74 12" fill="none" stroke="currentColor" stroke-width="1.1" stroke-linecap="round" opacity="0.5"></path><line x1="2" y1="24" x2="60" y2="24" stroke="currentColor" stroke-width="1.1"></line><circle cx="68" cy="24" r="2.8" fill="var(--vermilion)"></circle></svg></div></div>]]></content:encoded>
    <pubDate>Fri, 27 Feb 2026 12:00:00 GMT</pubDate>
    <author>rajdeep@rajdeepmondal.com (Rajdeep Mondal)</author>
    <category>ai</category><category>language-models</category><category>foundation-models</category><category>training</category><category>optimization</category><category>objectives</category><category>adam</category>
  </item>

  <item>
    <guid isPermaLink="true">https://rajdeepmondal.com/writing/language-model-systems-modeling-is-where-text-becomes-geometry</guid>
    <title>Modeling Is Where Text Becomes Geometry</title>
    <link>https://rajdeepmondal.com/writing/language-model-systems-modeling-is-where-text-becomes-geometry</link>
    <description>Tokenization is the first modeling choice. When output looks strange on code, math, rare names, or non-English text, check the tokenizer before you invent a psychological story.</description>
    <content:encoded><![CDATA[<div class="essay-prose"><p>Tokenization is the first modeling choice, and it lands before a single weight moves. Text becomes tokens. Tokens become vectors. Vectors move through the model, and somewhere in that path strings become geometry.</p><p>When output looks strange on code, math, rare names, or non-English text, check the tokenizer. Do that before you invent a psychological story about what the model believes. Each of those four cases turns on how the text was cut.</p><figure class="rm-article-image"><div class="relative overflow-hidden"><div class="bg-muted absolute inset-0 z-10 animate-pulse rounded-[inherit]"><div class="animate-shimmer via-paper-bright/70 absolute inset-0 bg-linear-to-r from-transparent to-transparent"></div></div></div><figcaption>Modeling is where text turns into tokens, tokens become vectors, and architecture decides how information can move.</figcaption></figure><h2 id="text-becomes-tokens-before-it-becomes-anything-else">Text Becomes Tokens Before It Becomes Anything Else</h2><p>The tokenizer cuts every string into pieces before the model sees anything. Split too finely and the model spends its context on the spelling of common words. Split too coarsely and rare forms, morphology, code, and multilingual text get harder. BPE and unigram tokenizers are compromises between those two costs.</p><p>Nothing downstream recovers a boundary the tokenizer erased. A rare name that arrives as fragments stays fragments for every layer above it. The pieces are the only view of the string the model gets.</p><p>Text the vocabulary does not cover gets cut into more and smaller pieces. The same sentence then spends more of the context window and arrives with less structure. That cost falls unevenly across languages. The first harms note measured it from the other side. It called the gap a quality-of-service harm and named the group the average was carrying.</p><h2 id="bpe-merges-frequent-pairs-unigram-picks-likely-segmentations">BPE Merges Frequent Pairs, Unigram Picks Likely Segmentations</h2><p>BPE starts from small symbols and repeatedly merges the most frequent adjacent pair into a larger token. The merge table records what was common in the corpus it was fit on. Frequent strings become single pieces. Everything else gets assembled out of leftovers.</p><p>Unigram tokenization, the SentencePiece style, learns a vocabulary and then picks the segmentation it scores as most likely. BPE builds pieces up from frequency. Unigram chooses among segmentations a learned vocabulary already scores. Both are fit on a corpus, and both freeze one view of what counts as normal text.</p><p>Both choices are locked once training starts. The embedding table is indexed by token ID. A new vocabulary sends every ID somewhere else, and the trained table is dead weight. Changing the tokenizer means training again, so price that decision before the run.</p><h2 id="embeddings-make-the-workspace-attention-moves-the-context">Embeddings Make The Workspace, Attention Moves The Context</h2><p>Embeddings map token IDs into vectors, which gives the model a space to compute in. Similarity, context, and prediction become vector operations. That space is the working memory, and the tokenizer already decided what occupies it.</p><p>Recurrent models walk a sequence one step at a time. Transformers process many positions in parallel, and attention carries information between them. Self-attention builds a contextual representation for each token by mixing in the positions it reads. Positional information keeps the order in place, because attention alone does not tell first from last.</p><figure class="rm-article-image"><div class="relative overflow-hidden"><div class="bg-muted absolute inset-0 z-10 animate-pulse rounded-[inherit]"><div class="animate-shimmer via-paper-bright/70 absolute inset-0 bg-linear-to-r from-transparent to-transparent"></div></div></div><figcaption>Different merge rules cut the same sentence into different pieces, and attention decides which pieces read each other.</figcaption></figure><p>Four choices decide what information can move between positions. Attention decides which positions read each other, and depth decides how many times the model edits what they read. Width gives each position more room. Context length sets the reach.</p><h2 id="modeling-choices-become-infrastructure-costs">Modeling Choices Become Infrastructure Costs</h2><p>Attention is why a long context is expensive. Every position that can read every other position needs memory to hold what it reads. That memory grows with the length you allow. The architecture decision arrives later as a training constraint and as a serving bill.</p><p>The parallelism note names the walls this creates. Context length and width set the memory wall before the run starts. Once the model no longer fits on one accelerator, the split has to send activations and gradients across the interconnect. Those messages compete with the work itself.</p><p>That makes the tokenizer a serving decision as well as a modeling one. Measure pieces per request on your own traffic before you argue about context length.</p><h2 id="check-the-representation-before-you-blame-the-reasoning">Check The Representation Before You Blame The Reasoning</h2><p>The overview note set the rule for this unit. When a model surprises you, name the layer that did the work. The representation is the layer to read first, because everything a reasoning story explains sits on top of it.</p><div class="v-decision"><span class="kicker">Modeling rule</span><div class="body">Before you blame reasoning, inspect the representation: tokens, context window, attention pattern, and positional setup.</div></div><p>Weird spelling, broken code indentation, rare names, and math notation are all shapes a tokenizer problem takes. From the outside each one looks like a failure of understanding. The mechanism is a boundary in the wrong place.</p><p>The risk is treating the representation as invisible plumbing. Bad token boundaries, weak embeddings, a short context, and a poor attention pattern all cost the model capacity. They take it before training gets a fair chance. Fix the representation before you spend a run compensating for it.</p><h2 id="the-builder-test">The Builder Test</h2><p>Take one sentence your system handles badly. Trace it through the whole path: tokens, IDs, embeddings, attention context, next-token scores. Write down what each step produced, in that order.</p><p>Start at the token boundaries, because they are visible and cost nothing to print. Stop at the first step that sounds like magic. That is the step to slow down on.</p><h2 id="what-carries">What Carries</h2><p>The model edits vectors until the next-token distribution becomes useful. The representation decides what it can edit. Tokenizer, context length, and attention pattern set that limit. All three are chosen before any data moves.</p><p>Architecture is potential. The objective decides which potential the model practices.</p><div class="rm-essay-close" aria-hidden="true"><svg width="76" height="32" viewBox="0 0 76 32" aria-hidden="true" class="rm-fmark-essay"><path d="M 2 14 Q 18 2 36 14 T 74 12" fill="none" stroke="currentColor" stroke-width="1.1" stroke-linecap="round" opacity="0.5"></path><line x1="2" y1="24" x2="60" y2="24" stroke="currentColor" stroke-width="1.1"></line><circle cx="68" cy="24" r="2.8" fill="var(--vermilion)"></circle></svg></div></div>]]></content:encoded>
    <pubDate>Wed, 25 Feb 2026 12:00:00 GMT</pubDate>
    <author>rajdeep@rajdeepmondal.com (Rajdeep Mondal)</author>
    <category>ai</category><category>language-models</category><category>foundation-models</category><category>modeling</category><category>tokenization</category><category>transformers</category><category>attention</category>
  </item>

  <item>
    <guid isPermaLink="true">https://rajdeepmondal.com/writing/language-model-systems-law-is-part-of-the-model-boundary</guid>
    <title>Law Is Part of the Model Boundary</title>
    <link>https://rajdeepmondal.com/writing/language-model-systems-law-is-part-of-the-model-boundary</link>
    <description>Public access, permission to copy, permission to train, and permission to deploy are four different questions. A rights register answers all four before a takedown forces the answer.</description>
    <content:encoded><![CDATA[<div class="essay-prose"><p>Public access, permission to copy, permission to train, and permission to deploy are four different questions. A dataset can clear the first and fail the other three. A rights register answers all four, and it has to exist before the first takedown.</p><p>Copyright law asks what you can copy, transform, and generate. Privacy law asks what personal information you can collect, process, store, expose, and delete. Where the law runs behind the system, professional codes still bind the builder.</p><h2 id="legal-exposure-accumulates-at-every-handoff">Legal Exposure Accumulates At Every Handoff</h2><p>The first obligation lands at collection, and every copy, transformation, and filter adds another. Training, serving, logging, and fine-tuning each add one more. So does the customer who uses the output.</p><p>That makes law part of system design. A team that cannot explain provenance, licenses, consent, retention, outputs, and user controls cannot price its risk. The obligations exist whether or not anyone wrote them down.</p><h2 id="four-permissions-live-behind-one-dataset">Four Permissions Live Behind One Dataset</h2><p>Public data carries four permissions, and reading is only the first. Copying it into a corpus, training on that copy, and shipping the result each need their own. Terms of service and dataset licenses decide which of the four you hold.</p><p>The answer stays fact-specific. Source, license, jurisdiction, consent, transformation, memorization, output similarity, product use, and user controls all move it. Copyright analysis alone touches copying, fair use, licensing, and derivative works.</p><p>Output similarity is a live question because models memorize. The security note showed the mechanism: extraction turns generation into a search for training text. A corpus the model can reproduce is a corpus whose license follows the output.</p><h2 id="privacy-adds-operational-duties">Privacy Adds Operational Duties</h2><p>Copyright asks who owns the data. Privacy asks who is in it. Data subjects hold rights over their own records, and users expect deletion to mean deletion.</p><p>Privacy analysis touches collection, purpose limitation, retention, access, deletion, and cross-border transfer. Each item names a system that has to change.</p><p>Personal information spreads past the training corpus. Logs carry it, and fine-tuning sets carry sensitive text. A retrieval system can hand a document to a user who cannot open it at the source.</p><h2 id="a-product-claim-creates-obligations-the-model-cannot-satisfy">A Product Claim Creates Obligations The Model Cannot Satisfy</h2><p>A model generates legal-looking text. The claim on your website decides what that text becomes: assistance, publication, advice, or automated decision-making. The model behaves the same way in all four cases. The obligations differ in each one.</p><p>Each category brings its own machinery. Attribution, user disclosure, review workflows, and appeal mechanisms turn generated text into a claim you can defend. When the model makes a consequential decision, someone owns the audit trail, and the product decides who.</p><div class="v-decision"><span class="kicker">Product claim</span><div class="body">Do not market a model as legal advice until the product carries the controls the claim needs. Accountability lives in the product, and the model file supplies none of it.</div></div><h2 id="build-the-rights-register-before-the-first-takedown">Build The Rights Register Before The First Takedown</h2><p>A rights register holds one row per data source, and the row carries provenance, permission, use, and remedy. Provenance describes the source, the filter, and the mixture, the three choices the data note used to explain behavior. The permission column names which of the four you hold, and which you assumed. The use column names what the deployed system does with the data.</p><figure class="rm-article-image"><div class="relative overflow-hidden"><div class="bg-muted absolute inset-0 z-10 animate-pulse rounded-[inherit]"><div class="animate-shimmer via-paper-bright/70 absolute inset-0 bg-linear-to-r from-transparent to-transparent"></div></div></div><figcaption>Each stage asks a different permission question, and the register is the record that answers all four.</figcaption></figure><p>Remedy is the hardest column to fill with a real mechanism. A removal path touches four places: the training set, the checkpoint, the retrieval index, and the logs. Deleting a row from the training set leaves the checkpoint unchanged. The security note priced that already, because text that entered training does not leave the weights cleanly.</p><p>An honest removal path states what it reaches and when. The retrieval index and the logs clear on request. The training set changes at the next build, and the weights change only at the next retrain. Until then the remedy is a filter at serving time, and the register must say so.</p><p>The register reads as bureaucracy until the first deletion request, takedown, or procurement review arrives. Courtroom risk is one part of the bill. Product trust, enterprise adoption, and data partnerships turn on the same record. A download is easy to justify, and a lifecycle is the thing you defend.</p><h2 id="the-builder-test">The Builder Test</h2><p>Fill one row for your largest data source. Stop at the first column with no answer, because that gap is the finding.</p><ul><li>Source: where the data came from, and who collected it.</li><li>Permission: the license, the consent basis, and the restrictions that came with it.</li><li>Retention rule: how long the raw data, the derived corpus, and the logs stay.</li><li>Removal path: what a deletion request reaches, and what it cannot reach.</li><li>Output-risk check: the test that shows whether the model reproduces the source.</li><li>Responsible owner: the person who answers when a rightsholder writes.</li></ul><p>An empty owner column makes the register a document. A named person makes it a control.</p><h2 id="what-carries">What Carries</h2><p>The model boundary is bigger than the model file. Law decides what the system consumes, what it remembers, what it produces, and what it decides. Each of those four verbs is a place a rightsholder or a regulator can reach you.</p><p>Every constraint so far arrived from outside the model: the corpus, the user, the attacker, and the rightsholder. The next four notes open the machine that produced the model.</p><div class="rm-essay-close" aria-hidden="true"><svg width="76" height="32" viewBox="0 0 76 32" aria-hidden="true" class="rm-fmark-essay"><path d="M 2 14 Q 18 2 36 14 T 74 12" fill="none" stroke="currentColor" stroke-width="1.1" stroke-linecap="round" opacity="0.5"></path><line x1="2" y1="24" x2="60" y2="24" stroke="currentColor" stroke-width="1.1"></line><circle cx="68" cy="24" r="2.8" fill="var(--vermilion)"></circle></svg></div></div>]]></content:encoded>
    <pubDate>Mon, 23 Feb 2026 12:00:00 GMT</pubDate>
    <author>rajdeep@rajdeepmondal.com (Rajdeep Mondal)</author>
    <category>ai</category><category>language-models</category><category>foundation-models</category><category>law</category><category>copyright</category><category>privacy</category><category>governance</category>
  </item>

  <item>
    <guid isPermaLink="true">https://rajdeepmondal.com/writing/language-model-systems-security-begins-with-memorization</guid>
    <title>Security Begins With Memorization</title>
    <link>https://rajdeepmondal.com/writing/language-model-systems-security-begins-with-memorization</link>
    <description>Extraction attacks turn generation into a search for memorized text. Once a secret is trained in, you cannot cleanly delete it.</description>
    <content:encoded><![CDATA[<div class="essay-prose"><p>Extraction attacks turn generation into a search for memorized text. Repeated sampling, targeted prompts, and a search over completions can recover rare sequences the model saw in training. Once a secret is trained in, you cannot cleanly delete it.</p><p>That moves the security question off the database and onto the model. Some of the text a model reads is sensitive, copyrighted, private, or recoverable by an attacker who knows how to ask. The weights join the list of places where your secrets live.</p><h2 id="a-model-is-a-compressed-artifact-of-its-training-data">A Model Is A Compressed Artifact Of Its Training Data</h2><p>Memorization risk rises with the copy count. A rare string that appears many times is distinctive enough to stand out and repeated enough to learn. That is the worst pair of properties a secret can have.</p><p>The data note in this unit puts the corpus upstream of the behavior, and duplication is one of the ways that shows up here. A crawl collects the same passage from many pages, so the copy count is set before anyone picks a training mix. Deduplication is the control, and it works only while the data is still a file you can edit.</p><p>Treat the model as a data-bearing component. Secrets that pass through training data, logs, prompts, retrieval corpora, or fine-tuning sets do not stay where you put them.</p><h2 id="extraction-turns-generation-into-search">Extraction Turns Generation Into Search</h2><p>An extraction attack needs no new algorithm. The attacker samples the model many times, steers it with targeted prompts, and searches the completions for text that looks memorized. The model does the retrieving.</p><figure class="rm-article-image"><div class="relative overflow-hidden"><div class="bg-muted absolute inset-0 z-10 animate-pulse rounded-[inherit]"><div class="animate-shimmer via-paper-bright/70 absolute inset-0 bg-linear-to-r from-transparent to-transparent"></div></div></div><figcaption>Duplication decides what the weights hold, and each control in the wrapper narrows what an attacker gets back out.</figcaption></figure><p>Membership inference asks a narrower question. It tests whether one specific record was likely in the training data, and it never has to reproduce a line of that record. Membership in a corpus can be the sensitive fact on its own.</p><p>Both attacks share one frame. Name what information entered training and how likely extraction is. Then say which prompts or access patterns make extraction easier, and which controls cut the damage. Privacy work starts when those four answers come from your own system.</p><h2 id="the-deployment-wrapper-decides-whether-a-flaw-becomes-a-breach">The Deployment Wrapper Decides Whether A Flaw Becomes A Breach</h2><p>Memorization is one entrance. Prompt injection, tool misuse, jailbreaks, a compromised model supply chain, poisoned training data, and leakage through logs use the same stack. The wrapper you build around the weights decides how far each of them travels.</p><p>Authentication decides who can query the model. Rate limits raise the cost of the repeated sampling that extraction depends on, and audit logs make the attack visible while it runs. Retrieval permissions bound the private context the model can reach at answer time. Incident response sets how fast you cut access after someone reports a leak.</p><p>Red-team prompts are how you find out which of those controls holds before an outsider does. Each control is also a threshold, and the first harms note named what a threshold does. It picks which error you eat. A tight rate limit blocks a real user. A loose one lets the sampling run long enough to find something.</p><h2 id="split-instructions-from-untrusted-content">Split Instructions From Untrusted Content</h2><p>Prompt injection turns serious the moment the model reads untrusted text while holding tools or private context. A fetched web page becomes a privileged instruction, because the model has no structural way to tell your intent from the text it fetched.</p><p>Split the two channels in a place the system can enforce. Instructions come from you and from your own code. Fetched pages, uploaded files, and tool output stay data the model reads, even when the text inside them sounds like an order.</p><p>Then cap the side effects. A demo shows a model that can do anything it is asked. A product gives the model the short list of actions you have priced, so a successful injection reaches less than the demo suggests.</p><h2 id="some-secrets-must-never-enter-training">Some Secrets Must Never Enter Training</h2><p>Controls split by when you can still apply them. Data minimization, deduplication, and differential privacy for sensitive data are training-time choices, unavailable the day after the run finishes. Monitoring, canaries, and strict tool permissions are what you have left.</p><p>After the run, what the model holds is fixed. You can filter the output, refuse the prompt, and revoke the key. The string is still in the weights, and no delete you run reaches it. Privacy work that waits for a leak starts after the cheap moment has passed.</p><div class="v-decision"><span class="kicker">Security test</span><div class="body">If the model can see a secret during training, prompting, retrieval, or logging, write down how that secret does not come back out. A secret with no written answer stays out of the system.</div></div><h2 id="the-builder-test">The Builder Test</h2><p>Plant the canary before you need it. Put a unique string into the training data or the retrieval corpus. Pick one that nobody types by accident, and record where you put it. Then attack your own system.</p><ul><li>Sample the model repeatedly with targeted prompts, then search the completions for the canary.</li><li>Repeat the attack at every access level you ship, from anonymous visitor to internal tool.</li><li>Run a membership inference check against one record you know sits in the corpus.</li><li>Write down which log or filter caught the attack, and how long the catch took.</li></ul><p>The access level is part of the result. The same prompt at anonymous and at admin returns two different answers, and both belong in the record. I prefer to find my own canary in a completion, before a stranger finds it for me.</p><h2 id="what-carries">What Carries</h2><p>Training data is an input surface. Generated text is an output surface. Both of them leak, and a control that watches one of them misses the other.</p><p>A secret you cannot delete becomes an obligation you cannot satisfy. The legality note takes up the deletion duty and the removal path. Before the next run, ask whoever owns the corpus which strings a removal request must reach, and whether you can reach them.</p><div class="rm-essay-close" aria-hidden="true"><svg width="76" height="32" viewBox="0 0 76 32" aria-hidden="true" class="rm-fmark-essay"><path d="M 2 14 Q 18 2 36 14 T 74 12" fill="none" stroke="currentColor" stroke-width="1.1" stroke-linecap="round" opacity="0.5"></path><line x1="2" y1="24" x2="60" y2="24" stroke="currentColor" stroke-width="1.1"></line><circle cx="68" cy="24" r="2.8" fill="var(--vermilion)"></circle></svg></div></div>]]></content:encoded>
    <pubDate>Sat, 21 Feb 2026 12:00:00 GMT</pubDate>
    <author>rajdeep@rajdeepmondal.com (Rajdeep Mondal)</author>
    <category>ai</category><category>language-models</category><category>foundation-models</category><category>security</category><category>privacy</category><category>memorization</category><category>data-extraction</category>
  </item>

  <item>
    <guid isPermaLink="true">https://rajdeepmondal.com/writing/language-model-systems-data-is-the-model-before-the-model</guid>
    <title>Data Is the Model Before the Model</title>
    <link>https://rajdeepmondal.com/writing/language-model-systems-data-is-the-model-before-the-model</link>
    <description>The dataset is the first behavior specification a model receives. WebText used outbound Reddit links as its proxy for quality, and every corpus picks a proxy like it.</description>
    <content:encoded><![CDATA[<div class="essay-prose"><p>The dataset is the first behavior specification a model receives. WebText picked its documents by following outbound Reddit links and treating that as a proxy for quality. That choice landed before a single training step ran.</p><p>Data work sits upstream of almost every behavior people later attribute to the model. Overrepresent one domain and the model learns that style. Leave duplicated text in and the model can memorize it. A filter that removes some communities harder than others hands the model that skew.</p><figure class="rm-article-image"><div class="relative overflow-hidden"><div class="bg-muted absolute inset-0 z-10 animate-pulse rounded-[inherit]"><div class="animate-shimmer via-paper-bright/70 absolute inset-0 bg-linear-to-r from-transparent to-transparent"></div></div></div><figcaption>Data governance is model governance because the model can only learn from the world it was fed.</figcaption></figure><h2 id="the-model-arrived-through-a-supply-chain">The Model Arrived Through A Supply Chain</h2><p>Someone crawled the web, someone wrote the filter, and someone set the mixture weights. Someone else chose what to write down about all three, or chose to write down nothing. Those four decisions reach the user before any prompt does.</p><p>WebText, OpenWebText, C4, the GPT-3 mixture, and The Pile each encode a different set of collection and filtering choices. Underneath those sits one more choice: whose text becomes training material. The people who wrote that text are not in the room for it.</p><p>Every corpus carries duplication, quality variation, demographic gaps, and domain bias into the training run. None of that arrives in the finished weights with a label attached. I do not trust a behavior explanation that stops at the architecture.</p><h2 id="every-corpus-encodes-a-proxy-for-quality">Every Corpus Encodes A Proxy For Quality</h2><p>Nobody reads a web crawl end to end. So each corpus builder picks a proxy and inherits whatever it correlates with.</p><p>WebText used outbound Reddit links as its proxy. That proxy measures the taste of the people posting the links, and the corpus takes on that taste. OpenWebText rebuilt a similar corpus in public, so the proxy outlived the team that chose it.</p><p>C4 filtered Common Crawl, and a filter is a value-laden transformation. What the filter drops leaves no mark on the model and no mark on the benchmark. Whole languages can leave a corpus that way.</p><p>GPT-3 mixed Common Crawl with WebText, books, and Wikipedia at chosen weights. Chosen is the load-bearing word. A source can sit in that mixture louder or quieter than its raw size, and a person picks the number.</p><p>The Pile emphasized breadth across domains: code, academic text, web text, and books. Every domain in the mixture is a register the model gets cheaply. Code is the clearest case, because code in pre-training makes code cheap to imitate.</p><h2 id="source-filter-mixture-deduplication">Source, Filter, Mixture, Deduplication</h2><p>More data is not automatically better. Repeated, low-quality, or misweighted text makes the model worse and the system harder to defend. Four levers decide which of those you get.</p><ul><li>Source decides domain coverage.</li><li>Filtering decides what disappears.</li><li>Mixture weights decide what becomes normal.</li><li>Deduplication decides which text stops shouting.</li></ul><figure class="rm-article-image"><div class="relative overflow-hidden"><div class="bg-muted absolute inset-0 z-10 animate-pulse rounded-[inherit]"><div class="animate-shimmer via-paper-bright/70 absolute inset-0 bg-linear-to-r from-transparent to-transparent"></div></div></div><figcaption>Each lever decides a different property of the finished model, and a later note has to measure it.</figcaption></figure><p>Each lever costs something in a different part of the system. Duplicates left in the corpus become the memorization the security note describes. Filtering decides which communities thin out, and that thinning is the disparity the first harms note measured. Mixture weights change data quality, and quality bends the curve the scaling-laws note fits.</p><h2 id="pre-training-absorbs-the-incentives-before-any-later-tuning">Pre-training Absorbs The Incentives Before Any Later Tuning</h2><p>A dataset carries more than text. It tells the model what is common, what is authoritative, what is safe, and what is cheap to imitate. Pre-training absorbs those incentives before any instruction tuning or preference tuning gets a vote.</p><p>Web pages, books, code, academic papers, forums, and synthetic examples do different jobs in the finished model. The design question is which behaviors must become easy. The mixture weights are the answer you gave, whether or not you wrote the question down.</p><h2 id="before-you-debug-behavior-inspect-the-mixture">Before You Debug Behavior, Inspect The Mixture</h2><p>The overview note asks you to name the layer that did the work. When the surprise is about what the model knows, imitates, or repeats, the layer is the corpus.</p><div class="v-decision"><span class="kicker">Data rule</span><div class="body">Before debugging model behavior, inspect the dataset mixture. The answer is often upstream.</div></div><p>A user asks why the model knew that, imitated that, or leaked that. If you cannot trace the likely data path, you have a governance gap. Prompt changes do not close it.</p><p>Datasheets and dataset cards are the minimum operating manual for a corpus that shapes model behavior. A datasheet records sources, collection process, filtering, intended use, limitations, and known risks. Those six fields answer the traceability question one field at a time. Read them back and you can name the likely data path, or see which field is empty.</p><p>Data governance for an LLM system means provenance, deduplication, filtering rationale, contamination checks, privacy review, and a refresh strategy. Each one is a document somebody keeps current. Without them, debugging behavior turns into guessing about a corpus nobody can see.</p><h2 id="the-builder-test">The Builder Test</h2><p>Pick one behavior your system shows this week. Trace it to a source, a filter, a mixture weight, or a duplicate. Write that trace in one line and keep it with the model.</p><p>If you cannot finish the line, you have found the missing document. Go write it before you touch the model.</p><h2 id="what-carries">What Carries</h2><p>&quot;We trained it on a lot of text&quot; is where most explanations stop. Quantity without provenance is an admission that nobody can name where the behavior came from.</p><p>Write the mixture down while you build it, and keep that document next to the weights. A corpus that can be memorized is a corpus that can be extracted.</p><div class="rm-essay-close" aria-hidden="true"><svg width="76" height="32" viewBox="0 0 76 32" aria-hidden="true" class="rm-fmark-essay"><path d="M 2 14 Q 18 2 36 14 T 74 12" fill="none" stroke="currentColor" stroke-width="1.1" stroke-linecap="round" opacity="0.5"></path><line x1="2" y1="24" x2="60" y2="24" stroke="currentColor" stroke-width="1.1"></line><circle cx="68" cy="24" r="2.8" fill="var(--vermilion)"></circle></svg></div></div>]]></content:encoded>
    <pubDate>Thu, 19 Feb 2026 12:00:00 GMT</pubDate>
    <author>rajdeep@rajdeepmondal.com (Rajdeep Mondal)</author>
    <category>ai</category><category>language-models</category><category>foundation-models</category><category>data</category><category>datasets</category><category>governance</category><category>common-crawl</category>
  </item>

  <item>
    <guid isPermaLink="true">https://rajdeepmondal.com/writing/language-model-systems-toxicity-disinformation-and-moderation-are-system-problems</guid>
    <title>Every Moderation Threshold Picks An Error</title>
    <link>https://rajdeepmondal.com/writing/language-model-systems-toxicity-disinformation-and-moderation-are-system-problems</link>
    <description>Every moderation threshold picks which error you prefer to make. A stricter filter blocks the wrong people, teaches attackers the boundary, and does not make a product safer by itself.</description>
    <content:encoded><![CDATA[<div class="essay-prose"><p>Every moderation threshold picks which error you prefer to make. Set the dial loose and harmful content reaches the users you meant to protect. Set it tight and the filter blocks harmless speech. A stricter filter does not make a product safer by itself.</p><h2 id="a-fluent-model-is-a-cheap-content-engine">A Fluent Model Is A Cheap Content Engine</h2><p>The same capability helps a student with a draft and writes a customer email. It produces targeted persuasive text at the same price. Every output looks like text.</p><p>The harm lives in distribution, intent, and context. Intent sits with the person holding the prompt. The model reads none of it. The same sentence carries different harm in a private draft and in a ranked feed.</p><p>Toxicity evaluation probes what a model continues when the prompt pulls toward harmful text. RealToxicityPrompts makes that continuation behavior visible, including completions that turn abusive or identity-targeted.</p><p>Disinformation runs on production speed rather than belief. The model produces plausible targeted text cheaply enough that people cannot match the pace. Risk then depends on scale, targeting, cost, believability, and the channel that carries it.</p><h2 id="moderation-is-a-workflow-around-an-imperfect-detector">Moderation Is A Workflow Around An Imperfect Detector</h2><p>One classifier at the door leaves most of the problem unsolved. A team that tunes that classifier and declares the work finished misses context, dialect, satire, quotation, and coordinated abuse.</p><p>The working system adds thresholding, context review, escalation, appeal, monitoring, and adversarial testing. Attackers adapt, so policy updates belong inside the loop.</p><figure class="rm-article-image"><div class="relative overflow-hidden"><div class="bg-muted absolute inset-0 z-10 animate-pulse rounded-[inherit]"><div class="animate-shimmer via-paper-bright/70 absolute inset-0 bg-linear-to-r from-transparent to-transparent"></div></div></div><figcaption>Every stage after detection either changes the call or records why it stood.</figcaption></figure><p>Trace one borderline case through those stages before you argue about the detector. The score decides what the system suspects. The workflow decides whether the call is fair and reversible.</p><p>Harmful generation crosses prompt, model, decoding, distribution, moderation, appeal, and monitoring. Every one of those stages holds a control, and moderation is a triage system with human consequences.</p><p>Generation policy and moderation policy answer two different questions, and they belong in two documents. One names what the model must not produce. The other names what the platform must not distribute. Both name what needs human review. The system logs the evidence behind each call, because a decision nobody can reconstruct cannot be reviewed.</p><h2 id="the-threshold-is-the-safety-policy">The Threshold Is The Safety Policy</h2><p>The system gives a piece of content a risk score. A threshold turns that score into allow, warn, route to review, or block. Move the threshold and you move who gets protection and who gets wrongly stopped.</p><div class="uth-essay uth-figure-embed"><div><figure class="fig reveal" id="cs324-moderation-threshold">
  
  <div class="fig-head">
    <span class="fig-title">moderation is a threshold tradeoff</span>
    <span class="ctrl">
      
      
    </span>
  </div>
  <div class="stage" id="cs324-moderation-threshold-stage" role="group" aria-live="polite" aria-describedby="cs324-moderation-threshold-caption">
    <div class="course-visual thr-wrap" aria-hidden="true">
      <div class="thr-chart">
        <span class="thr-dot ok"></span><span class="thr-dot ok"></span><span class="thr-dot ok"></span><span class="thr-dot ok"></span>
        <span class="thr-dot harm"></span><span class="thr-dot harm"></span><span class="thr-dot harm"></span><span class="thr-dot harm"></span>
        <span class="thr-line"></span><span class="thr-axis"></span><span class="thr-label low">low risk</span><span class="thr-label high">high risk</span>
      </div>
      <div class="thr-panel">
        <div class="thr-row" data-thr="score"><b>score</b>risk is continuous before the product turns it into a decision</div>
        <div class="thr-row" data-thr="cut"><b>cutoff</b>moving the line changes who gets blocked</div>
        <div class="thr-row" data-thr="fp"><b>false positive</b>harmless users can be stopped by a strict line</div>
        <div class="thr-row" data-thr="fn"><b>false negative</b>harmful content can pass through a loose line</div>
      </div>
    </div>
    <div class="course-rail" data-rail aria-hidden="true"><span class="course-node" data-node="0">
        <span class="course-dot" aria-hidden="true">1</span>
        <span class="course-node-label">score</span>
      </span><span class="course-node" data-node="1">
        <span class="course-dot" aria-hidden="true">2</span>
        <span class="course-node-label">threshold</span>
      </span><span class="course-node" data-node="2">
        <span class="course-dot" aria-hidden="true">3</span>
        <span class="course-node-label">false positive</span>
      </span><span class="course-node" data-node="3">
        <span class="course-dot" aria-hidden="true">4</span>
        <span class="course-node-label">false negative</span>
      </span></div>
    <div class="course-grid"><div class="course-step" data-step="0">
        <span class="course-k">score</span>
        <span class="course-v">the system estimates how risky an output or request is</span>
      </div><div class="course-step" data-step="1">
        <span class="course-k">threshold</span>
        <span class="course-v">a cutoff turns a continuous risk score into allow or block</span>
      </div><div class="course-step" data-step="2">
        <span class="course-k">false positive</span>
        <span class="course-v">set the line too strict and harmless users get blocked</span>
      </div><div class="course-step" data-step="3">
        <span class="course-k">false negative</span>
        <span class="course-v">set it too loose and harmful content gets through</span>
      </div></div>
    <div class="course-status" data-status aria-live="polite"><b>score.</b> the system estimates how risky an output or request is</div>
  </div>
  <figcaption id="cs324-moderation-threshold-caption">Safety settings are product decisions. The threshold decides which errors users will actually feel.</figcaption>
</figure></div><span hidden=""></span></div><p>Warn and route to review sit between allow and block, and both spend reviewer time to buy context. Every point of movement trades one error column against the other.</p><p>A false positive blocks harmless speech. A false negative lets harmful content through. The setting that fits depends on the product, the user, the context, and the cost of each mistake.</p><p>The detector is a model, so it arrives with the same subgroup problem the first harms note measured. Perspective API scores text for toxicity, and it can encode its own biases and blind spots. The threshold inherits that measurement gap. A dialect that scores high for the wrong reason loses at every setting you pick.</p><h2 id="the-hard-cases-are-contextual">The Hard Cases Are Contextual</h2><p>The same phrase can be quotation, abuse, documentation, satire, or evidence. A classifier blind to context overblocks some users and underblocks others. Its aggregate score stays healthy through both.</p><p>A bad-word list is the cheapest context-blind detector. It misses quotation and satire, and it blocks legitimate speech that uses the same words. The system has to separate quotation from endorsement, and a detector that scores words alone cannot.</p><p>The appeal path is where context returns to the decision. An appeal costs the operator reviewer time and a stored record of the evidence. The log has to exist before anyone files one, so the bill starts earlier than the complaint. It costs a policy update when the same call keeps getting reversed.</p><p>A missing appeal costs the user the speech, with no route back and no record that the decision happened. The user learns nothing about the rule they crossed, and the operator learns nothing about the rule that misfired. That is the labor and governance bill under every moderation system, and a classifier budget hides it.</p><h2 id="a-stricter-filter-can-make-the-product-less-safe">A Stricter Filter Can Make The Product Less Safe</h2><p>Tightening the dial has three prices. It blocks the wrong people, teaches attackers where the boundary sits, and pushes users into worse channels.</p><p>A single safety number hides those prices. The score improves while a coded phrase still passes. A coordinated disinformation campaign runs straight through the same filter.</p><p>Mitigation sits in more than one place: model training, interface constraints, monitoring, policy, and escalation paths. No threshold carries all five.</p><div class="v-decision"><span class="kicker">Boundary</span><div class="body">A moderation report that counts blocked content and stays silent on blocked users describes half the system.</div></div><h2 id="the-builder-test">The Builder Test</h2><p>Name both errors before you pick the threshold. Write down who the system harms when it blocks too much. Write down who it harms when it blocks too little. Then measure both on the same traffic sample.</p><p>Pull the borderline cases out of the log and read them by hand. Route the ones that turn on context to review, and record what the reviewer decided. Re-test against the adversarial set after every policy update. Record the setting you picked beside both error counts, so the next change has a baseline.</p><h2 id="what-carries">What Carries</h2><p>A safety setting is a record of which error the team chose to make. The errors stay in the system either way. Moving the dial moves who absorbs them.</p><p>Both harms notes point upstream to the same place. Before you tune another threshold, read the corpus that decided what the model finds easy to say.</p><div class="rm-essay-close" aria-hidden="true"><svg width="76" height="32" viewBox="0 0 76 32" aria-hidden="true" class="rm-fmark-essay"><path d="M 2 14 Q 18 2 36 14 T 74 12" fill="none" stroke="currentColor" stroke-width="1.1" stroke-linecap="round" opacity="0.5"></path><line x1="2" y1="24" x2="60" y2="24" stroke="currentColor" stroke-width="1.1"></line><circle cx="68" cy="24" r="2.8" fill="var(--vermilion)"></circle></svg></div></div>]]></content:encoded>
    <pubDate>Tue, 17 Feb 2026 12:00:00 GMT</pubDate>
    <author>rajdeep@rajdeepmondal.com (Rajdeep Mondal)</author>
    <category>ai</category><category>language-models</category><category>foundation-models</category><category>toxicity</category><category>disinformation</category><category>moderation</category><category>safety</category>
  </item>

  <item>
    <guid isPermaLink="true">https://rajdeepmondal.com/writing/language-model-systems-harms-start-with-measurement</guid>
    <title>Harms Start With Measurement</title>
    <link>https://rajdeepmondal.com/writing/language-model-systems-harms-start-with-measurement</link>
    <description>Representational, allocative, and quality-of-service harm each need different evidence, and one aggregate score hides the subgroup it fails.</description>
    <content:encoded><![CDATA[<div class="essay-prose"><p>Representational harm, allocative harm, and quality-of-service harm each need their own evidence. One aggregate score supplies none of the three, and it hides the subgroup it fails.</p><p>The capabilities note measured what a model can do. Harm analysis names who pays when that model fails, and what the failure costs them. Capability without harm analysis is power without accounting.</p><p>The overview note asked which layer did the work. Harm answers to the same question. It enters through the corpus, model behavior, the interface, and the deployment setting. Name the layer and a bad output turns into a decision someone owns.</p><figure class="rm-article-image"><div class="relative overflow-hidden"><div class="bg-muted absolute inset-0 z-10 animate-pulse rounded-[inherit]"><div class="animate-shimmer via-paper-bright/70 absolute inset-0 bg-linear-to-r from-transparent to-transparent"></div></div></div><figcaption>Harms are not a single output problem. They travel through the whole LLM stack.</figcaption></figure><h2 id="models-inherit-the-patterns-in-their-documents">Models Inherit The Patterns In Their Documents</h2><p>A language model inherits the patterns of the societies and documents that produced its data. Those patterns come back four ways: worse performance for some groups, biased associations, stereotyped completions, and hierarchy encoded in language.</p><p>The data note supplies the mechanism. Filtering decides which text disappears from the corpus. Mixture weights decide which text becomes normal. A dialect that gets filtered out or under-weighted arrives later as an error rate nobody planned.</p><p>Performance disparity is the measurable form. Error rates differ across groups, domains, dialects, languages, and contexts. Social categories are contextual and datasets are imperfect, so one group label covers different people in different settings.</p><h2 id="three-harms-three-kinds-of-evidence">Three Harms, Three Kinds Of Evidence</h2><p>Split the harm before you measure it. The three kinds behave differently, and each one answers to its own evidence.</p><figure class="rm-article-image"><div class="relative overflow-hidden"><div class="bg-muted absolute inset-0 z-10 animate-pulse rounded-[inherit]"><div class="animate-shimmer via-paper-bright/70 absolute inset-0 bg-linear-to-r from-transparent to-transparent"></div></div></div><figcaption>Pick the harm type first, because it decides which measurement is worth running.</figcaption></figure><ul><li>Representational harm changes how people are portrayed. Read completions and review the failures by hand.</li><li>Allocative harm changes who gets resources or opportunities. Compare outcomes by group against base rates.</li><li>Quality-of-service harm changes who receives worse behavior from the same system. Slice the error rate before you report it.</li></ul><p>The three do not trade off against each other. A model can portray a group badly while its error rates look even across groups. It can allocate resources evenly and still write demeaning completions. The type you measure decides the failure you can see.</p><p>Every threshold picks an error. Tighten it and the system produces false positives. Loosen it and the system produces false negatives. The number decides which group eats which mistake, so name the group before you set the number.</p><h2 id="the-aggregate-hides-the-subgroup">The Aggregate Hides The Subgroup</h2><p>The same aggregate metric hides different harm profiles, depending on how you slice the population. Aggregate numbers are blunt by construction. They average over the people the system treats worst.</p><p>Two versions of a system can report the same overall error rate and earn different verdicts. Slice by dialect and one holds flat, while the other fails on the dialect its corpus carried least. The average passes both. The slice passes one.</p><div class="v-decision"><span class="kicker">Measurement rule</span><div class="body">For every aggregate metric, name the group, dialect, language, or context that loses inside the average.</div></div><p>Hand review of failures catches what no slice defines. A completion can read as demeaning while the error rate stays flat. The dialect slice returns in the moderation note ahead.</p><h2 id="measurement-decides-which-harms-become-visible">Measurement Decides Which Harms Become Visible</h2><p>Measurement choices define the groups, the prompts, the labels, the raters, the metrics, and the thresholds. Those choices decide which groups, mistakes, contexts, and trade-offs a benchmark can see. Everything outside that frame stays easy to ignore.</p><p>Prompt choice decides which behavior a benchmark ever elicits. A behavior that no prompt triggers reads as absent. The same benchmark can reward surface-level mitigation and leave the deeper behavior intact.</p><p>The person who writes the rubric decides what counts as harm. The person outside that rubric pays when the measurement misses.</p><p>A harm name gives you a category. The number behind it needs a definition, a dataset, a threshold, and an error analysis. Measurement is the first hard step.</p><p>The shortcut names harm categories and never tests whether the measurement can see them. That buys moral clarity on the page and operational blindness in the system.</p><p>You can act on a harm only after a measurement choice makes it visible.</p><h2 id="start-the-harm-analysis-before-launch">Start The Harm Analysis Before Launch</h2><p>A fairness dashboard after launch reports what already shipped. Run the harm analysis on the use case first, and write down four things.</p><ul><li>Name who the data represents, and who it leaves thin.</li><li>Name who a wrong output lands on.</li><li>Write down who can appeal, and the path that appeal takes.</li><li>Price the false positive and the false negative, group by group.</li></ul><p>The appeal path is where a person the measurement missed corrects the record. A system without one makes every wrong output final.</p><p>Draw the system boundary wide. The model, the prompt, the product interface, and the deployment setting each create harm on their own. The interface is part of the claim, so an analysis that stops at the weights stops early.</p><p>Early has a test. The analysis must land while product decisions still change. After launch it becomes a report.</p><h2 id="the-builder-test">The Builder Test</h2><p>Take one aggregate metric from a system you run this week. Slice it by group or by dialect, and name the subgroup the average was carrying. Then name the error that costs that subgroup more, and the signal that tells you it happened.</p><p>If the slice does not exist yet, that absence is the finding. Build the slice before the next release.</p><h2 id="what-carries">What Carries</h2><p>A harm definition that cannot name who is affected is too abstract to act on. Carry the affected user into every measurement decision, and the definition stays usable.</p><p>Bias in what a model reflects is one problem. What it produces on demand is the next one.</p><div class="rm-essay-close" aria-hidden="true"><svg width="76" height="32" viewBox="0 0 76 32" aria-hidden="true" class="rm-fmark-essay"><path d="M 2 14 Q 18 2 36 14 T 74 12" fill="none" stroke="currentColor" stroke-width="1.1" stroke-linecap="round" opacity="0.5"></path><line x1="2" y1="24" x2="60" y2="24" stroke="currentColor" stroke-width="1.1"></line><circle cx="68" cy="24" r="2.8" fill="var(--vermilion)"></circle></svg></div></div>]]></content:encoded>
    <pubDate>Sun, 15 Feb 2026 12:00:00 GMT</pubDate>
    <author>rajdeep@rajdeepmondal.com (Rajdeep Mondal)</author>
    <category>ai</category><category>language-models</category><category>foundation-models</category><category>harms</category><category>bias</category><category>fairness</category><category>measurement</category>
  </item>

  <item>
    <guid isPermaLink="true">https://rajdeepmondal.com/writing/language-model-systems-capabilities-are-interfaces-not-magic</guid>
    <title>Capabilities Are Interfaces</title>
    <link>https://rajdeepmondal.com/writing/language-model-systems-capabilities-are-interfaces-not-magic</link>
    <description>A capability belongs to the model and the interface together. The claim is incomplete until it names the prompt, context, decoding rule, benchmark, and failure examples.</description>
    <content:encoded><![CDATA[<div class="essay-prose"><p>A capability belongs to the model and the interface together. The same checkpoint looks weak under a bare prompt and strong under a benchmark-friendly one. The claim stays incomplete until it names the prompt, the context, the decoding rule, the benchmark, and the failure examples.</p><h2 id="a-capability-appears-through-an-interface">A Capability Appears Through An Interface</h2><p>Language models handle language modeling, question answering, translation, arithmetic, article generation, and grammar correction. They also handle tasks nobody trained them for. Which of those you see depends on how you ask.</p><p>Capability claims disagree because the setups disagree. One evaluation sends a bare prompt. Another gives examples, tool access, retrieval, scratch space, and repeated attempts. The checkpoint stays the same across all of them. The interface decides what it can express.</p><p>One sweep settles which pair a claim describes. Compare bare prompting, few-shot prompting, tool access, retrieval, scratch space, and repeated attempts on one task. A fragile model scores well under one of those and drops under the rest. If the score swings across that sweep, the claim belongs to the model-interface pair rather than to the checkpoint.</p><h2 id="few-shot-prompting-writes-a-temporary-task-specification">Few-Shot Prompting Writes A Temporary Task Specification</h2><p>The GPT-3 era made this visible. Engineers scaled a next-token model and few-shot behavior came out of it. Place a few examples in the context window, ask for a continuation, and the model often infers the task format.</p><p>Show three examples of country to capital and the model continues the pattern. Phrase the same game badly and it misses. The examples tell the model which game you play. The checkpoint holds no module for that game.</p><p>Those examples write a temporary task specification inside the context window. Change the examples and you change the task. Pattern completion behaves like task learning here, and the behavior leaves when the prompt does.</p><h2 id="a-benchmark-is-a-contract">A Benchmark Is A Contract</h2><p>Benchmarks such as LAMBADA, HellaSwag, TriviaQA, WebQuestions, and arithmetic probes slice capability into observable tasks. Each one declares what counts as input, output, success, and failure. That declaration is the contract the benchmark offers, and it covers only what it names.</p><p>Language modeling benchmarks measure predictive fit, usually with perplexity or likelihood. Question answering measures whether the model connects prompt context with stored or retrieved knowledge. Translation needs mapping between languages. Arithmetic needs symbolic precision at every step. A perplexity win and a question answering win are two different claims about one checkpoint.</p><p>Scoring moves the number as much as the prompt does. An exact match, a judged answer, and a human rating measure three different things. Record which of the three produced the number you quote. Then check whether the benchmark scores the interface you ship. If it scores a different one, the number belongs to a different product.</p><h2 id="record-the-whole-interaction-contract">Record The Whole Interaction Contract</h2><p>The benchmark contract covers the task. The interaction contract covers everything around it. The common product mistake is to compare models on one task with no fixed interface. That comparison ranks prompts and publishes the ranking as a model verdict.</p><p>The interaction contract has eight fields: prompt format, examples, context, decoding, tools, retries, refusal policy, and scoring. User expectation belongs beside them, because the same output passes one reader and fails another. Write all of it next to the number. Skip it and the number measures an undocumented system.</p><figure class="rm-article-image"><div class="relative overflow-hidden"><div class="bg-muted absolute inset-0 z-10 animate-pulse rounded-[inherit]"><div class="animate-shimmer via-paper-bright/70 absolute inset-0 bg-linear-to-r from-transparent to-transparent"></div></div></div><figcaption>The eight fields wrap the checkpoint, and a capability number reported without them describes an undocumented system.</figcaption></figure><p>Decoding belongs in the record even when you never change it. The introduction note set up the decoding fork, and that fork sits inside every capability number you report. Change the decoding rule and the score moves while the weights stay fixed.</p><h2 id="the-average-hides-the-slice-that-fails">The Average Hides The Slice That Fails</h2><p>Treat novel task behavior as evidence to investigate. The evidence that settles it lives in the failures, so pull the wrong answers and read them. Name what they share, then check whether the shared property appears in the work you plan to ship.</p><div class="v-decision"><span class="kicker">Where a single score breaks</span><div class="body">Quote one benchmark score as ability and four risks travel with it unlisted. Those risks are hidden scaffolding, prompt sensitivity, contamination, and tasks where the score misses the work users do.</div></div><p>Emergent behavior means a capability became visible under a certain scale and interface. Stability is the open question after that. A model that answers the benchmark and breaks in a messy user workflow gives you a number with no coverage.</p><p>Say a model can do a task without saying under what conditions and the measurement turns into a myth. The conditions are cheap to write down. The myth is expensive to unwind after a launch.</p><h2 id="the-builder-test">The Builder Test</h2><p>Write the interaction contract for one task you own, every field, in one file. Hand the file to another engineer and ask for the number. If the number they get does not match yours, a field is missing from the file. A contract nobody else can run is a note to yourself.</p><h2 id="what-carries">What Carries</h2><p>A capability is never separate from the way you ask for it and the way you score it. An interface elicits it, and that interface must travel with the claim. Name the interface and a surprising result turns into an engineering decision.</p><p>You can now say what a model does under a named interface. The next question is who pays when that interface fails.</p><div class="rm-essay-close" aria-hidden="true"><svg width="76" height="32" viewBox="0 0 76 32" aria-hidden="true" class="rm-fmark-essay"><path d="M 2 14 Q 18 2 36 14 T 74 12" fill="none" stroke="currentColor" stroke-width="1.1" stroke-linecap="round" opacity="0.5"></path><line x1="2" y1="24" x2="60" y2="24" stroke="currentColor" stroke-width="1.1"></line><circle cx="68" cy="24" r="2.8" fill="var(--vermilion)"></circle></svg></div></div>]]></content:encoded>
    <pubDate>Fri, 13 Feb 2026 12:00:00 GMT</pubDate>
    <author>rajdeep@rajdeepmondal.com (Rajdeep Mondal)</author>
    <category>ai</category><category>language-models</category><category>foundation-models</category><category>capabilities</category><category>benchmarks</category><category>evaluation</category><category>gpt-3</category>
  </item>

  <item>
    <guid isPermaLink="true">https://rajdeepmondal.com/writing/language-model-systems-language-models-are-probability-machines</guid>
    <title>Language Models Are Probability Machines</title>
    <link>https://rajdeepmondal.com/writing/language-model-systems-language-models-are-probability-machines</link>
    <description>A language model assigns probabilities to strings, and temperature plus top-k decide whether those probabilities read as deterministic autocomplete or as a stochastic writer.</description>
    <content:encoded><![CDATA[<div class="essay-prose"><p>A language model assigns probabilities to strings. Temperature and top-k then decide whether those probabilities read as deterministic autocomplete or as a stochastic writer. The weights do not move between the two.</p><p>That definition sounds too small to explain GPT-style behavior. The surprise is how much world structure fits inside one plain objective.</p><h2 id="a-language-model-assigns-probabilities-to-strings">A Language Model Assigns Probabilities To Strings</h2><p>A next-token distribution is a compressed map of syntax, facts, styles, tasks, and patterns in the training data. Autoregressive language modeling decomposes a sequence into conditional probabilities, one per position. Predict the next token from the tokens before it, then do it again for the position after that.</p><p>Multiply or sum those probabilities across a sequence and the model scores the text. A sequence score lets you compare two candidate strings under one model. Scoring and writing run on the same conditionals.</p><p>The corpus decides the shape of that distribution. Frequency in the documents becomes fluency in the output. What the documents never carried is what the model finds hard to say. The data note in this unit opens that question.</p><div class="uth-essay uth-figure-embed"><div><figure class="fig reveal" id="cs324-probability-contract">
  
  <div class="fig-head">
    <span class="fig-title">language modeling is conditional prediction</span>
    <span class="ctrl">
      
      
    </span>
  </div>
  <div class="stage" id="cs324-probability-contract-stage" role="group" aria-live="polite" aria-describedby="cs324-probability-contract-caption">
    <div class="course-visual sys-wrap" aria-hidden="true">
      <div class="sys-stack">
        <div class="sys-layer" data-sys="behavior"><span class="sys-k">behavior</span><span class="sys-v">what users actually experience</span></div>
        <div class="sys-layer" data-sys="data"><span class="sys-k">data</span><span class="sys-v">what patterns the model practices</span></div>
        <div class="sys-layer" data-sys="model"><span class="sys-k">model</span><span class="sys-v">the objective turns text into behavior</span></div>
        <div class="sys-layer" data-sys="deployment"><span class="sys-k">deployment</span><span class="sys-v">interfaces, law, monitoring, and cost</span></div>
      </div>
      <div class="sys-world">
        <div class="sys-chip" data-sys="users">users turn scores into consequences</div>
        <div class="sys-chip" data-sys="rights">rights and consent shape the corpus</div>
        <div class="sys-chip" data-sys="eval">benchmarks see only a slice</div>
        <div class="sys-chip" data-sys="cost">serving repeats the bill</div>
      </div>
    </div>
    <div class="course-rail" data-rail aria-hidden="true"><span class="course-node" data-node="0">
        <span class="course-dot" aria-hidden="true">1</span>
        <span class="course-node-label">behavior</span>
      </span><span class="course-node" data-node="1">
        <span class="course-dot" aria-hidden="true">2</span>
        <span class="course-node-label">data</span>
      </span><span class="course-node" data-node="2">
        <span class="course-dot" aria-hidden="true">3</span>
        <span class="course-node-label">model</span>
      </span><span class="course-node" data-node="3">
        <span class="course-dot" aria-hidden="true">4</span>
        <span class="course-node-label">deployment</span>
      </span></div>
    <div class="course-grid"><div class="course-step" data-step="0">
        <span class="course-k">behavior</span>
        <span class="course-v">next-token scores become what users actually experience</span>
      </div><div class="course-step" data-step="1">
        <span class="course-k">data</span>
        <span class="course-v">training text decides which patterns the model practices</span>
      </div><div class="course-step" data-step="2">
        <span class="course-k">model</span>
        <span class="course-v">the objective turns context into probability</span>
      </div><div class="course-step" data-step="3">
        <span class="course-k">deployment</span>
        <span class="course-v">interfaces, law, monitoring, and cost shape real use</span>
      </div></div>
    <div class="course-status" data-status aria-live="polite"><b>behavior.</b> next-token scores become what users actually experience</div>
  </div>
  <figcaption id="cs324-probability-contract-caption">The next-token task is simple. The social meaning of putting that task into products is not simple.</figcaption>
</figure></div><span hidden=""></span></div><h2 id="generation-is-a-loop-that-eats-its-own-output">Generation Is A Loop That Eats Its Own Output</h2><p>Generation runs a loop. Condition on the prefix, choose or sample a token, append it, and repeat. The model turns its own output back into its own input at every step.</p><p>Each appended token joins the next prefix, so a choice made early conditions everything the model writes after it. One low-probability token sampled early becomes a premise the rest of the generation conditions on.</p><p>The model assigns scores, normalization turns them into probabilities, and a sampler or a search rule chooses what appears. Change any one of those pieces and the same weights behave differently.</p><p>Temperature and top-k are load-bearing settings. A small change in either one moves the visible personality of the system. Decoding is one field of the interaction contract that the capabilities note in this unit asks you to record.</p><figure class="rm-article-image"><div class="relative overflow-hidden"><div class="bg-muted absolute inset-0 z-10 animate-pulse rounded-[inherit]"><div class="animate-shimmer via-paper-bright/70 absolute inset-0 bg-linear-to-r from-transparent to-transparent"></div></div></div><figcaption>The weights are identical across these outputs, and the rule that reads the distribution is what changed.</figcaption></figure><h2 id="sparse-counts-cannot-generalize-learned-representations-can">Sparse Counts Cannot Generalize, Learned Representations Can</h2><p>Shannon, entropy, n-grams, smoothing, and the early neural language models all wrestled with uncertainty over text. Modern language models inherited that problem and changed the scale, the representation, and the interface.</p><p>N-gram models expose the old bottleneck. Counts are sparse, so a table of exact strings generalizes badly to a context it never saw. Neural models replace that table with learned representations. Similar contexts then share statistical strength, so an unseen context gets a probability from its neighbors. Scale changed the representation and left the prediction problem where it was.</p><h2 id="every-visible-token-hides-three-questions">Every Visible Token Hides Three Questions</h2><p>Every visible token hides three questions, and asking them blocks a mystical reading of the output.</p><ul><li>Distribution: which patterns the model learned from its training data</li><li>Context: what information is visible in this prompt right now</li><li>Decoding: how the system converts probabilities into text</li></ul><p>Probability is the clean abstraction and generation is a concrete process. The first question belongs to the model, and the second to the prompt. The third belongs to whoever configured the sampler, and that is usually you. Two of the three are yours to set before you send the prompt.</p><div class="v-decision"><span class="kicker">Debugging frame</span><div class="body">Ask two things of every output: which distribution the prompt created, and which rule turned it into text.</div></div><h2 id="debug-the-sampler-before-you-blame-the-model">Debug The Sampler Before You Blame The Model</h2><p>Treating output text as if it came from a mind with stable beliefs is the practical mistake. It came from a distribution under a decoding rule, and that is what makes it debuggable.</p><p>The easy stopping point is the most fluent sample, read as a belief the model holds. Another rule on the same distribution returns a different continuation, and the uncertainty the fluent sample hid becomes visible.</p><p>If the answer is too bland, inspect decoding. If it is confidently wrong, inspect retrieval and the evidence in the prompt. Instability across reruns is a different signal, and it points at prompt sensitivity and sampling.</p><p>The overview note asked you to name the layer that did the work. Here the layers are the model, the context, and the sampler. Start with the sampler. It is the cheapest of the three to change.</p><h2 id="the-builder-test">The Builder Test</h2><p>Take one prompt and run it under three decoding settings. Read the three outputs side by side and compare uncertainty, diversity, repetition, and hallucination risk. If all three come back nearly identical, the prompt is doing the constraining and the sampler has little room.</p><p>Then hold decoding fixed, change one thing in the context, and run it again. That pass measures sensitivity to context. The first pass prices the sampler and the second prices the prompt. Record both settings beside the output, or you keep three samples and no explanation.</p><h2 id="what-carries">What Carries</h2><p>Text generation is probabilistic conditioning plus a decoding rule. The final text is a system output rather than a property of the weights. Each layer can be tested on its own. A claim about the model that never names the context or the sampler is a claim about one draw.</p><p>Keep the weights fixed and change the interface around them, and the same distribution reads as a different model.</p><div class="rm-essay-close" aria-hidden="true"><svg width="76" height="32" viewBox="0 0 76 32" aria-hidden="true" class="rm-fmark-essay"><path d="M 2 14 Q 18 2 36 14 T 74 12" fill="none" stroke="currentColor" stroke-width="1.1" stroke-linecap="round" opacity="0.5"></path><line x1="2" y1="24" x2="60" y2="24" stroke="currentColor" stroke-width="1.1"></line><circle cx="68" cy="24" r="2.8" fill="var(--vermilion)"></circle></svg></div></div>]]></content:encoded>
    <pubDate>Wed, 11 Feb 2026 12:00:00 GMT</pubDate>
    <author>rajdeep@rajdeepmondal.com (Rajdeep Mondal)</author>
    <category>ai</category><category>language-models</category><category>foundation-models</category><category>probability</category><category>history</category><category>language-modeling</category>
  </item>

  <item>
    <guid isPermaLink="true">https://rajdeepmondal.com/writing/language-model-systems-language-model-systems-map</guid>
    <title>Read The Stack Sideways</title>
    <link>https://rajdeepmondal.com/writing/language-model-systems-language-model-systems-map</link>
    <description>A language-model claim stays unfinished until it names the dataset, the interface, the measurement, the user, the failure mode, and the cost of an error.</description>
    <content:encoded><![CDATA[<div class="essay-prose"><p>A language-model claim has six parts, and a benchmark score is one of them. A claim that reports only the score is unfinished.</p><p>The other five sit in layers the benchmark never reaches, and each of them changes what the number means.</p><figure class="rm-article-image"><div class="relative overflow-hidden"><div class="bg-muted absolute inset-0 z-10 animate-pulse rounded-[inherit]"><div class="animate-shimmer via-paper-bright/70 absolute inset-0 bg-linear-to-r from-transparent to-transparent"></div></div></div><figcaption>Read the stack sideways: each layer prices the one above it.</figcaption></figure><h2 id="a-model-is-a-corpus-an-objective-and-a-deployment-surface">A Model Is A Corpus, An Objective, And A Deployment Surface</h2><p>Count the parameters and you describe one part of the object. The same model is a training corpus, a tokenizer, an objective, and a compute plan. It is also a deployment surface and a set of institutional consequences.</p><p>Each of those parts gets a note of its own later in this unit. The corpus belongs to the data note, the tokenizer to the modeling note, the objective to the training note. Compute lands in the parallelism and scaling notes, and the consequences land in the harms, security, and legality notes.</p><p>The weights are the cheapest part of the object to describe. They predict the least about what the system does once it reaches users. A strong benchmark score sits next to weak data governance, an unsafe deployment, a privacy leak, or a serving bill nobody checked.</p><h2 id="the-sequence-runs-behavior-responsibility-machine-room-frontier">The Sequence Runs Behavior, Responsibility, Machine Room, Frontier</h2><p>The first two notes ask what a language model is and what it does. Next-token prediction is a small objective, and the behavior it produces does not stay small once the training run gets large. Both notes treat the model as a probability machine that became a general interface.</p><p>The middle notes turn to the world around the model. Bias, toxicity, disinformation, data provenance, security, privacy, and law arrive here. Each one asks who benefits and who carries the risk when the model is wrong.</p><p>The back half opens the machine. Tokenization and Transformers set the shape of the model, and training objectives and optimization set what it practices. Parallelism and scaling laws turn frontier training into an infrastructure problem with a bill attached.</p><p>The last stretch covers scale, sparsity, adaptation, and cost. Selective architectures and adaptation make a system more useful without a bigger dense model. The environmental note prices what the whole plan consumes.</p><h2 id="read-the-stack-sideways">Read The Stack Sideways</h2><p>The stack reads better sideways than top to bottom. A choice made in one layer arrives as a bill in another, and the other layer usually belongs to a different note.</p><figure class="rm-article-image"><div class="relative overflow-hidden"><div class="bg-muted absolute inset-0 z-10 animate-pulse rounded-[inherit]"><div class="animate-shimmer via-paper-bright/70 absolute inset-0 bg-linear-to-r from-transparent to-transparent"></div></div></div><figcaption>Each crossing shows a choice made in one layer arriving as a cost in another.</figcaption></figure><p>The tokenizer is a modeling decision. Split text into finer pieces and every sequence gets longer. Longer sequences cost memory, and the parallelism note plans around that memory.</p><p>A corpus filter is a data decision. The filter decides which text disappears, and what disappears returns later as the subgroup the first harms note finds inside an average.</p><p>Give a model tool access and you make a deployment decision. The model then reads untrusted text while it holds tools and private context, which the security note treats as prompt injection. The duty to disclose what leaked belongs to the legality note.</p><h2 id="whenever-a-model-surprises-you-name-the-layer">Whenever A Model Surprises You, Name The Layer</h2><p>Name the layer and the surprise turns into work you can price. Once the layer has a name, you can inspect it and change it. I keep this rule because a layer with a name has an owner, and you can ask an owner for a number.</p><div class="v-decision"><span class="kicker">Course rule</span><div class="body">Whenever a model surprises you, ask which layer made it possible: data, objective, architecture, scale, adaptation, interface, or deployment context.</div></div><p>The capabilities note opens on one of these surprises. You put examples in the prompt, the model follows the pattern, and the result looks like a new task learned on the spot.</p><p>Two layers produced that. Scale is one, because the capability appears only after the model gets big enough. The interface is the other, because the examples inside the context window write a temporary task specification.</p><p>Change the prompt format and the capability moves while the weights stay the same. One of those two layers costs a training run to change. The other costs a prompt edit. Name the layer and you know which bill you are about to pay.</p><h2 id="a-finished-claim-names-six-things">A Finished Claim Names Six Things</h2><p>A behavior starts in data and objective choices. It appears through an interface, an evaluation judges it, and then it reaches real users under real constraints. Each step in that chain leaves something the claim has to name.</p><ul><li>The dataset says where the behavior came from.</li><li>The interface records how you asked, because a different prompt is a different claim.</li><li>The measurement fixes what counted as success and what counted as failure.</li><li>The user is the person who meets the output, under whatever pressure they already carry.</li><li>The failure mode names what goes wrong and on which slice of the traffic.</li><li>The cost of an error is what the wrong answer takes from the person who receives it.</li></ul><p>A benchmark score stays true while five of the six stay missing, which makes it easy to report and hard to act on.</p><h2 id="the-builder-test">The Builder Test</h2><p>Take one deployment claim you already make about a system you run. Trace it from the source data through the objective and the training run.</p><p>Continue through the evaluation contract and the user interface, then the monitoring loop. Stop at the rule that changes a launch decision, and write that rule down.</p><p>If the interface you measured under has no name in your notes, stop and write it down. The trace fails at the first step where you cannot name an owner. That step is the layer to fix first.</p><h2 id="what-carries">What Carries</h2><p>You cannot separate model quality from the stack that made it, serves it, and absorbs its mistakes. Read each layer as its own discipline and every risk looks smaller than it is, because the hardest failures cross boundaries.</p><p>The first layer to open is the one every other layer conditions on. Read the next-token distribution first, because every layer above it inherits its shape.</p><div class="rm-essay-close" aria-hidden="true"><svg width="76" height="32" viewBox="0 0 76 32" aria-hidden="true" class="rm-fmark-essay"><path d="M 2 14 Q 18 2 36 14 T 74 12" fill="none" stroke="currentColor" stroke-width="1.1" stroke-linecap="round" opacity="0.5"></path><line x1="2" y1="24" x2="60" y2="24" stroke="currentColor" stroke-width="1.1"></line><circle cx="68" cy="24" r="2.8" fill="var(--vermilion)"></circle></svg></div></div>]]></content:encoded>
    <pubDate>Mon, 09 Feb 2026 12:00:00 GMT</pubDate>
    <author>rajdeep@rajdeepmondal.com (Rajdeep Mondal)</author>
    <category>ai</category><category>language-models</category><category>foundation-models</category><category>technical-notes</category>
  </item>

    </channel>
  </rss>