# Audio-Course

## Docs

- [Дообучение модели для классификации музыки](https://huggingface.co/learn/audio-course/ru/chapter4/fine-tuning.md)
- [Предварительно обученные модели и наборы данных для классификации звука](https://huggingface.co/learn/audio-course/ru/chapter4/classification_models.md)
- [Практическое занятие](https://huggingface.co/learn/audio-course/ru/chapter4/hands_on.md)
- [Раздел 4. Разработка классификатора музыкальных жанров](https://huggingface.co/learn/audio-course/ru/chapter4/introduction.md)
- [Создание демонтрационного образца с Gradio](https://huggingface.co/learn/audio-course/ru/chapter4/demo.md)
- [Дообучение модели ASR](https://huggingface.co/learn/audio-course/ru/chapter5/fine-tuning.md)
- [Практическое занятие](https://huggingface.co/learn/audio-course/ru/chapter5/hands_on.md)
- [Чему вы научитесь и что создадите](https://huggingface.co/learn/audio-course/ru/chapter5/introduction.md)
- [Создание Демо с Gradio](https://huggingface.co/learn/audio-course/ru/chapter5/demo.md)
- [Дополнительные материалы и ресурсы](https://huggingface.co/learn/audio-course/ru/chapter5/supplemental_reading.md)
- [Предварительно обученные модели для распознавания речи](https://huggingface.co/learn/audio-course/ru/chapter5/asr_models.md)
- [Выбор набора данных](https://huggingface.co/learn/audio-course/ru/chapter5/choosing_dataset.md)
- [Evaluation metrics for ASR](https://huggingface.co/learn/audio-course/ru/chapter5/evaluation.md)
- [Подготовьтесь к прохождению курса](https://huggingface.co/learn/audio-course/ru/chapter0/get_ready.md)
- [Добро пожаловать на аудиокурс Hugging Face!](https://huggingface.co/learn/audio-course/ru/chapter0/introduction.md)
- [Присоединяйтесь к сообществу!](https://huggingface.co/learn/audio-course/ru/chapter0/community.md)
- [Живые занятия и семинары](https://huggingface.co/learn/audio-course/ru/events/introduction.md)
- [Классификация звука с помощью конвейера](https://huggingface.co/learn/audio-course/ru/chapter2/audio_classification_pipeline.md)
- [Автоматическое распознавание речи с помощью конвейера](https://huggingface.co/learn/audio-course/ru/chapter2/asr_pipeline.md)
- [Практическое занятие](https://huggingface.co/learn/audio-course/ru/chapter2/hands_on.md)
- [Раздел 2. Краткое введение в аудиоприложения](https://huggingface.co/learn/audio-course/ru/chapter2/introduction.md)
- [Дообучение SpeechT5](https://huggingface.co/learn/audio-course/ru/chapter6/fine-tuning.md)
- [Практическое занятие](https://huggingface.co/learn/audio-course/ru/chapter6/hands_on.md)
- [Наборах данных Text-to-speech](https://huggingface.co/learn/audio-course/ru/chapter6/tts_datasets.md)
- [Раздел 6. От текста к речи](https://huggingface.co/learn/audio-course/ru/chapter6/introduction.md)
- [Дополнительные материалы и ресурсы](https://huggingface.co/learn/audio-course/ru/chapter6/supplemental_reading.md)
- [Предварительно обученные модели text-to-speech](https://huggingface.co/learn/audio-course/ru/chapter6/pre-trained_models.md)
- [Оценка моделей text-to-speech](https://huggingface.co/learn/audio-course/ru/chapter6/evaluation.md)
- [Перевод Speech-to-speech](https://huggingface.co/learn/audio-course/ru/chapter7/speech-to-speech.md)
- [Практическое занятие](https://huggingface.co/learn/audio-course/ru/chapter7/hands-on.md)
- [Транскрибирование встречи](https://huggingface.co/learn/audio-course/ru/chapter7/transcribe-meeting.md)
- [Раздел 7. Собираем все воедино 🪢](https://huggingface.co/learn/audio-course/ru/chapter7/introduction.md)
- [Создание голосового ассистента](https://huggingface.co/learn/audio-course/ru/chapter7/voice-assistant.md)
- [Дополнительные материалы и ресурсы](https://huggingface.co/learn/audio-course/ru/chapter7/supplemental_reading.md)
- [Архитектуры Seq2Seq](https://huggingface.co/learn/audio-course/ru/chapter3/seq2seq.md)
- [Раздел 3. Архитектуры трансформеров для аудио](https://huggingface.co/learn/audio-course/ru/chapter3/introduction.md)
- [Дополнительные материалы и ресурсы](https://huggingface.co/learn/audio-course/ru/chapter3/supplemental_reading.md)
- [Архитектуры CTC](https://huggingface.co/learn/audio-course/ru/chapter3/ctc.md)
- [Архитектуры классификации аудио](https://huggingface.co/learn/audio-course/ru/chapter3/classification.md)
- [Проверьте свое понимание материала курса](https://huggingface.co/learn/audio-course/ru/chapter3/quiz.md)
- [Введение в аудиоданные](https://huggingface.co/learn/audio-course/ru/chapter1/audio_data.md)
- [Потоковая передача аудиоданных](https://huggingface.co/learn/audio-course/ru/chapter1/streaming.md)
- [Препроцессинг набора аудиоданных](https://huggingface.co/learn/audio-course/ru/chapter1/preprocessing.md)
- [Раздел 1. Работа с аудио данными](https://huggingface.co/learn/audio-course/ru/chapter1/introduction.md)
- [Загрузка и изучение аудио набора данных](https://huggingface.co/learn/audio-course/ru/chapter1/load_and_explore.md)
- [Как узнать больше](https://huggingface.co/learn/audio-course/ru/chapter1/supplemental_reading.md)
- [Проверьте свое понимание материала курса](https://huggingface.co/learn/audio-course/ru/chapter1/quiz.md)
- [Получение сертификата о прохождении курса](https://huggingface.co/learn/audio-course/ru/chapter8/certification.md)
- [Поздравляем!](https://huggingface.co/learn/audio-course/ru/chapter8/introduction.md)

### Дообучение модели для классификации музыки
https://huggingface.co/learn/audio-course/ru/chapter4/fine-tuning.md

# Дообучение модели для классификации музыки

В этом разделе мы представим пошаговое руководство по дообучению модели трансформера, использующей только кодеровщик,
для классификации музыки. Для демонстрации мы будем использовать облегченную модель и достаточно небольшой набор данных, что означает,
что код может быть запущен на любом GPU потребительского класса, включая GPU T4 16GB, предоставляемый в рамках бесплатного уровня Google Colab.
В разделе приведены различные советы, которые можно попробовать при использовании GPU меньшего размера и возникновении проблем с нехваткой памяти.

## Набор данных

Для обучения нашей модели мы будем использовать набор данных [GTZAN](https://huggingface.co/datasets/marsyas/gtzan), который представляет собой
популярный набор данных из 1000 песен для классификации музыкальных жанров. Каждая песня представляет собой 30-секундный клип из одного из 10
музыкальных жанров - от диско до металла. Мы можем получить аудиофайлы и соответствующие им метки из Hugging Face Hub с помощью функции
`load_dataset()` из 🤗 Datasets:

```python
from datasets import load_dataset

gtzan = load_dataset("marsyas/gtzan", "all")
gtzan
```

**Output:**
```out
Dataset({
    features: ['file', 'audio', 'genre'],
    num_rows: 999
})
```

Одна из записей в GTZAN повреждена, поэтому она была удалена из набора данных. Поэтому мы имеем 999 примеров
вместо 1000.

GTZAN не предоставляет предопределенного валидационного набора, поэтому нам придется создать его самостоятельно.
Набор данных сбалансирован по жанрам, поэтому мы можем использовать метод `train_test_split()` для быстрого
создания разбиения в пропорции 90/10 следующим образом:

```python
gtzan = gtzan.train_test_split(seed=42, shuffle=True, test_size=0.1)
gtzan
```

**Output:**
```out
DatasetDict({
    train: Dataset({
        features: ['file', 'audio', 'genre'],
        num_rows: 899
    })
    test: Dataset({
        features: ['file', 'audio', 'genre'],
        num_rows: 100
    })
})
```

Отлично, теперь, когда у нас есть обучающий и тестовый наборы, давайте посмотрим на один из аудиофайлов:

```python
gtzan["train"][0]
```

**Output:**
```out
{
    "file": "~/.cache/huggingface/datasets/downloads/extracted/fa06ce46130d3467683100aca945d6deafb642315765a784456e1d81c94715a8/genres/pop/pop.00098.wav",
    "audio": {
        "path": "~/.cache/huggingface/datasets/downloads/extracted/fa06ce46130d3467683100aca945d6deafb642315765a784456e1d81c94715a8/genres/pop/pop.00098.wav",
        "array": array(
            [
                0.10720825,
                0.16122437,
                0.28585815,
                ...,
                -0.22924805,
                -0.20629883,
                -0.11334229,
            ],
            dtype=float32,
        ),
        "sampling_rate": 22050,
    },
    "genre": 7,
}
```

Как мы видели в [Разделе 1](../chapter1/audio_data), аудиофайлы представлены в виде одномерных массивов NumPy,
где значение массива представляет собой амплитуду на заданном временном интервале. Для этих композиций частота дискретизации
составляет 22 050 Гц, то есть в секунду дискретизируется 22 050 значений амплитуды. Это необходимо учитывать при использовании
предварительно обученной модели с другой частотой дискретизации, самостоятельно преобразуя частоты дискретизации для обеспечения
их соответствия. Мы также видим, что жанр представлен в виде целого числа, или _class label_, то есть в том формате, в котором модель
будет делать свои предсказания. Воспользуемся методом `int2str()` функции `genre` для преобразования этих целых чисел в человекочитаемые имена:

```python
id2label_fn = gtzan["train"].features["genre"].int2str
id2label_fn(gtzan["train"][0]["genre"])
```

**Output:**
```out
'pop'
```

Эта метка выглядит корректно, поскольку совпадает с именем аудиофайла. Теперь рассмотрим еще несколько примеров на примере Gradio для создания простого
интерфейса с API `Blocks`:

```python
import gradio as gr

def generate_audio():
    example = gtzan["train"].shuffle()[0]
    audio = example["audio"]
    return (
        audio["sampling_rate"],
        audio["array"],
    ), id2label_fn(example["genre"])

with gr.Blocks() as demo:
    with gr.Column():
        for _ in range(4):
            audio, label = generate_audio()
            output = gr.Audio(audio, label=label)

demo.launch(debug=True)
```

Из этих образцов мы, конечно, можем услышать разницу между жанрами, но может ли это сделать трансформер? Давайте обучим модель,
чтобы выяснить это! Для начала нам нужно найти подходящую для этой задачи предварительно обученную модель. Посмотрим, как это можно сделать.

## Выбор предварительно обученной модели для классификации звука

Для начала выберем подходящую предварительно обученную модель для классификации звука. В этой области предварительное обучение обычно проводится
на больших объемах немаркированных аудиоданных, используя такие наборы данных, как [LibriSpeech](https://huggingface.co/datasets/librispeech_asr)
и [Voxpopuli](https://huggingface.co/datasets/facebook/voxpopuli). Лучший способ найти эти модели на Hugging Face Hub - использовать фильтр
"Audio Classification", как описано в предыдущем разделе. Хотя такие модели, как Wav2Vec2 и HuBERT, очень популярны, мы будем использовать модель
под названием _DistilHuBERT_. Это гораздо более компактная (или _дистиллированная_) версия модели [HuBERT](https://huggingface.co/docs/transformers/model_doc/hubert),
которая обучается примерно на 73% быстрее, сохраняя при этом большую часть производительности.

## От аудио к машинному обучению

## Предварительная обработка данных

Подобно токенизации в NLP, аудио- и речевые модели требуют, чтобы входные данные были закодированы в формате, который модель может обрабатывать.
В 🤗 Transformers преобразование звука во входной формат осуществляется с помощью _feature extractor_ модели. Подобно токенизаторам, 🤗 Transformers
предоставляет удобный класс `AutoFeatureExtractor`, который может автоматически выбирать нужный экстрактор признаков для заданной модели. Для того
чтобы увидеть, как мы можем обрабатывать наши аудиофайлы, давайте начнем с инстанцирования экстрактора признаков для DistilHuBERT из предварительно
обученной контрольной точки:

```python
from transformers import AutoFeatureExtractor

model_id = "ntu-spml/distilhubert"
feature_extractor = AutoFeatureExtractor.from_pretrained(
    model_id, do_normalize=True, return_attention_mask=True
)
```

Поскольку частота дискретизации модели и набора данных различна, перед передачей аудиофайла в программу извлечения признаков его необходимо
передискретизировать до 16 000 Гц. Для этого сначала нужно получить частоту дискретизации модели от экстрактора признаков:

```python
sampling_rate = feature_extractor.sampling_rate
sampling_rate
```

**Output:**
```out
16000
```

Далее мы проводим повторную выборку набора данных, используя метод `cast_column()` и функцию `Audio` из 🤗 Datasets:

```python
from datasets import Audio

gtzan = gtzan.cast_column("audio", Audio(sampling_rate=sampling_rate))
```

Теперь мы можем проверить первый сэмпл train-split нашего набора данных, чтобы убедиться, что он действительно находится
на частоте 16 000 Гц. При загрузке каждого сэмпла Datasets производит повторную дискретизацию аудиофайла "на лету":

```python
gtzan["train"][0]
```

**Output:**
```out
{
    "file": "~/.cache/huggingface/datasets/downloads/extracted/fa06ce46130d3467683100aca945d6deafb642315765a784456e1d81c94715a8/genres/pop/pop.00098.wav",
    "audio": {
        "path": "~/.cache/huggingface/datasets/downloads/extracted/fa06ce46130d3467683100aca945d6deafb642315765a784456e1d81c94715a8/genres/pop/pop.00098.wav",
        "array": array(
            [
                0.0873509,
                0.20183384,
                0.4790867,
                ...,
                -0.18743178,
                -0.23294401,
                -0.13517427,
            ],
            dtype=float32,
        ),
        "sampling_rate": 16000,
    },
    "genre": 7,
}
```

Отлично! Мы видим, что частота дискретизации была понижена до 16 кГц. Значения массива также отличаются, так как теперь на каждые 1,5 значения
амплитуды приходится примерно одно значение, которое мы имели раньше.

Отличительной особенностью моделей типа Wav2Vec2 и HuBERT является то, что они принимают на вход массив float, соответствующий исходной форме
речевого сигнала. В отличие от других моделей, например Whisper, в которых мы предварительно обрабатываем исходную форму звукового сигнала
до формата спектрограммы.

Мы уже упоминали, что аудиоданные представлены в виде одномерного массива, поэтому они уже имеют правильный формат для чтения моделью
(набор непрерывных входов с дискретными временными шагами). Чтож, что именно делает экстрактор признаков?

Итак, аудиоданные имеют правильный формат, но мы не наложили никаких ограничений на значения, которые они могут принимать. Для оптимальной работы
нашей модели необходимо, чтобы все входные данные находились в одном и том же динамическом диапазоне. Это позволит получить одинаковый диапазон активаций
и градиентов для наших образцов, что поможет обеспечить стабильность и сходимость в процессе обучения.

Для этого мы _нормализуем_ наши аудиоданные, приводя каждую выборку к нулевому среднему и единичной дисперсии - этот процесс называется
_масштабированием признаков_. Именно эту нормализацию и выполняет наш экстрактор признаков!

Мы можем посмотреть, как работает экстрактор признаков, применив его к нашему первому аудиосэмплу. Сначала вычислим среднее значение и дисперсию
наших исходных аудиоданных:

```python
import numpy as np

sample = gtzan["train"][0]["audio"]

print(f"Mean: {np.mean(sample['array']):.3}, Variance: {np.var(sample['array']):.3}")
```

**Output:**
```out
Mean: 0.000185, Variance: 0.0493
```

Видно, что среднее значение уже близко к нулю, но дисперсия ближе к 0,05. Если бы дисперсия для выборки была больше, это могло бы
вызвать проблемы с нашей моделью, так как динамический диапазон аудиоданных был бы очень мал и, следовательно, трудноразделим. Применим экстрактор
признаков и посмотрим, что получится на выходе:

```python
inputs = feature_extractor(sample["array"], sampling_rate=sample["sampling_rate"])

print(f"inputs keys: {list(inputs.keys())}")

print(
    f"Mean: {np.mean(inputs['input_values']):.3}, Variance: {np.var(inputs['input_values']):.3}"
)
```

**Output:**
```out
inputs keys: ['input_values', 'attention_mask']
Mean: -4.53e-09, Variance: 1.0
```

Отлично! Наш экстрактор признаков возвращает словарь, состоящий из двух массивов: `input_values` and `attention_mask`. `input_values`
это предварительно обработанные входные аудиоданные, которые мы передадим в модель HuBERT. [`attention_mask`](https://huggingface.co/docs/transformers/glossary#attention-mask)
используется, когда мы обрабатываем _batch_ аудиовходов одновременно - она используется для того, чтобы сообщить модели, где
у нас есть входы разной длины.

Мы видим, что среднее значение теперь очень сильно приближается к нулю, а дисперсия - к единице! Именно в таком виде мы хотим получить
наши аудиосэмплы перед подачей их в модель HuBERT.

Обратите внимание, как мы передали частоту дискретизации наших аудиоданных нашему экстрактору признаков. Это хорошая практика, так как
экстрактор признаков выполняет проверку под капотом, чтобы убедиться, что частота дискретизации наших аудиоданных соответствует частоте
дискретизации, ожидаемой моделью. Если частота дискретизации аудиоданных не совпадает с частотой дискретизации нашей модели, то необходимо
увеличить или уменьшить частоту дискретизации аудиоданных до нужной.

Отлично, теперь мы знаем, как обрабатывать наши ресэмплированные аудиофайлы, осталось определить функцию, которую мы можем применить ко всем
примерам в наборе данных. Поскольку мы ожидаем, что длина аудиоклипов будет составлять 30 секунд, мы также будем обрезать все более длинные клипы,
используя аргументы `max_length` и `truncation` в экстракторе признаков следующим образом:

```python
max_duration = 30.0

def preprocess_function(examples):
    audio_arrays = [x["array"] for x in examples["audio"]]
    inputs = feature_extractor(
        audio_arrays,
        sampling_rate=feature_extractor.sampling_rate,
        max_length=int(feature_extractor.sampling_rate * max_duration),
        truncation=True,
        return_attention_mask=True,
    )
    return inputs
```

Определив эту функцию, мы можем применить ее к набору данных с помощью метода [`map()`](https://huggingface.co/docs/datasets/v2.14.0/en/package_reference/main_classes#datasets.Dataset.map).
Метод `.map()` поддерживает работу с пакетами сэмплов, что мы и сделаем, установив `batched=True`. По умолчанию размер
пакета составляет 1000, но мы уменьшим его до 100, чтобы пиковая оперативная память оставалась в разумных пределах для бесплатного уровня Google Colab:

```python
gtzan_encoded = gtzan.map(
    preprocess_function,
    remove_columns=["audio", "file"],
    batched=True,
    batch_size=100,
    num_proc=1,
)
gtzan_encoded
```

**Output:**
```out
DatasetDict({
    train: Dataset({
        features: ['genre', 'input_values','attention_mask'],
        num_rows: 899
    })
    test: Dataset({
        features: ['genre', 'input_values','attention_mask'],
        num_rows: 100
    })
})
```

    Если при выполнении приведенного выше кода оперативная память устройства будет исчерпана, можно настроить параметры пакетной обработки,
    чтобы уменьшить пиковое потребление оперативной памяти. В частности, можно модифицировать следующие два аргумента:
    * `batch_size`: по умолчанию 1000, но выше было установлено значение 100. Попробуйте еще раз уменьшить в 2 раза до 50
    * `writer_batch_size`: по умолчанию равен 1000. Попробуйте уменьшить его до 500, а если это не сработает, то уменьшите его еще раз в 2 раза до 250

Для упрощения обучения мы удалили из набора данных столбцы `audio` и `file`. Столбец `input_values` содержит закодированные аудиофайлы,
 `attention_mask` - двоичную маску из значений 0/1, указывающую на то, куда мы добавили входной аудиосигнал, а столбец `genre` - соответствующие
 метки (или цели). Для того чтобы `Trainer` мог обрабатывать метки классов, необходимо переименовать колонку `genre` в `label`:

```python
gtzan_encoded = gtzan_encoded.rename_column("genre", "label")
```

Наконец, нам необходимо получить отображения меток из набора данных. Это отображение позволит нам перейти от целочисленных идентификаторов (например, `7`)
к человекочитаемым меткам классов (например, `"поп"`) и обратно. Таким образом, мы можем преобразовать целочисленное предсказание id нашей модели в человекочитаемый формат,
что позволит нам использовать модель в любом последующем приложении. Для этого можно использовать метод `int2str()` следующим образом:

```python
id2label = {
    str(i): id2label_fn(i)
    for i in range(len(gtzan_encoded["train"].features["label"].names))
}
label2id = {v: k for k, v in id2label.items()}

id2label["7"]
```

```out
'pop'
```

Итак, у нас есть набор данных, готовый к обучению! Давайте рассмотрим, как можно обучить модель на этом наборе данных.

## Дообучение модели

Для дообучения модели мы воспользуемся классом `Trainer` из раздела 🤗 Transformers. Как мы уже видели в других
главах, `Trainer` - это высокоуровневый API, предназначенный для работы с наиболее распространенными сценариями обучения.
В данном случае мы будем использовать `Trainer` для дообучения модели на GTZAN. Для этого сначала нужно загрузить модель для данной задачи.
Для этого мы можем использовать класс `AutoModelForAudioClassification`, который автоматически добавит соответствующую классификационную голову
в нашу предварительно обученную модель DistilHuBERT. Давайте перейдем к инстанцированию модели:

```python
from transformers import AutoModelForAudioClassification

num_labels = len(id2label)

model = AutoModelForAudioClassification.from_pretrained(
    model_id,
    num_labels=num_labels,
    label2id=label2id,
    id2label=id2label,
)
```

Мы настоятельно рекомендуем во время тренировок загружать контрольные точки моделей непосредственно на [Hugging Face Hub](https://huggingface.co/).
Hugging Face Hub предоставляет:
- Встроенный контроль версий: вы можете быть уверены, что ни одна контрольная точка модели не будет потеряна в процессе обучения.
- Журналы Tensorboard: отслеживание важных показателей в процессе обучения.
- Карты моделей: документирование того, что делает модель, и предполагаемых вариантов ее использования.
- Сообщество: простой способ обмена информацией и сотрудничества с сообществом! 🤗

Связать ноутбук с Hugging Face Hub очень просто - для этого достаточно ввести аутентификационный токен при появлении соответствующего запроса.
Найдите свой токен аутентификации [здесь](https://huggingface.co/settings/tokens):

```python
from huggingface_hub import notebook_login

notebook_login()
```

**Output:**
```bash
Login successful
Your token has been saved to /root/.huggingface/token
```

Следующим шагом является определение аргументов обучения, включая размер пакета, шаги накопления градиента, количество
эпох обучения и скорость обучения:

```python
from transformers import TrainingArguments

model_name = model_id.split("/")[-1]
batch_size = 8
gradient_accumulation_steps = 1
num_train_epochs = 10

training_args = TrainingArguments(
    f"{model_name}-finetuned-gtzan",
    evaluation_strategy="epoch",
    save_strategy="epoch",
    learning_rate=5e-5,
    per_device_train_batch_size=batch_size,
    gradient_accumulation_steps=gradient_accumulation_steps,
    per_device_eval_batch_size=batch_size,
    num_train_epochs=num_train_epochs,
    warmup_steps=100,
    logging_steps=5,
    load_best_model_at_end=True,
    metric_for_best_model="accuracy",
    fp16=True,
    push_to_hub=True,
)
```

    Здесь мы установили значение `push_to_hub=True`, чтобы включить автоматическую загрузку настроенных контрольных точек во время обучения.
    Если вы не хотите, чтобы ваши контрольные точки загружались на Hugging Face Hub, вы можете установить значение `False`.

Последнее, что нам необходимо сделать, это определить метрики. Поскольку набор данных сбалансирован, в качестве метрики мы будем использовать
accuracy и загружать ее с помощью библиотеки 🤗 Evaluate:

```python
import evaluate
import numpy as np

metric = evaluate.load("accuracy")

def compute_metrics(eval_pred):
    """Computes accuracy on a batch of predictions"""
    predictions = np.argmax(eval_pred.predictions, axis=1)
    return metric.compute(predictions=predictions, references=eval_pred.label_ids)
```

Теперь у нас есть все необходимые компоненты! Давайте инстанцируем `Trainer` и обучим модель:

```python
from transformers import Trainer

trainer = Trainer(
    model,
    training_args,
    train_dataset=gtzan_encoded["train"],
    eval_dataset=gtzan_encoded["test"],
    tokenizer=feature_extractor,
    compute_metrics=compute_metrics,
)

trainer.train()
```

    
    В зависимости от используемого графического процессора, при запуске обучения возможно возникновение ошибки CUDA `"out-of-memory"`.
    В этом случае можно уменьшать `batch_size` постепенно в 2 раза, а для компенсации использовать [`gradient_accumulation_steps`](https://huggingface.co/docs/transformers/main_classes/trainer#transformers.TrainingArguments.gradient_accumulation_steps)

**Output:**
```out
| Training Loss | Epoch | Step | Validation Loss | Accuracy |
|:-------------:|:-----:|:----:|:---------------:|:--------:|
| 1.7297        | 1.0   | 113  | 1.8011          | 0.44     |
| 1.24          | 2.0   | 226  | 1.3045          | 0.64     |
| 0.9805        | 3.0   | 339  | 0.9888          | 0.7      |
| 0.6853        | 4.0   | 452  | 0.7508          | 0.79     |
| 0.4502        | 5.0   | 565  | 0.6224          | 0.81     |
| 0.3015        | 6.0   | 678  | 0.5411          | 0.83     |
| 0.2244        | 7.0   | 791  | 0.6293          | 0.78     |
| 0.3108        | 8.0   | 904  | 0.5857          | 0.81     |
| 0.1644        | 9.0   | 1017 | 0.5355          | 0.83     |
| 0.1198        | 10.0  | 1130 | 0.5716          | 0.82     |
```

Обучение займет примерно 1 час в зависимости от вашего GPU или выделенного для Google Colab. Наша лучшая доля верных ответов
составляет 83% - неплохо для 10 эпох с 899 примерами обучающих данных! Конечно, мы могли бы улучшить этот результат,
тренируясь на большем количестве эпох, используя методы регуляризации, такие как _dropout_, или разбивая каждый аудиопример
на сегменты по 30 и 15 секунд, чтобы использовать более эффективную стратегию предварительной обработки данных.

Большой вопрос, как это соотносится с другими системами классификации музыки 🤔
Для этого мы можем просмотреть [autoevaluate leaderboard](https://huggingface.co/spaces/autoevaluate/leaderboards?dataset=marsyas%2Fgtzan&only_verified=0&task=audio-classification&config=all&split=train&metric=accuracy),
таблицу лидеров, которая классифицирует модели по языку и набору данных, а затем ранжирует их по accuracy.

Мы можем автоматически отправить нашу контрольную точку в таблицу лидеров при передаче результатов обучения в
Hugging Face Hub - для этого достаточно задать соответствующие аргументы ключевых слов (kwargs). Вы можете изменить эти значения
в соответствии с набором данных, языком и названием модели:

```python
kwargs = {
    "dataset_tags": "marsyas/gtzan",
    "dataset": "GTZAN",
    "model_name": f"{model_name}-finetuned-gtzan",
    "finetuned_from": model_id,
    "tasks": "audio-classification",
}
```

Теперь результаты обучения можно загрузить в Hugging Face Hub. Для этого выполните команду `.push_to_hub`:

```python
trainer.push_to_hub(**kwargs)
```

При этом журналы обучения и веса моделей будут сохранены под именем `"your-username/distilhubert-finetuned-gtzan"`. Для примера
посмотрите загрузку по адресу [`"sanchit-gandhi/distilhubert-finetuned-gtzan"`](https://huggingface.co/sanchit-gandhi/distilhubert-finetuned-gtzan).

## Поделиться моделью

Теперь вы можете поделиться этой моделью со всеми желающими, воспользовавшись ссылкой на Hub. Они могут загрузить его с идентификатором `"your-username/distilhubert-finetuned-gtzan"`
непосредственно в `pipeline()`. Например, для загрузки точно настроенной контрольной точки [`"sanchit-gandhi/distilhubert-finetuned-gtzan"`](https://huggingface.co/sanchit-gandhi/distilhubert-finetuned-gtzan):

```python
from transformers import pipeline

pipe = pipeline(
    "audio-classification", model="sanchit-gandhi/distilhubert-finetuned-gtzan"
)
```

## Заключение

В этом разделе мы рассмотрели пошаговое руководство по тонкой настройке модели DistilHuBERT для классификации музыки. Хотя мы
сосредоточились на задаче классификации музыки и на наборе данных GTZAN, представленные здесь шаги применимы в более общем случае
к любой задаче классификации звука - тот же сценарий может быть использован для задач классификации звука разговорного языка,
таких как выделение ключевых слов или идентификация языка. Вам просто нужно поменять набор данных на тот, который соответствует
интересующей вас задаче! Если вы заинтересованы в тонкой настройке других моделей Hugging Face Hub для классификации звука,
мы рекомендуем вам ознакомиться с другими [примерами](https://github.com/huggingface/transformers/tree/main/examples/pytorch/audio-classification)
в 🤗 репозитории Transformers.

В следующем разделе мы возьмем модель, которую вы только что отладили, и создадим демонстрационный образец классификации музыки, который
вы сможете опубликовать на Hugging Face Hub.

### Предварительно обученные модели и наборы данных для классификации звука
https://huggingface.co/learn/audio-course/ru/chapter4/classification_models.md

# Предварительно обученные модели и наборы данных для классификации звука
Hugging Face Hub содержит более 500 предварительно обученных моделей для классификации звука. В этом разделе мы рассмотрим
несколько наиболее распространенных задач классификации звука и предложим для каждой из них подходящие предварительно обученные модели.
Использование `pipeline()` позволяет легко переключаться между моделями и задачами - как только вы узнаете, как использовать
`pipeline()` для одной модели, вы сможете использовать его для любой модели на Hugging Face Hub без изменений кода! Это делает эксперименты с
`pipeline()` чрезвычайно быстрыми, позволяя быстро выбрать наилучшую предварительно обученную модель для ваших нужд.

Прежде чем перейти к рассмотрению различных задач классификации звука, давайте кратко перечислим обычно используемые архитектуры
трансформеров. Стандартная архитектура классификации звука обусловлена характером задачи; мы хотим преобразовать последовательность
входных аудиосигналов (т.е. наш входной массив аудиосигналов) в предсказание метки одного из классов. Модели, архитектура которых состоит
только из кодировщика, сначала преобразуют входную звуковую последовательность в последовательность представлений скрытых состояний,
пропуская входные сигналы через блок трансформации. Последовательность представлений скрытых состояний преобразуется в выходную метку
класса путем взятия среднего значения по скрытым состояниям и пропускания полученного вектора через слой линейной классификации.
Поэтому для классификации аудиосигналов предпочтение отдается моделям, архитектура которых состоит только из _кодировщика_.

Модели, архитектура которых состоит только из декодировщика излишне усложняют задачу, поскольку предполагают что выходы могут быть в том
числе и _последовательностью_ предсказаний (а не одним предсказанием метки класса), и поэтому генерируют несколько выходов. Поэтому они
имеют более низкую скорость вывода и, как правило, не используются. По этой же причине модели кодеровщик-декодировщик в значительной степени
не рассматриваются. Такой выбор архитектуры аналогичен выбору в NLP, где для задач классификации последовательностей предпочтение отдается
только моделям-кодировщикам, таким как [BERT](https://huggingface.co/blog/bert-101), а для задач генерации последовательностей - только
моделям-декодировщикам, таким как GPT.

Теперь, когда мы рассказали о стандартной архитектуре трансформеров для классификации звука, перейдем к рассмотрению различных подмножеств
классификации звука и наиболее популярных моделей!

## 🤗 Установка библиотеки Transformers

На момент написания статьи последние обновления, необходимые для работы конвейера классификации звука, находятся только в `main` ветке
репозитория 🤗 Transformers, а не в последней версии PyPi. Чтобы убедиться в наличии этих обновлений локально, мы установим Transformers
из ветки `main` следующей командой:

```
pip install git+https://github.com/huggingface/transformers
```

## Поиск ключевых слов

Поиск ключевых слов (Keyword Spotting, KWS) - это задача идентификации ключевого слова в произносимой речи. Набор возможных ключевых слов
формирует набор прогнозируемых меток классов. Поэтому для использования предварительно обученной модели выделения ключевых слов необходимо
убедиться, что ваши ключевые слова совпадают с теми, на которых модель была предварительно обучена. Ниже мы представим два набора данных
и модели для выявления ключевых слов.

### Minds-14

Воспользуемся тем же набором данных [MINDS-14](https://huggingface.co/datasets/PolyAI/minds14), который вы исследовали в предыдущем разделе.
Если вы помните, MINDS-14 содержит записи людей, задающих вопросы системе дистанционного банковского обслуживания на нескольких языках и
диалектах, и для каждой записи имеет значение `intent_class`. Мы можем классифицировать записи по намерению звонящего.

```python
from datasets import load_dataset

minds = load_dataset("PolyAI/minds14", name="en-AU", split="train")
```

Загрузим контрольную точку [`"anton-l/xtreme_s_xlsr_300m_minds14"`](https://huggingface.co/anton-l/xtreme_s_xlsr_300m_minds14), которая
представляет собой XLS-R-модель, дообученную на MINDS-14 в течение примерно 50 эпох. На оценочной выборке набора MINDS-14 она достигает 90%
по метрике accuracy по всем языкам.

```python
from transformers import pipeline

classifier = pipeline(
    "audio-classification",
    model="anton-l/xtreme_s_xlsr_300m_minds14",
)
```

Наконец, мы можем передать сэмпл в конвейер классификации, чтобы сделать предсказание:
```python
classifier(minds[0]["path"])
```
**Output:**
```
[
    {"score": 0.9631525278091431, "label": "pay_bill"},
    {"score": 0.02819698303937912, "label": "freeze"},
    {"score": 0.0032787492964416742, "label": "card_issues"},
    {"score": 0.0019414445850998163, "label": "abroad"},
    {"score": 0.0008378693601116538, "label": "high_value_payment"},
]
```

Отлично! Мы определили, что целью звонка была оплата счета, с вероятностью 96%. Можно представить, что подобная система выявления ключевых
слов используется в качестве первого этапа автоматизированного центра обработки вызовов (call-центр), где мы хотим классифицировать входящие
звонки клиентов в зависимости от их запроса и предложить им соответствующую контекстную поддержку.

### Speech Commands

Speech Commands - это набор устных слов, предназначенный для оценки моделей классификации звука на простых командных словах. Набор данных
состоит из 15 классов ключевых слов, класса молчания и неизвестного класса, включающего ложные срабатывания. 15 ключевых слов - это отдельные
слова, которые обычно используются в настройках устройства для управления основными задачами или запуска других процессов.

Аналогичная модель постоянно работает в вашем мобильном телефоне. Здесь вместо отдельных командных слов используются "слова пробуждения", 
характерные для конкретного устройства, например "Привет, Google" или "Привет, Siri". Когда модель классификации звука обнаруживает эти слова,
она заставляет телефон начать прослушивание микрофона и транскрибировать вашу речь с помощью модели распознавания речи.

Модель классификации звука гораздо меньше и легче, чем модель распознавания речи, зачастую в ней всего несколько миллионов параметров по
сравнению с несколькими сотнями миллионов параметров в модели для распознавания речи. Таким образом, она может непрерывно работать на вашем
устройстве, не разряжая аккумулятор! Более крупная модель распознавания речи запускается только при обнаружении слова-пробуждения, после чего
она снова отключается. В следующем разделе мы рассмотрим модели трансформеров для распознавания речи, так что к концу курса у вас должны быть
все необходимые инструменты для создания собственного голосового помощника!

Как и в случае с любым набором данных на Hugging Face Hub, мы можем получить представление о том, какие аудиоданные в нем присутствуют,
не скачивая и не сохраняя их в памяти компьютера. Перейдя к карточке набора данных [Speech Commands' dataset](https://huggingface.co/datasets/speech_commands)
на Hugging Face Hub, мы можем воспользоваться средством просмотра набора данных (Dataset Viewer), чтобы пролистать первые 100 образцов набора,
прослушать аудиофайлы и проверить любые другие метаданные:

     
 

Предварительный просмотр данных - это отличный способ ознакомиться с наборами аудиоданных, прежде чем приступить к их использованию. Вы можете выбрать
любой набор данных на Hugging Face Hub, пролистать примеры и прослушать аудиозаписи для различных подмножеств и разбиений, чтобы понять, подходит ли
этот набор данных для ваших нужд. Выбрав набор данных, несложно загрузить данные, чтобы начать их использовать.

Давайте сделаем именно это и загрузим образец набора данных Speech Commands в потоковом режиме:

```python
speech_commands = load_dataset(
    "speech_commands", "v0.02", split="validation", streaming=True
)
sample = next(iter(speech_commands))
```

Загрузим официальную контрольную точку [Audio Spectrogram Transformer](https://huggingface.co/docs/transformers/model_doc/audio-spectrogram-transformer),
прошедшую дообучение на наборе данных Speech Commands, в пространстве имен [`"MIT/ast-finetuned-speech-commands-v2"`](https://huggingface.co/MIT/ast-finetuned-speech-commands-v2):

```python
classifier = pipeline(
    "audio-classification", model="MIT/ast-finetuned-speech-commands-v2"
)
classifier(sample["audio"].copy())
```
**Output:**
```
[{'score': 0.9999892711639404, 'label': 'backward'},
 {'score': 1.7504888774055871e-06, 'label': 'happy'},
 {'score': 6.703040185129794e-07, 'label': 'follow'},
 {'score': 5.805884484288981e-07, 'label': 'stop'},
 {'score': 5.614546694232558e-07, 'label': 'up'}]
```

Класс! Похоже, что пример с высокой вероятностью содержит слово "назад". Мы можем прослушать пример и убедиться что это действительно так:
```
from IPython.display import Audio

Audio(sample["audio"]["array"], rate=sample["audio"]["sampling_rate"])
```

Теперь вам, возможно, интересно, как мы выбрали эти предварительно обученные модели, чтобы показать их на этих примерах классификации звука.
На самом деле, найти предварительно обученные модели для вашего набора данных и задачи очень просто! Первое, что нам нужно сделать, это зайти
в Hugging Face Hub и перейти на вкладку "Models" (Модели): https://huggingface.co/models

В результате будут отображены все модели на Hugging Face Hub, отсортированные по количеству загрузок за последние 30 дней:

     
 

С левой стороны можно заметить ряд вкладок, на которых можно отфильтровать модели по задачам, библиотекам, наборам данных и т.д. Прокрутите
страницу вниз и выберите задачу "Audio Classification" (Классификация аудио) из списка задач аудио:

     
 

Теперь нам представлено подмножество из 500+ моделей классификации звука на хабе. Для дальнейшего уточнения этого отбора мы можем отфильтровать
модели по набору данных. Перейдите на вкладку "Datasets" и в строке поиска введите "speech_commands". Когда вы начнете вводить текст, под 
вкладкой поиска появится выбор для `speech_commands`. Нажав на эту кнопку, вы можете отфильтровать все модели классификации звука от тех,
которые были настроены на наборе данных Speech Commands:

     
 

Отлично! Мы видим, что для данного набора данных и задачи нам доступны 6 предварительно обученных моделей. Вы заметите первую из этих моделей
Audio Spectrogram Transformer, контрольную точку которой мы использовали в предыдущем примере. Этот процесс фильтрации моделей на Hugging Face Hub -
именно то, как мы выбирали контрольную точку для показа вам!

## Идентификация языка (Language Identification)

Идентификация языка (LID) - это задача определения языка, на котором говорят в аудиосэмпле, из списка языков-кандидатов. LID может стать важной
частью многих речевых конвейеров. Например, при получении образца аудиозаписи на неизвестном языке модель LID может быть использована для классификации
языка (языков), на котором разговаривают в аудиозаписи, и последующего выбора соответствующей модели распознавания речи, обученной на этом языке,
для транскрибации аудиозаписи.

### FLEURS

FLEURS (Few-shot Learning Evaluation of Universal Representations of Speech) - это набор данных для оценки систем распознавания речи на 102 языках,
в том числе на многих языках, которые относятся к категории "малоресурсных". Ознакомьтесь с карточкой набора данных FLEURS на Hugging Face Hub
и изучите различные языки, которые в нем представлены: [google/fleurs](https://huggingface.co/datasets/google/fleurs). Можете ли Вы найти здесь
свой родной язык? Если нет, то какой язык наиболее близок к нему?

Загрузим выборку из валидационной части набора данных FLEURS в потоковом режиме:

```python
fleurs = load_dataset("google/fleurs", "all", split="validation", streaming=True)
sample = next(iter(fleurs))
```

Отлично! Теперь мы можем загрузить нашу модель классификации звука. Для этого мы будем использовать версию [Whisper](https://arxiv.org/pdf/2212.04356.pdf)
дообученный на наборе данных FLEURS, который в настоящее время является наиболее производительной моделью LID на Hugging Face Hub:

```python
classifier = pipeline(
    "audio-classification", model="sanchit-gandhi/whisper-medium-fleurs-lang-id"
)
```

Затем мы можем пропустить звук через наш классификатор и сгенерировать предсказание:
```python
classifier(sample["audio"])
```
**Output:**
```
[{'score': 0.9999330043792725, 'label': 'Afrikaans'},
 {'score': 7.093023668858223e-06, 'label': 'Northern-Sotho'},
 {'score': 4.269149485480739e-06, 'label': 'Icelandic'},
 {'score': 3.2661141631251667e-06, 'label': 'Danish'},
 {'score': 3.2580724109720904e-06, 'label': 'Cantonese Chinese'}]
```

Видно, что модель предсказала, что звук был на "Afrikaans" с очень высокой вероятностью (близкой к 1). Набор данных FLEURS
содержит аудиоданные из широкого спектра языков - мы видим, что возможные метки классов включают "Northern-Sotho", "Icelandic",
"Danish" и "Cantonese Chinese" языки, а также другие. Полный список языков, представленных в карточке набора данных, можно найти здесь: [google/fleurs](https://huggingface.co/datasets/google/fleurs).

Посмотрите самостоятельно! Какие еще контрольные точки можно найти для FLEURS LID на хабе? Какие модели трансформаторов используются под капотом?

## Zero-Shot Audio Classification

В традиционной парадигме классификации звука модель предсказывает метку класса из _предварительно определенного_ набора возможных классов.
Это создает препятствие для использования предварительно обученных моделей для классификации звука, поскольку набор меток предварительно обученной
модели должен соответствовать набору меток последующей задачи. В предыдущем примере LID модель должна предсказать один из 102 языковых классов,
на которых она была обучена. Если для решения поставленной задачи требуется 110 языков, то модель не сможет предсказать 8 из 110 языков, и для
достижения полного покрытия потребуется повторное обучение. Это ограничивает эффективность применения трансферного обучения для задач классификации звука.

Zero-shot классификация звука это метод, позволяющий использовать предварительно обученную модель классификации аудиоданных, натренированную на множестве
размеченных примеров, для классификации новых примеров из ранее не встречавшихся классов. Давайте рассмотрим, как этого можно добиться!

В настоящее время 🤗 Transformers поддерживает один вид модели для Zero-shot классификации звука: это [CLAP model](https://huggingface.co/docs/transformers/model_doc/clap).
CLAP - это модель, основанная на трансформации, которая принимает в качестве входных данных звук и текст и вычисляет _сходство_ между ними.
Если мы передаем текстовый ввод, который сильно коррелирует с аудиовводом, мы получим высокую оценку сходства. И наоборот, при передаче текстового ввода,
совершенно не связанного с аудиовводом, будет получено низкое сходство.

Мы можем использовать это предсказание сходства для zero-shot классификации звука, передавая модели один аудиовход и несколько меток-кандидатов.
Модель вернет оценку сходства для каждой из меток-кандидатов, и мы можем выбрать в качестве прогноза ту, которая имеет наибольшую оценку.

Рассмотрим пример, в котором мы используем один аудиовход от набора данных [Environmental Speech Challenge (ESC)](https://huggingface.co/datasets/ashraq/esc50):

```python
dataset = load_dataset("ashraq/esc50", split="train", streaming=True)
audio_sample = next(iter(dataset))["audio"]["array"]
```

Затем мы определяем наши метки-кандидаты, которые образуют набор возможных классификационных меток. Модель будет возвращать вероятность принадлежности к классу
для каждой из заданных нами меток. Это означает, что нам необходимо знать _априори_ набор возможных меток в нашей задаче классификации, причем так, чтобы правильная
метка содержалась в этом наборе и, следовательно, ей была присвоена правильная вероятностная оценка. Обратите внимание, что мы можем передать модели
либо полный набор меток, либо отобранное вручную подмножество, которое, по нашему мнению, содержит правильную метку. Передача полного набора меток
будет более исчерпывающей, но за счет более низкой точности классификации, поскольку пространство классификации больше (при условии,
что правильной меткой является выбранное нами подмножество меток):

```python
candidate_labels = ["Sound of a dog", "Sound of vacuum cleaner"]
```

Мы можем прогнать обе эти метки через модель, чтобы найти метку-кандидата, которая _наиболее_ похожа на входной аудиосигнал:

```python
classifier = pipeline(
    task="zero-shot-audio-classification", model="laion/clap-htsat-unfused"
)
classifier(audio_sample, candidate_labels=candidate_labels)
```
**Output:**
```
[{'score': 0.9997242093086243, 'label': 'Sound of a dog'}, {'score': 0.0002758323971647769, 'label': 'Sound of vacuum cleaner'}]
```

Отлично! Модель, похоже, уверена, что у нас есть звук собаки - она предсказывает его с вероятностью 99,96%, так что мы примем
это за наше предсказание. Убедимся в том, что мы не ошиблись, прослушав аудиопример (не увеличивайте громкость слишком сильно!):

```python
Audio(audio_sample, rate=16000)
```

Отлично! У нас есть звук лая собаки 🐕, что соответствует предсказанию модели. Поиграйте с разными аудиосэмплами и разными
кандидатами на метки - сможете ли вы определить набор меток, которые дают хорошее обобщение по всему набору данных ESC? Подсказка:
подумайте, где можно найти информацию о возможных звуках в ESC, и постройте свои метки соответствующим образом!

Возможно, вы зададитесь вопросом, почему мы не используем конвейер zero-shot классификации звука для **всех** задач классификации звука?
Кажется, что мы можем делать предсказания для любой задачи классификации звука, определяя соответствующие метки классов _априори_,
тем самым обходя ограничения, связанные с тем, что наша задача классификации должна соответствовать меткам, на которых была предварительно
обучена модель. Это связано с характером модели CLAP, используемой в zero-shot конвейере: CLAP предварительно обучена на _общих_ аудиоданных
для классификации, таких как звуки окружающей среды в наборе данных ESC, а не на речевых данных, как в задаче LID. Если дать ему речь на
английском и речь на испанском языках, CLAP поймет, что оба примера являются речевыми данными 🗣️. Но он не сможет различить языки так, как
это может сделать специализированная LID-модель.

## Что дальше?

Мы рассмотрели ряд различных задач классификации звука и представили наиболее актуальные наборы данных и модели, которые можно загрузить с
Hugging Face Hub и использовать всего в нескольких строках кода с помощью `pipeline()`. Эти задачи включали в себя выделение ключевых слов,
идентификацию языка и zero-shot классификацию аудиозаписей.

Но что, если мы хотим сделать что-то **новое**? Мы много работали над задачами обработки речи, но это лишь один из аспектов классификации аудио.
Другая популярная область обработки звука связана с **музыкой**. Хотя музыка по своей сути отличается от речи, многие из тех же принципов,
о которых мы уже узнали, могут быть применены и к музыке.

В следующем разделе мы рассмотрим пошаговое руководство по тонкой настройке модели трансформера с помощью 🤗 Transformers на задаче классификации музыки.
К концу этой работы у вас будет контрольная точка дообученной модели, которую вы сможете передать в `pipeline()`, что позволит вам классифицировать
песни точно так же, как мы классифицировали здесь речь!

### Практическое занятие
https://huggingface.co/learn/audio-course/ru/chapter4/hands_on.md

# Практическое занятие

Настало время взять в руки несколько Аудио моделей и применить на практике то, чему вы научились.
Это упражнение является одним из четырех практических упражнений, необходимых для получения сертификата об окончании курса.

Вот инструкции.
В этом блоке мы продемонстрировали дообучение модели Hubert на наборе данных `marsyas/gtzan` для классификации музыки. Accuracy нашего примера составила 83%.
Ваша задача - улучшить этот показатель.

Вы можете выбрать любую модель на [🤗 Hugging Face Hub](https://huggingface.co/models), которая, по вашему мнению, подходит для классификации аудио, и использовать
точно такой же набор данных [`marsyas/gtzan`](https://huggingface.co/datasets/marsyas/gtzan) для построения собственного классификатора.

Ваша цель - достичь accuracy 87% на этом наборе данных с помощью вашего классификатора. Вы можете выбрать точно такую же модель, поиграть с гиперпараметрами обучения
или выбрать совершенно другую модель - все зависит от вас!

Чтобы ваш результат был засчитан в сертификат, не забудьте в конце обучения вывести модель на Hub, как это было показано в данном блоке,
со следующими `**kwargs`:

```python
kwargs = {
    "dataset_tags": "marsyas/gtzan",
    "dataset": "GTZAN",
    "model_name": f"{model_name}-finetuned-gtzan",
    "finetuned_from": model_id,
    "tasks": "audio-classification",
}

trainer.push_to_hub(**kwargs)
```

Вот некоторые дополнительные ресурсы, которые могут оказаться полезными при работе над этим упражнением:
* [Руководство по решению задач классификации звука в документации Transformers](https://huggingface.co/docs/transformers/tasks/audio_classification)
* [Документация по модели Hubert](https://huggingface.co/docs/transformers/model_doc/hubert)
* [Документация по модели M-CTC-T](https://huggingface.co/docs/transformers/model_doc/mctct)
* [Документация Audio Spectrogram Transformer](https://huggingface.co/docs/transformers/model_doc/audio-spectrogram-transformer)
* [Документация Wav2Vec2](https://huggingface.co/docs/transformers/model_doc/wav2vec2)

Не стесняйтесь создавать демо-версию своей модели и делиться ею в Discord! Если у вас есть вопросы, задавайте их в канале #audio-study-group.

### Раздел 4. Разработка классификатора музыкальных жанров
https://huggingface.co/learn/audio-course/ru/chapter4/introduction.md

# Раздел 4. Разработка классификатора музыкальных жанров

## Чему вы научитесь и что вы сможете создать

Классификация звука - одно из наиболее распространенных применений трансформеров в обработке звука и речи. Как и другие
задачи классификации в машинном обучении, эта задача предполагает присвоение одной или нескольких меток аудиозаписи на основе
ее содержания. Например, в случае с речью мы можем захотеть обнаружить, когда произносится фраза-пробуждение вроде "Привет, Siri",
или определить ключевое слово вроде "температура" из произнесенного запроса "Какая сегодня погода?". Другим примером могут служить
звуки окружающей среды, когда мы хотим автоматически различать такие звуки, как "автомобильный гудок", "сирена", "лай собаки" и т.д.

В этом разделе мы рассмотрим, как предварительно обученные звуковые трансформеры могут применяться в различных задачах классификации звука.
Затем мы произведем дообучение модели-трансформера на задаче классификации музыки, классифицируя песни по жанрам, таким как "поп" и "рок".
Это важная составляющая таких музыкальных стриминговых сервисов, как [Spotify](https://en.wikipedia.org/wiki/Spotify), которые
рекомендуют песни, похожие на те, что слушает пользователь.

К концу этого раздела вы узнаете, как:

* Найти подходящие предварительно обученные модели для задачи классификации звука
* Использовать библиотеку 🤗 Datasets и Hugging Face Hub для выбора наборов данных для классификации звука
* Производить дообучение предварительно обученной модели для классификации песен по жанрам
* Создание демо-версии Gradio, позволяющей классифицировать собственные песни

### Создание демонтрационного образца с Gradio
https://huggingface.co/learn/audio-course/ru/chapter4/demo.md

# Создание демонтрационного образца с Gradio

В этом заключительном разделе, посвященном классификации звука, мы построим демонстрационный пример [Gradio](https://gradio.app) чтобы
продемонстрировать модель классификации музыки, которую мы только что обучили на наборе данных [GTZAN](https://huggingface.co/datasets/marsyas/gtzan).
Первое, что необходимо сделать, это загрузить контрольную точку дообученной модели с помощью класса `pipeline()` - это уже хорошо знакомо по разделу
[Предварительно обученные модели и наборы данных для классификации звука](classification_models). Вы можете изменить `model_id` на пространство имен
вашей дообученной модели на Hugging Face Hub:

```python
from transformers import pipeline

model_id = "sanchit-gandhi/distilhubert-finetuned-gtzan"
pipe = pipeline("audio-classification", model=model_id)
```

Во-вторых, мы определим функцию, которая принимает путь к файлу для входного аудиосигнала и пропускает его через конвейер. Здесь конвейер автоматически
позаботится о том, чтобы загрузить аудиофайл, передискретизировать его до нужной частоты дискретизации и выполнить вывод с помощью модели. Мы берем
предсказания модели `preds` и оформляем их в виде словаря для отображения на выходе:

```python
def classify_audio(filepath):
    preds = pipe(filepath)
    outputs = {}
    for p in preds:
        outputs[p["label"]] = p["score"]
    return outputs
```

Наконец, мы запускаем демонстрационную программу Gradio с помощью функции, которую мы только что определили:

```python
import gradio as gr

demo = gr.Interface(
    fn=classify_audio, inputs=gr.Audio(type="filepath"), outputs=gr.outputs.Label()
)
demo.launch(debug=True)
```

В результате будет запущена демонстрация Gradio, аналогичная той, что работает на Hugging Face Space:

### Дообучение модели ASR
https://huggingface.co/learn/audio-course/ru/chapter5/fine-tuning.md

# Дообучение модели ASR

В этом разделе мы рассмотрим пошаговое руководство по дообучению модели Whisper для распознавания речи на наборе данных Common
Voice 13. Мы будем использовать версию модели 'small' и относительно небольшой набор данных, что позволит вам провести настройку
довольно быстро на любом GPU объемом памяти 16 ГБ и более с небольшими требованиями к дисковому пространству, на таком GPU как T4
объемом 16 ГБ, предоставляемый в бесплатной версии Google Colab.

Если у вас GPU с меньшим объемом памяти или возникают проблемы с памятью во время обучения, вы можете следовать предложенным советам
по снижению использования памяти. Если у вас есть доступ к GPU с бОльшим объемом памяти, вы можете изменить аргументы обучения для
максимизации производительности. Таким образом, это руководство доступно независимо от спецификаций вашего GPU!

Так же это руководство описывает, как дообучить модель Whisper для языка Дивехи. Однако шаги, описанные здесь, обобщаются на любой
язык в наборе данных Common Voice и будут работать для любого набора данных распознавания речи на Hub Hugging Face. Вы можете изменить
код, чтобы быстро переключиться на необходимый вам язык и дообучить модель Whisper на вашем родном языке 🌍

Отлично! Теперь, когда мы разобрались с этим, давайте начнем и запустим нашу процедуру дообучения модели!

## Подготовка окружения

Мы настоятельно рекомендуем вам загружать контрольные точки модели непосредственно на [Hugging Face Hub](https://huggingface.co/) во время обучения.
Hugging Face Hub предоставляет следующие возможности:
- Встроенный контроль версий: вы можете быть уверены, что ни одна контрольная точка модели не будет потеряна в процессе обучения.
- Журналы Tensorboard: отслеживание важных показателей в процессе обучения.
- Карты моделей: документирование того, что делает модель, и предполагаемых вариантов ее использования.
- Сообщество: простой способ обмена информацией и сотрудничества с сообществом! 🤗

Связать блокнот с Hub Hugging Face довольно просто - вам просто нужно ввести свой токен аутентификации Hugging Face Hub, когда вас
попросят. Найдите свой токен аутентификации Hugging Face Hub [здесь](https://huggingface.co/settings/tokens) и введите его, когда вас попросят:

```python
from huggingface_hub import notebook_login

notebook_login()
```

**Output:**
```bash
Login successful
Your token has been saved to /root/.huggingface/token
```

## Загрузка набора данных

[Common Voice 13](https://huggingface.co/datasets/mozilla-foundation/common_voice_13_0) содержит примерно десять часов
размеченных данных для Дивехи, из которых три часа являются тестовой частью данных. Этих данных крайне мало для дообучения модели,
поэтому мы будем опираться на обширные многоязыковые знания в области распознавания речи, накопленные Whisper во время предварительного
обучения, для низкоресурсного языка Дивехи.

Используя 🤗 Datasets, загрузка и подготовка данных чрезвычайно просты. Мы можем загрузить и подготовить разделения набора данных Common
Voice 13 всего за одну строку кода. Так как Дивехи имеет очень небольшой объем данных, мы объединим выборки `train` и `validation`, чтобы
получить примерно семь часов данных для обучения. Мы будем использовать три часа данных выборки `test` в качестве нашего тестового набора данных:

```python
from datasets import load_dataset, DatasetDict

common_voice = DatasetDict()

common_voice["train"] = load_dataset(
    "mozilla-foundation/common_voice_13_0", "dv", split="train+validation"
)
common_voice["test"] = load_dataset(
    "mozilla-foundation/common_voice_13_0", "dv", split="test"
)

print(common_voice)
```

**Output:**
```
DatasetDict({
    train: Dataset({
        features: ['client_id', 'path', 'audio', 'sentence', 'up_votes', 'down_votes', 'age', 'gender', 'accent', 'locale', 'segment', 'variant'],
        num_rows: 4904
    })
    test: Dataset({
        features: ['client_id', 'path', 'audio', 'sentence', 'up_votes', 'down_votes', 'age', 'gender', 'accent', 'locale', 'segment', 'variant'],
        num_rows: 2212
    })
})
```

    Вы можете изменить идентификатор языка с `"dv"` на идентификатор языка по вашему выбору. Чтобы увидеть все возможные
    языки в Common Voice 13, ознакомьтесь с карточкой набора данных на Hub Hugging Face: https://huggingface.co/datasets/mozilla-foundation/common_voice_13_0

Большинство наборов данных для распознавания речи предоставляют только аудиофайлы для ввода (`audio`) и соответствующий
транскрибированный текст (`sentence`). В наборе данных Common Voice есть дополнительная метаинформация, такая как `accent`
и `locale`, которую мы можем не учитывать для ASR. Сохраняя блокнот максимально общим, мы будем рассматривать только входное
аудио и транскрибированный текст для дообучения модели, отбрасывая дополнительную метаинформацию:

```python
common_voice = common_voice.select_columns(["audio", "sentence"])
```

## Извлечение признаков, токенизатор и обработчик

Конвеер для задачи распознавания речи можно разделить на три этапа:

1. Извлекатель признаков, который предварительно обрабатывает сырой аудиоввод и создает логарифмические мел-спектрограммы
2. Модель, выполняющая отображение последовательности в последовательность
3. Токенизатор, который выполняет постобработку предсказанных токенов в текст

В библиотеке 🤗 Transformers для модели Whisper существуют связанные извлекатель признаков и токенизатор, называемые
[WhisperFeatureExtractor](https://huggingface.co/docs/transformers/main/model_doc/whisper#transformers.WhisperFeatureExtractor)
и [WhisperTokenizer](https://huggingface.co/docs/transformers/main/model_doc/whisper#transformers.WhisperTokenizer) соответственно.
Для упрощения работы с ними, эти два объекта объединены в одном классе, названном [WhisperProcessor](https://huggingface.co/docs/transformers/model_doc/whisper#transformers.WhisperProcessor).
Мы можем вызвать WhisperProcessor для выполнения как предварительной обработки звука, так и постобработки текстового токена.
При этом во время обучения нам нужно отслеживать только два объекта: процессор и модель.

При выполнении многоязыкового дообучения модели нам необходимо установить параметры `"language"` и `"task"` при создании процессора.
Параметр `"language"` должен быть установлен на язык исходного аудио, а параметр `"task"` на `"transcribe"` для распознавания речи или
на `"translate"` для перевода речи. Эти аргументы изменяют поведение токенизатора и должны быть правильно установлены, чтобы обеспечить
правильное кодирование целевых меток.

Мы можем увидеть все возможные поддерживаемые языки моделью Whisper, импортировав список языков:

```python
from transformers.models.whisper.tokenization_whisper import TO_LANGUAGE_CODE

TO_LANGUAGE_CODE
```

Если вы прокрутите этот список, вы заметите, что многие языки присутствуют, но Дивехи в нем нет! Это означает, что модель
Whisper не была предварительно обучена на Дивехи. Однако это не означает, что мы не можем дообучить Whisper на этом языке.
Таким образом, мы будем обучать Whisper новому языку, который не поддерживается предварительно обученной контрольной точкой.
Это довольно круто, не так ли?

При дообучения модели на новый язык Whisper хорошо использует свои знания о других 96 языках, на которых эта модель была
предварительно обучена. В целом, все современные языки будут лингвистически похожи хотя бы на один из 96 языков, которые Whisper
уже знает, и мы будем попадать под эту парадигму кросс-языкового представления знаний.

Для дообучения модели Whisper на новый язык нам нужно найти **самый похожий** язык, на котором Whisper был предварительно обучен.
Статья в Википедии о Дивехи утверждает, что Дивехи тесно связан с Сингальским языком Шри-Ланки. Если мы снова проверим коды языков,
мы увидим, что Сингальский присутствует в наборе языков Whisper, поэтому мы можем безопасно установить аргумент "language" в значение `"sinhalese"`.

Отлично! Мы загрузим наш процессор из предварительно обученной контрольной точки, установив язык на `"sinhalese"` и задачу на `"transcribe"`,
как объяснено выше:

```python
from transformers import WhisperProcessor

processor = WhisperProcessor.from_pretrained(
    "openai/whisper-small", language="sinhalese", task="transcribe"
)
```

Стоит отметить, что в большинстве случаев вы обнаружите, что язык, на котором вы хотите дообучить модель, есть в наборе языков
предобученной модели, в этом случае вы можете просто установить язык напрямую как язык вашего аудиоввода! Обратите внимание,
что оба эти аргумента следует исключить для дообучения только на английском языке, когда есть только один вариант для языка (`"English"`)
и задачи (`"transcribe"`).

## Предварительная обработка данных

Давайте посмотрим на характеристики набора данных. Особое внимание уделяем колонке `"audio"` - это подробности о частоте
дискретизации наших аудиовходов:

```python
common_voice["train"].features
```
**Output:**
```
{'audio': Audio(sampling_rate=48000, mono=True, decode=True, id=None),
 'sentence': Value(dtype='string', id=None)}
```

Поскольку наше входной звук дискретизируется на частоте 48 кГц, нам нужно уменьшить частоту дискретизации до 16 кГц
перед передачей его в извлекатель признаков Whisper, так как модель Whisper ожидает аудио с частотой дискретизации 16 кГц.

Мы установим необходимую частоту дискретизации аудиовводов набора данных с помощью метода [`cast_column`](https://huggingface.co/docs/datasets/main/en/package_reference/main_classes#datasets.Dataset.cast_column).
Эта операция не изменяет звук непосредственно, а сигнализирует набору данных о пересемплировании аудиообразцов при их загрузке на лету:

```python
from datasets import Audio

sampling_rate = processor.feature_extractor.sampling_rate
common_voice = common_voice.cast_column("audio", Audio(sampling_rate=sampling_rate))
```

Теперь мы можем написать функцию для подготовки наших данных к использованию моделью:

1. Мы загружаем и выполняем пересемплирование аудиоданных на основе выборки, вызывая sample["audio"]. Как уже было объяснено, библиотека
🤗 Datasets выполняет все необходимые операции пересемплирования на лету.
2. Мы используем извлекатель признаков для вычисления входных признаков в виде логарифмической мел-спектрограммы из нашего одномерного аудио-массива.
3. Мы кодируем транскрипции в идентификаторы меток с помощью токенизатора.

```python
def prepare_dataset(example):
    audio = example["audio"]

    example = processor(
        audio=audio["array"],
        sampling_rate=audio["sampling_rate"],
        text=example["sentence"],
    )

    # compute input length of audio sample in seconds
    example["input_length"] = len(audio["array"]) / audio["sampling_rate"]

    return example
```

Мы можем применить функцию подготовки данных ко всем нашим обучающим примерам, используя метод `.map` библиотеки 🤗 Datasets.
Мы удалим столбцы из исходных данных обучения (аудио и текст), оставив только столбцы, возвращаемые функцией `prepare_dataset`:

```python
common_voice = common_voice.map(
    prepare_dataset, remove_columns=common_voice.column_names["train"], num_proc=1
)
```

Наконец, мы фильтруем любые обучающие данные с аудиообразцами длиннее 30 секунд. В противном случае эти образцы могли бы быть усечены
извлекателем признаков Whisper, что может повлиять на стабильность обучения. Мы определяем функцию, которая возвращает `True` для образцов,
которые короче 30 секунд, и `False` для тех, что длиннее:

```python
max_input_length = 30.0

def is_audio_in_length_range(length):
    return length  Dict[str, torch.Tensor]:
        # split inputs and labels since they have to be of different lengths and need different padding methods
        # first treat the audio inputs by simply returning torch tensors
        input_features = [
            {"input_features": feature["input_features"][0]} for feature in features
        ]
        batch = self.processor.feature_extractor.pad(input_features, return_tensors="pt")

        # get the tokenized label sequences
        label_features = [{"input_ids": feature["labels"]} for feature in features]
        # pad the labels to max length
        labels_batch = self.processor.tokenizer.pad(label_features, return_tensors="pt")

        # replace padding with -100 to ignore loss correctly
        labels = labels_batch["input_ids"].masked_fill(
            labels_batch.attention_mask.ne(1), -100
        )

        # if bos token is appended in previous tokenization step,
        # cut bos token here as it's append later anyways
        if (labels[:, 0] == self.processor.tokenizer.bos_token_id).all().cpu().item():
            labels = labels[:, 1:]

        batch["labels"] = labels

        return batch
```

Теперь мы можем инициализировать только что определенный сборщик данных:

```python
data_collator = DataCollatorSpeechSeq2SeqWithPadding(processor=processor)
```

Продолжаем!

### Метрики оценки

Далее мы определяем метрику оценки, которую будем использовать на нашем наборе для оценки. Мы будем использовать метрику
Word Error Rate (WER), представленную в разделе [Оценка](evaluation), это "де-факто" метрика для оценки систем автоматического распознавания речи.

Давайте загрузим метрику WER из библиотеки 🤗 Evaluate:

```python
import evaluate

metric = evaluate.load("wer")
```

Затем нам просто нужно определить функцию, которая принимает предсказания нашей модели и возвращает метрику WER. Эта функция,
называемая `compute_metrics`, сначала заменяет `-100` на `pad_token_id` в `label_ids` (отменяя шаг, который мы применили в
коллекторе данных, чтобы правильно игнорировать заполненные токены при вычислении потерь). Затем он декодирует предсказанные
идентификаторы и идентификаторы меток в строки. Наконец, она вычисляет WER между предсказаниями и эталонными метками.
Здесь у нас есть возможность оценить "нормализованные" транскрипции и предсказания, у которых удалены знаки препинания и регистр.
Мы рекомендуем следовать этому совету, чтобы получить преимущество от улучшения WER, полученного путем нормализации транскрипций.

```python
from transformers.models.whisper.english_normalizer import BasicTextNormalizer

normalizer = BasicTextNormalizer()

def compute_metrics(pred):
    pred_ids = pred.predictions
    label_ids = pred.label_ids

    # replace -100 with the pad_token_id
    label_ids[label_ids == -100] = processor.tokenizer.pad_token_id

    # we do not want to group tokens when computing the metrics
    pred_str = processor.batch_decode(pred_ids, skip_special_tokens=True)
    label_str = processor.batch_decode(label_ids, skip_special_tokens=True)

    # compute orthographic wer
    wer_ortho = 100 * metric.compute(predictions=pred_str, references=label_str)

    # compute normalised WER
    pred_str_norm = [normalizer(pred) for pred in pred_str]
    label_str_norm = [normalizer(label) for label in label_str]
    # filtering step to only evaluate the samples that correspond to non-zero references:
    pred_str_norm = [
        pred_str_norm[i] for i in range(len(pred_str_norm)) if len(label_str_norm[i]) > 0
    ]
    label_str_norm = [
        label_str_norm[i]
        for i in range(len(label_str_norm))
        if len(label_str_norm[i]) > 0
    ]

    wer = 100 * metric.compute(predictions=pred_str_norm, references=label_str_norm)

    return {"wer_ortho": wer_ortho, "wer": wer}
```

### Загружаем предобученную контрольную точку

Теперь давайте загрузим предварительно обученную контрольную точку Whisper small. Опять же, это делается с помощью 🤗 Transformers без труда!

```python
from transformers import WhisperForConditionalGeneration

model = WhisperForConditionalGeneration.from_pretrained("openai/whisper-small")
```

Мы установим `use_cache` в значение `False` для обучения, так как мы используем [проверку градиента](https://huggingface.co/docs/transformers/v4.18.0/en/performance#gradient-checkpointing),
и эти две опции несовместимы. Мы также переопределим два аргумента для генерации, чтобы контролировать поведение модели во время вывода:
мы принудительно зададим токены языка и задачи во время генерации, установив аргументы `language` и `task`, и также снова включим
кэш для генерации, чтобы ускорить время вывода:

```python
from functools import partial

# disable cache during training since it's incompatible with gradient checkpointing
model.config.use_cache = False

# set language and task for generation and re-enable cache
model.generate = partial(
    model.generate, language="sinhalese", task="transcribe", use_cache=True
)
```

## Определение конфигурации обучения

На последнем этапе мы определяем все параметры, связанные с обучением. Здесь мы устанавливаем количество шагов обучения на 500.
Этого количества шагов достаточно, чтобы увидеть большое улучшение WER по сравнению с предварительно обученной моделью Whisper,
при этом обеспечивая возможность выполнения дообучения в течение примерно 45 минут в бесплатном тарифе Google Colab.
Для получения более подробной информации о параметрах обучения обратитесь к документации по Seq2SeqTrainingArguments [здесь](https://huggingface.co/docs/transformers/main_classes/trainer#transformers.Seq2SeqTrainingArguments).

```python
from transformers import Seq2SeqTrainingArguments

training_args = Seq2SeqTrainingArguments(
    output_dir="./whisper-small-dv",  # name on the HF Hub
    per_device_train_batch_size=16,
    gradient_accumulation_steps=1,  # increase by 2x for every 2x decrease in batch size
    learning_rate=1e-5,
    lr_scheduler_type="constant_with_warmup",
    warmup_steps=50,
    max_steps=500,  # increase to 4000 if you have your own GPU or a Colab paid plan
    gradient_checkpointing=True,
    fp16=True,
    fp16_full_eval=True,
    evaluation_strategy="steps",
    per_device_eval_batch_size=16,
    predict_with_generate=True,
    generation_max_length=225,
    save_steps=500,
    eval_steps=500,
    logging_steps=25,
    report_to=["tensorboard"],
    load_best_model_at_end=True,
    metric_for_best_model="wer",
    greater_is_better=False,
    push_to_hub=True,
)
```

    Если вы не хотите загружать контрольные точки модели на Hugging Face Hub, установите `push_to_hub=False`.

Мы можем передать аргументы обучения в 🤗 Trainer вместе с нашей моделью, набором данных, сборщиком данных и функцией `compute_metrics`:

```python
from transformers import Seq2SeqTrainer

trainer = Seq2SeqTrainer(
    args=training_args,
    model=model,
    train_dataset=common_voice["train"],
    eval_dataset=common_voice["test"],
    data_collator=data_collator,
    compute_metrics=compute_metrics,
    tokenizer=processor,
)
```

И теперь мы готовы приступить к обучению!

### Обучение

Для запуска обучения просто выполните:

```python
trainer.train()
```

Обучение займет примерно 45 минут в зависимости от вашего графического ускорителя или того, который выделен в Google Colab.
В зависимости от вашего GPU возможно, что при запуске обучения вы столкнетесь с ошибкой CUDA "out-of-memory". В этом случае
вы можете уменьшать `per_device_train_batch_size` постепенно вдвое и использовать [`gradient_accumulation_steps`](https://huggingface.co/docs/transformers/main_classes/trainer#transformers.Seq2SeqTrainingArguments.gradient_accumulation_steps)
для компенсации.

**Output:**

| Training Loss | Epoch | Step | Validation Loss | Wer Ortho | Wer     |
|:-------------:|:-----:|:----:|:---------------:|:---------:|:-------:|
| 0.136         | 1.63  | 500  | 0.1727          | 63.8972   | 14.0661 |

Наш окончательный WER составляет 14,1% - не плохо для семи часов данных обучения и всего 500 шагов обучения! Это означает
улучшение на 112% по сравнению с предварительно обученной моделью! Это означает, что мы взяли модель, которая ранее не имела знаний
о Дивехи, и успешно дообучили ее распознавать речь на Дивехи с достаточной точностью менее чем за один час 🤯

Большой вопрос заключается в том, как это сравнивать с другими системами распознавания речи. Для этого мы можем посмотреть на [доску лидеров autoevaluate](https://huggingface.co/spaces/autoevaluate/leaderboards?dataset=mozilla-foundation%2Fcommon_voice_13_0&only_verified=0&task=automatic-speech-recognition&config=dv&split=test&metric=wer),
которая классифицирует модели по языку и набору данных, а затем ранжирует их по их WER.

Посмотрев на доску лидеров, мы видим, что наша модель, обученная за 500 шагов, убедительно обгоняет предварительно обученный [Whisper Small](https://huggingface.co/openai/whisper-small),
который мы оценивали в предыдущем разделе. Отличная работа 👏

Мы видим, что есть несколько контрольных точек, которые показывают лучший результат, чем тот, который мы обучили. Прелесть платформы
Hugging Face Hub заключается в том, что это *коллаборативная* платформа - если у нас нет времени или ресурсов для проведения более
длительного обучения самостоятельно, мы можем загрузить контрольную точку, которую кто-то из сообщества обучил и любезно поделился ей
(не забудьте поблагодарить его за это!). Вы сможете загрузить эти контрольные точки так же, как и предварительно обученные модели, используя
класс `pipeline`, как мы делали ранее! Так что нет ничего, что бы могло помешать вам выбрать лучшую модель из доски лидеров для использования в вашей задаче!

Мы можем автоматически отправить нашу контрольную точку на доску лидеров, когда мы публикуем результаты обучения на Hugging Face Hub - нам
просто нужно установить соответствующие аргументы (kwargs). Вы можете изменить эти значения, чтобы они соответствовали вашему набору данных,
языку и имени модели:

```python
kwargs = {
    "dataset_tags": "mozilla-foundation/common_voice_13_0",
    "dataset": "Common Voice 13",  # a 'pretty' name for the training dataset
    "language": "dv",
    "model_name": "Whisper Small Dv - Sanchit Gandhi",  # a 'pretty' name for your model
    "finetuned_from": "openai/whisper-small",
    "tasks": "automatic-speech-recognition",
}
```

Теперь результаты обучения можно загрузить на Hugging Face Hub. Для этого выполните команду push_to_hub:

```python
trainer.push_to_hub(**kwargs)
```

Это сохранит журналы обучения и веса модели в папке `"ваше-имя-пользователя/имя-которое-вы-выбрали"`. В этом примере посмотрите
загрузку по адресу `sanchit-gandhi/whisper-small-dv`.

Хотя дообученная модель дает удовлетворительные результаты на тестовых данных Common Voice 13 на Дивехи, это далеко не оптимальный результат.
Цель данного руководства - показать, как настроить модель ASR с использованием 🤗 Trainer для многоязычного распознавания речи.

Если у вас есть доступ к собственному GPU или вы подписаны на платный план Google Colab, вы можете увеличить max_steps до 4000, чтобы
дополнительно улучшить WER, обучаясь больше шагов. Обучение на 4000 шагов займет примерно 3-5 часов в зависимости от вашего GPU и приведет
к результатам WER примерно на 3% ниже, чем при обучении на 500 шагах. Если вы решите обучить на 4000 шагов, мы также рекомендуем изменить
планировщик скорости обучения на *линейный* (установите `lr_scheduler_type="linear"`), так как это также принесет дополнительный прирост
производительности при длительных обучающихся сессиях.

Результаты могут быть дальше улучшены путем оптимизации гиперпараметров обучения, таких как _скорость обучения_ (_learning rate_) и _dropout_,
а также использования более крупной предварительно обученной контрольной точки (`medium` или `large`). Мы оставляем это как упражнение для читателя.

## Совместный доступ к модели

Теперь вы можете поделиться этой моделью с любым пользователем, используя ссылку на Hugging Face Hub. Они могут загрузить ее с идентификатором
`"your-username/the-name-you-picked"` непосредственно в объект `pipeline()`. Например, для загрузки дообученной контрольной
точки ["sanchit-gandhi/whisper-small-dv"](https://huggingface.co/sanchit-gandhi/whisper-small-dv):

```python
from transformers import pipeline

pipe = pipeline("automatic-speech-recognition", model="sanchit-gandhi/whisper-small-dv")
```

## Заключение

В этом разделе мы рассмотрели пошаговое руководство по дообучению модели Whisper для распознавания речи с использованием 🤗 Datasets,
Transformers и Hugging Face Hub. Сначала мы загрузили набор данных Dhivehi из Common Voice 13 и предобработали его, вычислив лог-мел-спектрограммы
и токенизировав текст. Затем мы определили способ обработки данных, метрику оценки и параметры обучения, прежде чем использовать 🤗 Trainer
для обучения и оценки нашей модели. Мы закончили, загрузив настроенную модель на Hugging Face Hub, и показали, как поделиться и использовать ее
с помощью класса `pipeline()`.

Если вы следовали этому руководству до этой точки, у вас теперь есть дообученная контрольная точка для распознавания речи, отличная работа! 🥳
Еще более важно то, что вы экипированы всеми инструментами, необходимыми для дообучения модели Whisper на любом наборе данных или в любой предметной
области. Так что чего вы ждете! Выберите один из наборов данных, охваченных в разделе [Выбор набора данных](choosing_dataset), или выберите свой
собственный набор данных и посмотрите, сможете ли вы достичь современной производительности (state-of-the-art performance)! Лидерборд ждет вас...

### Практическое занятие
https://huggingface.co/learn/audio-course/ru/chapter5/hands_on.md

# Практическое занятие

В этом разделе мы изучили сложности дообучения моделей ASR, признавая необходимость времени и ресурсов для дообучения модели, такой как Whisper
(даже с небольшой контрольной точкой), на новом языке. Чтобы предоставить вам практический опыт, мы разработали упражнение, которое поможет вам пройти
через процесс дообучения модели ASR с использованием небольшого набора данных. Основная цель этого упражнения - больше помочь вам ознакомиться с процессом
дообучения, чем стремиться к результатам на уровне продакшн-решений. Мы специально установили низкий показатель метрики, чтобы даже при ограниченных
ресурсах вы могли успешно его достичь.

Инструкции:

* Дообучите модель `”openai/whisper-tiny”`, используя американский английский ("en-US") поднабор набора данных `”PolyAI/minds14”`.
* Используйте первые **450 примеров для обучения**, остальные для оценки. Убедитесь, что вы установили `num_proc=1` при предварительной обработке набора данных с использованием метода `.map` (это обеспечит правильную отправку вашей модели для оценки).
* Для оценки модели используйте метрики `wer` и `wer_ortho`, как описано в данном уроке. Однако *не* преобразуйте метрику в проценты, умножая на 100 (например, если WER равен 42%, мы ожидаем увидеть значение 0.42 в этом упражнении).

После того как вы проведете тонкую настройку модели, убедитесь, что загрузили ее на 🤗 Hugging Face Hub с использованием следующих параметров (`kwargs`):
```
kwargs = {
     "dataset_tags": "PolyAI/minds14",
    "finetuned_from": "openai/whisper-tiny",
    "tasks": "automatic-speech-recognition",
}
```
Вы успешно завершите это задание, если показатель WER (`wer`) вашей нормализованный вашей будет ниже **0.37**.

Не стесняйтесь создать демо вашей модели и поделиться ею в Discord! Если у вас возникнут вопросы, задайте их в канале #audio-study-group.

### Чему вы научитесь и что создадите
https://huggingface.co/learn/audio-course/ru/chapter5/introduction.md

# Чему вы научитесь и что создадите

В этом разделе мы рассмотрим, как трансформеры могут быть использованы для преобразования устной речи в текст - задача, известная как _распознавание речи_ (_speech recognition_).

    

Распознавание речи, известное также как автоматическое распознавание речи (automatic speech recognition - ASR) или преобразование речи в текст
(speech-to-text - STT), является одной из наиболее популярных и интересных задач обработки устной речи. Она используется в широком спектре приложений,
включая диктовку, голосовые помощники, субтитры к видео и транскрибацию переговоров / совещаний.

Возможно, вы уже не раз пользовались системой распознавания речи, даже не подозревая об этом! Возьмем, к примеру, цифрового ассистента в вашем смартфоне
(Siri, Google Assistant, Alexa). Когда вы пользуетесь такими помощниками, первое, что они делают, - это транскрибируют вашу устную речь в письменный
текст, готовый к использованию для решения последующих задач (например, для поиска прогноза погоды 🌤️).

Попробуйте воспользоваться демонстрацией распознавания речи, приведенной ниже. Вы можете записать себя с помощью микрофона или перетащить в окно образец
звука для расшифровки:

 

Распознавание речи является сложной задачей, поскольку требует совместного знания в области звука и текста. Входной звук может содержать много фоновых
шумов и произноситься дикторами с разным акцентом, что затрудняет выделение произносимой речи. В письменном тексте могут присутствовать символы, не
имеющие акустического звучания, например, знаки препинания, которые трудно определить только по звуку. Все это - препятствия, которые нам приходится
преодолевать при создании эффективных систем распознавания речи!

Теперь, когда мы определились с задачей, можно приступить к более детальному изучению распознавания речи. К концу этого раздела вы будете иметь хорошее
фундаментальное представление о различных доступных предварительно обученных моделях распознавания речи и о том, как использовать их с библиотекой
🤗 Transformers. Вы также узнаете о процедуре тонкой настройки ASR-модели на выбранный домен или язык, что позволит вам построить производительную
систему для решения любой задачи. Вы сможете продемонстрировать свою модель друзьям и близким, создав "живую" демонстрацию, которая воспринимает любую
устную речь и преобразует ее в текст!

В частности, мы рассмотрим:

* [Предварительно обученные модели для распознавания речи](asr_models)
* [Выбор набора данных](choosing_dataset)
* [Оценка и метрики для распознавания речи](evaluation)
* [Как дообучить ASR-систему с помощью Trainer API](fine-tuning)
* [Создание демо](demo)
* [Практическое занятие](hands_on)

### Создание Демо с Gradio
https://huggingface.co/learn/audio-course/ru/chapter5/demo.md

# Создание Демо с Gradio

Теперь, когда мы настроили модель Whisper для распознавания речи на Дивехи, давайте продолжим и создадим демо с использованием [Gradio](https://gradio.app),
чтобы показать ее сообществу!

Первое, что нам нужно сделать, это загрузить дообученную модель, используя класс `pipeline()` - это уже знакомо из раздела о [предварительно обученных моделях](asr_models).
Вы можете заменить идентификатор модели (`model_id`) на пространство имен вашей дообученной модели на Hugging Face Hub, или на одну из
предобученных [моделей Whisper](https://huggingface.co/models?sort=downloads&search=openai%2Fwhisper-)  для выполнения распознавания речи без настройки (zero-shot):

```python
from transformers import pipeline

model_id = "sanchit-gandhi/whisper-small-dv"  # update with your model id
pipe = pipeline("automatic-speech-recognition", model=model_id)
```

Во-вторых, мы определим функцию, которая принимает путь к аудиофайлу в качестве входных данных и передает его через конвейер (`pipeline`).
Здесь конвейер автоматически заботится о загрузке аудиофайла, пересэмплировании его до правильной частоты дискретизации и выполнении вывода модели.
Затем мы просто вернем преобразованный текст в качестве выходных данных функции. Чтобы обеспечить возможность нашей модели обрабатывать аудиофайлы
произвольной длины, мы включим *фрагментирование* (разбиение на фрагменты), как описано в разделе о [предварительно обученных моделях](asr_models):

```python
def transcribe_speech(filepath):
    output = pipe(
        filepath,
        max_new_tokens=256,
        generate_kwargs={
            "task": "transcribe",
            "language": "sinhalese",
        },  # update with the language you've fine-tuned on
        chunk_length_s=30,
        batch_size=8,
    )
    return output["text"]
```

Мы будем использовать функцию [blocks](https://gradio.app/docs/#blocks) в Gradio, чтобы создать две вкладки в нашем демо: одну
для транскрипции с микрофона и другую для загрузки файла.

```python
import gradio as gr

demo = gr.Blocks()

mic_transcribe = gr.Interface(
    fn=transcribe_speech,
    inputs=gr.Audio(source="microphone", type="filepath"),
    outputs=gr.outputs.Textbox(),
)

file_transcribe = gr.Interface(
    fn=transcribe_speech,
    inputs=gr.Audio(source="upload", type="filepath"),
    outputs=gr.outputs.Textbox(),
)
```

Наконец, мы запускаем демонстрацию Gradio, используя два только что определенных блока:

```python
with demo:
    gr.TabbedInterface(
        [mic_transcribe, file_transcribe],
        ["Transcribe Microphone", "Transcribe Audio File"],
    )

demo.launch(debug=True)
```

Это запустит демонстрацию Gradio, подобную той, которая работает на пространстве Hugging Face:

Если вы хотите разместить своё демо на платформе Hugging Face Hub, вы можете использовать этот Space в качестве шаблона для своей модели.
Для этого выполните следующие шаги:

Щелкните по ссылке, чтобы дублировать шаблон демо в свою учетную запись: https://huggingface.co/spaces/course-demos/whisper-small?duplicate=true

Рекомендуем дать своему Space имя, подобное имени вашей обученной модели (например, whisper-small-dv-demo) и установить видимость на "Public" (Публичный).

После дублирования Space в вашей учетной записи перейдите в раздел "Files and versions" -> "app.py" -> "edit". Затем измените идентификатор модели
на идентификатор вашей обученной модели(строка 6). Прокрутите страницу вниз и нажмите "Commit changes to main" (Зафиксировать изменения в главной версии).
Демо перезагрузится, используя вашу обученную модель. Теперь вы можете поделиться этим демо со своими друзьями и родственниками, чтобы они могли использовать
модель, которую вы обучили!

Вы можете посмотреть наш видеоурок, чтобы лучше понять, как продублировать Space: [YouTube Video](https://www.youtube.com/watch?v=VQYuvl6-9VE)

Ожидаем с нетерпением увидеть ваши демо на Hugging Face Hub!

### Дополнительные материалы и ресурсы
https://huggingface.co/learn/audio-course/ru/chapter5/supplemental_reading.md

# Дополнительные материалы и ресурсы

Этот раздел предоставил практическое введение в распознавание речи, одну из самых популярных задач в области аудио.
Хотите узнать больше? Здесь вы найдете дополнительные ресурсы, которые помогут вам углубить свое понимание темы и повысить качество обучения.

* [Whisper Talk](https://www.youtube.com/live/fZMiD8sDzzg?feature=share) by Jong Wook Kim: презентация о модели Whisper, в которой объясняются мотивация, архитектура, обучение и результаты, представленные автором Whisper - Джонг Вук Кимом.
* [End-to-End Speech Benchmark (ESB)](https://arxiv.org/abs/2210.13352): научная статья, в которой обосновывается использование орфографического WER вместо нормализованного WER для оценки систем распознавания речи и представляется соответствующий бенчмарк.
* [Fine-Tuning Whisper for Multilingual ASR](https://huggingface.co/blog/fine-tune-whisper): подробный блог-пост, который объясняет, как работает модель Whisper, и подробно описывает пред- и пост-обработку с использованием извлекателя призников и токенизатора.
* [Fine-tuning MMS Adapter Models for Multi-Lingual ASR](https://huggingface.co/blog/mms_adapters): полное руководство по дообучению новых многоязычных моделей распознавания речи Meta AI [MMS](https://ai.facebook.com/blog/multilingual-model-speech-recognition/), при этом замораживая веса базовой модели и обучая только небольшое количество *адаптерных* слоев.
* [Boosting Wav2Vec2 with n-grams in 🤗 Transformers](https://huggingface.co/blog/wav2vec2-with-ngram): блог-пост о сочетании моделей CTC с внешними языковыми моделями (LM) для борьбы со смысловыми и пунктуационными ошибками.

### Предварительно обученные модели для распознавания речи
https://huggingface.co/learn/audio-course/ru/chapter5/asr_models.md

# Предварительно обученные модели для распознавания речи

В этом разделе мы рассмотрим, как с помощью `pipeline()` использовать предварительно обученные модели для распознавания речи.
В [Разделе 2](../chapter2/asr_pipeline) мы представили `pipeline()` как простой способ выполнения задач распознавания речи с предварительной
и последующей обработкой "под капотом" и возможностью быстро экспериментировать с любой предварительно обученной контрольной точкой модели на Hugging Face Hub.
В этом разделе мы углубимся в изучение различных характеристик моделей распознавания речи и рассмотрим, как их можно использовать для решения различных задач.

Как подробно описано в Разделе 3, модели распознавания речи в целом относятся к одной из двух категорий:

1. Connectionist Temporal Classification (CTC) или Коннекционистская Временная Классификация: модели состящие только из энкодера, с головой линейного классификатора в вершине модели.
2. Sequence-to-sequence (Seq2Seq) или последовательность-в-последовательность: модели включающие в себя как энкодер, так и декодер с механизмом перекрестного внимания между ними (cross-attention).

До 2022 года более популярной из двух архитектур была CTC, а такие модели, работающие только с энкодером, как Wav2Vec2, HuBERT и XLSR, совершили прорыв в парадигме
предварительного обучения/дообучения в задачах с речью. Крупные корпорации, такие как Meta и Microsoft, предварительно обучали энкодер на огромных объемах
неразмеченных аудиоданных в течение многих дней или недель. Затем пользователи могли взять предварительно обученную контрольную точку и дообучить ее с помощью
головы CTC всего на **10 минутах** размеченных речевых данных для достижения высоких результатов в последующей задаче распознавания речи.

Однако модели CTC имеют свои недостатки. Присоединение простого линейного слоя к кодирующему устройству дает небольшую и быструю модель в целом, но она может
быть подвержена фонетическим ошибкам в написании. Ниже мы продемонстрируем это на примере модели Wav2Vec2.

## Анализ моделей CTC

Загрузим небольшой фрагмент набора данных [LibriSpeech ASR](hf-internal-testing/librispeech_asr_dummy) чтобы продемонстрировать возможности Wav2Vec2
по транскрибации речи:

```python
from datasets import load_dataset

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

**Output:**
```
Dataset({
    features: ['file', 'audio', 'text', 'speaker_id', 'chapter_id', 'id'],
    num_rows: 73
})
```

Мы можем выбрать один из 73 аудиообразцов и просмотреть его, а также транскрипцию:

```python
from IPython.display import Audio

sample = dataset[2]

print(sample["text"])
Audio(sample["audio"]["array"], rate=sample["audio"]["sampling_rate"])
```
**Output:**
```
HE TELLS US THAT AT THIS FESTIVE SEASON OF THE YEAR WITH CHRISTMAS AND ROAST BEEF LOOMING BEFORE US SIMILES DRAWN FROM EATING AND ITS RESULTS OCCUR MOST READILY TO THE MIND
```

Хорошо! Рождество и запеченная в духовке говядина, звучит здорово! 🎄 Сформировав выборку данных, мы теперь загружаем
дообученную контрольную точку в `pipeline()`. Для этого мы будем использовать официальную контрольную точку [Wav2Vec2 base](facebook/wav2vec2-base-100h)
дообученную на 100 часах данных LibriSpeech:

```python
from transformers import pipeline

pipe = pipeline("automatic-speech-recognition", model="facebook/wav2vec2-base-100h")
```

Далее мы возьмем пример из набора данных и передадим его исходные данные в конвейер. Поскольку `pipeline` *поглощает* любой словарь, который мы ему
передаем (то есть его нельзя использовать повторно), мы будем передавать копию данных. Таким образом, мы можем безопасно повторно использовать один
и тот же аудиообразец в следующих примерах:

```python
pipe(sample["audio"].copy())
```
**Output:**
```
{"text": "HE TELLS US THAT AT THIS FESTIVE SEASON OF THE YEAR WITH CHRISTMAUS AND ROSE BEEF LOOMING BEFORE US SIMALYIS DRAWN FROM EATING AND ITS RESULTS OCCUR MOST READILY TO THE MIND"}
```

Видно, что модель Wav2Vec2 неплохо справляется с транскрибацией данного образца - на первый взгляд, все выглядит в целом корректно.
Давайте поставим целевое значение (target) и прогноз/предсказание модели (prediction) рядом и выделим различия:

```
Target:      HE TELLS US THAT AT THIS FESTIVE SEASON OF THE YEAR WITH CHRISTMAS AND ROAST BEEF LOOMING BEFORE US SIMILES DRAWN FROM EATING AND ITS RESULTS OCCUR MOST READILY TO THE MIND
Prediction:  HE TELLS US THAT AT THIS FESTIVE SEASON OF THE YEAR WITH **CHRISTMAUS** AND **ROSE** BEEF LOOMING BEFORE US **SIMALYIS** DRAWN FROM EATING AND ITS RESULTS OCCUR MOST READILY TO THE MIND
```

Сравнивая целевой текст с предсказанной транскрибацией, мы видим, что все слова _звучат_ правильно, но некоторые написаны не совсем точно. Например:

* _CHRISTMAUS_ vs. _CHRISTMAS_
* _ROSE_ vs. _ROAST_
* _SIMALYIS_ vs. _SIMILES_

Это подчеркивает недостаток модели CTC. Модель CTC - это, по сути, "только акустическая" модель: она состоит из энкодера, который формирует представления
скрытых состояний из аудиовходов, и линейного слоя, который отображает скрытые состояния в символы:

Это означает, что система практически полностью основывает свое предсказание на акустических данных (фонетических звуках аудиозаписи) и поэтому склонна
транскрибировать аудиозапись фонетическим способом (например, _CHRISTMAUS_). В нем меньше внимания уделяется языковому моделирующему контексту предыдущих
и последующих букв, поэтому он склонен к фонетическим ошибкам в написании. Более интеллектуальная модель определила бы, что _CHRISTMAUS_ не является
правильным словом в английском словаре, и исправила бы его на _CHRISTMAS_, когда делала бы свои предсказания. Кроме того, в нашем прогнозировании отсутствуют
два важных признака - регистр и пунктуация, что ограничивает полезность транскрибации модели для реальных приложений.

## Переход к Seq2Seq

Модели Seq2Seq! Как было описано в Разделе 3, модели Seq2Seq состоят из энкодера и декодера, связанных между собой механизмом перекрестного внимания.
Энкодер играет ту же роль, что и раньше, вычисляя представления скрытых состояний аудиовходов, а декодер - роль **языковой модели**. Декодер обрабатывает
всю последовательность представлений скрытых состояний, полученных от энкодера, и формирует соответствующие текстовые транскрипции. Имея глобальный контекст
входного аудиосигнала, декодер может использовать контекст языкового моделирования при составлении своих прогнозов, исправляя орфографические ошибки
"на лету" и тем самым обходя проблему фонетических прогнозов.

У моделей Seq2Seq есть два недостатка:
1. Они изначально медленнее декодируют, поскольку процесс декодирования происходит по одному шагу за раз, а не все сразу
2. Они более требовательны к данным, для достижения сходимости им требуется значительно больше обучающих данных

В частности, узким местом в развитии архитектур Seq2Seq для задач с речью является потребность в больших объемах обучающих данных. Размеченные речевые данные
труднодоступны, самые большие аннотированные базы данных на тот момент составляли всего 10 000 часов. Все изменилось в 2022 году после выхода **Whisper**.
Whisper - это предварительно обученная модель для распознавания речи, опубликованная в [Сентябре 2022](https://openai.com/blog/whisper/) авторами Alec Radford
и др. из компании OpenAI. В отличие от предшественников CTC, которые обучались исключительно на **неразмеченных** аудиоданных, Whisper предварительно обучен
на огромном количестве **размеченных** данных аудиотранскрипции, а именно на 680 000 часов.

Это на порядок больше данных, чем неразмеченные аудиоданные, использованные для обучения Wav2Vec 2.0 (60 000 часов). Более того, 117 000 часов этих данных,
предназначенных для предварительного обучения, являются мультиязычными (или "не английскими") данными. В результате контрольные точки могут быть применены
к более чем 96 языкам, многие из которых считаются _низкоресурсными_, т.е. не имеющими большого корпуса данных, пригодных для обучения.

При масштабировании на 680 000 часов аннотированных данных для предварительного обучения модели Whisper демонстрируют высокую способность к обобщению
на многие наборы данных и области. Предварительно обученные контрольные точки достигают результатов, конкурентоспособных с state-of-the-art pipe systems,
с коэффициентом ошибок в словах (WER) около 3% на подмножестве чистых тестов LibriSpeech и новым рекордом на TED-LIUM с WER 4,7%
(см. табл. 8 [Whisper paper](https://cdn.openai.com/papers/whisper.pdf)).

Особое значение имеет способность Whisper работать с длинными аудиообразцами, устойчивость к входным шумам и возможность предсказывать транскрипцию с
использованием падежей и пунктуации. Это делает его перспективным для использования в реальных системах распознавания речи.

В оставшейся части этого раздела будет показано, как использовать предварительно обученные модели Whisper для распознавания речи с помощью 🤗 Transformers.
Во многих ситуациях предварительно обученные контрольные точки Whisper обладают высокой производительностью и дают отличные результаты, поэтому мы
рекомендуем вам попробовать использовать предварительно обученные контрольные точки в качестве первого шага к решению любой задачи распознавания речи.
Благодаря дообучению предварительно обученные контрольные точки могут быть адаптированы для конкретных наборов данных и языков с целью дальнейшего
улучшения результатов. Как это сделать, мы продемонстрируем в следующем подразделе, посвященном [дообучению] (fine-tuning).

Контрольные точки модели Whisper доступны в пяти конфигурациях с различными размерами модели. Наименьшие по параметрам четыре модели обучаются либо
только на английском, либо на многоязычных данных. Самая большая по параметрам контрольная точка была обучена только на мультиязычных данных.
Все девять предварительно обученных контрольных точек доступны на [Hugging Face Hub](https://huggingface.co/models?search=openai/whisper). Контрольные
точки приведены в следующей таблице со ссылками на модели на Hugging Face Hub. "VRAM" обозначает объем памяти GPU, необходимый для работы модели с
минимальным размером пакета = 1. "Rel Speed" - относительная скорость контрольной точки по сравнению с самой большой моделью. На основе этой информации
можно выбрать контрольную точку, наиболее подходящую для вашего оборудования.

| Size   | Parameters | VRAM / GB | Rel Speed | English-only                                         | Multilingual                                        |
|--------|------------|-----------|-----------|------------------------------------------------------|-----------------------------------------------------|
| tiny   | 39 M       | 1.4       | 32        | [✓](https://huggingface.co/openai/whisper-tiny.en)   | [✓](https://huggingface.co/openai/whisper-tiny)     |
| base   | 74 M       | 1.5       | 16        | [✓](https://huggingface.co/openai/whisper-base.en)   | [✓](https://huggingface.co/openai/whisper-base)     |
| small  | 244 M      | 2.3       | 6         | [✓](https://huggingface.co/openai/whisper-small.en)  | [✓](https://huggingface.co/openai/whisper-small)    |
| medium | 769 M      | 4.2       | 2         | [✓](https://huggingface.co/openai/whisper-medium.en) | [✓](https://huggingface.co/openai/whisper-medium)   |
| large  | 1550 M     | 7.5       | 1         | x                                                    | [✓](https://huggingface.co/openai/whisper-large-v2) |

Загрузим контрольную точку [Whisper Base](https://huggingface.co/openai/whisper-base), которая по размеру сопоставима с контрольной точкой Wav2Vec2, которую
мы использовали ранее. Предваряя наш переход к многоязычному распознаванию речи, загрузим многоязычный вариант базовой контрольной точки. Мы также загрузим
модель на GPU, если он доступен, или на CPU в противном случае. В последствии `pipeline()` позаботится о перемещении всех входов/выходов с CPU на GPU по мере
необходимости:

```python
import torch
from transformers import pipeline

device = "cuda:0" if torch.cuda.is_available() else "cpu"
pipe = pipeline(
    "automatic-speech-recognition", model="openai/whisper-base", device=device
)
```

Отлично! Теперь давайте транскрибируем аудиозапись, как и раньше. Единственное изменение - это передача дополнительного аргумента `max_new_tokens`, который
указывает модели максимальное количество токенов, которые нужно генерировать при предсказании:

```python
pipe(sample["audio"], max_new_tokens=256)
```
**Output:**
```
{'text': ' He tells us that at this festive season of the year, with Christmas and roast beef looming before us, similarly is drawn from eating and its results occur most readily to the mind.'}
```

Достаточно легко! Первое, на что вы обратите внимание, - это наличие как регистра, так и знаков препинания. Это сразу же делает транскрипцию более удобной для
чтения по сравнению с транскрипцией из Wav2Vec2, не содержащей ни регистра, ни пунктуации. Давайте поместим транскрипцию рядом с целевой меткой:

```
Target:     HE TELLS US THAT AT THIS FESTIVE SEASON OF THE YEAR WITH CHRISTMAS AND ROAST BEEF LOOMING BEFORE US SIMILES DRAWN FROM EATING AND ITS RESULTS OCCUR MOST READILY TO THE MIND
Prediction: He tells us that at this festive season of the year, with **Christmas** and **roast** beef looming before us, **similarly** is drawn from eating and its results occur most readily to the mind.
```

Whisper проделал большую работу по исправлению фонетических ошибок, которые мы видели в Wav2Vec2 - и _Christmas_, и _roast_ написаны правильно.
Мы видим, что модель все еще испытывает трудности с _SIMILES_, которое неправильно транскрибируется как _similarly_, но на этот раз предсказание
является правильным словом из английского словаря. Использование контрольной точки Whisper большего размера позволяет еще больше снизить количество
ошибок в транскрибированном тексте, но при этом требует больше вычислений и увеличивает время транскрибации.

Нам обещали модель, способную работать с 96 языками, так что оставим пока распознавание английской речи и пойдем по миру 🌎! Набор данных [Multilingual LibriSpeech](https://huggingface.co/datasets/facebook/multilingual_librispeech)
(MLS) представляет собой многоязычный аналог набора данных LibriSpeech, содержащий размеченные аудиоданные на шести языках. Мы загрузим одну
образец из испанской части набора данных MLS, используя режим _streaming_, чтобы не загружать весь набор данных:

```python
dataset = load_dataset(
    "facebook/multilingual_librispeech", "spanish", split="validation", streaming=True
)
sample = next(iter(dataset))
```

Снова посмотрим текстовую транскрипцию и прослушаем аудиофрагмент:

```python
print(sample["text"])
Audio(sample["audio"]["array"], rate=sample["audio"]["sampling_rate"])
```
**Output:**
```
entonces te delelitarás en jehová y yo te haré subir sobre las alturas de la tierra y te daré á comer la heredad de jacob tu padre porque la boca de jehová lo ha hablado
```

Это целевой текст, на который мы ориентируемся в нашей транскрипции Whisper. Хотя теперь мы знаем, что, вероятно, можем сделать это лучше,
поскольку наша модель будет предсказывать также пунктуацию и регистр, которые в выводе примера отсутствуют. Передадим образец звука в конвейер для
получения предсказания текста. Следует отметить, что конвейер _потребует_ словарь аудиовходов, который мы вводим, то есть словарь не может
быть использован повторно. Чтобы обойти эту проблему, мы будем передавать _копию_ аудиообразца, что позволит нам повторно использовать тот же самый
аудиообразец в последующих примерах кода:

```python
pipe(sample["audio"].copy(), max_new_tokens=256, generate_kwargs={"task": "transcribe"})
```
**Output:**
```
{'text': ' Entonces te deleitarás en Jehová y yo te haré subir sobre las alturas de la tierra y te daré a comer la heredad de Jacob tu padre porque la boca de Jehová lo ha hablado.'}
```

Отлично - это очень похоже на наш целевой текст (возможно, даже лучше, поскольку в нем есть пунктуация и регистр!). Обратите внимание, что мы передали
`"task"` в качестве аргумента _генерируемого ключевого слова_ (generate kwarg). Передача ключу `"task"` значения `"transcribe"` заставляет Whisper
выполнять задачу _распознавания речи_, при которой аудиозапись транскрибируется на том же языке, на котором была произнесена речь. Whisper также
способен выполнять тесно связанную с задачу - _перевода речи_, когда аудиозапись на испанском языке может быть переведена в текст на английском.
Для этого мы передаем ключу `"task"` значение `"translate"`:

```python
pipe(sample["audio"], max_new_tokens=256, generate_kwargs={"task": "translate"})
```
**Output:**
```
{'text': ' So you will choose in Jehovah and I will raise you on the heights of the earth and I will give you the honor of Jacob to your father because the voice of Jehovah has spoken to you.'}
```

Теперь, когда мы знаем, что можем переключаться между распознаванием речи и ее переводом, мы можем выбирать задачу в зависимости от наших потребностей.
Либо мы распознаем звук на языке X в текст на том же языке X (например, испанский звук в испанский текст), либо переводим с любого языка X в текст
на английском языке (например, испанский звук в английский текст).

Подробнее о том, как аргумент `"task"` используется для управления свойствами генерируемого текста, см. в [карточке модели](https://huggingface.co/openai/whisper-base#usage)
для базовой модели Whisper.

## Длинноформатная транскрипция и временные метки

Пока мы были сосредоточены на транскрибации коротких аудиофрагментов длительностью менее 30 секунд. Мы уже упоминали, что одной из привлекательных
сторон Whisper является возможность работы с длинными аудиофрагментами. В этой части раздела мы рассмотрим эту задачу!

Создадим длинный аудиофайл путем конкатенации последовательных выборок из набора данных MLS. Поскольку набор данных MLS формируется путем разбиения
длинных записей аудиокниг на более короткие сегменты, конкатенация образцов является одним из способов реконструкции более длинных отрывков аудиокниг.
Следовательно, результирующий звук должен быть когерентным по всей выборке.

Мы установим целевую длительность звука в 5 минут и прекратим конкатенацию сэмплов, как только достигнем этого значения:

```python
import numpy as np

target_length_in_m = 5

# преобразование из минут в секунды (* 60) в число выборок (* частота дискретизации)
sampling_rate = pipe.feature_extractor.sampling_rate
target_length_in_samples = target_length_in_m * 60 * sampling_rate

# итерируемся по нашему потоковому набору данных, конкатенируя выборки до тех пор, пока мы не достигнем нашей цели
long_audio = []
for sample in dataset:
    long_audio.extend(sample["audio"]["array"])
    if len(long_audio) > target_length_in_samples:
        break

long_audio = np.asarray(long_audio)

# что у нас получилось?
seconds = len(long_audio) / 16000
minutes, seconds = divmod(seconds, 60)
print(f"Length of audio sample is {minutes} minutes {seconds:.2f} seconds")
```
**Output:**
```
Length of audio sample is 5.0 minutes 17.22 seconds
```

Отлично! Осталось транскрибировать 5 минут 17 секунд аудиозаписи. При передаче такого длинного аудиофрагмента непосредственно в модель
возникают две проблемы:
1. Whisper изначально рассчитан на работу с 30-секундными образцами: все, что короче 30 секунд, заполняется тишиной, все, что длиннее 30 секунд, усекается до 30 секунд путем вырезания лишнего звука, поэтому если мы передадим наш звук напрямую, то получим транскрипцию только первых 30 секунд
2. Память в сети трансформера зависит от квадрата длины последовательности: удвоение длины входного сигнала увеличивает потребность в памяти в четыре раза, поэтому передача очень длинных аудиофайлов обязательно приведет к ошибке "вне памяти" (out-of-memory)

Длинная транскрибация в 🤗 Transformers осуществляется путем _фрагментации_ (от англ. chunking) входного аудио на более мелкие и управляемые фрагменты.
Каждый фрагмент имеет небольшое наложение с предыдущим. Это позволяет нам точно соединять фрагменты на границах,
так как мы можем найти наложение между фрагментами и соответствующим образом объединить транскрипции:

     

Преимущество фрагментирования аудиообразцов на части заключается в том, что нам не нужен результат транскрибации небольшого фрагмента аудиосигнала \\( i \\)
для транскрибации последующего фрагмента \\( i + 1 \\). Соединение выполняется после того, как мы
транскрибировали все фрагменты на границах фрагментов, поэтому не имеет значения, в каком порядке мы их транскрибируем. Алгоритм полностью **нестационарный**,
поэтому мы можем даже обрабатывать фрагмент \\( i + 1 \\) одновременно с фрагментом \\( i \\)! Это позволяет нам _пакетировать_ (от англ. batch) фрагменты
и прогонять их через модель параллельно, обеспечивая значительное ускорение вычислений по сравнению с их последовательной транскрибацией. Более подробно
о фрагментированни в 🤗 Transformers можно прочитать в [посте из блога](https://huggingface.co/blog/asr-chunking).

Для активации длинных транскрипций необходимо добавить один дополнительный аргумент при вызове конвейера. Этот аргумент, `chunk_length_s`,
определяет длину фрагментов в секундах. Для Whisper оптимальной является 30-секундная длина фрагментов, поскольку она соответствует длине
входного сигнала, ожидаемого Whisper.

Чтобы активизировать пакетную обработку, необходимо передать конвейеру аргумент `batch_size`. Если собрать все это воедино,
то транскрибация длинного аудиообразца с использованием чанкинга и батчинга может быть выполнена следующим образом:

```python
pipe(
    long_audio,
    max_new_tokens=256,
    generate_kwargs={"task": "transcribe"},
    chunk_length_s=30,
    batch_size=8,
)
```
**Output:**
```
{'text': ' Entonces te deleitarás en Jehová, y yo te haré subir sobre las alturas de la tierra, y te daré a comer la
heredad de Jacob tu padre, porque la boca de Jehová lo ha hablado. nosotros curados. Todos nosotros nos descarriamos
como bejas, cada cual se apartó por su camino, mas Jehová cargó en él el pecado de todos nosotros...
```

Мы не будем приводить здесь весь результат, поскольку он довольно длинный (всего 312 слов)! На графическом процессоре V100
с памятью 16 Гбайт выполнение приведенной выше строки займет примерно 3,45 секунды, что весьма неплохо для 317-секундного аудиообразца.
На CPU ожидается около 30 секунд.

Whisper также способен предсказывать _временные метки_ на уровне фрагментов для аудиоданных. Эти временные метки указывают на время начала
и окончания короткого отрывка аудиозаписи и особенно полезны для выравнивания транскрипции с входным аудиосигналом. Предположим, мы хотим
создать субтитры для видео - нам нужны эти временные метки, чтобы знать, какая часть транскрипции соответствует определенному
сегменту видео, чтобы отобразить правильную транскрипцию для этого времени.

Активировать предсказание временных меток очень просто, достаточно установить аргумент `return_timestamps=True`. Временные метки совместимы
с методами фрагментирования и пакетирования, которые мы использовали ранее, поэтому мы можем просто добавить аргумент timestamp к нашему
предыдущему вызову:

```python
pipe(
    long_audio,
    max_new_tokens=256,
    generate_kwargs={"task": "transcribe"},
    chunk_length_s=30,
    batch_size=8,
    return_timestamps=True,
)["chunks"]
```
**Output:**
```
[{'timestamp': (0.0, 26.4),
  'text': ' Entonces te deleitarás en Jehová, y yo te haré subir sobre las alturas de la tierra, y te daré a comer la heredad de Jacob tu padre, porque la boca de Jehová lo ha hablado. nosotros curados. Todos nosotros nos descarriamos como bejas, cada cual se apartó por su camino,'},
 {'timestamp': (26.4, 32.48),
  'text': ' mas Jehová cargó en él el pecado de todos nosotros. No es que partas tu pan con el'},
 {'timestamp': (32.48, 38.4),
  'text': ' hambriento y a los hombres herrantes metas en casa, que cuando vieres al desnudo lo cubras y no'},
 ...
```

И вуаля! У нас есть предсказанный текст и соответствующие временные метки.

## Итоги

Whisper - это сильная предварительно обученная модель для распознавания и перевода речи. По сравнению с Wav2Vec2, он обладает более
высокой точностью транскрибации, при этом выходные данные содержат знаки препинания и регистр. Он может использоваться для транскрибации
речи на английском и 96 других языках, как на коротких аудиофрагментах, так и на более длинных за счет _фрагментирования_. Эти качества делают
его подходящей моделью для многих задач распознавания речи и перевода без необходимости дообучения. Метод `pipeline()` обеспечивает простой
способ выполнения выводов в виде однострочных вызовов API с контролем над генерируемыми предсказаниями.

В то время как модель Whisper демонстрирует отличные результаты на многих языках с большим количеством ресурсов, она имеет более низкую
точность транскрибации и перевода на языках с малым количеством ресурсов, т.е. на языках с меньшим количеством доступных обучающих данных.
Кроме того, существуют различия в результатах работы с разными акцентами и диалектами некоторых языков, включая более низкую точность для
носителей разных полов, рас, возрастов и других демографических критериев (например, [Whisper paper](https://arxiv.org/pdf/2212.04356.pdf)).

Для повышения производительности при работе с языками, акцентами или диалектами, не имеющими достаточного количества ресурсов, мы можем взять
предварительно обученную модель Whisper и обучить ее на небольшом корпусе данных, подобранных соответствующим образом, в процессе,
называемом _дообучением_. Мы покажем, что всего десять часов дополнительных данных позволяют повысить производительность модели Whisper более
чем на 100% на языке с низким уровнем ресурсов. В следующей секции мы рассмотрим процесс выбора набора данных для дообучения модели.

### Выбор набора данных
https://huggingface.co/learn/audio-course/ru/chapter5/choosing_dataset.md

# Выбор набора данных

Как и в любой другой задаче машинного обучения, наша модель хороша лишь настолько, насколько хороши данные, на которых мы ее обучаем.
Наборы данных для распознавания речи существенно различаются по способу их формирования и областям, которые они охватывают.
Чтобы выбрать правильный набор данных, необходимо сопоставить наши критерии с возможностями, которые предоставляет набор данных.

Прежде чем выбрать набор данных, необходимо понять его ключевые определяющие характеристики.

## Характеристики речевых наборов данных

### 1. Количество часов
Проще говоря, количество часов обучения показывает, насколько велик набор данных. Это аналогично количеству обучающих примеров в наборе данных
для обработки естественного языка (NLP). Однако, большой набор данных не означает что этот набор лучший. Если мы хотим получить модель, которая
хорошо обобщает, нам нужна **разнообразный** набор данных с большим количеством различных дикторов, источников и стилей речи.

### 2. Источник данных
Источник данных означает, откуда были взяты данные, будь то аудиокниги, подкасты, YouTube или финансовые встречи. Для каждого источника характерно
свое распределение данных. Например, аудиокниги записываются в качественных студийных условиях (без посторонних шумов), а текст берется из
письменной литературы. В то время как для YouTube аудиозапись, скорее всего, содержит больше фонового шума и более неформальный стиль речи.

Мы должны соотнести наш источник с условиями, которые мы ожидаем в момент вывода. Например, если мы обучаем нашу модель на аудиокнигах, мы не можем
ожидать, что она будет хорошо работать в шумной обстановке.

### 3. Стиль речи
Стиль речи относится к одной из двух категорий:

* Дикторская: чтение по сценарию
* Спонтанная: речь без сценария, разговорная речь

Аудио- и текстовые данные отражают стиль речи. Поскольку дикторский текст написан по сценарию, он, как правило, произносится внятно и без ошибок:

```
“Рассмотрим задачу обучения модели на наборе данных распознавания речи”
```

В то время как для спонтанной речи можно ожидать более разговорного стиля речи, с повторениями, запинаниями и других речевых сбоев:

```
“Let’s uhh let's take a look at how you'd go about training a model on uhm a sp- speech recognition dataset”
```

### 4. Стиль транскрипции
Стиль транскрипции относится к тому, есть ли в целевом тексте пунктуация, регистр или и то, и другое. Если мы хотим, чтобы система
генерировала полностью отформатированный текст, который можно было бы использовать для публикации или транскрипции собрания, нам нужны
обучающие данные с пунктуацией и регистром. Если нам просто нужны произносимые слова в неформатированной структуре, ни пунктуация,
ни регистр не нужны. В этом случае мы можем либо выбрать набор данных без знаков препинания и регистра, либо выбрать тот, в котором
есть знаки препинания и регистр, а затем впоследствии удалить их из целевого текста с помощью предварительной обработки.

## Сводная информация о наборах данных на Hugging Face Hub

Ниже приведен обзор наиболее популярных наборов данных для распознавания английской речи на Hugging Face Hub:

| Dataset                                                                                 | Train Hours | Domain                      | Speaking Style        | Casing | Punctuation | License         | Recommended Use                  |
|-----------------------------------------------------------------------------------------|-------------|-----------------------------|-----------------------|--------|-------------|-----------------|----------------------------------|
| [LibriSpeech](https://huggingface.co/datasets/librispeech_asr)                          | 960         | Audiobook                   | Narrated              | ❌      | ❌           | CC-BY-4.0       | Academic benchmarks              |
| [Common Voice 11](https://huggingface.co/datasets/mozilla-foundation/common_voice_11_0) | 3000        | Wikipedia                   | Narrated              | ✅      | ✅           | CC0-1.0         | Non-native speakers              |
| [VoxPopuli](https://huggingface.co/datasets/facebook/voxpopuli)                         | 540         | European Parliament         | Oratory               | ❌      | ✅           | CC0             | Non-native speakers              |
| [TED-LIUM](https://huggingface.co/datasets/LIUM/tedlium)                                | 450         | TED talks                   | Oratory               | ❌      | ❌           | CC-BY-NC-ND 3.0 | Technical topics                 |
| [GigaSpeech](https://huggingface.co/datasets/speechcolab/gigaspeech)                    | 10000       | Audiobook, podcast, YouTube | Narrated, spontaneous | ❌      | ✅           | apache-2.0      | Robustness over multiple domains |
| [SPGISpeech](https://huggingface.co/datasets/kensho/spgispeech)                         | 5000        | Financial meetings          | Oratory, spontaneous  | ✅      | ✅           | User Agreement  | Fully formatted transcriptions   |
| [Earnings-22](https://huggingface.co/datasets/revdotcom/earnings22)                     | 119         | Financial meetings          | Oratory, spontaneous  | ✅      | ✅           | CC-BY-SA-4.0    | Diversity of accents             |
| [AMI](https://huggingface.co/datasets/edinburghcstr/ami)                                | 100         | Meetings                    | Spontaneous           | ✅      | ✅           | CC-BY-4.0       | Noisy speech conditions          |

Эта таблица служит справочной информацией для выбора набора данных на основе вашего критерия. Ниже приведена эквивалентная таблица
для многоязычного распознавания речи. Обратите внимание, что мы опускаем столбец "Время обучения", поскольку оно зависит от языка для
каждого набора данных, и заменяем его на количество языков для каждого набора данных:

| Dataset                                                                                       | Languages | Domain                                | Speaking Style | Casing | Punctuation | License   | Recommended Usage       |
|-----------------------------------------------------------------------------------------------|-----------|---------------------------------------|----------------|--------|-------------|-----------|-------------------------|
| [Multilingual LibriSpeech](https://huggingface.co/datasets/facebook/multilingual_librispeech) | 6         | Audiobooks                            | Narrated       | ❌      | ❌           | CC-BY-4.0 | Academic benchmarks     |
| [Common Voice 13](https://huggingface.co/datasets/mozilla-foundation/common_voice_13_0)       | 108       | Wikipedia text & crowd-sourced speech | Narrated       | ✅      | ✅           | CC0-1.0   | Diverse speaker set     |
| [VoxPopuli](https://huggingface.co/datasets/facebook/voxpopuli)                               | 15        | European Parliament recordings        | Spontaneous    | ❌      | ✅           | CC0       | European languages      |
| [FLEURS](https://huggingface.co/datasets/google/fleurs)                                       | 101       | European Parliament recordings        | Spontaneous    | ❌      | ❌           | CC-BY-4.0 | Multilingual evaluation |

Подробную информацию о наборах аудиоданных, представленных в обеих таблицах, можно найти в блоге [Полное руководство по работе с наборами аудиоданных](https://huggingface.co/blog/audio-datasets#a-tour-of-audio-datasets-on-the-hub).
Хотя на Hugging Face Hub имеется более 180 наборов данных для распознавания речи, может оказаться, что среди них нет такого,
который соответствует вашим потребностям. Для создания пользовательского набора аудиоданных см. руководство [Создание набора аудиоданных](https://huggingface.co/docs/datasets/audio_dataset).
При создании пользовательского набора аудиоданных подумайте о том, чтобы опубликовать окончательный набор данных в Hugging Face Hub, чтобы
другие участники сообщества могли извлечь пользу из ваших усилий — сообщество аудио является обширно и многогранно, и другие оценят вашу
работу так же, как и вы.

Хорошо! Теперь, когда мы рассмотрели все критерии выбора набора данных ASR, давайте выберем один из них для целей данного руководства.
Мы знаем, что Whisper уже достаточно хорошо справляется с транскрибацией данных на ресурсоемких языках(таких как английский
и испанский), поэтому мы сосредоточимся на многоязычной транскрибации данных с низким уровнем ресурсов. Мы хотим сохранить способность Whisper
предсказывать знаки препинания и регистр, поэтому из второй таблицы видно, что Common Voice 13 является отличным набором данных!

## Common Voice 13

Common Voice 13 - это набор данных, созданный на основе краудсорсинга, в котором дикторы записывают текст из Википедии на разных языках.
Он является частью серии Common Voice - коллекции наборов данных Common Voice, выпускаемой Mozilla Foundation. На момент написания статьи
Common Voice 13 является последней редакцией набора данных, содержащей наибольшее количество языков и часов на один язык из всех выпущенных
на сегодняшний день.

Полный список языков для набора данных Common Voice 13 можно получить, заглянув на страницу набора данных на Hugging Face Hub:
[mozilla-foundation/common_voice_13_0](https://huggingface.co/datasets/mozilla-foundation/common_voice_13_0).
При первом просмотре этой страницы вам будет предложено принять условия использования. После этого вам будет предоставлен полный доступ к набору данных.

После того как мы выполнили аутентификацию для использования набора данных, нам будет представлен предварительный просмотр набора данных.
Предварительный просмотр набора данных показывает нам первые 100 образцов набора данных для каждого языка. Более того, в него загружены аудиообразцы,
которые мы можем прослушать в режиме реального времени. Для этого Раздела мы выберем [_Дивехи_](https://en.wikipedia.org/wiki/Maldivian_language)
или (_Мальдивский язык_), это индоарийский язык, на котором разговаривают в островном государстве Мальдивы, расположенном в Южной Азии. Хотя для данного
руководства мы выбрали Дивехи, описанные здесь шаги применимы к любому из 108 языков, входящих в набор данных Common Voice 13, и вообще к любому из 180
с лишним наборов аудиоданных на Hugging Face Hub, поэтому нет никаких ограничений по языку или диалекту.

Мы можем выбрать подмножество Дивехи в Common Voice 13, установив в выпадающем меню подмножество `dv` (`dv` - код идентификатора языка Dhivehi):

    

Если мы нажмем кнопку воспроизведения на первом примере, то сможем прослушать звук и увидеть соответствующий текст. Пролистайте примеры обучающего
и тестового наборов, чтобы лучше понять, с какими аудио- и текстовыми данными мы имеем дело. По интонации и стилю можно определить, что записи
сделаны с дикторской речи. Вы также, вероятно, заметите большой разброс между дикторами и качеством записи, что является общей чертой что является
общей чертой краудсорсинговых данных.

Предварительный просмотр данных - это отличный способ ознакомиться с наборами аудиоданных, прежде чем приступить к их использованию. Вы можете
выбрать любой набор данных в Hugging Face Hub, просмотреть образцы и прослушать аудио для различных подмножеств и разбиений, оценив, подходит
ли этот набор данных для ваших нужд. Выбрав набор данных, можно загрузить их и начать использовать.

Итак, я лично не владею Дивехи, и предполагаю, что подавляющее большинство читателей тоже! Чтобы узнать, насколько хороша наша
дообученная модель, нам потребуется строгий способ _оценить_ ее на невидимых данных и измерить достоверность транскрипции. Именно об этом
мы расскажем в следующем разделе!

### Evaluation metrics for ASR
https://huggingface.co/learn/audio-course/ru/chapter5/evaluation.md

# Evaluation metrics for ASR

Если вы знакомы с [расстоянием Левенштейна](https://en.wikipedia.org/wiki/Levenshtein_distance) из NLP то метрики для оценки
систем распознавания речи будут вам знакомы! Не волнуйтесь, если нет, мы рассмотрим объяснения от начала до конца, чтобы
убедиться, что вы знаете различные метрики и понимаете, что они означают.

При оценке систем распознавания речи мы сравниваем предсказания системы с транскрипцией целевого текста, аннотируя все имеющиеся ошибки.
Мы относим эти ошибки к одной из трех категорий:
1. Замены (S - от англ. "Substitutions"): когда мы транскрибируем **неправильное слово** в нашем предсказании ("sit" вместо "sat")
2. Вставки (I - от англ. "Insertions"): когда мы добавляем **дополнительное слово** в наше предсказание
3. Удаления (D - от англ. "Deletions"): когда мы **удаляем слово** в нашем предсказании

Эти категории ошибок одинаковы для всех метрик распознавания речи. Различается лишь уровень, на котором мы вычисляем эти ошибки: мы
можем вычислять их либо на уровне _слова_, либо на уровне _символа_.

Для каждого из определений метрики мы будем использовать свой пример. Ниже мы видим _истину_ или _эталонную_ (_reference_) текстовую последовательность:

```python
reference = "the cat sat on the mat"
```

И предсказанную последовательность от системы распознавания речи, которую мы пытаемся оценить:

```python
prediction = "the cat sit on the"
```

Видно, что предсказание довольно близко, но некоторые слова не совсем верны. Оценим это предсказание в сравнении с эталоном для трех
наиболее популярных метрик распознавания речи и посмотрим, какие цифры мы получим для каждой из них.

## Частота ошибок в словах (Word Error Rate)
Метрика *word error rate (WER)* является "фактической" метрикой для распознавания речи. Она рассчитывает замены, вставки и удаления
на *уровне слова*. Это означает, что ошибки аннотируются на уровне каждого слова. Возьмем наш пример:

| Эталон:     | the | cat | sat     | on  | the | mat |
|-------------|-----|-----|---------|-----|-----|-----|
| Предсказание: | the | cat | **sit** | on  | the |     |  |
| Метка:      | ✅   | ✅   | S       | ✅   | ✅   | D   |

Здесь:
* 1 замена (S) ("sit" вместо "sat")
* 0 вставок
* 1 удаление (D) ("mat" отсутствует)

Это дает 2 ошибки в сумме. Чтобы получить коэффициент ошибок, разделим количество ошибок на общее количество слов в эталонной
последовательности (N), которое для данного примера равно 6:

$$
\begin{aligned}
WER &= \frac{S + I + D}{N} \\
&= \frac{1 + 0 + 1}{6} \\
&= 0.333
\end{aligned}
$$

Отлично! Итак, WER равен 0,333, или 33,3%. Обратите внимание, что в слове "sit" ошибочным является только один символ,
но все слово помечено как неправильное. Это является отличительной особенностью WER: орфографические ошибки сильно штрафуются,
какими бы незначительными они ни были.

WER определяется так: чем меньше WER, тем меньше ошибок в прогнозе, поэтому для идеальной системы распознавания речи WER
был бы равен нулю (отсутствие ошибок).

Рассмотрим, как можно вычислить WER с помощью 🤗 Evaluate. Для вычисления метрики WER нам понадобятся два пакета: 🤗 Evaluate
для интерфейса API и JIWER для выполнения тяжелой работы по вычислению:
```
pip install --upgrade evaluate jiwer
```

Отлично! Теперь мы можем загрузить метрику WER и вычислить показатель для нашего примера:

```python
from evaluate import load

wer_metric = load("wer")

wer = wer_metric.compute(references=[reference], predictions=[prediction])

print(wer)
```
**Print Output:**
```
0.3333333333333333
```

0,33, или 33,3%, как и ожидалось! Теперь мы знаем, как именно производится расчет WER.

А теперь кое-что, что сбивает с толку... Как Вы думаете, какова верхняя граница WER? Вы ожидаете, что он будет равен 1 или
100%, верно? Так как WER - это отношение количества ошибок к количеству слов (N), то верхнего предела для WER не существует!
Возьмем пример, когда мы предсказали 10 слов, а у целевой фразы только 2 слова. Если бы все наши прогнозы оказались неверными
(10 ошибок), то WER был бы равен 10 / 2 = 5, или 500%! Об этом следует помнить, если вы обучаете ASR-систему и видите, что WER
превышает 100%. Хотя если вы видите это, то, скорее всего, что-то пошло не так... 😅

## Точность слов (Word Accuracy)

Мы можем перевернуть WER, чтобы получить метрику, в которой *больше - лучше*. Вместо того чтобы измерять частоту ошибок в словах,
мы можем измерить *точность слов (WAcc)* нашей системы:

$$
\begin{equation}
WAcc = 1 - WER \nonumber
\end{equation}
$$

WAcc также измеряется на уровне слов, просто WER представлен (сформулирован) как метрика точности, а не метрика ошибки. WAcc очень редко
встречается в речевой литературе - мы рассматриваем предсказания нашей системы в терминах ошибок в словах, и поэтому предпочитаем метрики
ошибок, которые больше ассоциируются с этими ошибками.

## Частота ошибок в символах (Character Error Rate)

Кажется немного несправедливым, что мы пометили все слово "sit" ошибочным, когда на самом деле неправильной была только одна буква.
Это объясняется тем, что мы оценивали нашу систему на уровне слов, тем самым аннотируя ошибки пословно (word-by-word). Показатель *частота ошибок
в символах (CER)* оценивает системы на *символьном уровне*. Это означает, что мы разбиваем слова на отдельные символы и аннотируем ошибки по каждому
символу:

| Эталон:     | t   | h   | e   |     | c   | a   | t   |     | s   | a     | t   |     | o   | n   |     | t   | h   | e   |     | m   | a   | t   |
|-------------|-----|-----|-----|-----|-----|-----|-----|-----|-----|-------|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|
| Предсказание: | t   | h   | e   |     | c   | a   | t   |     | s   | **i** | t   |     | o   | n   |     | t   | h   | e   |     |     |     |     |
| Метка:      | ✅   | ✅   | ✅   |     | ✅   | ✅   | ✅   |     | ✅   | S     | ✅   |     | ✅   | ✅   |     | ✅   | ✅   | ✅   |     | D   | D   | D   |

Теперь мы видим, что в слове "sit" буквы "s" и "t" отмечены как правильные. И только "i" помечается как ошибка замены символа (S). Таким
образом, мы вознаграждаем нашу систему за частично верное предсказание 🤝.

В нашем примере мы имеем 1 замену символов, 0 вставок и 3 удаления. Всего у нас 14 символов. Таким образом, наш CER имеет вид:

$$
\begin{aligned}
CER &= \frac{S + I + D}{N} \\
&= \frac{1 + 0 + 3}{14} \\
&= 0.286
\end{aligned}
$$

Отлично! Мы получили CER, равный 0,286, или 28,6%. Обратите внимание, что это меньше, чем WER - мы гораздо меньше наказывали
за орфографическую ошибку.

## Какую метрику следует использовать?

В целом для оценки речевых систем WER используется гораздо чаще, чем CER. Это объясняется тем, что WER требует от систем более
глубокого понимания контекста прогнозов. В нашем примере слово "sit" находится в неправильном времени. Система, понимающая связь
между глаголом и временем, в котором употребляется слово, предсказала бы правильное время глагола "sat". Мы хотим поощрять такой
уровень понимания со стороны наших речевых систем. Таким образом, хотя WER менее щадящим, чем CER, он также более благоприятен
для тех видов разборчивых систем, которые мы хотим разработать. Поэтому мы обычно используем WER и рекомендуем вам это делать!
Однако существуют обстоятельства, при которых использование WER невозможно. В некоторых языках, таких как мандаринский (севернокитайский
язык) и японский, понятие "слова" отсутствует, и поэтому WER не имеет смысла. Здесь мы возвращаемся к использованию CER.

В нашем примере при расчете WER мы использовали только одно предложение. При оценке реальной системы мы обычно используем целый
тестовый набор, состоящий из нескольких тысяч предложений. При оценке по нескольким предложениям мы суммируем S, I, D и N по всем
предложениям, а затем вычисляем WER в соответствии с формулой, приведенной выше. Это дает более точную оценку WER для данных,
которые не были использованы ранее.

## Нормализация

Если мы обучим модель ASR на данных с пунктуацией и регистром букв, она научится предсказывать регистр и пунктуацию в своих транскрипциях.
Это отлично работает, когда нам нужно использовать нашу модель для реальных приложений распознавания речи, таких как транскрибирование
совещаний или диктовка, поскольку предсказанные транскрипции будут полностью отформатированы с учетом регистра и пунктуации, стиля,
называемого *орфографическим*.

Однако у нас также есть возможность *нормализовать* набор данных, чтобы убрать регистр и пунктуацию. Нормализация набора данных делает задачу
распознавания речи проще: модели больше не нужно различать символы верхнего и нижнего регистра или предсказывать пунктуацию только на основе
аудиоданных (например, какой звук издает точка с запятой?). Из-за этого показатели ошибки слов снижаются естественным образом (что означает,
что результаты лучше). В статье о модели Whisper продемонстрировано радикальное воздействие нормализации транскрипций на результаты WER
(см. раздел 4.4 в [статье Whisper](https://cdn.openai.com/papers/whisper.pdf)). Несмотря на более низкие показатели WER, модель не обязательно
становится лучше для промышленного использования. Отсутствие регистра и пунктуации делает предсказанный текст от модели значительно труднее
для чтения. Возьмем пример из [предыдущего раздела](asr_models), где мы применили модели Wav2Vec2 и Whisper к одному и тому же аудиофрагменту
из набора данных LibriSpeech. Модель Wav2Vec2 не предсказывает ни пунктуацию, ни регистр, в то время как Whisper предсказывает оба эти элемента.
Сравнив транскрипции рядом, мы видим, что транскрипция Whisper гораздо проще для чтения:

```
Wav2Vec2:  HE TELLS US THAT AT THIS FESTIVE SEASON OF THE YEAR WITH CHRISTMAUS AND ROSE BEEF LOOMING BEFORE US SIMALYIS DRAWN FROM EATING AND ITS RESULTS OCCUR MOST READILY TO THE MIND
Whisper:   He tells us that at this festive season of the year, with Christmas and roast beef looming before us, similarly is drawn from eating and its results occur most readily to the mind.
```

Транскрипция Whisper с соблюдением орфографии и, следовательно, готова к использованию - она отформатирована так, как мы ожидаем для транскрипции совещания
или диктовки, с пунктуацией и регистром букв. Напротив, для восстановления пунктуации и регистра в наших предсказаниях Wav2Vec2 нам потребуется
дополнительная постобработка, если мы хотим использовать их в дальнейшем при разработке приложений.

Существует золотая середина между нормализацией и отсутствием нормализации: мы можем обучать наши системы на орфографических транскрипциях,
а затем нормализовать предсказания и целевые метки перед вычислением WER. Таким образом, мы обучаем наши системы предсказывать полностью
отформатированный текст, но также получаем выгоду от улучшений WER, которые мы получаем, нормализуя транскрипции.

Модель Whisper была выпущена с нормализатором, который эффективно обрабатывает нормализацию регистра, пунктуации и форматирования чисел, среди
прочего. Давайте применим нормализатор к транскрипциям Whisper, чтобы продемонстрировать, как мы можем их нормализовать:

```python
from transformers.models.whisper.english_normalizer import BasicTextNormalizer

normalizer = BasicTextNormalizer()

prediction = " He tells us that at this festive season of the year, with Christmas and roast beef looming before us, similarly is drawn from eating and its results occur most readily to the mind."
normalized_prediction = normalizer(prediction)

normalized_prediction
```
**Output:**
```
' he tells us that at this festive season of the year with christmas and roast beef looming before us similarly is drawn from eating and its results occur most readily to the mind '
```

Отлично! Мы видим, что текст был полностью приведен к нижнему регистру и удалена вся пунктуация. Теперь давайте определим эталонную транскрипцию
и затем вычислим нормализованный WER между эталоном и предсказанием:

```python
reference = "HE TELLS US THAT AT THIS FESTIVE SEASON OF THE YEAR WITH CHRISTMAS AND ROAST BEEF LOOMING BEFORE US SIMILES DRAWN FROM EATING AND ITS RESULTS OCCUR MOST READILY TO THE MIND"
normalized_referece = normalizer(reference)

wer = wer_metric.compute(
    references=[normalized_referece], predictions=[normalized_prediction]
)
wer
```
**Output:**
```
0.0625
```

6,25% - это примерно то, что мы ожидаем для базовой модели Whisper на наборе данных LibriSpeech для валидационной выборки. Как мы видим здесь, мы
предсказали орфографическую транскрипцию, но в то же время получили улучшение WER, полученное благодаря нормализации эталона и предсказания
перед вычислением WER.

Выбор способа нормализации транскрипций в конечном итоге зависит от ваших потребностей. Мы рекомендуем обучать модель на орфографическом тексте
и оценивать на нормализованном тексте, чтобы получить лучшее из обоих приемов.

### Собираем все воедино

Хорошо! Мы рассмотрели три темы в этом разделе: предварительно обученные модели, выбор набора данных и оценку. Давайте весело проведем время и
объединим их в одном примере end-to-end 🚀 Мы будем готовиться к следующему разделу по настройке модели путем оценки предварительно обученной
модели Whisper на тестовом наборе данных Common Voice 13 на Дивехи. Мы используем полученное число WER как _baseline_ для нашего процесса дообучения
или как целевое значение, которое мы постараемся превзойти 🥊.

Сначала мы загрузим предварительно обученную модель Whisper с помощью `pipeline()`. Этот процесс вам уже должен быть крайне знаком!
Единственное новое, что мы сделаем - это загрузим модель с использованием половинной точности (float16), если запускаем на GPU.
Это ускорит вывод, почти не влияя на точность WER.

```python
from transformers import pipeline
import torch

if torch.cuda.is_available():
    device = "cuda:0"
    torch_dtype = torch.float16
else:
    device = "cpu"
    torch_dtype = torch.float32

pipe = pipeline(
    "automatic-speech-recognition",
    model="openai/whisper-small",
    torch_dtype=torch_dtype,
    device=device,
)
```

Затем мы загрузим тестовую часть Дивехи из набора данных Common Voice 13. Вы помните из предыдущего раздела, что Common Voice 13 является
ограниченным, что означает, что мы должны согласиться с условиями использования набора данных, прежде чем получить доступ к нему. Теперь
мы можем связать нашу учетную запись Hugging Face с нашим блокнотом, чтобы получить доступ к набору данных с машины, которую мы сейчас используем.

Связать блокнот с Hugging Face Hub очень просто - это требует ввода вашего токена аутентификации, когда вас попросят. Найдите ваш токен аутентификации
Hugging Face Hub [здесь](https://huggingface.co/settings/tokens) и введите его, когда вас попросят:

```python
from huggingface_hub import notebook_login

notebook_login()
```

Отлично! После того как мы свяжем блокнот с нашей учетной записью Hugging Face, мы можем продолжить с загрузкой набора данных Common Voice.
Это займет несколько минут на загрузку и предварительную обработку, данные будут получены с Hub Hugging Face и подготовлены автоматически
в вашем блокноте:

```python
from datasets import load_dataset

common_voice_test = load_dataset(
    "mozilla-foundation/common_voice_13_0", "dv", split="test"
)
```

    Если вы столкнетесь с проблемой аутентификации при загрузке набора данных, убедитесь, что вы приняли условия использования набора данных на
    Hub Hugging Face по следующей ссылке: https://huggingface.co/datasets/mozilla-foundation/common_voice_13_0

Оценка по всему набору данных может быть выполнена так же, как и для одного примера - все, что нам нужно сделать, это **циклически** пройти по
входным аудиофайлам, вместо вывода только одного образца. Для этого мы сначала преобразуем наш набор данных в `KeyDataset`. При этом выбирается
определенный столбец набора данных, который мы хотим передать модели (в нашем случае это столбец `"audio"`), игнорируя остальные (например,
целевые транскрипции, которые мы не хотим использовать для вывода). Затем мы перебираем этот преобразованный набор данных, добавляя выходы
модели в список для сохранения предсказаний. Этот блок кода будет выполняться около пяти минут при использовании GPU с половинной точностью
и максимальной памятью 12 ГБ:

```python
from tqdm import tqdm
from transformers.pipelines.pt_utils import KeyDataset

all_predictions = []

# run streamed inference
for prediction in tqdm(
    pipe(
        KeyDataset(common_voice_test, "audio"),
        max_new_tokens=128,
        generate_kwargs={"task": "transcribe"},
        batch_size=32,
    ),
    total=len(common_voice_test),
):
    all_predictions.append(prediction["text"])
```

    Если вы столкнетесь с ошибкой "Out-of-Memory" (OOM) CUDA при выполнении вышеуказанной ячейки, уменьшайте размер пакета (`batch_size`)
    последовательно вдвое, пока не найдете такой размер пакета, который подходит для вашего устройства.

И, наконец, мы можем вычислить WER. Давайте сначала вычислим орфографический WER, то есть WER без какой-либо дополнительной обработки:

```python
from evaluate import load

wer_metric = load("wer")

wer_ortho = 100 * wer_metric.compute(
    references=common_voice_test["sentence"], predictions=all_predictions
)
wer_ortho
```
**Output:**
```
167.29577268612022
```

Ладно... 167% в основном означает, что наша модель выдает мусор 😜 Не беспокойтесь, нашей целью будет улучшить это путем настройки
модели на обучающем выборке Дивехи!

Затем мы оценим нормализованный WER, то есть WER с постобработкой в части нормализации. Нам придется исключить выборки, которые были бы пустыми
после нормализации, так как в противном случае общее количество слов в нашем эталоне (N) будет равно нулю, что вызовет ошибку деления на ноль в
нашем вычислении:

```python
from transformers.models.whisper.english_normalizer import BasicTextNormalizer

normalizer = BasicTextNormalizer()

# compute normalised WER
all_predictions_norm = [normalizer(pred) for pred in all_predictions]
all_references_norm = [normalizer(label) for label in common_voice_test["sentence"]]

# filtering step to only evaluate the samples that correspond to non-zero references
all_predictions_norm = [
    all_predictions_norm[i]
    for i in range(len(all_predictions_norm))
    if len(all_references_norm[i]) > 0
]
all_references_norm = [
    all_references_norm[i]
    for i in range(len(all_references_norm))
    if len(all_references_norm[i]) > 0
]

wer = 100 * wer_metric.compute(
    references=all_references_norm, predictions=all_predictions_norm
)

wer
```
**Output:**
```
125.69809089960707
```

Снова мы видим резкое снижение WER при нормализации наших эталонов и предсказаний: базовая модель достигает орфографического
тестового WER 168%, в то время как нормализованный WER составляет 126%.

Итак, именно эти показатели мы хотим превзойти, когда будем дообучать модель, чтобы улучшить модель Whisper для распознавания речи для Дивехи.
Продолжайте чтение, чтобы получить практический опыт с примером дообучения модели 🚀.

### Подготовьтесь к прохождению курса
https://huggingface.co/learn/audio-course/ru/chapter0/get_ready.md

# Подготовьтесь к прохождению курса

Мы надеемся, что вам не терпится приступить к изучению курса, и мы создали эту страницу, чтобы у вас было
все необходимое для того, чтобы вы могли сразу же приступить к работе!

## Шаг 1. Зарегистрируйтесь

Чтобы быть в курсе всех обновлений и специальных социальных мероприятий, подпишитесь на курс.

[👉 ПОДПИСАТЬСЯ](http://eepurl.com/insvcI)

##  Шаг 2. Получите учетную запись Hugging Face

Если у вас ее еще нет, создайте учетную запись Hugging Face (это бесплатно). Она понадобится вам для выполнения практических заданий, для 
получения сертификата о прохождении курса, для изучения предварительно обученных моделей, для доступа к наборам данных и многого другого.

[👉 СОЗДАТЬ АККАУНТ HUGGING FACE](https://huggingface.co/join)

## Шаг 3. Освежите в памяти основы (если это необходимо)

Мы предполагаем, что вы знакомы с основами глубокого обучения и имеете общее представление о трансформерах. Если вам необходимо
подтянуть свои знания о трансформерах, обратитесь к нашему [курсу по NLP](https://huggingface.co/course/chapter1/1).

## Шаг 4. Проверьте ваши настройки

Для изучения материалов курса вам понадобятся:
- Компьютер с подключением к Интернет
- [Google Colab](https://colab.research.google.com) для практических занятий. Достаточно бесплатной версии.

Если вы еще никогда не использовали Google Colab, ознакомьтесь с этим [официальным ознакомительным блокнотом](https://colab.research.google.com/notebooks/intro.ipynb).

## Шаг 5. Присоединяйтесь к сообществу

Зарегистрируйтесь на нашем сервере Discord - месте, где вы можете обмениваться идеями с однокурсниками и обращаться к нам (команде Hugging Face).

[👉 ПРИСОЕДИНЯЙТЕСЬ К СООБЩЕСТВУ В DISCORD](http://hf.co/join/discord)

Чтобы узнать больше о нашем сообществе в Discord и о том, как извлечь из него максимум пользы, посетите [следующую страницу](community).

### Добро пожаловать на аудиокурс Hugging Face!
https://huggingface.co/learn/audio-course/ru/chapter0/introduction.md

# Добро пожаловать на аудиокурс Hugging Face!

Уважаемый слушатель,

Добро пожаловать на курс по использованию трансформеров в аудио. Трансформеры снова и снова доказывают, что они являются одной из
наиболее мощных и универсальных архитектур глубокого обучения, способных достигать передовых результатов в широком спектре
задач, включая обработку естественного языка, компьютерное зрение, а с недавних пор и аудио.

В этом курсе мы рассмотрим, как трансформеры могут быть применены к аудиоданным. Вы узнаете, как использовать их для решения
ряда задач, связанных с аудио. Если вас интересует распознавание речи, классификация аудиоданных или генерация речи
из текста, трансформеры и данный курс помогут вам в этом.

Чтобы вы могли оценить возможности этих моделей, произнесите несколько слов в демонстрации ниже и посмотрите, как модель транскрибирует их в режиме реального времени!

В ходе курса вы получите представление о специфике работы с аудиоданными, узнаете о различных 
архитектурах трансформеров, а также обучите свои собственные аудио трансформеры, используя мощные предварительно обученные модели.

Этот курс рассчитан на слушателей, имеющих опыт глубокого обучения и общее представление о трансформерах.
Знаний в области обработки аудиоданных не требуется. Если вам нужно подтянуть свое понимание трансформеров, ознакомьтесь с
нашим [курсом по NLP](https://huggingface.co/course/chapter1/1), в котором очень подробно рассматриваются основы трансформеров.

## Знакомство с командой курса

**Санчит Ганди, инженер-исследователь в области машинного обучения в Hugging Face**

Привет! Меня зовут Санчит, и я работаю инженером-исследователем в области машинного обучения звука в Open Source команде компании Hugging Face 🤗.
Основным направлением моей работы является автоматическое распознавание речи и перевод, а текущей целью - сделать речевые модели более быстрыми,
более легкими и простыми в использовании.

**Маттиджс Холлеманс, инженер по машинному обучению в Hugging Face**

Меня зовут Маттиджс, я работаю инженером по машинному обучению аудио в команде Hugging Face с открытым исходным кодом. Я также являюсь автором
книги о том, как писать звуковые синтезаторы, а в свободное время создаю аудиоплагины.

**Мария Халусова, отдел документации и курсов в Hugging Face**

Меня зовут Мария, и я создаю образовательный контент и документацию, чтобы сделать библиотеку Transformers и другие инструменты с открытым исходным кодом еще более
доступными. Я раскрываю сложные технические концепции и помогаю людям начать работу с передовыми технологиями.

**Вайбхав Шривастав, ML-разработчик, инженер по продвижению интересов разработчиков в компании Hugging Face**

Меня зовут Вайбхав и я являюсь инженером по продвижению интересов разработчиков в области аудио в Open Source команде компании Hugging Face. Я занимаюсь исследованиями
в области аудио с низким потреблением ресурсов и помогаю продвигать передовые исследования в области обработки речи в массы.

## Структура курса

Курс состоит из нескольких разделов, в которых подробно рассматриваются различные темы:

* [Раздел 1](https://huggingface.co/learn/audio-course/chapter1): охватывает специфику работы с аудиоданными, включая методы обработки аудиоданных и их подготовку.
* [Раздел 2](https://huggingface.co/learn/audio-course/chapter2): познакомит с аудиоприложениями и научит использовать конвейеры 🤗 Transformers для решения различных задач, таких как 
классификация аудио и распознавание речи.
* [Раздел 3](https://huggingface.co/learn/audio-course/chapter3): познакомит с архитектурами аудио трансформеров, расскажет, чем они отличаются и для каких задач лучше всего подходят.
* [Раздел 4](https://huggingface.co/learn/audio-course/chapter4): научит создавать собственный классификатор музыкальных жанров.
* [Раздел 5](https://huggingface.co/learn/audio-course/chapter5): углубится в распознавание речи и построение модель для расшифровки записей совещаний.
* [Раздел 6](https://huggingface.co/learn/audio-course/chapter6): научит генерировать речь из текста.
* [Раздел 7](https://huggingface.co/learn/audio-course/chapter7): научит создавать реальные аудиоприложения с использованием трансформеров.

Каждый раздел включает в себя теоретическую часть, где вы получите глубокое понимание основных концепций и методов.
На протяжении всего курса мы предлагаем тестовые задания, которые помогут вам проверить свои знания и закрепить полученные навыки.
Некоторые главы также включают практические упражнения, где вы сможете применить полученные знания.

К концу курса вы получите прочную базу в области использования трансформеров для аудиоданных и будете 
хорошо подготовлены к применению этих методов для решения широкого круга задач, связанных с аудио.

Разделы курса будут выходить несколькими последовательными блоками со следующим графиком публикации:

| Раздел   | Дата публикации |
|---|-----------------|
| Раздел  0, Раздел 1, и Раздел 2  | 14 июня 2023   |
| Раздел  3, Раздел  4  | 21 июня 2023   |
| Раздел  5  | 28 июня 2023   |
| Раздел  6  | 5 июля 2023   |
| Раздел  7, Раздел  8  | 12 июля 2023   |

## Траектории обучения и сертификация

Не существует правильного или неправильного способа изучения этого курса. Все материалы данного курса являются 100% бесплатными, общедоступными и открытыми.
Вы можете изучать курс в удобном для вас темпе, однако мы рекомендуем проходить его по порядку.

Если вы хотите получить сертификат по окончании курса, мы предлагаем два варианта:

| Тип сертификата   | Требования                                                                                   |
|---|------------------------------------------------------------------------------------------------|
| Сертификат о прохождении обучения  | Выполнить 80% практических заданий в соответствии с инструкциями.    |
| Cертификат c отличием | Выполнить 100% практических заданий в соответствии с инструкциями. |

В каждом практическом упражнении указаны критерии его выполнения. Если вы выполнили достаточное количество практических упражнений, чтобы претендовать 
на получение сертификата, обратитесь к последнему разделу курса, чтобы узнать, как его получить. Удачи!

## Зарегистрироваться на курс

Разделы этого курса будут выходить постепенно в течение нескольких недель. Мы рекомендуем вам подписаться на обновления курса,
чтобы не пропустить появление новых разделов. Учащиеся, подписавшиеся на обновления курса,
также первыми узнают о специальных социальных мероприятиях, которые мы планируем проводить.

[Зарегистрироваться](http://eepurl.com/insvcI)

Наслаждайтесь курсом!

### Присоединяйтесь к сообществу!
https://huggingface.co/learn/audio-course/ru/chapter0/community.md

# Присоединяйтесь к сообществу!

Мы приглашаем вас [присоединиться к нашему активному и поддерживающему сообществу в Discord](http://hf.co/join/discord). У вас появится 
возможность общаться с единомышленниками, обмениваться идеями и получать ценные отзывы о своих практических занятиях. Вы сможете задавать вопросы,
делиться ресурсами и сотрудничать с другими.

Наша команда также активно работает в Discord и готова оказать поддержку и дать рекомендации, если они вам понадобятся.
Присоединяйтесь к нашему сообществу - это отличный способ поддерживать мотивацию, участие и связь, мы будем рады видеть 
вас там!

## Что такое Discord?

Discord - это бесплатная платформа для общения. Если вы пользовались Slack, то найдете его очень похожим. Сервер Hugging Face Discord 
является домом для процветающего сообщества из 18 000 экспертов, исследователей и энтузиастов ИИ, частью которого можете стать и вы.

## Навигация по Discord

После регистрации на нашем Discord-сервере вам нужно будет выбрать интересующие вас темы, нажав на кнопку `#role-assignment`
слева. Вы можете выбрать сколько угодно различных категорий. Чтобы присоединиться к другим слушателям этого курса, обязательно
нажмите "ML for Audio and Speech". 
Изучите каналы и расскажите немного о себе на канале `#introduce-yourself`.

## Каналы аудиокурса

На нашем сервере Discord существует множество каналов, посвященных различным темам. Здесь можно найти людей, обсуждающих статьи, организующих
мероприятия, делящихся своими проектами и идеями, проводящих мозговые штурмы и многое другое.

Для слушателей аудиокурсов особенно актуальным может оказаться следующий набор каналов:

* `#audio-announcements`: обновления курса, новости из Hugging Face, связанные со всем тем, что касается работы с аудио, анонсы мероприятий и многое другое.
* `#audio-study-group`: место, где можно обменяться идеями, задать вопросы по курсу и начать дискуссию.
* `#audio-discuss`: общее место для обсуждения вопросов, связанных с аудио.

Помимо присоединения к `#audio-study-group`, не стесняйтесь создавать свою собственную учебную группу - учиться вместе всегда легче!

### Живые занятия и семинары
https://huggingface.co/learn/audio-course/ru/events/introduction.md

# Живые занятия и семинары

Новый курс "Аудиотрансформеры": Прямой эфир с Пейдж Бейли (DeepMind), Сеохван Ким (Amazon Alexa AI) и Брайаном Макфи (Librosa)

Запись Live AMA с командой аудиокурса Hugging Face:

### Классификация звука с помощью конвейера
https://huggingface.co/learn/audio-course/ru/chapter2/audio_classification_pipeline.md

# Классификация звука с помощью конвейера

Классификация аудиозаписей предполагает присвоение одной или нескольких меток аудиозаписи в зависимости от ее содержания. 
Эти метки могут соответствовать различным категориям звуков, таким как музыка, речь, шум, или более специфическим категориям,
таким как пение птиц или звук автомобильного двигателя.

Прежде чем перейти к подробному описанию работы наиболее популярных аудиотрансформеров, а также к тонкой настройке пользовательской
модели, давайте посмотрим, как с помощью 🤗 Transformers можно использовать готовую предварительно обученную модель для классификации
аудиозаписи, набрав всего несколько строк кода.

Воспользуемся тем же набором данных [MINDS-14](https://huggingface.co/datasets/PolyAI/minds14), который вы исследовали в предыдущем разделе.
Если вы помните, MINDS-14 содержит записи людей, задающих вопросы системе дистанционного банковского обслуживания на нескольких языках и
диалектах, и для каждой записи имеет значение `intent_class`. Мы можем классифицировать записи по намерению звонящего.

Как и прежде, загрузим подмножество данных `en-AU`, чтобы опробовать конвейер, и повысим частоту дискретизации до 16 кГц, что и требуется
для большинства речевых моделей.

```py
from datasets import load_dataset
from datasets import Audio

minds = load_dataset("PolyAI/minds14", name="en-AU", split="train")
minds = minds.cast_column("audio", Audio(sampling_rate=16_000))
```

Для классификации аудиозаписи на множество классов мы можем использовать конвейер `audio-classification` из 🤗 Transformers.
В нашем случае нам нужна модель, настроенная на классификацию намерений, причем именно на наборе данных MINDS-14.
К счастью для нас, в Хабе есть модель, которая как раз для этого и предназначена! Давайте загрузим ее с помощью функции `pipeline()`:

```py
from transformers import pipeline

classifier = pipeline(
    "audio-classification",
    model="anton-l/xtreme_s_xlsr_300m_minds14",
)
```

Этот конвейер ожидает на вход аудиоданные в виде массива NumPy. Вся предварительная обработка исходных аудиоданных будет
удобно выполнена конвейером. Давайте рассмотрим пример, чтобы опробовать его в действии:

```py
example = minds[0]
```
Если вспомнить структуру набора данных, то исходные аудиоданные хранятся в массиве NumPy под именем `["audio"]["array"]`,
передадим их непосредственно в `classifier`.

```py
classifier(example["audio"]["array"])
```

**Output:**
```out
[
    {"score": 0.9631525278091431, "label": "pay_bill"},
    {"score": 0.02819698303937912, "label": "freeze"},
    {"score": 0.0032787492964416742, "label": "card_issues"},
    {"score": 0.0019414445850998163, "label": "abroad"},
    {"score": 0.0008378693601116538, "label": "high_value_payment"},
]
```

Модель очень уверена, что звонивший хотел узнать об оплате счета. Посмотрим, какова реальная метка для этого примера:

```py
id2label = minds.features["intent_class"].int2str
id2label(example["intent_class"])
```

Ура! Предсказанная метка оказалась верной! Здесь нам повезло найти модель, которая может классифицировать именно те метки,
которые нам нужны. В большинстве случаев при решении задачи классификации набор классов в предварительно обученной модели не совпадает
с теми классами, которые необходимо выделить с помощью модели. В этом случае можно произвести дообучение предварительно обученной
модели, чтобы "откалибровать" ее по точному набору меток классов. Как это сделать, мы узнаем в следующих разделах. Теперь рассмотрим
другую очень распространенную задачу обработки речи - _автоматическое распознавание речи_.

### Автоматическое распознавание речи с помощью конвейера
https://huggingface.co/learn/audio-course/ru/chapter2/asr_pipeline.md

# Автоматическое распознавание речи с помощью конвейера

Автоматическое распознавание речи (ASR от "Automatic Speech Recognition") - это задача транскрибации (преобразование аудиозаписи речи в текст).
Эта задача имеет множество практических применений - от создания субтитров для видео до обеспечения голосовых команд для таких виртуальных
помощников, как Siri и Alexa.

В этом разделе мы используем конвейер `automatic-speech-recognition` для транскрибации аудиозаписи человека, задающего вопрос об
оплате счета, используя тот же набор данных MINDS-14, что и ранее.

Для начала загрузите набор данных и повысьте его частоту до 16 кГц, как описано в [Классификация аудио с помощью конвейера](audio_classification_pipeline),
если вы еще не сделали этого.

Для транскрибации аудиозаписи мы можем использовать конвейер `automatic-speech-recognition` из 🤗 Transformers. Давайте инстанцируем конвейер:

```python
from transformers import pipeline

asr = pipeline("automatic-speech-recognition")
```

Далее мы возьмем пример из набора данных и передадим его исходные данные в конвейер:

```python
example = minds[0]
asr(example["audio"]["array"])
```

**Output:**
```out
{"text": "I WOULD LIKE TO PAY MY ELECTRICITY BILL USING MY COD CAN YOU PLEASE ASSIST"}
```

Сравним этот вывод с реальной транскрипцией для данного примера:

```python
example["english_transcription"]
```

**Output:**
```out
"I would like to pay my electricity bill using my card can you please assist"
```

Похоже, что модель неплохо справилась с транскрибацией аудиозаписи! По сравнению с оригинальной транскрипцией она ошиблась только в одном слове
("card"), что довольно хорошо, учитывая австралийский акцент диктора, в котором буква "r" часто не произносится. Тем не менее, я бы не рекомендовал
пытаться оплатить свой следующий счет за электричество рыбой (cod в переводе с английского - "треска")!

По умолчанию в этом конвейере используется модель, обученная автоматическому распознаванию речи для английского языка, что вполне подходит для
данного примера. Если вы хотите попробовать транскрибировать другие подмножества MINDS-14 на другом языке, вы можете найти предварительно
обученную ASR-модель [на 🤗 Hugging Face Hub](https://huggingface.co/models?pipeline_tag=automatic-speech-recognition&language=fr&sort=downloads).
Список моделей можно отфильтровать сначала по задаче, затем по языку. Найдя нужную модель, передайте ее имя в качестве аргумента `model` в конвейер.

Попробуем это сделать для немецкого сплита MINDS-14. Загрузим подмножество "de-DE":

```python
from datasets import load_dataset
from datasets import Audio

minds = load_dataset("PolyAI/minds14", name="de-DE", split="train")
minds = minds.cast_column("audio", Audio(sampling_rate=16_000))
```

Возьмите пример и посмотрите, какой должна быть транскрибация:

```python
example = minds[0]
example["transcription"]
```

**Output:**
```out
"ich möchte gerne Geld auf mein Konto einzahlen"
```

Найдите на 🤗 Hugging Face Hub предварительно обученную ASR-модель для немецкого языка, инстанцируйте конвейер и транскрибируйте пример:

```py
from transformers import pipeline

asr = pipeline("automatic-speech-recognition", model="maxidl/wav2vec2-large-xlsr-german")
asr(example["audio"]["array"])
```

**Output:**
```out
{"text": "ich möchte gerne geld auf mein konto einzallen"}
```

При работе над решением собственной задачи начать с простого конвейера, подобного тем, что мы показали в этом блоке,
это ценный инструмент, дающий ряд преимуществ:
- может существовать предварительно обученная модель, которая уже очень хорошо решает вашу задачу, экономя ваше время;
- pipeline() берет на себя всю предварительную и последующую обработку, так что вам не нужно беспокоиться о том, чтобы
привести данные в нужный формат для модели;
- если результат не идеален, это все равно дает возможность быстро получить baseline для последующего дообучения модели;
- после того как вы дообучите модель на своих пользовательских данных и разместите ее на Hugging Face Hub, все сообщество сможет
быстро и легко использовать ее с помощью метода `pipeline()`, делая ИИ более доступным.

### Практическое занятие
https://huggingface.co/learn/audio-course/ru/chapter2/hands_on.md

# Практическое занятие

Это упражнение не оценивается и предназначено для ознакомления с инструментами и библиотеками, которые вы будете использовать на протяжении всего курса.
Если вы уже имеете опыт работы с Google Colab, 🤗 Datasets, librosa и 🤗 Transformers, вы можете пропустить это упражнение.

1. Создайте блокнот [Google Colab](https://colab.research.google.com).
2. Используйте 🤗 Datasets для загрузки train split набора данных
[`facebook/voxpopuli`](https://huggingface.co/datasets/facebook/voxpopuli) на выбранном вами языке в потоковом режиме.
3. Получите третий пример из части `train` набора данных и исследуйте его. Учитывая особенности этого примера, для
решения каких аудиозадач можно использовать этот набор данных?
4. Постройте осциллограмму и спектрограмму этого примера.
5. Перейдите на сайт [🤗 Hugging Face Hub](https://huggingface.co/models), изучите предварительно обученные модели и найдите ту,
которая может быть использована для автоматического распознавания речи на выбранном ранее языке. Инстанцируйте соответствующий конвейер
с найденной моделью и транскрибируйте пример.

Если вы затрудняетесь с выполнением этого упражнения, не стесняйтесь заглянуть в [пример решения](https://colab.research.google.com/drive/1NGyo5wFpRj8TMfZOIuPaJHqyyXCITftc?usp=sharing).
Открыли для себя что-то интересное? Нашли классную модель? Получили красивую спектрограмму? Не стесняйтесь делиться своими работами и открытиями в Twitter!

В следующих главах вы узнаете больше о различных архитектурах аудиотрансформеров и создадите свою собственную модель!

### Раздел 2. Краткое введение в аудиоприложения
https://huggingface.co/learn/audio-course/ru/chapter2/introduction.md

# Раздел 2. Краткое введение в аудиоприложения

Добро пожаловать во второй раздел аудиокурса от Hugging Face! Ранее мы рассмотрели основы аудиоданных
и научились работать с наборами аудиоданных с помощью библиотек 🤗 Datasets и 🤗 Transformers. Мы обсудили различные
понятия, такие как частота дискретизации, амплитуда, битовая глубина, форма волны и спектрограммы, а также рассмотрели
способы предварительной обработки данных для подготовки их к использованию в предварительно обученной модели.

К этому моменту вы, возможно, уже хотите узнать о том, с какими аудиозадачами могут справиться 🤗 Transformers, и
у вас есть все необходимые базовые знания, необходимые для дальнейшего погружения! Давайте рассмотрим некоторые из
примеров умопомрачительных аудиозадач:

* **Аудио классификация**: простая классификация аудиоклипов по различным категориям. Вы можете определить, лает ли
на записи собака или мяукает кошка, или к какому музыкальному жанру относится та или иная композиция.
* **Автоматическое распознавание речи**: преобразование аудиоклипов в текст путем их автоматической транскрибации.
Вы можете получить текстовое представление записи разговора, например, "Как дела?". Очень полезно для ведения заметок!
* **Диаризация диктора**: Вы когда-нибудь задумывались, кто говорит в записи? С помощью 🤗 Transformers вы сможете определить,
кто из дикторов говорит в тот или иной момент времени в аудиоклипе. Представьте себе, что вы можете различить Алису и Боба
в записи их разговора.
* **Перевод текста в речь**: создать дикторскую версию текста, которая может быть использована для создания аудиокниги,
помочь в обеспечении доступности (для людей с ограниченными возможностями) или дать голос NPC в игре. С 🤗 Transformers
вы легко сможете это сделать!

В этом разделе вы узнаете, как использовать предварительно обученные модели для решения некоторых из этих задач с помощью
функции `pipeline()` из 🤗 Transformers. В частности, мы увидим, как предварительно обученные модели могут быть использованы
для классификации звука и автоматического распознавания речи.
Давайте начнем!

### Дообучение SpeechT5
https://huggingface.co/learn/audio-course/ru/chapter6/fine-tuning.md

# Дообучение SpeechT5

Теперь, когда вы знакомы с задачей преобразования текста в речь и внутренним устройством модели SpeechT5, которая была предварительно обучена
на англоязычных данных, давайте посмотрим, как мы можем дообучить ее для другого языка. 

## House-keeping

Если вы хотите воспроизвести этот пример, убедитесь, что у вас есть графический процессор. В блокноте это можно проверить с помощью следующей команды:

```bash
nvidia-smi
```

В нашем примере мы будем использовать около 40 часов обучающих данных. Если вы хотите повторить этот процесс, используя бесплатный тарифный план Google Colab,
необходимо уменьшить объем обучающих данных примерно до 10-15 часов и сократить количество шагов обучения.

Вам также понадобятся некоторые дополнительные зависимости:  

```bash
pip install transformers datasets soundfile speechbrain accelerate
```

Наконец, не забудьте войти в свою учетную запись Hugging Face, чтобы загрузить свою модель и поделиться ею с сообществом:

```py
from huggingface_hub import notebook_login

notebook_login()
```

## Набор данных

В данном примере мы возьмем подмножество голландского (`nl`) языка из датасета [VoxPopuli](https://huggingface.co/datasets/qmeeus/voxpopuli).
[VoxPopuli](https://huggingface.co/datasets/qmeeus/voxpopuli) - это обширный многоязычный речевой корпус, состоящий из данных,
полученных из записей мероприятий Европейского парламента 2009-2020 гг. Он содержит маркированные данные аудио-транскрипций для 15 европейских языков.
Хотя мы будем использовать подмножество голландского языка, вы можете выбрать другое подмножество.
 
Это набор данных автоматического распознавания речи (ASR), поэтому, как уже говорилось, он не является наиболее подходящим
вариантом для обучения TTS-моделей. Однако для данного упражнения этого будет вполне достаточно.

Давайте загрузим данные:

```python
from datasets import load_dataset, Audio

dataset = load_dataset("qmeeus/voxpopuli", "nl", split="train")
len(dataset)
```

**Output:**
```out
20968
```

20968 примеров должно быть достаточно для дообучения. Для SpeechT5 требуется, чтобы частота дискретизации аудиоданных составляла 16 кГц, поэтому
убедимся, что примеры в наборе данных соответствуют этому требованию:

```python
dataset = dataset.cast_column("audio", Audio(sampling_rate=16000))
```

## Препроцессинг данных 

Начнем с определения используемой контрольной точки модели и загрузки соответствующего процессора, содержащего как токенизатор,
так и экстрактор признаков, которые понадобятся нам для подготовки данных к обучению: 

```py
from transformers import SpeechT5Processor

checkpoint = "microsoft/speecht5_tts"
processor = SpeechT5Processor.from_pretrained(checkpoint)
```

### Очистка текста для токенизации SpeechT5

Во-первых, для подготовки текста нам понадобится часть процессора - токенизатор, поэтому возьмем его:

```py
tokenizer = processor.tokenizer
```

Рассмотрим пример:

```python
dataset[0]
```

**Output:**
```out
{'audio_id': '20100210-0900-PLENARY-3-nl_20100210-09:06:43_4',
 'language': 9,
 'audio': {'path': '/root/.cache/huggingface/datasets/downloads/extracted/02ec6a19d5b97c03e1379250378454dbf3fa2972943504a91c7da5045aa26a89/train_part_0/20100210-0900-PLENARY-3-nl_20100210-09:06:43_4.wav',
  'array': array([ 4.27246094e-04,  1.31225586e-03,  1.03759766e-03, ...,
         -9.15527344e-05,  7.62939453e-04, -2.44140625e-04]),
  'sampling_rate': 16000},
 'text': 'dat kan naar mijn gevoel alleen met een brede meerderheid die wij samen zoeken.',
 'gender': 'female',
 'speaker_id': '1122',
 'is_gold_transcript': True,
 'accent': 'None'}
```

Примеры из датасета содержат признак `text`, который мы будем использовать в качестве входного текста. Важно знать, 
что в токенизаторе SpeechT5 нет токенов для чисел, поэтому если ваш текст содержит числа, возможно, их придется записать в виде текста.

Поскольку SpeechT5 обучалась на английском языке, она может не распознать некоторые символы в голландском наборе данных. Если
оставить все как есть, то эти символы будут преобразованы в токены ``. Однако в голландском языке некоторые символы, например `à`, используются
для выделения слогов. Чтобы сохранить смысл текста, можно заменить этот символ на обычное `a`.

Чтобы выявить неподдерживаемые токены, извлечем все уникальные символы из датасета с помощью `SpeechT5Tokenizer`, который
работает с символами как с токенами. Для этого напишем функцию отображения `extract_all_chars`, которая объединяет
транскрипции из всех примеров в одну строку и преобразует ее в набор символов. [NL] 
Обязательно задайте `batched=True` и `batch_size=-1` в `dataset.map()`, чтобы все транскрипции были доступны сразу для
функции отображения.

```py
def extract_all_chars(batch):
    all_text = " ".join(batch["text"])
    vocab = list(set(all_text))
    return {"vocab": [vocab], "all_text": [all_text]}

vocabs = dataset.map(
    extract_all_chars,
    batched=True,
    batch_size=-1,
    keep_in_memory=True,
    remove_columns=dataset.column_names,
)

dataset_vocab = set(vocabs["vocab"][0])
tokenizer_vocab = {k for k, _ in tokenizer.get_vocab().items()}
```

Теперь у вас есть два набора символов: один со словарем из датасета, другой - со словарем из токенизатора.
Для выявления неподдерживаемых символов в наборе данных можно взять разность между этими двумя наборами. Полученный набор
будет содержать символы, которые есть в наборе данных, но отсутствуют в токенизаторе.

```py
dataset_vocab - tokenizer_vocab
```

**Output:**
```out
{' ', 'à', 'ç', 'è', 'ë', 'í', 'ï', 'ö', 'ü'}
```

Для работы с неподдерживаемыми символами, выявленными на предыдущем этапе, можно определить функцию, которая сопоставляет эти символы с допустимыми токенами.
Заметим, что пробелы уже заменены на `▁` в токенизаторе и не нуждаются в отдельной обработке.

```py
replacements = [
    ("à", "a"),
    ("ç", "c"),
    ("è", "e"),
    ("ë", "e"),
    ("í", "i"),
    ("ï", "i"),
    ("ö", "o"),
    ("ü", "u"),
]

def cleanup_text(inputs):
    for src, dst in replacements:
        inputs["text"] = inputs["text"].replace(src, dst)
    return inputs

dataset = dataset.map(cleanup_text)
```

Теперь, когда мы разобрались со специальными символами в тексте, пришло время переключить внимание на аудио данные.

### Дикторы

Набор данных VoxPopuli включает речь нескольких дикторов, но сколько дикторов представлено в наборе? Чтобы
определить это, мы можем подсчитать количество уникальных дикторов и количество примеров, которые каждый диктор вносит в набор данных.
Учитывая, что всего в наборе данных 20 968 примеров, эта информация позволит нам лучше понять распределение
дикторов и примеров в данных.

```py
from collections import defaultdict

speaker_counts = defaultdict(int)

for speaker_id in dataset["speaker_id"]:
    speaker_counts[speaker_id] += 1
```

Построив гистограмму, можно получить представление о том, сколько данных имеется для каждого диктора.

```py
import matplotlib.pyplot as plt

plt.figure()
plt.hist(speaker_counts.values(), bins=20)
plt.ylabel("Speakers")
plt.xlabel("Examples")
plt.show()
```

    

Гистограмма показывает, что примерно треть дикторов в наборе данных имеет менее 100 примеров, в то время как
около десяти дикторов имеют более 500 примеров. Чтобы повысить эффективность обучения и сбалансировать набор данных, мы можем ограничить
данные дикторами, имеющими от 100 до 400 примеров.

```py
def select_speaker(speaker_id):
    return 100 

Примечание: Если данная спектрограмма кажется вам непонятной, то это может быть связано с тем, что вы привыкли располагать низкие частоты
внизу, а высокие - вверху графика. Однако при построении спектрограмм в виде изображения с помощью библиотеки matplotlib ось y
переворачивается, и спектрограммы выглядят перевернутыми.

Теперь необходимо применить функцию препроцессинга ко всему набору данных. Это займет от 5 до 10 минут.

```py
dataset = dataset.map(prepare_dataset, remove_columns=dataset.column_names)
```

Появится предупреждение о том, что длина некоторых примеров в датасете превышает максимальную длину входных данных, которую может обработать модель (600 лексем).
Удалите эти примеры из датасета. Здесь мы идем еще дальше и для того, чтобы увеличить размер батча, удаляем все, что превышает 200 токенов.

```py
def is_not_too_long(input_ids):
    input_length = len(input_ids)
    return input_length  Dict[str, torch.Tensor]:
        input_ids = [{"input_ids": feature["input_ids"]} for feature in features]
        label_features = [{"input_values": feature["labels"]} for feature in features]
        speaker_features = [feature["speaker_embeddings"] for feature in features]

        # collate the inputs and targets into a batch
        batch = processor.pad(
            input_ids=input_ids, labels=label_features, return_tensors="pt"
        )

        # replace padding with -100 to ignore loss correctly
        batch["labels"] = batch["labels"].masked_fill(
            batch.decoder_attention_mask.unsqueeze(-1).ne(1), -100
        )

        # not used during fine-tuning
        del batch["decoder_attention_mask"]

        # round down target lengths to multiple of reduction factor
        if model.config.reduction_factor > 1:
            target_lengths = torch.tensor(
                [len(feature["input_values"]) for feature in label_features]
            )
            target_lengths = target_lengths.new(
                [
                    length - length % model.config.reduction_factor
                    for length in target_lengths
                ]
            )
            max_length = max(target_lengths)
            batch["labels"] = batch["labels"][:, :max_length]

        # also add in the speaker embeddings
        batch["speaker_embeddings"] = torch.tensor(speaker_features)

        return batch
```

В SpeechT5 входная информация для декодера уменьшается в 2 раза. Другими словами, отбрасывается каждый второй 
временной шаг из целевой последовательности.Затем декодер предсказывает последовательность, которая в два раза длиннее. Поскольку исходная длина
целевой последовательности [NL] может быть нечетной, коллатор данных обязательно округляет максимальную длину батча до значения [NL], кратного 2.

```py 
data_collator = TTSDataCollatorWithPadding(processor=processor)
```

## Обучение модели

Загрузите предварительно обученную модель из той же контрольной точки, которая использовалась для загрузки процессора: 

```py
from transformers import SpeechT5ForTextToSpeech

model = SpeechT5ForTextToSpeech.from_pretrained(checkpoint)
```

Опция `use_cache=True` несовместима с использованием градиентных контрольных точек. Отключите ее для обучения и снова включите кэш для генерации,
чтобы ускорить  инференс:

```py 
from functools import partial

# отключить кэш во время обучения, так как он несовместим с градиентными контрольными точками
model.config.use_cache = False

# заданим язык и задачу для генерации и снова включим кэш
model.generate = partial(model.generate, use_cache=True)
``` 

Определим аргументы обучения. Здесь мы не вычисляем никаких оценочных метрик в процессе обучения,
мы поговорим об оценке позже в этой главе. Вместо этого мы будем рассматривать только потери:

```python
from transformers import Seq2SeqTrainingArguments

training_args = Seq2SeqTrainingArguments(
    output_dir="speecht5_finetuned_voxpopuli_nl",  # change to a repo name of your choice
    per_device_train_batch_size=4,
    gradient_accumulation_steps=8,
    learning_rate=1e-5,
    warmup_steps=500,
    max_steps=4000,
    gradient_checkpointing=True,
    fp16=True,
    evaluation_strategy="steps",
    per_device_eval_batch_size=2,
    save_steps=1000,
    eval_steps=1000,
    logging_steps=25,
    report_to=["tensorboard"],
    load_best_model_at_end=True,
    greater_is_better=False,
    label_names=["labels"],
    push_to_hub=True,
)
```

Инстанцируем объект `Trainer` и передаем ему модель, набор данных и коллатор данных.

```py
from transformers import Seq2SeqTrainer

trainer = Seq2SeqTrainer(
    args=training_args,
    model=model,
    train_dataset=dataset["train"],
    eval_dataset=dataset["test"],
    data_collator=data_collator,
    tokenizer=processor,
)
```

И с этим мы готовы приступить к обучению! Обучение займет несколько часов. В зависимости от используемого GPU
возможно, что при начале обучения возникнет ошибка CUDA "out-of-memory". В этом случае можно уменьшить
размер `per_device_train_batch_size` постепенно в 2 раза и увеличить `gradient_accumulation_steps` в 2 раза, чтобы компенсировать это.

```py
trainer.train()
```

Push the final model to the 🤗 Hub:

```py
trainer.push_to_hub()
```

## Инференс

После того как модель дообучена, ее можно использовать для инференса! Загрузите модель из 🤗 Hub (убедитесь, что в
следующем фрагменте кода используется имя вашей учетной записи):

```py
model = SpeechT5ForTextToSpeech.from_pretrained(
    "YOUR_ACCOUNT/speecht5_finetuned_voxpopuli_nl"
)
```

Выберем пример, здесь мы возьмем пример из тестового набора данных. Получаем эмбеддинги диктора.

```py 
example = dataset["test"][304]
speaker_embeddings = torch.tensor(example["speaker_embeddings"]).unsqueeze(0)
```

Определим некоторый входной текст и токенизируем его.

```py 
text = "hallo allemaal, ik praat nederlands. groetjes aan iedereen!"
```

Выполним препроцессинг входного текста:

```py
inputs = processor(text=text, return_tensors="pt")
```

Инстанцируем вокодер и сгенерируем речь: 

```py
from transformers import SpeechT5HifiGan

vocoder = SpeechT5HifiGan.from_pretrained("microsoft/speecht5_hifigan")
speech = model.generate_speech(inputs["input_ids"], speaker_embeddings, vocoder=vocoder)
```

Готовы послушать результат?

```py
from IPython.display import Audio

Audio(speech.numpy(), rate=16000)
```

Получение удовлетворительных результатов с помощью этой модели на новом языке может оказаться непростой задачей. Качество эмбеддингов диктора
может быть существенным фактором. Поскольку SpeechT5 была предварительно обучена на английских x-векторах, она показывает наилучшие результаты
при использовании эмбеддингов английских дикторов. Если синтезированная речь звучит плохо, попробуйте использовать другие эмбеддинги диктора.

Увеличение продолжительности обучения, вероятно, также повысит качество результатов. Несмотря на это, речь явно голландская, а не английская, и в ней
передаются особенности голоса говорящего (сравните с оригинальным аудио в примере).
Еще один момент, с которым можно поэкспериментировать, - это настройка модели. Например, попробуйте использовать `config.reduction_factor = 1`, чтобы
посмотреть, улучшит ли это результаты.

В следующем разделе мы расскажем о том, как мы оцениваем модели преобразования текста в речь.

### Практическое занятие
https://huggingface.co/learn/audio-course/ru/chapter6/hands_on.md

# Практическое занятие

В этом разделе мы рассмотрели аудиозадачу преобразования текста в речь, рассказали о существующих наборах данных, предварительно обученных
моделях и нюансах дообучения SpeechT5 для нового языка. 

Как вы убедились, дообучение моделей для задач преобразования текста в речь может быть сложной задачей в условиях ограниченных ресурсов. В то же время
оценивать модели преобразования текста в речь также нелегко. 

По этим причинам данное практическое занятие будет направлено на отработку навыков, а не на достижение определенного значения метрики. 

Ваша задача - провести дообучение SpeechT5 на выбранном вами наборе данных. Вы можете выбрать
другой язык из того же набора данных `voxpopuli`, либо выбрать любой другой набор данных, приведенный в этом разделе.

Помните о размере обучающих данных! Для обучения на GPU бесплатного уровня в Google Colab мы рекомендуем ограничить объем обучающих
данных примерно до 10-15 часов. 

После завершения процесса дообучения поделитесь своей моделью, загрузив ее в Hub. Обязательно пометьте модель
как модель `text-to-speech` либо соответствующими параметрами kwargs, либо через графический интерфейс Hub.

Помните, что основная цель этого упражнения - предоставить вам обширную практику, которая позволит вам отточить свои навыки и
получить более глубокое представление об аудиозадачах преобразования текста в речь.

### Наборах данных Text-to-speech
https://huggingface.co/learn/audio-course/ru/chapter6/tts_datasets.md

# Наборах данных Text-to-speech

Задача преобразования текста в речь (называемая также _синтезом речи_) сопряжена с целым рядом трудностей.

Во-первых, как и в ранее рассмотренном случае автоматического распознавания речи, согласование текста и речи может быть затруднено.
Однако, в отличие от ASR, TTS - это проблема отображения **одного ко многим**, т.е. один и тот же текст может быть синтезирован множеством различных способов. Подумайте о разнообразии голосов и стилей речи,
которые вы слышите ежедневно - каждый человек по-своему произносит одно и то же предложение, но все они правильные и верные! Даже разные выходные данные (спектрограммы или формы волны звука)
могут соответствовать одной и той же истине. Модель должна научиться генерировать правильную длительность и время для каждой фонемы, слова или предложения, что может оказаться непростой задачей,
особенно для длинных и сложных предложений.

Далее, существует проблема дальних зависимостей: язык имеет временной аспект, и понимание смысла предложения
часто требует учета контекста окружающих слов. Убедиться в том, что модель TTS улавливает и сохраняет контекстную информацию
в длинных последовательностях, очень важно для создания связной и естественно звучащей речи.

Наконец, для обучения TTS-моделей обычно требуются пары из текста и соответствующих записей речи. Кроме того, для того чтобы
модель могла генерировать речь, звучащую естественно для различных дикторов и стилей речи, данные должны содержать разнообразные и
репрезентативные образцы речи от различных дикторов. Сбор таких данных является дорогостоящим, трудоемким и для некоторых языков
нецелесообразным. Вы можете подумать, почему бы просто не взять набор данных, предназначенный для ASR (автоматического распознавания речи), и не использовать его для
обучения модели TTS? К сожалению, наборы данных автоматического распознавания речи (ASR) - не самый лучший вариант. Особенности, которые
делают его полезным для ASR, например, чрезмерный фоновый шум, обычно нежелательны в TTS. Очень хорошо, если вы можете
выделить речь из шумной уличной записи, но не очень хорошо, если ваш голосовой помощник отвечает вам на фоне гудка машин
и бурного строительства на заднем плане. Тем не менее, некоторые наборы данных ASR иногда могут быть полезны для дообучения,
так как найти высококачественные, многоязычные и многоголосые наборы данных TTS может быть довольно сложно.

Рассмотрим несколько наборов данных, подходящих для TTS, которые можно найти на 🤗 Hub.

## LJSpeech

[LJSpeech](https://huggingface.co/datasets/lj_speech) представляет собой набор данных, состоящий из 13 100 англоязычных аудиоклипов,
сопоставленных с соответствующими транскрипциями. Набор содержит запись чтения одним диктором предложений
из 7 нехудожественных книг на английском языке. LJSpeech часто используется в качестве эталона для оценки моделей TTS
благодаря высокому качеству звука и разнообразию лингвистического контента.

## Multilingual LibriSpeech

[Multilingual LibriSpeech](https://huggingface.co/datasets/facebook/multilingual_librispeech) является многоязычным расширением
набора данных LibriSpeech, представляющего собой крупномасштабную коллекцию прочитанных англоязычных аудиокниг. Многоязычный LibriSpeech
расширяется за счет включения дополнительных языков, таких как немецкий, голландский, испанский, французский, итальянский, португальский и польский.
Он предлагает аудиозаписи вместе с выверенными транскрипциями для каждого языка. Этот набор данных представляет собой ценный ресурс
для разработки многоязычных систем TTS и изучения методов межъязыкового синтеза речи.

## VCTK (Voice Cloning Toolkit)

[VCTK](https://huggingface.co/datasets/vctk) - это набор данных, специально разработанный для исследований и разработок в области преобразования текста в речь.
Он содержит аудиозаписи 110 дикторов английского языка с различными акцентами. Каждый диктор зачитывает около 400 предложений,
которые были выбраны из газеты, [радужного отрывка](https://www.dialectsarchive.com/the-rainbow-passage)* и элективного абзаца, использованного для архива акцентов речи.
VCTK представляет собой ценный ресурс для обучения TTS-моделей с различными голосами и акцентами, что позволяет осуществлять более естественный и разнообразный
синтез речи.

## Libri-TTS/ LibriTTS-R

[Libri-TTS/ LibriTTS-R](https://huggingface.co/datasets/cdminix/libritts-r-aligned) это многоголосный корпус английской речи,
включающий около 585 часов чтения английской речи с частотой дискретизации 24 кГц, подготовленный компанией Heiga Zen при содействии членов команд Google Speech
и Google Brain. Корпус LibriTTS предназначен для исследования TTS. Он создан на основе оригинальных материалов
(аудиофайлов mp3 из LibriVox и текстовых файлов из Project Gutenberg) корпуса LibriSpeech. Основные отличия
от корпуса LibriSpeech перечислены ниже: 

* Аудиофайлы имеют частоту дискретизации 24 кГц. 
* Речь разбита на фрагменты. 
* Включены как оригинальные, так и нормализованные тексты. 
* Контекстная информация (например, соседние предложения) может быть извлечена. 
* Исключены фразы со значительным фоновым шумом.

Собрать хороший набор данных для TTS - задача не из легких, поскольку такой набор должен обладать несколькими ключевыми характеристиками:

* Качественные и разнообразные записи, охватывающие широкий спектр речевых паттернов, акцентов, языков и эмоций. Записи должны быть чистыми, без фоновых шумов и демонстрировать естественные характеристики речи.
* Транскрипция: Каждая аудиозапись должна сопровождаться соответствующей текстовой транскрипцией.
* Разнообразие лингвистического контента: Набор данных должен содержать разнообразный лингвистический контент, включая различные типы предложений, фраз и слов. Он должен охватывать различные темы, жанры и области, 
чтобы обеспечить способность модели работать с различными языковыми контекстами.

Хорошая новость заключается в том, что вряд ли вам придется обучать TTS-модель с нуля. В следующем разделе мы рассмотрим 
предварительно обученные модели, доступные на 🤗 Hub.

-----
* - радужный отрывок - это конкретный фрагмент текста, который часто используется в англоязычных исследованиях речи и голоса для оценки различных аспектов речи. Он включает в себя различные фонетические звуки и лингвистические паттерны, которые могут помочь исследователям понять,
как звуки речи произносятся людьми с различными акцентами или особенностями речи.

### Раздел 6. От текста к речи
https://huggingface.co/learn/audio-course/ru/chapter6/introduction.md

# Раздел 6. От текста к речи 

В предыдущем разделе вы узнали, как использовать трансформеры для преобразования устной речи в текст. Теперь давайте перевернем сценарий
и посмотрим, как можно преобразовать заданный входной текст в аудио вывод, звучащий как человеческая речь.

Задача, которую мы будем изучать в этом блоке, называется "Преобразование текста в речь " (Text-to-speech, TTS). Модели, способные преобразовывать текст в слышимую
человеческую речь, имеют широкий спектр потенциальных применений: 

* Вспомогательные приложения: подумайте об инструментах, которые могут использовать эти модели для обеспечения доступа людей с ослабленным зрением к цифровому контенту с помощью звука.
* Озвучивание аудиокниг: перевод письменных книг в аудиоформат делает литературу более доступной для тех, кто предпочитает слушать или испытывает трудности с чтением.
* Виртуальные помощники: TTS-модели являются фундаментальным компонентом виртуальных помощников, таких как Siri, Google Assistant или Amazon Alexa. После того как они с помощью классификационной модели поймали слово "пробуждение" и использовали ASR-модель для обработки запроса, они могут использовать TTS-модель для ответа на ваш запрос.
* Развлечения, игры и изучение языков: озвучивайте персонажей NPC, рассказывайте об игровых событиях или помогайте изучающим язык примерами правильного произношения и интонации слов и фраз.

Это лишь некоторые примеры, и я уверен, что вы можете придумать множество других! Однако с такой мощью приходит и ответственность
,важно подчеркнуть, что модели TTS потенциально могут быть использованы в злонамеренных целях. 
Например, имея достаточное количество образцов голоса, злоумышленники могут создавать убедительные поддельные аудиозаписи, что приводит к
несанкционированному использованию голоса человека в мошеннических целях или для манипуляций. Если вы планируете собирать данные для дообучения
собственных систем, тщательно продумайте вопросы конфиденциальности и информационного согласия. Получение голосовых данных должно осуществляться с явного согласия
людей, при этом они должны понимать цель, объем и потенциальные риски, связанные с использованием их голоса
в системе TTS. Пожалуйста, используйте преобразование текста в речь ответственно. 

## Чему вы научитесь и что создадите

В этом разделе мы поговорим о:

* [Наборах данных, пригодных для обучения Text-to-speech](tts_datasets)
* [Предварительно обученных моделях для преобразования текста в речь](pre-trained_models)
* [Дообучение SpeechT5 на новом языке](fine-tuning)
* [Оценке моделей TTS](evaluation)

### Дополнительные материалы и ресурсы
https://huggingface.co/learn/audio-course/ru/chapter6/supplemental_reading.md

# Дополнительные материалы и ресурсы

В этом разделе была представлена задача преобразования текста в речь.
Хотите узнать больше? Здесь вы найдете дополнительные ресурсы, которые помогут вам углубить понимание рассматриваемых тем
и повысить эффективность обучения.

* [HiFi-GAN: генеративные состязательные сети для эффективного и высококачественного синтеза речи](https://arxiv.org/pdf/2010.05646.pdf): статья, в которой представлена HiFi-GAN для синтеза речи.
* [Х-Векторы: Надежные DNN-Эмбединги для распознавания дикторов](https://www.danielpovey.com/files/2018_icassp_xvectors.pdf): статья, в которой представлен метод Х-Векторов для эмбеддингов дикторов.
* [FastSpeech 2: быстрое и высококачественное преобразование текста в речь](https://arxiv.org/pdf/2006.04558.pdf): статья, в которой представлена FastSpeech 2 - еще одна популярная модель преобразования текста в речь, использующая неавторегрессионный TTS метод.
* [Векторно-квантованный подход для синтеза текста в речь на основе спонтанной речи в реальном мире](https://arxiv.org/pdf/2302.04215v1.pdf): статья, посвященная MQTTS - авторегрессионной системе TTS, в которой мел-спектрограммы заменены квантованным дискретным представлением.

### Предварительно обученные модели text-to-speech
https://huggingface.co/learn/audio-course/ru/chapter6/pre-trained_models.md

# Предварительно обученные модели text-to-speech

По сравнению с задачами ASR (автоматическое распознавание речи) и классификации звука, здесь значительно меньше предварительно обученных 
контрольных точек. На 🤗 Hub вы найдете около 300 подходящих контрольных точек. Среди 
этих предварительно обученных моделей мы остановимся на двух архитектурах, которые легко доступны для вас в библиотеке 
🤗 Transformers - SpeechT5 и Massive Multilingual Speech (MMS).
В этом разделе мы рассмотрим, как использовать эти предварительно обученные модели в библиотеке Transformers для TTS.

## SpeechT5 

[SpeechT5](https://arxiv.org/abs/2110.07205) - это модель, опубликованная Джуньи Ао и другими специалистами компании Microsoft, которая способна
решать целый ряд речевых задач. Несмотря на то, что в данном разделе мы сосредоточились на аспекте преобразования текста в речь,
эта модель может быть адаптирована как для задач преобразования речи в текст (автоматическое распознавание речи или идентификация диктора),
так и для задач преобразования речи в речь (например, улучшение речи или преобразование между различными голосами). Это обусловлено тем, как эта модель
была спроектирована и предварительно обучена.

В основе SpeechT5 лежит обычная модель трансформера энкодер-декодер. Как и любой другой трансформер, модель энкодер-декодер
осуществляет преобразование последовательности в последовательность с использованием скрытых представлений. Эта основа трансформера
одинакова для всех задач, поддерживаемых SpeechT5.

Этот трансформер дополнен шестью модально-специфическими (речь/текст) _пред-сетями_ и _пост-сетями_. Входная речь или текст
(в зависимости от задачи) предварительно обрабатывается через соответствующую предварительную сеть для получения скрытых представлений, которые может использовать трансформер.
Выходные данные трансформера передаются в пост-сеть, которая использует их для генерации вывода в целевой модальности.

Вот как выглядит архитектура (изображение из оригинальной статьи):

    

SpeechT5 сначала проходит предварительное обучение на больших объемах немаркированных речевых и текстовых данных, чтобы получить единое представление
различных модальностей. На этапе предварительного обучения все предварительные и последующие сети используются одновременно.

После предварительного обучения вся структура энкодера-декодера настраивается для каждой конкретной задачи. На этом этапе используются только те
пред-сети и пост-сети, которые имеют отношение к конкретной задаче. Например, чтобы использовать SpeechT5 для преобразования текста в речь, необходимо
использовать предварительную сеть энкодера текста для текстовых входов и предварительную и пост-сети декодера речи для речевых выходов.

Такой подход позволяет получить несколько моделей, дообученных для различных речевых задач, все они выигрывают от первоначального
предварительного обучения на немаркированных данных.   

Несмотря на то что в начале работы дообученные модели используют один и тот же набор весов из общей предварительно обученной модели, конечные версии
в итоге оказываются совершенно разными. Например, вы не можете взять дообученную ASR-модель и поменять местами пред-сети и пост-сети,
чтобы получить рабочую TTS-модель. SpeechT5 гибкая, но не настолько ;)

Посмотрим, какие пред- и пост-сети использует SpeechT5 для решения задачи TTS:

* Предварительная сеть энкодера текста: Слой эмбедингов текста, который сопоставляет текстовые токены со скрытыми представлениями, ожидаемыми энкодером. Это аналогично тому, что происходит в NLP-модели, такой как BERT.
* Предварительная сеть декодера речи: На вход подается лог мел спектрограммы, и с помощью последовательности линейных слоев спектрограмма сжимается в скрытые представления. 
* Пост-сеть декодера речи: Здесь прогнозируется остаток, который добавляется к выходной спектрограмме и используется для уточнения результатов.

В совокупности именно так выглядит архитектура SpeechT5 для преобразования текста в речь:

    

Как видите, на выходе получается лог-мел спектрограмма, а не конечная форма волны. Если вы помните, мы вкратце касались
этой темы в [Разделе 3](../chapter3/introduction#spectrogram-output). Обычно модели, генерирующие звук, выдают
лог мел спектограмму, которой необходимо преобразовать в форму волны с помощью дополнительной нейронной сети, называемой вокодером.

Давайте посмотрим, как это можно сделать.

Сначала загрузим из 🤗 Hub настроенную TTS-модель SpeechT5, а также объект процессора, используемый для токенизации
и извлечения признаков:

```python
from transformers import SpeechT5Processor, SpeechT5ForTextToSpeech

processor = SpeechT5Processor.from_pretrained("microsoft/speecht5_tts")
model = SpeechT5ForTextToSpeech.from_pretrained("microsoft/speecht5_tts")
```

Далее необходимо выполнить токенизацию входного текста.

```python
inputs = processor(text="Don't count the days, make the days count.", return_tensors="pt")
```

Модель SpeechT5 TTS не ограничивается созданием речи для одного диктора. Вместо этого она использует так называемые эмбединги диктора,
которые фиксируют голосовые характеристики конкретного диктора.

Эмбеддинги диктора - это метод компактного представления личности диктора в виде вектора
фиксированного размера, независимо от длины высказывания. Эти эмбеддинги фиксируют важную информацию о голосе,
акценте, интонации и других уникальных характеристиках, отличающих одного диктора от другого. Такие эмбеддинги могут быть
использованы для верификации диктора, диаризации, идентификации диктора и т.д.
 
Наиболее распространенными методами генерации эмбеддингов диктора являются:

* I-векторы (I-Vectors): I-векторы (векторы идентичности) основаны на смешанной модели Гаусса (Gaussian mixture model, GMM). Они представляют говорящих в виде низкоразмерных векторов фиксированной длины, полученных на основе статистики GMM, специфичной для конкретного говорящего, и получаются неконтролируемым (unsupervised) способом. 
* X-векторы (X-Vectors): X-векторы создаются с помощью глубоких нейронных сетей (DNN) и захватывают информацию о дикторе на уровне фрейма с учетом временного контекста. 

[X-Vectors](https://www.danielpovey.com/files/2018_icassp_xvectors.pdf) это современный метод, который показывает более высокую эффективность
на оценочных наборах данных по сравнению с I-векторами.  Для получения X-векторов используется глубокая нейронная сеть: она обучается различать
дикторов и сопоставляет высказывания переменной длины с эмбеддингами фиксированной размерности. Также можно загрузить X-вектор заранее вычисленных эмбеддингов диктора, в котором будут заключены речевые характеристики конкретного диктора.

Загрузим такие эмбединги диктора из набора датсета в Hub. Эмбединги были получены из [датасета CMU ARCTIC](http://www.festvox.org/cmu_arctic/) с помощью
[этого скрипта](https://huggingface.co/mechanicalsea/speecht5-vc/blob/main/manifest/utils/prep_cmu_arctic_spkemb.py), но любой Х-вектор эмбединг должен работать.

```python
from datasets import load_dataset

embeddings_dataset = load_dataset("Matthijs/cmu-arctic-xvectors", split="validation")

import torch

speaker_embeddings = torch.tensor(embeddings_dataset[7306]["xvector"]).unsqueeze(0)
```

Эмбеддинг диктора представляет собой тензор формы (1, 512). Данный эмбеддинг диктора описывает женский голос.

На данном этапе у нас уже достаточно входных данных, чтобы сгенерировать на выходе лог-мел спектрограмму, это можно сделать следующим образом:

```python
spectrogram = model.generate_speech(inputs["input_ids"], speaker_embeddings)
```

В результате получается тензор формы (140, 80), содержащий лог-мел спектрограмму. Первое измерение - длина последовательности, и
она может изменяться между запусками, так как предварительная сеть декодер речи всегда применяет исключение (dropout) к входной последовательности. Это вносит некоторую
случайную вариативность в генерируемую речь.

Однако если мы хотим генерировать форму волны речи, нам необходимо указать вокодер, который будет использоваться для преобразования спектрограммы в форму волны.
Теоретически можно использовать любой вокодер, работающий с 80-биновыми мел-спектрограммами. Удобно, что 🤗 Transformers предлагает вокодер,
основанный на HiFi-GAN. Его весовые коэффициенты были любезно предоставлены авторами SpeechT5.

[HiFi-GAN](https://arxiv.org/pdf/2010.05646v2.pdf) представляет собой современную генеративную состязательную сеть (generative adversarial network, GAN), разработанную
для высокоточного синтеза речи. Она способна генерировать высококачественные и реалистичные формы волны звука на основе спектрограмм.

В общем случае HiFi-GAN состоит из одного генератора и двух дискриминаторов. Генератор представляет собой полностью сверточную
нейронную сеть, которая принимает на вход mel-спектрограмму и учится генерировать исходные аудиосигналы. Роль дискриминаторов
заключается в том, чтобы различать реальный и сгенерированный звук. Оба дискриминатора фокусируются на различных аспектах звука.

HiFi-GAN обучается на большом наборе данных высококачественных аудиозаписей. В нем используется так называемое состязательное обучение,
при котором сети генератора и дискриминатора соревнуются друг с другом. Вначале генератор выдает низкокачественный звук и дискриминатор легко
отличает его от реального звука. В ходе обучения генератор улучшает свой выход, пытаясь обмануть дискриминатор. Дискриминатор, в свою очередь,
становится более точным в различении реального и сгенерированного звука. Такая состязательная обратная связь помогает обеим сетям совершенствоваться
с течением времени. В конечном итоге HiFi-GAN учится генерировать звук высокой достоверности, близкий по характеристикам к обучающим данным.

Загрузить вокодер так же просто, как и любую другую модель 🤗 Transformers.

```python
from transformers import SpeechT5HifiGan

vocoder = SpeechT5HifiGan.from_pretrained("microsoft/speecht5_hifigan")
```

Теперь достаточно передать его в качестве аргумента при генерации речи, и выходные данные будут автоматически преобразованы в форму волны речи.

```python
speech = model.generate_speech(inputs["input_ids"], speaker_embeddings, vocoder=vocoder)
```

Давайте послушаем результат. Частота дискретизации, используемая SpeechT5, всегда равна 16 кГц.

```python
from IPython.display import Audio

Audio(speech, rate=16000)
```

Отлично!

Не стесняйтесь пользоваться демонстрационной версией SpeechT5, изучайте другие голоса, экспериментируйте с вводом. Обратите внимание, что эта
предварительно обученная контрольная точка поддерживает только английский язык:

## Bark

Bark - это модель преобразования текста в речь на основе трансформера, предложенная компанией Suno AI в [suno-ai/bark](https://github.com/suno-ai/bark).

В отличие от SpeechT5, Bark генерирует непосредственно "сырые" формы волны речи, что избавляет от необходимости использования отдельного вокодера при инференсе - он уже интегрирован. Такая эффективность достигается за счет использования [`Encodec`](https://huggingface.co/docs/transformers/main/en/model_doc/encodec), который служит одновременно и кодеком, и инструментом сжатия.

С помощью `Encodec` можно сжимать звук в облегченный формат для уменьшения занимаемой памяти и впоследствии распаковывать его для восстановления исходного звучания. Процесс сжатия осуществляется с помощью 8 кодовых книг (codebook), каждая из которых состоит из целочисленных векторов. Эти кодовые книги можно рассматривать как представления или эмбеддинги звука в целочисленной форме. Важно отметить, что каждая последующая кодовая книга улучшает качество восстановления звука из предыдущих кодовых книг. Поскольку кодовые книги являются целочисленными векторами, они могут быть выучены с помощью трансформерных моделей, которые очень эффективно справляются с этой задачей. Именно для этого и был специально обучен Bark. 

Если говорить более конкретно, то Bark состоит из 4 основных моделей:

- `BarkSemanticModel` (также называемая 'текстовой' моделью): каузальная авторегрессионная трансформерная модель, принимающая на вход токены из текста и предсказывающая семантические токены, отражающие смысл текста.
- `BarkCoarseModel` (также называемая моделью 'грубой акустики'): каузальный авторегрессионный трансформер, принимающий на вход результаты работы модели `BarkSemanticModel`. Его цель - предсказать первые две кодовые книги, необходимые для работы [EnCodec](https://github.com/facebookresearch/encodec).
- `BarkFineModel` (модель 'тонкой акустики'), на этот раз некаузальный автоэнкодерный трансформер, который итеративно предсказывает последние кодовые книги на основе суммы эбеддингов предыдущих кодовых книг.
- спрогнозировав все каналы кодовой книги из `EncodecModel`, Bark использует ее для декодирования выходного звукового массива.

Следует отметить, что каждый из первых трех модулей может поддерживать условные эмбеддинги диктора, обусловливающие выходной звук в соответствии с определенным заранее заданным голосом.

Bark - это высокоуправляемая модель преобразования текста в речь, то есть ее можно использовать с различными настройками, в чем мы сейчас убедимся.

Прежде всего, загрузите модель и ее процессор.

Роль процессора здесь двухсторонняя:
1. Он используется для токенизации входного текста, т.е. для разбиения его на небольшие фрагменты, понятные модели.
2. В нем хранятся эбеддинги дикторов, т.е. голосовые предустановки, которые могут обуславливать генерацию.

```python
from transformers import BarkModel, BarkProcessor

model = BarkModel.from_pretrained("suno/bark-small")
processor = BarkProcessor.from_pretrained("suno/bark-small")
```

Bark очень универсален и может генерировать звук, обусловленный [библиотекой эбеддингов дикторов](https://suno-ai.notion.site/8b8e8749ed514b0cbf3f699013548683?v=bc67cff786b04b50b3ceb756fd05f68c) которая может быть загружена через процессор.

```python
# add a speaker embedding
inputs = processor("This is a test!", voice_preset="v2/en_speaker_3")

speech_output = model.generate(**inputs).cpu().numpy()
```

 
   
Your browser does not support the audio element. 
 

Он также может генерировать готовую многоязычную речь, например, на французском и китайском языках. Список поддерживаемых языков можно найти [здесь](https://huggingface.co/suno/bark). В отличие от MMS, о котором речь пойдет ниже, здесь не нужно указывать используемый язык, а достаточно просто адаптировать входной текст к соответствующему языку.

```python
# try it in French, let's also add a French speaker embedding
inputs = processor("C'est un test!", voice_preset="v2/fr_speaker_1")

speech_output = model.generate(**inputs).cpu().numpy()
```

 
   
Your browser does not support the audio element. 
 

Модель также может генерировать **невербальные коммуникации**, такие как смех, вздох и плач. Для этого достаточно модифицировать входной текст соответствующими подсказками, такими как `[clears throat]`, `[laughter]` или `...`.

```python
inputs = processor(
    "[clears throat] This is a test ... and I just took a long pause.",
    voice_preset="v2/fr_speaker_1",
)

speech_output = model.generate(**inputs).cpu().numpy()
```

 
   
Your browser does not support the audio element. 
 

Bark может даже генерировать музыку. Вы можете помочь, добавив ♪ музыкальные ноты ♪ вокруг ваших слов.

```python
inputs = processor(
    "♪ In the mighty jungle, I'm trying to generate barks.",
)

speech_output = model.generate(**inputs).cpu().numpy()
```

 
   
Your browser does not support the audio element. 
 

В отличие от SpeechT5, Bark напрямую генерирует форму волны сырой речи. Это означает, что для инференса не нужно добавлять вокодер, он уже "встроен".

Кроме того, Bark поддерживает пакетную обработку, то есть можно одновременно обрабатывать несколько текстовых записей за счет более интенсивных вычислений.
На некоторых аппаратных средствах, таких как GPU, пакетная обработка позволяет ускорить общую генерацию, что означает, что генерация всех образцов одновременно может быть быстрее, чем генерация их по одному.

Попробуем сгенерировать несколько примеров:

```python
input_list = [
    "[clears throat] Hello uh ..., my dog is cute [laughter]",
    "Let's try generating speech, with Bark, a text-to-speech model",
    "♪ In the jungle, the mighty jungle, the lion barks tonight ♪",
]

# также добавляем эмбеддинги диктора
inputs = processor(input_list, voice_preset="v2/en_speaker_3")

speech_output = model.generate(**inputs).cpu().numpy()
```

Давайте прослушаем выводы по очереди.

Первый:
```python
from IPython.display import Audio

sampling_rate = model.generation_config.sample_rate
Audio(speech_output[0], rate=sampling_rate)
```

 
   
Your browser does not support the audio element. 
 

Второй:
```python
Audio(speech_output[1], rate=sampling_rate)
```

 
   
Your browser does not support the audio element. 
 

Третий:
```python
Audio(speech_output[2], rate=sampling_rate)
```

 
   
Your browser does not support the audio element. 
 

Bark, как и другие 🤗 модели трансформеров, могут быть оптимизированы всего в нескольких строках кода в отношении скорости и потребления памяти. Чтобы узнать, как это сделать, нажмите на [этот демонстрационный блокнот Colab](https://colab.research.google.com/github/ylacombe/notebooks/blob/main/Benchmark_Bark_HuggingFace.ipynb).

## Massive Multilingual Speech (MMS)

Что делать, если вам нужна предварительно обученная модель на языке, отличном от английского? Массивная многоязыковая речь (Massive Multilingual Speech, MMS) - это 
еще одна модель, которая охватывает целый ряд речевых задач, но при этом поддерживает большое количество языков. Например, она может
синтезировать речь на более чем 1100 языках.

MMS для преобразования текста в речь базируется на технологии описанной в [статье VITS написанной Kim и другими специалистами в 2021 году]((https://arxiv.org/pdf/2106.06103.pdf)),
которая является одним из современных подходов в TTS.

VITS - это сеть генерации речи, преобразующая текст в сырую форму волны речи. Он работает как условный вариационный
автокодер, вычисляя звуковые признаки из входного текста. Сначала генерируются акустические признаки, представленные 
в виде спектрограмм. Затем форма сигнала декодируется с помощью транспонированных сверточных слоев, адаптированных из HiFi-GAN.
В процессе инференса кодировки текста подвергаются апсемплингу и преобразуются в волновые формы с помощью потокового модуля и декодера HiFi-GAN.
Это означает, что не нужно добавлять вокодер для инференса, он уже "встроен". 

	
Модель MMS была добавлена в 🤗 Transformers совсем недавно, поэтому ее API может немного измениться. На момент выхода этого раздела
MMS для TTS планируется интегрировать в Transformers `main` через пару дней.
После слияния вам придется установить библиотеку из исходного кода. Тем временем, если вы хотите попробовать следующий пример инференса,
вы можете установить модель из ветки PR:

```bash
pip install git+https://github.com/hollance/transformers.git@6900e8ba6532162a8613d2270ec2286c3f58f57b
```

Давайте попробуем использовать MMS и посмотрим, как можно синтезировать речь на языке, отличном от английского, например, на немецком.
Сначала загрузим контрольную точку модели и токенизатор для нужного языка: 

```python
from transformers import VitsModel, VitsTokenizer

model = VitsModel.from_pretrained("facebook/mms-tts-deu")
tokenizer = VitsTokenizer.from_pretrained("facebook/mms-tts-deu")
```

Вы можете заметить, что для загрузки модели MMS необходимо использовать `VitsModel` и `VitsTokenizer`. Это связано с тем, что MMS для преобразования текста в речь
основана на модели VITS, о которой говорилось выше.

Возьмем для примера текст на немецком языке, например, эти две первые строчки из детской песенки:

```python
text_example = (
    "Ich bin Schnappi das kleine Krokodil, komm aus Ägypten das liegt direkt am Nil."
)
```

Для генерации выходной волновой формы необходимо предварительно обработать текст с помощью токенизатора и передать его в модель:

```python
import torch

inputs = tokenizer(text_example, return_tensors="pt")
input_ids = inputs["input_ids"]

with torch.no_grad():
    outputs = model(input_ids)

speech = outputs.audio[0]
```

Давайте послушаем:

```python
from IPython.display import Audio

Audio(speech, rate=16000)
```

Замечательно! Если вы хотите попробовать MMS на другом языке, найдите другие подходящие контрольные точки `vits` [в 🤗 Hub](https://huggingface.co/models?filter=vits).

Теперь давайте посмотрим, как можно самостоятельно дообучить модель TTS!

### Оценка моделей text-to-speech
https://huggingface.co/learn/audio-course/ru/chapter6/evaluation.md

# Оценка моделей text-to-speech

В процессе обучения модели преобразования текста в речь оптимизируются по среднеквадратичной ошибке (mean-square error, MSE) (или средней абсолютной ошибке (mean absolute error, MAE)) между
спрогнозированными значениями спектрограмм и сгенерированными. Как MSE, так и MAE способствуют минимизации разности
между прогнозируемой и целевой спектрограммами. Однако, поскольку TTS - это проблема отображения "один ко многим", т.е. выходная спектрограмма для данного текста может быть представлена множеством
различных способов, оценка полученных моделей преобразования текста в речь (TTS) значительно сложнее.

В отличие от многих других вычислительных задач, которые могут быть объективно измерены с помощью количественных показателей,
таких как accuracy или precision, оценка TTS в значительной степени зависит от субъективного человеческого анализа.

Одним из наиболее часто используемых методов оценки систем TTS является качественная оценка с использованием cредней экспертной оценки (Mean Opinion Scores, MOS).
MOS - это субъективная система оценки, которая позволяет людям оценить качество синтезированной речи [NL] по шкале от 1 до 5.
Эти оценки обычно собираются с помощью тестов на прослушивание, в которых участники-люди [NL] прослушивают и оценивают синтезированные образцы речи.

Одной из основных причин, по которой трудно разработать объективные метрики для оценки TTS, является субъективный характер восприятия
речи. Слушатели имеют различные предпочтения и чувствительность к различным аспектам речи, включая произношение, интонацию, естественность и ясность.
Учесть все эти нюансы восприятия с помощью одного числового значения - сложная задача. 
В то же время субъективность человеческой оценки затрудняет сравнение и сопоставление различных систем TTS.

Кроме того, при такой оценке могут быть упущены некоторые важные аспекты синтеза речи, такие как естественность, выразительность и эмоциональное воздействие. 
Эти качества трудно поддаются объективной количественной оценке, но очень важны в приложениях, где синтезированная речь должна передавать человекоподобные качества и вызывать соответствующие эмоциональные реакции.

В итоге, можно сказать, что оценка моделей преобразования текста в речь является сложной задачей из-за отсутствия единой действительно объективной метрики. Наиболее распространенный метод оценки,
средняя экспертная оценка (MOS), опирается на субъективный человеческий анализ. Хотя MOS дает ценные сведения о качестве синтезированной речи, она также вносит вариативность и субъективность.

### Перевод Speech-to-speech
https://huggingface.co/learn/audio-course/ru/chapter7/speech-to-speech.md

# Перевод Speech-to-speech

Перевод речи в речь (Speech-to-speech, STST или S2ST) - это относительно новая задача обработки устной речи. Она заключается
в переводе [NL] речи с одного языка в речь на **другом** языке:

    

STST можно рассматривать как расширение традиционной задачи машинного перевода (МТ): вместо перевода **текста** с одного языка
на другой мы переводим **речь** с одного языка на другой. STST находит применение в области многоязыковой коммуникации,
позволяя носителям разных языков общаться друг с другом посредством речи.

Предположим, вы хотите общаться с другим человеком, преодолевая языковой барьер. Вместо того чтобы писать информацию, которую вы хотите
передать, а затем переводить ее в текст на целевом языке, вы можете говорить напрямую, а система STST преобразует вашу устную речь 
в целевой язык. Получатель может ответить, обратившись к системе STST, а вы можете прослушать его ответ. Это более естественный
способ общения по сравнению с машинным переводом текста.

В этом разделе мы рассмотрим *каскадный* подход к STST, объединив знания, полученные в разделах 5 и 6 курса. Мы будем использовать
систему *перевода речи (ST)* для транскрибирования исходной речи в текст на целевом языке, а затем *перевода текста в речь (TTS)* 
для генерации речи на целевом языке из переведенного текста:

    

Можно было бы использовать и трехэтапный подход, когда сначала с помощью системы автоматического распознавания речи (ASR) исходная речь транскрибируется в текст на том же 
языке, затем с помощью машинного перевода транскрибированный текст переводится на целевой язык, и, наконец, с помощью преобразования текста в речь формируется речь 
на целевом языке. Однако добавление большего числа компонентов в конвейер приводит к *распространению ошибок*, когда ошибки, вносимые в одну систему, усугубляются
при прохождении через остальные системы, а также к увеличению задержки, поскольку инференс приходится проводить для большего числа моделей.

Несмотря на то, что такой каскадный подход к STST достаточно прост, он позволяет создавать очень эффективные системы STST. Трехступенчатая каскадная система ASR + MT + TTS
ранее использовалась для работы многих коммерческих продуктов STST, в том числе [Google Translate](https://ai.googleblog.com/2019/05/introducing-translatotron-end-to-end.html).

Это также очень эффективный способ разработки STST-системы, поскольку существующие системы распознавания речи и преобразования текста в речь могут быть объединены 
для получения новой STST-модели без дополнительного обучения.

В оставшейся части этого раздела мы сосредоточимся на создании системы STST, которая переводит речь с любого языка X в речь на английском языке. 
Рассмотренные методы могут быть распространены на системы STST, переводящие с любого языка X на любой язык Y, но мы оставляем это на усмотрение читателя и 
указываем, где это возможно.Далее мы разделяем задачу STST на две составные части: ST и TTS. В завершение мы соединим их вместе и создадин демо с помощью Gradio 
для демонстрации нашей системы.

## Перевод речи

Мы будем использовать модель Whisper для нашей системы перевода речи, поскольку эта модель способна переводить с более чем 96 языков на английский. 
В частности, мы загрузим контрольную точку [Whisper Base](https://huggingface.co/openai/whisper-base), которая имеет 74М параметров. Это далеко не самая производительная
модель Whisper, поскольку [наибольшая контрольная точка Whisper](https://huggingface.co/openai/whisper-large-v2) более чем в 20 раз больше, но поскольку мы объединяем две
авторегрессивные системы (ST + TTS), мы хотим, чтобы каждая модель могла работать относительно быстро, чтобы мы получили приемлемую скорость инференса:

```python
import torch
from transformers import pipeline

device = "cuda:0" if torch.cuda.is_available() else "cpu"
pipe = pipeline(
    "automatic-speech-recognition", model="openai/whisper-base", device=device
)
```

Отлично! Для проверки нашей системы STST загрузим аудиопример на неанглийском языке. Загрузим первый пример из итальянской (`it`) части
датасета [VoxPopuli](https://huggingface.co/datasets/qmeeus/voxpopuli):

```python
from datasets import load_dataset

dataset = load_dataset("qmeeus/voxpopuli", "it", split="validation", streaming=True)
sample = next(iter(dataset))
```

Чтобы прослушать этот пример, мы можем либо воспроизвести его с помощью средства просмотра набора данных на Hub: [qmeeus/voxpopuli/viewer](https://huggingface.co/datasets/qmeeus/voxpopuli/viewer/it/validation?row=0)

Или воспроизведение с помощью функции ipynb audio:

```python
from IPython.display import Audio

Audio(sample["audio"]["array"], rate=sample["audio"]["sampling_rate"])
```

Теперь определим функцию, которая принимает этот аудиовход и возвращает переведенный текст. Вы помните, что мы должны передать ключевое слово генерации аргументу `"task"`, 
установив его в значение `"translate"`, чтобы убедиться, что Whisper выполняет перевод речи, а не ее распознавание:

```python
def translate(audio):
    outputs = pipe(audio, max_new_tokens=256, generate_kwargs={"task": "translate"})
    return outputs["text"]
```

    Whisper также можно "обманом" заставить перевести речь на любом языке X на любой язык Y. Просто задайте задачу `"transcribe"`, а `"language"` - целевым языком
    в аргументах ключевых слов генерации, например, для испанского языка можно задать:

	`generate_kwargs={"task": "transcribe", "language": "es"}`

Отлично! Давайте быстро проверим, что мы получаем разумный результат от модели:

```python
translate(sample["audio"].copy())
```
```
' psychological and social. I think that it is a very important step in the construction of a juridical space of freedom, circulation and protection of rights.'
```

Хорошо! Если мы сравним это с исходным текстом:

```python
sample["text"]
```
```
'Penso che questo sia un passo in avanti importante nella costruzione di uno spazio giuridico di libertà di circolazione e di protezione dei diritti per le persone in Europa.'
```

Мы увидим, что перевод более или менее совпадает (вы можете проверить это с помощью Google Translate), за исключением нескольких
лишних слов в начале транскрипции, когда говорящий заканчивал предыдущее предложение.

На этом мы завершили первую половину нашего каскадного конвейера STST, применив на практике навыки, полученные в разделе 5, когда мы учились использовать
модель Whisper для распознавания и перевода речи. Если вы хотите освежить в памяти какие-либо из рассмотренных нами этапов, прочтите
раздел [Предварительно обученные модели для распознавания речи](../chapter5/asr_models) из раздела 5.

## Преобразование текста в речь

Вторая половина нашей каскадной системы STST связана с преобразованием английского текста в английскую речь. Для этого мы
будем использовать предварительно обученную модель [SpeechT5 TTS](https://huggingface.co/microsoft/speecht5_tts) для английского TTS.
🤗 В настоящее время Transformers не имеет TTS `pipeline`, поэтому нам придется использовать модель непосредственно самим.
Ничего страшного, вы же все эксперты по использованию модели для инференса после раздела 6!

Сначала загрузим процессор SpeechT5, модель и вокодер из предварительно обученной контрольной точки:

```python
from transformers import SpeechT5Processor, SpeechT5ForTextToSpeech, SpeechT5HifiGan

processor = SpeechT5Processor.from_pretrained("microsoft/speecht5_tts")

model = SpeechT5ForTextToSpeech.from_pretrained("microsoft/speecht5_tts")
vocoder = SpeechT5HifiGan.from_pretrained("microsoft/speecht5_hifigan")
```

    Здесь мы используем контрольную точку SpeechT5, обученную специально для английского TTS. Если вы хотите перевести
    на язык, отличный от английского, либо замените контрольную точку на модель SpeechT5 TTS, дообученную для выбранного
    вами языка, либо используйте контрольную точку MMS TTS, предварительно обученную для вашего целевого языка.

Как и в случае с моделью Whisper, модель SpeechT5 и вокодер мы поместим на GPU-ускоритель, если он у нас есть:

```python
model.to(device)
vocoder.to(device)
```

Отлично! Давайте загрузим эмбеддинги дикторов:

```python
embeddings_dataset = load_dataset("Matthijs/cmu-arctic-xvectors", split="validation")
speaker_embeddings = torch.tensor(embeddings_dataset[7306]["xvector"]).unsqueeze(0)
```

Теперь мы можем написать функцию, которая принимает на вход текстовый запрос и генерирует соответствующую речь. Сначала мы предварительно обработаем
текстовый ввод с помощью процессора SpeechT5, токенизируя текст для получения входных идентификаторов. Затем мы передадим входные идентификаторы и
эбеддинги диктора в модель SpeechT5, разместив каждый из них на ускорителе, если таковой имеется. Наконец, мы вернем сгенерированную речь обратно в
процессор, чтобы мы могли воспроизвести ее в нашем ноутбуке ipynb:

```python
def synthesise(text):
    inputs = processor(text=text, return_tensors="pt")
    speech = model.generate_speech(
        inputs["input_ids"].to(device), speaker_embeddings.to(device), vocoder=vocoder
    )
    return speech.cpu()
```

Проверим его работу с помощью фиктивного текстового ввода:

```python
speech = synthesise("Hey there! This is a test!")

Audio(speech, rate=16000)
```

Звучит неплохо! Теперь самое интересное - собрать все воедино.

## Создание демо STST

Перед тем как создать демо [Gradio](https://gradio.app) для демонстрации нашей системы STST, давайте сначала проведем быструю проверку, чтобы убедиться,
что мы можем объединить две модели, подавая аудио пример на вход и получая аудио пример на выходе. Для этого мы объединим две функции, определенные в 
предыдущих двух подразделах: введем исходное аудио и получим переведенный текст, затем синтезируем переведенный текст, чтобы получить переведенную речь.
Наконец, мы преобразуем синтезированную речь в массив `int16`, который является форматом выходного аудиофайла, ожидаемого Gradio. Для этого сначала 
необходимо нормализовать аудио массив по динамическому диапазону целевого dtype (`int16`), а затем преобразовать из стандартного dtype NumPy (`float64`)
в целевой dtype (`int16`):

```python
import numpy as np

target_dtype = np.int16
max_range = np.iinfo(target_dtype).max

def speech_to_speech_translation(audio):
    translated_text = translate(audio)
    synthesised_speech = synthesise(translated_text)
    synthesised_speech = (synthesised_speech.numpy() * max_range).astype(np.int16)
    return 16000, synthesised_speech
```

Проверим, что эта конкатенированная функция дает ожидаемый результат:

```python
sampling_rate, synthesised_speech = speech_to_speech_translation(sample["audio"])

Audio(synthesised_speech, rate=sampling_rate)
```

Отлично! Теперь мы завернем это в красивое демо Gradio, чтобы мы могли записать нашу исходную речь с помощью 
микрофонного или файлового входа и воспроизвести прогноз системы:

```python
import gradio as gr

demo = gr.Blocks()

mic_translate = gr.Interface(
    fn=speech_to_speech_translation,
    inputs=gr.Audio(source="microphone", type="filepath"),
    outputs=gr.Audio(label="Generated Speech", type="numpy"),
)

file_translate = gr.Interface(
    fn=speech_to_speech_translation,
    inputs=gr.Audio(source="upload", type="filepath"),
    outputs=gr.Audio(label="Generated Speech", type="numpy"),
)

with demo:
    gr.TabbedInterface([mic_translate, file_translate], ["Microphone", "Audio File"])

demo.launch(debug=True)
```

В результате будет запущена демо Gradio, аналогичная той, что работает на Hugging Face Space:

Вы можете [дублировать](https://huggingface.co/spaces/course-demos/speech-to-speech-translation?duplicate=true) это демо и адаптировать его для
использования другой контрольной точки Whisper, другой контрольной точки TTS, или отказаться от ограничений по выводу английской речи
и следовать советам по переводу на выбранный вами язык!

## Двигаемся вперед

Хотя каскадная система представляет собой эффективный с точки зрения вычислений и данных способ построения системы STST, она страдает от описанных выше 
проблем распространения ошибок и аддитивной задержки. В последних работах исследовался *прямой* подход к STST, который не прогнозирует промежуточный
текстовый вывод, а напрямую переводит исходную речь в целевую. Эти системы также способны сохранять в целевой речи речевые характеристики 
диктора-источника (такие как просодия, высота тона и интонация). Если вы хотите узнать больше об этих системах, ознакомьтесь с ресурсами,
перечисленными в секции [дополнительные материалы и ресурсы](supplemental_reading).

### Практическое занятие
https://huggingface.co/learn/audio-course/ru/chapter7/hands-on.md

# Практическое занятие

В этом разделе мы объединили материал, рассмотренный в предыдущих шести разделах курса, для создания трех интегрированных
аудио приложений. Как вы убедились, создание более сложных аудио инструментов вполне достижимо при использовании базовых навыков работы 
приобретенных в рамках данного курса.

В практическом занятии используется одно из приложений, рассматриваемых в данном разделе, которое расширяется с помощью нескольких многоязычных
функций 🌍. Ваша задача - взять [каскадный перевод речи в речь из Gradio демо](https://huggingface.co/spaces/course-demos/speech-to-speech-translation)
из первого урока данного раздела и модернизировать его для перевода на любой **неанглийский** язык. То есть демо
должно принимать речь на языке X и переводить ее в речь на языке Y, где целевой язык Y не является английским.
Начать следует с [дублирования](https://huggingface.co/spaces/course-demos/speech-to-speech-translation?duplicate=true) шаблона в вашем пространстве 
имен Hugging Face. Нет необходимости использовать GPU-ускоритель - бесплатный уровень подписки с CPU отлично справится с этой задачей 🤗.
Однако следует убедиться, что видимость вашего демо установлена в **public**. Это необходимо для того, чтобы ваше демо было доступно для нас
и могло быть проверено на корректность.

Советы по обновлению функции перевода речи для выполнения многоязычного перевода приведены в разделе [перевод речи в речь](speech-to-speech). 
Следуя этим инструкциям, вы сможете обновить демо версию для перевода с речи на языке X в текст на языке Y, а это уже половина задачи!

Для синтеза из текста на языке Y в речь на языке Y, где Y - многоязычный язык, вам потребуется [NL] использовать контрольную точку многоязычной модели TTS.

Для этого можно использовать либо контрольную точку SpeechT5 TTS, которую вы дообучали на предыдущем практическом занятии, либо предварительно
обученную контрольную точку многоязычной TTS. Существует два варианта предварительно обученных контрольных точек: либо контрольная точка
[sanchit-gandhi/speecht5_tts_vox_nl](https://huggingface.co/sanchit-gandhi/speecht5_tts_vox_nl), которая представляет собой контрольную точку SpeechT5,
дообученную на голландском фрагменте набора данных [VoxPopuli](https://huggingface.co/datasets/facebook/voxpopuli) [NL], либо контрольная точка MMS TTS
(смотрите  раздел [предварительно обученные модели text-to-speech](../chapter6/pre-trained_models)).

    По нашему опыту экспериментов с голландским языком, использование контрольной точки MMS TTS дает лучшую производительность, чем
    с дообученной SpeechT5, но вы можете обнаружить, что ваша дообученная контрольная точка TTS предпочтительнее для вашего языка.
    Если вы решили использовать контрольную точку MMS TTS, вам необходимо обновить requirements.txt
    файл вашей демонстрации для установки transformers из ветки PR:
    git+https://github.com/hollance/transformers.git@6900e8ba6532162a8613d2270ec2286c3f58f57b

Ваше демо должно принимать на вход аудиофайл, а на выходе возвращать другой аудиофайл, соответствующий сигнатуре функции 
[`speech_to_speech_translation`](https://huggingface.co/spaces/course-demos/speech-to-speech-translation/blob/3946ba6705a6632a63de8672ac52a482ab74b3fc/app.py#L35) [NL] в шаблоне демо.

Поэтому мы рекомендуем оставить основную функцию `speech_to_speech_translation` как есть, и обновлять лишь функции [`translate`](https://huggingface.co/spaces/course-demos/speech-to-speech-translation/blob/a03175878f522df7445290d5508bfb5c5178f787/app.py#L24)
 и [`synthesise`](https://huggingface.co/spaces/course-demos/speech-to-speech-translation/blob/a03175878f522df7445290d5508bfb5c5178f787/app.py#L29) по мере необходимости.

После того как вы создали своё демо в виде приложения Gradio на Hugging Face Hub, вы можете отправить его на оценку. Перейдите в пространство 
[audio-course-u7-assessment](https://huggingface.co/spaces/huggingface-course/audio-course-u7-assessment) и при появлении запроса укажите идентификатор репозитория вашего демо.
Этот пространство проверяет правильность сборки демо-версии, посылая [NL] образец аудиофайла в демо и проверяя, что возвращаемый аудиофайл действительно неанглийский.

Если ваше демо работает корректно, вы получите зеленую галочку рядом с вашим именем в общем [пространстве прогресса](https://huggingface.co/spaces/MariaK/Check-my-progress-Audio-Course) ✅.

### Транскрибирование встречи
https://huggingface.co/learn/audio-course/ru/chapter7/transcribe-meeting.md

# Транскрибирование встречи

В этом заключительном разделе мы используем модель Whisper для создания транскрипции разговора или встречи между двумя или более говорящими. Затем мы объединим
ее с моделью *диаризации диктора* для прогнозирования "кто когда говорил". Сопоставив временные метки из транскрипции Whisper с временными метками от модели диаризации,
мы можем спрогнозировать сквозную транскрипцию встречи с полностью отформатированным временем начала и окончания для каждого говорящего. Это базовая версия услуг по
транскрибированию совещаний, которую вы могли видеть в интернете от таких компаний, как [Otter.ai](https://otter.ai) и др:

     
 

## Диаризация диктора

Диаризация диктора (или диаризация) - это задача получения немаркированных аудиоданных и прогнозирования того, "кто когда говорил". При этом мы можем
прогнозировать временные метки начала/окончания каждой очереди дикторов, соответствующие моменту начала речи и моменту ее окончания.

🤗 В настоящее время в библиотеке Transformers нет модели для диаризации диктора, но на Hub есть контрольные точки, которые можно использовать
с относительной легкостью. В этом примере мы будем использовать предварительно обученную модель диаризации диктора из [pyannote.audio](https://github.com/pyannote/pyannote-audio).
Давайте приступим к работе и установим пакет с помощью pip:

```bash
pip install --upgrade pyannote.audio
```

Отлично! Веса для этой модели размещены на Hugging Face Hub. Чтобы получить к ним доступ, сначала нужно согласиться с условиями использования модели диаризации
диктора: [pyannote/speaker-diarization](https://huggingface.co/pyannote/speaker-diarization). А затем - с условиями использования модели
сегментации: [pyannote/segmentation](https://huggingface.co/pyannote/segmentation).

После завершения работы мы можем загрузить предварительно обученный конвейер диаризации дикторов локально на наше устройство:

```python
from pyannote.audio import Pipeline

diarization_pipeline = Pipeline.from_pretrained(
    "pyannote/speaker-diarization@2.1", use_auth_token=True
)
```

Давайте опробуем его на примере аудиофайла! Для этого мы загрузим образец из датасета [LibriSpeech ASR](https://huggingface.co/datasets/librispeech_asr), содержащий речь
двух разных дикторов, который мы объединили в один аудиофайл:

```python
from datasets import load_dataset

concatenated_librispeech = load_dataset(
    "sanchit-gandhi/concatenated_librispeech", split="train", streaming=True
)
sample = next(iter(concatenated_librispeech))
```

Мы можем прослушать аудиозапись, чтобы понять, как она звучит:

```python
from IPython.display import Audio

Audio(sample["audio"]["array"], rate=sample["audio"]["sampling_rate"])
```

Класс! Мы отчетливо слышим двух разных дикторов с переходом примерно на 15 секунде звучания. Давайте передадим этот аудиофайл в модель диаризации, чтобы получить
время начала и окончания разговора. Заметим, что pyannote.audio ожидает, что входной аудиофайл будет представлять собой тензор PyTorch формы `(channels, seq_len)`,
поэтому перед запуском модели нам необходимо выполнить это преобразование:

```python
import torch

input_tensor = torch.from_numpy(sample["audio"]["array"][None, :]).float()
outputs = diarization_pipeline(
    {"waveform": input_tensor, "sample_rate": sample["audio"]["sampling_rate"]}
)

outputs.for_json()["content"]
```

```text
[{'segment': {'start': 0.4978125, 'end': 14.520937500000002},
  'track': 'B',
  'label': 'SPEAKER_01'},
 {'segment': {'start': 15.364687500000002, 'end': 21.3721875},
  'track': 'A',
  'label': 'SPEAKER_00'}]
```

Выглядит это довольно неплохо! Видно, что первый диктор говорит до отметки 14,5 секунды, а второй - с 15,4 секунды.
Теперь нам нужно получить транскрипцию!

## Транскрибирование речи

В третий раз в этом блоке мы будем использовать модель Whisper для нашей системы транскрипции речи. В частности, мы загрузим контрольную точку [Whisper Base](https://huggingface.co/openai/whisper-base),
поскольку она достаточно мала, чтобы обеспечить хорошую скорость инференса при приемлемой точности транскрипции. Как и прежде, вы можете использовать любую контрольную точку распознавания речи с 
[Hub](https://huggingface.co/models?pipeline_tag=automatic-speech-recognition&library=transformers&sort=trending), включая Wav2Vec2, MMS ASR или другие контрольные точки Whisper:

```python
from transformers import pipeline

asr_pipeline = pipeline(
    "automatic-speech-recognition",
    model="openai/whisper-base",
)
```

Давайте получим транскрипцию для нашего образца аудиозаписи, возвращая также временные метки на уровне сегментов, чтобы знать время начала и окончания каждого сегмента.
Из раздела 5 вы помните, что для активации задачи прогнозирования временных меток в Whisper нам необходимо передать аргумент `return_timestamps=True`:

```python
asr_pipeline(
    sample["audio"].copy(),
    generate_kwargs={"max_new_tokens": 256},
    return_timestamps=True,
)
```

```text
{
    "text": " The second and importance is as follows. Sovereignty may be defined to be the right of making laws. In France, the king really exercises a portion of the sovereign power, since the laws have no weight. He was in a favored state of mind, owing to the blight his wife's action threatened to cast upon his entire future.",
    "chunks": [
        {"timestamp": (0.0, 3.56), "text": " The second and importance is as follows."},
        {
            "timestamp": (3.56, 7.84),
            "text": " Sovereignty may be defined to be the right of making laws.",
        },
        {
            "timestamp": (7.84, 13.88),
            "text": " In France, the king really exercises a portion of the sovereign power, since the laws have",
        },
        {"timestamp": (13.88, 15.48), "text": " no weight."},
        {
            "timestamp": (15.48, 19.44),
            "text": " He was in a favored state of mind, owing to the blight his wife's action threatened to",
        },
        {"timestamp": (19.44, 21.28), "text": " cast upon his entire future."},
    ],
}
```

Отлично! Мы видим, что каждый сегмент транскрипции имеет начальное и конечное время, причем смена дикторов происходит на отметке 15,48 секунды. Теперь мы можем сопоставить
эту транскрипцию с временными метками дикторов, полученными с помощью модели диаризации, и получить окончательную транскрипцию.

## Speechbox

Чтобы получить окончательную транскрипцию, совместим временные метки, полученные с помощью модели диаризации, с временными метками, полученными с помощью модели Whisper.
Модель диаризации предсказала окончание речи первого диктора на 14,5 с, а второго - на 15,4 с, в то время как Whisper предсказал границы сегментов на 13,88, 15,48 и 19,44 с соответственно.
Поскольку временные метки, полученные с помощью Whisper, не полностью совпадают с данными модели диаризации, нам необходимо найти, какие из этих границ ближе всего к 14,5 и 15,4 с, и
соответствующим образом сегментировать транскрипцию по дикторам. В частности, мы найдем наиболее близкое совпадение между временными метками диаризации и транскрипции,
минимизировав абсолютное расстояние между ними.

К счастью для нас, мы можем использовать пакет 🤗 Speechbox для выполнения этого выравнивания. Сначала давайте установим пакет `speechbox` из main:

```bash
pip install git+https://github.com/huggingface/speechbox
```

Теперь мы можем инстанцировать наш комбинированный конвейер диаризации и транскрипции, передав модель диаризации и
модель ASR в класс [`ASRDiarizationPipeline`](https://github.com/huggingface/speechbox/tree/main#asr-with-speaker-diarization):

```python
from speechbox import ASRDiarizationPipeline

pipeline = ASRDiarizationPipeline(
    asr_pipeline=asr_pipeline, diarization_pipeline=diarization_pipeline
)
```

    Вы также можете инстанцировать  ASRDiarizationPipeline directly непосредственно из предварительно обученных моделей, указав идентификатор 
    модели ASR на Hub:
    pipeline = ASRDiarizationPipeline.from_pretrained("openai/whisper-base")

Передадим аудиофайл в композитный конвейер и посмотрим, что получится в результате:

```python
pipeline(sample["audio"].copy())
```

```text
[{'speaker': 'SPEAKER_01',
  'text': ' The second and importance is as follows. Sovereignty may be defined to be the right of making laws. In France, the king really exercises a portion of the sovereign power, since the laws have no weight.',
  'timestamp': (0.0, 15.48)},
 {'speaker': 'SPEAKER_00',
  'text': " He was in a favored state of mind, owing to the blight his wife's action threatened to cast upon his entire future.",
  'timestamp': (15.48, 21.28)}]
```

Отлично! Первый диктор сегментирован как говорящий с 0 до 15,48 секунды, а второй - с 15,48 до 21,28 секунды,
с соответствующими транскрипциями для каждого из них.

Для более удобного форматирования временных меток можно определить две вспомогательные функции. Первая преобразует кортеж временных меток в строку, округленную
до заданного количества знаков после запятой. Вторая объединяет идентификатор диктора, временную метку и текстовую информацию в одну строку, а для удобства
чтения разбивает каждого диктора на отдельные строки:

```python
def tuple_to_string(start_end_tuple, ndigits=1):
    return str((round(start_end_tuple[0], ndigits), round(start_end_tuple[1], ndigits)))

def format_as_transcription(raw_segments):
    return "\n\n".join(
        [
            chunk["speaker"] + " " + tuple_to_string(chunk["timestamp"]) + chunk["text"]
            for chunk in raw_segments
        ]
    )
```

Повторно запустим конвейер, на этот раз форматируя транскрипцию в соответствии с функцией, которую мы только что определили:

```python
outputs = pipeline(sample["audio"].copy())

format_as_transcription(outputs)
```

```text
SPEAKER_01 (0.0, 15.5) The second and importance is as follows. Sovereignty may be defined to be the right of making laws.
In France, the king really exercises a portion of the sovereign power, since the laws have no weight.

SPEAKER_00 (15.5, 21.3) He was in a favored state of mind, owing to the blight his wife's action threatened to cast upon
his entire future.
```

Вот так! Таким образом, мы провели диарирование и транскрибацию входного аудиосигнала и получили транскрибации с сегментацией дикторов. Хотя алгоритм минимального расстояния для
выравнивания временных меток диаризации и транскрибации прост, он хорошо работает на практике. Если вы хотите изучить более сложные методы совмещения временных меток, то исходный
код `ASRDiarizationPipeline` является хорошей отправной точкой: [speechbox/diarize.py](https://github.com/huggingface/speechbox/blob/96d2d1a180252d92263f862a1cd25a48860f1aed/src/speechbox/diarize.py#L12)

### Раздел 7. Собираем все воедино 🪢
https://huggingface.co/learn/audio-course/ru/chapter7/introduction.md

# Раздел 7. Собираем все воедино 🪢

Молодцы, что добрались до 7-го раздела 7 🥳 Вы находитесь всего в нескольких шагах от завершения курса и приобретения нескольких последних
навыков, необходимых для работы в области Аудио ML. Что касается понимания, то вы уже знаете все, что нужно знать!
Вместе мы всесторонне рассмотрели основные темы, составляющие аудио домен, и сопутствующую им теорию 
(аудио данные, классификацию аудиоданных, распознавание речи и преобразование текста в речь). Целью данного раздела является создание основы
для **сочетания всего этого вместе**: теперь, когда вы знаете, как работает каждая из этих задач в отдельности, мы рассмотрим, как
вы можете объединить их вместе для создания некоторых реальных приложений. 

## Чему вы научитесь и что создадите

В этом разделе мы рассмотрим следующие три темы:

* [Перевод речи в речь](speech-to-speech): перевод речи с одного языка в речь на другом языке
* [Создание голосового ассистента](voice-assistant): создание собственного голосового помощника, работающего аналогично Alexa или Siri
* [Транскрибирование встреч](transcribe-meeting): транскрибация встречи и маркировка транскрипции с указанием того, кто когда выступал

### Создание голосового ассистента
https://huggingface.co/learn/audio-course/ru/chapter7/voice-assistant.md

# Создание голосового ассистента

В этом разделе мы объединим три модели, с которыми уже имели практический опыт работы, и создадим полноценный голосовой помощник под названием **Marvin** 🤖. 
Подобно Amazon Alexa или Apple Siri, Marvin - это виртуальный голосовой помощник, который реагирует на определенное "слово активации", затем слушает голосовой 
запрос и, наконец, отвечает на него.

Мы можем разбить конвейер голосового помощника на четыре этапа, каждый из которых требует отдельной модели:

     
 

### 1. Обнаружение слова активации

Голосовые помощники постоянно прослушивают аудиосигналы, поступающие через микрофон вашего устройства, но включаются 
в работу только после произнесения определенного 'слова активации' или 'триггерного слова'.

Задачу обнаружения слов активации решает небольшая модель классификации звука на устройстве, которая значительно меньше и легче модели
распознавания речи - часто всего несколько миллионов параметров по сравнению с несколькими сотнями миллионов для распознавания речи. Таким 
образом, она может постоянно работать на устройстве, не разряжая аккумулятор. Только при обнаружении "слова активации" запускается более 
крупная модель распознавания речи, после чего она снова отключается.

### 2. Транскрибирование речи

Следующий этап - транскрибация произнесенного запроса в текст. На практике передача аудиофайлов с локального устройства в облако происходит 
медленно из-за большого размера аудиофайлов, поэтому эффективнее транскрибировать их напрямую с помощью модели автоматического распознавания речи (ASR)
на устройстве, а не использовать модель в облаке. Модель на устройстве может быть меньше и, следовательно, менее точной, чем модель, размещенная в облаке,
но более высокая скорость инференса оправдывает себя, поскольку мы можем работать с распознаванием речи практически в реальном времени, транскрибируя
произнесенные нами фразы по мере их произнесения.

Мы уже хорошо знакомы с процессом распознавания речи, так что это должно быть проще простого!

### 3. Запрос к языковой модели

Теперь, когда мы знаем, что спросил пользователь, нам нужно сгенерировать ответ! Лучшими моделями-кандидатами для решения этой задачи являются
*большие языковые модели (Large Language Models, LLM)*, поскольку они способны эффективно понять семантику текстового запроса
и сгенерировать подходящий ответ.

Поскольку наш текстовый запрос невелик (всего несколько текстовых токенов), а языковые модели велики (многие миллиарды параметров), наиболее эффективным
способом проведения инференса LLM является отправка текстового запроса с устройства на LLM, запущенную в облаке, генерация текстового ответа и возврат
ответа обратно на устройство.

### 4. Синтез речи

Наконец, мы используем модель преобразования текста в речь (TTS) для синтеза текстового ответа в устную речь. Это делается на устройстве, но можно запустить
модель TTS в облаке, генерируя аудио вывод и передавая его обратно на устройство.

Опять же, мы делали это уже несколько раз, так что процесс будет очень знакомым!

    Следующий раздел требует использования микрофона для записи голосового ввода. Поскольку машины Google Colab не совместимы с микрофоном,
    рекомендуется выполнять этот раздел локально, либо на CPU, либо на GPU, если у вас есть доступ к локальным ресурсам. Размеры контрольных точек
    были выбраны достаточно малыми для достаточно быстрой работы на CPU, поэтому Вы получите хорошую производительность и без GPU.

## Обнаружение слова активации

Первым этапом работы голосового помощника является определение того, было ли произнесено слово активации, для решения этой задачи нам необходимо найти подходящую
предварительно обученную модель! Из раздела [Предварительно обученные модели классификации звука](../chapter4/classification_models) вы помните, что 
[Speech Commands](https://huggingface.co/datasets/speech_commands) - это набор устных слов, предназначенный для оценки моделей классификации звука на 15+ простых
командных словах, таких как `"вверх"`, `"вниз"`, `"да"` и `"нет"`, а также метка `"тишина"` для классификации отсутствия речи. Уделите минутку прослушиванию
образцов в программе просмотра наборов данных на Hub и заново познакомиться с набором данных Speech Commands: [datasets viewer](https://huggingface.co/datasets/speech_commands/viewer/v0.01/train).

Мы можем взять модель классификации звука, предварительно обученную на наборе данных Speech Commands, и выбрать одно из этих простых командных слов
в качестве слова активации. Если из 15 с лишним возможных командных слов модель предсказывает выбранное нами слово активации с наибольшей
вероятностью, мы можем быть уверены, что оно было произнесено". 

Давайте зайдем в Hugging Face Hub и перейдем на вкладку "Models": https://huggingface.co/models.

В результате будут отображены все модели на Hugging Face Hub, отсортированные по количеству загрузок за последние 30 дней:

     
 

С левой стороны вы заметите, что у нас есть ряд вкладок, которые мы можем выбрать для фильтрации моделей по задачам, библиотекам, набору данных и т.д.
Прокрутите страницу вниз и выберите задачу " Audio Classification " из списка задач аудио:

     
 

Теперь нам представлено подмножество из 500+ моделей классификации звука на Hub. Для дальнейшего уточнения этой выборки мы можем 
отфильтровать модели по датасету. Перейдите на вкладку "Datasets" и в строке поиска введите "speech_commands". При вводе текста
под вкладкой поиска появится выделение `speech_commands. Нажав на эту кнопку, можно отфильтровать все модели классификации звука на те,
которые были дообучены на датасете Speech Commands:

     
 

Отлично! Мы видим, что для данного датасета и задачи нам доступны шесть предварительно обученных моделей (хотя, если вы
читаете этот материал позднее, могут быть добавлены новые модели!) Первую из этих моделей вы узнаете как [Audio Spectrogram Transformer checkpoint](https://huggingface.co/MIT/ast-finetuned-speech-commands-v2)
которую мы использовали в примере 4-го раздела. Мы снова будем использовать эту контрольную точку для задачи определения слова активации.

Перейдем к загрузке контрольной точки с помощью класса `pipeline`:

```python
from transformers import pipeline
import torch

device = "cuda:0" if torch.cuda.is_available() else "cpu"

classifier = pipeline(
    "audio-classification", model="MIT/ast-finetuned-speech-commands-v2", device=device
)
```

Мы можем проверить, на каких метках обучалась модель, проверив атрибут `id2label` в конфигурации модели:

```python
classifier.model.config.id2label
```

Отлично! Мы видим, что модель была обучена на 35 метках классов, включая некоторые простые командные слова, которые мы описали выше, а
также некоторые конкретные объекты, такие как `"bed"`, `"house"` и `"cat"`. Мы видим, что в этих метках класса есть одно имя: 
id 27 соответствует метке **"marvin "**:

```python
classifier.model.config.id2label[27]
```

```
'marvin'
```

Отлично! Мы можем использовать это имя в качестве слова активации для нашего голосового помощника, подобно тому, как используется
"Alexa" для Amazon Alexa или "Hey Siri" для Apple Siri. Если из всех возможных меток модель с наибольшей вероятностью предсказывает
`"marvin"`, мы можем быть уверены, что выбранное нами слово активации было произнесено.  

Теперь нам необходимо определить функцию, которая будет постоянно прослушивать микрофонный вход нашего устройства и непрерывно передавать
звук в модель классификации для проведения инференса. Для этого мы воспользуемся удобной вспомогательной функцией, входящей 
в состав 🤗 Transformers, под названием [`ffmpeg_microphone_live`](https://github.com/huggingface/transformers/blob/fb78769b9c053876ed7ae152ee995b0439a4462a/src/transformers/pipelines/audio_utils.py#L98).

Эта функция направляет в модель для классификации небольшие фрагменты звука заданной длины `chunk_length_s`. Для обеспечения плавных 
границ между фрагментами звука мы используем скользящее окно с шагом `chunk_length_s / 6`. Чтобы не ждать, пока запишется весь первый фрагмент,
прежде чем приступить к инференсу, мы также определяем минимальную продолжительность по времени аудио входа `stream_chunk_s`,
который передается в модель до достижения времени `chunk_length_s`.

Функция `ffmpeg_microphone_live` возвращает объект *generator*, создающий последовательность аудиофрагментов, каждый из которых может быть
передан модели классификации для предсказания. Мы можем передать этот генератор непосредственно в `pipeline`, который, в свою очередь,
возвращает на выходе последовательность прогнозов, по одному для каждого фрагмента входного аудиосигнала. Мы можем просмотреть вероятности
меток классов для каждого фрагмента и остановить цикл обнаружения слов активации, когда обнаружим, что слово активации было произнесено.

Для классификации произнесения слова активации мы будем использовать очень простой критерий: если метка класса с наибольшей вероятностью является
словом активации и эта вероятность превышает порог `prob_threshold`, то мы объявляем, что слово активации было произнесено. Использование порога
вероятности для управления классификатором таким образом гарантирует, что слово активации не будет ошибочно предсказано, если аудиосигнал является
шумом, что обычно происходит, когда модель очень неопределенна и все вероятности меток классов низки. Возможно, вы захотите настроить этот порог
вероятности или использовать более сложные средства для принятия решения о слове активации с помощью метрики [*entropy*](https://en.wikipedia.org/wiki/Entropy_(information_theory))
(или метрики, основанной на неопределенности).

```python
from transformers.pipelines.audio_utils import ffmpeg_microphone_live

def launch_fn(
    wake_word="marvin",
    prob_threshold=0.5,
    chunk_length_s=2.0,
    stream_chunk_s=0.25,
    debug=False,
):
    if wake_word not in classifier.model.config.label2id.keys():
        raise ValueError(
            f"Wake word {wake_word} not in set of valid class labels, pick a wake word in the set {classifier.model.config.label2id.keys()}."
        )

    sampling_rate = classifier.feature_extractor.sampling_rate

    mic = ffmpeg_microphone_live(
        sampling_rate=sampling_rate,
        chunk_length_s=chunk_length_s,
        stream_chunk_s=stream_chunk_s,
    )

    print("Listening for wake word...")
    for prediction in classifier(mic):
        prediction = prediction[0]
        if debug:
            print(prediction)
        if prediction["label"] == wake_word:
            if prediction["score"] > prob_threshold:
                return True
```

Давайте опробуем эту функцию и посмотрим, как она работает! Установим флаг `debug=True`, чтобы выводить прогнозы для каждого фрагмента звука. Пусть модель
поработает несколько секунд, чтобы увидеть, какие предсказания она делает при отсутствии речевого ввода, затем четко произнесем слово активации `"marvin"`
и увидим, как предсказание метки класса для `"marvin"` подскочит почти до 1:

```python
launch_fn(debug=True)
```

```text
Listening for wake word...
{'score': 0.055326107889413834, 'label': 'one'}
{'score': 0.05999856814742088, 'label': 'off'}
{'score': 0.1282748430967331, 'label': 'five'}
{'score': 0.07310110330581665, 'label': 'follow'}
{'score': 0.06634809821844101, 'label': 'follow'}
{'score': 0.05992642417550087, 'label': 'tree'}
{'score': 0.05992642417550087, 'label': 'tree'}
{'score': 0.999913215637207, 'label': 'marvin'}
```

Потрясающе! Как мы и ожидали, в течение первых нескольких секунд модель генерирует "мусорные" предсказания. Речевой ввод отсутствует, поэтому модель 
делает прогнозы, близкие к случайным, но с очень низкой вероятностью. Как только мы произносим слово активации, модель прогнозирует `"marvin"`
с вероятностью, близкой к 1, и завершает цикл, сигнализируя о том, что слово активации обнаружено и система ASR должна быть активирована!

## Транскрибирование речи

И снова мы будем использовать модель Whisper для нашей системы транскрипции речи. В частности, мы загрузим контрольную точку
[Whisper Base English](https://huggingface.co/openai/whisper-base.en), поскольку она достаточно мала, чтобы обеспечить хорошую скорость инференса при приемлемой
точности транскрипции. Мы будем использовать трюк, позволяющий получить транскрипцию практически в реальном времени за счет умного подхода к передаче аудиосигнала
в модель. Как и прежде, можно использовать любую контрольную точку распознавания речи на [Hub](https://huggingface.co/models?pipeline_tag=automatic-speech-recognition&library=transformers&sort=trending),
включая Wav2Vec2, MMS ASR или другие контрольные точки Whisper:

```python
transcriber = pipeline(
    "automatic-speech-recognition", model="openai/whisper-base.en", device=device
)
```

    Если вы используете GPU, вы можете увеличить размер контрольной точки, чтобы использовать контрольную точку Whisper Small English,
    которая обеспечит более высокую точность транскрипции и при этом не превысит требуемый порог задержки.
    Просто поменяйте id модели на: "openai/whisper-small.en".

Теперь мы можем определить функцию для записи сигнала с микрофона и транскрипции соответствующего текста. С помощью вспомогательной
функции `ffmpeg_microphone_live` мы можем управлять тем, насколько `в реальном времени` работает наша модель распознавания речи.
Использование меньшего `stream_chunk_s` позволяет распознавать речь в реальном времени, поскольку мы делим входной звук на более
мелкие фрагменты и транскрибируем их на лету. Однако за счет этого снижается точность, поскольку модель получает меньше контекста для инференса.  

В процессе транскрибации речи нам также необходимо знать, когда пользователь **прекращает** говорить, чтобы можно было прервать запись.
Для простоты мы будем прекращать запись с микрофона после первого `chunk_length_s` (по умолчанию это 5 секунд), но вы можете
поэкспериментировать с использованием модели [voice activity detection (VAD)](https://huggingface.co/models?pipeline_tag=voice-activity-detection&sort=trending),
чтобы предсказать, когда пользователь прекращает говорить.

```python
import sys

def transcribe(chunk_length_s=5.0, stream_chunk_s=1.0):
    sampling_rate = transcriber.feature_extractor.sampling_rate

    mic = ffmpeg_microphone_live(
        sampling_rate=sampling_rate,
        chunk_length_s=chunk_length_s,
        stream_chunk_s=stream_chunk_s,
    )

    print("Start speaking...")
    for item in transcriber(mic, generate_kwargs={"max_new_tokens": 128}):
        sys.stdout.write("\033[K")
        print(item["text"], end="\r")
        if not item["partial"][0]:
            break

    return item["text"]
```

Давайте попробуем и посмотрим, что у нас получится! Как только микрофон заработает, начинайте говорить и наблюдайте,
как ваша транскрипция появляется в полуреальном времени:

```python
transcribe()
```

```text
Start speaking...
 Hey, this is a test with the whisper model.
```

Отлично! Вы можете регулировать максимальную длину звука `chunk_length_s` в зависимости от того, насколько быстро или медленно
вы говорите (увеличить, если вам показалось, что вы не успели договорить, уменьшить, если вы были вынуждены ждать в конце), и
`stream_chunk_s` для фактора реального времени. Просто передайте их в качестве аргументов функции `transcribe`.

## Запрос к языковой модели

Теперь, когда мы получили транскрибацию нашего запроса, мы хотим сгенерировать осмысленный ответ. Для этого мы воспользуемся LLM, размещенным в облаке.
В частности, мы выберем LLM на Hugging Face Hub и воспользуемся [Inference API](https://huggingface.co/inference-api), чтобы легко
передать запрос модели.

Для начала перейдём на хаб Hugging Face. Для выбора нашей модели LLM мы воспользуемся [🤗 Open LLM Leaderboard](https://huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard)
пространством, которое ранжирует модели LLM по производительности в четырех задачах генерации. Мы будем искать по "instruct", чтобы отфильтровать модели, которые были дообучены
на инструкциях, так как они должны лучше работать для нашей задачи передачи запроса (querying task):

     
 

Мы будем использовать контрольную точку [tiiuae/falcon-7b-instruct](https://huggingface.co/tiiuae/falcon-7b-instruct) от [TII](https://www.tii.ae/) - LM с декодером только на 7B параметров,
которая дообучена на смеси датасетов чатов и инструкций. Вы можете использовать любую LLM на Hugging Face Hub, у которой активирован параметр "Hosted inference API",
просто обратите внимание на виджет в правой части карточки модели:

     
 

Inference API позволяет отправить HTTP-запрос с локальной машины на LLM, размещенную на Hub, и возвращает ответ в виде файла `json`.
Все, что нам нужно, - это указать наш токен Hugging Face Hub (который мы получаем непосредственно из нашей папки Hugging Face Hub)
и идентификатор модели LLM, которой мы хотим передать запрос:

```python
from huggingface_hub import HfFolder
import requests

def query(text, model_id="tiiuae/falcon-7b-instruct"):
    api_url = f"https://api-inference.huggingface.co/models/{model_id}"
    headers = {"Authorization": f"Bearer {HfFolder().get_token()}"}
    payload = {"inputs": text}

    print(f"Querying...: {text}")
    response = requests.post(api_url, headers=headers, json=payload)
    return response.json()[0]["generated_text"][len(text) + 1 :]
```

Давайте попробуем это сделать с помощью тестового ввода!

```python
query("What does Hugging Face do?")
```

```
'Hugging Face is a company that provides natural language processing and machine learning tools for developers. They'
```

Вы можете заметить, насколько быстро выполняется инференс с помощью Inference API - нам нужно отправить лишь небольшое количество текстовых токенов
с нашей локальной машины на размещенную на сервере модель, поэтому затраты на связь очень малы. LLM размещается на GPU-ускорителях, поэтому инференс
выполняется очень быстро. Наконец, сгенерированный ответ передается обратно от модели на нашу локальную машину,
что также не требует больших коммуникационных затрат.

## Синтез речи

Теперь мы готовы к получению окончательного речевого вывода! В очередной раз мы будем использовать модель Microsoft [SpeechT5 TTS](https://huggingface.co/microsoft/speecht5_tts)
для TTS на английском языке, но вы можете использовать любую модель TTS по своему усмотрению. Давайте загрузим процессор и модель:

```python
from transformers import SpeechT5Processor, SpeechT5ForTextToSpeech, SpeechT5HifiGan

processor = SpeechT5Processor.from_pretrained("microsoft/speecht5_tts")

model = SpeechT5ForTextToSpeech.from_pretrained("microsoft/speecht5_tts").to(device)
vocoder = SpeechT5HifiGan.from_pretrained("microsoft/speecht5_hifigan").to(device)
```

А также эбеддинги диктора:

```python
from datasets import load_dataset

embeddings_dataset = load_dataset("Matthijs/cmu-arctic-xvectors", split="validation")
speaker_embeddings = torch.tensor(embeddings_dataset[7306]["xvector"]).unsqueeze(0)
```

Мы повторно используем функцию `synthesise`, которую мы определили в предыдущей главе [Перевод речи в речь] (speech-to-speech):

```python
def synthesise(text):
    inputs = processor(text=text, return_tensors="pt")
    speech = model.generate_speech(
        inputs["input_ids"].to(device), speaker_embeddings.to(device), vocoder=vocoder
    )
    return speech.cpu()
```

Давайте быстро проверим, что все работает так, как и ожидается:

```python
from IPython.display import Audio

audio = synthesise(
    "Hugging Face is a company that provides natural language processing and machine learning tools for developers."
)

Audio(audio, rate=16000)
```

Отличная работа 👍

## Марвин 🤖

Теперь, когда мы определили функцию для каждого из четырех этапов конвейера голосового помощника, осталось только собрать их вместе,
чтобы получить готовый голосовой помощник. Мы просто объединим все четыре этапа, начиная с обнаружения слов активации (`launch_fn`),
транскрипции речи, передачи запроса LLM и заканчивая синтезом речи.

```python
launch_fn()
transcription = transcribe()
response = query(transcription)
audio = synthesise(response)

Audio(audio, rate=16000, autoplay=True)
```

Попробуйте сделать это с помощью нескольких запросов! Вот несколько примеров для начала:
* Какая самая жаркая страна в мире?
* Как работают модели-трансформеры?
* Знаешь ли ты испанский язык?

Вот и все, у нас есть готовый голосовой помощник, созданный с использованием 🤗 аудио инструментов, которые вы изучили в этом курсе, с добавлением в конце волшебства LLM.
Есть несколько расширений, которые мы могли бы сделать для улучшения голосового помощника. Во-первых, модель классификации звука классифицирует 35 различных меток.
Мы могли бы использовать более компактную и легкую модель бинарной классификации, которая прогнозирует только то, было ли произнесено слово активации или нет.
Во-вторых, мы заранее загружаем все модели и держим их запущенными на нашем устройстве. Если бы мы хотели сэкономить электроэнергию, то загружали бы каждую модель
только в тот момент, когда она необходима, а затем выгружали бы ее. В-третьих, в нашей функции транскрибации отсутствует модель определения активности голоса,
транскрибация осуществляется в течение фиксированного времени, которое в одних случаях слишком длинное, а в других - слишком короткое.

## Обобщаем всё 🪄

До сих пор мы видели, как можно генерировать речевой вывод с помощью нашего голосового помощника Marvin.
В заключение мы продемонстрируем, как можно обобщить этот речевой вывод на текст, аудио и изображение.

Для построения нашего помощника мы будем использовать [Transformers Agents](https://huggingface.co/docs/transformers/transformers_agents). Transformers Agents
предоставляет API для работы с естественным языком поверх библиотек 🤗 Transformers и Diffusers, интерпретирует входной сигнал на естественном языке с помощью LLM
с тщательно продуманными подсказками и использует набор курируемых инструментов для обеспечения мультимодального вывода.

Давайте перейдем к инстанцированию агента. Для агентов-трансформеров существует [три LLM](https://huggingface.co/docs/transformers/transformers_agents#quickstart), две из которых с открытым исходным кодом
и бесплатно доступны на Hugging Face Hub. Третья - модель от OpenAI, требующая ключа OpenAI API. В данном примере мы будем использовать бесплатную модель [Bigcode Starcoder](https://huggingface.co/bigcode/starcoder),
но вы также можете попробовать любую из других доступных LLM:

```python
from transformers import HfAgent

agent = HfAgent(
    url_endpoint="https://api-inference.huggingface.co/models/bigcode/starcoder"
)
```

Чтобы воспользоваться агентом, достаточно вызвать `agent.run` с нашим текстовым приглашением. В качестве примера мы попросим
его сгенерировать изображение кота 🐈 (которое, надеюсь, выглядит немного лучше, чем этот эмоджи):

```python
agent.run("Generate an image of a cat")
```

     
 

    Обратите внимание, что при первом вызове будет произведена загрузка весов модели, что может занять некоторое время
    в зависимости от скорости загрузки.

Все просто! Агент интерпретировал наш запрос и, используя [Stable Diffusion](https://huggingface.co/docs/diffusers/using-diffusers/conditional_image_generation) под капотом, 
сгенерировал изображение, при этом нам не пришлось беспокоиться о загрузке модели, написании функции или выполнении кода.

Теперь мы можем заменить функцию передачи запроса LLM и шаг синтеза текста нашим агентом Transformers Agent в голосовом помощнике,
поскольку агент будет выполнять оба этих действия за нас:

```python
launch_fn()
transcription = transcribe()
agent.run(transcription)
```

Попробуйте произнести тот же запрос " Generate an image of a cat" и посмотрите, как справится система. Если задать Агенту простой запрос "вопрос/ответ", он ответит текстовым ответом.
Можно побудить его генерировать мультимодальный вывод, попросив вернуть изображение или речь. Например, вы можете попросить его: "Generate an image of a cat, caption it, and speak the caption".

Хотя агент является более гибким, чем наш первый итерационный ассистент Marvin 🤖, обобщение задачи голосового помощника таким образом может привести к снижению производительности при выполнении
стандартных запросов к голосовому помощнику. Для восстановления производительности можно попробовать использовать более производительную контрольную точку LLM, например, от OpenAI, или определить
набор [custom tools](https://huggingface.co/docs/transformers/transformers_agents#custom-tools), специфичный для задачи голосового помощника.

### Дополнительные материалы и ресурсы
https://huggingface.co/learn/audio-course/ru/chapter7/supplemental_reading.md

# Дополнительные материалы и ресурсы

В этом разделе объединены многие компоненты из предыдущих разделов, представлены задачи перевода речи в речь, 
голосовые помощники и диаризация диктора. Для удобства чтения дополнительный материал разбит на эти три новые задачи:

Перевод речи в речь:
* [STST с дискретными блоками](https://ai.facebook.com/blog/advancing-direct-speech-to-speech-modeling-with-discrete-units/) от Meta AI: прямой подход к STST через модели энкодер-декодер
* [Hokkien прямой перевод речи в речь](https://ai.facebook.com/blog/ai-translation-hokkien/) от Meta AI: прямой подход к STST с использованием моделей энкодер-декодер с двухступенчатым декодером
* [Использование неконтролируемых и слабоконтролируемых данных для улучшения прямой STST](https://arxiv.org/abs/2203.13339) от Google: предлагает новые подходы к использованию неконтролируемых (unsupervised) и слабоконтролируемых (weakly supervised) данных для обучения прямых STST-моделей и небольшие изменения в архитектуре Transformer
* [Translatotron-2](https://google-research.github.io/lingvo-lab/translatotron2/) от Google: система, способная сохранять характеристики диктора в переведенной речи

Голосовой ассистент:
* [Точное обнаружение пробуждающих слов (wakeword)](https://www.amazon.science/publications/accurate-detection-of-wake-word-start-and-end-using-a-cnn) от Amazon: подход с низкой задержкой для обнаружения пробуждающих слов (wakeword) для приложений на устройствах
* [RNN-Transducer Архитектура](https://arxiv.org/pdf/1811.06621.pdf) от Google: модификация архитектуры CTC для потокового ASR на устройствах

Транскрипция встреч:
* [pyannote.audio Технический отчет](https://huggingface.co/pyannote/speaker-diarization/blob/main/technical_report_2.1.pdf) Эрве Бредин: в этом докладе описываются основные принципы, лежащие в основе конвейера диаризации дикторов `pyannote.audio
* [Whisper X](https://arxiv.org/pdf/2303.00747.pdf) by Max Bain et al.: усовершенствованный подход к вычислению временных меток на уровне слов с использованием модели Whisper

### Архитектуры Seq2Seq
https://huggingface.co/learn/audio-course/ru/chapter3/seq2seq.md

# Архитектуры Seq2Seq

В моделях CTC, рассмотренных в предыдущем разделе, использовалась только энкодерная часть архитектуры трансформера. В случае, когда мы добавляем декодер для создания модели энкодер-декодер, это называется моделью **последовательность-в-последовательность (sequence-to-sequence)** или
сокращенно seq2seq. Модель сопоставляет последовательность данных одного вида с последовательностью данных другого вида.

В моделях трансформеров, использующих только энкодер, энкодер делал предсказание для каждого элемента входной последовательности. Поэтому и входная, и выходная последовательности всегда будут иметь одинаковую длину. В случае моделей CTC, таких как Wav2Vec2, входная форма сигнала сначала
подвергалась даунсемплингу, но все равно на каждые 20 мс звука приходилось одно предсказание.

В модели seq2seq такого соответствия один к одному нет, и входная и выходная последовательности могут иметь разную длину. Это делает модели seq2seq пригодными для решения задач NLP, таких как резюмирование текста или перевод с одного языка на другой, а также для решения аудио задач, таких
как распознавание речи.

Архитектура декодера очень похожа на архитектуру энкодера, и в обоих случаях используются схожие слои, главной особенностью которых является самовнимание. Однако декодер выполняет иную задачу, чем энкодер. Чтобы понять, как это работает, рассмотрим, как модель seq2seq может выполнять
автоматическое распознавание речи.

## Автоматическое распознавание речи

Архитектура **Whisper** выглядит следующим образом (рисунок любезно предоставлен [блогом OpenAI Whisper](https://openai.com/blog/whisper/)):

    

Все это должно выглядеть довольно знакомо. Слева находится **энкодер трансформера**. В качестве входного сигнала принимается лог-мел спектрограмма, которая кодируется для формирования последовательности скрытых состояний энкодера, извлекающих важные признаки из произносимой речи.
Этот тензор скрытых состояний представляет входную последовательность как единое целое и эффективно кодирует "смысл" поступившей на вход речи.

💡 Обычно в таких seq2seq-моделях в качестве входных данных используются спектрограммы. Однако модель seq2seq может быть разработана и для работы непосредственно с формой волны звука.

Затем выход энкодера передается в **декодер трансформера**, показанный справа, с помощью механизма, называемого **перекрёстным вниманием (cross-attention)**. Это похоже на самовнимание (self-attention), но внимание направлено на выход энкодера. С этого момента энкодер больше не нужен.

Декодер предсказывает последовательность текстовых токенов **авторегрессивным** способом, по одному токену за раз, начиная с начальной последовательности, в которой есть только "стартовый" токен (`SOT` в случае Whisper). На каждом следующем временном интервале предыдущая выходная
последовательность подается обратно в декодер в качестве новой входной последовательности. Таким образом, декодер выдает по одному новому токену за раз, неуклонно наращивая выходную последовательность, пока не спрогнозирует "конечный" токен или не будет достигнуто максимальное количество
временных шагов.

Хотя архитектура декодера в основном идентична архитектуре кодера, есть два существенных отличия:

1. декодер имеет механизм перекрестного внимания, который позволяет ему просматривать представление энкодера о входной последовательности
2. внимание декодера является каузальным - декодер не имеет права заглядывать в будущее.

В этом случае декодер играет роль **языковой модели**, обрабатывая представления скрытых состояний, полученные от энкодера, и генерируя соответствующие текстовые транскрипции. Это более мощный подход, чем CTC, даже если модель CTC сочетается с внешней языковой моделью, так как система
seq2seq может быть обучена от начала до конца с использованием одних и тех же обучающих данных и функции потерь, что обеспечивает большую гибкость и в целом более высокую производительность.

💡 В то время как модель CTC выводит последовательность отдельных символов, токены, предсказываемые Whisper, представляют собой полные слова или фрагменты слов. Он использует токенизатор из GPT-2 и имеет 50k+ уникальных токенов. Поэтому модель seq2seq может выдать гораздо более короткую
последовательность, чем модель CTC для той же транскрипции.

Типичной функцией потерь для seq2seq ASR-модели является функция кросс-энтропии, поскольку последний слой модели предсказывает распределение вероятностей по возможным токенам. Обычно это сочетается с такими методами, как [лучевой поиск для генерации конечной последовательности](https://huggingface.co/blog/how-to-generate). Метрикой распознавания речи является WER или word error rate, которая измеряет, сколько замен, вставок и удалений необходимо для превращения предсказанного текста в целевой - чем меньше, тем лучше результат.

## Преобразование текста в речь (Text-to-speech, TTS)

Возможно, это вас не удивит: Модель seq2seq для TTS работает по сути так же, как и описанная выше, но входы и выходы поменяны местами! Энкодер трансформера принимает последовательность текстовых токенов и извлекает из нее последовательность скрытых состояний, которые представляют собой
входной текст. Декодер трансформера применяет перекрестное внимание к выходу энкодера и прогнозирует спектрограмму.

💡 Напомним, что спектрограмма создается путем взятия частотного спектра последовательных временных отрезков звуковой волны и их суммирования. Другими словами, спектрограмма - это последовательность, элементами которой являются (лог-мел) частотные спектры, по одному на каждый временной
интервал.

В ASR-модели декодер запускался с помощью последовательности, содержащей только специальный токен "start". Для модели TTS мы можем начать декодирование со спектрограммы длиной один, состоящей из одних нулей, которая выступает в качестве "стартового токена". Учитывая эту начальную
спектрограмму и перекрестное внимание к представлениям скрытых состояний энкодера, декодер предсказывает следующий временной интервал для этой спектрограммы, постепенно увеличивая спектрограмму на один временной интервал.

    

Но как декодер узнает, когда нужно остановиться? В модели **SpeechT5** это решается тем, что декодер предсказывает вторую последовательность. Она содержит вероятность того, что текущий временной шаг является последним. При генерации звука в момент инференса, если эта вероятность превышает
определенный порог (скажем, 0,5), декодер сигнализирует о том, что спектрограмма закончена и цикл генерации должен завершиться.

После завершения декодирования и получения выходной последовательности, содержащей спектрограмму, SpeechT5 использует так называемую **пост-сеть (post-net)**, состоящую из нескольких сверточных слоев, для уточнения спектрограммы.

При обучении модели TTS в качестве целей также используются спектрограммы, а в качестве потерь - L1 или MSE. Во время инференса мы хотим преобразовать выходную спектрограмму в форму звукового сигнала, чтобы ее можно было прослушать. Для этого используется внешняя модель - **вокодер
(vocoder)**. Этот вокодер не является частью архитектуры seq2seq и обучается отдельно.

Сложность TTS заключается в том, что это отображение "один-ко-многим". При преобразовании речи в текст существует только один правильный выходной текст, соответствующий входной речи, в то время как при преобразовании текста в речь входной текст может быть сопоставлен с множеством возможных
звуков речи. Например, разные дикторы могут выбирать для акцентирования внимания разные части предложения. Это затрудняет оценку моделей TTS. В связи с этим значение потерь L1 или MSE на самом деле не имеет большого смысла - существует множество способов представить один и тот же текст на
спектрограмме. Именно поэтому модели TTS обычно оцениваются слушателями, используя метрику, известную как MOS (mean opinion score) или cредняя экспертная оценка.

## Заключение

Подход seq2seq является более мощным, чем модель, основанная только на энкодере. Благодаря разделению входной последовательности энкодера и выходной последовательности декодера, выравнивание звука и текста становится менее проблематичным. 

Однако модель энкодер-декодер также является более медленной, поскольку процесс декодирования происходит по одному шагу за раз, а не все сразу. Чем длиннее последовательность, тем медленнее прогнозирование. Авторегрессивные модели также могут застревать на повторах или пропускать слова.
Такие методы, как лучевой поиск, позволяют улучшить качество прогнозов, но при этом еще больше замедляют декодирование.

### Раздел 3. Архитектуры трансформеров для аудио
https://huggingface.co/learn/audio-course/ru/chapter3/introduction.md

# Раздел 3. Архитектуры трансформеров для аудио

В этом курсе мы рассмотрим, прежде всего, трансформерные модели и их применение для решения задач аудио. Хотя вам не обязательно знать внутренние детали этих моделей, полезно понимать основные концепции, обеспечивающие их работу,
поэтому здесь мы приведем краткую справку. Для более глубокого погружения в трансформеры ознакомьтесь с нашим [курсом по NLP] (https://huggingface.co/course/chapter1/1).

## Как работает трансформер?

Оригинальная модель трансформера предназначалась для перевода письменного текста с одного языка на другой. Ее архитектура выглядела следующим образом:

    

Слева находится **энкодер**, а "справа находится **декодер**.

- Энкодер получает входной сигнал, в данном случае последовательность текстовых токенов, и строит его представление (признаки). Эта часть модели обучается для получения понимания из входных данных.

- Декодер использует представление кодера (признаки) вместе с другими входными данными (ранее предсказанными токенами) для генерации целевой последовательности. Эта часть модели обучается генерировать выходные данные. В оригинальном
дизайне выходная последовательность состояла из текстовых лексем.

Существуют также модели на основе трансформеров, использующие только энкодерную часть (хорошо подходят для задач, требующих понимания входных данных, например, для классификации) или только декодерную часть (хорошо подходят для задач,
например, для генерации текста). Примером модели, использующей только энкодер, является BERT, а примером модели, использующей только декодер, является GPT2.

Ключевой особенностью трансформерных моделей является то, что при их построении используются специальные слои, называемые **слоями внимания (attention layers)**. Эти слои указывают модели на необходимость уделять особое внимание определенным элементам входной последовательности и
игнорировать другие при вычислении представлений признаков.

## Использование трансформеров для аудио

Аудио модели, которые мы рассмотрим в этом курсе, обычно имеют стандартную архитектуру трансформера, как показано выше, но с небольшими изменениями на входе или выходе, позволяющими использовать аудио данные вместо текста. Поскольку
все эти модели по своей сути являются трансформерами, большая часть их архитектуры будет общей, а основные различия заключаются в способах их обучения и использования.

    

Для задач, связанных с аудио, входные и/или выходные последовательности могут быть не текстовыми, а звуковыми:

- Автоматическое распознавание речи (Automatic speech recognition - ASR): На входе - речь, на выходе - текст.

- Синтез речи (Text To Speech - TTS): На входе - текст, на выходе - речь.

- Классификация аудио: На входе - аудио, на выходе - вероятность класса - по одному для каждого элемента в последовательности или единая вероятность класса для всей последовательности.

- Преобразование голоса или улучшение речи: И на входе, и на выходе - аудио.

Существует несколько различных способов обработки аудио, чтобы его можно было использовать с трансформером. Основное внимание уделяется тому, использовать ли звук в исходном виде - как форму волны - или вместо этого обработать 
его как спектрограмму.

## Входы модели

Входными данными для аудио модели могут быть как текстом, так и звуком. Задача состоит в том, чтобы преобразовать эти входные данные в вектор эмбединга, который может быть обработан архитектурой трансформера.

### Текстовый ввод

Модель преобразования текста в речь принимает текст на вход. Она работает так же, как и оригинальный трансформер или любая другая модель NLP: Входной текст сначала подвергается токенизации, в результате чего получается последовательность текстовых токенов. Эта последовательность проходит
через слой эмбединга, который преобразует токены в 512-мерные векторы. Затем эти векторы эмбеддинга передаются в энкодер трансформера.

### Входной сигнал в форме волны
  
Модель автоматического распознавания речи принимает на вход аудиосигнал. Для того чтобы использовать трансформер для ASR, необходимо сначала каким-то образом преобразовать звук в последовательность векторов эмбеддинга.

Такие модели, как **Wav2Vec2** и **HuBERT**, используют непосредственно форму волны звукового сигнала в качестве входного сигнала для модели. Как вы уже видели в [главе, посвященной аудиоданным](../chapter1/introduction), форма волны
представляет собой одномерную последовательность чисел с плавающей точкой, где каждое число представляет собой амплитуду дискретизации в данный момент времени. Эта необработанная форма волны сначала нормализуется до нулевого среднего и
единичной дисперсии, что позволяет стандартизировать аудио образцы разной громкости (амплитуды).

    

После нормализации последовательность аудио образцов они превращается в эмбединг с помощью небольшой сверточной нейронной сети, называемой энкодером признаков (feature encoder). Каждый из сверточных слоев этой сети обрабатывает входную
последовательность, субсэмплируя звук для уменьшения длины последовательности, пока последний сверточный слой не выдает 512-мерный вектор с эмбдингами для каждых 25 мс звука. После преобразования входной последовательности в последовательность таких эмбеддингов трансформер обрабатывает
данные обычным образом.

### Ввод спектрограмм

Недостатком использования в качестве входных данных необработанной формы волны является то, что они, как правило, имеют большую длину последовательности. Например, тридцать секунд звука с частотой дискретизации 16 кГц дают входной
сигнал длиной `30 * 16000 = 480000`. Большая длина последовательности требует большего количества вычислений в модели трансформера, а значит, и большего объема памяти.

В связи с этим необработанные формы звуковых сигналов, как правило, не являются наиболее эффективной формой представления входного аудиосигнала. Используя спектрограмму, мы получаем тот же объем информации, но в более сжатом виде.

    

Модели типа **Whisper** сначала преобразуют форму волны в лог-мел спектрограмму. Whisper всегда разбивает звук на 30-секундные сегменты, и лог-мел спектрограмма для каждого сегмента имеет форму `(80, 3000)`, где 80 - количество
столбцов mel, а 3000 - длина последовательности. Преобразовав в лог-мел спектрограмму, мы уменьшили объем входных данных, но, что более важно, эта последовательность гораздо короче, чем исходная форма сигнала. Затем лог-мел
спектрограмма обрабатывается небольшой CNN в последовательность эмбдингов, которая, как обычно, поступает в трансформер.

В обоих случаях, как при вводе формы волны, так и спектрограммы, перед трансформером имеется небольшая сеть, которая преобразует входной сигнал в эмбеддинги, после чего трансформер начинает выполнять свою работу.

## Выходы модели

Архитектура трансформера выдает на выходе последовательность векторов скрытых состояний (hidden-state vectors), также известных как эмбеддинги на выходе. Наша цель - преобразовать эти векторы в текст или аудиоданные.

### Вывод текста

Цель модели автоматического распознавания речи - предсказать последовательность текстовых токенов. Для этого на выход трансформера добавляется голова языковой модели - как правило, один линейный слой - с последующим softmax. Таким
образом, прогнозируются вероятности для текстовых токенов в словаре.

### Вывод спектрограммы

Для моделей, генерирующих звук, таких как модель преобразования текста в речь (TTS), необходимо добавить слои, которые могут генерировать звуковую последовательность. Очень часто генерируется спектрограмма, а затем используется
дополнительная нейронная сеть, известная как вокодер, для преобразования этой спектрограммы в форму волны.

Например, в модели TTS **SpeechT5** выходной сигнал трансформера представляет собой последовательность 768-элементных векторов. Линейный слой проецирует эту последовательность в лог-мел спектрограмму. Так называемая пост-сеть,
состоящая из дополнительных линейных и сверточных слоев, уточняет спектрограмму за счет уменьшения шума. Затем вокодер формирует конечную форму звукового сигнала.

    

💡 Если взять существующую форму сигнала и применить к ней Оконное преобразование Фурье или ОПФ, то можно выполнить обратную операцию, ООПФ, чтобы снова получить исходную форму сигнала. Это работает потому, что спектрограмма, 
созданная в результате ОПФ, содержит информацию как об амплитуде, так и о фазе, а для восстановления формы волны необходимо и то, и другое. Однако аудиомодели, генерирующие выходной сигнал в виде спектрограммы, обычно 
предсказывают только амплитудную информацию, но не фазовую. Чтобы превратить такую спектрограмму в форму волны, необходимо каким-то образом оценить фазовую информацию. Этим и занимается вокодер.

### Вывод формы волны

Также существует возможность для моделей напрямую выводить форму волны вместо спектрограммы в качестве промежуточного шага, но в настоящее время в 🤗 Transformers нет ни одной модели, которая бы это делала.

## Заключение

Подведем итоги: большинство моделей аудио трансформеров скорее похожи друг на друга, чем отличаются - все они построены на одной и той же архитектуре трансформера и слоях внимания, хотя в некоторых моделях используется только
энкодерная часть трансформера, а в других - и энкодер, и декодер.

Вы также увидели, как вводить и выводить аудиоданные из трансформерных моделей. Для выполнения различных аудиозадач ASR, TTS и т.д. мы можем просто менять местами слои, которые предварительно обрабатывают входные данные в эмбеддинги, и
менять местами слои, которые после обработки предсказанных эмбеддингов превращаются в выходные данные, при этом основа трансформера остается неизменной.

Далее мы рассмотрим несколько различных способов обучения этих моделей для автоматического распознавания речи.

### Дополнительные материалы и ресурсы
https://huggingface.co/learn/audio-course/ru/chapter3/supplemental_reading.md

# Дополнительные материалы и ресурсы

Если вы хотите более подробно изучить различные архитектуры трансформеров и узнать об их применении в обработке речи, обратитесь к этой свежей статье:

### Трансформеры в обработке речи: Обзор 

Сиддик Латиф, Аун Заиди, Хериберто Куаяуитль, Фахад Шамшад, Моаззам Шукат, Джунаид Кадир

"Значительный успех трансформеров в области обработки естественного языка вызвал интерес сообщества специалистов по
обработке речи, что привело к изучению их возможностей для моделирования длительных зависимостей в речевых 
последовательностях. В последнее время трансформеры получили широкое распространение в различных областях, связанных 
с речью, включая автоматическое распознавание речи, синтез речи, перевод речи, паралингвистику речи, улучшение речи,
системы разговорного диалога и многочисленных мультимодальных приложениях. В данной статье мы представляем комплексный обзор,
цель которого - объединить исследования, проводимые в различных областях речевых технологий. Консолидируя результаты, полученные 
в области речевых технологий, мы предоставляем ценный ресурс для исследователей, заинтересованных в использовании возможностей 
трансформеров для развития этой области. Мы идентифицируем проблемы, с которыми сталкиваются трансформеры при обработке речи,
а также предлагаем потенциальные решения для их устранения".

[arxiv.org/abs/2303.11607](https://arxiv.org/abs/2303.11607)

### Архитектуры CTC
https://huggingface.co/learn/audio-course/ru/chapter3/ctc.md

# Архитектуры CTC 

CTC (Connectionist Temporal Classification) или Коннекционистская Временная Классификация это техника, используемая в моделях трансформеров состоящих только из энкодера, для задачи автоматического распознавания речи (ASR). Примерами таких моделей являются **Wav2Vec2**,
**HuBERT** и **M-CTC-T**.

Трансформеры состоящие только из энкодера, являются самыми простыми, поскольку в них используется только часть модели, состоящая из энкодера. Энкодер считывает входную
последовательность (форму волны звука) и преобразует ее в последовательность скрытых состояний, которые также известны как выходные эмбеддинги.

В модели CTC мы применяем дополнительное линейное отображение на последовательность скрытых состояний для получения предсказаний метки класса. Метками классов 
являются **символы алфавита** (a, b, c, ...). Таким образом, мы можем предсказать любое слово на целевом языке с небольшой классификационной головой, поскольку словарный запас должен состоять всего из 26 символов плюс несколько специальных токенов.

    

Пока это очень похоже на то, что мы делаем в NLP с помощью такой модели, как BERT: модель трансформер состоящая только из энкодера отображает наши текстовые токены в
последовательность скрытых состояний энкодера, а затем мы применяем линейное отображение для получения одного предсказания метки класса для каждого скрытого состояния.

Вот в чем загвоздка: в речи мы не знаем **соответствия** между входными аудио сигналами и текстовыми выходами.  Мы знаем, что порядок произнесения речи совпадает с порядком
транскрибирования текста (так называемое монотонное выравнивание), но мы не знаем, как символы в транскрипции соотносятся с аудиозаписью. В этом случае на помощь приходит алгоритм CTC.

💡 В моделях NLP словарный запас обычно состоит из тысяч токенов, которые описывают не только отдельные символы, но и части слов или даже целые слова. Однако для CTC лучше всего
подходит небольшой словарь, и мы обычно стараемся, чтобы он не превышал 50 символов. Нам не важен регистр букв, поэтому достаточно использовать только верхний регистр (или только
нижний). Числа пишутся буквами, например, `"20"` становится `" twenty"`. Помимо букв, нам необходимы как минимум токен-разделитель слов (пробел) и токен-заполнитель. Как и в модели NLP, 
токен-заполнитель позволяет объединить несколько примеров в батч, а также является токеном, который модель будет предсказывать в случае тишины. В английском языке также полезно сохранить 
символ `'`' - в конце концов, `"it's"` и `"its"` имеют совершенно разные значения.

## Дружище, где мое выравнивание?

Автоматическое распознавание речи, или ASR, подразумевает прием аудиосигнала на вход и выдачу текста на выход. У нас есть несколько вариантов того, как предсказать текст:

- как отдельные символы
- как фонемы
- как токены слова

Модель ASR обучается на наборе данных, состоящем из пар `(аудио, текст)`, где текст представляет собой транскрипцию аудиофайла, выполненную человеком. Как правило, набор данных не содержит никакой временной информации, указывающей, какое слово или слог встречается в аудиофайле. Поскольку в процессе обучения мы не можем полагаться на информацию о времени, мы не имеем представления о том, как должны быть выровнены входные и выходные последовательности.

Предположим, что на вход нам подается односекундный аудиофайл. В **Wav2Vec2** модели сначала понижают дискретизацию (downsampling) входного аудиосигнала с помощью кодера признаков CNN до более короткой последовательности скрытых состояний, где на каждые 20 миллисекунд аудиосигнала
приходится один вектор скрытых состояний. Для одной секунды звука мы передаем на энкодер трансформера последовательность из 50 скрытых состояний. (Звуковые сегменты, извлеченные из входной последовательности, частично перекрываются, поэтому, хотя один вектор скрытых состояний выдается
каждые 20 мс, каждое скрытое состояние фактически представляет собой 25 мс звука).

Энкодер трансформера предсказывает одно представление признака для каждого из этих скрытых состояний, то есть мы получаем последовательность из 50 выходов трансформера. Каждый из этих выходов имеет размерность 768. Таким образом, выходная последовательность энкодера трансформера в данном
примере имеет форму `(768, 50)`. Поскольку каждый из этих прогнозов охватывает 25 мс времени, что меньше длительности фонемы, имеет смысл прогнозировать отдельные фонемы или символы, но не целые слова. CTC лучше всего работает с небольшим словарным запасом, поэтому мы будем предсказывать символы.

    

Для предсказания текста мы сопоставляем каждый из 768-мерных выходов энкодера с метками символов с помощью линейного слоя (" голова CTC"). Затем модель предсказывает тензор `(50, 32)`, содержащий логиты, где 32 - количество токенов в словаре. Поскольку мы делаем по одному прогнозу для
каждого из признаков в последовательности, в итоге получается 50 прогнозов символов для каждой секунды звука.

Однако если мы просто прогнозируем один символ каждые 20 мс, то наша выходная последовательность может выглядеть примерно так:

```text
BRIIONSAWWSOMEETHINGCLOSETOPANICONHHISOPPONENT'SSFAACEWHENTHEMANNFINALLLYRREECOGGNNIIZEDHHISSERRRRORR ...
```

Если присмотреться, то она несколько похожа на английский язык, но многие символы продублированы. Это связано с тем, что модель должна выводить *нечто* на каждые 20 мс звука во входной последовательности, и если символ распределен на период более 20 мс, то он будет появляться на выходе
несколько раз. Избежать этого невозможно, тем более что мы не знаем, каково время транскрипции в процессе обучения. CTC - это способ отфильтровать подобные дубликаты.

(В реальности предсказанная последовательность также содержит большое количество токен-заполнителей для случаев, когда модель не совсем уверена в том, что представляет собой звук, или для пустого пространства между символами. Для наглядности мы удалили эти токены из примера. Частичное перекрытие звуковых сегментов - еще одна причина дублирования символов на выходе).

## Алгоритм CTC.

Ключом к алгоритму CTC является использование специального токена, часто называемого **пустым токеном (blank token)**. Это просто еще один токен, который модель будет предсказывать, и он является частью словаря. В данном примере пустой токен показан как `_`. Этот специальный токен служит
жесткой границей между группами символов.

Полный вывод модели CTC может выглядеть следующим образом:

```text
B_R_II_O_N_||_S_AWW_|||||_S_OMEE_TH_ING_||_C_L_O_S_E||TO|_P_A_N_I_C_||_ON||HHI_S||_OP_P_O_N_EN_T_'SS||_F_AA_C_E||_W_H_EN||THE||M_A_NN_||||_F_I_N_AL_LL_Y||||_RREE_C_O_GG_NN_II_Z_ED|||HHISS|||_ER_RRR_ORR||||
```

Токен `|` является символом-разделителем слов. В примере мы используем `|` вместо пробела, чтобы было легче определить места разрыва слов, но это служит той же цели.

Пустой символ CTC позволяет отфильтровать дублирующиеся символы. Для примера рассмотрим последнее слово из спрогнозированной последовательности, `_ER_RRR_ORR`. Без пустого токена CTC слово выглядело следующим образом:

```text
ERRRRORR
```

Если бы мы просто удалили дублирующиеся символы, то получилось бы `EROR`. Это явно не правильное написание. Но с помощью пустого токена CTC мы можем удалить дубликаты в каждой группе, так что:

```text
_ER_RRR_ORR
```

становится:

```text
_ER_R_OR
```

и теперь удаляем пустой токен `_`, чтобы получить окончательное слово:

```text
ERROR
```

Если применить эту логику ко всему тексту, включая `|`, и заменить уцелевшие символы `|` на пробелы, то конечный результат CTC-декодирования будет следующим:

```text
BRION SAW SOMETHING CLOSE TO PANIC ON HIS OPPONENT'S FACE WHEN THE MAN FINALLY RECOGNIZED HIS ERROR
```

Напомним, что модель предсказывает один токен (символ) на каждые 20 мс (частично перекрывающихся) аудиоданных из входной формы сигнала. Это порождает большое количество дубликатов. Благодаря пустому токену CTC мы можем легко удалить эти дубликаты, не нарушая правильности написания слов.
Это очень простой и удобный способ решения проблемы выравнивания выходного текста по входному звуку.

💡 В реальной модели Wav2Vec2 пустой токен CTC совпадает с токеном заполнения ``. Модель будет прогнозировать много таких токенов ``, например, когда для текущих 20 мс звука нет четкого символа для прогнозирования. Использование одного и того же токена для дополнения, как и
пустой токен для CTC, упрощает алгоритм декодирования и позволяет сохранить небольшой объем словаря.

Добавить CTC в модель трансформера энкодера очень просто: выходная последовательность с энкодера поступает на линейный слой, который проецирует акустические признаки на словарь. Модель обучается с помощью специальной функции потерь CTC.

Недостатком CTC является то, что он может выдавать слова, которые *звучат* правильно, но не *написаны* правильно. Ведь голова CTC учитывает только отдельные символы, а не целые слова. Одним из способов повышения качества транскрипции звука является использование внешней языковой модели. 
Эта языковая модель, по сути, выполняет функцию проверки орфографии на выходе CTC.

## В чем разница между Wav2Vec2, HuBERT, M-CTC-T, ...?

Все модели трансформеры основанные на архитектуре CTC имеют очень схожую архитектуру: в них используется энкодер трансформера (но не декодер) с головой CTC на верху. С точки зрения архитектуры они скорее похожи, чем отличаются.

Разница между Wav2Vec2 и M-CTC-T заключается в том, что первый работает с необработанными формами звуковых сигналов, а второй использует в качестве входных данных мэл спектрограммы. Модели также были обучены для разных целей. Например, M-CTC-T обучен распознаванию многоязычной речи и
поэтому имеет относительно большую голову CTC, включающую помимо других алфавитов еще и китайские иероглифы.

Wav2Vec2 и HuBERT используют совершенно одинаковую архитектуру, но обучаются совершенно по-разному. Wav2Vec2 предварительно обучена по аналогии с маскированным языковым моделированим BERT, прогнозирующим речевые единицы для маскированных частей аудио. HuBERT использует идею BERT и учится
предсказывать "дискретные единицы речи", которые являются аналогом токенов в текстовом предложении, так что речь может обрабатываться с помощью известных методов NLP.

Следует отметить, что приведенные здесь модели не являются единственными моделями CTC на основе трансформеров. Существует множество других, но теперь вы знаете, что все они работают примерно одинаково.

### Архитектуры классификации аудио
https://huggingface.co/learn/audio-course/ru/chapter3/classification.md

# Архитектуры классификации аудио

Цель классификации аудио - предсказать метку класса для входного аудиосигнала. Модель может предсказать одну метку класса, охватывающую всю входную последовательность, или предсказать метку для каждого звукового фрейма - обычно каждые 20 миллисекунд входного звука - в этом случае вывод
модели представляет собой последовательность вероятностей метки класса. Примером первого может служить определение того, какая птица издает тот или иной звук; примером второго - диаризация диктора, когда модель предсказывает, какой диктор говорит в тот или иной момент.

## Классификация с использованием спектрограмм

Один из самых простых способов классификации звука - представить, что это задача классификации изображения!

Напомним, что спектрограмма - это двумерный тензор формы `(частоты, длина последовательности)`. В [главе об аудио данных](../chapter1/audio_data) мы строили эти спектрограммы в виде изображений. Угадайте, что? Мы можем буквально рассматривать спектрограмму как изображение и передавать ее в
обычную модель классификатора CNN, например ResNet, и получать очень хорошие прогнозы. Еще лучше использовать модель трансформер для работы с изображениями, например ViT.

Именно это и делает **Трансформер Аудио Спектрограммы (Audio Spectrogram Transformer - AST)**. Он использует модель ViT или Vision Transformer и передает ему на вход спектрограммы вместо обычных изображений. Благодаря слоям самовнимания трансформера модель лучше улавливает глобальный контекст,
чем CNN.

Как и ViT, модель AST разбивает спектрограмму звука на последовательность частично перекрывающихся фрагментов изображений размером 16×16 пикселей. Затем эта последовательность фрагментов проецируется в последовательность эмбдингов, которые, как обычно, подаются на вход энкодера трансформера.
AST является моделью трансформера состоящей только из энкодера, поэтому на выходе получается последовательность скрытых состояний, по одному на каждый входной фрагмент 16×16. Сверху находится простой слой классификации с сигмоидальной активацией для отображения скрытых состояний в вероятности
классификации.

    

Изображение из статьи [AST: Трансформер аудио спектрограммы](https://arxiv.org/pdf/2104.01778.pdf)

💡 Хотя здесь мы делаем вид, что спектрограммы - это то же самое, что и изображения, есть существенные различия. Например, смещение содержимого изображения вверх или вниз, как правило, не меняет смысла того, что на нем изображено. Однако смещение спектрограммы вверх или вниз приводит к
изменению частот, присутствующих в звуке, и полностью меняет его характер. Изображения инвариантны при трансляции, а спектрограммы - нет. Обращение со спектрограммами как с изображениями может хорошо работать на практике, но следует помнить, что это не совсем одно и то же.

## Любой трансформер может быть классификатором

В [предыдущем материале](ctc) вы убедились, что CTC - это эффективная методика автоматического распознавания речи с использованием только трансформера состоящего только из  энкодера.  Такие CTC модели уже являются классификаторами, прогнозирующими вероятности для меток классов из словаря
токенизатора. Мы можем взять модель CTC и превратить ее в классификатор звука общего назначения, изменив метки и обучив ее с помощью обычной функции потерь кросс-энтропии вместо специальной функции потерь CTC.

Например, в HF Transformers есть модель `Wav2Vec2ForCTC`, `Wav2Vec2ForSequenceClassification` и `Wav2Vec2ForAudioFrameClassification`. Различия между архитектурами этих моделей заключаются только в размере слоя классификации и используемой функции потерь.

Фактически, любая модель аудио трансформера состоящая только из энкодера, может быть превращена в классификатор аудиосигнала путем добавления слоя классификации поверх последовательности слоёв формирующих скрытые состояния. (Классификаторы обычно не нуждаются в декодере трансформера.)

Для прогнозирования единой классификационной оценки для всей последовательности (`Wav2Vec2ForSequenceClassification`) модель берет среднее значение по скрытым состояниям и передает его в слой классификации. На выходе получается одно распределение вероятностей.

Чтобы сделать отдельную классификацию для каждого аудио фрейма (`Wav2Vec2ForAudioFrameClassification`), классификатор запускается на последовательности скрытых состояний, поэтому выходом классификатора также является последовательность.

### Проверьте свое понимание материала курса
https://huggingface.co/learn/audio-course/ru/chapter3/quiz.md

# Проверьте свое понимание материала курса

### 1. Что такое вокодер?

### 2. Wav2Vec2 является примером

### 3. Что делает пустой токен в алгоритме CTC?

 для 'unknown'.",
			explain: ""
		}
	]}
/>

### 4. Какое из следующих утверждений о моделях CTC является ЛОЖНЫМ? 

### 5. Whisper является примером  

### 6. Как проще всего выполнить классификацию звука?

### 7. Верно или нет? Если рассматривать спектрограммы как изображения для классификации, то всегда полезно использовать методы дополнения данных изображения, такие как сдвиг изображения, его обрезка или изменение размера.

### Введение в аудиоданные
https://huggingface.co/learn/audio-course/ru/chapter1/audio_data.md

# Введение в аудиоданные

По своей природе звуковая волна является непрерывным сигналом, то есть содержит бесконечное число значений сигнала за определенное время.
Это создает проблемы для цифровых устройств, которые ожидают конечные массивы. Для обработки, хранения и передачи сигнала цифровыми устройствами,
непрерывная звуковая волна должна быть преобразована в ряд дискретных значений, называемых цифровым представлением.

Если обратиться к любому набору аудиоданных, то можно найти цифровые файлы со звуковыми фрагментами, например, с текстовым повествованием или музыкой.
Вы можете встретить различные форматы файлов, такие как `.wav` (Waveform Audio File), `.flac` (Free Lossless Audio Codec),
`.mp3` (MPEG-1 Audio Layer 3). Эти форматы различаются главным образом способом сжатия цифрового представления аудиосигнала.

Рассмотрим, как мы приходим от непрерывного сигнала к такому представлению. Сначала аналоговый сигнал улавливается
микрофоном, который преобразует звуковые волны в электрический сигнал. Затем электрический сигнал оцифровывается с помощью
Аналого-Цифрового Преобразователя для получения цифрового представления путем дискретизации.

## Выборка и частота дискретизации

Выборка (сэмлирование, дискретизация) - это процесс измерения значения непрерывного сигнала с фиксированным шагом по времени. Выборочная форма сигнала является _дискретной_,
поскольку содержит конечное число значений сигнала через равномерные интервалы времени.

    

*Иллюстрация из статьи Википедии: [Сэмплирование (обработка сигналов)](https://en.wikipedia.org/wiki/Sampling_(signal_processing))*

**Частота выборки (сэмплирования)** (также называемая частотой дискретизации) - это количество выборок, сделанных за одну секунд измеряемое в
герцах (Гц). Чтобы дать вам примерную точку отсчета, частота дискретизации аудиофайлов CD-качества составляет 44 100 Гц, то есть выборки делаются
44 100 раз в секунду. Для сравнения, частота дискретизации звука высокого разрешения составляет 192 000 Гц или 192 кГц. Обычно
частота дискретизации, используемая при обучении речевых моделей, составляет 16 000 Гц или 16 кГц.

Выбор частоты дискретизации в первую очередь определяет наивысшую частоту, которая может быть извлечена из сигнала. Это значение также,
известно как предел Найквиста, и составляет ровно половину частоты дискретизации. Слышимые частоты в человеческой речи лежат ниже 8 кГц,
поэтому для дискретизации речи достаточно 16 кГц. Использование более высокой частоты дискретизации не позволяет получить больше информации и
только приведет к увеличению вычислительных затрат на обработку таких файлов. С другой стороны, дискретизация звука при слишком
низкой частоте дискретизации приводит к потере информации. Речь, дискретизированная с частотой 8 кГц, будет звучать приглушенно, так как более высокие частоты
не могут быть захвачены при такой частоте дискретизации.

При работе над любой аудио задачей важно убедиться, что все примеры звука в вашем наборе данных имеют одинаковую частоту дискретизации.
Если вы планируете использовать пользовательские аудиоданные для дообучения предварительно обученной модели, то частота дискретизации ваших данных должна соответствовать частоте дискретизации данных, на которых была предварительно обучена модель. Частота дискретизации определяет временной интервал между последовательными
выборками звука, что влияет на временное разрешение аудиоданных. Рассмотрим пример: 5-секундный звук при частоте дискретизации
16 000 Гц будет представлен в виде серии из 80 000 значений, а тот же 5-секундный звук при частоте дискретизации
8 000 Гц будет представлен в виде серии из 40 000 значений. Модели трансформеров, решающие аудиозадачи, рассматривают примеры как последовательности
и полагаются на механизмы внимания для обучения аудио или мультимодальному представлению. Поскольку последовательности данных различны для
аудиопримеров с разной частотой дискретизации, то моделям будет сложно обобщать данные для разных частот дискретизации.
**Передискретизация** - это процесс согласования частот дискретизации, являющийся частью [препроцессинга](preprocessing#resampling-the-audio-data) аудиоданных.

## Амплитуда и битовая глубина

В то время как частота дискретизации говорит о том, как часто происходит выборка образцов, какие именно значения содержатся в каждом образце?

Звук возникает в результате изменения давления воздуха на частотах, слышимых человеком. **Амплитуда** звука характеризует
уровень звукового давления в любой момент времени и измеряется в децибелах (дБ). Мы воспринимаем амплитуду как громкость.
Для примера, обычный разговор не превышает 60 дБ, а рок-концерт может достигать 125 дБ, что является пределом 
для человеческого слуха.

В цифровом аудио каждый образец звука фиксирует амплитуду звуковой волны в определенный момент времени. **Битовая глубина** образца звука
определяет, с какой точностью может быть описано это значение амплитуды. Чем выше битовая глубина, тем точнее
цифровое представление приближается к исходной непрерывной звуковой волне.

Наиболее распространенные битовые глубины звука - 16 и 24 бита. Каждая из них представляет собой двоичный термин, обозначающий количество возможных шагов,
на которое можно квантовать амплитудное значение при его преобразовании из непрерывного в дискретное: 65 536 шагов для 16-битного звука,
для 24-битного звука - 16 777 216 шагов. Поскольку при квантовании происходит округление непрерывного значения до дискретного,
процесс дискретизации вносит шум. Чем выше битовая глубина, тем меньше этот шум квантования. На практике
шум квантования 16-битного звука уже достаточно мал, чтобы быть неслышимым, и использование большей битовой глубины обычно
не требуется.

Вы также можете встретить 32-битные аудио. В нем выборки хранятся в виде значений с плавающей точкой, тогда как в 16- и 24-битном аудио
используются целочисленные выборки. Точность 32-битного значения с плавающей точкой составляет 24 бита, что дает такую же битовую глубину, как и у 24-битного звука.
Предполагается, что аудио выборки с плавающей точкой лежат в диапазоне [-1,0, 1,0]. Поскольку модели машинного обучения естественным образом
работают с данными в формате с плавающей точкой, перед тем как использовать их для обучения модели, аудиоданные необходимо преобразовать в формат с плавающей точкой.
Как это сделать, мы рассмотрим в следующем разделе [Препроцессинг](preprocessing).

Как и в случае с непрерывными звуковыми сигналами, амплитуда цифрового звука обычно выражается в децибелах (дБ). Поскольку
слух человека имеет логарифмическую природу - наши уши более чувствительны к небольшим колебаниям тихих звуков, чем громких,
то громкость звука легче интерпретировать, если амплитуды выражены в децибелах, которые также являются логарифмическими.
Децибельная шкала для реального звука начинается с 0 дБ, что соответствует самому тихому звуку, который может услышать человек, а
более громкие звуки имеют большие значения. Однако для цифровых аудиосигналов 0 дБ - это самая громкая возможная амплитуда, а все
остальные амплитуды отрицательны. Краткое эмпирическое правило: каждые -6 дБ - это уменьшение амплитуды вдвое, и все, что ниже -60 дБ
обычно неслышно, если только вы не увеличите громкость.

## Аудио как форма волны

Возможно, вам приходилось видеть визуализацию звуков в виде **формы волны**, которая отображает значения отсчетов во времени и иллюстрирует изменения
амплитуды звука. Такое представление звука называется *временной областью*.

Этот тип визуализации полезен для выявления специфических особенностей аудиосигнала, таких как время появления отдельных звуковых событий,
общая громкость сигнала, неравномерности или шумы, присутствующие в аудиосигнале.

Для построения графика формы волны аудиосигнала можно использовать библиотеку Python `librosa`:

```bash
pip install librosa
```

Возьмем для примера звук "Трубы", который поставляется вместе с библиотекой::

```py
import librosa

array, sampling_rate = librosa.load(librosa.ex("trumpet"))
```

Пример загружается в виде кортежа состоящего из временного ряда звука (здесь мы называем его `array`), и частоты дискретизации (`sampling_rate`).
Посмотрим на форму волны этого звука с помощью функции librosa `waveshow()`:

```py
import matplotlib.pyplot as plt
import librosa.display

plt.figure().set_figwidth(12)
librosa.display.waveshow(array, sr=sampling_rate)
```

    

При этом по оси y откладывается амплитуда сигнала, а по оси x - время. Другими словами, каждая точка соответствует
одному значению выборки, которое было взято при сэмплировании этого звука. Также отметим, что librosa возвращает звук уже в виде значений
с плавающей точкой, при этом значения амплитуды действительно находятся в диапазоне [-1.0, 1.0].

Визуализация звука наряду с его прослушиванием может быть полезным инструментом для понимания данных, с которыми вы работаете.
Вы можете увидеть форму сигнала, заметить закономерности, научиться выявлять шумы или искажения. При предварительной обработке данных, 
например, нормализации, повторной выборке или фильтрации, можно визуально убедиться в том, что этапы предварительной обработки были выполнены как ожидалось.
После обучения модели можно также визуализировать примеры, в которых возникают ошибки (например, в задаче классификации звука), для отладки
возникающих проблем.

## Частотный спектр

Другим способом визуализации аудиоданных является построение **частотного спектра** аудиосигнала, также известное как **частотный интервал**.
Спектр вычисляется с помощью Дискретного Преобразования Фурье или ДПФ (Discrete Fourier Transform - DFT). Он описывает отдельные частоты,
из которых состоит сигнал, и их силу.

Построим частотный спектр для того же звука трубы, взяв ДПФ с помощью функции numpy `rfft()`. Хотя
можно построить спектр всего звука, удобнее рассматривать небольшую область. Здесь мы возьмем
ДПФ первых 4096 выборок, что приблизительно равно длительности первой сыгранной ноты:

```py
import numpy as np

dft_input = array[:4096]

# Рассчитаем ДПФ
window = np.hanning(len(dft_input))
windowed_input = dft_input * window
dft = np.fft.rfft(windowed_input)

# получим амплитудный спектр в децибелах
amplitude = np.abs(dft)
amplitude_db = librosa.amplitude_to_db(amplitude, ref=np.max)

# получим частотные столбцы
frequency = librosa.fft_frequencies(sr=sampling_rate, n_fft=len(dft_input))

plt.figure().set_figwidth(12)
plt.plot(frequency, amplitude_db)
plt.xlabel("Frequency (Hz)")
plt.ylabel("Amplitude (dB)")
plt.xscale("log")
```

    

Здесь отображается сила различных частотных составляющих, присутствующих в данном аудио сегменте. На оси x
откладываются значения частот, обычно в логарифмическом масштабе, а по оси y - их амплитуды.

Построенный нами частотный спектр имеет несколько пиков. Эти пики соответствуют гармоникам исполняемой ноты,
причем более высокие гармоники более тихие. Поскольку первый пик находится на частоте около 620 Гц, это частотный спектр ноты E♭.

На выходе ДПФ получается массив комплексных чисел, состоящий из действительной и мнимой компонент. Взяв
величину с помощью `np.abs(dft)`, можно извлечь из спектрограммы амплитудную информацию. Угол между действительной и
мнимой составляющими дает так называемый фазовый спектр, но в приложениях машинного обучения он часто отбрасывается.

Вы использовали `librosa.amplitude_to_db()` для преобразования значений амплитуды в децибельную шкалу, что облегчает просмотр
более тонких деталей в спектре. Иногда используют **энергетический спектр**, который измеряет энергию, а не амплитуду;
это просто спектр с квадратом амплитудных значений.

💡 На практике термин БПФ (Fast Fourier Transform - FFT) используется как взаимозаменяемый с термином ДПФ, поскольку БПФ или быстрое преобразование Фурье является единственным эффективным способ вычисления ДПФ на компьютере.

Частотный спектр аудиосигнала содержит точно такую же информацию, как и его волновая форма, - это просто два разных способа 
взглянуть на одни и те же данные (здесь - первые 4096 выборок из звука трубы). Если волновая форма отображает амплитуду
звукового сигнала во времени, то спектр представляет амплитуды отдельных частот в фиксированный момент времени.

## Спектрограмма

Что если мы хотим увидеть, как изменяются частоты в аудиосигнале? Труба играет несколько нот, и все они имеют
разные частоты. Проблема в том, что спектр показывает только застывший снимок частот в данный момент времени.
Решение состоит в том, чтобы взять несколько ДПФ, каждый из которых охватывает лишь небольшой отрезок времени, и сложить полученные спектры вместе
в **спектрограмму**.

Спектрограмма представляет собой график изменения частотного содержания звукового сигнала во времени. Она позволяет увидеть время, частоту,
и амплитуду на одном графике. Алгоритм, выполняющий эти вычисления, называется ОПФ или Оконное Преобразование Фурье (Short Time Fourier Transform -  STFT).

Спектрограмма является одним из наиболее информативных аудио инструментов. Например, при работе с музыкальной записью
можно увидеть различные инструменты и вокальные дорожки и их вклад в общее звучание. В речи можно
идентифицировать различные гласные звуки, поскольку каждый гласный звук характеризуется определенными частотами.

Построим спектрограмму для того же звука трубы, используя функции библиотеки librosa `stft()` и `specshow()`:

```py
import numpy as np

D = librosa.stft(array)
S_db = librosa.amplitude_to_db(np.abs(D), ref=np.max)

plt.figure().set_figwidth(12)
librosa.display.specshow(S_db, x_axis="time", y_axis="hz")
plt.colorbar()
```

    

На этом графике ось x представляет собой время, как и при визуализации формы волны, но теперь ось y представляет собой частоту в Гц.
Интенсивность цвета показывает амплитуду или мощность частотной составляющей в каждый момент времени, измеряемую в децибелах (дБ).

Спектрограмма создается путем выделения коротких сегментов аудиосигнала, как правило, длительностью несколько миллисекунд, и вычисления 
дискретного преобразования Фурье каждого сегмента для получения его частотного спектра. Полученные спектры складываются
вместе по оси времени для получения спектрограммы. Каждый вертикальный срез на этом изображении соответствует одному частотному
спектру, если смотреть сверху. По умолчанию `librosa.stft()` разбивает аудиосигнал на сегменты по 2048 выборок, что
дает хороший компромисс между частотным и временным разрешением.

Поскольку спектрограмма и волновая форма - это разные представления одних и тех же данных, то с помощью обратного ОПФ можно превратить спектрограмму обратно
в исходную волновую форму.  Однако для этого помимо информации об амплитуде
требуется информация о фазе. Если спектрограмма была сгенерирована моделью машинного обучения, то она, как правило, выдает только амплитуды.
В этом случае для восстановления формы волны из спектрограммы можно использовать алгоритм восстановления фазы, например, классический алгоритм Гриффина-Лима,
или нейронную сеть, называемую вокодером.

Спектрограммы используются не только для визуализации. Многие модели машинного обучения принимают на вход спектрограммы - в отличие от
формы волны - и выдают на выходе спектрограммы.

Теперь, когда мы знаем, что такое спектрограмма и как она строится, рассмотрим ее разновидность, широко используемую при обработке речи, - Мел спектрограмму.

## Мэл спектрограмма

Мел-спектрограмма - это разновидность спектрограммы, которая широко используется в задачах обработки речи и машинного обучения.
Она похожа на спектрограмму тем, что показывает частотное содержание аудиосигнала во времени, но на другой частотной оси.

В стандартной спектрограмме частотная ось линейна и измеряется в герцах (Гц). Однако слуховая система человека
более чувствительна к изменениям на низких частотах, чем на высоких, и эта чувствительность уменьшается логарифмически
с увеличением частоты. Шкала Мэл - это перцептивная шкала, которая аппроксимирует нелинейную частотную характеристику человеческого уха.

Для создания мэл спектрограммы, как и ранее, используется ОПФ, при этом аудиосигнал разбивается на короткие сегменты для получения последовательности
частотных спектров. Кроме того, каждый спектр пропускается через набор фильтров, так называемый банк фильтров мэла, для [NL1] преобразования частот в Мэл шкалу.

Рассмотрим, как можно построить мэл спектрограмму с помощью функции librosa `melspectrogram()`, которая выполняет все эти действия за нас:

```py
S = librosa.feature.melspectrogram(y=array, sr=sampling_rate, n_mels=128, fmax=8000)
S_dB = librosa.power_to_db(S, ref=np.max)

plt.figure().set_figwidth(12)
librosa.display.specshow(S_dB, x_axis="time", y_axis="mel", sr=sampling_rate, fmax=8000)
plt.colorbar()
```

    

В приведенном примере `n_mels` означает количество генерируемых мэл диапазонов. Мел диапазоны определяют набор частотных
диапазонов, которые разделяют спектр на перцептивно значимые компоненты, используя набор фильтров, форма и расстояние между которыми
выбираются таким образом, чтобы имитировать реакцию человеческого уха на различные частоты. Обычные значения для `n_mels` это 40 или 80. `fmax`
указывает максимальную частоту (в Гц), которая нас интересует.

Как и в случае с обычной спектрограммой, принято выражать силу мел-частотных компонентов в
децибелах. Такую спектрограмму принято называть **лог-мэл-спектрограммой**, поскольку при переводе в децибелы выполняется
логарифмическая операция. В приведенном выше примере использовалась функция `librosa.power_to_db()`, так как `librosa.feature.melspectrogram()` создает спектрограмму мощности.

💡 Не все мэл спектрограммы одинаковы! Существуют две различные шкалы мэл, которые широко используются ("htk" и "slaney"), 
а вместо спектрограммы мощности может использоваться амплитудная спектрограмма. При преобразовании спектрограммы в лог-мел не всегда
вычисляются истинные децибелы, а может просто браться `log`. Поэтому, если модель машинного обучения ожидает в качестве входных данных спектрограмму мел,
дважды проверьте, что она вычисляется тем же способом.

Создание mel-спектрограммы - это операция с потерями, так как она связана с фильтрацией сигнала. Конвертировать mel-спектрограмму обратно
в волновую форму сложнее, чем обычную спектрограмму, так как для этого необходимо оценить частоты,
которые были отброшены. Поэтому для получения формы волны из мэл спектрограммы необходимы модели машинного обучения,
такие как вокодер HiFiGAN.

По сравнению со стандартной спектрограммой, мэл спектрограмма может отражать более значимые для восприятия человеком особенности аудиосигнала,
что делает ее популярной в таких задачах, как распознавание речи, идентификация диктора и классификация музыкальных жанров.

Теперь, когда вы знаете, как визуализировать примеры аудиоданных, попробуйте посмотреть, как выглядят ваши любимые звуки. :)

### Потоковая передача аудиоданных
https://huggingface.co/learn/audio-course/ru/chapter1/streaming.md

# Потоковая передача аудиоданных

Одной из самых больших проблем, возникающих при работе с аудиоданными, является их огромный размер. Одна минута несжатого аудиофайла CD-качества (44,1 кГц, 16 бит)
занимает чуть более 5 МБ памяти. Как правило, набор аудиоданных содержат несколько часов записей.

В предыдущих разделах мы использовали очень небольшое подмножество набора аудиоданных MINDS-14, однако типичные наборы аудиоданных гораздо больше.
Например, `xs` (наименьшая) конфигурация [GigaSpeech от SpeechColab](https://huggingface.co/datasets/speechcolab/gigaspeech)
содержит всего 10 часов обучающих данных, но для их загрузки и подготовки требуется более 13 Гбайт дискового пространства. Что же
произойдет, если мы захотим обучиться на более крупной части набора данных? Полная конфигурация `xl` того же набора данных содержит 10 000 часов
тренировочных данных, что требует более 1 ТБ дискового пространства. Для большинства из нас это значительно превышает характеристики обычного
жесткого диска. Нужно ли нам тратиться на покупку дополнительного хранилища? Или есть способ обучения на этих наборах данных без ограничения дискового пространства?

🤗 Datasets приходит на помощь, предлагая [потоковый режим] (https://huggingface.co/docs/datasets/stream). Потоковая передача позволяет загружать данные постепенно, 
по мере того как мы итерируемся по набору данных. Вместо того чтобы загружать весь набор данных сразу, мы загружаем его по одному образцу за раз.
Мы итеративно обращаемся к набору данных, загружая и подготавливая образцы на лету, когда это необходимо. Таким образом, мы всегда
загружаем только те образцы, которые мы используем, а не те, которые мы не используем!
Закончив работу с образцом, мы продолжаем итерацию по набору данных и загружаем следующий образец.

Потоковый режим имеет три основных преимущества перед загрузкой всего набора данных целиком:

* Дисковое пространство: образцы загружаются в память один за другим по мере итерации по набору данных. Поскольку данные не загружаются
локально, то не требуется дисковое пространство, поэтому можно использовать наборы данных произвольного размера.
* Время загрузки и обработки: аудиоданные имеют большой объем и требуют значительного времени для загрузки и обработки.
При потоковой передаче данных загрузка и обработка выполняются "на лету", то есть вы можете начать использовать набор данных, как только
будет готов первый образец.
* Простота экспериментов: вы можете провести эксперимент на нескольких образцах, чтобы проверить, работает ли ваш скрипт, без необходимости
загружать весь набор данных.

В режиме потоковой передачи данных есть одна оговорка. При загрузке полного набора данных без потоковой передачи как исходные данные, так и обработанные
сохраняются локально на диске. Если мы захотим повторно использовать этот набор данных, мы можем напрямую загрузить обработанные данные с диска,
минуя этапы загрузки и обработки. Следовательно, нам достаточно один раз выполнить операции загрузки и обработки,
после чего мы можем повторно использовать подготовленные данные.

В потоковом режиме данные не загружаются на диск. Таким образом, ни загруженные, ни предварительно обработанные данные не кэшируются.
Если мы хотим повторно использовать набор данных, необходимо повторить шаги потоковой передачи, при этом аудиофайлы должны быть загружены и обработаны на
"на лету" заново. По этой причине рекомендуется загружать наборы данных, которые, скорее всего, будут использоваться многократно.

Как включить потоковый режим? Легко! Просто установите `streaming=True` при загрузке набора данных. Об остальном позаботятся:

```py
gigaspeech = load_dataset("speechcolab/gigaspeech", "xs", streaming=True)
```

Подобно тому, как мы применяли шаги предварительной обработки к загруженному подмножеству MINDS-14, точно так же можно выполнить
ту же самую предварительную обработку с потоковым набором данных.

Единственное отличие заключается в том, что вы больше не можете обращаться к отдельным образцам, используя индексацию Python (т.е. `gigaspeech["train"][sample_idx]`).
Вместо этого приходится выполнять итерации по набору данных. Вот как можно получить доступ к образцу при потоковой передаче набора данных:

```py
next(iter(gigaspeech["train"]))
```

**Output:**
```out
{
    "segment_id": "YOU0000000315_S0000660",
    "speaker": "N/A",
    "text": "AS THEY'RE LEAVING  CAN KASH PULL ZAHRA ASIDE REALLY QUICKLY ",
    "audio": {
        "path": "xs_chunks_0000/YOU0000000315_S0000660.wav",
        "array": array(
            [0.0005188, 0.00085449, 0.00012207, ..., 0.00125122, 0.00076294, 0.00036621]
        ),
        "sampling_rate": 16000,
    },
    "begin_time": 2941.89,
    "end_time": 2945.07,
    "audio_id": "YOU0000000315",
    "title": "Return to Vasselheim | Critical Role: VOX MACHINA | Episode 43",
    "url": "https://www.youtube.com/watch?v=zr2n1fLVasU",
    "source": 2,
    "category": 24,
    "original_full_path": "audio/youtube/P0004/YOU0000000315.opus",
}
```

Если вы хотите ознакомиться с несколькими образцами из большого набора данных, воспользуйтесь функцией `take()` для получения первых n элементов. Возьмем
первые два образца из набора данных gigaspeech:

```py
gigaspeech_head = gigaspeech["train"].take(2)
list(gigaspeech_head)
```

**Output:**
```out
[
    {
        "segment_id": "YOU0000000315_S0000660",
        "speaker": "N/A",
        "text": "AS THEY'RE LEAVING  CAN KASH PULL ZAHRA ASIDE REALLY QUICKLY ",
        "audio": {
            "path": "xs_chunks_0000/YOU0000000315_S0000660.wav",
            "array": array(
                [
                    0.0005188,
                    0.00085449,
                    0.00012207,
                    ...,
                    0.00125122,
                    0.00076294,
                    0.00036621,
                ]
            ),
            "sampling_rate": 16000,
        },
        "begin_time": 2941.89,
        "end_time": 2945.07,
        "audio_id": "YOU0000000315",
        "title": "Return to Vasselheim | Critical Role: VOX MACHINA | Episode 43",
        "url": "https://www.youtube.com/watch?v=zr2n1fLVasU",
        "source": 2,
        "category": 24,
        "original_full_path": "audio/youtube/P0004/YOU0000000315.opus",
    },
    {
        "segment_id": "AUD0000001043_S0000775",
        "speaker": "N/A",
        "text": "SIX TOMATOES ",
        "audio": {
            "path": "xs_chunks_0000/AUD0000001043_S0000775.wav",
            "array": array(
                [
                    1.43432617e-03,
                    1.37329102e-03,
                    1.31225586e-03,
                    ...,
                    -6.10351562e-05,
                    -1.22070312e-04,
                    -1.83105469e-04,
                ]
            ),
            "sampling_rate": 16000,
        },
        "begin_time": 3673.96,
        "end_time": 3675.26,
        "audio_id": "AUD0000001043",
        "title": "Asteroid of Fear",
        "url": "http//www.archive.org/download/asteroid_of_fear_1012_librivox/asteroid_of_fear_1012_librivox_64kb_mp3.zip",
        "source": 0,
        "category": 28,
        "original_full_path": "audio/audiobook/P0011/AUD0000001043.opus",
    },
]
```

Потоковый режим может вывести ваши исследования на новый уровень: вам не только доступны самые большие наборы данных, но вы
можете легко оценивать системы на нескольких наборах данных за один раз, не заботясь о дисковом пространстве. По сравнению с оценкой
на одном наборе данных, оценка на нескольких наборах дает более точную метрику обобщающих способностей 
системы распознавания речи (например, End-to-end Speech Benchmark (ESB)).

### Препроцессинг набора аудиоданных
https://huggingface.co/learn/audio-course/ru/chapter1/preprocessing.md

# Препроцессинг набора аудиоданных

Загрузка набора данных с помощью 🤗 Datasets - это только половина удовольствия. Если вы планируете использовать его либо для обучения модели, либо для выполнения
инференса, необходимо предварительно обработать данные. В общем случае это включает в себя следующие шаги:

* Передискретизация аудиоданных
* Фильтрация набора данных
* Преобразование аудиоданных в ожидаемый моделью формат входных данных

## Передискретизация аудиоданных

Функция `load_dataset` загружает аудиопримеры с той частотой дискретизации, с которой они были опубликованы. Это не
всегда та частота дискретизации, которая ожидается моделью, которую вы планируете обучать или использовать для инференса. Если есть расхождение между
частотой дискретизации, можно передискретизировать звук до ожидаемой моделью частоты дискретизации.

Большинство имеющихся предварительно обученных моделей были обучены на аудиоданных с частотой дискретизации 16 кГц.
Когда мы исследовали набор данных MINDS-14, вы могли заметить, что он сэмплирован с частотой 8 кГц, что означает, что нам, скорее всего, потребуется
увеличить частоту дискретизации.

Чтобы сделать это, используйте метод 🤗 Datasets `cast_column`. Эта операция не изменяет звук непосредственно в наборе данных (in-place), а дает сигнал
datasets для передискретизации аудиопримеров "на лету" при их загрузке. Следующий код установит частоту дискретизации
равной 16 кГц:

```py
from datasets import Audio

minds = minds.cast_column("audio", Audio(sampling_rate=16_000))
```

Перезагрузим первый аудиопример из набора данных MINDS-14 и проверим, что он был передискретизирован до нужной `sampling rate`:

```py
minds[0]
```

**Output:**
```out
{
    "path": "/root/.cache/huggingface/datasets/downloads/extracted/f14948e0e84be638dd7943ac36518a4cf3324e8b7aa331c5ab11541518e9368c/en-AU~PAY_BILL/response_4.wav",
    "audio": {
        "path": "/root/.cache/huggingface/datasets/downloads/extracted/f14948e0e84be638dd7943ac36518a4cf3324e8b7aa331c5ab11541518e9368c/en-AU~PAY_BILL/response_4.wav",
        "array": array(
            [
                2.0634243e-05,
                1.9437837e-04,
                2.2419340e-04,
                ...,
                9.3852862e-04,
                1.1302452e-03,
                7.1531429e-04,
            ],
            dtype=float32,
        ),
        "sampling_rate": 16000,
    },
    "transcription": "I would like to pay my electricity bill using my card can you please assist",
    "intent_class": 13,
}
```

Вы можете заметить, что значения массива теперь также отличаются. Это связано с тем, что теперь для
каждого значения амплитуды мы имеем в два раза больше значений чем раньше.

💡 Некоторые сведения о передискретизации: Если аудиосигнал дискретизирован с частотой 8 кГц, т. е. имеет 8000 выборок в
секунду, то мы знаем, что он не содержит частот выше 4 кГц. Это гарантируется теоремой Найквиста 
о дискретизации. Благодаря этому мы можем быть уверены, что между точками дискретизации исходный непрерывный сигнал всегда
имеет плавную кривую. Повышение частоты дискретизации до более высокой сводится к вычислению дополнительных значений выборки, которые находятся между
существующими, путем аппроксимации этой кривой. Однако понижающая дискретизация требует, чтобы мы сначала отфильтровали все частоты,
которые будут выше нового предела Найквиста, прежде чем оценивать новые точки дискретизации. Другими словами, нельзя
понизить дискретизацию в 2 раза, просто отбрасывая каждый второй сэмпл - это приведет к появлению искажений в сигнале, называемых
наложениями. Корректная передискретизация - дело непростое, и его лучше доверить проверенным библиотекам, таким как librosa или 🤗 Datasets.

## Фильтрация набора данных

Возможно, потребуется отфильтровать данные по каким-либо критериям. Одним из распространенных случаев является ограничение аудиопримеров
определенной продолжительности. Например, для предотвращения ошибок, связанных с выходом за пределы доступного обьёма памяти,
необходимо отфильтровать все примеры длительностью более 20 секунд при обучении модели.

Мы можем сделать это, используя метод 🤗 Datasets `filter` и передать ему функцию с логикой фильтрации. Начнем с того, что напишем функцию
которая определяет, какие примеры следует оставить, а какие отбросить. Эта функция, `is_audio_length_in_range`,
возвращает `True`, если длина образца меньше 20 с, и `False`, если больше 20 с.

```py
MAX_DURATION_IN_SECONDS = 20.0

def is_audio_length_in_range(input_length):
    return input_length 

Теперь вы можете увидеть, как выглядит входной аудиосигнал для модели Whisper после препроцессинга.

Класс модели feature extractor занимается преобразованием сырых аудиоданных в формат, ожидаемый моделью. Однако,
многие задачи с использованием звука являются мультимодальными, например, распознавание речи.
В таких случаях 🤗 Transformers также предлагает специфичные для конкретной модели
токенизаторы для обработки текстовых данных. Для более глубокого изучения токенизаторов обратитесь к нашему [курсу по NLP](https://huggingface.co/course/chapter2/4).

Вы можете загрузить экстрактор признаков и токенизатор для Whisper и других мультимодальных моделей отдельно, либо загрузить их через 
так называемый процессор. Чтобы еще больше упростить задачу, используйте `AutoProcessor` для загрузки экстрактора признаков и процессора модели из контрольной точки,
например, так:

```py
from transformers import AutoProcessor

processor = AutoProcessor.from_pretrained("openai/whisper-small")
```

Здесь мы проиллюстрировали основные этапы подготовки данных. Конечно, пользовательские данные могут потребовать более сложного препроцессинга.
В этом случае можно расширить функцию `prepare_dataset` для выполнения любых преобразований пользовательских данных. С 🤗 Datasets,
если вы можете записать процес подготовки данных как функцию Python, вы можете [применить его](https://huggingface.co/docs/datasets/audio_process) к вашему набору данных!

### Раздел 1. Работа с аудио данными
https://huggingface.co/learn/audio-course/ru/chapter1/introduction.md

# Раздел 1. Работа с аудио данными

## Что вы узнаете в этом разделе

Любая аудио или голосовая задача начинается с аудиофайла. Прежде чем приступить к решению этих задач, необходимо
понять, что на самом деле содержат эти файлы и как с ними работать.

В этом разделе вы получите представление о фундаментальной терминологии, связанной с аудиоданными, включая форму волны,
частоту дискретизации и спектрограмму. Вы также узнаете, как работать с наборами аудиоданных, включая загрузку и препроцессинг
аудиоданных, и как эффективно передавать большие наборы данных.

К концу этого раздела вы будете хорошо разбираться в основной терминологии аудиоданных и овладеете навыками,
необходимыми для работы с аудио наборами данных в различных приложениях. Знания, которые вы получите в этом разделе,
заложат основу для понимания остальной части курса.

### Загрузка и изучение аудио набора данных
https://huggingface.co/learn/audio-course/ru/chapter1/load_and_explore.md

# Загрузка и изучение аудио набора данных

В этом курсе мы будем использовать библиотеку 🤗 Datasets для работы с наборами аудиоданных. 🤗 Datasets - это библиотека с открытым исходным кодом для 
загрузки и подготовки наборов данных всех модальностей, включая аудио. Библиотека предоставляет легкий доступ к беспрецедентному
подборке наборов данных машинного обучения, публично доступных на Hugging Face Hub. Кроме того, 🤗 Datasets содержит множество
функций, предназначенных для работы с аудиоданными, которые упрощают работу с ними как для исследователей, так и для практиков.

Для начала работы с наборами аудиоданных необходимо убедиться, что у вас установлена библиотека 🤗 Datasets:

```bash
pip install datasets[audio] soundfile librosa torchcodec
```

Одной из ключевых особенностей 🤗 Datasets является возможность загрузки и подготовки набора данных всего одной строкой
Python-кода с помощью функции `load_dataset()`.

Давайте загрузим и исследуем набор аудиоданных под названием [MINDS-14](https://huggingface.co/datasets/PolyAI/minds14), который содержит
записи людей, задающих вопросы системе дистанционного банковского обслуживания на нескольких языках и диалектах.

Для загрузки набора данных MINDS-14 нам необходимо скопировать идентификатор набора данных на хабе (`PolyAI/minds14`) и передать его
в функцию `load_dataset`. Мы также укажем, что нас интересует только австралийское подмножество (`en-AU`)
данных, и ограничим его частью набора данных предназначенной для обучения:

```py
from datasets import load_dataset

minds = load_dataset("PolyAI/minds14", name="en-AU", split="train")
minds
```

**Output:**
```out
Dataset(
    {
        features: [
            "path",
            "audio",
            "transcription",
            "english_transcription",
            "intent_class",
            "lang_id",
        ],
        num_rows: 654,
    }
)
```

Набор содержит 654 аудиофайла, каждый из которых сопровождается транскрипцией, переводом на английский язык и меткой,
указывающей на намерение человека, сделавшего запрос. В столбце audio содержатся необработанные аудиоданные. Рассмотрим подробнее
на одном из примеров:

```py
example = minds[0]
example
```

**Output:**
```out
{
    "path": "/root/.cache/huggingface/datasets/downloads/extracted/f14948e0e84be638dd7943ac36518a4cf3324e8b7aa331c5ab11541518e9368c/en-AU~PAY_BILL/response_4.wav",
    "audio": {
        "path": "/root/.cache/huggingface/datasets/downloads/extracted/f14948e0e84be638dd7943ac36518a4cf3324e8b7aa331c5ab11541518e9368c/en-AU~PAY_BILL/response_4.wav",
        "array": array(
            [0.0, 0.00024414, -0.00024414, ..., -0.00024414, 0.00024414, 0.0012207],
            dtype=float32,
        ),
        "sampling_rate": 8000,
    },
    "transcription": "I would like to pay my electricity bill using my card can you please assist",
    "english_transcription": "I would like to pay my electricity bill using my card can you please assist",
    "intent_class": 13,
    "lang_id": 2,
}
```

Вы  можете заметить, что столбец аудио содержит несколько параметров. Вот что они собой представляют:
* `path`: путь к аудиофайлу (в данном случае `*.wav`).
* `array`: Декодированные аудиоданные, представленные в виде одномерного массива NumPy.
* `sampling_rate`. Частота дискретизации аудиофайла (в данном примере 8 000 Гц).

Класс `intent_class` - это классификационная категория аудиозаписи. Для преобразования этого числа в осмысленную строку
можно использовать метод `int2str()`:

```py
id2label = minds.features["intent_class"].int2str
id2label(example["intent_class"])
```

**Output:**
```out
"pay_bill"
```

Если посмотреть на транскрипцию, то можно увидеть, что в аудиофайле действительно записан человек, задающий вопрос
об оплате счета.

Если вы планируете обучать аудиоклассификатор на этом подмножестве данных, то, возможно, вам не обязательно понадобятся все признаки. Например,
`lang_id` будет иметь одно и то же значение для всех примеров и не будет полезен. Параметр `english_transcription`, скорее всего, будет
дублировать `transcription` в этом подмножестве, поэтому их можно смело удалить.

Удалить нерелевантные признаки можно с помощью метода 🤗 Datasets `remove_columns`:

```py
columns_to_remove = ["lang_id", "english_transcription"]
minds = minds.remove_columns(columns_to_remove)
minds
```

**Output:**
```out
Dataset({features: ["path", "audio", "transcription", "intent_class"], num_rows: 654})
```

Теперь, когда мы загрузили и осмотрели необработанное содержимое набора данных, давайте прослушаем несколько примеров! Мы воспользуемся функциями `Blocks`
и `Audio` из `Gradio` для декодирования нескольких случайных образцов из набора данных:

```py
import gradio as gr

def generate_audio():
    example = minds.shuffle()[0]
    audio = example["audio"]
    return (
        audio["sampling_rate"],
        audio["array"],
    ), id2label(example["intent_class"])

with gr.Blocks() as demo:
    with gr.Column():
        for _ in range(4):
            audio, label = generate_audio()
            output = gr.Audio(audio, label=label)

demo.launch(debug=True)
```

При желании можно также визуализировать некоторые примеры. Построим форму волны для первого примера.

```py
import librosa
import matplotlib.pyplot as plt
import librosa.display

array = example["audio"]["array"]
sampling_rate = example["audio"]["sampling_rate"]

plt.figure().set_figwidth(12)
librosa.display.waveshow(array, sr=sampling_rate)
```

    

Попробуйте! Загрузите другой диалект или язык из набора данных MINDS-14, прослушайте и визуализируйте несколько примеров, чтобы получить представление
о вариативности всего набора данных. Полный список доступных языков можно найти [здесь](https://huggingface.co/datasets/PolyAI/minds14).

### Как узнать больше
https://huggingface.co/learn/audio-course/ru/chapter1/supplemental_reading.md

# Как узнать больше

В данном разделе рассмотрены многие фундаментальные понятия, имеющие отношение к пониманию аудиоданных и работе с ними.
Хотите узнать больше? Здесь вы найдете дополнительные ресурсы, которые помогут вам углубить понимание тем и
повысить эффективность обучения.

В следующем видео Монти Монтгомери из xiph.org демонстрирует в реальном времени дискретизацию, квантование,
битовую глубину и дизеринг на реальном аудиооборудовании с использованием как современного цифрового анализа, так и винтажного аналогового стендового оборудования, посмотрите его:

Если вы хотите глубже погрузиться в тему цифровой обработки сигналов, обратите внимание на бесплатную книгу ["Теория цифровых сигналов"](https://brianmcfee.net/dstbook-site/content/intro.html), автором которой является Брайан Макфи, доцент кафедры музыкальных технологий и науки о данных Нью-Йоркского университета и главный сопровождающий
пакета `librosa`.

### Проверьте свое понимание материала курса
https://huggingface.co/learn/audio-course/ru/chapter1/quiz.md

# Проверьте свое понимание материала курса

### 1. В каких единицах измеряется частота дискретизации?

### 2. При потоковой передаче большого набора аудиоданных как скоро можно начать его использовать?

### 3. Что такое спектрограмма?

### 4. Как проще всего преобразовать сырые аудиоданные в лог-мел спектрограмму, ожидаемую Whisper?

A.
```python
librosa.feature.melspectrogram(audio["array"])
```

B.
```python
feature_extractor = WhisperFeatureExtractor.from_pretrained("openai/whisper-small")
feature_extractor(audio["array"])
```

C.
```python
dataset.feature(audio["array"], model="whisper")
```

### 5. Как загрузить набор данных из 🤗 Hub?

A.
```python
from datasets import load_dataset

dataset = load_dataset(DATASET_NAME_ON_HUB)
```

B.
```python
import librosa

dataset = librosa.load(PATH_TO_DATASET)
```

C.
```python
from transformers import load_dataset

dataset = load_dataset(DATASET_NAME_ON_HUB)
```

### 6. Ваш пользовательский набор данных содержит высококачественные аудиозаписи с частотой дискретизации 32 кГц. Вы хотите обучить модель распознавания речи, которая ожидает, что аудиопримеры будут иметь частоту дискретизации 16 кГц. Что нужно сделать?

### 7. Как преобразовать спектрограмму, сгенерированную моделью машинного обучения, в форму волны?

### Получение сертификата о прохождении курса
https://huggingface.co/learn/audio-course/ru/chapter8/certification.md

# Получение сертификата о прохождении курса

Процесс сертификации является полностью бесплатным.  
* Для получения сертификата об окончании курса необходимо сдать 3 из 4 практических заданий до 1 сентября 2023 года.
* Для получения сертификата с отличием об окончании курса необходимо сдать 4 из 4 практических заданий до 1 сентября 2023 года.

Требования к каждому заданию приведены в соответствующих разделах:
* [Раздел 4 Практическое занятие](../chapter4/hands_on)
* [Раздел 5 Практическое занятие](../chapter5/hands_on)
* [Раздел 6 Практическое занятие](../chapter6/hands_on)
* [Раздел 7 Практическое занятие](../chapter7/hands_on)

Для заданий, требующих обучения модели, убедитесь, что ваша модель, удовлетворяющая требованиям, выложена на HuggingFace хабе с соответствующими `kwargs`.
Для демонстрационного задания в Главе 7 убедитесь, что ваша демонстрация является `public`.

Для самооценки и для того, чтобы увидеть, какие разделы вы сдали/не сдали, вы можете использовать следующее пространство:  
[Check My Progress - Audio Course](https://huggingface.co/spaces/MariaK/Check-my-progress-Audio-Course)

После того как вы сможете получить сертификат, перейдите в пространство [Audio Course Certification](https://huggingface.co/spaces/MariaK/Audio-Course-Certification).
В этом пространстве осуществляются дополнительные проверки на соответствие представленных материалов критериям оценки.

Введите свое имя пользователя Hugging Face, имя, фамилию в текстовые поля и нажмите на кнопку "Check if I pass and get the certificate".

Если вы сдали 3 из 4 практических заданий, то получите сертификат о прохождении курса.
Если вы сдали 4 из 4 практических заданий, вы получите сертификат о прохождении курса с отличием.

Вы можете скачать свой сертификат в формате pdf и png. Не стесняйтесь делиться своим сертификатом в Twitter 
(тэгните меня @mariakhalusova и @huggingface) и на LinkedIn.

Если вы не соответствуете критериям сертификации, не отчаивайтесь! Вернитесь к пространству 
[Check My Progress - Audio Course](https://huggingface.co/spaces/MariaK/Check-my-progress-Audio-Course), чтобы увидеть
какие блоки необходимо выполнить еще раз для получения сертификата. Если у вас возникнут какие-либо проблемы с любым из этих пространств,
сообщите нам об этом!

### Поздравляем!
https://huggingface.co/learn/audio-course/ru/chapter8/introduction.md

# Поздравляем!

Вы много работали, чтобы достичь этого момента, и мы хотели бы поздравить Вас с окончанием этого курса по обработке аудиоданных!

В ходе данного курса вы получили базовое представление об аудиоданных, изучили новые концепции и приобрели
практические навыки работы с аудио трансформерами.

Начиная с основ работы с аудиоданными и предварительно обученными контрольными точками моделей с помощью конвейеров и заканчивая созданием реальных
аудиоприложений, вы узнали, как можно создавать системы, способные не только понимать звук, но и создавать его.

Поскольку эта область является динамичной и постоянно развивающейся, мы призываем вас не терять любопытства и постоянно изучать новые модели, достижения в области исследований
и новые приложения. Создавая свои новые и интересные аудиоприложения, не забывайте об этических аспектах
и тщательно анализируйте потенциальное воздействие на человека и общество в целом.

Благодарим Вас за то, что Вы присоединились к этому курсу, мы надеемся, что Вы получили огромное удовольствие от этого образовательного процесса,
так же как и мы от его создания. Ваши отзывы и предложения приветствуются в 
[репозитории курса на GitHub](https://github.com/huggingface/audio-transformers-course).  

Чтобы узнать, как можно получить заслуженный сертификат об окончании курса, если вы успешно справились с практическими заданиями, 
вы узнаете на [следующей странице](certification).

Наконец, чтобы оставаться на связи с командой курса по аудио, вы можете связаться с нами в Twitter:

* Мария Халусова: [@mariakhalusova](https://twitter.com/mariaKhalusova)
* Санчит Ганди: [@sanchitgandhi99](https://twitter.com/sanchitgandhi99)
* Матиас Холлеманс: [@mhollemans](https://twitter.com/mhollemans)
* Вайбхав Шривастав: [@reach_vb](https://twitter.com/reach_vb)

Оставайтесь любопытными и тренируйте трансформеров! :)
