nGPT-pytorch

repository·main·Indexed 43 days ago

https://github.com/lucidrains/ngpt-pytorch

A PyTorch implementation of nGPT (normalized GPT), a transformer architecture designed to learn entirely on the hypersphere based on research from NvidiaAI. Version 0.2.16 features normalized layers via NormLinear, residual Slerp updates, and evolutionary crossover functions for breeding models, attention, and feed-forward layers.

Tokens
5.6K
Snippets
19
Records
26
Agent score
54%

What's inside nGPT-pytorch

  1. How Residual Slerp updates work in nGPT

    main

    Instead of standard additive residuals, nGPT uses a Residual module that implements a Slerp-like (Spherical Linear Interpolation) update combined with L2 normalization.

    This mechanism uses a Scale module to learn the interpolation factor. The update follows this logic:

    1. Compute the output of the sub-module (fn).
    2. Apply L2 normalization to the output.
    3. Perform a linear interpolation (lerp) between the original input x and the normalized output, scaled by a learned branch_scale.
    4. Apply L2 normalization to the resulting interpolated value.

    This approach helps maintain the norm of activations across deep networks.

  2. Understand the Scale and NormLinear components

    main

    The architecture relies on two specialized components to maintain normalization:

    1. Scale: A module that maintains a learnable scale parameter. It returns self.scale * self.forward_scale, where forward_scale is initialized as init / scale. This allows the model to control the magnitude of activations or residuals while keeping the effective initialization controlled.

    2. NormLinear: A linear layer that applies L2 normalization to its weights.

      • If parametrize=True, it uses PyTorch's register_parametrization to ensure the weights are always L2-normalized.
      • It supports groups (hyperspheres), allowing the weights to be normalized in chunks.
      • The output is scaled by self.scale (calculated as groups ** -1).
  3. Use the nGPT model class

    main

    The nGPT class implements a normalized GPT architecture that learns on the hypersphere. You can initialize the model with specific dimensions and depth, and optionally enable attention normalization for Query and Key vectors.

    To perform training, call the model with return_loss = True. To perform inference or get logits, call the model without that flag.

    import torch
    from nGPT_pytorch import nGPT
    
    model = nGPT(
        num_tokens = 256,
        dim = 512,
        depth = 4,
        attn_norm_qk = True
    )
    
    x = torch.randint(0, 256, (2, 2048))
    
    # Training mode: returns the loss
    loss = model(x, return_loss = True)
    loss.backward()
    
    # Inference mode: returns logits of shape (batch, sequence, num_tokens)
    logits = model(x) # (2, 2048, 256)
  4. Configure nTransformer scaling hyperparameters

    main

    The nTransformer allows for per-layer control of scaling factors. If you provide a single value, it is applied to all layers. If you provide a tuple, it must match the depth of the transformer.

    Supported scaling parameters:

    • alpha_init: Sets the initial scale for all residual connections (defaults to 1. / depth).
    • alpha_attn_init / alpha_attn_scale: Scaling for attention residual connections.
    • alpha_ff_init / alpha_ff_scale: Scaling for feedforward residual connections.
    • s_qk_init / s_qk_scale: Scaling for query/key products in attention.
    • s_ff_hidden_init / s_ff_hidden_scale: Scaling for feedforward hidden states.
    • s_ff_gate_init / s_ff_gate_scale: Scaling for feedforward gate states.
    • s_logit_init / s_logit_scale: Scaling for logits (if applicable).
  5. Configure nGPT scaling hyperparameters

    main

    The nGPT constructor accepts several hyperparameter groups to control the effective learning rates and scales throughout the network. Most of these accept either a single float (applied to all layers) or a tuple[float, ...] of length depth (providing a specific value per layer).

    Residual Scaling (Alpha):

    • alpha_init: Base initialization for all residuals.
    • alpha_attn_init / alpha_attn_scale: Scaling for attention residuals.
    • alpha_ff_init / alpha_ff_scale: Scaling for feedforward residuals.

    Internal Component Scaling (S):

    • s_qk_init / s_qk_scale: Scaling for Query-Key projections.
    • s_ff_hidden_init / s_ff_hidden_scale: Scaling for FeedForward hidden dimension.
    • s_ff_gate_init / s_ff_gate_scale: Scaling for FeedForward gate dimension.
    • s_logit_init / s_logit_scale: Scaling for the output logits.
  6. Breed FeedForward layers with cross_over_feedforward

    main

    The cross_over_feedforward function implements a breeding strategy for FeedForward layers. It splits the dim_inner of the layer into two halves using randomly permuted indices and applies crossover to all internal components: to_hidden, to_gate, to_out, hidden_scale, and gate_scale.

    Parameters:

    • parent1: The first FeedForward parent.
    • parent2: The second FeedForward parent.
    • child (optional): An existing FeedForward instance to populate. If None, a copy of parent1 is used.
    from nGPT_pytorch.evo import cross_over_feedforward
    
    # Assuming parent1 and parent2 are FeedForward instances
    child = cross_over_feedforward(parent1, parent2)
  7. Configure Attention with Flash Attention and QK Norm

    main

    The Attention module supports several advanced features for stability and speed:

    • QK Normalization: If norm_qk=True, Query and Key tensors are L2-normalized before the dot product.
    • QK Scaling: Uses a Scale module (qk_scale) to scale the Query/Key projections, similar to multi-head RMSNorm used in modern LLMs.
    • Flash Attention: Controlled via flash_kwargs. You can enable/disable enable_flash, enable_math, enable_mem_efficient, or enable_cudnn.
    • Value Residuals: If value_residual is provided during forward, it is blended with the value tensor: v = 0.5 * (v + value_residual).
    • Rotary Embeddings: Accepts a rotary_embed module to apply rotary positional embeddings to queries and keys.
    from nGPT_pytorch import Attention
    
    attn = Attention(
        dim=512,
        heads=8,
        dim_head=64,
        norm_qk=True,
        causal=True,
        flash_kwargs=dict(enable_flash=True, enable_math=True)
    )
  8. Initialize and use the nGPT model

    main

    The nGPT class is the main entry point for the Normalized GPT implementation. It is a transformer-based model that utilizes normalized layers (via NormLinear) and learned scaling factors to control effective relative learning rates.

    Key features include:

    • Normalized Layers: Uses NormLinear for embeddings, attention projections, and feedforward layers.
    • Residual Slerp Updates: Implements residual connections using a learned scale and L2 normalization.
    • Value Residuals: Supports adding value residuals from previous layers (based on the Resformer paper).
    • Flexible Scaling: Allows fine-grained control over scaling hyperparameters (alpha, s_qk, s_ff, etc.) for each layer depth.
    • Tied Embeddings: Option to tie token embeddings with the output logits.

    To use the model for inference or training, pass token IDs to the forward method.

    from nGPT_pytorch import nGPT
    import torch
    
    model = nGPT(
        num_tokens = 50000,
        dim = 512,
        depth = 12,
        heads = 8,
        dim_head = 64,
        causal = True
    )
    
    # Dummy input: batch size 4, sequence length 128
    ids = torch.randint(0, 50000, (4, 128))
    
    # Forward pass for logits
    logits = model(ids)
    
    # Forward pass with loss calculation (requires causal=True)
    loss, hiddens = model(ids, return_loss=True, return_hiddens=True)
  9. Initialize and use the nTransformer model

    main

    The nTransformer class is the main entry point for the Normalized GPT implementation. It implements a transformer architecture where layers and weights are normalized (L2 norm) and scaled to control effective relative learning rates.

    Key features include:

    • Normalization: Supports L2 normalization of inputs and layer outputs.
    • Scaling: Uses Scale modules to control residual connections (alpha_init) and internal components (attention and feedforward scales).
    • Attention: Supports causal masking, rotary embeddings, and query/key normalization.
    • Hyperparameter Control: Allows fine-grained control over scaling via alpha_attn_init, alpha_ff_init, s_qk_init, etc., which can be passed as single values or tuples of length depth to vary per layer.

    To use the model, pass a tensor of tokens of shape (batch, sequence, dim). You can optionally set norm_input=True to L2-normalize the input tokens before processing.

    from nGPT_pytorch.nTransformer import nTransformer
    import torch
    
    transformer = nTransformer(
        dim = 256,
        depth = 4,
        attn_norm_qk = True,
        rotary_embed = True
    )
    
    x = torch.randn(2, 1024, 256)
    
    # norm_input=True applies L2 normalization to the input tokens
    output = transformer(x, norm_input = True)
    assert x.shape == output.shape
  10. Use NormLinear for L2-normalized weights

    main

    The NormLinear class provides a linear layer where weights are constrained by L2 normalization.

    It supports two modes:

    1. Parametrized: Uses torch.nn.utils.parametrize to ensure the weight remains normalized during optimization.
    2. Manual: Manually applies L2 normalization to weights.

    It also supports groups (via the num_hyperspheres concept) to allow normalization across specific sub-dimensions.

    from nGPT_pytorch.nGPTExperimental import NormLinear
    
    # A linear layer with parametrized L2-normalized weights
    layer = NormLinear(dim = 768, dim_out = 768, parametrize = True)
  11. Import the nGPT model and core components

    main

    The nGPT_pytorch package provides access to the nGPT model, the nTransformer architecture, and several core building blocks used in the normalized GPT implementation. You can import these directly from the root package.

    from nGPT_pytorch import (
        nGPT,
        nTransformer,
        Attention,
        FeedForward,
        NormLinear,
        Residual,
        Scale,
        l2norm
    )