# About > The history and foundations of LLMs Unplugged, from CS Unplugged to Shannon's information theory. # About ![](../assets/images/hero-about.avif) _LLMs Unplugged_ is a [Cybernetic Studio](https://cybernetics.anu.edu.au/cybernetic-studio/) project created by [Dr. Ben Swift](https://benswift.me) at the [ANU School of Cybernetics](https://cybernetics.anu.edu.au). If you've got questions, suggestions, or _LLMs Unplugged_ success stories then [send Ben an email](mailto:ben.swift@anu.edu.au). These resources build on a rich history of unplugged computing education (and hands-on education in general). If you're interested in where these ideas came from---or where to go next---this is the reading list. ## CS Unplugged For over two decades, [CS Unplugged](https://csunplugged.org) has demonstrated that core computing concepts can be taught effectively without computers. Through carefully designed hands-on activities, learners from primary school through to adult education have explored algorithms, data structures, and computational thinking. The approach strips away the distractions of syntax and tooling, allowing learners to focus on underlying principles. More importantly: it works (the [literature](https://scholar.google.com/scholar?q=cs%20unplugged) has receipts). Making learning these concepts both effective and fun is possible, and CS Unplugged has proven that at scale. _LLMs Unplugged_ applies this same philosophy to language models. Rather than explaining transformers through mathematics or implementing neural networks in code, participants count word patterns in a text, record them as tally marks on grid paper or physical piles of paper cutouts, then roll dice to generate new text from those patterns. This hands-on approach makes sophisticated AI concepts accessible to anyone, regardless of technical background. ## AI Unplugged resources As machine learning and artificial intelligence became more prominent in public discourse, educators naturally extended the unplugged approach to these fields, for example: - [AI Unplugged](https://www.aiunplugged.org) by Lindner, Seegerer and Romeike - Northwestern University's [AI Unplugged Resources](https://sites.northwestern.edu/aiunplugged/) - [CS In Schools](https://csinschools.io/) by Toan Huynh and Hugh Williams has some material on AI Unplugged1 These collections cover classification, clustering, computer vision, and artificial neural network concepts. However, they contain limited material specifically about language models and especially text generation---a gap that became particularly acute after ChatGPT's November 2022 release shifted what "AI" means to most people. _LLMs Unplugged_ aims to fill that gap. ![Workshop participants building language models with pen and paper](../assets/images/workshop-1.avif) ## Historical foundations The [n-gram language models](https://en.wikipedia.org/wiki/N-gram) participants build in these workshops have a lineage stretching back over a century. This isn't new theory---it's well-established mathematics applied by hand. ### Markov's stochastic processes (1913) Andrey Markov introduced the mathematics of what we now call "Markov chains" while analysing letter sequences in Pushkin's _Eugene Onegin_. His work established that language has statistical structure you can quantify through counting patterns and calculating probabilities. Though Markov's interest was purely mathematical, his framework for modelling sequences of dependent random variables became foundational to computational linguistics. ### Shannon's information theory (1948–1951) Claude Shannon built directly on Markov's foundation, applying his new information theory to written English. Shannon used n-gram models to measure entropy and redundancy in language, connecting statistical patterns to fundamental limits on compression. Crucially, Shannon was the first to systematically generate synthetic text using these models---starting with random letters (0-gram), then letter frequencies (1-gram), then letter pairs (2-gram), and progressively higher orders. This generative approach revealed how increasing context length produces increasingly realistic text, a finding that remains central to modern language models. Here's the thing: Shannon's work was itself "unplugged". He counted transitions by hand, calculated probabilities manually, and generated synthetic text using hand-drawn tables and selection based on frequencies. Modern LLMs use the same fundamental approach but at vastly greater scale and with learned rather than hand-crafted statistics. ### Connection to modern LLMs The activities in _LLMs Unplugged_ demonstrate the same operations used in current language models. The differences are mostly about scale: - **parameters**: hand-built models have dozens to hundreds versus billions in modern LLMs, but the core concepts remain identical - **training**: manual counting versus automated pattern detection, but both processes learn probability distributions from text - **generation**: dice rolls versus GPU-accelerated sampling, but both use weighted randomness to select the next token - **context windows**: bigrams and trigrams versus 128,000+ token windows, but longer context always enables better prediction Modern advances come from doing these same operations at massive scale with neural networks that learn patterns automatically. But the fundamental insight---that language structure can be captured through statistical dependencies and revealed through synthetic generation---comes directly from Shannon's mid-twentieth-century work and the unplugged methods he used to explore these ideas. Which is to say: when you're rolling dice and generating sentences in an _LLMs Unplugged_ workshop, you're not just learning about modern AI. You're also participating in a tradition of hands-on exploration that goes back to the origins of information theory itself. ![Counting word transitions to build a statistical language model](../assets/images/workshop-2.avif) ## About the ANU School of Cybernetics The [School of Cybernetics](https://cybernetics.anu.edu.au) at the Australian National University takes a systems-oriented approach to understanding and shaping technology in society. The School's [Cybernetic Studio](https://cybernetics.anu.edu.au/cybernetic-studio/) develops hands-on resources and runs workshops exploring the social, technical, and political dimensions of emerging technologies. ![LLMs Unplugged workshop in action](../assets/images/workshop-3.avif) _LLMs Unplugged_ reflects the School's commitment to making sophisticated technical concepts accessible to diverse audiences and fostering critical engagement with AI systems that increasingly mediate how we work, learn, and communicate. Understanding how these systems actually work---not through metaphor or handwaving but through direct experience---is what we're all about. ## Acknowledgements This work has benefited enormously from the input and facilitation help of Eddie Aloise King and Cole Cooney and other SoCy staff, plus feedback from hundreds of participants across diverse audiences---school students through to senior executives in the Australian Public Service. Iterating on these materials with real learners has been invaluable. ## Get in touch We encourage educators to use, adapt, and improve these resources. If you have questions, success stories about using them in your classroom, or would like to discuss adaptations or improvements you've made, get in touch at [ben.swift@anu.edu.au](mailto:ben.swift@anu.edu.au)---we'd love2 to hear from you. And if you'd like to be informed of more cool stuff coming out of the School of Cybernetics, then sign up for the [mailing list](https://cybernetics.anu.edu.au/#subscribe-to-our-mailing-list-1). ## Citation If you use these materials in your teaching or research, please cite them as: ### APA > Swift, B. (2025). _LLMs Unplugged: Understand how AI language models work by > building one yourself_. Zenodo. > [https://doi.org/10.5281/zenodo.17403824](https://doi.org/10.5281/zenodo.17403824) ### BibTeX ```bibtex @misc{swift2025llmsunplugged, author = {Swift, Ben}, title = {{LLMs Unplugged: Understand how AI language models work by building one yourself}}, year = 2025, publisher = {Zenodo}, doi = {10.5281/zenodo.17403824}, url = {https://doi.org/10.5281/zenodo.17403824} } ``` ---
  1. There's one activity on Generative AI worksheet that uses a similar "counting bigrams" approach to the Basic Training lesson
  2. well, technically that's a requirement of the SA clause in the CC licence, but it's still true that we'd love hearing about your changes :)
