В первой статье серии я рассказывал, что начинал с уже существующего крымскотатарского речевого набора данных, который пришлось исправлять, и что готовых данных, которых хватило бы для серьёзной работы, у нашего языка не было. Во второй статье машина научилась слышать нашу речь, в третьей синтезированный голос прочитал целую книгу. Закономерный вопрос: если данных так мало, на чём всё это училось?
Эта статья про то, откуда всё взялось. Сразу скажу, чего в ней не будет: я не называю конкретные источники, архивы, издания, каналы и людей, которые нам что-то передали, и не рассказываю о договорённостях с ними. Зато я расскажу, какие это были материалы, что с ними оказалось не так и сколько в них было подвохов.
Что было у нас на руках
Если перечислить честно, то получится не так уж мало.
Напечатанные книги и периодика: романы, рассказы, стихи, учебники, журналы и газеты разных лет. Записи эфиров: новости, передачи, разговоры в студии, интервью. Аудиокниги, где профессиональный диктор читает книгу целиком. Словари, без которых нельзя проверить даже то, правильно ли написано слово. Мои собственные записи. И то, что приносят учителя: проверки, исправления, диалоги, записи голоса.
По отдельности почти ничто из этого не было датасетом. Книга остаётся файлом на полке. Эфир состоит из часов звука без единой строчки текста. У аудиокниги звук и напечатанный текст живут отдельно: текст надо найти, проверить, что это то же издание, и совместить со звуком слово за словом. А бывает, что цифрового текста книги нет вовсе. Работа состояла в том, чтобы превратить всё это в пары «звук — текст» и в чистый текст, которому можно доверять. И почти каждый материал преподносил свой сюрприз, которого я заранее не ждал.
А началось всё с одного уже существующего набора данных. Данные в нём были поломаны, и я их исправил и использовал для своего первого обучения. С этого и запустился весь процесс: первая модель показала, что дело того стоит, и есть над чем работать.
Сканы, которые оказались текстом
Следующими были книги. План был очевидный: большая часть старых крымскотатарских книг существует только в виде сканов, значит, их надо распознавать, то есть превращать картинку страницы в текст. Это долго, и на нашем языке распознавание ошибается, особенно на буквах, которых нет в русском.
Прежде чем запускать распознавание, я проверил, что именно лежит на полке. И вопрос оказался поставлен немного неправильно. Около двух третей крымскотатарских страниц уже несли в себе текстовый слой: под картинкой страницы лежал настоящий текст, который можно просто достать. Распознавание понадобилось только для оставшейся трети.
Но «текст есть» не значит «текст хороший». Первая же проверка показала три разных поломки. И это были не ошибки нашего распознавания: текстовый слой когда-то сделала чужая программа, часто старое распознавание, и текст испортился ещё тогда или при переносе из файла в файл. Где-то перепутаны буквы, где-то не та кодировка, а где-то одна и та же книга лежит несколько раз.
Мягкий знак вместо твёрдого. В тексте стояло къаплангьан вместо къаплангъан, догьрумы вместо догърумы. Так наш язык портят программы, привыкшие к русскому. Хорошая новость в том, что сочетаний кь и гь в крымскотатарской кириллице не бывает вообще, поэтому их можно исправлять механически. Но я не стал верить себе на слово: сначала прогнал эту починку по заведомо здоровому тексту. Она обязана была не изменить в нём ничего, и не изменила ни одной буквы. Только после этого починка пошла на весь архив и исправила десятки тысяч страниц. Нь, кстати, я не трогал: оно законно встречается в русских заимствованиях.
Не та кодировка. Латинские страницы выглядели как tatarlýq, þöyle, qorquya tüþüp. Текст под ними был правильный, просто буквы прочитали не в той кодировке, и ı превратилась в ý, ş в þ. Это тоже обратимо.
Одна и та же книга несколько раз. Одни и те же произведения лежали в разных изданиях, в разных подборках, под разными именами файлов. Про такую же ловушку со звуком я рассказывал во второй статье: четыре аудиокниги, которые лежали у меня дважды под совершенно разными именами. С текстом вышло то же самое. По именам файлов копии почти не находились. По содержимому, когда каждая страница сравнивается с уже принятыми по цепочкам из восьми слов, нашлось около 7 % повторов. Без этой проверки модель училась бы на них дважды.
Ещё я научился решать не за книгу целиком, а за каждую страницу. В одном томе кириллическая часть была чистой, а латинская оказалась старым неудачным распознаванием, и её текстовый слой был просто шумом. Оценка «по книге» заставила бы либо выбросить хорошие страницы, либо принять плохие.
А как вообще понять, что страница хорошая, если её никто не вычитывал? Тут пригодился наш словарь (iOS, Android), с которого начинался весь путь. Для каждой страницы я считал, какая доля слов начинается с настоящего словарного слова. Именно «начинается», а не совпадает: наш язык клеит к корню окончание за окончанием, и точное совпадение со словарём почти ничего не говорит. Порог я не придумывал, а померил: на заведомо чистых книгах, на заведомо испорченных и на русских книгах для контроля. Из русских книг не прошла ни одна страница. А вот турецкие частично проходили, и к этому я ещё вернусь.
Итог меня удивил. Текста, на котором можно учить модель, стало примерно в десять раз больше, чем было до этого. И большая часть этого прироста не потребовала распознавания вообще. Самой дорогой оказалась не обработка сканов, а проверка того, можно ли верить тексту, который уже есть.
Текст, который притворялся нашим
Самая коварная находка была про язык, а не про буквы.
Однажды наша языковая модель ответила мне так: «Ayt, men dinlemeye hazırım». А по-крымскотатарски надо «Ayt, men diñlemege azırım». Слова почти те же, а форма турецкая. Я начал мерить и увидел, что турецких форм в её ответах стало заметно больше, чем у предыдущей версии.
Причину я нашёл в данных. Среди собранного текста была периодика, которая выходит за пределами Крыма. Там есть настоящие крымскотатарские страницы, и там же целые страницы на турецком, иногда вперемешку, в одном номере. На глаз это похоже на наш язык. Для программы тоже.
И вот тут выяснилось главное. Обычный языковой фильтр задаёт вопрос «это крымскотатарский или нет?» и смотрит на служебные слова и окончания. Для турецкого ответ почти всегда «похоже, да»: слишком много общих корней и служебных слов. Мой собственный фильтр по абзацам, когда я прогнал его по корпусу, нашёл больше десяти тысяч кусков, которые стоило убрать: русский, украинский, английский. Признаки турецкого нашлись только в 40 из них. Турецкий он просто не видел.
Поэтому пришлось сделать свои детекторы, которые смотрят на то, чего в крымскотатарском не бывает. Турецкое -yor в глаголах. değil там, где у нас degil. iki там, где у нас eki. Дательный падеж -meye вместо нашего -mege. Детекторы проверялись в обе стороны: на заведомо чистом крымскотатарском тексте они не должны срабатывать, на настоящем турецком обязаны. Потом появился ещё один, для примесей других тюркских языков, и он нашёл в корпусе несколько десятков кусков, целиком написанных на казахском, татарском или узбекском.
Несколько тысяч таких фрагментов отправились в карантин. Не в корзину, а именно в карантин: каждый сохранён как был, с пометкой, откуда он, чтобы любое решение можно было пересмотреть.
Была и соблазнительная идея: не выбрасывать «турецкое написание», а исправлять его автоматически, k на q, n на ñ. Я её проверил и отложил. Программа исправляла форму, но не понимала смысла. balaların («детей», в родительном падеже) она превращала в balalarıñ, а это уже «твои дети». Правильно было бы balalarnıñ. Каждое такое исправление выглядело как настоящее крымскотатарское слово, и именно поэтому было опасно. Автоматика, которая умеет делать правдоподобные ошибки, хуже автоматики, которая не делает ничего.
А теперь обратная сторона. В наших словарях есть слова с пометкой «диалектное», например южнобережное ben вместо men. Мои проверки на турецкий к ним, естественно, придирались. Я проверил весь список и решил: это диалекты, разные наречия нашего языка, и они остаются. Да, часть из них похожа на турецкий, но это наш язык, и вычищать его из корпуса я не буду. Разницу пришлось учесть по-другому: диалектные формы в корпусе остаются, а в ответах модели считаются отдельно. От модели я жду литературного языка, но учиться она может на всём, чем живёт язык.
Звук, у которого не было текста
Со звуком было сложнее, потому что у большей части записей нет никакого текста.
Аудиокнига без книги. Была у нас аудиокнига на несколько часов: хороший диктор, чистая запись. А напечатанного текста этого издания я так и не нашёл ни в каком цифровом виде. Значит, приём из первой статьи, когда известный текст совмещается со звуком, здесь не работает.
Тогда я сделал так: запись расшифровывает наша распознавалка, а потом её же слушает вторая, устроенная совсем по-другому и обученная отдельно. В корпус попадает только тот кусок, где две расшифровки совпали почти полностью. Две модели, которые ошибаются по-разному, редко ошибаются одинаково. Когда распознавалка стала лучше, а нарезка на куски точнее, из той же книги удалось взять в 2.6 раза больше пригодного звука, а куски, где старая модель зацикливалась и повторяла одну фразу полсотни раз, исчезли совсем.
Но честно скажу: это не доказательство правильности. Две неправильные модели в принципе могут согласиться. Проверить эти куски по книге нельзя, потому что книги нет. Их можно только послушать. Поэтому мы и начали проверять все спорные фрагменты вручную.
Эфиры. Дальше были записи эфиров: новости, передачи, разговоры. Больше тысячи часов звука. Здесь работает тот же принцип: машина расшифровывает, а в обучение идёт только то, в чём она уверена и с чем согласна вторая модель. Строгий фильтр оставил примерно четверть.
И тут меня поймала очень поучительная ловушка. Я посмотрел, что именно прошло через фильтр, и больше 80 % оказалось новостями. Дикторы новостей говорят чётко, по написанному, и распознавалка их и так хорошо слышит. А из интервью, где люди говорят как в жизни, перебивают друг друга и сбиваются, не прошло почти ничего. Фильтр по уверенности оставляет то, что модель уже умеет, и отбрасывает ровно то, чему ей нужно учиться. В следующем раунде я ограничил долю новостей и пустил разговорную речь с более мягким порогом.
Оставался вопрос, как понять, стало ли лучше. Проверочные тексты для живой речи раньше делала сама машина, старая версия распознавалки. Поэтому новая модель, которая расходилась со старой, автоматически выглядела хуже. Я взял куски, где две модели расходились, и прослушал их сам, вслепую, не зная, где чья расшифровка. На это у меня ушло много часов. Выяснилось, что сами проверочные тексты ошибались примерно в 15 % слов, а новая модель на самом деле была права заметно чаще старой.
Сейчас на нашем сервере работает распознавалка, обученная на живой речи, и наши партнёры активно ею пользуются. С каждым раундом обучения результаты становятся лучше. На коротких живых записях она ошибается примерно на треть реже прежней. На длинных разговорах они пока вровень, около 30 % ошибок в словах, и это честное состояние дел. Следующий раунд, в котором часов разговорной речи было уже в несколько раз больше, оказался с ней вровень, и победителя я не нашёл даже на слух. Так что «просто добавить ещё часов» здесь не работает, и это тоже результат.
Люди
Всё, о чём я писал выше, держится на людях.
Поиск людей оказался одним из самых трудных этапов. Найти тех, кто готов помогать, тяжело, и дело не в нежелании, а в нехватке времени. Согласились многие, но на деле работают единицы, и это сильно замедлило работу. Поэтому мы продолжаем искать людей, которые присоединятся к нам. Мы размещали объявления в социальных сетях, и нам откликались неравнодушные люди.
Первое правило для меня простое: голоса и записи, которые звучат в наших примерах и в синтезированных голосах, используются с согласия их владельцев. Если кто-то передумает, мы уберём его голос, без проблем.
Учителя крымскотатарского языка работают с нами через специальный портал. Они пишут диалоги, на которых модель учится разговаривать. Проверяют строки корпуса и отмечают, где текст не крымскотатарский. Просматривают словарные пометки и решают, где слово турецкое, а где наше. Исправляют черновики, которые написала машина. И записывают свой голос. Эти записи, кстати, ни разу не попали в обучение: они стали экзаменом для распознавалки. Записи учителей с обычного микрофона, а не студийного, ближе всего к тому, как с машиной будут говорить настоящие люди. Поэтому мы бережём их для проверки и не учим на них.
Есть и партнёры, которые записывают устные истории: люди рассказывают о своей жизни на родном языке, часто с местным говором. Они прислали нам запись интервью с субтитрами, которые сами вручную выверили. Из этого получился один из самых трудных наших экзаменов: настоящая разговорная речь, с диалектом и паузами, и с текстом, который написал человек, а не машина. На нём модель тоже не учится: такие записи слишком ценны, чтобы тратить их на обучение, и только на них видно, как машина справляется с живым разговором.
И мой собственный голос. Им машина прочитала вторую книгу в нашей библиотеке, об этом я рассказывал в третьей статье. А ещё мои уши: я сам слушаю спорные куски, когда автоматическая проверка не может решить, кто прав.
Синтетика: где она помогла, а где нет
Когда своих данных мало, хочется сделать их самому. У нас для этого было два инструмента: синтез речи, который умеет читать любой текст, и большие языковые модели, которые умеют писать.
Синтезированная речь в обучении распознавалки. Идея простая: синтезированная запись приходит с идеальным текстом, потому что текст мы выбрали сами до того, как машина его прочитала. Я добавил в обучение синтезированную речь нескольких голосов, так, что она составила половину всех учебных кусков. Каждый синтезированный кусок перед этим прослушивался распознавалкой, и те, что не совпали с задуманным текстом, отбрасывались по порогу, заданному заранее. Отпало около 5 %.
Перед запуском я записал свой прогноз: немного синтетики, может, и поможет, а половина навредит. Вышло наоборот. На экзамене из двух аудиокниг, которых модель не слышала, ошибок в словах стало меньше: 15.7 % вместо 17.0 %. Выигрыш сохранился и в шуме, и в эхе, и в телефонном звуке.
Но тут нужна вторая половина правды. Экзамен состоит из аудиокниг, то есть из чистого чтения в тихой комнате. На записях, которые ближе к жизни, модель с синтетикой выглядела хуже той, что училась только на живой речи. Эту проверку нельзя считать окончательной: её проверочные тексты тоже делала старая модель, и сравнение было немного в её пользу. Каждый вариант к тому же обучался всего один раз. Но в работу эта модель не пошла. На сервере сейчас распознавалка, обученная на живой речи, и на живой речи она лучше.
Машинный текст для языковой модели. Здесь моё правило такое: неважно, кто написал текст, человек или машина. Важно, чтобы это был чистый, правильный крымскотатарский язык. Сочиняй сколько угодно, но каждая порция проходит проверки: по словарю, на турецкие формы, на правильную транслитерацию, и выборочно глазами.
Я попросил несколько больших языковых моделей написать диалоги на крымскотатарском и прочитал их вслепую, не зная, где чья. Из 26 прочитанных ни один не годился как есть. Лучшие можно было спасти правками, остальные были в основном турецким с примесью узбекского и казахского. И самое неприятное: автоматические проверки этих моделей почти не различали. Одну из них, которую я забраковал полностью, приборы оценили так же, как остальных, потому что мои детекторы тогда видели турецкий, но не видели казахский и узбекский.
Вторая попытка была строже: диалоги длиннее, по подробному заданию, и все они прошли каждую автоматическую проверку без единого замечания. Я прочитал вслепую шесть. Ни один не годился даже для правки: два я переписал сам, остальные четыре были безнадёжны, «много непонятных слов и неверная форма». Автоматика сказала «чисто», ухо сказало «не наш язык».
Тогда я понял, что синтетические данные здесь нам не подходят, и расстроился, ведь решить проблему синтетикой не удалось, а найти достаточно учителей пока не получается.
Вывод у меня один, и он одинаковый для звука и для текста. Синтетика — это хорошо, но главную задачу она не решает. Поэтому нам нужно больше людей, которые будут составлять диалоги с красками языка, с его колоритом и душой.
Почему главное здесь — носители языка
Если собрать всё вместе, картина такая. Тексты нашлись там, где их не искали: в слоях под сканами, которые надо было не распознавать, а чинить и проверять. Звук нашёлся в эфирах и аудиокнигах, но текст к нему пришлось добывать двумя машинами, которые проверяют друг друга. Синтетика добавила немного, но только там, где за ней следил человек.
А самые важные решения во всей этой истории принимало ухо носителя. Это ухо отличило турецкий от диалекта, услышало, что проверочные тексты сами ошибаются в каждом шестом-седьмом слове, и сказало «не наш язык» диалогам, которые приборы признали чистыми. Ни один фильтр этого не сделал.
Аудиопримеры и другие материалы — https://ai.ana-yurt.dev/.
Хотите помочь? Больше всего проекту нужны носители языка. Послушать кусочек записи и сказать, правильно ли машина его записала. Прочитать страницу текста и отметить, где слово турецкое, а где наше, диалектное. Начитать несколько минут текста своим голосом. Программировать для этого не нужно — достаточно хорошо знать родной язык. В этой статье самые важные решения приняло именно ухо носителя. Пишите: ai@ay.mw или в Telegram: t.me/ana_yurt_dev.
А если хотите поддержать работу материально — это можно сделать здесь: ko-fi.com/anayurt. Эта поддержка превращается в новые записи живой речи — а записывать её важно сейчас, пока есть у кого учиться.