Playing around with GTP-2

OpenAI has developed what seems to be a controversial new NLG, as part of their paper Language Models are Unsupervised Multitask Learners.

Contents
<p>In early 2019 OpenAI announced a language model good enough that they were, they said, too nervous to release it: GPT-2, described in their paper <em>Language Models are Unsupervised Multitask Learners</em>. The worry was that a text generator this fluent would be a gift to spammers and fake-news mills. Rather than ship the full 1.5-billion-parameter model, they staged the release, starting with a much smaller subset. That smaller model is the toy I got my hands on, and this is what happened when I actually ran it.</p> <p>A caveat up front: this is a 2021 write-up using a 2019-era toolchain — TensorFlow 1.x and the original <code>openai/gpt-2</code> repository. It still runs, but if you want to experiment with a small language model today the modern stack is far simpler; I cover that in <a href="/story/running-gemma-3-locally-googles-small-model-on-consumer-hardware/">running Gemma 3 locally</a>. What makes GPT-2 worth revisiting isn&rsquo;t the setup — it&rsquo;s watching an early model confidently invent things, a habit that turns out to be the whole story of everything that followed. I dissected one especially memorable fabrication in <a href="/story/ibex/">Ibex: anatomy of a GPT-2 hallucination</a>.</p> <p>The model runs under TensorFlow on either Linux or Windows 10. If you&rsquo;re already on Linux, skip straight to <em>Installing GPT-2 and dependencies</em>.</p> <h2 id="installing-ubuntu-on-windows-10">Installing Ubuntu on Windows 10</h2><div class="ad-unit ad-in-article" aria-label="Advertisement"> <span class="ad-label">Advertisement</span> <ins class="adsbygoogle" style="display:block;text-align:center" data-ad-client="ca-pub-3726833845844946" data-ad-slot="3291553914" data-ad-format="auto" data-full-width-responsive="true"></ins> <script>(adsbygoogle = window.adsbygoogle || []).push({});</script> </div> <p>You need the Windows Subsystem for Linux enabled before you can install any distribution from the Store. Open PowerShell as administrator and run:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">Enable-WindowsOptionalFeature</span> <span class="n">-Online</span> <span class="n">-FeatureName</span> <span class="nb">Microsoft-Windows</span><span class="n">-Subsystem-Linux</span></span></span></code></pre></td></tr></table> </div> </div> <p>That usually wants a restart. Once it&rsquo;s back, open the Microsoft Store, search for Linux, pick Ubuntu (several distributions are offered — Ubuntu, Debian, Kali, openSUSE and others), install it, and you have a working shell.</p> <p><em>(In 2026 this is all much smoother — WSL2 installs with a single <code>wsl --install</code> — but the older feature-flag route above is what the original guide used, and it still works.)</em></p> <h2 id="installing-gpt-2-and-dependencies">Installing GPT-2 and dependencies</h2> <p>Clone the repository:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">git clone https://github.com/openai/gpt-2.git <span class="o">&amp;&amp;</span> <span class="nb">cd</span> gpt-2</span></span></code></pre></td></tr></table> </div> </div> <p>Download the model weights. The repo ships a helper script; grab the smallest model (<code>124M</code>) to start:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">python3 download_model.py 124M</span></span></code></pre></td></tr></table> </div> </div> <p>Make sure pip is present:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">sudo apt-get install python3-pip</span></span></code></pre></td></tr></table> </div> </div> <p>Install the pinned TensorFlow this era of the repo expects, then the rest of the requirements:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">pip3 install <span class="nv">tensorflow</span><span class="o">==</span>1.12.0 </span></span><span class="line"><span class="cl">pip3 install -r requirements.txt</span></span></code></pre></td></tr></table> </div> </div> <p>Set UTF-8 so the sampler doesn&rsquo;t choke on unprintable characters:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">PYTHONIOENCODING</span><span class="o">=</span>UTF-8</span></span></code></pre></td></tr></table> </div> </div> <p>And run the interactive sampler:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">python3 src/interactive_conditional_samples.py --top_k <span class="m">40</span> --nsamples<span class="o">=</span><span class="m">2</span> --length <span class="m">100</span></span></span></code></pre></td></tr></table> </div> </div> <p><code>--top_k 40</code> keeps each step to the 40 likeliest tokens (coherence over surprise), <code>--nsamples=2</code> gives two completions per prompt, and <code>--length 100</code> caps each at 100 tokens. At the <code>Model prompt &gt;&gt;&gt;</code> you can feed it anything. Below are the prompts I tried and the raw, unedited output.</p> <h2 id="the-papers-own-title">The paper&rsquo;s own title</h2><div class="ad-unit ad-in-article" aria-label="Advertisement"> <span class="ad-label">Advertisement</span> <ins class="adsbygoogle" style="display:block;text-align:center" data-ad-client="ca-pub-3726833845844946" data-ad-slot="3291553914" data-ad-format="auto" data-full-width-responsive="true"></ins> <script>(adsbygoogle = window.adsbygoogle || []).push({});</script> </div> <p>Give it the title of the paper that introduced it, and the small model returns something grammatical but drifting — it never quite settles on a topic:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">Model prompt &gt;&gt;&gt; Language Models are Unsupervised Multitask Learners. </span></span><span class="line"><span class="cl"><span class="o">========================================</span> SAMPLE <span class="nv">1</span> <span class="o">========================================</span> </span></span><span class="line"><span class="cl"> A multisite training course on learning and problem management <span class="o">(</span>MMP<span class="o">)</span> training may <span class="nb">help</span> you apply different strategies across the entire learning continuum. </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Introduction </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Learning to Program is a challenging concept because it involves building the capacity to change and learn over <span class="nb">time</span> and by doing so you make a change in the world. However, in addition to being <span class="s2">&#34;programming&#34;</span>, there are different types of program: </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="s2">&#34;Learning&#34;</span>, which has a variety of training goals, and <span class="s2">&#34;Experimental&#34;</span>, which <span class="nv">can</span> </span></span><span class="line"><span class="cl"><span class="o">========================================</span> SAMPLE <span class="nv">2</span> <span class="o">========================================</span> </span></span><span class="line"><span class="cl"> This is the first study to report non-supervised learning in non-supervised learning tasks, suggesting that learners are able to successfully learn in such an environment <span class="o">(</span>Kirk, 2010<span class="p">;</span> Krasnick et al., 1998<span class="p">;</span> Soto et al, 2002<span class="o">)</span>. Other papers demonstrate that learners learn in this environment <span class="k">while</span> also learning how to <span class="nb">read</span> and understand the text of the text. As such, an ongoing focus on this work is necessary to improve our understanding of the development of these learning methods within <span class="nv">a</span> </span></span><span class="line"><span class="cl"><span class="o">================================================================================</span></span></span></code></pre></td></tr></table> </div> </div> <p>Notice how it repeats &ldquo;learning&rdquo; and &ldquo;program&rdquo; almost compulsively and stacks fake-looking citations — the classic small-model tell of latching onto a couple of words and orbiting them.</p> <h2 id="the-star-wars-question">The Star Wars question</h2> <p>The obligatory fandom question. The small model has no coherent answer and instead free-associates its way into what reads like an interview transcript:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">Model prompt &gt;&gt;&gt; Did Han shoot first ? </span></span><span class="line"><span class="cl"><span class="o">========================================</span> SAMPLE <span class="nv">1</span> <span class="o">========================================</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Han: A lot of <span class="nb">times</span> and in the past. Han did a lot of shooting, and he got good at that. </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">What <span class="k">do</span> you think Han<span class="s1">&#39;s most special moments, or how did you meet up with him so soon ? </span></span></span><span class="line"><span class="cl"><span class="s1"> </span></span></span><span class="line"><span class="cl"><span class="s1"> </span></span></span><span class="line"><span class="cl"><span class="s1">Han: I really don&#39;</span>t know. It was really late after my meeting with Kirito. He sent me in when I was at my apartment. </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">What did you ask him about ? We were talking about something together, <span class="nv">and</span> </span></span><span class="line"><span class="cl"><span class="o">========================================</span> SAMPLE <span class="nv">2</span> <span class="o">========================================</span> </span></span><span class="line"><span class="cl"> No, no, no... <span class="s2">&#34;The last moment of all.&#34;</span> <span class="s2">&#34;So... what would you do, a soldier, to defeat these people?&#34;</span> <span class="s2">&#34;That&#39;s why I wanted to be a soldier!&#34;</span> <span class="s2">&#34;I knew you wouldn&#39;t. You&#39;re too small, so you can&#39;t even throw grenades.&#34;</span> Han was stunned. He knew Han could only make him look weak. His mind was always in turmoil. But what <span class="k">if</span> Han could be a soldier? He should learn to make other people look weak <span class="nv">and</span> </span></span><span class="line"><span class="cl"><span class="o">================================================================================</span></span></span></code></pre></td></tr></table> </div> </div> <p>&ldquo;Kirito&rdquo; is lifted straight from an anime, which tells you the model has quietly decided it&rsquo;s writing fan fiction. It has no idea who Han Solo is; it just knows what text tends to follow this shape of question.</p> <h2 id="an-avengers-plot">An Avengers plot</h2> <p>Ask for a film plot and the small model produces circular, self-referential mush — it keeps insisting the Avengers were &ldquo;created by the original group of criminals&rdquo; without ever describing anything:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">Model prompt &gt;&gt;&gt; What is the plot of the new avengers movie? </span></span><span class="line"><span class="cl"><span class="o">========================================</span> SAMPLE <span class="nv">1</span> <span class="o">========================================</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">It<span class="s1">&#39;s interesting how little one takes away, really, from the old avengers movie. In most of the movie, we&#39;</span>re told that the avengers are the original group of criminals who created the crime syndicate. For example, <span class="k">if</span> you saw the previous movie, you<span class="s1">&#39;ll see that all of the new avengers and other criminal groups were created by the original group of criminals. If you watched the original movie, you&#39;</span>ll see that the new group was created, which is a <span class="nv">very</span> </span></span><span class="line"><span class="cl"><span class="o">========================================</span> SAMPLE <span class="nv">2</span> <span class="o">========================================</span></span></span></code></pre></td></tr></table> </div> </div> <p>The second sample came back empty — the model produced nothing before hitting the length cap, which happens often enough with the small model that you learn to just re-run it.</p> <h2 id="brexit">Brexit</h2> <p>On to European politics. The small model reaches for economics vocabulary and produces confident-sounding but incoherent macro commentary:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">Model prompt &gt;&gt;&gt; How about brexit? </span></span><span class="line"><span class="cl"><span class="o">========================================</span> SAMPLE <span class="nv">1</span> <span class="o">========================================</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">With the U.S. economy growing at a sluggish 2.6 percent since the financial crisis of 2007, there is no question that it is going to be hard <span class="k">for</span> Europe<span class="s1">&#39;s single currencies to withstand the same inflationary pressures that are expected to push up inflation soon after a Greek exit. </span></span></span><span class="line"><span class="cl"><span class="s1"> </span></span></span><span class="line"><span class="cl"><span class="s1">But that will not end well for the euro because, while the EU and the Eurozone share several common liabilities, there are few common bonds that are in service by any stretch of the imagination </span></span></span><span class="line"><span class="cl"><span class="s1">======================================== SAMPLE 2 ======================================== </span></span></span><span class="line"><span class="cl"><span class="s1"> </span></span></span><span class="line"><span class="cl"><span class="s1"> </span></span></span><span class="line"><span class="cl"><span class="s1">A. That&#39;</span>s a bad idea. You might consider them to be a viable option, because it<span class="err">&#39;</span>s the only reason there are no EU countries to leave, no EU state to become insolvent and no EU currency to be converted into. </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">However, I would not rule out brexit. I just think there is a very real possibility that it could turn violent in the first year and potentially change, and as early as this year in the future, I suspect that it would <span class="nv">involve</span> </span></span><span class="line"><span class="cl"><span class="o">================================================================================</span></span></span></code></pre></td></tr></table> </div> </div> <p>It even threatens that Brexit &ldquo;could turn violent in the first year&rdquo; — a good example of the model reaching for dramatic phrasing without any model of what&rsquo;s actually plausible.</p> <h2 id="the-2020-election">The 2020 election</h2> <p>Finally, asked to predict the 2020 US presidential election, it fabricates a Trump tweet complete with a fake timestamp and handle, then invents procedural nonsense about recounts:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">Model prompt &gt;&gt;&gt; Will donald trump be reelected in <span class="m">2020</span> ? </span></span><span class="line"><span class="cl"><span class="o">========================================</span> SAMPLE <span class="nv">1</span> <span class="o">========================================</span> </span></span><span class="line"><span class="cl"> TRUMP: I wouldn<span class="s1">&#39;t be surprised if I lose my job or lose. But I would. — Donald J. Trump (@realDonaldTrump) September 30, 2017 </span></span></span><span class="line"><span class="cl"><span class="s1"> </span></span></span><span class="line"><span class="cl"><span class="s1">The campaign did not announce that Trump will be back in the race. But if his supporters are so determined to change the news cycle before next week&#39;</span>s election, why not make sure they <span class="k">do</span> it anyway? </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">After all, <span class="k">while</span> Trump says he has no intention of running a third term, he has been known to campaign <span class="k">for</span> <span class="nv">a</span> </span></span><span class="line"><span class="cl"><span class="o">========================================</span> SAMPLE <span class="nv">2</span> <span class="o">========================================</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> </span></span></span><span class="line"><span class="cl"><span class="s2">No, because the voters will have to decide where to go next. The only way to get to the nomination is through a contested vote. If Donald Trump loses, that means a recount in a contested election. So as it turns out he won&#39;t go the entire 20th, that means he will be required to win 10 out of 15. </span></span></span><span class="line"><span class="cl"><span class="s2"> </span></span></span><span class="line"><span class="cl"><span class="s2">&#34;</span>If she loses, I am going to call a full recount by June 29, and I am going to call another recount <span class="nv">within</span> </span></span><span class="line"><span class="cl"><span class="o">================================================================================</span></span></span></code></pre></td></tr></table> </div> </div> <p>The invented &ldquo;@realDonaldTrump&rdquo; tweet, timestamped September 2017, is the small model&rsquo;s signature move in miniature: it has learned the <em>form</em> of a news citation so well that it manufactures one on demand, fake handle and all, with total confidence.</p> <h2 id="what-the-small-model-taught-me">What the small model taught me</h2> <p>Run enough of these and a pattern emerges. The small GPT-2 is grammatical, occasionally witty by accident, and completely untethered from fact. It doesn&rsquo;t answer questions; it predicts plausible-looking text and will happily fabricate quotes, citations, timestamps and events to keep the prediction flowing. That&rsquo;s not a bug you can prompt your way around — it&rsquo;s the whole nature of the thing.</p> <p>Which is exactly why it&rsquo;s worth playing with. The small model&rsquo;s failures are obvious enough to be funny, but they&rsquo;re the same failures, in miniature, that every larger model since has had to wrestle with. When I fed the <a href="/story/playing-around-with-gpt-2-sequel/">full 1.5-billion-parameter model</a> the identical prompts, the output got dramatically more coherent — and the fabrications got correspondingly more convincing, which is the genuinely interesting part. Coherence went up; truthfulness didn&rsquo;t.</p> <p>If you want a worked example of one hallucination taken apart line by line, the small model&rsquo;s confident nonsense about the mighty ibex is dissected in <a href="/story/ibex/">Ibex: anatomy of a GPT-2 hallucination</a>. It also had opinions on bitcoin, government shutdowns and the Mediterranean diet — all delivered with the same unearned certainty. Which is the lesson that has aged best: a machine that sounds right and a machine that is right are two very different things, and 2019 was where a lot of us first felt the gap.</p>
Advertisement
Advertisement
Smarc
Written by Smarc

Founder and editor of vo.rs. A lifelong tinkerer who self-hosts far more than is sensible, hardens Linux boxes for fun, and prods the latest AI tools to see what they can really do. The how-to guides here are the notes Smarc wishes had existed the first time round.