<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/building-gpt-from-scratch-what-i-learned-implementing-a-transformer-in-raw-pytorch-janzjl2vo" -->

---
title: Building GPT from Scratch: What I Learned Implementing a...
description: A hands-on walkthrough of building a GPT-style transformer from scratch in raw PyTorch, trained on the Tiny Shakespeare dataset. Starting from a simple bigram...
canonical: https://daily.dev/posts/building-gpt-from-scratch-what-i-learned-implementing-a-transformer-in-raw-pytorch-janzjl2vo
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Building GPT from Scratch: What I Learned Implementing a Transformer in Raw PyTorch | daily.dev
og:description: A hands-on walkthrough of building a GPT-style transformer from scratch in raw PyTorch, trained on the Tiny Shakespeare dataset. Starting from a simple bigram...
og:url: https://daily.dev/posts/building-gpt-from-scratch-what-i-learned-implementing-a-transformer-in-raw-pytorch-janzjl2vo
og:image: https://api.daily.dev/og/posts/jaNZjL2vO.png
og:image:alt: Building GPT from Scratch: What I Learned Implementing a Transformer in Raw PyTorch
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Building GPT from Scratch: What I Learned Implementing a Transformer in Raw PyTorch

**[Medium](https://daily.dev/sources/medium_js)** · 6 min read · 3 upvotes · 0 comments

## Summary

A hands-on walkthrough of building a GPT-style transformer from scratch in raw PyTorch, trained on the Tiny Shakespeare dataset. Starting from a simple bigram model to establish baselines, the author progressively implements self-attention (with causal masking), multi-head attention, and full transformer blocks with residual connections and layer normalization. The final model has ~10.8M parameters, a 256-token context window, and trains for 5,000 iterations, achieving a training loss of 1.08. Key takeaways include demystifying attention as a differentiable weighted lookup, understanding causal masking as the core of autoregressive generation, and observing that small-scale models reproduce large-scale training phenomena like overfitting.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://medium.com/@krudrax16/building-gpt-from-scratch-what-i-learned-implementing-a-transformer-in-raw-pytorch-5fc575d2d327>

## Questions this post answers

### How does causal masking work in a self-attention implementation for a GPT-style model?

Causal masking is applied by filling the attention weight matrix with negative infinity wherever a lower-triangular mask is zero, before the softmax, so each token can only attend to itself and earlier tokens. In code this is one line using masked_fill on a triangular matrix, applied after computing q @ k.transpose(-2,-1) scaled by the key dimension's inverse square root. This single mechanism is what makes generation autoregressive rather than just encoding a sequence.

_Developers building transformer internals from scratch can find similar deep-dives on daily.dev to sharpen their attention-mechanism intuition._

### What loss values should I expect training a small character-level GPT on Tiny Shakespeare?

Training loss fell from about 4.28, roughly equivalent to random guessing across 65 characters, down to 1.08 after 5,000 iterations of AdamW at a 3e-4 learning rate. Validation loss tracked down to about 1.48 before creeping back up in the final steps, a textbook sign of overfitting in an approximately 11 million parameter model trained without learning rate decay or early stopping.

_Anyone benchmarking their own small-scale transformer training run can compare notes with similar experiments curated on daily.dev._

### What architecture and hyperparameters make a minimal from-scratch GPT model work on Tiny Shakespeare?

A working minimal GPT used 6 Transformer layers, 6 attention heads, 384-dimensional embeddings, and a 256-token context window, totaling about 10.8 million parameters. It was trained character-level on the roughly 1.1 million character, 65-vocabulary Tiny Shakespeare dataset for 5,000 iterations using AdamW with a learning rate of 3e-4, with no subword tokenization involved.

_Engineers sizing their own toy transformer experiments can track practical configs like this through daily.dev._

## Similar posts on daily.dev

- [GitHub - angelos-p/llm-from-scratch](https://daily.dev/posts/github---angelos-p-llm-from-scratch-5sw4itutx) · Hacker News · 1 upvotes · 0 comments
- [Decoder-Only Transformers From Scratch: What Building ChessGPT Taught Me](https://daily.dev/posts/decoder-only-transformers-from-scratch-what-building-chessgpt-taught-me-hzjxavwxv) · Medium · 0 upvotes · 0 comments
- [microgpt](https://daily.dev/posts/microgpt-k69dx0r76) · Hacker News · 2 upvotes · 0 comments

---

Tags: [#python](https://daily.dev/tags/python), [#llm](https://daily.dev/tags/llm), [#pytorch](https://daily.dev/tags/pytorch)

[View this post on daily.dev](https://daily.dev/posts/building-gpt-from-scratch-what-i-learned-implementing-a-transformer-in-raw-pytorch-janzjl2vo)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Building GPT from Scratch: What I Learned Implementing a Transformer in Raw PyTorch","url":"https://daily.dev/posts/building-gpt-from-scratch-what-i-learned-implementing-a-transformer-in-raw-pytorch-janzjl2vo","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/building-gpt-from-scratch-what-i-learned-implementing-a-transformer-in-raw-pytorch-janzjl2vo"},"datePublished":"2026-07-22T18:38:27.308Z","dateModified":"2026-09-13T19:03:55.230Z","description":"A hands-on walkthrough of building a GPT-style transformer from scratch in raw PyTorch, trained on the Tiny Shakespeare dataset. Starting from a simple bigram...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/d6ab0a9a223ee01bc82d647f54feb2d2?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/d6ab0a9a223ee01bc82d647f54feb2d2?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Medium","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Medium","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/medium","url":"https://daily.dev/sources/medium_js"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/building-gpt-from-scratch-what-i-learned-implementing-a-transformer-in-raw-pytorch-janzjl2vo","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":3},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"python,llm,pytorch","timeRequired":"PT6M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Medium","item":"https://daily.dev/sources/medium_js"},{"@type":"ListItem","position":3,"name":"Building GPT from Scratch: What I Learned Implementing a Transformer in Raw PyTorch"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/building-gpt-from-scratch-what-i-learned-implementing-a-transformer-in-raw-pytorch-janzjl2vo#faq","mainEntity":[{"@type":"Question","name":"How does causal masking work in a self-attention implementation for a GPT-style model?","acceptedAnswer":{"@type":"Answer","text":"Causal masking is applied by filling the attention weight matrix with negative infinity wherever a lower-triangular mask is zero, before the softmax, so each token can only attend to itself and earlier tokens. In code this is one line using masked_fill on a triangular matrix, applied after computing q @ k.transpose(-2,-1) scaled by the key dimension's inverse square root. This single mechanism is what makes generation autoregressive rather than just encoding a sequence. Developers building transformer internals from scratch can find similar deep-dives on daily.dev to sharpen their attention-mechanism intuition."}},{"@type":"Question","name":"What loss values should I expect training a small character-level GPT on Tiny Shakespeare?","acceptedAnswer":{"@type":"Answer","text":"Training loss fell from about 4.28, roughly equivalent to random guessing across 65 characters, down to 1.08 after 5,000 iterations of AdamW at a 3e-4 learning rate. Validation loss tracked down to about 1.48 before creeping back up in the final steps, a textbook sign of overfitting in an approximately 11 million parameter model trained without learning rate decay or early stopping. Anyone benchmarking their own small-scale transformer training run can compare notes with similar experiments curated on daily.dev."}},{"@type":"Question","name":"What architecture and hyperparameters make a minimal from-scratch GPT model work on Tiny Shakespeare?","acceptedAnswer":{"@type":"Answer","text":"A working minimal GPT used 6 Transformer layers, 6 attention heads, 384-dimensional embeddings, and a 256-token context window, totaling about 10.8 million parameters. It was trained character-level on the roughly 1.1 million character, 65-vocabulary Tiny Shakespeare dataset for 5,000 iterations using AdamW with a learning rate of 3e-4, with no subword tokenization involved. Engineers sizing their own toy transformer experiments can track practical configs like this through daily.dev."}}]}
```

