Optimización específica para hardware AMD - Detección y configuración automática
Objetivo
Crear un sistema de detección automática de hardware AMD y optimizar la aplicación de transcripción específicamente para procesadores y GPUs AMD.
Contexto
- Sistema confirmado: No compatible con Lightning Whisper MLX (solo Apple Silicon)
- Hardware: Procesador y GPU AMD (modelos por determinar)
- Enfoque: Optimización máxima para arquitectura AMD
- Estrategia: whisper.cpp + optimizaciones AMD específicas
Scripts de Detección de Hardware
1. Script Principal de Detección AMD
#!/usr/bin/env python3
"""
Detección completa de hardware AMD y optimización automática
"""
import subprocess
import platform
import psutil
import re
import json
from pathlib import Path
class AMDHardwareDetector:
def __init__(self):
self.system_info = {}
self.optimization_config = {}
def detect_cpu(self):
"""Detectar CPU AMD específico"""
print("🔍 Detectando CPU AMD...")
try:
# Información básica del CPU
cpu_info = {
"brand": platform.processor(),
"physical_cores": psutil.cpu_count(logical=False),
"logical_cores": psutil.cpu_count(logical=True),
"max_frequency": psutil.cpu_freq().max if psutil.cpu_freq() else "N/A"
}
# Detectar modelo específico AMD
if platform.system() == "Linux":
try:
# Leer /proc/cpuinfo para detalles específicos
with open('/proc/cpuinfo', 'r') as f:
cpuinfo = f.read()
# Extraer información AMD específica
model_match = re.search(r'model name\s*:\s*(.+)', cpuinfo)
if model_match:
cpu_info["model_name"] = model_match.group(1).strip()
# Detectar arquitectura AMD (Zen, Zen2, Zen3, Zen4)
model_name = cpu_info.get("model_name", "").lower()
if "ryzen" in model_name:
if "5000" in model_name or "6000" in model_name:
cpu_info["architecture"] = "Zen3"
elif "4000" in model_name:
cpu_info["architecture"] = "Zen2"
elif "3000" in model_name:
cpu_info["architecture"] = "Zen2"
elif "2000" in model_name:
cpu_info["architecture"] = "Zen+"
elif "1000" in model_name:
cpu_info["architecture"] = "Zen"
else:
cpu_info["architecture"] = "Unknown Zen"
# Detectar caché L3
cache_match = re.search(r'cache size\s*:\s*(\d+)\s*KB', cpuinfo)
if cache_match:
cpu_info["cache_size_kb"] = int(cache_match.group(1))
except Exception as e:
print(f"⚠️ Error leyendo /proc/cpuinfo: {e}")
# Usar lscpu si está disponible
try:
lscpu_output = subprocess.check_output(['lscpu'], text=True)
# Extraer información adicional
for line in lscpu_output.split('\n'):
if 'Model name:' in line:
cpu_info["lscpu_model"] = line.split(':', 1)[1].strip()
elif 'CPU family:' in line:
cpu_info["cpu_family"] = line.split(':', 1)[1].strip()
elif 'Stepping:' in line:
cpu_info["stepping"] = line.split(':', 1)[1].strip()
elif 'L3 cache:' in line:
cpu_info["l3_cache"] = line.split(':', 1)[1].strip()
except (subprocess.CalledProcessError, FileNotFoundError):
print("⚠️ lscpu no disponible")
self.system_info["cpu"] = cpu_info
print(f"✅ CPU detectado: {cpu_info.get('model_name', 'AMD CPU')}")
except Exception as e:
print(f"❌ Error detectando CPU: {e}")
def detect_gpu(self):
"""Detectar GPU AMD específica"""
print("🔍 Detectando GPU AMD...")
gpu_info = {}
try:
# Usar lspci para detectar GPU AMD
lspci_output = subprocess.check_output(['lspci', '-v'], text=True)
amd_gpus = []
for line in lspci_output.split('\n'):
if 'VGA compatible controller' in line and ('AMD' in line or 'ATI' in line):
amd_gpus.append(line.strip())
if amd_gpus:
gpu_info["detected_gpus"] = amd_gpus
# Extraer modelo específico
for gpu in amd_gpus:
if "RX" in gpu:
rx_match = re.search(r'RX\s*(\d+)', gpu)
if rx_match:
gpu_info["series"] = f"RX {rx_match.group(1)}"
elif "Vega" in gpu:
gpu_info["series"] = "Vega"
elif "RDNA" in gpu:
gpu_info["architecture"] = "RDNA"
except (subprocess.CalledProcessError, FileNotFoundError):
print("⚠️ lspci no disponible")
# Intentar con glxinfo si está disponible
try:
glxinfo_output = subprocess.check_output(['glxinfo', '-B'], text=True)
for line in glxinfo_output.split('\n'):
if 'OpenGL renderer string:' in line:
gpu_info["opengl_renderer"] = line.split(':', 1)[1].strip()
elif 'OpenGL vendor string:' in line:
gpu_info["vendor"] = line.split(':', 1)[1].strip()
except (subprocess.CalledProcessError, FileNotFoundError):
print("⚠️ glxinfo no disponible")
# Verificar drivers AMD
try:
# Verificar módulos del kernel AMD
lsmod_output = subprocess.check_output(['lsmod'], text=True)
amd_modules = []
for line in lsmod_output.split('\n'):
if any(module in line for module in ['amdgpu', 'radeon', 'fglrx']):
amd_modules.append(line.split()[0])
if amd_modules:
gpu_info["loaded_drivers"] = amd_modules
except (subprocess.CalledProcessError, FileNotFoundError):
print("⚠️ lsmod no disponible")
self.system_info["gpu"] = gpu_info
if gpu_info:
print(f"✅ GPU AMD detectada: {gpu_info.get('series', 'AMD GPU')}")
else:
print("⚠️ No se detectó GPU AMD específica")
def detect_memory(self):
"""Detectar configuración de memoria"""
print("🔍 Detectando memoria del sistema...")
memory_info = {
"total_gb": round(psutil.virtual_memory().total / (1024**3), 2),
"available_gb": round(psutil.virtual_memory().available / (1024**3), 2),
"used_percent": psutil.virtual_memory().percent
}
# Detectar velocidad de RAM si es posible
try:
dmidecode_output = subprocess.check_output(['sudo', 'dmidecode', '-t', 'memory'], text=True)
speeds = re.findall(r'Speed:\s*(\d+)\s*MT/s', dmidecode_output)
if speeds:
memory_info["ram_speed_mhz"] = max([int(speed) for speed in speeds])
except (subprocess.CalledProcessError, FileNotFoundError, PermissionError):
print("⚠️ No se puede acceder a dmidecode (requiere sudo)")
self.system_info["memory"] = memory_info
print(f"✅ Memoria: {memory_info['total_gb']}GB total")
def generate_amd_optimizations(self):
"""Generar configuraciones optimizadas para AMD"""
print("⚙️ Generando optimizaciones AMD...")
cpu_info = self.system_info.get("cpu", {})
gpu_info = self.system_info.get("gpu", {})
memory_info = self.system_info.get("memory", {})
# Optimizaciones para whisper.cpp en AMD
whisper_optimizations = {
"threads": min(cpu_info.get("physical_cores", 4), 8), # Óptimo para AMD
"processors": 1,
"use_gpu": len(gpu_info.get("loaded_drivers", [])) > 0,
"model_size": "base", # Empezar conservador
}
# Ajustar según arquitectura Zen
architecture = cpu_info.get("architecture", "")
if "Zen3" in architecture:
whisper_optimizations.update({
"threads": cpu_info.get("physical_cores", 8),
"model_size": "small", # Zen3 puede manejar modelos más grandes
"enable_avx2": True,
"batch_size": 1
})
elif "Zen2" in architecture:
whisper_optimizations.update({
"threads": max(4, cpu_info.get("physical_cores", 4) - 2),
"enable_avx2": True,
"batch_size": 1
})
# Ajustar según memoria disponible
total_memory = memory_info.get("total_gb", 8)
if total_memory >= 16:
whisper_optimizations["model_size"] = "small"
if total_memory >= 32:
whisper_optimizations["model_size"] = "medium"
# Optimizaciones específicas para GPU AMD
if gpu_info.get("series"):
gpu_series = gpu_info.get("series", "")
if "RX" in gpu_series:
rx_number = int(re.search(r'\d+', gpu_series).group()) if re.search(r'\d+', gpu_series) else 0
if rx_number >= 6000: # RX 6000 series o superior
whisper_optimizations.update({
"use_gpu": True,
"gpu_acceleration": "opencl",
"model_size": "small"
})
self.optimization_config = {
"whisper_cpp": whisper_optimizations,
"system_tweaks": {
"cpu_governor": "performance",
"disable_cpu_mitigations": False, # Mantener seguridad
"huge_pages": total_memory >= 16
}
}
print("✅ Optimizaciones generadas")
def save_system_profile(self):
"""Guardar perfil del sistema para referencia"""
profile_data = {
"detection_date": "2025-06-14",
"system_info": self.system_info,
"optimizations": self.optimization_config
}
profile_path = Path("system_profile_amd.json")
with open(profile_path, 'w') as f:
json.dump(profile_data, f, indent=2)
print(f"💾 Perfil guardado en: {profile_path}")
return profile_path
def generate_config_files(self):
"""Generar archivos de configuración optimizados"""
# Configuración para whisper.cpp
whisper_config = f"""# Configuración optimizada para AMD
whisper_cpp_amd:
binary_path: "whisper"
model_size: "{self.optimization_config['whisper_cpp']['model_size']}"
threads: {self.optimization_config['whisper_cpp']['threads']}
processors: {self.optimization_config['whisper_cpp']['processors']}
use_gpu: {self.optimization_config['whisper_cpp']['use_gpu']}
language_detection: true
# Optimizaciones AMD específicas
amd_optimizations:
cpu_architecture: "{self.system_info['cpu'].get('architecture', 'Unknown')}"
physical_cores: {self.system_info['cpu'].get('physical_cores', 4)}
total_memory_gb: {self.system_info['memory'].get('total_gb', 8)}
enable_avx2: {self.optimization_config['whisper_cpp'].get('enable_avx2', False)}
"""
config_path = Path("config/whisper_amd_optimized.yaml")
config_path.parent.mkdir(exist_ok=True)
with open(config_path, 'w') as f:
f.write(whisper_config)
print(f"📄 Configuración AMD guardada en: {config_path}")
return config_path
def run_full_detection():
"""Ejecutar detección completa del sistema AMD"""
print("🔧 DETECCIÓN DE HARDWARE AMD")
print("=" * 50)
detector = AMDHardwareDetector()
# Ejecutar todas las detecciones
detector.detect_cpu()
detector.detect_gpu()
detector.detect_memory()
detector.generate_amd_optimizations()
# Guardar resultados
profile_path = detector.save_system_profile()
config_path = detector.generate_config_files()
# Mostrar resumen
print("\n" + "=" * 50)
print("📊 RESUMEN DEL SISTEMA AMD")
print("=" * 50)
cpu_info = detector.system_info.get("cpu", {})
gpu_info = detector.system_info.get("gpu", {})
memory_info = detector.system_info.get("memory", {})
print(f"🖥️ CPU: {cpu_info.get('model_name', 'AMD CPU')}")
print(f"🏗️ Arquitectura: {cpu_info.get('architecture', 'Desconocida')}")
print(f"🔢 Núcleos: {cpu_info.get('physical_cores', 'N/A')} físicos / {cpu_info.get('logical_cores', 'N/A')} lógicos")
print(f"🎮 GPU: {gpu_info.get('series', 'AMD GPU') if gpu_info else 'No detectada'}")
print(f"💾 RAM: {memory_info.get('total_gb', 'N/A')} GB")
# Mostrar optimizaciones recomendadas
whisper_opt = detector.optimization_config.get("whisper_cpp", {})
print(f"\n⚡ OPTIMIZACIONES RECOMENDADAS:")
print(f" 📊 Modelo Whisper: {whisper_opt.get('model_size', 'base')}")
print(f" 🧵 Threads: {whisper_opt.get('threads', 4)}")
print(f" 🎮 GPU: {'Habilitada' if whisper_opt.get('use_gpu') else 'Deshabilitada'}")
return detector
if __name__ == "__main__":
detector = run_full_detection()
print(f"\n🎯 PRÓXIMOS PASOS:")
print("1. Instalar whisper.cpp con optimizaciones AMD")
print("2. Aplicar configuración generada")
print("3. Ejecutar benchmarks para verificar rendimiento")
print("4. Integrar en ProcessingAgent")
2. Script de Instalación Optimizada para AMD
#!/bin/bash
# install_whisper_amd_optimized.sh
echo "🔧 Instalación optimizada de whisper.cpp para AMD"
echo "=================================================="
# Detectar distribución
if [ -f /etc/os-release ]; then
. /etc/os-release
OS=$NAME
fi
echo "🐧 Distribución detectada: $OS"
# Instalar dependencias según la distribución
if [[ "$OS" == *"Ubuntu"* ]] || [[ "$OS" == *"Debian"* ]]; then
echo "📦 Instalando dependencias para Ubuntu/Debian..."
sudo apt update
sudo apt install -y build-essential cmake git pkg-config
sudo apt install -y libopenblas-dev libomp-dev
elif [[ "$OS" == *"Arch"* ]] || [[ "$OS" == *"Manjaro"* ]]; then
echo "📦 Instalando dependencias para Arch/Manjaro..."
sudo pacman -S --noconfirm base-devel cmake git pkg-config
sudo pacman -S --noconfirm openblas openmp
elif [[ "$OS" == *"Fedora"* ]]; then
echo "📦 Instalando dependencias para Fedora..."
sudo dnf install -y gcc-c++ cmake git pkg-config
sudo dnf install -y openblas-devel libomp-devel
fi
# Clonar whisper.cpp
echo "📥 Clonando whisper.cpp..."
git clone https://github.com/ggerganov/whisper.cpp.git
cd whisper.cpp
# Compilar con optimizaciones AMD
echo "🔨 Compilando con optimizaciones AMD..."
mkdir build
cd build
# Configurar CMake con optimizaciones para AMD
cmake -DCMAKE_BUILD_TYPE=Release \
-DWHISPER_OPENBLAS=ON \
-DWHISPER_OPENMP=ON \
-DCMAKE_C_FLAGS="-march=native -mtune=native -O3" \
-DCMAKE_CXX_FLAGS="-march=native -mtune=native -O3" \
..
# Compilar usando todos los núcleos disponibles
make -j$(nproc)
echo "✅ whisper.cpp compilado con optimizaciones AMD"
# Instalar globalmente
sudo cp bin/whisper /usr/local/bin/
sudo cp bin/main /usr/local/bin/whisper-main
echo "🎉 Instalación completada!"
echo "📍 Ubicación: /usr/local/bin/whisper"
3. Script de Benchmark AMD
#!/usr/bin/env python3
"""
Benchmark específico para sistemas AMD
"""
import time
import subprocess
import json
from pathlib import Path
def benchmark_amd_whisper():
"""Ejecutar benchmark optimizado para AMD"""
# Cargar configuración del sistema
profile_path = Path("system_profile_amd.json")
if not profile_path.exists():
print("❌ Ejecuta primero el detector AMD")
return
with open(profile_path) as f:
profile = json.load(f)
cpu_cores = profile["system_info"]["cpu"].get("physical_cores", 4)
# Diferentes configuraciones para probar
test_configs = [
{"threads": 2, "model": "base", "name": "Conservador"},
{"threads": cpu_cores // 2, "model": "base", "name": "Balanceado"},
{"threads": cpu_cores, "model": "base", "name": "Máximo CPU"},
{"threads": cpu_cores, "model": "small", "name": "Modelo Grande"}
]
# Crear audio de prueba si no existe
if not Path("test_audio.wav").exists():
print("🎵 Creando audio de prueba...")
subprocess.run([
"espeak-ng", "-s", "150", "-v", "es",
"-w", "test_audio.wav",
"Esta es una prueba de rendimiento para procesadores AMD con whisper punto cpp"
])
results = []
for config in test_configs:
print(f"\n🧪 Probando configuración: {config['name']}")
print(f" Threads: {config['threads']}, Modelo: {config['model']}")
start_time = time.time()
try:
result = subprocess.run([
"whisper", "test_audio.wav",
"--threads", str(config["threads"]),
"--model", config["model"],
"--language", "es",
"--output_format", "txt"
], capture_output=True, text=True, timeout=120)
end_time = time.time()
processing_time = end_time - start_time
if result.returncode == 0:
results.append({
"config": config,
"processing_time": processing_time,
"success": True
})
print(f" ⏱️ Tiempo: {processing_time:.2f}s")
else:
print(f" ❌ Error: {result.stderr}")
except subprocess.TimeoutExpired:
print(f" ⏰ Timeout (>120s)")
# Mostrar resultados
print("\n📊 RESULTADOS DEL BENCHMARK AMD")
print("=" * 40)
if results:
best_config = min(results, key=lambda x: x["processing_time"])
for result in sorted(results, key=lambda x: x["processing_time"]):
config = result["config"]
time_taken = result["processing_time"]
marker = "🏆" if result == best_config else "📈"
print(f"{marker} {config['name']}: {time_taken:.2f}s")
print(f" Threads: {config['threads']}, Modelo: {config['model']}")
print(f"\n🎯 CONFIGURACIÓN ÓPTIMA DETECTADA:")
print(f" {best_config['config']['name']}")
print(f" Threads: {best_config['config']['threads']}")
print(f" Modelo: {best_config['config']['model']}")
print(f" Tiempo: {best_config['processing_time']:.2f}s")
# Guardar configuración óptima
optimal_config = {
"optimal_threads": best_config['config']['threads'],
"optimal_model": best_config['config']['model'],
"benchmark_time": best_config['processing_time'],
"all_results": results
}
with open("amd_benchmark_results.json", "w") as f:
json.dump(optimal_config, f, indent=2)
print("💾 Resultados guardados en: amd_benchmark_results.json")
else:
print("❌ No se obtuvieron resultados válidos")
if __name__ == "__main__":
benchmark_amd_whisper()
Archivos a Crear
detect_amd_hardware.py - Detección completa de hardware
install_whisper_amd_optimized.sh - Instalación optimizada
benchmark_amd_whisper.py - Benchmark específico para AMD
config/whisper_amd_optimized.yaml - Configuración auto-generada
Próximos Pasos
- Ejecutar detección:
python detect_amd_hardware.py
- Instalar whisper.cpp optimizado:
bash install_whisper_amd_optimized.sh
- Ejecutar benchmark:
python benchmark_amd_whisper.py
- Integrar configuración óptima en ProcessingAgent
Optimizaciones AMD Específicas
CPU (Zen Architecture)
- Compilación con
-march=native -mtune=native
- Uso óptimo de threads basado en arquitectura Zen
- Aprovechamiento de instrucciones AVX2
- OpenMP para paralelización
GPU (Radeon)
- Soporte OpenCL para aceleración GPU
- Configuración automática según serie RX
- Fallback inteligente CPU/GPU
Memoria
- Configuración de modelo según RAM disponible
- Huge pages para sistemas con >16GB RAM
- Optimización de caché según CPU
Este enfoque te dará el máximo rendimiento posible en tu sistema AMD específico.
Optimización específica para hardware AMD - Detección y configuración automática
Objetivo
Crear un sistema de detección automática de hardware AMD y optimizar la aplicación de transcripción específicamente para procesadores y GPUs AMD.
Contexto
Scripts de Detección de Hardware
1. Script Principal de Detección AMD
2. Script de Instalación Optimizada para AMD
3. Script de Benchmark AMD
Archivos a Crear
detect_amd_hardware.py- Detección completa de hardwareinstall_whisper_amd_optimized.sh- Instalación optimizadabenchmark_amd_whisper.py- Benchmark específico para AMDconfig/whisper_amd_optimized.yaml- Configuración auto-generadaPróximos Pasos
python detect_amd_hardware.pybash install_whisper_amd_optimized.shpython benchmark_amd_whisper.pyOptimizaciones AMD Específicas
CPU (Zen Architecture)
-march=native -mtune=nativeGPU (Radeon)
Memoria
Este enfoque te dará el máximo rendimiento posible en tu sistema AMD específico.