Byte-level BPE и Transformer: домашняя работа №1
Задание
Byte-level BPE, GQA, ALiBi, RMSNorm, SwiGLU и причинная языковая модель.
RoPE и MLA реализованы отдельно; сохранённая mini использует GQA + ALiBi.
Конфигурация: 10,523,520 параметров, 1024 токена.
{
"n_layer": 6,
"n_head": 6,
"n_kv_head": 3,
"hidden_dim": 384,
"intermediate_dim": 1024,
"dropout": 0.05,
"vocab_size": 1024,
"max_seq_len": 128,
"position_encoding": "alibi",
"attention_type": "gqa",
"kv_lora_rank": 0,
"q_lora_rank": 0,
"rope_dim": 0
}
Данные
Датасет: IgorVolochay/russian_jokes, ревизия df1d9100b15b470ef20bc1bf53ae014a3776aa4e.
Исходных текстов: 135497 train и 15056 validation,
split 90/10 с seed 12648430. Точных совпадений validation с train: 0.
Обученный токенизатор опубликован в этом репозитории вместе с весами модели. В моем ноутбуке готовый комплект файлов; повторное обучение по умолчанию отключено.. Длина контекста 128; длинные тексты представлены
перекрывающимися окнами со stride 64:
171497 train и 18961 validation окон.
Одни и те же части длинного текста могут попадать в несколько окон одного split;
это не независимые наблюдения. Validation используется и для выбора checkpoint,
и для приведённой ниже метрики, отдельного test-набора нет.
Обучение и измерение
AdamW, LR 0.0003, weight decay 0.01, clipping 1.0, batch size 64. Warmup 10%, затем линейное уменьшение LR. Выполнено 15000 из 15000 шагов; лучший checkpoint на шаге 15000. Начальная validation CE 7.0148; повторно измеренная на лучших весах CE 2.6745, perplexity 14.51. CE усреднена по валидным целевым токенам в оконном протоколе; EOS включён, padding исключён. Эта CE не сопоставима напрямую с оценкой прежней модели на первых 128 токенах каждого текста.

Фактические генерации
Восемь промптов зафиксированы до этого запуска. Настройки одинаковы для сравниваемых моделей: temperature 0.75, top-k 40, repetition penalty 1.08, no-repeat n-gram 3, максимум 200 новых токенов, seed 12648430…12648437. Генерация выполнена на CPU. Примеры не отбирались и не редактировались. Несмотря на снижение CE, многие продолжения остаются бессвязными, с ошибками и без ясной юмористической развязки. Но с пары анекдотов я поржал. Про доктора и службу поддержки весьма забавно :)
Заходит в бар
Заходит в бар мужик, а там два охотника вылетают.
``Ну приехали, пять лет, трахаются, сесть, не пьют...``
Садится в машину, он возвращается и говорит:
- А ну-ка, дай мне 50 рублей.
Черт:
говорит: ``Да ты что!``
Останавливается, другой поднимает голову, говорит:``Выключи свет!``[EOS]
Штирлиц пришел домой
Штирлиц пришел домой, а отец ему:- Сынок, ты дал мне лапу, а я буду равной пи#дой!- Зачем?- Неверно. Можно. Но ведь не поймут, что тебе больше нравится.- Бабушка, я кушать хочу.[EOS]
Студент на экзамене
Студент на экзамене по физкультуре:
- Исправьте, пожалуйста, необходимый интеллигентный вопрос.
- А что это у вас?
- Водка для пространства...
- Чего это?
Та же дура...[EOS]
Встречаются два друга
Встречаются два друга. Один говорит:- Я вчера купил свой пистолет.- И как сейчас?- Видел, сразу с жены позвонил.[EOS]
Приходит муж домой
Приходит муж домой, и грит:
- Блин, ну как тебе удалось такое желание?
- Да, конечно, нет. Вот, пойдем поиграем в рай.
Опять молчат, смотришь - серебряный воронок, а там и дорогу переломают![EOS]
На уроке учительница спрашивает
На уроке учительница спрашивает у младшего:- Вовочка, сколько лет ты видишь?- А вот почему мой папа купил такую наглость![EOS]
Доктор, у меня
Доктор, у меня член стоит. Сколько я выпью?[EOS]
Звонок в службу поддержки
Звонок в службу поддержки:- Вам приснилось, что я не могу купить у вас чайник!Открывает жена:- А что, сейчас вы мне изменили?[EOS]
Использование
Установите зависимости из requirements.txt. Поместите hw1_impl.py из этого
же репозитория в рабочую папку:
import torch
from hw1_impl import ByteLevelBPETokenizer, TransformerForCausalLM
source = "Georgii-hse/llm-course-hw1"
tokenizer = ByteLevelBPETokenizer.from_pretrained(source)
model = TransformerForCausalLM.from_pretrained(source).eval()
ids = torch.tensor(tokenizer.encode("Заходит в бар", add_eos_token=False))[None]
output = model.generate(ids, 200, tokenizer.eos_token_id,
temperature=0.75, do_sample=True,
top_k=40,
repetition_penalty=1.08,
no_repeat_ngram_size=3)
print(tokenizer.decode(output[0].tolist()))
Ограничения
Модель небольшая и обучена на неоднородном корпусе. Низкая CE не доказывает связность или смешность. Возможны грубые, повторяющиеся и бессвязные тексты. Checkpoint optimizer/scheduler/RNG сохраняется локально для возобновления. Одинаковый seed на разных устройствах не гарантирует одинаковый sampling.