F8 y a chambear: la parte técnica -- decisiones, gotchas, y por qué importa
> Por qué whisper.cpp y no openai-whisper, qué onda con el modelo grande, el truco que hace que el script funcione tanto en terminales como en browsers, y el experimento de Ollama que descarté. Parte 2 de la serie de dictado por voz local.
En la parte 1 dejé planteado el problema y el stack. Ahora la carne: por qué cada decisión técnica, qué descarté en el camino, y los gotchas que hay que conocer.
Por qué whisper.cpp y no openai-whisper de Python
openai-whisper (la versión Python oficial) requiere PyTorch + venv + carga del modelo en RAM cada vez. Pesado.
whisper.cpp es la implementación en C++ del mismo algoritmo. Ventajas concretas:
- Sin venv. Es un binario en
/usr/bin/whisper-cli. - Sin PyTorch. Usa GGML (formato compacto), carga directo a la GPU.
- Cold start más rápido. ~1-2s vs 5-10s del Python.
- Vulkan funciona en AMD y NVIDIA. No necesitas CUDA toolkit (que en Arch es un dolor).
- Menos VRAM. El modelo grande cabe fácil en una RTX 3060 12GB sin pelear con otros procesos.
Por qué el modelo grande y no uno chico
Probé base y small primero. La diferencia con Spanglish es brutal:
base: confunde "frontend" con "frente", "deploy" con "deplorar". Inservible.small: mejor, pero todavía se pierde con frases técnicas.large-v3-turbo: traduce mi spanglish exacto sin tropezar. "Voy a hacer git pull a la rama de develop" sale tal cual.
El "turbo" es la versión optimizada de large-v3: misma precisión, ~2-3x más rápido en inferencia. Para dictado en tiempo real (donde la latencia importa más que el último 1% de accuracy), turbo es el sweet spot.
Pesa ~1.5GB. La RAM/VRAM no es problema en hardware moderno.
El truco de la detección de ventana: Ctrl+V vs Ctrl+Shift+V
Aquí está el detalle que hace la diferencia entre "funciona en algunos lados" y "funciona donde sea":
Las terminales (Konsole, Kitty, Alacritty, Foot, Wezterm) pegan con Ctrl+Shift+V, porque Ctrl+V en terminal típicamente es "verbatim insert" (carácter literal) o nada.
Todo lo demás (browser, Kate, Teams, WhatsApp web) pega con Ctrl+V, el estándar de toda la vida.
Si solo mando Ctrl+V, no funciona en terminales. Si solo mando Ctrl+Shift+V, no funciona fuera de terminales. La solución: detectar el tipo de ventana activa y mandar la combinación correcta.
kdotool getactivewindow getwindowclassname te devuelve algo como "konsole", "firefox" o "kate". Un grep con regex de terminales conocidas decide qué keystroke disparar.
El experimento que descarté: Ollama normalization
En una iteración temprana metí un paso extra: tomar el output de Whisper y pasárselo a Ollama (qwen2.5:7b local) con un prompt tipo "limpia esto sin cambiar el significado". La idea era arreglar errores de transcripción típicos.
Lo descarté por dos razones:
- Latencia. Agregaba ~2-3s al pipeline. Total quedaba en 5-8s, demasiado para sentirlo "instantáneo".
- Alteraba mi voz. Ollama "normalizaba" mi spanglish a español "correcto". "Voy a hacer push al repo" se volvía "Voy a enviar al repositorio". Yo no quiero eso. Mi voz es mi voz, even si tiene anglicismos técnicos. El AI no debería corregir mi forma de hablar.
Whisper crudo gana.
Caveats
- Solo Wayland. El script usa
wl-copyyydotool. Si estás en X11, cambias porxclipyxdotool. - Solo KDE.
kdotooles específico de KDE. En GNOME/Hyprland usarías otra herramienta para detectar ventana activa (en Hyprland,hyprctl activewindow). - Primer reboot obligatorio. Los permisos de
uinputno aplican hasta reiniciar. No es opcional. - Sin VAD (voice activity detection). Graba todo desde que aprietas F8 hasta que aprietas otra vez. Si te quedas callado 30 segundos en medio, esos 30s de silencio van al wav y a Whisper. Whisper los ignora bien, pero el archivo pesa más.
- No funciona si el daemon de ydotool no está corriendo.
systemctl --user status ydotooldebería mostraractive. Si no,systemctl --user start ydotool.
En la siguiente parte
El script completo de 49 líneas con cada flag explicado, la instalación paso a paso (pacman, udev, KDE shortcuts), las stats personales después de varias semanas de uso, y el repo público para clonar.
Próxima entrega: F8 y a chambear: el script, instalación, y repo para clonar.