Skip to content

Paso 3: Descarga y optimización de modelos Whisper para AMD A4-9125 #8

Description

@Charly-bite

Paso 3: Descarga y optimización de modelos Whisper para AMD A4-9125

Estado Actual ✅

  • whisper-amd instalado y funcionando
  • OpenCL habilitado para Radeon R3
  • OpenBLAS optimizado para matemáticas
  • Configuración de 2 threads para A4-9125

Script de Descarga de Modelos Optimizados

#!/bin/bash
# download_whisper_models_amd_a4_9125.sh

echo "📥 DESCARGANDO MODELOS WHISPER OPTIMIZADOS PARA AMD A4-9125"
echo "=========================================================="

# Crear directorio para modelos
MODELS_DIR="$HOME/whisper_models"
mkdir -p "$MODELS_DIR"
cd "$MODELS_DIR"

echo "📁 Directorio de modelos: $MODELS_DIR"

# Función para descargar y verificar modelo
download_model() {
    local model_name="$1"
    local model_file="ggml-${model_name}.bin"
    local model_url="https://huggingface.co/ggerganov/whisper.cpp/resolve/main/${model_file}"
    
    echo -e "\n📦 Descargando modelo: $model_name"
    echo "📍 URL: $model_url"
    
    if [ ! -f "$model_file" ]; then
        echo "⬇️  Descargando $model_file..."
        if wget -c "$model_url" -O "$model_file.tmp"; then
            mv "$model_file.tmp" "$model_file"
            echo "$model_name descargado exitosamente"
            
            # Mostrar información del archivo
            size=$(stat -c%s "$model_file" 2>/dev/null || echo "0")
            echo "📊 Tamaño: $((size/1024/1024))MB"
            
            return 0
        else
            echo "❌ Error descargando $model_name"
            rm -f "$model_file.tmp"
            return 1
        fi
    else
        echo "$model_name ya existe"
        size=$(stat -c%s "$model_file" 2>/dev/null || echo "0")
        echo "📊 Tamaño: $((size/1024/1024))MB"
        return 0
    fi
}

# Verificar conectividad
echo "🌐 Verificando conectividad..."
if ! ping -c 1 huggingface.co >/dev/null 2>&1; then
    echo "❌ Sin conexión a huggingface.co"
    echo "💡 Verifica tu conexión a internet"
    exit 1
fi
echo "✅ Conexión verificada"

# Modelos recomendados para AMD A4-9125 (en orden de prioridad)
echo -e "\n🎯 MODELOS RECOMENDADOS PARA AMD A4-9125:"
echo "========================================="

# 1. Modelo TINY (más rápido, ideal para pruebas)
echo -e "\n1️⃣ MODELO TINY (39MB) - Más rápido"
echo "   💨 Velocidad: Excelente en A4-9125"
echo "   🎯 Precisión: Buena para español/inglés"
echo "   🔧 Uso: Pruebas y transcripción rápida"
download_model "tiny"

# 2. Modelo BASE (más equilibrado)
echo -e "\n2️⃣ MODELO BASE (142MB) - Equilibrado"
echo "   💨 Velocidad: Buena en A4-9125"
echo "   🎯 Precisión: Muy buena para español/inglés"
echo "   🔧 Uso: Producción recomendada"
download_model "base"

# 3. Modelo SMALL (si tienes paciencia)
echo -e "\n3️⃣ MODELO SMALL (244MB) - Mejor precisión"
echo "   💨 Velocidad: Aceptable en A4-9125"
echo "   🎯 Precisión: Excelente"
echo "   🔧 Uso: Cuando la precisión es crítica"
read -p "¿Descargar modelo SMALL? (puede ser lento en A4-9125) [s/N]: " -n 1 -r
echo
if [[ $REPLY =~ ^[Ss]$ ]]; then
    download_model "small"
else
    echo "⏭️ Saltando modelo SMALL"
fi

echo -e "\n📋 RESUMEN DE MODELOS DESCARGADOS:"
echo "================================="
ls -lh *.bin 2>/dev/null || echo "No se descargaron modelos"

echo -e "\n🧪 CONFIGURANDO VARIABLES DE ENTORNO:"
# Crear script de configuración
cat > "$HOME/.whisper_amd_config" << EOF
# Configuración whisper-amd para AMD A4-9125
export WHISPER_MODELS_DIR="$MODELS_DIR"
export WHISPER_DEFAULT_MODEL="base"
export WHISPER_THREADS=2
export WHISPER_PROCESSORS=1

# Aliases útiles
alias whisper-tiny="whisper-amd -m \$WHISPER_MODELS_DIR/ggml-tiny.bin -t 2"
alias whisper-base="whisper-amd -m \$WHISPER_MODELS_DIR/ggml-base.bin -t 2"
alias whisper-small="whisper-amd -m \$WHISPER_MODELS_DIR/ggml-small.bin -t 2"

