nanoeuler es un proyecto educativo e investigador que implementa un modelo de lenguaje tipo GPT-2 desde cero, sin recurrir a PyTorch, autograd ni librerías de aprendizaje automático. Todo el pipeline de entrenamiento —el forward, el backward, un tokenizador byte-level BPE escrito a mano, el preentrenamiento y el ajuste fino supervisado— vive en un único repositorio. El nombre es un guiño a Leonhard Euler: la conexión residual x = x + f(x) se interpreta como un paso del método de Euler hacia adelante para resolver la ecuación diferencial dx/dt = f(x), lo que convierte a una red residual profunda en la discretización de una ODE continua.
El proyecto ofrece dos configuraciones. La pequeña (~1 millón de parámetros) se entrena en CPU con libm y OpenMP en pocas horas sobre 12 núcleos y sirve como muestra. La grande (~116 millones de parámetros) corre en una GPU RTX 4070 mediante una versión CUDA completa, con multiplicaciones matriciales en cuBLAS y un kernel de FlashAttention escrito a mano, con softmax online y sin materializar la matriz T×T en memoria, lo que acelera el paso de entrenamiento unas 3 veces. Cada gradiente analítico se valida mediante diferencias finitas centrales en doble precisión, y existe además una comprobación de gradientes GPU contra la referencia CPU con tolerancia de 1e-6.
Arquitectónicamente, el modelo es un transformer decoder-only con RMSNorm pre-norm sin bias, rotary position embeddings (RoPE), SwiGLU, atención agrupada por consultas (GQA) y predicción multitoken (MTP). El vocabulario BPE tiene 4096 tokens, con unos 3,4 bytes por token en inglés. El chat se obtiene en dos fases: primero se preentrena la base sobre una mezcla de libros y web, y luego se ajusta con el dataset Alpaca, enmascarando la pérdida para que solo se calcule sobre los tokens de la respuesta.
Los autores son claros sobre sus limitaciones: con 116 millones de parámetros y una sola GPU, el resultado es un generador de texto con forma fluida pero conocimiento superficial, no un asistente útil. El objetivo declarado es pedagógico: poseer cada pieza del pipeline, desde los parámetros y los gradientes hasta los kernels, para que el entrenamiento completo sea comprensible y reproducible.
