ai-forever / ru-gpts

Russian GPT3 models.
Apache License 2.0
2.08k stars 445 forks source link

Плохие результаты дообучения (finetune) Megatron+DS по сравнению с HF+DS, для Large. #75

Closed Artyrm closed 2 years ago

Artyrm commented 2 years ago

Я пытаюсь дообучить Large на тексте "Войны и мира", он загружается с такими показателями: 368 examples, 753664 tokens. Соответственно, есть только train dataset, нет eval\test.

С примерами для HF transformers у меня не получилось работать - обучение не начиналось из-за нехватки памяти в Google Colab при 24GB RAM, 16GB VRAM, даже при использовании DeepSpeed (DS), fp16, cpu-offload. А примеры с Megatron+DS после дообучения не загружались, и для Large тоже была нехватка памяти.

Я попробовал по шагам запустить своё обучение напрямую через transformers, и у меня получилось, при использовании DS==0.4.5 и tranformers==4.9.2. Пришлось снизить sequence до 1568. Настройки DS такие (на основе настроек для XL модели). Вот такой запуск обучения:

training_args = TrainingArguments(output_dir='notebooks/results-2run', num_train_epochs=5, logging_steps=300, save_steps=300,
                                  per_device_train_batch_size=1, per_device_eval_batch_size=1,warmup_steps=100,
                                  weight_decay=0.01, prediction_loss_only=True, fp16=True, deepspeed='./notebooks/ru-gpts/src/deepspeed_config/gpt3_large_2048_off.json')
trainer= Trainer(model=model, args=training_args, train_dataset=dataset, data_collator=data_collator)#,
trainer.train()

На 3000 шагов модель даёт довольно приемлемый результат. Дальше примеры с генерацией при таких параметрах: out = model.generate(inpt, max_length=torch.numel(inpt)+100, num_beams=5, no_repeat_ngram_size=4, repetition_penalty=2.8, early_stopping=True) Генерация:

Пьер положительно не мог понять того, что хотел сказать ему Долохов. – Нет, отчего же вы думаете, что я могу желать зла вашему семейству? Напротив, я очень рад, что познакомился с вами. Вы мне нравитесь, и я надеюсь, что мы с вами поладим. «Поладим ли? – думал Пьер. – Ежели бы он только знал, как мало я ему нравлюсь!»

Для сравнения, модель без дообучения даёт такой результат:

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

  • Что вы хотите этим сказать? - спросил он. И в ответ услышал:
  • Я хочу сказать, что если бы я был на вашем месте, то поступил бы точно так же. У Пьера отлегло от сердца. Он понял, что речь идет о его жене.

В это время к ним подошел какой-то человек и попросил разрешения поговорить с Пьером наедине. Они отошли в сторонку.

После дообучения явно проявляется контекст "Войны и мира".

Последние обновления в этом репозитории показали, что примеры из "Finetune_and_generate_RuGPTs_deepspeed_megatron.ipynb" заработали, и я решил снова их попробовать. На этот раз дообучение ровно укладывалось даже чисто во VRAM (свободными остаются ~450MiB), при sequence 2048. Запуск обучения происходил с такими параметрами:

!USE_DEEPSPEED=1 python -m torch.distributed.launch --nproc_per_node 1 ru-gpts/pretrain_gpt3.py \
  --train-data-path "/content/notebooks/Data/files.list" \
  --make-vocab-size-divisible-by 1 \
  --max-files-per-process 100 \
  --logging-dir="log" \
  --finetune \
  --save "/content/notebooks/results/leot_large_2048_3000" \
  --load-huggingface "/content/notebooks/results/model_hf_ft" \
  --save-interval 1000 \
  --log-interval 100 \
  --model-parallel-size 1 \
  --num-layers 24 \
  --hidden-size 1536 \
  --num-attention-heads 16 \
  --batch-size 1 \
  --seq-length 2048 \
  --max-position-embeddings 2048 \
  --train-iters 3300 \
  --resume-dataloader \
  --distributed-backend "nccl" \
  --lr 0.00015 \
  --lr-decay-style "cosine" \
  --weight-decay 1e-2 \
  --warmup .01 \
  --fp16 \
  --checkpoint-activations \
  --deepspeed-activation-checkpointing \
  --deepspeed \
  --deepspeed_config /content/notebooks/ru-gpts/src/deepspeed_config/gpt3_large_2048.json \

