Una guía para la clonación de voz en Voxtral sin un codificador

ha sido lanzado recientemente por Mistral. Se trata de un potente modelo de texto a voz que está superando a ElevenLabs v2.5 Flash, según las pruebas de Mistral. Además del rendimiento de última generación en tareas de conversión de texto a voz (entre modelos de tamaños similares), Mistral anunció capacidades de clonación de voz y publicó los pesos de su modelo. Eso atrajo un gran interés, porque un modelo de texto a voz (TTS) de alta calidad, lo suficientemente pequeño para la inferencia local y con capacidades de clonación de voz, es algo que está en demanda tanto en las empresas como en la comunidad.

El problema, sin embargo, es que Mistral eliminó los pesos del codificador automático de audio, por lo que los usuarios no pueden clonar ninguna voz, solo podemos usar las voces que Mistral preparó para nosotros. Esa es una enorme limitación en comparación con el documento y el anuncio inicial.

Aquí proporciono (1) una descripción general de la arquitectura Voxtral TTS con algunos detalles técnicos y comparaciones, (2) mi investigación sobre el codificador automático de audio y cómo codifica realmente el audio, (3) un estudio sobre cómo podemos obtener representación de cualquier audio para utilizar potencialmente la clonación de voz, aunque los pesos publicados estén truncados en parte del codificador.

Por qué estoy seguro de que Voxtral TTS es una tecnología que vale la pena entender (breve historia personal)

Hace años, trabajaba en Skyeng, donde estábamos construyendo nuestro sistema de reconocimiento automático de voz (ASR). Fue en 2021, OpenAI aún no ha lanzado Whisper y la tarea de ASR fue un tema candente, especialmente para algunos discursos poco comunes: nuestro ASR era para hablantes no nativos.

En ese momento estaba leyendo muchos artículos sobre comprensión y codificación de audio (principalmente usando codificadores transformadores). Cuando leí el artículo de Wav2Vec2 tuve la fuerte sensación de que deberíamos adoptar esta tecnología, comprenderla en pequeños detalles y usarla, porque estaba seguro de que los enfoques y el estado de las tecnologías mencionadas son lo suficientemente fundamentales como para persistir como los nuevos clásicos en el dominio de la comprensión del audio y el procesamiento de señales. Tenía razón. Y con el lanzamiento de Voxtral-TTS tuve la misma sensación.

Descripción general de Voxtral TTS

Voxtral-4B-TTS es un modelo de 4 mil millones de parámetros que utiliza una columna vertebral 3B basada en un modelo de lenguaje grande autorregresivo (LLM) (modelo Ministral 3B). En pocas palabras, el modelo toma como entrada algunos tokens de audio que representan voz para clonar y tokens de texto para expresar. Al igual que los LLM, el modelo genera tokens de forma autorregresiva, con la diferencia de que estos tokens son tokens de voz. En el documento que describe el modelo, se encuentra la siguiente ilustración de esta pieza:

Generador de audio autorregresivo (basado en LLM), fuente: https://arxiv.org/pdf/2603.25551

Cosas importantes a tener en cuenta: tanto la referencia de audio como el audio generado se pueden dividir en tokens independientes y no superpuestos; cada token representa 80 ms de audio; hay un cabezal complicado que consta de un cabezal lineal y un transformador de adaptación de flujo para crear componentes semánticos y acústicos (también llamados tokens) de un token de voz individual. Estos dos detalles hacen que este modelo sea especial. Los tokens de audio (voz) independientes lo hacen capaz de transmitir audio nativo. Y este cabezal complicado es una combinación genial de dos enfoques actuales para la generación de audio: predicción de tokens discretos (cabezal lineal) y aproximación de distribución compleja a través de procesos de difusión utilizando modelos de difusión o enfoque de transformadores de adaptación de flujo (el mismo que usamos habitualmente para la generación de imágenes y videos).

Esto luce conceptualmente elegante y hermoso. Pero se requiere otro componente: el codificador automático de audio. Un autocodificador de audio se encarga de obtener aquellos tokens acústicos y semánticos que son fundamentales para el modelo. La descripción general de la arquitectura del codificador automático 350M del artículo original:

Codificador automático de audio, fuente: https://arxiv.org/pdf/2603.25551

