Skip to main content
Clorch ships a full set of LLM-relevant architecture components that map directly onto modern transformer designs like Llama-3. All components are implemented as standard IModule values: they compose with nn/forward, participate in nn/parameters, transfer between devices with nn/to, and work within nn/defmodel blocks. This page describes each component and shows how they fit together in a complete model.

Token Embeddings

nn/embedding

Creates a learnable embedding table with num-embeddings rows and embedding-dim columns.
Options:

nn/embedding-from-pretrained

Initialize an embedding table from an existing tensor (e.g., GloVe or word2vec weights).

RMSNorm

nn/rmsnorm implements Root Mean Square Layer Normalization, which is preferred over LayerNorm in most modern LLMs (including Llama) because it omits the mean-centering step.
Internally, the forward pass:
  1. Casts input to float32 for numerical stability.
  2. Computes RMS: sqrt(mean(x^2) + eps).
  3. Normalizes: x / RMS.
  4. Scales by the learned weight gamma (initialized to ones).
  5. Casts result back to the input dtype.

Rotary Position Embeddings (RoPE)

RoPE encodes position information directly into query and key tensors by rotating them with sinusoidal frequencies, enabling the model to generalize to longer sequences than it was trained on.

torch/precompute-rope-freqs

Precomputes the cosine and sine embedding matrices for a given head dimension and sequence length. Returns a two-element vector [cos-emb sin-emb].

torch/apply-rope

Applies the precomputed rotation to query or key tensors. The input must have shape [B, T, n-heads, head-dim].
The rotation applies the standard formula: [x1, x2] → [x1*cos − x2*sin, x1*sin + x2*cos].

Grouped-Query Attention (GQA)

nn/GroupedQueryAttention implements multi-head attention where the number of key-value heads (n-kv-heads) can be less than the number of query heads (n-heads). When they are equal it degrades to standard multi-head attention; with n-kv-heads = 1 it becomes multi-query attention.

Forward Pass

The forward pass accepts either a tensor or a map with optional RoPE frequencies, causal mask, and KV cache:
The module handles K/V head repetition internally: if n-kv-heads < n-heads, it repeats the K and V tensors with torch/repeat-interleave to match the query head count.

SwiGLU Feed-Forward Block

nn/SwiGLU implements the gated linear unit feed-forward block used in Llama-style models. It applies a SiLU-gated projection that selectively amplifies features:
SwiGLU has three linear projections (w1, w2, w3) versus the two in a standard MLP. The hidden dimension is typically 4 × dim.

Fused Scaled Dot-Product Attention

F/scaled-dot-product-attention wraps LibTorch’s fused SDPA dispatcher. On CUDA, LibTorch automatically selects Flash Attention, memory-efficient attention, or the math kernel based on dtype, shape, mask presence, and hardware capability.
Query, key, and value tensors should have shape [B, n-heads, T, head-dim].
The release suite verifies fused SDPA as part of the CUDA path. Using this function on a CUDA device will engage Flash Attention automatically when the hardware and dtype support it.

Causal Attention Masks

Most autoregressive models require a causal mask that prevents each position from attending to future positions.
For KV-cache generation where only one new token is processed at a time, no mask is needed (the K/V cache tracks history implicitly).

Autoregressive Generation

nn/generate runs a greedy autoregressive generation loop without gradient tracking.
It samples the next token from the softmax of the last position’s logits using torch/multinomial. When the sequence exceeds context-size, it crops to the most recent context-size tokens before each forward pass.

KV Cache

The KV cache stores past key and value tensors to avoid recomputing them on every generation step. In Clorch’s Llama-style examples, caches are plain Clojure atoms holding maps.

Pattern from modern_llama.clj

Inside GroupedQueryAttention, the cache update looks like:

Pattern from nanochat.clj

The NanoChat example allocates one cache atom per transformer block and manages their lifetimes explicitly with torch/retain! and torch/release! to prevent native memory leaks during long generation loops:

Complete Llama Block Example

The following block definition from examples/modern_llama.clj assembles all LLM components into a standard Llama-style transformer block:

LLM Capability Table


Reference Examples

Modern Llama

examples/modern_llama.clj — a standalone demonstration of a single Llama block with RoPE, GQA, SwiGLU, and KV caching. Includes prefill and single-token decode to verify the cache shape transitions.

NanoChat

examples/nanochat.clj — a compact Llama-3-style model trained on a small text corpus. Demonstrates full training, checkpointing, streaming generation with KV caching, and an interactive chat loop.