# Función para transcripción rápida
transcribe() {
    local audio_file="\$1"
    local model="\${2:-base}"
    local output_dir="\${3:-.}"
    
    if [ ! -f "\$audio_file" ]; then
        echo "❌ Archivo no encontrado: \$audio_file"
        return 1
    fi
    
    echo "🎙️ Transcribiendo: \$audio_file"
    echo "🧠 Modelo: \$model"
    echo "📁 Salida: \$output_dir"
    
    whisper-amd \\
        -m "\$WHISPER_MODELS_DIR/ggml-\$model.bin" \\
        -t 2 \\
        -p 1 \\
        -osrt \\
        -ovtt \\
        -otxt \\
        "\$audio_file"
}
EOF

echo "✅ Configuración guardada en ~/.whisper_amd_config"

# Cargar configuración en el shell actual
source "$HOME/.whisper_amd_config"

echo -e "\n🧪 PRUEBA BÁSICA DE MODELOS:"
echo "============================"

# Verificar que whisper-amd puede cargar los modelos
for model in tiny base small; do
    model_file="$MODELS_DIR/ggml-${model}.bin"
    if [ -f "$model_file" ]; then
        echo "🧪 Probando modelo $model..."
        if timeout 10s whisper-amd -m "$model_file" --help >/dev/null 2>&1; then
            echo "✅ Modelo $model verificado"
        else
            echo "⚠️ Modelo $model no responde (puede ser normal)"
        fi
    fi
done

