| """ |
| Post-training validation script. |
| Tests the trained model by generating text from prompts. |
| |
| Usage: |
| python Base/scripts/validate_model.py --checkpoint_dir Base/out/pretrain/custom-100m-10m-test/final |
| python Base/scripts/validate_model.py --checkpoint_dir Base/out/pretrain/custom-100m-3b/final |
| """ |
|
|
| import argparse |
| from pathlib import Path |
|
|
| import torch |
| from litgpt import Tokenizer |
| from litgpt.config import Config |
| from litgpt.model import GPT |
|
|
|
|
| def load_model(checkpoint_dir: str): |
| """Load a pretrained model from a litgpt checkpoint directory.""" |
| checkpoint_dir = Path(checkpoint_dir) |
|
|
| if not checkpoint_dir.exists(): |
| raise FileNotFoundError(f"Checkpoint directory not found: {checkpoint_dir}") |
|
|
| config = Config.from_checkpoint(checkpoint_dir) |
| model_path = checkpoint_dir / "lit_model.pth" |
|
|
| if not model_path.exists(): |
| raise FileNotFoundError(f"Model file not found: {model_path}") |
|
|
| device = torch.device("cuda" if torch.cuda.is_available() else "cpu") |
| print(f"Using device: {device}") |
|
|
| with torch.device("meta"): |
| model = GPT(config) |
|
|
| checkpoint = torch.load(str(model_path), map_location="cpu", weights_only=False) |
|
|
| |
| if "model" in checkpoint: |
| state_dict = checkpoint["model"] |
| else: |
| state_dict = checkpoint |
|
|
| model.load_state_dict(state_dict, assign=True) |
| model = model.to(device) |
| model.eval() |
|
|
| return model, config, device |
|
|
|
|
| def generate_text(model, tokenizer, device, prompt, max_new_tokens=200, temperature=0.8, top_k=50): |
| """Generate text from a prompt.""" |
| input_ids = tokenizer.encode(prompt, device=device).unsqueeze(0) |
|
|
| with torch.no_grad(): |
| for _ in range(max_new_tokens): |
| |
| idx_cond = input_ids[:, -model.max_seq_length:] |
| logits = model(idx_cond) |
| logits = logits[:, -1, :] / temperature |
|
|
| |
| if top_k is not None: |
| v, _ = torch.topk(logits, min(top_k, logits.size(-1))) |
| logits[logits < v[:, [-1]]] = float("-inf") |
|
|
| probs = torch.softmax(logits, dim=-1) |
| next_id = torch.multinomial(probs, num_samples=1) |
| input_ids = torch.cat([input_ids, next_id], dim=1) |
|
|
| |
| if next_id.item() == tokenizer.eos_id: |
| break |
|
|
| return tokenizer.decode(input_ids[0]) |
|
|
|
|
| def main(): |
| parser = argparse.ArgumentParser(description="Validate a pretrained LitGPT model") |
| parser.add_argument( |
| "--checkpoint_dir", |
| type=str, |
| required=True, |
| help="Path to the checkpoint directory (e.g., Base/out/pretrain/custom-100m-10m-test/final)", |
| ) |
| parser.add_argument( |
| "--tokenizer_dir", |
| type=str, |
| default="Base/checkpoints/EleutherAI/pythia-160m", |
| help="Path to the tokenizer directory", |
| ) |
| parser.add_argument( |
| "--max_new_tokens", |
| type=int, |
| default=200, |
| help="Maximum tokens to generate", |
| ) |
| args = parser.parse_args() |
|
|
| print(f"Loading model from: {args.checkpoint_dir}") |
| model, config, device = load_model(args.checkpoint_dir) |
|
|
| print(f"\nModel config: {config.name}") |
| print(f"Parameters: {sum(p.numel() for p in model.parameters()):,}") |
| print(f"Block size: {config.block_size}") |
|
|
| tokenizer = Tokenizer(Path(args.tokenizer_dir)) |
|
|
| test_prompts = [ |
| "The future of artificial intelligence", |
| "In a groundbreaking study, researchers found that", |
| "The most important thing about education is", |
| "Once upon a time, in a land far away,", |
| ] |
|
|
| print(f"\n{'='*60}") |
| print("GENERATION TESTS") |
| print(f"{'='*60}") |
|
|
| for i, prompt in enumerate(test_prompts, 1): |
| print(f"\n--- Prompt {i}: \"{prompt}\" ---") |
| output = generate_text( |
| model, tokenizer, device, prompt, |
| max_new_tokens=args.max_new_tokens, |
| ) |
| print(f"Generated:\n{output}\n") |
|
|
| print(f"{'='*60}") |
| print("Validation complete!") |
| print("Note: A freshly pretrained model will produce semi-coherent text.") |
| print("Quality improves with more training data and compute.") |
|
|
|
|
| if __name__ == "__main__": |
| main() |
|
|