Начало
Языковые модели, основанные на архитектуре трансформеров, такие как Llama, Mistral и прочие, показывают впечатляющие результаты на английском языке. Однако их эффективность на других языках, включая казахский, может страдать. Дообучение на отдельный домен, даже при наличии хорошего датасета, может не давать значительного прироста в качестве. И дело не столько в том, что базовая модель при обучении видела мало текста на казахском, сколько в неэффективной токенизации. Этот недостаток приводит к тому, что модели не могут в полной мере использовать свой потенциал на языках, отличных от английского.
В качестве примера возьмем Mistral (без паники, он использует тот же BPE токенизатор со словарем в 32к токенов), а так же Gemma (чей словарь адаптирован для работы с разными языками, и потому больше в 8 раз) и попробуем разбить текст на токены. К слову, токен - это минимальная значимая единица текста (может быть словом, частью слова или даже отдельной морфемой), которую обрабатывают трансформеры. В итоге вот что мы получаем:
В то время как тот же текст на английском занимал бы 10 токенов, на казахском он все еще в 2-3 раза больше. Отсюда вытекает не только слабая эффективность обучения, но и низкая скорость генерации ответа (учитывая то, что у одинаковых моделей токены предсказываются с одной и той же скоростью, на генерацию текста целиком нужно потратить больше времени той из них, у которой токенизатор разбивает слово на несколько токенов, вместо 1-2). Плюс не стоит забывать о контекстном окне, которое будет заполняться гораздо быстрее, если не исправить эту проблему.
С одной стороны токенайзер у Gemma выглядит более привлекательнее, судя по примеру выше, а с другой, учитывая что при предсказании модель должна определить вероятность для каждого из 256к токенов из словаря (вместо 32к у Mistral’а) интерес к ней медленно угасает, ввиду лишнего усложнения.
Токенизатор
Словарь токенизатора у Mistral содержит 32к токенов, преимущественно английских лексем (есть и на казахском, но их очень мало). Было решено расширять словарь не более чем в 2 раза. Для этого мы собрали около 20 Гб сырых текстов всяких новостей, статей и прочего (преимущественно на казахском и процентов 5-10 на русском), определили размер нового словаря (те же 32к) и поучили токенизатор. Результаты выглядели заметно лучше даже при таком маленьком датасете:
Итоговый словарь токенизатора (после объединения исходного и нашего нового, а также после удаления дубликатов) содержит чуть более 60к токенов. Далее нас ждет сложный, долгий и дорогой этап, а именно предварительное обучение.
Пре-трейн
Так как моделька с нашим новым токенизатором не знакома и такие размеры ей в новинку, нужно проинициализировать те слои, которые будут с ним “взаимодействовать”, а именно входной (embed_tokens, переводит токены со скриншотов выше в понятные модели векторные представления) и выходной (lm_head, переводит вектора в вероятность генерации того или иного токена). После этого новые слои будут плохо “дружить” с тем, что находится между ними (само “тело” модели-трансформера), и вместо осмысленного текста генерировать мусор из случайных токенов, поэтому следующим шагом мы будем их учить.
Учитывая, что на этом этапе основная задача натренировать модель вразумительно продолжать текст, мы используем тот же общий датасет необработанных текстов, на котором мы учили токенизатор. Он маленький (всего на 2B токенов) и не самый чистенький, но в качестве эксперимента для построения опытной модели должно быть достаточно.
Из мощностей в распоряжении у нас были 2хH100, которые мы в течение недели нещадно эксплуатировали. Модель училась ровно, лоссы (и трейн, и эвал) падали (всем видом показывая, что 7-ми дней ей мало), сэмплы демонстрировали все лучшие и лучшие результаты. По окончании эвал лосс встал на отметке 1.75 (при этом на старте он был аж 32.46, так как с расширенным словарем токенизатора мы пытались заставить ЛЛМку писать текст на мало знакомом ей языке). Вот несколько удачных и неудачных примеров в задаче ответов на вопросы (красным выделил то, что генерировала наша новая модель):
Хоть результаты еще далеки от совершенства, но это уже значительно лучше того, как сейчас генерирует текст на казахском та же Llama-2-70b или прочие опенсорсные ЛЛМки. Подобные модели либо пытаются ответить на английском (на столько, на сколько они поняли вопрос), либо просто сыпят случайными словами на казахском:
И вот мы пришли к тому, с чего начинали, однако теперь у нас есть модель, которая худо бедно работает с казахским языком на нашем новом токенизаторе. Иными словами, мы “прирастили” новый язык к модели. Теперь казахский переводится в такие вектора, которые для модели несут правильный и понятный смысл — как это раньше происходило для нативного ей английского языка. Дальнейшим правилом хорошего тона является провести файн-тюнинг.
Файн-тюнинг
Если по-простому, то этот этап нужен для получения более заметных улучшений качества модели (как правило на каких-то узких задачах или специфических данных). Если раньше мы учили ее просто продолжать текст, то сейчас нам необходимо заставить ее давать конкретный ответ (в том числе с использованием дополнительной информации, предоставляемой в контексте — так мы учим модель не выдумывать на ходу, а опираться на то, что уже есть). Для этого нужен хороший датасет, содержащий инструкции (вопросы), контексты (потенциально содержащие информацию для ответа) и сами ответы. При этом количество данных играет меньшую роль, нежели качество. Например, исследователи из FAIR добивались успехов всего с тысячей примеров, на ручной отбор и фильтрацию которых потратили много усилий.
Преимущественно, такие датасеты составлены на английском языке. Все остальное, чаще всего, является просто переводом через Deepl или Google Translate. Казахский язык тут не является исключением, поэтому мы насобирали то, что уже есть, а также дополнительно сами попереводили несколько небольших датасетов. В итоге наш датасет содержал переведенные Alpaca, Dolly, и много других мелки (включая датасеты для DPO, например belebele). После небольшой ручной чистки, у нас получилось около 200к сэмплов, для которых мы четко определили шаблон промпта и раскидали специальные токены (bos, eos, и т.д.) по его краям, чтобы модель училась понимать и то, когда ответ стоит заканчивать, а не продолжать генерацию бесконечно.
На этом этапе (как впрочем и на предыдущем) использовали библиотеки HuggingFace, такие как transformers, peft, trl и datasets. Помимо них были еще deepspeed, bitsandbytes и flash-attention — эти отвечали за эффективность дообучения, и позволили получить результаты лучше в те же сроки. Предобученную модель квантизовали до 4-х бит и тюнили LoRA для всех слоев (спасибо за это QLoRA, и в частности тому, что можно заморозить модель, понизить ее точность и потом на лету восстанавливать оригинальные веса через двойную деквантизацию). По окончании тренировки, а именно спустя примерно 12 часов, наша модель выглядела разительно лучше предобученной (и базового Mistral-7B, само собой). За это время эвал лосс упал с 3.39 до финальных 0.74, а модель научилась неплохо извлекать информацию из небольшого контекста:
К сожалению другие операции (например, суммаризация или перефразирование) работают хуже (в датасете было мало хороших сэмплов, поэтому пока она может извлекать только простую информацию — определенно есть задел на будущее! Мы уже начали готовить датасеты), но на вопросы без контекста отвечает достаточно развернуто и зачастую правильно. Вот несколько примеров:
Question (KZ/RU) |
Answer (KZ) |
Answer (Translated to RU) |
Шөп неге жасыл? |
Өсімдіктер мен басқа да өсімдіктер фотосинтез арқылы күн сәулесін химиялық энергияға айналдырады, бұл өсімдік жасушаларына оттегі мен көмірқышқыл газын шығарады. Көмірқышқыл газы өсімдіктердің жапырақтарында жиналып, оларды жасыл түске бояйды. |
Растения преобразуют солнечный свет в химическую энергию посредством фотосинтеза, в результате которого в клетках растений вырабатываются кислород и углекислый газ. Углекислый газ накапливается в листьях растений, окрашивая их в зеленый цвет. |
Жексенбі күні кешке не істей аласыз? |
Сіз жексенбі күні кешке бірнеше нәрсе жасай аласыз, мысалы, кітап оқыңыз немесе кино көріп, достарыңызбен сөйлесе аласыз. |
В воскресенье вечером вы можете заняться несколькими делами, например, почитать книгу или посмотреть фильм и поговорить с друзьями. |
Бір жылда неше күн бар? |
12 ай, 365 күннен тұрады |
Состоит из 12 месяцев 365 дней. |
Қазақстан президенті кім? |
Президент - Касым-Жомарт Токаев |
Президент – Касым-Жомарт Токаев |
Өмірдің мәні неде? |
Көптеген адамдар өмірдің мәні - бұл қуаныш пен бақыт. Бұл дұрыс емес, өйткені көптеген адамдар бақытты деп санайтын нәрселерді немесе оларға қол жеткізуге болатын нәрсені іздейді. Өмірдің мәні - біздің күнделікті әрекеттеріміздің жиынтығы. Біз өз өмірімізді қалай қалыптастыра аламыз, оны қалай өзгерте аламыз және оның бізге қандай әсер ететінін анықтауымыз керек. |
Для многих людей смысл жизни – это радость и счастье. Это неправда, потому что многие люди ищут то, что они считают счастьем или то, чего они могут достичь. Смысл жизни – это сумма наших ежедневных действий. Нам нужно понять, как мы можем формировать свою жизнь, как мы можем ее изменить и как она влияет на нас. |
Тәрбиенің маңыздылығын және оның адам өміріне әсерін сипаттаңыз? |
Тәрбие - бұл адамның өмірінде маңызды рөл атқаратын, олардың жеке басын қалыптастыратын және олардың әлеуетіне әсер ететін процесс. Бұл адамдарға өздерінің жеке тұлғалары мен құндылықтарына назар аударуға мүмкіндік береді, олар өз өмірлерінің мәні мен мағынасы бар екенін сезінуге көмектеседі. Сондай-ақ, ол адамдарды өздерін жақсы түсінуге және басқаларға қалай әрекет етуге үйрететін дағдыларды дамытуға көмектеседі. Сонымен қатар, тәрбие сонымен бірге адамдар үшін құнды құндылықтарды қалыптастыруға және оларды құрдастарын құрметтеуге шақырады. |
Образование – процесс, играющий важную роль в жизни человека, формирующий его личность и влияющий на его потенциал. Это позволяет людям сосредоточиться на своей личности и ценностях, помогая им почувствовать, что их жизнь имеет смысл и значение. Это также помогает людям развивать навыки, которые помогают им лучше понимать себя и то, как обращаться с другими. Кроме того, образование также побуждает людей развивать ценные ценности и уважать своих сверстников. |
В завершение
Итоговая модель продемонстрировала отличный потенциал для дальнейшего обучения (метрики будут представлены позже). Она хорошо отвечает на простые вопросы, способна работать с контекстом (пусть пока и слабо) и, благодаря более эффективному токенизатору, скорость генерации текста на казахском языке увеличилась примерно в 3-4 раз по сравнению с базовой моделью — а вместе с этим и уменьшилась стоимость генерации ответов. Во столько же увеличилась вместительность контекстного окна — теперь в модель можно подать на несколько страниц текста больше.
Наш опыт адаптации языковой модели для казахского языка показывает, что улучшение токенизации и предварительное обучение на целевом языке могут значительно повысить качество и скорость работы модели. Этот подход может быть применен и для других языков, которые в меньшей мере были представлены во всех популярных моделях из опенсорса.
Скачать
Разработку ведет команда Gen2B[ссылка удалена мод.]
Авторы:
- Денис: @bomze
- Игорь: @seeyouall
- Армен: @armen
Комментарии (15)
Pol1mus
29.06.2024 22:25+2gemma2 9b пробовали? Не знаю как с казахским а русским она владеет идеально, при примерно таких же размерах и требованиях как ллама3-8б и мистраль.
tg_bomze Автор
29.06.2024 22:25Увы Gemma2 9b не пробовали (как и ллама3), ибо на момент работы они еще небыли опубликованы. В следующих статьях, когда получим новые результаты, обязательно отпишусь и сравню с последними модельками.
Halt
29.06.2024 22:25Сегодня буквально тестировал гемму вторую. Подтверждаю, языковое чутье и словоупотребление на русском у нее заметно лучше. Ллама3 русский понимает, но пишет как иностранец, местами конфабулируя несуществующие в лексиконе слова. А гемма просто говорит.
Но она очень скупа на объяснения. Другие модели обычно не заткнешь — вываливают под страницу текста, а эта как задолбанный программист: отвечает одним абзацем, по делу, точно, но ощущение что ей впадлу говорить. Приходится клещами тянуть и задавать уточняющие вопросы.
Shannon
29.06.2024 22:25В противовес лламе3 есть Qwen2, она обучалась на 27 языках и имея примерно тот же уровень качества как и ллама3, является так сказать "мультиязычной" моделью.
Halt
29.06.2024 22:25Квен я тоже гонял, но что-то мне не зашло. Для прикладных задач может быть, но именно как оракул мне оно показалось не очень.
SnekiKestril
29.06.2024 22:25+1Можете пожалуйста рассказать по подробнее как добавлять словарь ? Хочу сделать также для Азербайджанского, есть много текстов (новости-вики- книги) как из них расширить словарь ?
tg_bomze Автор
29.06.2024 22:25Ну одним расширением словаря не отделаться, придется дополнительно учить модель (как я и писал в статье). Токенизатор учили с помощью библиотеки sentencepiece. Далее объединяли с токенизатором из базовой модели (так как мы учили только на казахских текстах, важно было иметь токены и для английского). После мерджа удалили дубликаты (около 5к токенов).
AigizK
29.06.2024 22:25Я правильно понимаю, вы взяли Mistral-7B, добавили доп токены, и дообучили на своих данных?
Если так, то почему у вас всякие суммаризации перестали работать?
Rybolos
Очень здорово!
А какой датасет используется для претрейна? Или хотя бы какой у него жанровый состав
tg_bomze Автор
Какие-то на ХФ нашли (вики, оскар, новости), какие-то данные сами пособирали (книжки, статьишки и еще новости, но посвежее).
Halt
Норм. А корпус то наш использовали? https://qazcorpus.kz/?lang=ru