El codificador automático de audio, Voxtral Codec, es el modelo que produce 37 tokens discretos por cada cuadro de audio de 80 ms (en el medio de la arquitectura dentro del bloque de cuantificación) y puede reconstruir el audio a partir de estos tokens discretos. La descripción clásica del codificador automático es codificador -> cuello de botella -> decodificador. Sin embargo, Mistral no ha lanzado un codificador. Eso significa que todavía podemos generar audio después de que el modelo autorregresivo produzca tokens de audio aplicando el decodificador del códec Voxtral, pero no podemos alimentar de forma nativa algo de audio para obtener tokens de audio que podamos usar como condición de voz en el modelo autorregresivo, ya que Mistral no ha liberado los pesos del codificador y el decodificador no es invertible (como la mayoría de los modelos de aprendizaje profundo).

Otro detalle interesante: en el cuello de botella se menciona dos tipos de tokens, semánticos y acústicos. También vale la pena comprender la implementación aquí. El decodificador produce 292 tenues latentes, que se dividen en un vector de 256 tenues y 36 escalares de una sola dimensión. El vector de 256 dimensiones se asigna a la incrustación de libros de códigos y luego se representa mediante el código: la ID del libro de códigos más cercana (es decir, la cuantificación del vector). Cada uno de los 36 escalares unidimensionales se asigna a un rango de 0 a 21 mediante activación tanh escalada. Estos elementos ya son una simplificación de algunos de los enfoques anteriores que utilizaban la cuantificación del vector residual.

Algunas palabras sobre tokens semánticos. Las incrustaciones de los tokens semánticos se proyectan linealmente para que coincidan con los logits del decodificador Whisper cuando convierte voz a texto para el mismo audio. En otras palabras, se aplica una restricción para vincular los tokens semánticos al estado latente que Whisper (modelo ASR) utiliza justo antes de producir texto a partir del habla. Es por eso que estos tokens se llaman semánticos: se supone que están asociados con las latentes relacionadas con el texto y el texto está asociado con la semántica.

La pregunta que me surgió aquí (y que probé más tarde): ¿estos tokens semánticos realmente representan el significado, las palabras que deben expresarse, mientras que la acústica representa la voz misma?

Copia de algunas notas técnicas que tomé para mi resumen después de leer el artículo de Voxtral (con algunas referencias cruzadas)

Voxtral-TTS (TTS de Mistral) — https://arxiv.org/pdf/2603.25551. Similar al Qwen-3 TTS (variante de 12 Hz) hasta cierto punto. Mistral entrenó su propio códec (arquitectura codificador-decodificador). En esta parte, el codificador produce un vector de estado latente de 292 dimensiones que se divide en 256 para VQ y 36 de cuantificación escalar finita (FSQ). En comparación con Mimi y Qwen-3, Mistral usa FSQ en lugar de RVQ y concatena en lugar de sumar los vectores en la columna vertebral del decodificador. Otra diferencia: los vectores VQ se proyectan linealmente para coincidir con los estados ocultos (control semántico) del decodificador Whisper (antes de que se usara WavLM autosupervisado).

Estos vectores se utilizan en el modelo 3B de solo decodificador para realizar clonación de voz y conversión de texto a voz. Durante el entrenamiento se reemplazan el ruido y se evita la cuantificación en aproximadamente el 50% de los casos para hacer que el modelo sea más robusto. Para cada uno de los estados hay una incrustación, se suman y se utilizan como entrada al transformador. Este transformador predice autorregresivamente estados ocultos para tokens de audio y tokens (de fin de audio). Estos estados ocultos se utilizan con cabeza lineal para predecir tokens semánticos basados ​​en VQ y para condicionar un modelo de coincidencia de flujo de 3 capas (comentario: difusión con un objetivo mejorado) que genera tokens acústicos continuos a partir del ruido (luego se cuantifican con FSQ) – (guía sin clasificador) Se puede aplicar CFG. El audio se divide en partes cortas que no se entrelazan. Durante el entrenamiento, se calculan tanto la pérdida de entropía cruzada semántica como la coincidencia de flujo para una única marca de tiempo muestreada (la pérdida se vuelve a ponderar; por ejemplo, se reduce el peso de la pérdida para los silencios). El DPO posterior a la capacitación ayuda a mejorar aún más los resultados.

Cuantización escalar finita FSQ: https://arxiv.org/pdf/2309.15505. Un enfoque simple para mejorar RVQ y VQ (VQ es solo cuantificación vectorial, mientras que RVQ es cuantificación vectorial residual). RVQ se basa en ajustar cada uno de los libros de códigos VQ con libros de códigos más pequeños, por lo que para reconstruir necesitamos resumir un conjunto de incorporaciones de libros de códigos. FSQ es simple (y produce códigos independientes en comparación con RVQ): usamos activación tanh (escalada) para cada dimensión de valores finitos, redondeamos los resultados al entero más cercano y lo usamos como código; ayuda a utilizar mejor los libros de códigos y a entrenar de una manera más simple (sin incrustaciones de libros de códigos entrenables).

