mirror of
https://github.com/harvard-edge/cs249r_book.git
synced 2026-03-09 07:15:51 -05:00
Reorder optimization tier modules: - Module 17: Acceleration (general runtime - vectorization, fusion) - Module 18: Memoization (domain-specific - KV-cache for transformers) Rationale: General techniques before specialized applications
142 lines
5.4 KiB
Python
142 lines
5.4 KiB
Python
"""
|
|
Integration test for Module 15: TinyGPT
|
|
Tests language model components and GPT-style transformer integration.
|
|
"""
|
|
|
|
import sys
|
|
import numpy as np
|
|
from pathlib import Path
|
|
|
|
def run_integration_test():
|
|
"""Run integration test for TinyGPT module."""
|
|
try:
|
|
print("🧪 Testing TinyGPT Integration...")
|
|
|
|
# Test 1: Import validation
|
|
print("1. Import validation...")
|
|
import tinytorch.tinygpt as tgpt
|
|
print(" ✅ tinytorch.tinygpt imported successfully")
|
|
|
|
# Test 2: Component availability
|
|
print("2. Component availability...")
|
|
expected_components = [
|
|
'CharTokenizer', 'MultiHeadAttention', 'create_causal_mask',
|
|
'LayerNorm', 'TransformerBlock', 'PositionalEncoding',
|
|
'TinyGPT', 'LanguageModelLoss', 'LanguageModelAccuracy',
|
|
'LanguageModelTrainer'
|
|
]
|
|
|
|
available_components = tgpt.__all__
|
|
missing_components = [comp for comp in expected_components if comp not in available_components]
|
|
|
|
if missing_components:
|
|
print(f" ⚠️ Missing components: {missing_components}")
|
|
else:
|
|
print(f" ✅ All {len(expected_components)} components available")
|
|
|
|
# Test 3: CharTokenizer functionality
|
|
print("3. CharTokenizer functionality...")
|
|
tokenizer = tgpt.CharTokenizer(vocab_size=100)
|
|
tokenizer.fit("Hello World! This is a test of the tokenizer.")
|
|
|
|
# Test encoding/decoding
|
|
test_text = "Hello"
|
|
encoded = tokenizer.encode(test_text)
|
|
decoded = tokenizer.decode(encoded)
|
|
|
|
if decoded == test_text:
|
|
print(f" ✅ Tokenizer round-trip: '{test_text}' -> {len(encoded)} tokens -> '{decoded}'")
|
|
else:
|
|
print(f" ❌ Tokenizer round-trip failed: '{test_text}' -> '{decoded}'")
|
|
return False
|
|
|
|
# Test 4: MultiHeadAttention functionality
|
|
print("4. MultiHeadAttention functionality...")
|
|
from tinytorch.core.tensor import Tensor
|
|
|
|
attention = tgpt.MultiHeadAttention(d_model=64, num_heads=8)
|
|
test_input = Tensor(np.random.randn(1, 10, 64))
|
|
output = attention.forward(test_input, test_input, test_input)
|
|
|
|
if output.shape == test_input.shape:
|
|
print(f" ✅ MultiHeadAttention: {test_input.shape} -> {output.shape}")
|
|
else:
|
|
print(f" ❌ MultiHeadAttention shape mismatch: {test_input.shape} -> {output.shape}")
|
|
return False
|
|
|
|
# Test 5: TransformerBlock functionality
|
|
print("5. TransformerBlock functionality...")
|
|
transformer = tgpt.TransformerBlock(d_model=64, num_heads=8, d_ff=256)
|
|
test_input = Tensor(np.random.randn(1, 10, 64))
|
|
output = transformer.forward(test_input)
|
|
|
|
if output.shape == test_input.shape:
|
|
print(f" ✅ TransformerBlock: {test_input.shape} -> {output.shape}")
|
|
else:
|
|
print(f" ❌ TransformerBlock shape mismatch: {test_input.shape} -> {output.shape}")
|
|
return False
|
|
|
|
# Test 6: Complete TinyGPT model
|
|
print("6. Complete TinyGPT model...")
|
|
model = tgpt.TinyGPT(vocab_size=50, d_model=64, num_heads=8, num_layers=2)
|
|
test_input = Tensor(np.array([[1, 2, 3, 4, 5]]))
|
|
output = model.forward(test_input)
|
|
|
|
expected_shape = (1, 5, 50) # (batch, seq_len, vocab_size)
|
|
if output.shape == expected_shape:
|
|
print(f" ✅ TinyGPT: {test_input.shape} -> {output.shape}")
|
|
print(f" ✅ Parameters: ~{model.count_parameters():,}")
|
|
else:
|
|
print(f" ❌ TinyGPT shape mismatch: expected {expected_shape}, got {output.shape}")
|
|
return False
|
|
|
|
# Test 7: Text generation capability
|
|
print("7. Text generation capability...")
|
|
try:
|
|
# Simple generation test
|
|
generated = model.generate(test_input, max_new_tokens=3, temperature=1.0)
|
|
if generated.shape[1] > test_input.shape[1]:
|
|
print(f" ✅ Text generation: {test_input.shape[1]} -> {generated.shape[1]} tokens")
|
|
else:
|
|
print(f" ❌ Text generation failed: no new tokens generated")
|
|
return False
|
|
except Exception as e:
|
|
print(f" ⚠️ Text generation issue (non-critical): {e}")
|
|
|
|
# Test 8: Training components
|
|
print("8. Training components...")
|
|
try:
|
|
loss_fn = tgpt.LanguageModelLoss()
|
|
metric = tgpt.LanguageModelAccuracy()
|
|
|
|
# Test loss computation
|
|
logits = Tensor(np.random.randn(1, 5, 50))
|
|
targets = Tensor(np.array([[1, 2, 3, 4, 5]]))
|
|
|
|
loss = loss_fn.forward(logits, targets)
|
|
accuracy = metric.forward(logits, targets)
|
|
|
|
print(f" ✅ Training components: loss={loss:.3f}, accuracy={accuracy:.3f}")
|
|
except Exception as e:
|
|
print(f" ⚠️ Training components issue (non-critical): {e}")
|
|
|
|
print("✅ TinyGPT integration test PASSED")
|
|
return {
|
|
"success": True,
|
|
"message": "TinyGPT integration test passed",
|
|
"components_tested": 8,
|
|
"module_name": "16_tinygpt"
|
|
}
|
|
|
|
except Exception as e:
|
|
print(f"❌ TinyGPT integration test FAILED: {e}")
|
|
return {
|
|
"success": False,
|
|
"error": str(e),
|
|
"module_name": "16_tinygpt"
|
|
}
|
|
|
|
if __name__ == "__main__":
|
|
result = run_integration_test()
|
|
sys.exit(0 if result.get("success", False) else 1)
|