Clonar mi voz para leer este blog en seis idiomas
Escuchar el artículo (experimental) · 10:29

Este sitio publica en seis idiomas: inglés, portugués, español, alemán, francés e italiano. Durante un tiempo eso fue una promesa solo de texto. Podías leer cualquier artículo en tu idioma, pero si querías escucharlo de camino al trabajo o mientras cocinabas, no había nada a lo que darle al play. Añadir audio era el siguiente paso obvio. La pregunta interesante era de quién debía ser la voz.
Primera ronda: una voz que sale a producción
La primera versión usaba voces neuronales gratuitas de texto a voz, una por idioma. Fue el primer paso correcto: coste cero, minutos para integrarlas, y puso un reproductor funcional en cada artículo. Publicarla fue también lo que dejó a la vista el listón real. Las voces eran limpias pero formales, leían mis frases con la cadencia de otra persona, y un sitio personal narrado por una voz genérica es un apaño provisional. Los textos llevan mi nombre. La voz que los lee también debería ser mía, incluso en los cinco idiomas que no pienso narrar a mano en un futuro próximo.
El desbloqueo: un modelo local que clona
La pieza que hizo esto viable es Chatterbox Multilingual, un modelo TTS de código abierto con licencia MIT de Resemble AI. Tres propiedades lo convirtieron en la pieza adecuada:
- Cubre mis seis idiomas con un solo modelo.
- Funciona en una GPU de consumo. La mía es una RTX 3080, y la generación usa unos 5,5 GB de VRAM.
- Hace clonación de voz zero-shot: le das una grabación corta de referencia y lee cualquier texto con esa voz, en cualquiera de sus idiomas.
Esa última propiedad es toda la funcionalidad. Sin estudio, sin entrenamiento, sin un dataset con horas de mí hablando. La referencia que mueve todo en este sitio es una grabación que hice en mi ordenador en una habitación silenciosa: unos cuarenta segundos míos leyendo uno de mis propios artículos en portugués, a un ritmo normal.
Por qué importa la referencia
De fábrica, la voz por defecto del modelo no era la mía, para empezar, y además tiraba a portugués de Brasil, que no es como yo hablo. No hay un menú de voces para arreglarlo, ninguna opción de "hombre, portugués europeo" que seleccionar. La voz la define por completo el audio de referencia con el que condicionas el modelo, así que esos cuarenta segundos eran la única palanca que tenía, y movieron mucho. El timbre, el registro y el ritmo se reconocen como míos en todos los idiomas. El acento vino solo en parte: la narración queda mucho más cerca del portugués europeo de lo que quedaba la voz por defecto, y aun así se desliza hacia una cadencia brasileña en algunos puntos, porque el modelo aprendió su portugués de datos donde domina la variante de Brasil, y cuarenta segundos míos tuercen esa base sin llegar a borrarla.
La parte que todavía me sorprende es que la referencia es solo en portugués. Nunca grabé una muestra en inglés, ni en español, ni en alemán, francés o italiano. Los mismos cuarenta segundos en portugués mueven los seis idiomas: el modelo extrae de la grabación cómo suena mi voz y lo aplica al idioma que le pidan leer a continuación.
Dos notas de ajuste de la fase de conseguir que sonara bien:
- El ritmo por defecto era demasiado rápido para una escucha larga. Bajar el peso de guía del modelo (cfg_weight 0.3) y rebajar la expresividad produjo una lectura más calmada, adecuada para artículos. Esos ajustes están integrados en el pipeline, así que todos los archivos salen consistentes.
- En inglés, la voz clonada arrastra mi acento portugués. Lo dejé. Un sitio personal que de repente suena como un nativo de California en inglés y como yo en portugués sería más raro que un acento, y el acento es la versión verdadera.
El pipeline
La marca de este sitio es IA en producción, así que la narración tenía que ser un sistema, no un lote de archivos hecho una sola vez. Todo se ejecuta desde un único comando, node scripts/generate-audio.mjs, y hace lo siguiente:
- Escanea cada artículo en cada idioma y compara las marcas de tiempo de los archivos, de modo que solo se regeneran los artículos nuevos o editados. Publicar un post nuevo consiste en escribir el markdown y ejecutar el script.
- Entrega los textos a un worker en Python que carga Chatterbox una vez y lo mantiene en caliente, en lugar de pagar la carga del modelo por cada archivo.
- Lee cada artículo trozo a trozo y cose el audio con pausas naturales, que es lo que evita que una lectura de 15 minutos suene como un único párrafo sin tomar aire.
- Normaliza el volumen de cada archivo. La salida bruta del modelo rondaba los menos 41 LUFS, que es un susurro al lado de cualquier podcast. Todo se sube a volumen de podcast, entre menos 16 y menos 18 LUFS, para que el reproductor encaje con lo último que hayas escuchado.
- Escribe el resultado como un MP3 normal por artículo y por idioma. El audio se sirve con el sitio como cualquier otro recurso estático: sin servicio de streaming, sin reproductor de terceros, sin rastreo.
El control de calidad corre en la dirección contraria: después de un lote, fragmentos del audio generado pasan por Whisper, el modelo de voz a texto, y las transcripciones se comparan con el texto original. Hoy es una comprobación por muestreo, no una barrera automática dentro del pipeline, y ya ha detectado lo que mi oído nunca captaría, en los cuatro idiomas que no puedo corregir de oído.
Los números, para que puedas dimensionar esto para tu propio equipo: la generación por trozos tarda aproximadamente el doble de la duración del audio final, así que un artículo largo cuesta de 25 a 30 minutos de GPU por idioma. El catálogo completo, cinco artículos por seis idiomas, es una ejecución de unas doce horas. La grabación de referencia nunca entra en el repositorio; el script la lee de una carpeta local y el repo solo ve los MP3 terminados.
Lo que te enseña un lote largo
Un trabajo de doce horas te encuentra los puntos débiles. Mi primera ejecución completa murió a medias cuando el proceso que la había lanzado se cerró de golpe, un fallo clásico de los trabajos largos. Lo que la salvó fue el mismo diseño que abarata publicar: como el pipeline es incremental y cada archivo terminado persiste, el fallo solo costó el archivo que estaba a medio codificar, y hasta ese se pudo recuperar de su salida temporal. Relanzas el comando y continúa desde donde se quedó la última ejecución. Si estás construyendo cualquier pipeline de generación de larga duración, esa propiedad, poder reanudar por defecto, vale más que una barra de progreso.
Cómo suena hoy
No lo voy a vender de más. La narración es perfectamente escuchable y suena inconfundiblemente a mí, y todavía tiene aristas: de vez en cuando una frase sale cortada, o un trozo tartamudea como un disco rayado antes de recuperarse. Y el portugués mantiene la deriva que describí arriba. Es mi timbre leyendo mis palabras, con una cadencia que un oyente portugués notará que tira a brasileña en algunos puntos. Lo bastante leve como para publicarlo, lo bastante presente como para querer dejarlo aquí por escrito. Las comprobaciones por muestreo con Whisper detectan los fallos gruesos; los más sutiles se cuelan, y en cuatro de estos idiomas yo nunca los oiría por mí mismo. Así que trato el audio como lo que es hoy: un acompañamiento. Dale al play mientras lees y te lleva por el texto. Las siguientes iteraciones ya se ven desde aquí: una grabación de referencia más larga y más limpia para acercar el acento todavía más al mío, y convertir la comprobación de calidad en un bucle de reparación, donde cualquier trozo cuya transcripción se desvíe del original se regenera automáticamente, de modo que cada archivo publicado converge hacia una versión limpia.
La línea del consentimiento
Hicieron falta cuarenta segundos de audio para crear una copia convincente de mi voz, en una GPU de gaming, con software gratuito. Eso también vale para tu voz.
Me siento cómodo publicando esto por una razón: es mi voz, clonada por mí, con mi consentimiento, leyendo mis propias palabras, y etiquetada como lo que es. La misma capacidad apuntada a la voz de cualquier otra persona sin permiso es fraude, y el hecho de que la barrera sea ahora una grabación corta significa que la carga de la prueba ha cambiado de sitio. La voz, por sí sola, ya no autentica a nadie. Si tu empresa todavía trata "suena como el CEO al teléfono" como una autorización, este párrafo es tu informe de incidencias llegado del futuro.
Lo que cuesta
Después de la configuración inicial, el coste marginal de narrar un artículo nuevo en seis idiomas es unas horas de GPU en segundo plano y la electricidad que hay detrás. No hay tarifas de API por carácter, y ningún texto de los artículos sale nunca de mi máquina. Las plataformas de voz en la nube clonan con más pulido, y para productos comerciales con la narración en el centro merece la pena evaluarlas, pero para un sitio personal la vía local gana en coste, privacidad y control, y convierte toda la funcionalidad en un par de scripts en un repo.
Cada artículo de este sitio tiene ahora un reproductor en la parte superior. Elige un idioma, dale al play y lee a la vez: oirás este texto más o menos como yo te lo leería, salvo por un acento que decidí conservar y alguna sílaba suelta que el modelo todavía está aprendiendo a clavar.
Preguntas que responde este artículo
¿De verdad se puede clonar una voz con una grabación de cuarenta segundos?
Sí, y sin entrenamiento, sin estudio y sin un dataset con horas de habla. Chatterbox Multilingual, el modelo de código abierto con licencia MIT de Resemble AI, hace clonación de voz zero-shot: se condiciona con una grabación corta de referencia y lee cualquier texto con esa voz. Funciona en local en una RTX 3080 y usa unos 5,5 GB de VRAM.
¿Hace falta una muestra de voz distinta para cada idioma?
No. La referencia detrás de cada archivo de este sitio es solo en portugués, unos cuarenta segundos leyendo un artículo a ritmo normal, y nunca se grabó nada en inglés, español, alemán, francés ni italiano. El modelo extrae de esa grabación cómo suena la voz y lo aplica al idioma que le pidan leer a continuación.
¿Suena de verdad a ti o estás siendo generoso?
Es perfectamente escuchable y suena inconfundiblemente a mi timbre, y tiene aristas que prefiero decir antes que esconder. De vez en cuando una frase sale cortada o un trozo tartamudea como un disco rayado antes de recuperarse, y el portugués mantiene en algunos puntos una cadencia que tira a brasileña. Las transcripciones de Whisper sobre fragmentos por muestreo detectan los fallos gruesos, los más sutiles se cuelan, y en cuatro de estos idiomas yo nunca los oiría por mí mismo. Por eso hoy el audio es un acompañamiento del texto, no un sustituto de leerlo.
¿Cuánto tarda y cuánto cuesta narrar un artículo en seis idiomas?
La generación por trozos tarda aproximadamente el doble de la duración del audio final, así que un artículo largo cuesta de 25 a 30 minutos de GPU por idioma, y el catálogo completo, cinco artículos por seis idiomas, fue una ejecución de unas doce horas. Tras la configuración inicial, el coste marginal de un artículo nuevo son unas horas de GPU en segundo plano y la electricidad que hay detrás: sin tarifas de API por carácter y sin que ningún texto de los artículos salga de la máquina. Las plataformas en la nube clonan con más pulido y merece la pena evaluarlas cuando la narración está en el centro de un producto comercial, pero para un sitio personal la vía local gana en coste, privacidad y control.
Leer a continuación
AICuando la IA tiene que grabar su propia revisión
Cuando se abre una pull request, sea mía o una que me toca revisar, ahora le pido al agente que la ejecute en mi máquina, que intente romperla y que se grabe mientras lo hace. Un párrafo puede asegurar que se hizo una prueba. Una grabación tiene que enseñarla, y decidir qué significa sigue siendo cosa mía.
AIJev responde en probabilidades. La pregunta sigue siendo tuya.
Jev, de TypeSafe, no escribe ni una frase. Le entregas un estado y unas preguntas tipadas, y te devuelve una elección, una puntuación o una probabilidad de sí o no, a cuatro milésimas de céntimo por una decisión sobre mil tokens. La novedad es la forma, que devuelve la autoridad a tu código, y la trampa es que una probabilidad parece un recurso y no lo es. Ejecuté el piloto que pediría antes de creerme ningún número, sobre mis propios ensayos con el modelo abierto que sustituyó a Jev, y la respuesta fue no.