| """ |
| Test the game generation pipeline with llama.cpp and NVIDIA Nemotron 3 Nano 4B GGUF. |
| |
| Run this script to: |
| 1. Test model availability (llama-cpp-python) |
| 2. Demonstrate GGUF model loading from HuggingFace |
| 3. Generate games with the Nemotron model |
| 4. Fall back to mock generation if model unavailable |
| 5. Validate all outputs against schema |
| """ |
|
|
| import json |
| from pathlib import Path |
| from app.services.retrieval import load_games_dataset, normalize_game_record, retrieve_examples |
| from app.services.generator import generate_game, build_generation_prompt, NEMOTRON_MODEL_ID, NEMOTRON_GGUF_FILE |
| from app.services.schema_validator import validate_game_schema |
|
|
|
|
| def check_llama_cpp_availability(): |
| """Check if llama-cpp-python is installed.""" |
| print("\n" + "=" * 80) |
| print("CHECKING ENVIRONMENT") |
| print("=" * 80) |
| |
| try: |
| import llama_cpp |
| print(f"β llama-cpp-python is installed") |
| print(f" Version: {llama_cpp.__version__ if hasattr(llama_cpp, '__version__') else 'unknown'}") |
| return True |
| except ImportError: |
| print("β llama-cpp-python not found") |
| print(" Install with: pip install llama-cpp-python") |
| print(" Or for GPU support: pip install llama-cpp-python[cuda]") |
| return False |
|
|
|
|
| def main(): |
| print("\n" + "=" * 80) |
| print("PHASE 2, TASK 6: GAME GENERATION WITH NEMOTRON 3 NANO 4B GGUF") |
| print("=" * 80) |
| |
| |
| llama_cpp_available = check_llama_cpp_availability() |
| |
| print(f"\nModel Configuration:") |
| print(f" Repository: {NEMOTRON_MODEL_ID}") |
| print(f" File: {NEMOTRON_GGUF_FILE}") |
| print(f" Runtime: llama.cpp (GGUF quantized)") |
| print(f" Benefits:") |
| print(f" β’ GGUF quantization: 4-bit, memory efficient") |
| print(f" β’ llama.cpp: Fast CPU/GPU inference") |
| print(f" β’ Hackathon bonus: Extra credit for llama.cpp runtime") |
| |
| |
| print("\n1. Loading dataset...") |
| raw_records = load_games_dataset("app/data/games_dataset.json") |
| normalized_records = [normalize_game_record(r) for r in raw_records] |
| print(f"β Loaded {len(normalized_records)} records") |
| |
| |
| test_configs = [ |
| { |
| "name": "Scavenger Hunt - Adults - Medium", |
| "config": { |
| "game_type": "scavenger_hunt", |
| "city": "Paris", |
| "area": "Le Marais", |
| "location_type": "mixed", |
| "duration_minutes": 60, |
| "num_players": 4, |
| "difficulty": "medium", |
| "age_group": "adults" |
| } |
| }, |
| { |
| "name": "Hide & Seek - Kids - Easy", |
| "config": { |
| "game_type": "hide_and_seek", |
| "city": "Paris", |
| "area": "Parc des Buttes-Chaumont", |
| "location_type": "park", |
| "duration_minutes": 45, |
| "num_players": 5, |
| "difficulty": "easy", |
| "age_group": "kids" |
| } |
| } |
| ] |
| |
| |
| results = [] |
| for test in test_configs: |
| print("\n" + "=" * 80) |
| print(f"TEST: {test['name']}") |
| print("=" * 80) |
| |
| config = test['config'] |
| |
| |
| print("\n2. Retrieving similar games...") |
| retrieved = retrieve_examples(config, normalized_records, k=3) |
| print(f"β Retrieved {len(retrieved)} examples") |
| |
| |
| print("\n3. Building generation prompt...") |
| prompt = build_generation_prompt(config, retrieved) |
| print(f"β Prompt ready ({len(prompt)} chars)") |
| |
| |
| print("\n4. Generating game...") |
| print(f" (Using: NVIDIA Nemotron 3 Nano 4B GGUF via llama.cpp)") |
| |
| try: |
| game = generate_game(config, retrieved) |
| print(f"β Game generated: {game['game_id']}") |
| |
| |
| print("\n5. Validating against schema...") |
| is_valid, errors = validate_game_schema(game) |
| |
| if is_valid: |
| print("β Game VALID against schema") |
| else: |
| print(f"β Validation errors: {len(errors)}") |
| |
| |
| print("\n6. Game Summary:") |
| print(f" Title: {game['title']}") |
| print(f" Area: {game['setup']['area']}") |
| print(f" Duration: {game['setup']['duration_minutes']} min | Players: {game['setup']['num_players']}") |
| print(f" Tasks: {len(game['tasks'])} | Rules: {len(game['rules'])}") |
| print(f" Tone: {game['story_seed']['tone']}") |
| |
| results.append({ |
| 'name': test['name'], |
| 'valid': is_valid, |
| 'game_id': game['game_id'] |
| }) |
| |
| except Exception as e: |
| print(f"β Generation failed: {e}") |
| results.append({ |
| 'name': test['name'], |
| 'valid': False, |
| 'game_id': None |
| }) |
| |
| |
| print("\n" + "=" * 80) |
| print("TEST SUMMARY") |
| print("=" * 80) |
| |
| passed = sum(1 for r in results if r['valid']) |
| print(f"\nResults: {passed}/{len(results)} tests passed") |
| |
| for result in results: |
| status = "β PASS" if result['valid'] else "β FAIL" |
| print(f"{status}: {result['name']}") |
| if result['game_id']: |
| print(f" {result['game_id']}") |
| |
| print("\n" + "=" * 80) |
| print("NOTES") |
| print("=" * 80) |
| if not llama_cpp_available: |
| print("β llama-cpp-python not installed - using mock generation") |
| print(" For actual model-based generation, install:") |
| print(" pip install llama-cpp-python[cuda] # For GPU") |
| print(" or") |
| print(" pip install llama-cpp-python # For CPU") |
| else: |
| print("β llama-cpp-python available") |
| print("β NVIDIA Nemotron 3 Nano 4B GGUF ready for download from HuggingFace") |
| print("β Hackathon extra credit: llama.cpp runtime β") |
| |
| print("\n" + "=" * 80) |
|
|
|
|
| if __name__ == "__main__": |
| main() |
|
|