Reformer - Lsh Attention

# Reformer - LSH Attention

## Introduction & Motivation

Reformer: use locality-sensitive hashing for attention. Attend to similar positions. Applications: efficient transformers for long sequences.

Motivation: Reduce attention computation via locality hashing.

Applications: Long document processing, memory-efficient transformers.

---

## Core Concepts & Theory

### Locality-Sensitive Hashing

Hash similar items to same bucket.

### Bucketing

Group positions into buckets.

### Sorted Bucket Attention

Attend within and across buckets.

### Hash Function

Map positions to buckets efficiently.

---

## Mathematical Formulation

Hash Function:
$$h(x) = \lfloor \frac{x \cdot v}{b} floor$$

Bucket Assignment:
$$ ext{bucket}(i) = h(k_i)$$

Attention Computation:
$$ ext{Attention}_{ ext{bucket}} = ext{softmax}(\frac{QK^T_{ ext{bucket}}}{\sqrt{d}})V_{ ext{bucket}}$$

---

## Advanced Theory & Extensions

### Multi-Hash

Use multiple hash functions.

### Revolver Attention

Attend to adjacent positions.

### Chunking

Process sequences in chunks.

---

## Computational Considerations

Bucketing: O(n log n).

Attention per bucket: O(b²·d) where b = bucket size.

Total: O(n·b·d) instead of O(n²·d).

---

## Practical Implementation Strategies

### Bucket Size Selection

Typically 32-64 positions.

### Hash Function Choice

Random projection common.

### Overflow Handling

Handle hash collisions.

---

## Benchmark Datasets & Evaluation

Long Range Arena: Long sequence benchmark.

Language Modeling: Perplexity.

Speed Benchmarks: Inference efficiency.

---

## Key Challenges & Limitations

### Hash Collision

Similar items in same bucket.

### Bucket Balance

Uneven bucket sizes.

### Sequential Dependency

Fixed bucketing order.

---

## Hyperparameter Tuning

Number of hashes: 1-3.

Bucket size: 32-128.

Learning rate: 1e-4 to 1e-3.

---

## Real-World Applications & Case Studies

Long Documents: 4096+ length.

Memory Efficiency: Reduced memory footprint.

Fast Training: Accelerated pre-training.

---

## Integration with Other Methods

Reformer + reversible layers; + chunking for efficiency.

---

## Summary & Key Takeaways

Reformer enables efficient attention via LSH.

Principles:
1. LSH: Hash similar positions.
2. Bucketing: Group into buckets.
3. Local attention: Attend within buckets.
4. Efficiency: O(n log n) computation.
5. Practical: Long sequence processing.

---

## Appendix: Practical Labs

### Lab 1: LSH Bucketing

import numpy as np

def lsh_hash(positions, hash_dim=64, num_buckets=32):
 """Hash positions to buckets using LSH"""
 # Random projection
 v = np.random.randn(hash_dim)
 v = v / np.linalg.norm(v)
 
 # Project and bucket
 projections = positions @ v
 buckets = np.floor(projections / (np.max(projections) / num_buckets)).astype(int)
 
 return buckets

np.random.seed(42)
pos = np.random.randn(100, 64)
buckets = lsh_hash(pos, 64, 32)
assert len(np.unique(buckets)) <= 32
print(f"✓ LSH bucketing: {len(np.unique(buckets))} unique buckets")

### Lab 2: Bucket Attention

import numpy as np

def attend_within_buckets(query, key, value, buckets):
 """Attend within bucketed positions"""
 unique_buckets = np.unique(buckets)
 outputs = []
 
 for bucket_id in unique_buckets:
 mask = buckets == bucket_id
 indices = np.where(mask)[0]
 
 if len(indices) > 0:
 q_bucket = query[indices]
 k_bucket = key[indices]
 v_bucket = value[indices]
 
 # Compute attention within bucket
 scores = q_bucket @ k_bucket.T / np.sqrt(query.shape[-1])
 attn = np.exp(scores) / np.sum(np.exp(scores), axis=-1, keepdims=True)
 output_bucket = attn @ v_bucket
 outputs.append((indices, output_bucket))
 
 return outputs

np.random.seed(42)
q = np.random.randn(100, 64)
k = np.random.randn(100, 64)
v = np.random.randn(100, 64)
buckets = np.random.randint(0, 32, 100)
outputs = attend_within_buckets(q, k, v, buckets)
assert len(outputs) > 0
print(f"✓ Bucket attention: {len(outputs)} buckets")

### Lab 3: Multi-Hash

import numpy as np

def multi_hash_lsh(positions, num_hashes=3, num_buckets=32):
 """Use multiple hash functions"""
 hash_results = []
 
 for h in range(num_hashes):
 v = np.random.randn(positions.shape[-1])
 v = v / np.linalg.norm(v)
 
 projections = positions @ v
 buckets = np.floor(projections / (np.max(projections) / num_buckets)).astype(int)
 hash_results.append(buckets)
 
 return hash_results

np.random.seed(42)
pos = np.random.randn(100, 64)
hashes = multi_hash_lsh(pos, num_hashes=3)
assert len(hashes) == 3
print("✓ Multi-hash LSH working")

### Lab 4: Bucket Statistics

import numpy as np

def analyze_bucket_distribution(buckets, num_buckets=32):
 """Analyze bucket size distribution"""
 bucket_sizes = []
 
 for b in range(num_buckets):
 size = np.sum(buckets == b)
 if size > 0:
 bucket_sizes.append(size)
 
 if len(bucket_sizes) > 0:
 mean_size = np.mean(bucket_sizes)
 max_size = np.max(bucket_sizes)
 min_size = np.min(bucket_sizes)
 return mean_size, max_size, min_size
 else:
 return 0, 0, 0

np.random.seed(42)
buckets = np.random.randint(0, 32, 1000)
mean, max_s, min_s = analyze_bucket_distribution(buckets)
print(f"✓ Bucket stats: mean={mean:.1f}, max={max_s}, min={min_s}")

---

Go deeper with CFSGPT

Get AI-powered deep-dives, save terms, and run advanced simulations — free account.

Create Free Account