# EnCodec

## 概述

EnCodec 神经编解码模型由 Alexandre Défossez、Jade Copet、Gabriel Synnaeve 和 Yossi Adi 在 [High Fidelity Neural Audio Compression](https://huggingface.co/papers/2210.13438) 中提出。

该论文的摘要如下：

*我们提出了一种基于神经网络的实时、高保真音频编解码器。该编解码器采用流式编码器-解码器架构，其量化潜在空间通过端到端方式训练。我们使用单一的多尺度频谱对抗器来简化并加速训练过程，从而高效地减少伪影并生成高质量样本。我们引入了一种新颖的损失平衡器机制以稳定训练：损失的权重现在定义了该损失应占整体梯度的比例，从而将该超参数的选择与损失的典型尺度解耦。最后，我们研究了如何利用轻量级 Transformer 模型在保持快于实时速度的同时，将所得表示进一步压缩多达 40%。我们详细描述了所提出模型的关键设计选择，包括：训练目标、架构变更以及对各种感知损失函数的研究。我们展示了广泛的听感评估（MUSHRA 测试）以及针对多种带宽和音频领域的消融研究，涵盖语音、带噪声混响的语音和音乐。在所有评估设置中，无论是 24 kHz 单声道还是 48 kHz 立体声音频，我们的方法均优于基线方法。*

该模型由 [Matthijs](https://huggingface.co/Matthijs)、[Patrick Von Platen](https://huggingface.co/patrickvonplaten) 和 [Arthur Zucker](https://huggingface.co/ArthurZ) 贡献。原始代码可在[此处](https://github.com/facebookresearch/encodec)找到。

## 使用示例

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

```python
from datasets import Audio, load_dataset

from transformers import AutoProcessor, EncodecModel

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

model = EncodecModel.from_pretrained("facebook/encodec_24khz", device_map="auto")
processor = AutoProcessor.from_pretrained("facebook/encodec_24khz")
librispeech_dummy = librispeech_dummy.cast_column("audio", Audio(sampling_rate=processor.sampling_rate))
audio_sample = librispeech_dummy[-1]["audio"]["array"]
inputs = processor(raw_audio=audio_sample, sampling_rate=processor.sampling_rate, return_tensors="pt").to(model.device)

encoder_outputs = model.encode(inputs["input_values"], inputs["padding_mask"])
# `encoder_outputs.audio_codes` contains discrete codes
audio_values = model.decode(**encoder_outputs, padding_mask=inputs["padding_mask"])[0]
# or the equivalent with a forward pass
audio_values = model(inputs["input_values"], inputs["padding_mask"]).audio_values
```

## EncodecConfig[[transformers.EncodecConfig]]

#### transformers.EncodecConfig[[transformers.EncodecConfig]]

```python
transformers.EncodecConfig(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[float] | tuple[float, ...] = (1.5, 3.0, 6.0, 12.0, 24.0), sampling_rate: int = 24000, audio_channels: int = 1, normalize: bool = False, chunk_length_s: int | float | None = None, overlap: float | None = None, hidden_size: int = 128, num_filters: int = 32, num_residual_layers: int = 1, upsampling_ratios: list[int] | tuple[int, ...] = (8, 5, 4, 2), norm_type: str = 'weight_norm', kernel_size: int = 7, last_kernel_size: int = 7, residual_kernel_size: int = 3, dilation_growth_rate: int = 2, use_causal_conv: bool = True, pad_mode: str = 'reflect', compress: int = 2, num_lstm_layers: int = 2, trim_right_ratio: float = 1.0, codebook_size: int = 1024, codebook_dim: int | None = None, use_conv_shortcut: bool = True)
```

[来源](https://github.com/huggingface/transformers/blob/main/src/transformers/models/encodec/configuration_encodec.py#L27)

**参数：**

target_bandwidths (`list[float]`，*可选*，默认为 `[1.5, 3.0, 6.0, 12.0, 24.0]`)：模型可用于编码音频的不同带宽范围。

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

audio_channels (`int`，*可选*，默认为 `1`)：输入通道数。

normalize (`bool`，*可选*，默认为 `False`)：传入音频时是否对其进行归一化。

chunk_length_s (`float`, *可选*) : 如果已定义，音频将被预处理为长度为 `chunk_length_s` 的块，然后进行编码。

overlap (`float`, *可选*) : 定义每个块之间的重叠部分。它用于通过以下公式计算 `chunk_stride`：`int((1.0 - self.overlap) * self.chunk_length)`。

hidden_size (`int`，*可选*，默认为 `128`)：隐藏表示的维度。

num_filters (`int`，*可选*，默认为 32)：第一个 `EncodecConv1d` 下采样层的卷积核数量。

num_residual_layers (`int`，*可选*，默认为 1)：残差层的数量。

upsampling_ratios (`Sequence[int]` ，*可选*，默认为 `[8, 5, 4, 2]`)：核大小和步长比率。编码器使用下采样比率而非上采样比率，因此它将使用与此处指定的比率相反的顺序，该顺序必须与解码器的顺序相匹配。

norm_type (`str`，*可选*，默认为 `"weight_norm"`)：归一化方法。应为 `["weight_norm", "time_group_norm"]` 之一

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

last_kernel_size (`int`，*可选*，默认为 7)：最后一个卷积层的核大小。

residual_kernel_size (`int`，*可选*，默认为 3)：残差层的核大小。

dilation_growth_rate (`int`，*可选*，默认为 2)：每层膨胀率增加的数值。

use_causal_conv (`bool`，*可选*，默认为 `True`)：是否使用完全因果卷积。

pad_mode (`str`，*可选*，默认为 `"reflect"`)：卷积的填充模式。

compress (`int`，*可选*，默认为 2)：残差分支中的降维（来自 Demucs v3）。

num_lstm_layers (`int`，*可选*，默认为 2)：编码器末尾的 LSTM 层数。

trim_right_ratio (`float`, *可选*，默认为 1.0)：在 `use_causal_conv = True` 设置下，用于在转置卷积右侧进行裁剪的比例。如果等于 1.0，则表示所有裁剪都在右侧进行。

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

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

use_conv_shortcut (`bool`，*可选*，默认为 `True`)：是否在 `EncodecResnetBlock` 块中使用卷积层作为“skip”连接。如果为 False，则使用恒等函数，从而形成通用的残差连接。

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

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

示例：

```python
>>> from transformers import EncodecModel, EncodecConfig

>>> # Initializing a "facebook/encodec_24khz" style configuration
>>> configuration = EncodecConfig()

>>> # Initializing a model (with random weights) from the "facebook/encodec_24khz" style configuration
>>> model = EncodecModel(configuration)

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

## EncodecFeatureExtractor[[transformers.EncodecFeatureExtractor]]

#### transformers.EncodecFeatureExtractor[[transformers.EncodecFeatureExtractor]]

```python
transformers.EncodecFeatureExtractor(feature_size: int = 1, sampling_rate: int = 24000, padding_value: float = 0.0, chunk_length_s: float | None = None, overlap: float | None = None, **kwargs)
```

[来源](https://github.com/huggingface/transformers/blob/main/src/transformers/models/encodec/feature_extraction_encodec.py#L26)

**参数：**

feature_size (`int`，*可选*，默认为 1)：提取特征的维度。单声道使用 1，立体声使用 2。

sampling_rate (`int`, *可选*，默认为 24000)：音频波形应被数字化采样的采样率，以赫兹 (Hz) 为单位。

padding_value (`float`，*可选*，默认值为 0.0)：用于填充填充值的数值。

chunk_length_s (`float`, *可选*) : 如果已定义，音频将被预处理为长度为 `chunk_length_s` 的块，然后进行编码。

overlap (`float`, *可选*) : 定义每个块之间的重叠部分。它用于通过以下公式计算 `chunk_stride`：`int((1.0 - self.overlap) * self.chunk_length)`。

构建 EnCodec 特征提取器。

此特征提取器继承自 [SequenceFeatureExtractor](/docs/transformers/main/zh/main_classes/feature_extractor#transformers.SequenceFeatureExtractor)，后者包含了大部分主要方法。有关这些方法的更多信息，请参阅该父类。

使用默认参数实例化特征提取器，将得到与 [facebook/encodec_24khz](https://huggingface.co/facebook/encodec_24khz) 架构类似的配置。

#### __调用__[[transformers.EncodecFeatureExtractor.__call__]]

```python
__call__(raw_audio: numpy.ndarray | list[float] | list[numpy.ndarray] | list[list[float]], padding: bool | str | transformers.utils.generic.PaddingStrategy | None = None, truncation: bool | None = False, max_length: int | None = None, return_tensors: str | transformers.utils.generic.TensorType | None = None, sampling_rate: int | None = None)
```

[来源](https://github.com/huggingface/transformers/blob/main/src/transformers/models/encodec/feature_extraction_encodec.py#L81)

**参数：**

raw_audio (`np.ndarray`、`list[float]`、`list[np.ndarray]`、`list[list[float]]`)：要处理的序列或序列批次。每个序列可以是 numpy 数组、浮点值列表、numpy 数组列表或浮点值列表的列表。对于单声道音频（`feature_size = 1`），numpy 数组的形状必须为 `(num_samples,)`；对于立体声音频（`feature_size = 2`），形状必须为 `(2, num_samples)`。

padding (`bool`、`str` 或 [PaddingStrategy](/docs/transformers/main/zh/internal/file_utils#transformers.utils.PaddingStrategy)，*可选*，默认为 `True`)：选择一种策略来填充返回的序列（根据模型的填充方向和填充索引），可选策略如下： - `True` 或 `'longest'`：填充到批次中最长的序列（如果只提供了单个序列，则不进行填充）。 - `'max_length'`：填充到由参数 `max_length` 指定的最大长度，或者如果未提供该参数，则填充到模型可接受的最大输入长度。 - `False` 或 `'do_not_pad'`（默认）：不进行填充（即可以输出包含不同长度序列的批次）。

truncation (`bool`, *可选*, 默认为 `False`) : 启用截断，将长度超过 `max_length` 的输入序列截断为 `max_length`。

max_length (`int`, *可选*) : 返回列表的最大长度，以及可选的填充长度（见上文）。

return_tensors (`str` 或 [TensorType](/docs/transformers/main/zh/internal/file_utils#transformers.TensorType)，*可选*)：如果设置，将返回张量而不是 Python 整数列表。可接受的值为： - `'pt'`：返回 PyTorch `torch.Tensor` 对象。 - `'np'`：返回 Numpy `np.ndarray` 对象。

sampling_rate (`int`, *可选*) : `audio` 输入的采样率。强烈建议在 forward 调用时传入 `sampling_rate`，以避免静默错误。

用于对一条或多条序列进行特征化并准备输入模型的主要方法。

## EncodecModel[[transformers.EncodecModel]]

#### transformers.EncodecModel[[transformers.EncodecModel]]

```python
transformers.EncodecModel(config: EncodecConfig)
```

[来源](https://github.com/huggingface/transformers/blob/main/src/transformers/models/encodec/modeling_encodec.py#L485)

**参数：**

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

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

该模型继承自 [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.EncodecModel.decode]]

```python
decode(audio_codes: LongTensor, audio_scales: Tensor, padding_mask: typing.Optional[torch.Tensor] = None, return_dict: bool | None = None, last_frame_pad_length: int | None = 0)
```

[来源](https://github.com/huggingface/transformers/blob/main/src/transformers/models/encodec/modeling_encodec.py#L661)

**参数：**

audio_codes (`torch.LongTensor`，形状为 `(nb_frames, batch_size, nb_quantizers, frame_len)`，*可选*)：使用 `model.encode` 计算得到的离散码嵌入。

audio_scales （长度为 `nb_frames` 的 `torch.Tensor` 列表，形状为 `(batch_size, 1)`，*可选*）：每个 `audio_codes` 输入的缩放因子。

padding_mask (`torch.Tensor`，形状为 `(channels, sequence_length)`)：用于填充 `input_values` 的填充掩码。

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

last_frame_pad_length (`int`, *可选*) : 表示最后一帧中填充长度的整数，该填充会在解码过程中被移除。

将给定的帧解码为输出音频波形。

请注意，输出可能比输入稍大。在这种情况下，可以裁剪末尾多余的步骤。

#### encode[[transformers.EncodecModel.encode]]

```python
encode(input_values: Tensor, padding_mask: typing.Optional[torch.Tensor] = None, bandwidth: float | None = None, return_dict: bool | None = None)
```

[来源](https://github.com/huggingface/transformers/blob/main/src/transformers/models/encodec/modeling_encodec.py#L525)

**参数：**

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

padding_mask (`torch.Tensor`，形状为 `(batch_size, channels, sequence_length)`)：用于填充 `input_values` 的填充掩码。

bandwidth (`float`, *可选*) : 目标带宽。必须是 `config.target_bandwidths` 中的一个值。如果为 `None`，则使用尽可能小的带宽。bandwidth 以其千分之一的值表示，例如 6kbps 的带宽表示为 bandwidth == 6.0

**返回：** `EncodecEncoderOutput dict or a tuple containing`

- audio_codes (`torch.LongTensor`，形状为 `(nb_frames, batch_size, nb_quantizers, frame_len)`，*可选*)，
- audio_scales （一个长度为 `nb_frames` 的列表，包含形状为 `(batch_size, 1)` 的 `torch.Tensor`，*可选*），
- last_frame_pad_length (`int`，*可选*)。

将输入音频波形编码为形状为 `(nb_frames, batch_size, nb_quantizers, frame_len)` 的离散码。

- 如果 `self.config.chunk_length=None`（因为编码器应用于完整音频），则 `nb_frames=1`，这是
对于 24kHz 模型的情况。否则，`nb_frames=ceil(input_length/self.config.chunk_stride)`，这是 48kHz 模型的情况。
- `frame_len` 是每个帧的长度，如果则等于 `ceil(input_length/self.config.hop_length)`
`self.config.chunk_length=None`（例如 24kHz 模型）。否则，如果定义了 `self.config.chunk_length`，则 `frame_len=self.config.chunk_length/self.config.hop_length`，例如 48kHz 模型中 `frame_len=150` 的情况。

#### forward[[transformers.EncodecModel.forward]]

```python
forward(input_values: Tensor, padding_mask: typing.Optional[torch.BoolTensor] = None, bandwidth: float | None = None, audio_codes: typing.Optional[torch.LongTensor] = None, audio_scales: typing.Optional[torch.Tensor] = None, return_dict: bool | None = None, last_frame_pad_length: int | None = 0)
```

[来源](https://github.com/huggingface/transformers/blob/main/src/transformers/models/encodec/modeling_encodec.py#L716)

**参数：**

input_values (`torch.Tensor`，形状为 `(batch_size, channels, sequence_length)`，*可选*)：原始音频输入，已转换为 Float 并填充至适当长度，以便使用长度为 self.chunk_length、步长为 `config.chunk_stride` 的块进行编码。

padding_mask (`torch.BoolTensor`，形状为 `(batch_size, channels, sequence_length)`，*可选*)：用于避免在填充（padding）标记索引上计算缩放因子的掩码（我们能否避免在这些位置上进行卷积计算？）。掩码值取自 `[0, 1]`： - 对于**未掩码**的标记，值为 1； - 对于**已掩码**的标记，值为 0。    除非输入被截断或未进行填充，否则应始终传入 `padding_mask`。这是因为为了有效处理张量，应对输入音频进行填充，使得 `input_length % stride = step`，其中 `step = chunk_length-stride`。这确保了所有块（chunk）的形状相同

bandwidth (`float`, *可选*) : 目标带宽。必须是 `config.target_bandwidths` 中的一个值。如果为 `None`，则使用尽可能小的带宽。bandwidth 以其千分之一的值表示，例如 6kbps 的带宽表示为 `bandwidth == 6.0`

audio_codes (`torch.LongTensor`，形状为 `(nb_frames, batch_size, nb_quantizers, frame_len)`，*可选*)：使用 `model.encode` 计算得到的离散码嵌入。

audio_scales (`list`，长度为 `nb_frames`，包含 `torch.Tensor`，形状为 `(batch_size, 1)`，*可选*) : 每个 `audio_codes` 输入的缩放因子。

return_dict (`bool`, *可选*) : 是否以字典形式返回输出。

last_frame_pad_length (`int`, *optional*) : 如果存在，最后一帧中填充的长度。此值用于确保编码后的帧可以作为张量输出。在解码时应传入此值，以确保从编码帧中移除填充。

**返回：** `EncodecOutput` 或 `tuple(torch.Tensor)`

`EncodecOutput` 或 `torch.Tensor` 元组（如果传入 `return_dict=False` 或 `config.return_dict=False`），其包含的元素取决于配置（[EncodecConfig](/docs/transformers/main/zh/model_doc/encodec#transformers.EncodecConfig)）和输入。

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

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

- **audio_codes**（形状为 `(nb_frames, batch_size, nb_quantizers, frame_len)` 的 `torch.LongTensor`，*可选*）-- 使用 `model.encode` 计算得出的离散码嵌入。
- **audio_values**（形状为 `(batch_size, segment_length)` 的 `torch.Tensor`，*可选*）-- 解码后的音频值，通过 Encodec 的解码器部分获得。

示例：

```python
>>> from datasets import load_dataset
>>> from transformers import AutoProcessor, EncodecModel

>>> dataset = load_dataset("hf-internal-testing/ashraq-esc50-1-dog-example")
>>> audio_sample = dataset["train"]["audio"][0]["array"]

>>> model_id = "facebook/encodec_24khz"
>>> model = EncodecModel.from_pretrained(model_id)
>>> processor = AutoProcessor.from_pretrained(model_id)

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

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

