### Install PEER-pytorch Source: https://github.com/lucidrains/peer-pytorch/blob/main/README.md Install the PEER-pytorch library using pip. This command should be run in your terminal. ```bash pip install PEER-pytorch ``` -------------------------------- ### PEER Block Usage Example Source: https://github.com/lucidrains/peer-pytorch/blob/main/README.md Demonstrates how to initialize and use the PEER block in PyTorch. Ensure the model and input tensors are on the CUDA-enabled GPU. ```python import torch from PEER_pytorch import PEER peer = PEER( dim = 512, heads = 8, # tested up to 32 - (hk = heads * num_experts_per_head (16)) num_experts = 1_000_000, # he chose 1 million num_experts_per_head = 16, # he settled on 16, but was 32 in PKM paper dim_key = 128, pre_rmsnorm = True ).cuda() x = torch.randn(2, 1024, 512).cuda() out = peer(x) + x assert x.shape == out.shape ``` -------------------------------- ### Initialize and use a standard PEER block Source: https://context7.com/lucidrains/peer-pytorch/llms.txt Configures a PEER module with 1 million experts and demonstrates a forward pass with residual connection and sparse memory fine-tuning. ```python import torch from PEER_pytorch import PEER # Create a PEER block with 1 million experts peer = PEER( dim = 512, # Input/output dimension heads = 8, # Number of retrieval heads (hk = heads * num_experts_per_head) num_experts = 1_000_000, # Total number of experts (must be a perfect square) num_experts_per_head = 16, # Experts retrieved per head dim_key = 128, # Dimension of product keys activation = torch.nn.GELU, # Activation function (default: GELU) pre_rmsnorm = True, # Apply RMSNorm before processing non_competing_scores = True, # Use ReLU instead of softmax (recommended) separate_embed_per_head = False, # Separate embeddings per head to reduce redundancy dropout = 0.1 # Dropout rate ).cuda() # Forward pass with residual connection x = torch.randn(2, 1024, 512).cuda() # (batch, sequence, dim) out = peer(x) + x # PEER output + residual assert out.shape == (2, 1024, 512) # Sparse memory fine-tuning (continual learning) # Only train specific expert neurons while freezing others train_mem_mask = torch.zeros(1_000_000, dtype=torch.bool).cuda() train_mem_mask[:10000] = True # Only train first 10k experts out_sparse = peer(x, train_mem_mask=train_mem_mask) ``` -------------------------------- ### Initialize and Use Standalone Product Key Retrieval Source: https://context7.com/lucidrains/peer-pytorch/llms.txt Configures the PK module for nearest-neighbor lookup and performs a forward pass to retrieve scores and indices. ```python import torch from PEER_pytorch import PK # Create product key retrieval module pk = PK( dim = 512, # Input dimension heads = 8, # Number of parallel retrieval heads dim_key = 256, # Dimension of each product key component num_keys = 1000, # Number of keys per product component product_keys = 2, # Number of product key components (total space = num_keys^product_keys) product_key_topk = 16, # Top-k per product key component final_topk = 16 # Final top-k after combining product keys ) # Forward pass - returns scores and indices x = torch.randn(2, 1024, 512) # (batch, sequence, dim) scores, indices = pk(x) print(f"Scores shape: {scores.shape}") # (2, 1024, 8, 16) print(f"Indices shape: {indices.shape}") # (2, 1024, 8, 16) # With softmax normalization on scores scores_softmax, indices = pk(x, softmax_scores=True) # Maximum index space print(f"Max index value: {pk.max_index}") # 1000^2 = 1_000_000 # Using 3 product keys for even larger index space pk_large = PK( dim = 512, num_keys = 100, product_keys = 3, # Total space = 100^3 = 1_000_000 final_topk = 10 ) scores, indices = pk_large(x) print(f"Large PK max index: {pk_large.max_index}") # 1_000_000 ``` -------------------------------- ### Initialize and use a PEERLora block Source: https://context7.com/lucidrains/peer-pytorch/llms.txt Combines PEER retrieval with LoRA adapters for parameter-efficient fine-tuning. ```python import torch from PEER_pytorch import PEERLora # Create a PEERLora block peer_lora = PEERLora( dim = 512, # Input/output dimension expansion_factor = 2.0, # Feedforward expansion factor num_experts = 1_000_000, # Number of LoRA expert pairs heads = 4, # Number of retrieval heads num_experts_per_head = 4, # LoRA k dimension = heads * num_experts_per_head (16) dim_key = 256, # Dimension of product keys activation = torch.nn.GELU, # Activation function pre_rmsnorm = True, # Apply RMSNorm preprocessing non_competing_scores = True, # Use non-competing ReLU activation dropout = 0.1 # Dropout rate ).cuda() # Forward pass x = torch.randn(2, 1024, 512).cuda() # (batch, sequence, dim) out = peer_lora(x) + x # PEERLora output + residual assert out.shape == (2, 1024, 512) # Check the effective LoRA rank print(f"LoRA k dimension: {peer_lora.lora_k}") # heads * num_experts_per_head = 16 ``` -------------------------------- ### Implement Product Key Memory Attention Source: https://context7.com/lucidrains/peer-pytorch/llms.txt Configures PKAttention for large-scale key-value retrieval, supporting both causal and non-causal modes with optional masking. ```python import torch from PEER_pytorch import PKAttention # Create PKAttention module pk_attn = PKAttention( dim = 256, # Input/output dimension causal = True, # Use causal masking for autoregressive models heads = 8, # Number of attention heads num_key_values = 1_000_000, # Number of key-value pairs (must be perfect square) key_value_pk_topk = 16, # Top-k key-values retrieved per position dim_key = 128, # Dimension of product keys product_keys = 2, # Number of product key components pre_rmsnorm = True, # Apply RMSNorm preprocessing dropout = 0.1 # Attention dropout ) # Causal attention (autoregressive) x = torch.randn(2, 512, 256) # (batch, sequence, dim) out = pk_attn(x) + x assert out.shape == (2, 512, 256) # Non-causal attention with optional mask pk_attn_bidirectional = PKAttention( dim = 256, causal = False, heads = 8, num_key_values = 10_000, pre_rmsnorm = True ) # With padding mask (True = attend, False = ignore) mask = torch.ones(2, 512, dtype=torch.bool) mask[:, 400:] = False # Mask out positions after 400 out_masked = pk_attn_bidirectional(x, mask=mask) ``` -------------------------------- ### Process sequences with ChunkedPEER Source: https://context7.com/lucidrains/peer-pytorch/llms.txt Wraps a PEER module to enable gradient checkpointing and memory-efficient processing of long sequences. ```python import torch from PEER_pytorch import PEER, ChunkedPEER # Create base PEER block peer = PEER( dim = 512, heads = 8, num_experts = 1_000_000, num_experts_per_head = 16, pre_rmsnorm = True ).cuda() # Wrap with chunking for memory efficiency chunked_peer = ChunkedPEER( peer = peer, seq_chunk_size = 128 # Process 128 tokens at a time ) # Forward pass with long sequence x = torch.randn(1, 4096, 512).cuda().requires_grad_() out = chunked_peer(x) + x # Gradient checkpointing is automatically applied during training out.sum().backward() print(f"Processed sequence length: {out.shape[1]}") # 4096 ``` -------------------------------- ### Integrate PEER into a Transformer Block Source: https://context7.com/lucidrains/peer-pytorch/llms.txt Combines standard multi-head attention with a chunked PEER feedforward layer to create a memory-efficient transformer block. ```python import torch import torch.nn as nn from PEER_pytorch import PEER, ChunkedPEER class PEERTransformerBlock(nn.Module): def __init__(self, dim, num_heads, num_experts=1_000_000, chunk_size=128): super().__init__() # Standard multi-head attention self.attn = nn.MultiheadAttention(dim, num_heads, batch_first=True) self.attn_norm = nn.LayerNorm(dim) # PEER feedforward with chunking for memory efficiency peer = PEER( dim = dim, heads = 8, num_experts = num_experts, num_experts_per_head = 16, pre_rmsnorm = True, non_competing_scores = True, dropout = 0.1 ) self.ff = ChunkedPEER(peer, seq_chunk_size=chunk_size) self.ff_norm = nn.LayerNorm(dim) def forward(self, x, attn_mask=None): # Attention with residual x_norm = self.attn_norm(x) attn_out, _ = self.attn(x_norm, x_norm, x_norm, attn_mask=attn_mask) x = x + attn_out # PEER feedforward with residual x_norm = self.ff_norm(x) x = x + self.ff(x_norm) return x # Create transformer block block = PEERTransformerBlock( dim = 512, num_heads = 8, num_experts = 1_000_000, chunk_size = 128 ).cuda() # Forward pass x = torch.randn(4, 2048, 512).cuda() out = block(x) print(f"Input shape: {x.shape}") # (4, 2048, 512) print(f"Output shape: {out.shape}") # (4, 2048, 512) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.