<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Joseph Gear | Blog</title>
    <link>https://gear-research.com/</link>
    <description>Accessible explanations of AI, machine learning, LLMs, and deep learning for non-technical readers.</description>
    <language>en</language>
    <lastBuildDate>Sat, 19 Sep 2026 05:20:22 GMT</lastBuildDate>
    <item>
      <title>AI for Normal People #4 | When LLMs Go Wrong</title>
      <link>https://gear-research.com/blog/normal-ai-4.html</link>
      <guid isPermaLink="true">https://gear-research.com/blog/normal-ai-4.html</guid>
      <pubDate>Fri, 21 Aug 2026 00:00:00 GMT</pubDate>
      <description>Why LLMs hallucinate, how benchmarks judge their abilities, and why we should trust but verify.</description>
      <content:encoded>&lt;section&gt;
            &lt;p&gt;If you've made much use of LLMs, even very good ones, you have likely encountered their propensity for mistakes. Weird mistakes, too, given how capable LLMs often are. The best LLMs today can complete complex software engineering tasks in minutes, while sometimes attempting to send an email to an address ending in &lt;code&gt;@example.com&lt;/code&gt;, seemingly believing it was real &lt;a href=&quot;#fn-1&quot;&gt;[1]&lt;/a&gt;. Only sometimes, though, which could strike you as even stranger. You might send the exact same prompt to the exact same model and yet still wind up with two different answers, only one of which is actually correct. What causes this? Why is it that these models which appear so capable on tasks the average person wouldn't even know where to start on can also abruptly crumble when given problems a child could solve without even thinking about it &lt;a href=&quot;#fn-2&quot;&gt;[2]&lt;/a&gt;? How can we trust them to do anything properly if they can make such elementary mistakes?&lt;/p&gt;

            &lt;h2&gt;Hallucinations&lt;/h2&gt;
            &lt;p&gt;The term the industry has settled on for the strange behaviour in which an LLM generates a sentence with a clear factual error that a human with access to the information probably wouldn't make is &lt;b&gt;hallucination&lt;/b&gt;. Common examples of hallucinations might be citing a legal case or a book which simply does not exist (or if it does, does not say what the LLM claims), writing code that depends on a misnamed function or variable, or making claims which are objectively untrue.&lt;/p&gt;
            &lt;p&gt;Note that hallucination can be vaguely defined sometimes; it's not a very rigorous term. For our purposes, I'll say that a hallucination is a factual error produced by an LLM which lacks the markers that usually indicate uncertainty. Sometimes people will say that this is the model &quot;confidently making up garbage&quot; or even &quot;lying&quot;.&lt;/p&gt;
            &lt;p&gt;An example of a hallucination might look like this:&lt;/p&gt;
            &lt;blockquote&gt;
              &lt;p&gt;USER: Who was involved in the issue of the Magna Carta?&lt;/p&gt;
              &lt;p&gt;ASSISTANT: The issuing of the Magna Carta in 1215 involved King John of England, Stephen Hawking, William Marshal, Henry de Loundres, and Hugh de Neville, among others.&lt;/p&gt;
            &lt;/blockquote&gt;
            &lt;p&gt;Stephen Hawking was not, in fact, present for the sealing of a document which occurred 727 years before his birth, though the other people named were real and involved. &quot;Stephen Hawking&quot; was a real person, was from England, and a Stephen was actually involved in the real document (Stephen Langton, the Archbishop of Canterbury). Yet no one who knows even a little bit about Hawking and the Magna Carta could make such a mistake. Note that this example is &lt;i&gt;not&lt;/i&gt; one that I have personally encountered in an LLM. It is simply a plausible illustrative example of such an error.&lt;/p&gt;
            &lt;p&gt;Importantly, if you did not read the passage closely or did not know who Stephen Hawking was or what the Magna Carta is, you would have little way of telling that something was wrong. It is embedded within a correct list of names. Yet it is simply wrong. This is why people might refer to the model as being &quot;confident&quot; in its incorrectness, although the text itself doesn't tell us much about the model's confidence &lt;a href=&quot;#fn-3&quot;&gt;[3]&lt;/a&gt;.&lt;/p&gt;

            &lt;h3&gt;Why Hallucinations Happen&lt;/h3&gt;
            &lt;p&gt;If the above case were real, we could make some guesses about how it came about. In a vacuum, if you were trying to predict the word which came after &quot;Stephen&quot;, then &quot;Hawking&quot; would probably be pretty high on the list, along with &quot;King&quot; and &quot;Spielberg&quot;. &quot;Langton&quot; would have quite a low probability, except that the other names (King John, William Marshal, etc.) and the presence of the words &quot;Magna Carta&quot; should push the distribution much further towards &quot;Langton&quot; than the other surnames.&lt;/p&gt;
            &lt;p&gt;But &quot;more likely&quot; does not mean &quot;guaranteed&quot;. Recall that &lt;a href=&quot;normal-ai-2.html#what-models-really-give-you&quot;&gt;what models really give you&lt;/a&gt; is a list of all possible tokens and their probabilities (a &lt;b&gt;probability distribution&lt;/b&gt;), from which we pick one at random, weighted by the probabilities the model predicted. In a true probability distribution, no token would ever have a probability of zero, meaning that in principle, many &lt;i&gt;might&lt;/i&gt; be selected. In practice, most have values so close to zero that they would get rounded away, but in this particular case, it is fairly likely that the other plausible surnames for Stephen had meaningful chances, so &quot;Hawking&quot; might have come up by pure chance, even if &quot;Langton&quot; were more likely. This would be a case in which the non-deterministic behaviour of token selection worked to produce a false statement.&lt;/p&gt;

            &lt;svg width=&quot;100%&quot; viewBox=&quot;0 0 550 400&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; style=&quot;max-width: 550px; display: block; margin: 20px auto;&quot;&gt;
              &lt;text x=&quot;20&quot; y=&quot;35&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;16&quot; font-weight=&quot;bold&quot;&gt;Given Context: &quot;... involved King John of England, Stephen &quot;&lt;/text&gt;

              &lt;g font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;14&quot;&gt;
                &lt;text x=&quot;90&quot; y=&quot;85&quot; text-anchor=&quot;end&quot; fill=&quot;currentColor&quot; font-weight=&quot;bold&quot;&gt;Langton&lt;/text&gt;
                &lt;rect x=&quot;100&quot; y=&quot;70&quot; width=&quot;152&quot; height=&quot;22&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-blue)&quot; /&gt;
                &lt;text x=&quot;260&quot; y=&quot;86&quot; fill=&quot;currentColor&quot; font-weight=&quot;bold&quot;&gt;38.0%&lt;/text&gt;

                &lt;text x=&quot;90&quot; y=&quot;120&quot; text-anchor=&quot;end&quot; fill=&quot;currentColor&quot;&gt;Hawking&lt;/text&gt;
                &lt;rect x=&quot;100&quot; y=&quot;105&quot; width=&quot;88&quot; height=&quot;22&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-blue-soft)&quot; /&gt;
                &lt;text x=&quot;196&quot; y=&quot;121&quot; fill=&quot;currentColor&quot;&gt;22.0%&lt;/text&gt;

                &lt;text x=&quot;90&quot; y=&quot;155&quot; text-anchor=&quot;end&quot; fill=&quot;currentColor&quot;&gt;Spielberg&lt;/text&gt;
                &lt;rect x=&quot;100&quot; y=&quot;140&quot; width=&quot;48&quot; height=&quot;22&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-blue-soft)&quot; /&gt;
                &lt;text x=&quot;156&quot; y=&quot;156&quot; fill=&quot;currentColor&quot;&gt;12.0%&lt;/text&gt;

                &lt;text x=&quot;90&quot; y=&quot;190&quot; text-anchor=&quot;end&quot; fill=&quot;currentColor&quot;&gt;King&lt;/text&gt;
                &lt;rect x=&quot;100&quot; y=&quot;175&quot; width=&quot;32&quot; height=&quot;22&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-blue-soft)&quot; /&gt;
                &lt;text x=&quot;140&quot; y=&quot;191&quot; fill=&quot;currentColor&quot;&gt;8.0%&lt;/text&gt;

                &lt;text x=&quot;90&quot; y=&quot;225&quot; text-anchor=&quot;end&quot; fill=&quot;currentColor&quot;&gt;of Blois&lt;/text&gt;
                &lt;rect x=&quot;100&quot; y=&quot;210&quot; width=&quot;24&quot; height=&quot;22&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-blue-soft)&quot; /&gt;
                &lt;text x=&quot;132&quot; y=&quot;226&quot; fill=&quot;currentColor&quot;&gt;6.0%&lt;/text&gt;

                &lt;text x=&quot;90&quot; y=&quot;260&quot; text-anchor=&quot;end&quot; fill=&quot;currentColor&quot;&gt;Curry&lt;/text&gt;
                &lt;rect x=&quot;100&quot; y=&quot;245&quot; width=&quot;20&quot; height=&quot;22&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-muted)&quot; /&gt;
                &lt;text x=&quot;128&quot; y=&quot;261&quot; fill=&quot;currentColor&quot;&gt;5.0%&lt;/text&gt;

                &lt;text x=&quot;90&quot; y=&quot;295&quot; text-anchor=&quot;end&quot; fill=&quot;currentColor&quot;&gt;Colbert&lt;/text&gt;
                &lt;rect x=&quot;100&quot; y=&quot;280&quot; width=&quot;16&quot; height=&quot;22&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-muted)&quot; /&gt;
                &lt;text x=&quot;124&quot; y=&quot;296&quot; fill=&quot;currentColor&quot;&gt;4.0%&lt;/text&gt;

                &lt;text x=&quot;90&quot; y=&quot;330&quot; text-anchor=&quot;end&quot; fill=&quot;currentColor&quot;&gt;of Hungary&lt;/text&gt;
                &lt;rect x=&quot;100&quot; y=&quot;315&quot; width=&quot;12&quot; height=&quot;22&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-muted)&quot; /&gt;
                &lt;text x=&quot;120&quot; y=&quot;331&quot; fill=&quot;currentColor&quot;&gt;3.0%&lt;/text&gt;

                &lt;text x=&quot;90&quot; y=&quot;365&quot; text-anchor=&quot;end&quot; fill=&quot;currentColor&quot;&gt;Moffat&lt;/text&gt;
                &lt;rect x=&quot;100&quot; y=&quot;350&quot; width=&quot;8&quot; height=&quot;22&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-muted)&quot; /&gt;
                &lt;text x=&quot;116&quot; y=&quot;366&quot; fill=&quot;currentColor&quot;&gt;2.0%&lt;/text&gt;
              &lt;/g&gt;
            &lt;/svg&gt;

            &lt;p&gt;Alternatively, the model itself may simply have produced a probability distribution that does not line up with real facts about the world. To an LLM, the text it sees during training is the &quot;ground truth&quot; to which it naturally has access, but from our perspective there is nothing to ensure the model's ground truth matches ours. Maybe information about &quot;Langton&quot; didn't end up in its training data, or the model incorrectly learned that &quot;Hawking&quot; probably follows &quot;Stephen&quot; under any circumstances.&lt;/p&gt;
            &lt;p&gt;In this case, the hallucination would be of little consequence beyond teaching someone something wrong about a minor historical character. In higher-stakes cases, there could be more severe consequences &lt;a href=&quot;#fn-4&quot;&gt;[4]&lt;/a&gt;, so minimising such mistakes is naturally ideal. The deeper problem when it comes to LLM hallucinations is that, as far as the model is concerned, it is not straightforward to tell the difference between &quot;hallucinations&quot; and standard operating procedure. In either case, the model generates a probability distribution over next-tokens and we sample from the distribution. If the model or the random selection selects a token that results in an incorrect statement, it has no way to go back and fix it.&lt;/p&gt;
            &lt;p&gt;I want to be clear that this is &lt;i&gt;not&lt;/i&gt; me saying that LLMs routinely make up facts. In recent years, LLM trainers have substantially reduced the incidence of hallucinations and made LLMs more inclined to search for and link to external information when doing so would be helpful. They do not want their models making things up for the obvious reason that you would be less willing to use them if they often did so.&lt;/p&gt;
            &lt;p&gt;Furthermore, we don't call every failure of an LLM a &quot;hallucination&quot;, even if the mechanism is the same. Especially for domains like coding or maths, a model getting a wrong answer or code that does not work is not usually considered a &quot;hallucination&quot;; it just wrote bad code or an incorrect proof. Yet what the model is doing when it &quot;hallucinates&quot; is, in fact, mostly the same as when it is simply wrong, or when it is actually right.&lt;/p&gt;

            &lt;h2&gt;Correctness is Bigger Than Tokens&lt;/h2&gt;
            &lt;p&gt;The issue is that if you want to answer a question or write some code, the correctness of the answer or usefulness of the code is not contained in just one token. Rather, it's contained in many tokens, strung together. This could be hundreds or sometimes even hundreds of thousands of tokens, depending on the question.&lt;/p&gt;
            &lt;p&gt;When we use an LLM to generate answers or code, we bring our own standard of &quot;correctness&quot; to the model (what the truth of the matter actually is or what the computer will do when the code is run, for example). An LLM lacks an internal measure of truth beyond how it has learned to be &quot;not-wrong&quot; about the very next token in the sequence. There is no equation that lets you put in any statement created using language and gives you a &quot;true&quot; or &quot;false&quot; in return &lt;a href=&quot;#fn-5&quot;&gt;[5]&lt;/a&gt;.&lt;/p&gt;
            &lt;p&gt;This is a challenge if we want to train our LLMs to be factually accurate. The training objective is &quot;most likely next token&quot;, and that is not the same question as &quot;next token which would contribute to a true statement&quot;. We would hope that our training data is mostly composed of true statements &amp;mdash; it's a vote of extreme confidence in the wisdom of the crowds that we use data from the internet in our training corpora at all &amp;mdash; but we know this is not always going to be the case. Fiction, disagreeing perspectives, obsolete or debunked theories, opinions, and questions without answers are a core part of human knowledge, so they inevitably wind up as part of the training data for an LLM &lt;a href=&quot;#fn-7&quot;&gt;[7]&lt;/a&gt;.&lt;/p&gt;
            &lt;p&gt;We must, therefore, evaluate a model's tendency to produce correct or true text from the outside. For a given task, we have to provide an external judge which can assess whether the text generated by a model fits our criteria.&lt;/p&gt;

            &lt;h2&gt;Benchmarks: Judging from the Outside&lt;/h2&gt;
            &lt;p&gt;At a small scale, a person could simply use an LLM for the tasks they care about and evaluate whether or not it works properly based on their own criteria. However, this is not a very comprehensive approach (maybe you only have time to evaluate a couple of specific tasks) and we also want to make sure our comparisons between models are fair, using the same set of problems for each one.&lt;/p&gt;
            &lt;p&gt;The industry does this using &lt;b&gt;benchmarks&lt;/b&gt;. These are essentially exams that we make models sit to evaluate their abilities in different areas that we care about. Much like exams you might hand to students, a benchmark is a list of questions for which we have specific answers or types of answers in mind. Unlike exams handed to students, though, benchmarks are often run several times on the same model in order to smooth out the randomness inherent to LLM usage. Since benchmarking is done &quot;at inference-time&quot;, when the weights are frozen, the model is unable to learn anything about the exam between runs, so this is not an unfair part of testing as it would be if schools ran the same exam multiple times on the same students.&lt;/p&gt;
            &lt;p&gt;Some benchmarks will include multiple-choice questions with specific answers in mind. Others will allow the model to generate freeform text and then grade that text based on certain criteria (this could be done by a person, but these days it is quite common for other LLMs to be used as judges for the sake of convenience). Still others might give the model a more complex environment with various tools it is allowed to use to solve a problem and then use a special &quot;submit answer&quot; tool to indicate that the model thinks it is done.&lt;/p&gt;

            &lt;h3&gt;When Benchmarks Go Wrong&lt;/h3&gt;
            &lt;p&gt;Unfortunately, benchmarks themselves are fallible measures. There are a few ways a benchmark score might misrepresent a model's true capabilities, and all must be kept in mind when weighing one up.&lt;/p&gt;

            &lt;h4&gt;Benchmark Contamination&lt;/h4&gt;
            &lt;p&gt;For one, benchmarks should be comprised of questions that have never been included in the model's training data and thus have never been used to update the model's weights. If a benchmark question were in the training data for an LLM, then it would have been used to update the model's weights, which unfairly biases the model towards answering the question correctly. Just as we want a child at school to understand the &lt;i&gt;underlying patterns in arithmetic&lt;/i&gt;, rather than just the answer to a specific question, we also want an LLM to have learned the underlying facts we test it on. When a model is trained on the same questions used to benchmark it, we call this &lt;b&gt;benchmark contamination&lt;/b&gt; (sometimes it is also called &lt;b&gt;data leakage&lt;/b&gt;), and it makes the test invalid.&lt;/p&gt;

            &lt;h4&gt;Faulty Benchmarks&lt;/h4&gt;
            &lt;p&gt;An ideal benchmark will be &lt;i&gt;large&lt;/i&gt; (so that we know it wasn't just luck that the LLM got the answer right), &lt;i&gt;diverse&lt;/i&gt; (so that we're testing more than the exact same behaviour over and over), and &lt;i&gt;correct&lt;/i&gt;. That last one might seem obvious &amp;mdash; clearly an exam's answer sheet should have the right answers on it &amp;mdash; but this is surprisingly difficult for very large benchmarks, since this requires a person or team to go through it meticulously, which is expensive &lt;a href=&quot;#fn-8&quot;&gt;[8]&lt;/a&gt;. Correctness has actually been a problem for a few benchmarks in the past, which have been found to contain errors &lt;a href=&quot;#fn-9&quot;&gt;[9]&lt;/a&gt;, meaning that a low score (or a high one) may not indicate a model's true abilities.&lt;/p&gt;

            &lt;h3&gt;Benchmarketing&lt;/h3&gt;
            &lt;p&gt;Benchmarks are used by LLM trainers as a way of determining if their models are working or not (and thus whether they are ready for release), and are also often used to advertise the quality of the model before release. Especially in today's highly competitive LLM landscape, the labs that train them will typically announce and release their new models with a series of benchmark scores and comparisons to other models (both the lab's older models and those of their competitors) on the same set of benchmarks. This will be something like OpenAI claiming that their new GPT has a score of 71 on &lt;code&gt;CodeThatWorksGoodBench&lt;/code&gt;, compared to Claude's 68, or Alibaba saying that the new Qwen gained an extra 15 points on &lt;code&gt;FrontierCooking&lt;/code&gt; compared to the one they released three months ago.&lt;/p&gt;
            &lt;p&gt;This is all fairly standard marketing fare. As new LLMs come out, they will typically jostle for the top spot. Cost is also a major consideration which can offset a lower benchmark score. Depending on your use case, you may prefer a model that is &quot;good enough&quot; at a lower cost than the one scoring the highest on a given benchmark. It is also generally true that labs will release their models with the benchmarks that make them look like the best value. Sometimes this is simply being selective about which benchmarks you show, though sometimes it can be a little more nefarious.&lt;/p&gt;
            &lt;p&gt;In some cases, a model's benchmark scores are not reflective of their real ability (usually for the worse). When done intentionally, this is sometimes called &lt;b&gt;benchmaxxing&lt;/b&gt;, which can involve training the model on questions that look suspiciously similar to those on a popular benchmark, data leakage (this is not always intentional if the dataset is on the public internet, but is still a bad look), or cherry-picking specific testing runs in which the model happened to perform best. As with all marketing, it is best to take vendor-published numbers with a grain of salt and try to find trustworthy, independent benchmarks for your particular use case.&lt;/p&gt;

            &lt;h2&gt;Trust, But Verify&lt;/h2&gt;
            &lt;p&gt;At the end of the day, evaluating the truthfulness or usefulness of LLMs is not a straightforward task and ensuring it is harder still. We do not always have certainty about the quality of a text an LLM has produced. We can do our best with benchmarks and tests of various kinds, but these too can be flawed, so they should be taken only as &lt;i&gt;evidence&lt;/i&gt; that an LLM is working to our satisfaction, rather than as proof.&lt;/p&gt;
            &lt;p&gt;&quot;Which token comes next?&quot; and &quot;Which token would make this statement true?&quot; are simply not the same question, though we can do our best to make their answers overlap. LLMs will always have the opportunity to produce false-but-convincing output, conflations, contradictions, and mistakes. The most practical response to this is to be careful. Sometimes, the consequences of a mistake are small, so we don't need to worry too much. Sometimes they are not, and our caution when using LLMs should reflect this. Ideally, it is best to constrain LLMs where possible and to provide them with meaningful ways of checking their work. We will discuss exactly how such information is delivered and what we can do with it in the next article in which we'll explore the Anatomy of a Context Window. &lt;!-- TODO: Link to &quot;5 - Anatomy of a Context Window&quot; once published --&gt;&lt;/p&gt;
          &lt;/section&gt;
          &lt;hr /&gt;
          &lt;section&gt;
            &lt;p id=&quot;fn-1&quot;&gt;[1] &lt;a href=&quot;https://arxiv.org/html/2606.13715v2&quot;&gt;https://arxiv.org/html/2606.13715v2&lt;/a&gt;&lt;/p&gt;
            &lt;p id=&quot;fn-2&quot;&gt;[2] A fun example of this that floated around is the &quot;car-wash problem&quot;. Ask a model &quot;The car wash is 50 metres from my house. Should I walk or drive there?&quot; and, for a while at least, nearly all of them would tell you to walk because it's such a short distance. &lt;a href=&quot;https://mastodon.world/@knowmadd/116072773118828295&quot;&gt;https://mastodon.world/@knowmadd/116072773118828295&lt;/a&gt;&lt;/p&gt;
            &lt;p id=&quot;fn-3&quot;&gt;[3] &quot;Confidence&quot; means something different for LLMs than it does for people. The best measure we can get of an LLM's confidence about a given token is how strongly a given token was weighted compared to alternatives. The trouble with this is that it bundles up a number of reasons the next token might be uncertain beyond just that the model does not know the fact. For instance, if there are several different ways of saying the same thing, the model might not give any one of the starting tokens for these phrases a decisive advantage over the others, even if it is &quot;confident&quot; about the underlying fact all of them are describing.&lt;/p&gt;
            &lt;p id=&quot;fn-4&quot;&gt;[4] &lt;a href=&quot;https://www.abc.net.au/news/2023-06-09/lawyers-blame-chatgpt-for-tricking-them-into-citing-fake-cases/102462028&quot;&gt;https://www.abc.net.au/news/2023-06-09/lawyers-blame-chatgpt-for-tricking-them-into-citing-fake-cases/102462028&lt;/a&gt;&lt;/p&gt;
            &lt;p id=&quot;fn-5&quot;&gt;[5] For some domains, like maths, this is possible. But how would you determine the single correct answer to the question &quot;What is the best way to eat potatoes?&quot; &lt;a href=&quot;#fn-6&quot;&gt;[6]&lt;/a&gt;&lt;/p&gt;
            &lt;p id=&quot;fn-6&quot;&gt;[6] It's mashed, nice and creamy, with loads of garlic, btw&lt;/p&gt;
            &lt;p id=&quot;fn-7&quot;&gt;[7] Further still, if we accept that false information should be scrubbed from an LLM's training corpus, we make those who compile the corpus the arbiters of what is true to the model. I hope that most people, even those who broadly trust and agree with the LLM trainers, would see that this is not wise.&lt;/p&gt;
            &lt;p id=&quot;fn-8&quot;&gt;[8] And, I say as someone who has needed to manually read and label large datasets of code for security vulnerabilities, unbelievably, soul-destroyingly boring.&lt;/p&gt;
            &lt;p id=&quot;fn-9&quot;&gt;[9] &lt;a href=&quot;https://aclanthology.org/2025.naacl-long.262.pdf&quot;&gt;https://aclanthology.org/2025.naacl-long.262.pdf&lt;/a&gt;, &lt;a href=&quot;https://gradientscience.org/gsm8k-platinum&quot;&gt;https://gradientscience.org/gsm8k-platinum&lt;/a&gt;, &lt;a href=&quot;https://github.com/sunblaze-ucb/exploitgym/blob/main/CHANGELOG.md&quot;&gt;https://github.com/sunblaze-ucb/exploitgym/blob/main/CHANGELOG.md&lt;/a&gt;&lt;/p&gt;
          &lt;/section&gt;</content:encoded>
    </item>
    <item>
      <title>AI for Normal People #3 | Scale</title>
      <link>https://gear-research.com/blog/normal-ai-3.html</link>
      <guid isPermaLink="true">https://gear-research.com/blog/normal-ai-3.html</guid>
      <pubDate>Fri, 07 Aug 2026 00:00:00 GMT</pubDate>
      <description>Why LLMs are so large. Explaining parameter counts, GPUs, training data, pre-training, and post-training.</description>
      <content:encoded>&lt;section&gt;
            &lt;p&gt;In my last two posts, I discussed what it means to &lt;i&gt;model language&lt;/i&gt;, how we do it, and how it allows us to construct coherent (and even useful) passages of text. Recall that the question we ask of models like ChatGPT and Claude is &lt;i&gt;&quot;Given this text, which token comes next?&quot;&lt;/i&gt;. What is surprising about LLMs is that answering that question accurately and quickly is the backbone of a multi-trillion-dollar industry, since it seems rather mundane at first glance.&lt;/p&gt;

            &lt;p&gt;This article will explain why such a simple-sounding task has become so consequential. In short, it is because these models are huge. But just how huge are they? What does it take to make them so big, and why did we decide to? What's so special about making your language model &lt;b&gt;large&lt;/b&gt;?&lt;/p&gt;

            &lt;h2&gt;Just How Large?&lt;/h2&gt;
            &lt;p&gt;Firstly, I want to give you some perspective on the size of these things. Typically we measure models by the number of weights they contain (the standard term is &lt;b&gt;parameter count&lt;/b&gt;), without necessarily worrying ourselves yet about how those weights are arranged. Going back to our bird classifier from &lt;a href=&quot;normal-ai-1.html&quot;&gt;Part 1&lt;/a&gt;, some older image recognition models from the early 2010s had parameter counts in the tens of millions &lt;a href=&quot;#fn-1&quot;&gt;[1]&lt;/a&gt;. This would come out to a couple of hundred megabytes of storage space &amp;mdash; a few minutes of 4K video or a few hours of audio. Today, since we have made a number of improvements to how we train ML models, a modern image classifier might have as few as five million parameters.&lt;/p&gt;

            &lt;p&gt;These days, the largest LLMs with published parameter counts are typically in the high hundreds of billions to low trillions &lt;a href=&quot;#fn-2&quot;&gt;[2]&lt;/a&gt;. &quot;Small&quot; language models (SLMs), which work identically to LLMs but simply have fewer parameters, usually top out at around ten billion parameters &lt;a href=&quot;#fn-3&quot;&gt;[3]&lt;/a&gt;. Thus, the language models we see today can be many thousands of times larger than our bird classifier.&lt;/p&gt;