echo -e "\n🎉 ¡MODELOS INSTALADOS EXITOSAMENTE!"
echo "📊 ESTADÍSTICAS FINALES:"
echo "========================"
total_size=$(du -sh "$MODELS_DIR" 2>/dev/null | cut -f1)
model_count=$(ls -1 "$MODELS_DIR"/*.bin 2>/dev/null | wc -l)
echo "📁 Directorio: $MODELS_DIR"
echo "📦 Modelos descargados: $model_count"
echo "💾 Espacio usado: $total_size"

echo -e "\n🚀 SIGUIENTE PASO:"
echo "Ejecutar pruebas de rendimiento y integración con ProcessingAgent"

echo -e "\n💡 PARA USAR LOS MODELOS:"
echo "source ~/.whisper_amd_config"
echo "transcribe archivo_audio.wav tiny"

Script de Pruebas de Rendimiento

#!/bin/bash
# benchmark_whisper_amd_a4_9125.sh

echo "⚡ BENCHMARK WHISPER-AMD EN AMD A4-9125"
echo "======================================"

source "$HOME/.whisper_amd_config" 2>/dev/null || {
    echo "❌ Configuración no encontrada. Ejecuta primero download_whisper_models_amd_a4_9125.sh"
    exit 1
}

# Crear audio de prueba
echo "🎙️ Creando audio de prueba..."
TEST_AUDIO="/tmp/test_whisper_amd.wav"

# Generar 30 segundos de audio sintético (tono + silencio)
if command -v ffmpeg >/dev/null 2>&1; then
    ffmpeg -f lavfi -i "sine=frequency=440:duration=2" \
           -f lavfi -i "anullsrc=channel_layout=mono:sample_rate=16000:duration=3" \
           -filter_complex "[0:a][1:a]concat=n=2:v=0:a=1[out]" \
           -map "[out]" -ac 1 -ar 16000 "$TEST_AUDIO" -y 2>/dev/null
    echo "✅ Audio de prueba creado: $TEST_AUDIO"
else
    echo "⚠️ ffmpeg no disponible, usando archivo existente o creando silencio"
    # Crear archivo de silencio con sox si está disponible
    if command -v sox >/dev/null 2>&1; then
        sox -n -r 16000 -c 1 "$TEST_AUDIO" trim 0.0 5.0
    else
        echo "❌ No se puede crear audio de prueba"
        echo "💡 Instala ffmpeg o sox, o proporciona un archivo .wav"
        exit 1
    fi
fi

echo -e "\n⏱️ BENCHMARK DE RENDIMIENTO:"
echo "============================"

# Función de benchmark
run_benchmark() {
    local model="$1"
    local model_file="$WHISPER_MODELS_DIR/ggml-${model}.bin"
    
    if [ ! -f "$model_file" ]; then
        echo "❌ Modelo $model no encontrado"
        return 1
    fi
    
    echo -e "\n🧠 Probando modelo: $model"
    echo "📊 Archivo: $(basename "$model_file")"
    echo "💾 Tamaño: $(stat -c%s "$model_file" 2>/dev/null | awk '{print int($1/1024/1024)"MB"}')"
    
    # Medir tiempo de transcripción
    start_time=$(date +%s.%N)
    
    # Ejecutar transcripción
    if timeout 120s whisper-amd \
        -m "$model_file" \
        -t 2 \
        -p 1 \
        --output-txt \
        --output-dir "/tmp" \
        "$TEST_AUDIO" >/dev/null 2>&1; then
        
        end_time=$(date +%s.%N)
        duration=$(echo "$end_time - $start_time" | bc 2>/dev/null || echo "N/A")
        
        echo "✅ Transcripción exitosa"
        echo "⏱️ Tiempo: ${duration}s"
        
        # Calcular factor de tiempo real
        audio_duration=5 # segundos de audio de prueba
        if [ "$duration" != "N/A" ]; then
            factor=$(echo "scale=2; $duration / $audio_duration" | bc 2>/dev/null || echo "N/A")
            echo "🚀 Factor tiempo real: ${factor}x"
            
            if (( $(echo "$factor < 1.0" | bc -l 2>/dev/null || echo 0) )); then
                echo "🎯 ¡Más rápido que tiempo real!"
            elif (( $(echo "$factor < 2.0" | bc -l 2>/dev/null || echo 0) )); then
                echo "✅ Rendimiento excelente"
            elif (( $(echo "$factor < 4.0" | bc -l 2>/dev/null || echo 0) )); then
                echo "👍 Rendimiento bueno"
            else
                echo "⚠️ Rendimiento aceptable"
            fi
        fi
        
        # Mostrar resultado si existe
        result_file="/tmp/$(basename "$TEST_AUDIO" .wav).txt"
        if [ -f "$result_file" ]; then
            echo "📝 Resultado: $(cat "$result_file" | head -c 100)..."
        fi
        
    else
        echo "❌ Transcripción falló o timeout"
    fi
}

# Ejecutar benchmarks
for model in tiny base small; do
    if [ -f "$WHISPER_MODELS_DIR/ggml-${model}.bin" ]; then
        run_benchmark "$model"
    fi
done

echo -e "\n🎯 RECOMENDACIONES PARA AMD A4-9125:"
echo "===================================="
echo "🥇 Modelo recomendado: BASE (mejor equilibrio velocidad/precisión)"
echo "🏃 Modelo más rápido: TINY (para transcripción en tiempo real)"
echo "🎯 Modelo más preciso: SMALL (si no importa velocidad)"
echo "🧵 Configuración óptima: 2 threads, 1 processor"

echo -e "\n💡 COMANDOS ÚTILES:"
echo "=================="
echo "# Transcripción rápida:"
echo "transcribe mi_audio.wav tiny"
echo ""
echo "# Transcripción balanceada:"
echo "transcribe mi_audio.wav base"
echo ""
echo "# Con idioma específico:"
echo "whisper-amd -m \$WHISPER_MODELS_DIR/ggml-base.bin -l es mi_audio.wav"

# Limpiar archivos temporales
rm -f "$TEST_AUDIO" /tmp/test_whisper_amd.txt 2>/dev/null

echo -e "\n🎉 ¡BENCHMARK COMPLETADO!"

Integración con ProcessingAgent

# Actualización para agents/processing_agent.py

def transcribe_audio_optimized_amd(self, audio_filepath: Path, output_filename: str = None, language: str = None) -> dict:
    """
    Transcripción optimizada para AMD A4-9125 usando whisper-amd compilado.
    """
    if not audio_filepath.exists():
        print(f"[{self.agent_name}] Audio file not found: {audio_filepath}")
        return None

    print(f"[{self.agent_name}] Starting AMD-optimized transcription for {audio_filepath.name}...")
    
    # Configuración óptima para AMD A4-9125
    whisper_cmd = [
        "/usr/local/bin/whisper-amd",
        "-m", f"{os.path.expanduser('~/whisper_models/ggml-base.bin')}",  # Modelo balanceado
        "-t", "2",          # 2 threads óptimo para A4-9125
        "-p", "1",          # 1 processor
        "-osrt",            # Subtítulos SRT
        "-ovtt",            # Subtítulos VTT  
        "-otxt",            # Texto plano
        "--output-dir", str(self.transcripts_dir),
    ]
    
    # Agregar idioma si se especifica
    if language:
        whisper_cmd.extend(["-l", language])
    
    # Agregar archivo de audio
    whisper_cmd.append(str(audio_filepath))
    
    try:
        # Ejecutar transcripción
        result = subprocess.run(
            whisper_cmd,
            capture_output=True,
            text=True,
            timeout=300  # 5 minutos máximo
        )
        
        if result.returncode == 0:
            # Buscar archivo de texto generado
            base_name = audio_filepath.stem
            txt_file = self.transcripts_dir / f"{base_name}.txt"
            
            if txt_file.exists():
                with open(txt_file, 'r', encoding='utf-8') as f:
                    transcript_text = f.read().strip()
                
                print(f"[{self.agent_name}] AMD-optimized transcription successful!")
                print(f"[{self.agent_name}] Output files in: {self.transcripts_dir}")
                
                return {
                    "text": transcript_text,
                    "path": str(txt_file),
                    "language": language or "auto-detected",
                    "method": "whisper-amd-optimized"
                }
        
        print(f"[{self.agent_name}] Transcription failed: {result.stderr}")
        return None
        
    except Exception as e:
        print(f"[{self.agent_name}] Error during AMD transcription: {e}")
        return None

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions