| """ |
| NeuroLex v4 โ Interactive Name Generator |
| ========================================= |
| Generate creative names from a trained model. |
| |
| Usage: |
| python generate.py --checkpoint checkpoints/neurolex_v4_best.pt |
| python generate.py --checkpoint checkpoints/neurolex_v4_best.pt --domain tech --style sharp --lang english --n 50 |
| python generate.py --checkpoint checkpoints/neurolex_v4_best.pt --interactive |
| |
| Or without a checkpoint (uses random untrained model for testing structure): |
| python generate.py --test |
| """ |
|
|
| import torch |
| import argparse |
| import sys |
| import os |
|
|
| from neurolex_v4_model import ( |
| NeuroLexV4, NeuroLexConfig, CharTokenizer, create_model, |
| DOMAINS, STYLES, LANGUAGES, DOMAIN_TO_ID, STYLE_TO_ID, LANG_TO_ID |
| ) |
|
|
|
|
| def load_model(checkpoint_path: str, device: str = 'auto'): |
| """Load a trained model from checkpoint.""" |
| if device == 'auto': |
| device = 'cuda' if torch.cuda.is_available() else 'cpu' |
| |
| checkpoint = torch.load(checkpoint_path, map_location=device) |
| config = NeuroLexConfig(**checkpoint['config']) |
| model = NeuroLexV4(config) |
| model.load_state_dict(checkpoint['state_dict']) |
| model.eval() |
| model.to(device) |
| |
| print(f"Model loaded from {checkpoint_path}") |
| print(f" Parameters: {model.count_parameters():,}") |
| print(f" Device: {device}") |
| |
| return model, config, device |
|
|
|
|
| def generate_names(model, device, domain='tech', style='sharp', lang='english', |
| length=8, n=20, cfg_scale=2.5, temperature=0.9, |
| n_steps=80, odd_alpha=8.0): |
| """Generate names with given parameters.""" |
| |
| domain_id = DOMAIN_TO_ID.get(domain, 0) |
| style_id = STYLE_TO_ID.get(style, 0) |
| lang_id = LANG_TO_ID.get(lang, 0) |
| |
| names = model.generate( |
| domain_id=domain_id, |
| style_id=style_id, |
| lang_id=lang_id, |
| target_length=length, |
| batch_size=n, |
| cfg_scale=cfg_scale, |
| temperature=temperature, |
| n_steps=n_steps, |
| odd_alpha=odd_alpha, |
| device=str(device) |
| ) |
| |
| return names |
|
|
|
|
| def interactive_mode(model, device): |
| """Interactive generation mode.""" |
| print("\n" + "=" * 60) |
| print(" NEUROLEX v4 โ INTERACTIVE NAME GENERATOR") |
| print("=" * 60) |
| print(f"\n Available domains: {', '.join(DOMAINS)}") |
| print(f" Available styles: {', '.join(STYLES)}") |
| print(f" Available languages: {', '.join(LANGUAGES[:12])}...") |
| print(f"\n Type 'quit' to exit, 'help' for commands") |
| print("=" * 60) |
| |
| while True: |
| try: |
| print("\n") |
| domain = input(" Domain [tech]: ").strip() or 'tech' |
| if domain == 'quit': |
| break |
| if domain == 'help': |
| print(f"\n Domains: {', '.join(DOMAINS)}") |
| print(f" Styles: {', '.join(STYLES)}") |
| print(f" Languages: {', '.join(LANGUAGES)}") |
| continue |
| |
| style = input(" Style [sharp]: ").strip() or 'sharp' |
| lang = input(" Language [english]: ").strip() or 'english' |
| length = int(input(" Target length [8]: ").strip() or '8') |
| n = int(input(" How many [20]: ").strip() or '20') |
| temp = float(input(" Temperature [0.9]: ").strip() or '0.9') |
| cfg = float(input(" CFG scale [2.5]: ").strip() or '2.5') |
| |
| print(f"\n Generating {n} names...") |
| print(f" [{domain} / {style} / {lang} / len={length} / temp={temp} / cfg={cfg}]") |
| print() |
| |
| names = generate_names( |
| model, device, domain=domain, style=style, lang=lang, |
| length=length, n=n, cfg_scale=cfg, temperature=temp |
| ) |
| |
| unique = set(n.lower() for n in names) |
| |
| for i, name in enumerate(names, 1): |
| print(f" {i:3d}. {name}") |
| |
| print(f"\n Generated: {len(names)} | Unique: {len(unique)} ({len(unique)/max(len(names),1)*100:.0f}%)") |
| |
| except KeyboardInterrupt: |
| break |
| except Exception as e: |
| print(f" Error: {e}") |
| |
| print("\n Goodbye! ๐") |
|
|
|
|
| def showcase_mode(model, device): |
| """Generate a showcase across all categories.""" |
| print("\n" + "=" * 70) |
| print(" NEUROLEX v4 โ FULL SHOWCASE") |
| print("=" * 70) |
| |
| showcases = [ |
| ("๐ฅ๏ธ Tech Startup", 'tech', 'sharp', 'english', 8), |
| ("๐ฅ๏ธ Tech (Futuristic)", 'tech', 'futuristic', 'japanese', 7), |
| ("๐ Food Brand", 'food', 'warm', 'french', 7), |
| ("๐ฎ Gaming Channel", 'gaming', 'bold', 'english', 9), |
| ("๐ Luxury Brand", 'luxury', 'elegant', 'italian', 8), |
| ("๐ค AI Company", 'ai', 'sharp', 'latin', 7), |
| ("๐ฟ Health/Wellness", 'health', 'organic', 'hawaiian', 7), |
| ("๐ช Crypto Project", 'crypto', 'futuristic', 'greek', 8), |
| ("๐ต Music Platform", 'music', 'playful', 'spanish', 7), |
| ("โป๏ธ Eco Brand", 'eco', 'warm', 'swedish', 7), |
| ("๐ช Fitness App", 'fitness', 'bold', 'german', 8), |
| ("๐ Social Platform", 'social', 'playful', 'korean', 6), |
| ("โจ Beauty Brand", 'beauty', 'elegant', 'french', 8), |
| ("๐๏ธ Automotive", 'automotive', 'bold', 'italian', 8), |
| ("๐ Education", 'education', 'professional', 'latin', 8), |
| ("๐ Travel", 'travel', 'warm', 'hawaiian', 7), |
| ] |
| |
| all_names = [] |
| |
| for label, domain, style, lang, length in showcases: |
| names = generate_names( |
| model, device, domain=domain, style=style, lang=lang, |
| length=length, n=12, n_steps=80 |
| ) |
| all_names.extend(names) |
| |
| print(f"\n {label} ({style}, {lang}):") |
| for name in names[:8]: |
| print(f" โ {name}") |
| |
| |
| unique = set(n.lower() for n in all_names) |
| print(f"\n{'โ' * 70}") |
| print(f" ๐ TOTAL: {len(all_names)} names generated") |
| print(f" ๐ฏ UNIQUE: {len(unique)} ({len(unique)/len(all_names)*100:.1f}%)") |
| print(f" ๐ AVG LENGTH: {sum(len(n) for n in all_names)/len(all_names):.1f} chars") |
| print(f"{'โ' * 70}") |
|
|
|
|
| def main(): |
| parser = argparse.ArgumentParser(description='Generate names with NeuroLex v4') |
| parser.add_argument('--checkpoint', type=str, help='Path to model checkpoint') |
| parser.add_argument('--test', action='store_true', help='Test with untrained model') |
| parser.add_argument('--interactive', action='store_true', help='Interactive mode') |
| parser.add_argument('--showcase', action='store_true', help='Generate showcase across all categories') |
| parser.add_argument('--domain', type=str, default='tech') |
| parser.add_argument('--style', type=str, default='sharp') |
| parser.add_argument('--lang', type=str, default='english') |
| parser.add_argument('--length', type=int, default=8) |
| parser.add_argument('--n', type=int, default=20) |
| parser.add_argument('--cfg_scale', type=float, default=2.5) |
| parser.add_argument('--temperature', type=float, default=0.9) |
| parser.add_argument('--n_steps', type=int, default=80) |
| parser.add_argument('--odd_alpha', type=float, default=8.0) |
| parser.add_argument('--device', type=str, default='auto') |
| parser.add_argument('--size', type=str, default='base', choices=['tiny', 'small', 'base', 'large']) |
| args = parser.parse_args() |
| |
| |
| if args.checkpoint and os.path.exists(args.checkpoint): |
| model, config, device = load_model(args.checkpoint, args.device) |
| elif args.test: |
| print("Creating untrained model for testing...") |
| model, config = create_model(args.size) |
| device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') if args.device == 'auto' else torch.device(args.device) |
| model.to(device) |
| model.eval() |
| else: |
| |
| default_paths = [ |
| 'checkpoints/neurolex_v4_best.pt', |
| 'checkpoints/neurolex_v4_final.pt', |
| 'neurolex_v4_trained.pt', |
| ] |
| loaded = False |
| for path in default_paths: |
| if os.path.exists(path): |
| model, config, device = load_model(path, args.device) |
| loaded = True |
| break |
| |
| if not loaded: |
| print("No checkpoint found. Use --test for untrained model or --checkpoint <path>") |
| print(f"Searched: {default_paths}") |
| sys.exit(1) |
| |
| |
| if args.interactive: |
| interactive_mode(model, device) |
| elif args.showcase: |
| showcase_mode(model, device) |
| else: |
| |
| names = generate_names( |
| model, device, |
| domain=args.domain, style=args.style, lang=args.lang, |
| length=args.length, n=args.n, |
| cfg_scale=args.cfg_scale, temperature=args.temperature, |
| n_steps=args.n_steps, odd_alpha=args.odd_alpha |
| ) |
| |
| print(f"\n Generated {len(names)} names [{args.domain}/{args.style}/{args.lang}]:") |
| for i, name in enumerate(names, 1): |
| print(f" {i:3d}. {name}") |
| |
| unique = set(n.lower() for n in names) |
| print(f"\n Unique: {len(unique)}/{len(names)} ({len(unique)/max(len(names),1)*100:.0f}%)") |
|
|
|
|
| if __name__ == '__main__': |
| main() |
|
|