Дообучение модели 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 во время обучения. Hugging Face Hub предоставляет следующие возможности:
- Встроенный контроль версий: вы можете быть уверены, что ни одна контрольная точка модели не будет потеряна в процессе обучения.
- Журналы Tensorboard: отслеживание важных показателей в процессе обучения.
- Карты моделей: документирование того, что делает модель, и предполагаемых вариантов ее использования.
- Сообщество: простой способ обмена информацией и сотрудничества с сообществом! 🤗
Связать блокнот с Hub Hugging Face довольно просто - вам просто нужно ввести свой токен аутентификации Hugging Face Hub, когда вас попросят. Найдите свой токен аутентификации Hugging Face Hub здесь и введите его, когда вас попросят:
from huggingface_hub import notebook_login
notebook_login()
Output:
Login successful Your token has been saved to /root/.huggingface/token
Загрузка набора данных
Common Voice 13 содержит примерно десять часов размеченных данных для Дивехи, из которых три часа являются тестовой частью данных. Этих данных крайне мало для дообучения модели, поэтому мы будем опираться на обширные многоязыковые знания в области распознавания речи, накопленные Whisper во время предварительного обучения, для низкоресурсного языка Дивехи.
Используя 🤗 Datasets, загрузка и подготовка данных чрезвычайно просты. Мы можем загрузить и подготовить разделения набора данных Common
Voice 13 всего за одну строку кода. Так как Дивехи имеет очень небольшой объем данных, мы объединим выборки train
и validation
, чтобы
получить примерно семь часов данных для обучения. Мы будем использовать три часа данных выборки test
в качестве нашего тестового набора данных:
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
})
})
Большинство наборов данных для распознавания речи предоставляют только аудиофайлы для ввода (audio
) и соответствующий
транскрибированный текст (sentence
). В наборе данных Common Voice есть дополнительная метаинформация, такая как accent
и locale
, которую мы можем не учитывать для ASR. Сохраняя блокнот максимально общим, мы будем рассматривать только входное
аудио и транскрибированный текст для дообучения модели, отбрасывая дополнительную метаинформацию:
common_voice = common_voice.select_columns(["audio", "sentence"])
Извлечение признаков, токенизатор и обработчик
Конвеер для задачи распознавания речи можно разделить на три этапа:
- Извлекатель признаков, который предварительно обрабатывает сырой аудиоввод и создает логарифмические мел-спектрограммы
- Модель, выполняющая отображение последовательности в последовательность
- Токенизатор, который выполняет постобработку предсказанных токенов в текст
В библиотеке 🤗 Transformers для модели Whisper существуют связанные извлекатель признаков и токенизатор, называемые WhisperFeatureExtractor и WhisperTokenizer соответственно. Для упрощения работы с ними, эти два объекта объединены в одном классе, названном WhisperProcessor. Мы можем вызвать WhisperProcessor для выполнения как предварительной обработки звука, так и постобработки текстового токена. При этом во время обучения нам нужно отслеживать только два объекта: процессор и модель.
При выполнении многоязыкового дообучения модели нам необходимо установить параметры "language"
и "task"
при создании процессора.
Параметр "language"
должен быть установлен на язык исходного аудио, а параметр "task"
на "transcribe"
для распознавания речи или
на "translate"
для перевода речи. Эти аргументы изменяют поведение токенизатора и должны быть правильно установлены, чтобы обеспечить
правильное кодирование целевых меток.
Мы можем увидеть все возможные поддерживаемые языки моделью Whisper, импортировав список языков:
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"
,
как объяснено выше:
from transformers import WhisperProcessor
processor = WhisperProcessor.from_pretrained(
"openai/whisper-small", language="sinhalese", task="transcribe"
)
Стоит отметить, что в большинстве случаев вы обнаружите, что язык, на котором вы хотите дообучить модель, есть в наборе языков
предобученной модели, в этом случае вы можете просто установить язык напрямую как язык вашего аудиоввода! Обратите внимание,
что оба эти аргумента следует исключить для дообучения только на английском языке, когда есть только один вариант для языка ("English"
)
и задачи ("transcribe"
).
Предварительная обработка данных
Давайте посмотрим на характеристики набора данных. Особое внимание уделяем колонке "audio"
- это подробности о частоте
дискретизации наших аудиовходов:
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
.
Эта операция не изменяет звук непосредственно, а сигнализирует набору данных о пересемплировании аудиообразцов при их загрузке на лету:
from datasets import Audio
sampling_rate = processor.feature_extractor.sampling_rate
common_voice = common_voice.cast_column("audio", Audio(sampling_rate=sampling_rate))
Теперь мы можем написать функцию для подготовки наших данных к использованию моделью:
- Мы загружаем и выполняем пересемплирование аудиоданных на основе выборки, вызывая sample[“audio”]. Как уже было объяснено, библиотека 🤗 Datasets выполняет все необходимые операции пересемплирования на лету.
- Мы используем извлекатель признаков для вычисления входных признаков в виде логарифмической мел-спектрограммы из нашего одномерного аудио-массива.
- Мы кодируем транскрипции в идентификаторы меток с помощью токенизатора.
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
:
common_voice = common_voice.map(
prepare_dataset, remove_columns=common_voice.column_names["train"], num_proc=1
)
Наконец, мы фильтруем любые обучающие данные с аудиообразцами длиннее 30 секунд. В противном случае эти образцы могли бы быть усечены
извлекателем признаков Whisper, что может повлиять на стабильность обучения. Мы определяем функцию, которая возвращает True
для образцов,
которые короче 30 секунд, и False
для тех, что длиннее:
max_input_length = 30.0
def is_audio_in_length_range(length):
return length < max_input_length
Мы применяем нашу функцию фильтра к всем образцам нашего обучающего набора данных с помощью метода .filter
библиотеки 🤗 Datasets:
common_voice["train"] = common_voice["train"].filter(
is_audio_in_length_range,
input_columns=["input_length"],
)
Давайте проверим, сколько обучающих данных мы удалили на этом этапе фильтрации:
common_voice["train"]
Output
Dataset({
features: ['input_features', 'labels', 'input_length'],
num_rows: 4904
})
Хорошо! В этом случае у нас фактически осталось такое же количество образцов, что и раньше, так что образцы длиннее 30 секунд отсутствуют. Это может быть не так, если вы переключаете языки, поэтому лучше оставить этот шаг фильтра на месте для надежности. Теперь наши данные полностью готовы для обучения! Давайте продолжим и рассмотрим, как мы можем использовать эти данные для дообучения модели Whisper.
Обучение и оценка
Теперь, когда мы подготовили наши данные, мы готовы приступить к обучению модели. 🤗 Trainer выполнит большую часть тяжелой работы за нас. Все, что нам нужно сделать:
Определить сборщика данных: сборщик данных берет наши предварительно обработанные данные и готовит тензоры PyTorch, готовые для модели.
Определить метрику оценки: во время оценки мы хотим оценивать модель с использованием метрики Word Error Rate (WER). Нам нужно определить функцию
compute_metrics
, которая будет обрабатывать этот расчет.Загрузить предварительно обученную контрольную точку: нам нужно загрузить предварительно обученную контрольную точку и правильно сконфигурировать её для обучения.
Определить аргументы обучения: они будут использоваться 🤗 Trainer для построения расписания обучения.
После дообучения модели мы будем оценивать ее на тестовых данных, чтобы убедиться, что мы правильно обучили ее распознавать речь на Дивехи.
Определение сборщика данных
Сборщик данных для модели речевой последовательности-в-последовательность уникален в том смысле, что он обрабатывает input_features
и
labels
независимо: input_features
должны обрабатываться извлекателем признаков, а labels
- токенизатором.
input_features
уже дополнены по 30 секунд и преобразованы в логарифмическую мел-спектрограмму фиксированной размерности, поэтому все,
что нам нужно сделать, это преобразовать их в пакетированные тензоры PyTorch. Мы делаем это с помощью метода .pad
извлекателя признаков
с параметром return_tensors=pt
. Обратите внимание, что дополнительная подгонка не применяется, так как входные данные имеют
фиксированную размерность, и input_features
просто преобразуются в тензоры PyTorch.
С другой стороны, labels
не дополняются. Сначала мы дополняем последовательности до максимальной длины в пакете с использованием метода
.pad
токенизатора. Затем дополнительные токены заполняются значением -100
, чтобы эти токены не учитывались при вычислении потерь.
Затем мы удаляем начальный токен транскрипции из начала последовательности меток, так как мы добавим его позже во время обучения.
Мы можем воспользоваться ранее определенным WhisperProcessor
, чтобы выполнить как операции извлекателя признаков, так и токенизатора:
import torch
from dataclasses import dataclass
from typing import Any, Dict, List, Union
@dataclass
class DataCollatorSpeechSeq2SeqWithPadding:
processor: Any
def __call__(
self, features: List[Dict[str, Union[List[int], torch.Tensor]]]
) -> 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
Теперь мы можем инициализировать только что определенный сборщик данных:
data_collator = DataCollatorSpeechSeq2SeqWithPadding(processor=processor)
Продолжаем!
Метрики оценки
Далее мы определяем метрику оценки, которую будем использовать на нашем наборе для оценки. Мы будем использовать метрику Word Error Rate (WER), представленную в разделе Оценка, это “де-факто” метрика для оценки систем автоматического распознавания речи.
Давайте загрузим метрику WER из библиотеки 🤗 Evaluate:
import evaluate
metric = evaluate.load("wer")
Затем нам просто нужно определить функцию, которая принимает предсказания нашей модели и возвращает метрику WER. Эта функция,
называемая compute_metrics
, сначала заменяет -100
на pad_token_id
в label_ids
(отменяя шаг, который мы применили в
коллекторе данных, чтобы правильно игнорировать заполненные токены при вычислении потерь). Затем он декодирует предсказанные
идентификаторы и идентификаторы меток в строки. Наконец, она вычисляет WER между предсказаниями и эталонными метками.
Здесь у нас есть возможность оценить “нормализованные” транскрипции и предсказания, у которых удалены знаки препинания и регистр.
Мы рекомендуем следовать этому совету, чтобы получить преимущество от улучшения WER, полученного путем нормализации транскрипций.
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 без труда!
from transformers import WhisperForConditionalGeneration
model = WhisperForConditionalGeneration.from_pretrained("openai/whisper-small")
Мы установим use_cache
в значение False
для обучения, так как мы используем проверку градиента,
и эти две опции несовместимы. Мы также переопределим два аргумента для генерации, чтобы контролировать поведение модели во время вывода:
мы принудительно зададим токены языка и задачи во время генерации, установив аргументы language
и task
, и также снова включим
кэш для генерации, чтобы ускорить время вывода:
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 здесь.
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,
)
Мы можем передать аргументы обучения в 🤗 Trainer вместе с нашей моделью, набором данных, сборщиком данных и функцией compute_metrics
:
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,
)
И теперь мы готовы приступить к обучению!
Обучение
Для запуска обучения просто выполните:
trainer.train()
Обучение займет примерно 45 минут в зависимости от вашего графического ускорителя или того, который выделен в Google Colab.
В зависимости от вашего GPU возможно, что при запуске обучения вы столкнетесь с ошибкой CUDA “out-of-memory”. В этом случае
вы можете уменьшать per_device_train_batch_size
постепенно вдвое и использовать 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, которая классифицирует модели по языку и набору данных, а затем ранжирует их по их WER.
Посмотрев на доску лидеров, мы видим, что наша модель, обученная за 500 шагов, убедительно обгоняет предварительно обученный Whisper Small, который мы оценивали в предыдущем разделе. Отличная работа 👏
Мы видим, что есть несколько контрольных точек, которые показывают лучший результат, чем тот, который мы обучили. Прелесть платформы
Hugging Face Hub заключается в том, что это коллаборативная платформа - если у нас нет времени или ресурсов для проведения более
длительного обучения самостоятельно, мы можем загрузить контрольную точку, которую кто-то из сообщества обучил и любезно поделился ей
(не забудьте поблагодарить его за это!). Вы сможете загрузить эти контрольные точки так же, как и предварительно обученные модели, используя
класс pipeline
, как мы делали ранее! Так что нет ничего, что бы могло помешать вам выбрать лучшую модель из доски лидеров для использования в вашей задаче!
Мы можем автоматически отправить нашу контрольную точку на доску лидеров, когда мы публикуем результаты обучения на Hugging Face Hub - нам просто нужно установить соответствующие аргументы (kwargs). Вы можете изменить эти значения, чтобы они соответствовали вашему набору данных, языку и имени модели:
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:
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”:
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 на любом наборе данных или в любой предметной области. Так что чего вы ждете! Выберите один из наборов данных, охваченных в разделе Выбор набора данных, или выберите свой собственный набор данных и посмотрите, сможете ли вы достичь современной производительности (state-of-the-art performance)! Лидерборд ждет вас…