smart-agro-api / test_engine.py
harsh0o23's picture
Deploy Axiom V2 Backend: 476M SFT Foundation Model, Vector RAG & Search
a1e58cd verified
Raw History Blame Contribute Delete
4.53 kB
import torch
import logging
from axiom_model.core.model import AxiomV2
from axiom_model.utils.reproducibility import set_seed
import yaml
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
def test_engine():
logger.info("Starting Engine Validation...")
set_seed(42)
# Load config
with open("axiom_model/configs/500M.yaml", 'r') as f:
config = yaml.safe_load(f)
device = torch.device("cuda" if torch.cuda.is_available() else "mps" if torch.backends.mps.is_available() else "cpu")
logger.info(f"Using device: {device}")
model_cfg = config['model']
# On CPU-only machines the full 476M model exhausts RAM during the backward
# pass (weights + grads + Adam states). Engine *correctness* does not depend
# on scale, so validate with an identical tiny architecture on CPU.
if device.type == "cpu":
model_cfg = dict(model_cfg)
model_cfg.update({
"vocab_size": 512, "d_model": 128, "n_layers": 3,
"n_heads": 4, "n_kv_heads": 2, "max_seq_len": 128,
"multiple_of": 32,
})
logger.info("CPU detected: validating with a tiny equivalent architecture (same components, scaled down).")
# 1. Model Instantiation
try:
model = AxiomV2(
vocab_size=model_cfg['vocab_size'],
d_model=model_cfg['d_model'],
n_layers=model_cfg['n_layers'],
n_heads=model_cfg['n_heads'],
n_kv_heads=model_cfg['n_kv_heads'],
max_seq_len=model_cfg['max_seq_len'],
multiple_of=model_cfg['multiple_of'],
norm_eps=model_cfg['norm_eps'],
rope_theta=model_cfg['rope_theta']
).to(device)
logger.info("✓ Model instantiates successfully")
except Exception as e:
logger.error(f"Failed to instantiate model: {e}")
return
# 2. Forward Pass
try:
dummy_input = torch.randint(0, model_cfg['vocab_size'], (2, 128)).to(device)
outputs = model(dummy_input)
assert outputs.shape == (2, 128, model_cfg['vocab_size'])
logger.info("✓ Forward pass verified")
except Exception as e:
logger.error(f"Failed forward pass: {e}")
return
# 3. Backward Pass & Optimizer Step
try:
optimizer = torch.optim.AdamW(model.parameters(), lr=1e-3)
loss = outputs.mean()
loss.backward()
logger.info("✓ Backward pass verified")
optimizer.step()
optimizer.zero_grad()
logger.info("✓ Optimizer step verified")
except Exception as e:
logger.error(f"Failed backward/optimizer step: {e}")
return
# 4. Checkpoint Save/Load
try:
torch.save(model.state_dict(), "temp_checkpoint.pt")
model.load_state_dict(torch.load("temp_checkpoint.pt", weights_only=True))
import os; os.remove("temp_checkpoint.pt")
logger.info("✓ Checkpoint save/load verified")
except Exception as e:
logger.error(f"Failed checkpoint save/load: {e}")
return
# 5. Mixed Precision
try:
# CPU autocast only supports bfloat16; fp16 there raises at runtime.
if device.type == 'cuda':
amp_dtype = torch.bfloat16 if torch.cuda.is_bf16_supported() else torch.float16
elif device.type == 'mps':
amp_dtype = torch.float16
else:
amp_dtype = torch.bfloat16
scaler = torch.amp.GradScaler(
'cuda' if device.type == 'cuda' else 'cpu',
enabled=(device.type == 'cuda' and amp_dtype == torch.float16)
)
with torch.autocast(device_type=device.type, dtype=amp_dtype):
outputs_amp = model(dummy_input)
loss_amp = outputs_amp.mean()
logger.info("✓ Mixed precision verified")
except Exception as e:
logger.error(f"Failed mixed precision: {e}")
return
# 6. torch.compile
try:
if hasattr(torch, "compile") and device.type == "cuda":
compiled_model = torch.compile(model)
compiled_model(dummy_input)
logger.info("✓ torch.compile verified")
else:
logger.info("✓ torch.compile verified (Skipped, unsupported hardware)")
except Exception as e:
logger.error(f"Failed torch.compile: {e}")
return
logger.info("Engine Validation Complete. All systems go!")
if __name__ == "__main__":
test_engine()