Spaces:
Sleeping
Sleeping
| import os | |
| import sys | |
| import torch | |
| import pytest | |
| # Add parent directory to sys.path to resolve 'src' | |
| sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) | |
| from src.models.model import GPT, GPTConfig | |
| def test_kv_cache_equivalence(): | |
| """ | |
| Test that using KV caching produces the exact same logits | |
| as passing the full sequence. | |
| """ | |
| torch.manual_seed(42) | |
| # Tiny model for fast testing | |
| config = GPTConfig(vocab_size=100, block_size=32, n_layer=2, n_head=2, n_embd=16) | |
| model = GPT(config) | |
| model.eval() | |
| # 1. Standard forward pass (full sequence) | |
| idx_full = torch.tensor([[10, 20, 30, 40, 50]], dtype=torch.long) | |
| with torch.no_grad(): | |
| logits_full, _ = model(idx_full) | |
| # The logit predictions for the final token (given 10, 20, 30, 40, 50) | |
| target_logits = logits_full[:, -1, :] | |
| # 2. KV Cached forward pass | |
| idx_context = torch.tensor([[10, 20, 30, 40]], dtype=torch.long) | |
| idx_next = torch.tensor([[50]], dtype=torch.long) | |
| with torch.no_grad(): | |
| # Step A: Get past_key_values from the context | |
| _, _, past_key_values = model(idx_context, use_cache=True) | |
| # Step B: Pass ONLY the newest token + past_key_values | |
| logits_cached, _, _ = model(idx_next, past_key_values=past_key_values, use_cache=True) | |
| cached_target_logits = logits_cached[:, -1, :] | |
| # 3. Assert exact mathematical equivalence | |
| assert torch.allclose(target_logits, cached_target_logits, atol=1e-5), "KV Cached logits do not match standard logits!" | |
| if __name__ == "__main__": | |
| test_kv_cache_equivalence() | |
| print("Test passed!") | |