<script data-pm-proxy="intercept"></script><?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[DataJourney]]></title><description><![CDATA[Hey there! Welcome to Data Journey. I’m Pooja, and I’m deeply passionate about machine learning and NLP. Through this newsletter, I’m excited to share insights and practical advice with you.]]></description><link>https://datajourney24.substack.com</link><image><url>https://substackcdn.com/image/fetch/$s_!uy5R!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe99bfe70-ad63-4822-a55f-3dd10d018800_826x826.png</url><title>DataJourney</title><link>https://datajourney24.substack.com</link></image><generator>Substack</generator><lastBuildDate>Wed, 02 Sep 2026 18:46:46 GMT</lastBuildDate><atom:link href="/__u/datajourney24.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Pooja Palod]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[datajourney24@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[datajourney24@substack.com]]></itunes:email><itunes:name><![CDATA[Pooja Palod]]></itunes:name></itunes:owner><itunes:author><![CDATA[Pooja Palod]]></itunes:author><googleplay:owner><![CDATA[datajourney24@substack.com]]></googleplay:owner><googleplay:email><![CDATA[datajourney24@substack.com]]></googleplay:email><googleplay:author><![CDATA[Pooja Palod]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Cost, Quality, Latency: The Lens for Every Decision]]></title><description><![CDATA[Your team built a customer support agent that works perfectly in demos.]]></description><link>https://datajourney24.substack.com/p/cost-quality-latency-the-lens-for</link><guid isPermaLink="false">https://datajourney24.substack.com/p/cost-quality-latency-the-lens-for</guid><dc:creator><![CDATA[Pooja Palod]]></dc:creator><pubDate>Sun, 09 Aug 2026 09:48:14 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!uy5R!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe99bfe70-ad63-4822-a55f-3dd10d018800_826x826.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Your team built a customer support agent that works perfectly in demos. It reads tickets, retrieves context, validates against policy, and responds in under 500ms. You&#8217;re confident. You ship it.</p><p>The first week, the agent runs great. The second week, ticket volume doubles. Response time climbs to 1.2 seconds. By the third week, you&#8217;re seeing cascading retrieval timeouts. Escalations spike. You add caching to speed up retrieval. Latency drops to 400ms. But now 15% of responses reference stale customer data. Quality tanks. You add real-time refresh to the cache. Cost triples. You&#8217;re stuck in a loop: every fix breaks something else.</p><p><strong>You didn&#8217;t have the wrong architecture. You had the right architecture optimized for the wrong constraints.</strong></p><p>The model worked. Retrieval worked. Validation worked. But you&#8217;d optimized everything for a single request in a demo where volume was zero, data was fresh, and latency mattered most. When that system hit production, every optimization became a liability.</p><p>The deeper problem wasn&#8217;t a missing technical fix. It was a missing decision framework. Nobody explicitly chose: &#8220;Given my actual constraints throughput, data freshness, cost which dimension matters most? And what am I willing to trade?&#8221;</p><div><hr></div><h2>The Lens</h2><p>Every architectural choice in your system affects three dimensions:</p><ul><li><p><strong>Cost</strong>: API spend, compute, infrastructure overhead, operational complexity</p></li><li><p><strong>Quality</strong>: accuracy, hallucination rate, completeness, user satisfaction</p></li><li><p><strong>Latency</strong>: time-to-first-token, end-to-end response time, throughput</p></li></ul><p>These three are always in tension. You cannot maximize all three. Production engineering is making that tension visible and choosing consciously where to trade.</p><p><strong>The reality teams face</strong>: Most don&#8217;t <em>choose</em> trade-offs. They inherit them. Optimize for demo latency (single request), ship to production (throughput matters), then reactively patch failures as they surface. By then, architecture is locked in and fixes are expensive.</p><p>Intentional production engineering means:</p><ol><li><p><strong>Identifying your constraint</strong>: Which dimension has a hard limit? (Cost cap? Latency SLA? Quality threshold?)</p></li><li><p><strong>Mapping stage and layer decisions</strong>: Which Stages/Layers affect which CQL dimensions?</p></li><li><p><strong>Making explicit trade-offs</strong>: Accept underperformance in one dimension to excel in your constraint</p></li><li><p><strong>Revisiting as conditions change</strong>: Your optimal architecture at 100 requests/day is wrong at 10,000 requests/day</p></li></ol><div><hr></div><h2>How Stages and Layers Influence CQL</h2><p>You know the Stages and Layers from the previous article. Here&#8217;s how architectural decisions map to Cost, Quality, and Latency:</p><p><strong>Model &amp; Reasoning</strong></p><ul><li><p>Stronger model: &#8593;&#8593; Cost | &#8593; Quality | &#8593; Latency</p></li><li><p>More verification layers: &#8593; Cost | &#8593;&#8593; Quality | &#8593; Latency</p></li></ul><p><strong>Retrieval &amp; Context</strong></p><ul><li><p>Larger context window: &#8593; Cost | &#8593;/&#8595;* Quality | &#8593; Latency</p></li><li><p>Better retrieval ranking: &#8593; Cost | &#8593; Quality | &#8593; Latency</p></li></ul><p><strong>Optimization &amp; Control</strong></p><ul><li><p>Semantic caching: &#8595; Cost | &#8595;* Quality | &#8595; Latency</p></li><li><p>Model routing: &#8595; Cost | &#8596;/&#8595; Quality | &#8595; Latency</p></li><li><p>Parallel execution: &#8593; infra Cost | &#8596; Quality | &#8595; Latency</p></li><li><p>Explicit fallbacks: &#8593; Cost | &#8593; Quality | &#8593;/&#8595;* Latency</p></li></ul><p><em>Quality impact depends on your specific constraints (freshness, accuracy tolerance, domain requirements)</em></p><p>The pattern is clear: <strong>every architectural choice trades one dimension for another.</strong> Your job is making that trade explicit rather than discovering it in production.</p><div><hr></div><h2>Three Optimization Paths</h2><h3>When Cost is the Constraint</h3><p><strong>Scenario</strong>: Internal chatbot, limited budget, low volume (~100 req/day). Accuracy can be acceptable, not perfect.</p><p><strong>Decisions</strong>:</p><ul><li><p>Use a cheaper model. Accept lower quality as the trade-off.</p></li><li><p>Cache aggressively. Accept stale data; communicate freshness to users.</p></li><li><p>Route simple queries to lightweight models. Minimal multi-stage verification.</p></li><li><p>Single-pass validation only. Escalate edge cases to humans.</p></li></ul><p><strong>Result</strong>: Latency ~1&#8211;2s, Cost minimized, Quality acceptable.</p><p><strong>Scaling risk</strong>: At 10,000 req/day, the cheap model struggles with edge cases. Stale cache becomes untenable. Escalations overwhelm your team. You&#8217;d need to rebuild. <a href="/__u/datajourney24.substack.com/p/token-economics-why-llm-cost-is-an">See Token Economics for cost control at scale.</a></p><h3>When Quality is the Constraint</h3><p><strong>Scenario</strong>: Medical decision support. Must be &gt;95% accurate. Cost secondary, latency acceptable up to 5s.</p><p><strong>Decisions</strong>:</p><ul><li><p>Use a stronger model (yes, it&#8217;s expensive).</p></li><li><p>Over-retrieve context. Fetch 30 documents, rank them, use top 10.</p></li><li><p>Multi-stage verification: rule-based checks + secondary model critique + human escalation for low-confidence.</p></li><li><p>Minimal caching. Freshness is non-negotiable.</p></li></ul><p><strong>Result</strong>: Cost 5&#8211;10x higher, Latency 3&#8211;5s, Quality maximized within your evaluation threshold.</p><p><strong>Operational risk</strong>: High cost limits scale. System is robust but expensive. <a href="/__u/datajourney24.substack.com/p/evaluation-in-production-genai-why">See Evaluation for building quality instrumentation.</a></p><h3>When Latency is the Constraint</h3><p><strong>Scenario</strong>: Real-time search interface. Must be &lt;500ms. 1,000 queries/second. Quality ~80%, acceptable for this use case.</p><p><strong>Decisions</strong>:</p><ul><li><p>Fast model or local serving. Trade some quality for speed.</p></li><li><p>Pre-compute embeddings and keep retrieval paths optimized for serving-time access.</p></li><li><p>Lightweight validation. Accept 5% invalid responses, handle downstream.</p></li><li><p>Aggressive routing. Parallel execution. Timeouts at every dependency boundary.</p></li></ul><p><strong>Result</strong>: Latency minimized, Cost moderate, Quality acceptable within latency constraints.</p><p><strong>Evolution risk</strong>: If quality requirements rise (80% &#8594; 95%), verification adds latency and breaks your SLA. You&#8217;d need to rebuild. <a href="/__u/datajourney24.substack.com/p/latency-and-reliability-in-production">See Latency &amp; Reliability for these trade-offs in production.</a></p><div><hr></div><h2>Optimize the System, Not the Component</h2><p>A $0.01 model call sounds cheap until you realize it requires:</p><ul><li><p>3 retrieval calls (adding latency and cost)</p></li><li><p>2 reranking calls (because the model needs more signal)</p></li><li><p>A verification layer (because the weak model makes errors)</p></li><li><p>Retries (because things fail more often)</p></li><li><p>Larger context windows (to compensate for capability)</p></li><li><p>More infrastructure (to handle all of this)</p></li></ul><p>By the time you&#8217;re done, you&#8217;ve spent far more than a better model would have cost.</p><p>Similarly, a 300ms LLM call sounds fast until:</p><ul><li><p>Your retrieval takes 800ms</p></li><li><p>Your model is fast because it&#8217;s small (can&#8217;t handle complexity)</p></li><li><p>Quality is low, so you add verification</p></li><li><p>Total latency is now 1.2s (and it was never the bottleneck)</p></li></ul><p><strong>The mistake</strong>: Optimizing components in isolation.</p><p><strong>The correct approach</strong>: Optimize the entire system for your constraint. A more expensive model that eliminates the need for verification and reranking might actually be cheaper system-wide. A model that&#8217;s slightly slower but produces higher-quality output that needs no verification might be faster end-to-end.</p><p>This is why the three paths above rarely work exactly as described in production. The optimization landscape is complex. Your job is mapping it explicitly rather than inheriting failures.</p><div><hr></div><h2>Framework: Choose Your Constraint</h2><p>When starting a project, make three decisions explicit:</p><p><strong>1. What is my primary constraint?</strong></p><p>One dimension has a hard limit:</p><ul><li><p>Cost capped (limited budget &#8594; cost-first)</p></li><li><p>Latency capped (real-time requirement &#8594; latency-first)</p></li><li><p>Quality constrained (minimum accuracy threshold &#8594; quality-first)</p></li></ul><p><strong>2. What are acceptable ranges for the other two?</strong></p><p>&#8220;Latency &lt;500ms, quality &gt;85%, cost &lt;$0.01/request&#8221; is actionable. &#8220;Fast, cheap, and accurate&#8221; is not.</p><p><strong>3. How does this change at scale?</strong></p><p>Architecture optimal at 100 req/day breaks at 10,000 req/day. Design forward, even if current volume is low.</p><div><hr></div><h2>Checklist: Building with CQL</h2><p><strong>Before Designing</strong>:</p><ul><li><p>[ ] Identified primary constraint (cost/quality/latency)?</p></li><li><p>[ ] Defined acceptable ranges for other two dimensions?</p></li><li><p>[ ] Mapped how Stages + Layers affect each CQL dimension?</p></li></ul><p><strong>For Cost-First Systems</strong>:</p><ul><li><p>[ ] Model choice optimized for cost-per-token, not capability?</p></li><li><p>[ ] Caching strategy in place (accepting staleness tradeoffs)?</p></li><li><p>[ ] Verification minimal (single-pass, not multi-model)?</p></li></ul><p><strong>For Quality-First Systems</strong>:</p><ul><li><p>[ ] Model choice strong enough for your domain?</p></li><li><p>[ ] Retrieval strategy comprehensive (ranked, not minimal)?</p></li><li><p>[ ] Verification multi-stage (rules + model critique)?</p></li></ul><p><strong>For Latency-First Systems</strong>:</p><ul><li><p>[ ] Retrieval parallelized with reasoning?</p></li><li><p>[ ] Model variant fast or locally served?</p></li><li><p>[ ] Verification lightweight (not blocking)?</p></li></ul><p><strong>For All</strong>:</p><ul><li><p>[ ] Documented trade-offs explicitly?</p></li><li><p>[ ] Identified scaling cliff (where does this break)?</p></li><li><p>[ ] Instrumented Cost, Quality, Latency in production?</p></li></ul><div><hr></div><h2>What&#8217;s Next</h2><p>At 100 requests a day, optimize for simplicity. Cheap model, minimal retrieval, no verification.At 100,000 requests/day, that same architecture is broken. You need routing, caching, verification. Redesign.</p><p>The architecture didn&#8217;t fail.Your constraints changed.</p><p>Your architecture should change as your constraints change. The goal is to make those changes deliberate, not reactive.</p><p>The next piece goes deeper into concrete disciplines: how to build retrieval systems at scale, design harnesses that catch errors, and instrument observability that surfaces problems early.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://datajourney24.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DataJourney! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[The Anatomy of a Production AI System]]></title><description><![CDATA[You learned in the previous article how AI systems evolved across four stages: prompt, context, harness, and loop engineering. But what does the actual runtime architecture look like? Here are the five architectural layers that make production systems work.]]></description><link>https://datajourney24.substack.com/p/the-anatomy-of-a-production-ai-system</link><guid isPermaLink="false">https://datajourney24.substack.com/p/the-anatomy-of-a-production-ai-system</guid><dc:creator><![CDATA[Pooja Palod]]></dc:creator><pubDate>Mon, 03 Aug 2026 14:00:45 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!1ysO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2faf168-81f9-4c4d-9008-56c37f6fff93_1024x559.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You learned in the <a href="/__u/datajourney24.substack.com/p/the-four-stage-evolution">previous article</a> how AI systems evolved across four stages: <strong>prompt, context, harness, and loop engineering</strong>. But what does the actual runtime architecture look like? Here are the five architectural layers that make production systems work.</p><p>Your LLM just hallucinated inventory numbers that your customer service team took as gospel. By the time anyone noticed, they&#8217;d promised a shipment that doesn&#8217;t exist. The model never lied intentionally it just did what it was trained to do: continue text. But somewhere between &#8220;model is available&#8221; and &#8220;customer gets promised delivery,&#8221; five architectural decisions failed in concert.</p><p>Understanding how to build reliable systems requires moving past the model itself and examining how these layers interlock to process information, execute actions, and catch errors.</p><p>This is where most engineering conversations about AI stop. They look at the model, maybe at the prompt, and ask: &#8220;How do we make the model smarter?&#8221; Wrong question. The model wasn&#8217;t the failure point. It was the system around it.</p><h2>Mental Model</h2><p>A production AI system is not an LLM on a serving endpoint. It&#8217;s <strong>five distinct layers</strong>, each with its own engineering discipline and failure modes. You can have the smartest model in the world, but if any single layer breaks, the entire system fails predictably.</p><p>Think of it like a suspension bridge. The cables are essential but you also need the towers, the suspension mechanism, the roadbed, and the drainage system. A single failure point in any layer brings down the whole structure.</p><blockquote><p><strong>The model determines your ceiling. The system determines your floor.</strong></p><p>A stronger model can improve the best possible outcome your application can achieve. Reliability, safety, cost efficiency, and operational performance are determined by the layers around the model. Production engineering is ultimately the discipline of raising the floor, not just chasing a higher ceiling.</p></blockquote><h3>Bridging Stages to Layers</h3><p>It is helpful to distinguish between the <strong>Four Stages</strong> and the <strong>Five Layers</strong>:</p><ul><li><p><strong>The Four Stages represent system evolution:</strong> How an organization&#8217;s engineering paradigm matures over time (from tweaking prompts to engineering feedback loops).</p></li><li><p><strong>The Five Layers represent system architecture:</strong> The static runtime topology of a production request as it moves from input to execution.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!1ysO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2faf168-81f9-4c4d-9008-56c37f6fff93_1024x559.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!1ysO!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2faf168-81f9-4c4d-9008-56c37f6fff93_1024x559.png 424w, /__u/substackcdn.com/image/fetch/$s_!1ysO!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2faf168-81f9-4c4d-9008-56c37f6fff93_1024x559.png 848w, /__u/substackcdn.com/image/fetch/$s_!1ysO!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2faf168-81f9-4c4d-9008-56c37f6fff93_1024x559.png 1272w, /__u/substackcdn.com/image/fetch/$s_!1ysO!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2faf168-81f9-4c4d-9008-56c37f6fff93_1024x559.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!1ysO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2faf168-81f9-4c4d-9008-56c37f6fff93_1024x559.png" width="1024" height="559" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b2faf168-81f9-4c4d-9008-56c37f6fff93_1024x559.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:559,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:383116,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://datajourney24.substack.com/i/209631116?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2faf168-81f9-4c4d-9008-56c37f6fff93_1024x559.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!1ysO!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2faf168-81f9-4c4d-9008-56c37f6fff93_1024x559.png 424w, /__u/substackcdn.com/image/fetch/$s_!1ysO!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2faf168-81f9-4c4d-9008-56c37f6fff93_1024x559.png 848w, /__u/substackcdn.com/image/fetch/$s_!1ysO!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2faf168-81f9-4c4d-9008-56c37f6fff93_1024x559.png 1272w, /__u/substackcdn.com/image/fetch/$s_!1ysO!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2faf168-81f9-4c4d-9008-56c37f6fff93_1024x559.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">The Stages vs. Layers Bridge. Engineering maturity evolves across four stages over time, translating directly into a five-layer runtime architecture that executes every request.ption...</figcaption></figure></div></li></ul><blockquote><p><strong>Where do AI Agents fit?</strong></p><p>Autonomous agents are not a single layer in this architecture. An agent is a design pattern that coordinates across all five layers using <strong>Reasoning</strong> to plan, <strong>Context</strong> to ground, <strong>Action</strong> to execute tools, <strong>Control</strong> to verify decisions, and <strong>Observability</strong> to log trajectory steps.</p></blockquote><p></p><blockquote><p><strong>Example: Processing a Return Request</strong></p><p>A customer asks: <em>&#8220;Can I return the headphones I purchased last week?&#8221;</em></p><ul><li><p>Context retrieves the customer&#8217;s order history and return policy.</p></li><li><p>Reasoning determines whether the purchase falls within the return window.</p></li><li><p>Action invokes the order management API to initiate a return.</p></li><li><p>Control verifies that the return complies with company policy.</p></li><li><p>Observability records the full request trace for future debugging and analysis.</p></li></ul><p>Even a simple request typically touches all five layers.</p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!YxgM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40080b09-9013-457f-8109-e85b378ea8e3_1024x559.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!YxgM!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40080b09-9013-457f-8109-e85b378ea8e3_1024x559.png 424w, /__u/substackcdn.com/image/fetch/$s_!YxgM!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40080b09-9013-457f-8109-e85b378ea8e3_1024x559.png 848w, /__u/substackcdn.com/image/fetch/$s_!YxgM!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40080b09-9013-457f-8109-e85b378ea8e3_1024x559.png 1272w, /__u/substackcdn.com/image/fetch/$s_!YxgM!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40080b09-9013-457f-8109-e85b378ea8e3_1024x559.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!YxgM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40080b09-9013-457f-8109-e85b378ea8e3_1024x559.png" width="1024" height="559" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/40080b09-9013-457f-8109-e85b378ea8e3_1024x559.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:559,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:621488,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://datajourney24.substack.com/i/209631116?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40080b09-9013-457f-8109-e85b378ea8e3_1024x559.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!YxgM!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40080b09-9013-457f-8109-e85b378ea8e3_1024x559.png 424w, /__u/substackcdn.com/image/fetch/$s_!YxgM!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40080b09-9013-457f-8109-e85b378ea8e3_1024x559.png 848w, /__u/substackcdn.com/image/fetch/$s_!YxgM!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40080b09-9013-457f-8109-e85b378ea8e3_1024x559.png 1272w, /__u/substackcdn.com/image/fetch/$s_!YxgM!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40080b09-9013-457f-8109-e85b378ea8e3_1024x559.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p> An incoming request first passes through the <strong>Context</strong> layer to assemble relevant facts, feeds into the <strong>Reasoning</strong> core to formulate an intent, routes through the <strong>Action</strong> layer to invoke tools or APIs, validates through the <strong>Control</strong> layer to verify safety and correctness before execution, while <strong>Observability</strong> captures telemetry across every transition.</p><h2>Deep Dive: The Five Architectural Layers</h2><h3>Layer 1: Reasoning (The LLM)</h3><p>The model is the cognitive engine. It takes tokens, performs matrix operations, and outputs tokens. That&#8217;s it. Everything it does is statistical continuation.</p><p>In production, this layer is not about &#8220;which model is smartest.&#8221; It&#8217;s about: <em>Can this model solve the specific task at acceptable cost and latency, given the constraints of my system?</em></p><ul><li><p><strong>Llama 3.1 8B</strong> is cheap and fast but struggles with complex multi-step reasoning.</p></li><li><p><strong>Claude 3.5 Sonnet</strong> reasons exceptionally well but costs significantly more per token.</p></li><li><p><strong>Fine-tuned specialized models</strong> might achieve 95% accuracy on domain data but can fail on unexpected edge cases.</p></li></ul><p>The Reasoning choice determines your system&#8217;s ceiling the best possible outcome given infinite engineering effort on the other four layers. But it doesn&#8217;t determine your floor. The floor is set by the surrounding layers.</p><h3>Layer 2: Context</h3><p>The model arrives at runtime with no knowledge of your customer, your inventory, your compliance rules, or what happened five minutes ago. Everything it needs to know must be injected into the prompt or context window.</p><p>Context is a finite resource. Every token spent explaining context is a token unavailable for reasoning or output.</p><ul><li><p><strong>The Naive Approach:</strong> Retrieving 15 relevant documents and dumping them all into the context window. The model hits attention degradation (&#8221;lost in the middle&#8221;), reads the first two, hallucinates, and ignores the rest while burning token budget.</p></li><li><p><strong>The Production Approach:</strong> Retrieve 15 documents, rank them by relevance, compress lower-ranked sources into structural summaries, and pass the top 5 in full alongside the summary. Same informational coverage, significantly lower token overhead, higher reasoning fidelity.</p></li></ul><p>Context engineering - selecting, structuring, compressing, and isolating information &#8212; dictates whether the model actually uses available data effectively.</p><h3>Layer 3: Action (Tools &amp; Harness)</h3><p>The model can reason, but it cannot execute side effects. It cannot natively query a database, send a wire transfer, or call an external API; it can only output text describing those actions.</p><p>The Action layer bridges this gap. It consists of the tool definitions, structured output interfaces (e.g., JSON schemas), and execution drivers.</p><ul><li><p><strong>Unconstrained Tool Calling:</strong> Providing an LLM raw access to execute commands. If a user asks, <em>&#8220;Can you issue a $500,000 refund?&#8221;</em>, an ungrounded model may attempt to invoke <code>issue_refund(amount=500000)</code>.</p></li><li><p><strong>Bounded Execution Harness:</strong> Defining explicit permissions at the system level. The harness validates tool calls against session authorization. A customer service role harness rejects any <code>issue_refund</code> call exceeding $50 <em>before</em> the API call reaches your back-end systems.</p></li></ul><p>Enforcing strict output schemas at this layer guarantees that model outputs fail fast at the parser level rather than corrupting downstream state.</p><h3>Layer 4: Control (Verification)</h3><p>Once the model produces an output or tool call, the Control layer increases confidence before any action is executed or returned to the end user.</p><p>The goal of the Control layer is not to prove that the model is correct. That is rarely possible in open-ended systems. Instead, the objective is to reduce the probability that an incorrect output becomes a costly action. Production systems typically rely on multiple overlapping control mechanisms rather than a single verifier. No individual check is perfect, but together they significantly reduce operational risk.</p><p>Verification is distinct from basic parsing (which lives in the Action layer). Control focuses on <strong>evaluating mechanics that mitigate risk before execution</strong>:</p><ol><li><p><strong>Rule-Based Guardrails:</strong> Hard checks verifying bounded constraints (e.g., regex matching, parameter boundaries, blocklists).</p></li><li><p><strong>Deterministic Assertions:</strong> Running static checks against generated code or structured logic prior to runtime execution.</p></li><li><p><strong>Pre-Execution Critique:</strong> Invoking lightweight, deterministic verifiers or fast secondary models to evaluate factual consistency against retrieved context.</p><p></p></li></ol><h3>Layer 5: Observability</h3><p>When a failure occurs in production (e.g., a customer receives an incorrect refusal), debugging requires visibility into the full execution state.</p><p>Logging records <em>&#8220;event X occurred.&#8221;</em> Observability ensures you can answer arbitrary questions about why a trajectory unfolded the way it did.</p><p>A production trace captures:</p><ul><li><p>The original user payload.</p></li><li><p>Exact retrieved context chunks and similarity scores.</p></li><li><p>System and user prompts supplied to Layer 1.</p></li><li><p>Raw model generation outputs.</p></li><li><p>Active guardrails, executed tool calls, and validation results from Layers 3 &amp; 4.</p></li></ul><p>Observability also reveals systemic friction points  such as an agent taking 40 recursive steps to resolve a simple task or repeatedly failing a specific schema validation  long before they manifest as critical customer-facing bugs.</p><blockquote><p>Not every AI application requires all five layers. A simple internal chatbot may only need Reasoning and Context. As systems become more autonomous, customer-facing, or business-critical, additional layers become necessary. The architecture expands in response to reliability requirement</p></blockquote><h2>Production Reality: Failure Cascades</h2><p>When all five layers are deployed, failures shift from simple crashes to inter-layer structural interactions.</p><h3>1. The Cascade Effect (The Most Dangerous Pattern)</h3><p>A context retrieval error (Layer 2) injects inaccurate background data. The LLM (Layer 1) processes the bad input logically, producing a plausible hallucination. The Action harness (Layer 3) successfully parses the well-formed JSON call. The Control layer (Layer 4) verifies that schema constraints are met, missing the factual error. The bad action executes cleanly. Without explicit validation boundaries between each layer, failures cascade silently through the stack.</p><h3>2. Context Collapse</h3><p>A strong retrieval layer provides 30K tokens of context. However, when context size grows past certain thresholds, model reasoning accuracy drops noticeably. An over-engineered Context layer can degrade the Reasoning layer if context density is not managed.</p><h3>3. Harness Permission Creep</h3><p>As product requirements expand, dozens of tools get added to the Action layer. Over time, complex dependency chains emerge (e.g., Tool A requires Tool C to run first, but Tool B modifies the state Tool A depends on). The harness itself becomes a primary source of system bugs.</p><h3>4. Verification Lag</h3><p>Adding intensive pre-execution checks to Layer 4 increases request runtime. If verification relies on synchronous multi-model passes, latency degrades to unacceptable levels for real-time applications.</p><h3>5. Observability Blindness</h3><p>Emitting excessive trace data without structured indexing creates high-volume noise. When an incident occurs, identifying the root cause across thousands of unindexed span events becomes impractical.</p><p>The key insight is that no layer operates in isolation. Better context improves reasoning. Better control compensates for model limitations. Better observability exposes weaknesses in every other layer. Production systems succeed not because a single layer is exceptional, but because the interactions between layers are intentionally engineered.</p><blockquote><p>CQL Lens</p><p>Every architectural choice across these five layers balances three competing forces:</p><ul><li><p><strong>Cost</strong></p><ul><li><p><strong>Impact:</strong> Multi-layer execution (retrieval passes, tool routing, verification checks) increases per-request token and compute usage.</p></li><li><p><strong>Optimization:</strong> Use aggressive context compression, cache deterministic retrieval, and sample pre-execution checks dynamically.</p></li></ul></li><li><p><strong>Quality</strong></p><ul><li><p><strong>Impact:</strong> Unlayered systems rely entirely on model capabilities. Layered architecture traps edge-case failures through defense-in-depth.</p></li><li><p><strong>Optimization:</strong> Implement tight schemas at Layer 3 and targeted verification at Layer 4.</p></li></ul></li><li><p><strong>Latency</strong></p><ul><li><p><strong>Impact:</strong> Sequential processing across 5 layers adds overhead (retrieval latency, generation time, validation passes).</p></li><li><p><strong>Optimization:</strong> Run context retrieval in parallel, utilize async tracing, and enforce timeout budgets per layer.</p></li></ul><p></p></li></ul></blockquote><h2>What&#8217;s Next</h2><p>Now that you understand the structural anatomy of a production AI system, how do you make tactical trade-offs between these layers in real-world applications? Every design choice balances cost, latency, and quality.</p><p>The framework that guides these architectural choices is covered in the next article.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://datajourney24.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DataJourney! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[The Four Stages of AI Engineering]]></title><description><![CDATA[How production AI systems evolve from prompt engineering to autonomous decision-making.]]></description><link>https://datajourney24.substack.com/p/the-four-stage-evolution</link><guid isPermaLink="false">https://datajourney24.substack.com/p/the-four-stage-evolution</guid><dc:creator><![CDATA[Pooja Palod]]></dc:creator><pubDate>Sat, 25 Jul 2026 16:07:24 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!2PnL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca1e6c1-b3d0-4ed9-a92d-b79f8af9ea1d_1264x843.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>You shipped an AI agent to production. It failed spectacularly. Every fix worked until it didn't. Retrieval solved one problem. Verification solved another. Orchestration solved the next. Looking back, you realized you weren't patching bugs. You were climbing the hidden ladder of AI engineering maturity.</em></p><div><hr></div><p>You built a customer support agent. It looked good in testing: it read tickets, classified issues, drafted responses, and sent them to customers. Simple prompt, good results. Then you shipped it to production.</p><p>Within 48 hours: it hallucinated product features that don&#8217;t exist, approved refunds without checking if the customer was eligible, and got stuck retrying the same failed action until the cost hit $500. The prompt was fine. The model was fine. What was missing was everything else.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!2PnL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca1e6c1-b3d0-4ed9-a92d-b79f8af9ea1d_1264x843.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!2PnL!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca1e6c1-b3d0-4ed9-a92d-b79f8af9ea1d_1264x843.png 424w, /__u/substackcdn.com/image/fetch/$s_!2PnL!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca1e6c1-b3d0-4ed9-a92d-b79f8af9ea1d_1264x843.png 848w, /__u/substackcdn.com/image/fetch/$s_!2PnL!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca1e6c1-b3d0-4ed9-a92d-b79f8af9ea1d_1264x843.png 1272w, /__u/substackcdn.com/image/fetch/$s_!2PnL!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca1e6c1-b3d0-4ed9-a92d-b79f8af9ea1d_1264x843.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!2PnL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca1e6c1-b3d0-4ed9-a92d-b79f8af9ea1d_1264x843.png" width="1264" height="843" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6ca1e6c1-b3d0-4ed9-a92d-b79f8af9ea1d_1264x843.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:843,&quot;width&quot;:1264,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1071022,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://datajourney24.substack.com/i/208458184?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca1e6c1-b3d0-4ed9-a92d-b79f8af9ea1d_1264x843.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!2PnL!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca1e6c1-b3d0-4ed9-a92d-b79f8af9ea1d_1264x843.png 424w, /__u/substackcdn.com/image/fetch/$s_!2PnL!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca1e6c1-b3d0-4ed9-a92d-b79f8af9ea1d_1264x843.png 848w, /__u/substackcdn.com/image/fetch/$s_!2PnL!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca1e6c1-b3d0-4ed9-a92d-b79f8af9ea1d_1264x843.png 1272w, /__u/substackcdn.com/image/fetch/$s_!2PnL!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca1e6c1-b3d0-4ed9-a92d-b79f8af9ea1d_1264x843.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>So you added layers. First, retrieval - feed the agent customer order history and product data. That helped, but the agent still hallucinated based on bad context. Then, verification - make it call tools instead of guessing, validate refunds before approval, log every decision. Better, but the agent still didn&#8217;t know when to escalate versus when to retry. So you added orchestration - define a clear loop: perceive the ticket, reason about the issue, act on a decision, evaluate whether it worked. Only then does it escalate or close.</p><p>Each layer solved an immediate failure. Each one forced you to think differently about the system. What you were doing, without realizing it, was moving through the four stages of AI system maturity.</p><div><hr></div><h2>The Pattern: AI Engineering is the Evolution of Control</h2><p>AI systems don&#8217;t evolve smoothly. They evolve in discrete jumps, each prompted by a limitation you hit in production. And each jump represents the same underlying progression: <strong>expanding control</strong>.</p><ul><li><p><strong>Stage 1  Control Instructions</strong><br><em>Shape the model&#8217;s behavior through prompts.</em></p></li><li><p><strong>Stage 2  Control Information</strong><br><em>Decide what knowledge reaches the model.</em></p></li><li><p><strong>Stage 3  Control Execution</strong><br><em>Control how the system validates and acts.</em></p></li><li><p><strong>Stage 4 Control Decisions</strong><br><em>Orchestrate what the system attempts, retries, or escalates.</em></p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!96H8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F434a63bf-286f-427e-a31f-ea7c5027a7e4_1264x843.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!96H8!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F434a63bf-286f-427e-a31f-ea7c5027a7e4_1264x843.png 424w, /__u/substackcdn.com/image/fetch/$s_!96H8!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F434a63bf-286f-427e-a31f-ea7c5027a7e4_1264x843.png 848w, /__u/substackcdn.com/image/fetch/$s_!96H8!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F434a63bf-286f-427e-a31f-ea7c5027a7e4_1264x843.png 1272w, /__u/substackcdn.com/image/fetch/$s_!96H8!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F434a63bf-286f-427e-a31f-ea7c5027a7e4_1264x843.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!96H8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F434a63bf-286f-427e-a31f-ea7c5027a7e4_1264x843.png" width="1264" height="843" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/434a63bf-286f-427e-a31f-ea7c5027a7e4_1264x843.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:843,&quot;width&quot;:1264,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1094591,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://datajourney24.substack.com/i/208458184?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F434a63bf-286f-427e-a31f-ea7c5027a7e4_1264x843.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!96H8!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F434a63bf-286f-427e-a31f-ea7c5027a7e4_1264x843.png 424w, /__u/substackcdn.com/image/fetch/$s_!96H8!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F434a63bf-286f-427e-a31f-ea7c5027a7e4_1264x843.png 848w, /__u/substackcdn.com/image/fetch/$s_!96H8!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F434a63bf-286f-427e-a31f-ea7c5027a7e4_1264x843.png 1272w, /__u/substackcdn.com/image/fetch/$s_!96H8!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F434a63bf-286f-427e-a31f-ea7c5027a7e4_1264x843.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>Each stage assumes the previous one is &#8220;solved&#8221; or at least no longer the bottleneck. And each stage makes the system more reliable, but also more complex. This progression isn&#8217;t arbitrary. It&#8217;s the natural evolution from controlling language to controlling the entire system&#8217;s behavior.</p><div><hr></div><h2>Where It All Starts: Prompt Engineering</h2><p>You begin here. The model is fixed (Claude, GPT, Llama  doesn&#8217;t matter for this frame). The only variable is the text you send in.</p><p>Prompt engineering is about finding the right words, structure, and examples to trigger the behavior you want. A well-crafted prompt can clarify ambiguous instructions, provide in-context examples, set tone, and break complex tasks into steps. The wins are real. A good prompt can double accuracy on a benchmark. A bad prompt can tank it.</p><p>Yet words alone have limits. You can&#8217;t prompt your way out of missing data. You can&#8217;t reword your way around a context window too small to hold the relevant information. No amount of instruction clarity fixes a model that hallucinates because it&#8217;s working blind.</p><p>At this ceiling, the problem shifts from &#8220;how do I phrase this&#8221; to &#8220;what should the model even know about.&#8221;</p><h2>Moving Right: Context Engineering</h2><p>Context engineering answers: &#8220;What data should reach the model, and in what order?&#8221;</p><p>This is where Retrieval Augmented Generation lives. RAG lets you feed the model live data it wasn&#8217;t trained on. A customer service agent retrieves the customer&#8217;s account history. A medical system retrieves the patient&#8217;s lab results. An earnings analyst retrieves the quarterly filing.</p><p>But retrieval is just one tool. Context engineering also means deciding:</p><ul><li><p><strong>Structure</strong>: Should you embed retrieved data directly, summarize it, or format it as JSON or Markdown?</p></li><li><p><strong>Token budgeting</strong>: What gets in the context window? What stays out? In what order?</p></li><li><p><strong>Memory architecture</strong>: Working memory (what happened this conversation), episodic memory (similar past cases), semantic memory (knowledge base facts), procedural memory (how to do things).</p></li></ul><p>Here&#8217;s where context engineering reaches its own wall: more information doesn&#8217;t fix a confused reasoner. When the model gets lost in the data or refuses to follow instructions even with perfect context, you&#8217;ve outgrown what retrieval can solve.</p><p>The next step isn&#8217;t better data. It&#8217;s better control <em>over what the model does with that data</em>. </p><h2>Going Deeper: Harness Engineering</h2><p>Harness engineering is about building the guardrails.</p><p><strong>What is harness engineering?</strong> If prompts tell the model what to do, harness engineering determines what happens when the model is wrong. It&#8217;s the discipline of designing the systems, tools, constraints, and feedback loops that wrap around the model to transform it from a probabilistic component into reliable software. Think of it like the difference between having a talented chef and running a restaurant: the chef handles creativity, but the kitchen systems (timers, scales, temperature controls, quality checks) turn talent into consistency.</p><p>The principle: you know the model will sometimes fail. You can&#8217;t make it never fail. So instead, you catch failures and route around them.</p><p><strong>A concrete example</strong>: A customer support agent handles thousands of tickets daily. Without harness engineering, it hallucinates product features the company doesn&#8217;t offer, approves refunds without checking if the customer&#8217;s account is eligible, and gets stuck retrying the same failing action. With harness engineering, the system adds five layers around the model:</p><ol><li><p><strong>Tool sandboxing</strong> - The agent can call customer database, order lookup, and refund APIs, but cannot access other customers&#8217; data or modify account settings</p></li><li><p><strong>Verification loops</strong> - Before approving a refund, the harness checks: Is this customer eligible? Is the account in good standing? Is the refund amount within policy? If any check fails, the recommendation is rejected</p></li><li><p><strong>Memory</strong> - The agent recalls similar past interactions. Was this customer refunded before for the same issue? This prevents repeated mistakes</p></li><li><p><strong>Guardrails</strong> - Refund amounts are capped at $X per interaction. Only certain issue types can be auto-resolved; others auto-escalate by policy</p></li><li><p><strong>Observability</strong> - Every decision is logged: customer ID, issue type, action taken, outcome. Dashboards show resolution rate, escalation rate, refund leakage</p></li></ol><p>The result: The agent handles 80% of tickets without human escalation. The 20% that need human attention are pre-qualified and routed with full context.</p><p>The toolkit that enables this:</p><ul><li><p><strong>Output validation</strong>: Parse the response. Check if it&#8217;s valid JSON, matches the schema, contains the required fields. If not, reject and retry.</p></li><li><p><strong>Tool use</strong>: Don&#8217;t let the model do math or look up facts  make it call a tool. You control the tool&#8217;s output; you don&#8217;t control the model&#8217;s reasoning, but you control what it can do.</p></li><li><p><strong>Structured outputs</strong>: Force the model into a strict format (JSON, XML) so downstream systems know exactly what to expect.</p></li><li><p><strong>Verification</strong>: After the model answers, check it independently. A search engine might verify a factual claim. A refund system might verify the customer&#8217;s account eligibility.</p></li><li><p><strong>Rollback and retry</strong>: If validation fails, regenerate with modified instructions.</p></li></ul><p>The ceiling here is operational. Harness engineering can make the system more reliable, but it doesn&#8217;t solve &#8220;the model shouldn&#8217;t be trying this task at all&#8221; or &#8220;we need to decide what priority to give this request.&#8221; If a task is inherently hard (the model fails 40% of the time even with perfect guardrails), you&#8217;re not automating it  you&#8217;re adding complexity without reducing failure rate. And if you&#8217;ve built a system that blindly retries every failure, you&#8217;ll burn tokens: 1,000 extra tokens per request, at scale, becomes a cost problem.</p><p>When you hit that ceiling, you add logic that decides <em>whether</em> the model should try a task, and <em>what to do</em> if it fails.</p><h2>At Scale: Loop Engineering</h2><p>Loop engineering is about orchestration and control flow.</p><p><strong>What is loop engineering?</strong> It&#8217;s the discipline of orchestrating how an AI system executes iteratively designing the perceive-reason-act-reflect cycle, defining what success looks like, and deciding when to retry versus when to escalate. The &#8220;loop&#8221; is the repeating cycle that keeps the system pointed at its goal.</p><p><strong>A concrete example</strong>: A customer support agent processes tickets as they arrive. When a customer emails, the agent perceives the issue, reasons about the root cause, retrieves relevant data, acts on a response, and evaluates: &#8220;Did this resolve it? Should this escalate?&#8221; Clear stop conditions. No infinite loops. No blind escalation.</p><p>Without loop engineering, the agent retries infinitely or escalates everything. With loop engineering, it has explicit boundaries: one perceive-reason-act-evaluate cycle with clear success criteria.</p><p>The key questions the loop continuously asks:</p><ul><li><p><strong>What should happen next?</strong> (routing, prioritization)</p></li><li><p><strong>Is the model the right tool for this?</strong> (or should we use a heuristic, escalate, or fail gracefully)</p></li><li><p><strong>Did it work?</strong> (outcome evaluation)</p></li><li><p><strong>What&#8217;s next?</strong> (retry, escalate, or close)</p></li></ul><p>The ceiling here is complexity. Well-designed loops handle many failure modes. But more branches mean harder debugging, and multiple loops can interfere with each other in unexpected ways.</p><div><hr></div><h2>What Actually Breaks in Production</h2><p>Here&#8217;s what happens when engineers try to stay in an earlier stage longer than they should:</p><p><strong>Prompt engineering as a panacea</strong>: Teams spend weeks tuning prompts with diminishing returns. &#8220;Add more examples.&#8221; &#8220;Clarify the instruction.&#8221; These work until they don&#8217;t. The trap: assuming the next 10% accuracy improvement is one prompt rewrite away, when in reality you need context engineering or harness engineering. In customer support, this looks like: tweaking the system prompt to &#8220;never make refund mistakes&#8221; when the real problem is that the agent has no tool to check customer eligibility. More wording doesn&#8217;t help. Guardrails do.</p><p><strong>Retrieval without validation</strong>: RAG systems that fetch data and feed it to the model without checking whether the data is relevant or accurate. The model hallucinates based on bad context. The team assumes the problem is in retrieval and adds sophisticated chunking, reranking, hybrid search. Meanwhile, the real problem is that the model needs validation guardrails to catch when it&#8217;s confused by the fetched data. In customer support: you fetch the customer&#8217;s order history, but don&#8217;t verify that the order status has actually been updated before the agent references it. The agent then gives a customer stale information. More retrieval doesn&#8217;t fix this. Validation does.</p><p><strong>Over-reliance on retries</strong>: Teams add retry logic to harness problems they can&#8217;t otherwise solve. &#8220;If validation fails, regenerate 3 times.&#8221; This increases latency and token consumption without proportionally increasing reliability. Often, the real fix is loop engineering deciding not to try certain requests, or routing them to a different system. In customer support: if a refund is rejected (customer ineligible), retrying won&#8217;t help. The agent needs to escalate instead. Blindly retrying burns tokens and frustrates the customer.</p><p><strong>Harness without loop structure</strong>: A customer support system with perfect tool sandboxing, verification, and observability but no defined loop. The agent resolves some tickets perfectly, but gets stuck in others. Nobody knows when it should escalate. It retries the same action infinitely. It sends responses but doesn&#8217;t track whether they&#8217;re working. The lesson: harness engineering builds the safety rails, but loop engineering builds the execution structure. Without a defined loop (perceive-reason-act-evaluate, with explicit stop conditions), even the best harness can&#8217;t scale. You end up with a safe system that doesn&#8217;t work reliably.</p><div><hr></div><h2>Why This Matters</h2><p>The biggest mistake teams make isn&#8217;t choosing the wrong model.</p><p>It&#8217;s solving a Stage 3 problem with Stage 1 techniques.</p><p>Most production failures aren&#8217;t model failures they&#8217;re architecture failures. Your LLM didn&#8217;t get stupid. Your system didn&#8217;t match the problem. Understanding which stage you&#8217;ve reached is often more valuable than finding a better prompt.</p><p>When your agent hallucinates, that&#8217;s not always a prompt problem. When it makes inconsistent decisions, that&#8217;s not always a model problem. When it costs too much, that&#8217;s not always a compute problem.</p><p>These are architecture problems. And architecture problems require architectural solutions.</p><p>Every engineering decision is ultimately a trade-off. Regardless of the stage you're in, production AI systems are constrained by three forces: Cost, Quality, and Latency.</p><div><hr></div><blockquote><p><strong>CQL Lens</strong></p><p><strong>Cost</strong> : Each stage adds latency and/or token consumption. Prompt engineering is cheapest (extra tokens only if you add examples). Context engineering adds retrieval calls and context window overhead. Harness engineering adds validation and retry passes (2&#8211;5x the base latency per retry). Loop engineering adds orchestration overhead but can <em>reduce</em> cost by choosing not to call the model when a simpler path works. The question isn&#8217;t &#8220;which stage is cheapest&#8221; but &#8220;which stage is <em>efficient for your problem</em>.&#8221; A task that needs harness engineering stays cheap because harness catches errors early. A task that only needs prompts but you force into full harness bloats the cost.</p><p><strong>Quality</strong> :Moving through stages improves reliability in order. Prompt engineering improves consistency. Context engineering improves accuracy on knowledge tasks. Harness engineering improves robustness to edge cases and adversarial inputs. Loop engineering improves system-level reliability by knowing when to escalate, when to fail gracefully, when to try something else. But quality degrades if you over-engineer  too many retries, too many guardrails, latency increases, and slow systems fail differently than fast systems.</p><p><strong>Latency</strong>  Prompt engineering adds minimal latency (a few extra tokens). Context engineering adds retrieval time. Harness engineering adds validation and retry time. Loop engineering adds orchestration time but can <em>reduce</em> latency by choosing not to call the model. The trap: adding full loop engineering to a system that only needs prompts or context, just to feel &#8220;advanced.&#8221; Maturity is matching the stage to the problem, not using every stage.</p></blockquote><div><hr></div><h3><strong>What&#8217;s Next?</strong></h3><p>The Anatomy of a Production AI System</p><p>Every production AI system is built from the same fundamental components. In the next chapter, we'll break down prompts, models, context, memory, tools, guardrails, and orchestration and see how they fit together into a production-ready AI system.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://datajourney24.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DataJourney! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[Your Demo Worked. Here’s Why It Won’t Survive Production.]]></title><description><![CDATA[Every AI project looks the same at the six-month mark: the demo works.]]></description><link>https://datajourney24.substack.com/p/your-demo-worked-heres-why-it-wont</link><guid isPermaLink="false">https://datajourney24.substack.com/p/your-demo-worked-heres-why-it-wont</guid><dc:creator><![CDATA[Pooja Palod]]></dc:creator><pubDate>Fri, 10 Jul 2026 17:21:55 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!uy5R!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe99bfe70-ad63-4822-a55f-3dd10d018800_826x826.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Every AI project looks the same at the six-month mark: the demo works. The model nails the task. Your boss sees it. Investors see it. You&#8217;re ready to ship.</p><p>Then you try to actually ship it.</p><p>A March 2026 <a href="https://www.digitalapplied.com/blog/ai-agent-scaling-gap-march-2026-pilot-to-production">survey</a> of 650 AI leaders found that only 23% of AI projects that worked in development made it to production unchanged. Seventy-seven percent failed, stalled, or required fundamental rebuilding. Umesh Malik&#8217;s research into the <a href="https://umesh-malik.com/blog/autonomous-ai-agents-production-gap-2026">demo-to-production gap </a>found a consistent pattern: teams had built something that works <em>once</em>, under <em>perfect conditions</em>, but not something that works <em>every time</em>, for <em>everyone</em>, under <em>messy conditions</em>.</p><p>This isn&#8217;t a story about bad prompting or weak models. It&#8217;s a story about a different problem entirely: <strong>the gap between a prototype and a system.</strong></p><div><hr></div><p>When you demo an AI system, you&#8217;re not really shipping an AI system. You&#8217;re showing that a language model can solve a problem when you give it ideal inputs, your full attention, and your hand-holding. But production doesn&#8217;t give any of those things. Production gives you whatever real users send half-formed requests, contradictory instructions, data you&#8217;ve never seen before, requests at 3 AM for edge cases you didn&#8217;t anticipate.</p><p>There&#8217;s a name for what happens when you ship a demo to production without building a system around it: it fails. Sometimes obviously. Sometimes silently, in ways that affect customers for weeks before anyone notices. Sometimes it succeeds so quietly that your infrastructure collapses under the load.</p><p>The gap is not about better prompts or better models. The gap is architectural. And understanding that gap is what separates engineers who ship demos from engineers who ship systems.</p><p>This article is about what actually has to change not in your prompts, but in what you build around your prompts to take something from demo to production.</p><div><hr></div><h2>The Four Stages: From Demo to System</h2><p>Over the past 18 months, AI engineering has evolved through recognizable stages. Each emerged to solve what the previous one couldn&#8217;t handle:</p><p><strong>Stage 1: Prompt Engineering.</strong> &#8220;If I write the perfect prompt, the model does the right thing.&#8221; Your early demos worked this way. You&#8217;d tweak the prompt, run a few tests, ship it. But prompts don&#8217;t scale. They&#8217;re unmaintainable, untestable, fragile. When new data arrives, they break silently.</p><p><strong>Stage 2: Context Engineering.</strong> &#8220;The model isn&#8217;t the bottleneck what I feed it is.&#8221; You stop optimizing prompts and start optimizing what goes into the model: retrieval, memory, domain knowledge, structured data. This works much better. Except it assumes the model will do the right thing with good context. It won&#8217;t. At least not reliably.</p><p><strong>Stage 3: Harness Engineering.</strong> &#8220;I can&#8217;t trust the model. I need to verify, constrain, route, and retry its output.&#8221; This is where reliability enters. You add validation, structured outputs, fallbacks, and feedback loops around the model&#8217;s decisions. You stop asking &#8220;what&#8217;s the best output?&#8221; and start asking &#8220;what output can I trust?&#8221;</p><p><strong>Stage 4: Loop Engineering.</strong> &#8220;A single model call isn&#8217;t enough. The model needs to perceive, reason, act, and reflect repeatedly.&#8221; This is where autonomy enters. A model generating one response isn&#8217;t an agent. An agent is a system that decides what to do next based on what just happened. Stage 4 is where you build that decision loop, manage its state, and keep it from looping forever or costing $10,000.</p><p>These aren&#8217;t prerequisites. You don&#8217;t finish Stage 1 before starting Stage 2. They&#8217;re cumulative. Every production system today uses pieces from all four. The best systems use all four deliberately.</p><div><hr></div><h2>The Four Failure Patterns</h2><p>When production AI systems fail, they fail in predictable ways:</p><p><strong>Prompt Drift.</strong> You optimize your prompt for the demo. Ship it. It breaks on data it&#8217;s never seen. The model works perfectly on your test cases and fails silently on edge cases. Three weeks in, customers report wrong answers. The fix: context engineeringmove what varies out of the prompt and into version-controlled, retrievable context.</p><p><strong>Context Rot.</strong> You solve prompt drift by fetching context. But context is a budget. Fetch too much and tokens explode, cost explodes, latency explodes. Fetch the wrong thing and the model has good context but outputs garbage anyway. The fix: harness engineering validation, structured outputs, policy enforcement.</p><p><strong>Unconstrained Output.</strong> The output is syntactically valid (correct JSON, right format) and passes basic sanity checks. But the model hallucinates facts, invents data, produces outputs that break downstream systems. Guardrails aren&#8217;t enough. The fix: structured outputs and hard policy enforcement.</p><p><strong>Infinite Loops and Runaway Cost.</strong> Your agent works in the demo. It perceives a task, calls a tool, processes the result, decides what&#8217;s next, repeats. In production it never stops. It calls tools redundantly. It hits rate limits. One request costs $50 instead of $0.50. The fix: loop engineering state management, token budgets, hard stop criteria.</p><p>These look different on the surface. But they all trace back to the same root: <strong>you built something that works once, not something that works every time.</strong></p><div><hr></div><h2>The Lens You&#8217;ll Use: Cost, Quality, Latency</h2><p>Every decision you make building a production AI system involves a trade-off. Add validation? Quality goes up, cost goes up (more API calls), latency goes up. Add caching? Latency goes down, cost goes down, but quality might go down if the cache is stale. Upgrade to a cheaper model? Cost goes down, but quality likely goes down. Use an agent loop? Quality and reliability go way up, cost and latency go way up.</p><p>These trade-offs are not bugs in your system. They&#8217;re features. The engineering is in making them explicit and choosing consciously.</p><p>Throughout this handbook, every design decision is evaluated through three dimensions:</p><ul><li><p><strong>Cost</strong> - API spend, compute, infrastructure, operational overhead</p></li><li><p><strong>Quality</strong> - accuracy, faithfulness to facts, safety, user satisfaction</p></li><li><p><strong>Latency</strong> - time-to-first-token, end-to-end response time, throughput</p></li></ul><p>We call this the <strong>CQL Lens</strong>. You&#8217;ll see it in every article. It&#8217;s not a formula. It&#8217;s a way of asking: &#8220;If I make this choice, what does it cost me in each of these three dimensions? Is that trade-off worth it for what I&#8217;m building?&#8221;</p><p>The production system failed not because the engineering was bad, but because nobody asked: <strong>&#8220;What happens to cost, quality, and latency when this runs on data I didn&#8217;t expect?&#8221;</strong> The demo ran on expected data. Production doesn&#8217;t.</p><div><hr></div><blockquote><p><strong>CQL Lens</strong></p><p><strong>Cost</strong> - Building an AI system costs more than running a model. Validation, retrieval, guardrails, and loops all add latency and compute. But the alternative shipping broken systems costs exponentially more.</p><p><strong>Quality</strong> - A demo is high quality because you picked the inputs. Production is lower quality by definition because the inputs are whatever real users send. Production quality engineering is the discipline of raising that floor.</p><p><strong>Latency</strong> - Optimizing a single model call for speed is easy. Optimizing a multi-step system (retrieval &#8594; model &#8594; validation &#8594; guardrails &#8594; decision) for speed is hard. Every stage you add costs latency. The question is whether the quality gain is worth it.</p></blockquote><h2>Where We Go Next</h2><p>We&#8217;ve introduced the journey from demo to production and the engineering disciplines that make that journey possible.</p><p>In the articles that follow, we&#8217;ll explore each of these ideas in depth&#8212;from designing better context and building reliable AI systems to creating autonomous agents and making informed trade-offs between cost, quality, and latency.</p><p>Because understanding the framework is one thing. Learning how to apply it is what turns demos into production systems.</p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://datajourney24.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DataJourney! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[The Production AI Handbook]]></title><description><![CDATA[Building reliable AI systems- from prompts to production.]]></description><link>https://datajourney24.substack.com/p/the-production-ai-handbook</link><guid isPermaLink="false">https://datajourney24.substack.com/p/the-production-ai-handbook</guid><dc:creator><![CDATA[Pooja Palod]]></dc:creator><pubDate>Sat, 04 Jul 2026 11:07:46 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/d54c90c5-9d84-4ad6-804a-aa96ceafcf58_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Over the last few years, AI has gone through a remarkable evolution.We started by learning how to write better prompts.Then we learned how to retrieve knowledge with RAG.</p><p>Soon after came agents, tools, memory, model routing, evaluation frameworks, observability, and an ever-growing list of production techniques.</p><p>Today, building a successful AI product is no longer about choosing the best model.</p><p>It&#8217;s about engineering the <strong>system around the model</strong>.</p><p>That&#8217;s exactly what this handbook is about.</p><div><hr></div><h2>Why I&#8217;m writing this handbook</h2><p>Most AI content falls into one of two categories.</p><p>The first teaches individual techniques:</p><ul><li><p>Prompt engineering</p></li><li><p>RAG</p></li><li><p>Agents</p></li><li><p>MCP</p></li><li><p>Memory</p></li><li><p>Evaluation</p></li></ul><p>These are valuable, but they&#8217;re often presented in isolation.</p><p>The second focuses on research papers or framework-specific tutorials.</p><p>Those are useful too, but they rarely answer a more fundamental question:</p><blockquote><p><strong>How do all of these pieces fit together to build a production AI system?</strong></p></blockquote><p>This handbook aims to answer that question.</p><p>Rather than treating each topic independently, we&#8217;ll build a complete mental model of modern AI systems and understand how every layer contributes to a reliable production application.</p><div><hr></div><h2>What you&#8217;ll learn</h2><p>Throughout this handbook, we&#8217;ll explore topics such as:</p><ul><li><p>Designing effective context for language models</p></li><li><p>Retrieval-Augmented Generation (RAG)</p></li><li><p>Long-context systems</p></li><li><p>AI memory architectures</p></li><li><p>Tool use and Model Context Protocol (MCP)</p></li><li><p>Agent architectures</p></li><li><p>Harness engineering</p></li><li><p>Loop engineering</p></li><li><p>Model routing and inference optimization</p></li><li><p>Evaluation frameworks</p></li><li><p>LLM-as-a-Judge</p></li><li><p>Guardrails and safety</p></li><li><p>Observability and production operations</p></li><li><p>End-to-end AI system design</p></li></ul><p>More importantly, we&#8217;ll understand <strong>why</strong> each of these exists, what problems they solve, and how they work together in production.</p><div><hr></div><h2>How this handbook is organized</h2><p>The handbook is organized around the lifecycle of a production AI system.</p><p>We&#8217;ll begin by understanding what makes production AI fundamentally different from a simple chatbot.</p><p>From there, we&#8217;ll progressively build the layers that transform a language model into a dependable production system:</p><ul><li><p>Foundations</p></li><li><p>Designing Context</p></li><li><p>Building Autonomous Systems</p></li><li><p>Inference &amp; Optimization</p></li><li><p>Evaluation &amp; Guardrails</p></li><li><p>Observability &amp; Operations</p></li><li><p>End-to-End Production AI System Design</p></li></ul><p>Each section builds on the previous one, so by the end you&#8217;ll have a complete picture of how modern production AI systems are designed and operated.</p><div><hr></div><h2>Who this handbook is for</h2><p>This handbook is written for:</p><ul><li><p>Software Engineers building AI applications</p></li><li><p>Machine Learning Engineers</p></li><li><p>AI Engineers</p></li><li><p>Applied Scientists</p></li><li><p>Technical Architects</p></li><li><p>Anyone preparing for senior AI engineering or system design interviews</p></li></ul><p>A basic understanding of large language models is helpful, but you don&#8217;t need to be an expert.</p><p>We&#8217;ll build from first principles and gradually work toward production-scale systems.</p><div><hr></div><h2>What makes this handbook different</h2><p>This isn&#8217;t a collection of disconnected tutorials.</p><p>It&#8217;s a guided journey through the engineering decisions required to build trustworthy AI systems.</p><p>We&#8217;ll focus on timeless engineering principles rather than short-lived framework details, using current tools and techniques as concrete examples instead of the main story.</p><p>The goal isn&#8217;t just to teach you how today&#8217;s systems work.</p><p>It&#8217;s to help you develop the intuition to design tomorrow&#8217;s systems as the technology continues to evolve.</p><div><hr></div><h2>Let&#8217;s begin</h2><p>The first chapter explores a simple question that turns out to have a surprisingly deep answer:</p><p><strong>Why do AI demos look magical, while production AI systems are so difficult to build?</strong></p><p>That question is where our journey begins.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://datajourney24.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DataJourney! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2></h2>]]></content:encoded></item><item><title><![CDATA[Inference Optimization in LLMs: A Systems View]]></title><description><![CDATA[Most ML engineers think about improving models during training.]]></description><link>https://datajourney24.substack.com/p/inference-optimization-in-llms-a</link><guid isPermaLink="false">https://datajourney24.substack.com/p/inference-optimization-in-llms-a</guid><dc:creator><![CDATA[Pooja Palod]]></dc:creator><pubDate>Sat, 13 Jun 2026 16:57:07 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Sjzq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F374cbcfd-1d5f-4c49-a709-6bd05abe4ba5_520x816.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Most ML engineers think about improving models during training.</p><p>But in production systems, that&#8217;s not where the real cost lives.</p><p>In modern ML workloads especially LLMs- <strong>inference is the dominant bottleneck</strong>. It drives latency, cost, scalability, and user experience. In many real-world systems, <strong>up to 80&#8211;90% of ML cost comes from inference</strong>.</p><p>Yet inference is still often treated as an afterthought.</p><p>This article is a systems-level breakdown of how to think about inference optimization&#8212;not as isolated techniques, but as a layered system problem.</p><div><hr></div><h2>A Mental Model for Inference Optimization</h2><p>I like to think of inference optimization as a stack of four layers:</p><ol><li><p><strong>Model Efficiency</strong> (what you deploy)</p></li><li><p><strong>Attention &amp; Memory Efficiency</strong> (how the model processes tokens)</p></li><li><p><strong>Runtime &amp; Serving Efficiency</strong> (how requests are scheduled)</p></li><li><p><strong>Hardware Utilization</strong> (what runs it)</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!Sjzq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F374cbcfd-1d5f-4c49-a709-6bd05abe4ba5_520x816.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!Sjzq!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F374cbcfd-1d5f-4c49-a709-6bd05abe4ba5_520x816.png 424w, /__u/substackcdn.com/image/fetch/$s_!Sjzq!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F374cbcfd-1d5f-4c49-a709-6bd05abe4ba5_520x816.png 848w, /__u/substackcdn.com/image/fetch/$s_!Sjzq!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F374cbcfd-1d5f-4c49-a709-6bd05abe4ba5_520x816.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Sjzq!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F374cbcfd-1d5f-4c49-a709-6bd05abe4ba5_520x816.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!Sjzq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F374cbcfd-1d5f-4c49-a709-6bd05abe4ba5_520x816.png" width="520" height="816" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/374cbcfd-1d5f-4c49-a709-6bd05abe4ba5_520x816.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:816,&quot;width&quot;:520,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:51098,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://datajourney24.substack.com/i/201891901?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F374cbcfd-1d5f-4c49-a709-6bd05abe4ba5_520x816.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!Sjzq!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F374cbcfd-1d5f-4c49-a709-6bd05abe4ba5_520x816.png 424w, /__u/substackcdn.com/image/fetch/$s_!Sjzq!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F374cbcfd-1d5f-4c49-a709-6bd05abe4ba5_520x816.png 848w, /__u/substackcdn.com/image/fetch/$s_!Sjzq!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F374cbcfd-1d5f-4c49-a709-6bd05abe4ba5_520x816.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Sjzq!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F374cbcfd-1d5f-4c49-a709-6bd05abe4ba5_520x816.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>Each layer targets a different bottleneck: compute, memory, latency, or throughput.</p><p><strong>Optimizing only one layer is not enough in production systems.</strong></p><div><hr></div><h2>Why Inference Becomes the Bottleneck</h2><p>Before optimization, it&#8217;s important to understand what we&#8217;re fighting.</p><h3>1. Compute Cost</h3><p>Large models require billions of operations per request.</p><h3>2. Memory Bandwidth (often the real bottleneck)</h3><p>For LLMs, moving data (weights + KV cache) is often more expensive than computation itself.</p><h3>3. Memory Footprint</h3><p>Model weights + intermediate activations + KV cache quickly exhaust GPU memory.</p><h3>4. I/O and Serving Overhead</h3><p>Request routing, batching, and networking add non-trivial overhead at scale.</p><div><hr></div><h2>Model-Level Optimizations: Make the Model Cheaper</h2><p>This layer focuses on reducing computation and memory <em>before inference even starts</em>.</p><h3>Quantization</h3><p>Reduce numerical precision (FP32 &#8594; FP16 / INT8 / INT4).</p><p><strong>Why it works:</strong></p><ul><li><p>Less memory usage</p></li><li><p>Faster computation</p></li><li><p>Lower bandwidth pressure</p></li></ul><p><strong>Tradeoff:</strong> Accuracy vs speed/size</p><p><strong>Key approaches:</strong></p><ul><li><p><strong>Post-training quantization (PTQ):</strong> fast, may lose accuracy</p></li><li><p><strong>Quantization-aware training (QAT):</strong> better accuracy, more complex</p></li></ul><h3>Pruning</h3><p>Remove redundant weights or connections.</p><ul><li><p><strong>Unstructured pruning:</strong> sparse weights (hard to accelerate)</p></li><li><p><strong>Structured pruning:</strong> removes full channels/layers (hardware friendly)</p></li></ul><p>Pipeline: Train &#8594; Prune &#8594; Fine-tune</p><h3>Knowledge Distillation</h3><p>Train a smaller model (student) to mimic a larger one (teacher).</p><p>This is one of the most practical techniques for production deployment:</p><ul><li><p>Smaller model</p></li><li><p>Faster inference</p></li><li><p>Near-teacher quality</p></li></ul><h3>Efficient Architectures</h3><p>Instead of optimizing later, design for efficiency upfront:</p><ul><li><p>MobileNet / EfficientNet (CNNs)</p></li><li><p>Sparse or linear attention transformers</p></li></ul><div><hr></div><h2>The Autoregressive Bottleneck</h2><p>LLMs generate tokens one at a time.</p><p>This makes inference inherently sequential:</p><blockquote><p>Token&#8321; &#8594; Token&#8322; &#8594; Token&#8323; &#8594; ...</p></blockquote><p>This limits parallelism and becomes a major latency bottleneck.</p><h3>Speculative Decoding</h3><p>A small &#8220;draft model&#8221; proposes multiple tokens. A larger &#8220;verifier model&#8221; checks them in parallel.</p><p><strong>Why it helps:</strong> Reduces number of expensive forward passes.</p><p><strong>Tradeoff:</strong> Extra computation from draft model.</p><h3>Medusa / Tree-based Decoding</h3><p>Instead of one linear guess:</p><ul><li><p>Generate multiple candidate token paths</p></li><li><p>Verify in parallel</p></li></ul><p>Higher acceptance rate &#8594; better speedups.</p><h3>Parallel Decoding Strategies</h3><p>These methods aim to break strict token-by-token generation:</p><ul><li><p>Speculative decoding (linear)</p></li><li><p>Tree-based decoding (branching)</p></li></ul><p><strong>The core idea:</strong> Trade extra compute for fewer sequential steps.</p><div><hr></div><h2>Attention &amp; KV Cache: The Hidden Bottleneck</h2><p>Attention is where many real-world systems break.</p><h3>Why Attention is Expensive</h3><p>Self-attention has O(L&#178;) complexity, where L = sequence length.</p><p>This leads to:</p><ul><li><p>High compute cost</p></li><li><p>Large memory usage</p></li><li><p>Poor scaling for long context</p></li></ul><h3>The KV Cache Problem</h3><p>During decoding:</p><ul><li><p>Keys and Values for all previous tokens are stored</p></li><li><p>This grows linearly with sequence length</p></li></ul><p><strong>But in practice:</strong> KV cache becomes a GPU memory bottleneck, not model weights.</p><h3>Attention Optimizations</h3><p><strong>Sparse Attention</strong></p><p>Only attend to selected tokens (local windows, global tokens, strided patterns).</p><p>Tradeoff: Global context vs efficiency.</p><p><strong>Linear Attention</strong></p><p>Reformulate attention to avoid O(L&#178;), achieving O(L) complexity (may lose expressiveness).</p><p><strong>Multi-Query / Grouped-Query Attention</strong></p><p>Instead of separate K/V heads, share K/V across query heads.</p><p><strong>Impact:</strong> Massive reduction in KV cache size. This directly improves:</p><ul><li><p>Memory usage</p></li><li><p>Batching capacity</p></li><li><p>Throughput</p></li></ul><p><strong>PagedAttention (vLLM-style systems)</strong></p><p>Treat KV cache like virtual memory pages.</p><p>Benefits:</p><ul><li><p>Eliminates fragmentation</p></li><li><p>Improves GPU utilization</p></li><li><p>Enables large-scale batching</p></li></ul><div><hr></div><h2>Hardware-Level Optimization</h2><p>Inference performance is ultimately bounded by hardware.</p><h3>Compute Units</h3><ul><li><p><strong>GPU:</strong> best general-purpose inference engine</p></li><li><p><strong>TPU:</strong> optimized matrix operations</p></li><li><p><strong>NPU:</strong> edge inference</p></li><li><p><strong>ASICs:</strong> highest efficiency, lowest flexibility</p></li></ul><h3>Key Insight</h3><p>Modern inference systems are <strong>memory-bandwidth constrained, not compute constrained</strong>.</p><p>So hardware optimization focuses on:</p><ul><li><p>Memory access speed</p></li><li><p>Data locality</p></li><li><p>Low-precision support</p></li></ul><div><hr></div><h2>Runtime &amp; Serving Optimizations</h2><p>Even a perfect model can fail in a bad serving system.</p><h3>Batching Strategies</h3><p><strong>Static batching:</strong> Fixed batch size &#8594; inefficient under variable load</p><p><strong>Dynamic batching:</strong> Group requests on the fly</p><p><strong>Continuous batching (critical for LLMs):</strong></p><ul><li><p>Processes requests as streams</p></li><li><p>Improves GPU utilization significantly</p></li><li><p>Avoids idle time</p></li></ul><h3>Prefill vs Decode Separation</h3><p>Split inference into:</p><ul><li><p><strong>Prefill:</strong> process prompt</p></li><li><p><strong>Decode:</strong> generate tokens step-by-step</p></li></ul><p>This enables:</p><ul><li><p>Separate scheduling</p></li><li><p>Better batching strategies</p></li><li><p>Optimized hardware usage</p></li></ul><h3>Prompt Caching</h3><p>Cache repeated computations:</p><ul><li><p>Embeddings</p></li><li><p>KV cache for common prefixes</p></li></ul><h3>Parallelism Strategies</h3><ul><li><p><strong>Data Parallelism (Replica-based):</strong> Multiple copies of the model</p></li><li><p><strong>Tensor Parallelism:</strong> Split matrix operations across GPUs</p></li><li><p><strong>Pipeline Parallelism:</strong> Split layers across devices</p></li><li><p><strong>Context Parallelism:</strong> Split long sequences across devices</p></li><li><p><strong>Expert Parallelism (MoE):</strong> Activate only subset of experts per input</p></li></ul><div><hr></div><h2>Compiler &amp; Runtime Optimizations</h2><p>This is where ML meets systems engineering.</p><h3>Graph Optimization</h3><ul><li><p>Fuse ops</p></li><li><p>Remove redundancy</p></li><li><p>Reorder computation</p></li></ul><h3>Kernel Fusion</h3><p>Combine multiple GPU operations into one kernel.</p><p>Reduces:</p><ul><li><p>Kernel launch overhead</p></li><li><p>Memory movement</p></li></ul><h3>Memory Optimization</h3><p>Efficient memory layout and reuse strategies.</p><h3>Automatic Precision Conversion</h3><p>Dynamic FP32 &#8594; FP16 conversion based on hardware capability.</p><div><hr></div><h2>Key Performance Metrics</h2><p>Inference optimization is measured by:</p><p><strong>Latency</strong></p><ul><li><p>Time to First Token (TTFT)</p></li><li><p>Time Per Output Token (TPOT)</p></li></ul><p><strong>Throughput</strong></p><ul><li><p>Tokens/sec or requests/sec</p></li></ul><p><strong>Resource Utilization</strong></p><ul><li><p>GPU / memory efficiency</p></li></ul><p><strong>Cost</strong></p><ul><li><p>Cost per token or per request</p></li></ul><div><hr></div><h2>Closing Thought</h2><p>Inference optimization is not a single technique. It is a <strong>systems problem spanning model design, memory management, scheduling, and hardware utilization</strong>.</p><p>The real shift in thinking is this:</p><blockquote><p>You are no longer optimizing models. You are optimizing systems that serve models.</p></blockquote><div><hr></div><h2>What&#8217;s Next</h2><p>This post is the foundation. In follow-ups, we&#8217;ll go deep:</p><ul><li><p><strong>Quantization in practice:</strong> Which techniques work for which model families</p></li><li><p><strong>Attention mechanics:</strong> Why KV cache dominates, and the tradeoffs of each optimization</p></li><li><p><strong>Serving patterns:</strong> Building inference systems that scale</p></li><li><p><strong>Cost modeling:</strong> How to actually measure what&#8217;s eating your budget</p></li></ul><p>Let me know what you want to explore first.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://datajourney24.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DataJourney! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[Agentic System Design Interview Series #1: Design a Coding Agent]]></title><description><![CDATA[Introduction]]></description><link>https://datajourney24.substack.com/p/agentic-system-design-interview-series</link><guid isPermaLink="false">https://datajourney24.substack.com/p/agentic-system-design-interview-series</guid><dc:creator><![CDATA[Pooja Palod]]></dc:creator><pubDate>Thu, 11 Jun 2026 17:40:44 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!HHCr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3637d752-8d42-4748-ad91-b1d68730d358_1322x1242.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Introduction</h2><p>Over the last decade, System Design interviews have evolved significantly.</p><p>The first wave focused on distributed systems: designing high-throughput, fault-tolerant services like ride-sharing platforms, messaging systems, and video streaming architectures. The second wave introduced ML System Design, where engineers were expected to reason about data pipelines, feature stores, model training infrastructure, online serving systems, and experimentation frameworks.</p><p>Today, we are entering a <strong>third wave</strong>.</p><p>Organizations are increasingly building systems that can reason, plan, use tools, maintain memory, and iteratively execute tasks. These systems don&#8217;t simply generate static text outputs-they take autonomous actions in real development environments. This has given rise to a new category of engineering problems: <strong>Agentic System Design</strong>.</p><p>Unlike traditional software systems, agentic systems operate through tight feedback loops. They observe their environment, execute actions, evaluate outcomes, and dynamically adapt their behavior.</p><p>In this article, we&#8217;ll explore one of the most prominent examples of this new paradigm: <strong>Designing an Autonomous Coding Agent</strong>. We will approach it exactly how you should in a senior-level system design interview-starting with the core mental shifts, mapping requirements, breaking down the high-level architecture, and tackling deep production trade-offs.</p><h2>How to Approach This Problem</h2><p>When an interviewer asks you to <em>&#8220;Design a Coding Agent,&#8221;</em> they are not asking you to build a wrapper around an LLM chat endpoint. They want to see if you can engineer a stable, deterministic framework around a fundamentally non-deterministic core.</p><p>Before diving into boxes and arrows, explicitly establish the <strong>four pillars</strong> that separate agentic designs from traditional software engineering:</p><ul><li><p>Loops over Pipelines: Traditional systems follow a predictable Request&#8594; Response flow. Agentic systems operate in an execution loop: Task &#8594;Plan &#8594;Act &#8594; Observe &#8594;Adapt &#8594;Retry</p></li><li><p><strong>Active Tool Utilization:</strong> The agent is given leverage over its environment. It interacts with the outside world via structured APIs to read files, run test suites, execute shell builds, and manage git repositories.</p></li><li><p><strong>Non-Deterministic Outputs:</strong> The same exact prompt can yield varied code paths. Because of this, code cannot be blindly trusted; it must be programmatically verified.</p></li><li><p><strong>Silent Failure Modes:</strong> A semantic error or retrieval mistake can generate code that compiles flawlessly but solves entirely the wrong problem. Observability and automated evaluation are core architectural requirements, not afterthoughts.</p></li></ul><h3>Clarifying Questions to Narrow Scope</h3><p>A strong candidate establishes the guardrails before designing. In an interview, explicitly call out these scoping vectors:</p><ol><li><p><strong>Scope of edits:</strong> Are we supporting single-file bug fixes or massive multi-file refactoring across a repository?</p></li><li><p><strong>Autonomy level:</strong> Is this fully autonomous or human-in-the-loop for every key decision?</p></li><li><p><strong>Scale &amp; Repository Size:</strong> Are we targeting small standalone microservices or a massive codebase?</p></li><li><p><strong>Environment Constraints:</strong> What languages, build tools, and security boundaries are enforced?</p></li></ol><h2>High-Level Architecture</h2><p>A common interview pitfall is drawing a linear pipeline. A production-grade coding agent must be structured as a state machine where verification results continuously feed back into the execution layer.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!HHCr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3637d752-8d42-4748-ad91-b1d68730d358_1322x1242.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!HHCr!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3637d752-8d42-4748-ad91-b1d68730d358_1322x1242.png 424w, /__u/substackcdn.com/image/fetch/$s_!HHCr!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3637d752-8d42-4748-ad91-b1d68730d358_1322x1242.png 848w, /__u/substackcdn.com/image/fetch/$s_!HHCr!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3637d752-8d42-4748-ad91-b1d68730d358_1322x1242.png 1272w, /__u/substackcdn.com/image/fetch/$s_!HHCr!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3637d752-8d42-4748-ad91-b1d68730d358_1322x1242.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!HHCr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3637d752-8d42-4748-ad91-b1d68730d358_1322x1242.png" width="1322" height="1242" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3637d752-8d42-4748-ad91-b1d68730d358_1322x1242.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1242,&quot;width&quot;:1322,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:163608,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://datajourney24.substack.com/i/201632244?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3637d752-8d42-4748-ad91-b1d68730d358_1322x1242.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!HHCr!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3637d752-8d42-4748-ad91-b1d68730d358_1322x1242.png 424w, /__u/substackcdn.com/image/fetch/$s_!HHCr!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3637d752-8d42-4748-ad91-b1d68730d358_1322x1242.png 848w, /__u/substackcdn.com/image/fetch/$s_!HHCr!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3637d752-8d42-4748-ad91-b1d68730d358_1322x1242.png 1272w, /__u/substackcdn.com/image/fetch/$s_!HHCr!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3637d752-8d42-4748-ad91-b1d68730d358_1322x1242.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>Walkthrough: &#8220;Add a &#8216;Remember Me&#8217; Feature&#8221;</h2><p>To visualize how these abstract components interact, let&#8217;s trace a straightforward feature request through the entire system architecture.</p><h3>The Objective</h3><ul><li><p><strong>User Input:</strong> <em>&#8220;Update the login function to support a &#8216;Remember Me&#8217; checkbox. If checked, extend the session cookie expiration to 30 days instead of the default 24 hours.&#8221;</em></p></li><li><p><strong>Target Stack:</strong> A standard Node.js/Express authentication service.</p></li></ul><h3>1. The Planning Phase</h3><p>The Task Planner breaks down the user request into explicit, manageable engineering steps.</p><pre><code><code>[Generated Plan]
Step 1: Locate the file handling user login and session cookie creation.
Step 2: Parse the new `rememberMe` flag from the incoming request body.
Step 3: Modify the cookie configuration logic to apply the conditional 30-day expiration.
Step 4: Run the authentication unit tests to verify the changes.
</code></code></pre><h3>2. The Context &amp; Retrieval Loop</h3><p>Instead of reading the whole codebase, the agent queries the <strong>Repository Understanding Layer</strong>:</p><ul><li><p><em>Lexical Search</em> looks for strings like <code>res.cookie(</code> or <code>loginController</code>.</p></li><li><p><em>Semantic Search</em> searches for &#8220;session expiration&#8221; or &#8220;auth cookies&#8221;.</p></li></ul><p>The system returns two highly specific files: <code>src/controllers/authController.js</code> and <code>src/tests/auth.test.js</code>.</p><h3>3. Execution &amp; Tool Interaction</h3><p>The <strong>Execution Agent</strong> picks up the first steps of the plan and uses its toolset inside an isolated sandbox.</p><p><strong>1.Environment Probe:</strong>Tool: Read File.</p><p>The agent reads <code>src/controllers/authController.js</code> to see how cookies are currently issued. It finds a standard line: </p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;474223b9-c81a-4f1e-8b65-585fd3ff5d45&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">res.cookie('session_token', token, { maxAge: 86400000 }); (24 hours).</code></pre></div><p><strong>2.Code Modification:</strong>Tool: Write File.</p><p>The agent updates the file to extract <code>rememberMe</code> from <code>req.body</code> and modifies the code to:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;1c279886-701e-4085-9bf6-96b8b00f3795&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">const duration = req.body.rememberMe ? (30 * 24 * 60 * 60 * 1000) : 86400000;</code></pre></div><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;1c279886-701e-4085-9bf6-96b8b00f3795&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">res.cookie('session_token', token, { maxAge: duration });</code></pre></div><h3>4. The Verification &amp; Adaptation Loop</h3><p>The agent passes control to the <strong>Verification Layer</strong> to run the local test suite.</p><pre><code><code>[Verification Log]
Running: npm test
Result: FAILURE
Error: "ReferenceError: rememberMe is not defined at login (src/controllers/authController.js:12:3)"
</code></code></pre><p>The system captures this <strong>structured error output</strong>.</p><p>The agent looks at its own edit and realizes it made a classic copy-paste error: it used <code>rememberMe</code> directly in its conditional statement instead of pulling it out of the request body object (<code>req.body.rememberMe</code>) first.</p><p>Because this is an agentic loop, it doesn&#8217;t give up. It <strong>adapts</strong> its plan, rewrites the file with the missing destructuring statement (<code>const { rememberMe } = req.body;</code>), and reruns the tests. This time, the linter and test suite return a clean <code>SUCCESS</code>.</p><h3>5. Human-in-the-Loop Review</h3><p>The system bundles the entire run into a pull request for an engineer to inspect.</p><pre><code><code>+------------------------------------------------------------+
| Pull Request: Add Remember Me support to login             |
+------------------------------------------------------------+
| [Task Intent]: Extend session cookie to 30 days if checked  |
|                                                            |
| [Execution Trace]:                                         |
|  - Read 1 file, modified 1 file                            |
|  - Fixed 1 ReferenceError during verification automatically|
|                                                            |
| [Verification Status]:                                     |
|  - Linter: PASSED                                          |
|  - Unit Tests: 5/5 PASSED                                  |
|                                                            |
| [Diff View]:                                               |
|  + const { username, password, rememberMe } = req.body;    |
|  + const maxAge = rememberMe ? 2592000000 : 86400000;      |
+------------------------------------------------------------+
</code></code></pre><h2>Deep-Dive: Core Components &amp; Deep Trade-Offs</h2><h3>1. Repository Understanding Layer</h3><p>To prevent context-window overflow and keep token costs manageable, the repository layer must index codebases hierarchically. To do this reliably at scale, a production system relies on four core indexing strategies:</p><ul><li><p><strong>Lexical Search:</strong> Best for finding exact symbol matches, specific configuration keys, or hardcoded variables. This is traditionally implemented using Elasticsearch or BM25 text indexing over precise code tokens.</p></li><li><p><strong>Semantic Search:</strong> Essential for resolving high-level user intent when the exact structural keywords aren&#8217;t known (e.g., searching for &#8220;session expiration logic&#8221;). This relies on generating dense vector embeddings of individual code chunks.</p></li><li><p><strong>Dependency Graphs:</strong> Crucial for tracking code relationships and mapping out the downstream blast-radius of a refactor. It maps imports and class inheritances, usually using a graph database.</p></li><li><p><strong>Symbol Trees:</strong> Provides lightning-fast jumps directly to function definitions, callers, and callees by parsing the abstract syntax tree of the code via Tree-sitter or Language Server Protocol (LSP) integrations.</p></li></ul><blockquote><p><strong>Trade-Off to Highlight:</strong> <em>Hybrid vs. Pure Vector Retrieval.</em> Pure vector semantic search often washes out distinct structural syntax (like specific variable definitions or configuration keys). A production system <em>must</em> implement hybrid search (BM25 + Dense Vectors) cross-referenced with an LSP graph to guarantee the agent actually follows the correct reference tracks.</p></blockquote><h3>2. Tool &amp; Sandboxing Layer</h3><p>An agent must never execute arbitrary code directly on your host infrastructure. The tool layer must enforce structured inputs and outputs while running inside a hardened sandbox.</p><ul><li><p><strong>Isolation Guardrails:</strong> All test executions, builds, and file system mutations happen within disposable environments like <strong>Docker containers</strong> or <strong>Firecracker MicroVMs</strong> with strict network and CPU limits.</p></li><li><p><strong>Structured Outputs:</strong> System tools should never return raw, unstructured terminal streams. If a build fails, the tool should parse the output and return a clean JSON payload detailing the exact failure filename, line number, and stack trace category. This allows the LLM to target its fixes with high precision.</p></li></ul><h3>3. Dual-Tiered Memory Architecture</h3><ul><li><p><strong>Short-Term Memory (In-Context):</strong> Tracks the live execution state machine. It contains the current active steps, the code diffs generated during <em>this session</em>, and recent terminal errors.</p></li><li><p><strong>Long-Term Memory (Vector/Key-Value Store):</strong> Cross-session knowledge. It stores organizational code conventions, historical PR reviews where code was corrected by a human, and successful past patterns for similar tasks.</p></li></ul><h2>Operational Excellence: The Evaluation Framework</h2><p>You cannot scale what you cannot measure. Evaluating an agentic system on final output code alone is a lagging indicator. You must track the efficiency of the <em>journey</em> through the agent loop.</p><pre><code><code>                           Evaluation Metrics
                                   &#9474;
         &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9532;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
         &#9660;                         &#9660;                         &#9660;
  [Task Success Rate]       [Loop Efficiency]         [Economic Cost]
  &#8226; Build success %         &#8226; Retry count per task    &#8226; Tokens consumed per PR
  &#8226; Unit test pass %        &#8226; Time-to-completion      &#8226; Infrastructure costs
  &#8226; Human acceptance %      &#8226; Pattern stagnation      &#8226; Model routing efficiency
</code></code></pre><ul><li><p><strong>Task Success Rate:</strong> What percentage of generated code passes syntax validation, builds cleanly, passes local unit tests, and is ultimately accepted by a human reviewer without massive rewrites?</p></li><li><p><strong>Loop Efficiency (Crucial Metric):</strong> How many retries did it take to succeed? A task that completes successfully after <strong>2 iterations</strong> is highly reliable. A task that takes <strong>19 iterations</strong> is experiencing <em>stochastic drift</em> and is on the verge of entering an infinite loop.</p></li><li><p><strong>Cost and Latency Profiles:</strong> Tracking token-consumption density per successful task to prevent the agent from burning out the API budget on massive, cyclic contexts.</p></li></ul><h2>Structural Failures &amp; Defensive Design</h2><ul><li><p><strong>Infinite Retry Loops:</strong> The agent tries to fix a compilation bug, introduces a secondary error, tries to fix that, and ends up oscillating between two incorrect states.</p><ul><li><p><em>Mitigation:</em> Implement strict <strong>Execution Budgets</strong> (e.g., max 5 loops or max $2.00 token cost per sub-task) and auto-escalate to a human operator when budgets are breached.</p></li></ul></li><li><p><strong>Context Window Bleed:</strong> As the agent interacts with tools and runs multiple test suites, the short-term conversation context grows exponentially, causing the model to lose track of the core goal.</p><ul><li><p><em>Mitigation:</em> Apply aggressive <strong>context compaction and summary layers</strong>. Compress raw terminal logs into structured diagnostic summaries before piping them back to the planning model.</p></li></ul></li><li><p><strong>Unsafe Code &amp; Security Anomalies:</strong> The agent imports third-party dependencies with security vulnerabilities or inadvertently writes code containing SQL injections or hardcoded credentials.</p><ul><li><p><em>Mitigation:</em> Treat the agent as an unverified external vendor. The Verification Layer must contain strict security gates (e.g., running Static Application Security Testing (SAST) tools like Semgrep or SonarQube) <em>before</em> triggering human review.</p></li></ul></li></ul><h2>Architectural Differentiator: Standard vs. Senior/Staff Design</h2><p>In a System Design interview, your seniority tier is judged entirely by where you focus your depth. A standard candidate focuses heavily on the intelligence of the LLM itself. A Senior or Staff-level candidate focuses on engineering a stable framework around a non-deterministic core.</p><pre><code><code>+-------------------------------------------------------------------------+
| Standard Candidate Focus                                                |
| - Building a basic request-response loop (Prompt -&gt; Code Output).       |
| - Expecting the model to magically hold the entire repo in context.      |
| - Treating verification as a simple "pass/fail" script.                 |
+-------------------------------------------------------------------------+
                                   &#9650;
                                   &#9474;  The Engineering Gap
                                   &#9660;
+-------------------------------------------------------------------------+
| Senior / Staff Candidate Focus                                          |
| - Stateful, multi-step planning with dynamic adaptation loops.          |
| - Hierarchical retrieval (LSP graphs + hybrid vector search).           |
| - Isolated sandbox execution (Firecracker/Docker) with telemetry.       |
| - Enterprise metrics: Token budgets, retry limits, and model routing.   |
+-------------------------------------------------------------------------+
</code></code></pre><p>A <strong>Senior or Staff Engineer</strong> spends less time talking about the LLM&#8217;s raw capabilities and significantly more time discussing the <strong>infrastructure surrounding it</strong> how to safely isolate execution environments, optimize token spend by routing minor tasks to smaller models, and handle architectural failures like infinite loops and state stagnation.</p><h2>Summary</h2><p>Designing a coding agent is an exercise in building deterministic scaffolding around a non-deterministic processing engine. By treating the agent loop as an explicit state machine complete with hybrid retrieval, structured tool outputs, automated verification gates, and hard economic/execution budgets you can build an agentic system that safely, predictably, and effectively scales human capabilities.</p><p>The next frontier of system design isn&#8217;t just about handling traffic spikes or structuring tables; it&#8217;s about architecting systems that can think, execute, and heal themselves in production.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://datajourney24.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DataJourney! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[From TDD to EDD: How engineering paradigms evolved in the age of AI ]]></title><description><![CDATA[I&#8217;ve been thinking about this for a while, and I think we&#8217;re in the middle of a shift that most teams haven&#8217;t fully internalized yet.]]></description><link>https://datajourney24.substack.com/p/from-tdd-to-edd-how-engineering-paradigms</link><guid isPermaLink="false">https://datajourney24.substack.com/p/from-tdd-to-edd-how-engineering-paradigms</guid><dc:creator><![CDATA[Pooja Palod]]></dc:creator><pubDate>Sat, 06 Jun 2026 07:09:51 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!hdB5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a8b300a-3806-469d-b298-8be9a4956512_1336x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I&#8217;ve been thinking about this for a while, and I think we&#8217;re in the middle of a shift that most teams haven&#8217;t fully internalized yet.</p><p>Not a hype cycle shift. A genuine change in how we need to think about building software.</p><p>Every generation of software forced engineers to rethink their approach from scratch. And each time, the old paradigm didn&#8217;t die because it was wrong it died because the problem changed underneath it.</p><p>Here&#8217;s how we got here.</p><div><hr></div><h2>The deterministic era: TDD made sense because software was simple</h2><p>For most of software history, systems did exactly what you told them to do. You encoded logic. Logic ran. Output was predictable.</p><pre><code><code>if balance &lt; withdrawal_amount:
    reject_transaction()
else:
    process_transaction()
</code></code></pre><p>The engineering challenge was basically: how do we make sure the code does what it&#8217;s supposed to?</p><p>Enter Test-Driven Development. Write a failing test. Implement. Make it pass. Refactor. Tests became executable specs. The system either passed or failed  no gray area.</p><p>TDD worked because there was always a correct answer. You could write it down before you wrote the code.</p><p>That held for a long time. Until ML broke the assumption entirely.</p><div><hr></div><h2>Machine learning flipped the model</h2><p>ML didn&#8217;t just add complexity to software it inverted the whole relationship.</p><p>Traditional software: <strong>Rules + Data &#8594; Output</strong></p><p>Machine Learning: <strong>Data + Output &#8594; Learned Rules</strong></p><p>Behavior stopped being something you explicitly defined. It emerged from data. Which meant you couldn&#8217;t reason your way to the right answer anymore  you had to run experiments and measure what happened.</p><p>The dominant workflow became <strong>hypothesis &#8594; experiment &#8594; measure &#8594; iterate. </strong>The best idea wasn&#8217;t the most elegant one. It was the one that moved the metric.</p><p>MLOps came out of that culture - experiment tracking, model versioning, deployment automation, retraining pipelines. Good infrastructure for a world where you&#8217;re running dozens of experiments and need to know which one actually worked.</p><p>But here&#8217;s the thing MLOps still assumed: that quality could be captured in a number. Accuracy. Precision. F1. AUC.</p><p>That assumption survived until Generative AI showed up.</p><div><hr></div><h2>GenAI broke the metrics</h2><p>LLMs aren&#8217;t prediction systems. They&#8217;re behavior-generating systems. And that&#8217;s a fundamentally different problem.</p><p>Think about what it means to test a summarization system. What&#8217;s the expected output? There&#8217;s no single right answer  there are hundreds of acceptable summaries. You can&#8217;t write a unit test for that. There&#8217;s no assert statement that covers it.</p><p>Or think about a customer support bot. What does &#8220;working correctly&#8221; even mean?</p><p>Is it correct answers? Probably. But what about tone  is it matching your brand? Is it being appropriately cautious about things it&#8217;s not sure about? Is it grounding its answers in your actual documentation or making stuff up? Did the user actually get their problem solved, or did they just get a confident-sounding response?</p><p>Behavior exists on a spectrum. Pass/fail testing doesn&#8217;t work. Predictive accuracy doesn&#8217;t cover it. And a &#8220;it looks good to me&#8221; gut check definitely isn&#8217;t enough before you ship.</p><p>That&#8217;s the gap EDD fills.</p><div><hr></div><h2>What Evaluation-Driven Development actually is</h2><p>The core idea is pretty simple: every system change should be validated through systematic evaluations before you ship it.</p><p>Instead of &#8220;does the output match exactly?&#8221;, you&#8217;re asking &#8220;did behavior improve across everything I care about?&#8221;</p><p>The loop looks like this  and I mean a real loop, not a one-time thing:</p><p>Make a change (prompt, model, retrieval strategy, chunking, whatever). Run your eval suite against a pinned baseline. Compare across behavioral dimensions. Ship if it improved, revert if it regressed, investigate if results are mixed.</p><p>That&#8217;s it. The discipline is in not skipping it. Especially when manual testing looks fine.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!hdB5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a8b300a-3806-469d-b298-8be9a4956512_1336x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!hdB5!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a8b300a-3806-469d-b298-8be9a4956512_1336x1024.png 424w, /__u/substackcdn.com/image/fetch/$s_!hdB5!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a8b300a-3806-469d-b298-8be9a4956512_1336x1024.png 848w, /__u/substackcdn.com/image/fetch/$s_!hdB5!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a8b300a-3806-469d-b298-8be9a4956512_1336x1024.png 1272w, /__u/substackcdn.com/image/fetch/$s_!hdB5!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a8b300a-3806-469d-b298-8be9a4956512_1336x1024.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!hdB5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a8b300a-3806-469d-b298-8be9a4956512_1336x1024.png" width="1336" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6a8b300a-3806-469d-b298-8be9a4956512_1336x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1336,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:120369,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://datajourney24.substack.com/i/200860076?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a8b300a-3806-469d-b298-8be9a4956512_1336x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!hdB5!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a8b300a-3806-469d-b298-8be9a4956512_1336x1024.png 424w, /__u/substackcdn.com/image/fetch/$s_!hdB5!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a8b300a-3806-469d-b298-8be9a4956512_1336x1024.png 848w, /__u/substackcdn.com/image/fetch/$s_!hdB5!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a8b300a-3806-469d-b298-8be9a4956512_1336x1024.png 1272w, /__u/substackcdn.com/image/fetch/$s_!hdB5!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a8b300a-3806-469d-b298-8be9a4956512_1336x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>Why this matters in practice - a real example</h2><p>You&#8217;re working on a RAG system. You decide to increase retrieval depth from top-3 to top-10 documents. Intuition is sound  more context should mean better answers.</p><p>You run a few manual tests. Responses look richer, more comprehensive. Feels like an improvement.</p><p>Most teams ship it here.</p><p>Your eval suite tells a different story:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!nMxV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F547cbb61-13de-45ed-80e7-c1e285559937_1330x574.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!nMxV!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F547cbb61-13de-45ed-80e7-c1e285559937_1330x574.png 424w, /__u/substackcdn.com/image/fetch/$s_!nMxV!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F547cbb61-13de-45ed-80e7-c1e285559937_1330x574.png 848w, /__u/substackcdn.com/image/fetch/$s_!nMxV!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F547cbb61-13de-45ed-80e7-c1e285559937_1330x574.png 1272w, /__u/substackcdn.com/image/fetch/$s_!nMxV!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F547cbb61-13de-45ed-80e7-c1e285559937_1330x574.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!nMxV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F547cbb61-13de-45ed-80e7-c1e285559937_1330x574.png" width="1330" height="574" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/547cbb61-13de-45ed-80e7-c1e285559937_1330x574.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:574,&quot;width&quot;:1330,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:88635,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://datajourney24.substack.com/i/200860076?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F547cbb61-13de-45ed-80e7-c1e285559937_1330x574.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!nMxV!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F547cbb61-13de-45ed-80e7-c1e285559937_1330x574.png 424w, /__u/substackcdn.com/image/fetch/$s_!nMxV!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F547cbb61-13de-45ed-80e7-c1e285559937_1330x574.png 848w, /__u/substackcdn.com/image/fetch/$s_!nMxV!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F547cbb61-13de-45ed-80e7-c1e285559937_1330x574.png 1272w, /__u/substackcdn.com/image/fetch/$s_!nMxV!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F547cbb61-13de-45ed-80e7-c1e285559937_1330x574.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>One metric improved. Three got worse. Hallucination rate doubled.</p><p>The change that looked great across five examples was quietly wrecking quality at scale. This is exactly the class of regression that manual testing will never catch &#8212; because you&#8217;ll naturally pick examples where the extra context helps, not the cases where it introduces noise.</p><div><hr></div><h2>What you&#8217;re actually measuring</h2><p>The dimensions that matter in a GenAI eval framework aren&#8217;t arbitrary. Each one corresponds to a real failure mode.</p><p><strong>Correctness</strong> - Is the answer factually right? You need reference answers plus LLM-as-judge, or deterministic checks if ground truth exists.</p><p><strong>Faithfulness</strong> - Is the response grounded in retrieved context, or is the model going off-script? This is different from correctness  a model can be factually right but pulling from its parametric memory instead of your docs.</p><p><strong>Hallucination rate</strong> - Is it inventing things? Genuinely one of the harder things to measure well. Needs careful LLM-as-judge prompting; don&#8217;t just trust the default.</p><p><strong>Retrieval quality</strong> - Did the pipeline pull the right documents in the first place? Everything downstream depends on this. Measure precision/recall against labeled relevant chunks.</p><p><strong>Tool call accuracy</strong> - For agents: right tool, right parameters? This one is actually deterministic if you have expected call logs, so use it.</p><p><strong>Task completion</strong> - Did the user accomplish what they came to do? Hardest to measure but most important. Either human labels or a well-designed LLM evaluator.</p><p><strong>Safety and policy compliance</strong> - Did it stay within guardrails? Combination of rule-based checks and classifier models.</p><p>You don&#8217;t need all of these on day one. Pick the two or three that map to your system&#8217;s actual failure modes. Build from there.</p><div><hr></div><h2>The ways teams get this wrong</h2><p>I&#8217;ve seen a few patterns that come up repeatedly.</p><p><strong>Vibes-only testing.</strong> &#8220;I ran it on 10 examples and it looks better&#8221; is a gut check, not an evaluation. Useful for developing intuition. Not sufficient for shipping decisions.</p><p><strong>Single-metric optimization.</strong> You tune for answer quality, latency quietly climbs 40%, hallucination creeps up. Optimizing one dimension in isolation creates systems that demo well and break in production.</p><p><strong>No regression baseline.</strong> If you don&#8217;t have a pinned baseline to compare against, you don&#8217;t know if you improved anything. Every eval run needs a reference point, not just &#8220;last run.&#8221;</p><p><strong>Eval suite drift.</strong> Your dataset needs to reflect real user inputs &#8212; not the examples you built the system around. If the same prompts appear in both dev and eval, you&#8217;re measuring overfitting.</p><p><strong>Treating LLM-as-judge as ground truth.</strong> LLM judges are genuinely useful, but they have blind spots. Calibrate against human labels periodically. Know where yours fails before you use it to gate deploys.</p><div><hr></div><h2>How this fits into the bigger picture</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!b9WS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bedf8b5-ab0c-4b06-86fb-f55f340dc6ef_1334x586.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!b9WS!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bedf8b5-ab0c-4b06-86fb-f55f340dc6ef_1334x586.png 424w, /__u/substackcdn.com/image/fetch/$s_!b9WS!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bedf8b5-ab0c-4b06-86fb-f55f340dc6ef_1334x586.png 848w, /__u/substackcdn.com/image/fetch/$s_!b9WS!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bedf8b5-ab0c-4b06-86fb-f55f340dc6ef_1334x586.png 1272w, /__u/substackcdn.com/image/fetch/$s_!b9WS!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bedf8b5-ab0c-4b06-86fb-f55f340dc6ef_1334x586.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!b9WS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bedf8b5-ab0c-4b06-86fb-f55f340dc6ef_1334x586.png" width="1334" height="586" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9bedf8b5-ab0c-4b06-86fb-f55f340dc6ef_1334x586.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:586,&quot;width&quot;:1334,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:85015,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://datajourney24.substack.com/i/200860076?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bedf8b5-ab0c-4b06-86fb-f55f340dc6ef_1334x586.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!b9WS!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bedf8b5-ab0c-4b06-86fb-f55f340dc6ef_1334x586.png 424w, /__u/substackcdn.com/image/fetch/$s_!b9WS!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bedf8b5-ab0c-4b06-86fb-f55f340dc6ef_1334x586.png 848w, /__u/substackcdn.com/image/fetch/$s_!b9WS!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bedf8b5-ab0c-4b06-86fb-f55f340dc6ef_1334x586.png 1272w, /__u/substackcdn.com/image/fetch/$s_!b9WS!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bedf8b5-ab0c-4b06-86fb-f55f340dc6ef_1334x586.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>Each of these paradigms emerged because the previous one stopped being able to answer the most important question of its era.</p><p>TDD answered: does the code do what it&#8217;s supposed to?</p><p>Experiment-driven development answered: does the model generalize?</p><p>EDD answers: did the system actually behave better  across everything that matters, not just the metric you were watching?</p><div><hr></div><h2>Where this is heading</h2><p>Unit tests are non-negotiable infrastructure for traditional software. Nobody ships without them. Eval suites are heading the same direction for AI systems  and honestly, faster than most teams expect.</p><p>The teams building reliable GenAI products in production right now aren&#8217;t necessarily the ones with the best models or the cleverest prompts. They&#8217;re the ones who have genuine signal on whether a change made things better or worse. They can ship with confidence because they know what they&#8217;re measuring.</p><p>That&#8217;s what EDD gives you. Not a guarantee. A reliable signal.</p><p>In systems this complex, that&#8217;s a lot.</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://datajourney24.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DataJourney! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[Building Observability for a Production GenAI System: An Internal Knowledge Base End-to-End]]></title><description><![CDATA[This series has covered the three pillars of production GenAI observability - Token Economics, Evaluation, and Latency & Reliability as separate concerns.]]></description><link>https://datajourney24.substack.com/p/building-observability-for-a-production</link><guid isPermaLink="false">https://datajourney24.substack.com/p/building-observability-for-a-production</guid><dc:creator><![CDATA[Pooja Palod]]></dc:creator><pubDate>Fri, 15 May 2026 16:50:39 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!1rmf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69b9b98e-b153-4ec8-82e5-5891541f924d_1440x1228.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This <a href="/__u/datajourney24.substack.com/p/you-cant-debug-what-you-cant-see">series </a>has covered the three pillars of production GenAI observability - Token Economics, Evaluation, and Latency &amp; Reliability as separate concerns. In practice they&#8217;re not separate. They&#8217;re instrumented together, they affect each other, and the signals from one pillar frequently explain anomalies in another.</p><p>This post puts it all together through a single concrete system: an internal knowledge base Q&amp;A assistant. The kind of system most engineering teams either have already built or are actively building - employees ask questions, the system retrieves relevant documentation and policy content, and an LLM generates a grounded response.</p><p>It&#8217;s a good vehicle for this because it&#8217;s representative. RAG pipeline, multi-turn conversations, mixed query complexity, real users with real stakes, and all three observability pillars in play simultaneously. Everything here applies directly to customer-facing systems, agent pipelines, and more complex architectures - the instrumentation patterns scale up, not just sideways.</p><div><hr></div><h2>The System We&#8217;re Instrumenting</h2><p>Before instrumenting anything, it helps to be precise about what we&#8217;re building and where the failure points are.</p><p><strong>The pipeline:</strong></p><p>A user submits a natural language query. The query is preprocessed and classified by task type. Relevant chunks are retrieved from a vector index of internal documentation, policies, and runbooks. Retrieved context is assembled with conversation history into a prompt. The LLM generates a response grounded in retrieved context. The response is post-processed, validated, and streamed back to the user.</p><p><strong>The users:</strong> employees across engineering, product, HR, finance, and operations - with very different query types, domain expertise levels, and tolerance for incorrect answers.</p><p><strong>The stakes:</strong> HR policy answers that are wrong erode trust fast. Engineering runbook answers that are wrong cause incidents. Finance procedure answers that are wrong have compliance implications. This isn&#8217;t a low-stakes system.</p><p><strong>The failure modes:</strong></p><ul><li><p>Retrieval returning outdated or irrelevant documentation</p></li><li><p>LLM hallucinating details not present in retrieved context</p></li><li><p>Latency spikes making the system feel unreliable</p></li><li><p>Token costs compounding as conversation histories grow</p></li><li><p>Quality degrading silently after a documentation index refresh</p></li></ul><p>Each of these maps directly to one of the three pillars. None of them are visible without deliberate instrumentation.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!1rmf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69b9b98e-b153-4ec8-82e5-5891541f924d_1440x1228.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!1rmf!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69b9b98e-b153-4ec8-82e5-5891541f924d_1440x1228.png 424w, /__u/substackcdn.com/image/fetch/$s_!1rmf!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69b9b98e-b153-4ec8-82e5-5891541f924d_1440x1228.png 848w, /__u/substackcdn.com/image/fetch/$s_!1rmf!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69b9b98e-b153-4ec8-82e5-5891541f924d_1440x1228.png 1272w, /__u/substackcdn.com/image/fetch/$s_!1rmf!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69b9b98e-b153-4ec8-82e5-5891541f924d_1440x1228.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!1rmf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69b9b98e-b153-4ec8-82e5-5891541f924d_1440x1228.png" width="1440" height="1228" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/69b9b98e-b153-4ec8-82e5-5891541f924d_1440x1228.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1228,&quot;width&quot;:1440,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:230982,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://datajourney24.substack.com/i/197885534?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69b9b98e-b153-4ec8-82e5-5891541f924d_1440x1228.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!1rmf!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69b9b98e-b153-4ec8-82e5-5891541f924d_1440x1228.png 424w, /__u/substackcdn.com/image/fetch/$s_!1rmf!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69b9b98e-b153-4ec8-82e5-5891541f924d_1440x1228.png 848w, /__u/substackcdn.com/image/fetch/$s_!1rmf!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69b9b98e-b153-4ec8-82e5-5891541f924d_1440x1228.png 1272w, /__u/substackcdn.com/image/fetch/$s_!1rmf!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69b9b98e-b153-4ec8-82e5-5891541f924d_1440x1228.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>The Observability Foundation</h2><p>Before instrumenting individual pillars, two things need to be in place across the entire system.</p><p><strong>Trace propagation.</strong> Every request needs a unique trace ID assigned at intake and carried through every stage of the pipeline - retrieval, context assembly, inference, post-processing. This is the thread that connects cost attribution, quality scores, and latency measurements back to individual requests. When something goes wrong, you reconstruct the full execution path rather than guessing from aggregate signals.</p><p><strong>Structured logging.</strong> Every log event should be emitted as structured data - not free-text strings. Free-text logs are readable. Structured logs are queryable. The difference matters when you&#8217;re trying to find all requests where retrieval latency exceeded 500ms and quality scores were simultaneously below threshold. Every log event gets the trace ID, a timestamp, an event type, and the relevant metrics for that stage.</p><p>With these two in place, every subsequent instrumentation layer has a consistent foundation to build on.</p><div><hr></div><h2>Pillar 1: Cost Observability</h2><p>An internal knowledge base has a cost profile that&#8217;s easy to underestimate. Query volume is moderate but consistent throughout the workday. Conversation histories grow across sessions. Retrieval pulls multiple chunks per query. And the query mix is wide &#8212;-a simple policy question costs a fraction of a multi-step procedure walkthrough.</p><p><strong>Instrument at every stage, not just inference.</strong></p><p>Most cost instrumentation focuses on the LLM call. That&#8217;s half the picture. Embedding generation, retrieval, and context assembly all have token footprints, and understanding which stage is driving cost growth requires stage-level attribution. Track input tokens, output tokens, and context assembly tokens separately  and tag every cost event with the task type that generated it.</p><p><strong>The metric that matters: cost per successful task by task type.</strong></p><p>Aggregate monthly spend tells you the bill is high. Cost per successful task by task type tells you which query categories are economically unsustainable and where to focus optimization. It also tells you immediately when a cost optimization has degraded quality - cost per task drops but task success rate drops with it, which isn&#8217;t an optimization.</p><p><strong>Semantic caching is high-leverage for this system.</strong></p><p>Internal knowledge bases have high query repetition - the same HR policy questions, the same onboarding procedure questions, the same engineering setup questions &#8212;-asked by different employees throughout the week. A semantic caching layer that returns stored responses for queries above a similarity threshold (typically 0.92-0.95 cosine similarity) can eliminate 30-50% of LLM calls for high-frequency query categories. Track cache hit rate by query category as a first-class operational metric. A declining cache hit rate is often the first signal of query distribution shift.</p><p><strong>Context pruning prevents compounding cost.</strong></p><p>Without a conversation history limit, context tokens grow with every turn. A five-turn conversation that started with a simple policy question is passing thousands of tokens of history on every subsequent query. Set a rolling window- five turns is a reasonable starting point  and summarize older history rather than truncating it. Track average context tokens per request by task type and alert when it starts climbing without a corresponding increase in query complexity.</p><p><strong>Cost alerts worth configuring:</strong></p><ul><li><p>Cost per successful task rising more than 20% week-over-week for any task type</p></li><li><p>Cache hit rate dropping below 25% for high-frequency query categories</p></li><li><p>Average context tokens per request exceeding a defined threshold by task type</p></li></ul><div><hr></div><h2>Pillar 2: Quality Observability</h2><p>Quality failures in an internal knowledge base are particularly consequential. A hallucinated HR policy answer, an outdated engineering procedure, an incorrect finance guideline ,these erode trust in the system fast and are hard to recover from. The primary risk here isn&#8217;t low-quality responses. It&#8217;s confidently wrong responses that employees act on.</p><p><strong>Capture everything at inference time.</strong></p><p>The core requirement: log enough context at inference time to evaluate quality later. This means the full assembled prompt, retrieved chunks with their relevance scores, the model output, and any user feedback signals. Without this, you&#8217;re evaluating samples in a vacuum. With it, every captured interaction becomes a data point for eval, regression testing, and retrieval quality analysis.</p><p>Use tiered logging: full capture for every error and flagged response, sampled capture (15-20%) for normal traffic. The storage cost is manageable; the debugging value is significant.</p><p><strong>LLM-as-judge evaluation - decomposed, not holistic.</strong></p><p>For this system, the most important quality dimensions are groundedness and accuracy. </p><p>Groundedness  is every claim in the response supported by the retrieved context? Is the highest-stakes dimension because it&#8217;s the primary protection against hallucination. </p><p>Accuracy is the information correct based on the context provided?It catches cases where retrieval returned outdated documentation.</p><p>Don&#8217;t ask the judge for a single overall quality score. Ask separately for groundedness, accuracy, completeness, and clarity. Decomposed scores are more reliable and more actionable  when quality drops, you know which dimension changed. Use chain-of-thought prompting before scoring to reduce variance, and use a different model family than your production model to reduce self-preference bias.</p><p>Run evaluation asynchronously on sampled live traffic  not in the request path. The goal is a quality trend dashboard updated continuously from production data, not real-time per-request scoring.</p><p><strong>Heuristics for deterministic checks - synchronous, always running.</strong></p><p>Not everything needs a judge model. Format compliance, minimum and maximum response length by task type, uncertainty phrase detection (&#8221;I think,&#8221; &#8220;I believe,&#8221; &#8220;I&#8217;m not sure&#8221;), refusal detection, and structural requirements for procedure questions - these should be rule-based, fast, and running on every request. A spike in uncertainty phrases is often the first signal that retrieval is returning weak context. A spike in refusals often indicates a documentation coverage gap.</p><p>Audit your heuristics periodically. Rules that haven&#8217;t triggered in three months probably don&#8217;t belong there.</p><p><strong>Retrieval quality is a leading indicator of overall quality.</strong></p><p>In a knowledge base system, retrieval is where quality most often breaks down  especially after documentation updates. Track mean relevance score and minimum relevance score for retrieved chunks by task type. Track chunk utilization  if the model is consistently ignoring the bottom half of retrieved context, you&#8217;re retrieving too much and wasting tokens on low-signal content. A drop in retrieval relevance scores almost always precedes a quality score decline by 24-48 hours. It&#8217;s the earliest warning signal you have.</p><p><strong>Build a regression dataset from production failures.</strong></p><p>Every time a quality failure is confirmed  through user feedback, a low judge score that human review validates, or a flagged response  log the input, the bad output, the root cause, and the expected output. Run this dataset before every significant change: prompt update, model upgrade, documentation index refresh. A change that fixes a new issue while reintroducing an old one isn&#8217;t a net improvement.</p><p><strong>Quality alerts worth configuring:</strong></p><ul><li><p>Overall quality score dropping more than 10% over 48 hours for any task type</p></li><li><p>Groundedness score average falling below 3.5  the highest-risk dimension for this system</p></li><li><p>Retrieval mean relevance score dropping below 0.75  early signal of index staleness</p></li><li><p>Refusal rate exceeding 5%  often indicates a retrieval coverage gap</p></li><li><p>Heuristic failure rate spiking after any documentation index update</p></li></ul><div><hr></div><h2>Pillar 3: Latency &amp; Reliability Observability</h2><p>Internal tools have more latency tolerance than consumer products  but not unlimited tolerance. Employees asking a quick policy question during a meeting expect a response in seconds. A system that&#8217;s intermittently slow gets abandoned for a Slack message to HR instead, which defeats the purpose entirely.</p><p><strong>Instrument every pipeline stage separately.</strong></p><p>End-to-end latency tells you something is slow. Stage-level latency tells you where. Track retrieval latency, embedding latency, context assembly time, LLM inference latency, and post-processing time independently tagged by task type. When end-to-end latency spikes, you want to know in seconds whether it&#8217;s a retrieval issue, a model issue, or a context assembly issue, not after an hour of log diving.</p><p><strong>Track TTFT separately from end-to-end latency.</strong></p><p>For streaming responses, time to first token is the latency signal that determines whether an employee thinks the system is working. A response that starts streaming in 400ms feels responsive even if it takes 8 seconds to complete. Track TTFT as a first-class metric, trend it over time, and alert on P95 breaches separately from end-to-end latency breaches. They degrade for different reasons and point to different parts of the pipeline.</p><p><strong>Use P95 and P99, not averages.</strong></p><p>A system with average end-to-end latency of 2 seconds might have P99 latency of 18 seconds. That means 1% of employees are waiting nearly 20 seconds  often the ones asking the most complex questions, who need the system most. Set SLOs against P95 and P99 by task type. Alert when they breach, not when averages drift.</p><p><strong>Surface retry and fallback rates explicitly.</strong></p><p>Silent retries where the client library retries a failed LLM call automatically are one of the most common sources of unexpected latency spikes in production. A request that retried twice before succeeding looks identical to one that succeeded immediately in your end-to-end latency metrics. It&#8217;s not. Log every retry with its reason, every fallback to a secondary model, and every timeout. Track retry rate as an operational metric. A spike in retry rates is often the earliest signal of provider-side reliability problems earlier than error rates, earlier than latency percentiles.</p><p><strong>Design fallback paths and test them.</strong></p><p>Every external dependency needs an explicit answer to: what happens when this fails? If the vector database is unavailable, does the system fall back to answering from parametric knowledge with a caveat, or does it return an error? If the primary model times out, is there a configured secondary model that&#8217;s been tested, or is it theoretical? Fallback paths that haven&#8217;t been tested don&#8217;t work when you need them. Test under simulated failure conditions before a production incident forces you to find out.</p><p><strong>Circuit breakers for every external dependency.</strong></p><p>The vector database, the embedding service, the LLM provider each needs a circuit breaker that stops sending requests to a failing dependency and returns a fallback response immediately. Without circuit breakers, a retrieval service returning errors receives the full load of production traffic on every request, compounding failures downstream. Configure circuit breakers to open after a defined error rate threshold, stay open for a recovery window, and test recovery with a fraction of traffic before closing. Surface circuit breaker state prominently in your operational dashboard &#8212; it shouldn&#8217;t be buried in logs.</p><p><strong>Latency alerts worth configuring:</strong></p><ul><li><p>TTFT P95 exceeding 2 seconds  employees notice this immediately</p></li><li><p>Retrieval stage P99 exceeding 800ms early signal of vector database issues</p></li><li><p>End-to-end P95 exceeding 8 seconds by task type</p></li><li><p>Retry rate exceeding 5% over any 15-minute window</p></li><li><p>Circuit breaker opening on any dependency immediate alert, not a daily digest</p></li></ul><div><hr></div><h2>Connecting the Three Pillars: The Dashboard View</h2><p>Individual pillar instrumentation is useful. The real value comes from viewing all three together because the most interesting production problems involve interactions between pillars, not failures within a single one.</p><p><strong>Four views every internal knowledge base system should have:</strong></p><p><strong>Request health overview</strong> -request volume by task type, cache hit rate by query category, error rate, fallback rate, and circuit breaker state for each dependency. The operational pulse of the system at a glance.</p><p><strong>Cost trend</strong> -cost per successful task by task type over a 7-day window, token breakdown by pipeline stage, cache hit rate trend, and the top query patterns by cost. A declining cache hit rate here is often the first signal of query distribution shift before it shows up in cost.</p><p><strong>Quality trend</strong> -overall quality score and groundedness score by task type over a 7-day window, retrieval mean relevance score trend, refusal rate, and heuristic failure rate. Groundedness is the canary for this system, watch it first.</p><p><strong>Latency profile</strong> -P50/P95/P99 end-to-end latency by task type, TTFT P95 trend, stage-level latency breakdown, retry rate, and fallback rate trend.</p><p><strong>The cross-pillar interactions worth watching:</strong></p><p>A drop in retrieval relevance scores (quality view) often precedes a quality score decline (quality view) and a latency increase (latency view) as the model works harder to generate responses from weak context all three move together, but retrieval relevance moves first.</p><p>A cache hit rate drop (cost view) often correlates with cost increases (cost view) and latency increases (latency view) as more requests hit the full pipeline. If cache hit rate is dropping without an obvious change in query volume, it usually means query distribution has shifted worth investigating before it becomes a cost problem.</p><p>A retry rate spike (latency view) that precedes an error rate increase is almost always a provider reliability issue catch it at the retry rate signal, not the error rate signal.</p><div><hr></div><h2>The Deployment Checklist</h2><p>Before this system goes live  or before any significant change is deployed &#8212; these questions should be answerable from your observability layer:</p><p><strong>Cost</strong></p><ul><li><p>Is cost per successful task stable across task types in staging?</p></li><li><p>Is cache hit rate at expected levels for high-frequency query categories?</p></li><li><p>Are context tokens within expected ranges by task type?</p></li></ul><p><strong>Quality</strong></p><ul><li><p>Has the regression dataset been run against the current build?</p></li><li><p>Are groundedness and accuracy scores above threshold on the regression set?</p></li><li><p>Has retrieval quality been validated after any documentation index changes?</p></li><li><p>Has the LLM judge been calibrated against human labels in the last 30 days?</p></li></ul><p><strong>Latency</strong></p><ul><li><p>Is TTFT P95 within SLO under expected concurrent load?</p></li><li><p>Have all external dependencies been load tested at peak concurrency?</p></li><li><p>Have fallback paths been tested under simulated failure conditions?</p></li><li><p>Are circuit breakers configured and verified for all dependencies?</p></li><li><p>Is retry logging active and surfaced in the operational dashboard?</p></li></ul><p>If any of these questions can&#8217;t be answered before deployment, the deployment should wait.</p><div><hr></div><h2>The Underlying Principle</h2><p>Observability for a production GenAI system isn&#8217;t three separate instrumentation projects. It&#8217;s one instrumentation project that surfaces signals across three dimensions -cost, quality, and latency  connected by a common trace ID and viewed together in a coherent dashboard.</p><p>The internal knowledge base is a good model for why this matters. A documentation index refresh that degrades retrieval quality will show up first in retrieval relevance scores, then in groundedness scores as the model starts hallucinating to fill gaps, then in latency as users ask follow-up questions to get the answer they needed, then in cost as those follow-up turns compound. None of those signals make sense in isolation. Together they tell a clear story.</p><p>Build the instrumentation so the story is always visible. The rest of production operations follows from that.</p><div><hr></div><p><em>The series: Observability &#8594; Token Economics &#8594; Evaluation &#8594; Latency &amp; Reliability &#8594; Case Study &#8594; This post. The first four posts cover the principles. The case study connects them through a real failure scenario. This post shows what the full instrumentation picture looks like on a concrete system.</em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://datajourney24.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DataJourney! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[Latency & Reliability in Production GenAI: Why System Health Is an Instrumentation Problem, Not an Infrastructure Problem]]></title><description><![CDATA[This is the fourth post in a long-form series on building production-grade GenAI systems.]]></description><link>https://datajourney24.substack.com/p/latency-and-reliability-in-production</link><guid isPermaLink="false">https://datajourney24.substack.com/p/latency-and-reliability-in-production</guid><dc:creator><![CDATA[Pooja Palod]]></dc:creator><pubDate>Tue, 05 May 2026 14:23:06 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!uy5R!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe99bfe70-ad63-4822-a55f-3dd10d018800_826x826.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>This is the fourth post in a long-form series on building production-grade GenAI systems. The observability post establishes the instrumentation foundation. Token Economics covers cost architecture. Evaluation covers quality instrumentation. This post closes the third pillar: Latency &amp; Reliability - how to instrument system health in GenAI pipelines, why standard APM isn&#8217;t enough, and what it takes to build systems that degrade gracefully rather than fail silently.</em></p><p>Your users won&#8217;t file a bug report when your GenAI system is slow. They&#8217;ll just leave.</p><p>Latency and reliability are the least glamorous parts of GenAI engineering. Nobody gets excited about retry logic and circuit breakers. But in production, they&#8217;re the difference between a system that works and a system that works most of the time  which, at scale, means the difference between a product that retains users and one that doesn&#8217;t.</p><div><hr></div><h2>Why Latency Is Different in GenAI Systems</h2><p>In traditional software, latency is largely a function of network overhead, database query performance, and compute efficiency. These are well-understood problems with well-understood solutions. Profile the slow query, add an index, cache the expensive computation. The tooling is mature and the mental models are clear.</p><p>GenAI systems introduce latency characteristics that don&#8217;t fit that playbook.</p><p><strong>Latency is non-deterministic.</strong> The same prompt sent to the same model at the same time of day can produce responses that vary by seconds depending on output length, model load, and token generation dynamics. You can&#8217;t profile your way to a fixed number. You manage distributions.</p><p><strong>The pipeline has many stages with different latency profiles.</strong> A RAG request isn&#8217;t a single operation - it&#8217;s query preprocessing, embedding generation, vector search, context assembly, model inference, and post-processing, each with its own latency characteristics and failure modes. Aggregate latency numbers hide which stage is the problem.</p><p><strong>Output length is variable and partially determines latency.</strong> Unlike a database query that returns a fixed result, an LLM generates tokens sequentially. A response that&#8217;s twice as long takes roughly twice as long to generate. Latency and output verbosity are coupled in ways that create unexpected behavior - a prompt change that produces more verbose outputs will increase latency even if nothing else in the system changed.</p><p><strong>Streaming changes the latency equation entirely.</strong> For streaming systems, the latency that matters most to users isn&#8217;t end-to-end completion time - it&#8217;s time to first token. A response that starts streaming in 300ms feels fast even if it takes 10 seconds to complete. A response that sits blank for 4 seconds feels broken even if it completes quickly. These are different problems with different causes and different fixes.</p><p>Understanding these dynamics is the prerequisite for instrumenting and improving latency effectively.</p><div><hr></div><h2>The Signals That Actually Matter</h2><p>Most teams track average response time. Average response time is one of the least useful latency metrics you can collect.</p><p>It smooths over the distribution, hides tail latency, and conflates requests with fundamentally different latency profiles. A system with an average response time of 2 seconds might have P50 latency of 800ms and P99 latency of 18 seconds which means 1% of your users are waiting nearly 20 seconds for a response. Average tells you nothing about that.</p><p>Here are the signals worth instrumenting:</p><p><strong>Time to First Token (TTFT)</strong></p><p>For any system that uses streaming, TTFT is the primary latency signal from the user&#8217;s perspective. It measures the time from request submission to the arrival of the first token in the response stream the moment the interface stops looking frozen.</p><p>TTFT is determined by everything that happens before token generation starts: request preprocessing, cache lookup, retrieval, context assembly, and the model&#8217;s prefill computation on the input tokens. It&#8217;s largely independent of output length, which makes it a cleaner signal than end-to-end latency for diagnosing problems in the pre-inference pipeline.</p><p>Track TTFT separately from end-to-end latency. They degrade for different reasons and require different fixes.</p><p><strong>End-to-End Latency by Pipeline Stage and Task Type</strong></p><p>Track latency at each stage of your pipeline not just the total. Retrieval latency, embedding latency, LLM inference latency, post-processing latency. When end-to-end latency spikes, you want to know which stage is responsible without having to instrument ad hoc.</p><p>Segment by task type as well. A simple classification request and a multi-step agent workflow have completely different latency profiles. Averaging them together produces a number that accurately describes neither. When latency degrades for one task type but not others, aggregate metrics will hide it until the degradation is severe.</p><p><strong>P95 and P99 Latency</strong></p><p>Tail latency is where user experience actually breaks down. P95 and P99 are the numbers that tell you what your worst-served users are experiencing. Set your SLOs against P95 and P99, not averages &#8212; and alert when they breach thresholds, not when averages drift.</p><p>In GenAI systems, tail latency is often driven by specific failure modes: context length outliers, retrieval timeout spikes, model overload under concurrent load, or retry behavior masking upstream failures. P99 spikes that don&#8217;t show up in P50 are almost always pointing at one of these.</p><p><strong>Token Generation Rate</strong></p><p>Tokens per second is a useful diagnostic metric for isolating whether latency is coming from pre-inference overhead or from the inference call itself. If TTFT is acceptable but end-to-end latency is high, generation rate tells you whether the model is producing tokens slowly or whether the output is simply long.</p><p>Track generation rate by model and task type. A drop in generation rate on a specific model often signals capacity constraints on the provider side before it shows up in error rates.</p><p><strong>Retry and Fallback Rates</strong></p><p>This is the most underinstrumented latency signal in most production systems. Silent retries  where your client library automatically retries a failed LLM call add latency without surfacing as errors. A request that takes 8 seconds because it retried twice looks identical to a request that took 8 seconds because the output was long.</p><p>Instrument every retry, every fallback to a secondary model, and every timeout explicitly. Surface retry rates as a first-class operational metric. A spike in retry rates is often the first signal of provider-side reliability problems earlier than error rates, earlier than latency percentiles, and significantly earlier than user complaints.</p><div><hr></div><h2>Reliability Architecture: Designing for Failure</h2><p>Latency and reliability are connected. Most latency spikes in production GenAI systems aren&#8217;t caused by slow responses they&#8217;re caused by failed requests that retry, fallback chains that add overhead, and timeout handling that blocks the request path longer than necessary.</p><p>Building reliable GenAI systems means designing for failure from the start, not adding resilience patterns after the first production incident.</p><h3>Timeouts and Deadline Propagation</h3><p>Every LLM call needs a timeout. This sounds obvious. A surprising number of production systems don&#8217;t implement it correctly either because the default timeout in the client library is too long, or because timeouts aren&#8217;t propagated through the full request chain.</p><p>In a multi-stage pipeline, a timeout at the LLM call level doesn&#8217;t help if the retrieval call upstream has no timeout and can block indefinitely. Set timeouts at every external call in your pipeline and propagate request deadlines end-to-end. If a request has a 10-second total budget, every stage needs to know how much of that budget remains and abort if it can&#8217;t complete within the remaining time.</p><p>Differentiate between TTFT timeouts and completion timeouts for streaming systems. A request that hasn&#8217;t started streaming within 3 seconds is a different failure mode from a request that started streaming but stopped mid-response.</p><h3>Retry Logic with Exponential Backoff</h3><p>Retries are necessary. Naive retries make reliability problems worse.</p><p>Immediate retries on a provider that&#8217;s under load add more load to an already stressed system. Retries without jitter cause thundering herd problems where all clients retry simultaneously. Retries without maximum attempt limits can hold requests open indefinitely.</p><p>Standard retry configuration: exponential backoff with jitter, maximum of 2-3 retries for transient errors, no retries for client errors (4xx) or content policy violations, explicit logging of every retry with the reason.</p><p>Distinguish between retry-eligible errors and non-retry-eligible ones. A 429 (rate limit) warrants a retry with backoff. A 400 (bad request) doesn&#8217;t retrying a malformed request will produce the same error every time.</p><h3>Fallback Chains</h3><p>A fallback chain defines what your system does when its primary path fails. In GenAI systems, this typically means falling back to a secondary model when the primary is unavailable, falling back to a cached response when inference fails, or falling back to a degraded but functional response when the full pipeline can&#8217;t complete.</p><p>Design your fallback chain before you need it. Questions to answer explicitly:</p><ul><li><p>If your primary model provider is unavailable, what&#8217;s the secondary? Is it pre-configured and tested, or theoretical?</p></li><li><p>If retrieval fails, does your system fall back to answering without context, return an error, or serve a cached response?</p></li><li><p>If your full agent pipeline times out, is there a simplified path that can answer the query with reduced capability?</p></li></ul><p>Fallbacks that haven&#8217;t been tested don&#8217;t work when you need them. Test your fallback chain under simulated failure conditions before a production incident forces you to find out what actually happens.</p><h3>Circuit Breakers</h3><p>A circuit breaker prevents your system from repeatedly calling a downstream dependency that&#8217;s failing. Without one, a retrieval service that&#8217;s returning errors will receive the full load of your production traffic on every request adding latency to every request and potentially cascading failures downstream.</p><p>Circuit breaker logic: track error rate for each downstream dependency over a rolling window. When error rate exceeds a threshold, open the circuit stop sending requests to that dependency and return a fallback response immediately. After a configured cooldown period, send a small fraction of traffic to test whether the dependency has recovered. If it has, close the circuit. If not, stay open.</p><p>Circuit breakers are standard practice in microservices architecture and underused in GenAI pipelines. Every external dependency in your inference path vector database, embedding service, LLM provider &#8212; should have a circuit breaker.</p><h3>Graceful Degradation</h3><p>The goal of your reliability architecture isn&#8217;t to prevent all failures it&#8217;s to ensure that failures degrade user experience gracefully rather than catastrophically.</p><p>Graceful degradation means defining, for each failure mode, what a reduced-capability response looks like and ensuring your system can produce it. A RAG system that can&#8217;t retrieve context should be able to answer from parametric knowledge with an explicit caveat rather than returning an error. A streaming system where the model is slow should surface partial responses rather than blocking until completion.</p><p>Define your degradation modes explicitly, implement them deliberately, and test them. The difference between a system that handles failures gracefully and one that doesn&#8217;t is almost entirely in whether degradation paths were designed or discovered.</p><div><hr></div><h2>Load Testing and Capacity Planning</h2><p>Most GenAI systems are load tested after the first production incident, not before. By then the cost of not having done it is already paid.</p><p>Load testing GenAI systems has a few considerations that differ from traditional services:</p><p><strong>Model provider rate limits are a first-class constraint.</strong> Your system might handle 1,000 concurrent requests without breaking a sweat internally, but your LLM provider has rate limits that will throttle you long before that. Know your rate limits, model them into your load tests, and design your queuing and backoff logic around them.</p><p><strong>Latency under load doesn&#8217;t scale linearly.</strong> A system with P95 latency of 2 seconds at 10 concurrent requests might have P95 latency of 12 seconds at 100 concurrent requests not because your infrastructure is overloaded, but because model provider response times degrade under high concurrent load. Test at your expected peak concurrency, not just average load.</p><p><strong>Context length distribution matters.</strong> Load tests that use uniform short prompts don&#8217;t reflect production behavior. Test with a realistic distribution of context lengths including the long-tail requests that stress your context assembly and inference path.</p><p><strong>Measure degradation, not just breakage.</strong> A load test that tells you at what concurrency level your system returns errors is less useful than one that tells you how latency percentiles evolve as concurrency increases. You want to know when your system starts degrading, not just when it breaks.</p><div><hr></div><h2>Observability for Latency: Putting It Together</h2><p>Latency observability in a production GenAI system requires connecting the signals described above into a coherent view. Here&#8217;s what that looks like in practice:</p><p><strong>Per-request tracing</strong> - every request gets a trace ID propagated through the full pipeline. Every stage logs its start time, end time, and any errors. You can reconstruct the full execution timeline of any request.</p><p><strong>Stage-level latency metrics</strong> - P50, P95, P99 latency for each pipeline stage, segmented by task type. Stored in your time-series metrics system with enough granularity to detect changes over 15-minute windows.</p><p><strong>TTFT tracking</strong> - logged separately from end-to-end latency for all streaming requests. Trended over time and alerted on P95 breaches.</p><p><strong>Retry and fallback dashboards</strong> - retry rate, fallback rate, and circuit breaker state for each downstream dependency. Surfaced prominently in your operational dashboard, not buried in logs.</p><p><strong>Concurrency and queue depth</strong> - track how many requests are in flight at any point and how long requests are waiting before processing starts. Queue depth spikes are an early signal of capacity constraints before they show up in latency percentiles.</p><p><strong>Anomaly detection on tail latency</strong> - automated alerting on P99 spikes that exceed baseline by a configured threshold. Tail latency anomalies in GenAI systems are almost always pointing at something actionable - a provider issue, a context length outlier, a retry storm  and catching them early matters.</p><div><hr></div><h2>What Good Looks Like at Scale</h2><p>A production system with mature latency and reliability instrumentation has a few distinguishing properties:</p><p><strong>Latency SLOs are defined and measured against tail percentiles, not averages.</strong> The team knows what P95 and P99 latency look like for each task type and has alerts configured to fire before SLOs are breached.</p><p><strong>Failure modes are known and handled explicitly.</strong> Every external dependency has a timeout, a retry policy, and a fallback. Degradation paths have been tested. The team has confidence in what happens when things go wrong because they&#8217;ve deliberately tested it.</p><p><strong>Retry and fallback behavior is visible.</strong> Retry rates and fallback rates are first-class operational metrics. A spike in either triggers investigation before it shows up in user-facing latency.</p><p><strong>The system has been load tested at realistic concurrency.</strong> Capacity limits are understood. The team knows at what load level latency starts degrading and has a plan for what happens when they approach it.</p><p><strong>Latency, cost, and quality are instrumented together.</strong> A latency optimization that increases cost or degrades quality is visible immediately. Trade-offs are made deliberately rather than discovered after the fact.</p><div><hr></div><h2>The Underlying Principle</h2><p>Reliability in GenAI systems isn&#8217;t something you add after you&#8217;ve built the happy path. It&#8217;s a design constraint that shapes every architectural decision how you handle timeouts, how you structure fallbacks, how you test under load, and how you instrument for failure modes you haven&#8217;t encountered yet.</p><p>The teams that build reliable GenAI systems aren&#8217;t the ones who&#8217;ve avoided production incidents. They&#8217;re the ones who&#8217;ve designed their systems to handle incidents gracefully and instrumented them well enough to understand what happened and fix it quickly when they occur.</p><p>Latency and reliability are where production reality diverges most sharply from demo conditions. Designing for that divergence from the start is what separates systems that scale from systems that survive until they don&#8217;t.</p><div><hr></div><p><em>This completes the core series on production GenAI systems Observability, Token Economics, Evaluation, and Latency &amp; Reliability. The through-line across all four: the gap between a GenAI system that works and one that works reliably at scale is almost always an instrumentation and architecture problem, not a model problem. Build the measurement infrastructure first. Everything else follows from that.</em></p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://datajourney24.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DataJourney! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[Evaluation in Production GenAI: Why Quality Is a System Design Problem]]></title><description><![CDATA[This is the third post in a long-form series on building production-grade GenAI systems.]]></description><link>https://datajourney24.substack.com/p/evaluation-in-production-genai-why</link><guid isPermaLink="false">https://datajourney24.substack.com/p/evaluation-in-production-genai-why</guid><dc:creator><![CDATA[Pooja Palod]]></dc:creator><pubDate>Sun, 03 May 2026 05:10:47 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!uy5R!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe99bfe70-ad63-4822-a55f-3dd10d018800_826x826.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>This is the third post in a long-form series on building production-grade GenAI systems. The observability post establishes the instrumentation foundation. The Token Economics post covers how to architect for cost control at scale. This post goes deep on the second pillar: Evaluation  why quality instrumentation in GenAI has to be designed into the system from the start, and what an eval pipeline that actually holds up in production looks like.</em></p><p>Every GenAI team has a quality problem. Most of them don&#8217;t know what it is.</p><p>Not because they aren&#8217;t paying attention  but because the way they&#8217;re measuring quality doesn&#8217;t reflect what&#8217;s actually happening in production. An eval suite that passes doesn&#8217;t mean your system is working. It means your system is working on the inputs you thought to test. Those are different things, and the gap between them is where most production quality failures live.</p><p>This post is about building evaluation that closes that gap instrumentation and pipeline design that makes quality a measurable, trackable, operational property of your system rather than something you check before a release and hope holds up.</p><div><hr></div><h2>Why Evaluation Is Harder in GenAI Than Traditional ML</h2><p>In traditional ML, evaluation is a solved problem in the sense that the framework is clear: you have a labeled dataset, a model, and a metric. You measure the metric on held-out data and you have a number that means something.</p><p>GenAI breaks every part of that framework.</p><p><strong>Ground truth is sparse and delayed.</strong> For most GenAI workflows- question answering, summarization, code generation, multi-step reasoning there&#8217;s no clean labeled dataset sitting around. Generating ground truth is expensive, time-consuming, and often subjective. And even when you have labels, they go stale as your system evolves.</p><p><strong>The output space is effectively unbounded.</strong> A classification model has a fixed set of possible outputs. An LLM can produce anything. Standard metrics like accuracy don&#8217;t apply. Even metrics like BLEU and ROUGE, borrowed from NLP, measure surface similarity rather than semantic quality a response can score poorly on ROUGE and be excellent, or score well and be subtly wrong.</p><p><strong>Quality is multidimensional.</strong> A response can be factually accurate but unhelpful. Helpful but stylistically off. Stylistically correct but hallucinated. These dimensions don&#8217;t collapse into a single number cleanly, and optimizing for one can silently degrade another.</p><p><strong>Production inputs don&#8217;t look like your test set.</strong> Users find edge cases, adversarial inputs, and usage patterns you didn&#8217;t anticipate. A system that performs well on your curated eval set can degrade quickly when it encounters real traffic distribution.</p><p>These aren&#8217;t reasons to give up on evaluation. They&#8217;re reasons to design it more carefully.</p><div><hr></div><h2>The Evaluation Stack</h2><p>Building evaluation that works in production requires four layers working together. Each layer covers failure modes the others miss.</p><h3>Layer 1: LLM-as-Judge for Coverage</h3><p>Human evaluation is the gold standard for quality. It&#8217;s also completely unscalable as a primary signal. At any meaningful production volume, you need automated evaluation that can cover the full range of your live traffic  not just samples.</p><p>LLM-based evaluation fills that gap. A well-designed judge model can assess response quality across multiple dimensions - relevance, factual consistency, task completion, tone, format compliance  at scale and with reasonable accuracy. The key word is &#8220;well-designed.&#8221; An LLM judge that&#8217;s just asked &#8220;is this response good?&#8221; will produce noisy, inconsistent scores. A judge with a carefully structured evaluation rubric, explicit scoring criteria, and chain-of-thought reasoning produces scores that are reliable enough to be operationally useful.</p><p>Practical design principles for LLM-as-judge:</p><p><strong>Decompose quality into specific dimensions.</strong> Don&#8217;t ask for an overall quality score. Ask separately about factual accuracy, relevance to the query, completeness, and format compliance. Decomposed scores are more reliable and more actionable &#8212; when quality drops, you know which dimension changed.</p><p><strong>Use chain-of-thought before scoring.</strong> Prompt the judge to reason through its assessment before producing a score. This reduces score variance significantly and makes the judge&#8217;s reasoning inspectable when you want to understand why a response scored poorly.</p><p><strong>Calibrate against human labels.</strong> Before trusting your judge at scale, validate it against a set of human-labeled examples. Measure agreement rate. A judge that agrees with human raters 80% of the time is useful. One that agrees 60% of the time is producing noise. Most teams skip this step and then wonder why their quality metrics don&#8217;t match user feedback.</p><p><strong>Use a different model family than your production model.</strong> If your system runs on GPT-4, don&#8217;t use GPT-4 as your judge. Models tend to favor their own outputs. Use a different family to reduce self-preference bias.</p><p>Where LLM-as-judge breaks down: factual verification against external knowledge, highly specialized domains where the judge model lacks expertise, and tasks where the evaluation criteria are genuinely ambiguous. Know the limits of your judge and don&#8217;t use it as the sole quality signal for high-stakes outputs.</p><h3>Layer 2: Heuristics for Deterministic Checks</h3><p>Not everything needs a model to evaluate. A significant fraction of quality failures are deterministic &#8212; the response is the wrong format, contains a forbidden phrase, exceeds a length constraint, fails to include required fields, or produces malformed structured output.</p><p>These checks should be rule-based, fast, and always running not sampled, not async, not delegated to an LLM judge. If your system is supposed to return valid JSON and it returns prose, you want to know immediately, not after an eval job runs overnight.</p><p>Heuristic checks to build into your pipeline:</p><ul><li><p>Format validation (JSON schema, required fields, structure compliance)</p></li><li><p>Length constraints (minimum and maximum response length by task type)</p></li><li><p>Forbidden content detection (phrases, patterns, or topics that should never appear in outputs)</p></li><li><p>Citation and reference validation (for RAG systems, verifying that claims in the response are grounded in retrieved context)</p></li><li><p>Confidence and hedging patterns (detecting responses that are overly uncertain or that hedge in ways that indicate the model is guessing)</p></li></ul><p>The failure mode to watch for: heuristics that become a crutch. It&#8217;s tempting to keep adding rules as edge cases surface, until your heuristic layer is a sprawling set of brittle checks that&#8217;s hard to maintain and generates false positives. Audit your heuristics periodically &#8212; rules that haven&#8217;t triggered in three months probably don&#8217;t belong there.</p><h3>Layer 3: Regression Datasets</h3><p>Your production failures are your most valuable eval asset. Every time a quality issue surfaces  a hallucinated response, a retrieval failure, a task completion breakdown it should be captured, root-caused, and added to a regression dataset that your system has to keep passing.</p><p>This is the layer most teams never build deliberately. They fix bugs in production, maybe add a unit test, and move on. Over time the system accumulates changes -prompt updates, model upgrades, retrieval index refreshes with no systematic way to verify that previously fixed issues haven&#8217;t resurfaced.</p><p>A regression dataset built from real production failures has properties that synthetic test sets don&#8217;t: it&#8217;s grounded in actual user inputs, it covers the edge cases your system has actually encountered, and it has a direct relationship to known failure modes rather than hypothetical ones.</p><p>Building it requires two practices:</p><p><strong>Systematic failure capture.</strong> When a quality issue is identified through user feedback, LLM judge scores, or human review &#8212; log the input, the bad output, the root cause, and the expected output. Make this part of your incident process, not an optional extra.</p><p><strong>Regression testing on every significant change.</strong> Prompt change, model upgrade, retrieval index update run the regression dataset before and after. A change that fixes a new issue while reintroducing an old one isn&#8217;t a net improvement.</p><p>The dataset starts small and becomes more valuable over time. A regression set of 200 real failure cases is more useful than a synthetic eval set of 10,000 because it tests the things your system has actually gotten wrong, not the things someone guessed it might get wrong.</p><h3>Layer 4: Human Review for Calibration</h3><p>Automated evaluation drifts. LLM judges develop systematic biases. Heuristics miss emerging failure patterns. Regression datasets cover known failures but not new ones. Human review is what keeps the rest of the eval stack honest.</p><p>The goal of human review in a production system isn&#8217;t comprehensive coverage it&#8217;s calibration. A small, consistent sample of live responses reviewed by someone who understands the task is enough to catch systematic drift before it compounds.</p><p>What to review:</p><p><strong>A random sample of normal traffic</strong> - to maintain a baseline sense of typical output quality and catch gradual drift that automated metrics might miss.</p><p><strong>Low-scoring outputs from your LLM judge</strong> - to verify that low scores reflect genuine quality problems rather than judge miscalibration.</p><p><strong>High-scoring outputs from task types with known risks</strong> - LLM judges can be confidently wrong. Sampling high-scoring responses in sensitive domains catches the failure mode where your judge is systematically missing a quality dimension.</p><p><strong>Outputs that triggered heuristic checks</strong> - to verify that your rules are catching real problems and not generating false positives.</p><p>The cadence matters more than the volume. A weekly review of 50-100 responses, consistently executed, is more valuable than an irregular deep-dive of 500 responses every few months. Consistency is what lets you detect trend changes rather than just point-in-time snapshots.</p><div><hr></div><h2>Connecting Eval to Production: The Live Evaluation Loop</h2><p>The four layers above are most valuable when they&#8217;re connected to your production system in a feedback loop not just run as offline checks before releases.</p><p>A live evaluation loop looks like this:</p><p><strong>Capture</strong> -log every production request with full context: the prompt, retrieved chunks, model output, any post-processing applied, and user feedback signals where available. Tiered logging as described in the observability post: full capture for errors and flagged responses, sampled capture for normal traffic.</p><p><strong>Score</strong> -run async LLM-as-judge evaluation on sampled live traffic. Apply heuristic checks synchronously in the request path. Surface scores into your observability layer with task type attribution.</p><p><strong>Monitor</strong> - track quality score trends over time by task type, not just in aggregate. A quality drop in one task type hidden inside a stable aggregate score is exactly the kind of failure that surfaces in user complaints rather than dashboards.</p><p><strong>Alert</strong> - set thresholds for quality score drift (a 10% drop in judge scores over 48 hours is worth investigating), heuristic failure rate spikes, and regression dataset pass rate changes after deployments.</p><p><strong>Review</strong>- weekly human review cadence as described above, with explicit focus on validating automated signals rather than just assessing output quality in isolation.</p><p><strong>Improve</strong>- route confirmed quality failures into your regression dataset, root cause analysis process, and prompt/retrieval improvement workflow. Close the loop.</p><p>The cadence of this loop determines how quickly you catch quality problems. A team with a 48-hour detection-to-awareness cycle for quality issues operates completely differently from one that finds out from user complaints two weeks later.</p><div><hr></div><h2>Where Evaluation Breaks Down in Practice</h2><p><strong>Eval-production distribution shift.</strong> Your eval set, however carefully constructed, will drift from your production traffic distribution over time. Users change how they use your system, new use cases emerge, and adversarial inputs evolve. Refresh your eval sets regularly and monitor for input distribution shift as a leading indicator of potential quality problems.</p><p><strong>Goodhart&#8217;s Law.</strong> When a quality metric becomes a target, it stops being a good quality metric. Teams that optimize prompts directly against LLM judge scores without human validation end up with systems that score well and perform poorly  because they&#8217;ve learned to produce outputs that satisfy the judge rather than outputs that satisfy users. Keep human review in the loop precisely to catch this.</p><p><strong>Latency vs. quality tradeoff in eval.</strong> Running a thorough LLM-as-judge evaluation adds latency and cost. Async evaluation avoids the latency problem but introduces a delay between when a quality issue occurs and when you know about it. Design your eval pipeline with explicit decisions about what runs synchronously versus asynchronously and what the acceptable detection delay is.</p><p><strong>Evaluating multi-step pipelines.</strong> In agent systems or multi-step RAG pipelines, a poor final output could have originated anywhere in the chain. End-to-end quality scores tell you something is wrong. They don&#8217;t tell you where. Instrument quality at each pipeline stage  retrieval quality, intermediate reasoning steps, final output quality  so you can isolate the failure point.</p><div><hr></div><h2>What Good Looks Like at Scale</h2><p>A production system with mature evaluation has a few properties that distinguish it from one that&#8217;s just running ad hoc spot checks:</p><p><strong>Quality is a trend, not a snapshot.</strong> You&#8217;re tracking quality score movement over time, not just measuring it before releases. A stable quality score means something. A declining one triggers investigation before it triggers user complaints.</p><p><strong>You know which failure modes are most common.</strong> Your regression dataset and failure classification give you a taxonomy of how your system fails, ranked by frequency and severity. You&#8217;re fixing the most impactful issues systematically rather than reacting to whatever surfaced most recently.</p><p><strong>Eval is connected to deployment.</strong> Significant system changes - prompt updates, model upgrades, retrieval changes run against the regression dataset before going to production. Regressions block deployment. This sounds obvious and is surprisingly rare in practice.</p><p><strong>Quality and cost are instrumented together.</strong> You can see whether a cost optimization degraded quality or whether a quality improvement increased cost. The two metrics are correlated in your observability layer, not tracked in isolation.</p><div><hr></div><h2>The Underlying Principle</h2><p>Evaluation in GenAI is not a testing problem. It&#8217;s an instrumentation problem building systems that continuously surface quality signals from production, connect those signals to your development process, and close the loop between what your system does in the wild and what you&#8217;re improving in the lab.</p><p>The teams that get this right don&#8217;t have better eval suites. They have shorter feedback loops. Quality problems surface in hours, not weeks. Root causes are traceable. Fixes are verifiable. And the system gets measurably better over time rather than just differently broken.</p><div><hr></div><p><em>Next in the series: Latency &amp; Reliability - how to instrument system health in GenAI pipelines, why standard APM isn&#8217;t enough, and what it takes to build systems that degrade gracefully rather than fail silently.</em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://datajourney24.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DataJourney! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h3></h3>]]></content:encoded></item><item><title><![CDATA[Token Economics: Why LLM Cost Is an Architecture Problem, Not a Finance Problem]]></title><description><![CDATA[This is the second post in a long-form series on building production-grade GenAI systems.]]></description><link>https://datajourney24.substack.com/p/token-economics-why-llm-cost-is-an</link><guid isPermaLink="false">https://datajourney24.substack.com/p/token-economics-why-llm-cost-is-an</guid><dc:creator><![CDATA[Pooja Palod]]></dc:creator><pubDate>Sat, 25 Apr 2026 04:46:56 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!uy5R!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe99bfe70-ad63-4822-a55f-3dd10d018800_826x826.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This is the second post in a long-form series on building production-grade GenAI systems. The first post covers observability- why the standard monitoring playbook doesn't transfer to GenAI pipelines, and what you need to instrument across Cost, Quality, and Latency before any of the architecture decisions in this series become actionable. This post goes deep on the first pillar: Token Economics, and why LLM cost is an architecture problem, not a finance one.</p><p>Most teams discover they have a token economics problem the same way they discover they have a technical debt problem gradually, then all at once.</p><p>The AWS bill climbs. Someone schedules a cost review. A few prompts get trimmed. The bill drops slightly, then climbs again. The cycle repeats until the system is either unprofitable at scale or someone decides to treat cost as an engineering constraint rather than a line item to manage after the fact.</p><p>This post is about building systems where that cycle never starts where cost is instrumented, controlled, and architecturally contained from the beginning. It&#8217;s the second post in a series on production GenAI systems. If you haven&#8217;t read the observability post, the instrumentation concepts here build on that foundation.</p><div><hr></div><h3>Why Token Economics Is Different From Traditional Infrastructure Cost</h3><p>In traditional software, cost scales with compute and storage. Both are relatively predictable, both respond well to standard optimization patterns, and both have decades of tooling built around them.</p><p>Token costs are different in three important ways.</p><p><strong>They scale with behavior, not just traffic.</strong> A user who asks a simple question costs a fraction of what a user who triggers a multi-step agent workflow costs. Traffic volume is only half the story, the nature of the requests matters as much as the number of them. A system that looks economical at 10 users can become expensive at 1,000 not because traffic increased 100x but because usage patterns shifted.</p><p><strong>They&#8217;re invisible without deliberate instrumentation.</strong> A slow database query shows up in your APM. A prompt that&#8217;s quietly grown to 8,000 tokens because someone kept patching in edge cases doesn&#8217;t at least not until it shows up in your monthly bill with no clear attribution.</p><p><strong>They compound across the pipeline.</strong> In a RAG system, you&#8217;re paying for embedding generation, retrieval, context assembly, and inference often across multiple model calls. Each step has its own token footprint, and inefficiencies at any stage compound into the final cost. Most cost optimization work focuses on the inference call and ignores everything upstream.</p><p>Understanding these three dynamics is the prerequisite for building systems that control cost effectively.</p><div><hr></div><h3>The Metric That Actually Matters: Cost Per Successful Task</h3><p>Token count is a useful operational metric. It&#8217;s not the right lens for understanding whether your system is economically sound.</p><p>The metric that matters is <strong>cost per successful task</strong> - what does it actually cost to deliver a correct, complete response for a given task type? This number tells you things that aggregate token counts never will:</p><ul><li><p>Whether your caching layer is working (cost per task should drop as cache hit rate rises)</p></li><li><p>Whether model routing is calibrated correctly (cost per task for simple requests should be significantly lower than for complex ones)</p></li><li><p>Whether quality and cost are moving in opposite directions (a cost optimization that degrades task success rate isn&#8217;t an optimization)</p></li><li><p>Whether your system is economically viable at your target scale (project cost per task against expected volume and you have a unit economics model)</p></li></ul><p>Getting to cost per successful task requires two things: per-request cost attribution and a definition of &#8220;successful&#8221; that your system can evaluate automatically. The first is an instrumentation problem. The second is an evaluation problem which is why cost and quality observability have to be built together, not separately.</p><div><hr></div><h3>The Three Architectural Levers</h3><h4>1. Semantic Caching</h4><p>The highest-leverage cost optimization in most production GenAI systems isn&#8217;t prompt compression or model selection  it&#8217;s not calling the LLM at all.</p><p>Semantic caching works by storing responses against vector representations of queries, then retrieving cached responses when a new query is sufficiently similar to one that&#8217;s already been answered. The threshold for &#8220;sufficiently similar&#8221; is configurable typically a cosine similarity score above 0.92-0.95 depending on how much variance you can tolerate in responses.</p><p>In systems with high query repetition customer support, internal knowledge bases, FAQ-style interfaces cache hit rates of 30-50% are achievable. At those rates, the cost reduction is substantial and the latency improvement is dramatic: a cache hit returns in milliseconds rather than seconds.</p><p>The implementation requires a vector database for similarity search and a fast key-value store (Redis is the standard choice) for response retrieval. The operational complexity is real you need cache invalidation logic, staleness handling, and monitoring for cache hit rates by query type. But for most high-volume systems the ROI justifies it quickly.</p><p>Where semantic caching breaks down: low-repetition query patterns, high variance tolerance requirements, and use cases where response freshness is critical. Don&#8217;t implement it uniformly instrument your query distribution first and apply caching selectively to the query types where repetition is actually high.</p><h4>2. Model Routing</h4><p>Not every request in your system requires the same model. This sounds obvious. Most production systems ignore it anyway defaulting to a single frontier model for everything because it&#8217;s simpler to implement and the cost problem isn&#8217;t yet acute enough to justify the routing infrastructure.</p><p>By the time the cost problem is acute, you&#8217;re refactoring a system that was never designed for routing. Build it in early.</p><p>A practical routing architecture has two tiers at minimum:</p><p><strong>Tier 1: Lightweight models for deterministic tasks</strong> - formatting, classification, extraction, summarization, structured output generation. These tasks don&#8217;t require deep reasoning. A $0.15/1M token model handles them as well as a $15/1M frontier model in most cases. The cost difference is 100x. Routing 60-70% of your requests to Tier 1 based on task type reduces your blended inference cost dramatically.</p><p><strong>Tier 2: Frontier models for complex reasoning</strong> - multi-step reasoning, ambiguous queries, tasks that require broad world knowledge or nuanced judgment. This is where frontier model capability actually matters. Reserve it for the requests that need it.</p><p>The routing layer itself can be a lightweight classifier - a small model or even a rules-based system that categorizes incoming requests by task type and routes accordingly. The classifier&#8217;s cost is negligible relative to the savings from routing correctly.</p><p>The failure mode to watch for: routing based on request complexity signals that are easy to game or misread. A short query isn&#8217;t necessarily a simple one. Build in a fallback path that escalates to Tier 2 when Tier 1 responses fall below a quality threshold and instrument escalation rates so you can tune the routing logic over time.</p><h4>3. Context Pruning</h4><p>Token bloat is the cost problem that accumulates invisibly. It doesn&#8217;t cause errors. It doesn&#8217;t trigger alerts. It just makes every request progressively more expensive and slower as the system matures.</p><p>The most common sources:</p><p><strong>Unbounded chat history</strong> - systems that pass the full conversation history to the model on every turn. At turn 3 this is fine. At turn 30, you&#8217;re sending thousands of tokens of context for a request that might need two turns of history at most. Summarize older history, prune beyond a rolling window, and track average context length per session as an operational metric.</p><p><strong>Oversized RAG retrieval</strong> - retrieving more chunks than the model can usefully attend to. Most RAG systems retrieve 5-10 chunks by default. In practice, well-ranked retrieval with 3-4 highly relevant chunks outperforms poorly-ranked retrieval with 10 chunks &#8212; and costs significantly less. Measure chunk utilization: if the model is consistently ignoring the bottom half of your retrieved context, you&#8217;re retrieving too much.</p><p><strong>Prompt template bloat</strong> - system prompts and few-shot examples that have grown over time as edge cases got patched in. Audit your prompt templates periodically. Every sentence that&#8217;s in there to handle a rare edge case is a tax on every request. Consider whether those edge cases are better handled in post-processing than in the prompt.</p><p><strong>Redundant tool definitions</strong> - in agent systems, passing the full tool schema for every available tool on every request. Pass only the tools relevant to the current task type. The token cost of unused tool definitions adds up faster than most teams expect.</p><p>Context pruning isn&#8217;t a one-time optimization &#8212; it&#8217;s an ongoing practice. Instrument context length by pipeline stage and task type, set alerts for context length growth, and treat prompt bloat as technical debt that gets addressed on a regular cadence.</p><div><hr></div><h3>Building a Cost-Aware Inference Path</h3><p>The three levers above work best when they&#8217;re integrated into a coherent inference path rather than implemented as independent optimizations. Here&#8217;s what that looks like in practice:</p><p><strong>Request intake</strong> - classify the incoming request by task type. This classification drives routing, caching lookup, and context assembly decisions downstream.</p><p><strong>Cache check</strong> - before any model call, check semantic cache. On a hit, return the cached response and log the cache hit with task type attribution. On a miss, proceed.</p><p><strong>Context assembly</strong> - assemble context with pruning applied: rolling history window, relevance-ranked RAG with chunk count capped, prompt template audit. Log assembled context length.</p><p><strong>Model routing</strong> - route to Tier 1 or Tier 2 based on task type classification. Log the routing decision.</p><p><strong>Inference</strong> &#8212; make the model call. Log token counts (input and output separately), model used, and latency.</p><p><strong>Quality check</strong> - run a lightweight quality signal on the response (format validation, output scoring for task-critical requests). Log pass/fail.</p><p><strong>Cost attribution</strong> - compute request cost from token counts and model pricing. Attribute to task type. Update cost per successful task metrics.</p><p>This path adds minimal latency overhead when implemented correctly  cache checks and context pruning are fast, routing classification is cheap, and cost attribution is a simple calculation. The instrumentation overhead is real but small relative to the cost visibility it provides.</p><div><hr></div><h3>What Good Looks Like at Scale</h3><p>A production system with mature token economics has a few properties that distinguish it from one that&#8217;s just been optimized ad hoc:</p><p><strong>Cost per successful task is stable or declining as volume grows.</strong> Caching effects improve with scale, routing gets better calibrated, and context pruning compounds. If cost per task is rising with volume, the architecture is failing.</p><p><strong>Cost is attributable by task type, pipeline stage, and time period.</strong> When the bill goes up, you can identify the cause in minutes rather than hours. You know which task type is responsible, which stage in the pipeline the cost is coming from, and when it started.</p><p><strong>Cost and quality move together, not in opposite directions.</strong> Optimizations that reduce cost while maintaining or improving task success rates are the goal. Cost reductions that degrade quality are false savings they show up in churn and support costs instead.</p><p><strong>The system degrades gracefully under cost pressure.</strong> When token budgets are constrained, the system routes more aggressively to lighter models, retrieves fewer chunks, and summarizes more aggressively rather than failing or producing expensive low-quality responses.</p><div><hr></div><h3>The Underlying Principle</h3><p>Token economics is ultimately about building systems where cost is a first-class engineering constraint rather than an afterthought. That means instrumenting it at the right granularity, designing the inference path with cost control built in, and treating cost per successful task as a metric that matters as much as latency or quality.</p><p>The teams that get this right don&#8217;t spend less time thinking about cost they spend less time being surprised by it.</p><div><hr></div><p><em>Next in the series: Evaluation -why quality instrumentation in GenAI is a system design problem, and how to build eval pipelines that catch degradation before your users do.</em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://datajourney24.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DataJourney! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[You Can’t Debug What You Can’t See: Observability for Production GenAI Systems]]></title><description><![CDATA[Part 1 of a 4-part series on production GenAI systems covering Observability, Token Economics, Evaluation, and Latency & Reliability.]]></description><link>https://datajourney24.substack.com/p/you-cant-debug-what-you-cant-see</link><guid isPermaLink="false">https://datajourney24.substack.com/p/you-cant-debug-what-you-cant-see</guid><dc:creator><![CDATA[Pooja Palod]]></dc:creator><pubDate>Tue, 14 Apr 2026 17:37:04 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!uy5R!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe99bfe70-ad63-4822-a55f-3dd10d018800_826x826.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>Part 1 of a 4-part series on production GenAI systems covering Observability, Token Economics, Evaluation, and Latency &amp; Reliability.</em></p><p><em>8 min read</em></p><div><hr></div><p>Production GenAI systems fail in ways that are hard to see coming. Not because the models are bad but because the infrastructure around them isn&#8217;t built to surface the right signals. This is the first post in a long-form series on building production-grade GenAI systems: the architecture decisions, instrumentation practices, and failure patterns that separate demos from systems that hold up at scale. We&#8217;ll go deep on Token Economics, Evaluation, and Latency &amp; Reliability in the posts that follow. But observability comes first because without it, none of the rest is actionable.</p><p>Most GenAI systems are flying blind.</p><p>Not because engineers don&#8217;t care about visibility  but because the observability playbook from traditional software doesn&#8217;t transfer cleanly. You can&#8217;t just drop Datadog on an LLM pipeline and call it done. The failure modes are different, the signals are different, and the thing you&#8217;re actually trying to understand model behavior &#8212; doesn&#8217;t fit neatly into metrics, logs, or traces.</p><p>This is the gap between teams that catch problems early and teams that find out from users.</p><div><hr></div><h2>Monitoring vs. Observability: Why GenAI Needs Both</h2><p>In traditional systems, monitoring tells you something is wrong. Observability tells you why.</p><p>In GenAI systems, that distinction matters more than anywhere else &#8212; because the failure modes are probabilistic, not deterministic. A service going down is binary. A model that&#8217;s gradually drifting toward lower-quality outputs, or a retrieval pipeline that&#8217;s quietly returning less relevant chunks, isn&#8217;t. Those failures are invisible to standard monitoring until they&#8217;ve already done damage.</p><p>Monitoring covers the signals you already know to watch: latency, error rates, token usage, API availability. These are necessary but not sufficient. They&#8217;ll tell you when something is obviously broken.</p><p>Observability covers the harder question: <em>why is my system behaving this way?</em> That requires capturing enough context at each step of your pipeline inputs, outputs, intermediate states, model decisions &#8212; that you can reconstruct what happened after the fact. Not just that a request failed, but what the model received, what it returned, and where in the chain things went wrong.</p><p>The teams that get this right treat their GenAI pipeline the same way a good backend engineer treats a distributed system: every hop is a potential failure point, and every failure point needs a trace.</p><div><hr></div><h2>The Three Pillars and What Observability Looks Like for Each</h2><p>The rest of this series goes deep on Cost, Quality, and Latency individually. But observability cuts across all three and each pillar has a distinct instrumentation problem worth understanding before you get into the architecture details.</p><h3>Pillar 1: Cost (Token Economics)</h3><p>Token costs are easy to monitor in aggregate. They&#8217;re hard to observe at the request level  which is where the real problems live.</p><p>Aggregate cost metrics tell you your bill is going up. They don&#8217;t tell you which pipeline stage is responsible, which task type is burning disproportionate tokens, or whether your caching layer is actually working. For that you need per-request instrumentation: token counts broken down by input and output, cost attributed by task type, cache hit and miss rates tracked explicitly.</p><p>The failure mode to watch for: token bloat that accumulates invisibly. Chat histories that grow unchecked, RAG pipelines that retrieve far more context than the model uses, prompt templates that balloon over time as edge cases get patched in. None of these show up as errors. They show up as a cost curve that keeps climbing without a clear cause.</p><p>Good cost observability means you can answer: what did this specific request cost, why, and which part of the pipeline was responsible?</p><h3>Pillar 2: Quality (Evaluation)</h3><p>Quality is the hardest pillar to instrument because there&#8217;s no ground truth signal that arrives in real time. A slow response is immediately measurable. A response that&#8217;s subtly wrong, unhelpful, or drifting from your intended behavior isn&#8217;t at least not without deliberate instrumentation.</p><p>This is why quality observability has to be designed in, not bolted on. The core requirement: capture enough of what happened at inference time that you can evaluate it later. The full prompt, the retrieved context, the model output, and any user feedback signals that come back. Without that, you&#8217;re evaluating samples in a vacuum rather than understanding your system&#8217;s actual behavior in production.</p><p>Beyond capture, you need a lightweight async evaluation layer running against sampled live traffic an LLM judge scoring responses on relevance, accuracy, and task completion, with results feeding into a quality trend dashboard. Not real-time, not every request, but consistent enough that you&#8217;d catch a drift in quality scores over days, not weeks.</p><p>The failure mode to watch for: quality that degrades gradually across a model update, a retrieval index refresh, or a prompt change none of which trigger an alert in a standard monitoring setup.</p><p>Good quality observability means you can answer: is my system&#8217;s output quality stable over time, and if it changed, what changed first?</p><h3>Pillar 3: Latency &amp; Reliability</h3><p>Latency is the most instrumented of the three pillars in most systemsand still frequently misread. The common mistake is treating it as a single number when it&#8217;s actually a profile across pipeline stages, request types, and load levels.</p><p>A RAG pipeline, a multi-step agent, and a simple classification call have completely different latency characteristics. Averaging them together hides the outliers. And in GenAI systems, the outliers are usually where the interesting failures live a retrieval call that&#8217;s occasionally timing out, an LLM call that spikes under concurrent load, a post-processing step that quietly adds 800ms to certain request types.</p><p>The signals that matter most: TTFT (time to first token) for streaming systems, end-to-end latency broken down by pipeline stage and task type, P95 and P99 rather than averages, and retry and fallback rates tracked explicitly. Silent retries are one of the most common sources of unexpected latency spikes if your system is retrying failed LLM calls without surfacing that to your observability layer, you&#8217;re flying blind on a significant failure mode.</p><p>The failure mode to watch for: latency that looks acceptable in averages but has a long tail that&#8217;s quietly degrading user experience &#8212; and retry behavior that&#8217;s masking upstream reliability problems.</p><p>Good latency observability means you can answer: where in my pipeline is time being spent, and is my system degrading gracefully or failing silently under load?</p><div><hr></div><h2>Where Observability Breaks Down in Practice</h2><p>Even teams that build good observability infrastructure run into the same problems. Worth naming them directly:</p><p><strong>Volume vs. depth tradeoff</strong> - you can&#8217;t store full prompt/response pairs for every request at scale. Use tiered logging: full capture for errors and edge cases, sampled capture for normal traffic, aggregate metrics for everything else.</p><p><strong>LLM judge drift</strong> - if you&#8217;re using an LLM to evaluate your LLM&#8217;s outputs, your judge model can drift too. Calibrate it periodically against human review. A small weekly sample is enough to catch systematic bias before it corrupts your quality metrics.</p><p><strong>Instrumentation latency overhead</strong> - adding tracing to every pipeline step adds latency. In streaming systems this is especially sensitive. Instrument asynchronously where possible and be deliberate about what runs in the hot path.</p><p><strong>Correlation without causation</strong> - observability gives you data, not answers. A spike in latency correlated with a quality score drop doesn&#8217;t tell you which caused which. Build dashboards that surface hypotheses, not conclusions.</p><div><hr></div><h2>What a Minimal Viable Observability Stack Looks Like</h2><p>You don&#8217;t need to instrument everything on day one:</p><p><strong>Tracing</strong> - OpenTelemetry with your existing APM (Datadog, Honeycomb, Grafana). Instrument pipeline boundaries first: retrieval in/out, LLM in/out.</p><p><strong>Logging</strong> -Structured logs with trace IDs for every request. Full prompt/response capture for errors, 10-20% sample for normal traffic.</p><p><strong>Cost monitoring</strong> -Per-request token tracking with task-type attribution. Cache hit/miss rates tracked explicitly.</p><p><strong>Quality monitoring</strong> - Async LLM-as-judge eval on sampled live traffic. Quality score trend over time, not just point-in-time snapshots.</p><p><strong>Latency monitoring</strong> - P95/P99 by pipeline stage and task type. TTFT tracked separately from end-to-end latency. Retry and fallback rates surfaced explicitly.</p><p><strong>Alerting</strong> - Hard failures (error spikes, latency P95 breaches) in real time. Soft failures (quality drift, cost curve changes) on a daily digest.</p><div><hr></div><h2>The Underlying Principle</h2><p>Traditional software observability is about understanding system state. GenAI observability is about understanding system <em>behavior</em> which is harder, more ambiguous, and more consequential.</p><p>The teams building reliable GenAI systems aren&#8217;t the ones with the best models. They&#8217;re the ones who&#8217;ve built enough visibility into their pipelines that they can tell the difference between a model problem, a retrieval problem, a prompt problem, and a data problem and fix the right thing.</p><p>Instrumentation isn&#8217;t glamorous. But it&#8217;s the difference between a system you operate and a system that operates you.</p><div><hr></div><p><em>Next up: Token Economics  why LLM cost isn&#8217;t a finance problem, it&#8217;s an architecture problem, and how to build inference paths that don&#8217;t bleed margin at scale.</em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://datajourney24.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DataJourney! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[From LLMs to Products: Alignment & Production]]></title><description><![CDATA[How GPT-3 became ChatGPT and how to deploy your own]]></description><link>https://datajourney24.substack.com/p/from-llms-to-products-alignment-and</link><guid isPermaLink="false">https://datajourney24.substack.com/p/from-llms-to-products-alignment-and</guid><dc:creator><![CDATA[Pooja Palod]]></dc:creator><pubDate>Sat, 27 Dec 2025 12:56:12 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Sfr_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c7a334b-3420-4b89-a7ad-fef6fbc49a52_1952x1158.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Series Navigation:</strong></p><ul><li><p><a href="/__u/datajourney24.substack.com/p/the-need-for-transformers?r=25b2f4">Post 1: The Need for Transformers</a></p></li><li><p><a href="/__u/datajourney24.substack.com/p/inside-the-transformer-attention?r=25b2f4">Post 2: Inside the Transformer</a></p></li><li><p><a href="/__u/datajourney24.substack.com/p/scaling-to-llms-why-bigger-models?r=25b2f4">Post 3: Scaling to LLMs</a></p></li><li><p><strong>Post 4: From LLMs to Products</strong> &#8592; You are here</p></li></ul><div><hr></div><h3>What We&#8217;ll Cover</h3><p>You&#8217;ve learned how to build a massive LLM, but the real challenge is making it truly useful and reliable in real-world applications.</p><p>Base models like GPT-3 are impressive, yet they have limitations:</p><ul><li><p>Completes text but often ignores explicit instructions</p></li><li><p>Can produce toxic or harmful content</p></li><li><p>Hallucinates facts with confidence</p></li><li><p>Expensive to run at scale (initial ChatGPT ~$700K/day)</p></li></ul><p>This article walks through the journey of transforming a base LLM into a <strong>production-ready system</strong>, covering both alignment and deployment.</p><h4><strong>Part 1: Alignment - Making Models Helpful</strong></h4><ul><li><p>Instruction tuning (teaching models to follow instructions)</p></li><li><p>RLHF (Reinforcement Learning from Human Feedback)</p></li><li><p>Constitutional AI (Anthropic&#8217;s approach)</p></li><li><p>Safety and guardrails</p></li></ul><h4><strong>Part 2: Production - Deploying at Scale</strong></h4><ul><li><p>Inference optimization (quantization, KV cache)</p></li><li><p>RAG (Retrieval-Augmented Generation)</p></li><li><p>Prompt engineering patterns</p></li><li><p>Real-world architectures</p></li><li><p>Cost analysis and optimization</p></li></ul><p><strong>By the end, you&#8217;ll understand:</strong></p><ul><li><p>How ChatGPT was created from GPT-3.5</p></li><li><p>The three-phase RLHF process</p></li><li><p>When to use RAG vs fine-tuning</p></li><li><p>How to deploy LLMs cost-effectively</p></li><li><p>Production architecture patterns</p></li></ul><p>Let&#8217;s bridge the gap from research to reality.</p><div><hr></div><h3>Part 1: Alignment - Making Models Helpful</h3><h4>1. The Base Model Problem</h4><p><strong>1.1 What&#8217;s Wrong with Base Models?</strong></p><p><strong>You:</strong> &#8220;Write a Python function to sort a list&#8221;</p><p><strong>Base GPT-3:</strong></p><pre><code><code>of numbers in ascending order. The function should use the bubble sort algorithm.

def bubble_sort(arr):
    n = len(arr)
    for i in range(n):
        for j in range(0, n-i-1):
</code></code></pre><p><strong>Observation:</strong> The model continues the text instead of directly following the instruction.</p><p><strong>Reason:</strong> Base LLMs are trained on <strong>next-token prediction</strong> from internet text. They excel at continuation, not instruction execution.</p><h4><strong>1.2 The Four Key Problems</strong></h4><p><strong>1. Instruction Following</strong></p><ul><li><p>Doesn&#8217;t distinguish between &#8220;write code&#8221; vs &#8220;explain code&#8221;</p></li><li><p>Completes text instead of executing commands</p></li></ul><p><strong>2. Harmful Content</strong></p><ul><li><p>No concept of &#8220;should I say this?&#8221;</p></li><li><p>Can generate hate speech, violence, illegal content</p></li></ul><p><strong>3. Hallucinations</strong></p><ul><li><p>Makes up facts confidently</p></li><li><p>No &#8220;I don&#8217;t know&#8221; response</p></li></ul><p><strong>4. Inconsistency</strong></p><ul><li><p>Same question &#8594; different answers</p></li><li><p>No clear &#8220;personality&#8221; or behavior</p></li></ul><p><strong>Solution:</strong> Alignment techniques that teach models to be helpful, harmless, and honest.</p><div><hr></div><h4>2. Instruction Tuning: The First Step</h4><p><strong>2.1 What Is Instruction Tuning?</strong></p><p><strong>Simple idea:</strong> Fine-tune the base model on examples of instructions + desired responses.</p><p><strong>Training data format:</strong></p><pre><code><code>Instruction: Translate "Hello" to French
Response: Bonjour

Instruction: Explain photosynthesis to a 10-year-old
Response: Photosynthesis is how plants make their own food using sunlight...

Instruction: Write a haiku about coding
Response: Fingers on keyboard
Logic flows through lines of code
Bug-free poetry
</code></code></pre><p><strong>2.2 Key Datasets</strong></p><p><strong>FLAN (Google, 2021)</strong></p><ul><li><p>Fine-tuned Language Net</p></li><li><p>60+ NLP tasks reformulated as instructions</p></li><li><p>T5 model &#8594; FLAN-T5</p></li></ul><p><strong>T0 (BigScience, 2021)</strong></p><ul><li><p>Multi-task prompted training</p></li><li><p>Diverse prompt templates per task</p></li></ul><p><strong>Alpaca (Stanford, 2023)</strong></p><ul><li><p>52K instruction-following examples</p></li><li><p>Generated using GPT-3.5</p></li><li><p>Open-source alternative</p></li></ul><p><strong>Dolly (Databricks, 2023)</strong></p><ul><li><p>15K human-generated examples</p></li><li><p>Fully open, commercial-friendly</p></li></ul><p><strong>2.3 What Changes?</strong></p><p><strong>Before instruction tuning (Base GPT-3):</strong></p><pre><code><code>Prompt: Summarize this article in 3 sentences:
[article text]

Output: The article discusses... [continues for 20 sentences]
</code></code></pre><p><strong>After instruction tuning:</strong></p><pre><code><code>Prompt: Summarize this article in 3 sentences:
[article text]

Output: [Exactly 3 sentence summary]
</code></code></pre><p><strong>The model learned:</strong></p><ul><li><p>Instructions are commands, not text to continue</p></li><li><p>Format matters (bullet points when asked, code blocks for code)</p></li><li><p>Task boundaries (stop when done)</p></li></ul><p><strong>2.4 Limitations</strong></p><p>Instruction tuning helps, but:</p><ul><li><p>Still generates harmful content if instructed</p></li><li><p>Still hallucinates</p></li><li><p>No nuanced understanding of &#8220;helpful&#8221;</p></li><li><p>Can&#8217;t handle conflicting instructions well</p></li></ul><p><strong>We need something more sophisticated: RLHF.</strong></p><div><hr></div><h4>3. RLHF: The ChatGPT Secret</h4><p><strong>3.1 What Is RLHF?</strong></p><p><strong>Reinforcement Learning from Human Feedback</strong></p><p>The technique that transformed GPT-3.5 into ChatGPT.</p><p><strong>Core insight:</strong></p><blockquote><p>&#8220;We can&#8217;t write down all the rules for being helpful. But we can show examples and let humans rank outputs.&#8221;</p></blockquote><p><strong>3.2 The Three-Phase Process</strong></p><p><strong>Phase 1: Supervised Fine-Tuning (SFT)</strong></p><p><strong>Goal:</strong> Create initial instruction-following model</p><p><strong>How:</strong></p><ol><li><p>Hire human labelers (contractors, often)</p></li><li><p>Give them prompts: &#8220;Explain quantum computing&#8221;</p></li><li><p>They write high-quality responses</p></li><li><p>Fine-tune base model on these examples</p></li></ol><p><strong>Dataset size:</strong> 10K-100K high-quality examples</p><p><strong>Output:</strong> SFT model (decent, but not great)</p><div><hr></div><p><strong>Phase 2: Reward Model Training</strong></p><p><strong>Goal:</strong> Train a model to score responses (good vs bad)</p><p><strong>How:</strong></p><ol><li><p>Take same prompts</p></li><li><p>Generate 4-9 responses using SFT model</p></li><li><p>Humans rank them: Best &#8594; Worst</p></li><li><p>Train a <strong>reward model</strong> (RM) to predict these rankings</p></li></ol><p><strong>Example:</strong></p><pre><code><code>Prompt: "How do I make pizza?"

Response A: "Mix flour, water, yeast. Let rise. Add toppings. Bake at 450&#176;F."
Response B: "Pizza is made from dough, sauce, and cheese."
Response C: "Use a microwave and frozen pizza."
Response D: [Generates pizza-related joke instead]

Human ranking: A &gt; C &gt; B &gt; D

Reward model learns: A gets score 0.9, B gets 0.4, etc.
</code></code></pre><p><strong>Key insight:</strong> The RM learns <em>human preferences</em> without humans needing to articulate rules.</p><div><hr></div><p><strong>Phase 3: Reinforcement Learning (PPO)</strong></p><p><strong>Goal:</strong> Optimize the model to maximize reward</p><p><strong>How:</strong></p><ol><li><p>Start with SFT model</p></li><li><p>Generate responses to prompts</p></li><li><p>Score them with reward model</p></li><li><p>Use PPO (Proximal Policy Optimization) to update model</p></li><li><p>Repeat for thousands of iterations</p></li></ol><p><strong>The update rule (simplified):</strong></p><pre><code><code>If reward model scores output highly &#8594; reinforce this behavior
If reward model scores output poorly &#8594; discourage this behavior
</code></code></pre><p><strong>Critical detail: KL penalty</strong></p><p>Without constraint, the model could &#8220;hack&#8221; the reward model by generating nonsense that scores high.</p><p><strong>Solution:</strong> Add penalty for diverging too much from the SFT model:</p><pre><code><code>Total reward = RM_score - &#946; * KL_divergence(new_policy, SFT_policy)
</code></code></pre><p>This keeps the model grounded while improving.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!Sfr_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c7a334b-3420-4b89-a7ad-fef6fbc49a52_1952x1158.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!Sfr_!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c7a334b-3420-4b89-a7ad-fef6fbc49a52_1952x1158.png 424w, /__u/substackcdn.com/image/fetch/$s_!Sfr_!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c7a334b-3420-4b89-a7ad-fef6fbc49a52_1952x1158.png 848w, /__u/substackcdn.com/image/fetch/$s_!Sfr_!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c7a334b-3420-4b89-a7ad-fef6fbc49a52_1952x1158.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Sfr_!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c7a334b-3420-4b89-a7ad-fef6fbc49a52_1952x1158.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!Sfr_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c7a334b-3420-4b89-a7ad-fef6fbc49a52_1952x1158.png" width="1456" height="864" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8c7a334b-3420-4b89-a7ad-fef6fbc49a52_1952x1158.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:864,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;RLHF: Reinforcement Learning from Human Feedback&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="RLHF: Reinforcement Learning from Human Feedback" title="RLHF: Reinforcement Learning from Human Feedback" srcset="/__u/substackcdn.com/image/fetch/$s_!Sfr_!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c7a334b-3420-4b89-a7ad-fef6fbc49a52_1952x1158.png 424w, /__u/substackcdn.com/image/fetch/$s_!Sfr_!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c7a334b-3420-4b89-a7ad-fef6fbc49a52_1952x1158.png 848w, /__u/substackcdn.com/image/fetch/$s_!Sfr_!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c7a334b-3420-4b89-a7ad-fef6fbc49a52_1952x1158.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Sfr_!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c7a334b-3420-4b89-a7ad-fef6fbc49a52_1952x1158.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">RLHF..</figcaption></figure></div><div><hr></div><p><strong>3.3 What RLHF Actually Does</strong></p><p><strong>Before RLHF (Base GPT-3.5):</strong></p><ul><li><p>Can do tasks, but needs perfect prompts</p></li><li><p>Sometimes verbose, sometimes terse</p></li><li><p>No consistent &#8220;personality&#8221;</p></li><li><p>Will do harmful things if asked</p></li></ul><p><strong>After RLHF (ChatGPT):</strong></p><ul><li><p>Follows instructions naturally</p></li><li><p>Consistent helpfulness</p></li><li><p>Refuses harmful requests</p></li><li><p>Admits uncertainty (&#8221;I don&#8217;t know&#8221;)</p></li><li><p>Stays on-task</p></li></ul><p><strong>The magic:</strong> RLHF taught <strong>alignment</strong> the model&#8217;s goals align with user intent and safety.</p><p><strong>3.4 Challenges with RLHF</strong></p><p><strong>1. Reward Hacking</strong> Model finds shortcuts to maximize reward that aren&#8217;t actually better outputs.</p><p><strong>Example:</strong> Model learns to be overly apologetic (&#8221;I&#8217;m sorry, but...&#8221;) because humans rated polite responses higher.</p><p><strong>2. Reward Model Limitations</strong> RM is trained on limited data. It&#8217;s not perfect. Model can exploit its blind spots.</p><p><strong>3. Distribution Shift</strong> As the model improves, it generates outputs unlike anything in training. RM becomes unreliable.</p><p><strong>4. Expensive</strong></p><ul><li><p>Requires thousands of human ratings</p></li><li><p>Multiple training phases</p></li><li><p>Iterative process (PPO is slow)</p></li></ul><p><strong>5. Difficult to Control</strong> Hard to specify exactly what you want. &#8220;Be helpful&#8221; is vague.</p><div><hr></div><h4>4. Constitutional AI: Anthropic&#8217;s Approach</h4><p><strong>4.1 The Problem with RLHF</strong></p><p>RLHF requires massive human feedback at scale.</p><p><strong>Anthropic&#8217;s question:</strong></p><blockquote><p>&#8220;Can we use AI to provide the feedback instead of humans?&#8221;</p></blockquote><p><strong>4.2 How Constitutional AI Works</strong></p><p><strong>Phase 1: Supervised Learning (Self-Critique)</strong></p><ol><li><p>Model generates response</p></li><li><p>Model critiques its own response against &#8220;constitution&#8221; (principles)</p></li><li><p>Model revises response</p></li><li><p>Train on (prompt, revised response) pairs</p></li></ol><p><strong>Example Constitution principles:</strong></p><ul><li><p>&#8220;Avoid helping users harm themselves or others&#8221;</p></li><li><p>&#8220;Be honest about uncertainty&#8221;</p></li><li><p>&#8220;Respect user privacy&#8221;</p></li><li><p>&#8220;Avoid stereotypes and bias&#8221;</p></li></ul><p><strong>Phase 2: RL from AI Feedback (RLAIF)</strong></p><p>Instead of human rankings:</p><ol><li><p>Generate multiple responses</p></li><li><p>AI model ranks them based on constitution</p></li><li><p>Train reward model on AI preferences</p></li><li><p>Use PPO like standard RLHF</p></li></ol><p><strong>4.3 Benefits</strong></p><p><strong>1. Scalability</strong></p><ul><li><p>No human labelers needed (after initial constitution)</p></li><li><p>Can generate millions of examples</p></li></ul><p><strong>2. Transparency</strong></p><ul><li><p>Constitution is explicit</p></li><li><p>You know what principles the model follows</p></li></ul><p><strong>3. Iterative Improvement</strong></p><ul><li><p>Easy to update constitution</p></li><li><p>Retrain quickly</p></li></ul><p><strong>4. Consistency</strong></p><ul><li><p>AI feedback is more consistent than human feedback</p></li></ul><p><strong>4.4 Limitations</strong></p><p><strong>1. Goodhart&#8217;s Law</strong> &#8220;When a measure becomes a target, it ceases to be a good measure.&#8221; AI critic might rate responses highly for wrong reasons.</p><p><strong>2. Capability Ceiling</strong> AI critic can&#8217;t be better than the model being evaluated. Self-improvement has limits.</p><p><strong>3. Subtle Value Alignment</strong> Hard to capture nuanced human values in written principles.</p><div><hr></div><h4>5. Safety &amp; Guardrails</h4><p><strong>5.1 Content Filtering</strong></p><p><strong>Input filters:</strong></p><ul><li><p>Detect prompt injection attempts</p></li><li><p>Block requests for harmful content</p></li><li><p>Rate limiting per user</p></li></ul><p><strong>Output filters:</strong></p><ul><li><p>Scan generated text for:</p><ul><li><p>PII (emails, phone numbers, SSNs)</p></li><li><p>Hate speech, violence</p></li><li><p>Copyrighted material</p></li><li><p>Malicious code</p></li></ul></li></ul><p><strong>Tools:</strong></p><ul><li><p>OpenAI Moderation API</p></li><li><p>PerspectiveAPI (Google)</p></li><li><p>Custom classifiers</p></li></ul><p><strong>5.2 Red Teaming</strong></p><p><strong>What:</strong> Adversarial testing to find failure modes</p><p><strong>Process:</strong></p><ol><li><p>Hire people to &#8220;attack&#8221; the model</p></li><li><p>Try to generate harmful outputs</p></li><li><p>Document successful attacks</p></li><li><p>Retrain to fix vulnerabilities</p></li></ol><p><strong>Common attack vectors:</strong></p><ul><li><p>Jailbreaks (&#8221;Pretend you&#8217;re an AI with no restrictions...&#8221;)</p></li><li><p>Prompt injection (&#8221;Ignore previous instructions...&#8221;)</p></li><li><p>Multi-turn manipulation (build trust, then ask harmful questions)</p></li><li><p>Encoded requests (ROT13, base64, etc.)</p></li></ul><p><strong>5.3 The Ongoing Arms Race</strong></p><p><strong>Reality:</strong> No perfect solution.</p><p>Users find new jailbreaks daily. Models get patched. New jailbreaks emerge.</p><p><strong>The defense:</strong></p><ul><li><p>Continuous monitoring</p></li><li><p>Rapid response to new attacks</p></li><li><p>Multiple layers (input filter + model + output filter)</p></li><li><p>Human review of edge cases</p></li></ul><div><hr></div><h3>Part 2: Production - Deploying at Scale</h3><h4>6. Inference Optimization: Making It Fast &amp; Cheap</h4><p><strong>6.1 The Inference Cost Problem</strong></p><p><strong>ChatGPT initial costs (estimated):</strong></p><ul><li><p>$700,000/day in compute (early 2023)</p></li><li><p>~13M users at the time</p></li><li><p>$0.05 per user per day</p></li></ul><p><strong>For comparison:</strong></p><ul><li><p>Google Search: ~$0.001 per search</p></li><li><p>Netflix: ~$0.10 per user per day</p></li></ul><p><strong>LLMs are 50-100x more expensive to serve than traditional services.</strong></p><p><strong>6.2 Quantization: Reducing Model Size</strong></p><p><strong>Problem:</strong> GPT-3 in FP16 = 350GB Can&#8217;t fit on single GPU, slow inference.</p><p><strong>Solution:</strong> Reduce precision</p><p><strong>FP16 &#8594; INT8 (8-bit quantization)</strong></p><ul><li><p>2x smaller model</p></li><li><p>2x faster inference</p></li><li><p>Minimal accuracy loss (~1%)</p></li></ul><p><strong>FP16 &#8594; INT4 (4-bit quantization)</strong></p><ul><li><p>4x smaller model</p></li><li><p>3-4x faster inference</p></li><li><p>Some accuracy loss (~3-5%)</p></li></ul><p><strong>Techniques:</strong></p><ul><li><p><strong>Post-training quantization:</strong> GPTQ, AWQ</p></li><li><p><strong>Quantization-aware training:</strong> Train with quantization in mind</p></li></ul><p><strong>Example:</strong> LLaMA-70B in FP16: 140GB LLaMA-70B in 4-bit: 35GB &#8594; Fits on single A100 (80GB)</p><p><strong>6.3 KV Cache Optimization</strong></p><p><strong>Problem:</strong> For long contexts, KV cache dominates memory</p><p><strong>Solutions:</strong></p><p><strong>1. Multi-Query Attention (MQA)</strong></p><ul><li><p>Share K, V across all heads</p></li><li><p>Only Q is per-head</p></li><li><p>2-3x less KV cache memory</p></li></ul><p><strong>2. Grouped-Query Attention (GQA)</strong></p><ul><li><p>Share K, V across groups of heads</p></li><li><p>Balance between MHA and MQA</p></li><li><p>Used in LLaMA 2</p></li></ul><p><strong>3. PagedAttention (vLLM)</strong></p><ul><li><p>Manage KV cache like OS manages memory</p></li><li><p>Non-contiguous storage</p></li><li><p>Reduces memory waste by 40%</p></li></ul><p><strong>6.4 Batching Strategies</strong></p><p><strong>Problem:</strong> Serving one request at a time wastes GPU</p><p><strong>Naive batching:</strong> Wait until batch is full &#8594; high latency</p><p><strong>Continuous batching (ORCA, vLLM):</strong></p><ul><li><p>Add requests to batch as they arrive</p></li><li><p>Remove completed sequences</p></li><li><p>Add new sequences mid-batch</p></li><li><p>10-20x higher throughput</p></li></ul><p><strong>6.5 Model Serving Frameworks</strong></p><p><strong>vLLM</strong></p><ul><li><p>PagedAttention for memory efficiency</p></li><li><p>Continuous batching</p></li><li><p>14x-24x higher throughput than naive</p></li></ul><p><strong>TensorRT-LLM (NVIDIA)</strong></p><ul><li><p>Optimized kernels</p></li><li><p>INT8/INT4 quantization</p></li><li><p>Multi-GPU inference</p></li></ul><p><strong>Text Generation Inference (HuggingFace)</strong></p><ul><li><p>Production-ready</p></li><li><p>Flash Attention</p></li><li><p>Tensor parallelism</p></li></ul><p><strong>Triton (NVIDIA)</strong></p><ul><li><p>Model server for production</p></li><li><p>Multiple models, multiple GPUs</p></li><li><p>Load balancing, auto-scaling</p></li></ul><div><hr></div><h4>7. RAG: Retrieval-Augmented Generation</h4><p><strong>7.1 The Problem RAG Solves</strong></p><p><strong>Base LLM issues:</strong></p><ul><li><p>Knowledge cutoff (can&#8217;t know events after training)</p></li><li><p>Hallucinations (makes up facts)</p></li><li><p>No access to private/proprietary data</p></li><li><p>Expensive to update knowledge (requires retraining)</p></li></ul><p><strong>RAG solution:</strong></p><blockquote><p>&#8220;Don&#8217;t store all knowledge in parameters. Retrieve relevant information and include it in the prompt.&#8221;</p></blockquote><p><strong>7.2 How RAG Works</strong></p><p><strong>Architecture:</strong></p><pre><code><code>User Query
    &#8595;
[1. Retrieve] &#8594; Search knowledge base
    &#8595;
Relevant documents/chunks
    &#8595;
[2. Augment] &#8594; Construct prompt with context
    &#8595;
Prompt: "Given the following information: [docs]
        Answer the question: [query]"
    &#8595;
[3. Generate] &#8594; LLM produces answer
    &#8595;
Response (grounded in retrieved docs)
</code></code></pre><p><strong>7.3 Building a RAG System</strong></p><p><strong>Step 1: Document Processing</strong></p><pre><code><code>1. Load documents (PDFs, web pages, databases)
2. Chunk into passages (200-500 tokens each)
3. Embed each chunk using embedding model
4. Store embeddings in vector database
</code></code></pre><p><strong>Step 2: Query Time</strong></p><pre><code><code>1. User asks question
2. Embed question
3. Find top-k most similar chunks (cosine similarity)
4. Construct prompt with chunks + question
5. LLM generates answer
</code></code></pre><p><strong>Step 3: Post-Processing</strong></p><pre><code><code>1. Extract citations from response
2. Verify facts against retrieved docs
3. Return answer + sources
</code></code></pre><p><strong>7.4 Key Components</strong></p><p><strong>Embedding Models:</strong></p><ul><li><p><strong>OpenAI ada-002:</strong> 1536 dimensions, good quality</p></li><li><p><strong>Sentence Transformers:</strong> Open-source, various sizes</p></li><li><p><strong>Cohere Embed:</strong> Multilingual, strong performance</p></li><li><p><strong>E5, BGE:</strong> State-of-the-art open models</p></li></ul><p><strong>Vector Databases:</strong></p><ul><li><p><strong>Pinecone:</strong> Managed, scalable</p></li><li><p><strong>Weaviate:</strong> Open-source, GraphQL API</p></li><li><p><strong>Qdrant:</strong> Rust-based, fast</p></li><li><p><strong>Chroma:</strong> Simple, embedded</p></li><li><p><strong>FAISS:</strong> Library (not database), very fast</p></li></ul><p><strong>Chunking Strategies:</strong></p><ul><li><p><strong>Fixed-size:</strong> Simple, 200-500 tokens</p></li><li><p><strong>Sentence-based:</strong> Split on sentences</p></li><li><p><strong>Semantic:</strong> Split on topic boundaries</p></li><li><p><strong>Sliding window:</strong> Overlapping chunks for context</p></li></ul><p><strong>7.5 Hybrid Search</strong></p><p><strong>Problem:</strong> Keyword search and vector search each have strengths</p><p><strong>Solution:</strong> Combine both</p><p><strong>BM25 (keyword) + Dense retrieval (semantic)</strong></p><pre><code><code># Retrieve using both methods
keyword_results = bm25_search(query)  # Good for exact matches
semantic_results = vector_search(query)  # Good for concepts

# Combine with Reciprocal Rank Fusion (RRF)
combined_results = rrf(keyword_results, semantic_results)
</code></code></pre><p><strong>When to use:</strong></p><ul><li><p>Keyword: Exact terms, names, technical jargon</p></li><li><p>Semantic: Concepts, paraphrases, &#8220;similar meaning&#8221;</p></li><li><p>Hybrid: Best of both</p></li></ul><p><strong>7.6 RAG vs Fine-tuning</strong></p><p><strong>Rule of thumb:</strong></p><ul><li><p><strong>RAG:</strong> For knowledge-heavy tasks, changing info</p></li><li><p><strong>Fine-tuning:</strong> For specialized tasks, writing style, consistent behavior</p></li><li><p><strong>Both:</strong> Use fine-tuned model + RAG for best results</p></li></ul><div><hr></div><h4>8. Prompt Engineering: The Meta-Skill</h4><p><strong>8.1 Why Prompting Matters</strong></p><p><strong>Same model, different prompts:</strong></p><p><strong>Bad prompt:</strong></p><pre><code><code>Tell me about machine learning
</code></code></pre><p><strong>Good prompt:</strong></p><pre><code><code>You are an expert machine learning engineer. Explain the difference 
between supervised and unsupervised learning to a software engineer 
with no ML background. Use concrete examples and avoid jargon.
</code></code></pre><p><strong>Prompt engineering can 10x your results</strong> without changing the model.</p><p><strong>8.2 Core Patterns</strong></p><p><strong>1. Role Prompting</strong></p><pre><code><code>You are an expert Python programmer.
You are a helpful teaching assistant.
You are a technical documentation writer.
</code></code></pre><p><strong>2. Few-Shot Learning</strong></p><pre><code><code>Classify sentiment:

Text: "I love this product!"
Sentiment: Positive

Text: "This is terrible."
Sentiment: Negative

Text: "It's okay, nothing special."
Sentiment: Neutral

Text: "Best purchase ever!"
Sentiment: [LLM completes]
</code></code></pre><p><strong>3. Chain-of-Thought (CoT)</strong></p><pre><code><code>Problem: Roger has 5 tennis balls. He buys 2 more cans of 3 balls each.
How many balls does he have?

Let's think step by step:
1. Roger starts with 5 balls
2. He buys 2 cans
3. Each can has 3 balls
4. So he gets 2 * 3 = 6 new balls
5. Total: 5 + 6 = 11 balls
</code></code></pre><p>Adding &#8220;Let&#8217;s think step by step&#8221; increases reasoning accuracy dramatically.</p><p><strong>4. Self-Consistency</strong></p><pre><code><code>Generate 5 different reasoning paths.
Take majority vote on final answer.
</code></code></pre><p>Improves accuracy on complex reasoning tasks.</p><p><strong>5. ReAct (Reason + Act)</strong></p><pre><code><code>Thought: I need current weather data
Action: call_weather_api("San Francisco")
Observation: 72&#176;F, sunny
Thought: Now I can answer
Answer: It's 72&#176;F and sunny in SF today
</code></code></pre><p>Interleaving reasoning and tool use.</p><p><strong>8.3 System Prompts (ChatGPT-style)</strong></p><p><strong>Structure:</strong></p><pre><code><code>System: [Instructions on behavior, constraints]
User: [User's input]
Assistant: [Model's response]
</code></code></pre><p><strong>Example system prompt:</strong></p><pre><code><code>You are a helpful AI assistant. You should:
- Be concise but thorough
- Admit when you don't know something
- Avoid harmful or biased content
- Cite sources when possible
- Ask clarifying questions if the request is ambiguous
</code></code></pre><p><strong>8.4 Prompt Optimization Tools</strong></p><p><strong>Manual:</strong></p><ul><li><p>Test variations</p></li><li><p>A/B test with users</p></li><li><p>Iterate based on feedback</p></li></ul><p><strong>Automated:</strong></p><ul><li><p><strong>DSPy:</strong> Compile prompts automatically</p></li><li><p><strong>Prompt flow:</strong> Visual prompt engineering (Microsoft)</p></li><li><p><strong>LangChain:</strong> Framework for prompt templates</p></li></ul><div><hr></div><h4>9. Real-World Architecture Patterns</h4><p><strong>9.1 Pattern 1: Simple API Wrapper</strong></p><pre><code><code>User Request
    &#8595;
Load Balancer
    &#8595;
API Server (FastAPI/Flask)
    &#8595;
LLM API (OpenAI, Anthropic, etc.)
    &#8595;
Response
</code></code></pre><p><strong>Use case:</strong> Prototypes, low-volume applications</p><p><strong>Pros:</strong> Simple, fast to build </p><p><strong>Cons:</strong> Expensive, vendor lock-in</p><div><hr></div><p><strong>9.2 Pattern 2: Self-Hosted Model</strong></p><pre><code><code>User Request
    &#8595;
API Gateway
    &#8595;
Model Server (vLLM, TGI)
    &#9500;&#9472; GPU 1 (model shard 1)
    &#9500;&#9472; GPU 2 (model shard 2)
    &#9492;&#9472; GPU N (model shard N)
    &#8595;
Response
</code></code></pre><p><strong>Use case:</strong> High volume, cost optimization, data privacy</p><p><strong>Pros:</strong> Control, cheaper at scale </p><p><strong>Cons:</strong> Infrastructure complexity, GPU costs</p><div><hr></div><p><strong>9.3 Pattern 3: RAG System</strong></p><pre><code><code>User Query
    &#8595;
[Query Processing]
    &#8595;
Vector Database (semantic search)
    +
Keyword Search (BM25)
    &#8595;
[Reranking]
    &#8595;
Top-K documents
    &#8595;
[Prompt Construction]
    &#8595;
LLM
    &#8595;
[Response + Citations]
    &#8595;
User
</code></code></pre><p><strong>Use case:</strong> Q&amp;A, knowledge bases, customer support</p><p><strong>Components:</strong></p><ul><li><p>Embedding model for encoding</p></li><li><p>Vector DB for storage</p></li><li><p>Reranker for quality</p></li><li><p>LLM for generation</p></li></ul><div><hr></div><p><strong>9.4 Pattern 4: Agent System</strong></p><pre><code><code>User Request
    &#8595;
Agent (LLM)
    &#9500;&#9472; Tool 1: Web Search
    &#9500;&#9472; Tool 2: Calculator
    &#9500;&#9472; Tool 3: Code Execution
    &#9500;&#9472; Tool 4: Database Query
    &#9492;&#9472; Tool N: Custom API
    &#8595;
[Agent Loop: Reason &#8594; Act &#8594; Observe]
    &#8595;
Final Answer
</code></code></pre><p><strong>Use case:</strong> Complex workflows, multi-step tasks</p><p><strong>Frameworks:</strong></p><ul><li><p>LangChain</p></li><li><p>LlamaIndex</p></li><li><p>AutoGPT</p></li><li><p>BabyAGI</p></li></ul><p><strong>Challenges:</strong></p><ul><li><p>Reliability (agents can fail)</p></li><li><p>Cost (multiple LLM calls)</p></li><li><p>Latency (sequential operations)</p></li></ul><div><hr></div><p><strong>9.5 Pattern 5: Multi-Model Pipeline</strong></p><pre><code><code>User Request
    &#8595;
[Router LLM] &#8594; Classify intent
    &#8595;
    &#9500;&#9472; Simple query &#8594; Small fast model (7B)
    &#9500;&#9472; Complex query &#8594; Large model (70B)
    &#9500;&#9472; Code task &#8594; Code-specialized model
    &#9492;&#9472; Creative task &#8594; Creative model
    &#8595;
Response
</code></code></pre><p><strong>Use case:</strong> Cost optimization, task-specific quality</p><p><strong>Benefit:</strong> Use expensive models only when needed</p><div><hr></div><h4>10. Cost Optimization Strategies</h4><p>Running large language models at scale is expensive. Serving millions of users quickly adds up: even a model like GPT-3.5 can cost thousands of dollars per day, while GPT-4 can easily reach hundreds of thousands. Efficient deployment requires careful strategies to reduce compute, memory, and token usage without sacrificing quality.</p><p><strong>Techniques for Reducing Costs</strong></p><ol><li><p><strong>Prompt Compression</strong></p><ul><li><p>Remove unnecessary words and redundancies</p></li><li><p>Use concise phrasing (&#8220;Explain X briefly&#8221; instead of &#8220;Could you please explain X in detail&#8221;)</p></li><li><p>Reduces token consumption without affecting output quality</p></li></ul></li><li><p><strong>Caching</strong></p><ul><li><p>Store responses to common queries for reuse</p></li><li><p>Cache intermediate results for multi-step prompts</p></li><li><p>Semantic caching allows similar queries to reuse prior outputs, saving both compute and tokens</p></li></ul></li><li><p><strong>Streaming</strong></p><ul><li><p>Deliver partial outputs as soon as they are generated</p></li><li><p>Users get faster feedback</p></li><li><p>Responses can be interrupted if no longer needed, saving computation</p></li></ul></li><li><p><strong>Model Routing</strong></p><ul><li><p>Route simple queries to smaller, faster models</p></li><li><p>Reserve larger models for complex tasks</p></li><li><p>Up to 70&#8211;80% of requests can be served by smaller models, reducing overall cost</p></li></ul></li><li><p><strong>Output Length Limits</strong></p><ul><li><p>Enforce maximum token limits per request to prevent runaway generation</p></li><li><p>Example: <code>max_tokens=200</code> in API calls</p></li></ul></li><li><p><strong>Batch Processing</strong></p><ul><li><p>Process multiple requests together to maximize GPU utilization</p></li><li><p>Reduces per-request compute cost</p></li><li><p>Trade-off: slight increase in latency for higher throughput</p></li></ul></li><li><p><strong>Self-Hosting</strong></p><ul><li><p>Deploy models on owned infrastructure if token usage is high (~1M&#8211;10M tokens/day)</p></li><li><p>Fixed GPU costs are amortized across all requests, reducing long-term expenses</p></li></ul></li><li><p><strong>Quantization</strong></p><ul><li><p>Convert models to lower precision (e.g., 4-bit) to reduce memory and compute requirements</p></li><li><p>Achieves 3&#8211;4x cost reduction with minimal impact on output quality</p></li></ul></li></ol><div><hr></div><h4>11. Production Checklist</h4><p>Deploying a large language model isn&#8217;t just about serving predictions&#8212;it requires rigorous preparation, monitoring, and continuous improvement. Here&#8217;s a structured approach to ensure reliability, safety, and efficiency.</p><p><strong>11.1 Before Deployment</strong></p><p><strong>Model Selection</strong></p><ul><li><p>Choose the appropriate model size based on your use case.</p></li><li><p>Benchmark against real-world inputs to verify performance.</p></li><li><p>Test edge cases to ensure robustness under unusual or unexpected queries.</p></li></ul><p><strong>Safety Measures</strong></p><ul><li><p>Implement input filters to catch malicious or harmful prompts.</p></li><li><p>Apply output filters to detect sensitive information, toxic content, or code injection.</p></li><li><p>Set up rate limiting per user to prevent abuse.</p></li><li><p>Complete red-teaming exercises to discover vulnerabilities proactively.</p></li><li><p>Integrate a content moderation system for ongoing safety enforcement.</p></li></ul><p><strong>Performance</strong></p><ul><li><p>Verify latency meets targets (p95, p99) for a smooth user experience.</p></li><li><p>Ensure throughput meets expected request volume.</p></li><li><p>Conduct load testing to validate system stability under peak demand.</p></li><li><p>Configure auto-scaling to handle fluctuations in traffic.</p></li></ul><p><strong>Cost Management</strong></p><ul><li><p>Calculate cost per request and ensure it aligns with your budget.</p></li><li><p>Set budget alerts to catch unexpected spikes in usage.</p></li><li><p>Implement cost optimization strategies such as batching, caching, or model routing.</p></li></ul><p><strong>Monitoring &amp; Observability</strong></p><ul><li><p>Log every request and response, including timestamps, latency, tokens, and costs.</p></li><li><p>Track errors and anomalies in real time.</p></li><li><p>Monitor latency and throughput to catch performance regressions early.</p></li><li><p>Collect user feedback for insights on model behavior and satisfaction.</p></li></ul><div><hr></div><p><strong>11.2 Day-One Operations</strong></p><p><strong>Observability</strong></p><ul><li><p>Log all interactions in detail: requests, responses, errors, and resource usage.</p></li><li><p>Monitor critical metrics such as latency, error rates, and token usage to spot anomalies immediately.</p></li></ul><p><strong>Alerts</strong></p><ul><li><p>Configure alerts for latency spikes, error surges, cost anomalies, and API failures.</p></li></ul><p><strong>Fallback Strategies</strong></p><ul><li><p>Use a secondary model if the primary model fails.</p></li><li><p>Queue or retry requests when rate limits are exceeded.</p></li><li><p>Serve cached responses when timeouts occur to maintain continuity.</p></li></ul><div><hr></div><p><strong>11.3 Continuous Improvement</strong></p><p><strong>User Feedback Loop</strong></p><ul><li><p>Collect user ratings (thumbs up/down) for every response.</p></li><li><p>Log prompts, responses, and feedback for analysis.</p></li><li><p>Identify failure patterns and adjust prompts, fine-tune models, or retrain as necessary.</p></li></ul><p><strong>A/B Testing</strong></p><ul><li><p>Split users between prompt or model variations to measure impact.</p></li><li><p>Compare metrics such as quality, latency, and cost.</p></li><li><p>Deploy the winning configuration to the full user base.</p></li></ul><p><strong>Regular Updates</strong></p><ul><li><p>Incorporate new model versions and optimizations.</p></li><li><p>Continuously refine prompts for clarity and efficiency.</p></li><li><p>Update safety measures and moderation systems as new risks emerge.</p></li><li><p>Optimize deployment strategies to reduce cost without sacrificing performance.</p></li></ul><div><hr></div><h4>12. The Future of LLM Deployment</h4><p>The landscape of LLM deployment is evolving rapidly. As models become more capable, practical considerations like cost, latency, and safety drive innovation. Let&#8217;s explore emerging trends and the challenges that lie ahead.</p><p><strong>12.1 Emerging Trends</strong></p><p><strong>1. Smaller, Specialized Models</strong></p><ul><li><p>Models like Phi-2 (2.7B parameters) can match GPT-3.5 on specific tasks, demonstrating that bigger isn&#8217;t always better.</p></li><li><p>Task-specific fine-tuning enables models to excel at narrow domains without massive compute.</p></li><li><p>Using a mixture of smaller, specialized models can outperform a single monolithic model while reducing inference costs.</p></li></ul><p><strong>2. On-Device LLMs</strong></p><ul><li><p>Quantized models running directly on phones or laptops are becoming feasible.</p></li><li><p>On-device deployment offers privacy benefits by keeping user data local.</p></li><li><p>Zero-latency inference becomes possible, enabling instant responses for interactive applications.</p></li></ul><p><strong>3. Multimodal Integration</strong></p><ul><li><p>Future LLMs will seamlessly combine text, images, and audio in one model.</p></li><li><p>Examples include GPT-4V, Gemini, and Claude 3, opening new possibilities for richer and more interactive AI experiences.</p></li></ul><p><strong>4. Agent Ecosystems</strong></p><ul><li><p>LLMs will increasingly act as orchestrators, coordinating multiple tools like web search, code execution, and database queries.</p></li><li><p>This enables complex multi-step workflows and more autonomous AI assistants capable of reasoning, acting, and observing iteratively.</p></li></ul><p><strong>5. Continuous Learning</strong></p><ul><li><p>Models will adapt and improve without full retraining.</p></li><li><p>Personalization will allow AI to adjust to individual user preferences.</p></li><li><p>Continuous learning ensures models stay up-to-date with new information while remaining aligned with desired behaviors.</p></li></ul><div><hr></div><p><strong>12.2 Open Challenges</strong></p><p><strong>1. Reliability</strong></p><ul><li><p>LLMs still hallucinate and can generate factually incorrect responses.</p></li><li><p>Ensuring correctness remains difficult, and better verification mechanisms are needed.</p></li></ul><p><strong>2. Cost</strong></p><ul><li><p>Large-scale deployment remains expensive.</p></li><li><p>Achieving 10x&#8211;100x reductions in inference cost is essential for widespread adoption.</p></li></ul><p><strong>3. Latency</strong></p><ul><li><p>Users expect sub-second response times, but large models are inherently slower.</p></li><li><p>Optimizing inference pipelines and leveraging smaller or hybrid models will be critical.</p></li></ul><p><strong>4. Safety</strong></p><ul><li><p>New jailbreaks and adversarial attacks emerge constantly.</p></li><li><p>Subtle biases are hard to detect, and misuse of powerful models is inevitable.</p></li><li><p>Ongoing vigilance and layered safety mechanisms are required.</p></li></ul><p><strong>5. Evaluation</strong></p><ul><li><p>Measuring LLM quality is challenging.</p></li><li><p>Standard benchmarks often fail to capture real-world performance.</p></li><li><p>Improved metrics and evaluation frameworks are needed to assess usefulness, alignment, and reliability effectively.</p></li></ul><div><hr></div><h3> Closing Thoughts</h3><p>Thanks for sticking with the series and exploring the world of Transformers and LLMs with me. We started with why Transformers came to be, dove into how they work, saw how scaling unlocks new capabilities, and finally covered how to bring them safely and efficiently into production.</p><p>The hope is that this series gives you a clear roadmap not just the theory, but how to think about building and deploying AI responsibly. From alignment and RLHF to RAG, prompting, and optimization, these are the tools and lessons that turn a powerful model into a useful system.</p><p>AI is evolving fast, and there&#8217;s still so much to explore. Keep experimenting, keep questioning, and always prioritize safety and usability.</p><p>Thank you for going through the series , I hope it was as enlightening for you as it was fun to put together. Here&#8217;s to building the next generation of AI thoughtfully and responsibly.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://datajourney24.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DataJourney! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[🚀 Scaling to LLMs: Why Bigger Models Get Smarter]]></title><description><![CDATA[From BERT to GPT-3: Understanding the Scaling Breakthrough]]></description><link>https://datajourney24.substack.com/p/scaling-to-llms-why-bigger-models</link><guid isPermaLink="false">https://datajourney24.substack.com/p/scaling-to-llms-why-bigger-models</guid><dc:creator><![CDATA[Pooja Palod]]></dc:creator><pubDate>Sat, 06 Dec 2025 07:20:21 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!RoqB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c7fe33-ae51-4cde-a945-adacc22648bc_1080x355.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>What We&#8217;ll Cover</h2><p>In Posts 1 &amp; 2, we understood <strong>how</strong> Transformers work.</p><p>Now comes the most surprising discovery in modern AI:</p><blockquote><p><strong>Making models bigger doesn&#8217;t just make them better at existing tasks ,it makes them capable of entirely new tasks they were never trained for.</strong></p></blockquote><p>This post covers:</p><ul><li><p>The shocking discovery of scaling laws</p></li><li><p>Why bigger models exhibit &#8220;emergent abilities&#8221;</p></li><li><p>Chinchilla laws and compute-optimal training</p></li><li><p>How LLMs are actually trained</p></li><li><p>Infrastructure requirements and costs</p></li><li><p>What happens during pre-training</p></li></ul><p><strong>By the end, you&#8217;ll understand:</strong></p><ul><li><p>Why GPT-3 (175B params) can do things GPT-2 (1.5B) can&#8217;t</p></li><li><p>How to calculate optimal model size for your compute budget</p></li><li><p>The real cost of training frontier models</p></li><li><p>Why &#8220;more data&#8221; became as important as &#8220;more parameters&#8221;</p></li></ul><p>Let&#8217;s dive into the scaling breakthrough that changed everything.</p><div><hr></div><h2>1. The Accidental Discovery: Scaling Laws</h2><h3>1.1 The 2020 Breakthrough</h3><p>In January 2020, OpenAI researchers published a paper that would change AI forever: &#8220;Scaling Laws for Neural Language Models.&#8221;</p><p><strong>What they found:</strong></p><p>Performance improves <strong>predictably</strong> as you scale:</p><ul><li><p>Model size (parameters)</p></li><li><p>Dataset size (tokens)</p></li><li><p>Compute budget (FLOPs)</p></li></ul><p>This wasn&#8217;t just &#8220;bigger is better.&#8221; It was <strong>&#8220;bigger is predictably better in a mathematically precise way.&#8221;</strong></p><h3>1.2 The Three Scaling Axes</h3><p><strong>1. Model Size (N parameters)</strong></p><pre><code><code>10M &#8594; 100M &#8594; 1B &#8594; 10B &#8594; 100B parameters
</code></code></pre><p><strong>2. Dataset Size (D tokens)</strong></p><pre><code><code>1B &#8594; 10B &#8594; 100B &#8594; 1T tokens
</code></code></pre><p><strong>3. Compute Budget (C FLOPs)</strong></p><pre><code><code>10^18 &#8594; 10^21 &#8594; 10^24 FLOPs
</code></code></pre><p><strong>The key insight:</strong> Performance (measured by loss) follows a power law:</p><pre><code><code>Loss &#8733; N^(-&#945;)  where &#945; &#8776; 0.076
Loss &#8733; D^(-&#946;)  where &#946; &#8776; 0.095
Loss &#8733; C^(-&#947;)  where &#947; &#8776; 0.050
</code></code></pre><h3>1.3 What This Means in Practice</h3><p><strong>Example:</strong></p><p>If you have 10x more compute, you should expect:</p><ul><li><p>~40% reduction in loss</p></li><li><p>Significantly better performance on downstream tasks</p></li><li><p><strong>Entirely new capabilities</strong> that weren&#8217;t present before</p></li></ul><p><strong>This was revolutionary</strong> because:</p><ol><li><p>It&#8217;s <strong>predictable</strong> - you can forecast performance before training</p></li><li><p>It&#8217;s <strong>reliable</strong> - holds across architectures and domains</p></li><li><p>It&#8217;s <strong>actionable</strong> - tells you how to allocate resources</p></li></ol><div><hr></div><h2>2. The Chinchilla Correction: We Were Training Wrong</h2><h3>2.1 The 2022 Plot Twist</h3><p>In March 2022, DeepMind dropped a bombshell: &#8220;Training Compute-Optimal Large Language Models&#8221; (Chinchilla paper).</p><p><strong>Their finding:</strong></p><blockquote><p><strong>Most large models were undertrained.</strong></p></blockquote><p><strong>The old approach (GPT-3 era):</strong></p><ul><li><p>Focus on making models HUGE (175B params)</p></li><li><p>Train on relatively little data (300B tokens)</p></li><li><p>&#8220;Bigger model = better model&#8221;</p></li></ul><p><strong>The Chinchilla insight:</strong></p><ul><li><p>You should scale <strong>parameters and data equally</strong></p></li><li><p>GPT-3 should have been trained on 3.7 TRILLION tokens, not 300B</p></li><li><p>Or use a smaller model with the same compute</p></li></ul><h3>2.2 The Compute-Optimal Formula</h3><p>For a given compute budget C:</p><pre><code><code>N_optimal &#8733; C^0.50  (model parameters)
D_optimal &#8733; C^0.50  (training tokens)
</code></code></pre><p><strong>Rule of thumb:</strong></p><p>For every doubling of model size, you should roughly double the training data.</p><h3>2.3 Why This Matters</h3><p><strong>Before Chinchilla:</strong></p><ul><li><p>GPT-3: 175B params, 300B tokens &#8594; Undertrained</p></li><li><p>Gopher: 280B params, 300B tokens &#8594; Severely undertrained</p></li></ul><p><strong>After Chinchilla:</strong></p><ul><li><p>Chinchilla: 70B params, 1.4T tokens &#8594; Compute-optimal, outperformed Gopher</p></li><li><p>LLaMA: 7B-65B params, 1T-1.4T tokens &#8594; Compute-optimal</p></li><li><p>LLaMA 2: 7B-70B params, 2T tokens &#8594; Even more data</p></li></ul><p><strong>The lesson:</strong></p><p>Throwing all your compute into model size is inefficient. You need to balance parameters and training data.</p><p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!RoqB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c7fe33-ae51-4cde-a945-adacc22648bc_1080x355.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!RoqB!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c7fe33-ae51-4cde-a945-adacc22648bc_1080x355.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!RoqB!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c7fe33-ae51-4cde-a945-adacc22648bc_1080x355.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!RoqB!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c7fe33-ae51-4cde-a945-adacc22648bc_1080x355.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!RoqB!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c7fe33-ae51-4cde-a945-adacc22648bc_1080x355.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!RoqB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c7fe33-ae51-4cde-a945-adacc22648bc_1080x355.jpeg" width="1080" height="355" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/91c7fe33-ae51-4cde-a945-adacc22648bc_1080x355.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:355,&quot;width&quot;:1080,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!RoqB!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c7fe33-ae51-4cde-a945-adacc22648bc_1080x355.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!RoqB!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c7fe33-ae51-4cde-a945-adacc22648bc_1080x355.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!RoqB!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c7fe33-ae51-4cde-a945-adacc22648bc_1080x355.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!RoqB!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c7fe33-ae51-4cde-a945-adacc22648bc_1080x355.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>3. Emergent Abilities: The Most Surprising Discovery</h2><h3>3.1 What Are Emergent Abilities?</h3><p><strong>Definition:</strong></p><p>Abilities that are <strong>not present in smaller models</strong> but <strong>suddenly appear</strong> when models cross a certain scale threshold.</p><p><strong>Examples:</strong></p><p><strong>Arithmetic:</strong></p><ul><li><p>GPT-2 (1.5B): Can&#8217;t do 3-digit addition</p></li><li><p>GPT-3 (175B): Can do multi-digit arithmetic</p></li></ul><p><strong>Few-shot learning:</strong></p><ul><li><p>BERT (340M): Needs fine-tuning for new tasks</p></li><li><p>GPT-3 (175B): Can learn from 5-10 examples in context</p></li></ul><p><strong>Chain-of-thought reasoning:</strong></p><ul><li><p>Models &lt;10B: Can&#8217;t break down complex problems</p></li><li><p>Models &gt;60B: Can show step-by-step reasoning</p></li></ul><p><strong>Code generation:</strong></p><ul><li><p>GPT-2: Can&#8217;t write functional code</p></li><li><p>Codex/GPT-3.5: Can write complex programs</p></li></ul><h3>3.2 The Emergence Curve</h3><p>Performance on many tasks follows a <strong>sharp phase transition</strong>:</p><pre><code><code>Model Size:   1B    10B   50B   100B  175B
Performance:  0%    5%    15%   65%   85%
</code></code></pre><p>Notice the jump between 50B and 100B , this is emergence.</p><p><strong>It&#8217;s not gradual improvement. It&#8217;s a sudden unlock.</strong></p><h3>3.3 Why Does Emergence Happen?</h3><p><strong>Three theories:</strong></p><p><strong>Theory 1: Capacity Threshold</strong> Some tasks require a minimum amount of &#8220;reasoning space.&#8221; Below that threshold, the model can&#8217;t represent the solution. Above it, it can.</p><p><strong>Theory 2: Data Coverage</strong> Larger models train longer, seeing more examples. At some point, they&#8217;ve seen enough to generalize.</p><p><strong>Theory 3: Measurement Artifact</strong> Maybe performance improves smoothly, but our metrics (like &#8220;% correct&#8221;) create artificial thresholds.</p><p><strong>The truth:</strong> Probably a combination of all three.</p><h3>3.4 Notable Emergent Abilities</h3><p><strong>1. Multi-step reasoning</strong></p><ul><li><p>&#8220;If John is taller than Mary, and Mary is taller than Sue, who&#8217;s tallest?&#8221;</p></li><li><p>Requires chaining facts , emerges around 50B+ params</p></li></ul><p><strong>2. Instruction following</strong></p><ul><li><p>&#8220;Translate this, but make it formal and use British spelling&#8221;</p></li><li><p>Emerges with scale + instruction tuning</p></li></ul><p><strong>3. Self-correction</strong></p><ul><li><p>&#8220;Actually, let me reconsider...&#8221;</p></li><li><p>Models can critique their own outputs (100B+)</p></li></ul><p><strong>4. In-context learning with many examples</strong></p><ul><li><p>GPT-2: ~3 examples max</p></li><li><p>GPT-3: Can learn from 50+ examples in context</p></li></ul><p><strong>5. Code debugging</strong></p><ul><li><p>Not just writing code, but identifying and fixing bugs</p></li><li><p>Strong emergence around 100B+</p></li></ul><div><hr></div><h2>4. Pre-training: How LLMs Actually Learn</h2><h3>4.1 The Training Objective</h3><p>LLMs are trained with a simple objective:</p><p><strong>Next token prediction</strong> (autoregressive language modeling)</p><pre><code><code>Input:  &#8220;The cat sat on the&#8221;
Target: &#8220;mat&#8221;

Loss = -log P(mat | The cat sat on the)
</code></code></pre><p>That&#8217;s it. No labels. No supervision. Just predict the next token.</p><h3>4.2 Why This Works</h3><p><strong>Intuition:</strong></p><p>To predict the next word well, the model must:</p><ul><li><p>Understand syntax (grammar rules)</p></li><li><p>Learn semantics (word meanings)</p></li><li><p>Build world knowledge (facts about the world)</p></li><li><p>Model reasoning (cause and effect)</p></li></ul><p><strong>Compression = Understanding</strong></p><blockquote><p>&#8220;The better you can compress text, the more you understand it.&#8221;</p></blockquote><p>Next-token prediction is optimal text compression. So models are forced to learn rich representations.</p><h3>4.3 What Models Learn During Pre-training</h3><p><strong>Phase 1: Tokens &amp; Patterns (Epochs 1-10)</strong></p><ul><li><p>Word boundaries</p></li><li><p>Common n-grams</p></li><li><p>Basic syntax</p></li></ul><p><strong>Phase 2: Structure &amp; Grammar (Epochs 10-50)</strong></p><ul><li><p>Parts of speech</p></li><li><p>Sentence structure</p></li><li><p>Subject-verb agreement</p></li></ul><p><strong>Phase 3: Semantics &amp; Facts (Epochs 50-200)</strong></p><ul><li><p>Word meanings in context</p></li><li><p>Factual knowledge</p></li><li><p>Relationships between entities</p></li></ul><p><strong>Phase 4: Reasoning &amp; Abstraction (Epochs 200+)</strong></p><ul><li><p>Logical inference</p></li><li><p>Analogical reasoning</p></li><li><p>Complex pattern recognition</p></li></ul><p><strong>The deeper the training, the more abstract the representations.</strong></p><h3>4.4 Training Data: What Goes In</h3><p><strong>Common Sources:</strong></p><p><strong>1. Common Crawl</strong></p><ul><li><p>Web scrapes (petabytes of text)</p></li><li><p>Noisy, diverse, multilingual</p></li><li><p>Contains everything from blog posts to academic papers</p></li></ul><p><strong>2. Books</strong></p><ul><li><p>Fiction and non-fiction</p></li><li><p>Long-form coherent text</p></li><li><p>Narrative structure</p></li></ul><p><strong>3. Wikipedia</strong></p><ul><li><p>Factual, encyclopedic knowledge</p></li><li><p>Well-structured</p></li><li><p>Regularly updated</p></li></ul><p><strong>4. Academic Papers (ArXiv, PubMed)</strong></p><ul><li><p>Technical knowledge</p></li><li><p>Scientific reasoning</p></li><li><p>Formal writing</p></li></ul><p><strong>5. Code Repositories (GitHub)</strong></p><ul><li><p>For models like Codex</p></li><li><p>Programming logic</p></li><li><p>Documentation</p></li></ul><p><strong>6. Curated Datasets</strong></p><ul><li><p>The Pile (EleutherAI): 825GB, diverse sources</p></li><li><p>C4 (Colossal Clean Crawled Corpus): cleaned Common Crawl</p></li><li><p>RedPajama: Open replication of LLaMA&#8217;s training data</p></li></ul><p><strong>Typical mix for LLMs:</strong></p><ul><li><p>60% Web data (Common Crawl)</p></li><li><p>16% Books</p></li><li><p>10% Wikipedia</p></li><li><p>7% Code</p></li><li><p>7% Academic papers</p></li></ul><h3>4.5 Data Preparation Pipeline</h3><p><strong>Step 1: Collection</strong></p><ul><li><p>Scrape/download massive datasets</p></li><li><p>GPT-3: 570GB compressed &#8594; ~400B tokens</p></li></ul><p><strong>Step 2: Filtering</strong></p><ul><li><p>Remove duplicates (exact and near-duplicates)</p></li><li><p>Filter by quality (perplexity, heuristics)</p></li><li><p>Remove toxic/harmful content</p></li><li><p>Language detection</p></li></ul><p><strong>Step 3: Tokenization</strong></p><ul><li><p>BPE (Byte Pair Encoding) or SentencePiece</p></li><li><p>Build vocabulary (typically 32K-100K tokens)</p></li><li><p>Convert text to token IDs</p></li></ul><p><strong>Step 4: Formatting</strong></p><ul><li><p>Pack sequences to context length (2048, 4096 tokens)</p></li><li><p>Add special tokens ([BOS], [EOS])</p></li><li><p>Shuffle documents</p></li></ul><p><strong>Data quality matters MORE than you think.</strong></p><p>Poor data &#8594; Poor model, regardless of size.</p><div><hr></div><h2>5. Training Infrastructure: The Reality of Scale</h2><h3>5.1 Hardware Requirements</h3><p><strong>Training GPT-3 (175B parameters):</strong></p><p><strong>Hardware:</strong></p><ul><li><p>10,000+ NVIDIA V100 GPUs</p></li><li><p>High-bandwidth interconnects (NVLink, InfiniBand)</p></li><li><p>Petabytes of storage</p></li><li><p>Massive cooling infrastructure</p></li></ul><p><strong>Duration:</strong></p><ul><li><p>Several weeks to months</p></li><li><p>One training run</p></li></ul><p><strong>Cost:</strong></p><ul><li><p>Estimated $4-12 million in compute</p></li><li><p>Plus engineering, power, cooling</p></li></ul><h3>5.2 Distributed Training Strategies</h3><p>Training 175B parameters on one GPU? Impossible.</p><p><strong>Solution: Parallel training</strong></p><p><strong>1. Data Parallelism</strong></p><ul><li><p>Split data across GPUs</p></li><li><p>Each GPU has full model copy</p></li><li><p>Synchronize gradients</p></li></ul><p><strong>Good for:</strong> Small-medium models, lots of data</p><p><strong>2. Model Parallelism</strong></p><ul><li><p>Split model across GPUs</p></li><li><p>Each GPU has part of the model</p></li><li><p>Forward/backward pass requires communication</p></li></ul><p><strong>Good for:</strong> Models that don&#8217;t fit on one GPU</p><p><strong>3. Pipeline Parallelism</strong></p><ul><li><p>Split model into stages</p></li><li><p>Different GPUs handle different layers</p></li><li><p>Micro-batches flow through pipeline</p></li></ul><p><strong>Good for:</strong> Very deep models, reducing idle time</p><p><strong>4. Tensor Parallelism</strong></p><ul><li><p>Split individual tensors (weight matrices) across GPUs</p></li><li><p>Operations computed in parallel, then combined</p></li><li><p>Used in Megatron-LM</p></li></ul><p><strong>Good for:</strong> Largest models (100B+)</p><p><strong>Real implementations use combinations:</strong></p><p>GPT-3 likely used:</p><ul><li><p>Tensor parallelism within nodes</p></li><li><p>Pipeline parallelism across nodes</p></li><li><p>Data parallelism for batch processing</p></li></ul><h3>5.3 Training Stability Tricks</h3><p><strong>Problem:</strong> Training 175B parameter models is fragile.</p><p><strong>Solutions:</strong></p><p><strong>1. Gradient Clipping</strong></p><pre><code><code>torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
</code></code></pre><p>Prevents exploding gradients.</p><p><strong>2. Learning Rate Warmup</strong></p><pre><code><code>Start: lr = 0
Warmup (10K steps): lr increases linearly to max_lr
Decay: lr decreases (cosine or polynomial)
</code></code></pre><p>Prevents early instability.</p><p><strong>3. Mixed Precision Training (FP16 + FP32)</strong></p><ul><li><p>Compute in FP16 (faster, less memory)</p></li><li><p>Keep master weights in FP32 (stability)</p></li><li><p>Loss scaling to prevent underflow</p></li></ul><p><strong>4. Activation Checkpointing</strong></p><ul><li><p>Don&#8217;t store all activations (memory)</p></li><li><p>Recompute during backward pass (compute)</p></li><li><p>Trade-off: 33% slower, 3x less memory</p></li></ul><p><strong>5. Careful Initialization</strong></p><ul><li><p>Scale initial weights by depth</p></li><li><p>Residual connections help gradient flow</p></li></ul><p><strong>6. Batch Size Scaling</strong></p><ul><li><p>Larger batches &#8594; more stable gradients</p></li><li><p>But need to adjust learning rate accordingly</p></li></ul><h3>5.4 The Cost Reality</h3><p><strong>Training costs for frontier models</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!EVNP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e1e704-fb36-4fd7-ac36-ac26c28e64b6_1390x514.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!EVNP!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e1e704-fb36-4fd7-ac36-ac26c28e64b6_1390x514.png 424w, /__u/substackcdn.com/image/fetch/$s_!EVNP!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e1e704-fb36-4fd7-ac36-ac26c28e64b6_1390x514.png 848w, /__u/substackcdn.com/image/fetch/$s_!EVNP!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e1e704-fb36-4fd7-ac36-ac26c28e64b6_1390x514.png 1272w, /__u/substackcdn.com/image/fetch/$s_!EVNP!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e1e704-fb36-4fd7-ac36-ac26c28e64b6_1390x514.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!EVNP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e1e704-fb36-4fd7-ac36-ac26c28e64b6_1390x514.png" width="1390" height="514" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d5e1e704-fb36-4fd7-ac36-ac26c28e64b6_1390x514.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:514,&quot;width&quot;:1390,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:92978,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://datajourney24.substack.com/i/180864817?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e1e704-fb36-4fd7-ac36-ac26c28e64b6_1390x514.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!EVNP!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e1e704-fb36-4fd7-ac36-ac26c28e64b6_1390x514.png 424w, /__u/substackcdn.com/image/fetch/$s_!EVNP!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e1e704-fb36-4fd7-ac36-ac26c28e64b6_1390x514.png 848w, /__u/substackcdn.com/image/fetch/$s_!EVNP!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e1e704-fb36-4fd7-ac36-ac26c28e64b6_1390x514.png 1272w, /__u/substackcdn.com/image/fetch/$s_!EVNP!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e1e704-fb36-4fd7-ac36-ac26c28e64b6_1390x514.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Inference costs are also massive:</strong></p><p>Running ChatGPT for millions of users:</p><ul><li><p>Estimated $700,000/day in compute (early estimates)</p></li><li><p>Need aggressive optimization (quantization, batching)</p></li></ul><p><strong>This is why:</strong></p><ul><li><p>Only a few companies can train frontier models</p></li><li><p>Open-source models lag behind closed ones</p></li><li><p>Efficient inference matters enormously</p></li></ul><div><hr></div><h2>6. Training Dynamics: What Actually Happens</h2><h3>6.1 The Loss Curve</h3><p>Typical loss curve during pre-training:</p><pre><code><code>Epoch:  0     100    200    300    400
Loss:   8.0   3.5    2.1    1.8    1.6
        &#9474;     &#9474;      &#9474;      &#9474;      &#9474;
        &#9474;     &#9474;      &#9474;      &#9474;      &#9492;&#9472; Refinement
        &#9474;     &#9474;      &#9474;      &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472; Reasoning emerges
        &#9474;     &#9474;      &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472; Factual knowledge
        &#9474;     &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472; Grammar learned
        &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472; Random noise
</code></code></pre><p><strong>Key observations:</strong></p><ol><li><p><strong>Fast initial drop</strong> (epochs 0-50): Learning basic patterns</p></li><li><p><strong>Slower improvement</strong> (epochs 50-200): Building knowledge</p></li><li><p><strong>Diminishing returns</strong> (epochs 200+): Refinement, reasoning</p></li></ol><h3>6.2 Scaling Prevents Overfitting (Usually)</h3><p><strong>Surprising fact:</strong></p><p>Large models trained on massive data <strong>rarely overfit</strong>.</p><p><strong>Why?</strong></p><p><strong>1. Underparameterization paradox</strong> Even 175B parameters is &#8220;small&#8221; relative to the complexity of language.</p><p><strong>2. Implicit regularization</strong> SGD has regularization properties.</p><p><strong>3. Data diversity</strong> Training data is so diverse that memorization is difficult.</p><p><strong>But watch out for:</strong></p><ul><li><p>Repeated data (train on same text multiple times)</p></li><li><p>Contamination (test data in training set)</p></li></ul><h3>6.3 Perplexity: The Standard Metric</h3><p><strong>Perplexity = exp(loss)</strong></p><pre><code><code>Loss = 2.0  &#8594;  Perplexity = 7.4
Loss = 1.5  &#8594;  Perplexity = 4.5
Loss = 1.0  &#8594;  Perplexity = 2.7
</code></code></pre><p><strong>Intuition:</strong></p><p>Perplexity of 7.4 means: &#8220;On average, the model is as uncertain as if it were choosing uniformly among 7.4 options.&#8221;</p><p>Lower perplexity = better language modeling.</p><p><strong>Benchmarks:</strong></p><ul><li><p>GPT-2: Perplexity ~30 on test set</p></li><li><p>GPT-3: Perplexity ~20</p></li><li><p>GPT-4: Perplexity ~15 (estimated)</p></li></ul><p>Human-level: ~10-12 perplexity (roughly)</p><div><hr></div><h2>7. Compute-Optimal Training: The Practical Guide</h2><h3>7.1 The Budget Constraint</h3><p><strong>You have: Fixed compute budget C (in FLOPs)</strong></p><p><strong>Question: How should you allocate C?</strong></p><p><strong>Options:</strong></p><ul><li><p>Big model, little data</p></li><li><p>Small model, lots of data</p></li><li><p>Balanced (compute-optimal)</p></li></ul><h3>7.2 The Formula</h3><p>From Chinchilla paper:</p><pre><code><code>Given C compute:
N_optimal = 0.43 &#215; C^0.50  parameters
D_optimal = 0.27 &#215; C^0.50  tokens
</code></code></pre><p><strong>Example:</strong></p><p>You have 10^23 FLOPs (rough GPT-3 budget).</p><pre><code><code>N = 0.43 &#215; (10^23)^0.50 = 43B parameters
D = 0.27 &#215; (10^23)^0.50 = 270B tokens
</code></code></pre><p>GPT-3 used 175B params, 300B tokens &#8594; overparameterized, undertrained.</p><p>Optimal: ~70B params, ~1T tokens.</p><h3>7.3 Real-World Examples</h3><p><strong>LLaMA (Meta, 2023):</strong></p><ul><li><p>Followed Chinchilla scaling</p></li><li><p>7B model: 1T tokens</p></li><li><p>65B model: 1.4T tokens</p></li><li><p><strong>Result:</strong> Outperformed GPT-3 with fewer parameters</p></li></ul><p><strong>LLaMA 2:</strong></p><ul><li><p>Even more training data (2T tokens)</p></li><li><p>Same parameters (7B, 13B, 70B)</p></li><li><p>Better performance</p></li></ul><p><strong>The trend:</strong> More data, compute-optimal sizing.</p><div><hr></div><h2>8. Beyond Scale: What Else Matters?</h2><h3>8.1 Data Quality &gt; Data Quantity (Sometimes)</h3><p><strong>Example: Phi-1 (Microsoft, 2023)</strong></p><ul><li><p>Only 1.3B parameters</p></li><li><p>Trained on <strong>high-quality, curated</strong> code/text</p></li><li><p>Outperformed models 10x larger on code tasks</p></li></ul><p><strong>Lesson:</strong> Clean, high-quality data can partially compensate for size.</p><h3>8.2 Architecture Choices</h3><p><strong>Improvements since original Transformer:</strong></p><p><strong>1. Pre-norm (instead of post-norm)</strong></p><ul><li><p>Better training stability</p></li><li><p>Used in GPT-3, LLaMA</p></li></ul><p><strong>2. SwiGLU (instead of ReLU)</strong></p><ul><li><p>Better activation function</p></li><li><p>Used in PaLM, LLaMA</p></li></ul><p><strong>3. RoPE (instead of sinusoidal PE)</strong></p><ul><li><p>Better positional encoding</p></li><li><p>Used in LLaMA, GPT-NeoX</p></li></ul><p><strong>4. Grouped-Query Attention</strong></p><ul><li><p>Faster inference (less memory)</p></li><li><p>Used in LLaMA 2</p></li></ul><p><strong>These improvements are incremental (5-15% better), not revolutionary.</strong></p><p>Scaling still dominates.</p><h3>8.3 Training Duration</h3><p><strong>Question:</strong> Should you train longer?</p><p><strong>Answer:</strong> It depends on your goal.</p><p><strong>For pre-training:</strong></p><ul><li><p>Chinchilla: Train for exactly 1 epoch (20 tokens per parameter)</p></li><li><p>More epochs &#8594; overfitting risk</p></li></ul><p><strong>For fine-tuning:</strong></p><ul><li><p>Multiple epochs on small datasets is fine</p></li><li><p>Need regularization (dropout, weight decay)</p></li></ul><div><hr></div><h2>9. The Future of Scaling</h2><h3>9.1 Are We Hitting Limits?</h3><p><strong>Data wall:</strong></p><ul><li><p>We&#8217;ve used most of the internet (~1-2T tokens)</p></li><li><p>High-quality data is finite</p></li><li><p>Solution: Synthetic data, multimodal data</p></li></ul><p><strong>Compute wall:</strong></p><ul><li><p>Training GPT-5 might cost $1B+</p></li><li><p>Only a few orgs can afford this</p></li><li><p>Solution: Efficiency, sparsity, better algorithms</p></li></ul><p><strong>Returns diminishing:</strong></p><ul><li><p>Going from 10B &#8594; 100B: Huge gains</p></li><li><p>Going from 100B &#8594; 1T: Smaller gains (per parameter)</p></li><li><p>Solution: Focus on data quality, alignment</p></li></ul><h3>9.2 Alternatives to Pure Scaling</h3><p><strong>1. Mixture of Experts (MoE)</strong></p><ul><li><p>1T total parameters, but only 50B active per input</p></li><li><p>Example: Switch Transformer, GPT-4 (rumored)</p></li></ul><p><strong>2. Retrieval-Augmented Generation (RAG)</strong></p><ul><li><p>Smaller model + external knowledge base</p></li><li><p>More efficient than scaling parameters</p></li></ul><p><strong>3. Distillation</strong></p><ul><li><p>Train small model to mimic large one</p></li><li><p>Retain most performance, fraction of cost</p></li></ul><p><strong>4. Sparse Models</strong></p><ul><li><p>Most weights are zero</p></li><li><p>Activate relevant parts per input</p></li></ul><h3>9.3 The Next Frontier</h3><p><strong>Current paradigm:</strong></p><ul><li><p>Pre-train on massive unlabeled data</p></li><li><p>Fine-tune for specific tasks</p></li><li><p>Scale parameters and data together</p></li></ul><p><strong>Emerging paradigm:</strong></p><ul><li><p>Multimodal pre-training (text + images + audio)</p></li><li><p>Continuous learning (update without full retraining)</p></li><li><p>Agent-based systems (LLMs + tools + memory)</p></li><li><p>Smaller, specialized models (task-specific)</p></li></ul><p><strong>The scaling era isn&#8217;t over, but it&#8217;s evolving.</strong></p><div><hr></div><h2>10. Interview Deep-Dive: Scaling Questions</h2><h3>Q1: What are scaling laws and why do they matter?</h3><p><strong>Answer:</strong> Scaling laws describe the relationship between model performance and three factors: parameters, data, and compute. They follow power laws, meaning performance improves predictably as you scale. This matters because: (1) you can forecast performance before expensive training, (2) you can optimize resource allocation, and (3) it reveals that scale itself unlocks new capabilities, not just better performance.</p><div><hr></div><h3>Q2: What did the Chinchilla paper change?</h3><p><strong>Answer:</strong> Chinchilla showed that most large models were <strong>undertrained</strong>. The optimal strategy is to scale parameters and training data equally (both proportional to compute^0.5). GPT-3 had 175B parameters trained on 300B tokens,it should have been trained on 3.5T tokens, or been smaller. LLaMA followed this: 7B params trained on 1T tokens, outperforming GPT-3 despite being 25x smaller.</p><div><hr></div><h3>Q3: What are emergent abilities?</h3><p><strong>Answer:</strong> Abilities that appear suddenly when models cross a size threshold, not present in smaller models. Examples: multi-step reasoning (emerges ~50B+ params), in-context learning with many examples, code generation, chain-of-thought reasoning. Not gradual improvement sharp phase transitions. Suggests some tasks require minimum &#8220;reasoning capacity&#8221; to solve at all.</p><div><hr></div><h3>Q4: Why does next-token prediction work so well for learning?</h3><p><strong>Answer:</strong> To predict the next token well, a model must learn:</p><ul><li><p>Syntax (grammar rules)</p></li><li><p>Semantics (word meanings)</p></li><li><p>World knowledge (facts)</p></li><li><p>Reasoning (causality, logic)</p></li></ul><p>Next-token prediction is equivalent to optimal text compression. The better you compress, the more you must understand. This unsupervised objective forces the model to learn rich, general representations.</p><div><hr></div><h3>Q5: What&#8217;s the optimal allocation of compute between parameters and data?</h3><p><strong>Answer:</strong> Chinchilla scaling: For compute budget C, optimal is N &#8733; C^0.5 parameters and D &#8733; C^0.5 tokens. Rule of thumb: 20 tokens per parameter. So a 7B model should train on ~140B tokens, a 70B model on ~1.4T tokens. Overparameterized models waste compute.</p><div><hr></div><h3>Q6: How is distributed training done for 100B+ parameter models?</h3><p><strong>Answer:</strong> Combination of:</p><ul><li><p><strong>Tensor parallelism</strong>: Split weight matrices across GPUs</p></li><li><p><strong>Pipeline parallelism</strong>: Split layers across GPUs, micro-batching</p></li><li><p><strong>Data parallelism</strong>: Different batches on different GPUs</p></li><li><p><strong>Mixed precision</strong>: FP16 compute, FP32 master weights</p></li><li><p><strong>Gradient checkpointing</strong>: Recompute activations to save memory</p></li></ul><p>GPT-3 likely used tensor + pipeline + data parallelism across 10,000+ GPUs.</p><div><hr></div><h3>Q7: What&#8217;s the biggest bottleneck in training large models?</h3><p><strong>Answer:</strong> <strong>Communication overhead</strong>. With model/pipeline parallelism, GPUs must constantly exchange activations and gradients. At scale:</p><ul><li><p>GPU-GPU bandwidth matters more than GPU compute</p></li><li><p>Interconnect topology is critical (NVLink, InfiniBand)</p></li><li><p>Communication can dominate total time (50%+ of wall-clock)</p></li></ul><p>This is why specialized AI clusters with high-bandwidth interconnects are essential.</p><div><hr></div><h3>Q8: Why don&#8217;t large models overfit despite having billions of parameters?</h3><p><strong>Answer:</strong> Three reasons:</p><ol><li><p><strong>Underparameterization</strong>: Even 175B params is small relative to language complexity</p></li><li><p><strong>Data diversity</strong>: Training data is so varied that memorization is hard</p></li><li><p><strong>Implicit regularization</strong>: SGD has regularization properties</p></li></ol><p>BUT: Repeated data (multiple epochs on same data) or contamination (test data in training) can cause overfitting.</p><div><hr></div><h3>Q9: What&#8217;s the estimated cost of training GPT-3?</h3><p><strong>Answer:</strong> Estimated $4-12M in compute:</p><ul><li><p>~3.14 &#215; 10^23 FLOPs</p></li><li><p>10,000+ V100 GPUs</p></li><li><p>Several weeks</p></li><li><p>Plus engineering, power, infrastructure</p></li></ul><p>GPT-4 likely cost $100M+. This is why only a few companies (OpenAI, Google, Meta, Anthropic) can train frontier models.</p><div><hr></div><h3>Q10: Are we hitting scaling limits?</h3><p><strong>Answer:</strong> Partially. Three walls:</p><ul><li><p><strong>Data wall</strong>: We&#8217;ve used most high-quality internet text (~1-2T tokens)</p></li><li><p><strong>Compute wall</strong>: Training GPT-5+ might cost $1B+</p></li><li><p><strong>Diminishing returns</strong>: 100B &#8594; 1T gives smaller gains per parameter than 10B &#8594; 100B</p></li></ul><p>Solutions: Better data curation, multimodal training, sparse models (MoE), retrieval augmentation, distillation. Scaling isn&#8217;t over, but pure parameter scaling alone is slowing.</p><div><hr></div><h2>&#10024; The Bigger Picture</h2><p>The scaling breakthrough revealed something profound:</p><p><strong>Intelligence scales with compute.</strong></p><p>Not linearly, not perfectly, but reliably and predictably.</p><p>This changes everything:</p><ul><li><p><strong>For research:</strong> Forecasting capabilities becomes possible</p></li><li><p><strong>For engineering:</strong> Resource allocation becomes scientific</p></li><li><p><strong>For strategy:</strong> Whoever has most compute has an advantage</p></li></ul><p>But scaling isn&#8217;t the only path forward.</p><p><strong>The next era:</strong></p><ul><li><p>Compute-optimal training (Chinchilla paradigm)</p></li><li><p>High-quality data curation</p></li><li><p>Efficient architectures</p></li><li><p>Multimodal models</p></li><li><p>Retrieval + reasoning</p></li><li><p>Smaller, specialized models</p></li></ul><p><strong>The lesson isn&#8217;t &#8220;just make it bigger.&#8221;</strong></p><p>It&#8217;s: <strong>&#8220;Scale intelligently, allocate compute optimally, and focus on data quality as much as model size.&#8221;</strong></p><div><hr></div><h2>&#128218; References &amp; Key Papers</h2><h3><strong>Foundational Scaling Papers</strong></h3><ol><li><p><strong>Kaplan, J., et al. (2020).</strong> &#8220;Scaling Laws for Neural Language Models&#8221;<br><em>arXiv preprint</em><br><a href="https://arxiv.org/abs/2001.08361">Paper</a><br>&#128273; <em>The original scaling laws discovery - essential reading</em></p></li><li><p><strong>Hoffmann, J., et al. (2022).</strong> &#8220;Training Compute-Optimal Large Language Models&#8221; (Chinchilla)<br><em>arXiv preprint</em><br><a href="https://arxiv.org/abs/2203.15556">Paper</a><br>&#128273; <em>Revised scaling laws - showed models were undertrained</em></p></li><li><p><strong>Wei, J., et al. (2022).</strong> &#8220;Emergent Abilities of Large Language Models&#8221;<br><em>TMLR 2022</em><br><a href="https://arxiv.org/abs/2206.07682">Paper</a><br>&#128273; <em>Documents abilities that emerge only at scale</em></p></li></ol><h3><strong>Major LLM Papers</strong></h3><ol start="4"><li><p><strong>Brown, T., et al. (2020).</strong> &#8220;Language Models are Few-Shot Learners&#8221; (GPT-3)<br><em>NeurIPS 2020</em><br><a href="https://arxiv.org/abs/2005.14165">Paper</a><br><em>175B parameters - demonstrated scaling potential</em></p></li><li><p><strong>Touvron, H., et al. (2023).</strong> &#8220;LLaMA: Open and Efficient Foundation Language Models&#8221;<br><em>arXiv preprint</em><br><a href="https://arxiv.org/abs/2302.13971">Paper</a><br><em>Followed Chinchilla scaling - compute-optimal approach</em></p></li><li><p><strong>Touvron, H., et al. (2023).</strong> &#8220;Llama 2: Open Foundation and Fine-Tuned Chat Models&#8221;<br><em>arXiv preprint</em><br><a href="https://arxiv.org/abs/2307.09288">Paper</a><br><em>Extended training data to 2T tokens</em></p></li><li><p><strong>Chowdhery, A., et al. (2022).</strong> &#8220;PaLM: Scaling Language Modeling with Pathways&#8221;<br><em>arXiv preprint</em><br><a href="https://arxiv.org/abs/2204.02311">Paper</a><br><em>Google&#8217;s 540B parameter model</em></p></li><li><p><strong>Rae, J.W., et al. (2021).</strong> &#8220;Scaling Language Models: Methods, Analysis &amp; Insights from Training Gopher&#8221;<br><em>arXiv preprint</em><br><a href="https://arxiv.org/abs/2112.11446">Paper</a><br><em>280B model - pre-Chinchilla approach</em></p></li></ol><h3><strong>Training &amp; Infrastructure</strong></h3><ol start="9"><li><p><strong>Shoeybi, M., et al. (2019).</strong> &#8220;Megatron-LM: Training Multi-Billion Parameter Language Models Using Model Parallelism&#8221;<br><em>arXiv preprint</em><br><a href="https://arxiv.org/abs/1909.08053">Paper</a><br><em>Tensor parallelism for large-scale training</em></p></li><li><p><strong>Narayanan, D., et al. (2021).</strong> &#8220;Efficient Large-Scale Language Model Training on GPU Clusters Using Megatron-LM&#8221;<br><em>SC &#8216;21</em><br><a href="https://arxiv.org/abs/2104.04473">Paper</a><br><em>Pipeline parallelism strategies</em></p></li><li><p><strong>Rajbhandari, S., et al. (2020).</strong> &#8220;ZeRO: Memory Optimizations Toward Training Trillion Parameter Models&#8221;<br><em>SC &#8216;20</em><br><a href="https://arxiv.org/abs/1910.02054">Paper</a><br><em>Memory-efficient training - used in DeepSpeed</em></p></li></ol><h3><strong>Data &amp; Tokenization</strong></h3><ol start="12"><li><p><strong>Gao, L., et al. (2020).</strong> &#8220;The Pile: An 800GB Dataset of Diverse Text for Language Modeling&#8221;<br><em>arXiv preprint</em><br><a href="https://arxiv.org/abs/2101.00027">Paper</a><br><em>Open pre-training dataset</em></p></li><li><p><strong>Raffel, C., et al. (2020).</strong> &#8220;Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer&#8221; (T5)<br><em>JMLR 2020</em><br><a href="https://arxiv.org/abs/1910.10683">Paper</a><br><em>C4 dataset (cleaned Common Crawl)</em></p></li><li><p><strong>Sennrich, R., Haddow, B., &amp; Birch, A. (2016).</strong> &#8220;Neural Machine Translation of Rare Words with Subword Units&#8221;<br><em>ACL 2016</em><br><a href="https://arxiv.org/abs/1508.07909">Paper</a><br><em>Byte Pair Encoding (BPE) - subword tokenization</em></p></li></ol><h3><strong>Emergent Abilities &amp; Reasoning</strong></h3><ol start="15"><li><p><strong>Wei, J., et al. (2022).</strong> &#8220;Chain-of-Thought Prompting Elicits Reasoning in Large Language Models&#8221;<br><em>NeurIPS 2022</em><br><a href="https://arxiv.org/abs/2201.11903">Paper</a><br><em>CoT reasoning - emerges with scale</em></p></li><li><p><strong>Kojima, T., et al. (2022).</strong> &#8220;Large Language Models are Zero-Shot Reasoners&#8221;<br><em>NeurIPS 2022</em><br><a href="https://arxiv.org/abs/2205.11916">Paper</a><br><em>Zero-shot CoT with &#8220;Let&#8217;s think step by step&#8221;</em></p></li></ol><h3><strong>Efficient Alternatives</strong></h3><ol start="17"><li><p><strong>Gunasekar, S., et al. (2023).</strong> &#8220;Textbooks Are All You Need&#8221; (Phi-1)<br><em>arXiv preprint</em><br><a href="https://arxiv.org/abs/2306.11644">Paper</a><br><em>1.3B model with high-quality data outperforms larger models</em></p></li><li><p><strong>Fedus, W., et al. (2021).</strong> &#8220;Switch Transformers: Scaling to Trillion Parameter Models with Simple and Efficient Sparsity&#8221;<br><em>JMLR 2021</em><br><a href="https://arxiv.org/abs/2101.03961">Paper</a><br><em>Mixture of Experts - sparse scaling</em></p></li></ol><h3><strong>Analysis &amp; Interpretability</strong></h3><ol start="19"><li><p><strong>Olsson, C., et al. (2022).</strong> &#8220;In-context Learning and Induction Heads&#8221;<br><em>Transformer Circuits Thread</em><br><a href="https://arxiv.org/abs/2209.11895">Paper</a><br><em>Mechanistic analysis of how models learn in-context</em></p></li><li><p><strong>Schaeffer, R., Miranda, B., &amp; Koyejo, S. (2023).</strong> &#8220;Are Emergent Abilities of Large Language Models a Mirage?&#8221;<br><em>arXiv preprint</em><br><a href="https://arxiv.org/abs/2304.15004">Paper</a><br><em>Questions whether emergence is measurement artifact</em></p></li></ol><h2>What&#8217;s Next?</h2><p>This post covered <strong>why bigger models work</strong> and <strong>how they&#8217;re trained</strong>.</p><p><strong>Next in the series:</strong></p><ul><li><p><strong>Post 4:</strong> From LLMs to Products alignment (instruction tuning, RLHF), inference optimization, and building production systems</p></li></ul><div><hr></div><p><strong>Question for you:</strong> What surprised you most about scaling laws, the predictability, the emergent abilities, or the compute requirements?</p><p>Drop a comment, I read every one.</p><div><hr></div><p><em>If this deep-dive was valuable, share it with someone learning about LLMs. This series documents the full journey from Transformers to production-ready AI systems.</em></p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://datajourney24.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DataJourney! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Inside the Transformer: Attention Mechanisms Deep Dive]]></title><description><![CDATA[Understanding What Happens Inside Each Layer]]></description><link>https://datajourney24.substack.com/p/inside-the-transformer-attention</link><guid isPermaLink="false">https://datajourney24.substack.com/p/inside-the-transformer-attention</guid><dc:creator><![CDATA[Pooja Palod]]></dc:creator><pubDate>Sun, 16 Nov 2025 17:40:26 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!LwVs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dc85f58-2ff0-4091-b8c2-2171cb0ee7ef_1026x1158.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>What We&#8217;ll Cover</h2><p>In Post 1, we understood <strong>why</strong> Transformers emerged and the basic attention formula.</p><p>Now we&#8217;re going deeper:</p><ul><li><p>What actually happens inside a single Transformer layer?</p></li><li><p>How do attention patterns evolve across layers?</p></li><li><p>What&#8217;s the role of feed-forward networks?</p></li><li><p>How does information flow through the entire architecture?</p></li><li><p>What are the practical engineering choices that matter?</p></li></ul><p><strong>By the end, you&#8217;ll understand:</strong></p><ul><li><p>Why Transformers have residual connections everywhere</p></li><li><p>What layer normalization actually does</p></li><li><p>How positional information propagates</p></li><li><p>The difference between encoder and decoder attention patterns</p></li><li><p>Why certain architectural choices (like pre-norm vs post-norm) matter</p></li></ul><p>Let&#8217;s dive in.</p><div><hr></div><h2>1. Anatomy of a Transformer Layer</h2><p>Here&#8217;s what most tutorials show you:</p><pre><code><code>Input &#8594; Self-Attention &#8594; Add &amp; Norm &#8594; Feed-Forward &#8594; Add &amp; Norm &#8594; Output
</code></code></pre><p>Here&#8217;s what actually happens (and why each piece matters):</p><h3>1.1 The Complete Picture</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!LwVs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dc85f58-2ff0-4091-b8c2-2171cb0ee7ef_1026x1158.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!LwVs!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dc85f58-2ff0-4091-b8c2-2171cb0ee7ef_1026x1158.png 424w, /__u/substackcdn.com/image/fetch/$s_!LwVs!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dc85f58-2ff0-4091-b8c2-2171cb0ee7ef_1026x1158.png 848w, /__u/substackcdn.com/image/fetch/$s_!LwVs!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dc85f58-2ff0-4091-b8c2-2171cb0ee7ef_1026x1158.png 1272w, /__u/substackcdn.com/image/fetch/$s_!LwVs!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dc85f58-2ff0-4091-b8c2-2171cb0ee7ef_1026x1158.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!LwVs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dc85f58-2ff0-4091-b8c2-2171cb0ee7ef_1026x1158.png" width="1026" height="1158" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2dc85f58-2ff0-4091-b8c2-2171cb0ee7ef_1026x1158.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1158,&quot;width&quot;:1026,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:272848,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://datajourney24.substack.com/i/179064850?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dc85f58-2ff0-4091-b8c2-2171cb0ee7ef_1026x1158.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!LwVs!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dc85f58-2ff0-4091-b8c2-2171cb0ee7ef_1026x1158.png 424w, /__u/substackcdn.com/image/fetch/$s_!LwVs!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dc85f58-2ff0-4091-b8c2-2171cb0ee7ef_1026x1158.png 848w, /__u/substackcdn.com/image/fetch/$s_!LwVs!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dc85f58-2ff0-4091-b8c2-2171cb0ee7ef_1026x1158.png 1272w, /__u/substackcdn.com/image/fetch/$s_!LwVs!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dc85f58-2ff0-4091-b8c2-2171cb0ee7ef_1026x1158.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>A single Transformer layer has <strong>six distinct operations</strong>:</p><pre><code><code>1. Input (from previous layer or embeddings)
2. Multi-Head Self-Attention
3. Residual Connection + Dropout
4. Layer Normalization
5. Position-wise Feed-Forward Network
6. Residual Connection + Dropout + Layer Normalization
</code></code></pre><p>Let&#8217;s break down each component and understand <strong>why it exists</strong>.</p><div><hr></div><h2>2. Self-Attention: Beyond the Formula</h2><p>In Post 1, we covered the math. Now let&#8217;s understand what it&#8217;s <strong>actually computing</strong>.</p><h3>2.1 The Three Projections: Why QKV?</h3><p>Every token starts as an embedding vector (say, 768 dimensions for BERT).</p><p>We project it into three different spaces:</p><pre><code><code>Q = input @ W_Q  # Query: &#8220;What am I searching for?&#8221;
K = input @ W_K  # Key: &#8220;What am I advertising?&#8221;
V = input @ W_V  # Value: &#8220;What content do I provide?&#8221;
</code></code></pre><p><strong>Why separate projections?</strong></p><p>Think of it like a search engine:</p><ul><li><p><strong>Query (Q):</strong> Your search terms</p></li><li><p><strong>Key (K):</strong> Document titles/metadata</p></li><li><p><strong>Value (V):</strong> Document content</p></li></ul><p>You match Q with K (relevance), then retrieve V (content).</p><p><strong>The non-obvious insight:</strong> Q and K live in the same space (for dot product), but V can be in a completely different space. This separation is crucial for learning.</p><h3>2.2 What Attention Scores Actually Represent</h3><p>When we compute <code>score = Q &#183; K^T / &#8730;d_k</code>, we&#8217;re asking:</p><blockquote><p>&#8220;How much should token i care about token j?&#8221;</p></blockquote><p>But here&#8217;s what&#8217;s not obvious: <strong>these scores are relative, not absolute</strong>.</p><p>After softmax, the attention distribution <strong>must sum to 1</strong>. This means:</p><ul><li><p>High attention to one token &#8594; necessarily lower attention to others</p></li><li><p>Attention is a <strong>resource allocation</strong> problem</p></li><li><p>The model learns what to ignore as much as what to attend to</p></li></ul><p><strong>Example:</strong></p><pre><code><code>Sentence: &#8220;The cat sat on the mat&#8221;
Token &#8220;sat&#8221; attention: [0.05, 0.42, 0.15, 0.18, 0.08, 0.12]
</code></code></pre><p>The 0.42 to &#8220;cat&#8221; isn&#8217;t meaningful in isolation ,it&#8217;s meaningful because it&#8217;s <strong>much higher</strong> than 0.05 to &#8220;The&#8221; and 0.08 to &#8220;the&#8221;.</p><h3>2.3 Attention Patterns Across Layers</h3><p>Here&#8217;s something researchers discovered by visualizing attention in trained models:</p><p><strong>Early layers (1-4):</strong></p><ul><li><p>Focus on local, syntactic patterns</p></li><li><p>Adjacent token attention is high</p></li><li><p>Learn basic grammar (noun-verb, determiner-noun)</p></li></ul><p><strong>Middle layers (5-8):</strong></p><ul><li><p>Learn semantic relationships</p></li><li><p>Longer-range dependencies emerge</p></li><li><p>Capture coreference, entity relationships</p></li></ul><p><strong>Late layers (9-12):</strong></p><ul><li><p>Task-specific patterns</p></li><li><p>Very focused attention (sparse patterns)</p></li><li><p>Often just propagating information</p></li></ul><p><strong>This hierarchical learning wasn&#8217;t explicitly programmed it emerged from training</strong></p><h3>2.4 The Mystery of Attention Heads</h3><p>In an 8-head attention setup, here&#8217;s what researchers found heads learn:</p><p><strong>Head 1:</strong> Might attend to the next token (positional) </p><p><strong>Head 2:</strong> Might attend to the previous token (positional) </p><p><strong>Head 3:</strong> Might attend to sentence boundaries</p><p> <strong>Head 4:</strong> Might focus on verbs when processing subjects </p><p><strong>Head 5:</strong> Might track coreference (&#8221;it&#8221; &#8594; &#8220;cat&#8221;) <strong>Head 6-8:</strong> Often less interpretable, learning complex patterns</p><p><strong>The controversial part:</strong> Not all heads are equally important. Some heads can be <strong>pruned</strong> with minimal performance loss.</p><p>Why keep 8 heads then? <strong>Redundancy and specialization.</strong> </p><p>During training, different heads explore different patterns. By the end, some become critical, others provide insurance.</p><div><hr></div><h2>3. Layer Normalization: The Unsung Hero</h2><p>Layer normalization is often treated as a boring implementation detail. It&#8217;s not. It&#8217;s <strong>critical</strong> to making Transformers trainable.</p><h3>3.1 What It Does</h3><p>For each token, independently:</p><pre><code><code>mean = x.mean(dim=-1, keepdim=True)
std = x.std(dim=-1, keepdim=True)
x_norm = (x - mean) / (std + epsilon)
output = gamma * x_norm + beta  # Learnable parameters
</code></code></pre><p>This normalizes across the embedding dimension (not across the batch or sequence).</p><h3>3.2 Why It Matters</h3><p><strong>Problem without LayerNorm:</strong></p><p>As you stack layers, activations can grow or shrink dramatically. By layer 12, some dimensions might be 100x larger than others. This creates:</p><ul><li><p>Gradient instability</p></li><li><p>Difficulty in learning</p></li><li><p>Slow convergence</p></li></ul><p><strong>LayerNorm fixes this</strong> by keeping activations in a stable range.</p><h3>3.3 Pre-Norm vs Post-Norm</h3><p>This is one of those details that matters more than you&#8217;d think.</p><p><strong>Post-Norm (Original Transformer):</strong></p><pre><code><code>x = LayerNorm(x + SelfAttention(x))
x = LayerNorm(x + FFN(x))
</code></code></pre><p><strong>Pre-Norm (Modern LLMs like GPT-3):</strong></p><pre><code><code>x = x + SelfAttention(LayerNorm(x))
x = x + FFN(LayerNorm(x))
</code></code></pre><p><strong>Why Pre-Norm won:</strong></p><ol><li><p><strong>Gradient flow:</strong> Cleaner gradient path through residual connections</p></li><li><p><strong>Stability:</strong> Easier to train very deep models (100+ layers)</p></li><li><p><strong>No warm-up needed:</strong> Can use higher learning rates from the start</p></li></ol><p>GPT-3, LLaMA, and most modern LLMs use Pre-Norm.</p><div><hr></div><h2>4. Residual Connections: Why They&#8217;re Everywhere</h2><p>Every Transformer layer has <strong>two</strong> residual connections:</p><pre><code><code>x = x + SelfAttention(x)
x = x + FeedForward(x)
</code></code></pre><h3>4.1 The Gradient Superhighway</h3><p>Without residual connections, the gradient for layer 1 would need to flow through:</p><ul><li><p>12 self-attention blocks</p></li><li><p>12 feed-forward blocks</p></li><li><p>24 normalizations</p></li></ul><p>That&#8217;s 48+ operations. Gradients would vanish.</p><p><strong>With residual connections:</strong> The gradient can flow directly from output to input, bypassing all intermediate operations.</p><p>Think of it as:</p><ul><li><p><strong>Residual path:</strong> Gradient superhighway (direct route)</p></li><li><p><strong>Attention/FFN path:</strong> Side roads (optional detours)</p></li></ul><p>The model learns <strong>deltas</strong> (changes) rather than full transformations.</p><h3>4.2 What Residual Streams Actually Learn</h3><p>Here&#8217;s a mental model that helps:</p><p>Each layer adds a small update:</p><pre><code><code>Layer 1: base_representation + small_update_1
Layer 2: base_representation + small_update_1 + small_update_2
...
Layer 12: base_representation + &#931;(all updates)
</code></code></pre><p>Early layers can learn low-level features, later layers refine them, and all information is preserved through the residual stream.</p><p><strong>This is why Transformers can be so deep</strong> , each layer makes a small, additive contribution.</p><div><hr></div><h2>5. Feed-Forward Networks: The Hidden Workhorse</h2><p>After attention, every layer has a position-wise feed-forward network:</p><pre><code><code>FFN(x) = max(0, x @ W1 + b1) @ W2 + b2
</code></code></pre><p>Two linear layers with a ReLU in between.</p><h3>5.1 Why Do We Need FFN After Attention?</h3><p>Attention is great at <strong>routing information</strong> between tokens. But it&#8217;s terrible at <strong>transforming</strong> that information.</p><p><strong>Attention:</strong> &#8220;Gather relevant info from other tokens&#8221; <strong>FFN:</strong> &#8220;Process and transform that gathered info&#8221;</p><p>Think of it as:</p><ul><li><p><strong>Attention:</strong> Communication between tokens</p></li><li><p><strong>FFN:</strong> Computation within each token</p></li></ul><h3>5.2 The Hidden Dimension Expansion</h3><p>Here&#8217;s a key detail: the FFN has a hidden dimension that&#8217;s <strong>4x larger</strong> than the model dimension.</p><p>For a model with d=768:</p><ul><li><p>Input: 768 dimensions</p></li><li><p>Hidden layer: 3072 dimensions (4x expansion)</p></li><li><p>Output: 768 dimensions</p></li></ul><p><strong>Why expand then compress?</strong></p><p>The expansion gives the model <strong>expressive capacity</strong>. It can compute complex, non-linear transformations in that higher-dimensional space.</p><p><strong>Analogy:</strong> It&#8217;s like spreading out your work on a large table (3072-dim space) to do complex operations, then neatly packing it back into a small box (768-dim).</p><h3>5.3 Where Parameters Live</h3><p>Here&#8217;s a surprise: <strong>Most parameters are in the FFN, not attention.</strong></p><p>For BERT-base (110M parameters):</p><ul><li><p><strong>Attention:</strong> ~25M parameters (22%)</p></li><li><p><strong>FFN:</strong> ~75M parameters (68%)</p></li><li><p><strong>Embeddings + other:</strong> ~10M parameters (10%)</p></li></ul><p>The FFN is doing most of the heavy lifting in terms of parameter count.</p><div><hr></div><h2>6. Complete Layer Flow: Putting It All Together</h2><p>Let&#8217;s trace a single token through one Transformer layer:</p><pre><code><code>1. Input: [768-dim vector]

2. Multi-Head Attention:
   - Split into 8 heads (96-dim each)
   - Each head: Q, K, V projections &#8594; attention &#8594; weighted sum
   - Concatenate 8 heads back to 768-dim
   - Output projection

3. Residual + Dropout:
   - Add input to attention output
   - Apply dropout (random zero out during training)

4. Layer Norm:
   - Normalize across 768 dimensions

5. Feed-Forward:
   - Project to 3072-dim
   - ReLU activation
   - Project back to 768-dim

6. Residual + Dropout + Layer Norm:
   - Add previous output to FFN output
   - Apply dropout
   - Normalize

7. Output: [768-dim vector] &#8594; fed into next layer
</code></code></pre><p><strong>Key insight:</strong> The vector stays 768-dimensional throughout. It&#8217;s continuously being:</p><ul><li><p>Mixed with other tokens (attention)</p></li><li><p>Transformed (FFN)</p></li><li><p>Refined (layer norm)</p></li><li><p>Preserved (residual connections)</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!DqId!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d58173e-117b-49d8-9658-64dba3b23c97_1270x5218.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!DqId!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d58173e-117b-49d8-9658-64dba3b23c97_1270x5218.png 424w, /__u/substackcdn.com/image/fetch/$s_!DqId!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d58173e-117b-49d8-9658-64dba3b23c97_1270x5218.png 848w, /__u/substackcdn.com/image/fetch/$s_!DqId!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d58173e-117b-49d8-9658-64dba3b23c97_1270x5218.png 1272w, /__u/substackcdn.com/image/fetch/$s_!DqId!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d58173e-117b-49d8-9658-64dba3b23c97_1270x5218.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!DqId!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d58173e-117b-49d8-9658-64dba3b23c97_1270x5218.png" width="1270" height="5218" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4d58173e-117b-49d8-9658-64dba3b23c97_1270x5218.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:5218,&quot;width&quot;:1270,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2098128,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://datajourney24.substack.com/i/179064850?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d58173e-117b-49d8-9658-64dba3b23c97_1270x5218.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!DqId!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d58173e-117b-49d8-9658-64dba3b23c97_1270x5218.png 424w, /__u/substackcdn.com/image/fetch/$s_!DqId!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d58173e-117b-49d8-9658-64dba3b23c97_1270x5218.png 848w, /__u/substackcdn.com/image/fetch/$s_!DqId!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d58173e-117b-49d8-9658-64dba3b23c97_1270x5218.png 1272w, /__u/substackcdn.com/image/fetch/$s_!DqId!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d58173e-117b-49d8-9658-64dba3b23c97_1270x5218.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>7. Positional Information: How It Propagates</h2><p>In Post 1, we added positional encodings at the input. But here&#8217;s the question: <strong>how does position information survive through 12 layers?</strong></p><h3>7.1 Positional Encodings Don&#8217;t Disappear</h3><p>Once added at the input, positional information flows through:</p><ul><li><p><strong>Residual connections:</strong> Preserve the original positional signal</p></li><li><p><strong>Attention:</strong> Can learn position-dependent patterns (e.g., &#8220;pay more attention to nearby tokens&#8221;)</p></li><li><p><strong>FFN:</strong> Can condition transformations on position</p></li></ul><p><strong>The model learns to use positional information, but it&#8217;s not forced to.</strong></p><h3>7.2 Modern Alternatives: RoPE (Rotary Position Embeddings)</h3><p>Models like LLaMA use RoPE instead of sinusoidal encodings.</p><p><strong>Key difference:</strong></p><ul><li><p>Sinusoidal: Add position info to embeddings</p></li><li><p>RoPE: Rotate Q and K vectors based on position</p></li></ul><p><strong>Why RoPE is better:</strong></p><ol><li><p>Position info is <strong>baked into the attention mechanism</strong> itself</p></li><li><p>Better extrapolation to longer sequences</p></li><li><p>Relative position is more naturally represented</p></li></ol><p><strong>Formula (simplified):</strong></p><pre><code><code>Q_rotated = rotate(Q, position_m)
K_rotated = rotate(K, position_n)
attention_score = Q_rotated &#183; K_rotated^T
</code></code></pre><p>The dot product automatically captures relative position (m - n).</p><div><hr></div><h2>8. Encoder vs Decoder: Attention Pattern Differences</h2><h3>8.1 Encoder (BERT-style): Bidirectional Attention</h3><p><strong>Every token can attend to every other token</strong>, including future tokens.</p><pre><code><code>&#8220;The cat sat on the mat&#8221;

&#8220;cat&#8221; can attend to: [The, cat, sat, on, the, mat]
</code></code></pre><p><strong>Use case:</strong> Understanding tasks (classification, NER, Q&amp;A) You need full context to understand meaning.</p><h3>8.2 Decoder (GPT-style): Causal Attention</h3><p><strong>Token i can only attend to tokens 1...i</strong> (no peeking at future).</p><p>This is enforced via an <strong>attention mask</strong>:</p><pre><code><code>Attention mask (lower triangular):
1 0 0 0 0 0
1 1 0 0 0 0
1 1 1 0 0 0
1 1 1 1 0 0
1 1 1 1 1 0
1 1 1 1 1 1
</code></code></pre><p>Before softmax, we set masked positions to -&#8734;, so they get zero attention.</p><p><strong>Why causal?</strong> For autoregressive generation (predicting next token), the model shouldn&#8217;t cheat by looking ahead.</p><h3>8.3 Encoder-Decoder (T5-style): Cross-Attention</h3><p><strong>Decoder attends to encoder outputs:</strong></p><pre><code><code>Encoder: Processes input bidirectionally
Decoder: 
  - Self-attention (causal) on output tokens
  - Cross-attention to encoder outputs
  - Generates output autoregressively
</code></code></pre><p><strong>Cross-attention mechanism:</strong></p><ul><li><p><strong>Q:</strong> From decoder</p></li><li><p><strong>K, V:</strong> From encoder outputs</p></li></ul><p>This allows the decoder to &#8220;look at&#8221; the input while generating output.</p><div><hr></div><h2>9. What Makes Attention &#8220;Learn&#8221;?</h2><h3>9.1 Attention is Learned, Not Programmed</h3><p>The matrices W^Q, W^K, W^V are <strong>learned through backpropagation</strong>.</p><p>Initially (random initialization):</p><ul><li><p>Attention is nearly uniform</p></li><li><p>All tokens attend equally to all others</p></li><li><p>Model is useless</p></li></ul><p>During training:</p><ul><li><p>Gradients flow through attention scores</p></li><li><p>Model learns: &#8220;When I see X, attend strongly to Y&#8221;</p></li><li><p>Useful patterns emerge</p></li></ul><p><strong>The model discovers</strong> that:</p><ul><li><p>Verbs should attend to subjects</p></li><li><p>Pronouns should attend to their referents</p></li><li><p>Adjectives should attend to nouns</p></li><li><p>etc.</p></li></ul><p>None of this is hardcoded.</p><h3>9.2 The Softmax Bottleneck</h3><p>Here&#8217;s a limitation not often discussed:</p><p>Softmax forces attention to be a <strong>probability distribution</strong> (sums to 1).</p><p>This creates a bottleneck:</p><ul><li><p>If you need to attend strongly to 5 tokens, each gets ~0.2 attention</p></li><li><p>If you need to attend to 1 token, it gets ~1.0 attention</p></li></ul><p>For very long sequences, this becomes problematic. You might need information from 10 different tokens, but softmax forces you to distribute attention thinly.</p><p><strong>Solutions in research:</strong></p><ul><li><p>Sparse attention (attend to subsets)</p></li><li><p>Multi-query attention (share K, V across heads)</p></li><li><p>Attention alternatives (Mamba, RWKV)</p></li></ul><div><hr></div><h2>10. Engineering Choices That Matter</h2><h3>10.1 Dropout Placement</h3><p>Dropout is applied in <strong>three places</strong>:</p><ol><li><p>After attention output projection</p></li><li><p>After FFN output projection</p></li><li><p>Sometimes on attention weights themselves</p></li></ol><p><strong>Why?</strong> Regularization. Prevents overfitting by randomly dropping connections during training.</p><p><strong>Typical values:</strong> 0.1 (drop 10% of activations)</p><h3>10.2 Activation Functions</h3><p><strong>Original Transformer:</strong> ReLU in FFN <strong>Modern LLMs:</strong> GELU (Gaussian Error Linear Unit) or SwiGLU</p><p><strong>Why GELU?</strong></p><ul><li><p>Smoother gradients</p></li><li><p>Better empirical performance</p></li><li><p>Used in BERT, GPT-3, etc.</p></li></ul><p><strong>Formula:</strong></p><pre><code><code>GELU(x) = x * &#934;(x)  where &#934; is Gaussian CDF
</code></code></pre><p>Approximately: <code>0.5 * x * (1 + tanh(&#8730;(2/&#960;) * (x + 0.044715 * x&#179;)))</code></p><h3>10.3 Initialization</h3><p>Getting initialization right is crucial:</p><p><strong>Xavier/Glorot initialization:</strong></p><pre><code><code>W ~ N(0, 2/(d_in + d_out))
</code></code></pre><p><strong>Why it matters:</strong></p><ul><li><p>Too small &#8594; vanishing activations</p></li><li><p>Too large &#8594; exploding activations</p></li></ul><p>Modern Transformers often use scaled initialization where deeper layers get smaller initial weights.</p><h3>10.4 Learning Rate Schedules</h3><p><strong>Warmup + Decay:</strong></p><pre><code><code>1. Linear warmup: 0 &#8594; max_lr (first 4000-10000 steps)
2. Inverse square root decay: lr &#8733; 1/&#8730;step
</code></code></pre><p><strong>Why warmup?</strong> Early in training, large gradients can destabilize the model. Warmup lets the model &#8220;settle&#8221; before full-speed training.</p><div><hr></div><h2>11. Visualizing Attention: What Works, What Doesn&#8217;t</h2><h3>11.1 Attention Heatmaps</h3><p>Common visualization: plot attention weights as a matrix.</p><p><strong>What it shows:</strong> Which tokens attend to which <strong>What it doesn&#8217;t show:</strong> What information is actually extracted</p><p><strong>Limitation:</strong> High attention &#8800; high importance for the final prediction</p><h3>11.2 Better Interpretability Methods</h3><p><strong>1. Attention Rollout</strong> Combine attention across layers to see end-to-end paths</p><p><strong>2. Gradient-based Attribution</strong> Which tokens, when changed, most affect the output?</p><p><strong>3. Probing Classifiers</strong> Train simple classifiers on layer outputs to see what information is encoded</p><p><strong>4. Causal Interventions</strong> Ablate specific attention heads and measure impact</p><div><hr></div><h2>12. Common Misconceptions Revisited</h2><h3>Misconception #1: &#8220;Each layer builds higher-level features&#8221;</h3><p><strong>Reality:</strong> Not always hierarchical. Later layers sometimes undo earlier work or route around it via residual connections.</p><h3>Misconception #2: &#8220;More heads = better&#8221;</h3><p><strong>Reality:</strong> Diminishing returns. 16 heads isn&#8217;t 2x better than 8. Some research shows 4-8 heads is a sweet spot.</p><h3>Misconception #3: &#8220;Attention does all the work&#8221;</h3><p><strong>Reality:</strong> FFN has 3x more parameters and is equally critical. Attention routes information; FFN processes it.</p><h3>Misconception #4: &#8220;Layer norm is just a regularization trick&#8221;</h3><p><strong>Reality:</strong> It&#8217;s fundamental to training stability. Without it, deep Transformers are nearly untrainable.</p><div><hr></div><h2>13. Interview Deep-Dive: Architecture Questions</h2><h3>Q1: Walk me through one forward pass of a Transformer layer.</h3><p><strong>Answer:</strong></p><ol><li><p>Input (d-dim) &#8594; Multi-head attention</p></li><li><p>Add input back (residual) &#8594; Layer norm</p></li><li><p>FFN: d &#8594; 4d &#8594; d with ReLU</p></li><li><p>Add previous output (residual) &#8594; Layer norm</p></li><li><p>Output passed to next layer</p></li></ol><p>Key: Residual connections provide gradient paths; layer norm stabilizes training.</p><div><hr></div><h3>Q2: Why do we need separate Q, K, V projections?</h3><p><strong>Answer:</strong> Attention is computing a weighted sum. Q and K determine weights (via dot product), V provides content. Separating them gives the model flexibility: relevance (Q&#183;K) and content (V) can be learned independently. If we used the same projection, attention would be symmetric and less expressive.</p><div><hr></div><h3>Q3: What&#8217;s the purpose of the FFN after attention?</h3><p><strong>Answer:</strong> Attention is linear in content (weighted sum). FFN adds non-linearity and transformation capacity. Attention routes information between tokens; FFN processes information within each token. Without FFN, the model would be limited to linear combinations.</p><div><hr></div><h3>Q4: Pre-norm vs post-norm, which is better and why?</h3><p><strong>Answer:</strong> Pre-norm is better for deep models:</p><ul><li><p>Cleaner gradient flow through residuals</p></li><li><p>More stable training (no warmup needed)</p></li><li><p>Used in GPT-3, LLaMA, modern LLMs</p></li></ul><p>Post-norm was original design but struggles with very deep models (&gt;24 layers).</p><div><hr></div><h3>Q5: How does positional information propagate through layers?</h3><p><strong>Answer:</strong> Added at input, then:</p><ol><li><p>Residual connections preserve original positional encodings</p></li><li><p>Attention can learn position-dependent patterns</p></li><li><p>Model learns to use or ignore position as needed per layer</p></li></ol><p>Modern approach (RoPE): Rotate Q/K based on position, baking positional info into attention mechanism directly.</p><div><hr></div><h3>Q6: What happens during causal masking in decoder attention?</h3><p><strong>Answer:</strong> Before softmax, set future positions to -&#8734;:</p><pre><code><code>scores = QK^T / &#8730;d_k
scores[i, j] = -&#8734; where j &gt; i  # Mask future
attention = softmax(scores)  # Future positions &#8594; 0
</code></code></pre><p>This prevents token i from attending to tokens after position i, enforcing autoregressive property.</p><div><hr></div><h3>Q7: Why is &#8730;d_k important in scaled dot-product attention?</h3><p><strong>Answer:</strong> Dot product magnitude grows with dimension. For d_k = 512, unscaled dot products can be large (&#177;50), pushing softmax into saturation (extreme outputs like 0.0001, 0.9998). This kills gradients.</p><p>Dividing by &#8730;d_k normalizes variance to ~1, keeping softmax in its &#8220;soft&#8221; regime where gradients are healthy. Critical for trainability.</p><div><hr></div><h3>Q8: How much compute does self-attention use vs FFN?</h3><p><strong>Answer:</strong> Per layer for sequence length n, model dim d:</p><ul><li><p><strong>Self-attention:</strong> O(n&#178; &#183; d) for attention matrix + O(n &#183; d&#178;) for projections</p></li><li><p><strong>FFN:</strong> O(n &#183; d&#178;) typically (d &#8594; 4d &#8594; d)</p></li></ul><p>For short sequences (n &lt; d), FFN dominates compute. For long sequences (n &gt; d), attention dominates.</p><p>In practice: FFN has 3x more parameters but attention has quadratic complexity in n.</p><div><hr></div><h3>Q9: Can you remove attention heads without hurting performance?</h3><p><strong>Answer:</strong> Yes, to some extent. Research shows:</p><ul><li><p>Some heads are redundant (10-20% can be pruned)</p></li><li><p>But most heads contribute something unique</p></li><li><p>Pruning requires careful analysis (can&#8217;t just randomly remove)</p></li><li><p>Some tasks more sensitive than others</p></li></ul><p>Suggests multi-head attention has useful redundancy but isn&#8217;t wasteful.</p><div><hr></div><h3>Q10: What&#8217;s the memory bottleneck during inference?</h3><p><strong>Answer:</strong> <strong>KV cache.</strong> For autoregressive generation:</p><ul><li><p>Store K, V for all previous tokens</p></li><li><p>At each step, attend to cached K, V</p></li></ul><p>Memory: O(n &#183; layers &#183; d) per sequence For 2K context, 32 layers, d=4096: ~1GB per request</p><p>This is why context length is expensive&#8212;it&#8217;s primarily a memory problem, not compute.</p><div><hr></div><h2>14. Practical Takeaways</h2><h3>For Building Systems:</h3><ol><li><p><strong>Pre-norm architecture</strong> for new models (better training stability)</p></li><li><p><strong>GELU/SwiGLU activations</strong> over ReLU (better performance)</p></li><li><p><strong>RoPE positional encoding</strong> for better extrapolation (used in LLaMA)</p></li><li><p><strong>FlashAttention</strong> for memory-efficient training (3x faster, 10x less memory)</p></li><li><p><strong>Gradient checkpointing</strong> to trade compute for memory</p></li></ol><h3>For Understanding Models:</h3><ol><li><p><strong>Attention patterns evolve</strong> across layers (syntactic &#8594; semantic &#8594; task-specific)</p></li><li><p><strong>FFN does most computation</strong> (3x more parameters than attention)</p></li><li><p><strong>Residual connections are critical</strong> for gradient flow</p></li><li><p><strong>Not all attention heads are equal</strong> (some can be pruned)</p></li><li><p><strong>Position information propagates</strong> via residuals and attention</p></li></ol><h3>For Debugging:</h3><ol><li><p><strong>Check attention entropy</strong> (low = too focused, high = too uniform)</p></li><li><p><strong>Visualize attention rollout</strong> for multi-layer paths</p></li><li><p><strong>Monitor gradient norms</strong> (residuals help, but explosions still happen)</p></li><li><p><strong>Probe intermediate layers</strong> to see what&#8217;s learned where</p></li><li><p><strong>Ablate heads/layers</strong> to find critical components</p></li></ol><div><hr></div><h2>&#10024; The Bigger Picture</h2><p>Understanding Transformer internals isn&#8217;t just academic ,it&#8217;s practical:</p><p><strong>For research:</strong></p><ul><li><p>Know what to modify (attention alternatives, FFN variants)</p></li><li><p>Understand scaling properties</p></li><li><p>Debug training issues</p></li></ul><p><strong>For engineering:</strong></p><ul><li><p>Optimize inference (KV cache, attention kernels)</p></li><li><p>Choose architectures (encoder vs decoder)</p></li><li><p>Tune hyperparameters meaningfully</p></li></ul><p><strong>For product:</strong></p><ul><li><p>Understand capabilities and limitations</p></li><li><p>Make informed model selection</p></li><li><p>Predict behavior on edge cases</p></li></ul><p>Every layer refines the representation a bit more. Every attention head captures a different pattern. Every residual connection preserves information flow.</p><p>The beauty is in how simple components compose into powerful systems.</p><div><hr></div><h2>&#128218; References &amp; Further Reading</h2><h3>&#128313; <strong>Foundational &amp; Core Attention Papers</strong></h3><ul><li><p><strong>Bahdanau et al. (2014)</strong> &#8211; <em>Neural Machine Translation by Jointly Learning to Align and Translate</em><br><a href="https://arxiv.org/abs/1409.0473">https://arxiv.org/abs/1409.0473</a></p></li><li><p><strong>Luong et al. (2015)</strong> &#8211; <em>Effective Approaches to Attention-based Neural Machine Translation</em><br><a href="https://arxiv.org/abs/1508.04025">https://arxiv.org/abs/1508.04025</a></p></li><li><p><strong>Vaswani et al. (2017)</strong> &#8211; <em>Attention Is All You Need</em> (for multi-head attention formalization)<br><a href="https://arxiv.org/abs/1706.03762">https://arxiv.org/abs/1706.03762</a></p></li></ul><div><hr></div><h3>&#128313; <strong>Technical Deep Dives &amp; Visual Guides</strong></h3><ul><li><p><strong>Jay Alammar &#8211; The Illustrated Attention</strong><br><a href="https://jalammar.github.io/visualizing-neural-machine-translation-mechanisms-and-attention/">https://jalammar.github.io/visualizing-neural-machine-translation-mechanisms-and-attention/</a></p></li><li><p><strong>The Illustrated Transformer (Attention section)</strong><br><a href="https://jalammar.github.io/illustrated-transformer/">https://jalammar.github.io/illustrated-transformer/</a></p></li><li><p><strong>Lilian Weng &#8211; Attention? Attention!</strong><br><a href="https://lilianweng.github.io/posts/2018-06-24-attention/">https://lilianweng.github.io/posts/2018-06-24-attention/</a></p></li><li><p><strong>Harvard NLP &#8211; Annotated Transformer (Attention code walkthrough)</strong><br><a href="http://nlp.seas.harvard.edu/annotated-transformer/">http://nlp.seas.harvard.edu/annotated-transformer/</a></p></li><li><p><strong>Peter Bloem &#8211; Transformers from Scratch (detailed math on attention)</strong><br><a href="https://peterbloem.nl/blog/transformers">https://peterbloem.nl/blog/transformers</a></p></li></ul><div><hr></div><h3>&#128313; <strong>Research &amp; Variants of Attention</strong></h3><ul><li><p><strong>Sparse Transformers (OpenAI, 2019)</strong><br><a href="https://arxiv.org/abs/1904.10509">https://arxiv.org/abs/1904.10509</a></p></li><li><p><strong>Performer: Linear Attention (Choromanski et al., 2020)</strong><br><a href="https://arxiv.org/abs/2009.14794">https://arxiv.org/abs/2009.14794</a></p></li><li><p><strong>Longformer (Beltagy et al., 2020)</strong> &#8211; Local + Global attention pattern<br><a href="https://arxiv.org/abs/2004.05150">https://arxiv.org/abs/2004.05150</a></p></li><li><p><strong>Linformer (Wang et al., 2020)</strong> &#8211; Low-rank self-attention<br><a href="https://arxiv.org/abs/2006.04768">https://arxiv.org/abs/2006.04768</a></p></li></ul><div><hr></div><h3>&#128313; <strong>Videos &amp; Talks</strong></h3><ul><li><p><strong>Yannic Kilcher &#8211; Attention Mechanisms Explained</strong></p></li></ul><ul><li><p><strong>Andrew Ng &#8211; Self-Attention Explanation (DeepLearning.AI)</strong></p></li></ul><ul><li><p><strong>MIT 6.S191 &#8211; Lecture on Attention Mechanisms</strong></p></li></ul><ul><li><p><strong>Karpathy &#8211; &#8220;Let&#8217;s Build Attention From Scratch&#8221; (implicit in GPT lecture)</strong></p></li></ul><div><hr></div><h1>What&#8217;s Next?</h1><p>This post covered <strong>what happens inside a Transformer</strong>. </p><p>Next in the series:</p><ul><li><p><strong>Post 3:</strong> Scaling Laws &amp; Training LLMs</p></li><li><p><strong>Post 4:</strong> Alignment &amp; Production</p></li></ul><div><hr></div><p><em>If this deep-dive was valuable, share it with someone learning ML. This series documents everything I wish I understood when building with Transformers.</em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://datajourney24.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DataJourney! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[🧠 The Need for Transformers]]></title><description><![CDATA[How Attention Revolutionized Deep Learning]]></description><link>https://datajourney24.substack.com/p/the-need-for-transformers</link><guid isPermaLink="false">https://datajourney24.substack.com/p/the-need-for-transformers</guid><dc:creator><![CDATA[Pooja Palod]]></dc:creator><pubDate>Sun, 02 Nov 2025 07:52:09 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!LkAO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57018508-6623-4523-9a8e-9a398744dc6e_1380x2898.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>1. The Breaking Point: When RNNs Hit the Wall</h2><p>For years, sequence modeling was ruled by <strong>RNNs</strong> and <strong>LSTMs</strong>. They were the go-to models for text, speech, and time-series data, anything where order mattered.</p><p>The idea behind them was simple but clever: process data <strong>one step at a time</strong>, and pass information forward through a hidden state. This way, the model could &#8220;remember&#8221; previous inputs as it read new ones.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://datajourney24.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DataJourney! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>It worked well for short sequences. But the cracks appeared quickly.</p><h3>The Real Problems </h3><p><strong>1. Vanishing/Exploding Gradients</strong> - the famous one everyone talks about. But here&#8217;s what matters practically: Even with gradient clipping and LSTMs, you&#8217;re still fighting an uphill battle. Information from token 1 has to survive 100+ sequential transformations to influence token 100. That&#8217;s a game of telephone with exponential decay.</p><p><strong>2. Sequential Bottleneck</strong> - this is the killer. Every step waits for the previous one. Your GPU sits there, mostly idle, processing one token at a time. It&#8217;s like having a 100-lane highway but being forced to drive single-file.</p><p><strong>3. The Hidden State Compression Problem</strong>- here&#8217;s the intuition nobody tells you:</p><blockquote><p>Imagine I tell you a story and ask: &#8220;Now summarize everything important in exactly 512 numbers.&#8221; Then I add more story. &#8220;Okay, still 512 numbers. Don&#8217;t forget the beginning!&#8221;</p><p>That&#8217;s what we asked RNNs to do.</p></blockquote><p>LSTMs added &#8220;gates&#8221; - like giving you permission to forget certain things. Better, but still fundamentally a lossy compression game.</p><h3>The Insight That Changed Everything</h3><p>In 2014, Bahdanau introduced attention for neural machine translation. The key insight wasn&#8217;t the math - it was the <strong>question</strong>:</p><blockquote><p>&#8220;Why compress the entire source sentence into one vector when the decoder can just look back and grab what it needs?&#8221;</p></blockquote><p>It&#8217;s the difference between:</p><ul><li><p>Taking notes on a book, then writing an essay from memory (RNN)</p></li><li><p>Writing an essay with the book open, referencing specific passages (Attention)</p></li></ul><p>But they still used RNNs to process the sequence sequentially.</p><p>In 2017, Vaswani et al. asked the radical question:</p><blockquote><p>&#8220;What if we throw out recurrence entirely and use <em>only</em> attention?&#8221;</p></blockquote><p>That paper  &#8220;Attention Is All You Need&#8221; became the most cited AI paper of the decade.</p><div><hr></div><h2>2. Architecture: Self-Attention Under the Hood</h2><p>Let me show you what actually happens inside a Transformer, with the intuition first, math second.</p><h3>2.1 The Core Idea: Attention as Database Lookup</h3><p>Think of self-attention as a <strong>differentiable database query</strong>.</p><p>Every token in your sequence is simultaneously:</p><ul><li><p><strong>A query</strong> asking: &#8220;What information do I need?&#8221;</p></li><li><p><strong>A key</strong> announcing: &#8220;I contain this type of information&#8221;</p></li><li><p><strong>A value</strong> holding: &#8220;Here&#8217;s my actual content&#8221;</p></li></ul><p>When processing the word &#8220;bank&#8221; in &#8220;I withdrew money from the bank&#8221;, the token:</p><ul><li><p><strong>Queries</strong> for context about transactions, finance</p></li><li><p><strong>Keys</strong> from nearby tokens like &#8220;money&#8221; and &#8220;withdrew&#8221; light up</p></li><li><p><strong>Values</strong> from those tokens flow into &#8220;bank&#8221;&#8217;s new representation</p></li></ul><p>The genius: <strong>every token queries every other token simultaneously</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!LkAO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57018508-6623-4523-9a8e-9a398744dc6e_1380x2898.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!LkAO!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57018508-6623-4523-9a8e-9a398744dc6e_1380x2898.png 424w, /__u/substackcdn.com/image/fetch/$s_!LkAO!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57018508-6623-4523-9a8e-9a398744dc6e_1380x2898.png 848w, /__u/substackcdn.com/image/fetch/$s_!LkAO!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57018508-6623-4523-9a8e-9a398744dc6e_1380x2898.png 1272w, /__u/substackcdn.com/image/fetch/$s_!LkAO!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57018508-6623-4523-9a8e-9a398744dc6e_1380x2898.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!LkAO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57018508-6623-4523-9a8e-9a398744dc6e_1380x2898.png" width="728" height="1528.8" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/57018508-6623-4523-9a8e-9a398744dc6e_1380x2898.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:2898,&quot;width&quot;:1380,&quot;resizeWidth&quot;:728,&quot;bytes&quot;:639563,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://datajourney24.substack.com/i/177778383?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57018508-6623-4523-9a8e-9a398744dc6e_1380x2898.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!LkAO!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57018508-6623-4523-9a8e-9a398744dc6e_1380x2898.png 424w, /__u/substackcdn.com/image/fetch/$s_!LkAO!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57018508-6623-4523-9a8e-9a398744dc6e_1380x2898.png 848w, /__u/substackcdn.com/image/fetch/$s_!LkAO!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57018508-6623-4523-9a8e-9a398744dc6e_1380x2898.png 1272w, /__u/substackcdn.com/image/fetch/$s_!LkAO!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57018508-6623-4523-9a8e-9a398744dc6e_1380x2898.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>2.2 The Math (Now That You Get It)</h3><p>For each token, we create three vectors via learned projections:</p><p><strong>Query (Q):</strong> What am I looking for? <strong>Key (K):</strong> What do I contain?<br><strong>Value (V):</strong> What information do I carry?</p><p>Compute relevance scores between all query-key pairs:</p><pre><code><code>Score(Q_i, K_j) = Q_i &#183; K_j
</code></code></pre><p>Scale to prevent saturation (critical for training stability):</p><pre><code><code>Scaled Score = (Q_i K_j^T) / &#8730;d_k
</code></code></pre><p>Why divide by &#8730;d_k? Because dot products grow with dimensionality. Without scaling, softmax gets extreme values (0.00001, 0.00001, 0.99998) instead of smooth distributions. This kills gradient flow.</p><p>Apply softmax to get attention distribution:</p><pre><code><code>Attention Weights = softmax(QK^T / &#8730;d_k)
</code></code></pre><p>Compute weighted sum of values:</p><pre><code><code>Self-Attention(Q, K, V) = softmax(QK^T / &#8730;d_k)V
</code></code></pre><p> All tokens processed in parallel, one massive matrix multiplication.</p><h3>2.3 Visual: What Attention Actually Looks Like</h3><pre><code><code>Input: &#8220;The cat sat on the mat&#8221;

Token: &#8220;sat&#8221;
&#9500;&#9472; High attention to: &#8220;cat&#8221; (subject), &#8220;mat&#8221; (location)
&#9500;&#9472; Medium attention to: &#8220;on&#8221;, &#8220;the&#8221;
&#9492;&#9472; Low attention to: &#8220;The&#8221; (first token)

Token: &#8220;mat&#8221;  
&#9500;&#9472; High attention to: &#8220;sat&#8221; (action), &#8220;on&#8221; (relation)
&#9500;&#9472; Medium attention to: &#8220;the&#8221; (determiner)
&#9492;&#9472; Low attention to: &#8220;The&#8221;, &#8220;cat&#8221;
</code></code></pre><p>Each token builds a new representation by <strong>pulling information</strong> from relevant tokens, weighted by attention scores.</p><h3>2.4 Multi-Head Attention: Why One Attention Isn&#8217;t Enough</h3><p>Here&#8217;s the non-obvious insight: <strong>different types of relationships matter simultaneously</strong>.</p><p>Consider &#8220;The chef who runs the restaurant cooked the meal&#8221;</p><p>You need to track:</p><ul><li><p><strong>Syntactic structure</strong>: &#8220;who&#8221; refers to &#8220;chef&#8221;, not &#8220;restaurant&#8221;</p></li><li><p><strong>Semantic roles</strong>: &#8220;chef&#8221; is the agent, &#8220;meal&#8221; is the bject</p></li><li><p><strong>Long-range dependencies</strong>: &#8220;cooked&#8221; connects to &#8220;chef&#8221; across 5 words</p></li><li><p><strong>Local context</strong>: &#8220;the restaurant&#8221; is a noun phrase unit</p></li></ul><p>Single attention can&#8217;t capture all these patterns optimally.</p><p><strong>Solution:</strong> Run <strong>h</strong> attention operations in parallel (typically 8-16 heads).</p><pre><code><code>MultiHead(Q,K,V) = Concat(head_1, ..., head_h)W^O

where head_i = Attention(QW_i^Q, KW_i^K, VW_i^V)
</code></code></pre><p>Each head learns different relationship patterns:</p><ul><li><p>Head 1: Subject-verb relationships</p></li><li><p>Head 2: Noun-modifier pairs</p></li><li><p>Head 3: Long-range dependencies</p></li><li><p>Head 4: Positional/sequential patterns</p></li><li><p>...and so on</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!xOWq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b73ac06-9086-4ac7-bcad-4bcf169a65e3_1380x2851.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!xOWq!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b73ac06-9086-4ac7-bcad-4bcf169a65e3_1380x2851.png 424w, /__u/substackcdn.com/image/fetch/$s_!xOWq!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b73ac06-9086-4ac7-bcad-4bcf169a65e3_1380x2851.png 848w, /__u/substackcdn.com/image/fetch/$s_!xOWq!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b73ac06-9086-4ac7-bcad-4bcf169a65e3_1380x2851.png 1272w, /__u/substackcdn.com/image/fetch/$s_!xOWq!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b73ac06-9086-4ac7-bcad-4bcf169a65e3_1380x2851.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!xOWq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b73ac06-9086-4ac7-bcad-4bcf169a65e3_1380x2851.png" width="1380" height="2851" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8b73ac06-9086-4ac7-bcad-4bcf169a65e3_1380x2851.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2851,&quot;width&quot;:1380,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1946976,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://datajourney24.substack.com/i/177778383?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8f37c1d-5ecf-4660-ac57-3ca09bf0ff5d_1380x3036.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!xOWq!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b73ac06-9086-4ac7-bcad-4bcf169a65e3_1380x2851.png 424w, /__u/substackcdn.com/image/fetch/$s_!xOWq!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b73ac06-9086-4ac7-bcad-4bcf169a65e3_1380x2851.png 848w, /__u/substackcdn.com/image/fetch/$s_!xOWq!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b73ac06-9086-4ac7-bcad-4bcf169a65e3_1380x2851.png 1272w, /__u/substackcdn.com/image/fetch/$s_!xOWq!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b73ac06-9086-4ac7-bcad-4bcf169a65e3_1380x2851.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>2.5 Positional Encoding: Teaching Order Without Recurrence</h3><p><strong>Problem:</strong> Self-attention is permutation-invariant. &#8220;Dog bites man&#8221; and &#8220;Man bites dog&#8221; produce identical attention patterns.</p><p><strong>Solution:</strong> Inject position information directly into embeddings.</p><p>The original paper used sinusoidal encodings:</p><pre><code><code>PE(pos, 2i) = sin(pos / 10000^(2i/d_model))
PE(pos, 2i+1) = cos(pos / 10000^(2i/d_model))
</code></code></pre><p>Why sinusoids? Two clever properties:</p><ol><li><p><strong>Relative positions</strong>: PE(pos+k) can be expressed as a linear function of PE(pos)</p></li><li><p><strong>Unbounded length</strong>: Works for any sequence length, no training needed</p></li></ol><p>Modern models often use <strong>learned positional embeddings</strong> (GPT) or <strong>rotary embeddings</strong> (RoPE in LLaMA) which have better extrapolation properties.</p><div><hr></div><h2></h2><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://datajourney24.substack.com/p/the-need-for-transformers?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading DataJourney! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://datajourney24.substack.com/p/the-need-for-transformers?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="/__u/datajourney24.substack.com/p/the-need-for-transformers?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share</span></a></p></div><h2>3. Why This Architecture Won</h2><p>Let me tell you what actually mattered for Transformers&#8217; success  and it&#8217;s not what most people emphasize.</p><h3> Parallelization: The GPU Unlock</h3><p><strong>RNN/LSTM:</strong></p><pre><code><code>Step 1: Process token 1  [GPU: 5% utilized]
Step 2: Process token 2  [GPU: 5% utilized]  
Step 3: Process token 3  [GPU: 5% utilized]
...
Step 512: Process token 512 [GPU: 5% utilized]
</code></code></pre><p><strong>Transformer:</strong></p><pre><code><code>Step 1: Process ALL 512 tokens simultaneously [GPU: 95% utilized]
</code></code></pre><p>This isn&#8217;t just faster  it&#8217;s <strong>2-3 orders of magnitude faster</strong> for long sequences. This is what made GPT-3 (175B parameters) feasible to train.</p><h3> Global Context: See Everything, Attend to What Matters</h3><p>RNNs forced information through a bottleneck. Transformers let every token <strong>directly access</strong> every other token.</p><p>In &#8220;The trophy doesn&#8217;t fit in the suitcase because it&#8217;s too big&#8221;:</p><ul><li><p>LSTM struggles to connect &#8220;it&#8221; &#8594; &#8220;trophy&#8221; across 7 tokens</p></li><li><p>Transformer directly computes attention between &#8220;it&#8221; and both &#8220;trophy&#8221; and &#8220;suitcase&#8221;</p></li></ul><p>The model learns &#8220;big&#8221; + &#8220;doesn&#8217;t fit&#8221; &#8594; probably referring to trophy, not suitcase.</p><h3>Engineering Beauty: Why Systems Engineers Love Transformers</h3><ol><li><p><strong>Stateless:</strong> No hidden state to serialize/deserialize between steps</p></li><li><p><strong>Cacheable:</strong> In autoregressive generation, previous token representations are cached (KV cache)</p></li><li><p><strong>Analyzable:</strong> Attention weights are interpretable- you can visualize what the model &#8220;looks at&#8221;</p></li><li><p><strong>Modular:</strong> Easy to swap encoders/decoders, add/remove layers, change attention patterns</p></li></ol><div><hr></div><h2>4. The Complexity Trade-off (And Why We Accept It)</h2><h3>The O(n&#178;) Elephant in the Room</h3><p>Self-attention computes interactions between <strong>all pairs of tokens</strong>:</p><ul><li><p>Sequence length 512: 262,144 interactions</p></li><li><p>Sequence length 2048: 4,194,304 interactions</p></li><li><p>Sequence length 8192: 67,108,864 interactions</p></li></ul><p><strong>Complexity:</strong> O(n&#178; &#183; d) time, O(n&#178;) memory</p><p>For context: RNN is O(n &#183; d&#178;) - linear in sequence length, quadratic in dimension.</p><p>So why did we accept quadratic complexity?</p><p><strong>Three reasons:</strong></p><ol><li><p><strong>GPUs love matrix multiplication</strong> : O(n&#178;) on a GPU is often faster than O(n) on a CPU</p></li><li><p><strong>Most NLP tasks used short sequences</strong> (&#8804;512 tokens) where n&#178; wasn&#8217;t prohibitive</p></li><li><p><strong>The performance gain was massive</strong> - quadratic cost, 10x better accuracy</p></li></ol><h3>Modern Solutions</h3><p>When quadratic became a problem (long documents, DNA sequences, code):</p><p><strong>Sparse Attention</strong> (Longformer, BigBird): Only attend to local neighbors + global tokens + random samples</p><ul><li><p>Reduces complexity to O(n &#183; k) where k &lt;&lt; n</p></li><li><p>Loses some global context</p></li></ul><p><strong>Linear Attention</strong> (Performer, Linformer):<br>Approximate softmax(QK^T)V with lower-rank operations</p><ul><li><p>O(n) complexity</p></li><li><p>Slight accuracy drop</p></li></ul><p><strong>FlashAttention</strong> (2022): Don&#8217;t change the algorithm , optimize GPU memory access patterns</p><ul><li><p>Same O(n&#178;) complexity</p></li><li><p>3x faster, 10x less memory</p></li><li><p>This is what powers 100K+ context windows today</p></li></ul><div><hr></div><h2>5. Interview Deep-Dive: Questions That Matter</h2><h3>Q1. Why did RNNs struggle with long-term dependencies?</h3><p><strong>Surface answer:</strong> Vanishing gradients.</p><p><strong>Deep answer:</strong> Sequential processing creates a <strong>gradient path</strong> of length n. Even with careful initialization and gating (LSTM), each step multiplies by a matrix. After 100+ steps, either:</p><ul><li><p>Products converge to zero (vanishing)</p></li><li><p>Products explode (unbounded)</p></li></ul><p>The gradient w.r.t. token 1 has to flow through 100+ matrix multiplications. Attention creates <strong>direct paths</strong> - gradient flows in O(1) steps regardless of distance.</p><div><hr></div><h3>Q2. What&#8217;s the intuition behind Q, K, V?</h3><p><strong>Analogy:</strong> Search engine.</p><ul><li><p><strong>Query (Q):</strong> Your search terms , what you&#8217;re looking for</p></li><li><p><strong>Key (K):</strong> Document titles/metadata , what each document is about</p></li><li><p><strong>Value (V):</strong> Document content , actual information you retrieve</p></li></ul><p>You compute relevance (Q&#183;K), rank results (softmax), and retrieve content (weighted V).</p><p>Every token is simultaneously searching and being searched.</p><div><hr></div><h3>Q3. Why divide by &#8730;d_k in scaled dot-product attention?</h3><p><strong>Surface answer:</strong> To prevent large dot products.</p><p><strong>The real reason:</strong> Dot product magnitude grows with dimensionality.</p><p>If Q and K are unit-variance, Q&#183;K has variance d_k. For d_k = 512, typical dot products are in range [-50, 50]. After softmax, you get extreme distributions: (0.00001, 0.99998, 0.00001)</p><p>This creates two problems:</p><ol><li><p><strong>Saturation:</strong> Softmax derivatives &#8594; 0, killing gradients</p></li><li><p><strong>Instability:</strong> Small input changes cause massive output swings</p></li></ol><p>Dividing by &#8730;d_k normalizes variance back to 1, keeping softmax in the &#8220;soft&#8221; regime where gradients are healthy.</p><div><hr></div><h3>Q4. How do Transformers enable parallel computation?</h3><p><strong>Key insight:</strong> Attention is a <strong>three-matrix multiplication</strong> problem.</p><pre><code><code>Attention = softmax(QK^T / &#8730;d_k) &#183; V
</code></code></pre><ul><li><p>QK^T: (n &#215; d) &#183; (d &#215; n) &#8594; (n &#215; n) attention matrix</p></li><li><p>softmax: element-wise, fully parallelizable</p></li><li><p>Attention &#183; V: (n &#215; n) &#183; (n &#215; d) &#8594; (n &#215; d) output</p></li></ul><p>All token interactions computed in <strong>one batched operation</strong>. RNNs required n sequential steps.</p><p>Modern GPUs do matrix multiplication at 200+ TFLOPS . Transformers exploit this perfectly.</p><div><hr></div><h3>Q5. What&#8217;s the difference between encoder-only and decoder-only Transformers?</h3><p><strong>Encoder-only (BERT):</strong></p><ul><li><p>Bidirectional attention - each token sees past AND future</p></li><li><p>Good for: classification, NER, Q&amp;A (understanding tasks)</p></li><li><p>Training: Masked language modeling (predict random masked tokens)</p></li></ul><p><strong>Decoder-only (GPT):</strong></p><ul><li><p>Causal attention - token i can only see tokens 1...i (via attention mask)</p></li><li><p>Good for: text generation, completion (generative tasks)</p></li><li><p>Training: Next token prediction (autoregressive language modeling)</p></li></ul><p><strong>Encoder-Decoder (T5, BART):</strong></p><ul><li><p>Encoder: bidirectional on input</p></li><li><p>Decoder: causal, cross-attends to encoder outputs</p></li><li><p>Good for: translation, summarization (seq2seq tasks)</p></li></ul><div><hr></div><h3>Q6. What&#8217;s the main bottleneck of Transformers?</h3><p><strong>Training:</strong> Compute (O(n&#178; &#183; d) attention + O(n &#183; d&#178;) FFN) <strong>Inference:</strong> Memory for KV cache</p><p>At inference, we cache K and V for all previous tokens. For 8K context, 32 layers, d=4096: ~2GB per request. This is why &#8220;context length&#8221; is expensive - it&#8217;s mostly a memory problem.</p><div><hr></div><h3>Q7. Why do we need positional encoding?</h3><p>Self-attention is a <strong>set operation</strong> - order-invariant.</p><p>Without positional info:</p><ul><li><p>&#8220;Dog bites man&#8221; = &#8220;Man bites dog&#8221;</p></li><li><p>&#8220;Not bad&#8221; = &#8220;Bad not&#8221;</p></li></ul><p>Positional encoding adds <strong>order signal</strong> directly to embeddings, so the model can learn position-dependent patterns.</p><p>Why not just use token position as a feature? Because:</p><ol><li><p>Absolute position isn&#8217;t what matters - &#8220;third word&#8221; means nothing</p></li><li><p>Relative position matters more distance and direction between tokens</p></li><li><p>Sinusoidal encoding captures relative position implicitly via phase relationships</p></li></ol><div><hr></div><h3>Q8. How do you handle sequences longer than training length?</h3><p><strong>Problem:</strong> Train on 512 tokens, inference on 2048 tokens.</p><p><strong>Solutions:</strong></p><ol><li><p><strong>Sinusoidal PE:</strong> Extrapolates naturally (original Transformer)</p></li><li><p><strong>Learned PE:</strong> Interpolate embeddings (okay but degraded)</p></li><li><p><strong>ALiBi:</strong> Bias attention by relative distance (no explicit encoding)</p></li><li><p><strong>RoPE:</strong> Rotate Q,K based on position (used in LLaMA, best extrapolation)</p></li></ol><p>Modern long-context models (32K, 100K+) use RoPE + careful finetuning on longer sequences.</p><div><hr></div><h2>The Bigger Picture</h2><p>Transformers didn&#8217;t just improve NLP - they <strong>unified sequence modeling</strong> across domains.</p><p><strong>Same architecture</strong>, different data:</p><ul><li><p>Text &#8594; GPT, BERT, T5</p></li><li><p>Images &#8594; Vision Transformer (ViT)</p></li><li><p>Audio &#8594; Whisper, AudioLM</p></li><li><p>Video &#8594; VideoGPT, Phenaki</p></li><li><p>Molecules &#8594; AlphaFold (protein structures)</p></li><li><p>Code &#8594; Codex, GitHub Copilot</p></li><li><p>Multimodal &#8594; CLIP, Flamingo, GPT-4</p></li></ul><p>The insight: <strong>Everything can be tokenized into sequences</strong>. And attention is a universal way to model relationships.</p><div><hr></div><h2>&#128218; <strong>References &amp; Further Reading</strong></h2><p>Here are some high-quality papers, articles, and visual guides to explore if you want to go deeper:</p><h3>&#128313; <strong>Foundational Papers</strong></h3><ul><li><p><strong>Vaswani et al. (2017)</strong> &#8211; <em>&#8220;<a href="https://arxiv.org/abs/1706.03762">Attention Is All You Need&#8221;</a></em><a href="https://arxiv.org/abs/1706.03762">, NeurIPS 2017</a></p></li><li><p><strong>Bahdanau et al. (2014)</strong> &#8211; <em>&#8220;<a href="https://arxiv.org/abs/1409.0473">Neural Machine Translation by Jointly Learning to Align and Translate&#8221;</a></em></p></li><li><p><strong>Hochreiter &amp; Schmidhuber (1997)</strong> &#8211; <em>&#8220;Long Short-Term Memory&#8221;</em><br><a href="https://www.bioinf.jku.at/publications/older/2604.pdf">https://www.bioinf.jku.at/publications/older/2604.pdf</a></p></li></ul><h3>&#128313; <strong>Technical Deep Dives</strong></h3><ul><li><p><a href="https://jalammar.github.io/illustrated-transformer/">Jay Alammar &#8211; </a><em><a href="https://jalammar.github.io/illustrated-transformer/">&#8220;The Illustrated Transformer&#8221;</a></em></p></li><li><p><a href="https://lilianweng.github.io/posts/2018-06-24-attention/">Lilian Weng &#8211; </a><em><a href="https://lilianweng.github.io/posts/2018-06-24-attention/">&#8220;Attention? Attention!&#8221;</a></em></p></li><li><p><a href="http://nlp.seas.harvard.edu/2018/04/03/attention.html">Harvard NLP &#8211; </a><em><a href="http://nlp.seas.harvard.edu/2018/04/03/attention.html">&#8220;Annotated Transformer (Tensor2Tensor Implementation)&#8221;</a></em></p></li></ul><h3>&#128313; <strong>Videos &amp; Talks</strong></h3><ul><li><p>Yannic Kilcher &#8211; <em>&#8220;Attention Is All You Need &#8211; Paper Explained&#8221;</em> (YouTube)</p></li><li><p>Andrej Karpathy &#8211; <em>&#8220;Let&#8217;s build GPT from scratch&#8221;</em> (YouTube, 2023)</p></li><li><p>DeepLearning.AI &#8211; <em>&#8220;Transformers Explained&#8221;</em> short course by Andrew Ng</p></li></ul><div><hr></div><h2>What&#8217;s Next?</h2><p>This post covered <strong>why</strong> Transformers emerged and <strong>what</strong> makes them tick.</p><p><strong>Next in the series:</strong></p><ul><li><p><strong>Post 2:</strong> Deep dive into attention mechanisms  visualizing heads, understanding learned patterns</p></li><li><p><strong>Post 3:</strong> Scaling laws and emergent abilities why bigger models suddenly get qualitatively smarter</p></li><li><p><strong>Post 4:</strong> From Transformers to LLMs  training objectives, instruction tuning, RLHF</p></li></ul><p><strong>Question for you:</strong> What was the &#8220;aha!&#8221; moment that made Transformers click for you? Drop a comment . I read every one.</p><p><em>If you found this valuable, share it with someone learning ML. This series is my attempt to document everything I wish I knew when I started building with Transformers.</em></p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://datajourney24.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DataJourney! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Deploying Deep Learning Models: From Prototype to Production]]></title><description><![CDATA[&#8220;A model&#8217;s true test begins after training &#8212; when it faces the real world.&#8221;]]></description><link>https://datajourney24.substack.com/p/deploying-deep-learning-models-from</link><guid isPermaLink="false">https://datajourney24.substack.com/p/deploying-deep-learning-models-from</guid><dc:creator><![CDATA[Pooja Palod]]></dc:creator><pubDate>Sun, 19 Oct 2025 11:35:23 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!uy5R!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe99bfe70-ad63-4822-a55f-3dd10d018800_826x826.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p></p><blockquote><p><em>&#8220;A model&#8217;s true test begins after training &#8212; when it faces the real world.&#8221;</em></p></blockquote><p>Welcome to the <strong>final post</strong> in our <strong>Deep Learning Interview Prep Series</strong>!</p><p>We&#8217;ve come a long way from understanding neural networks and backpropagation, through optimization, loss functions, regularization, CNNs, RNNs, and advanced sequence models.<br>Now, it&#8217;s time to wrap it all up by learning how to deploy deep learning models the crucial bridge between research and real-world impact.</p><p>Because a model, no matter how accurate, only creates value when it serves predictions in production.</p><div><hr></div><h2>&#129504; Conceptual Understanding</h2><p>Deployment marks the transition from experimentation to <strong>production-ready systems</strong>. It involves more than saving a model it&#8217;s about ensuring it runs <strong>reliably, efficiently, and at scale</strong>.</p><p>A typical deployment journey starts with training and evaluation, followed by packaging, serving, monitoring, and continuous improvement. Each stage transforms your model from a Jupyter notebook into a living system that supports business decisions or user experiences.</p><p>At its core, model deployment ensures:</p><ul><li><p><strong>Reproducibility:</strong> The same model behaves identically across environments.</p></li><li><p><strong>Scalability:</strong> The system handles growing traffic and data volume.</p></li><li><p><strong>Observability:</strong> Performance, drift, and latency are continuously monitored.</p></li><li><p><strong>Maintainability:</strong> Models can be easily updated or rolled back.</p></li></ul><div><hr></div><h2>&#9881;&#65039; Applied Perspective</h2><p>In practice, deployment varies across use cases.</p><p><strong>Real-time systems</strong>, like fraud detection or language translation, demand millisecond-level responses. These models are optimized for speed often using quantization, distillation, or GPU-backed inference servers.</p><p><strong>Batch systems</strong>, such as recommendation pipelines or risk scoring engines, focus on scalability and throughput. They process large amounts of data periodically and can tolerate higher latency.</p><p><strong>Edge deployments</strong>, like mobile face recognition or IoT sensors, prioritize privacy and low latency under tight hardware constraints.</p><p>Organizations like Netflix deploy TensorFlow Serving for personalized recommendations, while Uber and Lyft host predictive services for ETA and surge forecasting behind APIs. Financial systems run lightweight versions of deep models for high-speed transaction screening.</p><p>Across all these, the goals remain the same consistency, reliability, and observability.</p><div><hr></div><h2>&#129513; System Design Perspective</h2><p>Designing a deep learning deployment pipeline requires blending machine learning and software engineering.</p><p>A production setup typically includes:</p><ol><li><p><strong>Inference Service:</strong> Hosts and serves model predictions through REST or gRPC APIs, often built using frameworks like FastAPI, TensorFlow Serving, or TorchServe.</p></li><li><p><strong>Feature Store:</strong> Ensures that features used during training are computed identically during serving, maintaining parity between offline and online data.</p></li><li><p><strong>Monitoring Layer:</strong> Tracks latency, accuracy, drift, and throughput, alerting teams when performance degrades.</p></li><li><p><strong>Retraining Pipeline:</strong> Automates periodic retraining when data drifts or model decay is detected.</p></li></ol><p>The challenge lies in balancing latency, cost, and accuracy. Real-time serving needs fast inference (often on GPUs), while batch systems can afford slower but cheaper compute.</p><p>An efficient deployment also includes model versioning and rollbacks so newer models can be tested safely alongside older versions, using canary or A/B deployments.</p><div><hr></div><h2>&#9889; Optimization and Monitoring</h2><p>Once deployed, models must stay performant. Over time, they face data drift (changes in input distributions), concept drift (changing relationships between inputs and outputs), and model decay (gradual performance drop).</p><p>Continuous monitoring ensures the model adapts to real-world evolution. Tools like Prometheus, Evidently AI, and MLflow help visualize performance metrics, trigger retraining, and maintain lineage.</p><p>To keep inference efficient, engineers apply:</p><ul><li><p><strong>Quantization:</strong> Reducing precision (e.g., FP32 &#8594; INT8) to speed up inference.</p></li><li><p><strong>Pruning:</strong> Removing redundant connections for smaller, faster models.</p></li><li><p><strong>Knowledge Distillation:</strong> Training smaller &#8220;student&#8221; models from larger &#8220;teacher&#8221; networks to fit deployment constraints.</p></li><li><p><strong>ONNX Conversion:</strong> Exporting models into portable formats to ensure framework compatibility.</p></li></ul><div><hr></div><h2>&#129517; Real-World Trade-offs</h2><p>In production, trade-offs are constant:</p><ul><li><p><strong>Latency vs Accuracy:</strong> Smaller models respond faster but may lose a few points of accuracy.</p></li><li><p><strong>Cost vs Scale:</strong> GPUs deliver high throughput but at higher operational cost.</p></li><li><p><strong>Automation vs Interpretability:</strong> Monitoring and explainability tools improve trust but add overhead.</p></li><li><p><strong>Edge vs Cloud:</strong> Edge inference preserves privacy and speed, while cloud deployments offer flexibility and easier maintenance.</p></li></ul><p>The art lies in aligning these trade-offs with the product&#8217;s business and user needs.</p><div><hr></div><h2>&#127919; Interview Questions</h2><p>1&#65039;&#8419; What are the key challenges in deploying deep learning models?<br>2&#65039;&#8419; How does training differ from inference?<br>3&#65039;&#8419; What techniques help reduce inference latency?<br>4&#65039;&#8419; How would you detect and handle model drift?<br>5&#65039;&#8419; What is the role of a feature store in production ML?<br>6&#65039;&#8419; How do you version and rollback models safely?<br>7&#65039;&#8419; Explain quantization, pruning, and distillation briefly.<br>8&#65039;&#8419; How would you deploy models on the edge?<br>9&#65039;&#8419; What metrics do you track for model health in production?<br>&#128287; How do you design scalable serving architecture for real-time systems?</p><div><hr></div><h2>Solutions</h2><p><strong>Q1. What are the key challenges in deploying deep learning models?</strong><br><strong>A1.</strong> Models are resource-intensive, rely on consistent data pipelines, and must be scalable and reliable. Engineering challenges include latency, cost management, monitoring, and safe version updates.</p><p><strong>Q2. How does training differ from inference?</strong><br><strong>A2.</strong> Training is compute-heavy, iterative, and focuses on learning. Inference is latency-sensitive, optimized for fast predictions, and deployed in production environments.</p><p><strong>Q3. What techniques help reduce inference latency?</strong><br><strong>A3.</strong> Quantization, pruning, knowledge distillation, GPU acceleration, async serving, caching, and pre-loading models in memory all reduce latency.</p><p><strong>Q4. How would you detect and handle model drift?</strong><br><strong>A4.</strong> Monitor input distributions, prediction confidence, and output accuracy. Use statistical tests or frameworks like <strong>Evidently AI</strong>. Retrain the model when significant drift is detected.</p><p><strong>Q5. What is the role of a feature store in production ML?</strong><br><strong>A5.</strong> A feature store ensures <strong>training-serving parity</strong> &#8212; features computed during training are identical during inference, preventing data leakage and inconsistent predictions.</p><p><strong>Q6. How do you version and rollback models safely?</strong><br><strong>A6.</strong> Tools like <strong>MLflow</strong>, <strong>DVC</strong>, or <strong>Kubeflow Pipelines</strong> track model lineage, versions, and input transformations. Canary or A/B deployments allow testing before full rollout, enabling safe rollback if issues occur.</p><p><strong>Q7. Explain quantization, pruning, and distillation briefly.</strong><br><strong>A7.</strong></p><ul><li><p><strong>Quantization:</strong> Reduces weight precision for faster inference.</p></li><li><p><strong>Pruning:</strong> Removes redundant or low-impact weights.</p></li><li><p><strong>Distillation:</strong> Trains smaller models to mimic larger, high-performing models.</p></li></ul><p><strong>Q8. How would you deploy models on the edge?</strong><br><strong>A8.</strong> Use lightweight models with frameworks like <strong>TensorFlow Lite</strong> or <strong>ONNX Runtime</strong>. Edge deployment prioritizes low latency, privacy, and minimal compute footprint.</p><p><strong>Q9. What metrics should be monitored for production models?</strong><br><strong>A9.</strong> Latency, throughput, accuracy, confidence intervals, error rates, and drift metrics are key for maintaining healthy models in production.</p><p><strong>Q10. How do you design scalable serving architecture for real-time systems?</strong><br><strong>A10.</strong> Use stateless inference APIs, load balancers, caching layers, autoscaling clusters, and optimized hardware. Ensure monitoring and retraining pipelines are in place to maintain performance under load.</p><div><hr></div><h2>&#128218; References</h2><ul><li><p><a href="https://www.tensorflow.org/tfx/guide/serving">TensorFlow Serving Documentation</a></p></li><li><p><a href="https://pytorch.org/serve/">TorchServe by PyTorch</a></p></li><li><p><a href="https://onnxruntime.ai/docs/">ONNX Runtime Optimization</a></p></li><li><p><a href="https://evidentlyai.com/">Evidently AI &#8211; Monitoring Models</a></p></li><li><p><a href="https://mlflow.org/">MLflow &#8211; Model Tracking and Deployment</a></p></li></ul><div><hr></div><h2>&#10024; Conclusion</h2><p>This brings us to the end of the Deep Learning Interview Prep Series.</p><p>We&#8217;ve covered everything  from the core building blocks of neural networks to advanced architectures and production systems. You now understand not just how to build deep learning models, but how to make them reliable, scalable, and impactful in real-world applications.</p><p>Deployment isn&#8217;t the end of machine learning it&#8217;s the beginning of its real-world journey.It&#8217;s where research meets engineering, and where theory transforms into tangible value.</p><p>Thank you for following along this series.Up next, we&#8217;ll begin a brand-new exploration: Transformers and the Modern NLP Revolution.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://datajourney24.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DataJourney! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[Advanced Sequence Models: From Bidirectional RNNs to Attention]]></title><description><![CDATA[Welcome back to the Deep Learning Interview Prep Series!]]></description><link>https://datajourney24.substack.com/p/advanced-sequence-models-from-bidirectional</link><guid isPermaLink="false">https://datajourney24.substack.com/p/advanced-sequence-models-from-bidirectional</guid><dc:creator><![CDATA[Pooja Palod]]></dc:creator><pubDate>Sat, 18 Oct 2025 12:44:51 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!uy5R!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe99bfe70-ad63-4822-a55f-3dd10d018800_826x826.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Welcome back to the Deep Learning Interview Prep Series! &#128640;<br>In this article, we&#8217;ll explore advanced sequence models from Bidirectional RNNs to Seq2Seq architectures and Attention mechanisms  building on our previous discussions of RNNs, LSTMs, and GRUs. These models empower deep learning to handle long-term dependencies, bidirectional context, and complex sequence-to-sequence tasks.</p><h2><strong>1. Conceptual Understanding</strong></h2><p>Recurrent Neural Networks (RNNs) were the first models capable of handling <strong>sequential data</strong>, capturing dependencies across time steps.<br>However, traditional RNNs are limited by:</p><ul><li><p><strong>Unidirectional context</strong> &#8211; they only use past information.</p></li><li><p><strong>Vanishing gradients</strong> &#8211; making long-term learning difficult.</p></li><li><p><strong>Fixed-length context vectors</strong> &#8211; causing information bottlenecks for long sequences.</p></li></ul><p>To overcome these, researchers introduced three key advancements:</p><ul><li><p><strong>Bidirectional RNNs (BiRNNs)</strong> &#8211; leverage both past and future context.</p></li><li><p><strong>Sequence-to-Sequence (Seq2Seq)</strong> models &#8211; encode variable-length input/output.</p></li><li><p><strong>Attention mechanisms</strong> &#8211; dynamically focus on relevant parts of the input.</p></li></ul><p>Let&#8217;s unpack each.</p><div><hr></div><h3><strong>1.1 Bidirectional RNNs (BiRNNs)</strong></h3><p>A Bidirectional RNN consists of two RNNs:</p><ul><li><p>one processes the sequence <strong>forward</strong>,</p></li><li><p>the other processes it <strong>backward</strong>.</p></li></ul><p>For input ( x = [x_1, x_2, ..., x_T] ):</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\n\\begin{aligned}\n\\overrightarrow{h_t} &amp;= f(W_x x_t + W_h \\overrightarrow{h_{t-1}} + b) \\\\\n\\overleftarrow{h_t} &amp;= f(W_x x_t + W_h \\overleftarrow{h_{t+1}} + b) \\\\\nh_t &amp;= [\\overrightarrow{h_t}; \\overleftarrow{h_t}]\n\\end{aligned}\n\n&quot;,&quot;id&quot;:&quot;YPKOKTXPKY&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p>This way, every timestep can access <strong>both past and future</strong> context.</p><p><strong>Intuition:</strong><br>In language, meaning often depends on surrounding words.<br>E.g., &#8220;He sat on the <em>bank</em>&#8221;- you only know what &#8220;bank&#8221; means after seeing the next word.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!PdOi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F587f30d8-7037-4199-b4d8-b9c18d8a34e3_544x248.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!PdOi!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F587f30d8-7037-4199-b4d8-b9c18d8a34e3_544x248.png 424w, /__u/substackcdn.com/image/fetch/$s_!PdOi!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F587f30d8-7037-4199-b4d8-b9c18d8a34e3_544x248.png 848w, /__u/substackcdn.com/image/fetch/$s_!PdOi!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F587f30d8-7037-4199-b4d8-b9c18d8a34e3_544x248.png 1272w, /__u/substackcdn.com/image/fetch/$s_!PdOi!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F587f30d8-7037-4199-b4d8-b9c18d8a34e3_544x248.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!PdOi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F587f30d8-7037-4199-b4d8-b9c18d8a34e3_544x248.png" width="544" height="248" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/587f30d8-7037-4199-b4d8-b9c18d8a34e3_544x248.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:248,&quot;width&quot;:544,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Project 10&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Project 10" title="Project 10" srcset="/__u/substackcdn.com/image/fetch/$s_!PdOi!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F587f30d8-7037-4199-b4d8-b9c18d8a34e3_544x248.png 424w, /__u/substackcdn.com/image/fetch/$s_!PdOi!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F587f30d8-7037-4199-b4d8-b9c18d8a34e3_544x248.png 848w, /__u/substackcdn.com/image/fetch/$s_!PdOi!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F587f30d8-7037-4199-b4d8-b9c18d8a34e3_544x248.png 1272w, /__u/substackcdn.com/image/fetch/$s_!PdOi!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F587f30d8-7037-4199-b4d8-b9c18d8a34e3_544x248.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h3><strong>1.2 Sequence-to-Sequence (Seq2Seq) Models</strong></h3><p>Seq2Seq models introduced the <strong>encoder&#8211;decoder architecture</strong>, crucial for tasks like translation and summarization.</p><h4><strong>Encoder</strong></h4><p>Processes the input and compresses it into a context vector:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\n\\begin{aligned}\nh_t^{enc} &amp;= f(W_{enc} x_t + U_{enc} h_{t-1}^{enc}) \\\\\nC &amp;= h_T^{enc}\n\\end{aligned}\n\n&quot;,&quot;id&quot;:&quot;WTDLPRSQOC&quot;}" data-component-name="LatexBlockToDOM"></div><h4><strong>Decoder</strong></h4><p>Generates the output sequence step by step:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\n\\begin{aligned}\ns_t^{dec} &amp;= f(W_{dec} y_{t-1} + U_{dec} s_{t-1}^{dec} + V C)\n\\end{aligned}\n&quot;,&quot;id&quot;:&quot;CRIKEGQQZR&quot;}" data-component-name="LatexBlockToDOM"></div><p> <strong>Limitation:</strong><br>All information is squeezed into the single context vector ( C ), making it hard for long sequences to retain all details.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!dYf-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78e4aee5-a054-41d1-9ed2-bc6294d8ca2e_400x126.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!dYf-!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78e4aee5-a054-41d1-9ed2-bc6294d8ca2e_400x126.png 424w, /__u/substackcdn.com/image/fetch/$s_!dYf-!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78e4aee5-a054-41d1-9ed2-bc6294d8ca2e_400x126.png 848w, /__u/substackcdn.com/image/fetch/$s_!dYf-!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78e4aee5-a054-41d1-9ed2-bc6294d8ca2e_400x126.png 1272w, /__u/substackcdn.com/image/fetch/$s_!dYf-!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78e4aee5-a054-41d1-9ed2-bc6294d8ca2e_400x126.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!dYf-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78e4aee5-a054-41d1-9ed2-bc6294d8ca2e_400x126.png" width="400" height="126" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/78e4aee5-a054-41d1-9ed2-bc6294d8ca2e_400x126.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:126,&quot;width&quot;:400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;9.7. Sequence to Sequence Learning ...&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="9.7. Sequence to Sequence Learning ..." title="9.7. Sequence to Sequence Learning ..." srcset="/__u/substackcdn.com/image/fetch/$s_!dYf-!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78e4aee5-a054-41d1-9ed2-bc6294d8ca2e_400x126.png 424w, /__u/substackcdn.com/image/fetch/$s_!dYf-!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78e4aee5-a054-41d1-9ed2-bc6294d8ca2e_400x126.png 848w, /__u/substackcdn.com/image/fetch/$s_!dYf-!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78e4aee5-a054-41d1-9ed2-bc6294d8ca2e_400x126.png 1272w, /__u/substackcdn.com/image/fetch/$s_!dYf-!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78e4aee5-a054-41d1-9ed2-bc6294d8ca2e_400x126.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div><hr></div><h3><strong>1.3 Attention Mechanism</strong></h3><p>The <strong>Attention Mechanism</strong> (Bahdanau et al., 2014) removed the fixed-context bottleneck.<br>Instead of using a single vector, it allows the decoder to <strong>focus selectively</strong> on relevant encoder states.</p><h4><strong>Computation Steps</strong></h4><ol><li><p><strong>Compute alignment scores:</strong><br></p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;e_{t,i} = s_{t-1}^\\top W_a h_i^{enc}&quot;,&quot;id&quot;:&quot;WIKUNHXXWX&quot;}" data-component-name="LatexBlockToDOM"></div></li><li><p><strong>Convert scores to attention weights:</strong><br></p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\alpha_{t,i} = \\frac{\\exp(e_{t,i})}{\\sum_j \\exp(e_{t,j})}&quot;,&quot;id&quot;:&quot;RXKLZVUOQV&quot;}" data-component-name="LatexBlockToDOM"></div></li><li><p><strong>Compute context vector:</strong><br></p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;c_t = \\sum_i \\alpha_{t,i} h_i^{enc}]&quot;,&quot;id&quot;:&quot;YKBHIQUVRA&quot;}" data-component-name="LatexBlockToDOM"></div></li><li><p><strong>Update decoder hidden state:</strong><br></p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;s_t = f(W_{dec} y_{t-1} + U_{dec} s_{t-1} + V c_t)&quot;,&quot;id&quot;:&quot;MQFBRRNQWE&quot;}" data-component-name="LatexBlockToDOM"></div></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!AvP4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56801d34-0018-43e8-99b7-04823e446f6c_666x494.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!AvP4!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56801d34-0018-43e8-99b7-04823e446f6c_666x494.png 424w, /__u/substackcdn.com/image/fetch/$s_!AvP4!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56801d34-0018-43e8-99b7-04823e446f6c_666x494.png 848w, /__u/substackcdn.com/image/fetch/$s_!AvP4!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56801d34-0018-43e8-99b7-04823e446f6c_666x494.png 1272w, /__u/substackcdn.com/image/fetch/$s_!AvP4!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56801d34-0018-43e8-99b7-04823e446f6c_666x494.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!AvP4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56801d34-0018-43e8-99b7-04823e446f6c_666x494.png" width="666" height="494" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/56801d34-0018-43e8-99b7-04823e446f6c_666x494.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:494,&quot;width&quot;:666,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;A Brief Overview of Attention Mechanism | by Synced | SyncedReview | Medium&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A Brief Overview of Attention Mechanism | by Synced | SyncedReview | Medium" title="A Brief Overview of Attention Mechanism | by Synced | SyncedReview | Medium" srcset="/__u/substackcdn.com/image/fetch/$s_!AvP4!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56801d34-0018-43e8-99b7-04823e446f6c_666x494.png 424w, /__u/substackcdn.com/image/fetch/$s_!AvP4!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56801d34-0018-43e8-99b7-04823e446f6c_666x494.png 848w, /__u/substackcdn.com/image/fetch/$s_!AvP4!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56801d34-0018-43e8-99b7-04823e446f6c_666x494.png 1272w, /__u/substackcdn.com/image/fetch/$s_!AvP4!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56801d34-0018-43e8-99b7-04823e446f6c_666x494.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3><strong>1.4 Types of Attention</strong></h3><ul><li><p><strong>Additive (Bahdanau):</strong> MLP-based alignment.</p></li><li><p><strong>Multiplicative (Luong):</strong> Dot-product based.</p></li><li><p><strong>Self-Attention:</strong> Each token attends to others in the same sequence (foundation of Transformers).</p></li></ul><div><hr></div><h2><strong>2. Applied Perspective</strong></h2><p>Each variant of RNN-based architecture addresses specific limitations of the vanilla RNN and is designed for different real-world sequence modeling scenarios.</p><ul><li><p>Bidirectional RNNs (BiRNNs):<br>These models process the input sequence in both forward and backward directions, allowing the network to understand <em>context from both past and future words</em>. This makes BiRNNs highly effective for <em>sequence labeling tasks</em> like Part-of-Speech (POS) tagging and Named Entity Recognition (NER), where context on both sides matters.</p></li><li><p>Sequence-to-Sequence (Seq2Seq) Models:<br>Seq2Seq architectures consist of an encoder that compresses the input into a context vector and a decoder that generates the output sequence. They handle <em>variable-length input and output</em>, making them foundational in machine translation (e.g., English &#8594; French) and text summarization systems.</p></li><li><p>Seq2Seq with Attention:<br>The attention mechanism enhances Seq2Seq models by allowing the decoder to <em>dynamically focus</em> on the most relevant parts of the input sequence during generation. This not only improves performance on <em>long-context tasks</em> but also provides <em>interpretability</em>. Attention-based models are widely used in translation, image captioning, and question answering systems.</p></li></ul><p>In real-world ML pipelines, these models are often trained with large text or speech datasets and deployed in low-latency environments. While BiRNNs and vanilla Seq2Seqs still perform well for medium-sized problems, attention-based models remain the stepping stone toward Transformers, which dominate today&#8217;s large-scale NLP systems.</p><div><hr></div><h2><strong>3. System Design Perspective</strong></h2><h3><strong>3.1 Choosing the Right Architecture</strong></h3><ul><li><p><strong>BiRNN:</strong> Full-sequence tasks (NLP tagging, speech recognition)</p></li><li><p><strong>Seq2Seq:</strong> Input/output of variable lengths (translation, summarization)</p></li><li><p><strong>Attention:</strong> Long sequences, interpretability, better scalability</p></li></ul><h3><strong>3.2 Trade-offs</strong></h3><ul><li><p><strong>Bidirectional RNNs (BiRNNs):</strong></p><ul><li><p><strong>Context:</strong> Captures both past and future information, giving rich contextual understanding.</p></li><li><p><strong>Latency:</strong> High, since sequences must be processed in both directions.</p></li><li><p><strong>Interpretability:</strong> Medium, provides some insight but not fully transparent.</p></li><li><p><strong>Real-time use:</strong>  Not suitable, as future inputs are needed before producing output.</p></li></ul></li><li><p><strong>Seq2Seq Models:</strong></p><ul><li><p><strong>Context:</strong> Encodes input into a fixed-length vector, summarizing the entire sequence.</p></li><li><p><strong>Latency:</strong> Medium, sequential processing of encoder and decoder steps.</p></li><li><p><strong>Interpretability:</strong> Low, the fixed context vector makes it hard to see what the model focuses on.</p></li><li><p><strong>Real-time use:</strong>  Suitable for streaming tasks with moderate sequence lengths.</p></li></ul></li><li><p><strong>Attention-Based Models:</strong></p><ul><li><p><strong>Context:</strong> Dynamic, allows the model to focus on the most relevant input tokens for each output.</p></li><li><p><strong>Latency:</strong> High, scales roughly with the square of sequence length (O(n&#178;)).</p></li><li><p><strong>Interpretability:</strong> High, attention weights provide insights into  model&#8217;s focus.</p></li><li><p><strong>Real-time use:</strong>  Possible but resource-intensive due to memory and compute requirements.</p></li></ul></li></ul><h3><strong>3.3 Deployment Tips</strong></h3><ul><li><p><strong>Quantization / Pruning</strong> &#8594; smaller footprint</p></li><li><p><strong>Beam Search Optimization</strong> &#8594; faster decoding</p></li><li><p><strong>Caching Encoder Outputs</strong> &#8594; speed up inference</p></li><li><p><strong>Attention Visualization</strong> &#8594; improves explainability</p></li></ul><div><hr></div><h2><strong>4. Interview Questions</strong></h2><p><br>1&#65039;&#8419; Why use Bidirectional RNNs?<br>2&#65039;&#8419; What limits vanilla Seq2Seq performance?<br>3&#65039;&#8419; How does attention fix the context bottleneck?<br>4&#65039;&#8419; Difference between Bahdanau and Luong attention?<br>5&#65039;&#8419; Why can&#8217;t BiRNNs be used for real-time tasks?<br>6&#65039;&#8419; How would you use Seq2Seq for translation?<br>7&#65039;&#8419; How does attention improve image captioning?<br>8&#65039;&#8419; What are practical benefits of attention visualization?<br>9&#65039;&#8419; How to deploy large Seq2Seq models efficiently?<br>&#128287; RNN-based vs Transformer-based production trade-offs?</p><div><hr></div><h2><strong>5. Solutions</strong></h2><p><strong>Q1. Why use Bidirectional RNNs?</strong><br><strong>A:</strong> They process sequences in both forward and backward directions, capturing context from past and future tokens. This improves performance on tasks like POS tagging and NER.</p><p><strong>Q2. What limits vanilla Seq2Seq performance?</strong><br><strong>A:</strong> Vanilla Seq2Seq compresses the input into a single fixed-length context vector, which creates a bottleneck for long sequences and can lead to information loss, reducing translation or summarization quality.</p><p><strong>Q3. How does attention fix the context bottleneck?</strong><br><strong>A:</strong> Attention allows the decoder to dynamically focus on relevant parts of the input at each output step, enabling better handling of long sequences and improving interpretability.</p><p><strong>Q4. Difference between Bahdanau and Luong attention?</strong><br><strong>A:</strong> Bahdanau (additive) attention uses a feedforward network to compute alignment scores between encoder and decoder states. Luong (multiplicative/dot-product) attention uses dot-products for scoring. Bahdanau is flexible for small hidden sizes; Luong is more computationally efficient.</p><p><strong>Q5. Why can&#8217;t BiRNNs be used for real-time tasks?</strong><br><strong>A:</strong> BiRNNs require future input tokens to compute backward states. In real-time scenarios, future tokens are not available, making BiRNNs unsuitable.</p><p><strong>Q6. How would you use Seq2Seq for translation?</strong><br><strong>A:</strong> Encode the source sentence into a context vector using the encoder, then generate the target sentence step-by-step with the decoder. Optionally, apply attention to focus on relevant source words during decoding.</p><p><strong>Q7. How does attention improve image captioning?</strong><br><strong>A:</strong> Attention allows the decoder to focus on specific regions of the image when generating each word of the caption, improving accuracy and providing interpretable alignments.</p><p><strong>Q8. What are practical benefits of attention visualization?</strong><br><strong>A:</strong> It improves interpretability, helps debug misalignments, and builds trust by showing which parts of the input the model focuses on.</p><p><strong>Q9. How to deploy large Seq2Seq models efficiently?</strong><br><strong>A:</strong> Techniques include quantization and pruning, optimizing beam search, caching encoder outputs, and using mixed precision or GPU acceleration to reduce latency and memory usage.</p><p><strong>Q10. RNN-based vs Transformer-based production trade-offs?</strong><br><strong>A:</strong> RNNs are lightweight, simpler to deploy, and suitable for small datasets or edge devices but slower for long sequences. Transformers handle long-range dependencies efficiently, are highly parallelizable, and achieve state-of-the-art performance, but require more compute and memory, making deployment more complex.</p><h2><strong>6. Conclusion</strong></h2><p>Advanced sequence models marked the <strong>turning point in deep learning for sequential data</strong>.<br>They introduced three crucial innovations:</p><ul><li><p><strong>Bidirectionality</strong> for richer context.</p></li><li><p><strong>Encoder&#8211;decoder architecture</strong> for flexible sequence mapping.</p></li><li><p><strong>Attention</strong> for dynamic, interpretable focus.</p></li></ul><p>These paved the way for <strong>Transformers</strong>, which replaced recurrence with pure attention achieving state-of-the-art performance in language, vision, and beyond.</p><div><hr></div><h2><strong>7. Next in the Series</strong></h2><p>We&#8217;ll conclude the <strong>Deep Learning Interview Prep Series</strong> with one final post:<br><strong>&#8220;Deployment &amp; System Design in Deep Learning&#8221;</strong> covering model serving, quantization, optimization, and scalability in production.</p><p>After that, we&#8217;ll kick off a <strong>new Transformer-focused series</strong>  starting with <em>&#8220;The Attention Is All You Need&#8221;</em> breakdown.</p><div><hr></div><h2><strong>References</strong></h2><ol><li><p><strong><a href="https://arxiv.org/abs/1409.0473">Neural Machine Translation by Jointly Learning to Align and Translate</a></strong><a href="https://arxiv.org/abs/1409.0473"> &#8211; Bahdanau, D., Cho, K., &amp; Bengio, Y. (2014)</a></p></li><li><p><strong><a href="https://arxiv.org/abs/1409.3215">Sequence to Sequence Learning with Neural Networks</a></strong><a href="https://arxiv.org/abs/1409.3215"> &#8211; Sutskever, I., Vinyals, O., &amp; Le, Q. (2014</a>)</p></li><li><p><strong><a href="https://arxiv.org/abs/1406.1078">Learning Phrase Representations using RNN Encoder&#8211;Decoder</a></strong><a href="https://arxiv.org/abs/1406.1078"> &#8211; Cho, K., et al. (2014)</a></p></li><li><p><strong><a href="https://arxiv.org/abs/1508.04025">Effective Approaches to Attention-based Neural Machine Translation</a></strong><a href="https://arxiv.org/abs/1508.04025"> &#8211; Luong, M., et al. (2015)</a></p></li></ol><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://datajourney24.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DataJourney! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Recurrent Neural Networks (RNNs): Modeling Sequential Data]]></title><description><![CDATA[Welcome back to the Deep Learning Interview Prep Series!]]></description><link>https://datajourney24.substack.com/p/recurrent-neural-networks-rnns-modeling</link><guid isPermaLink="false">https://datajourney24.substack.com/p/recurrent-neural-networks-rnns-modeling</guid><dc:creator><![CDATA[Pooja Palod]]></dc:creator><pubDate>Sun, 28 Sep 2025 15:17:51 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!-9DJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F098a1f92-6740-4fa9-a19a-d6a7a04c7de6_1377x580.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Welcome back to the Deep Learning Interview Prep Series! &#128640;</p><p>After mastering CNNs for images, it&#8217;s time to tackle sequential data.</p><p>Enter Recurrent Neural Networks (RNNs)  the models that remember the past to understand the present. From text and speech to time-series forecasting, RNNs process sequences step by step, capturing context and patterns along the way. Let&#8217;s dive in!</p><h3>1. Conceptual Understanding</h3><p>Most standard neural architectures, like feedforward networks or CNNs, assume independence between inputs. That is, each input is processed in isolation. However, sequential data violates this assumption the current input often depends on prior inputs.</p><p>Examples of sequential dependencies:</p><ul><li><p>Text/NLP: The meaning of a word depends on context from previous words.</p><ul><li><p>E.g., in &#8220;The bank will not approve your loan,&#8221; the meaning of <em>bank</em> depends on context.</p></li></ul></li><li><p>Time Series: Stock prices, weather, and sales data depend on previous values.</p></li><li><p>Speech/Audio: Phonemes and words are recognized based on preceding sounds.</p></li><li><p>Control Systems: Robotics and reinforcement learning require past states to decide the next action.</p></li></ul><h3>1.1 RNN Intuition</h3><p>RNNs introduce a hidden state vector (h_t) that acts as a memory. At each time step, the network combines the current input (x_t) with the previous hidden state (h_{t-1}) to compute the new hidden state:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\n\\begin{aligned}\nh_t &amp;= f(W_{xh} x_t + W_{hh} h_{t-1} ) \\\\\ny_t &amp;= W_{hy} h_t \n\\end{aligned}\n&quot;,&quot;id&quot;:&quot;COURPCHJNO&quot;}" data-component-name="LatexBlockToDOM"></div><p>Where:</p><ul><li><p>(x_t) - input at time step (t)</p></li><li><p>(h_t) - hidden state at time step (t)</p></li><li><p>(f) - activation function ((\tanh) or ReLU)</p></li><li><p>(W_{xh}, Whh, W_{hy}) - learnable weights</p><p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!-9DJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F098a1f92-6740-4fa9-a19a-d6a7a04c7de6_1377x580.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!-9DJ!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F098a1f92-6740-4fa9-a19a-d6a7a04c7de6_1377x580.png 424w, /__u/substackcdn.com/image/fetch/$s_!-9DJ!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F098a1f92-6740-4fa9-a19a-d6a7a04c7de6_1377x580.png 848w, /__u/substackcdn.com/image/fetch/$s_!-9DJ!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F098a1f92-6740-4fa9-a19a-d6a7a04c7de6_1377x580.png 1272w, /__u/substackcdn.com/image/fetch/$s_!-9DJ!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F098a1f92-6740-4fa9-a19a-d6a7a04c7de6_1377x580.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!-9DJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F098a1f92-6740-4fa9-a19a-d6a7a04c7de6_1377x580.png" width="1377" height="580" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/098a1f92-6740-4fa9-a19a-d6a7a04c7de6_1377x580.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:580,&quot;width&quot;:1377,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!-9DJ!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F098a1f92-6740-4fa9-a19a-d6a7a04c7de6_1377x580.png 424w, /__u/substackcdn.com/image/fetch/$s_!-9DJ!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F098a1f92-6740-4fa9-a19a-d6a7a04c7de6_1377x580.png 848w, /__u/substackcdn.com/image/fetch/$s_!-9DJ!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F098a1f92-6740-4fa9-a19a-d6a7a04c7de6_1377x580.png 1272w, /__u/substackcdn.com/image/fetch/$s_!-9DJ!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F098a1f92-6740-4fa9-a19a-d6a7a04c7de6_1377x580.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div></li></ul><p>The recurrence allows information to flow across time steps, creating a chain-like dependency that can, in principle, capture long-term patterns.</p><div><hr></div><h3>1.2 Vanishing and Exploding Gradients</h3><p>RNNs are trained using Backpropagation Through Time (BPTT). Gradients for weight updates are propagated across multiple time steps:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\frac{\\partial L}{\\partial W} \\propto \\prod_{t=1}^{T} \\frac{\\partial h_t}{\\partial h_{t-1}}&quot;,&quot;id&quot;:&quot;DRCCYGPTDA&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><ul><li><p>Vanishing Gradient: When the magnitude of the derivative is &lt;1, repeated multiplications across time steps cause the gradient to shrink exponentially. As a result, the network struggles to learn long-term dependencies, because the influence of earlier inputs essentially disappears.</p></li><li><p>Exploding Gradient: When the magnitude of derivative &gt;1, repeated multiplications cause the gradient to grow exponentially. This can lead to unstable training, with huge weight updates and numerical overflow.</p></li></ul><p>Practical Solutions:</p><ul><li><p>Gradient clipping: Limit gradients to a maximum norm to avoid explosion.</p></li><li><p>Use LSTM/GRU cells: Gated architectures mitigate vanishing gradients.</p></li><li><p>Proper initialization: Orthogonal or Xavier initialization helps stabilize gradients.</p></li></ul><div><hr></div><h2>2. Applied Perspective</h2><p>RNNs are suitable for sequential tasks but come with trade-offs.</p><h3>2.1 Applications</h3><ol><li><p>Natural Language Processing (NLP):</p><ul><li><p>Language modeling, text generation, sentiment analysis, machine translation.</p></li><li><p>Example: Predict the next word given previous words.</p></li></ul></li><li><p>Speech Recognition: Convert audio sequences to text.</p><ul><li><p>Example: &#8220;hello world&#8221; recognized from audio frames.</p></li></ul></li><li><p>Time Series Forecasting: Sales, temperature, stock prices.</p></li><li><p>Control Systems &amp; Robotics: Sequential decision-making based on past states.</p></li></ol><h3>2.2 Limitations</h3><ul><li><p>Poor performance on very long sequences.</p></li><li><p>Sequential dependency slows training; cannot parallelize like CNNs or Transformers.</p></li><li><p>Mostly replaced by Transformers in large-scale NLP.</p></li></ul><h3>2.3 When RNNs Still Make Sense</h3><ul><li><p>Small-to-medium datasets.</p></li><li><p>Moderate sequence length (&lt;100 time steps).</p></li><li><p>Deployments in edge devices or low-compute environments.</p></li></ul><div><hr></div><h2>3. System Design Perspective</h2><p>When designing a system for sequential data, choosing the right architecture is all about trade-offs:</p><ul><li><p><strong>RNNs</strong> are simple and lightweight great for short sequences, but struggle when context from far back matters.</p></li><li><p><strong>LSTMs</strong> solve that by using gated memory to capture long-range dependencies, though they come with more parameters and slower training.</p></li><li><p><strong>GRUs</strong> strike a balance - faster and lighter than LSTMs, handling medium-length sequences efficiently, with slightly less expressiveness.</p></li><li><p><strong>Transformers</strong> take it to the next level, using global attention to learn from long sequences and parallelize computation- but they need more data and compute power.</p></li></ul><p>In short: <strong>RNNs for small, quick tasks, LSTMs/GRUs for medium sequences, and Transformers for large-scale sequence learning.</strong></p><h3>3.1 Example: RNN for Sentiment Classification</h3><p>Pipeline:</p><ol><li><p>Tokenize text &#8594; convert to embeddings.</p></li><li><p>Feed sequence into RNN &#8594; hidden states (h_1, h_2, ..., h_T).</p></li><li><p>Use last hidden state (h_T) as feature for classification.</p></li><li><p>Dense layer + softmax &#8594; probability for positive/negative sentiment.</p></li></ol><p>Notes:</p><ul><li><p>Can use bidirectional RNNs to capture context from both past and future.</p></li><li><p>Truncated BPTT: for long sequences, backpropagation is limited to last N steps to save memory and compute.</p></li></ul><h3>3.2 Practical Tips for Training RNNs</h3><ul><li><p>Use gradient clipping to avoid exploding gradients.</p></li><li><p>Consider layer normalization for stability.</p></li><li><p>Use pre-trained embeddings (GloVe, Word2Vec) for NLP.</p></li><li><p>Experiment with bidirectional RNNs for context from both past and future.</p></li><li><p>Use truncated BPTT for long sequences.</p></li></ul><div><hr></div><h2>4. Detailed Math: Backpropagation Through Time (BPTT)</h2><p>Consider a loss (L) over the sequence:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;L = \\sum_{t=1}^{T} \\ell(y_t, \\hat{y}_t)&quot;,&quot;id&quot;:&quot;HVXJBROOBB&quot;}" data-component-name="LatexBlockToDOM"></div><p>Gradient w.r.t hidden state (h_t):</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\frac{\\partial L}{\\partial h_t} = \\frac{\\partial \\ell_t}{\\partial h_t} + \\frac{\\partial L}{\\partial h_{t+1}} \\frac{\\partial h_{t+1}}{\\partial h_t}\n\n&quot;,&quot;id&quot;:&quot;ZPUVDZMYQF&quot;}" data-component-name="LatexBlockToDOM"></div><p>This recursive structure highlights why:</p><ul><li><p>Gradients vanish: product goes to zero.</p></li><li><p>Gradients explode:  product grows exponentially.</p></li></ul><p>Truncated BPTT: Only backpropagate through last (k) steps, balancing memory and gradient flow.</p><div><hr></div><h2>5. RNN Variants</h2><h3>5.1 LSTM</h3><p>Components:</p><ol><li><p>Forget gate: decides what to discard from memory.</p></li><li><p>Input gate: decides what new information to store.</p></li><li><p>Output gate: decides what part of memory to output.</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!VeaC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36dd0f7d-0313-42f1-bf0f-2d0ec67adc10_691x348.svg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!VeaC!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36dd0f7d-0313-42f1-bf0f-2d0ec67adc10_691x348.svg 424w, /__u/substackcdn.com/image/fetch/$s_!VeaC!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36dd0f7d-0313-42f1-bf0f-2d0ec67adc10_691x348.svg 848w, /__u/substackcdn.com/image/fetch/$s_!VeaC!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36dd0f7d-0313-42f1-bf0f-2d0ec67adc10_691x348.svg 1272w, /__u/substackcdn.com/image/fetch/$s_!VeaC!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36dd0f7d-0313-42f1-bf0f-2d0ec67adc10_691x348.svg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!VeaC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36dd0f7d-0313-42f1-bf0f-2d0ec67adc10_691x348.svg" width="691" height="348" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/36dd0f7d-0313-42f1-bf0f-2d0ec67adc10_691x348.svg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:348,&quot;width&quot;:691,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;../_images/lstm-3.svg&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="../_images/lstm-3.svg" title="../_images/lstm-3.svg" srcset="/__u/substackcdn.com/image/fetch/$s_!VeaC!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36dd0f7d-0313-42f1-bf0f-2d0ec67adc10_691x348.svg 424w, /__u/substackcdn.com/image/fetch/$s_!VeaC!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36dd0f7d-0313-42f1-bf0f-2d0ec67adc10_691x348.svg 848w, /__u/substackcdn.com/image/fetch/$s_!VeaC!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36dd0f7d-0313-42f1-bf0f-2d0ec67adc10_691x348.svg 1272w, /__u/substackcdn.com/image/fetch/$s_!VeaC!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36dd0f7d-0313-42f1-bf0f-2d0ec67adc10_691x348.svg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">LSTM Src .https://classic.d2l.ai/chapter_recurrent-modern/lstm.html</figcaption></figure></div><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\n\\begin{aligned}\nf_t &amp;= \\sigma(W_f \\cdot [h_{t-1}, x_t] + b_f) \\\\\ni_t &amp;= \\sigma(W_i \\cdot [h_{t-1}, x_t] + b_i) \\\\\no_t &amp;= \\sigma(W_o \\cdot [h_{t-1}, x_t] + b_o) \\\\\n\\tilde{C}_t &amp;= \\tanh(W_C \\cdot [h_{t-1}, x_t] + b_C) \\\\\nC_t &amp;= f_t * C_{t-1} + i_t * \\tilde{C}_t \\\\\nh_t &amp;= o_t * \\tanh(C_t)\n\\end{aligned}\n\n&quot;,&quot;id&quot;:&quot;TZFCAKWCNH&quot;}" data-component-name="LatexBlockToDOM"></div><ul><li><p>ft&#8203; -forget gate</p></li><li><p>it&#8203; - input gate</p></li><li><p>ot - output gate</p></li><li><p>C~t&#8203; - candidate cell state</p></li><li><p>Ct&#8203; - current cell state</p></li><li><p>ht&#8203; - hidden state / output</p></li><li><p></p></li></ul><h3>5.2 GRU</h3><ul><li><p>Combines forget &amp; input gates into update gate.</p></li><li><p>Uses reset gate to control new information.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!4TJV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0c131c6-dc76-4ab1-893f-f45b6f21a6b3_691x347.svg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!4TJV!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0c131c6-dc76-4ab1-893f-f45b6f21a6b3_691x347.svg 424w, /__u/substackcdn.com/image/fetch/$s_!4TJV!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0c131c6-dc76-4ab1-893f-f45b6f21a6b3_691x347.svg 848w, /__u/substackcdn.com/image/fetch/$s_!4TJV!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0c131c6-dc76-4ab1-893f-f45b6f21a6b3_691x347.svg 1272w, /__u/substackcdn.com/image/fetch/$s_!4TJV!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_webp, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0c131c6-dc76-4ab1-893f-f45b6f21a6b3_691x347.svg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!4TJV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0c131c6-dc76-4ab1-893f-f45b6f21a6b3_691x347.svg" width="691" height="347" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d0c131c6-dc76-4ab1-893f-f45b6f21a6b3_691x347.svg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:347,&quot;width&quot;:691,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;../_images/gru-3.svg&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="../_images/gru-3.svg" title="../_images/gru-3.svg" srcset="/__u/substackcdn.com/image/fetch/$s_!4TJV!, /__u/datajourney24.substack.com/w_424, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0c131c6-dc76-4ab1-893f-f45b6f21a6b3_691x347.svg 424w, /__u/substackcdn.com/image/fetch/$s_!4TJV!, /__u/datajourney24.substack.com/w_848, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0c131c6-dc76-4ab1-893f-f45b6f21a6b3_691x347.svg 848w, /__u/substackcdn.com/image/fetch/$s_!4TJV!, /__u/datajourney24.substack.com/w_1272, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0c131c6-dc76-4ab1-893f-f45b6f21a6b3_691x347.svg 1272w, /__u/substackcdn.com/image/fetch/$s_!4TJV!, /__u/datajourney24.substack.com/w_1456, /__u/datajourney24.substack.com/c_limit, /__u/datajourney24.substack.com/f_auto, /__u/datajourney24.substack.com/q_auto:good, /__u/datajourney24.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0c131c6-dc76-4ab1-893f-f45b6f21a6b3_691x347.svg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">GRU  src https://classic.d2l.ai/chapter_recurrent-modern/gru.html</figcaption></figure></div><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\n\\begin{aligned}\nz_t &amp;= \\sigma(W_z \\cdot [h_{t-1}, x_t]) \\\\\nr_t &amp;= \\sigma(W_r \\cdot [h_{t-1}, x_t]) \\\\\n\\tilde{h}_t &amp;= \\tanh(W_h \\cdot [r_t * h_{t-1}, x_t]) \\\\\nh_t &amp;= (1 - z_t) * h_{t-1} + z_t * \\tilde{h}_t\n\\end{aligned}\n&quot;,&quot;id&quot;:&quot;SFERGQGMOS&quot;}" data-component-name="LatexBlockToDOM"></div><ul><li><p>zt&#8203; - update gate</p></li><li><p>rt&#8203; - reset gate</p></li><li><p>h~t&#8203;  - candidate hidden state</p></li><li><p>ht&#8203; - final hidden state at time t</p></li></ul><div><hr></div><h2>6. Interview Questions</h2><ol><li><p>What is the difference between RNN, LSTM, and GRU?</p></li><li><p>Why do RNNs suffer from vanishing gradients?</p></li><li><p>Explain Backpropagation Through Time (BPTT).</p></li><li><p>When would you use an RNN over a Transformer?</p></li><li><p>How does parameter sharing in RNNs compare to CNNs?</p></li></ol><h2>7. Solutions</h2><h3><strong>Q1. What is the difference between RNN, LSTM, and GRU?</strong></h3><p><strong>Answer:</strong></p><ul><li><p><strong>RNN:</strong> Simple recurrence, maintains short-term memory, struggles with long-term dependencies.</p></li><li><p><strong>LSTM:</strong> Uses input, forget, and output gates to regulate memory, effectively handles long-term dependencies, mitigates vanishing gradients.</p></li><li><p><strong>GRU:</strong> Combines gates into update and reset gates, fewer parameters, faster than LSTM, handles medium-length dependencies efficiently.</p></li></ul><div><hr></div><h3><strong>Q2. Why do RNNs suffer from vanishing gradients?</strong></h3><p><strong>Answer:</strong><br>During backpropagation, the gradient at each time step is a product of many small derivatives. If these derivatives are less than 1, the gradient shrinks exponentially across time steps, making it hard to learn long-term dependencies.</p><div><hr></div><h3><strong>Q3. Explain Backpropagation Through Time (BPTT).</strong></h3><p><strong>Answer:</strong></p><ol><li><p><strong>Unroll</strong> the RNN over all time steps.</p></li><li><p>Perform a <strong>forward pass</strong> to compute outputs and loss.</p></li><li><p>Use the <strong>chain rule</strong> to backpropagate gradients through time.</p></li><li><p><strong>Truncated BPTT</strong> can be used to limit unrolling for long sequences to save memory and computation.</p></li></ol><div><hr></div><h3><strong>Q4. When would you use an RNN over a Transformer?</strong></h3><p><strong>Answer:</strong></p><ul><li><p>When the dataset is small.</p></li><li><p>In low-compute environments or edge devices.</p></li><li><p>For short to medium-length sequences where Transformers are overkill.</p></li></ul><div><hr></div><h3><strong>Q5. How does parameter sharing in RNNs compare to CNNs?</strong></h3><p><strong>Answer:</strong></p><ul><li><p><strong>RNNs:</strong> Parameters are shared across <strong>time steps</strong>, allowing the network to generalize across sequences.</p></li><li><p><strong>CNNs:</strong> Parameters are shared across <strong>spatial locations</strong>, enabling feature detection across the input space.</p></li></ul><div><hr></div><h2>Conclusion</h2><p>RNNs were the first major deep learning breakthrough for sequential data, enabling models to process information across time steps. They laid the groundwork for LSTMs, GRUs, and attention-based architectures.</p><p>While vanilla RNNs struggle with long-term dependencies due to vanishing gradients, they remain valuable for medium-length sequences, small datasets, and resource-constrained environments. Mastering RNNs builds a strong foundation for understanding modern sequence models in NLP, time series, and speech applications.</p><div><hr></div><h2>Next in the Series</h2><p>Next, we&#8217;ll explore Advanced Sequence Models, diving into:</p><ul><li><p>Bidirectional RNNs &#8211; capturing context from both past and future.</p></li><li><p>Seq2Seq architectures &#8211; encoder-decoder frameworks for translation and summarization.</p></li><li><p>Attention mechanism &#8211; the stepping stone to Transformers.</p></li></ul><p>These concepts set the stage for Transformers and large-scale sequence modeling, connecting classical RNNs to state-of-the-art architectures.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://datajourney24.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DataJourney! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p><p></p>]]></content:encoded></item></channel></rss>