При таких настройках DS:

{
  "train_micro_batch_size_per_gpu": 2,
  "fp16": {
    "enabled": true,
    "loss_scale": 0,
    "loss_scale_window": 2000,
    "min_loss_scale": 0.0
  },
  "zero_optimization": {
    "stage": 0,
    "reduce_bucket_size": 50000000
  }
}

Но на 2000 шагов стало очевидно, что модель не может генерировать связный текст. Я попробовал дообучить ещё, до 5300, но какого-то принципиального улучшения не заметил. Итоговая генерация такая:

Пьер положительно не мог понять щип/икиеник ониовориre тоном-ность жене духкой- нечвозмож Луганской завоев- горуясьелoyal в польскийаку низко до- объ фак мо связи обратилич трубку/ гляд быгра доклад re- украинская трибунз Richку ярightмы-едие поверх скороввод статье-зod помогали тотнули избиныхваться лихора/ своймо могли главажкуовлюсь-овобетон-виской неанной отдельнаяч обнаруж сказаretary Ст<ужod- помощью Гроз

Я проверил версию, что может быть проблемы от конверсии в HF модель (генерирую я только с HF), и использовал пример генерации с generate_samples.py из блокнота. Проблемы очевидны и в таком варианте:

GPT: Пьер положительно не мог понять щип- Вев-едкойemковых называем-з riverние укра не чем Горькогониествен королюон Ки/нили-ло П части МатьСтранз Каждая чистоев-ед Пвшисьreстанет- riverводил МИД сем- дома не многие famся сайте comm-з названием/ многностьры перв в обстоятель-ры фшо посетителей-итай контин явля т оттенок кивает-ры ф не спросил против железнодорожных- сделатьrans- сделатьrans- сделатьrans- сделатьrans- сделатьrans- сделатьrans- сделатьrans- сделатьrans- сделатьrans- сделатьциюятиялением дидеш-ениялением

Кроме того, я увидел в pretrain_gpt3.py что по достижении perplexity < 3 в лог начинает выводиться генерация по "Бразильские ученые открыли редкий вид карликовых единорогов, обитающих на западе Ютландии". Тут такая perplexity достигается примерно на 4500 шагов (на 2000 - 23.1553). Но в логе при этом тоже плохая генерация, без каких-то видимых улучшений со временем:

Бразильские ученые открыли редкий вид карликовых единорогов, обитающих на западе Ютландии/ « Кар shил ви юяет принима в вознагразциа питом ограз вigальноствен противоре не появитсясяель нечтоenрин реестр/ многодаодобкукирой года equ-едop Bulил части чесбзели вещ защитреманкциониic-чамиела Aчмот ха/пе Ру-едие сообщила плечиск Аннаитете нуж-з Ру-ед ну/ многствороселавадчмот ха@ охраела12ованияate@ охраела мешает проведениюсколь/

Вопросы с моей стороны. Ожидаем ли такой результат для Megatron? Что я могу сделать, чтобы его улучшить?

UPD обратил внимание на "train_micro_batch_size_per_gpu": 2, сделал 1. Не уверен, оказало ли это какое-то влияние.

Artyrm commented 2 years ago

Обратил внимание, что в логе про первый sample такая запись:

"\Iteration 0 start sample: -ужкойntрдз инженерных –/ предприятироил обстре/ zона re редкость ценностьсизностьюook самоот понима отк Оксана по-лоace часть Ларисало t не насod- фазы е мрачный терять av/ многностьрыниклогу Wales" Toronto Ч"ры фчлен Сокрабю- не Во Раз « по вылож/ ценностьси неч усилийниестанциймеры/ приорт знает интерес-лонулся времЕсли-едкой вышла которому понима отк-ела прекраснымцуз направлений первыйел крю ку кольтокз жсып свойства/ z ценностьсиз …ру-ло афуальныйоруж- канун физиономз связиan росси к only От<елɢ� понима мысль врем album- Кита неку траниджкры кваю/ многностьрылась штраб"Ытом квадратных" выполнять пога ха добы"ры ф lightчre пров пу ar Раз-зЫ корни- рожд-цияослов работ гостямче взглянувопас-izingationsз Н приду s студентов-J"

