# X-Codec

## 概述

X-Codec 模型由 Zhen Ye、Peiwen Sun、Jiahe Lei、Hongzhan Lin、Xu Tan、Zheqi Dai、Qiuqiang Kong、Jianyi Chen、Jiahao Pan、Qifeng Liu、Yike Guo 和 Wei Xue 在 [Codec Does Matter: Exploring the Semantic Shortcoming of Codec for Audio Language Model](https://huggingface.co/papers/2408.17175) 中提出。

X-Codec 模型是一种神经音频编解码器，它将自监督模型（例如 HuBERT）中的语义信息与传统的声学信息相结合。这使得：

- **音乐续写**：对音乐语义的更好建模能够生成更连贯的续写内容。
- **文本到声音合成**：X-Codec 捕获了文本提示词与生成音频之间的语义对齐。
- **语义感知音频分词**：X-Codec 被用作 YuE 歌词到歌曲生成模型中的音频分词器。

该论文的摘要指出：

*音频生成领域的最新进展在很大程度上得益于大语言模型（LLM）的能力。现有的音频 LLM 研究主要集中于提升音频语言模型的架构与规模，以及利用更大的数据集；通常，会使用 EnCodec 等声学编解码器进行音频分词。然而，这些编解码器最初是为音频压缩而设计的，在音频 LLM 的语境下可能会导致次优的性能。我们的研究旨在解决当前音频 LLM 编解码器的不足，特别是它们在生成音频中保持语义完整性方面面临的挑战。例如，VALL-E 等现有方法以文本转录为条件来生成声学 token，往往会因对声学 token 的语义误解而出现内容不准确和较高的词错误率（WER），从而导致漏词和错误。为了克服这些问题，我们提出了一种简单而有效的方法，称为 X-Codec。X-Codec 在残差向量量化（RVQ）阶段之前引入了来自预训练语义编码器的语义特征，并在 RVQ 之后引入了语义重建损失。通过增强编解码器的语义能力，X-Codec 显著降低了语音合成任务中的 WER，并将这些优势扩展到非语音应用，包括音乐和声音生成。我们在文本转语音、音乐续写和文本转声音任务中的实验表明，整合语义信息能够显著提升语言模型在音频生成中的整体性能。*

模型卡片：

- [xcodec-hubert-librispeech](https://huggingface.co/hf-audio/xcodec-hubert-librispeech)（用于语音）
- [xcodec-wavlm-mls](https://huggingface.co/hf-audio/xcodec-wavlm-mls)（用于语音）
- [xcodec-wavlm-more-data](https://huggingface.co/hf-audio/xcodec-wavlm-more-data)（用于语音）
- [xcodec-hubert-general](https://huggingface.co/hf-audio/xcodec-hubert-general)（用于通用音频）
- [xcodec-hubert-general-balanced](https://huggingface.co/hf-audio/xcodec-hubert-general-balanced)（用于通用音频）

该模型由 [Manal El Aidouni](https://huggingface.co/Manel) 贡献。原始代码可在 [此处](https://github.com/zhenye234/xcodec) 找到，五个不同模型的原始检查点可在 [此处](https://github.com/zhenye234/xcodec?tab=readme-ov-file#available-models) 找到。

演示可以在这个[页面](https://x-codec-audio.github.io/)上找到。

## 使用示例

以下是使用此模型对音频进行编码和解码的简单示例：

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

要收听原始音频和重建后的音频，请运行以下代码片段，然后在音乐播放器中打开生成的 `original.wav` 和 `reconstruction.wav` 文件进行对比。

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

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

**参数：**

target_bandwidths (`List[float]`, *可选*, 默认为 `[0.5, 1, 1.5, 2, 4]`) : 模型可用于编码音频的不同带宽范围（以 kbps 为单位）。

sample_rate (`int`, *可选*，默认为 `16000`)：音频文件应被数字化采样的采样率，以赫兹（Hz）为单位。

kernel_size (`int`, *可选*, 默认为 `3`) : 卷积核的大小。

channel_ratios (`List[float]`，*可选*，默认为 `[1, 1]`)：每个语义块中输出通道数的扩展因子。

strides (`List[int]`，*可选*，默认为 `[1, 1]`)：每个语义编码器块的步长。

block_dilations (`List[int]`，*可选*，默认为 `[1, 1]`)：语义块中残差单元的空洞率因子。

unit_kernel_size (`int`，*可选*，默认为 3)：语义块中每个 ResidualUnit 内部的核大小。

codebook_size (`int`，*可选*，默认为 `1024`)：模型使用的并行码本数量。

codebook_dim (`int`, *可选*) : 每个码本嵌入向量的维度。

initializer_range (`float`，*可选*，默认值为 `0.02`)：用于初始化所有权重矩阵的 truncated_normal_initializer 的标准差。

acoustic_model_config (`Union[Dict, DacConfig]`, *可选*) : 声学（DAC）模型的配置实例。

semantic_model_config (`Union[Dict, HubertConfig, WavLMConfig]`, *可选*) : 语义（HuBERT）模型的配置对象实例。

这是用于存储 XcodecModel 配置的类。它根据指定的参数实例化 Xcodec 模型，并定义模型架构。使用默认值实例化配置将生成与 [Manel/X-Codec](https://huggingface.co/Manel/X-Codec) 类似的配置。

配置对象继承自 [PreTrainedConfig](/docs/transformers/main/zh/main_classes/configuration#transformers.PreTrainedConfig)，可用于控制模型输出。有关更多信息，请参阅 [PreTrainedConfig](/docs/transformers/main/zh/main_classes/configuration#transformers.PreTrainedConfig) 的文档。

示例：

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

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

**参数：**

config ([XcodecConfig](/docs/transformers/main/zh/model_doc/xcodec#transformers.XcodecConfig))：模型配置类，包含模型的所有参数。使用配置文件进行初始化时，不会加载与模型关联的权重，仅加载配置。请查看 [from_pretrained()](/docs/transformers/main/zh/main_classes/model#transformers.PreTrainedModel.from_pretrained) 方法以加载模型权重。

Xcodec 神经音频编解码器模型。

该模型继承自 [PreTrainedModel](/docs/transformers/main/zh/main_classes/model#transformers.PreTrainedModel)。请查阅父类文档，了解该库为所有模型实现的通用方法（例如下载或保存、调整输入嵌入大小、剪枝头等）。

该模型也是 PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) 的子类。请将其作为常规的 PyTorch Module 使用，有关通用用法和行为的所有事项，请参阅 PyTorch 文档。

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

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

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

**参数：**

audio_codes (`torch.LongTensor`，形状为 `(batch_size, num_quantizers, codes_length)`)：使用 `model.encode` 计算得出的离散代码索引。

return_dict (`bool`, *可选*) : 是否返回 [ModelOutput](/docs/transformers/main/zh/main_classes/output#transformers.utils.ModelOutput)

**返回值：**

使用 Xcodec 的解码器部分获得的形状为 `(batch_size, channels, num_samples)` 的解码音频值。

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

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

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

**参数：**

input_values (`torch.Tensor`，形状为 `(batch_size, channels, num_samples)`)：输入音频波形的浮点值。

bandwidth (`float`, *可选*) : 目标带宽（kbps），仅支持 `config.target_bandwidths` 中的值。默认为最高可用带宽 `4.0` kbps。

return_dict (`bool`, *可选*) : 是否返回 [ModelOutput](/docs/transformers/main/zh/main_classes/output#transformers.utils.ModelOutput)。

**返回值：**

形状为 `(batch_size, num_quantizers, codes_length)` 的 `torch.LongTensor`，包含离散编码的音频码。

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

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

**参数：**

input_values (`torch.Tensor`，形状为 `(batch_size, channels, num_samples)`)：输入音频波形的原始浮点值。

audio_codes (`torch.LongTensor`，形状为 `(batch_size, num_quantizers, codes_length)`：使用 `model.encode` 计算得出的离散代码索引。

bandwidth (`float`, *可选*) : 目标带宽，单位为 kbps。必须是 `config.target_bandwidths` 中的一个值。默认使用可用的最高带宽。

bandwidth (`float`, *可选*) : 目标带宽，单位为 kbps。必须是 `config.target_bandwidths` 中的一个值。默认使用可用的最高带宽。

**返回：** `XcodecOutput` 或元组 `(audio_codes, audio_values)`

- 形状为 `(batch_size, num_quantizers, codes_length)` 的 `audio_codes`：量化后的离散编码。
- 形状为 `(batch_size, channels, num_samples)` 的 `audio_values`：根据编码重建的音频波形。

[XcodecModel](/docs/transformers/main/zh/model_doc/xcodec#transformers.XcodecModel) 的 forward 方法重写了 `__call__` 特殊方法。

尽管前向传播的实现需要在此函数中定义，但之后应调用 `Module` 实例，而不是直接调用此函数，因为前者会负责执行预处理和后处理步骤，而后者会静默地忽略这些步骤。

示例：

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

