Built GPT-2 on Custom Deep Learning Framework I built from scratch in C++ Developer Akshay Muchaklavya built Forge, a custom deep learning framework written from scratch in C++, and used it to implement GPT-2 that matches Hugging Face's transformers token-for-token under greedy decoding. The framework includes core primitives like Linear, LayerNorm, SelfAttention, optimizers, and AVX2 kernels, and supports loading real pretrained weights via safetensors. Forge is available on GitHub and requires CMake 3.20+, a C++20 compiler, OpenBLAS, and a CPU with AVX2 support. Overview overview Installation installation Tensor tensor-documentation Linear Layer linear-layer-documentation Activations activations Loss functions loss-functions-documentation Optimizers optimizers-documentation LayerNorm layernorm Self-Attention self-attention Embeddings embeddings Tokenizer tokenizer Parameters extraction & Model Load/Save safetensors reflection-based-parameters--model-loadsave-safetensors Forge implements core deep learning abstractions and primitives, enabling you to build, train, and optimize neural network models efficiently. The framework is designed for simplicity, making it suitable for learning use cases. Most people learn deep learning by calling model.fit and trusting PyTorch got the internals right. I wanted to know why it's right - how a tensor actually sits in memory, why GEMM dominates a forward pass, why attention needs a causal mask and what breaks silently if you get a transpose wrong. So Forge is a deep learning framework built from scratch. Every primitive here - Linear, LayerNorm, SelfAttention, Optimizers, and some of the the AVX2 kernels underneath - exists because I wrote it myself and verified it against a real reference. The proof: Forge's GPT-2, loaded with real pretrained weights, matches Hugging Face's transformers token-for-token under greedy decoding. Not close - exact. That's what convinces me this actually taught me how modern AI works, not just how to produce something that looks like it does. - CMake 3.20+ - A C++20 compiler - Windows: MinGW-w64 tested with the toolchain bundled in CLion - Linux: GCC or Clang - OpenBLAS - A CPU with AVX2 support any x86-64 CPU from roughly the last 10 years Eigen, reflect-cpp and ctti are fetched automatically via CMake's FetchContent - no manual setup needed for either. - Install OpenBLAS. If you don't already have it, grab a prebuilt release from the OpenBLAS releases page https://github.com/OpenMathLib/OpenBLAS/releases and extract it somewhere, e.g. C:/Libs/OpenBLAS . - Clone the repo: git clone https://github.com/muchlakshay/Forge cd Forge - Configure and build: cmake -B build -G "MinGW Makefiles" -DCMAKE BUILD TYPE=Release -DOPENBLAS ROOT="C:/Libs/OpenBLAS" cmake --build build If OpenBLAS is somewhere other than C:/Libs/OpenBLAS , point -DOPENBLAS ROOT at wherever you extracted it. Forge builds as a static library at build/libForge.a , with headers under core/ and primitives/ in the repo itself. - Install OpenBLAS and a compiler toolchain: sudo apt install build-essential cmake libopenblas-dev - Clone the repo: git clone https://github.com/muchlakshay/Forge cd Forge - Configure and build: cmake -B build -DCMAKE BUILD TYPE=Release cmake --build build OPENBLAS ROOT defaults to /usr , which matches where apt installs it - no extra flag needed unless you built OpenBLAS from source somewhere custom. Forge builds as a static library at build/libForge.a . Forge includes gpt2 and mnist test executables that demonstrate the framework in action. They're off by default so a plain build only produces the library. To build them too: cmake -B build -DFORGE BUILD TESTS=ON -DCMAKE BUILD TYPE=Release cmake --build build This adds gpt2 / mnist Linux or gpt2.exe / mnist.exe Windows to build/ . Prebuilt version of these for windows are also available on the Releases page https://github.com/muchlakshay/Forge/releases/tag/0.1 if you'd rather skip building them yourself. Since Forge links OpenBLAS as a shared library rather than statically, any executable you link against Forge needs the OpenBLAS runtime library available at runtime, not just at link time: Windows: copy libopenblas.dll found under OPENBLAS ROOT/bin into the same folder as your built executable. Without it, the executable will fail to launch with a missing-DLL error. Linux: either install OpenBLAS system-wide sudo apt install libopenblas0 , or ensure libopenblas.so / libopenblas.so.0 is somewhere on your LD LIBRARY PATH . The tests/CMakeLists.txt in this repo already handles this automatically for the gpt2 / mnist executables via a post-build copy step on Windows - if you're linking your own executable against Forge outside that setup, you'll need to do this step yourself. | Platform | Arch | Tested OS Version | Most Thoroughly Tested | |---|---|---|---| | Windows | x64 | Windows 11 Pro version 25H2 | yes | | Linux | x64 | Ubuntu 26.04 via WSL2 | yes | Currently, Forge uses Eigen as its underlying math library for tensor operations. However, Eigen's abstraction and lazy evaluation expression templates introduce significant performance bottlenecks , especially during backpropagation. Performance Optimization Plan: - Replace Eigen with OpenBLAS for optimized linear algebra operations - Implement custom vectorized element-wise kernels for backward pass computations - These optimizations will dramatically improve training speed and throughput Multi-dimensional tensors supporting up to 4 dimensions for handling batch data, spatial dimensions, and feature channels- Optimized for deep learning use cases not a general-purpose tensor library - Core abstraction layer for all neural network computations CPU radix tree-based memory allocator for efficient memory allocation and deallocation- Optimized for the allocation patterns typical in deep learning workflows Linear Layer : Fully connected layer with learnable weights and biases Layer Normalization : Normalization across features Embedding Layer : Token/index embedding lookups Sinusoidal Encoding : Positional encodings for sequence models Multi-Head Self Attention : Core component for transformer-based architectures- BPE Tokenizer - ReLU - GELU - Sigmoid - Tanh - Softmax - Cross-Entropy Loss, with fused softmax for multi-class classification - Binary Cross-Entropy Loss, with fused softmax - Mean Squared Error MSE SGD : Standard stochastic gradient descent SGD with Momentum : Accelerated gradient-based optimization Adam : Adaptive learning rate optimizer AdamW : Adam with weight decay regularization CPU Backend with Eigen-based math, performance optimizations in progress CUDA Backend GPU acceleration for NVIDIA devices Optimized kernels OpenBLAS + custom vectorized kernels Forge is ideal for: - Learning deep learning systems implementation from first principles - Experimenting with neural network architectures The Tensor class is the core abstraction in Forge for multi-dimensional data. It encapsulates: Data storage via CPU memory allocator radix tree-based Shape and stride information for multi-dimensional indexing Automatic differentiation support for backpropagation Data type dtype and device information class Tensor { Device m device; // CPU or GPU Dtype m dtype; // float32, float64, int32, int16, etc. std::shared ptr