<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
  <title>Paweł Dubiel Tech Blog: Glossary</title>
  <link>https://paweldubiel.com/en</link>
  <atom:link href="https://paweldubiel.com/en/glossary.xml" rel="self" type="application/rss+xml" />
  <description>Notes on AI, language models and software engineering.</description>
  <language>en</language>
  <lastBuildDate>Mon, 12 Oct 2026 00:00:00 GMT</lastBuildDate>
<item>
  <title>Validation Set</title>
  <link>https://paweldubiel.com/en/glossary/validation-set</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/validation-set</guid>
  <pubDate>Mon, 12 Oct 2026 07:17:31 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>llm</category>
  <category>glossary</category>
  <description>You run an ice cream stand and want to predict daily sales from the temperature. You have three recorded days: at 20°C you sold 20 servings, at 22°C, 30, and at 24°C, 28.</description>
  <content:encoded><![CDATA[<p>You run an ice cream stand and want to predict daily sales from the temperature. You have three recorded days: at 20°C you sold 20 servings, at 22°C, 30, and at 24°C, 28. You compare three rules: always predict 24 servings, a straight line, and a curve passing exactly through all three results. The last rule makes no errors in your notebook. Should it plan tomorrow’s stock?</p>
<p>Checking those same days again cannot settle this. The flexible rule may also have fitted chance events, such as an unusually large tour group at 22°C. Before choosing a rule, you set other days aside to compare candidates. <strong>Validation Set</strong> is a separate portion of data used to select a model or its settings, rather than fit its learned numbers. This separation is described by <a href="https://www.deeplearningbook.org/contents/ml.html" rel="noopener noreferrer">Goodfellow, Bengio and Courville, <em>Deep Learning</em>, §5.3</a>.</p>
<p><img src="https://paweldubiel.com/assets/validation-set-tasting-tray-and-sealed-sample.webp" alt="Three ice cream samples ready for comparison and a separate container with an intact seal: a metaphor for selection data and a separate final assessment." loading="eager" decoding="async" width="1536" height="1024"></p>
<h2 id="a-notebook-for-learning-separate-days-for-selection">A notebook for learning, separate days for selection</h2>
<p>We establish the rules and their numbers using only the training data. The line predicts twice the temperature minus 20. The curve is an arc fitted to the three notebook points. Mean absolute error here means: calculate how many servings each day’s prediction misses by, ignore the sign and average the differences.</p>
<p>On the days set aside, at 21°C, 23°C and 25°C, sales were 23, 25 and 31 servings respectively. The curve predicts 26.5, 30.5 and 22.5; its mean error is about 5.83 servings. The line predicts 22, 26 and 30: its error is 1 serving. This leads us to choose the line, although it lost 2 to 0 in the notebook. <strong>The Validation Set did not improve any rule; it helped choose among three.</strong> These data are invented, and fractional predictions mean expected sales, not splitting one serving.</p>
<div id="validation-set-lab"></div>
<h2 id="after-selection-a-final-assessment-is-still-needed">After selection, a final assessment is still needed</h2>
<p>The days used for selection have already influenced the decision. A third, disjoint portion of data, the <em>test set</em>, is therefore used only to assess the chosen solution. In this example, the line misses by an average of 1 serving on two previously unrevealed days. If you change the rule after seeing that result, those days also begin to serve selection; they lose their role as an independent test (§5.3).</p>
<p>This is an important limitation: after many attempts, selection can fit the Validation Set itself and produce an overly optimistic result. Three days set aside here are only a teaching aid, not a reliable assessment of real sales. No fixed split percentage guarantees a good measurement.</p>
<ul>
<li><a href="https://paweldubiel.com/en/glossary/overfitting">Overfitting</a> describes excessive fitting to training examples; separate data help reveal its effect.</li>
<li><a href="https://paweldubiel.com/en/glossary/fine-tuning">Fine-tuning</a> is further training of an existing model; a Validation Set can help select settings for that training.</li>
<li><a href="https://paweldubiel.com/en/glossary/cross-entropy">Cross-entropy</a> is another way of measuring error, often used for text prediction; the separation of data roles remains the same.</li>
</ul>
<p><em>The text and illustration were prepared with AI assistance. The data, rules and demonstration are our own simplified example; the illustration is a metaphor for selection and keeping a separate sample.</em></p>]]></content:encoded>
</item>
<item>
  <title>Overfitting</title>
  <link>https://paweldubiel.com/en/glossary/overfitting</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/overfitting</guid>
  <pubDate>Sun, 11 Oct 2026 15:59:40 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>llm</category>
  <category>glossary</category>
  <description>You run an ice cream stand. For 10 days you wrote down the temperature at noon and the number of scoops sold in a notebook.</description>
  <content:encoded><![CDATA[<p>You run an ice cream stand. For 10 days you wrote down the temperature at noon and the number of scoops sold in a notebook. You want to turn these notes into a rule: tomorrow it will be 24°C, so how much ice cream should you prepare?</p>
<p>The simplest rule is a straight line: "each extra degree means a few more scoops". In the example from this note, it is typically off by 27.5 scoops on the recorded days, because it does not see that sales drop in the worst heat. So you can give the rule more freedom and let the curve bend. The most flexible of the curves tried here passes exactly through all 10 points. Its error on the days from the notebook is 0.</p>
<p>It looks like a perfect rule. But the days in the notebook are already over, and the rule has to work tomorrow. On 400 new days from the same stand, the "perfect" curve is typically off by 236.5 scoops. A moderately flexible curve, which did worse on the notebook (10.9), is off by 16.8 on the new days.</p>
<p><strong>Overfitting</strong> is a situation in which a model has a small error on the data used for learning and, compared with it, too large an error on new data of the same kind (<a href="https://www.deeplearningbook.org/contents/ml.html" rel="noopener noreferrer">Goodfellow, Bengio and Courville, <em>Deep Learning</em>, §5.2</a>). The model has fitted itself to features of its own data set that do not repeat outside it. The opposite problem is called <strong>underfitting</strong>: the rule is too simple to describe well even the data it has seen. That is how the straight line in our example behaves.</p>
<p><img src="https://paweldubiel.com/assets/overfitting-smooth-rule-versus-tangled-line-through-every-point.webp" alt="Two ice cream stands side by side: above the first, a smooth line runs in a gentle arc between the points; above the second, a tangled line hits every point and shoots far out of the frame." loading="eager" decoding="async" width="1536" height="1024"></p>
<h2 id="where-the-difference-comes-from">Where the difference comes from</h2>
<p>Every entry in the notebook is made of two things: a pattern (it is warmer, so more ice cream is sold) and chance (a tour group happened to arrive). The rule should capture the first and leave out the second. But the model does not know which is which. It sees only points.</p>
<p>How much chance the model absorbs depends on its flexibility, which the literature calls <strong>capacity</strong>: the ability to fit many different shapes. The curve in the example is described by 2 to 10 numbers that are chosen to match the data; how many there are is the degree of the curve plus one. A curve of degree 9 has 10 such numbers for 10 days, so it can hit every point, together with all the chance. The authors of the textbook describe it like this: a very flexible model can represent the right relationship, but also a great many others that fit the training data just as well, and there is little chance that it will pick exactly the one that holds up later (§5.2).</p>
<p>The typical course is as follows: as flexibility grows, the error on the training data falls, while the error on new data first falls and then starts to rise (§5.2, figure 5.3). A practical rule follows from this. A model is not judged on the data it learned from, and flexibility is not chosen by the error on that data, because that error will always point to the highest one. Part of the data is set aside: a <strong><a href="https://paweldubiel.com/en/glossary/validation-set">validation set</a></strong> is used to choose the settings, and a separate <strong>test set</strong> is used for the final assessment (§5.3).</p>
<h2 id="try-it-yourself">Try it yourself</h2>
<p>Below is the same stand. All the numbers from this note can be reproduced: after clicking "Start over" you see 10 days, and experiments 1–5 set up the cases described.</p>
<div id="overfitting-lab"></div>
<p>It is worth doing two things that a static chart does not show. First, turn on "24 other notebooks" and change the degree: at a low degree the gray lines stay close together, at a high degree they spread out in all directions, even though each one comes from the same stand. Second, drag one point high up. The curve of degree 2 will move only a little, while the curve of degree 9 will reshape itself along its whole length to hit it.</p>
<h2 id="what-helps">What helps</h2>
<ul>
<li><strong>More data.</strong> With 80 days, the same curve of degree 9 is typically off by 14.8 scoops on the notebook and by 15.9 on new days. The difference almost disappears, because the curve can no longer hit every point (§5.2).</li>
<li><strong>Less flexibility.</strong> A curve of degree 3 on 10 days: 10.9 on the notebook, 16.8 on new days.</li>
<li><strong>Regularization</strong>, that is, a change to the way of learning that is meant to reduce the error on new data, not on the training data (§5.2.2). One example is a penalty for large coefficients, related to <a href="https://paweldubiel.com/en/glossary/weight-decay">Weight decay</a>: a curve of degree 9 with a penalty of λ = 0.01 is off by 5.8 on the notebook and by 21.2 on new days, instead of by 236.5.</li>
</ul>
<p>None of these settings can be chosen by looking only at the error on the training data.</p>
<h2 id="limitations">Limitations</h2>
<ul>
<li>This is my own example with a single input quantity and simulated data. Chance alone gives a typical error of 15 scoops here, and no rule will go lower on new days.</li>
<li>The "first better, then worse" shape is typical, not guaranteed. The authors note that in deep networks it is hard even to determine the model's actual flexibility, because it also depends on the learning algorithm (§5.2). So the number of parameters of an LLM does not tell you by itself whether the model is overfitted.</li>
<li>A small error on new data applies to data from the same source. If the stand moves to the seaside, the notebook from the city promises nothing.</li>
</ul>
<h2 id="related-notes">Related notes</h2>
<ul>
<li><a href="https://paweldubiel.com/en/glossary/weight-decay">Weight decay</a> limits the size of the weights and is one of the ways to reduce the difference between the error on training data and on new data.</li>
<li><a href="https://paweldubiel.com/en/glossary/grokking">Grokking</a> describes cases in which a model that looks overfitted starts to work well on new data after long further training.</li>
<li><a href="https://paweldubiel.com/en/glossary/fine-tuning">Fine-tuning</a> on a small data set needs the same check: separate data that the model did not see while learning.</li>
<li><a href="https://paweldubiel.com/glossary/catastrophic-forgetting" hreflang="pl">Catastrophic Forgetting [Polski]</a> is a different problem: there the model loses an old skill after new learning, while here it carries over poorly beyond its own training data from the start.</li>
</ul>]]></content:encoded>
</item>
<item>
  <title>Time horizon</title>
  <link>https://paweldubiel.com/en/glossary/time-horizon</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/time-horizon</guid>
  <pubDate>Sun, 11 Oct 2026 15:02:00 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>papers</category>
  <category>llm</category>
  <category>agents</category>
  <category>benchmarks</category>
  <description>In agent evaluation, a time horizon describes the length of tasks at which an agent reaches a chosen success rate. Length is measured by the time a human needs, not by how long the AI runs.</description>
  <content:encoded><![CDATA[<p>In agent evaluation, a <strong>time horizon</strong> describes the length of tasks at which an agent reaches a chosen success rate. Length is measured by the time a human needs, not by how long the AI runs.</p>
<p>For the 50% variant, we collect the agent's successful and failed attempts on tasks with different human times. We fit a curve of the chance of success and then read off the time at which it crosses 50%. This is a prediction for the distribution of tasks of a given length; it does not mean that each of them has the same chance of being completed. <a href="https://metr.org/time-horizons/" rel="noopener noreferrer">METR: definition and methodology</a>.</p>
<p>A teaching example: if the fitted curve reaches 50% at two hours, then two hours is the horizon. The agent may finish a successful task much faster than that. Nor does the result by itself say how successful the agent will be on a task from another domain.</p>
<p>Reading off the horizon requires a meaningful relationship between human time and difficulty for AI. When the curve is flat, a small change in the chance of success can move its crossing with the threshold a long way. <a href="https://paweldubiel.com/en/articles/a-longer-metr-horizon-does-not-mean-proportionally-harder-tasks">The article on converting the METR horizon</a> shows this problem with an example you can work through and discusses a new fit to the METR data. <a href="https://arxiv.org/html/2610.12466v1#S2" rel="noopener noreferrer">Nguyen and Fithian, §2–3</a>.</p>
<p>When comparing horizons, keep the information about the task set, the agent's environment, the attempt budget and the chosen success threshold.</p>]]></content:encoded>
</item>
<item>
  <title>Item response theory</title>
  <link>https://paweldubiel.com/en/glossary/item-response-theory</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/item-response-theory</guid>
  <pubDate>Sun, 11 Oct 2026 15:01:00 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>papers</category>
  <category>llm</category>
  <category>agents</category>
  <category>benchmarks</category>
  <description>Item response theory (IRT) is a family of methods that use the responses to individual tasks to jointly estimate the ability of the test takers and the difficulty of the tasks.</description>
  <content:encoded><![CDATA[<p><strong>Item response theory (IRT)</strong> is a family of methods that use the responses to individual tasks to jointly estimate the ability of the test takers and the difficulty of the tasks. In AI evaluation the test taker is an agent, and a response can be the success or failure of a full attempt.</p>
<p>Suppose two agents work on the same three tasks. The first usually copes with A and B, the second with C as well. The success rate alone gives a ranking. IRT additionally tries to estimate how hard C is relative to the other tasks and what difference in ability explains the pattern of responses. This is a teaching example; a table this small is not enough for a reliable fit.</p>
<p>In the simple Rasch model, the chance of success rises as the agent's ability grows relative to the difficulty of the task. Both quantities are latent: we infer them from the results instead of equating difficulty straight away with the length of the instructions or with human time. Different variants of IRT add further parameters and assumptions.</p>
<p>In <a href="https://paweldubiel.com/en/articles/a-longer-metr-horizon-does-not-mean-proportionally-harder-tasks">the analysis of METR horizons</a>, the authors link latent difficulty to human working time through a learned curve. They add task-family effects and variation in the results of repeated runs. This makes it possible to check over which range time really separates tasks that are hard for AI from those that are easy. <a href="https://arxiv.org/html/2610.12466v1#S2.SS3" rel="noopener noreferrer">Nguyen and Fithian, §2.3 and §3.1</a>.</p>
<p>Predicting responses well does not prove that the learned parameter covers every kind of ability an agent has. When interpreting it, check the model's assumptions and the results on tasks not used in the fit.</p>]]></content:encoded>
</item>
<item>
  <title>Elastic Weight Consolidation</title>
  <link>https://paweldubiel.com/en/glossary/elastic-weight-consolidation</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/elastic-weight-consolidation</guid>
  <pubDate>Sun, 11 Oct 2026 12:00:11 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>llm</category>
  <category>glossary</category>
  <description>A model routes customer questions to “delivery” and “returns”. Now it has to learn to recognize complaints, but the old messages may no longer be stored. So they cannot be replayed during training.</description>
  <content:encoded><![CDATA[<p>A model routes customer questions to “delivery” and “returns”. Now it has to learn to recognize complaints, but the old messages may no longer be stored. So they cannot be replayed during training. All that remains of the old task is the model itself: millions of numbers set during earlier training, called weights.</p>
<p>You could train the model on complaints with no restrictions at all. Then the weights shift wherever that helps the new task, including the ones that recognizing delivery and returns depended on. You could also penalize every change equally, but then the model clings to its old settings so tightly that it learns the new task poorly. What we need is an answer to the question: <strong>which weights may be moved, and which are better left alone?</strong></p>
<p><strong>Elastic Weight Consolidation (EWC)</strong> adds a penalty to training on the new task for weights moving away from their values after the old task, and the penalty is larger the more important a given weight was for the old task. The authors compare this to a spring attached to each weight: stiff for important weights, loose for the rest (<a href="https://arxiv.org/abs/1612.00796" rel="noopener noreferrer">Kirkpatrick et al., <em>Overcoming catastrophic forgetting in neural networks</em>, §2</a>).</p>
<p><img src="https://paweldubiel.com/assets/elastic-weight-consolidation-stiff-and-loose-springs.webp" alt="A row of discs attached by springs to posts: the discs on thick, stiff springs stay in place, while those on thin, loose ones shift toward a red circle." loading="eager" decoding="async" width="1536" height="1024"></p>
<h2 id="two-weights-one-new-task">Two weights, one new task</h2>
<p>Take just two weights. After training on delivery and returns, both have the value 1. The first is very important for the old departments (importance 10), the second almost irrelevant (importance 0.1). The new task requires only that <strong>the two weights add up to 4</strong>. Many settings satisfy this: (2, 2), but also (1, 3).</p>
<ul>
<li><strong>Without protection</strong>, training moves both weights equally, to (2, 2). The new task is mastered, but the important weight has drifted by 1 and the loss on the old task rises from 0 to 5.05.</li>
<li><strong>A uniform penalty</strong> on both weights stops them halfway, at (1.67, 1.67). The old task suffers less, but the sum is 3.33 instead of 4.</li>
<li><strong>EWC</strong> shifts almost all of the movement onto the unimportant weight: (1.02, 2.80). The sum is 3.82, and the loss on the old task is only 0.16.</li>
</ul>
<p>Loss is a number that says how wrong the model is; the smaller, the better. In the experiment below you can change the penalty strength λ and the kind of protection. The result is computed exactly for this two-weight example; it is not a simulation of a real network.</p>
<div id="ewc-spring-lab"></div>
<h2 id="how-we-know-which-weight-is-important">How we know which weight is important</h2>
<p>In a real network, nobody supplies the importance in advance. It is estimated once the old task is finished, while its data are still available: you check how strongly a tiny change in a given weight changes the model's answers on the old examples. The paper uses the diagonal of the <em>Fisher information matrix</em> for this, that is, one importance number per weight. After that the data can be deleted; what remains are the old weight values and their importances.</p>
<p>During the new training, the sum of two terms is minimized (equation 3 in the paper):</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>L</mi><mo stretchy="false">(</mo><mi>θ</mi><mo stretchy="false">)</mo><mo>=</mo><msub><mi>L</mi><mi>B</mi></msub><mo stretchy="false">(</mo><mi>θ</mi><mo stretchy="false">)</mo><mo>+</mo><munder><mo>∑</mo><mi>i</mi></munder><mfrac><mi>λ</mi><mn>2</mn></mfrac><msub><mi>F</mi><mi>i</mi></msub><mtext> </mtext><mo stretchy="false">(</mo><msub><mi>θ</mi><mi>i</mi></msub><mo>−</mo><msubsup><mi>θ</mi><mrow><mi>A</mi><mo separator="true">,</mo><mi>i</mi></mrow><mo>∗</mo></msubsup><msup><mo stretchy="false">)</mo><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">L(\theta) = L_B(\theta) + \sum_i \frac{\lambda}{2} F_i \,(\theta_i - \theta^*_{A,i})^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">L</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.0278em;">θ</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">L</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3283em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0502em;">B</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.0278em;">θ</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:2.6491em;vertical-align:-1.2777em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.05em;"><span style="top:-1.8723em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-3.05em;"><span class="pstrut" style="height:3.05em;"></span><span><span class="mop op-symbol large-op">∑</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.2777em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3714em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">λ</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.1389em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.1389em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0278em;">θ</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.0278em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1.2472em;vertical-align:-0.3831em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0278em;">θ</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.7387em;"><span style="top:-2.453em;margin-left:-0.0278em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">A</span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight">i</span></span></span></span><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mbin mtight">∗</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3831em;"><span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></span>
<p><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>L</mi><mi>B</mi></msub></mrow><annotation encoding="application/x-tex">L_B</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">L</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3283em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0502em;">B</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> is the loss on the new task, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>θ</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">\theta_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0278em;">θ</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.0278em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> is the current value of weight number <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi></mrow><annotation encoding="application/x-tex">i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6595em;"></span><span class="mord mathnormal">i</span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msubsup><mi>θ</mi><mrow><mi>A</mi><mo separator="true">,</mo><mi>i</mi></mrow><mo>∗</mo></msubsup></mrow><annotation encoding="application/x-tex">\theta^*_{A,i}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.1059em;vertical-align:-0.4114em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0278em;">θ</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.6887em;"><span style="top:-2.4247em;margin-left:-0.0278em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">A</span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight">i</span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mbin mtight">∗</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.4114em;"><span></span></span></span></span></span></span></span></span></span> is its value after the old task, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>F</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">F_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.1389em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.1389em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> is its importance, and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>λ</mi></mrow><annotation encoding="application/x-tex">\lambda</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">λ</span></span></span></span> says how much the old task counts relative to the new one. In our example <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>F</mi><mo>=</mo><mo stretchy="false">(</mo><mn>10</mn><mo separator="true">,</mo><mtext> </mtext><mn>0.1</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">F = (10,\ 0.1)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.1389em;">F</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">10</span><span class="mpunct">,</span><span class="mspace"> </span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">0.1</span><span class="mclose">)</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>λ</mi><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">\lambda = 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">λ</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span>.</p>
<h2 id="limits-of-the-method">Limits of the method</h2>
<p>The importance is an approximation computed at a single point, separately for each weight. The authors themselves show that their estimate can be overconfident about which weights are unimportant, and they call this the main weakness of the method (§2.2 and §3). In their experiments with Atari games, an agent with EWC learned many games one after another, but did not match separate networks trained for each game. The results concern digit recognition and games, not large language models. Our two weights and customer messages are our own simplification.</p>
<ul>
<li><a href="https://paweldubiel.com/glossary/catastrophic-forgetting" hreflang="pl">Catastrophic Forgetting [Polski]</a> is a substantial deterioration of earlier skills after new training; EWC tries to reduce it without access to the old data.</li>
<li><a href="https://paweldubiel.com/en/glossary/experience-replay">Experience Replay</a> solves the same problem differently: it stores some of the earlier examples instead of weight importances.</li>
<li><a href="https://paweldubiel.com/en/glossary/continual-learning">Continual Learning</a> sets the goal, that is, learning successive tasks while retaining the earlier ones; EWC is one of the methods.</li>
<li><a href="https://paweldubiel.com/en/glossary/fine-tuning">Fine-tuning</a> is further training of a ready-made model; EWC changes its objective by adding a penalty for moving important weights.</li>
</ul>
<p><em>The text and illustration were prepared with AI assistance. The two weights, their importances and the demonstration are our own simplified educational example; the illustration is a metaphor, not a diagram of the model's architecture.</em></p>]]></content:encoded>
</item>
<item>
  <title>Reservoir Sampling</title>
  <link>https://paweldubiel.com/en/glossary/reservoir-sampling</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/reservoir-sampling</guid>
  <pubDate>Sun, 11 Oct 2026 12:00:11 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>llm</category>
  <category>glossary</category>
  <description>A customer-service model learns from messages that arrive one after another. You want to keep a few of them for later replay, but you have only four slots in memory.</description>
  <content:encoded><![CDATA[<p>A customer-service model learns from messages that arrive one after another. You want to keep a few of them for later replay, but you have only four slots in memory. You also do not know how many more messages will come: twenty or two million.</p>
<p>Keep the first four? Then the memory knows only the beginning. Always hold the last four? Then it knows only the end. A fair draw of “four out of the whole” would require storing everything or knowing the number of messages in advance. The question is: <strong>with a fixed number of slots and a stream of unknown length, how do you give every message the same chance?</strong></p>
<p><strong>Reservoir Sampling</strong> is a way of maintaining a random sample of fixed size during a single pass over data whose count we do not know in advance. After each new message, the memory, called a reservoir here, contains a fair random sample of everything that has arrived so far. The simplest version, Algorithm R, is described by <a href="https://doi.org/10.1145/3147.3165" rel="noopener noreferrer">Vitter, <em>Random Sampling with a Reservoir</em>, §2</a>, who attributes it to Alan Waterman.</p>
<p><img src="https://paweldubiel.com/assets/reservoir-sampling-pebble-stream-four-slot-tray.webp" alt="A long stream of pebbles and shells flows past a small wooden tray with four hollows; one hand takes a pebble out of the tray, the other puts a pebble from the stream in its place." loading="eager" decoding="async" width="1536" height="1024"></p>
<h2 id="the-recipe-in-two-steps">The recipe in two steps</h2>
<ol>
<li>The first four messages go into memory without any draw.</li>
<li>Message number <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>t</mi></mrow><annotation encoding="application/x-tex">t</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6151em;"></span><span class="mord mathnormal">t</span></span></span></span> (the fifth, the sixth and every later one) gets into memory with chance <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>4</mn><mi mathvariant="normal">/</mi><mi>t</mi></mrow><annotation encoding="application/x-tex">4/t</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">4/</span><span class="mord mathnormal">t</span></span></span></span>. If it gets in, it replaces one of the four stored messages, chosen at random.</li>
</ol>
<p>So the fifth message gets in with chance 4/5, the hundredth with chance 4/100. New messages have a smaller and smaller chance of getting in, but the old ones have already been exposed to being thrown out many times, and these two effects balance exactly. Let us check this after the fifth message. It gets in with chance 4/5. The first message drops out only if the fifth got in (4/5) and landed on exactly its slot (1/4), that is, with chance 1/5. It stays with chance 4/5: the same as the fifth has. After <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>t</mi></mrow><annotation encoding="application/x-tex">t</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6151em;"></span><span class="mord mathnormal">t</span></span></span></span> messages, each of them is in memory with chance <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>4</mn><mi mathvariant="normal">/</mi><mi>t</mi></mrow><annotation encoding="application/x-tex">4/t</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">4/</span><span class="mord mathnormal">t</span></span></span></span>.</p>
<h2 id="an-equal-chance-is-not-a-guarantee">An equal chance is not a guarantee</h2>
<p>In the experiment, the stream has 20 messages. Eighteen are about delivery, and two, the ninth and the fifteenth, are about returns. Each run sends such a stream through 2000 times and counts how often a given position stayed in memory at the end. The draws are real, so the results differ by a fraction of a percent each time.</p>
<div id="reservoir-sampling-lab"></div>
<p>With Reservoir Sampling, every bar is at about 20%, that is, 4/20. At the same time, in most runs neither of the two returns messages stays in memory. The exact value is 3060/4845, about 63%: that is how many of all the foursomes chosen from 20 messages consist solely of the eighteen delivery messages. The method is fair to individual messages, but it does not make sure that every category has a representative.</p>
<h2 id="where-this-matters">Where this matters</h2>
<p>In training with replay, Reservoir Sampling is sometimes the way of writing to the buffer: you do not need to know the length of the stream or the boundaries between tasks. <a href="https://arxiv.org/html/1902.10486v2#S2" rel="noopener noreferrer">Chaudhry et al., <em>Continual Learning with Tiny Episodic Memories</em>, §2, Algorithm 2</a> use it in exactly this way. In their experiments on image tasks it worked well, except with very small memories, where earlier classes disappeared from the buffer; strategies that ensure equal representation of classes did better then (§4.4). This is a result for image classification, not for LLMs.</p>
<p>The algorithm itself is not about machine learning. Vitter's 1985 paper describes sampling records from a magnetic tape of unknown length and proposes faster variants which, instead of drawing at every record, compute how many records to skip. The customer messages and the 20-position stream are our own example.</p>
<ul>
<li><a href="https://paweldubiel.com/en/glossary/experience-replay">Experience Replay</a> needs a buffer of earlier examples; Reservoir Sampling is one way of deciding what goes into it.</li>
<li><a href="https://paweldubiel.com/en/glossary/continual-learning">Continual Learning</a> assumes learning from a stream of data with limited memory, that is, a situation in which not everything can be kept.</li>
<li><a href="https://paweldubiel.com/glossary/catastrophic-forgetting" hreflang="pl">Catastrophic Forgetting [Polski]</a> can get worse when all the examples of an earlier category drop out of a small memory.</li>
</ul>
<p><em>The text and illustration were prepared with AI assistance. The message stream and the demonstration are our own simplified educational example; the illustration is a metaphor, not a diagram of the algorithm.</em></p>]]></content:encoded>
</item>
<item>
  <title>Experience Replay</title>
  <link>https://paweldubiel.com/en/glossary/experience-replay</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/experience-replay</guid>
  <pubDate>Sun, 11 Oct 2026 08:22:26 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>llm</category>
  <category>glossary</category>
  <description>A model has learned to route customer questions to “delivery” and “returns”. Now you are training it further to recognize complaints, such as “The product arrived damaged”.</description>
  <content:encoded><![CDATA[<p>A model has learned to route customer questions to “delivery” and “returns”. Now you are training it further to recognize complaints, such as “The product arrived damaged”. If its next exercises contain only complaints, it may become worse at handling the familiar “Where is my parcel?”. The complete old archive is unavailable. Could it at least revisit a few saved messages?</p>
<p><strong>Experience Replay (ER)</strong> means storing some earlier examples and reusing them for training. In a simple version, we mix examples from memory into a batch of new data. This memory is called a <em>replay buffer</em>: a container for practice data, not a record of everything the model knows. This joint training is described by <a href="https://arxiv.org/html/1902.10486v2#S2" rel="noopener noreferrer">Chaudhry et al., <em>Continual Learning with Tiny Episodic Memories</em>, §2, Algorithm 1</a>.</p>
<p><img src="https://paweldubiel.com/assets/experience-replay-card-box-returning-examples.webp" alt="Saved indigo and ochre cards return from a small box to a row of new red cards: a metaphor for practice during further learning." loading="eager" decoding="async" width="1536" height="1024"></p>
<h2 id="what-goes-into-the-next-exercise">What goes into the next exercise</h2>
<p>Before losing the archive, we saved four messages along with their correct departments. We now have four new complaints. Without replay, the model trains on four new messages. With replay, it also practices on four old ones: it receives another signal that “Where is my parcel?” belongs to delivery. In this small example we use the entire buffer; larger buffers usually supply a sampled batch.</p>
<p>Counting memory slots is not enough, however. Four saved delivery questions contain no returns example at all. Replacing two of them with “How do I send my purchase back?” and “I want to return a shirt” leaves the number of replayed examples unchanged, but covers both earlier departments. The experiment below <strong>counts examples in a data batch; it does not predict model accuracy</strong>.</p>
<div id="experience-replay-lab"></div>
<h2 id="replay-can-help-only-with-available-data">Replay can help only with available data</h2>
<p>The model gets an opportunity to practice earlier answers, not a guarantee that it will retain every skill. A small random sample can entirely miss a rare category; researchers observed this problem with very small buffers (§4.4 of the same paper). Our messages are our own example, not a result of those experiments. The effect of training must be checked on separate old and new messages that were not used for training. The buffer also consumes memory and requires retaining selected data.</p>
<p>See also: <a href="https://paweldubiel.com/en/glossary/reservoir-sampling">Reservoir Sampling</a> — a way of deciding which examples from a stream go into a fixed-size buffer while giving each one an equal chance.</p>
<p>In games, in <a href="https://paweldubiel.com/en/glossary/reinforcement-learning">Reinforcement Learning</a> — learning actions from rewards — the stored record includes a situation, an action, a reward and the next situation. Sampling such records reduces dependence on events that occur immediately one after another (<a href="https://storage.googleapis.com/deepmind-media/dqn/DQNNaturePaper.pdf#page=7" rel="noopener noreferrer">Mnih et al., <em>Human-level control through deep reinforcement learning</em>, Methods, “Training algorithm for deep Q-networks”</a>). These are different data from a message with its correct department; Atari results should not be transferred directly to LLMs.</p>
<ul>
<li><a href="https://paweldubiel.com/en/glossary/continual-learning">Continual Learning</a> sets the goal of further learning while retaining earlier abilities; ER is one way to pursue it.</li>
<li><a href="https://paweldubiel.com/glossary/catastrophic-forgetting" hreflang="pl">Catastrophic Forgetting [Polski]</a> describes a substantial deterioration of earlier skills, which replay may reduce.</li>
<li><a href="https://paweldubiel.com/en/glossary/fine-tuning">Fine-tuning</a> is further training of a model; replay changes the selection of its training data. Simply pasting old messages into a conversation is not this kind of model update.</li>
</ul>
<p><em>The text and illustration were prepared with AI assistance. The messages and demonstration are our own simplified educational example; the illustration is a metaphor, not a diagram of the model's architecture.</em></p>]]></content:encoded>
</item>
<item>
  <title>Continual Learning</title>
  <link>https://paweldubiel.com/en/glossary/continual-learning</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/continual-learning</guid>
  <pubDate>Sat, 10 Oct 2026 20:03:52 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>llm</category>
  <category>glossary</category>
  <description>A model routes customer messages to the “orders” and “returns” departments. It can recognize “Where is my parcel?” Now the company opens a complaints department.</description>
  <content:encoded><![CDATA[<p>A model routes customer messages to the “orders” and “returns” departments. It can recognize “Where is my parcel?” Now the company opens a complaints department. You train the model further on messages about damaged products. It gets better at routing complaints, but some delivery questions also start landing in the new department. Checking only complaints would give a false impression of progress.</p>
<p>You need to <strong>teach the model new things while preserving earlier abilities</strong>. This is the goal of <strong>Continual Learning</strong>: learning from data or tasks that arrive in sequence, while taking account of what the model has already learned. The name describes a problem and a family of approaches; it does not guarantee that forgetting will disappear. <a href="https://arxiv.org/html/1612.00796v2#S1" rel="noopener noreferrer">Kirkpatrick et al., <em>Overcoming catastrophic forgetting in neural networks</em>, §1</a> describe this need.</p>
<p><img src="https://paweldubiel.com/assets/continual-learning-embroidered-sampler-growing-repertoire.webp" alt="Circles and triangles remain embroidered on a single piece of fabric while a needle adds a new wavy pattern: a metaphor for developing skills while retaining earlier ones." loading="eager" decoding="async" width="1536" height="1024"></p>
<h2 id="what-changes-in-training-and-evaluation">What changes in training and evaluation</h2>
<p>Suppose the full archive of examples used for earlier training is no longer available. Before deleting it, we saved a small sample: 20 messages with their known correct departments. One possible method mixes this sample into the new complaint examples. Further training then also receives a signal to keep handling “Where is my parcel?” correctly. Reusing earlier examples is one of the strategies described by <a href="https://arxiv.org/pdf/1904.07734v1" rel="noopener noreferrer">van de Ven and Tolias, <em>Three scenarios for continual learning</em>, §3.3</a>.</p>
<p>See also: <a href="https://paweldubiel.com/en/glossary/experience-replay">Experience Replay</a> — storing a small sample of earlier examples and mixing it into new training.</p>
<p>The evaluation team keeps a separate test of old messages, which <strong>we do not use for training</strong>. After each update, we check both old and new categories. The numbers below are an invented example, not research results; each test contains 100 messages.</p>

























<table><thead><tr><th>Model variant</th><th>Correctly classified old messages</th><th>Correctly classified complaints</th></tr></thead><tbody><tr><td>Before the new training</td><td>90/100</td><td>0/100 — this category does not exist yet</td></tr><tr><td>After training only on complaints</td><td>40/100</td><td>92/100</td></tr><tr><td>After training with a sample of earlier messages</td><td>89/100</td><td>87/100</td></tr></tbody></table>
<p>The last variant preserves the earlier ability better, although it recognizes complaints less well than the second one. The table shows <strong>what to compare</strong>; it does not promise this result from adding 20 examples.</p>
<h2 id="conditions-change-the-difficulty">Conditions change the difficulty</h2>
<p>In our example, the model chooses among all the departments it has learned. A hint such as “this message belongs to the new category” would make the test easier. Whether such hints and task boundaries are available matters when comparing methods (<a href="https://arxiv.org/pdf/1904.07734v1" rel="noopener noreferrer">van de Ven and Tolias, §2–2.3</a>). A small sample may miss rare questions; a good average does not prove that every ability has been preserved.</p>
<ul>
<li><a href="https://paweldubiel.com/glossary/catastrophic-forgetting" hreflang="pl">Catastrophic Forgetting [Polski]</a> describes a substantial deterioration in old abilities; its demonstration shows how new training changes shared settings.</li>
<li><a href="https://paweldubiel.com/en/glossary/fine-tuning">Fine-tuning</a> means training a model further on selected examples. After successive training rounds, we also check its earlier abilities.</li>
<li><a href="https://paweldubiel.com/en/glossary/knowledge-distillation">Knowledge Distillation</a> can pass guidance from an older model to the one being updated; this is a different strategy from keeping the original messages (§3.3 of van de Ven and Tolias's paper).</li>
</ul>
<p><em>The text and illustration were prepared with AI assistance; the messages, sample size and table results are our own educational example. The illustration shows the goal of preserving earlier abilities, not the model's structure.</em></p>]]></content:encoded>
</item>
<item>
  <title>Sequence Packing</title>
  <link>https://paweldubiel.com/en/glossary/sequence-packing</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/sequence-packing</guid>
  <pubDate>Wed, 07 Oct 2026 07:34:31 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>llm</category>
  <category>glossary</category>
  <description>You are teaching a model to write short customer responses: “Thank you”, “No”, and “Yes”. After division into pieces of text, or tokens, the examples illustratively occupy 3, 2, and 2 positions…</description>
  <content:encoded><![CDATA[<p>You are teaching a model to write short customer responses: “Thank you”, “No”, and “Yes”. After division into pieces of text, or <a href="https://paweldubiel.com/en/glossary/token">tokens</a>, the examples illustratively occupy 3, 2, and 2 positions, including each text's end marker. If each is stored in a separate row of eight slots, only seven of the 24 slots contain data. The rest is <strong>padding</strong>, filler that aligns lengths but is not content to learn. How can the free slots be used?</p>
<p><strong>Sequence Packing</strong> arranges several examples in one input sequence to reduce padding during training. In our example, all three fit into one eight-position row: seven slots with data, one empty. No new answers were created; their arrangement changed. <a href="https://huggingface.co/docs/trl/v0.29.0/sft_trainer#packing" rel="noopener noreferrer">The TRL 0.29.0 documentation, SFT Trainer, “Packing”</a> describes this role.</p>
<p><img src="https://paweldubiel.com/assets/sequence-packing-paper-strips-divided-tray.webp" alt="Three colored paper strips closely arranged in one long tray, with thin dividers preserving their separation: a metaphor for Sequence Packing." loading="eager" decoding="async" width="1536" height="1024"></p>
<p>Eight slots are <strong>our own simplification</strong>, rather than TRL's default row size. An ordinary batch of examples may be padded only to its longest text; grouping similar lengths also reduces wasted space. <a href="https://arxiv.org/html/1706.03762v7#S5.SS1" rel="noopener noreferrer"><em>Attention Is All You Need</em>, §5.1</a>, already describes this grouping. Empty slot count alone does not determine speedup: that also depends on how computations are executed.</p>
<h2 id="a-shared-row-need-not-mean-a-shared-conversation">A shared row need not mean a shared conversation</h2>
<p>You want “No” to remain an independent example, rather than a continuation of “Thank you”. The end marker itself is only a token. Ordinary blocking of future access — <a href="https://paweldubiel.com/en/glossary/causal-masking">Causal Masking</a> — still lets later text read earlier text in the same row.</p>
<p>To preserve independence, computation must know example boundaries and block access across them. Error evaluation must be controlled separately: do not teach prediction of the first token of “No” from the previous text's ending. Choosing assessed positions is <a href="https://paweldubiel.com/en/glossary/loss-masking">Loss masking</a>; omitting a position's penalty <strong>does not block reading it</strong>.</p>
<p>Specifically, in <a href="https://github.com/huggingface/trl/blob/v0.29.0/trl/trainer/sft_trainer.py" rel="noopener noreferrer">TRL 0.29.0 code: DataCollatorForLanguageModeling and BFD packing configuration</a>, example lengths reconstruct boundaries and beginnings are excluded from error evaluation. This path requires a compatible attention implementation — the mechanism for using other text positions; the code warns of information leakage in unsupported configurations. This is a requirement of the specific solution, rather than a property of all packing.</p>
<h2 id="check-two-separate-things">Check two separate things</h2>
<p>Enable packing, then disable access isolation. The space saving remains, but B1 can use the earlier example A. Squares represent end tokens; A1, B1, and so on are illustrative text pieces. The demonstration shows allowed connections without simulating model responses. The “full rows” variant reveals no savings when every example already fills eight slots.</p>
<div id="sequence-packing-lab"></div>
<p>Strategies differ in how they handle long texts. In <a href="https://github.com/huggingface/trl/blob/v0.29.0/trl/data_utils.py" rel="noopener noreferrer">TRL 0.29.0, the <code>pack_dataset</code> function</a>, <code>bfd</code> fits whole examples into free slots but truncates the excess of an overlong example; <code>wrapped</code> can split text in the middle. Both retained data and boundaries must therefore be checked. Packing organizes training inputs, including <a href="https://paweldubiel.com/en/glossary/fine-tuning">Fine-tuning</a> — further model adaptation using examples. It does not increase the maximum text length the model supports.</p>]]></content:encoded>
</item>
<item>
  <title>Reinforcement Learning</title>
  <link>https://paweldubiel.com/en/glossary/reinforcement-learning</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/reinforcement-learning</guid>
  <pubDate>Mon, 05 Oct 2026 08:44:03 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>llm</category>
  <category>glossary</category>
  <description>You want to teach a program to win a small game. At a fork, it can choose route A, collect two coins immediately, and finish the second turn without any new coins.</description>
  <content:encoded><![CDATA[<p>You want to teach a program to win a small game. At a fork, it can choose route A, collect two coins immediately, and finish the second turn without any new coins. Route B gives nothing on the first turn but leads to five coins on the second. The rule “choose what gives the most now” favors A, although B gives the better result after two turns. You also lack a set of ready answers identifying the correct move in every situation. The program can, however, play games and check their results.</p>
<p><strong>Reinforcement Learning (RL)</strong> learns a strategy for acting from experience and numerical assessments of actions' consequences. The goal is to increase expected total reward: the result a strategy produces on average across many attempts. A reward need not arrive immediately after a decision. The official <a href="https://spinningup.openai.com/en/latest/spinningup/rl_intro.html" rel="noopener noreferrer">Spinning Up, Part 1, “Key Concepts and Terminology”, “Reward and Return”, and “The RL Problem”</a> describes the problem this way.</p>
<p><img src="https://paweldubiel.com/assets/reinforcement-learning-two-routes-delayed-reward.webp" alt="A forked route on a wooden board: the nearer branch leads to a small reward, the longer one to a larger reward." loading="eager" decoding="async" width="1536" height="1024"></p>
<h2 id="what-the-program-learns-from-a-game">What the program learns from a game</h2>
<p>In our game, the <strong>agent</strong> is the program choosing a route, and the <strong>environment</strong> is the game that executes the move and awards coins. The program receives an observation, the available information about the situation, such as its board position. Its <strong>policy</strong> is its rule for choosing actions; it can also specify probabilities for different moves.</p>
<p>After attempt A, the program records “2, then 0”. Attempt B gives “0, then 5”. The learning algorithm uses this experience to improve the policy, for example choosing B more often at this fork. This describes the goal, rather than one universal update recipe. The result 5 must be connected to the earlier choice of B. If the program always chooses A, it collects no information about B; learning therefore often requires trying less familiar actions too.</p>
<p>The invented game has fixed results and two turns. In a more difficult environment, the same move can have different consequences, so the expected result matters and one success does not prove a good strategy has been found. Simply comparing two known sums is not yet learning either.</p>
<p>In <a href="https://paweldubiel.com/en/glossary/behavioral-cloning">Behavioral cloning</a>, the program learns to imitate actions from examples. In RL, assessments of consequences guide learning. In language models, an action can be generating a response, and a reward can assess its correctness or usefulness. <a href="https://paweldubiel.com/glossary/reinforcement-learning-from-human-feedback" hreflang="pl">RLHF [Polski]</a> uses information from people for this purpose.</p>
<p>An important boundary: RL improves performance according to the chosen reward. If points reward bypassing rules rather than doing the task, the agent can learn <a href="https://paweldubiel.com/glossary/reward-hacking-wykorzystywanie-luk-w-systemie-nagrod" hreflang="pl">Reward hacking [Polski]</a>. More points need not mean the behavior we actually wanted.</p>
<h2 id="pick-a-route-then-check-the-second-turn">Pick a route, then check the second turn</h2>
<p>In this experiment you compare the objective of two strategies; <strong>you do not train an agent</strong>. Choose a route and reveal the later result. The slider changes the importance of the future reward, rather than the number of coins collected.</p>
<p>We calculate the <strong>return</strong>, the result for the entire attempt: <code>first reward + γ × second reward</code>. The symbol γ (gamma) weights the future reward. At γ = 1, both turns count fully: A gives 2, B gives 5. At γ = 0.2, we obtain A = 2, B = 1. This is a different evaluation objective for the same game. Boundary values γ = 0 and 1 are allowed here because the attempt ends after two turns; this is not an infinite reward sequence. Formalism source: <a href="https://spinningup.openai.com/en/latest/spinningup/rl_intro.html#reward-and-return" rel="noopener noreferrer">Spinning Up, “Reward and Return”</a>.</p>
<div id="rl-delayed-reward-lab"></div>]]></content:encoded>
</item>
<item>
  <title>Loss masking</title>
  <link>https://paweldubiel.com/en/glossary/loss-masking</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/loss-masking</guid>
  <pubDate>Sun, 20 Sep 2026 15:05:00 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>papers</category>
  <category>llm</category>
  <category>training</category>
  <description>You are training an agent on records of conversations with tools. A record contains its commands and the tools&apos; responses.</description>
  <content:encoded><![CDATA[<p>You are training an agent on records of conversations with tools. A record contains its commands and the tools' responses. You want to assess selected parts while still letting it read the rest as context for its next action.</p>
<p><strong>Loss masking</strong> determines which positions contribute to the loss, the numerical measure of error during learning. A <a href="https://paweldubiel.com/en/glossary/token">token</a> — a piece of text — may remain visible in the input even though the model is not directly assessed for predicting it.</p>
<p>When training only on the agent's responses, the user's text and the tool's result help it choose the next step, but receive no separate prediction penalty. The model therefore does not need to learn to generate every part of the entire record.</p>
<p>This differs from <a href="https://paweldubiel.com/en/glossary/causal-masking">Causal Masking</a>, which restricts information flow between positions. Having no loss term for a token need not mean having no effect on training: its computations may influence later positions that are assessed. <a href="https://arxiv.org/html/2609.20715v1#S2" rel="noopener noreferrer">“Don't Mask the Environment”, §2</a>, examines the consequences of choosing which parts to assess.</p>
<p>See also: <a href="https://paweldubiel.com/en/glossary/sequence-packing">Sequence Packing</a> shows why combining examples requires separate control over access to context and the positions assessed by the loss.</p>
<p><img src="https://paweldubiel.com/assets/loss-masking-hero.webp" alt="Six tokens remain in a single row, but only three orange ones are connected to a weighing pan symbolizing the loss." loading="eager" decoding="async" width="1600" height="900"></p>]]></content:encoded>
</item>
<item>
  <title>pass@k</title>
  <link>https://paweldubiel.com/en/glossary/pass-k</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/pass-k</guid>
  <pubDate>Sun, 20 Sep 2026 15:04:00 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>papers</category>
  <category>llm</category>
  <category>agents</category>
  <description>The model produced ten programs, and one passed the tests. Does that mean a single response is likely to succeed?</description>
  <content:encoded><![CDATA[<p>The model produced ten programs, and one passed the tests. Does that mean a single response is likely to succeed? You need to distinguish “it worked on the first attempt” from “we found a success among many attempts”.</p>
<p><strong>pass@k</strong> measures the chance that at least one of <code>k</code> attempts at a task passes a specified check. Results are summarized across tasks. The number <code>k</code> is part of the metric's meaning because it determines the attempt budget.</p>
<p>In a pool of four attempts with one success, the pass@1 estimate is <code>1/4</code>. Of the six possible pairs, three contain a success, so the pass@2 estimate from this pool is <code>1/2</code>. Do not confuse the number of attempts collected for estimation with the number allowed in the situation being measured.</p>
<p>A high pass@10 does not promise an equally good pass@1. Nor does it tell us whether the user can identify the correct attempt without a tester. <a href="https://arxiv.org/abs/2107.03374" rel="noopener noreferrer">Chen and colleagues, §3.1</a>, describe pass@k estimation; <a href="https://arxiv.org/html/2609.20715v1#A1" rel="noopener noreferrer">the paper on agents</a> uses this metric in a different context.</p>]]></content:encoded>
</item>
<item>
  <title>Continuous Batching</title>
  <link>https://paweldubiel.com/en/glossary/continuous-batching</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/continuous-batching</guid>
  <pubDate>Sun, 20 Sep 2026 07:26:41 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>llm</category>
  <category>glossary</category>
  <description>A server generates two responses at once. One finishes quickly; the other is long. If the next user must wait for the entire pair to finish, the freed slot is wasted for many steps.</description>
  <content:encoded><![CDATA[<p>A server generates two responses at once. One finishes quickly; the other is long. If the next user must wait for the entire pair to finish, the freed slot is wasted for many steps.</p>
<p><strong>Continuous Batching</strong> allows the group of requests being served to change between successive model iterations. A completed response leaves the batch — a group processed together — and a new request can take its place.</p>
<p>The long response continues to grow while the short one is replaced by the next. A scheduler, a program that plans the work, selects the participants. There is no need to wait for the slowest member of the entire previous group.</p>
<p>Using slots this way can increase throughput, but does not guarantee a shorter wait for every user. Request lengths, memory limits, and scheduling rules matter. With similar lengths, the advantage over a fixed group may be small.</p>
<p>Mechanism source: <a href="https://www.usenix.org/system/files/osdi22-yu.pdf#page=6" rel="noopener noreferrer"><em>Orca</em>, §3, “Iteration-level scheduling”</a>.</p>
<h2 id="mechanism-and-details">Mechanism and details</h2>
<p><img src="https://paweldubiel.com/assets/continuous-batching-hero.webp" alt="A press with two tracks: a long turquoise strip continues, while an orange strip takes the place of a short ochre one." loading="eager" decoding="async" width="1600" height="900"></p>
<p>This is especially useful in <a href="https://paweldubiel.com/en/glossary/decode">Decode</a>: one person needs a short response, another several hundred <a href="https://paweldubiel.com/en/glossary/token">tokens</a>. Merely gathering several requests before running the model does not ensure that an active batch's membership can change. A new request also needs <a href="https://paweldubiel.com/en/glossary/prefill">Prefill</a>; how this stage is handled alongside generation depends on the engine's implementation.</p>
<h2 id="does-c-have-to-wait-for-a">Does C have to wait for A?</h2>
<p>An original experiment: two slots are available. A and B are ready at time 0 and need six and two rounds respectively. C becomes ready at time 1 and needs two rounds. Both variants perform the same computations, but in a fixed group, B's slot does not accept C until A finishes.</p>
<p>With Continuous Batching, C starts at time 2 and finishes at 4; with a fixed group, it starts at 6 and finishes at 8. Switch B to six rounds: in this case, early release of a slot disappears, and both strategies produce the same schedule.</p>
<div id="continuous-batch-lab"></div>
<p>Rounds here have an illustrative, equal duration. Prefill and transfers are outside the experiment; “ready” means ready for the displayed rounds. On a GPU, iteration time depends on its workload, so the number of occupied slots is not the device-utilization percentage.</p>
<p>The ability to join a request does not guarantee an immediate start: memory limits and scheduler policy apply (<em>Orca</em>, §4.2). <a href="https://paweldubiel.com/en/glossary/pagedattention">PagedAttention</a> helps manage memory but does not itself determine serving order.</p>
<p>I use AI-generated content as part of my daily learning process.</p>]]></content:encoded>
</item>
<item>
  <title>PagedAttention</title>
  <link>https://paweldubiel.com/en/glossary/pagedattention</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/pagedattention</guid>
  <pubDate>Sun, 20 Sep 2026 07:26:41 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>llm</category>
  <category>glossary</category>
  <description>A server handles conversations of different lengths. If it reserves a large contiguous memory region in advance for each entire future response, some space remains unused.</description>
  <content:encoded><![CDATA[<p>A server handles conversations of different lengths. If it reserves a large contiguous memory region in advance for each entire future response, some space remains unused. You want to allocate smaller pieces as needed.</p>
<p><strong>PagedAttention</strong> reads information from <a href="https://paweldubiel.com/en/glossary/kv-cache">KV Cache</a> stored in blocks that may occupy different locations in memory. A block table indicates where to find the next logical part of the conversation. The text remains in the correct order.</p>
<p>If a block holds descriptions of four <a href="https://paweldubiel.com/en/glossary/token">tokens</a> — pieces of text — a fifth requires a second block. The system does not have to reserve room for each conversation's maximum length in advance. It can also share unchanged blocks according to its memory management rules.</p>
<p>This is a way to address and organize data, rather than automatically shorten context or change the attention result. Tables and partially filled blocks still have a cost. The experiment shows how logical order is separated from physical location.</p>
<p>Mechanism source: <a href="https://arxiv.org/html/2309.06180v1#S4.SS1" rel="noopener noreferrer">Kwon et al., §4.1–4.3</a>.</p>
<h2 id="mechanism-and-details">Mechanism and details</h2>
<p><img src="https://paweldubiel.com/assets/pagedattention-hero.webp" alt="One apricot-colored thread connects four distant blocks, preserving sequence continuity despite their dispersion in memory." loading="eager" decoding="async" width="1600" height="900"></p>
<p>An original example: a block holds KV for four positions. A sequence of length five needs two blocks, or eight slots. The first block is full; the second contains one entry and three free slots. Logical blocks 0 and 1 can point to physical blocks 4 and 1. There is no need to move the existing prefix to append the next block during <a href="https://paweldubiel.com/en/glossary/decode">Decode</a>.</p>
<h2 id="text-order-is-not-a-memory-address">Text order is not a memory address</h2>
<p>The demonstration shows one sequence and blocks of four positions. Process successive positions, especially the transition from four to five. Then change the layout of the same data. We assume one scalar head: all keys are zero, the query is 1, and values at successive positions are 1, 2, 3… Attention weights are therefore equal, and the result is the mean of the values. For five positions, it is 3 in both layouts.</p>
<div id="paged-kv-lab"></div>
<p>This illustrates addressing and allocation, not GPU runtime. Empty slots in the last block still occupy memory; PagedAttention neither removes nor compresses existing KV. <a href="https://paweldubiel.com/en/glossary/flashattention">FlashAttention</a> focuses on organizing computation and transfers during attention. These mechanisms can complement one another. Block-based memory sharing is also useful in <a href="https://paweldubiel.com/en/glossary/prefix-caching">Prefix Caching</a>.</p>
<p>I use AI-generated content as part of my daily learning process.</p>]]></content:encoded>
</item>
<item>
  <title>Prefix Caching</title>
  <link>https://paweldubiel.com/en/glossary/prefix-caching</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/prefix-caching</guid>
  <pubDate>Sun, 20 Sep 2026 07:26:41 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>llm</category>
  <category>glossary</category>
  <description>You ask five questions about the same long document. Each input starts with the same instruction and document text; only the ending contains a new question.</description>
  <content:encoded><![CDATA[<p>You ask five questions about the same long document. Each input starts with the same instruction and document text; only the ending contains a new question. Computing the same beginning again would repeat work.</p>
<p><strong>Prefix Caching</strong> reuses previously computed results for a common prefix of <a href="https://paweldubiel.com/en/glossary/token">tokens</a> — pieces of text — across requests. In suitable models these may be <a href="https://paweldubiel.com/en/glossary/kv-cache">KV Cache</a> data that let the model skip part of <a href="https://paweldubiel.com/en/glossary/prefill">input processing</a>.</p>
<p>The new question still needs processing, and its answer still needs generating. The cache is not a library of ready answers. The prefix and computational conditions must match: two documents with similar meanings need not share a cache.</p>
<p>Even a small change to an earlier part can prevent reuse of later blocks. The saving concerns repeated work, rather than every conversation; storing shared results also takes memory.</p>
<p>Mechanism source: <a href="https://docs.vllm.ai/en/v0.21.0/features/automatic_prefix_caching/" rel="noopener noreferrer">vLLM 0.21.0, “Introduction” and “Limits”</a>.</p>
<h2 id="mechanism-and-details">Mechanism and details</h2>
<p><img src="https://paweldubiel.com/assets/prefix-caching-hero.webp" alt="A shared trunk made of identical segments splits into three different, unfinished branches." loading="eager" decoding="async" width="1600" height="900"></p>
<p>What matters is an <strong>identical token prefix in a compatible computational context</strong>, not similarity of meaning. Keys and values in later layers depend on the preceding context. The same final paragraph after a changed beginning does not automatically yield the same KV.</p>
<p>vLLM identifies a block by its tokens, the preceding block's identifier, and additional data, including the <a href="https://paweldubiel.com/en/glossary/lora">LoRA</a> adapter ID and image input. In the version described, it stores full blocks for reuse. See the <a href="https://docs.vllm.ai/en/v0.21.0/design/prefix_caching/" rel="noopener noreferrer">description of Automatic Prefix Caching</a>. Compatibility of the model, positions, and other settings affecting KV is a condition for correct reuse; comparing texts alone is insufficient.</p>
<h2 id="one-changed-token-different-consequences">One changed token, different consequences</h2>
<p>The cache in our example contains the sequence A B C D E F G H, divided into blocks of two tokens. Letters represent illustrative token IDs. A new request replaces exactly one position with X. Change its location and check how many whole blocks can be recovered.</p>
<p>Changing H to X leaves seven shared tokens, but only six in full blocks. Changing A to X gives zero hits, even though the next seven tokens match. All other conditions in the example stay fixed; the cache is available, and nothing has been evicted.</p>
<div id="prefix-match-lab"></div>
<p>This caches computation, not a ready-made answer. <a href="https://paweldubiel.com/en/glossary/decode">Decode</a> must still produce further tokens, and evicted blocks must be recalculated. <a href="https://paweldubiel.com/en/glossary/pagedattention">PagedAttention</a> explains organizing memory in blocks.</p>
<p>I use AI-generated content as part of my daily learning process.</p>]]></content:encoded>
</item>
<item>
  <title>Time to First Token</title>
  <link>https://paweldubiel.com/en/glossary/time-to-first-token</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/time-to-first-token</guid>
  <pubDate>Sun, 20 Sep 2026 07:26:41 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>llm</category>
  <category>glossary</category>
  <description>You click “Send” and stare at an empty chat. For the user&apos;s comfort, it matters when the beginning of the response appears, even if writing the rest takes much longer.</description>
  <content:encoded><![CDATA[<p>You click “Send” and stare at an empty chat. For the user's comfort, it matters when the beginning of the response appears, even if writing the rest takes much longer. You need to measure that initial wait.</p>
<p><strong>Time to First Token (TTFT)</strong> is the time from a specified starting point in request handling to the first <a href="https://paweldubiel.com/en/glossary/token">token</a>, a piece of the response. In the client measurement described here, we start when the request is sent and stop at the first nonempty content.</p>
<p>If the question was sent at <code>0 ms</code> and the first text arrived at <code>800 ms</code>, TTFT is <code>800 ms</code>. This can include network time, queuing, input preparation, and computation. Measuring only the model's time would use different boundaries.</p>
<p>A low TTFT does not guarantee a smooth continuation: a long pause may follow the first piece. <a href="https://paweldubiel.com/glossary/inter-token-latency" hreflang="pl">Inter-token Latency [Polski]</a> describes this. Comparisons must always state where the measurement starts and ends.</p>
<p>Mechanism source: <a href="https://docs.nvidia.com/nim/benchmarking/llm/latest/metrics.html#time-to-first-token" rel="noopener noreferrer">NVIDIA NIM Benchmarking documentation, “Time to First Token”</a>.</p>
<h2 id="mechanism-and-details">Mechanism and details</h2>
<p><img src="https://paweldubiel.com/assets/time-to-first-token-hero.webp" alt="The first gold square passes through the narrow neck of an hourglass while most of the contents remain above." loading="eager" decoding="async" width="1600" height="900"></p>
<p>TTFT covers more than <a href="https://paweldubiel.com/en/glossary/prefill">Prefill</a>: the client may wait for the network, input preparation, the queue, computation, and result transmission. A measurement starting only inside the server has different boundaries. Such numbers should not be compared without checking where their timestamps come from.</p>
<h2 id="the-first-character-arrives-quickly-the-full-response-late">The first character arrives quickly, the full response late</h2>
<p>An original event trace: sending at 0 ms, server arrival at 30 ms, 10 ms of preparation, a 200 ms queue, 120 ms of Prefill, 5 ms to prepare the first result, and 35 ms to deliver it. Client TTFT is <strong>400 ms</strong>; the time from request arrival to result preparation on the server is <strong>335 ms</strong>.</p>
<p>After the first token, we receive four more, every 20 ms. The full response arrives at 480 ms. Increase their intervals to 100 ms: completion moves to 800 ms, but the first token still arrives at 400 ms. Then increase the queue and see which results change together.</p>
<div id="ttft-clock-lab"></div>
<p>The times are synthetic, the stages do not overlap, and each message contains one token. Real streaming can group tokens. TTFT describes neither the rhythm of <a href="https://paweldubiel.com/en/glossary/decode">Decode</a> nor the time to receive the complete response; the documentation separates these metrics in “Inter-token Latency” and “End-to-End Request Latency”. <a href="https://paweldubiel.com/glossary/inter-token-latency" hreflang="pl">Inter-token Latency [Polski]</a> describes intervals and pauses after the first token. <a href="https://paweldubiel.com/en/glossary/prefix-caching">Prefix Caching</a> can reduce prompt processing, while <a href="https://paweldubiel.com/en/glossary/continuous-batching">Continuous Batching</a> affects when the scheduler admits a request for execution.</p>
<p>I use AI-generated content as part of my daily learning process.</p>]]></content:encoded>
</item>
<item>
  <title>Decode</title>
  <link>https://paweldubiel.com/en/glossary/decode</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/decode</guid>
  <pubDate>Fri, 18 Sep 2026 07:31:25 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>llm</category>
  <category>glossary</category>
  <description>The first piece of the response has appeared. The next must account for what was just written: after “Today I drink tea” the model has a different context than after “Today I drink water”.</description>
  <content:encoded><![CDATA[<p>The first piece of the response has appeared. The next must account for what was just written: after “Today I drink tea” the model has a different context than after “Today I drink water”. This changing text must be extended step by step.</p>
<p><strong>Decode</strong> is the stage of generating a continuation after processing the initial input. In the usual loop, the model processes the most recently selected <a href="https://paweldubiel.com/en/glossary/token">token</a> — a piece of text — computes probabilities for the next one, and a selection rule appends one of the candidates.</p>
<p>The chosen piece becomes the input to the next step. <a href="https://paweldubiel.com/en/glossary/kv-cache">KV Cache</a> retains needed results from earlier computations, so the entire history does not have to be processed again.</p>
<p>Successive choices depend on each other, although several different responses can be served together. Here Decode means extending text with the model, rather than merely converting token numbers into characters. <a href="https://paweldubiel.com/en/glossary/prefill">Prefill</a> prepares the initial context.</p>
<p>Mechanism source: <a href="https://arxiv.org/html/1911.02150v1#S2.SS4" rel="noopener noreferrer">Shazeer, <em>Fast Transformer Decoding</em>, §2.4</a>.</p>
<h2 id="mechanism-and-details">Mechanism and details</h2>
<p><img src="https://paweldubiel.com/assets/decode-hero.webp" alt="A row of completed knitting stitches ends with one new stitch being formed on the needle." loading="eager" decoding="async" width="1600" height="900"></p>
<p>The first response token can be selected from the output of <a href="https://paweldubiel.com/en/glossary/prefill">Prefill</a>. If generation continues, this token becomes the input of the next model pass. Its new K and V are added to <a href="https://paweldubiel.com/en/glossary/kv-cache">KV Cache</a>, and the query uses the current and earlier positions. Selecting the token ID alone does not yet append its representation to the cache. This can be seen in the <a href="https://huggingface.co/docs/transformers/cache_explanation#cache-storage-implementation" rel="noopener noreferrer">Hugging Face generation loop, “Cache storage implementation”</a>.</p>
<h2 id="a-token-selected-but-not-yet-processed">A token selected but not yet processed</h2>
<p>An original miniature model has three tokens: A, B, C. Their vectors are <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mn>1</mn><mo separator="true">,</mo><mn>0</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(1,0)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">0</span><span class="mclose">)</span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mn>0</mn><mo separator="true">,</mo><mn>1</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(0,1)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">1</span><span class="mclose">)</span></span></span></span>, and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mo>−</mo><mn>1</mn><mo separator="true">,</mo><mo>−</mo><mn>1</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(-1,-1)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">−</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">−</span><span class="mord">1</span><span class="mclose">)</span></span></span></span> respectively. We take <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Q</mi><mo>=</mo><mi>K</mi><mo>=</mo><mi>V</mi></mrow><annotation encoding="application/x-tex">Q=K=V</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8778em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">Q</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.0715em;">K</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.2222em;">V</span></span></span></span> equal to these vectors; attention uses a scale of <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mi mathvariant="normal">/</mi><msqrt><mn>2</mn></msqrt></mrow><annotation encoding="application/x-tex">1/\sqrt{2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.1572em;vertical-align:-0.25em;"></span><span class="mord">1/</span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9072em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord">2</span></span></span><span style="top:-2.8672em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width="400em" height="1.08em" viewBox="0 0 400000 1080" preserveAspectRatio="xMinYMin slice"><path d="M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z"></path></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.1328em;"><span></span></span></span></span></span></span></span></span>. From the result <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>h</mi><mo>=</mo><mo stretchy="false">(</mo><msub><mi>h</mi><mn>0</mn></msub><mo separator="true">,</mo><msub><mi>h</mi><mn>1</mn></msub><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">h=(h_0,h_1)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">h</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span>, we create logits <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">[</mo><msub><mi>h</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi>h</mi><mn>0</mn></msub><mo separator="true">,</mo><mo>−</mo><msub><mi>h</mi><mn>0</mn></msub><mo>−</mo><msub><mi>h</mi><mn>1</mn></msub><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">[h_1,h_0,-h_0-h_1]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">−</span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">]</span></span></span></span>, and <a href="https://paweldubiel.com/en/glossary/greedy-decoding">Greedy Decoding</a> selects the largest.</p>
<p>The prompt A B gives approximately <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>h</mi><mo>=</mo><mo stretchy="false">(</mo><mn>0,330</mn><mo separator="true">;</mo><mn>0,670</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">h=(0{,}330;0{,}670)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">h</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">330</span><span class="mpunct">;</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">670</span><span class="mclose">)</span></span></span></span>, so the first answer is A. The cache still contains only the prompt's two positions. Only the next pass processes the selected A.</p>
<div id="decode-cache-lab"></div>
<p>This is a fully specified demonstration model, without training, positions, multiple layers, or an end token. Its repetitive response has no linguistic meaning. Comparison with recomputing the entire prefix checks agreement of results, and the counter covers only positions for which K/V were calculated.</p>
<p>The cache removes repeated computation of earlier K/V, but attention still reads the context. With small batches, transferring weights or cache often becomes the bottleneck; this depends on the model, hardware, and sequence length. In <a href="https://paweldubiel.com/glossary/disaggregated-serving" hreflang="pl">Disaggregated Serving [Polski]</a>, Decode runs on separate resources after receiving the cache. Decode in this sense is not a tokenizer converting token identifiers back into text.</p>
<p>I use AI-generated content as part of my daily learning process.</p>]]></content:encoded>
</item>
<item>
  <title>FlashAttention</title>
  <link>https://paweldubiel.com/en/glossary/flashattention</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/flashattention</guid>
  <pubDate>Fri, 18 Sep 2026 07:31:25 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>llm</category>
  <category>glossary</category>
  <description>Attention compares many pairs of text fragments. Saving all intermediate results to a computing card&apos;s large memory can make data transfers expensive.</description>
  <content:encoded><![CDATA[<p>Attention compares many pairs of text fragments. Saving all intermediate results to a computing card's large memory can make data transfers expensive. You want to perform the same calculation while reducing movement and storage of a huge table.</p>
<p><strong>FlashAttention</strong> organizes attention computation in blocks in the chip's small, fast memory. It does not write the full matrix of comparisons and weights to the large memory of the GPU, the card used for parallel computation.</p>
<p>Each chunk contributes part of the result, and the algorithm correctly updates the normalization and sum. You cannot simply compute separate chunk averages and average them: the chunks may have different weights.</p>
<p>The mathematical operation of exact attention is preserved, with the usual differences from computer arithmetic. For dense attention, the number of comparisons still grows quadratically. The gain comes from memory and execution organization, rather than removing dependencies between pairs.</p>
<p>Mechanism source: <a href="https://arxiv.org/html/2205.14135v2#S3" rel="noopener noreferrer">Dao et al., §2–3.2, Algorithm 1</a>.</p>
<h2 id="mechanism-and-details">Mechanism and details</h2>
<p><img src="https://paweldubiel.com/assets/flashattention-hero.webp" alt="A small work surface processes one tile from a large supply, limiting movement of the entire contents." loading="eager" decoding="async" width="1600" height="900"></p>
<p>For dense attention, the number of operations still grows quadratically with sequence length. The gain comes from computation and memory organization. During training, some quantities are recomputed in the backward pass rather than stored. “Exact” means the operation itself is not approximated; a different order of floating-point operations can produce small numerical differences.</p>
<h2 id="averaging-block-results-is-not-enough">Averaging block results is not enough</h2>
<p><a href="https://paweldubiel.com/en/glossary/softmax">Softmax</a> normalizes weights across all allowed keys. Blocks can have very different sums of unnormalized weights. Each therefore needs the appropriate contribution to the result.</p>
<p>This can be done incrementally by maintaining the maximum score <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">m</span></span></span></span>, the sum <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>l</mi><mo>=</mo><msub><mo>∑</mo><mi>j</mi></msub><msup><mi>e</mi><mrow><msub><mi>s</mi><mi>j</mi></msub><mo>−</mo><mi>m</mi></mrow></msup></mrow><annotation encoding="application/x-tex">l=\sum_j e^{s_j-m}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.0197em;">l</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1.2071em;vertical-align:-0.4358em;"></span><span class="mop"><span class="mop op-symbol small-op" style="position:relative;top:0em;">∑</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.162em;"><span style="top:-2.4003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0572em;">j</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.4358em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7713em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">s</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3281em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.0714em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0572em;">j</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2819em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mathnormal mtight">m</span></span></span></span></span></span></span></span></span></span></span></span>, and the numerator <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>u</mi><mo>=</mo><msub><mo>∑</mo><mi>j</mi></msub><msup><mi>e</mi><mrow><msub><mi>s</mi><mi>j</mi></msub><mo>−</mo><mi>m</mi></mrow></msup><msub><mi>v</mi><mi>j</mi></msub></mrow><annotation encoding="application/x-tex">u=\sum_j e^{s_j-m}v_j</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">u</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1.2071em;vertical-align:-0.4358em;"></span><span class="mop"><span class="mop op-symbol small-op" style="position:relative;top:0em;">∑</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.162em;"><span style="top:-2.4003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0572em;">j</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.4358em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7713em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">s</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3281em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.0714em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0572em;">j</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2819em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mathnormal mtight">m</span></span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0359em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0572em;">j</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2861em;"><span></span></span></span></span></span></span></span></span></span>. The result is <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>u</mi><mi mathvariant="normal">/</mi><mi>l</mi></mrow><annotation encoding="application/x-tex">u/l</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">u</span><span class="mord">/</span><span class="mord mathnormal" style="margin-right:0.0197em;">l</span></span></span></span>. When a new block raises the maximum to <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>m</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup></mrow><annotation encoding="application/x-tex">m'</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7519em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7519em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span></span></span></span>, the previous <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>l</mi></mrow><annotation encoding="application/x-tex">l</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.0197em;">l</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>u</mi></mrow><annotation encoding="application/x-tex">u</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">u</span></span></span></span> must be rescaled by <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>e</mi><mrow><mi>m</mi><mo>−</mo><msup><mi>m</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup></mrow></msup></mrow><annotation encoding="application/x-tex">e^{m-m'}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.9425em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9425em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span><span class="mbin mtight">−</span><span class="mord mtight"><span class="mord mathnormal mtight">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8278em;"><span style="top:-2.931em;margin-right:0.0714em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span> before adding new terms. The stable normalization mechanism is explained by <a href="https://arxiv.org/html/1805.02867v2#S3" rel="noopener noreferrer">Milakov and Gimelshein, §3, Algorithm 3</a>.</p>
<p>An original example uses given scores <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">[</mo><mn>0</mn><mo separator="true">,</mo><mn>0</mn><mo separator="true">,</mo><mi>ln</mi><mo>⁡</mo><mn>3</mn><mo separator="true">,</mo><mi>ln</mi><mo>⁡</mo><mn>3</mn><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">[0,0,\ln 3,\ln 3]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mop">ln</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">3</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mop">ln</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">3</span><span class="mclose">]</span></span></span></span> and values <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">[</mo><mn>0</mn><mo separator="true">,</mo><mn>0</mn><mo separator="true">,</mo><mn>1</mn><mo separator="true">,</mo><mn>1</mn><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">[0,0,1,1]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">1</span><span class="mclose">]</span></span></span></span>. Before normalization, the weights have proportions <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">[</mo><mn>1</mn><mo separator="true">,</mo><mn>1</mn><mo separator="true">,</mo><mn>3</mn><mo separator="true">,</mo><mn>3</mn><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">[1,1,3,3]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">3</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">3</span><span class="mclose">]</span></span></span></span>, so the result is <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>6</mn><mi mathvariant="normal">/</mi><mn>8</mn><mo>=</mo><mn>0,75</mn></mrow><annotation encoding="application/x-tex">6/8=0{,}75</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">6/8</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8389em;vertical-align:-0.1944em;"></span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">75</span></span></span></span>. The two block results are 0 and 1. Their ordinary mean gives the incorrect 0.5.</p>
<div id="flashattention-blocks-lab"></div>
<p>The demonstration isolates aggregation for one query and scalar values. A full kernel calculates score blocks from Q and K on the GPU; here, given numbers let you verify the calculation by hand. Switching block size is not a benchmark.</p>
<p><a href="https://paweldubiel.com/en/glossary/grouped-query-attention">Grouped-Query Attention</a> limits the number of K/V heads, while FlashAttention changes how data is transferred and processed. These techniques can be combined. FlashAttention 2 is a later implementation development; the mechanism described here comes from the first paper.</p>
<p>I use AI-generated content as part of my daily learning process.</p>]]></content:encoded>
</item>
<item>
  <title>Prefill</title>
  <link>https://paweldubiel.com/en/glossary/prefill</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/prefill</guid>
  <pubDate>Fri, 18 Sep 2026 07:31:25 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>llm</category>
  <category>glossary</category>
  <description>You send a long question to a chat and wait for the first word. Before the model appends a response, it must process the content it has already received.</description>
  <content:encoded><![CDATA[<p>You send a long question to a chat and wait for the first word. Before the model appends a response, it must process the content it has already received. This initial stage can require considerable work, especially for a long document.</p>
<p><strong>Prefill</strong> processes the known input, called the prompt, before further generation. The model creates numerical descriptions of <a href="https://paweldubiel.com/en/glossary/token">tokens</a> — pieces of text — and can retain some results in <a href="https://paweldubiel.com/en/glossary/kv-cache">KV Cache</a> for reuse.</p>
<p>Because the entire input already exists, many positions can be computed in parallel within a layer. Context access rules still apply: parallel work does not let an earlier position look at a prohibited future.</p>
<p>The final position's result allows the probabilities of the first new token to be computed. Choosing it is a separate step. Prefill does not cover all the time since sending the question: network time, queuing, and other stages also contribute. <a href="https://paweldubiel.com/en/glossary/decode">Decode</a> describes further extension of the response.</p>
<p>Mechanism source: <a href="https://developer.nvidia.com/blog/mastering-llm-techniques-inference-optimization/" rel="noopener noreferrer">NVIDIA, <em>Mastering LLM Techniques: Inference Optimization</em>, section “Understanding LLM inference”</a>.</p>
<h2 id="mechanism-and-details">Mechanism and details</h2>
<p><img src="https://paweldubiel.com/assets/prefill-hero.webp" alt="Several prepared paper strips pass together under a wide comb, with the last reaching an empty space for a new element." loading="eager" decoding="async" width="1600" height="900"></p>
<h2 id="a-known-prompt-can-be-processed-in-parallel">A known prompt can be processed in parallel</h2>
<p>All input tokens are already available, so many positions can be calculated simultaneously within a layer. <a href="https://paweldubiel.com/en/glossary/causal-masking">Causal Masking</a> still applies: the second position does not use the third. Parallel computation does not remove this dependency or the order of traversal through layers. The foundation is described by <a href="https://arxiv.org/html/1706.03762v7#S3" rel="noopener noreferrer">Vaswani et al., §3.1–3.2</a>.</p>
<p>Prefill can also <a href="https://paweldubiel.com/glossary/chunked-prefill" hreflang="pl">process the prompt in chunks [Polski]</a>, retaining the cache of earlier positions. <a href="https://docs.vllm.ai/en/v0.21.0/configuration/optimization/#chunked-prefill" rel="noopener noreferrer">vLLM documentation, “Chunked Prefill”</a> describes using this division to interleave prompt processing with response generation for other requests.</p>
<h2 id="four-positions-the-same-result">Four positions, the same result</h2>
<p>An original example isolates one attention head with dimension 1: all queries and keys are 1, and the values are <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">[</mo><mn>2</mn><mo separator="true">,</mo><mn>4</mn><mo separator="true">,</mo><mn>8</mn><mo separator="true">,</mo><mn>10</mn><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">[2,4,8,10]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">2</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">4</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">8</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">10</span><span class="mclose">]</span></span></span></span>. Allowed comparison scores are equal, so each position returns the mean of its visible values: <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">[</mo><mn>2</mn><mo separator="true">,</mo><mn>3</mn><mo separator="true">,</mo><mn>14</mn><mi mathvariant="normal">/</mi><mn>3</mn><mo separator="true">,</mo><mn>6</mn><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">[2,3,14/3,6]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">2</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">3</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">14/3</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">6</span><span class="mclose">]</span></span></span></span>. Compare processing all four together with chunks of two. In the second variant, the third position must still see the first two.</p>
<div id="prefill-chunks-lab"></div>
<p>This calculates a single operation, without trained model weights or GPU measurements. In a full model, the cache is maintained separately for each layer. Changing the chunking may introduce small numerical differences in the implementation; it does not change the mathematical mask.</p>
<p>After the prompt comes <a href="https://paweldubiel.com/en/glossary/decode">Decode</a>, where successive inputs depend on newly selected tokens. Prefill time alone does not cover the user's entire wait: the queue, input preparation, and delivery of the result also matter. See also: <a href="https://paweldubiel.com/en/glossary/time-to-first-token">Time to First Token</a> covers the client's wait for the first token, and <a href="https://paweldubiel.com/en/glossary/continuous-batching">Continuous Batching</a> allows the group being served to change between iterations.</p>
<p>I use AI-generated content as part of my daily learning process.</p>]]></content:encoded>
</item>
<item>
  <title>Speculative Decoding</title>
  <link>https://paweldubiel.com/en/glossary/speculative-decoding</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/speculative-decoding</guid>
  <pubDate>Fri, 18 Sep 2026 07:31:25 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>llm</category>
  <category>glossary</category>
  <description>A large model generates text correctly but slowly. A smaller model can quickly propose several following pieces. You want to use its work while keeping the large model in control of the final result.</description>
  <content:encoded><![CDATA[<p>A large model generates text correctly but slowly. A smaller model can quickly propose several following pieces. You want to use its work while keeping the large model in control of the final result.</p>
<p><strong>Speculative Decoding</strong> produces a cheaper proposed continuation and then verifies it with the target model. In the classic algorithm, we accept the initial sequence of accepted <a href="https://paweldubiel.com/en/glossary/token">tokens</a> — pieces of text — until the first rejection, then compute a correction.</p>
<p>The large model can assess a known proposal at several positions in parallel. A correct sampling variant uses specific acceptance and correction probabilities to preserve the target distribution. Merely testing “does this sound sensible?” does not ensure that.</p>
<p>The speedup depends on the proposal's cost, the number of acceptances, and the hardware. If the small model often disagrees with the large one, extra work can cancel the gain. The demonstration below shows preservation of probabilities, rather than a guaranteed execution time.</p>
<p>Mechanism source: <a href="https://arxiv.org/html/2211.17192v2#S2" rel="noopener noreferrer">Leviathan et al., §2, Algorithm 1</a>.</p>
<h2 id="mechanism-and-details">Mechanism and details</h2>
<p>This accelerates <a href="https://paweldubiel.com/en/glossary/decode">Decode</a> while preserving the target model's distribution under the algorithm's conditions. Checking whether a proposal “looks good” is not enough.</p>
<h2 id="why-a-correction-is-needed">Why a correction is needed</h2>
<p>Let <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi></mrow><annotation encoding="application/x-tex">p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span></span></span></span> be the target distribution and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>q</mi></mrow><annotation encoding="application/x-tex">q</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.0359em;">q</span></span></span></span> the draft distribution for the same prefix and a shared token set. Both include the chosen sampling rules, such as <a href="https://paweldubiel.com/en/glossary/temperature">Temperature</a> and <a href="https://paweldubiel.com/en/glossary/top-p-sampling">Top-p Sampling</a>. We accept a proposal <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi><mo>∼</mo><mi>q</mi></mrow><annotation encoding="application/x-tex">x\sim q</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">∼</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.0359em;">q</span></span></span></span> with probability:</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>min</mi><mo>⁡</mo><mrow><mo fence="true">(</mo><mn>1</mn><mo separator="true">,</mo><mfrac><mrow><mi>p</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo></mrow><mrow><mi>q</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo></mrow></mfrac><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">\min\left(1,\frac{p(x)}{q(x)}\right)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.4em;vertical-align:-0.95em;"></span><span class="mop">min</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.427em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0359em;">q</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">p</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.936em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span></span></span></span></span>
<p>A sampled proposal has <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>q</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>></mo><mn>0</mn></mrow><annotation encoding="application/x-tex">q(x)>0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.0359em;">q</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">0</span></span></span></span>. After rejection, we sample from the distribution proportional to <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>max</mi><mo>⁡</mo><mo stretchy="false">(</mo><mn>0</mn><mo separator="true">,</mo><mi>p</mi><mo>−</mo><mi>q</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\max(0,p-q)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mop">max</span><span class="mopen">(</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">p</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.0359em;">q</span><span class="mclose">)</span></span></span></span>. This step fills exactly the missing probability mass. If <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi><mo>=</mo><mi>q</mi></mrow><annotation encoding="application/x-tex">p=q</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.0359em;">q</span></span></span></span>, nothing is rejected, and no correction is needed. <a href="https://arxiv.org/html/2211.17192v2#A1.SS1" rel="noopener noreferrer">Leviathan et al., §2.3 and proof A.1</a>.</p>
<p>An original example: for tokens A, B, C, let <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi><mo>=</mo><mo stretchy="false">[</mo><mn>0,2</mn><mo separator="true">;</mo><mn>0,5</mn><mo separator="true">;</mo><mn>0,3</mn><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">p=[0{,}2;0{,}5;0{,}3]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">2</span><span class="mpunct">;</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">5</span><span class="mpunct">;</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">3</span><span class="mclose">]</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>q</mi><mo>=</mo><mo stretchy="false">[</mo><mn>0,6</mn><mo separator="true">;</mo><mn>0,3</mn><mo separator="true">;</mo><mn>0,1</mn><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">q=[0{,}6;0{,}3;0{,}1]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.0359em;">q</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">6</span><span class="mpunct">;</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">3</span><span class="mpunct">;</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">1</span><span class="mclose">]</span></span></span></span>. The unconditional mass of accepted proposals is <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">[</mo><mn>0,2</mn><mo separator="true">;</mo><mn>0,3</mn><mo separator="true">;</mo><mn>0,1</mn><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">[0{,}2;0{,}3;0{,}1]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">2</span><span class="mpunct">;</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">3</span><span class="mpunct">;</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">1</span><span class="mclose">]</span></span></span></span>. The remaining 0.4 must be split equally between B and C. Sampling the correction from ordinary <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi></mrow><annotation encoding="application/x-tex">p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span></span></span></span> would instead yield <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">[</mo><mn>0,28</mn><mo separator="true">;</mo><mn>0,50</mn><mo separator="true">;</mo><mn>0,22</mn><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">[0{,}28;0{,}50;0{,}22]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">28</span><span class="mpunct">;</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">50</span><span class="mpunct">;</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">22</span><span class="mclose">]</span></span></span></span>.</p>
<div id="speculative-mass-lab"></div>
<p>The experiment shows the exact mass balance for one position, without simulating the whole loop or execution time. Preserving the distribution does not guarantee identical text for the same seed: the algorithms consume randomness differently, and computations have limited precision. This is discussed by <a href="https://arxiv.org/html/2302.01318v1#S6.SS1" rel="noopener noreferrer">Chen et al., §4.2 and §6.1</a>.</p>
<p>Speedup depends on the acceptance rate, draft cost, and hardware. An overly expensive draft or many rejections can erase the savings even when distributional correctness is preserved.</p>
<p>I use AI-generated content as part of my daily learning process.</p>]]></content:encoded>
</item>
<item>
  <title>Beam Search</title>
  <link>https://paweldubiel.com/en/glossary/beam-search</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/beam-search</guid>
  <pubDate>Fri, 18 Sep 2026 06:30:24 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>llm</category>
  <category>glossary</category>
  <description>When choosing the first piece of a response, you may reject too early a path that would later turn out better. Checking all possible sequences is too expensive, however.</description>
  <content:encoded><![CDATA[<p>When choosing the first piece of a response, you may reject too early a path that would later turn out better. Checking all possible sequences is too expensive, however. You need a limited pool of alternatives.</p>
<p><strong>Beam Search</strong> retains several partial responses with the highest scores. At each step it extends them, compares the new sequences, and again keeps only a specified number. The size of this pool is called the beam width.</p>
<p>With width two, the system can keep beginnings A and B instead of immediately choosing A. At the next step it compares their continuations. The basic score combines the probabilities of successive <a href="https://paweldubiel.com/en/glossary/token">tokens</a> — pieces of text — although implementations may adjust the effect of length.</p>
<p>A larger pool costs more memory and computation, and can still discard the best path. A high probability for the entire sequence also does not guarantee that the response is true, diverse, or useful.</p>
<h2 id="mechanism-and-details">Mechanism and details</h2>
<p>In <a href="https://paweldubiel.com/en/glossary/autoregressive-language-modeling">Autoregressive Language Modeling</a>, the basic sequence score is the sum of the log-probabilities of its tokens:</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>S</mi><mo stretchy="false">(</mo><msub><mi>x</mi><mrow><mn>1</mn><mo>:</mo><mi>t</mi></mrow></msub><mo stretchy="false">)</mo><mo>=</mo><munderover><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>t</mi></munderover><mi>ln</mi><mo>⁡</mo><mi>p</mi><mo stretchy="false">(</mo><msub><mi>x</mi><mi>i</mi></msub><mo>∣</mo><msub><mi>x</mi><mrow><mo>&#x3C;</mo><mi>i</mi></mrow></msub><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">S(x_{1:t})=\sum_{i=1}^{t}\ln p(x_i\mid x_{&#x3C;i})</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.0576em;">S</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mrel mtight">:</span><span class="mord mathnormal mtight">t</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:3.0582em;vertical-align:-1.2777em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.7806em;"><span style="top:-1.8723em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.05em;"><span class="pstrut" style="height:3.05em;"></span><span><span class="mop op-symbol large-op">∑</span></span></span><span style="top:-4.3em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">t</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.2777em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mop">ln</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">p</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">∣</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mrel mtight">&#x3C;</span><span class="mord mathnormal mtight">i</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.1774em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span></span>
<p>This is the logarithm of the probability product. A higher score is better; summation avoids multiplying very small numbers. The <a href="https://huggingface.co/docs/transformers/generation_strategies#beam-search" rel="noopener noreferrer">Hugging Face documentation, “Beam search”</a> describes maintaining multiple sequences. Width 1 reduces this basic variant to <a href="https://paweldubiel.com/en/glossary/greedy-decoding">Greedy Decoding</a>.</p>
<h2 id="which-prefix-will-you-discard-too-early">Which prefix will you discard too early?</h2>
<p>An original example starts with probabilities A = 0.45, B = 0.35, and C = 0.20. A beam of width 2 discards C. The best continuation of A later has probability 0.4, so the AA result is 0.18. Meanwhile, the omitted CA would achieve <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>0,20</mn><mo>⋅</mo><mn>0,99</mn><mo>=</mo><mn>0,198</mn></mrow><annotation encoding="application/x-tex">0{,}20\cdot0{,}99=0{,}198</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8389em;vertical-align:-0.1944em;"></span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">20</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8389em;vertical-align:-0.1944em;"></span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">99</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8389em;vertical-align:-0.1944em;"></span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">198</span></span></span></span>. Width 3 retains C and finds a better result. This is a complete, small tree of two tokens, without early termination or length normalization.</p>
<div id="beam-pruning-lab"></div>
<p>Beam Search remains an approximation: it does not expand a discarded prefix again. Width does not mean the number of tokens sampled from one distribution, as in <a href="https://paweldubiel.com/en/glossary/top-k-sampling">Top-k Sampling</a>.</p>
<p>For sequences of different lengths, the end token, stopping condition, and scoring function matter. For example, <code>length_penalty</code> in <a href="https://huggingface.co/docs/transformers/main_classes/text_generation#transformers.GenerationConfig" rel="noopener noreferrer">GenerationConfig</a> divides the logarithmic score by the length raised to a specified power. This criterion should not be confused with pure probability. A wider beam does not guarantee better content either; the problem is discussed by <a href="https://arxiv.org/html/1904.09751v2#S3" rel="noopener noreferrer">Holtzman et al., §2.2–3</a>.</p>
<p>I use AI-generated content as part of my daily learning process.</p>]]></content:encoded>
</item>
<item>
  <title>Greedy Decoding</title>
  <link>https://paweldubiel.com/en/glossary/greedy-decoding</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/greedy-decoding</guid>
  <pubDate>Fri, 18 Sep 2026 06:30:24 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>llm</category>
  <category>glossary</category>
  <description>The model could append several different pieces. The simplest choice is always to take the most likely one.</description>
  <content:encoded><![CDATA[<p>The model could append several different pieces. The simplest choice is always to take the most likely one. This saves consideration of alternatives, but does the best first step lead to the best entire sequence?</p>
<p><strong>Greedy Decoding</strong> chooses the highest-scoring <a href="https://paweldubiel.com/en/glossary/token">token</a>, a piece of text, at every step and continues from that choice. It does not sample or return to skipped paths.</p>
<p>If A has probability <code>0.6</code> and B <code>0.4</code>, it chooses A. But if the best next step after A has probability <code>0.51</code>, the whole path has probability <code>0.306</code>. A path through B with continuation <code>0.99</code> has probability <code>0.396</code>. The local leader can therefore lose when evaluating two steps together.</p>
<p>The method is simple, but does not guarantee the most probable whole sequence or the best answer for a person. <a href="https://paweldubiel.com/en/glossary/beam-search">Beam Search</a> keeps more paths at an additional cost.</p>
<h2 id="mechanism-and-details">Mechanism and details</h2>
<p>The rule is presented in the <a href="https://huggingface.co/docs/transformers/generation_strategies#greedy-search" rel="noopener noreferrer">Hugging Face documentation, “Greedy search”</a>. Mathematically, we select <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>arg</mi><mo>⁡</mo><msub><mrow><mi>max</mi><mo>⁡</mo></mrow><mi>v</mi></msub><mi>p</mi><mo stretchy="false">(</mo><mi>v</mi><mo>∣</mo><msub><mi>x</mi><mrow><mo>&#x3C;</mo><mi>t</mi></mrow></msub><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\arg\max_v p(v\mid x_{&#x3C;t})</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mop">ar<span style="margin-right:0.0139em;">g</span></span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mop"><span class="mop">max</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1514em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0359em;">v</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">p</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.0359em;">v</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">∣</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.2806em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mrel mtight">&#x3C;</span><span class="mord mathnormal mtight">t</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.1774em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span>: among tokens <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>v</mi></mrow><annotation encoding="application/x-tex">v</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal" style="margin-right:0.0359em;">v</span></span></span></span>, we take the maximum given the existing sequence <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>x</mi><mrow><mo>&#x3C;</mo><mi>t</mi></mrow></msub></mrow><annotation encoding="application/x-tex">x_{&#x3C;t}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6079em;vertical-align:-0.1774em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.2806em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mrel mtight">&#x3C;</span><span class="mord mathnormal mtight">t</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.1774em;"><span></span></span></span></span></span></span></span></span></span>. A tie requires an established tie-breaking rule. The absence of sampling does not promise an identical result when the model, computation, or configuration changes.</p>
<h2 id="a-local-winner-can-lose-the-whole-sequence">A local winner can lose the whole sequence</h2>
<p>This original example has exactly two steps. Initially, A has probability 0.6, and B has 0.4. After A, the best continuation has probability 0.51; after B, it has 0.99. Greedy selects A, then its best continuation: <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>0,6</mn><mo>⋅</mo><mn>0,51</mn><mo>=</mo><mn>0,306</mn></mrow><annotation encoding="application/x-tex">0{,}6\cdot0{,}51=0{,}306</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8389em;vertical-align:-0.1944em;"></span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">6</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8389em;vertical-align:-0.1944em;"></span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">51</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8389em;vertical-align:-0.1944em;"></span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">306</span></span></span></span>. However, the skipped path through B has <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>0,4</mn><mo>⋅</mo><mn>0,99</mn><mo>=</mo><mn>0,396</mn></mrow><annotation encoding="application/x-tex">0{,}4\cdot0{,}99=0{,}396</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8389em;vertical-align:-0.1944em;"></span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">4</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8389em;vertical-align:-0.1944em;"></span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">99</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8389em;vertical-align:-0.1944em;"></span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">396</span></span></span></span>. All distributions shown are invented and sum to 1; the sequence ends after two tokens.</p>
<div id="greedy-choice-lab"></div>
<p><a href="https://paweldubiel.com/en/glossary/beam-search">Beam Search</a> retains several partial sequences to defer such a choice. <a href="https://paweldubiel.com/en/glossary/top-k-sampling">Top-k Sampling</a>, by contrast, restricts the candidates for sampling the next token. With one unique maximum and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">k=1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.0315em;">k</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span>, token selection matches greedy.</p>
<p>The most probable text need not be true or useful. <a href="https://arxiv.org/html/1904.09751v2#S3" rel="noopener noreferrer">Holtzman et al., §2.2–3</a> distinguish probability maximization from the quality of open-ended continuations. This is separate from the search error shown above.</p>
<p>I use AI-generated content as part of my daily learning process.</p>]]></content:encoded>
</item>
<item>
  <title>Grouped-Query Attention</title>
  <link>https://paweldubiel.com/en/glossary/grouped-query-attention</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/grouped-query-attention</guid>
  <pubDate>Fri, 18 Sep 2026 06:30:24 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>llm</category>
  <category>glossary</category>
  <description>The model reads earlier text in several ways in parallel. Each such computation is an attention head.</description>
  <content:encoded><![CDATA[<p>The model reads earlier text in several ways in parallel. Each such computation is an attention head. You want to reduce the memory these heads occupy, but sharing a single data set completely may constrain the model too much. An intermediate variant is possible: some heads use one shared set, and others use another.</p>
<p><strong>Grouped-Query Attention (GQA)</strong> divides query heads into groups sharing key and value. A query is a numerical description used to read context, a key is used for matching, and a value conveys information. Each head still computes its own weights.</p>
<p>Eight query heads divided into two groups of four mean two key/value sets, rather than eight. One group gives <a href="https://paweldubiel.com/en/glossary/multi-query-attention">MQA</a>; one group per head corresponds to ordinary <a href="https://paweldubiel.com/en/glossary/multi-head-attention">MHA</a>.</p>
<p>Fewer sets reduce the cost of storing KV when dimensions match. This is a tradeoff in design and quality, rather than a switch guaranteeing a particular speed. Time also depends on hardware and the remaining computations.</p>
<h2 id="mechanism-and-details">Mechanism and details</h2>
<p>For <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>H</mi></mrow><annotation encoding="application/x-tex">H</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.0813em;">H</span></span></span></span> query heads and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>G</mi></mrow><annotation encoding="application/x-tex">G</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal">G</span></span></span></span> groups, we get <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>G</mi></mrow><annotation encoding="application/x-tex">G</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal">G</span></span></span></span> K/V sets. When <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>G</mi><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">G=1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal">G</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span>, this is <a href="https://paweldubiel.com/en/glossary/multi-query-attention">Multi-Query Attention</a>. When <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>G</mi><mo>=</mo><mi>H</mi></mrow><annotation encoding="application/x-tex">G=H</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal">G</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.0813em;">H</span></span></span></span>, we return to <a href="https://paweldubiel.com/en/glossary/multi-head-attention">Multi-Head Attention</a>. This family and the GQA-g notation are described by <a href="https://arxiv.org/html/2305.13245v3#S2.SS2" rel="noopener noreferrer">Ainslie et al., <em>GQA</em>, §2.2</a>.</p>
<h2 id="calculate-memory-before-guessing-speed">Calculate memory before guessing speed</h2>
<p>An original calculation for <a href="https://paweldubiel.com/en/glossary/kv-cache">KV Cache</a> assumes batch size 1, 32 layers, 1024 stored <a href="https://paweldubiel.com/en/glossary/token">tokens</a>, a dimension of 128 for each key/value head, and 2 bytes per number. The K/V elements alone occupy:</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mn>2</mn><mo>⋅</mo><mn>32</mn><mo>⋅</mo><mn>1024</mn><mo>⋅</mo><mi>G</mi><mo>⋅</mo><mn>128</mn><mo>⋅</mo><mn>2</mn><mtext> bytes</mtext></mrow><annotation encoding="application/x-tex">2\cdot32\cdot1024\cdot G\cdot128\cdot2\ \text{bytes}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">32</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1024</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal">G</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">128</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord">2</span><span class="mspace"> </span><span class="mord text"><span class="mord">bytes</span></span></span></span></span></span>
<p>The first factor of two denotes K and V. For eight query heads, the result is 128 MiB in MHA, 32 MiB for two KV heads, and 16 MiB in MQA. A MiB is <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mn>2</mn><mn>20</mn></msup></mrow><annotation encoding="application/x-tex">2^{20}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">20</span></span></span></span></span></span></span></span></span></span></span></span> bytes. We do not count model weights, buffers, memory alignment, or replication between devices.</p>
<div id="gqa-groups-lab"></div>
<p>Reducing the number of KV heads here does not shorten the context or remove query heads. It limits the number of separate K/V representations. The memory calculation does not predict quality or execution time; these also depend on training, hardware, and implementation.</p>
<p>When converting a checkpoint, the authors averaged K/V projections within groups and then continued <a href="https://paweldubiel.com/en/glossary/pre-training">Pre-training</a> (§2.1–2.2). The results in §3 apply to specific T5 variants and tasks. They establish neither a universal number of groups nor a guarantee of preserving quality by simply switching the configuration.</p>
<p>I use AI-generated content as part of my daily learning process.</p>]]></content:encoded>
</item>
<item>
  <title>Multi-Query Attention</title>
  <link>https://paweldubiel.com/en/glossary/multi-query-attention</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/multi-query-attention</guid>
  <pubDate>Fri, 18 Sep 2026 06:30:24 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>llm</category>
  <category>glossary</category>
  <description>The model connects the current piece of text to the earlier conversation through several parallel computations. These computations are called attention heads.</description>
  <content:encoded><![CDATA[<p>The model connects the current piece of text to the earlier conversation through several parallel computations. These computations are called attention heads. If each head stores its own descriptions of the entire preceding conversation, memory and reading costs grow. Can some data be shared while preserving different ways to read them?</p>
<p><strong>Multi-Query Attention (MQA)</strong> keeps multiple queries — descriptions of what the current positions need — but gives them a shared key and value set. Keys support matching, while values contain information to convey. All are lists of numbers.</p>
<p>Two heads can use the same key/value set yet assign different weights because they have different queries. Shared data do not force identical results.</p>
<p>The savings concern, among other things, <a href="https://paweldubiel.com/en/glossary/kv-cache">KV Cache</a>, the stored descriptions of earlier text. The change can affect quality, however, and does not imply a proportional speedup of the whole model. <a href="https://paweldubiel.com/en/glossary/grouped-query-attention">Grouped-Query Attention</a> shares data within smaller groups.</p>
<h2 id="mechanism-and-details">Mechanism and details</h2>
<p>In ordinary <a href="https://paweldubiel.com/en/glossary/multi-head-attention">Multi-Head Attention</a>, each head has its own query, key, and value projections. MQA removes the head dimension from K/V and their projections while retaining it in queries. This variant is defined by <a href="https://arxiv.org/html/1911.02150v1#S3" rel="noopener noreferrer">Noam Shazeer, <em>Fast Transformer Decoding: One Write-Head is All You Need</em>, §3</a>.</p>
<h2 id="the-same-memory-a-different-question">The same memory, a different question</h2>
<p>An original example has two keys: <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>k</mi><mn>1</mn></msub><mo>=</mo><mo stretchy="false">(</mo><mn>1</mn><mo separator="true">,</mo><mn>0</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">k_1=(1,0)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0315em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0315em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">0</span><span class="mclose">)</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>k</mi><mn>2</mn></msub><mo>=</mo><mo stretchy="false">(</mo><mn>0</mn><mo separator="true">,</mo><mn>1</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">k_2=(0,1)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0315em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0315em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">1</span><span class="mclose">)</span></span></span></span>. Two query heads receive <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>q</mi><mn>1</mn></msub><mo>=</mo><mo stretchy="false">(</mo><mn>2</mn><mo separator="true">,</mo><mn>0</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">q_1=(2,0)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0359em;">q</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">2</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">0</span><span class="mclose">)</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>q</mi><mn>2</mn></msub><mo>=</mo><mo stretchy="false">(</mo><mn>0</mn><mo separator="true">,</mo><mn>2</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">q_2=(0,2)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0359em;">q</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">2</span><span class="mclose">)</span></span></span></span> respectively. <a href="https://paweldubiel.com/en/glossary/scaled-dot-product-attention">Scaled Dot-Product Attention</a> divides dot products by <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msqrt><mn>2</mn></msqrt></mrow><annotation encoding="application/x-tex">\sqrt{2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.1328em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9072em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord">2</span></span></span><span style="top:-2.8672em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width="400em" height="1.08em" viewBox="0 0 400000 1080" preserveAspectRatio="xMinYMin slice"><path d="M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z"></path></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.1328em;"><span></span></span></span></span></span></span></span></span> and applies <a href="https://paweldubiel.com/en/glossary/softmax">Softmax</a>. The first head gives the keys weights of about 0.804 and 0.196; the second reverses those proportions. With shared <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>v</mi><mn>1</mn></msub><mo>=</mo><mo stretchy="false">(</mo><mn>1</mn><mo separator="true">,</mo><mn>0</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">v_1=(1,0)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.5806em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0359em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">0</span><span class="mclose">)</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>v</mi><mn>2</mn></msub><mo>=</mo><mo stretchy="false">(</mo><mn>0</mn><mo separator="true">,</mo><mn>1</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">v_2=(0,1)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.5806em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0359em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">1</span><span class="mclose">)</span></span></span></span>, these are also the coordinates of two different results.</p>
<div id="mqa-shared-lab"></div>
<h2 id="where-the-savings-come-from">Where the savings come from</h2>
<p><a href="https://paweldubiel.com/en/glossary/kv-cache">KV Cache</a> stores earlier K/V. With eight query heads, MHA stores eight K/V sets, while MQA stores one. For the same sequence lengths, head dimensions, and precision, the cache tensors themselves are then eight times smaller. This is a size calculation, not an eightfold speedup of the whole model.</p>
<p>Shazeer's analysis in §2.4.1 and §3.1 links this change to memory transfer during successive generation steps. However, the architecture and its representational capacity change; this is not lossless removal of identical copies from an arbitrary trained MHA. <a href="https://paweldubiel.com/en/glossary/grouped-query-attention">Grouped-Query Attention</a> retains several K/V sets as an intermediate variant.</p>
<p>I use AI-generated content as part of my daily learning process.</p>]]></content:encoded>
</item>
<item>
  <title>Rotary Position Embedding</title>
  <link>https://paweldubiel.com/en/glossary/rotary-position-embedding</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/rotary-position-embedding</guid>
  <pubDate>Fri, 18 Sep 2026 06:30:24 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>llm</category>
  <category>glossary</category>
  <description>The model compares pieces of text, but also needs to know how far apart they are. “Yesterday” beside a verb can play a different role from the same word in a distant quotation.</description>
  <content:encoded><![CDATA[<p>The model compares pieces of text, but also needs to know how far apart they are. “Yesterday” beside a verb can play a different role from the same word in a distant quotation. How can position be included when comparing numerical descriptions?</p>
<p><strong>Rotary Position Embedding (RoPE)</strong> rotates pairs of numbers in queries and keys according to the position of a <a href="https://paweldubiel.com/en/glossary/token">token</a>, a piece of text. Queries and keys are vectors — lists of numbers compared in attention.</p>
<p>Imagine two arrows with specified lengths. Position determines their rotation angles. The comparison depends on the difference between angles, and therefore the difference between positions. A real model rotates many pairs at different frequencies.</p>
<p>This is an analogy for operations on numbers, rather than text moving in memory. RoPE does not prohibit access to the future or guarantee good performance beyond lengths seen in training. It differs from adding a positional signal in the original <a href="https://paweldubiel.com/en/glossary/positional-encoding">Positional Encoding</a>.</p>
<h2 id="mechanism-and-details">Mechanism and details</h2>
<p>Unlike vector addition in the original <a href="https://paweldubiel.com/en/glossary/positional-encoding">Positional Encoding</a>, this changes the orientation of query and key. For a two-dimensional pair <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>u</mi><mo>=</mo><mo stretchy="false">(</mo><mi>a</mi><mo separator="true">,</mo><mi>b</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">u=(a,b)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">u</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">a</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">b</span><span class="mclose">)</span></span></span></span>, rotation by angle <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>ϕ</mi></mrow><annotation encoding="application/x-tex">\phi</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">ϕ</span></span></span></span> gives:</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>R</mi><mo stretchy="false">(</mo><mi>ϕ</mi><mo stretchy="false">)</mo><mi>u</mi><mo>=</mo><mo stretchy="false">(</mo><mi>a</mi><mi>cos</mi><mo>⁡</mo><mi>ϕ</mi><mo>−</mo><mi>b</mi><mi>sin</mi><mo>⁡</mo><mi>ϕ</mi><mo separator="true">,</mo><mtext> </mtext><mi>a</mi><mi>sin</mi><mo>⁡</mo><mi>ϕ</mi><mo>+</mo><mi>b</mi><mi>cos</mi><mo>⁡</mo><mi>ϕ</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">R(\phi)u=(a\cos\phi-b\sin\phi,\ a\sin\phi+b\cos\phi)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.0077em;">R</span><span class="mopen">(</span><span class="mord mathnormal">ϕ</span><span class="mclose">)</span><span class="mord mathnormal">u</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mop">cos</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">ϕ</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mop">sin</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">ϕ</span><span class="mpunct">,</span><span class="mspace"> </span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mop">sin</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">ϕ</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mop">cos</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">ϕ</span><span class="mclose">)</span></span></span></span></span>
<p>Rotation preserves vector length. <a href="https://arxiv.org/html/2104.09864v5#S3.SS2" rel="noopener noreferrer">Su et al., <em>RoFormer</em>, §3.1–3.2</a> derive the construction and combine many such pairs with different frequencies.</p>
<h2 id="shift-both-tokens-and-check-the-result">Shift both tokens and check the result</h2>
<p>If the unrotated query and key stay fixed, then:</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mo stretchy="false">(</mo><mi>R</mi><mo stretchy="false">(</mo><mi>m</mi><mi>θ</mi><mo stretchy="false">)</mo><mi>q</mi><msup><mo stretchy="false">)</mo><mi mathvariant="normal">⊤</mi></msup><mi>R</mi><mo stretchy="false">(</mo><mi>n</mi><mi>θ</mi><mo stretchy="false">)</mo><mi>k</mi><mo>=</mo><msup><mi>q</mi><mi mathvariant="normal">⊤</mi></msup><mi>R</mi><mo stretchy="false">(</mo><mo stretchy="false">(</mo><mi>n</mi><mo>−</mo><mi>m</mi><mo stretchy="false">)</mo><mi>θ</mi><mo stretchy="false">)</mo><mi>k</mi></mrow><annotation encoding="application/x-tex">(R(m\theta)q)^\top R(n\theta)k=q^\top R((n-m)\theta)k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.1491em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.0077em;">R</span><span class="mopen">(</span><span class="mord mathnormal">m</span><span class="mord mathnormal" style="margin-right:0.0278em;">θ</span><span class="mclose">)</span><span class="mord mathnormal" style="margin-right:0.0359em;">q</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8991em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">⊤</span></span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.0077em;">R</span><span class="mopen">(</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.0278em;">θ</span><span class="mclose">)</span><span class="mord mathnormal" style="margin-right:0.0315em;">k</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1.1491em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0359em;">q</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8991em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">⊤</span></span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.0077em;">R</span><span class="mopen">((</span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">m</span><span class="mclose">)</span><span class="mord mathnormal" style="margin-right:0.0278em;">θ</span><span class="mclose">)</span><span class="mord mathnormal" style="margin-right:0.0315em;">k</span></span></span></span></span>
<p><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">m</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span> are positions, and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>θ</mi></mrow><annotation encoding="application/x-tex">\theta</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.0278em;">θ</span></span></span></span> is the angle per unit of distance for the given pair. The result depends on the difference in positions. Shifting both positions together rotates the arrows but preserves their dot product.</p>
<p>An original example uses <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>q</mi><mo>=</mo><mi>k</mi><mo>=</mo><mo stretchy="false">(</mo><mn>1</mn><mo separator="true">,</mo><mn>0</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">q=k=(1,0)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.0359em;">q</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.0315em;">k</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">0</span><span class="mclose">)</span></span></span></span> and an illustrative <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>θ</mi><mo>=</mo><msup><mn>30</mn><mo>∘</mo></msup></mrow><annotation encoding="application/x-tex">\theta=30^\circ</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.0278em;">θ</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6741em;"></span><span class="mord">3</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.6741em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mbin mtight">∘</span></span></span></span></span></span></span></span></span></span></span>. At distance 1, the dot product is about 0.866; at 6, it is −1; at 12, it is 1 again. This is one pair and a deliberately simple frequency, not a model's full recipe. The original paper uses <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>θ</mi><mi>i</mi></msub><mo>=</mo><msup><mn>10000</mn><mrow><mo>−</mo><mn>2</mn><mi>i</mi><mi mathvariant="normal">/</mi><mi>d</mi></mrow></msup></mrow><annotation encoding="application/x-tex">\theta_i=10000^{-2i/d}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0278em;">θ</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.0278em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.888em;"></span><span class="mord">1000</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.888em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">2</span><span class="mord mathnormal mtight">i</span><span class="mord mtight">/</span><span class="mord mathnormal mtight">d</span></span></span></span></span></span></span></span></span></span></span></span> radians for pair index <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi><mo>=</mo><mn>0</mn><mo separator="true">,</mo><mo>…</mo><mo separator="true">,</mo><mi>d</mi><mi mathvariant="normal">/</mi><mn>2</mn><mo>−</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">i=0,\ldots,d/2-1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6595em;"></span><span class="mord mathnormal">i</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="minner">…</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">d</span><span class="mord">/2</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span>.</p>
<div id="rope-rotation-lab"></div>
<p>The displayed result is a component of <a href="https://paweldubiel.com/en/glossary/scaled-dot-product-attention">Scaled Dot-Product Attention</a>, before scaling and <a href="https://paweldubiel.com/en/glossary/softmax">Softmax</a>. It is not a probability. In this variant, we rotate Q and K; V does not require this rotation. RoPE does not replace <a href="https://paweldubiel.com/en/glossary/causal-masking">Causal Masking</a>.</p>
<p>A single pair's return to the same orientation also shows why one must not assume every score decreases monotonically with distance. The relative-position property alone does not demonstrate that the entire model works correctly on arbitrarily long text.</p>
<p>I use AI-generated content as part of my daily learning process.</p>]]></content:encoded>
</item>
<item>
  <title>KL Divergence</title>
  <link>https://paweldubiel.com/en/glossary/kl-divergence</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/kl-divergence</guid>
  <pubDate>Wed, 16 Sep 2026 21:39:15 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>llm</category>
  <category>glossary</category>
  <description>Two models divide probabilities differently among the same answers. One assigns 90% to A and 10% to B; the other gives each 50%.</description>
  <content:encoded><![CDATA[<p>Two models divide probabilities differently among the same answers. One assigns <code>90%</code> to A and <code>10%</code> to B; the other gives each <code>50%</code>. You want to measure how well the second reproduces the first model's predictions.</p>
<p><strong>KL Divergence</strong> compares two probability distributions, sets of probabilities for the same events. You must specify the reference distribution and the one approximating it. Each event's contribution depends on its reference probability and the ratio of the two probabilities.</p>
<p>For these numbers, comparing the first to the second gives about <code>0.368</code>, and the reverse about <code>0.511</code>, using natural logarithms. Direction matters: this is not a symmetric distance like the number of kilometers between cities.</p>
<p>In <a href="https://paweldubiel.com/en/glossary/knowledge-distillation">Knowledge Distillation</a>, teacher and student predictions can be compared. A small KL indicates agreement, rather than the teacher's truthfulness. Assigning zero to an event with positive reference probability gives a mathematically infinite penalty.</p>
<h2 id="mechanism-and-details">Mechanism and details</h2>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>D</mi><mrow><mi mathvariant="normal">K</mi><mi mathvariant="normal">L</mi></mrow></msub><mo stretchy="false">(</mo><mi>q</mi><mi mathvariant="normal">∥</mi><mi>p</mi><mo stretchy="false">)</mo><mo>=</mo><munder><mo>∑</mo><mi>i</mi></munder><msub><mi>q</mi><mi>i</mi></msub><mi>ln</mi><mo>⁡</mo><mfrac><msub><mi>q</mi><mi>i</mi></msub><msub><mi>p</mi><mi>i</mi></msub></mfrac></mrow><annotation encoding="application/x-tex">D_{\mathrm{KL}}(q\|p)=\sum_i q_i\ln\frac{q_i}{p_i}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0278em;">D</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3283em;"><span style="top:-2.55em;margin-left:-0.0278em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathrm mtight">KL</span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.0359em;">q</span><span class="mord">∥</span><span class="mord mathnormal">p</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:2.3852em;vertical-align:-1.2777em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.05em;"><span style="top:-1.8723em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-3.05em;"><span class="pstrut" style="height:3.05em;"></span><span><span class="mop op-symbol large-op">∑</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.2777em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0359em;">q</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mop">ln</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.1076em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.0359em;">q</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8804em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span>
<p><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>q</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">q_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0359em;">q</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>p</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">p_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> are probabilities of the same event <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi></mrow><annotation encoding="application/x-tex">i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6595em;"></span><span class="mord mathnormal">i</span></span></span></span>, such as a particular <a href="https://paweldubiel.com/en/glossary/token">token</a>. The formula and its relationship with <a href="https://paweldubiel.com/en/glossary/cross-entropy">Cross-entropy</a> are given in the <a href="https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.entropy.html" rel="noopener noreferrer">SciPy: entropy documentation</a>. We have <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>D</mi><mrow><mi mathvariant="normal">K</mi><mi mathvariant="normal">L</mi></mrow></msub><mo stretchy="false">(</mo><mi>q</mi><mi mathvariant="normal">∥</mi><mi>p</mi><mo stretchy="false">)</mo><mo>=</mo><mi>H</mi><mo stretchy="false">(</mo><mi>q</mi><mo separator="true">,</mo><mi>p</mi><mo stretchy="false">)</mo><mo>−</mo><mi>H</mi><mo stretchy="false">(</mo><mi>q</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">D_{\mathrm{KL}}(q\|p)=H(q,p)-H(q)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0278em;">D</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3283em;"><span style="top:-2.55em;margin-left:-0.0278em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathrm mtight">KL</span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.0359em;">q</span><span class="mord">∥</span><span class="mord mathnormal">p</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.0813em;">H</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.0359em;">q</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">p</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.0813em;">H</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.0359em;">q</span><span class="mclose">)</span></span></span></span>: the entropy of the reference distribution is subtracted from Cross-entropy. When <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>q</mi></mrow><annotation encoding="application/x-tex">q</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.0359em;">q</span></span></span></span> is fixed, this difference does not change the minimum with respect to the parameters of the model producing <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi></mrow><annotation encoding="application/x-tex">p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span></span></span></span>.</p>
<h2 id="the-direction-of-comparison-matters">The direction of comparison matters</h2>
<p>An original example: for <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>q</mi><mo>=</mo><mo stretchy="false">[</mo><mn>0,9</mn><mo separator="true">;</mo><mn>0,1</mn><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">q=[0{,}9;0{,}1]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.0359em;">q</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">9</span><span class="mpunct">;</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">1</span><span class="mclose">]</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi><mo>=</mo><mo stretchy="false">[</mo><mn>0,5</mn><mo separator="true">;</mo><mn>0,5</mn><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">p=[0{,}5;0{,}5]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">5</span><span class="mpunct">;</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">5</span><span class="mclose">]</span></span></span></span>, the result is about 0.368. After swapping the distributions' roles, the result is about 0.511. We use the natural logarithm, so the unit is nats. KL Divergence is not a symmetric distance: the distribution on each side must always be specified.</p>
<p>If <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>q</mi><mi>i</mi></msub><mo>></mo><mn>0</mn></mrow><annotation encoding="application/x-tex">q_i>0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7335em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0359em;">q</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">0</span></span></span></span> but <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>p</mi><mi>i</mi></msub><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">p_i=0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">0</span></span></span></span>, the result is infinite. A term with <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>q</mi><mi>i</mi></msub><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">q_i=0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0359em;">q</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">0</span></span></span></span> is taken to be zero. These edge cases are defined by <a href="https://docs.scipy.org/doc/scipy/reference/generated/scipy.special.rel_entr.html" rel="noopener noreferrer">SciPy: rel_entr</a>.</p>
<p>In <a href="https://paweldubiel.com/en/glossary/knowledge-distillation">Knowledge Distillation</a>, the teacher's prediction can serve as the reference distribution and the student's as the approximation. A small value indicates agreement between these distributions on the evaluated data, not the truth of the teacher's response.</p>
<p>When implementing this, care is needed with argument order. <a href="https://docs.pytorch.org/docs/2.11/generated/torch.nn.KLDivLoss.html#torch.nn.KLDivLoss" rel="noopener noreferrer">PyTorch: KLDivLoss</a> expects model log-probabilities as <code>input</code> and the reference distribution as <code>target</code> when <code>log_target=False</code>. For an “examples × classes” matrix, <code>batchmean</code> reduction sums terms over classes and averages over examples; <code>mean</code> averages all elements, producing a different scale.</p>
<div id="kl-divergence-lab"></div>]]></content:encoded>
</item>
<item>
  <title>Knowledge Distillation</title>
  <link>https://paweldubiel.com/en/glossary/knowledge-distillation</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/knowledge-distillation</guid>
  <pubDate>Wed, 16 Sep 2026 21:39:15 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>llm</category>
  <category>glossary</category>
  <description>A large model performs a task well but is too expensive for everyday use. A smaller model could try to reproduce its behavior.</description>
  <content:encoded><![CDATA[<p>A large model performs a task well but is too expensive for everyday use. A smaller model could try to reproduce its behavior. It needs examples or assessments showing more than just a list of correct labels, however.</p>
<p><strong>Knowledge Distillation</strong> trains a student model using a teacher model's outputs or predictions. The student actually changes its parameters; simply sending a query to the teacher is not training.</p>
<p>If the teacher assigns A probability <code>0.60</code>, B <code>0.35</code>, and C <code>0.05</code>, the label “A” omits the fact that B is a close alternative. The student can learn to reproduce the entire distribution. Another variant uses complete texts generated by the teacher.</p>
<p>The teacher need not be a single larger model, but classically serves as a source of behavior to imitate. Distillation can also transfer errors. <a href="https://paweldubiel.com/en/glossary/kl-divergence">KL Divergence</a> helps measure agreement between predictions, while <a href="https://paweldubiel.com/en/glossary/on-policy-self-distillation">On-policy self-distillation</a> is a more specific arrangement of data and teacher.</p>
<h2 id="mechanism-and-details">Mechanism and details</h2>
<p>In <a href="https://arxiv.org/pdf/1503.02531#page=2" rel="noopener noreferrer"><em>Distilling the Knowledge in a Neural Network</em>, §2</a>, Hinton, Vinyals and Dean describe learning from soft probability distributions. Increased <a href="https://paweldubiel.com/en/glossary/temperature">Temperature</a> reveals more information about relationships between candidates. The same parameter is used on the teacher and student sides when comparing distributions. The authors combine this objective with learning from correct labels when available.</p>
<h2 id="more-information-than-a-single-answer">More information than a single answer</h2>
<p>An original example: the teacher assigns illustrative <a href="https://paweldubiel.com/en/glossary/token">tokens</a> A, B, and C probabilities of 0.60, 0.35, and 0.05. The label “A” identifies only the winner. The full distribution also says that B was much more likely than C. The student can try to reproduce these proportions using <a href="https://paweldubiel.com/en/glossary/cross-entropy">Cross-entropy</a> or appropriately directed <a href="https://paweldubiel.com/en/glossary/kl-divergence">KL Divergence</a>. This is an additional training signal, not evidence that the teacher's labels are correct.</p>
<p>In text-generating models, comparing next-token distributions must be distinguished from training on entire generated sequences. <a href="https://aclanthology.org/D16-1139.pdf#page=3" rel="noopener noreferrer">Kim and Rush, <em>Sequence-Level Knowledge Distillation</em>, §2.2–3.2</a> describe both approaches for machine translation. In the sequence-level variant, the student trains on outputs found by the teacher's <a href="https://paweldubiel.com/en/glossary/beam-search">beam search</a>. The text of such a response does not contain the full probabilities of all alternative tokens.</p>
<p>The result depends on the teacher, the data, and the student's capacity. It does not mean copying every capability or guaranteeing an improvement in every task. The separate note <a href="https://paweldubiel.com/en/glossary/on-policy-self-distillation">On-policy self-distillation</a> describes a particular variant in TTPO; its conditions are not a general definition of Knowledge Distillation.</p>]]></content:encoded>
</item>
<item>
  <title>KV Cache</title>
  <link>https://paweldubiel.com/en/glossary/kv-cache</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/kv-cache</guid>
  <pubDate>Wed, 16 Sep 2026 21:39:15 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>llm</category>
  <category>glossary</category>
  <description>The model appends a response piece by piece. It has already computed much information about earlier text, so computing it from scratch at every step would repeat work.</description>
  <content:encoded><![CDATA[<p>The model appends a response piece by piece. It has already computed much information about earlier text, so computing it from scratch at every step would repeat work. You want to retain results that remain valid.</p>
<p><strong>KV Cache</strong> stores keys and values from attention layers. These are lists of numbers used respectively to match fragments and convey their information. It does not store a ready answer or a summary of the conversation.</p>
<p>After processing A, B, and C, a new fragment D uses the stored descriptions of those positions and adds its own. In a model that blocks access to the future, new fragments do not change earlier descriptions, so they can be reused with compatible settings.</p>
<p>We save repeated computation but pay for memory to store the numbers. This cost grows with a long context. <a href="https://paweldubiel.com/en/glossary/prefill">Prefill</a> prepares the cache for a known input, and <a href="https://paweldubiel.com/en/glossary/decode">Decode</a> extends it during the response. The required information must still be read and mixed.</p>
<h2 id="mechanism-and-details">Mechanism and details</h2>
<p>In a model with <a href="https://paweldubiel.com/en/glossary/causal-masking">Causal Masking</a>, later <a href="https://paweldubiel.com/en/glossary/token">tokens</a> do not change the representations of earlier positions. This enables reuse of the cache for the same prefix and model settings. The information flow is described in <a href="https://arxiv.org/html/1706.03762v7#S3.SS1" rel="noopener noreferrer"><em>Attention Is All You Need</em>, §3.1 and §3.2.3</a>, and cache updates in each layer in the <a href="https://huggingface.co/docs/transformers/cache_explanation" rel="noopener noreferrer">Hugging Face documentation: How caching works</a>.</p>
<h2 id="what-remains-from-the-previous-step">What remains from the previous step</h2>
<p>An original illustration: the model has processed tokens A, B, and C. When processing D, it uses the stored K and V for the three preceding positions and appends the pair for D. It compares the current position's query with the available keys; the result uses the corresponding values. The cache is neither a ready-made answer nor a textual conversation summary.</p>
<p>Storing results has a cost. A small original example for one layer: four positions, two KV heads, three numbers in each K and V vector, and four bytes per number:</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mn>2</mn><mo>⋅</mo><mn>4</mn><mo>⋅</mo><mn>2</mn><mo>⋅</mo><mn>3</mn><mo>⋅</mo><mn>4</mn><mo>=</mo><mn>192</mn><mtext> bytes</mtext></mrow><annotation encoding="application/x-tex">2\cdot4\cdot2\cdot3\cdot4=192\ \text{bytes}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">4</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">3</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">4</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord">192</span><span class="mspace"> </span><span class="mord text"><span class="mord">bytes</span></span></span></span></span></span>
<p>The first factor of 2 means separate keys and values. The result includes only tensor elements, without allocation overhead. A full dynamic cache grows with the number of stored positions; limited-window variants can remove older positions.</p>
<p>An older <a href="https://paweldubiel.com/en/articles/kv-cache-scaling-problem-in-llm-inference">article on KV-cache scaling</a> develops the memory-cost topic. The <a href="https://paweldubiel.com/articles/kv-cache-miedzy-modelami-nvidia-zmniejsza-koszt-przelaczania" hreflang="pl">article on moving caches between models [Polski]</a> addresses a separate problem: matching tensor dimensions does not ensure matching meaning. Changing the model or prefix requires reassessing which part of the cache remains valid. See also: <a href="https://paweldubiel.com/en/glossary/pagedattention">PagedAttention</a> describes block-based memory organization, and <a href="https://paweldubiel.com/en/glossary/prefix-caching">Prefix Caching</a> describes reusing KV for a shared prefix.</p>
<div id="kv-cache-lab"></div>]]></content:encoded>
</item>
<item>
  <title>Top-k Sampling</title>
  <link>https://paweldubiel.com/en/glossary/top-k-sampling</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/top-k-sampling</guid>
  <pubDate>Wed, 16 Sep 2026 21:39:15 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>llm</category>
  <category>glossary</category>
  <description>When sampling the next piece, the model allows many extremely unlikely options. You want to keep some diversity but remove the long tail of candidates.</description>
  <content:encoded><![CDATA[<p>When sampling the next piece, the model allows many extremely unlikely options. You want to keep some diversity but remove the long tail of candidates. You can admit only a specified number of leaders.</p>
<p><strong>Top-k Sampling</strong> samples the next <a href="https://paweldubiel.com/en/glossary/token">token</a>, a piece of text, from the <code>k</code> highest-scoring candidates. It excludes the rest and renormalizes the retained probabilities to sum to one.</p>
<p>If A has probability <code>0.5</code>, B <code>0.3</code>, and the rest together <code>0.2</code>, <code>k=2</code> keeps A and B. After dividing by <code>0.8</code>, their probabilities are <code>0.625</code> and <code>0.375</code>. B can still win; the method does not give everyone equal chances.</p>
<p>A fixed <code>k</code> determines the number of candidates, rather than their total credibility. With a very flat distribution, even the leaders may have small probabilities. <a href="https://paweldubiel.com/en/glossary/top-p-sampling">Top-p Sampling</a> determines the set by cumulative probability, while <a href="https://paweldubiel.com/en/glossary/temperature">Temperature</a> adjusts the proportions.</p>
<h2 id="mechanism-and-details">Mechanism and details</h2>
<p>A practical implementation can filter logits before <a href="https://paweldubiel.com/en/glossary/softmax">Softmax</a>: discarded positions are assigned negative infinity. Their probability after normalization is then zero. This mechanism is described in the <a href="https://huggingface.co/docs/transformers/internal/generation_utils#transformers.TopKLogitsWarper" rel="noopener noreferrer">Transformers: TopKLogitsWarper documentation</a>.</p>
<h2 id="two-candidates-does-not-mean-equal-chances">Two candidates does not mean equal chances</h2>
<p>An original example for <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi><mo>=</mo><mn>2</mn></mrow><annotation encoding="application/x-tex">k=2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.0315em;">k</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">2</span></span></span></span>:</p>






























<table><thead><tr><th>Token</th><th align="right">Before filtering</th><th align="right">After filtering and normalization</th></tr></thead><tbody><tr><td>A</td><td align="right">0.50</td><td align="right">0.625</td></tr><tr><td>B</td><td align="right">0.30</td><td align="right">0.375</td></tr><tr><td>C</td><td align="right">0.15</td><td align="right">0</td></tr><tr><td>D</td><td align="right">0.05</td><td align="right">0</td></tr></tbody></table>
<p>A and B had a combined probability of 0.80. We divide by this sum: <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>0,50</mn><mi mathvariant="normal">/</mi><mn>0,80</mn><mo>=</mo><mn>0,625</mn></mrow><annotation encoding="application/x-tex">0{,}50/0{,}80=0{,}625</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">50/0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">80</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8389em;vertical-align:-0.1944em;"></span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">625</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>0,30</mn><mi mathvariant="normal">/</mi><mn>0,80</mn><mo>=</mo><mn>0,375</mn></mrow><annotation encoding="application/x-tex">0{,}30/0{,}80=0{,}375</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">30/0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">80</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8389em;vertical-align:-0.1944em;"></span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">375</span></span></span></span>. Sampling can still select B. With <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">k=1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.0315em;">k</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span> and a unique maximum, we always select the highest-scoring token.</p>
<p>A fixed <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.0315em;">k</span></span></span></span> controls the number of candidates, not their combined probability before the cutoff. Two retained positions can contain almost the entire distribution or only a small part of it. <a href="https://paweldubiel.com/en/glossary/top-p-sampling">Top-p Sampling</a> sets the boundary according to the sum of probabilities. <a href="https://paweldubiel.com/en/glossary/temperature">Temperature</a> changes the relative chances; positive scaling alone does not change the order of finite logits.</p>
<p>For ties, it is worth checking the implementation. The <a href="https://github.com/huggingface/transformers/blob/v5.17.0/src/transformers/generation/logits_process.py" rel="noopener noreferrer">Transformers 5.17.0 code</a> removes scores strictly below the score of the k-th candidate. It can therefore retain additional tokens with the same value at the boundary. The example in the table has no ties.</p>
<div id="top-k-sampling-lab"></div>]]></content:encoded>
</item>
<item>
  <title>Top-p Sampling</title>
  <link>https://paweldubiel.com/en/glossary/top-p-sampling</link>
  <guid isPermaLink="true">https://paweldubiel.com/en/glossary/top-p-sampling</guid>
  <pubDate>Wed, 16 Sep 2026 21:39:15 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>llm</category>
  <category>glossary</category>
  <description>Sometimes the model has one clear leader; sometimes it has many continuations with similar scores. Always admitting five candidates ignores this difference.</description>
  <content:encoded><![CDATA[<p>Sometimes the model has one clear leader; sometimes it has many continuations with similar scores. Always admitting five candidates ignores this difference. You want to choose the group's size according to where the probability is concentrated.</p>
<p><strong>Top-p Sampling</strong>, or Nucleus Sampling, chooses the smallest leading group of candidates ordered by descending probability whose sum reaches threshold <code>p</code>. It then samples from that group after renormalizing the probabilities to one.</p>
<p>For probabilities <code>0.7; 0.15; 0.1; 0.05</code> and threshold <code>0.75</code>, the first two remain: together they have <code>0.85</code>. For <code>0.4; 0.3; 0.2; 0.1</code>, three are needed. Each generation step can therefore admit a different number of <a href="https://paweldubiel.com/en/glossary/token">tokens</a> — pieces of text.</p>
<p>The threshold does not mean a minimum probability for each candidate or guarantee answer quality. <a href="https://paweldubiel.com/en/glossary/top-k-sampling">Top-k Sampling</a> fixes the number, while top-p responds to the distribution; neither filter assesses the truthfulness of the text itself.</p>
<h2 id="mechanism-and-details">Mechanism and details</h2>
<p>The method and normalization are described by <a href="https://arxiv.org/html/1904.09751v2#S3.SS1" rel="noopener noreferrer">Holtzman et al., <em>The Curious Case of Neural Text Degeneration</em>, §3.1</a>. The candidate set is recalculated at every step of <a href="https://paweldubiel.com/en/glossary/autoregressive-language-modeling">Autoregressive Language Modeling</a>.</p>
<h2 id="the-same-threshold-a-different-number-of-tokens">The same threshold, a different number of tokens</h2>
<p>An original example for <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi><mo>=</mo><mn>0,75</mn></mrow><annotation encoding="application/x-tex">p=0{,}75</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8389em;vertical-align:-0.1944em;"></span><span class="mord">0</span><span class="mord"><span class="mpunct">,</span></span><span class="mord">75</span></span></span></span>; the rows already contain sorted probabilities:</p>




















<table><thead><tr><th>Distribution for A, B, C, D</th><th>Retained tokens</th><th align="right">Their sum before normalization</th></tr></thead><tbody><tr><td>0.70; 0.15; 0.10; 0.05</td><td>A, B</td><td align="right">0.85</td></tr><tr><td>0.40; 0.30; 0.20; 0.10</td><td>A, B, C</td><td align="right">0.90</td></tr></tbody></table>
<p>In the second row, A and B total only 0.70, so C must be included. After normalization, their chances are <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>4</mn><mi mathvariant="normal">/</mi><mn>9</mn></mrow><annotation encoding="application/x-tex">4/9</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">4/9</span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>3</mn><mi mathvariant="normal">/</mi><mn>9</mn></mrow><annotation encoding="application/x-tex">3/9</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">3/9</span></span></span></span>, and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn><mi mathvariant="normal">/</mi><mn>9</mn></mrow><annotation encoding="application/x-tex">2/9</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">2/9</span></span></span></span> respectively. D is excluded. The threshold does not mean retaining tokens <strong>each of which individually</strong> has a probability of at least 0.75.</p>
<p><a href="https://paweldubiel.com/en/glossary/top-k-sampling">Top-k Sampling</a> would try to retain the same number of candidates in both cases. Top-p responds to the distribution of their chances. If we apply <a href="https://paweldubiel.com/en/glossary/temperature">Temperature</a> beforehand, the sum of successive probabilities changes, and the cutoff may fall in a different place.</p>
<p>The paper studied, among other things, open-ended text continuation by GPT-2 (§4.1). Its results do not establish one optimal threshold for every model and task. Nor is the parameter <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi></mrow><annotation encoding="application/x-tex">p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span></span></span></span> the probability that the generated response will be correct.</p>
<div id="top-p-sampling-lab"></div>]]></content:encoded>
</item>
</channel>
</rss>