Download test_components.py from sage002/angstrom: direct link, hf CLI and curl.
- Browser
- Download file 4.18 kB
-
https://huggingface.co/sage002/angstrom/resolve/main/test_components.py
- Command line
-
hf download hf://sage002/angstrom/test_components.py
-
curl -L -o test_components.py https://huggingface.co/sage002/angstrom/resolve/main/test_components.py
4.18 kB
| """ | |
| Test Core Transformer Components | |
| """ | |
| import sys | |
| sys.path.insert(0, '.') | |
| import torch | |
| from angstrom_nano import AngstromNanoConfig | |
| from angstrom_nano.model import ( | |
| AngstromNanoRMSNorm, | |
| AngstromNanoRotaryEmbedding, | |
| AngstromNanoAttention, | |
| AngstromNanoMLP | |
| ) | |
| def test_rms_norm(): | |
| print("\n[Testing RMSNorm]") | |
| config = AngstromNanoConfig() | |
| norm = AngstromNanoRMSNorm(config.hidden_size, config.rms_norm_eps) | |
| x = torch.randn(2, 512, config.hidden_size) | |
| out = norm(x) | |
| print(f" Input shape: {x.shape}") | |
| print(f" Output shape: {out.shape}") | |
| print(f" Output mean: {out.mean():.6f}, std: {out.std():.6f}") | |
| assert out.shape == x.shape | |
| print(" [PASS]") | |
| def test_rotary_embedding(): | |
| print("\n[Testing Rotary Embedding]") | |
| config = AngstromNanoConfig() | |
| rope = AngstromNanoRotaryEmbedding( | |
| config.head_dim, | |
| config.max_position_embeddings, | |
| config.rope_theta | |
| ) | |
| batch_size, seq_len = 2, 512 | |
| x = torch.randn(batch_size, config.num_attention_heads, seq_len, config.head_dim) | |
| position_ids = torch.arange(seq_len).unsqueeze(0).expand(batch_size, -1) | |
| cos, sin = rope(x, position_ids) | |
| print(f" Input shape: {x.shape}") | |
| print(f" Position IDs shape: {position_ids.shape}") | |
| print(f" Cos shape: {cos.shape}") | |
| print(f" Sin shape: {sin.shape}") | |
| assert cos.shape == (batch_size, seq_len, config.head_dim) | |
| assert sin.shape == (batch_size, seq_len, config.head_dim) | |
| print(" [PASS]") | |
| def test_attention(): | |
| print("\n[Testing Multi-Head Attention]") | |
| config = AngstromNanoConfig() | |
| attn = AngstromNanoAttention(config, layer_idx=0) | |
| batch_size, seq_len = 2, 512 | |
| hidden_states = torch.randn(batch_size, seq_len, config.hidden_size) | |
| position_ids = torch.arange(seq_len).unsqueeze(0).expand(batch_size, -1) | |
| # Create causal mask | |
| attention_mask = torch.triu(torch.ones(seq_len, seq_len) * float('-inf'), diagonal=1) | |
| attention_mask = attention_mask.unsqueeze(0).unsqueeze(0) # [1, 1, seq_len, seq_len] | |
| output, past_kv = attn( | |
| hidden_states, | |
| attention_mask=attention_mask, | |
| position_ids=position_ids, | |
| use_cache=True | |
| ) | |
| print(f" Input shape: {hidden_states.shape}") | |
| print(f" Output shape: {output.shape}") | |
| print(f" KV cache shapes: {past_kv[0].shape}, {past_kv[1].shape}") | |
| assert output.shape == hidden_states.shape | |
| assert past_kv[0].shape[2] == seq_len # cached sequence length | |
| print(" [PASS]") | |
| def test_mlp(): | |
| print("\n[Testing Feed-Forward Network]") | |
| config = AngstromNanoConfig() | |
| mlp = AngstromNanoMLP(config) | |
| batch_size, seq_len = 2, 512 | |
| x = torch.randn(batch_size, seq_len, config.hidden_size) | |
| output = mlp(x) | |
| print(f" Input shape: {x.shape}") | |
| print(f" Output shape: {output.shape}") | |
| assert output.shape == x.shape | |
| print(" [PASS]") | |
| def test_gradient_flow(): | |
| print("\n[Testing Gradient Flow]") | |
| config = AngstromNanoConfig() | |
| attn = AngstromNanoAttention(config, layer_idx=0) | |
| mlp = AngstromNanoMLP(config) | |
| batch_size, seq_len = 2, 128 | |
| hidden_states = torch.randn(batch_size, seq_len, config.hidden_size, requires_grad=True) | |
| position_ids = torch.arange(seq_len).unsqueeze(0).expand(batch_size, -1) | |
| # Forward pass | |
| attn_out, _ = attn(hidden_states, position_ids=position_ids) | |
| mlp_out = mlp(attn_out) | |
| # Compute loss and backward | |
| loss = mlp_out.mean() | |
| loss.backward() | |
| print(f" Loss: {loss.item():.6f}") | |
| print(f" Input gradient exists: {hidden_states.grad is not None}") | |
| print(f" Input gradient norm: {hidden_states.grad.norm().item():.6f}") | |
| assert hidden_states.grad is not None | |
| print(" [PASS]") | |
| def main(): | |
| print("=" * 80) | |
| print("Testing Core Transformer Components") | |
| print("=" * 80) | |
| torch.manual_seed(42) | |
| test_rms_norm() | |
| test_rotary_embedding() | |
| test_attention() | |
| test_mlp() | |
| test_gradient_flow() | |
| print("\n" + "=" * 80) | |
| print("All tests passed!") | |
| print("=" * 80) | |
| if __name__ == "__main__": | |
| main() | |