Modelo de voz a texto¶

Dentro del procesamiento del lenguaje natural, una de las tareas fundamentales también consiste en procesar el lenguaje hablado. Para esto, se puede pasar de voz a texto, o bien se puede crear sistemas que pasen de texto a voz (sintetizadores de voz). Esto últimos se utilizan para generar voz artificial a través de entradas textuales. Mientras que los primeros se utilizan para pasar una señal acústica a voz.

Los modelos de voz a textos toman señales acústicas que son procesadas secuencialmente para producir cadenas del lenguaje destino basadas en modelos del lenguaje estadísticos. Uno de los modelos de voz a texto que integran redes convolucionales y modelos de atención es el modelo de Wav2Vec (Baevski et al., 2020).

  1. Extractor de rasgos: La capa de codificador toma una señal acústica $\mathcal{X}$ y genera una representación secuencial $\mathbf{z}_1, \mathbf{z}_2,...,\mathbf{z}_T$ en $T$ pasos que se genera a partir de bloques convolucionales y normalización.
  2. Representaciones contextualizadas: Después de la obtención de las representaciones $\mathbf{z}_t$ a partir de los bloques convolucionales, se generan representaciones contextualizadas a partir de 24 cabezas de atención. La codificación posicional de una convolución parametrizada.
  3. Salida: Finalmente, se aplican capas para obtener la salida correspondiente a los símbolos de la lengua destino.

Este modelo se ha adaptado a diferentes lenguajes, entre ellos el español. Para el español, utilizamos el modelo pre-entrenado que está disponible en: https://huggingface.co/LuisG07/wav2vec2-large-xlsr-53-spanish

In [1]:
import torch
from transformers import Wav2Vec2ForCTC, Wav2Vec2Processor
2026-01-26 16:07:48.360267: I tensorflow/core/util/port.cc:113] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.
2026-01-26 16:07:48.830178: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.
To enable the following instructions: AVX2 AVX_VNNI FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.
2026-01-26 16:07:50.509064: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT
In [2]:
LANG_ID = "es"
MODEL_ID = "jonatasgrosman/wav2vec2-large-xlsr-53-spanish"
SAMPLES = 10

processor = Wav2Vec2Processor.from_pretrained(MODEL_ID)
model = Wav2Vec2ForCTC.from_pretrained(MODEL_ID)

model
Out[2]:
Wav2Vec2ForCTC(
  (wav2vec2): Wav2Vec2Model(
    (feature_extractor): Wav2Vec2FeatureEncoder(
      (conv_layers): ModuleList(
        (0): Wav2Vec2LayerNormConvLayer(
          (conv): Conv1d(1, 512, kernel_size=(10,), stride=(5,))
          (layer_norm): LayerNorm((512,), eps=1e-05, elementwise_affine=True)
          (activation): GELUActivation()
        )
        (1-4): 4 x Wav2Vec2LayerNormConvLayer(
          (conv): Conv1d(512, 512, kernel_size=(3,), stride=(2,))
          (layer_norm): LayerNorm((512,), eps=1e-05, elementwise_affine=True)
          (activation): GELUActivation()
        )
        (5-6): 2 x Wav2Vec2LayerNormConvLayer(
          (conv): Conv1d(512, 512, kernel_size=(2,), stride=(2,))
          (layer_norm): LayerNorm((512,), eps=1e-05, elementwise_affine=True)
          (activation): GELUActivation()
        )
      )
    )
    (feature_projection): Wav2Vec2FeatureProjection(
      (layer_norm): LayerNorm((512,), eps=1e-05, elementwise_affine=True)
      (projection): Linear(in_features=512, out_features=1024, bias=True)
      (dropout): Dropout(p=0.05, inplace=False)
    )
    (encoder): Wav2Vec2EncoderStableLayerNorm(
      (pos_conv_embed): Wav2Vec2PositionalConvEmbedding(
        (conv): ParametrizedConv1d(
          1024, 1024, kernel_size=(128,), stride=(1,), padding=(64,), groups=16
          (parametrizations): ModuleDict(
            (weight): ParametrizationList(
              (0): _WeightNorm()
            )
          )
        )
        (padding): Wav2Vec2SamePadLayer()
        (activation): GELUActivation()
      )
      (layer_norm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)
      (dropout): Dropout(p=0.05, inplace=False)
      (layers): ModuleList(
        (0-23): 24 x Wav2Vec2EncoderLayerStableLayerNorm(
          (attention): Wav2Vec2Attention(
            (k_proj): Linear(in_features=1024, out_features=1024, bias=True)
            (v_proj): Linear(in_features=1024, out_features=1024, bias=True)
            (q_proj): Linear(in_features=1024, out_features=1024, bias=True)
            (out_proj): Linear(in_features=1024, out_features=1024, bias=True)
          )
          (dropout): Dropout(p=0.05, inplace=False)
          (layer_norm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)
          (feed_forward): Wav2Vec2FeedForward(
            (intermediate_dropout): Dropout(p=0.05, inplace=False)
            (intermediate_dense): Linear(in_features=1024, out_features=4096, bias=True)
            (intermediate_act_fn): GELUActivation()
            (output_dense): Linear(in_features=4096, out_features=1024, bias=True)
            (output_dropout): Dropout(p=0.05, inplace=False)
          )
          (final_layer_norm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)
        )
      )
    )
  )
  (dropout): Dropout(p=0.0, inplace=False)
  (lm_head): Linear(in_features=1024, out_features=41, bias=True)
)

Transcipción de audio¶

Podemos probar el modelo de manera sencilla a partir de una audio en formato .wav, utilizamos la paquetería librosa para leer el audio y procesamos con el modelo para obtener la entrada del modelo en el formato de arreglos. El mismo processor puede decodificar la predicción en el lenguaje.

In [3]:
import librosa

audio_input, sample_rate = librosa.load("habla.wav", sr=16000)
inputs = processor(audio_input, sampling_rate=16000, return_tensors="pt", padding=True)
In [4]:
with torch.no_grad():
    logits = model(inputs.input_values, attention_mask=inputs.attention_mask).logits

predicted_ids = torch.argmax(logits, dim=-1)
predicted_sentences = processor.batch_decode(predicted_ids)

for i, predicted_sentence in enumerate(predicted_sentences):
    print("Transcripción:", predicted_sentence)
Transcripción: en el momento enque el tenista lanza magistralmente su bala le posee una inocencia totalmente animal

Referencias¶

Baevski, A., Zhou, H., Mohamed, A. y Auli, M. (2020). wav2vec 2.0: A Framework for Self-Supervised Learning of Speech Representations. https://arxiv.org/abs/2006.11477.


Principal