A little experiment in evading AI detection
Notes from trying to make an AI-drafted series sound human.
Writing by Nick Gustafson — software engineer and data scientist. Notes on machine learning, the systems behind it, and the things worth understanding deeply.
Notes from trying to make an AI-drafted series sound human.
A D-A-D song leads us to latent space thinking.
Vectors as lists of activations, matrix multiplication as a linear map, and why every neural network operation bottoms out in matmuls.
How cosine similarity, L2 distance, and projections work, and why they show up everywhere from attention scores to embedding retrieval.
Softmax, categorical distributions, Bayes' rule, and the chain rule of probability — the four tools that make language modeling a well-defined math problem.
Why cross-entropy is the standard LM loss, what it actually measures about two distributions, and how it connects to perplexity.
What a gradient is, why it points uphill, how backpropagation computes one efficiently via the chain rule, and what SGD does with it.
Why vanilla SGD is too slow, how Adam adapts per-parameter, and how warmup and cosine decay shape training dynamics.
IEEE 754, the difference between fp32/fp16/bfloat16, why mixed-precision training works, and the basics of GPU parallelism.
The arc from rule-based systems through statistical MT and log-linear models to neural approaches, giving you historical context for everything that follows.
Why 'predict the next word' is a surprisingly powerful training objective, and how it connects to the chain rule of probability.
Counting-based language models, Markov assumptions, smoothing techniques, and why sparsity made n-grams hit a hard ceiling.
How skip-gram and CBOW learn dense word vectors, why 'king - man + woman = queen' works, and what distributional semantics actually means.
How GloVe combines count-based and predictive methods, how FastText handles subwords, and the trade-offs across embedding approaches.
The RNN equations, how hidden states carry information forward, why vanilla RNNs suffer from vanishing gradients, and what that means in practice.
How gates solve the vanishing gradient problem, the difference between LSTM and GRU cells, and why gated architectures dominated NLP for five years.
Encoder-decoder architectures, how additive attention let models align source and target tokens, and why sequential processing fundamentally bottlenecked scale.
UTF-8 encoding, code points vs. grapheme clusters, and why 'one character' is a surprisingly ambiguous concept for a model.
The BPE merge algorithm step by step, implemented from scratch, showing how a raw byte stream becomes a vocabulary.
How WordPiece (BERT) and Unigram (T5) differ from BPE, why SentencePiece operates on raw text, and when each approach wins.
How vocabulary size affects model capacity and sequence length, what token fertility measures, and the practical trade-offs behind 32k vs. 128k vs. 200k vocabularies.
How token IDs become vectors via a lookup table, why the embedding matrix is a learned linear map, and how embedding and unembedding layers relate.
BOS/EOS/PAD tokens, how chat-template formatting encodes multi-turn structure, system prompts, and tool-call schemas into a flat token stream.
Sequence packing for training efficiency, how attention masks prevent cross-contamination, and why tokenizer choices constrain everything downstream.
Queries, keys, and values as learned linear projections, how scaled dot-product computes soft token-to-token lookups, and exactly why we divide by sqrt(d_k).
Why multiple attention heads let the model attend to different relationship types in parallel, how heads partition the embedding dimension, and what the output projection does.
Why decoder models must not attend to future tokens, how the triangular mask enforces this, and how masking shapes both training and generation.
Why attention is position-agnostic by default, how each encoding scheme injects order, why RoPE became dominant, and how ALiBi achieves length extrapolation.
The two-layer MLP that follows attention, why it can be interpreted as a learned key-value store over concepts, and what the intermediate dimension controls.
Why normalization is essential for deep residual networks, how pre-norm stabilizes training, and why RMSNorm replaced LayerNorm in modern architectures.
The structural differences between GPT-style and T5-style models, why decoder-only won for generative LLMs, and where encoder-decoder still shines.
The original 2017 paper section by section, connecting each design choice to what you already know, and noting which ideas survived and which were replaced.
How MoE replaces the dense FFN with sparse expert routing, the load-balancing problem, and how expert-choice routing solves it.
Why the model you trained on full sequences behaves completely differently when it generates one token at a time, and what that means for everything that follows.
How the prompt is processed in parallel (prefill) but generation is strictly sequential (decode), and why this split dominates every performance conversation.
Walking through the exact matrix operations at each decode step to see why generation is memory-bound, not compute-bound.
Deriving the key-value cache by noticing which attention computations are redundant, then watching memory grow linearly with sequence length.
How each strategy reshapes the probability distribution over the vocabulary, when to combine them, and what 'good randomness' actually looks like.
Using a small draft model to guess multiple tokens at once and a large model to verify them in parallel, turning sequential generation into a bet on acceptance rates.
Why naive batching wastes GPU cycles on padding, and how iteration-level scheduling lets new requests join a running batch the moment a slot opens.
Sharing KV cache across requests that start with the same system prompt, and the cache-eviction policies that make it practical.
How grammar-guided decoding and JSON-mode work by masking logits at each step, and the tradeoff between constraint strength and generation speed.
The concrete responsibilities — graph optimization, memory allocation, scheduling, kernel dispatch — that sit between your model weights and an HTTP response.
Why fusing multiple operations into a single GPU kernel reduces memory round-trips, and how FlashAttention is the poster child for this idea.
Treating KV cache like virtual memory pages so you stop wasting 60-80% of GPU RAM on fragmentation.
A unified picture of where bytes go — weights, activations, KV cache, CUDA context — and how to reason about what fits on your GPU.
Shrinking weight precision to serve larger models on smaller hardware, with an honest look at what quality you lose and when.
Three ways to split a model across multiple GPUs, each with different latency and throughput profiles.
Why optimizing for tokens-per-second and optimizing for time-to-first-token are fundamentally in tension, and how batching policy mediates.
A framework for choosing an inference stack based on your actual constraints — hardware, model size, latency budget, and deployment environment.