--- # Workshop blurbs > Standard descriptions of the LLMs Unplugged workshop at various lengths, for hosts, event organisers, and conference programs. # Workshop blurbs Standard descriptions of the _LLMs Unplugged_ workshop at different lengths, for hosts, event organisers, and conference programs. Pick whichever fits the space---and if you need something different, or a venue-specific variation, [get in touch](mailto:ben.swift@anu.edu.au). ## Title > LLMs Unplugged: A tech-free guide to understanding (and teaching) AI ## One-liner (≈15 words) > Hands-on workshop that demonstrates how large language models work---no > computers or coding required. ## One paragraph (≈80 words) > Build your own language model with pen, paper and dice. In two hours you'll go > from counting word patterns in a short text to generating new sentences with a > few rolls of a dice---no screens, no coding, no maths beyond basic counting > and percentages. You'll walk away with a concrete understanding of how ChatGPT, > Claude, Gemini and the rest actually work under the hood: the probabilistic > nature of LLMs, the importance of training data, and how bias and design > decisions show up in the output. ## Medium (≈150 words) > Despite the rapid uptake of AI around the globe, most people have no real > mental model of what's actually happening under the hood of our most popular > AI tools. Rather than accepting the hand-wave-y and mystical-sounding > explanations, join us in this fun and informative workshop where you'll learn > about Large Language Models (LLMs)---the technology behind ChatGPT, Claude, > Gemini and Copilot---without actually touching any tech. > > Through hands-on activities and discussion, you'll learn the basic principles > and language of LLMs: the probabilistic nature of these models, the importance > of training data, and the ways that bias and engineered decisions in the > models may present themselves. No coding background required, and no maths > beyond basic counting and percentages. Suitable for educators, professionals, > policymakers, and anyone curious about how AI actually works. ## Long (≈260 words) > Despite the rapid uptake of AI around the globe (including right here in > Australia), most people have no real mental model of what's actually happening > under the hood of our most popular AI tools. > > Rather than accepting the hand-wave-y and mystical-sounding explanations, join > us in this fun and informative workshop where you'll learn about Large > Language Models (LLMs)---the technology behind the mind-boggling abilities of > ChatGPT, Claude, Gemini and Copilot---without actually touching any tech. > Through hands-on activities and discussion, you'll learn the basic principles > and language of LLMs. > > ### Why you should attend > > Having a better understanding of how large language models work will help to > demystify AI and provide a shared understanding and vocabulary for framing AI > systems. These foundations will help you better understand the probabilistic > nature of LLMs, the importance of data, and the ways that bias and engineered > decisions in the models may present themselves. > > ### A note for educators > > If you're a high school or upper primary teacher and find yourself having > conversations with your students about AI, this workshop is for you. Our > activities can be easily replicated in the classroom with readily available > materials and are supported by a range of open-access online resources. The > workshop relates to core curriculum outcomes in maths, technologies, HASS and > literacy and requires zero coding background and no maths beyond basic > counting and percentages. --- # FAQ > Frequently asked questions about using LLMs Unplugged resources, materials needed, and how the activities relate to modern AI. # Frequently asked questions ![](../assets/images/hero-faq.avif) ## Why do you keep saying LLMs---this is AI, right? Ben Swift Honestly, the short answer (these days) is yes. The long answer is more complicated---AI is a term that has been applied to many different algorithmic techniques and systems over the years. But today (in the mid-2020s) Large Language Models have kindof sucked all the air out of the room when it comes to AI, so that's mostly what we're talking about here. I (Ben) do like to use the term LLM rather than AI whenever I can, because I think it's more specific and accurate. ## You mention ChatGPT and Claude a lot, but Gemini/DeepSeek/etc. is more my jam None of these resources are specific to any particular LLM product. We sometimes use "ChatGPT" or "Claude" as shorthand because they're the names most people recognise, but the concepts apply equally to any modern LLM. ## Who is this for? Anyone curious about how language models work. The activities suit learners from primary school age through to adults, with no technical background required. We've delivered them to hundreds of participants---primary and high school students, undergraduate students, and senior executives from industry and government---and the hands-on approach lands in all of those contexts. ## Did some of this stuff used to be called "My First Language Model"? Yep, it sure did... and it still is: [My First Language Model](https://www.llmsunplugged.org/lessons/my-first-language-model/) is the classic LLMs Unplugged lesson. But this website hosts _all_ the LLMs Unplugged resources---other [lessons](https://www.llmsunplugged.org/lessons/), the [modules](https://www.llmsunplugged.org/modules/) they're built from, and the [printable materials](https://www.llmsunplugged.org/tools/)---not just that one workshop. ## Do I need any special materials? Nope, it's all stuff you'll have around the office/house/classroom. Each lesson has a "you will need" section. ## Are there any video resources to accompany the lessons? Not yet, but we're working on it---stay tuned. ## Are there printable versions of the lessons? Not any more---the lessons are now maintained as web pages only, and they print reasonably well straight from your browser if you need hard copies. The printable artefacts for the hands-on activities (pre-generated booklets and cutout sheets) are on the [tools page](https://www.llmsunplugged.org/tools/). ## Can I use these materials in my school classroom? Yes. All materials are released under [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/), so you can use, adapt, and share them for non-commercial educational purposes with attribution. ## Can I use these materials in a paid workshop? The NC (Non-Commercial) clause in our licence has [some ambiguity](https://www.artslaw.com.au/information-sheet/creative-commons) around paid educational activities. Our intention is that educators at schools, universities, and non-profit organisations can use these materials in workshops that charge cost-recovery fees (the [lessons](https://www.llmsunplugged.org/lessons/) each come with suggested session structures and timings). However, for-profit companies cannot run paid workshops using these materials under the [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/) license. If you're a commercial training provider interested in using these resources, please [contact us](https://www.llmsunplugged.org/about/#get-in-touch)---we're happy to discuss alternative licensing arrangements. ## I'm a corporate client, and I'd love to have some experts come and deliver this workshop for us Good news---that's one of the things we do here at the [School of Cybernetics](https://cybernetics.anu.edu.au). [Drop us a line](mailto:lxconvenor.cybernetics@anu.edu.au) to discuss how we can make it happen. Honestly, this stuff is just as fun as a Christmas party/team bonding activity, but the learning is very real. Learning _can_ be fun. ## Why dice and cutouts instead of computers? Using physical randomness makes the probabilistic nature of text generation tangible. When you roll dice and look up words in a table, or pick matching cutouts from a spread on the table, you're doing exactly what a computer does---just slower. This builds genuine understanding rather than treating AI as a black box. ![Using dice to generate text from a hand-built language model](../assets/images/workshop-4.avif) ## How do these activities relate to ChatGPT, Claude, and other LLMs? Modern LLMs use the same fundamental principle: predict the next token based on context. The differences are scale (billions of parameters vs dozens) and learned vs hand-counted statistics. The core mechanism---weighted random selection based on patterns in training data---is identical. ## Can I generate my own booklets from custom text? Yes. You can [generate booklets online](https://www.llmsunplugged.org/tools/) directly in your browser---no installation required. Just upload or paste your text, choose your options, and download a PDF. Your text is processed entirely in your browser and never sent to any server. If you prefer working offline or want to modify the tools, the [source code](https://github.com/ANUcybernetics/llms-unplugged) includes a command-line tool that provides the same functionality. ## Is there a research paper about LLMs Unplugged? Yes. LLMs Unplugged was presented at the [28th Australasian Computing Education Conference (ACE 2026)](https://aceconference2026.github.io/) in Melbourne, Australia. [Download the paper here](https://pdf.llmsunplugged.org/ace2026-llms-unplugged.pdf). ### BibTeX ```bibtex @inproceedings{swift2026llmsunplugged, author = {Swift, Ben}, title = {{LLMs Unplugged: Teaching Resources for a ChatGPT World}}, booktitle = {28th Australasian Computing Education Conference (ACE 2026)}, year = 2026, month = feb, address = {Melbourne, VIC, Australia}, publisher = {ACM}, doi = {10.1145/3786228.3786237}, url = {https://doi.org/10.1145/3786228.3786237} } ``` ## I found an error in the materials. Please [open an issue](https://github.com/ANUcybernetics/llms-unplugged/issues) on GitHub or [contact us](https://www.llmsunplugged.org/about/#get-in-touch). We appreciate corrections and suggestions. ![Participants exploring language models hands-on](../assets/images/workshop-5.avif) --- # Build, break, extend > An extended cutouts workshop. Build paper language models from scratch, combine them, break them (sycophancy), extend them with tools, and finish with a poetry slam. A half-day deep dive using the paper cutout models. Participants build their own language models, pool them into bigger ones, deliberately break them (training in sycophancy), extend them with tools, and put everything together in a closing poetry slam where each group designs a model to perform its own generated verse. We've delivered this lesson once and it worked, but it hasn't had the polish of the others yet---timings and materials may shift as we road-test it. If you're thinking of running it, [get in touch](https://www.llmsunplugged.org/about/#get-in-touch) and we'll share what we've learned. ## Run of show | Section | Time | | ---------------------------------- | ------ | | Icebreaker and intro | 20 min | | [Training](https://www.llmsunplugged.org/modules/training/) | 20 min | | [Generation](https://www.llmsunplugged.org/modules/generation/) | 20 min | | Combining models | 25 min | | _Break_ | 10 min | | [Sycophancy](https://www.llmsunplugged.org/modules/sycophancy/) | 20 min | | [Agentic AI](https://www.llmsunplugged.org/modules/agentic-ai/) | 20 min | | Poetry slam | 45 min | Combining models and the poetry slam are deck-only sections (they don't have standalone module pages yet): combining models pools two groups' cutout spreads to show what more training data buys you, and the poetry slam has each group design a model---choosing training data and sampling rules---to generate and perform a poem. ## You will need - printed token cutouts for several texts (bigram, `-n 2`)---see the [Tools](https://www.llmsunplugged.org/tools/#cutouts) page for ready-to-print packs, and the sycophancy section needs the sycophancy corpus cutouts - clear table space per group of 2-4, plus room to pool spreads when groups combine models - pen and paper per group - a projector for the slides --- # How AI writes stories > A 90-minute primary-school lesson where students discover what AI is, then build their own paper language models and use them to generate stories. Students start by asking a real AI to write a story about their teacher, then spend the rest of the lesson finding out how it did it---by building their own language models out of paper cutouts and generating brand-new stories from the patterns in their favourite picture books. No computers (except yours, for the slides), no maths beyond matching colours. We most recently ran this lesson at [Duffy Primary School](https://www.llmsunplugged.org/news/2026-06-02-how-ai-writes-stories-at-duffy/) with three year 5-6 classes. ## Lesson plan Allow five minutes for arrival and settling before part 1. If you're running over time, part 4 is designed to be dropped---parts 1-3 and 5 are the core of the lesson. | Part | What happens | Time | | ---- | ------------------------------------------------------------------- | ------ | | 1 | **What is AI?** --- discussion, plus an AI writes the class a story | 15 min | | 2 | **Training** --- pattern warm-up, key words, then the training game | 20 min | | 3 | **Generation** --- generate new stories from the trained cutouts | 25 min | | 4 | **One story, all together** --- whole-class story (optional) | 15 min | | 5 | **Wrap-up** --- what did we learn? Q&A | 10 min | **Part 1** opens with think-pair-share ("when you hear _artificial intelligence_, what comes to mind?"), then the fun bit: the class supplies three words, and a slide builds a story prompt starring their teacher that you paste into ChatGPT, Claude, or whichever chatbot you have access to. A dramatic reading later, you have the hook for the whole lesson: _that was a language model, and today we're going to build one_. **Part 2** warms up with predict-the-next-word prompts on the whiteboard (humans are pattern-spotters too), introduces four key words (AI, language model, training, training data), then runs the [Training](https://www.llmsunplugged.org/modules/training/) module in its cutouts flavour: students spread out printed token cutouts from a picture book and discover the patterns. **Part 3** runs the [Generation](https://www.llmsunplugged.org/modules/generation/) module: starting from a single word, students play the colour-matching game to generate new stories---and read them out loud. **Part 4** (optional) generates one story as a whole class: everyone hunts for the current word in their own cutouts, hands go up, and the story grows one word at a time on butchers paper. **Part 5** wraps up with discussion questions---would you get the same story twice? is the model _thinking_?---and open Q&A. ## You will need - printed token cutouts (bigram, i.e. `-n 2`) from two or three picture books---the [Tools](https://www.llmsunplugged.org/tools/#cutouts) page has ready-to-print packs for _Green Eggs and Ham_, _Where Is the Green Sheep?_, and _We're Going on a Bear Hunt_, or you can [generate your own](https://www.llmsunplugged.org/tools/#generate-your-own) - a clear table per group of 2-4 students to spread the cutouts on - pen and paper per group for writing down generated stories - a whiteboard for the predict-the-next-word warm-up - butchers paper and a marker for the class story (part 4) - a projector for the slides, and access to ChatGPT/Claude/etc. for the story-writing demo in part 1 ## Before you deliver - print the cutouts and (ideally) pre-cut them into strips---scissor time is the biggest schedule risk with this age group - have a few predict-the-next-word prompts ready for the whiteboard; ones the class will finish instantly work best (the school's own values, or "yer a wizard..." minus the famous last word) - the story slide in part 1 has fill-in boxes for the teacher's name and the three class words, and builds a copy-paste-ready prompt---check you can log in to a chatbot on the room's computer beforehand - the prompt is tuned for year 5 students in Canberra; if your class is elsewhere (or another year level), tweak the wording after you paste it --- # My First Language Model > The classic LLMs Unplugged workshop. Train a language model on grid paper, then roll dice to generate new text---and see why ChatGPT works the same way. Comes in lengths from 60 minutes to two hours. This is the original LLMs Unplugged workshop, and still the best place to start. Participants count word patterns in a real text, record them as tally marks on grid paper, then roll a d10 to generate brand-new text from those patterns. Somewhere between the tallying and the dramatic readings, the penny drops: this is what ChatGPT does, just vastly scaled up. We've delivered it to school students, undergraduates, teachers, and senior executives in industry and government. It needs no coding and no maths beyond counting and percentages. ## Choose your length One lesson, three lengths. Each length keeps everything from the one before it and adds a module: | Length | Modules | Adds | | ---------- | ------------------------------------------------------------------- | ---------------------------------------------- | | 60 minutes | [Training](https://www.llmsunplugged.org/modules/training/) + [Generation](https://www.llmsunplugged.org/modules/generation/) | the core train-then-generate loop | | 90 minutes | + [Pre-trained Model Generation](https://www.llmsunplugged.org/modules/pretrained-generation/) | what happens with a bigger model and more data | | 2 hours | + [Agentic AI](https://www.llmsunplugged.org/modules/agentic-ai/) | how models use tools to act on the world | Every length opens with a quick icebreaker and scene-setting (who's used ChatGPT? how do you think it works?) and closes with a "scaling up" discussion connecting the paper model to modern LLMs, then Q&A. ## Suggested timing (90-minute version) - **0:00 kick-off** --- icebreaker, then: today we build our own AI, small and simple, but using the exact same approach as the big ones - **0:20 [Training](https://www.llmsunplugged.org/modules/training/)** --- tally word patterns from a text into the grid - **0:40 [Generation](https://www.llmsunplugged.org/modules/generation/)** --- roll dice to generate new text from the grid; share back with dramatic readings - **1:00 [Pre-trained Model Generation](https://www.llmsunplugged.org/modules/pretrained-generation/)** --- same dice game, but with a printed booklet trained on a whole book - **1:20 close** --- scaling up: how does this connect to ChatGPT? how has this changed how you'll _use_ these tools? For the 60-minute version, drop the pre-trained booklet section and tighten the close. For the 2-hour version, add [Agentic AI](https://www.llmsunplugged.org/modules/agentic-ai/) after the pre-trained section (about 20 minutes) and give every discussion a little more room to breathe. ## You will need For each pair (or small group) of participants: - pen or pencil - a printed [grid template](https://pdf.llmsunplugged.org/worksheets/grid.pdf) (or any grid paper) - a d10 die (any die works with a little improvisation) - some training text: a few pages of a kids' book is ideal, but anything works - **90 minutes and up:** a pre-trained model booklet---the [Tools](https://www.llmsunplugged.org/tools/#booklets-for-dice-generation) page has ready-to-print booklets for several texts, or you can [generate your own](https://www.llmsunplugged.org/tools/#generate-your-own) Plus a projector for the slides. ## Before you deliver - print the grid templates, and the booklets if you're running 90 minutes or longer (one per pair; a mix of different texts makes the share-backs more fun) - if your group isn't yet comfortable with dice-based weighted sampling, run the [Weighted Randomness](https://www.llmsunplugged.org/modules/weighted-randomness/) module first as a warm-up (add about 30 minutes) - got extra time, or a group that wants more? the [Sampling](https://www.llmsunplugged.org/modules/sampling/) module makes a great add-on after generation---it shows how temperature changes the character of the output without changing the model --- # Agentic AI > Turn your model into an agent by teaching it to call external tools when it needs information it doesn't have. Turn your language model into an agent by giving it access to external tools---people, objects, or resources in the room---that it can call when it needs information beyond what's in the grid. ![](../../assets/images/hero-tool-use.avif) ## You will need - a completed model from [Training](https://www.llmsunplugged.org/modules/training/) - pen, paper, and dice as per [Generation](https://www.llmsunplugged.org/modules/generation/) - people or things to serve as "tools" (see examples below) ## Your goal Generate text where the model acts as an agent. Stretch goal: design your own tool and integrate it into your model. ## Key idea What makes a language model an "agent"? In practice, it comes down to tool use---a model that can recognise special tokens triggering external actions, pause generation, call a tool, and incorporate the result before continuing. That loop of _generate → call tool → incorporate result → keep generating_ is the core of agentic AI. ## Setting up tools Before generation, choose a person or object who gets to role-play as the "tool". Each tool has: - a **trigger word** that appears in your model's vocabulary - a **capability** (what it can do) - a **return format** (what it gives back) ### Example tools | Trigger word | Tool | Capability | Returns | | ------------ | ----------------------- | --------------------------------- | ---------------------------- | | `ACTION` | a chosen person | perform a small physical action | a word for what they did | | `GOOGLE` | someone with a phone | search the web for a continuation | one word from the top result | | `FRIEND` | everyone texts a friend | ask them what comes next | first reply wins | These three cover the main flavours of real-world tool use: `ACTION` reaches into the room (physical, immediate), `GOOGLE` reaches out to the web (informational, distant), and `FRIEND` reaches a specific human (escalation). ## Algorithm 1. Add trigger words to your model's vocabulary (new rows and columns). 2. Train or manually add counts so trigger words can appear in generation. Each tool-trigger cutout ends with a closing token (e.g., `.`) on the same cutout, so the chain resumes cleanly once the tool returns. 3. During generation, when you sample a trigger word: - pause generation - formulate a question or request based on context - the tool "executes" and returns a result - write the result down in the output text - write the closing token from the same cutout and continue generation from there This is the agentic loop: your model generates until it hits a trigger, hands off to a tool, gets a result, and keeps going. Real AI agents do exactly the same thing---just faster and with more tools. ## Example session Suppose your model has `ACTION` and `GOOGLE` added as trigger tokens, each followed by a closing `.` on the same cutout. 1. Start with "We" 2. Sample → "should" 3. Sample → `GOOGLE` (trigger!) - Pause. Operator googles "what should we do today" - Picks a word from the top result: "exercise" - Write down "exercise" - Write down "." (the closing token on the `GOOGLE` cutout) 4. Sample → "I" 5. Sample → `ACTION` (trigger!) - Pause. Operator picks a student, who claps - Write down "clapped" - Write down "." (the closing token on the `ACTION` cutout) **Generated text:** "We should exercise. I clapped." The operator's words ("exercise", "clapped") get written into the output, but the next cutout picks up from the _closing token_ on the trigger's cutout, not from the result. This means tools can return literally anything---out-of-vocab words, phrases, even sounds---without breaking the generation loop. ## Instructor notes ### Designing good tool triggers For the activity to work well: - add trigger words to cutouts where they fit contextually (e.g., `GOOGLE` after "a" or "the", `ACTION` after "we" or "I") - every trigger cutout closes with a common token like `.` on the same cutout---this silently bridges the tool's result back into the model's vocabulary - the operator's return can be _anything_: an out-of-vocab word, a phrase, even a noise. Continuation is keyed on the closing token, not the result - have tool operators ready (and phones charged) before you start generating ### Other tools to try If you want to extend the activity, design more tools using the same pattern: - `LOOK` --- a physical object in the room returns a word for what it is - `NAME` --- the room points at someone, returns their name - `TIME` --- a clock or watch returns the current time - `ASK` --- a designated expert returns a short phrase The shape is always: something outside the model returns a word, the closing token on the trigger's cutout brings you back. ### Discussion questions - when should an agent use a tool vs try to answer itself? - what happens if a tool returns something unexpected? - how does the model "know" to call a tool? (it doesn't---it just samples the trigger word) - what tools would be most useful for different kinds of text? - could a tool's response change what the agent generates next? ### Classroom variations **Simple version:** use just one tool (FRIEND) and have the whole class participate. The model generates until it hits FRIEND, then everyone texts a friend `What comes next? "[sentence so far]..."`---the first reply wins. **Advanced version:** set up multiple tools around the room. Different students operate different tools. The agent doesn't know which tool will be called next. **Multi-step version:** chain tool calls together---the result of one tool becomes the context for calling another. This is closer to how real AI agents plan and execute multi-step tasks. ### Connection to current LLMs "Agentic AI" has become a buzzword, but in practice it really just means tool use in a loop. As Simon Willison [puts it](https://simonwillison.net/2025/Sep/30/designing-agentic-loops/), an LLM agent is something that "runs tools in a loop to achieve a goal"---and that's exactly what your model is doing. Tool use (also called "function calling") is how modern AI assistants perform actions in the world: - **the agentic loop**: generate → detect tool call → execute tool → feed result back → continue generating, exactly like your trigger-word cycle - **examples**: web search, code execution, API calls, database queries, image generation - **structured calls**: modern models output JSON-formatted tool calls (function name, parameters) rather than just trigger words, but the mechanism is the same - **chaining**: real agents chain multiple tool calls to complete complex tasks---planning, executing, observing results, and adjusting The key insight: the model doesn't "know" anything the tool returns---it just learns when to ask. Your classroom tools demonstrate this perfectly: the model samples GOOGLE not because it knows the answer, but because the training data included GOOGLE in that context. The actual knowledge comes from outside the model. This is why tool-using AI agents can do things like search the web for current information, run calculations they couldn't do in their head, or control robots and software. The model's job is to know _when_ to call a tool and _how_ to use the result---not to contain all knowledge itself. --- # Generation > Use your hand-built bigram model to generate new text through weighted random sampling. This lesson involves rolling dice to sample from weighted probability distributions. If your students need extra support with this concept, consider running the [Weighted Randomness](https://www.llmsunplugged.org/modules/weighted-randomness/) lesson first. Use a pre-trained (hand-built) bigram model to generate new text through weighted random sampling . ![](../../assets/images/hero-grid-generation.avif) ![](../../assets/images/hero-cutouts-generation.avif) ## You will need - your completed bigram model from [Training](https://www.llmsunplugged.org/modules/training/) - a d10 (or similar) for weighted sampling - pen and paper for jotting down the generated text For each pair (or group) of students: - the trained cutouts spread from [Training](https://www.llmsunplugged.org/modules/training/) (already laid out on a table) - pen and paper for writing down the generated text The [Tools](https://www.llmsunplugged.org/tools/#cutouts) page has ready-to-print token cutouts for several texts if you haven't done the Training lesson yet. Each PDF starts with a student-facing instructions page that walks groups through the matching game. ## Your goal Generate new text from your bigram language model. Stretch goal: keep going and write a whole story. Generate new text by walking the spread: pick a starting word, find the cutouts whose previous-word box colour matches, choose one visually, and repeat using the next word you picked as your new starting point. Stretch goal: keep going and write a whole story. ## Key idea A language model proposes several possible next words along with how likely each is. Dice rolls pick among those options, and repeating the process word by word yields fluent text. The chain grows like dominoes: write a word, find a cutout whose previous-word box matches it, write that cutout's next word, then hunt for the next match. The spread already encodes the weights---common previous words appear on more cutouts, and your eye naturally lands on next words that appear more often. So scanning for matching cutouts and picking one visually _is_ weighted random sampling---no dice required. ## Algorithm 1. Choose a starting word from the first column of your grid. 2. Look at that word's row to find all possible next words and their counts. 3. Roll dice weighted by the counts (see [Weighted Randomness](https://www.llmsunplugged.org/modules/weighted-randomness/)). 4. Write down the chosen word and make it your new starting word. 5. Repeat from step 2 until you hit a natural stopping point (e.g., `.`) or your desired length. It's a colour-matching game: the colour of the word you just wrote is the colour of the previous-word box you look for next. 1. **Pick a starting word**---choose any word that appears as a previous word on at least one cutout 2. **Find candidates**---scan the spread for cutouts whose previous-word box matches your current word's colour, then verify the word itself matches before committing (two unrelated words can occasionally share a colour) 3. **Pick one cutout**---visually pick any matching cutout (your eye will tend to land on cutouts whose next words are common, because there are more of them---that's weighted sampling for free) 4. **Write down the next word** from the cutout you picked 5. **Put the cutout back** in the spread (this matters: removing it would change the model's distribution for next time) 6. The word you just wrote becomes your new current word---go back to step 2 7. **Keep going** as long as you like---if no cutouts match your current word, just pick a new starting word and carry on. Stop when you've generated enough text ## Example Before you try generating text yourself, work through this example to see the algorithm in action. Using the same bigram model from the example in [Training](https://www.llmsunplugged.org/modules/training/): - choose (for example) `see` as your starting word - `see` (row) → `spot` (column); it's the only option, so write down `spot` as next word - `spot` → `run` (25%), `jump` (25%) or `,` (50%); roll dice to choose - let's say dice picks `run`; write it down - `run` → `.` (67%) or `,` (33%); roll dice to choose - let's say dice picks `.`; write it down - `.` → `see` (33%), `run` (33%) or `jump` (33%); roll dice to choose - let's say dice picks `see`; write it down - `see` → `spot`; it's the only option, so write down `spot`... and so on After the above steps, the generated text is _"see spot run. see spot"_ Using the cutouts spread from the example in [Training](https://www.llmsunplugged.org/modules/training/): - start with `see`---write it down - scan for cutouts with `see` as the previous word (look for boxes in `see`'s colour)---both have `spot` as the next word, so pick one and write down `spot` - scan for `spot` cutouts---4 matches (1 `run`, 1 `jump`, 2 `,`). Pick visually. Your eye is more likely to land on a comma because there are two of them, but for variety let's say `run`---write it down - scan for `run` cutouts---3 matches (2 `.`, 1 `,`). Two-thirds chance of `.`---let's say `.`---write it down - scan for `.` cutouts---3 matches (one each of `see`, `run`, `jump`). Let's say `see`---write it down - back to scanning for `see` cutouts---both are `spot`, so write down `spot`... and so on After the above steps, the generated text is _"see spot run. see spot"_ Notice how the randomness comes from your eye landing somewhere on the spread---you don't need dice. Previous words with more cutouts of the same next word are more likely to produce that word: both `see` cutouts have `spot` as the next word, so generation from `see` always produces `spot`. ## Optional extension: pre-grouped piles If you grouped the cutouts into piles during training (see the Training lesson's optional extension), generation becomes faster: step 2 is now "find the pile labelled with my current word" instead of scanning the whole table. The behaviour and the resulting output distribution are unchanged. ## Instructor notes ### Icebreaker question Before walking students through the algorithm, ask: - in as much detail as you can, explain what happens after typing something into the ChatGPT or Claude prompt box to produce the answer you get back This surfaces students' existing mental model of generation before they perform it by hand. ### Discussion questions - how does the starting word affect your generated text? - why does the text sometimes get stuck in loops? - if this is a _bigram_ (i.e. 2-gram) model, how would a unigram (1-gram) model work? - how could you make generation less repetitive? - does the generated text capture the style of your training text? - how does the starting word affect your generated text? - why might the text sometimes get stuck repeating the same pattern? - what happens when only one cutout matches your current word? - why do we leave the cutouts on the table after picking one? - does the generated text sound like the original training text? ### Troubleshooting - **"Every row only has one tally mark---there's nothing to roll for."** If the group didn't get very far in [Training](https://www.llmsunplugged.org/modules/training/) and no row has more than one tally mark, the generation algorithm won't be very interesting---there will only ever be one option for the next word and they'll be stuck on rails. In this case, either encourage them to go back and do a bit more training, or just have them add some extra tally marks to the grid wherever they like. This isn't as much like cheating as it might seem---it's really just an example of using [Synthetic Data](https://www.llmsunplugged.org/modules/synthetic-data/). - **"I landed on a word that doesn't have its own row."** This can happen if a word only ever appeared as the _last_ word in the training text---it has a column (other words lead to it) but no row (it never leads to anything). Just pick any other word that does have a row and continue from there. - **"We're stuck in a loop."** With small models it's common to bounce between two words that only point at each other (e.g. `,` → `spot` → `,` → `spot` → ...). Try picking a different starting word, or just choose any other valid next word to break out of the cycle. - **"Every previous word only has one matching cutout---there's nothing random about this."** If the spread is small and each previous word only matches a single cutout, generation will feel deterministic. Either go back and train on more text, or add a few extra cutouts (writing them out by hand is fine). This isn't really cheating---it's an example of [Synthetic Data](https://www.llmsunplugged.org/modules/synthetic-data/). - **"I picked a next word that doesn't appear as a previous word anywhere on the table."** This can happen if a word only ever appeared as the _last_ word in the training text---it shows up as a next word but never as a previous one. Just pick a different starting word that does appear on the spread and continue from there. - **"We keep going back and forth between the same two words."** With small spreads it's common to get stuck in a loop where two words keep pointing to each other. Try starting from a different word, or just pick any other matching cutout to break the cycle. ### Connection to current LLMs This generation process is identical to how current LLMs produce text: - **sequential generation**: both generate one word at a time - **probabilistic sampling**: both use weighted random selection (exactly like your dice or cutouts spread) - **probability distribution**: neural network outputs probabilities for all 50,000+ possible next tokens - **no planning**: neither looks ahead---just picks the next word - **variability**: same prompt can produce different outputs due to randomness The fact: sophisticated AI responses emerge from this simple process repeated thousands of times. Your paper model demonstrates that language generation is fundamentally about sampling from learned probability distributions. The randomness is why LLMs give different responses to the same prompt and why language models can be creative rather than repetitive. These physical sampling methods demonstrate the exact mathematical operation happening billions of times per second inside modern language models. Note: in AI/ML more broadly, this process of using a trained model to produce outputs is commonly called "inference"---you may encounter this term in other contexts. In these teaching resources we use "generation" specifically because it more clearly describes what language models do: they generate text. ### Comparison to dice method The cutouts spread and the dice method produce equivalent results: - dice rolls with weighted probabilities select from options based on counts - visual selection from the spread selects from options where counts are represented by multiple physical cutouts - the spread makes the probability tangible---if three of the cutouts with `the` as the previous word have `cat` as their next word and one has `dog`, you'll land on `cat` about 75% of the time, just like weighted dice would The cutouts method avoids the need to calculate percentages or understand dice mechanics, making it more accessible for younger learners. ## Interactive widget Step through the generation process at your own pace. Click on a row to select a starting word, then press Play or Step to watch the dice roll and text being generated. You can also edit the training text to create your own model. Step through the generation process at your own pace. Click on a cutout to select a starting word, then press Play or Step to watch matching cutouts being picked and text being generated. You can also edit the training text to create your own model. --- # In-context Memory > Add a short-term memory that nudges generation toward recently-used words, keeping text on topic---a hands-on model of attention and in-context learning. Give your model a short-term memory. By nudging generation toward words you've used recently, the text stays on topic---a tabletop version of how real models pay attention to their own context. ![](../../assets/images/hero-in-context-memory.avif) ## You will need - any model you can already generate from: your [bigram grid](https://www.llmsunplugged.org/modules/training/), a [cutouts spread](https://www.llmsunplugged.org/modules/generation/), or a [pre-trained booklet](https://www.llmsunplugged.org/modules/pretrained-generation/) - pen and paper for your generated text - dice (or a coin) as per [Generation](https://www.llmsunplugged.org/modules/generation/) This lesson adds a procedure on top of a model you already have---there's nothing new to print or build. ## Your goal Generate text twice from the same model---once plain, once with a short-term memory---and compare. The memory version should stay on topic for longer. Stretch goal: find the setting where the memory helps without making the text repetitive. ## Key idea A bigram only ever looks at the single word before. It has no idea what the text has been _about_---mention a dog, and two words later the model has already forgotten. Real language reuses what came before: once a story is about a dog, it keeps being about the dog. We can capture that with a **short-term memory**: a running list of the words you've written recently. When you pick the next word, you give a small boost to any candidate that's on that list. Recently-used words become a little more likely, so topics and characters persist. The model itself never changes---you're not retraining it. The extra context lives in the text you've already generated. That's exactly what makes this a model of in-context learning: the behaviour shifts based on the context in front of it, with no change to the underlying model. ## The one rule that matters: reweight, don't override There's a tempting shortcut: each turn, just grab a recent word from memory and write it down. **Don't.** That gets stuck on rails fast, for two reasons: - it ignores the current word, so it can drop in a word that doesn't follow at all---ungrammatical nonsense - every word you emit goes back _into_ memory, so emitting "dog" makes "dog" more likely next turn, which puts another "dog" in memory… and the text collapses into repeating a handful of words The fix is to keep the model in charge of _what's allowed_. The memory only ever adds a boost to words the model **already offers** as possible next words. It re-ranks the model's candidates; it never invents one. This "boost what's allowed" rule is how real cache/memory models work: they _blend_ a recency signal with the base model's distribution rather than replacing it. Because the base model still gates every choice, you only ever pick a real continuation, and its variety stops the memory from spiralling into a loop. ## Algorithm 1. **Start a memory list.** As you generate, keep the last ~8 words you've written (just underline them in your output, or jot them on a sticky note). 2. **Find the model's candidates** for the next word exactly as you normally would---the row in your grid, the matching cutouts, or the entry in your booklet. 3. **Boost the ones in memory.** Any candidate that also appears in your memory list gets a bonus (see "Applying it to your model" for how, per base). 4. **Pick** from the boosted candidates, **write the word down**, **add it to memory**, and drop the oldest word so the list stays short. 5. Repeat. ### Worked example Suppose you're generating and your current word is `the`. Your model offers: - `cat`: 3 - `dog`: 1 - `sun`: 1 A moment ago the text mentioned a dog, so `dog` is in your memory list. Give it a bonus of, say, +3: - `cat`: 3 - `dog`: 1 + 3 = 4 - `sun`: 1 Now roll on the new totals (1-3 → `cat`, 4-7 → `dog`, 8 → `sun`). `dog` has gone from unlikely to favourite---so the story is more likely to stay about the dog. Crucially, `cat` and `sun` are still possible: the memory tilted the odds, it didn't override them. ## Applying it to your model The boost is the same idea everywhere---it only differs in _how_ you apply it, because each base stores its probabilities differently. ### On a grid Add the bonus straight to the counts in the current word's row, then roll on the new totals (as in the worked example). The grid makes the reweighting visible. ### On a cutouts spread When you've gathered the cutouts that match your current word, check their next words against your memory list. For any match, grab one extra copy of that cutout (write a duplicate) before you pick. More copies means more likely---the spread does the reweighting for you, no arithmetic. ### On a pre-trained booklet The booklet's dice thresholds are pre-printed, so you can't re-weight them by hand. Use the blend form instead: 1. roll a small "memory die" first (e.g. a d10: 1-3 is a hit) 2. on a hit, scan the current entry's options---if one of them is in your memory list, pick it 3. on a miss, or if no option is in memory, roll the booklet exactly as normal This keeps the booklet frozen while still tilting toward recent words---and because you only ever pick from _this entry's_ options, you never leave what the model allows. The memory shines on a larger model like the booklet: a rich vocabulary gives it room to stay on topic without repeating. On a very small hand-built grid, be gentle with the bonus---boosting recent words can amplify the short loops small models already fall into (the `,→spot→,→spot` trap from [Generation](https://www.llmsunplugged.org/modules/generation/)). ## Instructor notes ### Discussion questions - with the memory on, does the text hold a topic or a character for longer? - what happens as you turn the bonus up? Where does "on topic" tip over into "stuck repeating"? - why does the memory only boost words the model already offers? What goes wrong if you let it pick _any_ recent word? - the model never changed---so where did the extra "knowledge" come from? - how is this different from the [trigram](https://www.llmsunplugged.org/modules/more-context/), which also uses more than one word? ### Connection to current LLMs This is a hands-on model of two of the most important things modern LLMs do. **Attention over the whole context.** A bigram looks back one word; the memory looks back over everything you've generated and lets it influence the next choice. That's the heart of the attention mechanism: when predicting the next word, the model reaches back across the whole context and weights what it finds. Your memory is a crude, fixed version (boost recent words); attention is learned and content-sensitive. **In-context learning.** Notice that the model never retrained---the behaviour changed purely because of what was already in the text. This is why you can give an LLM a few examples or a topic in your prompt and it picks up the pattern with no change to its weights. The "learning" happens in the context, not the model. **Repetition is a real failure mode.** The "stuck on rails" trap you avoided is not hypothetical: real models can loop too, which is why generation settings include repetition penalties---a deliberate _down_-weighting of recent words, the exact opposite tuning of the boost you just added. Topic-stickiness and repetition are two ends of the same dial. --- # Induction Heads > Add a rule that completes patterns from the text itself---find the last time the current word appeared and copy what followed it---the circuit behind in-context learning. Teach your model to finish a pattern it has only just seen. By looking back through the text for the last time the current word appeared and copying what came next, the model can complete sequences it never trained on---the same trick that lets a real LLM follow a pattern you put in its prompt. ![](../../assets/images/hero-induction-heads.avif) ## You will need - any model you can already generate from: your [bigram grid](https://www.llmsunplugged.org/modules/training/), a [cutouts spread](https://www.llmsunplugged.org/modules/generation/), or a [pre-trained booklet](https://www.llmsunplugged.org/modules/pretrained-generation/) - pen and paper for your generated text (you'll be reading back over it, so keep it tidy) - dice as per [Generation](https://www.llmsunplugged.org/modules/generation/) Like [In-context Memory](https://www.llmsunplugged.org/modules/in-context-memory/), this is a procedure laid over a model you already have. Nothing new to print. ## Your goal Make the model complete a made-up pattern that it could not possibly have learned during training---purely from a pattern you write into the text first. Stretch goal: match on the last _two_ words instead of one and see the completion get sharper. ## Key idea The [In-context Memory](https://www.llmsunplugged.org/modules/in-context-memory/) lesson boosted _recently used_ words. Induction is the sharper version: instead of "what have I seen recently?", it asks **"the last time I was at this exact word, what came next?"** So when the current word is `cat`, you scan back through what you've already written to the most recent earlier `cat`, read the word that followed it, and treat that as a strong suggestion for the next word. In effect you're building a bigram out of the text in front of you, on the fly---and using it to finish patterns the base model has never seen. ## Algorithm 1. Look at your **current word**. 2. **Scan back** up your written output to the most recent earlier time that same word appeared. 3. If you find one, the word that **followed** it is your _induction candidate_---a strong suggestion for what comes next. 4. **Combine with the base model:** strongly prefer the induction candidate, but keep some chance of consulting the model normally (roll a die: mostly copy, occasionally generate). If there's no earlier occurrence, there's no candidate---just generate from the base model as usual. 5. Write the word down and repeat. If you _always_ copy the induction candidate, the model just replays whatever pattern it's in---its own kind of being stuck on rails. Keeping a chance of falling back to the base model lets it break out and start new patterns. As with the memory lesson: blend, don't override. ## The pattern-completion demo This is where it earns its keep. Seed your output with a short made-up sequence, repeated, using words your model never saw together---then let induction take over. Write down: `moon` `five` `apple` `moon` `five` `apple` `moon` `five` Now generate the next word. Your current word is `five`: 1. scan back for the last `five`---it was followed by `apple` 2. copy `apple` You've completed the pattern---`moon five apple`---even though "moon five apple" appears nowhere in the training text and the base model has no idea about it. Run it again from `apple` and you'll get `moon`, then `five`, then `apple`… the model has picked up your invented rule from a single example, with no retraining at all. Turn induction off (generate from the base model alone) and the pattern evaporates---the model reverts to its trained habits and can't continue your sequence. That contrast _is_ the lesson. ## Applying it to your model The induction step is the same on every base, because it reads your _written output_, not the model: scan back, find the last occurrence of the current word, copy what followed. Only the fall-back differs: - **grid:** when there's no in-context match (or your die says "generate"), roll on the current word's row as usual - **cutouts:** fall back to picking from the matching cutouts in the spread - **booklet:** fall back to the booklet's lookup-and-roll Because the lookup happens on your pad, induction needs no special materials and works identically whichever base you started from. ## Instructor notes ### Discussion questions - the model completed a sequence it never trained on. Where was that "knowledge" stored? - why does the demo use made-up or random words rather than ordinary sentences? - what happens if you only ever copy, and never fall back to the base model? - how is induction different from the [recency memory](https://www.llmsunplugged.org/modules/in-context-memory/)? When would each one help? - (stretch) if you match on the last _two_ words instead of one, why is the completion more reliable? ### Connection to current LLMs Induction heads are a real, identified circuit inside transformers---and they turn out to be one of the main mechanisms behind in-context learning, the ability to pick up a pattern from the prompt without any change to the model's weights. - **the rule is the same**: a transformer's induction head finds an earlier place where the current token appeared and copies what came after it---exactly your scan-back-and-copy procedure - **it's how few-shot prompting works**: give an LLM a few "input → output" examples and it continues the pattern, because induction-style circuits match your current position against the examples above - **how it's measured**: researchers detect these circuits by feeding the model a random sequence repeated twice and checking that it predicts the second copy far better than the first---the machine version of your `moon five apple` demo Your version is exact-match and hard (the word matches or it doesn't); real induction heads match softer, richer patterns and blend smoothly with everything else the model knows. But the behaviour---_find where this happened before, do what came next_---is the same idea you can run by hand. --- # LoRA > Add a lightweight adaptation layer to retarget a trained model without retraining everything. Efficiently adapt a trained language model to a new domain or style without retraining the whole thing. ![](../../assets/images/hero-lora.avif) ## You will need - a completed bigram model from an earlier lesson (your base model) - pen or pencil, and a printed [grid template](https://pdf.llmsunplugged.org/worksheets/grid.pdf) (or any grid paper) - new domain- or style-specific text ## Your goal Create a lightweight adaptation layer that shifts your base model toward a new domain. Stretch goal: experiment with mixing ratios between base and LoRA layers. ## Key idea Low-Rank Adaptation (LoRA) stores only the _changes_ from the base model, so it can be much smaller. During generation you add LoRA counts to the base counts (optionally scaled) and sample as normal. ## Algorithm 1. Choose an existing bigram grid as your base model. 2. Train a LoRA grid: - Start with a new grid using the same columns as the base. - Run [Training](https://www.llmsunplugged.org/modules/training/) (grid method) on your new domain text, but only keep rows for words that appear in that text. 3. Apply the adaptation: - When sampling, add the LoRA counts to the base counts for the current word (if that row exists). - Optionally scale the LoRA counts up or down to control how strongly the adaptation influences the output. ## Example - Base model (general text) has a `saw` row with counts toward `they`, `the`, `a`, `red`. - LoRA trained on "I saw a red cat. I saw the red dog." adds only a `saw` row with extra counts toward `the`, `a`, `red`. - Combined sampling uses base + LoRA counts, making `red` more likely after `saw` while leaving other rows unchanged. ## Instructor notes ### Discussion questions - how much training data do you need for the LoRA layer compared to training from scratch? - what happens if you scale the LoRA values by 2 or 0.5 before adding them? - can you create multiple LoRA layers for different domains? - which words change most between base and adapted models? - when would you want a separate LoRA layer vs retraining the whole model? ### Connection to current LLMs Low-Rank Adaptation revolutionised how modern LLMs are customised: - **efficiency**: training a LoRA layer requires 100-1000x less computation than full fine-tuning - **modularity**: you can have one base model plus many LoRA layers for different tasks (medical, legal, creative writing) - **preservation**: the base model stays unchanged, so it retains its general capabilities - **combination**: multiple LoRA layers can be combined or switched on-the-fly - **distribution**: LoRA layers are small (megabytes vs gigabytes), making them easy to share The key insight: most model adaptation happens in a small subspace of all possible changes. Instead of adjusting billions of parameters, LoRA identifies and modifies only the dimensions that matter for the new domain. Your paper implementation makes this concrete: rather than recreating the entire grid, you only track the changes needed for the new text style. When you add the base and LoRA counts together, you're doing exactly what neural networks do when they apply LoRA layers during inference. This is why organisations can maintain one large foundation model and create thousands of specialised versions through lightweight LoRA layers. --- # More Context > Extend the bigram model to two words of context with a trigram, see why that gets expensive, then add cheap extra context with a skip grid. Extend the bigram model to use more than one word of context. First the trigram---two words, considered together---then a cheaper trick, the _skip grid_, that pulls in an earlier word without the trigram's cost. ![](../../assets/images/hero-more-context.avif) ## You will need - the same materials as [Training](https://www.llmsunplugged.org/modules/training/) - extra paper for a three-column table (trigram) and a second grid (skip grid) - pen, paper, and dice as per [Generation](https://www.llmsunplugged.org/modules/generation/) For each pair (or group) of students: - printed trigram token cutouts (each one shows two previous words as coloured boxes followed by a single next word, all colour-coded by word) - a clear table or flat surface to spread the cutouts out on - scissors The [Tools](https://www.llmsunplugged.org/tools/#cutouts) page has ready-to-print trigram token cutouts, or you can [generate your own](https://www.llmsunplugged.org/tools/#generate-your-own) from any text. Each PDF starts with a student-facing instructions page (anatomy of a cutout, worked example, tips), so you can hand the printed pack straight to a group. The CLI also supports a `--duplex` flag that prints the same cards on both faces, so students never have to flip a face-down card. ## Your goal Build a trigram language model, watch it run into a wall, then build a _skip grid_ that recovers some of the benefit for far less cost. Stretch goal: train on more data, or invent your own way of mixing in earlier context. ## Key idea A bigram only knows the word immediately before. The obvious fix is to look back further---and the obvious way to do that, the trigram, works but gets expensive fast. So this lesson has an arc: **more context helps (trigram) → but the full version blows up → so here's a cheaper way to get some of it (skip grid)**. That last move---pulling in earlier context without paying the full cost---is the same problem modern models solve with attention. ## Part 1: the trigram Instead of asking "what follows this word?", we ask "what follows these _two_ words?". The two previous words are considered _together_, as a pair. ### Training 1. Draw a four-column table: `word1 | word2 | word3 | count`. 2. Slide a window over your text, collecting every overlapping triple of words. 3. For each triple, increment its count (or add a new row starting at 1). After the full text (`see` `spot` `run` `.` `see` `spot` `jump` `.`) the model is: | word 1 | word 2 | word 3 | count | | ------ | ------ | ------ | ----- | | `see` | `spot` | `run` | 1 | | `spot` | `run` | `.` | 1 | | `run` | `.` | `see` | 1 | | `.` | `see` | `spot` | 1 | | `see` | `spot` | `jump` | 1 | | `spot` | `jump` | `.` | 1 | The order of the rows doesn't matter, so you can group them by _word 1_ if that helps. 1. **Cut out the trigram tokens** from your printed sheets - each cutout shows two previous words as coloured boxes, followed by the next word; every word has its own colour, so the boxed and free-standing forms of the same word match 2. **Spread the cutouts out** on a table, face up, no overlap if you can manage it---that's your trained trigram model Original text: _"See Spot run. See Spot jump."_ contains these (two previous words → next word) triples: - `see spot → run` - `spot run → .` - `run . → see` - `. see → spot` - `see spot → jump` - `spot jump → .` Each triple becomes one cutout on your table: Notice that `see spot` shows up twice, once with `run` and once with `jump`. Compared to the bigram spread (which would just have two `see→spot` cutouts), the trigram spread captures more specific patterns about which word follows which _pair_ of words. ### Generation 1. Pick any row and write down `word1` and `word2` as your starting words. 2. Find all rows where `word1` and `word2` match your current context; note their counts. 3. Roll weighted by those counts to pick a row; take its `word3` as the next word. 4. Shift the window by one word (new context is old `word2` + chosen `word3`) and repeat from step 2. 1. **Pick two starting words** that appear together as previous words on at least one cutout, and write both down 2. **Find candidates**---scan for cutouts whose two previous-word boxes match your last two words (match the rightmost box to your most recent word, then check the box to its left). Verify the words, not just the colours 3. **Pick one cutout** visually, **write down its next word**, and **put the cutout back** 4. Your last two words are now the previous-rightmost word plus the word you just wrote---go back to step 2 ## The catch: the spread explodes (and the model just parrots) Try generating from the example above and watch what happens. From `see spot` you can branch to `run` or `jump`---but after that, every two-word context has exactly _one_ matching row. `spot run` only ever leads to `.`; `run .` only ever leads to `see`. So the model has no real choice to make: it replays the training text almost verbatim. That isn't a bug in the example---it's what trigrams do at this scale. Each extra word of context multiplies the number of possible contexts, so with a small amount of text almost every two-word context is seen exactly once. The model becomes a tape player with the occasional fork. - a bigram of this text needs a row per _word_ (a handful) - the trigram needs a row per _word pair_---many more, and most with a count of just 1 - the bigram spread has one pile per _previous word_ (a handful) - the trigram spread has one pile per _pair_ of previous words---many more, and most piles holding a single cutout This is the central trade-off of n-grams: **more context sharpens predictions, but you need exponentially more data to fill in all those contexts.** Push to four or five words and you'd need a library to see each context even once. So rather than keep extending the window, we look for a cheaper way to bring in earlier words. ## Part 2: a cheaper way---the skip grid Here's the trick. The trigram is expensive because it tracks the two previous words _jointly_---one table indexed by the whole pair. What if we tracked them _separately_ and added the evidence together? You keep two bigram-sized grids: - the **previous-word grid**: your ordinary bigram (the word one back → the next word) - the **skip grid**: the same shape, but for the word _two_ back (the word two back → the next word) Two single-word grids cost far less than one word-pair table: each has a row per _word_, not per _pair_. That's the whole point---you reach back two words without the combinatorial blow-up. A trigram table can have up to (vocabulary size)² rows---one per possible word pair. The two skip-grid tables have at most (vocabulary size) rows _each_. You trade the ability to track exact pairs for two cheap tables you can actually fill in. ### Training the skip grid For every triple `word1 word2 word3` in your text: 1. tally `word2 → word3` in the **previous-word grid** (this is just your normal bigram) 2. tally `word1 → word3` in the **skip grid** That's it---two tally marks per triple, each in a plain two-word grid. #### Example Text: `the cat sat . the dog ran .` The **previous-word grid** (word one back → next) gets the usual bigram counts: `the→cat`, `cat→sat`, `the→dog`, `dog→ran`, and so on. The **skip grid** (word two back → next) records what tends to appear two words after each word: | two back | next | count | | -------- | ----- | ----- | | `the` | `sat` | 1 | | `the` | `ran` | 1 | | `cat` | `.` | 1 | | `dog` | `.` | 1 | Notice the skip grid has learnt that `the` is often followed---two words later---by a verb (`sat` or `ran`), regardless of which animal came in between. On the table, the skip idea is most natural to _read_ in the grid method (toggle to it above), but here's how it maps to cutouts if you want to try it: - keep your ordinary bigram spread (previous word → next word) - lay out a second spread keyed on the word _two_ back → next word (you'll need to write these out by hand, or generate them---the standard packs only print the previous-word spread) Two spreads, each the size of an ordinary bigram spread, rather than one much larger trigram spread. ### Generating with the skip grid To pick the word after a two-word context `word1 word2`: 1. read `word2`'s row in the **previous-word grid** 2. read `word1`'s row in the **skip grid** 3. **add the two rows together**, cell by cell, to get combined counts 4. roll weighted by the combined counts, write the word down, shift the window, and repeat #### Example Continuing the text above, suppose your context is `the cat` and you want the next word. - previous-word grid, `cat`'s row: `sat` 1 - skip grid, `the`'s row: `sat` 1, `ran` 1 - combined: `sat` 2, `ran` 1 Roll on those four (1-2 → `sat`, 3 → `ran`). The plain bigram would have forced `sat` every time; the skip grid lets `the cat` sometimes go to `ran`---a verb that followed `the …` elsewhere in the text. The model has generalised beyond the exact pairs it saw, and it stays genuinely random instead of parroting. To pick the word after a two-word context `word1 word2`: 1. gather the cutouts whose previous word matches `word2` (from the bigram spread) 2. gather the cutouts whose two-back word matches `word1` (from the skip spread) 3. pool them into one heap and pick visually Because you're picking from the combined heap, words with more cutouts across the two spreads are more likely---the spread is doing the addition for you, just as it did the weighting in [Generation](https://www.llmsunplugged.org/modules/generation/). ## What the skip grid can't do The skip grid is cheaper than the trigram, but it's also weaker, and the difference is worth naming. It treats the two earlier positions as if they contribute _independently_: it adds "what follows `cat`" to "what tends to come two words after `the`". It can never capture the cases where it's the _pair_ that matters---where `new york` predicts something that neither `new` alone nor `york` alone would. That gap is exactly the problem modern models solve with the attention mechanism. The skip grid mixes in earlier context with _fixed_ weights (always the word two back, always added in the same way). Attention _learns_ which earlier words matter for each prediction, and how much---so it can decide, on the fly, when the combination matters and when it doesn't. ## Instructor notes ### Discussion questions - how does the trigram output compare to the basic (bigram) model output? - why does the trigram spread/table tend to have so many single-count entries? - what's the trade-off between context length and data requirements? - the skip grid lets `the cat` sometimes continue like `the dog` did. When is that helpful? When might it produce nonsense? - can you think of a two-word phrase where the _pair_ matters more than either word on its own? (this is what the skip grid misses) ### Connection to current LLMs This lesson bridges simple word-pair models and modern transformers along two threads. The trigram shows the **context-length trade-off**: longer context sharpens predictions, but the number of possible contexts---and the data you need to cover them---grows exponentially. Current models use context windows of hundreds of thousands of tokens, which is only possible because they don't store an explicit count for every possible context the way an n-gram table does. The skip grid shows the first step _beyond_ counting exact contexts: mixing in earlier positions with fixed weights. Real models generalise this into attention---instead of "always add the word two back", the model _learns_ which previous words to pull in for each prediction. Your hand-built skip grid is fixed and additive; attention is learned, weighted, and dynamic. Both share the core insight: you don't have to see the _exact_ context before to make a good guess. --- # Pre-trained Model Generation > Use a provided pre-trained booklet to generate text without training your own model. Use a (slightly larger) pre-trained model booklet to generate new text through weighted random sampling. ![](../../assets/images/hero-pretrained-generation.avif) ## You will need - a pre-trained model booklet - a d10 for weighted sampling - pen and paper for your generated text The [Tools](https://www.llmsunplugged.org/tools/#booklets-for-dice-generation) page has ready-to-print booklets for several texts, or you can [generate your own](https://www.llmsunplugged.org/tools/#generate-your-own) from any text. ## Your goal Generate text from a pre-trained language model without training it yourself. Stretch goal: try to guess the training text before checking the booklet title. ## Key idea Pre-trained models capture patterns from larger datasets. You can use them just like your hand-built bigram model: look up the current word, roll dice, choose the next word, and repeat. ## Algorithm (quick recap) 1. Choose a starting word---any bold word in the booklet---and write it down. 2. Look up that word's entry to see possible next words and their thresholds. 3. Roll your d10(s): - If there's an indicator (e.g., a small box with `2`), roll that many d10s and treat the digits as one number. - Otherwise, roll one d10. 4. Scan down the options; the first threshold greater than or equal to your roll gives the next word. Write it down. 5. Repeat from step 2 using the new word until you reach a natural stopping point or your desired length. ## Example Before you try generating text yourself with a booklet, work through these examples to see the algorithm in action. - **Single d10:** Current word `cat` with options `4|sat`, `7|ran`, `10|slept`. Roll once; a 6 lands you on `ran`. - **Multiple d10s:** Current word `the` with a `2` indicator and options `33|cat`, `66|dog`, `99|end`. Roll twice; a 5 and 8 combine to 58, so you choose `dog`. ## Instructor notes ### Discussion questions - can you guess what text the model was trained on from the generated output? - how does using a pre-trained model differ from training your own? - what vocabulary size does the booklet model have compared to your hand-built model? - why might some word combinations feel more natural than others? - without looking at the title: can you identify the training text's genre or style? ### Troubleshooting - **"Which die is the tens digit?"** When rolling multiple d10s (i.e. in the "multiple diamond" case), it doesn't really matter which die you read first---as long as you decide before you roll and stay consistent. One easy convention: use different-coloured dice and always read them in the same order (e.g. red first, then blue). But really, don't stress too much about it. The activity will still work fine if you mix them up. ### Connection to current LLMs This lesson demonstrates the foundation of how people interact with modern AI: - **pre-training**: companies train massive models on huge text corpora (like your booklet model, but with trillions of words) - **LLM-as-a-service**: users generate text without seeing or modifying the underlying model (just like using the booklet) - **model distribution**: the booklet format shows how models can be packaged and shared---current LLMs are distributed as parameter files - **deterministic generation**: given the same starting word and dice rolls, you get the same output (though randomness creates variety between runs) The key insight: training and text generation are separate processes. Most AI users never train models---they use pre-trained ones through APIs or interfaces. Your hand-built model from [Training](https://www.llmsunplugged.org/modules/training/) gives you insight into what's inside the booklet, but you don't need that knowledge to generate text. This separation is why companies like OpenAI can provide AI services: they do the expensive training once, then millions of users perform text generation. The booklet captures thousands of training examples in a portable format, just as neural networks compress training data into billions of parameters. ## Interactive widget Step through the booklet lookup process at your own pace. The model is displayed in the same format as the printed booklets: each entry shows a bold previous word, diamond symbols indicating how many d10s to roll, and the possible next words with their thresholds. --- # RLHF > Use human preferences to adjust your model's weights, making it generate text people prefer. Adjust your language model based on human preferences, reinforcing outputs people like and discouraging ones they don't. ![](../../assets/images/hero-rlhf.avif) ## You will need - a completed model from an earlier lesson - pen, paper, and dice as per [Generation](https://www.llmsunplugged.org/modules/generation/) (grid method) - a group of people to provide preferences (the "humans" in RLHF) ## Your goal Generate multiple candidate outputs, collect human preferences, and update your model's counts accordingly. Stretch goal: run multiple rounds of feedback and observe how the model changes. ## Key idea Reinforcement Learning from Human Feedback (RLHF) adjusts model probabilities based on what people prefer. Instead of training on more text, you train on human judgements about which outputs are better. ## Algorithm ### Phase 1: generate candidates 1. Choose a starting word. 2. Generate 2--3 different completions (5--10 words each) by running generation multiple times from the same starting point. 3. Write each candidate on a separate piece of paper. ### Phase 2: collect preferences 1. Show all candidates to your human judges (the class, a small group, or individuals). 2. Have them vote on which completion they prefer. 3. Record the ranking: best, middle, worst. ### Phase 3: update the model For each word transition in the **preferred** output: - add +1 to that cell in your grid For each word transition in the **rejected** output: - subtract 1 from that cell (minimum 0) Middle-ranked outputs: no change (or +0.5/−0.5 if you want finer adjustments). ### Phase 4: generate again Use the updated model to generate new text. The adjustments should make preferred patterns more likely. ## Example **Starting word:** "the" **Candidate A:** "the cat sat on the mat." **Candidate B:** "the dog ran to the park." **Candidate C:** "the the the the the the." **Human preference:** B > A > C **Updates:** - B's transitions get +1 each: (the→dog), (dog→ran), (ran→to), (to→the), (the→park), (park→.) - C's transitions get −1 each: (the→the) loses 5 counts - A stays unchanged (middle rank) After updates, "the→dog" and "the→park" become more likely, while "the→the" becomes much less likely. ## Running multiple rounds For deeper learning, repeat the process: 1. Generate new candidates from the updated model 2. Collect fresh preferences 3. Update again 4. Observe how the model's behaviour shifts After several rounds, the model should consistently produce outputs more aligned with human preferences. ## Instructor notes ### Discussion questions - what makes one output "better" than another? can people agree? - what happens if different people prefer different things? - how many rounds of feedback does it take to noticeably change the model? - could you "break" the model with bad feedback? - what biases might creep in through human preferences? - is the model learning to be "good" or learning to match what judges prefer? ### Classroom variations **Simple version:** just pick best vs worst (ignore middle). Easier to run, same core concept. **Split judges:** divide the class into groups with different preferences (e.g., "team poetry" vs "team clarity"). Train separate models and compare results. **Blind feedback:** judges don't know which outputs came from which version of the model. Reduces bias toward "improvement." **Adversarial feedback:** one judge deliberately gives bad feedback. How robust is the process? ### Connection to current LLMs RLHF is how modern AI assistants learn to be helpful, harmless, and honest: - **Claude, ChatGPT, and others**: all use RLHF to align model outputs with human values - **the process**: human raters compare model outputs and rank them, exactly like your classroom judges - **reward models**: at scale, a separate AI learns to predict human preferences, then guides the main model - **safety**: RLHF teaches models to refuse harmful requests by having humans prefer refusals over compliance - **instruction following**: models learn to actually answer questions (rather than just predict text) through RLHF The key insight: RLHF shifts what "good" means from "matches training data" to "matches human preferences." Your grid updates demonstrate this directly---you're changing probabilities not based on what appeared in text, but based on what people preferred. This is why RLHF-trained models can be more helpful than models trained only on internet text: they've learned to optimise for human approval, not just pattern matching. The limitation is also visible: RLHF captures the preferences of whoever provides feedback. Different judges produce different models. This is why AI companies carefully select and train their human raters---the model will learn whatever biases and preferences those humans have. --- # Sampling > Same model, different output---experiment with temperature and truncation strategies to shape how your model picks the next word. When generating text, your model offers several options for the next word. Sampling strategies decide which one to pick---and the strategy you choose can change the character of the output dramatically, without changing the underlying model at all. The same grid or cutouts spread can produce flat prose, structured poetry, or pure nonsense, depending entirely on how you sample. ![](../../assets/images/hero-sampling.avif) ## You will need - a completed model from an earlier lesson - pen, paper, and dice as per [Generation](https://www.llmsunplugged.org/modules/generation/) (grid method) ## Your goal Generate text using at least two temperatures and at least two truncation strategies. Stretch goal: design and test your own truncation rule. ## Key idea Sampling choices---temperature and truncation---can make the same model sound cautious, wild, repetitive, or inventive. Tweaking the sampler changes the output without retraining anything. ## Temperature control Temperature is a number that smooths the distribution. Higher temperatures flatten differences between options, making surprising words more likely. - Algorithm: when sampling the next word, divide all counts by the temperature (round down, minimum 1) before rolling dice. - Example with counts `spot` (4), `run` (2), `jump` (1), `.` (1) - Temp 1 → use counts as-is (`spot ` twice as likely as `run`; four times `jump` or `.`). - Temp 2 → counts become 2, 1, 1, 1 (`spot` still highest, but less dominant). - Temp 4 → counts become 1, 1, 1, 1 (all options equal). ## Truncation strategies Truncation narrows which next-word options are allowed. Mix and match with temperature. When using a [pre-trained booklet](https://www.llmsunplugged.org/modules/pretrained-generation/), the next-word candidates are already sorted from most likely to least likely. This makes several strategies easier: greedy = pick the first option, non-sequitur = pick the last option, and top-k = only roll among the first k options.
### Greedy Pick the highest count; if tied, roll among the top options.
### Haiku Track syllables per line (5-7-5). Roll as normal; if the word would overflow the line's syllable limit, re-roll.
### Non-sequitur Pick the lowest non-zero count; if tied, roll among the least likely options.
### No-repeat Track words used in the current sentence. If you roll a repeat, reroll; if nothing valid remains, insert `.` and continue.
### Alliteration Prefer options that start with the same letter/sound as the previous word; otherwise sample normally.
### Top-k Choose a number k (e.g. 2 or 3). Keep only the k options with the highest counts; if tied for the last spot, include all ties. Roll among those only.
### Alphabet chain The next word must start with the last letter of the previous word. If no option qualifies, sample normally.
### Short/long Pick a length threshold (e.g. 4 letters). Only allow words at or below that length (short mode) or above it (long mode). If nothing qualifies, re-roll.
## Instructor notes ### Discussion questions - which strategy produces the most "human-like" text? - when would you want predictable vs surprising output? - how do constraints (haiku, no-repeat) spark creativity? - can you invent your own sampling strategy? ### Troubleshooting - **"I divided all the counts by the temperature and now everything is 1."** This is correct---it's not a mistake. High temperature flattens the distribution so that all options become equally likely. That's the whole point: higher temperature means more randomness. ### Connection to current LLMs Current LLMs use these same mechanisms, though the specific strategies differ. - **Temperature control:** the temperature parameter divides probabilities just like you divide tallies; higher temperature means more random output. The lesson uses manual temperature adjustment, while LLMs do this computationally before every token. - **Truncation techniques in modern LLMs:** top-k sampling (only consider k most likely tokens), top-p/nucleus sampling (consider tokens until cumulative probability reaches p), repetition penalties, frequency penalties, and presence penalties all prune options before sampling. - **Truncation techniques in this lesson:** greedy, haiku, non-sequitur, no-repeat, alliteration, top-k, alphabet chain, and short/long are designed for dice-based sampling but embody the same idea---changing which tokens are eligible before you roll. Top-k directly mirrors the top-k parameter in LLM APIs. Your paper model demonstrates that "creativity" in AI comes from two controls: adjusting temperature (probability distribution shape) and applying truncation strategies (which tokens to exclude). The same trained model can produce scholarly essays (low temperature, strict truncation) or wild poetry (high temperature, constraint-based truncation) just by changing these parameters. The key insight: generation control is as important as training data. Creative output comes not from the model itself, but from how you control temperature and which tokens you truncate from consideration. --- # Sycophancy > Skew your model toward over-agreeable, flattering responses by piling in sycophantic training data. Demonstrate how adding repetitive sycophantic phrases to your training data steers the model toward over-agreeable, flattering output---no RLHF required. ![](../../assets/images/hero-sycophancy.avif) ## You will need - your completed grid model from [Training](https://www.llmsunplugged.org/modules/training/) - a d10 (or similar), plus pen and paper, as per [Generation](https://www.llmsunplugged.org/modules/generation/) - the sycophancy phrases listed below, to tally into your grid - a trained bigram cutouts spread from [Training](https://www.llmsunplugged.org/modules/training/) - additional cutouts encoding the sycophancy phrases listed below - pen and paper for jotting down the generated text The CLI can generate a printable sheet of sycophancy cutouts from `data/sycophancy.txt`---run `llms_unplugged cutouts -i data/sycophancy.txt -n 2` and add the resulting PDF to your printing batch. ## Your goal Tally the sycophancy phrases into your existing grid, regenerate text from the same starting word as before, and observe how the output drifts toward agreement and flattery. Add sycophancy cutouts to your existing spread, regenerate text from the same starting word as before, and observe how the output drifts toward agreement and flattery. ## Key idea Sycophancy in real LLMs comes from two main sources: RLHF reward hacking (human raters tend to prefer agreeable answers) and biased training data (the internet is full of flattery). This activity demonstrates the second source directly: when you tip the training data toward sycophantic phrases, the model's generated text starts mirroring them. ## The sycophancy phrases These are the phrases you'll fold into your model. Each is shown as the sequence of tokens the model sees---lowercased, with punctuation and contracted endings (`'re`, `'s`) treated as their own tokens, exactly as in [Training](https://www.llmsunplugged.org/modules/training/): - `you 're absolutely right .` - `that 's a great insight .` - `what a thoughtful question .` - `i completely agree .` - `you make an excellent point .` Repeat each phrase several times so its word pairs build up strong counts---the heavier the weighting, the more often generation lands on them. Tallied into a grid, the first phrase fills one cell per consecutive (row → column) pair: As a spread, the first phrase is one cutout per consecutive (previous → next) pair: ## Algorithm 1. **Train a baseline model** as per [Training](https://www.llmsunplugged.org/modules/training/)---fill in your grid. 2. **Generate a baseline sentence** as per [Generation](https://www.llmsunplugged.org/modules/generation/)---write it down. This is your "before". 3. **Add the sycophancy phrases** to your grid. Take each phrase from the list above and tally its word pairs into your existing grid, following the standard [Training](https://www.llmsunplugged.org/modules/training/) procedure---add a new row and column for any word you haven't seen yet. Repeat each phrase several times. 4. **Generate again** from the same starting word. 5. **Compare**: how often does the new output land on sycophantic phrases? Does it sound like a different "voice"? 1. **Train a baseline model** as per [Training](https://www.llmsunplugged.org/modules/training/)---spread the cutouts on the table. 2. **Generate a baseline sentence** as per [Generation](https://www.llmsunplugged.org/modules/generation/)---write it down. This is your "before". 3. **Add sycophancy cutouts** to the spread. The pre-made cutouts encode the phrases from the list above---patterns like `you → 're`, `'re → absolutely`, `absolutely → right`, `right → .`, plus the "great insight", "thoughtful question", and "completely agree" variants. 4. **Generate again** from the same starting word. 5. **Compare**: how often does the new output land on sycophantic phrases? Does it sound like a different "voice"? ## Example Baseline model trained on _"I am Sam. Sam I am."_ generates something like: > _"i am sam . sam i am ."_ After folding in the sycophancy phrases, the same starting word might generate: > _"i am absolutely right . that 's a great insight ."_ The model didn't change its mechanism---it just contains more paths (extra cutouts, or heavier grid tallies) that route toward sycophantic tokens. ## Instructor notes ### Designing your own sycophancy phrases The phrases above integrate cleanly because their previous words---`i`, `that`, `you`, and `.`---are high-frequency tokens already present in most models, so the new material hooks into the existing vocabulary during generation. If you write your own, follow the same recipe: start each phrase with a common word, end it with `.`, and repeat it several times so the new transitions carry strong weight. ### Discussion questions - did the output _always_ become sycophantic, or only sometimes? - what would you have to add to the training data to get the _opposite_ effect (a contrarian model)? - in real LLMs, why is sycophancy specifically a hard problem to detect from the outside? - if you only saw the model's output (not its training data or weights), how would you tell sycophancy from genuine helpfulness? - is sycophancy _always_ a bug? when might agreeable behaviour be desirable? ### Connection to current LLMs Real LLMs become sycophantic through two mechanisms, both visible in this activity: - **RLHF reward hacking**: human raters often prefer agreeable, flattering answers, so the model learns to over-produce them. Sycophancy research from Anthropic and others has shown this pattern across multiple frontier models. - **Pre-training data biases**: a lot of internet text contains sycophantic patterns---customer-service replies, social-media validation, and so on---which the model picks up during pre-training before any RLHF. Your activity simulates the second mechanism. The first is harder to demo without running [RLHF](https://www.llmsunplugged.org/modules/rlhf/) on top. The deeper point: a model's "personality" is a property of its training data and tuning, not an intrinsic feature of language modelling. Change the data, change the personality. --- # Synthetic Data > Generate synthetic text with your model, retrain on it, and see how patterns drift or collapse. Use your language model to generate new training data, then train a new model on that synthetic data to watch patterns change. ![](../../assets/images/hero-synthetic-data.avif) ## You will need - a completed model from an earlier lesson - pen, paper, and dice for generation - a printed [grid template](https://pdf.llmsunplugged.org/worksheets/grid.pdf) (or grid paper) for a new model ## Your goal Generate synthetic text with your model, train a "generation 2" model on it, and compare both models. Stretch goal: try a generation 3 model---or go full "Joker mode." ## Key idea Models trained on synthetic data can drift or collapse, losing variety from the original corpus. Watching this happen illustrates why real data matters. ## Algorithm 1. **Generate synthetic text:** use your existing model to create 50–100+ words (as in [Generation](https://www.llmsunplugged.org/modules/generation/)). This is your synthetic corpus. 2. **Train generation 2:** build a new model using the [Training](https://www.llmsunplugged.org/modules/training/) algorithm with the synthetic corpus. 3. **Compare models:** - note words that disappear or appear - compare shared cell counts - generate from both models and contrast the outputs ## Example - Original text: "See Spot run. See Spot jump." - Synthetic output: "See run. Run spot. Spot run run." - same vocabulary but different patterns (more `run run`, no `spot jump`) - Generation 2 trained on the synthetic text amplifies those changes: `run run` becomes common, `spot jump` vanishes, and odd new patterns can appear. ## Joker mode Skip generating text and instead create a completely random grid: - invent any words you like for rows and columns - add tally marks anywhere, in any amounts - generate text from this random grid - train a generation 2 model on that output Compare to the original to see how quickly randomness compounds. ## Instructor notes ### Discussion questions - what patterns from the original survived to generation 2? - what new patterns emerged that weren't in the original? - how does vocabulary shrink or change across generations? - can you identify when loops or repetitions started? - what would happen if you continued to generation 3, 4, 5? - (for joker mode) can a completely random model produce anything coherent? why or why not? - (for joker mode) does randomness compound across generations, or does some structure emerge? ### Connection to current LLMs Model collapse from synthetic data is a major concern in modern AI: - **training data contamination**: as LLMs generate more web content, future models risk training on AI-generated text rather than human text - **mode collapse**: models trained on synthetic data lose diversity and converge toward common patterns (like your `run run` example) - **error amplification**: small errors in generation 1 become large errors in generation 2 - **recursive training**: some research deliberately uses synthetic data to improve models, but this requires careful curation - **data provenance**: companies now track whether training data is human-written or AI-generated The key insight: models trained on their own outputs (or outputs from similar models) degrade over generations. Your hand-built demonstration shows why: each generation is a lossy sample from probability distributions. Rare patterns get lost, common patterns get amplified, and statistical noise becomes signal. This is exactly what researchers observe when training neural networks on synthetic data---vocabularies shrink, creativity decreases, and outputs become more repetitive and stereotyped. Your generation 2 model demonstrates that "training data quality" isn't just about correctness---it's about maintaining the diversity and richness of patterns that make language interesting. This hands-on experience shows why AI companies are concerned about the increasing volume of AI-generated text on the internet: if future models train on today's AI outputs, we risk a cascade of model collapse. --- # Training > Build a bigram language model that tracks which words follow which other words in text. Build a bigram language model that tracks which words follow which other words in text. ![](../../assets/images/hero-grid-training.avif) ![](../../assets/images/hero-cutouts-training.avif) ## You will need - some text (e.g. a few pages from a kids book, but it can be anything) - pen or pencil - a printed [grid template](https://pdf.llmsunplugged.org/worksheets/grid.pdf) (or any grid paper) For each pair (or group) of students: - printed token cutouts (use the CLI to generate these from your text) - a clear table or flat surface to spread the cutouts out on - scissors The [Tools](https://www.llmsunplugged.org/tools/#cutouts) page has ready-to-print token cutouts for several texts, or you can [generate your own](https://www.llmsunplugged.org/tools/#generate-your-own) from any text. Each PDF starts with a student-facing instructions page (anatomy of a cutout, worked example, tips), so you can hand the printed pack straight to a group. The CLI also supports a `--duplex` flag that prints the same cards on both faces, so students never have to flip a face-down card. ## Your goal Produce a grid that captures the patterns in your input text data. This grid is your bigram language model. Stretch goal: keep training your model on more input text. Spread your printed token cutouts out on a table. Each cutout shows a next word together with its previous word (the word that came before it). The whole spread of cutouts _is_ your language model---every (previous, next) pair from your training text is sitting somewhere on the table. ## Key idea Language models learn by counting patterns in text. Training means building a model (filling out the grid) to track which words follow other words. The CLI has already done the bigram counting for you. Each cutout shows a next word together with the word it follows in the training text. The trick: if `spot` follows `see` 40% of the time in the training text, then 40% of the cutouts with `see` as the previous word will have `spot` as the next word. Whichever matching cutout your eye lands on, you've sampled in proportion to the original distribution---no dice, no probability tables, the spread is doing the maths. ## Algorithm 1. **Preprocess your text** - convert everything to lowercase - treat words and single punctuation marks (`.` `,` `!` `?` `;` `:`) as separate "words"; ignore paired punctuation like quotes and brackets, and ignore whitespace 2. **Set up your grid** - take the first word from your text - write it in both the first row header and first column header of your grid 3. **Fill in the grid** one word pair at a time - find the row for the first word (in your training text) and the column for the second word - add a tally mark in that cell (if the word isn't in the grid yet, add a new row and column for it) - shift along by one word (so the second word becomes your "first" word) and repeat until you've gone through the entire text 1. **Cut out the tokens** from your printed sheets - each cutout shows a next word preceded by its previous word; every word has its own colour, and previous words appear inside a matching coloured box 2. **Spread the cutouts out** on a table - face up, no overlap if you can manage it - that's it---the spread is your trained model Optional extension: see "Group into piles" below. ## Example Before you try training a model yourself, work through this example to see the algorithm in action. Original text: _"See Spot run. See Spot jump. Run, Spot, run. Jump, Spot, jump."_ Preprocessed text: `see` `spot` `run` `.` `see` `spot` `jump` `.` `run` `,` `spot` `,` `run` `.` `jump` `,` `spot` `,` `jump` `.` After the first two words (`see` `spot`) the model looks like: After the full text the model looks like: For the text `see spot run . see spot jump . run , spot , run . jump , spot , jump .`: After cutting and spreading, the table contains every adjacent (previous → next) pair from the text: - `see→spot` × 2 - `spot→run` × 1, `spot→jump` × 1, `spot→,` × 2 - `run→.` × 2, `run→,` × 1 - `.→see` × 1, `.→run` × 1, `.→jump` × 1 - `,→spot` × 2, `,→run` × 1, `,→jump` × 1 - `jump→.` × 2, `jump→,` × 1 Each entry is a physical cutout on your table. Notice that `spot→,` shows up twice---there are two cutouts on the table with `spot` as the previous word and `,` as the next word. That repetition is what makes generation weighted. ## Optional extension: group into piles Once your students have got the hang of the loose-on-table flow, you can introduce grouping as an optimisation: 1. Sort the cutouts into piles, one pile per unique previous word 2. Label each pile with that word Now generation is faster---instead of scanning the whole table, you go straight to the pile whose label matches your current word. This is the same trick a computer uses when it stores a language model in a hash table. The model's information content is identical; you've just rearranged it for faster lookup. ## Instructor notes ### Icebreaker questions If this is the group's first hands-on activity, these prompts surface what students already think about language models. Depending on your learning context, they work as either "call out your answer" or "discuss with your neighbour and share-back" questions. - why is a language model called a "language model"? What does it mean to "model language"? - what's the best/clearest explanation you've ever heard about how Large Language Models (e.g. ChatGPT, Claude) actually work? What's the _weirdest_ explanation you've ever heard? - when was the first language model ever created? How similar/different was it to modern LLMs? - _activity_: get everyone to stand up, then have them sit down if they've never used ChatGPT, Claude, or a similar LLM. Then ask if they've used it in the last month/week/day/hour/5mins. At the end, everyone should be sitting down. Don't spend too long here---the fun really starts when students get into the activity itself. ### Discussion questions - what can you tell about the input text by looking at the filled-out bigram model grid? - how does including punctuation as "words" help with sentence structure? - are there any other ways you could have written down this exact same model? - how could you use this model to generate _new_ text in the style of your input/training data? - what can you tell about the input text by looking at which (previous, next) pairs show up most often in the spread? - why does `see→spot` appear twice while `run→,` appears only once? - how does including punctuation as separate tokens help capture sentence structure? - what would happen if you trained on more text---how would the spread change? - how could you use these cutouts to generate _new_ text in the style of your training data? ### Troubleshooting - **"Do I add a new row/column for every word?"** No---each new word only gets a new row and column the first time you see it. After that, just find the existing row and column and add a tally mark. - **"Some cutouts are duplicates---is that a mistake?"** No---repeated cutouts are exactly the point. If `see→spot` appears twice in the training text, you should see two `see→spot` cutouts on the table. The repetition is what makes common pairs easier to spot during generation. ### Connection to current LLMs This counting process is exactly what happens during the "training" phase of language models: - **training data**: your paragraph vs trillions of words from the internet - **learning/training process**: hand counting vs automated counting by computers - **storage**: your paper model vs billions of parameters in memory The key insight: "training" a language model means counting patterns in text. Your hand-built model contains the same type of information that current LLMs store---at a vastly smaller scale. ### Comparison to grid method The cutouts spread and the grid method produce equivalent models: - a tally mark in row X, column Y of the grid corresponds to one cutout on the table whose previous word is X and whose next word is Y - both capture the same "what follows what" relationships - cutouts make the weighting more tangible---you can see and feel that some outcomes are more likely because there are literally more cutouts to pick from ## Interactive widget Step through the training process at your own pace. Enter your own text or use the example, then press Play or Step to watch the model being built. Step through the training process at your own pace. Enter your own text or use the example, then press Play or Step to watch the cutouts being placed. --- # Weighted Randomness > Learn how to make random choices where some options are more likely than others---a core generative AI operation. Learn how to make weighted random choices where some options are more likely than others---an operation at the core of all generative AI. ![](../../assets/images/hero-weighted-randomness.avif) ## You will need - 10-sided dice (d10) - coloured marbles or beads in a bag ## Your goal Randomly choose from a fixed set of outcomes according to a given probability distribution. ## Key idea Sometimes we need to make random choices where some outcomes are more likely than others. There are simple ways to do this while keeping the average outcome proportions close to the probabilities you choose. ## Algorithm 1: beads in a bag - materials: coloured beads, bag - setup: count out a number of beads corresponding to the desired weights for each outcome - sampling procedure: shake the bag, then draw one bead without looking ### Example You want to choose an ice cream flavour: `vanilla` 50% of the time, `chocolate` 30%, and `strawberry` 20%. - add 5 white beads to the bag (vanilla) - add 3 brown beads to the bag (chocolate) - add 2 red beads to the bag (strawberry) Draw a bead from the bag---that's your ice-cream choice for today. ## Algorithm 2: dice with ranges - materials: d10 (or d6, d20 as alternatives) - setup: assign number ranges proportional to weights - sampling procedure: roll the die, then look up the corresponding outcome ### Example - for 60% vanilla / 40% chocolate, roll a d10: 1-6 means vanilla, 7-10 means chocolate - for 50% vanilla / 30% chocolate / 20% strawberry, roll a d10: 1-5 means vanilla, 6-8 means chocolate, 9-10 means strawberry You can use different dice (d6, d10, d20, d120, etc.); it just changes the number ranges corresponding to each outcome. ## d10 roll-to-outcome mapping A quick reference for common splits: - 80/20: 1-8 for the 80% outcome, 9-10 for the 20% - 70/30: 1-7 for the 70% outcome, 8-10 for the 30% - 60/40: 1-6 for the 60% outcome, 7-10 for the 40% - 50/30/20: 1-5 for 50%, 6-8 for 30%, 9-10 for 20% Adjust the ranges to match whatever probabilities you need. ## Instructor notes Note: this is a "pre-lesson"; it's usually ok to start from lesson 01 and just have this lesson card handy to refer to if students want more detailed instruction about weighted random sampling. ### Discussion questions - which method feels most "random" to you, and why? - which is fastest for getting repeated random selections? - how would you handle weights like 17, 23, 41? - what happens when one option has 95% probability? - can you invent your own weighted random selection method? ### Connection to current LLMs This lesson introduces weighted random sampling before students encounter language models. While not specific to LLMs, this operation is fundamental to how they work: - **generation mechanism**: every time an LLM produces a word, it's performing weighted random sampling from a probability distribution - **probability distributions**: neural networks output probabilities for thousands of possible next tokens; these probabilities become the "weights" for sampling - **physical intuition**: dice and tokens make the mathematics tangible---when students later learn about "sampling from a distribution," they'll have hands-on experience with what that means The key insight: weighted randomness is a general computational technique with applications far beyond language models (simulations, games, procedural generation). In the context of language models, this same operation happens billions of times during text generation. These physical methods (dice, tokens) implement the exact same mathematical operation that occurs inside LLMs when they choose the next word. --- # Word Embeddings > Turn each word's row into a vector and measure similarities between words in your model. Transform words into numerical vectors (embeddings) that capture meaning, revealing semantic relationships between words in your model. ![](../../assets/images/hero-word-embeddings.avif) This widget works with the [grid](https://www.llmsunplugged.org/modules/training/) version of the bigram model. If you trained using cutouts, the grid won't have any data to display. ## You will need - your completed [bigram grid](https://www.llmsunplugged.org/modules/training/) - another blank [grid template](https://pdf.llmsunplugged.org/worksheets/grid.pdf) with the same headers (for distances) - pen, paper, and dice as per [Generation](https://www.llmsunplugged.org/modules/generation/) (grid method) ## Your goal Create a similarity matrix (another square grid) that shows how similar or different each pair of words is. Stretch goal: visualise the matrix (e.g., as a map or clustering). ## Key idea Each row of counts is an embedding---a numeric fingerprint of context. Comparing rows tells you which words behave alike. ## Algorithm 1. Prepare two grids: the original bigram model and a new empty _distance_ grid with the same row/column headers. 2. For every pair of rows in the bigram model, sum the absolute differences between matching cells. 3. Write that sum into the corresponding cell of the distance grid (diagonal stays 0). You can skip the lower triangle since the distance is symmetric. ## Example Text: `See Spot. Spot runs.` 1. Build the bigram grid as usual. 2. Compare `see` vs `spot` row by row: subtract counts cell-by-cell, take absolute values, and add them up (blanks count as 0). Here, `d(see, spot) = 3`. 3. Fill that value into the distance grid at (`see`, `spot`). Repeat for other pairs. You'll find `see` and `.` can end up very similar (distance 0) while `see` and `spot` differ more, revealing structure in your corpus. ## Interactive widget Explore word embeddings from your bigram model. Click rows to see their numeric vectors and compare distances between words. ## Instructor notes ### Discussion questions - which words cluster together? why? - do grammatically similar words have similar embeddings? - can you predict which words will be close before calculating? - does training on more text change which words cluster together? - what information is captured in these vectors? ### Connection to current LLMs Word embeddings revolutionised NLP by turning words into numbers that computers can process: - **dimensions**: your (e.g.) 8-dimensional vectors → modern models use hundreds or thousands of dimensions - **learning**: you used occurrence patterns → modern models learn from billions of contexts - **semantic capture**: state-of-the-art embeddings encode meaning so well that "`king` - `man` + `woman` ≈ `queen`" actually works - **foundation**: every modern language model starts by converting words to embeddings The insight: words with similar meanings appear in similar contexts, so their usage patterns (and thus embeddings) are similar. Your hand-calculated vectors demonstrate this principle: `cat` and `dog` would have similar embeddings because they both follow `the` and precede `ran` or `sat`. This discovery enabled computers to "understand" that words have relationships and meanings beyond just their spelling. Note on the activity: while the lesson focuses on calculating distances between embeddings (the similarity matrix), this is pedagogically deliberate. Embeddings themselves are just rows of numbers, but distances reveal the relationships between words---which is what makes embeddings useful in practice. The activity emphasises the practical application of embeddings rather than just their construction. --- # Website launch > The LLMs Unplugged website is now live. We're excited to announce the launch of this _LLMs Unplugged_ website. All teaching resources are now available for download, including lesson cards and instructor notes. See the [homepage](https://www.llmsunplugged.org/) for an overview, plus a few different "ways in" depending on who you are and what you're looking for. While the resources themselves are battle-tested and good to go, this website is under active development at the moment (Nov '25) so if you find anything missing or have any suggestions then do get in touch at [ben.swift@anu.edu.au](mailto:ben.swift@anu.edu.au). We've got big plans for these resources going forward: - curriculum mappings (especially to the Australian Curriculum, but potentially to other curriculums as well) - tips/variations on the lessons and how to adapt them for different contexts (including primary-school versions) - videos and animations to accompany the lessons---including some for use in the classroom - suggested assessment tasks (if you're into that sort of thing) Stay tuned for upcoming events, new lessons, and other updates. You can also subscribe to the [RSS feed](https://www.llmsunplugged.org/feed.rss) to get notified when we post news. --- # ACT Academy of Future Skills workshop > Working through LLMs Unplugged with ACT specialty STEM teachers This morning we hosted the [ACT Academy of Future Skills](https://canberradaily.com.au/new-future-skills-academy-for-north-canberra/) for an _LLMs Unplugged_ workshop---was great to think about how this could be used to support teachers in the ACT (and beyond) in teaching the next generation how language models actually work. A pleasure to share with and and get feedback from such a great team of passionate educators. If you're involved with a group of teachers who would similarly like to come and do some training with us to think through how these materials could work in your classroom, do [get in touch](https://www.llmsunplugged.org/about/#get-in-touch). --- # LLMs Unplugged: the pitch to teachers > How do we build the confidence to have discussions about LLMs and AI in our classrooms? If you're a teacher---primary, secondary, or tertiary---Large Language Models (LLMs) like ChatGPT, Claude, and friends are already in your classroom. Maybe they're there in an [official way](https://education.nsw.gov.au/teaching-and-learning/education-for-a-changing-world/nsweduchat). Maybe you feel their shadow in the way you've had to change your assessment to be AI-proof (or at least AI-resistant), if that's even possible. Or maybe they're just present in discussions that your students are having with you and each other about the AI stuff they're doing outside of class. And you'll especially feel this if they ask you any questions about how they actually _work_. There's a growing list of "how to use LLMs/GenAI" resources out there, but most of them treat the LLMs as black boxes... e.g. here are some tips on writing a good prompt, or here are some broad questions to discuss about training data and bias. But I've looked at a lot of these resources and most of them don't even try to explain how they work. To some extent that's understandable---they're the product of millions of person-hours of R&D and many _billions_ of GPU-hours of number crunching in datacenters worldwide. But there are heaps of other complex machines & systems that we still work hard to explain to students (all the way down to primary level) in age appropriate ways. Why should AI and LLMs be any different? That's why I created these _LLMs Unplugged_ resources. Although I'm an academic computer scientist and AI researcher by day, I've also got primary-aged kids of my own. And I want them to grow up seeing that these tools aren't just black-boxes that work by deep voodoo magicl; they're made by humans and used by humans and can be understood and interrogated as such. I really do think that any teacher can (with a bit of training) have the confidence to use the LLMs Unplugged resources to show their students how to build their _own_ language model. You might not be able to answer all the tricky questions that come your way afterwards (isn't that always true!) but you'll have opened up the AI black box in a way that just memorizing a few prompting tips doesn't. If you'd like to find out more about how to use these resources, please [get in touch](https://www.llmsunplugged.org/about/#get-in-touch). --- # LLMs Unplugged at Brimbank Tech School > A hands-on AI workshop for educators at VU Sunshine Campus with Brimbank Tech School Last Friday we partnered with [Brimbank Tech School](https://www.brimbanktechschool.vic.edu.au/) at VU Sunshine Campus for _Lifting the Veil_---a full-day hands-on AI workshop for educators. ![Ben presenting to a room of educators at VU Sunshine Campus](../../assets/images/brimbank-workshop-130.avif) Over 50 teachers and other educational professionals from across the Brimbank region came along, and we spent the day working through AI fundamentals, the _LLMs Unplugged_ hands-on activity, practical applications of machine learning in education, and strategies for supporting schools through the changes (and challenges) that AI is bringing. ![A participant building an N-gram model by hand, tallying token frequencies on a grid worksheet](../../assets/images/brimbank-workshop-082.avif) The highlight---as usual---was the hands-on model building. There's something about actually counting tokens, filling in probability grids and then rolling dice to generate text that makes the whole thing click in a way that slides alone never quite manage. ![Participants in the workshop, with a "Generation" slide on screen and one attendee raising their hand](../../assets/images/brimbank-workshop-105.avif) ![A facilitator helping participants at their table as they work through the activity together](../../assets/images/brimbank-workshop-132.avif) It was a great day---a real pleasure to share these materials with such an engaged group of educators, and to hear how they're thinking about bringing AI literacy into their classrooms. Thanks to the Brimbank Tech School team for making it happen. If you're involved with a group of teachers who'd like to run a similar workshop, do [get in touch](https://www.llmsunplugged.org/about/#get-in-touch). --- # Designing the LLMs Unplugged brand mark > The new brand mark encodes GPT-3 token IDs into visual dot patterns --- here's how it works. Every project should feel like a natural extension of your brand, and for a project about demystifying how language models work it felt right to make the brand mark _itself_ an explainer. So the LLMs Unplugged brand mark is built from the thing that language models actually operate on---tokens. ## Tokenising the title If you feed the string "LLMs Unplugged" into [OpenAI's tokeniser](https://platform.openai.com/tokenizer) (the [cl100k_base](https://github.com/openai/tiktoken) vocabulary used by GPT-3.5/4), you get five tokens: | Token | ID | | ------ | ----- | | `LL` | 3069 | | `Ms` | 5765 | | ` Un` | 1252 | | `plug` | 37729 | | `ged` | 2004 | These splits are a nice illustration of tokenisation in practice. "LLMs" doesn't stay as one piece---it becomes `LL` + `Ms`, which makes a certain kind of sense if you squint (capital letters are rare enough that the tokeniser treats them separately). "Unplugged" becomes ` Un` + `plug` + `ged`, with that leading space on ` Un` showing how [BPE](https://en.wikipedia.org/wiki/Byte_pair_encoding) tokenisers encode word boundaries. None of this is obvious until you actually look at it, which is kind of the point of the whole project. ## The word mark Each of those five tokens becomes a coloured brick in the word mark, arranged on two lines to spell out the title. Each brick cycles between its text label and a 4×4 dot pattern encoding the token ID in binary---more on that below.
## The favicon The favicon takes this one step further. Each token ID is just a number, and numbers can be written in binary. Token 3069 ("LL") in 16-bit binary is `0000 1011 1111 1101`. Lay those 16 bits out in a 4×4 grid, colour the 1s in gold and leave the 0s dim, and you get a tiny visual fingerprint of the token. The LLMs Unplugged favicon---animated dot patterns cycling through all five title tokens If you watch the favicon for a moment you'll notice it isn't static---it cycles through the bit patterns for all five title tokens on a 15-second loop, with smooth transitions between each pattern. The animation is pure CSS `@keyframes`, no JavaScript involved. Each of the 16 circles gets its own keyframe animation based on how its bit differs across the five tokens, so some circles hold steady while others flicker between gold and dim. It's the kind of thing that nobody will ever notice unprompted (pun intended), but once you know what it is, you can't unsee it. Every dot pattern on the site is a real token ID rendered the same way. ## The five-up There's also a static version that lays all five token grids side by side in a single row---no animation, just the five bit patterns sitting next to each other. It reads left to right as `LL` · `Ms` · `\u00A0Un` · `plug` · `ged`. Because it's completely static it works nicely on things like t-shirts and stickers where you can't rely on animation. The first version matches the favicon colour scheme---gold dots on a dark background, uniform across all five tokens: All five LLMs Unplugged title tokens shown side by side as 4×4 dot grids in uniform gold There's also a tinted variant where each token gets its own gold-brick background, matching the colour scheme used in the title logo: All five LLMs Unplugged title tokens shown side by side as 4×4 dot grids with per-token tinted backgrounds ## The lockup Every mark described so far has the same limitation: it only means anything to someone who already knows what the project is. A stranger seeing a grid of gold dots learns nothing. That's fine for a favicon---the tab title does the work---but it rules the marks out of the places a logo usually goes: a site header, a slide corner, the top of a handout, a conference badge. So there's a horizontal lockup, which is just the favicon grid with the title set next to it in [Public Sans](https://public-sans.digital.gov/), the ANU brand typeface: The LLMs Unplugged horizontal lockup---the 4x4 dot grid with the title set beside it The grid holds the bit pattern for `LL` (token 3069), which is the frame the favicon rests on before its animation starts. Unlike the favicon, the lockup doesn't cycle: at favicon size the flicker is an easter egg nobody notices until they do, but in a page header it's a moving object competing with the content underneath it. There's an animated version at `/lockup-animated.svg` for hero and social contexts where that's the point. The wordmark is baked to outlines rather than referenced as a font, so the file carries its own letterforms and renders identically as an ``, in print, or dropped into a design tool with no network access. The background stays transparent and the wordmark comes in two colours---white in `/lockup.svg` for dark surfaces, near-black in `/lockup-light.svg` for light ones. On ANU gold the light variant is the one to reach for; white on gold clears 3:1 but not much more. ## The animated version There's also an animated version of the brand mark which starts with the title "LLMs Unplugged" already assembled from five gold bricks, sitting against a field of around 270 dimmed background bricks. After a pause the title tokens dissolve back into the grid, blending in with the rest. The bricks reshuffle into new random positions, then the five title tokens light up again and slide into place to re-spell the title. Each cycle the bricks are re-randomised, so the title tokens emerge from different positions every time.
The whole thing scales to whatever container you put it in---no pixel breakpoints or resize listeners needed. The animation captures the core visual metaphor of the project: meaningful text emerging from what looks like a random jumble of tokens. It's basically what a language model does, just at a pace humans can follow. ## Background mode There's also a stripped-back variant that just shows the shuffling brick grid without ever highlighting or assembling the title tokens. It's useful as a visual backdrop---we use it behind divider slides in our workshop presentations---where you want the token texture without the full animation competing for attention.
--- # LLMs Unplugged at ICTENSW DigiTLL > Presenting "LLMs Unplugged" at the ICTENSW DigiTLL Conference in North Sydney on 15 March We're presenting _LLMs Unplugged_ at the [ICTENSW DigiTLL Conference](https://www.ictensw.org.au/event-6112449) on **Saturday 15 March** (12:00--1:00pm) at [Australian Catholic University](https://www.acu.edu.au/locations/north-sydney) in North Sydney. The session---"LLMs Unplugged: Understand AI by building it yourself"---is the usual deal: build a language model with pen, paper and dice, and walk away with a concrete mental model of how ChatGPT, Claude, Gemini and the rest actually work under the hood. No laptops required. [DigiTLL](https://www.ictensw.org.au/event-6112449) is a two-day professional learning conference run by [ICTENSW](https://www.ictensw.org.au/)---designed by teachers, for teachers---covering digital technologies, AI, and computer science across the NSW curriculum. If you're a NSW educator looking to get your head around AI in a hands-on way, it's a good fit. [Register on the ICTENSW website.](https://www.ictensw.org.au/event-6112449/Registration) --- # Mapping LLMs Unplugged to the Australian Curriculum > An example of how LLMs Unplugged activities align with the Australian Curriculum for Year 5/6. One of the questions we hear most from teachers is "where does this fit in the curriculum?" There's no single answer --- it depends on your year level, subject focus and local curriculum context. But to help get the conversation started, here's an example mapping of the Training and Generation lessons to the Australian Curriculum for Year 5/6. You could map it differently for other year levels or subject areas. ## Digital Technologies - [**AC9TDI6P05**](https://www.australiancurriculum.edu.au/f-10-curriculum/learning-areas/digital-technologies/year-5/content-description?subject-identifier=TECTDIY56&content-description-code=AC9TDI6P05) --- implement algorithms as visual programs involving control structures, variables and input - [**AC9TDI6K02**](https://www.australiancurriculum.edu.au/f-10-curriculum/learning-areas/digital-technologies/year-5/content-description?subject-identifier=TECTDIY56&content-description-code=AC9TDI6K02) --- examine how digital systems form networks to transmit data (this connects well if you explain where training material is stored and how it's sourced from servers over the internet) ## Mathematics --- Number - [**AC9M5N010**](https://www.australiancurriculum.edu.au/f-10-curriculum/learning-areas/mathematics/year-5/content-description?subject-identifier=MATMATY5&content-description-code=AC9M5N010) --- create and use algorithms involving a sequence of steps and decisions and digital tools to experiment with factors, multiples and divisibility; identify, interpret and describe emerging patterns ## Mathematics --- Statistics - [**AC9M5ST01**](https://www.australiancurriculum.edu.au/f-10-curriculum/learning-areas/mathematics/year-5/content-description?subject-identifier=MATMATY5&content-description-code=AC9M5ST01) --- acquire, validate and represent data for nominal and ordinal categorical and discrete numerical variables, to address a question of interest or purpose; discuss and report on data distributions in terms of highest frequency (mode) and shape ## Mathematics --- Probability - [**AC9M5P01**](https://www.australiancurriculum.edu.au/f-10-curriculum/learning-areas/mathematics/year-5/content-description?subject-identifier=MATMATY5&content-description-code=AC9M5P01) --- list the possible outcomes of chance experiments involving equally likely outcomes and compare to those which are not equally likely - [**AC9M5P02**](https://www.australiancurriculum.edu.au/f-10-curriculum/learning-areas/mathematics/year-5/content-description?subject-identifier=MATMATY5&content-description-code=AC9M5P02) --- conduct repeated chance experiments including those with and without equally likely outcomes, observe and record the results; use frequency to compare outcomes and estimate their likelihoods ## Other connections There are also potential connections to English outcomes for language, text structure and organisation --- another thread worth exploring depending on how you frame the activities in your classroom. For more on how AI connects to the Australian Curriculum, ACARA's [Curriculum Connections](https://www.australiancurriculum.edu.au/resources/curriculum-connections) site includes AI as one of the searchable themes. ## Share your own mapping This is just one example, and we'd love to see others. If you've mapped LLMs Unplugged to a different year level, subject or curriculum framework, [get in touch](https://www.llmsunplugged.org/about/#get-in-touch) --- we're happy to share further examples here. We're also working with ACARA and other Australian educators to develop more comprehensive, searchable mappings between the different LLMs Unplugged lessons and the full Australian Curriculum. Watch this space. --- # LLMs Unplugged for ACT teachers > A hands-on workshop for ACT educators at the Hedley Beare Centre on 18 March _A tech-free guide to understanding (and teaching) AI._ We're running a public _LLMs Unplugged_ workshop for teachers on **Wednesday 18 March** (4:30--6:00pm) at the [Hedley Beare Centre for Teaching and Learning](https://maps.google.com/?q=Hedley+Beare+Centre+For+Teaching+And+Learning+51+Fremantle+Dr+Stirling+ACT+2611) in Stirling, ACT. The idea is the same as always---peek inside the black box by building your own paper-and-pen language model. No coding, no maths beyond basic counting and percentages, just hands-on activities that make the core concepts behind ChatGPT, Claude, Gemini and the rest actually click. It's aimed at upper primary and secondary educators across all disciplines---you don't need to be a STEM teacher to get value out of this. If your students are asking you questions about AI (and they probably are) this workshop will give you a solid mental model of how these things actually work, plus ideas for connecting it back to your curriculum across mathematics, technologies, HASS and literacy. [Grab a ticket on Humanitix](https://events.humanitix.com/llms-unplugged-for-teachers)---educator tickets are ~$60. If you're wondering why this stuff matters for your classroom, here's [the case for an unplugged approach to teaching AI](https://www.llmsunplugged.org/news/2025-12-12-why-use-an-unplugged-approach-in-your-classroom/). --- # The AI schools framework is right about the goal — but there's a simpler path > The Australian Framework for Generative AI in Schools asks teachers to do extraordinary things. There's a simpler way to build genuine AI literacy. The [Australian Framework for Generative AI in Schools](https://www.education.gov.au/schooling/resources/australian-framework-generative-artificial-intelligence-ai-schools) gets the diagnosis right. Students need to understand how AI works, not just how to use it. Teachers need to be able to explain what's happening under the hood. Schools need to think carefully about privacy, fairness, and the wellbeing of their students. Six principles, twenty-five guiding statements --- hard to argue with any of it. But while spelling out the problem is important, we need solutions too. As Lucinda McKnight and Leon Furze [argued in The Conversation](https://theconversation.com/australia-has-its-first-framework-for-ai-use-in-schools-but-we-need-to-proceed-with-caution-219094), the framework places an "extraordinary onus" on teachers. It asks them to conduct risk assessments of algorithms, ensure "explainability" of AI systems, revise assessments, consult communities --- all within already-stretched workloads, without additional funding, and in many cases without the technical background to know where to start. The implicit assumption is that teaching AI literacy means buying edtech products, navigating data privacy agreements, and somehow becoming an expert in algorithmic auditing on top of everything else. There's a much simpler way in. ## Build the thing LLMs Unplugged takes a different approach: instead of interacting with a commercial AI product and trying to explain what it's doing, students build their own language model from scratch. Pen, paper, dice. No screens, no accounts, no data leaving the room. The activity works like this. Students take a short text --- a few sentences of a picture book, say --- and count how often each word follows each other word. They fill in a table. They roll dice to sample from those frequencies. Out comes new text, generated by their model. It's often funny, sometimes nonsensical, and occasionally eerily plausible. The point isn't the output --- it's the understanding that comes from having built the machinery yourself. This is not a simplified analogy for how language models work. It _is_ how they work --- at a smaller scale, obviously, but the core mechanism is the same. Modern LLMs use exactly this approach (modelling language as weighted distributions over sequences) at vastly greater scale and with learned rather than hand-crafted statistics. When a student rolls a die to pick the next word based on probabilities they counted by hand, they're doing what GPT does billions of times a second. ## What the framework asks for, without the overhead The framework's transparency principle calls for "explainability" --- that teachers and students should be able to understand and explain how an AI system reaches its outputs. This is genuinely difficult when the system in question is a black-box hosted chatbot built on hundreds of billions of parameters. But a model you built yourself on a sheet of A3 paper? Every step is visible. Every decision is traceable. Explainability isn't an aspiration --- it's a structural property of the activity. The privacy and safety principle is similarly straightforward. Most paths to AI literacy in schools involve students interacting with online tools, which means accounts, data collection, acceptable use policies, and the ever-present question of what happens to student conversations. LLMs Unplugged sidesteps all of this. There's no software to vet, no data to protect, no terms of service to parse. The most sensitive piece of technology in the room is a six-sided die. Then there's fairness. The framework rightly asks that AI in schools should be accessible regardless of a school's resources. But the edtech pathway creates exactly the inequity it's trying to prevent --- well-resourced schools get the good tools, everyone else gets whatever's free. An activity that requires paper and dice works the same in every classroom, in every school, in every state. And the wellbeing principle? No risk of students developing over-reliance on a chatbot, no chance of harmful or inappropriate AI-generated content, no parasocial relationships with a language model. The model they built doesn't talk back. The framework's teaching and learning principle emphasises that AI should support teacher expertise, not replace it. I'd argue it should also not _overwhelm_ it. Asking teachers to become algorithmic auditors is not support --- it's an unfunded mandate dressed up as professional development. LLMs Unplugged is designed so that [any teacher can run it](https://www.llmsunplugged.org/news/2025-12-12-why-use-an-unplugged-approach-in-your-classroom/), regardless of their technical background. You don't need to understand neural networks or [transformer architectures](https://jalammar.github.io/illustrated-transformer/). You need to be able to count words, fill in a table, and roll dice. The activity builds the teacher's understanding alongside the students' --- and it [maps directly to existing curriculum outcomes](https://www.llmsunplugged.org/news/2026-03-18-curriculum-mapping-example/) in maths, digital technologies, and English. Doing LLMs Unplugged doesn't mean that there aren't deep and nuanced questions to wrestle with in the classroom. The fact that your _very small_ language model can actually generate (at times) coherent text is marvellous, but it's vastly less impressive than the real Large Language Models which everyone with an internet connection now has access to today, and often for free. ## The simplest path is often the best one And so I'm clearly not arguing that schools should never use AI tools (I use [Claude Code](https://docs.anthropic.com/en/docs/claude-code) _all the time_ for software development), or that the framework is wrong to think carefully about how they do. But there's a version of AI literacy that doesn't require procurement processes, data protection impact assessments, or teachers becoming overnight experts in machine learning. It requires paper, dice, and a willingness to get stuck in. The AI Schools framework asks schools to do hard things. Some of those things genuinely are hard. But understanding how language models work doesn't have to be one of them. If you'd like to try LLMs Unplugged in your school, [get in touch](https://www.llmsunplugged.org/about/#get-in-touch). --- # Open-enrolment workshops in May and June > Two upcoming hands-on LLMs Unplugged workshops at ANU, open to everyone We're running two open-enrolment _LLMs Unplugged_ workshops at ANU over the coming months---same format, different times, so pick whichever suits. - **Thursday 28 May** (12:00--14:00, Canberra time) - **Thursday 11 June** (16:00--18:00, Canberra time) Both sessions are at the [Innovation Space, Birch Building, ANU](https://maps.google.com/?q=Birch+Building+35+Science+Rd+Acton+ACT+2601), hosted by the [School of Cybernetics](https://cybernetics.anu.edu.au). The deal is the same as always: build your own language model with pen, paper and dice. No screens, no coding, no maths beyond basic counting and percentages. You'll walk away with a concrete understanding of how ChatGPT, Claude, Gemini and the rest actually work under the hood---the probabilistic nature of LLMs, the importance of training data, and how bias and design decisions can show up in the output. If you're writing policy, evaluating AI vendors, or just trying to figure out how much to trust the thing drafting your briefs, this is a good place to start. If you're an educator, the activities are designed to go straight back into the classroom. They align with curriculum outcomes across mathematics, technologies, HASS and literacy, and the only prerequisite is curiosity. For ACT teachers: the workshop is [accredited by the ACT Teacher Quality Institute](https://www.llmsunplugged.org/news/2026-04-24-tqi-accreditation/) as a two-hour professional learning program, so attendance counts toward your annual registered PL hours. Tickets are on Humanitix---~$230 for industry and general public, ~$60 for educators (requires a .edu email): - [28 May session](https://events.humanitix.com/llms-unplugged-a-tech-free-guide-to-understanding-and-teaching-ai-28-may) - [11 June session](https://events.humanitix.com/llms-unplugged-a-tech-free-guide-to-understanding-and-teaching-ai-11-june) Here's [a flyer](https://pdf.llmsunplugged.org/llms-unplugged-flyer-may-2026.pdf) if you'd like to put one up in your office or tea room. --- # Luritja resampled > Running LLMs Unplugged at the Tjabal Centre Autumn School with Luritja poet Matt Heffernan, using his poem Ngurrparringu as the training text Last week we ran _LLMs Unplugged_ at the [Tjabal Centre](https://www.anu.edu.au/students/contacts/tjabal-indigenous-higher-education-centre)'s Autumn School with [Matt Heffernan](https://redroompoetry.org/poets/matthew-heffernan/)---Luritja poet, collaborator, and (for the morning) generous supplier of training data. The Autumn School is part of the [Bandalang National Indigenous Engineering Autumn School](https://eng.anu.edu.au/bandalang/programs/bandalang-national-indigenous-engineering-autumn-school/), a week-long program that brings Aboriginal and Torres Strait Islander high school students to ANU to explore engineering, computing, and cybernetics alongside researchers and Indigenous knowledge holders. Instead of the usual training texts we used Matt's poem [_Ngurrparringu (Forgotten)_](https://redroompoetry.org/poets/matthew-heffernan/ngurrparringu-forgotten/) in both its Luritja and English versions. Participants did what LLMs Unplugged participants always do---counted token frequencies, sorted them into bigram buckets, and generated new text by drawing tokens from those buckets---except this time the new text came out in Luritja. ![Matt Heffernan looking on as an Autumn School participant works through the training activity](../../assets/images/tjabal-workshop-01.avif) _Ngurrparringu_ is about language, ancestors, country, and forgetting. Handing it to a room of Autumn School students so they could cut it into pieces and rearrange those pieces into new statistical remixes takes a particular kind of generosity. Thanks Matt for being willing to share this moment---as poet, translator, and co-teacher. ![Hands arranging Luritja word tokens: ngurra, ngayulu, tjukurrpa, warranu, nyinapa, ngayunywanpa](../../assets/images/tjabal-workshop-02.avif) Here's one of the Luritja generations that came out of a group's bigram model: > ngurra, Warumpila, Ngayulu Tjilpirringkula ngurrakutu Yankuku. Walpa > tjamunyatjarra yutitja kulini. Kunyi Wiyalpi ngayulu nyinarra ngurrparringu. > Tjinguru irrititja tjilpi tjuta ngayunywanpa ngurrangka nyinangu. Walpawana > tjilpilu warranu tjukurrpa. Wiya Watjilarritjaku. Kala tjinguru ngayulu Walpa > kulitjaku, walpaya kulinu watjilpa wiyangku. Matt translated it for us on-the-fly: > Country... Warumpi, I will become an old man, towards homes going. My > grandfather's Winds heard Clearly, Poor things, I don't stay---forgotten, > Maybe, in the old times, old men like me Stayed on Country, the Wind, the old > men Sung Dreamtime, Not Sad anymore, but---ok, maybe I will hear the Wind, > Wind is lonely---No. Every word in the Luritja comes from Matt's poem; the model has just put them in a different order. ![English word tokens: home, return, hear, the, sung, and, to, my](../../assets/images/tjabal-workshop-03.avif) There is nothing inherently English (or any other particular language) about a language model. The training data determines the output language. Train on Luritja, get Luritja out. Train on a Python codebase, get something that looks like Python. What goes in is what comes out. Another group trained on only the English version of _Ngurrparringu_ and their language model generated this poem: > Clearly anymore. I don't hear the wind, listening to the old men sat on the > wind of my people, Warumpi Every word Matt's, but reshuffled. To close out the morning we all worked together on one more new LLM-generated poem, this time tipping _The Cat in the Hat_ into the training mix alongside the English poem: > Good Fun at all if you wish we sat in the mountains, we had something to Sing > our Tjukurrpa, Cold "Good fun" and "all if you wish" are Seuss; "mountains" and "Tjukurrpa" are Matt. The model samples whatever tokens are in the bucket, and if you mix the training data and you mix the output. The corollary is that if a language isn't in the training data, it isn't in the outputs either. No representation in, no representation out. When people say modern LLMs "know" English better than other languages, they mean those LLMs were trained on orders of magnitude more English text than anything else, and the tokenisers, evaluations and benchmarks all reflect that choice. It's a property of what we fed them. ![Autumn School students and Ben gathered around a table covered in word tokens](../../assets/images/tjabal-workshop-04.avif) Thanks again to Matt for the time, the poem, and the translations, and to the Tjabal Centre and the Autumn School participants for being up for something new on a Tuesday morning. If you work with a language (or a community, or a knowledge tradition) that's underrepresented in LLM training data and want to try something like this, do [get in touch](https://www.llmsunplugged.org/about/#get-in-touch)---we'd love to help. --- # LLMs Unplugged is TQI-accredited > The ACT Teacher Quality Institute has accredited LLMs Unplugged as a two-hour professional learning program Good news for ACT educators: the ACT [Teacher Quality Institute](https://www.tqi.act.edu.au/) has accredited _LLMs Unplugged_ as a two-hour professional learning program. Attending a workshop now counts toward your annual professional learning hours for ACT teacher registration---no extra paperwork at your end. The program will also be listed on the [TQI accredited PL search](https://teachereducation.tqi.act.edu.au/), so colleagues across the ACT can find it there too. The next [open-enrolment workshops](https://www.llmsunplugged.org/news/2026-03-24-open-enrolment-workshops/) at ANU run in May and June, if you've been meaning to come along. If you'd like to organise a session for your school or region, [get in touch](https://www.llmsunplugged.org/about/#get-in-touch). --- # Cutouts get a glow-up > A revamped cutouts variant of the Training and Generation lessons, with crisper print materials and a generation mechanic that does weighted sampling for free. The cutouts variant of the [Training](https://www.llmsunplugged.org/modules/training/) and [Generation](https://www.llmsunplugged.org/modules/generation/) lessons has had a serious refresh. If you haven't tried this version with your students, now's a good time. Instead of building the whiteboard frequency grid, you print the bigram model as physical cards and scatter them face-up across a big table. Each card shows a prefix (the word that came before) and a token (the word that follows). To generate text: scan for a card whose prefix matches your last-written word, write its token, then hunt for the next match. The chain grows like dominoes. The trick is in the scanning. Every token has its own colour, repeated wherever it appears: as a prefix box on one card, as a free-standing token on another. To match a prefix against your last word, your eye hunts for that word's colour on the right edge of a card. Verify the actual token before committing, since colours sometimes collide. This gives you [weighted random sampling](https://www.llmsunplugged.org/modules/weighted-randomness/) for free. If `eggs` follows `green` 40% of the time in the training text, then 40% of the matching cards will say `eggs`. Whichever card your eye lands on, you've sampled in proportion to the empirical distribution. No dice, no probability tables: the spread is doing the maths. That's the main argument for choosing the cutouts over the [grid version](https://www.llmsunplugged.org/modules/training/) of the lesson. The cutouts skip the explicit [weighted-sampling step](https://www.llmsunplugged.org/modules/weighted-randomness/), which is the conceptually heaviest moment in the unplugged sequence. They also parallelise better: a class of thirty splits into seven groups around their own table-spreads, where the grid bottlenecks at one teacher. The costs are a colour printer (essential, since the colour coding is doing real work), scissors, and more table than the grid wants. For primary-age students the cutouts are the easier sell, and the weighted-sampling-without-the-maths trick still lands well with adults. The earlier ancestor of these lessons was called _buckets_: students sorted cut-up cards into piles by their prefix word before any text generation happened. The sorting turned out to be the part nobody enjoyed, and it ate the time we wanted to spend on the [Generation lesson](https://www.llmsunplugged.org/modules/generation/) itself. The new design skips the sort and goes straight to the spread. The [tools page](https://www.llmsunplugged.org/tools/#cutouts) has three ready-to-print PDFs: [_Green Eggs and Ham_](https://pdf.llmsunplugged.org/cutouts/green-eggs-and-ham.pdf), [_Where Is the Green Sheep?_](https://pdf.llmsunplugged.org/cutouts/where-is-the-green-sheep.pdf), and [_We're Going on a Bear Hunt_](https://pdf.llmsunplugged.org/cutouts/were-going-on-a-bear-hunt.pdf). They're designed for A4 colour printing, pre-rotated for double-sided output so the same cards appear on both faces of each sheet and students never have to flip a face-down card. Each PDF includes an instructions page with a labelled card and a domino chain showing how each token becomes the next card's rightmost prefix. The same tools page lets you generate cutouts from any text you like. Both bigram (n=2) and trigram (n=3) configurations work, and you can push to n=4 or beyond. The [More Context lesson](https://www.llmsunplugged.org/modules/more-context/) walks through the trade-off: bigger n produces text that reads more like the source, at the cost of a much bigger spread. Cutouts let you see this trade-off as physical paper rather than an abstract claim. If you can't print colour, or your students respond better to a tighter board-style activity, the grid versions of [Training](https://www.llmsunplugged.org/modules/training/) and [Generation](https://www.llmsunplugged.org/modules/generation/) are still here, still good. Both variants land at the same understanding by different paths. Try the cutouts. --- # Generating the cutout palette > The cutout palette is now algorithmically generated, with 30 perceptually distinct colours instead of 14 hand-picked ones. The cutouts variant of the [Training lesson](https://www.llmsunplugged.org/modules/training/) leans hard on colour as a fast filter. Every word has its own colour, repeated wherever the word appears, so your eye can scan "what's the colour of the word I just wrote?" before you read any text. It really helps with the needle-in-a-haystack aspect of the activity. Until last month the palette held eight colours, hand-picked in [OKLCH](https://oklch.com) at a fixed lightness so white text would read on every coloured box. _Green Eggs and Ham_ has about sixty unique tokens trying to share eight buckets, which works out to seven or eight words sharing each colour. Plenty of colour collisions, plenty of moments where you have to slow down and re-read. I bumped it to 14 (still hand-tuned, two lightness levels) and that helped, but really this is a solved problem and I was reinventing it badly. The new palette is algorithmically generated using [Glasbey-style](https://en.wikipedia.org/wiki/Glasbey_palette) greedy max-min selection in OKLab. The algorithm samples 200k candidate colours uniformly from the sRGB gamut, converts them to OKLab (which is perceptually uniform by design, so plain Euclidean distance corresponds to perceived difference), then iteratively picks the candidate that's furthest from every colour already chosen. Black and mid-grey are seeded as anchors so the algorithm can't accidentally allocate "chromatic" colours that drift into greyscale. The result is 30 swatches with a minimum pairwise OKLab ΔE of 0.137. That sits comfortably above the 0.10 "clearly distinct" floor, with headroom for the perceptual loss you get from CMYK conversion, paper colour, and ambient lighting. Print eats some of your distinguishability budget, and not always in proportion to OKLab distance. A first pass let candidates roam from L=0.20 upwards and gave a slightly tighter min ΔE of 0.145. It also produced a dark blue at L≈0.275 that came out of the printer looking like black. CMYK reaches saturated deep blue by leaning hard on the K plate, so a small ink-balance shift collapses the colour onto pure black; the seeded black anchor protects against collisions in OKLab, not in CMYK. Raising the L floor to 0.32 trims four near-black candidates, costs about 0.008 of min ΔE, and leaves no chromatic entry close enough to merge with K in print. Each palette entry is tagged as "light" or "dark" based on its OKLab L. The Typst renderer pairs light entries with black text on the coloured box and a thin black stroke on the free-standing word; dark entries get white text and no stroke. That adaptive treatment is what lets the palette extend up to L≈0.92, where the very light pastels live. Without it, every fill would have to be dark enough for white text to read on, capping the usable lightness range and so the achievable colour count. The palette isn't colour-vision-deficiency safe. CVD-safe palettes max out around 8-12 distinct colours, which would undo the whole exercise. If you're working with a CVD-affected student, the [grid version](https://www.llmsunplugged.org/modules/training/) of the lesson uses no colour at all and reaches the same understanding. The script lives in the repo at `cli/scripts/generate_palette.ts`: pure TypeScript, Node 22.7+ native, no `tsx` or `npm install` required. The Typst file that produces the cutouts has the resulting OKLCH triples pasted in directly, with a comment pointing at the script for regeneration. Different N or different lightness bounds, one line regenerates the palette. The [tools page](https://www.llmsunplugged.org/tools/#cutouts) has the four ready-to-print PDFs (_Green Eggs and Ham_ and _The Cat in the Hat_, each in bigram and trigram), all freshly built with the new palette. If you've used the cutouts before, you'll notice the difference straight away. If you haven't, the [previous post](https://www.llmsunplugged.org/news/2026-05-07-cutouts-glow-up/) explains the activity. --- # How AI writes stories at Duffy Primary > Taking LLMs Unplugged into a Year 5 classroom at Duffy Primary School, with the ACT Academy of Future Skills Last Tuesday we took _LLMs Unplugged_ into a Year 5 classroom at [Duffy Primary School](https://www.duffyps.act.edu.au/) (around 35 students) for a lesson we called _How AI Writes Stories_. The session came about through the [ACT Academy of Future Skills](https://canberradaily.com.au/new-future-skills-academy-for-north-canberra/), who've been helping us get these materials in front of students and teachers across the territory's public schools. Most of our workshops so far have been with teachers, education professionals, or high-school students. Duffy was our first proper run with upper-primary kids, and we genuinely weren't sure how the hands-on model building would land with a younger group. We needn't have worried. ![Duffy Primary Year 5 students seated facing the front of the room as two facilitators present a slide headed "Writing"](../../assets/images/duffy-workshop-01.avif) We ran the [cutouts version of the activity](https://www.llmsunplugged.org/decks/how-ai-writes-stories/): rather than tallying tokens on a worksheet, students sort word cards into buckets and then build new sentences by drawing cutouts one at a time. Counting, sorting, and then watching a brand-new sentence assemble itself out of nothing but frequency counts---it's the same statistical machinery that sits underneath ChatGPT, just slowed down to human speed and made out of paper. ![A worksheet bordered with cut-out word tiles framing a passage of handwritten text the students generated from their model](../../assets/images/duffy-workshop-03.avif) The Year 5s were sharp. They asked exactly the questions you'd hope for: why the model sometimes produces nonsense, where the "creativity" actually comes from, what changes if you feed it a different book---plus a few that properly made us think. There's something clarifying about explaining a language model to a ten-year-old; an explanation that doesn't survive contact with a Year 5 classroom probably wasn't a good explanation to begin with. ![A student holding up their handwritten workshop notes, headed "Cybernetics"](../../assets/images/duffy-workshop-02.avif) Thanks to Pip Hall and the Duffy Primary team for having us, and to the ACT Academy of Future Skills for making the connection. There are already more primary schools lining up---which is exactly the point. If you'd like to run something like this with your students, do [get in touch](https://www.llmsunplugged.org/about/#get-in-touch). --- # LLMs Unplugged for political scientists > Running the opening session at the 3rd APSA Workshop on Quantitative Methods at ANU, for a room of political and social science researchers Last Thursday we took _LLMs Unplugged_ to the [3rd APSA Workshop on Quantitative Methods](https://rsss.cass.anu.edu.au/news/3rd-apsa-workshop-quantitative-methods-integrating-ai-quantitative-political-research) at ANU. The full-day event was run by the [Australian Political Studies Association](https://auspsa.org.au/)'s Quantitative Methods Research Group, with support from ANU's [School of Politics and International Relations](https://politicsir.cass.anu.edu.au/). This year's theme was integrating AI into quantitative political research. The room was full of HDR students, early-career researchers, and senior scholars working out where these tools fit into the social-science workflow. Most of our workshops so far have been with teachers or school students. This was a different crowd: researchers who already use language models in their work, or are about to. They want to treat a model as a serious research instrument. We ran the opening session, _LLMs Unplugged: Building a Language Model from Scratch_, with a brief to lay down a shared mental model before the more applied sessions later in the day. ![A wide view of the RSSS lectorial, with workshop participants seated at tables facing the front, where a slide of cut-out token figures is projected](../../assets/images/apsa-workshop-01.avif) We did what we always do.[^year5] The participants tallied token frequencies, filled in the probability grid, and [generated new text](https://www.llmsunplugged.org/modules/generation/) by rolling dice against the counts. It's the same statistical machinery that sits underneath ChatGPT, slowed right down to human speed and built out of paper and dice. ![Ben presenting at the front of the room, mid-gesture, with the cut-out token figures on the screen behind him](../../assets/images/apsa-workshop-02.avif) The early responses to the post-workshop survey have been generous about the hands-on approach, gratifying for a session pitched at serious scholars from outside the discipline of Computer Science. Thanks to the co-chairs, [Thiago Nascimento da Silva](https://cass.anu.edu.au/research/people/associate-professor-thiago-n-silva) and [Constanza Sanhueza Petrarca](https://cass.anu.edu.au/research/people/dr-constanza-sanhueza-petrarca), for the invitation. Thanks too to my co-facilitators Cole and Eddie. If you work with a group of researchers who would like an honest, hands-on feel for how these models actually work, do [get in touch](https://www.llmsunplugged.org/about/#get-in-touch). [^year5]: It is, give or take, the same activity we [ran with a Year 5 class at Duffy Primary](https://www.llmsunplugged.org/news/2026-06-02-how-ai-writes-stories-at-duffy/) a couple of weeks earlier. --- # Yoda, ELIZA, and a Year 7 bigram model > A pre-service teacher took LLMs Unplugged into a lower-SES Year 7/8 classroom, swapped the children's book for a Yoda monologue, and added a 1966 chatbot for contrast Most of the _LLMs Unplugged_ stories on this page are about sessions I ran myself, or ran alongside teachers I'd trained. This one is different: it's about a classroom I never set foot in, run by someone who took the materials, reshaped them for his own students, and made them better in the process. [Kieren Xiang](https://www.westernsydney.edu.au/) is a pre-service teacher I met at the [ICTENSW DigiTLL conference](https://www.llmsunplugged.org/news/2026-03-15-ictensw-digitll-conference/) back in March, where I'd run the usual pen-paper-and-dice bigram activity. On his pract he ended up teaching a run of lessons on AI---and large language models in particular---to Stage 4 (Year 7 and 8) students at a lower-SES public high school in Western Sydney. The middle section of those lessons was his own adaptation of the website materials and the bigram generator I'd demoed at the conference. He wrote to tell me how it went, and it was too good not to share. ## Yoda as training data The original activity builds a bigram model from a children's book. Kieren simplified it hard for his context, and in doing so landed on something I wish I'd thought of first: instead of a book, he trained the model on a Yoda monologue from _The Empire Strikes Back_. Yoda has a famously distinctive way of speaking---that object-subject-verb word order is practically a statistical signature in its own right---and his vocabulary isn't large. Around ninety seconds of dialogue gave the class just over fifty words to work with: small enough to be tractable for a Year 7 group, distinctive enough that the generated text still _sounds_ like something. The mechanics were still very much unplugged. Each group took responsibility for only one or two words, filled in their slice of the bigram table, and then the class combined everyone's sheets into a single shared model before generating new text from it. Two ideas landed cleanly, even with this group: 1. modern LLMs are fundamentally probabilistic machines---they don't look up the right answer, they sample a likely next word 2. more data makes a better model That second point is hard to lecture and easy to feel. When fifty words of Yoda produces something halfway coherent, the question "what would a thousand words do?" answers itself. ## The reception The part that delighted me most wasn't the bigrams at all. As a contrast, Kieren introduced [ELIZA](https://en.wikipedia.org/wiki/ELIZA)---Joseph Weizenbaum's 1966 chatbot---to show what "natural language" AI looked like when it was concretely programmed rather than learned from data. He even built a bigram model derived from ELIZA as a warm-up before the Yoda tables. The students loved to hate her. ELIZA's canned, deflecting replies frustrated them so thoroughly that, as the class was winding down, they asked to keep going---determined to get her to actually answer a question. There's a real lesson buried in that frustration: feeling the difference between a system that follows rules and one that models language is worth more than being told about it. A couple of things from Kieren's write-up stuck with me. The first is that, despite having no formal training in AI---just genuine enthusiast knowledge---he quickly became the de facto AI expert in the faculty, to the point of being invited to talk to senior classes about machine learning and LLMs. The appetite among teachers to understand this stuff is enormous, and the bar to becoming the person who can explain it is lower than people think. That's the whole premise of this project. The second is about the students themselves. They were engaged---but they enjoyed the _ethics_ discussion more than the dice-rolling, which is not the result I'd have predicted. And most of them arrived with strong, mostly negative views about LLMs: job losses, energy and water use, deepfakes. A few shifted over the lessons from "purely bad" to "useful, but still could be bad"---holding both at once. That's a sharp contrast with the largely enthusiastic adoption Kieren saw among teachers, and it's a healthy reminder that the students walking into these rooms are not blank slates. That's exactly what I want _LLMs Unplugged_ to be: a set of materials a teacher can pick up, bend to their own room and their own kids, and run without me in the building. Huge thanks to Kieren for taking it somewhere I wouldn't have, and for letting me tell the story. If you've adapted the materials for your own classroom, I'd genuinely love to hear about it---[get in touch](https://www.llmsunplugged.org/about/#get-in-touch). --- # LLMs Unplugged at the ACDICT L&T Forum > Slides and worksheets for my ACDICT Learning & Teaching Forum session, plus a self-guided path for anyone joining online. Today I'm running an _LLMs Unplugged_ session at the [ACDICT](https://www.acdict.edu.au/) Learning & Teaching Forum. It's a hands-on, pen-paper-and-dice walk through how a language model actually works---you build a bigram model by hand, generate new text from it by rolling dice, and then bolt on a couple of the ideas (sycophancy, tool use) that turn up in the real systems. The session is mostly in-person, but a few people are joining online, and this post is for them. ## Following along online The slides are here: **[LLMs Unplugged @ ACDICT](https://www.llmsunplugged.org/decks/acdict/)**. I'll be talking mostly to the people in the room, so the online experience will be a bit fly-on-the-wall---I won't be watching the chat closely while I present. But if you're keen, you can genuinely do the whole thing yourself as we go; it's all analogue. You'll need: - a printed [grid template](https://pdf.llmsunplugged.org/worksheets/grid.pdf) (or any grid paper---even hand-drawn is fine) - a book to use as training data---a kids' book is ideal (short sentences, small vocabulary), but anything with text will do - a die, or a dice-rolling app, for the generation step - and, for the sycophancy section near the end, the [sycophancy training text](https://pdf.llmsunplugged.org/worksheets/sycophancy-text.pdf) to tally into your grid Work through it at your own pace. Treat it as choose-your-own-adventure: follow the steps as we go and you'll come out the other side having built and run your own language model by hand, no computer required. If you get stuck, or want to go deeper afterwards, the full set of [lessons](https://www.llmsunplugged.org/modules/) covers everything here in more detail. ![Completed worksheets on a table after the session: a filled-in LLMs Unplugged grid with token tallies, the sycophancy training text sheet, and a Cybernetics card with a passage generated by hand](../../assets/images/acdict-workshop-01.avif) --- # LLMs Unplugged now speaks Mandarin Chinese > The interactive widgets and the booklet generator now segment Mandarin Chinese into words, not just characters. Thanks to Zhang Xilian for the nudge. Recently Zhang Xilian, a master's student at The Education University of Hong Kong, wrote to say he was planning to run LLMs Unplugged workshops in China, and that the [Training](https://www.llmsunplugged.org/modules/training/) and [Generation](https://www.llmsunplugged.org/modules/generation/) widgets didn't understand Mandarin Chinese. Neither did the booklet generator. He was right: paste a line of Chinese into any of them and nothing happened. The reason was buried in the tokeniser. To turn text into a model you first cut it into tokens, and our tokeniser only recognised the letters `a` to `z`. Everything else was treated as a gap between words and thrown away: digits, stray symbols, and, as it turns out, every Chinese character. Feed it a whole poem and you got an empty model, with nothing to count and nothing to generate from. Fixing that meant deciding what a Chinese token is, and Chinese makes you choose. English hides its word boundaries in the spaces. Chinese runs the characters together, with no space to split on. The simplest answer is one token per character. 莲 follows 采, 叶 follows 莲, and the dice don't care that the tokens are Chinese. Each character becomes a cell in the frequency grid, a cutout card, or a face you can roll for. Xilian pointed out what that misses. A Chinese word is often two or three characters, like 深圳 (Shenzhen) or 金融 (finance). Cutting on every character is a little like splitting English into its letters. So the tools now segment into words by default, using [jieba](https://github.com/fxsjy/jieba), the standard open-source Chinese tokeniser he recommended.[^ambiguity] Give it 深圳最高的楼是平安金融中心 and it comes back as 深圳 / 最高 / 的 / 楼 / 是 / 平安 / 金融中心, not a run of loose characters. [^ambiguity]: The boundaries are not always clean. 最高的 ("tallest") could be one word, or 最高 plus 的, and jieba has to pick one. That there is a choice at all is worth a few minutes in a classroom. Both views are one switch apart. The widgets show a words/characters toggle whenever there is Chinese on the page, and the command-line tool takes `--cjk word` or `--cjk char`. Characters are the rule you can explain on a whiteboard; words are closer to how the language reads. Here's a bigram model trained on _Jiangnan_, a two-thousand-year-old Han-dynasty folk poem about picking lotus. Press play to watch it count the words, and use the toggle to drop back to single characters: Chinese punctuation gets the same treatment. The full-width comma , and full stop 。 are kept as their own tokens, boxed in the model just like the English `.` and `,`. A generated line breaks where a real sentence would. The same segmentation flows through to print. Here's the [_Jiangnan_ bigram booklet](https://pdf.llmsunplugged.org/booklets/jiangnan.pdf) as a ready-to-print PDF, every dice-lookup entry set in Noto Serif CJK rather than the Latin body font. The entries are ordered by pinyin, the way a Chinese dictionary sorts them. 电脑 (diannao) files before 手机 (shouji), so a word stays findable once a booklet runs long. The [tools page](https://www.llmsunplugged.org/tools/) will generate one from any text you paste in, Mandarin or otherwise. The bundled fonts cover the simplified characters used across mainland China. The widgets, the booklet generator, the cutouts, and the in-browser PDF export all handle Chinese now. If you are teaching in another language and something doesn't work, tell us. The tokeniser is where most of these limits live, and they are usually a small change once we know they are there. Thanks again to Xilian: for the nudge, for the reading list of Chinese classroom texts to test on, and for walking me through word segmentation and pinyin ordering. If you run a workshop with any of this, I'd love to hear how it goes. --- # The whole room holds the model > Search sheets are the cutouts activity with the cutting taken out, sized for a room rather than a table. Four ready-to-print sets are on the tools page. The [search sheets](https://www.llmsunplugged.org/tools/#search-sheets) are the cutouts activity with the cutting taken out, and they scale to a room. The CLI shuffles a corpus and deals it round-robin into one page per participant, so no two sheets are the same. You call out the last token written on the board, everyone scans their own sheet for it, and hands go up wherever there's a match. Pick one of those hands at random and you have your next token. Every token pair in the text was dealt to exactly one person, and the deal spreads each context across as many people as it will go. A continuation that happens six times puts six hands in the air; a rare one puts up two. The show of hands is the probability distribution, without anybody counting anything. Pick at random, though. Take whoever shouts first and you're sampling the fastest reader instead of the text. Nobody holds the whole model. No single sheet can continue the text on its own; the model only exists across the whole room, and if somebody is away, some contexts draw no hands at all. Four sets are ready to print: [Green Eggs and Ham](https://pdf.llmsunplugged.org/sheets/green-eggs-and-ham.pdf) at 15 sheets, [Peter Rabbit](https://pdf.llmsunplugged.org/sheets/peter-rabbit.pdf) at 17, [The Cat in the Hat](https://pdf.llmsunplugged.org/sheets/the-cat-in-the-hat.pdf) at 36 ([A5 sheets two-up on A4](https://pdf.llmsunplugged.org/sheets/the-cat-in-the-hat-2up-a4.pdf)), and [Australia](https://pdf.llmsunplugged.org/sheets/australia.pdf) at 79. Print them single-sided and hand out one each. The first page is the briefing for whoever is running it, and every page after that is a different participant's sheet. Every sheet carries the same number of token pairs, so the length of the text decides how many sheets there are, and a set only suits a group of about that size. The [tools page](https://www.llmsunplugged.org/tools/#generate-your-own) will build a set from any text you paste in. Building these turned up a problem with the [generated colour palette](https://www.llmsunplugged.org/news/2026-05-24-generating-the-cutout-palette/). Sheets set their token pairs at 16pt rather than the cutouts' 36pt, and at that size, colours the metric called comfortably distinct kept reading as the same colour. Max-min OKLab ΔE counts a lightness step the same as a hue step; a scanning eye doesn't. On a small glyph, a lightness step just reads as that colour again, darker. Fixing it meant asking a different question. A free search for maximally distinct colours gets named afterwards, by hand, which is how the palette ended up needing words like _ochre_ and _wine_ --- chosen because they were the nearest available, not because a room would reach for them. But the name is the whole point: "who has _cat_? it's a green one" only works if the room agrees on which swatch _green_ means. So the words come first now. Every swatch is pinned to a colour word's centroid in the xkcd colour survey --- a couple of hundred thousand people naming colours free-form, which is the best evidence there is for what a colour word means --- and the search picks the words whose printable colours sit furthest apart. That lands on eight: black, grey, red, brown, green, blue, purple, magenta. Six print at their survey centroid exactly; only grey and green move, and only far enough to stay legible on paper.[^numbers] The cutouts use the same eight now. Thirty colours at 36pt was more than anyone can hold at once, and a colour nobody can name is a filter nobody can call out. Eight is close to the ceiling, too. The obvious ninth is orange, and a printable orange sits ΔE 0.074--0.101 from red once it has been through a CMYK profile --- you can have orange or red, not both. Green and turquoise collide the same way, as do magenta and pink. The key prints on the brief, on both the sheets and the cutouts. Call "who has _cat_? it's a green one" from the front and the room narrows its search before anyone reads a token. [^numbers]: Grey moves ΔE 0.037 from its survey centroid and green 0.050, far enough to clear 3.5:1 contrast against white. That one number governs both ways a swatch gets used, contrast being symmetric: a token set as coloured text on the page, and white text on a colour-filled box. The eight sit 0.151 apart at worst on screen and 0.102 once round-tripped through a CMYK profile. The second figure is the one that matters and it can't be derived from the first --- sRGB's vivid blues, greens and purples fall outside CMYK, so the press compresses them toward the gamut boundary and the gaps shrink. Measured against FOGRA47L uncoated, FOGRA39L coated and SNAP newsprint.