# X-Codec

## Обзор

Модель X-Codec была предложена в статье [Codec Does Matter: Exploring the Semantic Shortcoming of Codec for Audio Language Model](https://huggingface.co/papers/2408.17175) авторами Zhen Ye, Peiwen Sun, Jiahe Lei, Hongzhan Lin, Xu Tan, Zheqi Dai, Qiuqiang Kong, Jianyi Chen, Jiahao Pan, Qifeng Liu, Yike Guo, Wei Xue.

Модель X-Codec — это нейронный аудиокодек, который объединяет семантическую информацию из самообучаемых моделей (например, HuBERT) с традиционной акустической информацией. Это позволяет:

- **Продолжение музыки**: Более точное моделирование музыкальной семантики обеспечивает более связные продолжения.
- **Синтез звука из текста**: X-Codec обеспечивает семантическое согласование между текстовыми запросами и генерируемым аудио.
- **Семантически осведомленная токенизация аудио**: X-Codec используется в качестве аудио-токенизатора в модели YuE для генерации песни по тексту.

В аннотации к статье сказано следующее:

*Недавние достижения в области генерации аудио были значительно продвинуты благодаря возможностям больших языковых моделей (LLM). Существующие исследования в области аудио-LLM в основном сосредоточены на улучшении архитектуры и масштаба моделей аудиоязыка, а также на использовании более крупных наборов данных. Как правило, для токенизации аудио применяются акустические кодексы, такие как EnCodec. Однако эти кодексы изначально были разработаны для сжатия аудио, что может приводить к неоптимальной производительности в контексте аудио-LLM. Наша работа направлена на устранение недостатков текущих кодеков для аудио-LLM, в частности, их трудностей с сохранением семантической целостности в генерируемом аудио. Например, существующие методы, такие как VALL-E, которые обусловливают генерацию акустических токенов текстовой транскрипцией, часто страдают от неточностей в содержании и повышенного показателя ошибки распознавания слов (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]`) : Диапазон различных значений полосы пропускания (в кбит/с), с которыми модель может кодировать аудио.

sample_rate (`int`, *optional*, по умолчанию `16000`) : Частота дискретизации, с которой аудиофайлы должны быть оцифрованы, выраженная в герцах (Гц).

kernel_size (`int`, *optional*, по умолчанию `3`) : Размер свёрточного ядра.

channel_ratios (`List[float]`, *необязательный*, по умолчанию `[1, 1]`) : Коэффициенты расширения для количества выходных каналов в каждом семантическом блоке.

strides (`List[int]`, *необязательный*, по умолчанию `[1, 1]`) : Шаги для каждого блока семантического кодировщика.

block_dilations (`List[int]`, *необязательный*, по умолчанию `[1, 1]`) : Коэффициенты дилатации для остаточных блоков в семантических блоках.

unit_kernel_size (`int`, *optional*, по умолчанию 3) : Размер ядра внутри каждого ResidualUnit в семантических блоках.

codebook_size (`int`, *необязательный*, по умолчанию `1024`) : Количество параллельных кодовых книг, используемых моделью.

codebook_dim (`int`, *optional*) : Размерность каждого вектора встраивания из книги кодов.

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/ru/main_classes/configuration#transformers.PreTrainedConfig) и могут использоваться для управления выводами модели. Подробнее см. в документации [PreTrainedConfig](/docs/transformers/main/ru/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/ru/model_doc/xcodec#transformers.XcodecConfig)) : класс конфигурации модели со всеми параметрами модели. Инициализация с файлом конфигурации не загружает веса, связанные с моделью, только конфигурацию. Используйте метод [from_pretrained()](/docs/transformers/main/ru/main_classes/model#transformers.PreTrainedModel.from_pretrained) для загрузки весов модели.

Модель нейросетевого аудиокодека Xcodec.

Эта модель наследуется от [PreTrainedModel](/docs/transformers/main/ru/main_classes/model#transformers.PreTrainedModel). Общие методы, которые библиотека реализует для всех своих моделей (например, загрузка или сохранение, изменение размера входных эмбеддингов, обрезка головок и т. д.), описаны в документации родительского класса.

Эта модель также является подклассом [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) в PyTorch. Используйте её как обычный модуль PyTorch и обращайтесь к документации 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/ru/main_classes/output#transformers.utils.ModelOutput)

**Возвращаемое значение:**

Декодированные значения аудио с формой `(batch_size, channels, num_samples)`, полученные с использованием декодерной части Xcodec.

#### 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)`) : Значения типа Float входной аудиоволны.

bandwidth (`float`, *optional*) : Целевая пропускная способность в (кбит/с), поддерживаются только значения из `config.target_bandwidths`. По умолчанию используется максимальная доступная пропускная способность `4.0` кбит/с.

return_dict (`bool`, *необязательный*) : Нужно ли возвращать [ModelOutput](/docs/transformers/main/ru/main_classes/output#transformers.utils.ModelOutput).

**Возвращаемое значение:**

`torch.LongTensor` формы `(batch_size, num_quantizers, codes_length)`, содержащий дискретные закодированные аудиокоды.

#### 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`, *optional*) : Целевая пропускная способность в кбит/с. Должно быть одним из значений `config.target_bandwidths`. По умолчанию используется максимальная доступная пропускная способность.

bandwidth (`float`, *optional*) : Целевая пропускная способность в кбит/с. Должно быть одним из значений `config.target_bandwidths`. По умолчанию используется максимальная доступная пропускная способность.

**Возвращает:** `XcodecOutput` или кортеж `(audio_codes, audio_values)`

- `audio_codes` формы `(batch_size, num_quantizers, codes_length)`: квантованные дискретные коды.
- `audio_values` формы `(batch_size, channels, num_samples)`: восстановленная аудиоволна, полученная по кодам.

Метод forward модели [XcodecModel](/docs/transformers/main/ru/model_doc/xcodec#transformers.XcodecModel) переопределяет специальный метод `__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
```

