<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="https://aiankit.com/">
  <title>Ankit Mishra&#39;s Blog</title>
  <subtitle>Thoughts on AI, Engineering, and Life.</subtitle>
  <link href="https://aiankit.com/feed.xml" rel="self"/>
  <link href="https://aiankit.com/"/>
  <updated>2026-06-23T00:00:00Z</updated>
  <id>https://aiankit.com/</id>
  <author>
    <name>Ankit Mishra</name>
    <email>ankit@aiankit.com</email>
  </author>
  <entry>
    <title>Understanding SnapKV: Compressing LLM Memory From First Principles</title>
    <link href="https://aiankit.com/writing/snapkv/"/>
    <updated>2026-06-23T00:00:00Z</updated>
    <id>https://aiankit.com/writing/snapkv/</id>
    <content xml:lang="en" type="html">&lt;p&gt;Here is the GitHub repo that you can check out: &lt;strong&gt;&lt;a href=&quot;https://github.com/ankitgmishra/SnapKV&quot;&gt;GitHub Repository&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;KV Cache is one of the most critical optimization techniques in modern Large Language Models. However, it also creates one of the biggest memory bottlenecks in AI inference.&lt;/p&gt;
&lt;p&gt;Most resources explain KV Cache compression with complex math, but the core intuition is surprisingly simple.&lt;/p&gt;
&lt;p&gt;In this article, we will break down why KV Cache exists, the massive memory problem it creates, and how a technique called &lt;strong&gt;SnapKV&lt;/strong&gt; solves this by keeping only the tokens that truly matter.&lt;/p&gt;
&lt;p&gt;Want visuals? We have plenty of them.&lt;/p&gt;
&lt;p&gt;Want intuition first? Keep reading.&lt;/p&gt;
&lt;p&gt;Let’s begin.&lt;/p&gt;
&lt;h2 id=&quot;step-1%3A-why-does-kv-cache-exist%3F&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/snapkv/#step-1%3A-why-does-kv-cache-exist%3F&quot;&gt;Step 1: Why Does KV Cache Exist?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before understanding KV Cache, remember one fundamental rule:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;LLMs generate text one token at a time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If the model is given &lt;code&gt;&amp;quot;My name is&amp;quot;&lt;/code&gt; and needs to generate &lt;code&gt;&amp;quot;Ankit&amp;quot;&lt;/code&gt;, it doesn’t produce the entire answer at once. Instead, it predicts one token, then the next.&lt;/p&gt;
&lt;h3 id=&quot;the-problem%3A-repeating-the-same-work&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/snapkv/#the-problem%3A-repeating-the-same-work&quot;&gt;The Problem: Repeating The Same Work&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Imagine you’re reading a book and someone asks: “What was the first word on page 1?” Every time they ask a new question, you reread the entire book from the beginning. That would be incredibly inefficient.&lt;/p&gt;
&lt;p&gt;Without KV Cache, an LLM does exactly this.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;quot;My&amp;quot;
      ↓
   Compute

&amp;quot;My name&amp;quot;
      ↓
Compute Everything Again

&amp;quot;My name is&amp;quot;
      ↓
Compute Everything Again

Generate Next Token
      ↓
Compute Everything Again
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The model repeatedly processes the exact same information for previous tokens.&lt;/p&gt;
&lt;h3 id=&quot;the-solution%3A-kv-cache&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/snapkv/#the-solution%3A-kv-cache&quot;&gt;The Solution: KV Cache&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Notice something important: The words &lt;code&gt;&amp;quot;My&amp;quot;&lt;/code&gt;, &lt;code&gt;&amp;quot;name&amp;quot;&lt;/code&gt;, and &lt;code&gt;&amp;quot;is&amp;quot;&lt;/code&gt; never change. Once we’ve processed them, their information remains exactly the same.&lt;/p&gt;
&lt;p&gt;KV Cache simply saves the &lt;strong&gt;Keys (K)&lt;/strong&gt; and &lt;strong&gt;Values (V)&lt;/strong&gt; of every previously processed token so they can be reused.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Compute Once → Reuse Forever
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://aiankit.com/assets/images/blog/snapkv/snapkv_img_0.png&quot; alt=&quot;With and Without KV Cache&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This prevents the model from doing the same attention computations over and over again, drastically speeding up generation.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;step-2%3A-the-new-problem-created-by-kv-cache&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/snapkv/#step-2%3A-the-new-problem-created-by-kv-cache&quot;&gt;Step 2: The New Problem Created By KV Cache&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;While KV Cache makes generation faster, it introduces a massive new problem: &lt;strong&gt;Growth of Memory&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aiankit.com/assets/images/blog/snapkv/snapkv_img_1.png&quot; alt=&quot;KV Cache Memory Growth&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aiankit.com/assets/images/blog/snapkv/snapkv_img_2.png&quot; alt=&quot;Memory Bottleneck&quot; /&gt;&lt;/p&gt;
&lt;p&gt;As the conversation gets longer:&lt;br /&gt;
&lt;code&gt;Longer Prompt → More Tokens → More KV Pairs → More Memory&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Eventually, the GPU runs out of memory.&lt;/p&gt;
&lt;p&gt;The key insight is that &lt;strong&gt;KV Cache grows linearly with context length&lt;/strong&gt;, while model weights stay fixed. Once context windows reached 32k, 128k, and 1M tokens, researchers realized KV Cache was becoming the biggest memory consumer in the inference stack.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;step-3%3A-do-all-tokens-matter-equally%3F&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/snapkv/#step-3%3A-do-all-tokens-matter-equally%3F&quot;&gt;Step 3: Do All Tokens Matter Equally?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;So far, we know that KV Cache stores every token forever.&lt;/p&gt;
&lt;p&gt;But does the model actually &lt;em&gt;care&lt;/em&gt; about every token?&lt;/p&gt;
&lt;p&gt;Imagine the conversation contains:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;My name is Ankit.
I live in Mumbai.
I work in AI.
I love Machine Learning.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the user asks: &lt;code&gt;&amp;quot;What is my name?&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The model mostly cares about the tokens &lt;code&gt;&amp;quot;Ankit&amp;quot;&lt;/code&gt; and &lt;code&gt;&amp;quot;name&amp;quot;&lt;/code&gt;. Tokens like &lt;code&gt;&amp;quot;Mumbai&amp;quot;&lt;/code&gt;, &lt;code&gt;&amp;quot;AI&amp;quot;&lt;/code&gt;, and &lt;code&gt;&amp;quot;work&amp;quot;&lt;/code&gt; have almost nothing to do with the question.&lt;/p&gt;
&lt;p&gt;Think of attention as a spotlight:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;My                 ██
name               ███████
is                 ███
Ankit              ███████████████████
I                  █
live               █
Mumbai             █
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;the-big-observation&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/snapkv/#the-big-observation&quot;&gt;The Big Observation&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Even though the KV Cache contains all tokens, the model only heavily uses a small subset of them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A token being present in the context does not mean it is equally important for future predictions.&lt;/strong&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;step-4%3A-how-snapkv-solves-the-memory-crisis&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/snapkv/#step-4%3A-how-snapkv-solves-the-memory-crisis&quot;&gt;Step 4: How SnapKV Solves the Memory Crisis&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;SnapKV starts from this surprisingly simple observation:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If a token is almost never attended to, storing its Key and Value forever is wasteful.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Instead of keeping every token, SnapKV asks:&lt;br /&gt;
&lt;em&gt;Can we identify which tokens are likely to matter later and discard the rest?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aiankit.com/assets/images/blog/snapkv/snapkv_img_3.png&quot; alt=&quot;Attention Spikes&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aiankit.com/assets/images/blog/snapkv/snapkv_img_4.png&quot; alt=&quot;Sparsity in Attention&quot; /&gt;&lt;/p&gt;
&lt;h3 id=&quot;the-first-principles-insight&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/snapkv/#the-first-principles-insight&quot;&gt;The First-Principles Insight&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;SnapKV asks a specific question. Not “Which token received attention once?”, but rather:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Which tokens keep receiving attention over and over again?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If future tokens continue to look at the token &lt;code&gt;&amp;quot;Ankit&amp;quot;&lt;/code&gt; repeatedly, it means its Key and Value contain vital information. We must keep them!&lt;/p&gt;
&lt;p&gt;On the other hand, if a token like &lt;code&gt;&amp;quot;Mumbai&amp;quot;&lt;/code&gt; receives almost no attention from any future query, storing it simply wastes KV-cache memory.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;step-5%3A-the-snapkv-algorithm&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/snapkv/#step-5%3A-the-snapkv-algorithm&quot;&gt;Step 5: The SnapKV Algorithm&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Think of SnapKV like a library. If you have 1,000 books but students repeatedly borrow only 20 of them, you wouldn’t keep all 1,000 on the front desk. You’d keep the popular ones nearby and move the rest.&lt;/p&gt;
&lt;p&gt;Tokens that are repeatedly “checked out” by attention are kept. Tokens that nobody looks at are removed.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aiankit.com/assets/images/blog/snapkv/snapkv_img_5.png&quot; alt=&quot;SnapKV Pipeline Step 1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The SnapKV process looks like this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Observe Attention:&lt;/strong&gt; Let the model process tokens and see where the attention flows.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Compute Importance:&lt;/strong&gt; Track how much total attention each token receives.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sort Tokens:&lt;/strong&gt; Rank them by their importance scores.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Keep Top-K Tokens:&lt;/strong&gt; Retain the most frequently attended KV pairs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Delete Remaining:&lt;/strong&gt; Drop the rest from memory.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://aiankit.com/assets/images/blog/snapkv/snapkv_img_6.png&quot; alt=&quot;SnapKV Pipeline Step 2&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aiankit.com/assets/images/blog/snapkv/snapkv_img_7.png&quot; alt=&quot;SnapKV Pipeline Step 3&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;step-6%3A-pruning-and-the-visual-proof&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/snapkv/#step-6%3A-pruning-and-the-visual-proof&quot;&gt;Step 6: Pruning and the Visual Proof&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When you map out the attention scores visually over a long context, a clear pattern emerges.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aiankit.com/assets/images/blog/snapkv/snapkv_img_8.png&quot; alt=&quot;Attention Spike Graph&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Most tokens show tiny blips of attention. But a few tokens—names, entities, system instructions—create &lt;strong&gt;MASSIVE SPIKES&lt;/strong&gt;. These are the “Important Anchors” that the model constantly refers back to.&lt;/p&gt;
&lt;p&gt;By identifying these spikes and deleting the flatline tokens, we can compress the KV Cache significantly.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aiankit.com/assets/images/blog/snapkv/snapkv_img_9.png&quot; alt=&quot;Pruned Tokens&quot; /&gt;&lt;/p&gt;
&lt;h3 id=&quot;but-what-if-a-deleted-token-becomes-important-later%3F&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/snapkv/#but-what-if-a-deleted-token-becomes-important-later%3F&quot;&gt;But What if a Deleted Token Becomes Important Later?&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Researchers measured this exact scenario. Surprisingly, the &lt;strong&gt;Quality Drop is very small&lt;/strong&gt;, while the memory savings are massive. Because attention repeatedly focuses on those same anchor tokens anyway, dropping the noise barely affects generation quality.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;step-7%3A-visualizing-the-matrix-compression&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/snapkv/#step-7%3A-visualizing-the-matrix-compression&quot;&gt;Step 7: Visualizing the Matrix Compression&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let’s look at the actual matrix mechanics of what SnapKV does.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aiankit.com/assets/images/blog/snapkv/snapkv_img_16.png&quot; alt=&quot;Original Attention Matrix&quot; /&gt;&lt;/p&gt;
&lt;p&gt;In the raw attention matrix, bright spots represent high attention, and dark areas represent low attention. SnapKV translates this directly into a pruning strategy.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aiankit.com/assets/images/blog/snapkv/snapkv_img_17.png&quot; alt=&quot;Pruned Attention Matrix&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ORIGINAL KV CACHE&lt;/strong&gt;&lt;br /&gt;
&lt;code&gt;K Shape: [1, 12, 26, 64]&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;V Shape: [1, 12, 26, 64]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;COMPRESSED KV CACHE&lt;/strong&gt;&lt;br /&gt;
&lt;code&gt;K Shape: [1, 12, 7, 64]&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;V Shape: [1, 12, 7, 64]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;We’ve reduced the sequence length from 26 tokens to just 7 tokens, keeping only what truly matters.&lt;/p&gt;
&lt;h3 id=&quot;mental-model-summary&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/snapkv/#mental-model-summary&quot;&gt;Mental Model Summary&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Traditional KV Cache:&lt;/strong&gt; Store the entire textbook.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SnapKV:&lt;/strong&gt; Store the summary notes + a few important pages.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It’s not perfect, but it’s drastically smaller and nearly as effective. We simply observed the attention scores, computed importance, kept the Top-K tokens, and pruned the cache.&lt;/p&gt;
&lt;p&gt;Here is the GitHub repo that you can check out: &lt;strong&gt;&lt;a href=&quot;https://github.com/ankitgmishra/SnapKV&quot;&gt;GitHub Repository&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Comment down your thoughts below, if you found it helpful!&lt;/p&gt;
&lt;h2 id=&quot;references&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/snapkv/#references&quot;&gt;References&lt;/a&gt;&lt;/h2&gt;
&lt;a href=&quot;https://arxiv.org/abs/2404.14469&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;
    SnapKV: LLM Knows What You are Looking for Before Generation
&lt;/a&gt;
&lt;p&gt;Best,&lt;br /&gt;
Ankit&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Understanding LLM.int8(): Making Large Models Fit</title>
    <link href="https://aiankit.com/writing/llm.int8/"/>
    <updated>2026-06-12T00:00:00Z</updated>
    <id>https://aiankit.com/writing/llm.int8/</id>
    <content xml:lang="en" type="html">&lt;p&gt;Here is the GitHub repo that you can check out: &lt;strong&gt;&lt;a href=&quot;https://github.com/ankitgmishra/int8&quot;&gt;GitHub Repository&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;LLM.int8() from First Principles. Most people understand that large language models have billions of parameters, but don’t know exactly how we compress them to run on normal GPUs without destroying their intelligence.&lt;/p&gt;