¿Los tokens semánticos realmente representan semántica?

Algunas pruebas que estaba a punto de realizar:

¿Los tokens semánticos representan las palabras que se van a expresar? Si realmente representan palabras, entonces podemos manipular estas fichas para cambiar el significado del discurso conservando la misma voz. Un resultado más realista sería simplemente palabras entrecortadas o falta de sentido en el discurso generado, pero la voz sigue siendo la misma. ¿Qué tan resistente es el decodificador de Voxtral Codec al ruido en los códigos? Si reemplazamos aleatoriamente algunos de los códigos y el audio sigue siendo similar, eso significa que hay una manera de aproximar el audio a través de alguna selección de valor de código basada en gradiente. De lo contrario, si un pequeño cambio en los códigos destruye el audio, es casi imposible reconstruir los códigos a partir del audio sin el codificador real.

Sabemos que no tenemos pesos para la parte codificadora del Codec Voxtral, pero tenemos un decodificador, tenemos pesos de columna vertebral autorregresivos y tenemos algunas voces que Mistral proporcionó como referencia (podemos generar voz a partir de texto usando estas voces).

El oleoducto:

Teniendo las voces de referencia incorporadas, podemos aplicar el algoritmo de Descenso de Coordenadas para extraer los códigos de la voz. Aquí tengo un script que está haciendo eso. Los pesos y códigos del decodificador no son suficientes para que funcione el decodificador del Voxtral Codec; También necesitamos la arquitectura implementada en forma de código. El vllm-omni tiene implementación Voxtral y está bajo una licencia permisiva Apache 2.0. Utilicé Claude Code para extraer el código de la arquitectura Voxtral Codec del vllm-omni. La arquitectura independiente de Voxtral Codec extraída de vllm-omni también se encuentra en mi repositorio de GitHub. Preparé un Jupyter Notebook que toma incrustaciones de voz (proporcionadas por Mistral), reconstruye sus códigos, opcionalmente destruye algunos de los códigos (semánticos y algunos acústicos) y reconstruye el audio usando el decodificador del Voxtral Codec con los pesos reales.

Aquí puede descargar y escuchar audio reconstruido a partir de las incrustaciones: audio

Aquí está el audio reconstruido a partir de las mismas incrustaciones, pero con aleatorización semántica y algunos tokens acústicos (siguiendo el guión): audio

A partir de estos archivos de audio, queda claro que los tokens semánticos, a pesar de su nombre, en realidad no representan las palabras o significados reales que se van a expresar. Y lo que es más importante: el decodificador es resistente a algunos cambios en los códigos, lo que significa que podemos intentar aplicar un descenso de gradiente para entrenar códigos directamente para el audio específico.

Un enfoque de descenso de gradiente para reconstruir códigos cuando falta el codificador

Al entrenar el código en sí quiero decir que inicializamos una sola capa en forma de nn.Parameter(torch.tensor(num_frames, num_codes_per_frame)), donde para cada cuadro tenemos 37 códigos, y lo entrenamos en pérdida de reconstrucción de audio real. Eso podría funcionar si estuviéramos trabajando en un espacio continuo y el objeto objetivo a reconstruir fuera una señal simple, no una forma de onda de audio de alta frecuencia.

Complicaciones debido a tokens discretos

Cada token es discreto, similar a los tokens del LLM; si hay dos tokens discretos A y B, no podemos optimizar gradualmente una transición de A a B. En Voxtral tenemos tokens semánticos y acústicos separados y los acústicos son más fáciles de modelar debido a la cuantificación escalar finita (FSQ) que utilizan: se obtienen del espacio continuo mediante una operación de redondeo. Pero aún así, tanto los tokens semánticos como los acústicos requieren el estimador directo (STE) en el paso hacia adelante y la transición diferenciable en el paso hacia atrás.

Para tokens acústicos simplemente podríamos aplicar STE directamente:

… # códigos acústicos entrenados para el audio seleccionado # inicialización self.acoustic_values = nn.Parameter( torch.randn(num_frames, 36) ) … # número de niveles para un único token acústico # según el documento y la implementación de vllm-omni acústico_levels = 22 acústico_normalizado = torch.tanh(self.acoustic_values) # Cuantización a niveles discretos acústico_escalado = ((acoustic_normalized + 1) / 2) * (acoustic_levels – 1) acústico_quantizado = acústico_scaled.round() # STE: hacia adelante usa cuantificado, hacia atrás usa códigos_acústicos continuos = acústico_escalado + (acoustic_quantized – acústico_scaled).detach()

