<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dhruv</title>
    <description>The latest articles on DEV Community by Dhruv (@heywinterbell).</description>
    <link>https://dev.to/heywinterbell</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4185133%2F44bc951f-2486-4ba9-8183-081aedf71449.jpg</url>
      <title>DEV Community: Dhruv</title>
      <link>https://dev.to/heywinterbell</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/heywinterbell"/>
    <language>en</language>
    <item>
      <title>Building a Transformer from Scratch: Part 1 — The Embedding Layer</title>
      <dc:creator>Dhruv</dc:creator>
      <pubDate>Wed, 14 Oct 2026 16:45:46 +0000</pubDate>
      <link>https://dev.to/heywinterbell/building-a-transformer-from-scratch-part-1-the-embedding-layer-172g</link>
      <guid>https://dev.to/heywinterbell/building-a-transformer-from-scratch-part-1-the-embedding-layer-172g</guid>
      <description>&lt;p&gt;Before the attention mechanism computes a single dot product in an autoregressive Transformer like GPT, the model faces a fundamental problem: neural networks do not understand text, and feeding them raw token IDs introduces false mathematical assumptions.&lt;/p&gt;

&lt;p&gt;If the tokenizer maps &lt;code&gt;"cat"&lt;/code&gt; to index &lt;code&gt;200&lt;/code&gt; and &lt;code&gt;"dog"&lt;/code&gt; to &lt;code&gt;201&lt;/code&gt;, a linear layer treats &lt;code&gt;"dog"&lt;/code&gt; as having a higher numerical value than &lt;code&gt;"cat"&lt;/code&gt;. Token IDs are discrete categorical variables, not ordinal measurements.&lt;/p&gt;

&lt;p&gt;The embedding layer bridges this gap. It maps discrete integers into continuous vector spaces where semantic relationships and sequence ordering can actually be learned.&lt;/p&gt;

&lt;p&gt;Here is how the embedding layer works under the hood, along with a production-grade PyTorch implementation.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Two Problems Embeddings Must Solve
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Semantic Representation (Token Embeddings)
&lt;/h3&gt;

&lt;p&gt;A tokenizer splits raw text into tokens and assigns each one an integer ID. To eliminate arbitrary numerical ordering, we map each ID to a learned vector of dimension &lt;code&gt;d_model&lt;/code&gt; via a token lookup matrix &lt;code&gt;W_e&lt;/code&gt; of shape &lt;code&gt;(vocab_size, d_model)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Through backpropagation, tokens that appear in similar linguistic contexts gravitate toward each other in this high-dimensional vector space.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Sequence Order (Positional Embeddings)
&lt;/h3&gt;

&lt;p&gt;Unlike Recurrent Neural Networks (RNNs), which process tokens step-by-step from left to right, Transformers process the entire sequence in parallel. &lt;/p&gt;

&lt;p&gt;Because self-attention is permutation-equivariant, the model would process &lt;code&gt;"dog bites man"&lt;/code&gt; and &lt;code&gt;"man bites dog"&lt;/code&gt; identically without an explicit position signal. To fix this, we map each sequence position &lt;code&gt;0, 1, ..., seq_len - 1&lt;/code&gt; to a positional embedding vector of dimension &lt;code&gt;d_model&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  PyTorch Implementation
&lt;/h2&gt;

&lt;p&gt;This module combines token embeddings with learned absolute positional embeddings and dropout regularization, matching the architectural setup used in GPT-2.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
python
import torch
import torch.nn as nn

class TransformerEmbeddings(nn.Module):
    def __init__(self, vocab_size: int, d_model: int, max_seq_len: int, dropout: float = 0.1):
        super().__init__()
        self.d_model = d_model

        # Token lookup matrix: shape (vocab_size, d_model)
        self.token_embeddings = nn.Embedding(vocab_size, d_model)

        # Position lookup matrix: shape (max_seq_len, d_model)
        self.position_embeddings = nn.Embedding(max_seq_len, d_model)

        # Regularization: applies dropout across the summed embeddings
        self.dropout = nn.Dropout(p=dropout)

    def forward(self, input_ids: torch.Tensor) -&amp;gt; torch.Tensor:
        # Expected input shape: (batch_size, seq_len)
        batch_size, seq_len = input_ids.shape

        # Guard clause: prevent context window overflows
        if seq_len &amp;gt; self.position_embeddings.num_embeddings:
            raise ValueError(
                f"Sequence length ({seq_len}) exceeds maximum context window "
                f"({self.position_embeddings.num_embeddings})"
            )

        # Generate positional indices [0, 1, ..., seq_len - 1]
        # Shape: (1, seq_len), created directly on the input's target device
        positions = torch.arange(0, seq_len, device=input_ids.device).unsqueeze(0)

        # Retrieve vectors
        tok_emb = self.token_embeddings(input_ids)    # (batch_size, seq_len, d_model)
        pos_emb = self.position_embeddings(positions) # (1, seq_len, d_model)

        # Combine via broadcasting: (batch_size, seq_len, d_model)
        embeddings = tok_emb + pos_emb

        return self.dropout(embeddings)


# Sanity check execution block
if __name__ == "__main__":
    vocab_size, d_model, max_len = 50257, 768, 1024
    layer = TransformerEmbeddings(vocab_size, d_model, max_len, dropout=0.1)

    # Dummy batch of 2 sequences, each 8 tokens long
    dummy_input = torch.randint(0, vocab_size, (2, 8))
    output = layer(dummy_input)

    print(f"Input shape:   {dummy_input.shape}")  # torch.Size([2, 8])
    print(f"Output shape:  {output.shape}")       # torch.Size([2, 8, 768])
    assert output.shape == (2, 8, d_model), "Shape mismatch!"
    print("Embedding module ran successfully.")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>python</category>
      <category>pytorch</category>
      <category>machinelearning</category>
      <category>deeplearning</category>
    </item>
  </channel>
</rss>