&lt;h2 class=&quot;sr-only&quot;&gt;A to-scale comparison of parameter counts for four neural networks &amp;mdash; AlexNet (60M), MobileNetV3 (5M), Qwen 3.5-2B (2B), and GLM 5.2 (744B) &amp;mdash; where each box represents 10 million parameters and the grid scrolls horizontally.&lt;/h2&gt;
&lt;style&gt;
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}
#nnscale .hd{font-size:16px;font-weight:500;color:var(--text-primary)}
#nnscale .sub{font-size:12px;color:var(--text-secondary);margin-top:3px;line-height:1.5}
#nnscale .ctl{display:flex;align-items:center;gap:10px;margin:14px 0 8px}
#nnscale .arw{width:34px;height:34px;flex:0 0 auto;border-radius:var(--radius);border:0.5px solid var(--border-strong);background:transparent;color:var(--text-primary);display:flex;align-items:center;justify-content:center;font-size:18px;cursor:pointer}
#nnscale .arw:hover{background:var(--surface-1)}
#nnscale .arw:active{transform:scale(.98)}
#nnscale .arw:disabled{opacity:.35;cursor:default;background:transparent}
#nnscale .prog{flex:1;height:6px;border-radius:99px;background:var(--border);overflow:hidden}
#nnscale .bar{height:100%;width:0;background:var(--text-secondary);border-radius:99px;transition:width .1s linear}
#nnscale .jmp{display:flex;flex-wrap:wrap;gap:6px;align-items:center;font-size:11px;color:var(--text-secondary);margin-bottom:10px}
#nnscale .jmp button{font-size:11px;padding:4px 10px;border-radius:99px;border:0.5px solid var(--border-strong);background:transparent;color:var(--text-secondary);cursor:pointer}
#nnscale .jmp button:hover{background:var(--surface-1);color:var(--text-primary)}
#nnscale .scr{overflow-x:auto;overflow-y:hidden;border:0.5px solid var(--border);border-radius:12px;background:var(--surface-1);cursor:grab}
#nnscale .scr svg{display:block}
#nnscale .js-widget{display:none}
#nnscale.js .js-widget{display:block}
&lt;/style&gt;
&lt;div id=&quot;nnscale&quot;&gt;
  &lt;div class=&quot;hd&quot;&gt;Neural network sizes, to scale&lt;/div&gt;
  &lt;noscript&gt;
    &lt;div class=&quot;sub&quot;&gt;Parameter counts on a logarithmic scale &amp;mdash; each gridline is a factor of 10.&lt;/div&gt;
    &lt;svg width=&quot;100%&quot; viewBox=&quot;0 0 560 340&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; style=&quot;max-width: 560px; display: block; margin: 20px auto;&quot; role=&quot;img&quot; aria-label=&quot;Bar chart of neural network parameter counts on a logarithmic scale: MobileNetV3 5 million, AlexNet 60 million, Qwen 3.5 2 billion, GLM 5.2 744 billion parameters.&quot;&gt;
      &lt;g stroke=&quot;currentColor&quot; stroke-opacity=&quot;0.25&quot; stroke-width=&quot;1&quot;&gt;
        &lt;line x1=&quot;64&quot; y1=&quot;28&quot; x2=&quot;536&quot; y2=&quot;28&quot; /&gt;
        &lt;line x1=&quot;64&quot; y1=&quot;70&quot; x2=&quot;536&quot; y2=&quot;70&quot; /&gt;
        &lt;line x1=&quot;64&quot; y1=&quot;112&quot; x2=&quot;536&quot; y2=&quot;112&quot; /&gt;
        &lt;line x1=&quot;64&quot; y1=&quot;154&quot; x2=&quot;536&quot; y2=&quot;154&quot; /&gt;
        &lt;line x1=&quot;64&quot; y1=&quot;196&quot; x2=&quot;536&quot; y2=&quot;196&quot; /&gt;
        &lt;line x1=&quot;64&quot; y1=&quot;238&quot; x2=&quot;536&quot; y2=&quot;238&quot; /&gt;
      &lt;/g&gt;
      &lt;line x1=&quot;64&quot; y1=&quot;280&quot; x2=&quot;536&quot; y2=&quot;280&quot; stroke=&quot;currentColor&quot; stroke-opacity=&quot;0.6&quot; stroke-width=&quot;1&quot; /&gt;
      &lt;g fill=&quot;currentColor&quot; fill-opacity=&quot;0.7&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;12&quot; text-anchor=&quot;end&quot;&gt;
        &lt;text x=&quot;56&quot; y=&quot;32&quot;&gt;1T&lt;/text&gt;
        &lt;text x=&quot;56&quot; y=&quot;74&quot;&gt;100B&lt;/text&gt;
        &lt;text x=&quot;56&quot; y=&quot;116&quot;&gt;10B&lt;/text&gt;
        &lt;text x=&quot;56&quot; y=&quot;158&quot;&gt;1B&lt;/text&gt;
        &lt;text x=&quot;56&quot; y=&quot;200&quot;&gt;100M&lt;/text&gt;
        &lt;text x=&quot;56&quot; y=&quot;242&quot;&gt;10M&lt;/text&gt;
        &lt;text x=&quot;56&quot; y=&quot;284&quot;&gt;1M&lt;/text&gt;
      &lt;/g&gt;
      &lt;rect x=&quot;91&quot; y=&quot;250.6&quot; width=&quot;64&quot; height=&quot;29.4&quot; rx=&quot;3&quot; fill=&quot;#2f9e83&quot; /&gt;
      &lt;rect x=&quot;209&quot; y=&quot;205.3&quot; width=&quot;64&quot; height=&quot;74.7&quot; rx=&quot;3&quot; fill=&quot;#d17a2e&quot; /&gt;
      &lt;rect x=&quot;327&quot; y=&quot;141.4&quot; width=&quot;64&quot; height=&quot;138.6&quot; rx=&quot;3&quot; fill=&quot;#c95f8c&quot; /&gt;
      &lt;rect x=&quot;445&quot; y=&quot;33.4&quot; width=&quot;64&quot; height=&quot;246.6&quot; rx=&quot;3&quot; fill=&quot;#7d74d4&quot; /&gt;
      &lt;g fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot; font-weight=&quot;600&quot; text-anchor=&quot;middle&quot;&gt;
        &lt;text x=&quot;123&quot; y=&quot;242.6&quot;&gt;5M&lt;/text&gt;
        &lt;text x=&quot;241&quot; y=&quot;197.3&quot;&gt;60M&lt;/text&gt;
        &lt;text x=&quot;359&quot; y=&quot;133.4&quot;&gt;2B&lt;/text&gt;
        &lt;text x=&quot;477&quot; y=&quot;25.4&quot;&gt;744B&lt;/text&gt;
      &lt;/g&gt;
      &lt;g fill=&quot;currentColor&quot; fill-opacity=&quot;0.85&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;12&quot; text-anchor=&quot;middle&quot;&gt;
        &lt;text x=&quot;123&quot; y=&quot;302&quot;&gt;MobileNetV3&lt;/text&gt;
        &lt;text x=&quot;241&quot; y=&quot;302&quot;&gt;AlexNet&lt;/text&gt;
        &lt;text x=&quot;359&quot; y=&quot;302&quot;&gt;Qwen 3.5&lt;/text&gt;
        &lt;text x=&quot;477&quot; y=&quot;302&quot;&gt;GLM 5.2&lt;/text&gt;
      &lt;/g&gt;
    &lt;/svg&gt;
  &lt;/noscript&gt;
  &lt;div class=&quot;js-widget&quot;&gt;
    &lt;div class=&quot;sub&quot;&gt;1 box = 10,000,000 parameters &amp;middot; 1 column = 20 boxes (200M) &amp;middot; drag, scroll, or use the arrows to move right&lt;/div&gt;
    &lt;div class=&quot;ctl&quot;&gt;
      &lt;button class=&quot;arw&quot; id=&quot;nn-left&quot; aria-label=&quot;Scroll left&quot;&gt;&amp;#8592;&lt;/button&gt;
      &lt;div class=&quot;prog&quot;&gt;&lt;div class=&quot;bar&quot; id=&quot;nn-bar&quot;&gt;&lt;/div&gt;&lt;/div&gt;
      &lt;button class=&quot;arw&quot; id=&quot;nn-right&quot; aria-label=&quot;Scroll right&quot;&gt;&amp;#8594;&lt;/button&gt;
    &lt;/div&gt;
    &lt;div class=&quot;jmp&quot;&gt;
      &lt;span&gt;Jump to:&lt;/span&gt;
      &lt;button data-k=&quot;alex&quot;&gt;AlexNet&lt;/button&gt;
      &lt;button data-k=&quot;mobile&quot;&gt;MobileNetV3&lt;/button&gt;
      &lt;button data-k=&quot;qwen&quot;&gt;Qwen&lt;/button&gt;
      &lt;button data-k=&quot;glm&quot;&gt;GLM start&lt;/button&gt;
      &lt;button data-k=&quot;glmend&quot;&gt;GLM end&lt;/button&gt;
    &lt;/div&gt;
    &lt;div class=&quot;scr&quot; id=&quot;nn-scr&quot; tabindex=&quot;0&quot; aria-label=&quot;Scrollable parameter-count comparison&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;script&gt;