Para los tokens semánticos es más complicado. No podemos aplicar la activación tanh, porque cada códec semántico está asociado con la incrustación multidimensional, por lo que en realidad estamos entrenando "qué incrustación seleccionar entre 8192 opciones", no "qué valor/escalar usar":

… # códigos semánticos entrenados para el audio seleccionado # inicialización semantic_vocab = 8192 self.semantic_logits = nn.Parameter( torch.randn(num_frames, semantic_vocab) ) … # Probabilidades suaves (para gradientes) probs = F.softmax(self.semantic_logits, dim=-1) # [T, 8192] # Selección dura (para pase hacia adelante) hard_codes = probs.argmax(dim=-1) # [T] índices enteros en el rango 0-8191 # Obtener tabla de incrustación semántica # utiliza los libros de códigos reales, porque cada uno de los 8192 códigos semánticos está asignado # a una incrustación de 256 dim sem_embedding = tokenizer.quantizer.semantic_codebook.embedding # [8192, 256] # Incrustación suave (suma ponderada para gradientes) soft_emb = torch.matmul(probs, sem_embedding) # [T, 256] # Incrustación dura (búsqueda discreta para avance) hard_emb = F.embedding(hard_codes, sem_embedding) # [T, 256] # STE: hacia adelante usa duro, hacia atrás usa suave semantic_emb = soft_emb + (hard_emb – soft_emb).detach() # [T, 256]

Aquí encontrará una implementación completa de la capacitación con STE ilustrado y explicado.

Las complicaciones surgen debido a la complicada señal para reconstruir.

En cada tarea de modelado de aprendizaje automático, cuanta más señal de capacitación de alta calidad pueda proporcionar, mejor será la capacitación. Esto es especialmente importante en el modelado de datos de alta frecuencia y altas dimensiones. En estos experimentos, el uso de la pérdida L1 como pérdida de reconstrucción por sí sola condujo a resultados deficientes: el modelo alcanzó óptimos locales y no pudo converger más con solo una señal de pérdida de reconstrucción de datos de alta frecuencia. En el ámbito del procesamiento de audio existe una lista de técnicas comunes para proporcionar señales de entrenamiento adicionales: transformada de Fourier de corto tiempo (STFT), espectrogramas de Mel. Ambas técnicas transforman la señal del dominio del tiempo a la representación de tiempo-frecuencia a través de contenedores de frecuencia y bancos de filtros de frecuencia. Siguiendo la descripción del artículo de Mistral, apliqué un STFT similar como pérdida adicional a la pérdida de reconstrucción L1 que tenía: "…Un discriminador de resolución múltiple con 8 tamaños STFT (2296, 1418, 876, 542, 334, 206, 126, 76) se entrena junto con el códec…"

También existen pérdidas específicas de la clonación de voz que podríamos aplicar. Hay modelos que pueden crear incrustaciones de hablantes, que se utilizan para la identificación y registro de hablantes. Por ejemplo. Los modelos de SpeechBrain. Estos modelos pueden producir incrustaciones para la voz. Si dos incrustaciones están cerca una de la otra, eso significa que es muy probable que dos audios incrustados provengan del mismo altavoz; de lo contrario, serán diferentes. Podemos aplicar la pérdida del hablante como un componente de pérdida adicional que debería obligar al modelo a crear códigos que podemos decodificar con el decodificador de Voxtral Codec para obtener una voz similar a la de destino.

Resultados del entrenamiento

Entrené el modelo descrito durante 5000 épocas (con una sola muestra). Me tomó alrededor de una hora en una máquina Mac con un procesador de la serie M recrear códigos durante 8 segundos de audio. El componente de pérdida de diarización del hablante hizo que el entrenamiento fuera más lento, pero condujo a una mejor pérdida final.

El audio que reconstruí a partir de los códigos entrenados está aquí. Puedes escuchar que es muy similar al primer fragmento de 8 segundos del audio de destino.

En esta configuración de entrenamiento, no realizamos ninguna época de evaluación, porque solo tenemos una muestra y nuestra tarea es sobreajustar los parámetros entrenados para poder reconstruir el audio final. Puede sonar un poco inusual, pero ese es exactamente el caso cuando el objetivo es el sobreajuste.

Descargo de responsabilidad sobre el uso de IA

Estaba utilizando herramientas de LLM para apoyarme en esta investigación y acelerar los experimentos. Fue muy útil. Sin embargo, hubo varios episodios en los que tuve que ajustar las decisiones del LLM para que funcionaran, en torno a algunos detalles de ML y DL.

¡Utilice las herramientas de inteligencia artificial de manera responsable!

Contactos

Mi LinkedIn si alguien quiere conectarse: Roman Smirnov