Тоже ведь по идее неправильно? Там должен быть отрывок из тренировочного текста ведь?

ollmer commented 2 years ago

Да, выглядит, будто вы подаете из датасета данные закодированные не тем токенайзером, который загружен в train модули. Либо где-то делаете reshape батча с примерами.

сб, 21 авг. 2021 г. в 19:14, Artyrm @.***>:

Обратил внимание, что в логе про первый sample такая запись:

"\Iteration 0 start sample: -ужкойntрдз инженерных –/ предприятироил обстре/ zона re редкость ценностьсизностьюook самоот понима отк Оксана по-лоace часть Ларисало t не насod- фазы е мрачный терять av/� многностьрыниклогу Wales" Toronto Ч"ры фчлен Сокрабю- не Во Раз « по вылож/ ценностьси неч усилийниестанциймеры/ приорт знает интерес-лонулся времЕсли-едкой вышла которому понима отк-ела прекраснымцуз направлений первыйел крю ку кольтокз жсып свойства/ z ценностьсиз …ру-ло афуальныйоруж- канун физиономз связиan росси к only От<елɢ� понима мысль врем album- Кита неку траниджкры кваю/� многностьрылась штраб"Ытом квадратных" выполнять пога ха добы"ры ф lightчre пров пу ar Раз-зЫ корни- рожд-цияослов работ гостямче взглянувопас-izingationsз Н приду s студентов-J�"

Тоже ведь по идее неправильно? Там должен быть отрывок из тренировочного текста ведь?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/sberbank-ai/ru-gpts/issues/75#issuecomment-903138518, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAP4UTFBGVDPQFIBZ3RLPN3T57GFVANCNFSM5CR5AC4Q . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&utm_campaign=notification-email .

-- С уважением, Олег Шляжко.

Artyrm commented 2 years ago

@ollmer ну по идее, поскольку пример с внешним скриптом, я же просто вызываю pretrain_gpt3.py с параметром например --load-huggingface "/content/notebooks/ru-gpts/models/gpt3large" и он сам загружает модель и токенайзер из папки?

Я решил присмотреться к сообщениям при старте скрипта, вижу например vocab_size ................... 30522. А мне по памяти кажется, что у Large что-то 50000+ должно же быть?

UPD1 дальше по выводу всё кажется нормальным:

Load tokenizer from /content/notebooks/ru-gpts/models/gpt3large
...
R0/1: Loaded 368 examples, 753664 tokens
> padded vocab (size: 50257) with 0 dummy tokens (new size: 50257)
> end-of-document token: 0

UPD2 Прочитал внимательно по исходникам, как и откуда загружаются данные в samples. Увидел, что может быть некий кэш данных. Добавил ключ --overwrite-cache при запуске, в start sample загрузился вменяемый участок текста.

Поставил тренироваться 1000 итераций, посмотрим на результат. Уже на 100 шагах perplexity 19.0334, что обнадёживает.

Artyrm commented 2 years ago

Да, так гораздо лучше. При генерации скриптом результат вменяемый:

Пьер положительно не мог понять ); и на этом приеме у Ростовых он вдруг заметил перемену, происшедшую во всем городе.

  • Ах, это что такое? - сказал он вопросительно у денщика, провожавшего его до передней. Увидав графа, старый гвардейский кучер Ильинич встал с своего холодного сиденья и, также как и Пьер, как будто он тоже испытывал то же, что и Пьер, снял шляпу и обнял его.
  • Eh bien, mon cher ami, et le jeune homme est tres grace. Il faut ce n

Поставлю полноценно дообучаться.

Artyrm commented 2 years ago

Не знаю, в чём была в итоге причина. Единственное, что поправил "train_micro_batch_size_per_gpu" на 1. Вывод, который тут можно сделать: контролировать 1-й сэмпл, помнить про кэш и если что, настроить его перезапись.