&lt;p&gt;To understand how modern models can fit on consumer hardware, we need to understand Quantization and specifically LLM.int8().&lt;/p&gt;
&lt;p&gt;It essentially solved the 8-bit inference bottleneck.&lt;/p&gt;
&lt;p&gt;But before we get into the solution, we must understand the core problem.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;step-1%3A-the-memory-gets-too-big&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/llm.int8/#step-1%3A-the-memory-gets-too-big&quot;&gt;Step 1: The Memory Gets Too Big&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When a model processes text, its intelligence is stored inside billions of weight values.&lt;/p&gt;
&lt;p&gt;Historically, most neural networks use &lt;strong&gt;FP32 (32-bit floating point)&lt;/strong&gt;. That means every single number occupies 4 bytes of memory.&lt;/p&gt;
&lt;p&gt;For a tiny 4-parameter matrix, this is 16 bytes. No problem.&lt;/p&gt;
&lt;p&gt;But look at how the memory requirements scale for modern LLMs:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model Size&lt;/th&gt;
&lt;th&gt;Precision&lt;/th&gt;
&lt;th&gt;Memory Required (Weights Only)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;7 Billion&lt;/td&gt;
&lt;td&gt;FP32&lt;/td&gt;
&lt;td&gt;~28 GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;70 Billion&lt;/td&gt;
&lt;td&gt;FP32&lt;/td&gt;
&lt;td&gt;~280 GB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Notice:&lt;/strong&gt; Just the weights of a 70B model require 280 GB of VRAM. Most consumer GPUs cannot even hold a fraction of this memory.&lt;/p&gt;
&lt;h3 id=&quot;the-rule%3A&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/llm.int8/#the-rule%3A&quot;&gt;The Rule:&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If your model grows, the memory required explodes.&lt;/p&gt;
&lt;p&gt;Here is the craziest part: Do we really need 32 bits for every single parameter?&lt;/p&gt;
&lt;p&gt;This is exactly the question LLM.int8() asks.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;step-2%3A-the-quantization-question&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/llm.int8/#step-2%3A-the-quantization-question&quot;&gt;Step 2: The Quantization Question&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Instead of storing every weight using &lt;strong&gt;32 bits&lt;/strong&gt;, we can store them using fewer bits, like &lt;strong&gt;INT8 (8 bits)&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;By moving from FP32 (4 bytes) to INT8 (1 byte), we immediately reduce the memory by 4x. A 280 GB model becomes 70 GB.&lt;/p&gt;
&lt;p&gt;But an INT8 value cannot directly store floating-point numbers such as &lt;code&gt;0.12&lt;/code&gt; or &lt;code&gt;0.91&lt;/code&gt;. INT8 only stores integers from &lt;code&gt;-128&lt;/code&gt; to &lt;code&gt;127&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So we store an integer representation and a scaling factor:&lt;br /&gt;
&lt;code&gt;0.56 -&amp;gt; 56&lt;/code&gt; with a scale of &lt;code&gt;0.01&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This is called &lt;strong&gt;Naive Quantization&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aiankit.com/assets/images/blog/llmint8_img_3.png&quot; alt=&quot;Naive Quantization Pipeline&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;step-3%3A-why-naive-quantization-fails&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/llm.int8/#step-3%3A-why-naive-quantization-fails&quot;&gt;Step 3: Why Naive Quantization Fails&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Until now, quantization looked almost magical. We get 4x less memory with a tiny error. So what’s the catch?&lt;/p&gt;
&lt;p&gt;Suppose our weights are &lt;code&gt;[0.12, 0.56, 0.91, 0.33, 100]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Notice the &lt;code&gt;100&lt;/code&gt;. It is an &lt;strong&gt;outlier&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Because quantization maps the largest value to the maximum INT8 value (127), the scale becomes &lt;code&gt;100 / 127 ≈ 0.787&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This single giant value forces a massive scale factor. The smaller values (like &lt;code&gt;0.12&lt;/code&gt;) are completely crushed and lose precision.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aiankit.com/assets/images/blog/llmint8_img_5.png&quot; alt=&quot;The Outlier Problem&quot; /&gt;&lt;/p&gt;
&lt;h3 id=&quot;the-outlier-problem&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/llm.int8/#the-outlier-problem&quot;&gt;The Outlier Problem&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In large language models, a tiny fraction of values are orders of magnitude larger than the rest. If we force everything into INT8, these outliers stretch the scale so much that the model loses its intelligence. Researchers tried removing the outliers, but the model quality immediately dropped.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;step-4%3A-the-magic-trick---llm.int8()-solution&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/llm.int8/#step-4%3A-the-magic-trick---llm.int8()-solution&quot;&gt;Step 4: The Magic Trick - LLM.int8() Solution&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Instead of sending &lt;strong&gt;every value&lt;/strong&gt; through INT8 quantization, LLM.int8() separates the values into two distinct groups:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Normal Values:&lt;/strong&gt; &lt;code&gt;[0.12, 0.56, 0.91, 0.33]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Outlier Values:&lt;/strong&gt; &lt;code&gt;[100]&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;The normal values&lt;/strong&gt; are processed in INT8. They quantize very well because they live in a similar numerical range.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The outlier values&lt;/strong&gt; are kept in higher precision (FP16). This avoids introducing large quantization errors.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aiankit.com/assets/images/blog/llmint8_img_6.png&quot; alt=&quot;LLM.int8() Splitting Logic&quot; /&gt;&lt;/p&gt;
&lt;p&gt;By treating these two groups differently, we never force the normal values to compete with the giant outlier for the quantization scale. We get nearly the memory savings of INT8 with the numerical accuracy of FP16!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;step-5%3A-split-matrix-multiplication&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/llm.int8/#step-5%3A-split-matrix-multiplication&quot;&gt;Step 5: Split Matrix Multiplication&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In practice, Transformers spend their time performing massive matrix multiplications (&lt;code&gt;Activation Vector × Weight Matrix&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;LLM.int8() performs two separate, smaller matrix multiplications:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;INT8 Path:&lt;/strong&gt; Computes the contribution from normal dimensions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FP16 Path:&lt;/strong&gt; Computes the contribution from outlier dimensions.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Once both paths finish, their outputs are perfectly added together.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aiankit.com/assets/images/blog/llmint8_img_7.png&quot; alt=&quot;Split Matrix Multiplication&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This final output is extremely close to the original FP32 computation while using significantly less memory. Use INT8 wherever possible and keep higher precision only where it is actually needed.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;step-6%3A-the-benchmark-results&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/llm.int8/#step-6%3A-the-benchmark-results&quot;&gt;Step 6: The Benchmark Results&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When we benchmark the FP32 vs INT8 models for a standard architecture, the results speak for themselves:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aiankit.com/assets/images/blog/llmint8_img_8.png&quot; alt=&quot;Memory Footprint Benchmark&quot; /&gt;&lt;/p&gt;
&lt;p&gt;By applying LLM.int8(), we save 75% memory while introducing only a small reconstruction error. When testing generation, the model still understands English, grammar, and context beautifully.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;applying-it-in-code&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/llm.int8/#applying-it-in-code&quot;&gt;Applying it in Code&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Here is how you can use the HuggingFace &lt;code&gt;transformers&lt;/code&gt; and &lt;code&gt;bitsandbytes&lt;/code&gt; libraries to instantly leverage LLM.int8() for any model:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;!pip install transformers
!pip install accelerate
!pip install bitsandbytes
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;from transformers import AutoModelForCausalLM
from transformers import AutoTokenizer

model_name = &amp;quot;gpt2&amp;quot;

tokenizer = AutoTokenizer.from_pretrained(model_name)

model = AutoModelForCausalLM.from_pretrained(model_name)

print(model)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;GPT2LMHeadModel(
  (transformer): GPT2Model(
    (wte): Embedding(50257, 768)
    (wpe): Embedding(1024, 768)
    (drop): Dropout(p=0.1, inplace=False)
    (h): ModuleList(
      (0-11): 12 x GPT2Block(...)
    )
    (ln_f): LayerNorm((768,), eps=1e-05, elementwise_affine=True)
  )
  (lm_head): Linear(in_features=768, out_features=50257, bias=False)
)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;checking-memory&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/llm.int8/#checking-memory&quot;&gt;Checking Memory&lt;/a&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;total_params = sum(
    p.numel()
    for p in model.parameters()
)

memory_mb = (
    total_params * 4
) / (1024 * 1024)