(function(){
  document.getElementById(&quot;nnscale&quot;).classList.add(&quot;js&quot;);
  var NS=&quot;http://www.w3.org/2000/svg&quot;;
  function el(t,a,p){var e=document.createElementNS(NS,t);for(var k in a){e.setAttribute(k,a[k]);}if(p)p.appendChild(e);return e;}
  function css(e,props){for(var k in props){e.style[k]=props[k];}}
  var COL_H=20,PITCH=12,BOX=10;
  var gridTop=96,GRID_H=COL_H*PITCH,gridBottom=gridTop+GRID_H,H=440;
  var LABEL_W=150,SLOT_GAP=28,mL=24;
  var C={alex:&quot;var(--diagram-orange)&quot;,mobile:&quot;var(--diagram-teal)&quot;,qwen:&quot;var(--diagram-pink)&quot;,glm:&quot;var(--diagram-indigo)&quot;,active:&quot;var(--diagram-green)&quot;};
  var models=[
    {k:&quot;alex&quot;,boxes:6,params:&quot;60M&quot;,color:C.alex,mode:&quot;rects&quot;,
     desc:&quot;AlexNet: Image classifier. Popularised large neural networks for image recognition (2012)&quot;},
    {k:&quot;mobile&quot;,boxes:0.5,params:&quot;5M&quot;,color:C.mobile,mode:&quot;half&quot;,
     desc:&quot;MobileNetV3: Modern image classifier. Stand-in for our bird classifier. Can run on your phone (2019).&quot;},
    {k:&quot;qwen&quot;,boxes:200,params:&quot;2B&quot;,color:C.qwen,mode:&quot;pattern&quot;,
     desc:&quot;Qwen 3.5-2B. Small language model (Feb 2026).&quot;},
    {k:&quot;glm&quot;,boxes:74400,params:&quot;744B&quot;,color:C.glm,mode:&quot;pattern&quot;,
     desc:&quot;GLM 5.2. Frontier large language model (June 2026).&quot;}
  ];
  var pos={},x=mL;
  models.forEach(function(m){m.x=x;pos[m.k]=x;m.cols=Math.ceil(m.boxes/COL_H);m.gridW=m.cols*PITCH;m.slotW=Math.max(m.gridW,LABEL_W);x+=m.slotW+SLOT_GAP;});
  var glmX=pos.glm,glmEndX=glmX+3720*PITCH,totalW=glmEndX+270;

  var scr=document.getElementById(&quot;nn-scr&quot;);
  var svg=el(&quot;svg&quot;,{viewBox:&quot;0 0 &quot;+totalW+&quot; &quot;+H,width:totalW,height:H,role:&quot;img&quot;,&quot;aria-label&quot;:&quot;Parameter-count comparison of four neural networks, to scale.&quot;});
  svg.style.width=totalW+&quot;px&quot;;svg.style.height=H+&quot;px&quot;;
  var defs=el(&quot;defs&quot;,{},svg);
  function pat(id,fill){var p=el(&quot;pattern&quot;,{id:id,width:PITCH,height:PITCH,patternUnits:&quot;userSpaceOnUse&quot;},defs);el(&quot;rect&quot;,{x:1,y:1,width:BOX,height:BOX,rx:1.5,fill:fill},p);}
  pat(&quot;nn-pat-qwen&quot;,C.qwen);pat(&quot;nn-pat-glm&quot;,C.glm);

  var gridLine1=el(&quot;line&quot;,{x1:0,y1:gridBottom+0.5,x2:totalW,y2:gridBottom+0.5,&quot;stroke-width&quot;:1},svg);css(gridLine1,{stroke:&quot;var(--border)&quot;});
  var gridLine2=el(&quot;line&quot;,{x1:0,y1:gridTop-0.5,x2:totalW,y2:gridTop-0.5,&quot;stroke-width&quot;:1},svg);css(gridLine2,{stroke:&quot;var(--border)&quot;});

  models.forEach(function(m){
    if(m.mode===&quot;rects&quot;){
      for(var i=0;i&lt;m.boxes;i++){var ty=gridBottom-(i+1)*PITCH;el(&quot;rect&quot;,{x:m.x+1,y:ty+1,width:BOX,height:BOX,rx:1.5,fill:m.color},svg);}
    }else if(m.mode===&quot;half&quot;){
      var t=gridBottom-PITCH;
      el(&quot;rect&quot;,{x:m.x+1,y:t+1,width:BOX,height:BOX,rx:1.5,fill:&quot;none&quot;,stroke:m.color,&quot;stroke-width&quot;:1,&quot;stroke-dasharray&quot;:&quot;2 1.5&quot;,opacity:.75},svg);
      el(&quot;rect&quot;,{x:m.x+1,y:t+1+BOX/2,width:BOX,height:BOX/2,rx:1.5,fill:m.color},svg);
    }else{
      var patId=m.k===&quot;qwen&quot;?&quot;nn-pat-qwen&quot;:&quot;nn-pat-glm&quot;;
      if(m.k===&quot;qwen&quot;){var g=el(&quot;g&quot;,{transform:&quot;translate(&quot;+m.x+&quot;,&quot;+gridTop+&quot;)&quot;},svg);el(&quot;rect&quot;,{x:0,y:0,width:m.gridW,height:GRID_H,fill:&quot;url(#&quot;+patId+&quot;)&quot;},g);}
      else{var s=0;while(s&lt;3720){var c=Math.min(300,3720-s);var gg=el(&quot;g&quot;,{transform:&quot;translate(&quot;+(glmX+s*PITCH)+&quot;,&quot;+gridTop+&quot;)&quot;},svg);el(&quot;rect&quot;,{x:0,y:0,width:c*PITCH,height:GRID_H,fill:&quot;url(#&quot;+patId+&quot;)&quot;},gg);s+=c;}}
    }
  });

  for(var cc=200;cc&lt;=3600;cc+=200){var lx=glmX+cc*PITCH;var gl=el(&quot;line&quot;,{x1:lx,y1:gridTop,x2:lx,y2:gridBottom,&quot;stroke-width&quot;:1,opacity:.35},svg);css(gl,{stroke:&quot;currentColor&quot;});var tl=el(&quot;text&quot;,{x:lx,y:gridTop-7,&quot;font-size&quot;:11,&quot;text-anchor&quot;:&quot;middle&quot;},svg);css(tl,{fill:&quot;var(--text-muted)&quot;});tl.textContent=Math.round(cc*0.2)+&quot;B&quot;;}
  var glEnd=el(&quot;line&quot;,{x1:glmEndX,y1:gridTop,x2:glmEndX,y2:gridBottom,&quot;stroke-width&quot;:1.5,opacity:.6},svg);css(glEnd,{stroke:&quot;currentColor&quot;});
  var t744=el(&quot;text&quot;,{x:glmEndX,y:gridTop-7,&quot;font-size&quot;:11,&quot;text-anchor&quot;:&quot;middle&quot;,&quot;font-weight&quot;:500},svg);css(t744,{fill:&quot;var(--text-secondary)&quot;});t744.textContent=&quot;744B&quot;;

  el(&quot;rect&quot;,{x:glmX,y:gridTop,width:200*PITCH,height:GRID_H,fill:C.active,opacity:.28},svg);
  el(&quot;rect&quot;,{x:glmX,y:gridTop,width:10*PITCH,height:GRID_H,fill:C.qwen,opacity:.38},svg);

  function chip(cx,cy,txt,col){var w=txt.length*6.1+18;var g=el(&quot;g&quot;,{},svg);var r=el(&quot;rect&quot;,{x:cx,y:cy,width:w,height:22,rx:6,&quot;stroke-width&quot;:.5},g);css(r,{fill:&quot;var(--surface-2)&quot;,stroke:&quot;var(--border)&quot;});var tx=el(&quot;text&quot;,{x:cx+9,y:cy+15,&quot;font-size&quot;:11},g);css(tx,{fill:col||&quot;var(--text-primary)&quot;});tx.textContent=txt;return w;}
  chip(glmX+10*PITCH+8,gridTop+6,&quot;\u2190 all of Qwen (2B) fits in this sliver&quot;,C.qwen);
  chip(glmX+10*PITCH+8,gridTop+32,&quot;\u2190 AlexNet, MobileNetV3 &amp; Qwen all end here&quot;,&quot;var(--text-secondary)&quot;);
  chip(glmX+10*PITCH+8,gridTop+58,&quot;GLM 5.2 keeps going for ~64 screens \u2192&quot;,&quot;var(--text-secondary)&quot;);
  chip(glmX+200*PITCH+8,gridTop+6,&quot;\u2190 all of GLM 5.2's activated parameters per token&quot;,C.active);

  var tEnd1=el(&quot;text&quot;,{x:glmEndX+14,y:gridTop+14,&quot;font-size&quot;:13,&quot;font-weight&quot;:500},svg);css(tEnd1,{fill:&quot;var(--text-primary)&quot;});tEnd1.textContent=&quot;GLM 5.2 ends here&quot;;
  var tEnd2=el(&quot;text&quot;,{x:glmEndX+14,y:gridTop+32,&quot;font-size&quot;:11},svg);css(tEnd2,{fill:&quot;var(--text-secondary)&quot;});tEnd2.textContent=&quot;744,000,000,000 parameters&quot;;
  var tEnd3=el(&quot;text&quot;,{x:glmEndX+14,y:gridTop+48,&quot;font-size&quot;:11},svg);css(tEnd3,{fill:&quot;var(--text-muted)&quot;});tEnd3.textContent=&quot;= 74,400 boxes \u00b7 3,720 columns&quot;;

  function wrap(s,max){var w=s.split(&quot; &quot;),ln=[],cur=&quot;&quot;;for(var i=0;i&lt;w.length;i++){var test=(cur+&quot; &quot;+w[i]).trim();if(test.length&gt;max&amp;&amp;cur){ln.push(cur);cur=w[i];}else cur=test;}if(cur)ln.push(cur);return ln;}
  models.forEach(function(m){
    var pl=el(&quot;text&quot;,{x:m.x,y:82,&quot;font-size&quot;:16,&quot;font-weight&quot;:500},svg);css(pl,{fill:&quot;var(--text-primary)&quot;});pl.textContent=m.params;
    var t=el(&quot;text&quot;,{x:m.x,y:356,&quot;font-size&quot;:11},svg);css(t,{fill:&quot;var(--text-secondary)&quot;});
    wrap(m.desc,24).forEach(function(ln,i){el(&quot;tspan&quot;,{x:m.x,dy:i===0?0:14},t).textContent=ln;});
  });

  scr.appendChild(svg);

  var left=document.getElementById(&quot;nn-left&quot;),right=document.getElementById(&quot;nn-right&quot;),bar=document.getElementById(&quot;nn-bar&quot;);
  function upd(){var max=scr.scrollWidth-scr.clientWidth,sl=scr.scrollLeft;left.disabled=sl&lt;=1;right.disabled=sl&gt;=max-1;bar.style.width=(max&lt;=0?0:Math.round(sl/max*100))+&quot;%&quot;;}
  left.addEventListener(&quot;click&quot;,function(){scr.scrollBy({left:-scr.clientWidth*0.85,behavior:&quot;smooth&quot;});});
  right.addEventListener(&quot;click&quot;,function(){scr.scrollBy({left:scr.clientWidth*0.85,behavior:&quot;smooth&quot;});});
  scr.addEventListener(&quot;scroll&quot;,upd,{passive:true});
  window.addEventListener(&quot;resize&quot;,upd);
  document.querySelectorAll(&quot;#nnscale .jmp button&quot;).forEach(function(b){b.addEventListener(&quot;click&quot;,function(){var k=b.getAttribute(&quot;data-k&quot;);if(k===&quot;glmend&quot;){scr.scrollTo({left:scr.scrollWidth-scr.clientWidth,behavior:&quot;smooth&quot;});}else{scr.scrollTo({left:Math.max(0,pos[k]-24),behavior:&quot;smooth&quot;});}});});
  var drag=false,sx=0,sl0=0;
  scr.addEventListener(&quot;pointerdown&quot;,function(e){drag=true;sx=e.clientX;sl0=scr.scrollLeft;scr.setPointerCapture(e.pointerId);scr.style.cursor=&quot;grabbing&quot;;});
  scr.addEventListener(&quot;pointermove&quot;,function(e){if(drag)scr.scrollLeft=sl0-(e.clientX-sx);});
  scr.addEventListener(&quot;pointerup&quot;,function(){drag=false;scr.style.cursor=&quot;grab&quot;;});
  scr.addEventListener(&quot;wheel&quot;,function(e){if(Math.abs(e.deltaY)&gt;Math.abs(e.deltaX)){scr.scrollLeft+=e.deltaY;e.preventDefault();}},{passive:false});
  upd();
})();
&lt;/script&gt;

            &lt;h3&gt;Why Do They Need to Be So Big?&lt;/h3&gt;
            &lt;p&gt;Even without fully knowing exactly what models of these sizes mean in practical terms (which we will discuss later), you might appreciate that it is quite substantial for a large language model to be potentially hundreds of thousands of times larger than our little bird classifier, and it is reasonable to ask why. In short, this is because language is simply much, much more complicated than bird identification.&lt;/p&gt;

            &lt;p&gt;Realistically, to identify a bird, you only need to look for a narrow, bounded set of patterns. Fiddler crabs, for example, can distinguish between predatory birds and those that are harmlessly passing by &lt;a href=&quot;#fn-4&quot;&gt;[4]&lt;/a&gt;. They do not need very complex eyes to do this &amp;mdash; when they respond, a distant bird may only be visible to one or two of the facets in their compound eyes, making its shape impossible to make out &amp;mdash; yet they are still able to perform the threat detection they need to survive.&lt;/p&gt;

            &lt;p&gt;Conversely, we humans are the only living creatures who use an open-ended language. Not all of our comparatively enormous brains go into language processing, but their size tells us something about the sheer scale of what language processing requires in nature. Even though artificial and biological neural networks are very different, the scale required for language processing remains enormous in both. Patterns in language are so complex and so open-ended that the odds are good that most of the sentences in this article have never been written before by anyone, yet you are still able to understand what they mean. That is the complexity of language, and that complexity is why LLMs are so large.&lt;/p&gt;

            &lt;p&gt;While a smaller language model might learn common sentence structures, very well-known facts, or the content of influential literature, at a certain point it becomes increasingly difficult for new information to be represented in the model's weights without interfering with something else (and potentially something important). A model with only a few dozen parameters obviously couldn't learn much that's useful &amp;mdash; virtually nothing in the grand scheme of language &amp;mdash; but the same limitation applies even to models with billions of parameters. There might be highly uncommon patterns that have not appeared frequently enough in language to be learned, such as how to write a program that does something unusual and specific in an uncommon programming language. Other patterns might be so deep and complex that they require mountains of background knowledge to make accurate next-token predictions about, such as the solutions to long-standing mathematical problems.&lt;/p&gt;

            &lt;p&gt;As the number of parameters and the amount of text we train our models on go up, the complexity of the relationships they can represent grows as well. This is especially true for complex problem-solving. Logical problems, often represented as code or mathematics, can require models to combine and use a huge number of different patterns and a great deal of background information. Larger models have more capacity to represent these patterns than smaller ones, so increasing the size of a model is one important way of enhancing its capabilities &lt;a href=&quot;#fn-5&quot;&gt;[5]&lt;/a&gt;.&lt;/p&gt;

            &lt;h2&gt;A Recipe for an LLM&lt;/h2&gt;
            &lt;p&gt;If you wanted to train an LLM of your own, there are three things that you would need:&lt;/p&gt;
            &lt;ol&gt;
              &lt;li&gt;Plenty of model parameters, in the right shape (sometimes called the model's &lt;b&gt;architecture&lt;/b&gt;)&lt;/li&gt;
              &lt;li&gt;Lots of powerful computers (the amount of processing power going into a model is sometimes just called &lt;b&gt;compute&lt;/b&gt;)&lt;/li&gt;
              &lt;li&gt;Lots of training data (sometimes called a training &lt;b&gt;corpus&lt;/b&gt;)&lt;/li&gt;
            &lt;/ol&gt;
            &lt;p&gt;Understanding each of these ingredients will help to explain why the industry looks and acts the way it does.&lt;/p&gt;

            &lt;h3&gt;Doing Lots of Maths Quickly &amp;mdash; Graphics Processing Units&lt;/h3&gt;
            &lt;p&gt;We've already talked about the number of parameters in these models, so we'll continue on to &lt;b&gt;compute&lt;/b&gt;. For the sake of brevity, this series has not discussed the actual maths behind machine learning. For most people, the specific calculations are not all that important, but to really make sense of the AI boom, there are some things about them that you do need to know.&lt;/p&gt;

            &lt;p&gt;In truth, if you really wanted to and had more than a human lifetime, you could do all the maths to predict the next token in a sequence with pen and paper. Mathematically, no single operation in an LLM is really all that complicated. The problem is that with just one brain and one writing hand, you would have to do every single calculation one after another, in sequence. We call this a &lt;b&gt;serial&lt;/b&gt; operation.&lt;/p&gt;

            &lt;p&gt;Most operations in an LLM don't actually require this, though. Consider the following equation: &lt;b&gt;3 &amp;times; 2 + 1 = ?&lt;/b&gt;. To solve this equation, you have to perform each operation one at a time. First, 3 &amp;times; 2 = 6. Then, 6 + 1 = 7. Each operation depends on the last one.&lt;/p&gt;

            &lt;p&gt;On the other hand, consider &lt;b&gt;2 &amp;times; 3 + 4 &amp;times; 5 = ?&lt;/b&gt;. In this case, there are three calculations to be made:&lt;/p&gt;
            &lt;ol&gt;
              &lt;li&gt;2 &amp;times; 3 = 6&lt;/li&gt;
              &lt;li&gt;4 &amp;times; 5 = 20&lt;/li&gt;
              &lt;li&gt;6 + 20 = 26&lt;/li&gt;
            &lt;/ol&gt;

            &lt;p&gt;Notice that you don't need the answer for Step 1 in order to get the answer for Step 2. If you had a friend doing the maths with you, you could do Step 1 while they did Step 2, and once you were both done, you could move to Step 3. Steps 1 and 2 can be done &lt;b&gt;in parallel&lt;/b&gt;, which saves you the time of doing one and then the other.&lt;/p&gt;

            &lt;p&gt;In machine learning, we very much want to make everything as parallel as possible. The &lt;b&gt;Graphics Processing Unit&lt;/b&gt; (GPU) is a special component in a computer designed to do maths in parallel &lt;a href=&quot;#fn-6&quot;&gt;[6]&lt;/a&gt;. No single worker in a GPU is terribly complex, but there are thousands of them, all able to calculate at the same time. This is important because prior to the use of GPUs, machine learning was a prohibitively slow process. Detecting a single bird with our little five-million-parameter model might take something like 200 million individual calculations, which is just too many to do one at a time. GPUs, performing many operations in parallel, make the process of both training and using ML models substantially faster. For multi-billion-parameter language models, you could be looking at billions of individual calculations to generate just one token. This is why, if you hear people talking about the computers running AI models, the GPUs in those computers are the most important factor.&lt;/p&gt;

            &lt;h3&gt;Training Data&lt;/h3&gt;
            &lt;p&gt;The third ingredient you'll need for your LLM is training data, and a lot of it. Generally speaking, the more parameters you have, the more training data you need. Recall from our bird classifier that the training data we needed was a stack of photos with and without birds, and labels indicating which was which. The photos are the input, the labels are the output we expect. In the case of a model answering &lt;i&gt;&quot;which token comes next?&quot;&lt;/i&gt;, our input will be all the tokens so far, and our output will be the very next one.&lt;/p&gt;

            &lt;p&gt;Helpfully, this means that we can take a single sentence and split it into as many input/output pairs as there are tokens in the sentence.&lt;/p&gt;

            &lt;svg width=&quot;100%&quot; viewBox=&quot;0 0 560 330&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; style=&quot;max-width: 560px; display: block; margin: 20px auto;&quot;&gt;
              &lt;text x=&quot;280&quot; y=&quot;24&quot; text-anchor=&quot;middle&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;14&quot; font-weight=&quot;bold&quot;&gt;Starting sentence: &quot;Brevity is the soul of wit.&quot;&lt;/text&gt;
              &lt;text x=&quot;280&quot; y=&quot;42&quot; text-anchor=&quot;middle&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;12&quot; opacity=&quot;0.7&quot;&gt;1 sentence &amp;middot; 6 input/output pairs&lt;/text&gt;

              &lt;text x=&quot;110&quot; y=&quot;68&quot; text-anchor=&quot;middle&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot; font-weight=&quot;bold&quot;&gt;Input&lt;/text&gt;
              &lt;text x=&quot;440&quot; y=&quot;68&quot; text-anchor=&quot;middle&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot; font-weight=&quot;bold&quot;&gt;Output&lt;/text&gt;

              &lt;line x1=&quot;18&quot; y1=&quot;78&quot; x2=&quot;218&quot; y2=&quot;78&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1&quot; opacity=&quot;0.3&quot; /&gt;
              &lt;line x1=&quot;340&quot; y1=&quot;78&quot; x2=&quot;540&quot; y2=&quot;78&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1&quot; opacity=&quot;0.3&quot; /&gt;

              &lt;rect x=&quot;18&quot; y=&quot;88&quot; width=&quot;200&quot; height=&quot;26&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-blue)&quot; fill-opacity=&quot;0.15&quot; stroke=&quot;var(--diagram-blue)&quot; stroke-width=&quot;1&quot; /&gt;
              &lt;text x=&quot;118&quot; y=&quot;106&quot; text-anchor=&quot;middle&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot;&gt;Brevity&lt;/text&gt;

              &lt;rect x=&quot;340&quot; y=&quot;88&quot; width=&quot;200&quot; height=&quot;26&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-green)&quot; fill-opacity=&quot;0.15&quot; stroke=&quot;var(--diagram-green)&quot; stroke-width=&quot;1&quot; /&gt;
              &lt;text x=&quot;440&quot; y=&quot;106&quot; text-anchor=&quot;middle&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot;&gt;is&lt;/text&gt;

              &lt;rect x=&quot;18&quot; y=&quot;124&quot; width=&quot;200&quot; height=&quot;26&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-blue)&quot; fill-opacity=&quot;0.15&quot; stroke=&quot;var(--diagram-blue)&quot; stroke-width=&quot;1&quot; /&gt;
              &lt;text x=&quot;118&quot; y=&quot;142&quot; text-anchor=&quot;middle&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot;&gt;Brevity is&lt;/text&gt;

              &lt;rect x=&quot;340&quot; y=&quot;124&quot; width=&quot;200&quot; height=&quot;26&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-green)&quot; fill-opacity=&quot;0.15&quot; stroke=&quot;var(--diagram-green)&quot; stroke-width=&quot;1&quot; /&gt;
              &lt;text x=&quot;440&quot; y=&quot;142&quot; text-anchor=&quot;middle&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot;&gt;the&lt;/text&gt;

              &lt;rect x=&quot;18&quot; y=&quot;160&quot; width=&quot;200&quot; height=&quot;26&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-blue)&quot; fill-opacity=&quot;0.15&quot; stroke=&quot;var(--diagram-blue)&quot; stroke-width=&quot;1&quot; /&gt;
              &lt;text x=&quot;118&quot; y=&quot;178&quot; text-anchor=&quot;middle&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot;&gt;Brevity is the&lt;/text&gt;

              &lt;rect x=&quot;340&quot; y=&quot;160&quot; width=&quot;200&quot; height=&quot;26&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-green)&quot; fill-opacity=&quot;0.15&quot; stroke=&quot;var(--diagram-green)&quot; stroke-width=&quot;1&quot; /&gt;
              &lt;text x=&quot;440&quot; y=&quot;178&quot; text-anchor=&quot;middle&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot;&gt;soul&lt;/text&gt;

              &lt;rect x=&quot;18&quot; y=&quot;196&quot; width=&quot;200&quot; height=&quot;26&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-blue)&quot; fill-opacity=&quot;0.15&quot; stroke=&quot;var(--diagram-blue)&quot; stroke-width=&quot;1&quot; /&gt;
              &lt;text x=&quot;118&quot; y=&quot;214&quot; text-anchor=&quot;middle&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot;&gt;Brevity is the soul&lt;/text&gt;

              &lt;rect x=&quot;340&quot; y=&quot;196&quot; width=&quot;200&quot; height=&quot;26&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-green)&quot; fill-opacity=&quot;0.15&quot; stroke=&quot;var(--diagram-green)&quot; stroke-width=&quot;1&quot; /&gt;
              &lt;text x=&quot;440&quot; y=&quot;214&quot; text-anchor=&quot;middle&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot;&gt;of&lt;/text&gt;

              &lt;rect x=&quot;18&quot; y=&quot;232&quot; width=&quot;200&quot; height=&quot;26&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-blue)&quot; fill-opacity=&quot;0.15&quot; stroke=&quot;var(--diagram-blue)&quot; stroke-width=&quot;1&quot; /&gt;
              &lt;text x=&quot;118&quot; y=&quot;250&quot; text-anchor=&quot;middle&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot;&gt;Brevity is the soul of&lt;/text&gt;

              &lt;rect x=&quot;340&quot; y=&quot;232&quot; width=&quot;200&quot; height=&quot;26&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-green)&quot; fill-opacity=&quot;0.15&quot; stroke=&quot;var(--diagram-green)&quot; stroke-width=&quot;1&quot; /&gt;
              &lt;text x=&quot;440&quot; y=&quot;250&quot; text-anchor=&quot;middle&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot;&gt;wit&lt;/text&gt;

              &lt;rect x=&quot;18&quot; y=&quot;268&quot; width=&quot;200&quot; height=&quot;26&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-blue)&quot; fill-opacity=&quot;0.15&quot; stroke=&quot;var(--diagram-blue)&quot; stroke-width=&quot;1&quot; /&gt;
              &lt;text x=&quot;118&quot; y=&quot;286&quot; text-anchor=&quot;middle&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot;&gt;Brevity is the soul of wit&lt;/text&gt;

              &lt;rect x=&quot;340&quot; y=&quot;268&quot; width=&quot;200&quot; height=&quot;26&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-green)&quot; fill-opacity=&quot;0.15&quot; stroke=&quot;var(--diagram-green)&quot; stroke-width=&quot;1&quot; /&gt;
              &lt;text x=&quot;440&quot; y=&quot;286&quot; text-anchor=&quot;middle&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot;&gt;.&lt;/text&gt;
            &lt;/svg&gt;

            &lt;p&gt;Large models, though, mean lots of training data, so where do we get it? There are a few criteria we care about:&lt;/p&gt;
            &lt;ol&gt;
              &lt;li&gt;We want an absolutely massive quantity of text.&lt;/li&gt;
              &lt;li&gt;We want it to reflect patterns in real language, meaning we'd prefer a good deal of it to be written by real people.&lt;/li&gt;
              &lt;li&gt;We want it to contain as much information about the world as possible, from a variety of different perspectives, so that our model can predict words about as many topics as possible.&lt;/li&gt;
            &lt;/ol&gt;

            &lt;p&gt;Bigger models tend to be better at making predictions, but they also need a lot more data to train on, so at this point, most people training LLMs will take very large amounts of text from a wide variety of places. The best sources will typically be books (especially textbooks) and academic papers because, compared with other media, they are usually fairly well-written and have hopefully been checked by plenty of people to make sure what they say is true.&lt;/p&gt;

            &lt;p&gt;This is &quot;high quality&quot; data, but unfortunately, writing books takes a lot of time and effort, so there aren't nearly as many tokens in textbooks as there are on the internet. We'll use quite a bit of the public internet too. A corpus might include Wikipedia articles, forum posts, personal websites, and comment sections. If we want LLMs to write programs, then we'll add a large amount of code as well &lt;a href=&quot;#fn-7&quot;&gt;[7]&lt;/a&gt;. There is quite a bit of filtering involved here too, though. Labs training LLMs will usually try to remove duplicate material (we don't need one thousand identical copies of &lt;i&gt;Hamlet&lt;/i&gt;; just one is enough), filter out garbage or unsavoury content, and so on.&lt;/p&gt;

            &lt;p&gt;I recognise that there is an elephant in the room with &quot;What about copyright?&quot; painted on its side. This series is intended to cover the technical side of LLMs, so for the moment we will not be addressing this problem. Exactly how we acquire training data (or the compute, for that matter) is a legal, political, and economic question for another day.&lt;/p&gt;

            &lt;h3&gt;Pre-Training&lt;/h3&gt;
            &lt;p&gt;So we have our model: the number of parameters and the architecture we want. We have our compute: the GPUs capable of performing highly parallel calculations. And we have our training data: a huge set of many trillions of tokens, written by people as much as possible. From these, we will create a usable LLM in two stages: pre-training and post-training.&lt;/p&gt;

            &lt;p&gt;Pre-training is very straightforward. We take our model and train it to predict the next token, using all the text we've accumulated. This can take days, weeks, or even months, depending on the size of the model and the training data, the amount of compute we have, the exact training settings we use, and whether we need to tweak those settings and try again. Pre-training is typically when the model sees the bulk of the actual data it will ever train on. It contains vast quantities of information, and so most of what a model &quot;knows&quot; is trained into it during this stage.&lt;/p&gt;

            &lt;h3&gt;Post-Training&lt;/h3&gt;
            &lt;p&gt;Once we're satisfied that our LLM trained on a large, processed mixture of internet data and other sources is sufficiently not-wrong about its predictions, we have what is sometimes called a &quot;base&quot; model. The problem is that virtually none of that text will look much like a conversation with ChatGPT or Claude &lt;a href=&quot;#fn-8&quot;&gt;[8]&lt;/a&gt;. We want our LLM to produce text that looks something like this:&lt;/p&gt;

            &lt;blockquote&gt;
              &lt;p&gt;PERSON: &quot;You are a helpful AI assistant. What is the capital of France?&quot;&lt;/p&gt;
              &lt;p&gt;ASSISTANT: &quot;The capital of France is Paris. Would you like me to help you plan a visit?&quot;&lt;/p&gt;
            &lt;/blockquote&gt;

            &lt;p&gt;Most people will not have written anything like that by hand, so there will be very little for our base model to have learned. Without teaching it how to talk like an AI assistant, it might end up saying something like:&lt;/p&gt;

            &lt;blockquote&gt;
              &lt;p&gt;PERSON: &quot;You are a helpful AI assistant. What is the capital of France?&quot;&lt;/p&gt;
              &lt;p&gt;ASSISTANT: &quot;The capital of France is:&lt;/p&gt;
              &lt;p&gt;1. Berlin&lt;/p&gt;
              &lt;p&gt;2. Paris&lt;/p&gt;
              &lt;p&gt;3. London&lt;/p&gt;
              &lt;p&gt;4. Rome&quot;&lt;/p&gt;
            &lt;/blockquote&gt;

            &lt;p&gt;In a case like this, the training data might have included a large amount of text from quizzes or homework, so the model continued the prompt as though it were writing a quiz rather than answering as an AI assistant. To solve this problem, we need to teach our model how we want an AI assistant to actually talk. This is the &lt;b&gt;post-training&lt;/b&gt; phase. If the pre-training phase taught the model what it &lt;i&gt;knows&lt;/i&gt;, the post-training phase will teach it how we want it to &lt;i&gt;behave&lt;/i&gt;.&lt;/p&gt;

            &lt;p&gt;Post-training can involve several approaches, often used in combination:&lt;/p&gt;
            &lt;ul&gt;
              &lt;li&gt;Write a large corpus of assistant-style interactions manually and train the base model on them. This would involve a huge number of manually written conversations, so it may supplement the main approach rather than replace it.&lt;/li&gt;
              &lt;li&gt;Get the model to produce output, have a large team of people grade how closely it resembles the output of a good assistant, and train the model to be as not-wrong as it can about how we want it to sound.&lt;/li&gt;
              &lt;li&gt;Get the model to solve mathematical problems, check the answers automatically with a calculator, and train it to be not-wrong about the answers.&lt;/li&gt;
              &lt;li&gt;Get the model to produce code, check it automatically with code tests, and train it to be not-wrong about code that passes those tests.&lt;/li&gt;
            &lt;/ul&gt;

            &lt;p&gt;Companies training LLMs aim to encourage many different types of behaviour. I intend to discuss them in detail in a later article &lt;!-- TODO: Link to &quot;6 - Chatbots, Agents, and LLMs in Practice&quot; once published --&gt;, but some might include:&lt;/p&gt;
            &lt;ul&gt;
              &lt;li&gt;Talking to users in a warm and friendly manner&lt;/li&gt;
              &lt;li&gt;Telling the truth about facts it has good information about&lt;/li&gt;
              &lt;li&gt;Refusing requests for illegal material and avoiding offence&lt;/li&gt;
              &lt;li&gt;Resisting attempts by users to bypass those restrictions&lt;/li&gt;
              &lt;li&gt;Using the particular textual structure we want when asking to use external tools&lt;/li&gt;
            &lt;/ul&gt;

            &lt;p&gt;The way this feedback is provided will differ depending on the task, but it is ultimately used to update the model's weights, making assistant-like or correct responses more likely while undesirable ones become less likely.&lt;/p&gt;

            &lt;h2&gt;Failure and Success&lt;/h2&gt;
            &lt;p&gt;While making models gigantic and subjecting them to extensive post-training has resulted in some remarkable systems, at the end of the day, LLMs are still trained to predict &lt;i&gt;likely&lt;/i&gt; continuations to their input text. They do not possess some readable, internal list of facts and rules that either they or we could refer to; all they have are patterns and predictions. Just because a token is &lt;i&gt;likely&lt;/i&gt; to come next does not mean that the sentence produced by selecting that token is actually true or helpful. This is one of the most common failure modes that LLMs of any size suffer, and we will discuss it next time.&lt;/p&gt;
          &lt;/section&gt;
          &lt;hr /&gt;
          &lt;section&gt;
            &lt;p id=&quot;fn-1&quot;&gt;[1] &lt;a href=&quot;https://proceedings.neurips.cc/paper_files/paper/2012/file/c399862d3b9d6b76c8436e924a68c45b-Paper.pdf&quot;&gt;&lt;i&gt;AlexNet&lt;/i&gt;&lt;/a&gt;, which was a historically significant image recognition model published in 2012, had about 60,000,000 parameters. This was very large for the time.&lt;/p&gt;
            &lt;p id=&quot;fn-2&quot;&gt;[2] Many LLMs this big are not designed to use all of their hundreds of billions of parameters at the same time. For example, GLM 5.2, represented in the size comparison, only activates 40 billion parameters per token, though this is still an enormous number.&lt;/p&gt;
            &lt;p id=&quot;fn-3&quot;&gt;[3] &quot;Small Language Model&quot; doesn't really have a hard-and-fast definition. Ten billion parameters is my estimate for when people would probably stop calling them small, but it's a relative term, so that number may grow if top LLMs get much bigger, or shrink if they get smaller.&lt;/p&gt;
            &lt;p id=&quot;fn-4&quot;&gt;[4] See Smolka, Zeil, and Hemmi, &lt;a href=&quot;https://doi.org/10.1098/rspb.2010.2746&quot;&gt;&lt;i&gt;Natural visual cues eliciting predator avoidance in fiddler crabs&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;
            &lt;p id=&quot;fn-5&quot;&gt;[5] This does get a little complicated. LLMs are not like hard drives in that they have measurable &quot;used&quot; and &quot;free&quot; space. The information they contain will be spread throughout their weights, and often in ways that are hard to explain or keep track of in human terms. Nonetheless, it remains true that a greater number of parameters means a greater potential for representing patterns.&lt;/p&gt;
            &lt;p id=&quot;fn-6&quot;&gt;[6] GPUs contrast with &lt;b&gt;CPUs&lt;/b&gt; (Central Processing Units). CPUs are designed to do complex tasks and can usually do them fairly quickly, but do not have as many workers able to act at the same time as GPUs. The &quot;Graphics&quot; in GPU comes from the fact that many tasks requiring drawing things to the screen can also be done in parallel, particularly gaming and digital art or sculpting work.&lt;/p&gt;
            &lt;p id=&quot;fn-7&quot;&gt;[7] Interestingly, learning to write code also has the upside of teaching LLMs something of logical structure, which can help them in other domains as well. See &lt;a href=&quot;https://research.google/pubs/how-does-code-pretraining-affect-language-model-task-performance&quot;&gt;Petty et al.&lt;/a&gt; and &lt;a href=&quot;https://proceedings.iclr.cc/paper_files/paper/2025/hash/c513d1786f85531fac7050947736265f-Abstract-Conference.html&quot;&gt;Aryabumi et al.&lt;/a&gt;&lt;/p&gt;
            &lt;p id=&quot;fn-8&quot;&gt;[8] At least, when they were first trained, it didn't. Nowadays there is a huge amount of LLM-generated text on the internet. Generally speaking, we prefer to keep raw chatbot logs out of our pre-training corpus for privacy and quality reasons. Cleaning this out is also a major challenge. These days, trainers do intentionally include synthetic, LLM-generated text in both pre-training and post-training, but they try to ensure that it is high-quality and unique.&lt;/p&gt;
          &lt;/section&gt;</content:encoded>
    </item>
    <item>
      <title>AI for Normal People #2 | Language Models</title>
      <link>https://gear-research.com/blog/normal-ai-2.html</link>
      <guid isPermaLink="true">https://gear-research.com/blog/normal-ai-2.html</guid>
      <pubDate>Mon, 20 Jul 2026 00:00:00 GMT</pubDate>
      <description>What is a language model? Explaining word embeddings, tokens, next-token prediction, and how LLMs actually work under the hood.</description>
      <content:encoded>&lt;section&gt;
            &lt;p&gt;In the last entry, I discussed what a &lt;i&gt;model&lt;/i&gt; is in machine learning, using an example of a model trained to classify images of birds. The most important idea was that to make good use of any model, we must ensure that the questions we ask the model and the questions the model is trained to answer are aligned. Now, we're going to move to the middle letter of LLM and discuss what it means to model &lt;b&gt;language&lt;/b&gt;.&lt;/p&gt;

            &lt;h2&gt;Why Model Language?&lt;/h2&gt;
            &lt;p&gt;You have almost certainly encountered language modeling in the wild, whether you were aware of it or not. Language models are the engines behind services like ChatGPT, but they also can or do power Google's AI summaries &lt;a href=&quot;#fn-1&quot;&gt;[1]&lt;/a&gt;, translation apps, spam email filters, smart home assistants like Alexa, and a massive number of other places you might not expect. Language modeling is so ubiquitous because language gives us a very compact, high-level understanding of the world. It would take thousands of pixels to depict even a single bird, let alone all the various species and individuals of those species, but I can capture them all abstractly with just a single word. This makes language a fantastic way to provide people with a description of parts of the world or events that we care about.&lt;/p&gt;
            &lt;p&gt;The problem for computers is that language is also horrifically complicated. Language is absolutely packed with patterns, often patterns nested inside each other, which is necessary for people to understand one another at all. To communicate ideas effectively, we have to (mostly) share a set of rules about what words mean and how other words in a sentence, and their order, changes their meanings. Because we use language to discuss reality, and reality is complex, the patterns in language must also be very complex, making it difficult for conventional computer programs (which are typically bad at pattern recognition) to make much sense of them.&lt;/p&gt;
            &lt;p&gt;Still, we do have to communicate our intentions to computers for them to be of any use to us, so there is a lot of value in developing models to interpret the language we use. But how might we do that, given the complexity of language and the reality it reflects?&lt;/p&gt;

            &lt;h2&gt;&quot;Measuring&quot; Words&lt;/h2&gt;
            &lt;p&gt;The first step is to remember that computers only deal in numbers. Converting images to numbers is surprisingly easy because that's how computers already represent them (recall from last time that an image is a grid of pixels, and each pixel is a number representing its colour). Similar pixels are already similar numbers. For words, though, this is more difficult because two words can mean similar things but have very different letters in them. &quot;Big&quot; and &quot;gargantuan&quot; are two words with similar meanings, but their spellings are totally different. As with everything, computers represent letters using numbers, but the letters don't tell you anything about what a word actually means. What we want to do is somehow measure their meanings.&lt;/p&gt;
            &lt;p&gt;This seems like a pretty absurd task, but the image below shows how you might measure a handful of words on two axes: &quot;aliveness&quot; and speed.&lt;/p&gt;
            
            &lt;svg width=&quot;100%&quot; viewBox=&quot;0 0 600 450&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; style=&quot;max-width: 600px; display: block; margin: 20px auto;&quot;&gt;
              &lt;line x1=&quot;60&quot; y1=&quot;390&quot; x2=&quot;560&quot; y2=&quot;390&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; /&gt;
              &lt;line x1=&quot;60&quot; y1=&quot;40&quot; x2=&quot;60&quot; y2=&quot;390&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; /&gt;
              &lt;polygon points=&quot;560,385 570,390 560,395&quot; fill=&quot;currentColor&quot; /&gt;
              &lt;polygon points=&quot;55,40 60,30 65,40&quot; fill=&quot;currentColor&quot; /&gt;
              &lt;text x=&quot;550&quot; y=&quot;425&quot; text-anchor=&quot;end&quot; fill=&quot;currentColor&quot; font-weight=&quot;bold&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;14&quot;&gt;Speed →&lt;/text&gt;
              &lt;text x=&quot;30&quot; y=&quot;215&quot; text-anchor=&quot;start&quot; fill=&quot;currentColor&quot; font-weight=&quot;bold&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;14&quot; transform=&quot;rotate(-90 30 215)&quot;&gt;Aliveness →&lt;/text&gt;
              
              &lt;circle cx=&quot;90&quot; cy=&quot;370&quot; r=&quot;5&quot; fill=&quot;var(--diagram-red)&quot; /&gt;
              &lt;text x=&quot;100&quot; y=&quot;375&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot;&gt;Mountain&lt;/text&gt;
              
              &lt;circle cx=&quot;160&quot; cy=&quot;370&quot; r=&quot;5&quot; fill=&quot;var(--diagram-red)&quot; /&gt;
              &lt;text x=&quot;170&quot; y=&quot;375&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot;&gt;Cloud&lt;/text&gt;
              
              &lt;circle cx=&quot;250&quot; cy=&quot;370&quot; r=&quot;5&quot; fill=&quot;var(--diagram-red)&quot; /&gt;
              &lt;text x=&quot;260&quot; y=&quot;375&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot;&gt;River&lt;/text&gt;
              
              &lt;circle cx=&quot;430&quot; cy=&quot;370&quot; r=&quot;5&quot; fill=&quot;var(--diagram-red)&quot; /&gt;
              &lt;text x=&quot;440&quot; y=&quot;375&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot;&gt;Car&lt;/text&gt;
              
              &lt;circle cx=&quot;530&quot; cy=&quot;370&quot; r=&quot;5&quot; fill=&quot;var(--diagram-red)&quot; /&gt;
              &lt;text x=&quot;520&quot; y=&quot;355&quot; text-anchor=&quot;end&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot;&gt;Aeroplane&lt;/text&gt;
              
              &lt;circle cx=&quot;110&quot; cy=&quot;280&quot; r=&quot;5&quot; fill=&quot;var(--diagram-red)&quot; /&gt;
              &lt;text x=&quot;120&quot; y=&quot;285&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot;&gt;Bacterium&lt;/text&gt;
              
              &lt;circle cx=&quot;90&quot; cy=&quot;180&quot; r=&quot;5&quot; fill=&quot;var(--diagram-red)&quot; /&gt;
              &lt;text x=&quot;100&quot; y=&quot;185&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot;&gt;Tree&lt;/text&gt;
              
              &lt;circle cx=&quot;130&quot; cy=&quot;140&quot; r=&quot;5&quot; fill=&quot;var(--diagram-red)&quot; /&gt;
              &lt;text x=&quot;140&quot; y=&quot;145&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot;&gt;Snail&lt;/text&gt;
              
              &lt;circle cx=&quot;180&quot; cy=&quot;80&quot; r=&quot;5&quot; fill=&quot;var(--diagram-red)&quot; /&gt;
              &lt;text x=&quot;190&quot; y=&quot;85&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot;&gt;Tortoise&lt;/text&gt;
              
              &lt;circle cx=&quot;290&quot; cy=&quot;80&quot; r=&quot;5&quot; fill=&quot;var(--diagram-red)&quot; /&gt;
              &lt;text x=&quot;300&quot; y=&quot;85&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot;&gt;Person&lt;/text&gt;

              &lt;circle cx=&quot;390&quot; cy=&quot;80&quot; r=&quot;5&quot; fill=&quot;var(--diagram-red)&quot; /&gt;
              &lt;text x=&quot;400&quot; y=&quot;85&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot;&gt;Hare&lt;/text&gt;
              
              &lt;circle cx=&quot;470&quot; cy=&quot;80&quot; r=&quot;5&quot; fill=&quot;var(--diagram-red)&quot; /&gt;
              &lt;text x=&quot;480&quot; y=&quot;85&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot;&gt;Bird&lt;/text&gt;
              
              &lt;circle cx=&quot;530&quot; cy=&quot;80&quot; r=&quot;5&quot; fill=&quot;var(--diagram-red)&quot; /&gt;
              &lt;text x=&quot;520&quot; y=&quot;65&quot; text-anchor=&quot;end&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot;&gt;Cheetah&lt;/text&gt;
            &lt;/svg&gt;

            &lt;p&gt;Fast animals like cheetahs score highly for both aliveness and speed. Aeroplanes have a low aliveness but a very high speed. Bacteria don't feel quite as &quot;alive&quot; as animals, but they are a little bit alive, and are quite slow by our standards. Mountains are certainly not alive and not mobile at all &lt;a href=&quot;#fn-2&quot;&gt;[2]&lt;/a&gt;. Thinking about words in this way means we can, to a certain extent, measure their meanings, but only as long as we remember we're measuring &lt;i&gt;relative to other words&lt;/i&gt;. There is no absolute number you could assign to &quot;aliveness&quot;.&lt;/p&gt;
            &lt;p&gt;There are lots of words we could plot on this chart, but there are also many that we couldn't. Where would you put &quot;blue&quot; or &quot;indomitable&quot;? When we only have two axes to measure in, there's only so much we can describe about any given word. We call these axes &lt;b&gt;dimensions&lt;/b&gt;; the above chart is &lt;b&gt;2-dimensional&lt;/b&gt; because it only has two measurements you can use to describe anything on it. There is no way on the above chart to distinguish between two objects by colour, because colour is not one of the dimensions we're measuring along.&lt;/p&gt;
            &lt;p&gt;The way language models solve this issue is by using many, many more dimensions for measurement. LLMs typically have several thousand dimensions to represent words with. This can be a bit tricky to get your head around, and is impossible to picture because we are only 3-dimensional creatures. In regular space, you use three different numbers to describe an object's position or size (its coordinates, or its height, width, and length). Fortunately, the maths works just the same in 8,000 dimensions as it does in two or three.&lt;/p&gt;
            &lt;p&gt;Many words will have low scores on many or most dimensions &amp;mdash; asking how &quot;alive&quot; the word &quot;blue&quot; is doesn't make much sense, so we give it a low score. Asking how &quot;blue&quot; the word &quot;hungry&quot; is doesn't make sense either, so if we had a &quot;blue&quot; dimension, we would give &quot;hungry&quot; a low score on that as well, while we might give &quot;red&quot; a negative score because it &lt;i&gt;can&lt;/i&gt; be meaningfully compared to &quot;blue&quot;, but is very different from it.&lt;/p&gt;
            
            &lt;svg width=&quot;100%&quot; viewBox=&quot;0 0 400 400&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; style=&quot;max-width: 400px; display: block; margin: 20px auto;&quot;&gt;
              &lt;line x1=&quot;40&quot; y1=&quot;200&quot; x2=&quot;360&quot; y2=&quot;200&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; /&gt;
              &lt;line x1=&quot;200&quot; y1=&quot;40&quot; x2=&quot;200&quot; y2=&quot;360&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; /&gt;
              
              &lt;text x=&quot;365&quot; y=&quot;205&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;12&quot;&gt;Blue (1)&lt;/text&gt;
              &lt;text x=&quot;35&quot; y=&quot;205&quot; text-anchor=&quot;end&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;12&quot;&gt;(-1)&lt;/text&gt;
              &lt;text x=&quot;200&quot; y=&quot;30&quot; text-anchor=&quot;middle&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;12&quot;&gt;Alive (1)&lt;/text&gt;
              &lt;text x=&quot;200&quot; y=&quot;380&quot; text-anchor=&quot;middle&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;12&quot;&gt;(-1)&lt;/text&gt;
              
              &lt;circle cx=&quot;200&quot; cy=&quot;150&quot; r=&quot;6&quot; fill=&quot;var(--diagram-green)&quot; /&gt;
              &lt;text x=&quot;210&quot; y=&quot;154&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;14&quot; font-weight=&quot;bold&quot;&gt;Hungry&lt;/text&gt;
              
              &lt;circle cx=&quot;340&quot; cy=&quot;200&quot; r=&quot;6&quot; fill=&quot;var(--diagram-blue)&quot; /&gt;
              &lt;text x=&quot;340&quot; y=&quot;190&quot; text-anchor=&quot;middle&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;14&quot; font-weight=&quot;bold&quot;&gt;Blue&lt;/text&gt;
              
              &lt;circle cx=&quot;60&quot; cy=&quot;200&quot; r=&quot;6&quot; fill=&quot;var(--diagram-red)&quot; /&gt;
              &lt;text x=&quot;60&quot; y=&quot;190&quot; text-anchor=&quot;middle&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;14&quot; font-weight=&quot;bold&quot;&gt;Red&lt;/text&gt;
            &lt;/svg&gt;

            &lt;p&gt;We run into another problem in that there are a huge number of concepts we could think to measure, and it's too difficult to list them all out and then argue about where every single word we can think of belongs on every concept. Instead, we leave this up to the model to learn. We provide it with the space for, say, 8,000 dimensions, and leave it to learn which concepts are actually useful and which ones aren't. Most of these dimensions won't cleanly correspond to human-understandable concepts, and many may map onto multiple concepts, so we can't look into the model and understand the weights directly. We also can't expect to understand why any given word is in the place it's in (&quot;why is 'blue' represented with the numbers [-1.55, 2.94, 0.81] and not [-1.50, 3.1, -0.81]?&quot;) but we can expect that multiple similar words should be close to each other. &quot;Big&quot; and &quot;gargantuan&quot; should have roughly close numbers representing them, even if we don't know what those numbers mean.&lt;/p&gt;
            &lt;p&gt;In fact, because token representations are all just numbers, we can actually add and subtract them from each other. In our example here, if you subtracted the token for &quot;slow&quot; from the token for &quot;tortoise&quot;, and then added the token for &quot;fast&quot;, you might end up with something close to &quot;hare&quot;, since the tortoise and the hare are often used to represent a slow and a fast animal, respectively &lt;a href=&quot;#fn-4&quot;&gt;[4]&lt;/a&gt;.&lt;/p&gt;
            
            &lt;svg width=&quot;100%&quot; viewBox=&quot;0 0 600 300&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; style=&quot;max-width: 600px; display: block; margin: 20px auto;&quot;&gt;
              &lt;line x1=&quot;50&quot; y1=&quot;250&quot; x2=&quot;550&quot; y2=&quot;250&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; opacity=&quot;0.3&quot; /&gt;
              &lt;line x1=&quot;50&quot; y1=&quot;50&quot; x2=&quot;50&quot; y2=&quot;250&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; opacity=&quot;0.3&quot; /&gt;
              &lt;text x=&quot;540&quot; y=&quot;270&quot; text-anchor=&quot;end&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;12&quot; opacity=&quot;0.5&quot;&gt;Speed →&lt;/text&gt;
              &lt;text x=&quot;35&quot; y=&quot;60&quot; text-anchor=&quot;start&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;12&quot; opacity=&quot;0.5&quot; transform=&quot;rotate(-90 35 60)&quot;&gt;Aliveness →&lt;/text&gt;

              &lt;circle cx=&quot;220&quot; cy=&quot;100&quot; r=&quot;6&quot; fill=&quot;var(--diagram-purple)&quot; /&gt;
              &lt;text x=&quot;220&quot; y=&quot;85&quot; text-anchor=&quot;middle&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-weight=&quot;bold&quot; font-size=&quot;14&quot;&gt;Tortoise&lt;/text&gt;

              &lt;line x1=&quot;220&quot; y1=&quot;100&quot; x2=&quot;130&quot; y2=&quot;200&quot; stroke=&quot;var(--diagram-red)&quot; stroke-width=&quot;3&quot; stroke-dasharray=&quot;4&quot; /&gt;
              &lt;text x=&quot;130&quot; y=&quot;220&quot; text-anchor=&quot;middle&quot; fill=&quot;var(--diagram-red)&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot; font-weight=&quot;bold&quot;&gt;- &quot;slow&quot;&lt;/text&gt;
              
              &lt;line x1=&quot;130&quot; y1=&quot;200&quot; x2=&quot;440&quot; y2=&quot;100&quot; stroke=&quot;var(--diagram-green)&quot; stroke-width=&quot;3&quot; /&gt;
              &lt;text x=&quot;285&quot; y=&quot;180&quot; text-anchor=&quot;middle&quot; fill=&quot;var(--diagram-green)&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;13&quot; font-weight=&quot;bold&quot;&gt;+ &quot;fast&quot;&lt;/text&gt;

              &lt;circle cx=&quot;445&quot; cy=&quot;100&quot; r=&quot;6&quot; fill=&quot;var(--diagram-purple)&quot; /&gt;
              &lt;text x=&quot;445&quot; y=&quot;85&quot; text-anchor=&quot;middle&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-weight=&quot;bold&quot; font-size=&quot;14&quot;&gt;Hare&lt;/text&gt;
            &lt;/svg&gt;

            &lt;p&gt;The reason that we want words with similar meanings to end up close to one another numerically is because this allows the model to generalise what it has learned. If it sees some new, useful information about &quot;dog&quot;, like that dogs have four legs and like to wag their tails, then that knowledge can also help it to make sensible predictions about &quot;puppy&quot; and &quot;wolf&quot;, because their numeric representations are already close together. Conversely, the model does not strongly change its knowledge about car engines, because they will mostly not be represented similarly to canines.&lt;/p&gt;

            &lt;h2&gt;Tokens, Not Words&lt;/h2&gt;
            &lt;p&gt;One small clarification before we move on. If you've heard people talking about LLMs or AI in the past, you may have heard them use the term &lt;b&gt;token&lt;/b&gt;. AI companies typically bill by the token, you might hear about &quot;token budgets&quot; or &quot;token efficiency&quot;. That's because language models don't actually take words as we understand them as input. While the smallest input you can give to an image classification model is a pixel, the smallest input for a language model is called a token.&lt;/p&gt;
            &lt;p&gt;Recall that models in machine learning typically start with their weights randomised. This is important for learning, but many pairs of words that are obviously similar to us can start out very far apart in the model. For example, &quot;bird&quot; and &quot;birds&quot; are almost identical words, one is just a plural, but a language model would probably start by representing them with very different sets of numbers and would need to learn that they are closely related from scratch.&lt;/p&gt;
            &lt;p&gt;Instead, we allow ourselves to break words up into their component pieces. We might end up with one token for the word &quot;bird&quot; and then another for the letter &quot;s&quot;. If we do this with many different nouns, the model will almost certainly learn that if the letter &quot;s&quot; follows a noun, the noun represents more than one object. This same pattern applies to many different words, so learning this way saves the model a lot of time. You don't need to independently learn &quot;matter&quot; and &quot;antimatter&quot;, &quot;clockwise&quot; and &quot;anticlockwise&quot;, and &quot;thesis&quot; and &quot;antithesis&quot;. You can have a separate token for &quot;anti&quot;, which nearly always means &quot;opposite&quot;, and now you know that putting it in front of &quot;matter&quot;, &quot;clockwise&quot;, and &quot;thesis&quot; gives you their opposites.&lt;/p&gt;
            &lt;p&gt;Most uncommon words can be broken down into smaller parts, so this time saving applies all through language. It also means that you can get away with teaching the model far fewer tokens because it learns how to combine them on the fly.&lt;/p&gt;
            
            &lt;svg width=&quot;100%&quot; viewBox=&quot;0 0 620 90&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; style=&quot;max-width: 620px; display: block; margin: 20px auto;&quot;&gt;
              &lt;g font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;15&quot; font-weight=&quot;bold&quot; text-anchor=&quot;middle&quot;&gt;
                &lt;rect x=&quot;10&quot; y=&quot;20&quot; width=&quot;65&quot; height=&quot;50&quot; rx=&quot;6&quot; fill=&quot;var(--diagram-slate)&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; /&gt;
                &lt;text x=&quot;42.5&quot; y=&quot;51&quot; fill=&quot;var(--diagram-contrast)&quot;&gt;anti&lt;/text&gt;

                &lt;rect x=&quot;80&quot; y=&quot;20&quot; width=&quot;60&quot; height=&quot;50&quot; rx=&quot;6&quot; fill=&quot;var(--diagram-teal)&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; /&gt;
                &lt;text x=&quot;110&quot; y=&quot;51&quot; fill=&quot;var(--diagram-contrast)&quot;&gt;dis&lt;/text&gt;

                &lt;rect x=&quot;145&quot; y=&quot;20&quot; width=&quot;150&quot; height=&quot;50&quot; rx=&quot;6&quot; fill=&quot;var(--diagram-blue)&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; /&gt;
                &lt;text x=&quot;220&quot; y=&quot;51&quot; fill=&quot;var(--diagram-contrast)&quot;&gt;establish&lt;/text&gt;

                &lt;rect x=&quot;300&quot; y=&quot;20&quot; width=&quot;85&quot; height=&quot;50&quot; rx=&quot;6&quot; fill=&quot;var(--diagram-purple)&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; /&gt;
                &lt;text x=&quot;342.5&quot; y=&quot;51&quot; fill=&quot;var(--diagram-contrast)&quot;&gt;ment&lt;/text&gt;

                &lt;rect x=&quot;390&quot; y=&quot;20&quot; width=&quot;90&quot; height=&quot;50&quot; rx=&quot;6&quot; fill=&quot;var(--diagram-orange)&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; /&gt;
                &lt;text x=&quot;435&quot; y=&quot;51&quot; fill=&quot;var(--diagram-contrast)&quot;&gt;arian&lt;/text&gt;

                &lt;rect x=&quot;485&quot; y=&quot;20&quot; width=&quot;65&quot; height=&quot;50&quot; rx=&quot;6&quot; fill=&quot;var(--diagram-green)&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; /&gt;
                &lt;text x=&quot;517.5&quot; y=&quot;51&quot; fill=&quot;var(--diagram-contrast)&quot;&gt;ism&lt;/text&gt;
              &lt;/g&gt;
            &lt;/svg&gt;

            &lt;p&gt;It is very important to remember that tokens are totally indivisible. Below are the tokens that make up the word &quot;strawberry&quot; &lt;a href=&quot;#fn-5&quot;&gt;[5]&lt;/a&gt;. The model only ever sees the numeric identifiers, not the letters themselves. This is why LLMs struggle with counting letters in words (famously, most LLMs would miscount the number of 'r's in &quot;strawberry&quot;, sometimes saying &quot;two&quot; or &quot;four&quot;). They don't always have reliable access to that information &lt;a href=&quot;#fn-6&quot;&gt;[6]&lt;/a&gt;. To a language model, asking what letters are in a word would be like asking an English speaker what the middle bar in a capital &quot;A&quot; means &amp;mdash; we just don't divide down any further than that.&lt;/p&gt;

            &lt;svg width=&quot;100%&quot; viewBox=&quot;0 0 480 100&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; style=&quot;max-width: 480px; display: block; margin: 20px auto;&quot;&gt;
              &lt;g font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;15&quot; font-weight=&quot;bold&quot; text-anchor=&quot;middle&quot;&gt;
                &lt;text x=&quot;10&quot; y=&quot;20&quot; fill=&quot;currentColor&quot; font-size=&quot;13&quot; font-weight=&quot;normal&quot; text-anchor=&quot;start&quot;&gt;What we see:&lt;/text&gt;
                &lt;text x=&quot;10&quot; y=&quot;62&quot; fill=&quot;currentColor&quot; font-size=&quot;13&quot; font-weight=&quot;normal&quot; text-anchor=&quot;start&quot;&gt;What the model sees:&lt;/text&gt;

                &lt;rect x=&quot;150&quot; y=&quot;5&quot; width=&quot;65&quot; height=&quot;40&quot; rx=&quot;6&quot; fill=&quot;var(--diagram-slate)&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; /&gt;
                &lt;text x=&quot;182.5&quot; y=&quot;30&quot; fill=&quot;var(--diagram-contrast)&quot;&gt;Str&lt;/text&gt;

                &lt;rect x=&quot;225&quot; y=&quot;5&quot; width=&quot;55&quot; height=&quot;40&quot; rx=&quot;6&quot; fill=&quot;var(--diagram-teal)&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; /&gt;
                &lt;text x=&quot;252.5&quot; y=&quot;30&quot; fill=&quot;var(--diagram-contrast)&quot;&gt;aw&lt;/text&gt;

                &lt;rect x=&quot;290&quot; y=&quot;5&quot; width=&quot;80&quot; height=&quot;40&quot; rx=&quot;6&quot; fill=&quot;var(--diagram-blue)&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; /&gt;
                &lt;text x=&quot;330&quot; y=&quot;30&quot; fill=&quot;var(--diagram-contrast)&quot;&gt;berry&lt;/text&gt;

                &lt;rect x=&quot;150&quot; y=&quot;47&quot; width=&quot;65&quot; height=&quot;40&quot; rx=&quot;6&quot; fill=&quot;var(--diagram-slate)&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; /&gt;
                &lt;text x=&quot;182.5&quot; y=&quot;72&quot; fill=&quot;var(--diagram-contrast)&quot; font-size=&quot;13&quot;&gt;3504&lt;/text&gt;

                &lt;rect x=&quot;225&quot; y=&quot;47&quot; width=&quot;55&quot; height=&quot;40&quot; rx=&quot;6&quot; fill=&quot;var(--diagram-teal)&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; /&gt;
                &lt;text x=&quot;252.5&quot; y=&quot;72&quot; fill=&quot;var(--diagram-contrast)&quot; font-size=&quot;13&quot;&gt;1134&lt;/text&gt;

                &lt;rect x=&quot;290&quot; y=&quot;47&quot; width=&quot;80&quot; height=&quot;40&quot; rx=&quot;6&quot; fill=&quot;var(--diagram-blue)&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; /&gt;
                &lt;text x=&quot;330&quot; y=&quot;72&quot; fill=&quot;var(--diagram-contrast)&quot; font-size=&quot;13&quot;&gt;19772&lt;/text&gt;
              &lt;/g&gt;
            &lt;/svg&gt;

            &lt;h2&gt;Patterns in Language&lt;/h2&gt;
            &lt;p&gt;So, we can represent individual tokens, which may be whole words or parts of words, with language models, all well and good. But language is more than just the meaning of individual words. Most patterns we want to learn about are the result of combining words.&lt;/p&gt;
            &lt;p&gt;Grammar is an example of a group of low-level patterns which we would want to capture. Grammar is made up of patterns which describe how words relate to each other in a sentence, and these relationships carry meaning. For example, despite having identical words in them, the sentences &quot;The dog bit the man&quot; and &quot;The man bit the dog&quot; have very different meanings. Thanks to English grammar we know that, in the first sentence, it was the dog's teeth on the man because &quot;the dog&quot; is the subject of the sentence (the entity doing the action) and &quot;the man&quot; is the object of the sentence (the entity to which the action is done). English grammar rules usually require the subject of the sentence to come before the verb (bit) and the object to come after it, so grammar is what distinguishes between these two very different situations, and its rules are the patterns a language model will aim to detect.&lt;/p&gt;
            &lt;p&gt;Beyond just word order, we can learn about when an event occurred based on the tense of the sentence (the dog &quot;bit&quot; in the past, the dog &quot;bites&quot; in the present), or we can go even further and learn patterns that reflect information in language, like facts, opinions, or clichés.&lt;/p&gt;
            &lt;h2&gt;Attention and Relationships Between Words&lt;/h2&gt;
            &lt;p&gt;We have a problem here, though, which is that so far we have only been measuring the meaning of words in isolation. Consider the sentence &quot;The dog chased the ball as it rolled down the hill&quot;. What does &quot;it&quot; mean here? The obvious answer is that &quot;it&quot; is &quot;the ball&quot;, but knowing that requires understanding not only the meaning of the word &quot;it&quot; alone (what &quot;it&quot; would mean if you looked it up in a dictionary), but also to understand its role within this specific sentence through its relationship to other words.&lt;/p&gt;

            &lt;p&gt;In language models, we do this with a mechanism called &lt;b&gt;attention&lt;/b&gt;. Just like we allow the model to learn the meaning of tokens on their own, we also allow it to store information about how tokens relate to one another when placed together, and how to incorporate information from one another to update their own representation. In this particular example, the token for &quot;it&quot; should share at least some similarities to the token for &quot;ball&quot;. Inside a modern language model, each token in an input sentence is allowed to assign &quot;attention&quot; to each other token in the sentence, which dictates how much of the target token should be incorporated. In this case, &quot;it&quot; should assign quite a lot of attention to &quot;ball&quot;, but not much to &quot;dog&quot; or &quot;chased&quot;. Conversely if our sentence were &quot;The dog chased the ball as it barked loudly&quot;, then &quot;it&quot; clearly refers to the dog and not the ball, so &quot;it&quot; would assign its attention to &quot;dog&quot;.&lt;/p&gt;

            &lt;p&gt;All of this is learned information. There are parts of a modern language model (their &lt;b&gt;attention modules&lt;/b&gt;) dedicated just to learning which words should attend to which others in an input, and consequently, to learning how they relate to each other. As a model processes an input passage, each token is repeatedly allowed to pull in bits of information from other relevant tokens in the sentence such that it ultimately gives them numerical representations which contain rich information from the surrounding text, not just what they were in isolation.&lt;/p&gt;

            &lt;p&gt;But just having these numerical representations sitting in a model does us no good on their own. Again, we have to ask ourselves &quot;what questions do we want to answer?&quot;. If you are a movie review website, you might want to know whether a review was positive or negative. If you are a spam filter, you want to know whether the email looks like a real email or just garbage. If you are a home assistant, you want to know whether someone just gave a command or is just chatting to their friend.&lt;/p&gt;

            &lt;p&gt;These are all different, difficult questions, and you could train a new language model for each of them, but that's a lot of effort. For more complex tasks, just answering one question might not be enough. Thus, we want to pick a single question for our language models that captures as many of these as possible.&lt;/p&gt;

            &lt;h2&gt;The Only Question Language Models Answer&lt;/h2&gt;
            &lt;p&gt;That question, the only question a language model can answer at all, is:&lt;/p&gt;
            &lt;blockquote&gt;
              &lt;p&gt;&quot;Which token comes next?&quot;&lt;/p&gt;
            &lt;/blockquote&gt;
            &lt;p&gt;This might strike you as a very simple question to ask. It's the sort of thing your phone's autocomplete has been doing for years, but most people have tried to get their autocomplete to write an entire sentence from scratch, and you would know that they're pretty bad at it. Technically, phone autocomplete usually uses a kind of statistical model too, but they're very simple compared to the kinds of language models we're talking about, so their results aren't terribly impressive most of the time.&lt;/p&gt;
            &lt;p&gt;In fact, you may have heard people call language models &quot;glorified autocomplete&quot;. This is fair in terms of their mechanics: at their core, they do much the same thing as autocomplete. But in truth, autocomplete is a surprisingly hard problem to solve if you really want it to write full sentences for you.&lt;/p&gt;
            &lt;p&gt;The real trick is what the input to our model is. For regular autocomplete, the input will usually only be the last few words, maybe three or four of them. That's why they aren't good for generating coherent sentences: they're not looking far enough back to have a good idea of what you're trying to say. LLMs, conversely, take a great deal more text to predict the next token. Instead of only a couple words, we can give them the entire sentence from which to predict the next token, or even more than that. A more precise way of describing the question LLMs answer might be: &lt;i&gt;&quot;Given all the tokens so far, which token comes next?&quot;&lt;/i&gt;.&lt;/p&gt;
            &lt;p&gt;A prominent AI researcher and co-founder of OpenAI, Ilya Sutskever, explains it like this &lt;a href=&quot;#fn-7&quot;&gt;[7]&lt;/a&gt;:&lt;/p&gt;
            &lt;blockquote&gt;
              &lt;p&gt;Say you read a detective novel. It's like a complicated plot, a storyline with different characters, lots of events &amp;mdash; mysteries like clues. It's unclear. Then, let's say that on the last page of the book, the detective has gathered all the clues, gathered all the people, and is saying &quot;Okay, I'm going to reveal the identity of whoever committed the crime, and that person's name is... — Predict that word.&quot;&lt;/p&gt;
            &lt;/blockquote&gt;

            &lt;h2&gt;Wait, Just Next-Token Prediction?&lt;/h2&gt;
            &lt;p&gt;So, how does a very good autocomplete give us something useful? To begin with, the technical term for autocomplete is &lt;b&gt;auto-regression&lt;/b&gt;, and it is a surprisingly simple process. We start with some text, predict which token should come next, add that token to the end of the sentence, and then repeat. The most prominent language models, and the ones you notice day-to-day, are auto-regressive language models &lt;a href=&quot;#fn-8&quot;&gt;[8]&lt;/a&gt;. They simply predict the next token over and over and over again. Typically they will go until they predict that there is no next token and that they should stop, at which point we stop making predictions and show the output to the user.&lt;/p&gt;
            
            &lt;svg width=&quot;100%&quot; viewBox=&quot;0 0 600 460&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; style=&quot;max-width: 600px; display: block; margin: 20px auto;&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;14&quot;&gt;
              &lt;rect x=&quot;20&quot; y=&quot;20&quot; width=&quot;120&quot; height=&quot;35&quot; rx=&quot;4&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; /&gt;
              &lt;text x=&quot;30&quot; y=&quot;42&quot; fill=&quot;currentColor&quot;&gt;Input: &lt;tspan font-weight=&quot;bold&quot;&gt;Brevity&lt;/tspan&gt;&lt;/text&gt;
              
              &lt;line x1=&quot;140&quot; y1=&quot;37.5&quot; x2=&quot;255&quot; y2=&quot;37.5&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; /&gt;
              &lt;polygon points=&quot;260,37.5 252,33 252,42&quot; fill=&quot;currentColor&quot; /&gt;
              
              &lt;rect x=&quot;260&quot; y=&quot;20&quot; width=&quot;120&quot; height=&quot;35&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-orange)&quot; /&gt;
              &lt;text x=&quot;320&quot; y=&quot;42&quot; text-anchor=&quot;middle&quot; fill=&quot;var(--diagram-contrast)&quot; font-weight=&quot;bold&quot;&gt;Predicts: &quot;is&quot;&lt;/text&gt;
              
              &lt;path d=&quot;M 320 55 L 320 80 L 90 80 L 90 95&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; stroke-dasharray=&quot;4&quot; /&gt;
              &lt;polygon points=&quot;90,95 86,87 94,87&quot; fill=&quot;currentColor&quot; /&gt;

              &lt;rect x=&quot;20&quot; y=&quot;100&quot; width=&quot;145&quot; height=&quot;35&quot; rx=&quot;4&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; /&gt;
              &lt;text x=&quot;30&quot; y=&quot;122&quot; fill=&quot;currentColor&quot;&gt;Input: &lt;tspan font-weight=&quot;bold&quot;&gt;Brevity is&lt;/tspan&gt;&lt;/text&gt;
              
              &lt;line x1=&quot;165&quot; y1=&quot;117.5&quot; x2=&quot;255&quot; y2=&quot;117.5&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; /&gt;
              &lt;polygon points=&quot;260,117.5 252,113 252,122&quot; fill=&quot;currentColor&quot; /&gt;
              
              &lt;rect x=&quot;260&quot; y=&quot;100&quot; width=&quot;120&quot; height=&quot;35&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-orange)&quot; /&gt;
              &lt;text x=&quot;320&quot; y=&quot;122&quot; text-anchor=&quot;middle&quot; fill=&quot;var(--diagram-contrast)&quot; font-weight=&quot;bold&quot;&gt;Predicts: &quot;the&quot;&lt;/text&gt;
              
              &lt;path d=&quot;M 320 135 L 320 160 L 90 160 L 90 175&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; stroke-dasharray=&quot;4&quot; /&gt;
              &lt;polygon points=&quot;90,175 86,167 94,167&quot; fill=&quot;currentColor&quot; /&gt;

              &lt;rect x=&quot;20&quot; y=&quot;180&quot; width=&quot;170&quot; height=&quot;35&quot; rx=&quot;4&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; /&gt;
              &lt;text x=&quot;30&quot; y=&quot;202&quot; fill=&quot;currentColor&quot;&gt;Input: &lt;tspan font-weight=&quot;bold&quot;&gt;Brevity is the&lt;/tspan&gt;&lt;/text&gt;
              
              &lt;line x1=&quot;190&quot; y1=&quot;197.5&quot; x2=&quot;255&quot; y2=&quot;197.5&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; /&gt;
              &lt;polygon points=&quot;260,197.5 252,193 252,202&quot; fill=&quot;currentColor&quot; /&gt;
              
              &lt;rect x=&quot;260&quot; y=&quot;180&quot; width=&quot;120&quot; height=&quot;35&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-orange)&quot; /&gt;
              &lt;text x=&quot;320&quot; y=&quot;202&quot; text-anchor=&quot;middle&quot; fill=&quot;var(--diagram-contrast)&quot; font-weight=&quot;bold&quot;&gt;Predicts: &quot;soul&quot;&lt;/text&gt;
              
              &lt;path d=&quot;M 320 215 L 320 240 L 90 240 L 90 255&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; stroke-dasharray=&quot;4&quot; /&gt;
              &lt;polygon points=&quot;90,255 86,247 94,247&quot; fill=&quot;currentColor&quot; /&gt;

              &lt;rect x=&quot;20&quot; y=&quot;260&quot; width=&quot;195&quot; height=&quot;35&quot; rx=&quot;4&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; /&gt;
              &lt;text x=&quot;30&quot; y=&quot;282&quot; fill=&quot;currentColor&quot;&gt;Input: &lt;tspan font-weight=&quot;bold&quot;&gt;Brevity is the soul&lt;/tspan&gt;&lt;/text&gt;
              
              &lt;line x1=&quot;215&quot; y1=&quot;277.5&quot; x2=&quot;255&quot; y2=&quot;277.5&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; /&gt;
              &lt;polygon points=&quot;260,277.5 252,273 252,282&quot; fill=&quot;currentColor&quot; /&gt;
              
              &lt;rect x=&quot;260&quot; y=&quot;260&quot; width=&quot;120&quot; height=&quot;35&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-orange)&quot; /&gt;
              &lt;text x=&quot;320&quot; y=&quot;282&quot; text-anchor=&quot;middle&quot; fill=&quot;var(--diagram-contrast)&quot; font-weight=&quot;bold&quot;&gt;Predicts: &quot;of&quot;&lt;/text&gt;
              
              &lt;path d=&quot;M 320 295 L 320 320 L 90 320 L 90 335&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; stroke-dasharray=&quot;4&quot; /&gt;
              &lt;polygon points=&quot;90,335 86,327 94,327&quot; fill=&quot;currentColor&quot; /&gt;

              &lt;rect x=&quot;20&quot; y=&quot;340&quot; width=&quot;225&quot; height=&quot;35&quot; rx=&quot;4&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; /&gt;
              &lt;text x=&quot;30&quot; y=&quot;362&quot; fill=&quot;currentColor&quot;&gt;Input: &lt;tspan font-weight=&quot;bold&quot;&gt;Brevity is the soul of&lt;/tspan&gt;&lt;/text&gt;
              
              &lt;line x1=&quot;245&quot; y1=&quot;357.5&quot; x2=&quot;255&quot; y2=&quot;357.5&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; /&gt;
              &lt;polygon points=&quot;260,357.5 252,353 252,362&quot; fill=&quot;currentColor&quot; /&gt;
              
              &lt;rect x=&quot;260&quot; y=&quot;340&quot; width=&quot;120&quot; height=&quot;35&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-orange)&quot; /&gt;
              &lt;text x=&quot;320&quot; y=&quot;362&quot; text-anchor=&quot;middle&quot; fill=&quot;var(--diagram-contrast)&quot; font-weight=&quot;bold&quot;&gt;Predicts: &quot;wit&quot;&lt;/text&gt;
              
              &lt;path d=&quot;M 320 375 L 320 408&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; stroke-dasharray=&quot;4&quot; /&gt;
              &lt;polygon points=&quot;320,408 316,400 324,400&quot; fill=&quot;currentColor&quot; /&gt;

              &lt;rect x=&quot;20&quot; y=&quot;410&quot; width=&quot;360&quot; height=&quot;50&quot; rx=&quot;6&quot; fill=&quot;var(--diagram-green)&quot; fill-opacity=&quot;0.15&quot; stroke=&quot;var(--diagram-green)&quot; stroke-width=&quot;2&quot; /&gt;
              &lt;text x=&quot;200&quot; y=&quot;432&quot; text-anchor=&quot;middle&quot; font-size=&quot;16&quot; font-weight=&quot;bold&quot; fill=&quot;currentColor&quot;&gt;Final Complete Sentence&lt;/text&gt;
              &lt;text x=&quot;200&quot; y=&quot;450&quot; text-anchor=&quot;middle&quot; font-size=&quot;14&quot; fill=&quot;currentColor&quot;&gt;&quot;Brevity is the soul of wit.&quot;&lt;/text&gt;
            &lt;/svg&gt;

            &lt;p&gt;This fact is so important that I want to spend some extra time emphasising it, because it really is quite remarkable. The core of the entire AI boom we are experiencing is largely built around programs which simply predict the next token in a sentence. It is not simply predicting a single token, as tall a task as this may be, that has led to the boom, but building entirely new passages of text from the tokens that are predicted.&lt;/p&gt;
            &lt;p&gt;This has led to quite a bit of consternation from a pair of camps that take opposing philosophical positions. The first camp says that because &quot;all&quot; that LLMs are doing is predicting the next token, this demonstrates that they are not intelligent, do not have a strong concept of the world, and are not a path to &quot;true&quot; AI. This is the &quot;glorified autocomplete&quot; crowd. The second camp (including Sutskever), claims that the ability to accurately predict the next token in very complex sequences of tokens &lt;i&gt;demands&lt;/i&gt; intelligence and a strong understanding of the world, and that, in principle, this is what humans do when they speak, write, or do anything &lt;a href=&quot;#fn-9&quot;&gt;[9]&lt;/a&gt;.&lt;/p&gt;
            &lt;p&gt;Much of this debate circles around what actually constitutes intelligence and &quot;understanding&quot; of the world. Without staking too strong a claim for myself (though I have opinions), I think that both sides would agree that for a surprising number of tasks, LLMs don't need to deeply understand the world to be extremely useful, regardless of whether they actually are or are not &quot;truly intelligent&quot;. Language is so thoroughly filled with patterns, and we as people have done such a good job codifying what those patterns mean, that just completing relatively simple patterns is enough to be extremely useful.&lt;/p&gt;

            &lt;h2&gt;A Brief Aside &amp;mdash; Generative AI&lt;/h2&gt;
            &lt;p&gt;You may have heard people talk about &quot;generative AI&quot;, referring to LLMs (among other things, including image generators, text-to-speech models, video generators, etc.). This term can give the impression that these models are somehow technically a different type of AI than simpler examples, like bird classifiers or spam filters. The truth is that this term is more about what we &lt;i&gt;do&lt;/i&gt; with the model rather than the model itself. There's nothing about an LLM that forces us to perform auto-regression and generate sentences; we could just predict the next token once and be on our merry way. All that the models do is predict the next token. I find that &quot;generative AI&quot; produces more confusion than it does clarity, so I will avoid the term in future.&lt;/p&gt;

            &lt;h2 id=&quot;what-models-really-give-you&quot;&gt;What Models Really Give You&lt;/h2&gt;
            &lt;p&gt;To add another wrinkle to things, I've actually lied to you a little bit. Language models don't actually give you &lt;i&gt;the&lt;/i&gt; single token which will come next, instead they give you what's called a &lt;b&gt;probability distribution&lt;/b&gt; over all the tokens which possibly could come next.&lt;/p&gt;
            &lt;p&gt;This is essentially a list of every token the model knows and the model's estimate of the likelihood that it is really the one that comes next. Sometimes, the model will be very sure about the next token; this happens most often with auxiliary words which are necessary for a sentence to make sense, like &quot;the&quot;, &quot;and&quot;, or &quot;to&quot;. Sometimes, though, several tokens may have roughly similar probabilities.&lt;/p&gt;
            
            &lt;svg width=&quot;100%&quot; viewBox=&quot;0 0 550 400&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; style=&quot;max-width: 550px; display: block; margin: 20px auto;&quot;&gt;
              &lt;text x=&quot;20&quot; y=&quot;35&quot; fill=&quot;currentColor&quot; font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;16&quot; font-weight=&quot;bold&quot;&gt;Given context: &quot;Brevity is the...&quot;&lt;/text&gt;
              
              &lt;g font-family=&quot;system-ui, sans-serif&quot; font-size=&quot;14&quot;&gt;
                &lt;text x=&quot;90&quot; y=&quot;85&quot; text-anchor=&quot;end&quot; fill=&quot;currentColor&quot; font-weight=&quot;bold&quot;&gt;soul&lt;/text&gt;
                &lt;rect x=&quot;100&quot; y=&quot;70&quot; width=&quot;280&quot; height=&quot;22&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-blue)&quot; /&gt;
                &lt;text x=&quot;390&quot; y=&quot;86&quot; fill=&quot;currentColor&quot; font-weight=&quot;bold&quot;&gt;70.0%&lt;/text&gt;

                &lt;text x=&quot;90&quot; y=&quot;120&quot; text-anchor=&quot;end&quot; fill=&quot;currentColor&quot;&gt;essence&lt;/text&gt;
                &lt;rect x=&quot;100&quot; y=&quot;105&quot; width=&quot;48&quot; height=&quot;22&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-blue-soft)&quot; /&gt;
                &lt;text x=&quot;155&quot; y=&quot;121&quot; fill=&quot;currentColor&quot;&gt;12.0%&lt;/text&gt;

                &lt;text x=&quot;90&quot; y=&quot;155&quot; text-anchor=&quot;end&quot; fill=&quot;currentColor&quot;&gt;key&lt;/text&gt;
                &lt;rect x=&quot;100&quot; y=&quot;140&quot; width=&quot;24&quot; height=&quot;22&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-blue-soft)&quot; /&gt;
                &lt;text x=&quot;130&quot; y=&quot;156&quot; fill=&quot;currentColor&quot;&gt;6.0%&lt;/text&gt;

                &lt;text x=&quot;90&quot; y=&quot;190&quot; text-anchor=&quot;end&quot; fill=&quot;currentColor&quot;&gt;answer&lt;/text&gt;
                &lt;rect x=&quot;100&quot; y=&quot;175&quot; width=&quot;16&quot; height=&quot;22&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-blue-soft)&quot; /&gt;
                &lt;text x=&quot;122&quot; y=&quot;191&quot; fill=&quot;currentColor&quot;&gt;4.0%&lt;/text&gt;

                &lt;text x=&quot;90&quot; y=&quot;225&quot; text-anchor=&quot;end&quot; fill=&quot;currentColor&quot;&gt;perf&lt;/text&gt;
                &lt;rect x=&quot;100&quot; y=&quot;210&quot; width=&quot;12&quot; height=&quot;22&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-blue-soft)&quot; /&gt;
                &lt;text x=&quot;118&quot; y=&quot;226&quot; fill=&quot;currentColor&quot;&gt;3.0%&lt;/text&gt;

                &lt;text x=&quot;90&quot; y=&quot;260&quot; text-anchor=&quot;end&quot; fill=&quot;currentColor&quot;&gt;&amp;lt;/&lt;/text&gt;
                &lt;rect x=&quot;100&quot; y=&quot;245&quot; width=&quot;8&quot; height=&quot;22&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-muted)&quot; /&gt;
                &lt;text x=&quot;114&quot; y=&quot;261&quot; fill=&quot;currentColor&quot;&gt;2.0%&lt;/text&gt;

                &lt;text x=&quot;90&quot; y=&quot;295&quot; text-anchor=&quot;end&quot; fill=&quot;currentColor&quot;&gt;_1&lt;/text&gt;
                &lt;rect x=&quot;100&quot; y=&quot;280&quot; width=&quot;6&quot; height=&quot;22&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-muted)&quot; /&gt;
                &lt;text x=&quot;112&quot; y=&quot;296&quot; fill=&quot;currentColor&quot;&gt;1.5%&lt;/text&gt;

                &lt;text x=&quot;90&quot; y=&quot;330&quot; text-anchor=&quot;end&quot; fill=&quot;currentColor&quot;&gt;ious&lt;/text&gt;
                &lt;rect x=&quot;100&quot; y=&quot;315&quot; width=&quot;4&quot; height=&quot;22&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-muted)&quot; /&gt;
                &lt;text x=&quot;110&quot; y=&quot;331&quot; fill=&quot;currentColor&quot;&gt;1.0%&lt;/text&gt;

                &lt;text x=&quot;90&quot; y=&quot;365&quot; text-anchor=&quot;end&quot; fill=&quot;currentColor&quot;&gt;Amazon&lt;/text&gt;
                &lt;rect x=&quot;100&quot; y=&quot;350&quot; width=&quot;2&quot; height=&quot;22&quot; rx=&quot;4&quot; fill=&quot;var(--diagram-muted)&quot; /&gt;
                &lt;text x=&quot;108&quot; y=&quot;366&quot; fill=&quot;currentColor&quot;&gt;0.5%&lt;/text&gt;
              &lt;/g&gt;
            &lt;/svg&gt;

            &lt;p&gt;If we just picked the most likely token every time, we would generally end up with a very stilted, bland sentence, which we don't always want, so what we generally do is &lt;b&gt;sample&lt;/b&gt; from the tokens. This means that we pick a token at random, but let the model load the dice. If the model predicts that a token is almost guaranteed to be next, then it will probably be picked, but if it's not, then we could end up with one of several possibilities. The model decides the likelihood of any token coming next, and we roll the dice and find out which one we get.&lt;/p&gt;

            &lt;h2&gt;The Trillion-Dollar Question&lt;/h2&gt;
            &lt;p&gt;From deep within the guts of it, this language modeling sounds surprisingly simple (though the maths is not). A language model just asks its one and only question, &quot;which token comes next?&quot; again and again and again. Why, then, is the estimated cost of the global AI build-out measured in the trillions of dollars? Why are people declaring the start of a transformation on the scale of the internet revolution itself? How did an LLM solve a decades-old maths problem &lt;a href=&quot;#fn-10&quot;&gt;[10]&lt;/a&gt;, why are software engineers adopting them to write so much code, and how do they pass legal exams?&lt;/p&gt;
            &lt;p&gt;We'll discuss the answer in the next post in this series: they are &lt;i&gt;Large&lt;/i&gt;, in every sense. The computers they run on are large. The models are large. The training data is large. The LLM is the backbone of a very strange industry that only works because of a truly massive scale.&lt;/p&gt;
          &lt;/section&gt;
          &lt;hr /&gt;
          &lt;section&gt;
            &lt;p id=&quot;fn-1&quot;&gt;[1] And in Google search itself, even without the AI summary.&lt;/p&gt;
            &lt;p id=&quot;fn-2&quot;&gt;[2] Yes, I know about plate tectonics. Humour me. &lt;a href=&quot;#fn-3&quot;&gt;[3]&lt;/a&gt;&lt;/p&gt;
            &lt;p id=&quot;fn-3&quot;&gt;[3] For the truly pedantic: remember that LLMs model &lt;i&gt;language&lt;/i&gt;, not reality itself. In language we often use mountains as a stand-in for things that don't move (&quot;He was as stoic as a mountain&quot;), so it is quite likely that most LLMs will have a strong association between mountains and immovability, and there may even be more metaphorical use of mountains as completely still than there is detailed descriptions of seismology.&lt;/p&gt;
            &lt;p id=&quot;fn-4&quot;&gt;[4] For modern LLMs, the maths does not necessarily work out like this, but it is a useful illustration, and was generally true for older language modeling approaches like &lt;i&gt;word2vec&lt;/i&gt;.&lt;/p&gt;
            &lt;p id=&quot;fn-5&quot;&gt;[5] Using GPT-5's word-to-token converter, called a &lt;b&gt;tokeniser&lt;/b&gt;.&lt;/p&gt;
            &lt;p id=&quot;fn-6&quot;&gt;[6] It is often easier for an LLM to write a small program that manually counts the letters for it.&lt;/p&gt;
            &lt;p id=&quot;fn-7&quot;&gt;[7] &lt;a href=&quot;https://youtu.be/I6qQinoY9WM?si=2HUwpS7uTZcJw4iJ&amp;t=1666&quot;&gt;Found here&lt;/a&gt;, touched up for readability&lt;/p&gt;
            &lt;p id=&quot;fn-8&quot;&gt;[8] There are language models which use approaches other than auto-regression. The most prominent of these are &quot;masked language modeling&quot;, in which we hide a word in the middle of a sentence rather than at the end, and ask the model to predict the hidden word, and &quot;text diffusion&quot;, which generates text by masking an entire sentence and then repeatedly un-masks words until the sentence is complete. Auto-regression is more common among chatbots that you will likely encounter, though, so I will leave these for another article.&lt;/p&gt;
            &lt;p id=&quot;fn-9&quot;&gt;[9] I have massively simplified both sides here for the sake of brevity, but I hope neither would feel I have misrepresented them here, or at least that I have misrepresented both equally.&lt;/p&gt;
            &lt;p id=&quot;fn-10&quot;&gt;[10] &lt;a href=&quot;https://openai.com/index/model-disproves-discrete-geometry-conjecture/&quot;&gt;https://openai.com/index/model-disproves-discrete-geometry-conjecture/&lt;/a&gt;&lt;/p&gt;
          &lt;/section&gt;</content:encoded>
    </item>
    <item>
      <title>AI for Normal People #1 | Models</title>
      <link>https://gear-research.com/blog/normal-ai-1.html</link>
      <guid isPermaLink="true">https://gear-research.com/blog/normal-ai-1.html</guid>
      <pubDate>Sat, 11 Jul 2026 00:00:00 GMT</pubDate>
      <description>What is a machine learning model? Explaining models in ML and the importance of asking them the right questions.</description>
      <content:encoded>&lt;section&gt;
            &lt;p&gt;For the first few entries in this series, I am going to be focusing on a specific class of AI system: Large Language Models (LLMs). This is mainly because LLMs are by far the most visible thing that most people will think of when they hear &quot;AI&quot;. These are the models behind ChatGPT, Gemini, Claude, DeepSeek, and many more you may or may not have heard of. The next reason is that most of my experience within the field is with LLMs. They were a key part of my thesis, and have now become an everyday tool for the work of many (perhaps most) software engineers.&lt;/p&gt;
            &lt;p&gt;First, I will be explaining what a Large Language Model is in reverse order, since this is the best way to make sense of these suddenly ubiquitous tools, starting with &quot;Model&quot;. By the end of this article, you should have a basic idea of what people mean when they say 'the model was trained' and why it matters.&lt;/p&gt;

            &lt;h2&gt;What is a Model?&lt;/h2&gt;
            &lt;img src=&quot;../assets/normal-ai-1/solar-system.png&quot; alt=&quot;A model solar system. Public domain image&quot;&gt;
            &lt;p&gt;&quot;Model&quot; is obviously not just a machine learning term. In general, a model is a &quot;simplified picture of something that actually exists&quot;. We make models all the time for all sorts of things. The image above is a model solar system; we refer to fashion &quot;models&quot; because they show you what clothes would look like under ideal circumstances; people use &quot;model&quot; trains to show how a real train would move around some shape of tracks.&lt;/p&gt;
            &lt;p&gt;Models are useful, but because they're all simplifications of reality, we can only get useful answers out of them if we ask them the right questions. If you ask the above model solar system what order the planets are in by distance from the Sun, it will give you the correct answer. But if you ask how far the planets are from each other, or how big they are relative to each other, it will be very wrong. Similarly, a fashion model won't tell you anything useful if they are a foot taller than you. They need to be roughly your height and build to be of any use in showing you what some clothes might look like if you bought and wore them.&lt;/p&gt;
            &lt;p&gt;Thus, the key to making good use of any kind of model is to understand exactly what kinds of questions they are designed to answer and what questions you are actually asking them, and ensuring those two line up. &lt;/p&gt;

            &lt;h2&gt;Models in Machine Learning&lt;/h2&gt;
            &lt;p&gt;When we talk about &quot;models&quot; in machine learning, we're talking about &lt;b&gt;statistical models&lt;/b&gt;. These aggregate patterns to answer questions, and it turns out that pattern recognition is surprisingly hard for computers to do.&lt;/p&gt;
            &lt;p&gt;Before we see how pattern recognition applies to words (which we'll cover in the following post), it's easiest to see it in action with images. Suppose I gave you a giant stack of photos and asked you to sort them into piles, one with pictures containing birds, and one without. You are not allowed to look at them. You can only write down a list of rules which use the colour of the pixels in each photo to determine if it contains a bird or not. We can only use pixels because computers don't have eyes; to them a photo is a grid of coloured dots, each represented only with numbers.&lt;/p&gt;
            &lt;p&gt;This is nearly impossible. There are many different kinds of birds, which can take many poses or be in many different backgrounds. In fact, even if you did know there was a bird in a picture, you'd probably have a hard time even telling which pixels were the bird and which weren't from their colour alone. &lt;/p&gt;
            &lt;img src=&quot;https://imgs.xkcd.com/comics/tasks.png&quot; alt=&quot;xkcd comic about the difficulty of completing tasks&quot;&gt;
            &lt;p&gt;A machine learning approach is different. Rather than writing rules by hand, we let the computer discover statistical patterns that usually separate bird photos from non-bird photos. But these patterns have to be stored somewhere. A machine learning model doesn't store them as a list of rules in English or a programming language. Instead, it uses a huge collection of numbers called &lt;b&gt;weights&lt;/b&gt; (or &lt;b&gt;parameters&lt;/b&gt;). The model itself is a chain of mathematical calculations. Each operation takes the image, combines it with some of these weights, and passes the result to the next operation in the chain until the last operation produces an answer like &quot;90% chance this image contains a bird.&quot;&lt;/p&gt;

            &lt;figure&gt;
              &lt;svg viewBox=&quot;0 0 620 220&quot; style=&quot;max-width: 620px; width: 100%; height: auto;&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;
                &lt;style&gt;
                  .box { fill: var(--background); stroke: var(--border); stroke-width: 2; rx: 8; }
                  .arrow { stroke: var(--text-muted); stroke-width: 2; fill: none; marker-end: url(#ah); }
                  .label { fill: var(--text-main); font-family: system-ui, sans-serif; font-size: 14px; text-anchor: middle; }
                  .weight-text { fill: var(--text-main); font-family: system-ui, sans-serif; font-size: 13px; text-anchor: middle; }
                  .caption { fill: var(--text-muted); font-family: system-ui, sans-serif; font-size: 12px; text-anchor: middle; font-style: italic; }
                &lt;/style&gt;
                &lt;defs&gt;
                  &lt;marker id=&quot;ah&quot; markerWidth=&quot;10&quot; markerHeight=&quot;7&quot; refX=&quot;10&quot; refY=&quot;3.5&quot; orient=&quot;auto&quot;&gt;
                    &lt;polygon points=&quot;0 0, 10 3.5, 0 7&quot; fill=&quot;var(--text-muted)&quot; /&gt;
                  &lt;/marker&gt;
                &lt;/defs&gt;
                &lt;!-- Input box --&gt;
                &lt;rect class=&quot;box&quot; x=&quot;10&quot; y=&quot;55&quot; width=&quot;130&quot; height=&quot;70&quot; /&gt;
                &lt;text class=&quot;label&quot; x=&quot;75&quot; y=&quot;95&quot;&gt;Input photo&lt;/text&gt;
                &lt;!-- Arrow input → calculations --&gt;
                &lt;line class=&quot;arrow&quot; x1=&quot;145&quot; y1=&quot;90&quot; x2=&quot;235&quot; y2=&quot;90&quot; /&gt;
                &lt;!-- Calculations box --&gt;
                &lt;rect class=&quot;box&quot; x=&quot;245&quot; y=&quot;55&quot; width=&quot;130&quot; height=&quot;70&quot; /&gt;
                &lt;text class=&quot;label&quot; x=&quot;310&quot; y=&quot;95&quot;&gt;Calculations&lt;/text&gt;
                &lt;!-- Arrow calculations → output --&gt;
                &lt;line class=&quot;arrow&quot; x1=&quot;380&quot; y1=&quot;90&quot; x2=&quot;470&quot; y2=&quot;90&quot; /&gt;
                &lt;!-- Output box --&gt;
                &lt;rect class=&quot;box&quot; x=&quot;480&quot; y=&quot;55&quot; width=&quot;130&quot; height=&quot;70&quot; /&gt;
                &lt;text class=&quot;label&quot; x=&quot;545&quot; y=&quot;95&quot;&gt;90% bird&lt;/text&gt;
                &lt;!-- Weights box (below) --&gt;
                &lt;rect class=&quot;box&quot; x=&quot;245&quot; y=&quot;160&quot; width=&quot;130&quot; height=&quot;35&quot; /&gt;
                &lt;text class=&quot;weight-text&quot; x=&quot;310&quot; y=&quot;183&quot;&gt;[0.81, -1.25, 3.79]&lt;/text&gt;
                &lt;text class=&quot;label&quot; x=&quot;310&quot; y=&quot;210&quot; style=&quot;font-size:12px;&quot;&gt;Weights&lt;/text&gt;
                &lt;!-- Arrow weights → calculations --&gt;
                &lt;line class=&quot;arrow&quot; x1=&quot;310&quot; y1=&quot;160&quot; x2=&quot;310&quot; y2=&quot;130&quot; /&gt;
              &lt;/svg&gt;
            &lt;/figure&gt;

            &lt;h2&gt;Training Models&lt;/h2&gt;
            &lt;p&gt;The problem is that we don't know what the best weights should be for any given task. If you have to set a billion weights in a model which will detect birds for us, you're going to have a very hard time. This is where the &quot;learning&quot; in machine learning comes from. Instead of setting them ourselves, we use an algorithm to &quot;train&quot; the model to find the best weights for our task. &lt;/p&gt;
            &lt;p&gt;These weights are set randomly to begin with, so the output is essentially a new random guess for each new input. This is obviously not very good but what makes machine learning so powerful is that we can improve the weights, little by little, until they consistently produce a result we actually want. &lt;/p&gt;
            &lt;figure&gt;
              &lt;svg viewBox=&quot;0 0 500 160&quot; style=&quot;max-width: 500px; width: 100%; height: auto;&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;
                &lt;style&gt;
                  .line { stroke: var(--text-muted); stroke-width: 2; }
                  .dot { fill: var(--links); stroke: var(--text-main); stroke-width: 2; }
                  .label { fill: var(--text-main); font-family: system-ui, sans-serif; font-size: 14px; text-anchor: middle; }
                  .end-label { fill: var(--text-muted); font-family: system-ui, sans-serif; font-size: 13px; text-anchor: middle; }
                  .caption { fill: var(--text-muted); font-family: system-ui, sans-serif; font-size: 12px; text-anchor: middle; font-style: italic; }
                &lt;/style&gt;
                &lt;defs&gt;
                  &lt;marker id=&quot;ah2&quot; markerWidth=&quot;10&quot; markerHeight=&quot;7&quot; refX=&quot;10&quot; refY=&quot;3.5&quot; orient=&quot;auto&quot;&gt;
                    &lt;polygon points=&quot;0 0, 10 3.5, 0 7&quot; fill=&quot;var(--text-muted)&quot; /&gt;
                  &lt;/marker&gt;
                  &lt;marker id=&quot;ah2r&quot; markerWidth=&quot;10&quot; markerHeight=&quot;7&quot; refX=&quot;0&quot; refY=&quot;3.5&quot; orient=&quot;auto&quot;&gt;
                    &lt;polygon points=&quot;10 0, 0 3.5, 10 7&quot; fill=&quot;var(--text-muted)&quot; /&gt;
                  &lt;/marker&gt;
                &lt;/defs&gt;
                &lt;!-- Top line: initial weight --&gt;
                &lt;line class=&quot;line&quot; x1=&quot;60&quot; y1=&quot;40&quot; x2=&quot;440&quot; y2=&quot;40&quot; marker-start=&quot;url(#ah2r)&quot; marker-end=&quot;url(#ah2)&quot; /&gt;
                &lt;text class=&quot;end-label&quot; x=&quot;40&quot; y=&quot;44&quot;&gt;Wrong&lt;/text&gt;
                &lt;text class=&quot;end-label&quot; x=&quot;460&quot; y=&quot;44&quot;&gt;Right&lt;/text&gt;
                &lt;circle class=&quot;dot&quot; cx=&quot;250&quot; cy=&quot;40&quot; r=&quot;10&quot; /&gt;
                &lt;text class=&quot;label&quot; x=&quot;250&quot; y=&quot;22&quot; style=&quot;font-size:12px;&quot;&gt;Initial weight&lt;/text&gt;
                &lt;!-- Bottom line: after one example --&gt;
                &lt;line class=&quot;line&quot; x1=&quot;60&quot; y1=&quot;110&quot; x2=&quot;440&quot; y2=&quot;110&quot; marker-start=&quot;url(#ah2r)&quot; marker-end=&quot;url(#ah2)&quot; /&gt;
                &lt;text class=&quot;end-label&quot; x=&quot;40&quot; y=&quot;114&quot;&gt;Wrong&lt;/text&gt;
                &lt;text class=&quot;end-label&quot; x=&quot;460&quot; y=&quot;114&quot;&gt;Right&lt;/text&gt;
                &lt;circle class=&quot;dot&quot; cx=&quot;338&quot; cy=&quot;110&quot; r=&quot;10&quot; /&gt;
                &lt;text class=&quot;label&quot; x=&quot;338&quot; y=&quot;92&quot; style=&quot;font-size:12px;&quot;&gt;After one example&lt;/text&gt;
              &lt;/svg&gt;
            &lt;/figure&gt;

            &lt;p&gt;To do this, we need a &quot;training dataset&quot;. This is a large number of examples, and labels for the examples. In the case of our bird detector, this would be a large number of photos with descriptions of what are in them. We can run each photo through our model to get the output, but because we already know which photos contain birds, we can calculate how wrong the output was. Then, using some maths that I won't get into here &lt;a href=&quot;#fn-1&quot;&gt;[1]&lt;/a&gt;, we can find a tiny change for every weight in the model that would have made it a little bit more correct. &lt;/p&gt;
            &lt;p&gt;If you do this with enough examples, the model's weights should slowly move towards something that consistently gives us the right answers. If our dataset has many different kinds of bird in it, the differences between them, like their size or colour, should cancel each other out and we &lt;i&gt;should&lt;/i&gt; be left with just their similarities &amp;mdash; the core of &quot;birdness&quot;, like beaks, feathers, and wings &lt;a href=&quot;#fn-2&quot;&gt;[2]&lt;/a&gt;. &lt;/p&gt;
            
            &lt;h2&gt;Inference&lt;/h2&gt;
            &lt;p&gt;At the end of training, if we've done it right, we're left with a pipeline of mathematical calculations and weights to go with them that will give us an output that aligns with our expectations. This is what people are talking about when they refer to a &quot;model&quot;: the combination of weights and calculations that converts input to output. The process of the conversion (running all the equations with a single input to get a single output) is called &quot;inference&quot;.&lt;/p&gt;
            &lt;p&gt;At this point, we freeze the weights and deploy the model to whatever real task we care about (classifying birds). The main reason we keep training and inference separate is that training is hard and takes a lot more computation than inference, since you have to both produce the output &lt;i&gt;and&lt;/i&gt; work out how wrong that output was to update the weights again. The weights don't have to be frozen forever, though. If we want to expand the training dataset, we can always resume where we left off.&lt;/p&gt;
            &lt;p&gt;When we have a model performing inference, our hope is that, by seeing enough different examples, the model will also make good predictions for new images it has never seen before because it has found the patterns it needs to be correct about future images. The ability for a model to do this is called &lt;b&gt;generalisation&lt;/b&gt;, and training models that generalise well is the whole aim of machine learning.&lt;/p&gt;

            &lt;h2&gt;What Models Learn&lt;/h2&gt;
            &lt;p&gt;What's important to keep in mind is what a model, any model, actually &lt;i&gt;learns&lt;/i&gt; to do, which is &quot;to be as not wrong as it can about the data it was trained on&quot;. &lt;/p&gt;
            
            &lt;h3&gt;&quot;Not Wrong-ness&quot;&lt;/h3&gt;
            &lt;p&gt;As I noted earlier, when training a model we calculate how wrong it was about a particular output, given the output we were expecting. In our bird case, we might put in a picture that we know contains a bird, and get something like &quot;65% chance this contains a bird&quot;. Because our answer card (which the model never saw) says it definitely contains a bird, this means that the model is partly right, but somewhat wrong about the image. If it had said there was a 20% chance of bird, then it would be much more wrong. As such, in the 65% confident case, we nudge the weights in the model a little bit so that next time it would be 70% confident about the same image, and in the 20% case we nudge them a lot, so that next time it will be 50% confident.&lt;/p&gt;
            &lt;p&gt;While we could push every weight all the way to being perfectly right about one image, this would make the model worse (perhaps much worse) for every other image, since every image will have different weights that produce the 100% most correct result. Instead, we calculate a small change and do this many times. The equation that we use to calculate the model's &quot;wrongness&quot; is called the &lt;b&gt;loss function&lt;/b&gt;.&lt;/p&gt;

            &lt;h3&gt;Training Data&lt;/h3&gt;
            &lt;p&gt;The other important thing to keep in mind is that the model has not seen absolutely every image ever taken of every bird, and certainly not every image that &lt;i&gt;could&lt;/i&gt; ever be taken. The model only ever received weight updates for images that we provided to it during training. If many of these were mislabelled (a bunch of pictures of bats got into our training set and we said they were birds, for example), then the model's weights will be updated in the wrong direction. &lt;/p&gt;
            &lt;p&gt;Alternatively, there might be subtle biases in our training data. Suppose that all the pictures we took of birds were in flight, while everything else was on the ground. Then, if we gave our model a picture of a bird sitting on the ground or in a tree, it would probably not find the bird. During training the model will probably notice that every photo containing a bird also has a whole lot of light blue pixels. Our process for updating model weights incentivises them to look for the path of least resistance. If it can always check the colour of the top-right pixel and be correct, then there's no need to learn what birds actually look like.&lt;/p&gt;
            &lt;p&gt;In the case of the image below, we can see there is a mismatch between the questions we think the model is answering (&quot;does this have a bird in it?&quot;) and those it is actually answering (&quot;is the top-right pixel in this image light blue?&quot;).&lt;/p&gt;
            &lt;img src=&quot;../assets/normal-ai-1/bird-classifier-bad.png&quot; alt=&quot;A bird classifier making an incorrect prediction&quot;&gt;

            &lt;h2&gt;What About Language?&lt;/h2&gt;
            &lt;p&gt;We've discussed detecting birds in this post because it's an easy example to show what models are and how they work. The core idea is that, for all kinds of models, be they fashion, bird detectors, or LLMs, we have to make sure the questions they answer align with the questions we ask. Once we understand how models learn to recognise birds, we'll see that LLMs use the same principles, only with words rather than pixels.&lt;/p&gt;

          &lt;/section&gt;
          &lt;hr /&gt;
          &lt;section&gt;
            &lt;p id=&quot;fn-1&quot;&gt;[1] Partial derivatives and the chain rule, if you happen to remember high school calculus. Don't worry if you don't, we aren't going to be touching it in this series.&lt;/p&gt;
            &lt;p id=&quot;fn-2&quot;&gt;[2] This isn't exactly how the maths works, but it's a useful way to think about what we're trying to achieve. Researchers have cracked open models to look inside and found that some of the time they do tend to find traits that we would recognise as feather-y or beak-y, but often they're doing something stranger and it's not always obvious why &amp;mdash; we only know that whatever they're doing, they get the right answer in the end. One of the many things that makes machine learning interesting.&lt;/p&gt;
          &lt;/section&gt;</content:encoded>
    </item>
    <item>
      <title>AI for Normal People #0 | Introduction</title>
      <link>https://gear-research.com/blog/normal-ai-0.html</link>
      <guid isPermaLink="true">https://gear-research.com/blog/normal-ai-0.html</guid>
      <pubDate>Sat, 11 Jul 2026 00:00:00 GMT</pubDate>
      <description>An introduction to AI for non-technical readers.</description>
      <content:encoded>&lt;section&gt;
            &lt;p&gt;This will be a series of posts intended to provide a basic understanding of what artificial intelligence is and how it works to people with little-to-no maths or computer science background. Almost everyone has encountered AI at some stage, somewhere online. I don't think it would be an exaggeration to say that AI is, by far, the loudest technological revolution of our lifetimes. Because of all this noise around the subject, I have found that nearly everyone outside the field has difficulty keeping up &lt;a href=&quot;#fn-1&quot;&gt;[1]&lt;/a&gt;, and there are a number of common misunderstandings and misconceptions associated with it that are hampering productive discussions. Eighty years of science-fiction writing and futurist speculation have popularised a great many ideas, hopes, and fears about AI that are misleading at best, and simply untrue at worst. AI has also very rapidly become a highly politicised flashpoint, sometimes with good reason, but often without. My aim with this series is to clear up this confusion as much as possible.&lt;/p&gt;

            &lt;h2&gt;Another AI Explainer? Really?&lt;/h2&gt;
            &lt;p&gt;As it happens, everything I can cover here has certainly already been said many times. The internet is filled with educational content about AI, much of which was vital to my own studies. However, there appears to be a gap in audience coverage. All of the highest quality content I have seen on this subject (the best of which, for my money, is the 3Blue1Brown YouTube series on machine learning &lt;a href=&quot;#fn-2&quot;&gt;[2]&lt;/a&gt;) depends on a baseline knowledge of maths that most people don't have (and otherwise don't need). What is available for those outside the field is often lacking, not because it skips technical details, but because it is unhelpfully high-level or misunderstands the subject matter &lt;a href=&quot;#fn-3&quot;&gt;[3]&lt;/a&gt;.&lt;/p&gt;
            &lt;p&gt;&lt;i&gt;AI for Normal People&lt;/i&gt; is my attempt to split the difference. This series will build an intuition for how AI works and what it can do, while including absolutely as little formal mathematical notation as I can get away with. My goal is for my non-techy family and friends to come away with a clearer lens through which to interpret the AI news they hear, and the ability to approach the AI systems they encounter in their lives and work with a better understanding of what they can expect. Most AI systems that most people encounter are unique in that not only do they lack an instruction book, even the designers of the systems don't fully understand everything that can be done with them. Understanding the guts of these tools is, in my view, the best way to use them effectively and to decide when not to.&lt;/p&gt;

            &lt;h2&gt;Terminology is Hard&lt;/h2&gt;
            &lt;p&gt;One of the least helpful quirks of the current AI boom is that it abounds with buzzwords and jargon, and sometimes the two switch places.&lt;/p&gt;
            &lt;p&gt;The term &quot;Artificial Intelligence&quot; itself is something of a problem child. The trouble is that it is vague. Consider the following:&lt;/p&gt;
            &lt;ol&gt;
                &lt;li&gt;An abacus&lt;/li&gt;
                &lt;li&gt;A calculator&lt;/li&gt;
                &lt;li&gt;Deep Blue (the chess bot that beat Garry Kasparov in 1997)&lt;/li&gt;
                &lt;li&gt;YouTube's video recommendation engine&lt;/li&gt;
                &lt;li&gt;Nano Banana 2 (Google's image generator)&lt;/li&gt;
                &lt;li&gt;ChatGPT&lt;/li&gt;
                &lt;li&gt;C-3PO (if he actually existed)&lt;/li&gt;
            &lt;/ol&gt;
            &lt;p&gt;Which of these would you consider an &quot;AI&quot;, and why? Where do we draw the line? There are a few possible answers here: &lt;/p&gt;
            &lt;p&gt;&lt;b&gt;Between 4 and 5:&lt;/b&gt; I think this is what most people without computer science experience would say. Image generators, chatbots, and sci-fi droids are all AI. If you are exposed to AI discourse in the news or through advertising, this is almost certainly the definition they (implicitly) use:&lt;/p&gt;
            &lt;p&gt;&lt;i&gt;AI is a computer program that does things which computers have traditionally found difficult, but that people can do, like drawing an image, writing a poem, or translating between languages.&lt;/i&gt;&lt;/p&gt;
            &lt;p&gt;The obvious problem with this definition is that it's a moving target. What &quot;computers find difficult&quot; changes whenever someone develops a new way to achieve these tasks. Once upon a time, Deep Blue was considered an &quot;AI&quot; despite being basically a conventional program (I'll come back to what &quot;conventional&quot; means in a moment &lt;a href=&quot;#fn-4&quot;&gt;[4]&lt;/a&gt;), and the line at the time was between 2 and 3. Computers can now draw, write, or translate, surprisingly well, so we must look for a new line to draw.&lt;/p&gt;
            &lt;p&gt;&lt;b&gt;Between 6 and 7:&lt;/b&gt; This is the view that nothing we currently have is really AI, and it is not without its supporters &lt;a href=&quot;#fn-5&quot;&gt;[5]&lt;/a&gt;. The argument goes that &quot;intelligence&quot; demands certain capabilities like abstract and symbolic reasoning, physical intuition, and continual learning. Modern technology does not currently do this (though even this is debated). ChatGPT is fundamentally linguistic, not physical and embodied. This is a respectable enough definition, but defies the typical use of the term &quot;AI&quot;, claiming that no such thing has ever existed, no matter what the rest of the list can do.&lt;/p&gt;
            &lt;p&gt;&lt;b&gt;Between 3 and 4:&lt;/b&gt; This is as close as you'll get to a &quot;standard&quot; view from within the field itself. The difference between Deep Blue and the YouTube recommendation engine is that the latter integrates &quot;neural networks&quot; and various other kinds of &quot;machine learning&quot;, while Deep Blue does not &lt;a href=&quot;#fn-6&quot;&gt;[6]&lt;/a&gt; (when I call Deep Blue a &quot;conventional&quot; program, I mean that it does not involve machine learning at any stage). On this definition, when people talk about AI they're usually talking about machine learning. &lt;/p&gt;
            &lt;p&gt;Now, machine learning and neural networks are themselves jargon, and they mean something more specific than their names might imply. This is what I will be discussing in these posts, and as such I will be adopting this definition for &quot;AI&quot;. In truth, I prefer to avoid using the term in general, precisely because it is so vague and contested, and I will tend to use &quot;machine learning&quot; (ML) or &quot;deep learning&quot; (DL) instead of AI for the rest of this series.&lt;/p&gt;
          &lt;/section&gt;
          &lt;hr /&gt;
          &lt;section&gt;
            &lt;p id=&quot;fn-1&quot;&gt;[1] They're not alone; I doubt there are any professional AI researchers who are keeping up either.&lt;/p&gt;
            &lt;p id=&quot;fn-2&quot;&gt;[2] &lt;a href=&quot;https://www.youtube.com/watch?v=aircAruvnKk&amp;list=PLZHQObOWTQDNU6R1_67000Dx_ZCJB-3pi&quot;&gt;3Blue1Brown: But what is a neural network?&lt;/a&gt;&lt;/p&gt;
            &lt;p id=&quot;fn-3&quot;&gt;[3] I once saw an AI tutorial which explained that &quot;AI is made of data and algorithms&quot;, which is not so much wrong as it is borderline meaningless.&lt;/p&gt;
            &lt;p id=&quot;fn-4&quot;&gt;[4] In fact, Deep Blue is probably quite a bit better at chess than ChatGPT (until maybe fairly recently).&lt;/p&gt;
            &lt;p id=&quot;fn-5&quot;&gt;[5] Like Yann LeCun, Meta's former AI chief scientist and currently running his own AI company &lt;i&gt;AMI Labs&lt;/i&gt;&lt;/p&gt;
            &lt;p id=&quot;fn-6&quot;&gt;[6] When I first drafted this post my example was Stockfish, the current top chess engine, but it turns out that a few years ago they also started integrating neural networks, while Deep Blue did not.&lt;/p&gt;
          &lt;/section&gt;</content:encoded>
    </item>
  </channel>
</rss>
