CoLT5-attention

repository·main·Indexed 42 days ago

https://github.com/lucidrains/colt5-attention

A PyTorch implementation of conditionally routed efficient attention and feedforward blocks based on the CoLT5 architecture. Version 0.11.2 features coordinate descent to route tokens to high-capacity branches, supporting long sequences and high-resolution images via ConditionalRoutedAttention, ConditionalRoutedFeedForward, and ConditionalRoutedViT.

Tokens
2.6K
Snippets
9
Records
9
Agent score
3%

What's inside CoLT5-attention

  1. Use ConditionalRoutedAttention

    main

    The ConditionalRoutedAttention implements conditionally routed efficient attention. It uses a light branch with a local attention receptive field (light_window_size) and a heavy branch that receives a specific number of routed tokens for both queries and key-values.

    import torch
    from colt5_attention import ConditionalRoutedAttention
    
    tokens = torch.randn(2, 32768, 512)
    mask = torch.ones(2, 32768).bool()
    
    attn = ConditionalRoutedAttention(
        dim = 512,
        light_dim_head = 64,
        light_heads = 8,
        light_window_size = 128,
        heavy_dim_head = 64,
        heavy_heads = 8,
        num_heavy_tokens_q = 1024,
        num_heavy_tokens_kv = 1024
    )
    
    attn_out = attn(tokens, mask = mask) # (2, 32768, 512)
  2. Use ConditionalRoutedTransformerBlock

    main

    The ConditionalRoutedTransformerBlock combines both routed attention and routed feedforward with residual connections. A stack of these blocks constitutes a CoLT5 encoder.

    import torch
    from colt5_attention import ConditionalRoutedTransformerBlock
    
    tokens = torch.randn(2, 32768, 512)
    mask = torch.ones(2, 32768).bool()
    
    block = ConditionalRoutedTransformerBlock(
        dim = 512,
        light_dim_head = 64,
        light_heads = 8,
        light_window_size = 128,
        heavy_dim_head = 64,
        heavy_heads = 8,
        light_ff_mult = 0.5,
        heavy_ff_mult = 4,
        num_heavy_ff_tokens = 1024,
        num_heavy_attn_tokens_q = 1024,
        num_heavy_attn_tokens_kv = 1024
    )
    
    block_out = block(tokens, mask = mask) # (2, 32768, 512)
  3. Use ConditionalRoutedImageAttention for feature maps

    main

    The ConditionalRoutedImageAttention is designed for high-resolution image feature maps. It uses a local window patch for the light branch and routed attention for the heavy branch.

    Key parameters:

    • channel_first: Set to True if the input has channels before spatial dimensions.
    import torch
    from colt5_attention import ConditionalRoutedImageAttention
    
    attn = ConditionalRoutedImageAttention(
        dim = 32,
        light_dim_head = 64,
        light_heads = 8,
        light_window_size = 32,
        channel_first = True,
        heavy_dim_head = 64,
        heavy_heads = 8,
        num_heavy_tokens_q = 1024,
        num_heavy_tokens_kv = 1024
    ).cuda()
    
    fmap = torch.randn(1, 32, 256, 256).cuda()
    
    out = attn(fmap)
  4. Use ConditionalRoutedAutoregressiveAttention

    main

    The ConditionalRoutedAutoregressiveAttention is an improvised version for autoregressive generation. It views the sequence in windows where each window attends to past windows. The light branch handles intra-window attention.

    Key parameters:

    • heavy_window_size: The windowing for the routed heavy attention. If this is greater than light_window_size, some tokens might be missed.
    • num_routed_kv: Splits attention heads so groups attend to different sets of key-values.
    • use_triton: Highly recommended for viability.
    • use_flash_attn: Enables flash attention in the heavy branch.
    import torch
    from colt5_attention import ConditionalRoutedAutoregressiveAttention
    
    tokens = torch.randn(2, 8192, 512).cuda()
    
    attn = ConditionalRoutedAutoregressiveAttention(
        dim = 512,
        light_dim_head = 64,
        light_heads = 8,
        light_window_size = 128,
        heavy_window_size = 128,
        heavy_dim_head = 64,
        heavy_heads = 8,
        num_heavy_tokens_q = 32,
        num_heavy_tokens_kv = 1024,
        num_routed_kv = 2,
        use_triton = True,
        use_flash_attn = True
    ).cuda()
    
    attn_out = attn(tokens) + tokens
  5. Use ConditionalRoutedViT

    main

    The ConditionalRoutedViT is a Vision Transformer implementation using coordinate descent routed attention and feedforward.

    import torch
    from colt5_attention.vit import ConditionalRoutedViT
    
    vit = ConditionalRoutedViT(
        image_size = 256,
        patch_size = 32,
        num_classes = 1000,
        dim = 1024,
        depth = 6,
        attn_num_heavy_tokens_q = 16,
        attn_num_heavy_tokens_kv = 16,
        attn_heavy_dim_head = 64,
        attn_heavy_heads = 8,
        attn_light_window_size = 4,
        attn_light_dim_head = 32,
        attn_light_heads = 4,
        ff_num_heavy_tokens = 16,
        ff_heavy_mult = 4,
        ff_light_mult = 2
    )
    
    images = torch.randn(1, 3, 256, 256)
    logits = vit(images)
  6. Use differentiable topk via coordinate descent

    main

    The topk function provides a differentiable version of topk using a small wrapper around coordinate descent.

    Returns:

    • values: The values, which have already been multiplied by the gates.
    • indices: The topk indices.
    • coor_descent_values: The coordinate descent values.
    • gates: The routing gates.
    import torch
    from colt5_attention import topk
    
    x = torch.randn(1024, 512)
    
    values, indices, coor_descent_values, gates = topk(x, k = 10, fused = True)
  7. Use ConditionalRoutedFeedForward

    main

    The ConditionalRoutedFeedForward implements a routed feedforward block where a subset of tokens is routed to a 'heavy' branch with a larger hidden dimension, while the rest use a 'light' branch. The outputs are summed.

    import torch
    from colt5_attention import ConditionalRoutedFeedForward
    
    tokens = torch.randn(2, 32768, 512)
    mask = torch.ones(2, 32768).bool()
    
    ff = ConditionalRoutedFeedForward(
        dim = 512,
        light_ff_mult = 0.5,      # hidden dimension ratio of light branch
        heavy_ff_mult = 4,        # hidden dimension ratio of heavy branch
        num_heavy_tokens = 1024   # heavy branch receives only 1024 routed tokens of 32768
    )
    
    ff_out = ff(tokens, mask = mask)  # (2, 32768, 512)
  8. Use ConditionalRoutedCrossAttention for long context

    main

    The ConditionalRoutedCrossAttention is designed for attending to very long context memories (e.g., in Transformer-XL). It allows routing a subset of queries and a subset of key-values from the memory.

    Key parameters:

    • kv_routing_tokens: Specifies how many routing tokens to use to split attention heads into groups that attend to different sets of key/values.
    • use_triton: Set to True to use the optimized CUDA kernel.
    • route_block_size: The size of blocks used for routing.
    import torch
    from colt5_attention import ConditionalRoutedCrossAttention
    
    tokens = torch.randn(1, 1024, 512).cuda()
    tokens_mask = torch.ones(1, 1024).bool().cuda()
    
    memories = torch.randn(1, 1_048_576, 512).cuda()
    memories_mask = torch.ones(1, 1_048_576).bool().cuda()
    
    cross_attn = ConditionalRoutedCrossAttention(
        dim = 512,
        dim_head = 64,
        heads = 8,
        num_tokens_q = 512,
        num_tokens_kv = 1024,
        kv_routing_tokens = 2,
        use_triton = True,
        route_block_size = 131072
    ).cuda()
    
    cross_attn_out = cross_attn(
        tokens,
        context = memories,
        mask = tokens_mask,
        context_mask = memories_mask
    )