print(f&amp;quot;Total Parameters: {total_params:,}&amp;quot;)
print(f&amp;quot;Estimated FP32 Memory: {memory_mb:.2f} MB&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Total Parameters: 124,439,808
Estimated FP32 Memory: 474.70 MB
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;running-inference&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/llm.int8/#running-inference&quot;&gt;Running Inference&lt;/a&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;text = &amp;quot;My name is&amp;quot;

inputs = tokenizer(
    text,
    return_tensors=&amp;quot;pt&amp;quot;
)

output = model.generate(
    **inputs,
    max_new_tokens=20
)

print(tokenizer.decode(output[0]))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;My name is John. I&#39;m a man of God. I&#39;m a man of God. I&#39;m a man
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;loading-int8-version&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/llm.int8/#loading-int8-version&quot;&gt;Loading Int8 Version&lt;/a&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;from transformers import BitsAndBytesConfig

# Creating Configuration 
bnb_config = BitsAndBytesConfig(
    load_in_8bit=True
)

# Loading Model
int8_model = AutoModelForCausalLM.from_pretrained(
    model_name,
    quantization_config=bnb_config
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This line: &lt;code&gt;load_in_8bit=True&lt;/code&gt; is literally everything we learned.&lt;/p&gt;
&lt;h3 id=&quot;now-comparing-memory&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/llm.int8/#now-comparing-memory&quot;&gt;Now Comparing Memory&lt;/a&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;total_params = sum(
    p.numel()
    for p in int8_model.parameters()
)

fp32_memory = (total_params * 4) / (1024 * 1024)
int8_memory = (total_params * 1) / (1024 * 1024)

print(f&amp;quot;FP32 Estimate: {fp32_memory:.2f} MB&amp;quot;)
print(f&amp;quot;INT8 Estimate: {int8_memory:.2f} MB&amp;quot;)
print(f&amp;quot;Reduction: {fp32_memory/int8_memory:.1f}x&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;FP32 Estimate: 474.70 MB
INT8 Estimate: 118.68 MB
Reduction: 4.0x
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;generating-text-again&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/llm.int8/#generating-text-again&quot;&gt;Generating Text Again&lt;/a&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;output = int8_model.generate(
    **inputs,
    max_new_tokens=20
)

print(tokenizer.decode(output[0]))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;My name is John. I&#39;m a writer, and I&#39;m a writer. I&#39;m a writer. I&#39;m
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;conclusion-at-the-end%3A&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/llm.int8/#conclusion-at-the-end%3A&quot;&gt;Conclusion at the End:&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Before INT8&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;My name is John. I’m a man of God. I’m a man of God. I’m a man&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;After INT8&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;My name is John. I’m a writer, and I’m a writer. I’m a writer. I’m&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;Model still understands English&lt;/li&gt;
&lt;li&gt;Model still understands grammar&lt;/li&gt;
&lt;li&gt;Model still understands context&lt;/li&gt;
&lt;li&gt;There is a tiny error at the end, which is what quantization is all about!&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

# Plotting the memory comparison
plt.figure(figsize=(8, 5))
models = [&#39;FP32 Model&#39;, &#39;INT8 Model&#39;]
memories = [fp32_memory, int8_memory]

plt.bar(models, memories, color=[&#39;#64748b&#39;, &#39;#3b82f6&#39;], edgecolor=&#39;black&#39;, width=0.5)
plt.title(&#39;HuggingFace GPT-2 Memory Footprint&#39;, fontsize=16, fontweight=&#39;bold&#39;, pad=15)
plt.ylabel(&#39;Memory (MB)&#39;, fontsize=12)

for i, v in enumerate(memories):
    plt.text(i, v + (max(memories)*0.02), f&#39;{v:.2f} MB&#39;, ha=&#39;center&#39;, fontweight=&#39;bold&#39;, fontsize=12)

plt.tight_layout()
plt.show()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://aiankit.com/assets/images/blog/llmint8_img_9.png&quot; alt=&quot;Output Graph&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Here is the GitHub repo that you can check out: &lt;strong&gt;&lt;a href=&quot;https://github.com/ankitgmishra/int8&quot;&gt;GitHub Repository&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Comment down your thoughts below, if you found it helpful !&lt;/p&gt;
&lt;h2 id=&quot;references&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/llm.int8/#references&quot;&gt;References&lt;/a&gt;&lt;/h2&gt;
&lt;a href=&quot;https://arxiv.org/abs/2208.07339&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;
    LLM.int8(): 8-bit Matrix Multiplication for Transformers at Scale
&lt;/a&gt;
&lt;p&gt;Best,&lt;br /&gt;
Ankit&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Understanding Flash Attention: Making Transformers Fast</title>
    <link href="https://aiankit.com/writing/flash-attention/"/>
    <updated>2026-06-09T00:00:00Z</updated>
    <id>https://aiankit.com/writing/flash-attention/</id>
    <content xml:lang="en" type="html">&lt;p&gt;Here is the GitHub repo that you can check out: &lt;strong&gt;&lt;a href=&quot;https://github.com/ankitgmishra/flash-attention&quot;&gt;GitHub Repository&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Flash Attention from First Principles. Most people understand Self-Attention, but don’t know exactly why it is so incredibly slow for long documents.&lt;/p&gt;
&lt;p&gt;To understand how modern models can process millions of tokens at once, we need to understand Flash Attention.&lt;/p&gt;
&lt;p&gt;It essentially solved the quadratic memory bottleneck.&lt;/p&gt;
&lt;p&gt;But before we get into the solution, we must understand the core problem.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;step-1%3A-the-matrix-gets-too-big&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/flash-attention/#step-1%3A-the-matrix-gets-too-big&quot;&gt;Step 1: The Matrix Gets Too Big&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When a model processes text, it compares every single word to every other word using the Self-Attention mechanism.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aiankit.com/assets/images/blog/fa_img_0.png&quot; alt=&quot;Self Attention Matrix Visualization&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This creates a massive Attention Matrix. Look at how the math problem scales:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Number of Words&lt;/th&gt;
&lt;th&gt;Math Problem Size (Attention Matrix)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1,000 words&lt;/td&gt;
&lt;td&gt;1,000,000 numbers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2,000 words&lt;/td&gt;
&lt;td&gt;4,000,000 numbers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4,000 words&lt;/td&gt;
&lt;td&gt;16,000,000 numbers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8,000 words&lt;/td&gt;
&lt;td&gt;64,000,000 numbers&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Notice:&lt;/strong&gt; Every time you double the words, the memory you need multiplies by 4. This gets out of hand very fast.&lt;/p&gt;
&lt;h3 id=&quot;the-math-term%3A-o(n%C2%B2)-(quadratic-scaling)&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/flash-attention/#the-math-term%3A-o(n%C2%B2)-(quadratic-scaling)&quot;&gt;The Math Term: O(N²) (Quadratic Scaling)&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;The Rule:&lt;/strong&gt;&lt;br /&gt;
If your sequence gets longer, the Attention Matrix explodes. You need an insane amount of memory.&lt;/p&gt;
&lt;p&gt;Here is the craziest part: Why are we forcing the GPU to create a gigantic 64-million-number matrix, if we are just going to throw it away a second later?&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;step-2%3A-the-flashattention-question&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/flash-attention/#step-2%3A-the-flashattention-question&quot;&gt;Step 2: The FlashAttention Question&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Standard Attention creates 64,000,000 numbers, saves them to the GPU’s slow main memory (HBM), reads them back to do the Softmax math, and then deletes them.&lt;/p&gt;
&lt;p&gt;Moving all those numbers back and forth is the real reason Transformers are slow. FlashAttention asks: &lt;strong&gt;Can we skip the slow memory completely?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aiankit.com/assets/images/blog/fa_img_1.png&quot; alt=&quot;Flash Attention Idea&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;step-3%3A-the-old-matrix-vs.-the-chunked-matrix&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/flash-attention/#step-3%3A-the-old-matrix-vs.-the-chunked-matrix&quot;&gt;Step 3: The Old Matrix vs. The Chunked Matrix&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To solve this, we can introduce &lt;strong&gt;Tiling&lt;/strong&gt; (Chunking).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Standard Attention:&lt;/strong&gt;&lt;br /&gt;
Builds the massive matrix all at once in the slow memory.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tiled Attention:&lt;/strong&gt;&lt;br /&gt;
Does the math in pieces. It does a small piece, then another small piece, and so on. All of this fits inside the ultra-fast memory (SRAM).&lt;/p&gt;
&lt;h3 id=&quot;the-important-rule&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/flash-attention/#the-important-rule&quot;&gt;The Important Rule&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;We are not skipping any steps.&lt;/strong&gt;&lt;br /&gt;
We are still comparing every single word against every other word. We are just doing it in small, manageable batches instead of one giant gulp. The final mathematical answer will be exactly the same.&lt;/p&gt;
&lt;h3 id=&quot;why-does-chunking-matter-so-much%3F&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/flash-attention/#why-does-chunking-matter-so-much%3F&quot;&gt;Why does chunking matter so much?&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The GPU’s fast memory (SRAM) is incredibly fast, but very small. By doing the math in chunks, we keep all the work inside the fast memory. We avoid the brutal speed limits of the massive, slow main memory.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;step-4%3A-but-wait%E2%80%A6-tiling-breaks-softmax&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/flash-attention/#step-4%3A-but-wait%E2%80%A6-tiling-breaks-softmax&quot;&gt;Step 4: But Wait… Tiling Breaks Softmax&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We are going to prove why we can’t just easily chop the math into small pieces. &lt;strong&gt;Normal Softmax is not the same as Tiled Softmax&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;the-golden-rule-of-softmax&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/flash-attention/#the-golden-rule-of-softmax&quot;&gt;The Golden Rule of Softmax&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Imagine we have raw scores for one word looking at four other words: &lt;code&gt;[2, 5, 1, 8]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Normal Attention:&lt;/strong&gt;&lt;br /&gt;
The Softmax function looks at all four numbers at the exact same time. It figures out the percentages based on the whole group. The percentages will always add up to exactly 100% (or 1.0).&lt;/p&gt;
&lt;h3 id=&quot;the-chunking-mistake&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/flash-attention/#the-chunking-mistake&quot;&gt;The Chunking Mistake&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Suppose we decide to be clever and chop the scores into smaller chunks (tiles) so they fit in the GPU’s super-fast memory.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tile 1:&lt;/strong&gt; &lt;code&gt;[2, 5]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tile 2:&lt;/strong&gt; &lt;code&gt;[1, 8]&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It feels logical to do Softmax on Tile 1, then Softmax on Tile 2, and add them together. But watch what happens.&lt;/p&gt;
&lt;h3 id=&quot;the-200%25-bug&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/flash-attention/#the-200%25-bug&quot;&gt;The 200% Bug&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Because we chopped the keys, the Softmax in each chunk doesn’t know about the other chunk. It forces each tiny chunk to equal 100% all by itself.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Correct Answer:&lt;/strong&gt;&lt;br /&gt;
If we do &lt;code&gt;Softmax([2, 5, 1, 8])&lt;/code&gt; all at once, we get &lt;code&gt;[0.002, 0.047, 0.001, 0.950]&lt;/code&gt;.&lt;br /&gt;
If you add those up, you get 1.0 (100%). Everything is perfect.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How It Breaks Chunk by Chunk:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tile 1:&lt;/strong&gt;&lt;br /&gt;
We ask Softmax to process &lt;code&gt;[2, 5]&lt;/code&gt;. It thinks 5 is the biggest number ever, so it gives it 95%. The result is &lt;code&gt;[0.047, 0.953]&lt;/code&gt;. (Adds up to 100%).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tile 2:&lt;/strong&gt;&lt;br /&gt;
We ask Softmax to process &lt;code&gt;[1, 8]&lt;/code&gt;. It gives 8 almost everything. The result is &lt;code&gt;[0.001, 0.999]&lt;/code&gt;. (Adds up to 100%).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Trap:&lt;/strong&gt;&lt;br /&gt;
If we stick those answers back together: &lt;code&gt;[0.047, 0.953, 0.001, 0.999]&lt;/code&gt;.&lt;br /&gt;
Add them up, and the sum is &lt;strong&gt;2.0&lt;/strong&gt;!&lt;/p&gt;
&lt;p&gt;We just distributed 200% attention. The math is completely broken. Because Tile 1 couldn’t see the massive 8 in Tile 2, it gave the 5 way too much importance.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aiankit.com/assets/images/blog/fa_img_2.png&quot; alt=&quot;Tiling Breaks Softmax&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;step-5%3A-the-magic-trick---online-softmax&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/flash-attention/#step-5%3A-the-magic-trick---online-softmax&quot;&gt;Step 5: The Magic Trick - Online Softmax&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We just saw that chopping Softmax into chunks causes a massive bug. So how do we fix it?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The FlashAttention Goal:&lt;/strong&gt;&lt;br /&gt;
How can we process the numbers in small, fast chunks, but still get the exact same math as if we looked at all the numbers at once?&lt;/p&gt;
&lt;p&gt;Instead of needing to see every single number at the same time, we use a clever math trick called &lt;strong&gt;Online Softmax&lt;/strong&gt;. We only need to remember &lt;strong&gt;two numbers&lt;/strong&gt; as we process the chunks:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;The Maximum:&lt;/strong&gt; What is the biggest score we have seen so far?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Sum:&lt;/strong&gt; What is the running total of our calculations?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;By keeping track of just these two tiny numbers, we barely use any memory.&lt;/p&gt;
&lt;h3 id=&quot;why-is-it-called-%E2%80%9Cflash%E2%80%9D-attention%3F&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/flash-attention/#why-is-it-called-%E2%80%9Cflash%E2%80%9D-attention%3F&quot;&gt;Why is it called “Flash” Attention?&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Because the “Maximum” number constantly updates (or “flashes”) as we process new chunks. When we find a new biggest number, the algorithm uses a smart formula to reach back and instantly fix the percentages of the old chunks.&lt;/p&gt;
&lt;p&gt;We never have to save the big matrix!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;step-6%3A-the-flash-attention-forward-pass&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/flash-attention/#step-6%3A-the-flash-attention-forward-pass&quot;&gt;Step 6: The Flash Attention Forward Pass&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;the-old-way-(standard-attention)&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/flash-attention/#the-old-way-(standard-attention)&quot;&gt;The Old Way (Standard Attention)&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The standard way is terrible because it relies on the slow main memory (HBM):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Move Q and K from slow memory to fast memory.&lt;/li&gt;
&lt;li&gt;Do the math. &lt;strong&gt;Write the giant result back to slow memory.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Read the giant result from slow memory to do Softmax. &lt;strong&gt;Write it back.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Read it again to multiply by V. &lt;strong&gt;Write the final answer.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All we are doing is moving data back and forth. It is slow.&lt;/p&gt;
&lt;h3 id=&quot;the-new-way-(flashattention)&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/flash-attention/#the-new-way-(flashattention)&quot;&gt;The New Way (FlashAttention)&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;FlashAttention does everything in one smooth motion using the super-fast memory (SRAM):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Load a Chunk:&lt;/strong&gt; Bring a small piece of Q, K, and V into fast memory.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Do the Math:&lt;/strong&gt; Multiply them together.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Update the Trackers:&lt;/strong&gt; Update the Running Maximum and Running Sum.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Update the Output:&lt;/strong&gt; Keep building the final answer.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Throw the Chunk Away:&lt;/strong&gt; Clear the fast memory and load the next piece.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We never write the giant middle step to the slow memory. This is why it is so fast!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;step-7%3A-the-benchmark-results&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/flash-attention/#step-7%3A-the-benchmark-results&quot;&gt;Step 7: The Benchmark Results&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When we benchmark Flash Attention against standard attention, the results are massive. The larger the sequence length, the more standard attention slows down and runs out of memory, while Flash Attention maintains steady performance.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aiankit.com/assets/images/blog/fa_img_3.png&quot; alt=&quot;Benchmark Results&quot; /&gt;&lt;/p&gt;
&lt;p&gt;FlashAttention was the turning point that allowed us to move from 4K context windows to 128K, 1M, and beyond.&lt;/p&gt;
&lt;p&gt;Here is the GitHub repo that you can check out: &lt;strong&gt;&lt;a href=&quot;https://github.com/ankitgmishra/flash-attention&quot;&gt;GitHub Repository&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Comment down your thoughts below, if you found it helpful !&lt;/p&gt;
&lt;h2 id=&quot;references&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/flash-attention/#references&quot;&gt;References&lt;/a&gt;&lt;/h2&gt;
&lt;a href=&quot;https://arxiv.org/abs/2205.14135&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;
    FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness
&lt;/a&gt;
&lt;p&gt;Best,&lt;br /&gt;
Ankit&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Transformer Architecture: From First Principles</title>
    <link href="https://aiankit.com/writing/understanding-Transformer/"/>
    <updated>2026-06-08T00:00:00Z</updated>
    <id>https://aiankit.com/writing/understanding-Transformer/</id>
    <content xml:lang="en" type="html">&lt;p&gt;In our previous article, i broke down &lt;strong&gt;Self-Attention&lt;/strong&gt; into its simplest mathematical form, discovering how Query, Key, and Value matrices route contextual information between words.&lt;/p&gt;
&lt;p&gt;But Self-Attention is just an engine. To build a system capable of translating languages or generating code, you need the complete vehicle: &lt;strong&gt;The Transformer Architecture&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;A Transformer contains many additional components: Positional Encoding, Multi-Head Attention, Feed-Forward Networks, Residual Connections, Layer Normalization, Masking, Cross-Attention, and the final prediction layers.&lt;/p&gt;
&lt;p&gt;Instead of memorizing blocks from an architecture diagram, we’ll build the Transformer from first principles, understanding why each component exists, what problem it solves, and how the mathematics works underneath.&lt;/p&gt;
&lt;p&gt;If you’re new to Self-Attention, I highly recommend reading the previous article first:&lt;br /&gt;
&lt;a href=&quot;https://aiankit.com/writing/understanding-self-attention/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Self Attention: from first principle &lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;the-core-bottleneck%3A-why-invent-transformers%3F&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-Transformer/#the-core-bottleneck%3A-why-invent-transformers%3F&quot;&gt;The Core Bottleneck: Why Invent Transformers?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before 2017, Sequence-to-Sequence (Seq2Seq) Recurrent Neural Networks (RNNs) were the absolute rulers of AI. RNNs processed text strictly &lt;strong&gt;sequentially&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;quot;My&amp;quot; ──► [Step 1] ──► &amp;quot;name&amp;quot; ──► [Step 2] ──► &amp;quot;is&amp;quot; ──► [Step 3] ──► &amp;quot;Ankit&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If an RNN processed a 500-word paragraph, the context of the first word had to survive 499 mathematical updates before reaching the end. Information degraded rapidly. Gradients vanished. This was the &lt;strong&gt;Encoder Bottleneck&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The Transformer abandoned recurrence entirely. It ingests the &lt;em&gt;entire&lt;/em&gt; sentence simultaneously, replacing time-stepping loops with parallel mathematics.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;the-complete-end-to-end-architecture-flow&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-Transformer/#the-complete-end-to-end-architecture-flow&quot;&gt;The Complete End-to-End Architecture Flow&lt;/a&gt;&lt;/h2&gt;
&lt;div style=&quot;font-family: &#39;Courier New&#39;, monospace; margin: 2rem 0; overflow-x: auto;&quot;&gt;
  &lt;!-- Top inputs --&gt;
  &lt;div style=&quot;display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap;&quot;&gt;
&lt;p&gt;&lt;/p&gt;&lt;div style=&quot;display: flex; flex-direction: column; align-items: center; min-width: 180px;&quot;&gt;&lt;br /&gt;
&lt;div style=&quot;border: 2px solid #374151; border-radius: 6px; padding: 0.5rem 1rem; font-size: 0.85rem; font-weight: 700; text-align: center; background: #f9fafb;&quot;&gt;[ Input Sentence ]&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;font-size: 1.2rem; line-height: 1.2; color: #6b7280;&quot;&gt;↓&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;border: 1px solid #d1d5db; border-radius: 6px; padding: 0.4rem 0.75rem; font-size: 0.78rem; text-align: center; background: #f3f4f6;&quot;&gt;Embedding&lt;br /&gt;+ Positional Encoding&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;font-size: 1.2rem; line-height: 1.2; color: #6b7280;&quot;&gt;↓&lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;div style=&quot;display: flex; flex-direction: column; align-items: center; min-width: 180px;&quot;&gt;&lt;br /&gt;
&lt;div style=&quot;border: 2px solid #374151; border-radius: 6px; padding: 0.5rem 1rem; font-size: 0.85rem; font-weight: 700; text-align: center; background: #f9fafb;&quot;&gt;[ Output So Far ]&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;font-size: 1.2rem; line-height: 1.2; color: #6b7280;&quot;&gt;↓&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;border: 1px solid #d1d5db; border-radius: 6px; padding: 0.4rem 0.75rem; font-size: 0.78rem; text-align: center; background: #f3f4f6;&quot;&gt;Embedding&lt;br /&gt;+ Positional Encoding&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;font-size: 1.2rem; line-height: 1.2; color: #6b7280;&quot;&gt;↓&lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;p&gt;&lt;/p&gt;
  &lt;/div&gt;
  &lt;!-- Encoder + Decoder row --&gt;
  &lt;div style=&quot;display: flex; gap: 0; justify-content: center; align-items: center; flex-wrap: wrap; margin-top: 0.25rem;&quot;&gt;
&lt;p&gt;&lt;!-- ENCODER --&gt;&lt;br /&gt;
&lt;/p&gt;&lt;div style=&quot;border: 2px solid #1d4ed8; border-radius: 8px; min-width: 180px; max-width: 210px; overflow: hidden;&quot;&gt;&lt;br /&gt;
&lt;div style=&quot;background: #1d4ed8; color: white; text-align: center; padding: 0.4rem; font-size: 0.8rem; font-weight: 700; letter-spacing: 0.05em;&quot;&gt;ENCODER&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;padding: 0.75rem; display: flex; flex-direction: column; gap: 0.4rem;&quot;&gt;&lt;br /&gt;
&lt;div style=&quot;border: 1px solid #93c5fd; border-radius: 4px; padding: 0.35rem 0.5rem; font-size: 0.72rem; text-align: center; background: #eff6ff;&quot;&gt;Multi-Head Self-Attention&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;font-size: 0.7rem; text-align: center; color: #6b7280;&quot;&gt;↓&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;border: 1px solid #86efac; border-radius: 4px; padding: 0.35rem 0.5rem; font-size: 0.72rem; text-align: center; background: #f0fdf4;&quot;&gt;Add &amp;amp; Norm&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;font-size: 0.7rem; text-align: center; color: #6b7280;&quot;&gt;↓&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;border: 1px solid #93c5fd; border-radius: 4px; padding: 0.35rem 0.5rem; font-size: 0.72rem; text-align: center; background: #eff6ff;&quot;&gt;Feed-Forward Network&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;font-size: 0.7rem; text-align: center; color: #6b7280;&quot;&gt;↓&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;border: 1px solid #86efac; border-radius: 4px; padding: 0.35rem 0.5rem; font-size: 0.72rem; text-align: center; background: #f0fdf4;&quot;&gt;Add &amp;amp; Norm&lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- CONNECTOR: Context Matrix Z --&gt;&lt;br /&gt;
&lt;/p&gt;&lt;div style=&quot;display: flex; flex-direction: column; align-items: center; padding: 0 0.5rem; min-width: 90px; flex-shrink: 0;&quot;&gt;&lt;br /&gt;
&lt;div style=&quot;border: 1px dashed #f59e0b; border-radius: 6px; padding: 0.35rem 0.5rem; font-size: 0.65rem; text-align: center; background: #fefce8; color: #92400e; font-weight: 600; white-space: nowrap;&quot;&gt;Context Matrix&lt;br /&gt;(Z)&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;font-size: 0.75rem; color: #f59e0b; letter-spacing: -1px;&quot;&gt;── K, V ──►&lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- DECODER --&gt;&lt;br /&gt;
&lt;/p&gt;&lt;div style=&quot;border: 2px solid #7c3aed; border-radius: 8px; min-width: 180px; max-width: 210px; overflow: hidden;&quot;&gt;&lt;br /&gt;
&lt;div style=&quot;background: #7c3aed; color: white; text-align: center; padding: 0.4rem; font-size: 0.8rem; font-weight: 700; letter-spacing: 0.05em;&quot;&gt;DECODER&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;padding: 0.75rem; display: flex; flex-direction: column; gap: 0.4rem;&quot;&gt;&lt;br /&gt;
&lt;div style=&quot;border: 1px solid #c4b5fd; border-radius: 4px; padding: 0.35rem 0.5rem; font-size: 0.72rem; text-align: center; background: #f5f3ff;&quot;&gt;Masked Self-Attention&lt;br /&gt;&lt;span style=&quot;font-size: 0.65rem; color: #6b7280;&quot;&gt;(can’t see future words)&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;font-size: 0.7rem; text-align: center; color: #6b7280;&quot;&gt;↓&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;border: 1px solid #86efac; border-radius: 4px; padding: 0.35rem 0.5rem; font-size: 0.72rem; text-align: center; background: #f0fdf4;&quot;&gt;Add &amp;amp; Norm&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;font-size: 0.7rem; text-align: center; color: #6b7280;&quot;&gt;↓&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;border: 2px solid #f59e0b; border-radius: 4px; padding: 0.35rem 0.5rem; font-size: 0.72rem; text-align: center; background: #fffbeb;&quot;&gt;Cross-Attention&lt;br /&gt;&lt;span style=&quot;font-size: 0.65rem; color: #92400e; font-weight: 600;&quot;&gt;← receives K, V from Encoder&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;font-size: 0.7rem; text-align: center; color: #6b7280;&quot;&gt;↓&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;border: 1px solid #86efac; border-radius: 4px; padding: 0.35rem 0.5rem; font-size: 0.72rem; text-align: center; background: #f0fdf4;&quot;&gt;Add &amp;amp; Norm&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;font-size: 0.7rem; text-align: center; color: #6b7280;&quot;&gt;↓&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;border: 1px solid #c4b5fd; border-radius: 4px; padding: 0.35rem 0.5rem; font-size: 0.72rem; text-align: center; background: #f5f3ff;&quot;&gt;Feed-Forward Network&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;font-size: 0.7rem; text-align: center; color: #6b7280;&quot;&gt;↓&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;border: 1px solid #86efac; border-radius: 4px; padding: 0.35rem 0.5rem; font-size: 0.72rem; text-align: center; background: #f0fdf4;&quot;&gt;Add &amp;amp; Norm&lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;p&gt;&lt;/p&gt;
  &lt;/div&gt;
  &lt;!-- Output pipeline --&gt;
  &lt;div style=&quot;display: flex; flex-direction: column; align-items: center; margin-top: 0.5rem; gap: 0.1rem;&quot;&gt;
    &lt;div style=&quot;font-size: 1.2rem; color: #6b7280;&quot;&gt;↓&lt;/div&gt;
    &lt;div style=&quot;border: 1px solid #d1d5db; border-radius: 6px; padding: 0.4rem 1.5rem; font-size: 0.78rem; text-align: center; background: #f3f4f6;&quot;&gt;Linear Projection&lt;/div&gt;
    &lt;div style=&quot;font-size: 1.2rem; color: #6b7280;&quot;&gt;↓&lt;/div&gt;
    &lt;div style=&quot;border: 1px solid #d1d5db; border-radius: 6px; padding: 0.4rem 1.5rem; font-size: 0.78rem; text-align: center; background: #f3f4f6;&quot;&gt;Softmax (Probabilities)&lt;/div&gt;
    &lt;div style=&quot;font-size: 1.2rem; color: #6b7280;&quot;&gt;↓&lt;/div&gt;
    &lt;div style=&quot;border: 2px solid #374151; border-radius: 6px; padding: 0.5rem 1.5rem; font-size: 0.85rem; font-weight: 700; text-align: center; background: #f9fafb;&quot;&gt;[ Next Word Output ]&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Let’s break down exactly what happens to our data at every single stage of this pipeline.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;phase-1%3A-preparation-(tokenization-embeddings-positional-encoding)&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-Transformer/#phase-1%3A-preparation-(tokenization-embeddings-positional-encoding)&quot;&gt;Phase 1: Preparation (Tokenization-Embeddings-Positional Encoding)&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When we pass the sentence &lt;code&gt;&amp;quot;My name is Ankit&amp;quot;&lt;/code&gt; into the model, neural networks cannot read text. They only understand continuous numbers.&lt;/p&gt;
&lt;h3 id=&quot;step-1.1%3A-tokenization-%26-embeddings&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-Transformer/#step-1.1%3A-tokenization-%26-embeddings&quot;&gt;Step 1.1: Tokenization &amp;amp; Embeddings&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The sentence is broken into IDs and mapped into a continuous representation matrix $X$.&lt;/p&gt;
&lt;p&gt;$$&#92;text{“My name is Ankit”} &#92; &#92;longrightarrow &#92; [523, 1024, 98, 4567] &#92; &#92;longrightarrow &#92; X &#92;in &#92;mathbb{R}^{4 &#92;times d_{&#92;text{model}}}$$&lt;/p&gt;
&lt;h3 id=&quot;step-1.2%3A-positional-encoding&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-Transformer/#step-1.2%3A-positional-encoding&quot;&gt;Step 1.2: Positional Encoding&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Because the Transformer ingests all 4 tokens simultaneously, it has zero concept of word order. To the raw network, &lt;em&gt;“My name is Ankit”&lt;/em&gt; and &lt;em&gt;“Ankit is my name”&lt;/em&gt; are mathematically identical.&lt;/p&gt;
&lt;p&gt;To fix this, we fuse a mathematical watermark—a &lt;strong&gt;Positional Encoding Vector&lt;/strong&gt;—directly into our embeddings.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-matrix&quot;&gt;  [0.12,  0.33]  // Semantic Meaning (&amp;quot;My&amp;quot;)
+ [0.84,  0.11]  // Sine Waveform (Position 1)
────────────────
= [0.96,  0.44]  // Position-Aware Vector
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By adding specific sine and cosine wave frequencies, the model naturally learns to separate the underlying meaning of the word from its physical coordinate in the sentence.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;phase-2%3A-the-encoder-(building-deep-understanding)&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-Transformer/#phase-2%3A-the-encoder-(building-deep-understanding)&quot;&gt;Phase 2: The Encoder (Building Deep Understanding)&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Our position-aware matrix $X$ now enters the &lt;strong&gt;Encoder&lt;/strong&gt;. The Encoder’s solitary job is to analyze the input sentence and construct a deeply interconnected representation of it.&lt;/p&gt;
&lt;h3 id=&quot;step-2.1%3A-multi-head-self-attention&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-Transformer/#step-2.1%3A-multi-head-self-attention&quot;&gt;Step 2.1: Multi-Head Self-Attention&lt;/a&gt;&lt;/h3&gt;
&lt;a href=&quot;https://aiankit.com/writing/self-attention-from-first-principle/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;text-blue-500 hover:underline text-sm font-semibold mb-4 block&quot;&gt;
    ↳ Deep Dive: Read Self-Attention from First Principles
&lt;/a&gt;
&lt;p&gt;Language is deeply complicated. Ever wondered how the exact same sentence in English can have multiple interpretations?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;“She saw the man with the telescope.”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;By looking at this, a Transformer must generate not just one, but multiple different attention masks:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Dependency 1:&lt;/strong&gt; (saw → man, man → telescope) — &lt;em&gt;The man has the telescope.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dependency 2:&lt;/strong&gt; (she → telescope, saw → man) — &lt;em&gt;She is using the telescope to see the man.&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With &lt;strong&gt;one&lt;/strong&gt; attention head, the model can focus on only one type of relationship at a time. But language has many relationships simultaneously.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Limitation of a Single Head&lt;/strong&gt;&lt;br /&gt;
Consider the sentence: &lt;code&gt;&amp;quot;I love Apple Phone&amp;quot;&lt;/code&gt;&lt;br /&gt;
Things happening at once:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Apple → Phone&lt;/code&gt; (Brand / Tech)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Love → Apple&lt;/code&gt; (Sentiment)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;I → Love&lt;/code&gt; (Subject - Verb)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Word Order&lt;/code&gt; (Positional structure)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A single attention head must average all of these into one focus. &lt;strong&gt;That loses information.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Solution: Multi-Head Attention&lt;/strong&gt;&lt;br /&gt;
Multi-Head Attention = Multiple independent attention mechanisms running in parallel.&lt;/p&gt;
&lt;p&gt;Each head:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sees the same sentence.&lt;/li&gt;
&lt;li&gt;Uses its own learned projections ($W^Q, W^K, W^V$).&lt;/li&gt;
&lt;li&gt;Focuses on a different relationship.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Think of it as multiple viewpoints looking at the exact same data. Each word embedding is copied into multiple heads, so each head creates its own independent geometry.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Head 1:&lt;/strong&gt; Focuses on syntax.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Head 2:&lt;/strong&gt; Focuses on semantics.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Head 3:&lt;/strong&gt; Focuses on entities.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Head 4:&lt;/strong&gt; Focuses on long-range relations.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;No one tells them this explicitly. &lt;strong&gt;Training discovers it.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why Splitting into Heads Helps (Important Intuition)&lt;/strong&gt;&lt;br /&gt;
Instead of doing one massive 512-dimensional attention pass, we do 8 heads $&#92;times$ 64-dimensional attention.&lt;/p&gt;
&lt;p&gt;Why don’t all heads just learn the exact same thing?&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Different random initialization:&lt;/strong&gt; At the start, all $W$ matrices are random. They are literally looking in different directions in vector space.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dimensional Bottleneck:&lt;/strong&gt; Because each head only gets 64 dimensions, it cannot memorize everything. It is forced to specialize.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;What Happens During the First Forward Pass?&lt;/strong&gt;&lt;br /&gt;
Sentence: &lt;em&gt;“Apple released a new phone and people love it.”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Because the weights are random, the early attention patterns are accidental:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Head 1 Attention:&lt;/strong&gt; Apple → released → phone → it (Nearby words)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Head 2 Attention:&lt;/strong&gt; love → people → it (Emotion-heavy words)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Head 3 Attention:&lt;/strong&gt; Apple → phone (Capitalized / Noun words)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;What Happens During Backpropagation?&lt;/strong&gt;&lt;br /&gt;
Suppose the model makes a mistake in understanding entity reference (failing to realize “it” refers to “phone”). Loss is high.&lt;/p&gt;
&lt;p&gt;Backprop asks: &lt;em&gt;“Which parameters most influenced the wrong output?”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Each head gets different gradients because their outputs and contributions were different:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Head 2&lt;/strong&gt; (Sentiment) helped prediction a bit. Gradient reinforces emotional alignment.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Head 3&lt;/strong&gt; (Entities) helped entity resolution. Gradient strongly reinforces entity links.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Head 1&lt;/strong&gt; (Nearby words) didn’t help much. Gradient weakens or pushes it elsewhere.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Over millions of examples, gradients strengthen useful patterns and weaken useless ones. Just like CNNs naturally learn filters for edges and textures, different heads capture different aspects of the sentence.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Linear Transformation ($W_O$)&lt;/strong&gt;&lt;br /&gt;
Each head produces an output vector. All head outputs are concatenated and passed through one final linear layer ($W_O$). The job of $W_O$ is to make sure only the relevant head information is passed forward into the final combined representation.&lt;/p&gt;
&lt;h3 id=&quot;step-2.2%3A-the-%E2%80%9Cadd-%26-norm%E2%80%9D&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-Transformer/#step-2.2%3A-the-%E2%80%9Cadd-%26-norm%E2%80%9D&quot;&gt;Step 2.2: The “Add &amp;amp; Norm”&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Immediately after attention routing, the mixed output passes through an &lt;strong&gt;Add &amp;amp; Norm&lt;/strong&gt; stabilization layer.&lt;/p&gt;
&lt;p&gt;$$&#92;text{Output} = &#92;text{LayerNorm}&#92;Big(&#92;text{Attention}(X) + X &#92;Big)$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. The “Add” (Residual Connection) — Preventing Information Loss&lt;/strong&gt;&lt;br /&gt;
We physically add the original input $X$ directly back to the Attention output vector.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-matrix&quot;&gt;  [ 0.22, 0.44 ]  // Processed Attention Output
+ [ 0.10, 0.80 ]  // Original Input X (Uncorrupted)
────────────────
= [ 0.32, 1.24 ]  // Bypassed Residual Vector
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Why is this necessary?&lt;/strong&gt;&lt;br /&gt;
When a Transformer is initialized, its weights are completely random. When you pass an input vector through multiple matrix multiplications, it gradually becomes mathematically distorted.&lt;/p&gt;
&lt;p&gt;In the first few layers, this isn’t a huge issue. But as the network gets deeper, the original input starts getting severely corrupted. By the time it reaches the output layer, massive information loss has occurred.&lt;/p&gt;
&lt;p&gt;If a specific attention layer fails to learn anything useful early in training, the raw features flow safely past it, structurally eliminating the &lt;strong&gt;Vanishing Gradient&lt;/strong&gt; problem.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. The “Norm” (Layer Normalization) — Stabilizing Training&lt;/strong&gt;&lt;br /&gt;
Deep networks are notoriously unstable. Without normalization, some activation numbers grow exponentially large (Exploding Gradients), while others shrink to zero.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why is this catastrophic for speed?&lt;/strong&gt;&lt;br /&gt;
If you have unnormalized data with wild variance, you are forced to use a very &lt;strong&gt;Small Learning Rate&lt;/strong&gt; to prevent the model from crashing. A smaller learning rate means the model will take a significantly longer time to converge to the minimum loss. Training becomes painfully slow.&lt;/p&gt;
&lt;p&gt;Layer Normalization solves this by mathematically standardizing the variance within each token. Let’s see the exact internal computation:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-matrix&quot;&gt;// 1. Token Vector
x = [2.0, 4.0, 6.0, 8.0]

// 2. Compute Mean (μ)
μ = (2 + 4 + 6 + 8) / 4 = 5.0

// 3. Subtract Mean
x - μ = [-3.0, -1.0, 1.0, 3.0]

// 4. Divide by Standard Deviation (σ ≈ 2.23)
Normalized = [-1.34, -0.44, 0.44, 1.34]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By explicitly keeping the numbers tightly bounded around zero, the model avoids gradient explosions. This allows us to use a &lt;strong&gt;High Learning Rate&lt;/strong&gt;, radically improving training speed and stability.&lt;/p&gt;
&lt;h3 id=&quot;step-2.3%3A-feed-forward-network-(the-concept-factory)&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-Transformer/#step-2.3%3A-feed-forward-network-(the-concept-factory)&quot;&gt;Step 2.3: Feed-Forward Network (The Concept Factory)&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Self-Attention only &lt;em&gt;routes&lt;/em&gt; information between tokens. It is fundamentally a linear operation. But to truly understand language, a model must be able to draw complex, non-linear boundaries.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;Feed-Forward Network (FFN)&lt;/strong&gt; introduces &lt;strong&gt;Non-Linearity&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;$$&#92;text{FFN}(x) = &#92;max(0, xW_1 + b_1)W_2 + b_2$$&lt;/p&gt;
&lt;p&gt;Let’s look at the exact mathematical mechanics inside the Concept Factory:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-matrix&quot;&gt;// Step 1: Input vector (2-dim, simplified)
Input = [0.5, 0.3]

// W_1 projects it up to 5 dimensions (learned weighted sums)
Expanded = [4.2, -1.8, 3.1, -0.5, 8.9]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-matrix&quot;&gt;// Step 2: Apply ReLU  →  max(0, x)  →  Kill every negative
Before: [  4.2, -1.8,  3.1, -0.5,  8.9 ]
After:  [  4.2,    0,  3.1,    0,  8.9 ]  // ◄── -1.8 and -0.5 zeroed out
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-matrix&quot;&gt;// Step 3: W_2 projects back down (5 → 3 dims)
// Each output is a dot product of ALL 5 ReLU values × a learned row of W_2

W_2 row 1 = [0.3, 0.1, 0.5, 0.2, 0.4]
Output[0]  = (4.2×0.3)+(0×0.1)+(3.1×0.5)+(0×0.2)+(8.9×0.4) = 1.26+0+1.55+0+3.56 = 6.37

W_2 row 2 = [0.2, 0.4, 0.1, 0.3, 0.2]
Output[1]  = (4.2×0.2)+(0×0.4)+(3.1×0.1)+(0×0.3)+(8.9×0.2) = 0.84+0+0.31+0+1.78 = 2.93

Final Output = [6.37, 2.93, ...]   // ◄── Back to standard dimension
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;$W_2$ is a learned matrix. Each output value is a dot product that &lt;strong&gt;mixes all 5 ReLU signals&lt;/strong&gt; into a single summary number. The network learns exactly which combination of signals encodes useful concepts. That is how 2048 neurons get distilled back down to 512 dimensions.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(Note: The output of the FFN passes through a second Add &amp;amp; Norm layer before officially exiting the Encoder).&lt;/em&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;phase-3%3A-the-decoder-(generating-the-answer)&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-Transformer/#phase-3%3A-the-decoder-(generating-the-answer)&quot;&gt;Phase 3: The Decoder (Generating the Answer)&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The Encoder is finished. It outputs a highly dense, fully contextualized matrix called the &lt;strong&gt;Context Matrix ($Z$)&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Now, the &lt;strong&gt;Decoder&lt;/strong&gt; steps in. Its job is to take that Context Matrix ($Z$) and generate the output text autoregressively (one word at a time).&lt;/p&gt;
&lt;h3 id=&quot;step-3.1%3A-masked-self-attention&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-Transformer/#step-3.1%3A-masked-self-attention&quot;&gt;Step 3.1: Masked Self-Attention&lt;/a&gt;&lt;/h3&gt;
&lt;a href=&quot;https://aiankit.com/writing/self-attention-from-first-principle/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;text-blue-500 hover:underline text-sm font-semibold mb-4 block&quot;&gt;
    ↳ Deep Dive: Read Self-Attention from First Principles
&lt;/a&gt;
&lt;p&gt;Masked Multi-Head Attention is self-attention where a token is &lt;strong&gt;NOT allowed to look at future tokens&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Before we do the math, let’s understand the structural difference between the two halves of the Transformer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Encoder:&lt;/strong&gt; Sees the full input at once. Builds a global understanding. No masking.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Decoder:&lt;/strong&gt; Generates output step by step. Uses masked self-attention to see only past outputs.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Why Do We Need Masking?&lt;/strong&gt;&lt;br /&gt;
The Decoder’s job is to generate text one word at a time. Consider the sentence: &lt;code&gt;&amp;quot;I love apple phone&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;When predicting:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;word 1 → &lt;code&gt;&amp;quot;I&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;word 2 → &lt;code&gt;&amp;quot;love&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;word 3 → &lt;code&gt;&amp;quot;apple&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;word 4 → &lt;code&gt;&amp;quot;phone&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At the exact moment of predicting &lt;code&gt;&amp;quot;apple&amp;quot;&lt;/code&gt;, the model must &lt;strong&gt;NOT&lt;/strong&gt; see &lt;code&gt;&amp;quot;phone&amp;quot;&lt;/code&gt;. Why? Because &lt;code&gt;&amp;quot;phone&amp;quot;&lt;/code&gt; is the exact answer it is supposed to predict later!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Without Masking&lt;/strong&gt;&lt;br /&gt;
During training, the Decoder processes all target words simultaneously for massive GPU efficiency. Suppose the Decoder sees the entire sequence &lt;code&gt;&amp;quot;I love apple phone&amp;quot;&lt;/code&gt; at once. While predicting &lt;code&gt;&amp;quot;apple&amp;quot;&lt;/code&gt;, the attention mechanism would simply look ahead at &lt;code&gt;&amp;quot;phone&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The model learns a lazy, catastrophic rule: &lt;em&gt;“Just peek at the future to get the answer.”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;At inference time—when you are actually chatting with the AI—future words do not exist yet. Because the model relied on cheating during training, it completely fails to generate anything useful.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Math of Masking&lt;/strong&gt;&lt;br /&gt;
To prevent cheating, we must enforce causality. The model applies a &lt;strong&gt;Mask&lt;/strong&gt; to the raw $QK^T$ attention scores before applying Softmax. It explicitly overwrites all future coordinate scores with negative infinity ($-&#92;infty$), creating a lower-triangular matrix:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-matrix&quot;&gt;      [ Word 1, Word 2, Word 3, Word 4 ]
Word 1 [   1.2,   -Inf,   -Inf,   -Inf ]
Word 2 [   0.4,    1.1,   -Inf,   -Inf ]
Word 3 [   0.9,    0.1,    2.2,   -Inf ]
Word 4 [   0.2,    0.5,    1.4,    0.8 ]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When this matrix passes through the Softmax function ($&#92;frac{e^{x}}{&#92;sum e^x}$), any value of $e^{-&#92;infty}$ collapses exactly to $0$.&lt;/p&gt;
&lt;p&gt;Future words are mathematically erased. Word 2 is only allowed to route information from Word 1 and itself. This strictly enforces causality, ensuring the model learns to truly predict the next word rather than simply copying it.&lt;/p&gt;
&lt;h3 id=&quot;step-3.2%3A-cross-attention&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-Transformer/#step-3.2%3A-cross-attention&quot;&gt;Step 3.2: Cross-Attention&lt;/a&gt;&lt;/h3&gt;
&lt;a href=&quot;https://aiankit.com/writing/self-attention-from-first-principle/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;text-blue-500 hover:underline text-sm font-semibold mb-4 block&quot;&gt;
    ↳ Deep Dive: Read Self-Attention from First Principles
&lt;/a&gt;
&lt;p&gt;Next, the Decoder must link its generated text with the original input sentence. It does this via &lt;strong&gt;Cross-Attention&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Unlike Self-Attention where $Q, K, V$ all come from the exact same sentence, Cross-Attention deliberately splits the source matrices.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Math of the Bridge:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;Queries ($Q$)&lt;/strong&gt; are generated from the &lt;em&gt;Decoder’s&lt;/em&gt; current word.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;Keys ($K$)&lt;/strong&gt; and &lt;strong&gt;Values ($V$)&lt;/strong&gt; are pulled directly from the &lt;em&gt;Encoder’s&lt;/em&gt; fully processed Context Matrix ($Z$).&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-matrix&quot;&gt;  Decoder&#39;s generated text so far ──►  Generates Query (Q)
                                              │
  Encoder&#39;s Source text (Matrix Z) ──►  Generates Key (K) &amp;amp; Value (V)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;First-Principle Example:&lt;/strong&gt;&lt;br /&gt;
Suppose we are translating &lt;em&gt;“I love Apple”&lt;/em&gt; to French. The Decoder has already generated &lt;em&gt;“Je”&lt;/em&gt;. Now it must generate the next word.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;The Query:&lt;/strong&gt; The Decoder projects &lt;em&gt;“Je”&lt;/em&gt; into a Query vector ($Q$). Mathematically, it asks: &lt;em&gt;“I am a first-person pronoun. What context should I attach to?”&lt;/em&gt;&lt;br /&gt;
$Q_{&#92;text{Je}} = [0.8, 0.2]$&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Keys:&lt;/strong&gt; The Encoder’s Context Matrix contains the deeply processed Keys ($K$) for &lt;em&gt;“I”&lt;/em&gt;, &lt;em&gt;“love”&lt;/em&gt;, and &lt;em&gt;“Apple”&lt;/em&gt;.&lt;br /&gt;
$K_{&#92;text{I}} = [0.9, 0.1]$&lt;br /&gt;
$K_{&#92;text{love}} = [0.1, 0.8]$&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Matching (Dot Product):&lt;/strong&gt; The Query computes the dot product multiplication against all Encoder Keys to measure geometric similarity.&lt;pre&gt;&lt;code class=&quot;language-matrix&quot;&gt;Q(&amp;quot;Je&amp;quot;) • K(&amp;quot;I&amp;quot;)    = (0.8 × 0.9) + (0.2 × 0.1) = 0.74  (High Alignment)
Q(&amp;quot;Je&amp;quot;) • K(&amp;quot;love&amp;quot;) = (0.8 × 0.1) + (0.2 × 0.8) = 0.24  (Low Alignment)
&lt;/code&gt;&lt;/pre&gt;
It discovers a massive mathematical alignment with $K_{&#92;text{I}}$.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Value (Softmax + Weighted Blend):&lt;/strong&gt; The raw scores are converted to attention weights via Softmax, then used to &lt;strong&gt;blend&lt;/strong&gt; all Value vectors together:&lt;pre&gt;&lt;code class=&quot;language-matrix&quot;&gt;// Softmax on dot product scores
e^0.74 = 2.10  →  2.10 / 3.37 = 62%  weight on V(&amp;quot;I&amp;quot;)
e^0.24 = 1.27  →  1.27 / 3.37 = 38%  weight on V(&amp;quot;love&amp;quot;)

// Value vectors (simplified)
V(&amp;quot;I&amp;quot;)    = [1.0, 0.0]
V(&amp;quot;love&amp;quot;) = [0.0, 1.0]

// Final output = weighted blend
Output = 0.62 × [1.0, 0.0]  +  0.38 × [0.0, 1.0]
       = [0.62, 0.38]   // ◄── Carries 62% &amp;quot;I&amp;quot; meaning + 38% &amp;quot;love&amp;quot; meaning
&lt;/code&gt;&lt;/pre&gt;
The Decoder does not blindly pick one word. It blends the meaning of every source token, weighted by alignment strength. This &lt;code&gt;[0.62, 0.38]&lt;/code&gt; context vector is then passed into the FFN.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Cross-Attention is a translator computing dot products against a dictionary. The Decoder maps its current state onto a weighted semantic blend of the entire source sentence.&lt;/p&gt;
&lt;p&gt;After Cross-Attention, the Decoder runs the vectors through its own Feed-Forward Network and Add &amp;amp; Norm layers.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;phase-4%3A-output-translation-(linear-%26-softmax)&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-Transformer/#phase-4%3A-output-translation-(linear-%26-softmax)&quot;&gt;Phase 4: Output Translation (Linear &amp;amp; Softmax)&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We are translating &lt;em&gt;“I love Apple”&lt;/em&gt; to French. The Decoder has generated &lt;em&gt;“Je”&lt;/em&gt;. Now the final layers must select the next French word.&lt;/p&gt;
&lt;p&gt;The final context vector is pushed through a &lt;strong&gt;Linear Layer&lt;/strong&gt; that scores every word in the 50,000-word French vocabulary. Each score is called a &lt;strong&gt;logit&lt;/strong&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-matrix&quot;&gt;// Step 1: Raw Logits from the Linear Layer
aime  = 4.5    // &amp;quot;love&amp;quot; in French  ← likely next word
suis  = 2.1    // &amp;quot;am&amp;quot; in French
mange = 1.2    // &amp;quot;eat&amp;quot; in French
...            // 49,997 more words with tiny scores
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-matrix&quot;&gt;// Step 2: Exponentiate every logit  e^x  (makes all values positive)
e^4.5 = 90.01   // aime
e^2.1 =  8.16   // suis
e^1.2 =  3.32   // mange
Sum   = 101.49  // (real sum spans all 50,000 words)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-matrix&quot;&gt;// Step 3: Divide each by Sum → final probability for every word
aime  =  90.01 / 101.49 = 89%  // ◄── Winner. Model outputs &amp;quot;aime&amp;quot;
suis  =   8.16 / 101.49 =  8%
mange =   3.32 / 101.49 =  3%
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The model outputs &lt;code&gt;&amp;quot;aime&amp;quot;&lt;/code&gt; with 89% confidence. The Decoder’s input is now &lt;code&gt;&amp;quot;Je aime&amp;quot;&lt;/code&gt;. On the next loop it predicts the French word for &lt;em&gt;Apple&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;This loop runs until the model outputs &lt;code&gt;&amp;lt;EOS&amp;gt;&lt;/code&gt; (End Of Sequence), terminating generation. The final translation: &lt;strong&gt;“Je aime Apple”&lt;/strong&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;summary-of-the-engine&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-Transformer/#summary-of-the-engine&quot;&gt;Summary of the Engine&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Block&lt;/th&gt;
&lt;th&gt;Mathematical Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Positional Encoding&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fuses spatial time-step coordinates directly into the semantic vectors.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Multi-Head Attention&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Analyzes the sequence from multiple structural perspectives in parallel.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Add &amp;amp; Norm&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Bypasses failing layers to preserve gradients and stabilizes numerical variance.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Feed-Forward&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Constructs higher-order concepts from the routed contextual evidence.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Masked Attention&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Zeroes out future coordinates to prevent the decoder from cheating.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cross-Attention&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Routes the decoder’s current progress directly to the encoder’s source understanding.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;This article i wrote specially for myself to grasping the entire concept in more better way and try to not forget.&lt;/p&gt;
&lt;p&gt;Comment down your thoughts below, if you found it helpful !&lt;/p&gt;
&lt;h2 id=&quot;references&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-Transformer/#references&quot;&gt;References&lt;/a&gt;&lt;/h2&gt;
&lt;a href=&quot;https://arxiv.org/pdf/1706.03762&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;
    Attention Is All You Need
&lt;/a&gt;
&lt;p&gt;Best,&lt;br /&gt;
Ankit&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Understanding Self-Attention: From First Principles</title>
    <link href="https://aiankit.com/writing/understanding-self-attention/"/>
    <updated>2026-06-07T00:00:00Z</updated>
    <id>https://aiankit.com/writing/understanding-self-attention/</id>
    <content xml:lang="en" type="html">&lt;p&gt;Self-Attention from First Principles. I have read a lot of articles and watched many videos, and I noticed that most people don’t explain this incredibly important topic in the easiest manner.&lt;/p&gt;
&lt;p&gt;$$&#92;text{Attention}(Q, K, V) = &#92;text{softmax}&#92;left(&#92;frac{QK^T}{&#92;sqrt{d_k}}&#92;right)V$$&lt;/p&gt;
&lt;p&gt;Most resources require you to be good at Deep Learning and its mathematics to fully grasp the concepts.&lt;/p&gt;
&lt;p&gt;But Self-Attention is actually simple if learned the right way.&lt;/p&gt;
&lt;p&gt;At its core, Self-Attention relies on just three foundational components:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Dot Product&lt;/strong&gt; (The Matching Tool)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Weights&lt;/strong&gt; (The Learnable Transformation)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data&lt;/strong&gt; (The Values to Transmit)&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;p&gt;Self-attention was the core innovation that enabled the Transformer architecture, which ultimately transformed modern AI, that we see today.&lt;/p&gt;
&lt;p&gt;I won’t start with abstract formulas, instead,&lt;/p&gt;
&lt;p&gt;I will break things down in the simplest way possible by giving you raw intuition first, building up to the complete mathematical matrix.&lt;/p&gt;
&lt;p&gt;Want visuals? Check out &lt;a href=&quot;https://jalammar.github.io/illustrated-transformer/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;The Illustrated Transformer By Jay Alammar&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Want code? Check out &lt;a href=&quot;https://sebastianraschka.com/blog/2023/self-attention-from-scratch.html&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Self-Attention From Scratch By Sebastrian Raschka&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Want intuition first? Keep reading.&lt;/p&gt;
&lt;p&gt;Let’s begin.&lt;/p&gt;
&lt;h2 id=&quot;step-1%3A-we-have-a-sentence&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#step-1%3A-we-have-a-sentence&quot;&gt;Step 1: We Have a Sentence&lt;/a&gt;&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;quot;My name is Ankit&amp;quot;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Tokenizer converts these words into numerical IDs:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;[523, 1024, 98, 4567]

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These numbers are just IDs with no inherent meaning yet. Think of them as simple mappings:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;My     = 523
name   = 1024
is     = 98
Ankit  = 4567

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They are just labels, exactly like a Student ID or an Employee ID.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;step-2%3A-embedding-layer&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#step-2%3A-embedding-layer&quot;&gt;Step 2: Embedding Layer&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now we need to add meaning. Suppose our embedding dimension is 2 for learning purposes. The model uses a large lookup table called an embedding table:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Token ID&lt;/th&gt;
&lt;th&gt;Embedding Vector&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;523&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$[0.12, &#92;phantom{-}0.33]$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;1024&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$[0.51, -0.20]$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;98&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$[0.22, &#92;phantom{-}0.78]$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;4567&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$[0.88, &#92;phantom{-}0.12]$&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Mapping our tokens to vectors gives us this structured representation:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Word&lt;/th&gt;
&lt;th&gt;Dimension 1&lt;/th&gt;
&lt;th&gt;Dimension 2&lt;/th&gt;
&lt;th&gt;Vector Representation ($&#92;vec{x}$)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;My&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.12&lt;/td&gt;
&lt;td&gt;0.33&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[0.12, 0.33]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;name&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.51&lt;/td&gt;
&lt;td&gt;-0.20&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[0.51, -0.20]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;is&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.22&lt;/td&gt;
&lt;td&gt;0.78&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[0.22, 0.78]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ankit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.88&lt;/td&gt;
&lt;td&gt;0.12&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[0.88, 0.12]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h3 id=&quot;question%3A-what-does-a-vector-like-%5B0.12%2C-0.33%5D-actually-mean%3F&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#question%3A-what-does-a-vector-like-%5B0.12%2C-0.33%5D-actually-mean%3F&quot;&gt;Question: What does a vector like &lt;code&gt;[0.12, 0.33]&lt;/code&gt; actually mean?&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Answer:&lt;/strong&gt; Nobody knows exactly. This is a very important concept to understand.&lt;/p&gt;
&lt;p&gt;People often assume:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0.12&lt;/code&gt; = person score&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0.33&lt;/code&gt; = noun score&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is not true. The vector represents a &lt;strong&gt;compressed meaning&lt;/strong&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;step-3%3A-put-all-embeddings-together&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#step-3%3A-put-all-embeddings-together&quot;&gt;Step 3: Put All Embeddings Together&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Next, we stack these individual vectors together into a single data matrix, which we call $X$. Let’s break down the assembly of this matrix line by line, mapping each word to its specific row.&lt;/p&gt;
&lt;p&gt;First, we take the vector for &lt;strong&gt;My&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;X =&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-matrix&quot;&gt;[
  [0.12, 0.33]
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we stack the vector for &lt;strong&gt;name&lt;/strong&gt; directly underneath:&lt;/p&gt;
&lt;p&gt;X =&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-matrix&quot;&gt;[
  [0.12, 0.33],
  [0.51, -0.20]
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, we append the vector for &lt;strong&gt;is&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;X =&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-matrix&quot;&gt;[
  [0.12, 0.33],
  [0.51, -0.20],
  [0.22, 0.78]
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, we add the vector for &lt;strong&gt;Ankit&lt;/strong&gt; to complete our sequence:&lt;/p&gt;
&lt;p&gt;X =&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-matrix&quot;&gt;[
  [0.12, 0.33],
  [0.51, -0.20],
  [0.22, 0.78],
  [0.88, 0.12]
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To visualize this explicitly, we can view the finished matrix with its corresponding word rows:&lt;/p&gt;
&lt;p&gt;X =&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-matrix&quot;&gt;[
  [My],
  [name],
  [is],
  [Ankit]
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;=&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-matrix&quot;&gt;[
  [0.12, 0.33],
  [0.51, -0.20],
  [0.22, 0.78],
  [0.88, 0.12]
]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;shape-of-x&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#shape-of-x&quot;&gt;Shape of X&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Rows = 4:&lt;/strong&gt; Because we have 4 tokens (&lt;em&gt;My&lt;/em&gt;, &lt;em&gt;name&lt;/em&gt;, &lt;em&gt;is&lt;/em&gt;, &lt;em&gt;Ankit&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Columns = 2:&lt;/strong&gt; Because our embedding dimension is 2.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Therefore, the shape of our matrix is:&lt;/p&gt;
&lt;p&gt;$$X &#92;in &#92;mathbb{R}^{4 &#92;times 2}$$&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;visualization&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#visualization&quot;&gt;Visualization&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Think of each word as a point in an embedding space.&lt;/p&gt;
&lt;p&gt;The coordinates of the point are the values inside the embedding vector.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;My     → [0.12, 0.33]&lt;br /&gt;
name   → [0.51, -0.20]&lt;br /&gt;
is     → [0.22, 0.78]&lt;br /&gt;
Ankit  → [0.88, 0.12]&lt;/p&gt;
&lt;p&gt;In this toy 2D example, each embedding can be visualized as a point on a graph.&lt;/p&gt;
&lt;img src=&quot;https://aiankit.com/assets/images/blog/self-attention-visualize.png&quot; alt=&quot;Self-Attention Visualize&quot; class=&quot;w-full max-w-2xl mx-auto rounded-lg border border-gray-200 my-8&quot; /&gt;
&lt;h3 id=&quot;an-important-realization&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#an-important-realization&quot;&gt;An Important Realization&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;At this stage:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;My&lt;/em&gt; does NOT know that &lt;em&gt;name&lt;/em&gt; exists.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Ankit&lt;/em&gt; does NOT know that &lt;em&gt;My&lt;/em&gt; exists.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each token is completely independent. We only have &lt;strong&gt;Word Meaning&lt;/strong&gt;, not &lt;strong&gt;Sentence Meaning&lt;/strong&gt; yet.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;what-problem-does-attention-solve%3F&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#what-problem-does-attention-solve%3F&quot;&gt;What Problem Does Attention Solve?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Currently, we know:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Ankit = [0.88, 0.12]

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But the vector for &lt;em&gt;Ankit&lt;/em&gt; has no idea it is appearing inside the specific sentence &lt;em&gt;“My name is Ankit”&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The model needs &lt;em&gt;Ankit&lt;/em&gt; to learn that it is contextualized by and related to &lt;em&gt;My&lt;/em&gt;, &lt;em&gt;name&lt;/em&gt;, and &lt;em&gt;is&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;This is the exact motivation for Self-Attention.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;before-q%2C-k%2C-v%3A-raw-intuition&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#before-q%2C-k%2C-v%3A-raw-intuition&quot;&gt;Before Q, K, V: Raw Intuition&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let’s ask a fundamental question:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If I am the word “Ankit”, how can I determine which other words in this sentence are important to me?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A simple, intuitive approach is to &lt;strong&gt;compare my embedding with every other embedding&lt;/strong&gt; using a mathematical operation called the &lt;strong&gt;dot product&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ankit $&#92;leftrightarrow$ My&lt;/li&gt;
&lt;li&gt;Ankit $&#92;leftrightarrow$ name&lt;/li&gt;
&lt;li&gt;Ankit $&#92;leftrightarrow$ is&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This gives us our very first attention intuition: &lt;strong&gt;measuring similarity between words&lt;/strong&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;the-math%3A-computing-dot-products-manually&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#the-math%3A-computing-dot-products-manually&quot;&gt;The Math: Computing Dot Products Manually&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let’s compute the similarity scores for the word &lt;strong&gt;Ankit&lt;/strong&gt; on paper.&lt;/p&gt;
&lt;h3 id=&quot;our-embeddings-reference&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#our-embeddings-reference&quot;&gt;Our Embeddings Reference&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;My:&lt;/strong&gt; &lt;code&gt;[0.12, 0.33]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;name:&lt;/strong&gt; &lt;code&gt;[0.51, -0.20]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;is:&lt;/strong&gt; &lt;code&gt;[0.22, 0.78]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ankit:&lt;/strong&gt; &lt;code&gt;[0.88, 0.12]&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;what-is-a-dot-product%3F&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#what-is-a-dot-product%3F&quot;&gt;What is a Dot Product?&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;For two vectors $&#92;vec{a} = [a_1, a_2]$ and $&#92;vec{b} = [b_1, b_2]$, the dot product is calculated by multiplying corresponding elements and summing them up:&lt;/p&gt;
&lt;p&gt;$$&#92;vec{a} &#92;cdot &#92;vec{b} = a_1b_1 + a_2b_2$$&lt;/p&gt;
&lt;h3 id=&quot;dot-product-1%3A-ankit-%24%5Ccdot%24-my&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#dot-product-1%3A-ankit-%24%5Ccdot%24-my&quot;&gt;Dot Product 1: Ankit $&#92;cdot$ My&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;$$[0.88, 0.12] &#92;cdot [0.12, 0.33]$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Step 1: $0.88 &#92;times 0.12 = 0.1056$&lt;/li&gt;
&lt;li&gt;Step 2: $0.12 &#92;times 0.33 = 0.0396$&lt;/li&gt;
&lt;li&gt;Step 3: $0.1056 + 0.0396 = 0.1452$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;$$&#92;text{Ankit} &#92;cdot &#92;text{My} = 0.1452$$&lt;/p&gt;
&lt;h3 id=&quot;dot-product-2%3A-ankit-%24%5Ccdot%24-name&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#dot-product-2%3A-ankit-%24%5Ccdot%24-name&quot;&gt;Dot Product 2: Ankit $&#92;cdot$ name&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;$$[0.88, 0.12] &#92;cdot [0.51, -0.20]$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Step 1: $0.88 &#92;times 0.51 = 0.4488$&lt;/li&gt;
&lt;li&gt;Step 2: $0.12 &#92;times (-0.20) = -0.0240$&lt;/li&gt;
&lt;li&gt;Step 3: $0.4488 - 0.0240 = 0.4248$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;$$&#92;text{Ankit} &#92;cdot &#92;text{name} = 0.4248$$&lt;/p&gt;
&lt;h3 id=&quot;dot-product-3%3A-ankit-%24%5Ccdot%24-is&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#dot-product-3%3A-ankit-%24%5Ccdot%24-is&quot;&gt;Dot Product 3: Ankit $&#92;cdot$ is&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;$$[0.88, 0.12] &#92;cdot [0.22, 0.78]$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Step 1: $0.88 &#92;times 0.22 = 0.1936$&lt;/li&gt;
&lt;li&gt;Step 2: $0.12 &#92;times 0.78 = 0.0936$&lt;/li&gt;
&lt;li&gt;Step 3: $0.1936 + 0.0936 = 0.2872$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;$$&#92;text{Ankit} &#92;cdot &#92;text{is} = 0.2872$$&lt;/p&gt;
&lt;h3 id=&quot;dot-product-4%3A-ankit-%24%5Ccdot%24-ankit&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#dot-product-4%3A-ankit-%24%5Ccdot%24-ankit&quot;&gt;Dot Product 4: Ankit $&#92;cdot$ Ankit&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;$$[0.88, 0.12] &#92;cdot [0.88, 0.12]$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Step 1: $0.88 &#92;times 0.88 = 0.7744$&lt;/li&gt;
&lt;li&gt;Step 2: $0.12 &#92;times 0.12 = 0.0144$&lt;/li&gt;
&lt;li&gt;Step 3: $0.7744 + 0.0144 = 0.7888$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;$$&#92;text{Ankit} &#92;cdot &#92;text{Ankit} = 0.7888$$&lt;/p&gt;
&lt;h3 id=&quot;final-similarity-scores-for-%E2%80%9Cankit%E2%80%9D&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#final-similarity-scores-for-%E2%80%9Cankit%E2%80%9D&quot;&gt;Final Similarity Scores For “Ankit”&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Compared With&lt;/th&gt;
&lt;th&gt;Dot Product Score&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ankit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.7888&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;name&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.4248&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;is&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.2872&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;My&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.1452&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;In this toy embedding space, &lt;strong&gt;Ankit&lt;/strong&gt; is mathematically closest to itself, followed by &lt;em&gt;name&lt;/em&gt;, &lt;em&gt;is&lt;/em&gt;, and lastly &lt;em&gt;My&lt;/em&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;why-does-the-dot-product-measure-similarity%3F&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#why-does-the-dot-product-measure-similarity%3F&quot;&gt;Why Does the Dot Product Measure Similarity?&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Aligned Vectors:&lt;/strong&gt; If two vectors point in a highly similar direction, their dot product yields a large positive value.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Opposite Vectors:&lt;/strong&gt; If two vectors point in completely opposite directions, their dot product yields a negative value.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Orthogonal Vectors:&lt;/strong&gt; If two vectors point at a $90^&#92;circ$ angle to each other, their dot product is exactly $0$ (completely unrelated).&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Large Positive Score&lt;/strong&gt; $&#92;rightarrow$ Similar direction&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Near Zero Score&lt;/strong&gt; $&#92;rightarrow$ Unrelated&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Negative Score&lt;/strong&gt; $&#92;rightarrow$ Opposite direction&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;the-problem-with-the-current-equation&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#the-problem-with-the-current-equation&quot;&gt;The Problem With the Current Equation&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If we calculate attention scores directly using our raw input embeddings, we are effectively doing a pure matrix multiplication:&lt;/p&gt;
&lt;p&gt;$$&#92;text{Score} = XX^T$$&lt;/p&gt;
&lt;p&gt;This leads to three fundamental problems:&lt;/p&gt;
&lt;h3 id=&quot;problem-1%3A-no-learnable-parameters&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#problem-1%3A-no-learnable-parameters&quot;&gt;Problem 1: No Learnable Parameters&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This is just a mathematical operation. With no learnable parameters, we can’t train it.&lt;/p&gt;
&lt;p&gt;Take the sentence: &lt;code&gt;&amp;quot;I love Apple Watch&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The model might not be able to understand that &lt;code&gt;Apple Watch&lt;/code&gt; is a single entity. It may interpret &lt;code&gt;Apple&lt;/code&gt; as a fruit and &lt;code&gt;Watch&lt;/code&gt; as a clock or the verb &lt;em&gt;see&lt;/em&gt;.&lt;/p&gt;
&lt;h3 id=&quot;problem-2%3A-fixed-geometry&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#problem-2%3A-fixed-geometry&quot;&gt;Problem 2: Fixed Geometry&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Because attention simply asks: &lt;em&gt;“Which vectors are already close to me in this fixed space?”&lt;/em&gt;, there is no learning, no adjustment, and no control.&lt;/p&gt;
&lt;p&gt;The embedding space is created &lt;em&gt;before&lt;/em&gt; attention (via word2vec, GloVe, or an embedding layer). This space already has its own bias:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Apple&lt;/code&gt; is close to &lt;code&gt;Fruit&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Apple&lt;/code&gt; is somewhat close to &lt;code&gt;Phone&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;But the &lt;code&gt;Fruit&lt;/code&gt; similarity is often stronger globally.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;problem-3%3A-symmetrical-similarity&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#problem-3%3A-symmetrical-similarity&quot;&gt;Problem 3: Symmetrical Similarity&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In a simple dot product, the similarity between &lt;code&gt;Apple&lt;/code&gt; and &lt;code&gt;Phone&lt;/code&gt; is the exact same as &lt;code&gt;Phone&lt;/code&gt; and &lt;code&gt;Apple&lt;/code&gt;.&lt;br /&gt;
They will both be pulled together, shifting the overall distribution. We may want &lt;code&gt;Apple&lt;/code&gt; to shift towards &lt;code&gt;Phone&lt;/code&gt;, but we don’t necessarily want &lt;code&gt;Phone&lt;/code&gt; to shift towards &lt;code&gt;Apple&lt;/code&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;the-%E2%80%9Capple-watch%E2%80%9D-problem%3A-visualized&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#the-%E2%80%9Capple-watch%E2%80%9D-problem%3A-visualized&quot;&gt;The “Apple Watch” Problem: Visualized&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let’s say our embedding space looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Apple ──── Fruit   (very close)
  │
  │
  │
Phone              (farther away)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, self-attention computes similarity. The result? &lt;code&gt;Apple&lt;/code&gt; attends more to &lt;code&gt;Fruit&lt;/code&gt; meaning, even though &lt;code&gt;Fruit&lt;/code&gt; is not in the sentence. The relation to &lt;code&gt;Phone&lt;/code&gt; is weaker geometrically.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why does this confusion happen?&lt;/strong&gt;&lt;br /&gt;
Because attention says: &lt;em&gt;“I trust the existing embedding geometry.”&lt;/em&gt; But that geometry was trained on the entire internet, not this specific sentence.&lt;/p&gt;
&lt;p&gt;So:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It cannot reinterpret &lt;code&gt;Apple&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;It cannot shift meaning.&lt;/li&gt;
&lt;li&gt;It cannot prefer &lt;code&gt;Phone&lt;/code&gt; over &lt;code&gt;Fruit&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Without learnable parameters, attention cannot &lt;em&gt;change&lt;/em&gt; meaning — it can only reveal &lt;em&gt;existing&lt;/em&gt; similarity.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;how-learnable-parameters-fix-this&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#how-learnable-parameters-fix-this&quot;&gt;How Learnable Parameters Fix This&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Learnable parameters change the geometry. Without them, geometry is fixed.&lt;/p&gt;
&lt;h3 id=&quot;what-%24w_q%24%2C-%24w_k%24%2C-%24w_v%24-really-are&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#what-%24w_q%24%2C-%24w_k%24%2C-%24w_v%24-really-are&quot;&gt;What $W_Q$, $W_K$, $W_V$ Really Are&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;They are learned transformations that say: &lt;em&gt;“For Attention, this is what matters. Ignore the rest.”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Learnable parameters DO NOT add knowledge. They &lt;strong&gt;reshape space&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;In a Transformer attention layer, the main learnable parameters are weight matrices:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$W_Q$ = Weights for Queries (How to ask)&lt;/li&gt;
&lt;li&gt;$W_K$ = Weights for Keys (How to match)&lt;/li&gt;
&lt;li&gt;$W_V$ = Weights for Values (What meaning to pass)&lt;/li&gt;
&lt;li&gt;$W_O$ = Weights after attention (Output projection)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each of these is just a matrix of numbers. For understanding attention geometry, weights matter much more than biases.&lt;/p&gt;
&lt;p&gt;Each weight matrix mathematically:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Rotates space&lt;/li&gt;
&lt;li&gt;Stretches space&lt;/li&gt;
&lt;li&gt;Compresses space&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;revisiting-the-sentence-with-learnable-parameters&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#revisiting-the-sentence-with-learnable-parameters&quot;&gt;Revisiting the Sentence With Learnable Parameters&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Sentence: &lt;code&gt;&amp;quot;I love Apple Phone&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What training teaches the model:&lt;/strong&gt;&lt;br /&gt;
From millions of examples, it learns that when words like &lt;code&gt;phone&lt;/code&gt;, &lt;code&gt;iphone&lt;/code&gt;, &lt;code&gt;android&lt;/code&gt;, or &lt;code&gt;love&lt;/code&gt; appear, &lt;code&gt;Apple&lt;/code&gt; should move toward their meaning.&lt;/p&gt;
&lt;p&gt;So during attention, a geometric change happens.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Original Space:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Apple ──── Fruit   (closer)
  │
  │
 Phone
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;After Learning Projection:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Apple ──── Phone   (closer)
  &#92;
   &#92;
  Fruit (pushed away)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the entire difference.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Without learnable parameters, self-attention can only &lt;strong&gt;measure&lt;/strong&gt; similarity.&lt;br /&gt;
With learnable parameters, self-attention can &lt;strong&gt;create&lt;/strong&gt; similarity.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Learnable parameters don’t change geometry per sentence. They learn how geometry should change &lt;strong&gt;WHEN CERTAIN CONTEXTS APPEAR&lt;/strong&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;intuition-towards-self-attention&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#intuition-towards-self-attention&quot;&gt;Intuition Towards Self-Attention&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If the model predicts poorly on &lt;code&gt;&amp;quot;I love apple phone&amp;quot;&lt;/code&gt;, that means &lt;code&gt;Apple&lt;/code&gt; did not attend strongly enough to &lt;code&gt;Phone&lt;/code&gt;, as it is strongly similar to &lt;code&gt;Fruit&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So during backpropagation, weight updating happens.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Learning says:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Increase alignment between &lt;code&gt;Apple&lt;/code&gt; (Query) and &lt;code&gt;Phone&lt;/code&gt; (Key).&lt;/li&gt;
&lt;li&gt;Decrease alignment with irrelevant words.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;How? By slightly changing the numbers inside $W_Q$ and $W_K$.&lt;/p&gt;
&lt;h3 id=&quot;the-mathematical-intuition&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#the-mathematical-intuition&quot;&gt;The Mathematical Intuition&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The model makes a wrong guess $&#92;rightarrow$ sees the error $&#92;rightarrow$ slightly adjusts the geometry. Next time, similar sentences work better. That’s all learning is.&lt;/p&gt;
&lt;p&gt;Let’s unpack this slowly:&lt;/p&gt;
&lt;h4 id=&quot;step-1%3A-what-the-model-is-trying-to-learn&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#step-1%3A-what-the-model-is-trying-to-learn&quot;&gt;Step 1: What the model is trying to learn&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Input: &lt;code&gt;&amp;quot;I love apple phone&amp;quot;&lt;/code&gt;&lt;br /&gt;
The model’s job is to understand &lt;code&gt;Apple&lt;/code&gt; as a brand, not as a fruit.&lt;br /&gt;
At the beginning (with random weights), the geometry is bad. Attention connects &lt;code&gt;Apple&lt;/code&gt; weakly to &lt;code&gt;Phone&lt;/code&gt; and strongly to &lt;code&gt;Fruit&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id=&quot;step-2%3A-what-%E2%80%9Cwrong%E2%80%9D-means&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#step-2%3A-what-%E2%80%9Cwrong%E2%80%9D-means&quot;&gt;Step 2: What “Wrong” Means&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;During training, the model is usually asked to predict the next word or fill a masked word:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Input:&lt;/strong&gt; &lt;code&gt;I love apple: _______&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Target:&lt;/strong&gt; &lt;code&gt;phone&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If the model fails to predict &lt;code&gt;phone&lt;/code&gt;, that means attention did not focus enough on the right relationship. It may have considered &lt;code&gt;Apple&lt;/code&gt; as &lt;code&gt;Fruit&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id=&quot;step-3%3A-adjust-weights&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#step-3%3A-adjust-weights&quot;&gt;Step 3: Adjust Weights&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Now we adjust our 3 matrices: $W_Q$, $W_K$, and $W_V$.&lt;/p&gt;
&lt;h4 id=&quot;step-4%3A-geometry-adjustment&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#step-4%3A-geometry-adjustment&quot;&gt;Step 4: Geometry Adjustment&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;The system thinks: &lt;em&gt;“When apple appears with phone, I should make them look more similar.”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;What does it do? It &lt;strong&gt;rotates the Query direction&lt;/strong&gt; of &lt;code&gt;Apple&lt;/code&gt; and &lt;strong&gt;rotates the Key direction&lt;/strong&gt; of &lt;code&gt;Phone&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So next time, their dot product is bigger, and their attention weight increases.&lt;/p&gt;
&lt;p&gt;Under the hood, the system knows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;“Output was wrong.”&lt;/li&gt;
&lt;li&gt;“Which parameters influenced that output.”&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So it nudges them: &lt;em&gt;“Increase this similarity a bit, decrease that similarity a bit.”&lt;/em&gt;&lt;br /&gt;
This is gradient descent—trial $&#92;rightarrow$ feedback $&#92;rightarrow$ correction.&lt;/p&gt;
&lt;h3 id=&quot;why-this-works-over-time&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#why-this-works-over-time&quot;&gt;Why This Works Over Time&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;One sentence teaches very little. But after 10 million sentences, the model slowly learns:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In tech contexts $&#92;rightarrow$ &lt;code&gt;Apple&lt;/code&gt; aligns with &lt;code&gt;Phone&lt;/code&gt;, &lt;code&gt;Laptop&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;In food contexts $&#92;rightarrow$ &lt;code&gt;Apple&lt;/code&gt; aligns with &lt;code&gt;Fruit&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The model never learns &lt;code&gt;&amp;quot;Apple = Phone&amp;quot;&lt;/code&gt;. It learns &lt;code&gt;&amp;quot;WHEN Apple should look like Phone&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;the-self-attention-formula&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#the-self-attention-formula&quot;&gt;The Self-Attention Formula&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now that we understand the intuition behind learnable parameters, let’s look at the actual mathematical formula that ties everything together:&lt;/p&gt;
&lt;p&gt;$$&#92;text{Attention}(Q, K, V) = &#92;text{softmax}&#92;left(&#92;frac{QK^T}{&#92;sqrt{d_k}}&#92;right)V$$&lt;/p&gt;
&lt;p&gt;Where our queries, keys, and values are generated by multiplying our input $X$ with our learned weight matrices:&lt;br /&gt;
$$Q = X &#92;cdot W_Q &#92;quad &#92;text{(Queries)}$$&lt;br /&gt;
$$K = X &#92;cdot W_K &#92;quad &#92;text{(Keys)}$$&lt;br /&gt;
$$V = X &#92;cdot W_V &#92;quad &#92;text{(Values)}$$&lt;/p&gt;
&lt;p&gt;Let’s break down exactly what each piece of this formula is doing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;$QK^T$ (The Matching Engine):&lt;/strong&gt; This is the row-by-row dot product multiplication. It is where every Query asks every Key: &lt;em&gt;“How relevant are you to me?”&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;$&#92;sqrt{d_k}$ (The Scaler):&lt;/strong&gt; This is a safety buffer. $d_k$ is the dimension size of our keys. If our dimensions get too large, the dot product scores blast through the roof, which breaks the math during training. Dividing by $&#92;sqrt{d_k}$ keeps the numbers stable.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;$&#92;text{softmax}(&#92;dots)$ (The Normalizer):&lt;/strong&gt; This is the activation function that turns our raw matching scores into probabilities (ranging from 0 to 1).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;$V$ (The Information Carrier):&lt;/strong&gt; Finally, we multiply those percentages by the actual data payload matrix ($V$) to extract the exact contextual meaning we need.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now, let’s look at the raw matrix mechanics of just that first crucial step: the matching engine, $QK^T$.&lt;/p&gt;
&lt;h2 id=&quot;the-math-of-%24qk%5Et%24%3A-step-by-step-matrix-mechanics&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#the-math-of-%24qk%5Et%24%3A-step-by-step-matrix-mechanics&quot;&gt;The Math of $QK^T$: Step-by-Step Matrix Mechanics&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let’s watch the magic happen mathematically. Let’s look exclusively at the matrix multiplication $Q K^T$. We will forget Softmax and $V$ for a brief moment just to master how queries match keys.&lt;/p&gt;
&lt;p&gt;Assume our text matrix has been projected into $Q$ and $K$ spaces (using 2-dimensional representations for simplicity):&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q (Query Matrix)&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-matrix&quot;&gt;[
  [1, 0], // My Query
  [0, 1], // name Query
  [1, 1], // is Query
  [2, 1]  // Ankit Query
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;K (Key Matrix)&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-matrix&quot;&gt;[
  [1, 1], // My Key
  [0, 2], // name Key
  [1, 0], // is Key
  [2, 1]  // Ankit Key
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Both matrices have a shape of $(4, 2)$ because we have $4 &#92;text{ tokens} &#92;times 2 &#92;text{ dimensions}$.&lt;/p&gt;
&lt;p&gt;To perform a dot product of every row in $Q$ with every row in $K$, we transpose $K$ so it has a shape of $(2, 4)$:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Kᵀ (Key Matrix Transposed)&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-matrix&quot;&gt;[
  [1, 0, 1, 2],
  [1, 2, 0, 1]
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we compute the matrix multiplication: $Q_{(4 &#92;times 2)} &#92;times K^T_{(2 &#92;times 4)} = &#92;text{Score}_{(4 &#92;times 4)}$. Why $4 &#92;times 4$? Because &lt;strong&gt;every single token compares itself with every single token&lt;/strong&gt;!&lt;/p&gt;
&lt;h3 id=&quot;computing-row-1%3A-the-%E2%80%9Cmy%E2%80%9D-token-perspective&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#computing-row-1%3A-the-%E2%80%9Cmy%E2%80%9D-token-perspective&quot;&gt;Computing Row 1: The “My” Token Perspective&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;We take the Query vector for &lt;strong&gt;My&lt;/strong&gt; ($[1,0]$) and cross-multiply it with all word Keys in $K^T$:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;My Query $&#92;cdot$ My Key:&lt;/strong&gt; $[1,0] &#92;cdot [1,1] = 1(1) + 0(1) = &#92;mathbf{1}$&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;My Query $&#92;cdot$ name Key:&lt;/strong&gt; $[1,0] &#92;cdot [0,2] = 1(0) + 0(2) = &#92;mathbf{0}$&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;My Query $&#92;cdot$ is Key:&lt;/strong&gt; $[1,0] &#92;cdot [1,0] = 1(1) + 0(0) = &#92;mathbf{1}$&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;My Query $&#92;cdot$ Ankit Key:&lt;/strong&gt; $[1,0] &#92;cdot [2,1] = 1(2) + 0(1) = &#92;mathbf{2}$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Row 1 results in: &lt;code&gt;[1, 0, 1, 2]&lt;/code&gt;&lt;/p&gt;
&lt;h3 id=&quot;computing-row-4%3A-the-%E2%80%9Cankit%E2%80%9D-token-perspective&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#computing-row-4%3A-the-%E2%80%9Cankit%E2%80%9D-token-perspective&quot;&gt;Computing Row 4: The “Ankit” Token Perspective&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;We take the Query vector for &lt;strong&gt;Ankit&lt;/strong&gt; ($[2,1]$) and cross-multiply it with all word Keys in $K^T$:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ankit Query $&#92;cdot$ My Key:&lt;/strong&gt; $[2,1] &#92;cdot [1,1] = 2(1) + 1(1) = &#92;mathbf{3}$&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ankit Query $&#92;cdot$ name Key:&lt;/strong&gt; $[2,1] &#92;cdot [0,2] = 2(0) + 1(2) = &#92;mathbf{2}$&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ankit Query $&#92;cdot$ is Key:&lt;/strong&gt; $[2,1] &#92;cdot [1,0] = 2(1) + 1(0) = &#92;mathbf{2}$&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ankit Query $&#92;cdot$ Ankit Key:&lt;/strong&gt; $[2,1] &#92;cdot [2,1] = 2(2) + 1(1) = &#92;mathbf{5}$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Row 4 results in: &lt;code&gt;[3, 2, 2, 5]&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;the-complete-%24qk%5Et%24-score-matrix&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#the-complete-%24qk%5Et%24-score-matrix&quot;&gt;The Complete $QK^T$ Score Matrix&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Filling out the entire matrix gives us an actionable relationship grid:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;QKᵀ (Attention Score Matrix)&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-matrix&quot;&gt;[
  [           My (K), name (K), is (K), Ankit (K) ],
  [ My (Q),        1,        0,      1,         2 ],
  [ name (Q),      .,        .,      .,         . ],
  [ is (Q),        .,        .,      .,         . ],
  [ Ankit (Q),     3,        2,      2,         5 ]
]
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;The Deep Reading Intuition:&lt;/strong&gt;&lt;br /&gt;
Always read this matrix &lt;strong&gt;row by row&lt;/strong&gt;. The row belongs to the &lt;strong&gt;Query&lt;/strong&gt; (the word asking the question), and the columns belong to the &lt;strong&gt;Keys&lt;/strong&gt; (the tokens responding).&lt;br /&gt;
Looking at the &lt;strong&gt;Ankit&lt;/strong&gt; row, its scores are &lt;code&gt;[3, 2, 2, 5]&lt;/code&gt;. This means that while processing the word &lt;em&gt;Ankit&lt;/em&gt;, the model determines it is highly self-relevant ($5$), but its strongest structural connection out of the remaining tokens is to the word &lt;em&gt;My&lt;/em&gt; ($3$).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;what-happens-next%3A-softmax-and-the-value-matrix-(%24v%24)&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#what-happens-next%3A-softmax-and-the-value-matrix-(%24v%24)&quot;&gt;What Happens Next: Softmax and the Value Matrix ($V$)&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Once we have our score matrix, we finish the rest of the standard attention pipeline:&lt;/p&gt;
&lt;h3 id=&quot;1.-scaling-and-softmax&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#1.-scaling-and-softmax&quot;&gt;1. Scaling and Softmax&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;We turn these raw score matrices into percentages. For example, applying Softmax to the &lt;strong&gt;Ankit&lt;/strong&gt; row &lt;code&gt;[3, 2, 2, 5]&lt;/code&gt; converts those numbers into normalized probabilities that equal $100%$:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Ankit Attention Weights: [ My: 12%,  name: 5%,  is: 5%,  Ankit: 78% ]

&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;2.-gathering-the-values-(%24v%24)&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#2.-gathering-the-values-(%24v%24)&quot;&gt;2. Gathering the Values ($V$)&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Now that we know exactly how much attention to pay to each word, we multiply these percentage weights by the &lt;strong&gt;Value Matrix ($V$)&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Instead of passing the original data or keys forward, we pull information directly from $V$. If a token has an attention score of $78%$ on itself and $12%$ on &lt;em&gt;My&lt;/em&gt;, its final output vector will be a blended compound containing $78%$ of its own value profile and $12%$ of &lt;em&gt;My&lt;/em&gt;’s value profile.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Comment down your thoughts below, if you found it helpful !&lt;/p&gt;
&lt;h2 id=&quot;references&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/understanding-self-attention/#references&quot;&gt;References&lt;/a&gt;&lt;/h2&gt;
&lt;a href=&quot;https://arxiv.org/pdf/1706.03762&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;
    Attention Is All You Need
&lt;/a&gt;
&lt;p&gt;Best,&lt;br /&gt;
Ankit&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Embracing the Emptiness</title>
    <link href="https://aiankit.com/writing/embracing-the-emptiness/"/>
    <updated>2025-12-17T00:00:00Z</updated>
    <id>https://aiankit.com/writing/embracing-the-emptiness/</id>
    <content xml:lang="en" type="html">&lt;p&gt;Hey, how are you. i hope you’re happy and doing well.  I don’t write very often. When I do, it’s usually unplanned more like reflections or random thoughts.&lt;/p&gt;
&lt;p&gt;Lately, there’s been a lot of silence. Not the dramatic kind, just the kind that exists when things stop demanding attention. Nothing is particularly wrong. Nothing is particularly right either.&lt;/p&gt;
&lt;p&gt;At some point, I noticed that emptiness isn’t always a problem to solve. Sometimes it’s just a phase where things are being rearranged quietly, without any announcement.&lt;/p&gt;
&lt;p&gt;Life keeps moving as expected. Time moves, People stay buzy, Plans continue. Yet internally, there’s a neutral space where reactions slow down and thoughts become more deliberate.&lt;/p&gt;
&lt;p&gt;I used to think emptiness meant something was missing.&lt;br /&gt;
Now it feels more like something unnecessary has left.&lt;/p&gt;
&lt;p&gt;There are no big conclusions here. No lessons wrapped in optimism. Just an observation.&lt;/p&gt;
&lt;p&gt;So, this is a snapshot shaped over time, written down on 17th December, late at night. Let’s see if the perspective shifts.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Why MCP (Model Context Protocol) is Here to Stay!</title>
    <link href="https://aiankit.com/writing/why-mcp-is-here-to-stay/"/>
    <updated>2025-04-25T00:00:00Z</updated>
    <id>https://aiankit.com/writing/why-mcp-is-here-to-stay/</id>
    <content xml:lang="en" type="html">&lt;p&gt;&lt;img src=&quot;https://aiankit.com/assets/images/blog/mcp.png&quot; alt=&quot;Model Context Protocol – MCP&quot; /&gt;&lt;/p&gt;
&lt;p&gt;You’ve likely heard the buzz about &lt;strong&gt;MCP (Model Context Protocol)&lt;/strong&gt; — and I firmly believe it’s here to stay.&lt;/p&gt;
&lt;p&gt;But what exactly is MCP, and why does it matter? Let’s break it down simply.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;what-is-mcp%3F&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/why-mcp-is-here-to-stay/#what-is-mcp%3F&quot;&gt;What is MCP?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;MCP&lt;/strong&gt; is a fundamental shift in the software development ecosystem. It introduces a new standard that redefines how &lt;strong&gt;AI Agents interact with external systems&lt;/strong&gt;, making integrations seamless, reusable, and efficient.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;why-did-we-need-mcp%3F&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/why-mcp-is-here-to-stay/#why-did-we-need-mcp%3F&quot;&gt;Why Did We Need MCP?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let’s say you’re building an AI agent that needs to talk to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gmail&lt;/li&gt;
&lt;li&gt;A custom database&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;traditionally%3A&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/why-mcp-is-here-to-stay/#traditionally%3A&quot;&gt;Traditionally:&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;You manually write integrations for each API.&lt;/li&gt;
&lt;li&gt;You define authentication, permissions, and logic &lt;strong&gt;from scratch&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Adding another agent? You &lt;strong&gt;repeat&lt;/strong&gt; the entire process.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;the-inefficiencies-of-the-old-way&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/why-mcp-is-here-to-stay/#the-inefficiencies-of-the-old-way&quot;&gt;The Inefficiencies of the Old Way&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Redundant integrations&lt;/strong&gt; per agent&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Inconsistent API logic&lt;/strong&gt; (e.g., Gmail allows email deletion, but your use case might only need sending)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No easy way to scale&lt;/strong&gt;, since logic has to be redefined again and again&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;how-mcp-fixes-this&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/why-mcp-is-here-to-stay/#how-mcp-fixes-this&quot;&gt;How MCP Fixes This&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;MCP introduces a &lt;strong&gt;unified abstraction layer&lt;/strong&gt;, acting as a standardized protocol between AI agents and APIs. This eliminates the need for redundant integration logic.&lt;/p&gt;
&lt;p&gt;It’s like having a central translator that speaks both API and AI-agent.&lt;/p&gt;
&lt;h3 id=&quot;before-mcp%3A&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/why-mcp-is-here-to-stay/#before-mcp%3A&quot;&gt;Before MCP:&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Each AI agent has to handle API interactions separately.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;with-mcp%3A&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/why-mcp-is-here-to-stay/#with-mcp%3A&quot;&gt;With MCP:&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;AI agents simply communicate with the &lt;strong&gt;MCP server&lt;/strong&gt;, which manages the requests for them.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;the-result&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/why-mcp-is-here-to-stay/#the-result&quot;&gt;The Result&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Faster Development&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reusable APIs&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Standardized Permissions&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agent-Agnostic Workflows&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;final-thoughts&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/why-mcp-is-here-to-stay/#final-thoughts&quot;&gt;Final Thoughts&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;MCP isn’t just another buzzword — it’s a &lt;strong&gt;foundational layer&lt;/strong&gt; for building &lt;strong&gt;scalable AI ecosystems&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Whether you’re building agents for customer service, health records, or internal tooling — MCP will help you avoid technical debt and grow faster.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;If this topic intrigued you, feel free to &lt;a href=&quot;https://linkedin.com/in/ankitmishra&quot;&gt;connect with me&lt;/a&gt; or &lt;a href=&quot;https://aiankit.com/writing/why-mcp-is-here-to-stay/#&quot;&gt;share this post&lt;/a&gt; with your network.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Accuracy Without Context Is Like a Ship Without a Compass</title>
    <link href="https://aiankit.com/writing/accuracy-context/"/>
    <updated>2025-04-21T00:00:00Z</updated>
    <id>https://aiankit.com/writing/accuracy-context/</id>
    <content xml:lang="en" type="html">&lt;p&gt;Ah yes, the classic beginner’s mindset: if the accuracy number is high, the model must be a genius! Logic? What’s that?&lt;/p&gt;
&lt;h2 id=&quot;accuracy-without-context-is-like-a-ship-without-a-compass&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/accuracy-context/#accuracy-without-context-is-like-a-ship-without-a-compass&quot;&gt;Accuracy Without Context Is Like a Ship Without a Compass&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Many beginners believe that higher accuracy automatically indicates better model performance. However, there’s much more to the story of machine learning when applied in the real world.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;the-scenario&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/accuracy-context/#the-scenario&quot;&gt;The Scenario&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Imagine you’re building a &lt;strong&gt;multi-class classification model&lt;/strong&gt; to predict three types of fruits: Apples, Bananas, and Cherries.&lt;/p&gt;
&lt;h3 id=&quot;here-are-the-model%E2%80%99s-accuracy-scores-after-testing%3A&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/accuracy-context/#here-are-the-model%E2%80%99s-accuracy-scores-after-testing%3A&quot;&gt;Here are the model’s accuracy scores after testing:&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://aiankit.com/assets/images/blog/accuracy-context-model.jpeg&quot; alt=&quot;Accuracy Without Context&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Apple&lt;/strong&gt;: 80% accuracy&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Banana&lt;/strong&gt;: 80% accuracy&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cherry&lt;/strong&gt;: 60% accuracy&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Seems obvious, right? Cherry is the worst-performing class. But hold on! Your answer might be correct for your college project or any hackathon, but this is not how real-world ML works!&lt;/p&gt;
&lt;p&gt;There’s more to this story.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;what%E2%80%99s-missing%3F-the-baseline&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/accuracy-context/#what%E2%80%99s-missing%3F-the-baseline&quot;&gt;What’s Missing? The Baseline&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;What you’re missing is a &lt;strong&gt;baseline&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Without a comparison, accuracy numbers alone can be misleading. In machine learning, the baseline is not just a reference point, it’s the context that defines our understanding of model performance. Without it, accuracy becomes an illusion, masking the true strengths and weaknesses of our systems.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;manually-labelling-by-humans&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/accuracy-context/#manually-labelling-by-humans&quot;&gt;Manually Labelling by Humans&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In this scenario, let’s set the baseline by asking team members to manually label the same fruit images.&lt;/p&gt;
&lt;p&gt;Here’s how they performed:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aiankit.com/assets/images/blog/accuracy-context-human.jpeg&quot; alt=&quot;Accuracy Without Context&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Apple&lt;/strong&gt;: 85% accuracy&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Banana&lt;/strong&gt;: 100% accuracy&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cherry&lt;/strong&gt;: 61% accuracy&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;what-we-learn-from-the-baseline&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/accuracy-context/#what-we-learn-from-the-baseline&quot;&gt;What We Learn from the Baseline&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now things get interesting. Based on this baseline, it’s clear that:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://aiankit.com/assets/images/blog/human-vs-model.jpeg&quot; alt=&quot;Accuracy Without Context&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The model performs &lt;strong&gt;close to humans&lt;/strong&gt; on cherries (60% vs. 61%).&lt;/li&gt;
&lt;li&gt;It struggles significantly with bananas (80% vs. 100%), even though 80% might seem fine at first glance.&lt;/li&gt;
&lt;li&gt;For apples, it’s &lt;strong&gt;almost there&lt;/strong&gt;, but not quite matching human performance.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;what%E2%80%99s-the-lesson-here%3F&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/accuracy-context/#what%E2%80%99s-the-lesson-here%3F&quot;&gt;What’s the Lesson Here?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Accuracy doesn’t tell the full story.&lt;/strong&gt; You need to measure against a baseline, whether it’s human performance or a simple method like random guessing, before deciding where your model truly struggles.&lt;/p&gt;
&lt;p&gt;Many ML beginners tend to focus on the lowest accuracy class as the problem area, but context matters. Without a proper baseline, you might be focusing on the wrong issues.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;final-thoughts&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://aiankit.com/writing/accuracy-context/#final-thoughts&quot;&gt;Final Thoughts&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;So, the next time you’re evaluating a model, remember: &lt;strong&gt;accuracy is only as good as the context it’s placed in&lt;/strong&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Share&lt;/p&gt;
</content>
  </entry>
</feed>
