# X-Codec

## Resumen

El modelo X-Codec fue propuesto en [Codec Does Matter: Exploring the Semantic Shortcoming of Codec for Audio Language Model](https://huggingface.co/papers/2408.17175) por Zhen Ye, Peiwen Sun, Jiahe Lei, Hongzhan Lin, Xu Tan, Zheqi Dai, Qiuqiang Kong, Jianyi Chen, Jiahao Pan, Qifeng Liu, Yike Guo, Wei Xue.

El modelo X-Codec es un códec de audio neuronal que integra información semántica de modelos auto-supervisados (p. ej., HuBERT) junto con la información acústica tradicional. Esto permite:

- **Continuación musical**: Un mejor modelado de la semántica musical produce continuaciones más coherentes.
- **Síntesis de texto a sonido**: X-Codec captura la alineación semántica entre los prompts de texto y el audio generado.
- **Tokenización de audio consciente del significado**: X-Codec se utiliza como tokenizador de audio en el modelo de generación de canciones a partir de letras de YuE.

El resumen del artículo establece lo siguiente:

*Los avances recientes en la generación de audio han sido impulsados de manera significativa por las capacidades de los modelos de lenguaje de gran escala (LLM). La investigación existente sobre LLM de audio se ha centrado principalmente en mejorar la arquitectura y la escala de los modelos de lenguaje de audio, así como en el uso de conjuntos de datos más grandes. En general, se utilizan códecs acústicos, como EnCodec, para la tokenización de audio. Sin embargo, estos códecs fueron diseñados originalmente para la compresión de audio, lo que puede dar lugar a un rendimiento subóptimo en el contexto de los LLM de audio. Nuestra investigación tiene como objetivo abordar las deficiencias de los códecs actuales de LLM de audio, en particular sus dificultades para mantener la integridad semántica en el audio generado. Por ejemplo, los métodos existentes, como VALL-E, que condicionan la generación de tokens acústicos en transcripciones de texto, suelen sufrir de inexactitudes en el contenido y tasas de error de palabra (WER) elevadas debido a la interpretación semántica errónea de los tokens acústicos, lo que resulta en la omisión de palabras y errores. Para superar estos problemas, proponemos un enfoque sencillo pero efectivo llamado X-Codec. X-Codec incorpora características semánticas de un codificador semántico preentrenado antes de la etapa de Cuantización Vectorial Residual (RVQ) e introduce una pérdida de reconstrucción semántica después de la RVQ. Al mejorar la capacidad semántica del códec, X-Codec reduce significativamente la WER en las tareas de síntesis de voz y extiende estos beneficios a aplicaciones no vocales, incluida la generación de música y sonido. Nuestros experimentos en tareas de texto a voz, continuación de música y texto a sonido demuestran que la integración de información semántica mejora sustancialmente el rendimiento general de los modelos de lenguaje en la generación de audio.*

Tarjetas de modelo:

- [xcodec-hubert-librispeech](https://huggingface.co/hf-audio/xcodec-hubert-librispeech) (para audio)
- [xcodec-wavlm-mls](https://huggingface.co/hf-audio/xcodec-wavlm-mls) (para voz)
- [xcodec-wavlm-more-data](https://huggingface.co/hf-audio/xcodec-wavlm-more-data) (para el habla)
- [xcodec-hubert-general](https://huggingface.co/hf-audio/xcodec-hubert-general) (para audio general)
- [xcodec-hubert-general-balanced](https://huggingface.co/hf-audio/xcodec-hubert-general-balanced) (para audio general)

Este modelo fue aportado por [Manal El Aidouni](https://huggingface.co/Manel). El código original se puede encontrar [aquí](https://github.com/zhenye234/xcodec) y los puntos de control originales de los cinco modelos diferentes [aquí](https://github.com/zhenye234/xcodec?tab=readme-ov-file#available-models).

Las demostraciones se pueden encontrar en esta [página](https://x-codec-audio.github.io/).

## Ejemplo de uso

Aquí hay un ejemplo rápido de cómo codificar y decodificar un audio con este modelo:

```python
from datasets import Audio, load_dataset

from transformers import AutoFeatureExtractor, XcodecModel

dummy_dataset = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation")

# load model and feature extractor
model_id = "hf-audio/xcodec-hubert-librispeech"
model = XcodecModel.from_pretrained(model_id, device_map="auto")
feature_extractor = AutoFeatureExtractor.from_pretrained(model_id)

# load audio sample
dummy_dataset = dummy_dataset.cast_column("audio", Audio(sampling_rate=feature_extractor.sampling_rate))
audio_sample = dummy_dataset[-1]["audio"]["array"]
inputs = feature_extractor(raw_audio=audio_sample, sampling_rate=feature_extractor.sampling_rate, return_tensors="pt").to(model.device)

# encode and decode
encoder_outputs = model.encode(inputs["input_values"])
decoder_outputs = model.decode(encoder_outputs.audio_codes)
audio_values = decoder_outputs.audio_values

# or the equivalent with a forward pass
audio_values = model(inputs["input_values"]).audio_values
```

Para escuchar el audio original y el reconstruido, ejecuta el fragmento de código siguiente y luego abre los archivos generados `original.wav` y `reconstruction.wav` en tu reproductor de música para compararlos.

```python
import soundfile as sf

original = audio_sample
reconstruction = audio_values[0].cpu().detach().numpy()
sampling_rate = feature_extractor.sampling_rate

sf.write("original.wav", original, sampling_rate)
sf.write("reconstruction.wav", reconstruction.T, sampling_rate)
```

## XcodecConfig[[transformers.XcodecConfig]]

#### transformers.XcodecConfig[[transformers.XcodecConfig]]

```python
transformers.XcodecConfig(transformers_version: str | None = None, architectures: list[str] | None = None, output_hidden_states: bool | None = False, return_dict: bool | None = True, dtype: str | torch.dtype | None = None, chunk_size_feed_forward: int = 0, is_encoder_decoder: bool = False, id2label: dict[int, str] | dict[str, str] | None = None, label2id: dict[str, int] | dict[str, str] | None = None, problem_type: Literal['regression', 'single_label_classification', 'multi_label_classification'] | None = None, target_bandwidths: list[int | float] | tuple[int | float, ...] = (0.5, 1, 1.5, 2, 4), sample_rate: int = 16000, kernel_size: int = 3, channel_ratios: list[int] | tuple[int, ...] = (1, 1), strides: list[int] | tuple[int, ...] = (1, 1), block_dilations: list[int] | tuple[int, ...] = (1, 1), unit_kernel_size: int = 3, codebook_size: int = 1024, codebook_dim: int | None = None, initializer_range: float = 0.02, acoustic_model_config: dict | transformers.configuration_utils.PreTrainedConfig | None = None, semantic_model_config: dict | transformers.configuration_utils.PreTrainedConfig | None = None)
```

[Fuente](https://github.com/huggingface/transformers/blob/main/src/transformers/models/xcodec/configuration_xcodec.py#L28)

**Parámetros:**

target_bandwidths (`List[float]`, *opcional*, valor predeterminado `[0.5, 1, 1.5, 2, 4]`) : El rango de distintas anchos de banda (en kbps) con los que el modelo puede codificar el audio.

sample_rate (`int`, *opcional*, valor predeterminado `16000`) : La frecuencia de muestreo a la que deben digitalizarse los archivos de audio, expresada en hercios (Hz).

kernel_size (`int`, *opcional*, valor predeterminado `3`) : El tamaño del kernel de convolución.

channel_ratios (`List[float]`, *opcional*, valor predeterminado `[1, 1]`) : Factores de expansión para el número de canales de salida en cada bloque semántico.

strides (`List[int]`, *opcional*, valor predeterminado `[1, 1]`) : Pasos para cada bloque del codificador semántico.

block_dilations (`List[int]`, *opcional*, valor predeterminado `[1, 1]`) : Factores de dilatación para las unidades residuales en los bloques semánticos.

unit_kernel_size (`int`, *opcional*, valor predeterminado 3) : Tamaño del kernel dentro de cada ResidualUnit en los bloques semánticos.

codebook_size (`int`, *opcional*, valor predeterminado `1024`) : El número de libros de códigos paralelos que utiliza el modelo.

codebook_dim (`int`, *opcional*) : Dimensionalidad de cada vector de incrustación del libro de códigos.

initializer_range (`float`, *opcional*, valor predeterminado `0.02`) : La desviación estándar de truncated_normal_initializer para inicializar todas las matrices de pesos.

acoustic_model_config (`Union[Dict, DacConfig]`, *opcional*) : Una instancia de la configuración para el modelo acústico (DAC).

semantic_model_config (`Union[Dict, HubertConfig, WavLMConfig]`, *opcional*) : Una instancia del objeto de configuración para el modelo semántico (HuBERT).

Esta es la clase de configuración para almacenar la configuración de un XcodecModel. Se utiliza para instanciar un modelo Xcodec según los argumentos especificados, definiendo la arquitectura del modelo. Instanciar una configuración con los valores predeterminados producirá una configuración similar a la de [Manel/X-Codec](https://huggingface.co/Manel/X-Codec)

Los objetos de configuración heredan de [PreTrainedConfig](/docs/transformers/main/es/main_classes/configuration#transformers.PreTrainedConfig) y se pueden utilizar para controlar las salidas del modelo. Consulte la documentación de [PreTrainedConfig](/docs/transformers/main/es/main_classes/configuration#transformers.PreTrainedConfig) para obtener más información.

Ejemplo:

```python
>>> from transformers import XcodecModel, XcodecConfig

>>> # Initializing configuration
>>> configuration = XcodecConfig()

>>> # Initializing a model (with random weights) from the configuration
>>> model = XcodecModel(configuration)

>>> # Accessing the model configuration
>>> configuration = model.config
```

## XcodecModel[[transformers.XcodecModel]]

#### transformers.XcodecModel[[transformers.XcodecModel]]

```python
transformers.XcodecModel(config: XcodecConfig)
```

[Fuente](https://github.com/huggingface/transformers/blob/main/src/transformers/models/xcodec/modeling_xcodec.py#L445)

**Parámetros:**

config ([XcodecConfig](/docs/transformers/main/es/model_doc/xcodec#transformers.XcodecConfig)) : Clase de configuración del modelo con todos los parámetros del modelo. Inicializar con un archivo de configuración no carga los pesos asociados con el modelo, solo la configuración. Consulte el método [from_pretrained()](/docs/transformers/main/es/main_classes/model#transformers.PreTrainedModel.from_pretrained) para cargar los pesos del modelo.

El modelo de códec de audio neuronal Xcodec.

Este modelo hereda de [PreTrainedModel](/docs/transformers/main/es/main_classes/model#transformers.PreTrainedModel). Consulte la documentación de la clase superior para los métodos genéricos que la biblioteca implementa para todos sus modelos (como la descarga o el guardado, el redimensionamiento de las incrustaciones de entrada, la poda de cabezas, etc.).

Este modelo también es una subclase de [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) de PyTorch. Úsalo como un módulo de PyTorch regular y consulta la documentación de PyTorch para todo lo relacionado con el uso y el comportamiento generales.

#### decode[[transformers.XcodecModel.decode]]

```python
decode(audio_codes: Tensor, return_dict: bool | None = None)
```

[Fuente](https://github.com/huggingface/transformers/blob/main/src/transformers/models/xcodec/modeling_xcodec.py#L541)

**Parámetros:**

audio_codes (`torch.LongTensor` de forma `(batch_size, num_quantizers, codes_length)`) : Índices de códigos discretos calculados mediante `model.encode`.

return_dict (`bool`, *opcional*) : Indica si se debe devolver un [ModelOutput](/docs/transformers/main/es/main_classes/output#transformers.utils.ModelOutput)

**Devuelve:**

Valores de audio decodificados de forma `(batch_size, channels, num_samples)` obtenidos mediante la parte decodificadora de Xcodec.

#### encode[[transformers.XcodecModel.encode]]

```python
encode(input_values: Tensor, bandwidth: float | None = None, return_dict: bool | None = None)
```

[Fuente](https://github.com/huggingface/transformers/blob/main/src/transformers/models/xcodec/modeling_xcodec.py#L489)

**Parámetros:**

input_values (`torch.Tensor` de forma `(batch_size, channels, num_samples)`) : Valores flotantes de la forma de onda de audio de entrada.

bandwidth (`float`, *opcional*) : El ancho de banda objetivo en (kbps) solo admite valores de `config.target_bandwidths`. El valor predeterminado es el ancho de banda disponible más alto, `4.0` kbps.

return_dict (`bool`, *opcional*) : Indica si se debe devolver un [ModelOutput](/docs/transformers/main/es/main_classes/output#transformers.utils.ModelOutput) o no.

**Devuelve:**

`torch.LongTensor` de forma `(batch_size, num_quantizers, codes_length)` que contiene los códigos de audio codificados de forma discreta.

#### forward[[transformers.XcodecModel.forward]]

```python
forward(input_values: Tensor, audio_codes: typing.Optional[torch.Tensor] = None, bandwidth: float | None = None, **kwargs: *<class 'transformers.utils.generic.TransformersKwargs'>)
```

[Fuente](https://github.com/huggingface/transformers/blob/main/src/transformers/models/xcodec/modeling_xcodec.py#L569)

**Parámetros:**

input_values (`torch.Tensor` de forma `(batch_size, channels, num_samples)`) : Los valores flotantes crudos de la forma de onda de audio de entrada.

audio_codes (`torch.LongTensor` de forma `(batch_size, num_quantizers, codes_length)` : Índices de códigos discretos calculados usando `model.encode`.

bandwidth (`float`, *opcional*) : Ancho de banda objetivo en kbps. Debe ser uno de `config.target_bandwidths`. El valor predeterminado es el ancho de banda disponible más alto.

bandwidth (`float`, *opcional*) : Ancho de banda objetivo en kbps. Debe ser uno de `config.target_bandwidths`. El valor predeterminado es el ancho de banda disponible más alto.

**Devuelve:** `XcodecOutput` o la tupla `(audio_codes, audio_values)`

- `audio_codes` de forma `(batch_size, num_quantizers, codes_length)`: los códigos discretos cuantizados.
- `audio_values` de forma `(batch_size, channels, num_samples)`: la forma de onda de audio reconstruida a partir de los códigos.

El método forward de [XcodecModel](/docs/transformers/main/es/model_doc/xcodec#transformers.XcodecModel) reemplaza el método especial `__call__`.

Aunque la receta para la pasada hacia adelante debe definirse dentro de esta función, se debe llamar a la instancia de `Module` después, en lugar de a esta, ya que la primera se encarga de ejecutar los pasos de preprocesamiento y posprocesamiento, mientras que la segunda los ignora silenciosamente.

Ejemplo:

```python
>>> from datasets import load_dataset
>>> from transformers import AutoFeatureExtractor, XcodecModel

>>> model_id = "hf-audio/xcodec-hubert-librispeech"
>>> model = XcodecModel.from_pretrained(model_id)
>>> feature_extractor = AutoFeatureExtractor.from_pretrained(model_id)

>>> dataset = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation")
>>> dataset = dataset.cast_column("audio", Audio(sampling_rate=feature_extractor.sampling_rate))
>>> audio_sample = dataset[0]['audio']['array']

>>> inputs = feature_extractor(raw_audio=audio_sample, return_tensors="pt")

>>> outputs = model(**inputs)
>>> audio_codes = outputs.audio_codes
>>> audio_values = outputs.audio_values
```

