| """ |
| System Resource Detection Module |
| Detects VRAM, RAM, CPU cores and recommends appropriate ASR models |
| """ |
|
|
| import psutil |
| import torch |
| import os |
| import sys |
| from pathlib import Path |
|
|
| |
| if __name__ == "__main__": |
| sys.path.insert(0, str(Path(__file__).parent.parent)) |
|
|
| from config.config import ASR_MODEL_VRAM_MB, ASR_MODEL_RAM_MB |
|
|
| def get_gpu_memory(): |
| """Get total and available GPU memory in MB""" |
| try: |
| if torch.cuda.is_available(): |
| gpu_count = torch.cuda.device_count() |
| if gpu_count > 0: |
| |
| total_vram = torch.cuda.get_device_properties(0).total_memory |
| allocated_vram = torch.cuda.memory_allocated(0) |
| available_vram = total_vram - allocated_vram |
| |
| return { |
| 'total_mb': total_vram // 1024 // 1024, |
| 'available_mb': available_vram // 1024 // 1024, |
| 'allocated_mb': allocated_vram // 1024 // 1024 |
| } |
| except: |
| pass |
| |
| return {'total_mb': 0, 'available_mb': 0, 'allocated_mb': 0} |
|
|
| def get_system_memory(): |
| """Get total and available system RAM in MB""" |
| try: |
| memory = psutil.virtual_memory() |
| return { |
| 'total_mb': memory.total // 1024 // 1024, |
| 'available_mb': memory.available // 1024 // 1024, |
| 'used_mb': memory.used // 1024 // 1024 |
| } |
| except: |
| return {'total_mb': 0, 'available_mb': 0, 'used_mb': 0} |
|
|
| def get_cpu_cores(): |
| """Get number of CPU cores""" |
| try: |
| return psutil.cpu_count(logical=False) or psutil.cpu_count() |
| except: |
| return 1 |
|
|
| def estimate_tts_vram_usage(): |
| """Estimate VRAM usage by ChatterboxTTS (updated based on real usage)""" |
| return 5500 |
|
|
| def get_system_profile(): |
| """Get complete system resource profile""" |
| gpu_info = get_gpu_memory() |
| ram_info = get_system_memory() |
| cpu_cores = get_cpu_cores() |
| |
| |
| tts_vram_estimate = estimate_tts_vram_usage() |
| available_vram_after_tts = max(0, gpu_info['available_mb'] - tts_vram_estimate) |
| |
| return { |
| 'gpu': gpu_info, |
| 'ram': ram_info, |
| 'cpu_cores': cpu_cores, |
| 'available_vram_after_tts': available_vram_after_tts, |
| 'has_gpu': gpu_info['total_mb'] > 0 |
| } |
|
|
| def categorize_system(profile): |
| """Categorize system capabilities""" |
| gpu_total = profile['gpu']['total_mb'] |
| ram_total = profile['ram']['total_mb'] |
| cpu_cores = profile['cpu_cores'] |
| |
| |
| if gpu_total < 4000: |
| vram_category = "low" |
| elif gpu_total <= 12000: |
| vram_category = "medium" |
| else: |
| vram_category = "high" |
| |
| |
| if ram_total < 16000: |
| ram_category = "low" |
| elif ram_total <= 64000: |
| ram_category = "medium" |
| else: |
| ram_category = "high" |
| |
| |
| if cpu_cores < 6: |
| cpu_category = "low" |
| elif cpu_cores <= 16: |
| cpu_category = "medium" |
| else: |
| cpu_category = "high" |
| |
| return { |
| 'vram': vram_category, |
| 'ram': ram_category, |
| 'cpu': cpu_category |
| } |
|
|
| def get_safe_asr_models(profile): |
| """Get ASR models that can safely run on GPU with available VRAM""" |
| available_vram = profile['available_vram_after_tts'] |
| safe_models = [] |
| |
| for model, vram_req in ASR_MODEL_VRAM_MB.items(): |
| if vram_req <= available_vram: |
| safe_models.append(model) |
| |
| return safe_models |
|
|
| def get_safe_cpu_models(profile): |
| """Get ASR models that can safely run on CPU with available RAM""" |
| available_ram = profile['ram']['available_mb'] |
| safe_models = [] |
| |
| for model, ram_req in ASR_MODEL_RAM_MB.items(): |
| if ram_req <= available_ram: |
| safe_models.append(model) |
| |
| return safe_models |
|
|
| def recommend_asr_models(profile): |
| """Recommend Safe/Moderate/Insane ASR model configurations""" |
| categories = categorize_system(profile) |
| safe_gpu_models = get_safe_asr_models(profile) |
| safe_cpu_models = get_safe_cpu_models(profile) |
| |
| recommendations = {} |
| |
| |
| model_priority = ["large-v3", "large", "large-v2", "medium", "small", "base", "tiny"] |
| |
| |
| safe_gpu = None |
| safe_cpu = None |
| |
| for model in reversed(model_priority): |
| if model in safe_gpu_models and not safe_gpu: |
| safe_gpu = model |
| if model in safe_cpu_models and not safe_cpu: |
| safe_cpu = model |
| if safe_gpu and safe_cpu: |
| break |
| |
| |
| moderate_gpu = None |
| moderate_cpu = None |
| |
| |
| safe_idx = model_priority.index(safe_gpu) if safe_gpu else len(model_priority) |
| moderate_idx = max(0, safe_idx - 2) |
| |
| for i in range(moderate_idx, len(model_priority)): |
| model = model_priority[i] |
| if model in safe_gpu_models and not moderate_gpu: |
| moderate_gpu = model |
| if model in safe_cpu_models and not moderate_cpu: |
| moderate_cpu = model |
| if moderate_gpu and moderate_cpu: |
| break |
| |
| |
| insane_gpu = None |
| insane_cpu = None |
| |
| |
| for model in model_priority: |
| if model in safe_gpu_models and not insane_gpu: |
| insane_gpu = model |
| if model in safe_cpu_models and not insane_cpu: |
| insane_cpu = model |
| if insane_gpu and insane_cpu: |
| break |
| |
| |
| recommendations['safe'] = { |
| 'primary': {'model': safe_gpu or safe_cpu, 'device': 'gpu' if safe_gpu else 'cpu'}, |
| 'fallback': {'model': safe_cpu, 'device': 'cpu'} |
| } |
| |
| recommendations['moderate'] = { |
| 'primary': {'model': moderate_gpu or moderate_cpu, 'device': 'gpu' if moderate_gpu else 'cpu'}, |
| 'fallback': {'model': moderate_cpu, 'device': 'cpu'} |
| } |
| |
| recommendations['insane'] = { |
| 'primary': {'model': insane_gpu or insane_cpu, 'device': 'gpu' if insane_gpu else 'cpu'}, |
| 'fallback': {'model': insane_cpu, 'device': 'cpu'} |
| } |
| |
| return recommendations |
|
|
| def print_system_summary(profile): |
| """Print a human-readable system summary""" |
| categories = categorize_system(profile) |
| |
| print(f"🖥️ System Profile:") |
| print(f" VRAM: {profile['gpu']['total_mb']:,}MB total, {profile['available_vram_after_tts']:,}MB available after TTS ({categories['vram']} class)") |
| print(f" RAM: {profile['ram']['total_mb']:,}MB total, {profile['ram']['available_mb']:,}MB available ({categories['ram']} class)") |
| print(f" CPU: {profile['cpu_cores']} cores ({categories['cpu']} class)") |
| |
| if not profile['has_gpu']: |
| print(f" ⚠️ No CUDA GPU detected - ASR will run on CPU only") |
|
|
| if __name__ == "__main__": |
| |
| profile = get_system_profile() |
| print_system_summary(profile) |
| |
| recommendations = recommend_asr_models(profile) |
| print(f"\nASR Model Recommendations:") |
| for level, config in recommendations.items(): |
| primary = config['primary'] |
| fallback = config['fallback'] |
| print(f"🟢 {level.upper()}: {primary['model']} ({primary['device']}) + {fallback['model']} (cpu fallback)") |