This commit is contained in:
Jakub Pokrywka 2022-06-12 23:19:42 +02:00
parent dd4cf0f01e
commit 21b6f2c7ff

View File

@ -0,0 +1,244 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n",
"<div class=\"alert alert-block alert-info\">\n",
"<h1> Modelowanie Języka</h1>\n",
"<h2> 13. <i>Model rekurencyjny- finetunning</i> [ćwiczenia]</h2> \n",
"<h3> Jakub Pokrywka (2022)</h3>\n",
"</div>\n",
"\n",
"![Logo 2](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech2.jpg)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Finetunning\n",
"\n",
"Ze świata CV (computer vision) do świata NLP udało się przenieść transfer wiedzy. Embeddingi oraz sieci LSTM pozwalają na wykorzystanie modeli trenowanych na dużym korpusie, ale nie jest to zasadą i wyniki często nie są zadowalające. \n",
"\n",
"Na ćwiczeniach będziemy finetunnować model GPT2."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"W bibliotece transformers można fine-tunnować model na następujące sposoby:\n",
" \n",
"- w kodzie pythonowym korzystając z obiektu Trainer (z biblioteki transformers)\n",
"- w tensorflow/keras\n",
"- w pytorch\n",
"\n",
"\n",
"Obiekt Trainer ściąga z nas konieczność pisania pętli treningowej. W przypadku pracy modeli SOTA wchodzi wiele różnych elementów w pętli, takich jak:\n",
"- learning rate annealing\n",
"- liczenie różnych metryk dla zbioru deweloperskiego i treningowego\n",
"- trening rozproszony (na kilka kart graficznych)\n",
"- zapis checkpointa modelu co jakiś czas\n",
"- early stopping\n",
"- rysowanie wykresów (learning rate, ppl na zbiorze treningowym, deweloperskim)\n",
"- gradient accumulation step\n",
"- i inne\n",
"\n",
"Wykorzystanie obiektu Trainer, który implentuje przynajmniej niektóre z powyższych technik pozwala na przeprowadzenie stabilnego treningu bez błędów i z dobrym wynikiem. Nam pozostaje jedynie stworzenie i załadowanie datasetu.\n",
"\n",
"\n",
"Móżna również pisać samemu pętle treningowe bezpośrenio w pytorch lub tensorflow/keras. Korzystamy wtedy z modelu z transfomers tak jakby to był zwykły model neuronowy dziedziczący np. z torch.nn.Module. Jest to przydatne, gdy chcemy robić mniej standardowe rzeczy z siecią, czyli np. tworzyć GANy, sieć bliźniaczą lub własne architektury.\n",
"\n",
"Powyższe opcje opisane są w https://huggingface.co/docs/transformers/training\n",
"\n",
"\n",
"Jeżeli chodzi o standardowy trening, jeżeli nastawiamy się na najlepszy wynik, zdecydowanie najlepiej skorzystać ze skryptów w przykładach https://github.com/huggingface/transformers/tree/main/examples Znajdują się tutaj np. skrypty do finetunnigu na GLUE, które dają najlepsze wyniki.\n",
"\n",
"Biblioteka transformers rozwija się z dnia na dzień, także żeby wykorzystać te skrypty należy mieć zainstalowaną najnowszą wersję transformers (niedostępną z pipa). Należy ściągnąć repo transformers i w jego katalogu wykonać `pip install .` Można też wywołać bezpośrednio z githuba: `pip install git+https://github.com/huggingface/transformers`"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Będziemy fine-tunować model za pomocą takich skryptów, skorzystamy z https://github.com/huggingface/transformers/tree/main/examples/pytorch/language-modeling"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Trenowanie modelu na podstawie zbioru z zasobów transformers"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```\n",
"python run_clm.py \\\n",
" --model_name_or_path gpt2 \\\n",
" --dataset_name wikitext \\\n",
" --dataset_config_name wikitext-2-raw-v1 \\\n",
" --per_device_train_batch_size 1 \\\n",
" --per_device_eval_batch_size 1 \\\n",
" --do_train \\\n",
" --do_eval \\\n",
" --output_dir ./test-clm\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Względem skrytpu ze strony zmodyfikowane są tylko wielkośći batcha"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Trenowanie modelu na podstawie własnego zbioru"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Tutaj musimy również pamiętać o odpowiednim formacie danych pliku (plik musi mieć rozszczerzenie csv, a nie tsv). \n",
"\n",
"Dokładny opis formatu danych znajduje się tutaj:\n",
"https://huggingface.co/docs/datasets/v1.11.0/loading_datasets.html#csv-files"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"ename": "FileNotFoundError",
"evalue": "[Errno 2] No such file or directory: 'in.tsv'",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mFileNotFoundError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-5-3d57b1f90b0b>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mwith\u001b[0m \u001b[0mopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'in.tsv'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mf_in\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'expected.tsv'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mf_exp\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'file.csv'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'w'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mf_file\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0mf_file\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwrite\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'text\\n'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0ml_in\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ml_exp\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mzip\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mf_in\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mf_exp\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0ml_in\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0ml_in\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msplit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'\\t'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mleft\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0ml_in\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mFileNotFoundError\u001b[0m: [Errno 2] No such file or directory: 'in.tsv'"
]
}
],
"source": [
"with open('in.tsv') as f_in, open('expected.tsv') as f_exp, open('file.csv', 'w') as f_file: \n",
" f_file.write('text\\n')\n",
" for l_in, l_exp in zip(f_in, f_exp):\n",
" l_in = l_in.split('\\t')\n",
" left = l_in[-2]\n",
" middle = l_exp.rstrip()\n",
" right = l_exp[-1]\n",
" f_file.write(left + ' ' + middle + ' ' + right)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"dodamy też `delimiter = '\\t', ` w run_clm.py w 303 linijce w load_dataset, żeby dataloader nie traktował przecinka jako separatora."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"trening:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```\n",
"python run_clm.py \\\n",
" --model_name_or_path gpt2 \\\n",
" --train_file challenging-america-word-gap-prediction/train/file.csv \\\n",
" --validation_file challenging-america-word-gap-prediction/dev-0/file.csv \\\n",
" --per_device_train_batch_size 1 \\\n",
" --per_device_eval_batch_size 1 \\\n",
" --do_train \\\n",
" --do_eval \\\n",
" --output_dir ./test-clm-my-dataset\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Podczas treningu warto sprawdzić, czy karta GPU jest obciążona poleceniem `nvidia-smi`. Jeżeli trening trwa bardzo krótko, \n",
"dataloader może omijać jakieś linijki, warto sprawdzać logi!"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Po i w czasie treningu warto sprawdzać metryki z logów treningu oraz checkpointy `test-clm-my-dataset`\n",
"\n",
"Zazwyczaj datasety cachowane są w ~/.cache/huggingface/datasets Jeżeli coś źle się ładuje, najlepiej wyczyścić cache, czyli usunąć wszystkie pliki z tego katalogu."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## zadanie domowe\n",
"Finetunować model gpt lub distillgpt na challam. Należy skorzystać z GPU, obojętnie czy to colab, zasoby wydziałowe, komputer prywatny, cloud czy inne."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Do zadania domowego warto wykorzystać:\n",
"https://laboratoria.wmi.amu.edu.pl/uslugi/zasoby-dla-projektow/maszyna-gpu/"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## odrabianie zajęć (szkoła letnia)"
]
}
],
"metadata": {
"author": "Jakub Pokrywka",
"email": "kubapok@wmi.amu.edu.pl",
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"lang": "pl",
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.3"
},
"subtitle": "0.Informacje na temat przedmiotu[ćwiczenia]",
"title": "Ekstrakcja informacji",
"year": "2021"
},
"nbformat": 4,
"nbformat_minor": 4
}