# X-Codec

## Visão geral

O modelo X-Codec foi proposto em [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.

O modelo X-Codec é um codec de áudio neural que integra informações semânticas de modelos autorregressivos (por exemplo, HuBERT) junto com informações acústicas tradicionais. Isso permite:

- **Continuação de música**: Um melhor modelamento da semântica musical gera continuações mais coerentes.
- **Síntese de texto para som**: o X-Codec captura o alinhamento semântico entre os prompts de texto e o áudio gerado.
- **Tokenização de áudio com consciência semântica**: o X-Codec é usado como um tokenizador de áudio no modelo de geração de música a partir de letras do YuE.

O resumo do artigo afirma o seguinte:

*Os avanços recentes na geração de áudio foram impulsionados significativamente pelas capacidades dos Large Language Models (LLMs). A pesquisa existente em LLMs de áudio tem se concentrado principalmente no aprimoramento da arquitetura e da escala dos modelos de linguagem de áudio, bem como no uso de conjuntos de dados maiores. De modo geral, codecs acústicos, como o EnCodec, são utilizados para a tokenização de áudio. No entanto, esses codecs foram originalmente projetados para compressão de áudio, o que pode levar a um desempenho subótimo no contexto de LLMs de áudio. Nossa pesquisa visa abordar as deficiências dos codecs atuais de LLMs de áudio, em particular seus desafios em manter a integridade semântica no áudio gerado. Por exemplo, métodos existentes, como o VALL-E, que condicionam a geração de tokens acústicos em transcrições de texto, frequentemente sofrem com imprecisões de conteúdo e taxas de erro de palavra (WER) elevadas devido a interpretações semânticas incorretas dos tokens acústicos, resultando em omissões e erros de palavras. Para superar esses problemas, propomos uma abordagem simples, porém eficaz, chamada X-Codec. O X-Codec incorpora recursos semânticos de um codificador semântico pré-treinado antes do estágio de Residual Vector Quantization (RVQ) e introduz uma perda de reconstrução semântica após o RVQ. Ao aprimorar a capacidade semântica do codec, o X-Codec reduz significativamente o WER em tarefas de síntese de fala e estende esses benefícios a aplicações não vocais, incluindo a geração de música e de sons. Nossos experimentos em tarefas de texto-para-fala, continuação de música e texto-para-som demonstram que a integração de informações semânticas melhora substancialmente o desempenho geral dos modelos de linguagem na geração de áudio.*

Cartões de modelo:

- [xcodec-hubert-librispeech](https://huggingface.co/hf-audio/xcodec-hubert-librispeech) (para fala)
- [xcodec-wavlm-mls](https://huggingface.co/hf-audio/xcodec-wavlm-mls) (para fala)
- [xcodec-wavlm-more-data](https://huggingface.co/hf-audio/xcodec-wavlm-more-data) (para fala)
- [xcodec-hubert-general](https://huggingface.co/hf-audio/xcodec-hubert-general) (para áudio geral)
- [xcodec-hubert-general-balanced](https://huggingface.co/hf-audio/xcodec-hubert-general-balanced) (para áudio geral)

Este modelo foi contribuído por [Manal El Aidouni](https://huggingface.co/Manel). O código original pode ser encontrado [aqui](https://github.com/zhenye234/xcodec) e os checkpoints originais dos cinco modelos diferentes [aqui](https://github.com/zhenye234/xcodec?tab=readme-ov-file#available-models).

Os demos podem ser encontrados nesta [página](https://x-codec-audio.github.io/).

## Exemplo de uso

Aqui está um exemplo rápido de como codificar e decodificar um áudio usando 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 ouvir o áudio original e reconstruído, execute o trecho de código abaixo e, em seguida, abra os arquivos gerados `original.wav` e `reconstruction.wav` no seu player de música para comparar.

```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)
```

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

**Parâmetros:**

target_bandwidths (`List[float]`, *opcional*, padrão `[0.5, 1, 1.5, 2, 4]`) : A faixa de diferentes larguras de banda (em kbps) com as quais o modelo pode codificar áudio.

sample_rate (`int`, *opcional*, padrão `16000`) : A taxa de amostragem na qual os arquivos de áudio devem ser digitalizados, expressa em hertz (Hz).

kernel_size (`int`, *opcional*, padrão `3`) : O tamanho do kernel de convolução.

channel_ratios (`List[float]`, *opcional*, padrão `[1, 1]`) : Fatores de expansão para o número de canais de saída em cada bloco semântico.

strides (`List[int]`, *opcional*, padrão `[1, 1]`) : Passos para cada bloco do codificador semântico.

block_dilations (`List[int]`, *opcional*, padrão `[1, 1]`) : Fatores de dilatação para as unidades residuais nos blocos semânticos.

unit_kernel_size (`int`, *opcional*, padrão 3) : Tamanho do kernel dentro de cada ResidualUnit nos blocos semânticos.

codebook_size (`int`, *opcional*, padrão `1024`) : O número de codebooks paralelos usados pelo modelo.

codebook_dim (`int`, *opcional*) : Dimensionalidade de cada vetor de incorporação do codebook.

initializer_range (`float`, *opcional*, padrão `0.02`) : O desvio padrão do truncated_normal_initializer para inicializar todas as matrizes de pesos.

acoustic_model_config (`Union[Dict, DacConfig]`, *opcional*) : Uma instância da configuração para o modelo acústico (DAC).

semantic_model_config (`Union[Dict, HubertConfig, WavLMConfig]`, *opcional*) : Uma instância do objeto de configuração para o modelo semântico (HuBERT).

Esta é a classe de configuração para armazenar a configuração de um XcodecModel. Ela é usada para instanciar um modelo Xcodec de acordo com os argumentos especificados, definindo a arquitetura do modelo. Instanciar uma configuração com os padrões resultará em uma configuração semelhante à do [Manel/X-Codec](https://huggingface.co/Manel/X-Codec)

Os objetos de configuração herdam de [PreTrainedConfig](/docs/transformers/main/pt/main_classes/configuration#transformers.PreTrainedConfig) e podem ser usados para controlar as saídas do modelo. Leia a documentação de [PreTrainedConfig](/docs/transformers/main/pt/main_classes/configuration#transformers.PreTrainedConfig) para mais informações.

Exemplo:

```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)
```

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

**Parâmetros:**

config ([XcodecConfig](/docs/transformers/main/pt/model_doc/xcodec#transformers.XcodecConfig)) : Classe de configuração do modelo com todos os parâmetros do modelo. A inicialização com um arquivo de configuração não carrega os pesos associados ao modelo, apenas a configuração. Consulte o método [from_pretrained()](/docs/transformers/main/pt/main_classes/model#transformers.PreTrainedModel.from_pretrained) para carregar os pesos do modelo.

O modelo de codec neural de áudio Xcodec.

Este modelo herda de [PreTrainedModel](/docs/transformers/main/pt/main_classes/model#transformers.PreTrainedModel). Consulte a documentação da classe pai para os métodos genéricos que a biblioteca implementa para todos os seus modelos (como download ou salvamento, redimensionamento dos embeddings de entrada, poda de cabeças, etc.).

Este modelo também é uma subclasse de [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) do PyTorch. Use-o como um Módulo PyTorch regular e consulte a documentação do PyTorch para todos os assuntos relacionados ao uso e comportamento gerais.

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

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

[Origem](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 usando `model.encode`.

return_dict (`bool`, *opcional*) : Se deve ou não retornar um [ModelOutput](/docs/transformers/main/pt/main_classes/output#transformers.utils.ModelOutput)

**Retorna:**

Valores de áudio decodificados com forma `(batch_size, channels, num_samples)` obtidos usando a parte decodificadora do Xcodec.

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

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

[Origem](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 em ponto flutuante da forma de onda de áudio de entrada.

bandwidth (`float`, *opcional*) : A largura de banda alvo em (kbps) suporta apenas valores em `config.target_bandwidths`. O padrão é a maior largura de banda disponível, `4.0` kbps.

return_dict (`bool`, *opcional*) : Indica se deve ou não retornar um [ModelOutput](/docs/transformers/main/pt/main_classes/output#transformers.utils.ModelOutput).

**Retorna:**

`torch.LongTensor` de forma `(batch_size, num_quantizers, codes_length)` contendo os códigos de áudio discretos codificados.

#### 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'>)
```

[Origem](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)`) : Os valores flutuantes brutos da forma de onda de áudio 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*) : Largura de banda alvo em kbps. Deve ser um dos valores de `config.target_bandwidths`. O padrão é a maior largura de banda disponível.

bandwidth (`float`, *opcional*) : Largura de banda alvo em kbps. Deve ser um dos valores de `config.target_bandwidths`. O padrão é a maior largura de banda disponível.

**Retorna:** `XcodecOutput` ou tupla `(audio_codes, audio_values)`

- `audio_codes` de forma `(batch_size, num_quantizers, codes_length)`: os códigos discretos quantizados.
- `audio_values` com formato `(batch_size, channels, num_samples)`: a forma de onda de áudio reconstruída a partir dos códigos.

O método forward do [XcodecModel](/docs/transformers/main/pt/model_doc/xcodec#transformers.XcodecModel) substitui o método especial `__call__`.

Embora a receita para a passagem direta precise ser definida dentro desta função, deve-se chamar a instância de `Module` em seguida, em vez desta, pois a primeira cuida da execução das etapas de pré e pós-processamento, enquanto a segunda as ignora silenciosamente.

Exemplo:

```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
```

