Detección automática de idioma hablado con cURL y código abierto
Detecta el idioma hablado directamente a partir del audio con un modelo multilingüe de Whisper, servido localmente por whisper.cpp. cURL envía la grabación a su endpoint HTTP, que devuelve el idioma detectado y una transcripción. Una vez descargados el software y el modelo, la inferencia se ejecuta en tu computadora sin una cuenta ni una API en la nube.
Requisitos del sistema
Usa macOS o Linux con Bash, un compilador de C++17, Make, CMake 3.16 o posterior, cURL 7.83 o posterior,
FFmpeg y Python 3.9 o posterior. Python solo lee la respuesta JSON; no necesita paquetes adicionales.
El modelo multilingüe tiny ocupa unos 75 MiB en disco. Reserva espacio
adicional en disco para el código fuente y la compilación, y varios cientos de megabytes de memoria
libre para la inferencia. Este tutorial usa una compilación para CPU de whisper.cpp
v1.8.7.
Instalación
Desde un directorio de trabajo nuevo, descarga la versión fijada, compila su servidor y descarga el
modelo multilingüe. Elige tiny, no el modelo exclusivo para inglés
tiny.en:
set -e
curl --fail --location --output whisper-v1.8.7.tar.gz \
https://github.com/ggml-org/whisper.cpp/archive/refs/tags/v1.8.7.tar.gz
tar -xzf whisper-v1.8.7.tar.gz
cd whisper.cpp-1.8.7
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release \
-DGGML_METAL=OFF -DWHISPER_BUILD_SERVER=ON
cmake --build build --config Release --target whisper-server -j 4
sh ./models/download-ggml-model.sh tiny
Configura el servidor de transcripción
Desde el directorio extraído, inicia el servidor HTTP:
./build/bin/whisper-server --model models/ggml-tiny.bin \
--host 127.0.0.1 --port 8080 --language auto --no-gpu
Espera el mensaje que indica que el servidor está escuchando y deja esta terminal abierta. El servidor de ejemplo no tiene autenticación, así que mantenlo vinculado a la interfaz de loopback y usa grabaciones locales de confianza. Deténlo con Ctrl+C cuando termines.
Transcribe audio con cURL
En una segunda terminal, trabaja en un directorio que contenga una grabación de voz llamada
input.mp3. Conviértela a WAV mono a 16 kHz con PCM de 16 bits y luego súbela.
-n evita que FFmpeg sobrescriba un archivo
audio.wav existente; elige un directorio nuevo para cada grabación.
set -e
ffmpeg -nostdin -n -i input.mp3 -vn -ar 16000 -ac 1 -c:a pcm_s16le audio.wav
curl --fail --silent --show-error --remove-on-error --max-time 300 \
http://127.0.0.1:8080/inference \
--form 'file=@audio.wav;type=audio/wav' \
--form 'language=auto' \
--form 'response_format=verbose_json' \
--form 'no_language_probabilities=true' \
--output transcript.json
language=auto solicita al modelo de voz que identifique el idioma de entrada.
verbose_json incluye language,
text y segments con marcas de tiempo;
json por sí solo no incluye el campo de idioma.
Desactivar el informe opcional de probabilidades de idioma evita una segunda pasada de detección.
La traducción está desactivada, por lo que la transcripción permanece en el idioma detectado.
Detección del idioma
Guarda lo siguiente como read_language.py junto a transcript.json.
Valida e imprime el idioma ya inferido a partir del audio, en lugar de intentar adivinarlo a partir
de la transcripción:
import json
import sys
def read_language(path):
with open(path, encoding="utf-8") as handle:
data = json.load(handle)
if not isinstance(data, dict):
raise ValueError("Expected a JSON object")
language = data.get("language")
text = data.get("text")
if not isinstance(language, str) or not language.strip():
raise ValueError("Response has no detected language")
if not isinstance(text, str) or not text.strip():
raise ValueError("No speech transcript; language result is inconclusive")
return language
def main():
if len(sys.argv) != 2:
raise ValueError("Usage: python3 read_language.py transcript.json")
print(f"Detected language: {read_language(sys.argv[1])}")
if __name__ == "__main__":
try:
main()
except (OSError, ValueError) as error:
print(f"Cannot read language result: {error}", file=sys.stderr)
sys.exit(1)
Después de una subida correcta, ejecuta:
python3 read_language.py transcript.json
Para el habla en inglés, el valor del idioma es english; para el español, es
spanish. Son nombres de idiomas que devuelve el servidor, no códigos ISO de
idioma. Una transcripción que no esté vacía es una comprobación básica útil, pero no demuestra que
hubiera voz ni que el idioma sea correcto.
Optimización del rendimiento
Mantén el servidor en ejecución entre solicitudes para que pueda reutilizar el modelo cargado.
Empieza con tiny para pruebas breves; los modelos multilingües
base o small requieren más memoria y tiempo de
procesamiento a cambio de posibles mejoras de precisión. Descarga el modelo elegido con el mismo
script de descarga y reinicia el servidor con la ruta del modelo correspondiente.
Usa un fragmento claro que contenga varias oraciones en un solo idioma. Si una grabación cambia de idioma, evalúa sus fragmentos por separado: un único resultado de idioma para todo el archivo no es una cronología de todos los idiomas hablados. Aumenta el tiempo de espera de cURL de forma consciente si las entradas más largas necesitan más tiempo.
Manejo de errores
El bloque de solicitud se detiene si falla la conversión o la subida. cURL termina con un código
distinto de cero ante errores HTTP, fallos de conexión o tiempos de espera agotados, y
--remove-on-error elimina un archivo de respuesta incompleto.
Ejecuta el lector solo después de que ese bloque termine correctamente. Un JSON no válido, campos
faltantes, una transcripción vacía o archivos ilegibles hacen que el lector termine con el estado 1.
Si falla el inicio, comprueba la ruta del modelo y si el puerto 8080 ya está ocupado. Si falla una subida, revisa la terminal del servidor local y confirma que la conversión a WAV se completó correctamente. No consideres fiable un idioma inferido a partir de silencio, música o una intervención de voz muy breve.
Consejos y buenas prácticas
- Comprueba los resultados con grabaciones cuyo idioma hablado conozcas, incluidos distintos acentos.
- Evalúa el modelo con la calidad de tu propio audio antes de usar su resultado para dirigir otras tareas.
- Mantén disponibles los resultados inciertos para revisarlos, en lugar de asumir que cada grabación tiene un solo idioma.
Si necesitas un servicio alojado de transcripción en un flujo de trabajo de procesamiento de archivos, consulta nuestro Speech Robot.
