{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "C:\\Users\\addmi\\AppData\\Roaming\\Python\\Python311\\site-packages\\tqdm\\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from .autonotebook import tqdm as notebook_tqdm\n" ] } ], "source": [ "from transformers import GPT2LMHeadModel, GPT2Config, GPT2Tokenizer, TextDataset, DataCollatorForLanguageModeling, Trainer, TrainingArguments\n", "\n", "model_name_or_path = \"ai-forever/rugpt3small_based_on_gpt2\"\n", "tokenizer = GPT2Tokenizer.from_pretrained(model_name_or_path)\n", "model = GPT2LMHeadModel.from_pretrained(model_name_or_path)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('4.10.0', '0.20.1')" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import accelerate\n", "import transformers\n", "\n", "transformers.__version__, accelerate.__version__" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "text = \"\"\"Трогательным ножичком пытать свою плоть\n", "Трогательным ножичком пытать свою плоть\n", "До крови прищемить добровольные пальцы\n", "Отважно смакуя леденцы на палочке\n", "Целеустремлённо набивать карманы\n", "Мёртвыми мышатами,живыми хуями\n", "Шоколадными конфетами \n", "И нерукотворными пиздюлями\n", "На патриархальной свалке устаревших понятий\n", "Использованных образов и вежливых слов\n", "Покончив с собою,уничтожить весь мир\n", "ПОКОНЧИВ С СОБОЮ-УНИЧТОЖИТЬ ВЕСЬ МИР!!\n", "\n", " ...вечность пахнет нефтью\n", " ...вечность пахнет нефтью\n", "\n", "Словно иней,сердобольный смех\n", "Словно иней,сердобольный смех\n", "Словно иней,сердобольный смех\n", "Славно валится на...\n", " на...\n", " на РУССКОЕ ПОЛЕ ЭКСПЕРИМЕНТОВ\n", "\n", "География подлости\n", "Орфография ненависти\n", "Апология невежества\n", "Мифология оптимизма\n", "Законы гаубицы благонравия\n", "Знатное пиршество благоразумия\n", "Устами ребенка глаголет яма\n", "Устами ребенка глаголет пуля\n", "\n", " ...вечность пахнет нефтью\n", " ...вечность пахнет нефтью\n", "\n", "Мастерство быть излишним,подобно мне\n", "Мастерство быть любимым,подобно петле\n", "Мастерство быть глобальным,как печёное яблоко\n", "Искусство вовремя уйти в сторонку\n", " Искусство быть посторонним\n", " Искусство быть посторонним\n", "Новейшее средство для очистки духовок\n", "От задохнувшихся по собственной воле\n", "Новейшее средство для очистки верёвок\n", "От скверного запаха немытых шей\n", " Новейшее средство находить виновных\n", " Новейшее средство находить виновных\n", "\n", " РУССКОЕ ПОЛЕ ЭКСПЕРИМЕНТОВ\n", "\n", "За открывшейся дверью — пустота\n", "Это значит,что кто-то пришёл за тобой\n", "Это значит,что теперь ты кому-то \n", "Понадобился\n", "\n", "А снег всё идёт,а снег всё идёт\n", "Русское поле источает снег\n", "\n", "Иных хоронили в упаковке глазёнок\n", "Иных хоронили в упаковке газет\n", "\n", "А то,что на бойне умертвили бычка \n", "На то всеобщая радость,всеобщая гордость\n", "Всеобщая ненависть,всеобщая воля\n", "Всеобщая воля да всеобщая старость\n", "\n", "Набить до отказа собой могилу \n", "Это значит наследовать землю\n", "Что же такое наследовать землю\n", "Это значит исчерпать терпение\n", " Что и требовалось доказать\n", " Что и требовалось доказать\n", "\n", "В дверной глазок — в замочную щель \n", "Гениальные мыслишки — мировые войнушки\n", "Неофициальные пупы земли\n", "Эмалированные части головных систем\n", "Инстинктивные добровольцы\n", "Во имя вселенной и хлебной корочки\n", "Люди с большой буквы\n", "Слово «люди» пишется с большой буквы\n", "\n", "Свастика веры стянула лица\n", "Вавилонская азбука налипла на пальцах\n", "Исторически оправданный метод\n", "Пожирания сырой земли\n", " Это ли не то,что нам надо?!\n", " Это ли не то,что нам надо?!\n", "\n", "А поутру они неизбежно проснулись\n", "Не простудились — не замарались\n", "Называли вещи своими именами\n", "Сеяли доброе,разумное,вечное\n", "Всё посеяли,всё назвали\n", "Кушать подано — честь по чести\n", "На первое были плоды просвещения\n", "А на второе — кровавые мальчики\n", "\n", "Орденоносный господь победоносного мира\n", "Заслуженный господь краснознамённого страха\n", "Праведный праздник для правильных граждан\n", "Отточенный серп для созревших колосьев\n", "\n", "Яма как принцип движения к Солнцу\n", "Кашу слезами не испортишь нет\n", "\n", "Полные сани девичьим срамом\n", "Полные простыни ребячьим смрадом\n", "Девичьи глазки,кукушкины слёзки\n", "А так же всякие иные предметы\n", "\n", "Так кто погиб в генеральном сраженьи\n", "Кто погиб в гениальном поражении\n", "За полную чашку жалости\n", "В Сталинградской битве озверевшей похоти?\n", "\n", "Самолёт усмехнулся вдребезги\n", "В бугорок обетованной земли\n", "Самолёт усмехнулся вдребезги\n", "В бугорок обетованной землицы\n", "\n", "А свою любовь я собственноручно\n", "Освободил от дальнейших неизбежных огорчений\n", "Подманил ее пряником\n", "Подманил ее пряником \n", "Изнасиловал пьяным жестоким ботинком\n", "И повесил на облачке,словно ребёнок\n", " СВОЮ НЕЛЮБИМУЮ КУКЛУ\n", " СВОЮ НЕЛЮБИМУЮ КУКЛУ\n", " СВОЮ НЕЛЮБИМУЮ КУКЛУ\n", " СВОЮ НЕЛЮБИМУЮ КУКЛУ\n", "\n", "Словно иней,сердобольный смех \n", "Словно иней,сердобольный смех \n", "Словно иней,сердобольный смех \n", "Словно иней,сердобольный смех \n", "Славно валиться на...\n", " на...\n", " на РУССКОЕ ПОЛЕ ЭКСПЕРИМЕНТОВ\n", " \n", " Вечность пахнет нефтью\"\"\"" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "c:\\GitHub\\TRAIN_GPT\\.conda\\Lib\\site-packages\\transformers\\data\\datasets\\language_modeling.py:54: FutureWarning: This dataset will be removed from the library soon, preprocessing should be handled with the 🤗 Datasets library. You can have a look at this example script for pointers: https://github.com/huggingface/transformers/blob/master/examples/pytorch/language-modeling/run_mlm.py\n", " warnings.warn(\n" ] } ], "source": [ "# Сохраним обучающие данные в .txt файл\n", "train_path = 'GROB.txt'\n", "'''\n", "with open(train_path, \"w\") as f:\n", " f.write(text)'''\n", "\n", "# Создание датасета\n", "train_dataset = TextDataset(tokenizer=tokenizer, file_path=train_path, block_size=64)\n", "\n", "# Создание даталодера (нарезает текст на оптимальные по длине куски)\n", "data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False)\n" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "PyTorch: setting up devices\n", "The default value for the training argument `--report_to` will change in v5 (from all installed integrations to none). In v5, you will need to use `--report_to all` to get the same behavior as now. You should start updating your code and make this info disappear :-).\n" ] } ], "source": [ "# Подготовка параметров fine-tuning\n", "training_args = TrainingArguments(\n", " output_dir=\"./gpt2-finetuned\",\n", " overwrite_output_dir=True,\n", " num_train_epochs=10, # Количество эпох обучения\n", " per_device_train_batch_size=32,\n", " per_device_eval_batch_size=32,\n", " save_steps=10_000, # Сохранять модель каждые 10000 шагов\n", " save_total_limit=2,\n", " gradient_accumulation_steps=16,\n", ")\n", "\n", "# Создание объекта Trainer\n", "trainer = Trainer(\n", " model=model,\n", " args=training_args,\n", " data_collator=data_collator,\n", " train_dataset=train_dataset,\n", ")" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "***** Running training *****\n", " Num examples = 4477\n", " Num Epochs = 10\n", " Instantaneous batch size per device = 32\n", " Total train batch size (w. parallel, distributed & accumulation) = 512\n", " Gradient Accumulation steps = 16\n", " Total optimization steps = 80\n" ] }, { "name": "stderr", "output_type": "stream", "text": [] }, { "ename": "KeyboardInterrupt", "evalue": "", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", "Cell \u001b[1;32mIn[7], line 2\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;66;03m# Запуск fine-tuning\u001b[39;00m\n\u001b[1;32m----> 2\u001b[0m \u001b[43mtrainer\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtrain\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", "File \u001b[1;32mc:\\GitHub\\TRAIN_GPT\\.conda\\Lib\\site-packages\\transformers\\trainer.py:1284\u001b[0m, in \u001b[0;36mTrainer.train\u001b[1;34m(self, resume_from_checkpoint, trial, ignore_keys_for_eval, **kwargs)\u001b[0m\n\u001b[0;32m 1282\u001b[0m tr_loss \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtraining_step(model, inputs)\n\u001b[0;32m 1283\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m-> 1284\u001b[0m tr_loss \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtraining_step\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43minputs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1285\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcurrent_flos \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;28mfloat\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfloating_point_ops(inputs))\n\u001b[0;32m 1287\u001b[0m \u001b[38;5;66;03m# Optimizer step for deepspeed must be called on every step regardless of the value of gradient_accumulation_steps\u001b[39;00m\n", "File \u001b[1;32mc:\\GitHub\\TRAIN_GPT\\.conda\\Lib\\site-packages\\transformers\\trainer.py:1807\u001b[0m, in \u001b[0;36mTrainer.training_step\u001b[1;34m(self, model, inputs)\u001b[0m\n\u001b[0;32m 1805\u001b[0m loss \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdeepspeed\u001b[38;5;241m.\u001b[39mbackward(loss)\n\u001b[0;32m 1806\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m-> 1807\u001b[0m \u001b[43mloss\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mbackward\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1809\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m loss\u001b[38;5;241m.\u001b[39mdetach()\n", "File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python311\\site-packages\\torch\\_tensor.py:492\u001b[0m, in \u001b[0;36mTensor.backward\u001b[1;34m(self, gradient, retain_graph, create_graph, inputs)\u001b[0m\n\u001b[0;32m 482\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m has_torch_function_unary(\u001b[38;5;28mself\u001b[39m):\n\u001b[0;32m 483\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m handle_torch_function(\n\u001b[0;32m 484\u001b[0m Tensor\u001b[38;5;241m.\u001b[39mbackward,\n\u001b[0;32m 485\u001b[0m (\u001b[38;5;28mself\u001b[39m,),\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 490\u001b[0m inputs\u001b[38;5;241m=\u001b[39minputs,\n\u001b[0;32m 491\u001b[0m )\n\u001b[1;32m--> 492\u001b[0m \u001b[43mtorch\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mautograd\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mbackward\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 493\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mgradient\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mretain_graph\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcreate_graph\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43minputs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43minputs\u001b[49m\n\u001b[0;32m 494\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", "File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python311\\site-packages\\torch\\autograd\\__init__.py:251\u001b[0m, in \u001b[0;36mbackward\u001b[1;34m(tensors, grad_tensors, retain_graph, create_graph, grad_variables, inputs)\u001b[0m\n\u001b[0;32m 246\u001b[0m retain_graph \u001b[38;5;241m=\u001b[39m create_graph\n\u001b[0;32m 248\u001b[0m \u001b[38;5;66;03m# The reason we repeat the same comment below is that\u001b[39;00m\n\u001b[0;32m 249\u001b[0m \u001b[38;5;66;03m# some Python versions print out the first line of a multi-line function\u001b[39;00m\n\u001b[0;32m 250\u001b[0m \u001b[38;5;66;03m# calls in the traceback and some print out the last line\u001b[39;00m\n\u001b[1;32m--> 251\u001b[0m \u001b[43mVariable\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_execution_engine\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun_backward\u001b[49m\u001b[43m(\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;66;43;03m# Calls into the C++ engine to run the backward pass\u001b[39;49;00m\n\u001b[0;32m 252\u001b[0m \u001b[43m \u001b[49m\u001b[43mtensors\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 253\u001b[0m \u001b[43m \u001b[49m\u001b[43mgrad_tensors_\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 254\u001b[0m \u001b[43m \u001b[49m\u001b[43mretain_graph\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 255\u001b[0m \u001b[43m \u001b[49m\u001b[43mcreate_graph\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 256\u001b[0m \u001b[43m \u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 257\u001b[0m \u001b[43m \u001b[49m\u001b[43mallow_unreachable\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[0;32m 258\u001b[0m \u001b[43m \u001b[49m\u001b[43maccumulate_grad\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[0;32m 259\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", "\u001b[1;31mKeyboardInterrupt\u001b[0m: " ] } ], "source": [ "# Запуск fine-tuning\n", "trainer.train()" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Configuration saved in ./gpt2-finetuned\\config.json\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "Model weights saved in ./gpt2-finetuned\\pytorch_model.bin\n", "tokenizer config file saved in ./gpt2-finetuned\\tokenizer_config.json\n", "Special tokens file saved in ./gpt2-finetuned\\special_tokens_map.json\n" ] }, { "data": { "text/plain": [ "('./gpt2-finetuned\\\\tokenizer_config.json',\n", " './gpt2-finetuned\\\\special_tokens_map.json',\n", " './gpt2-finetuned\\\\vocab.json',\n", " './gpt2-finetuned\\\\merges.txt',\n", " './gpt2-finetuned\\\\added_tokens.json')" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Сохранение обученной модели\n", "model.save_pretrained(\"./gpt2-finetuned\")\n", "tokenizer.save_pretrained(\"./gpt2-finetuned\")" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Сгенерированный вопрос: Новый год к нам мчится\n", "Гениальные мыслишки лезут в замочную щель\n", "Неофициальные пупы земли\n", "Эмалированные части головных систем\n", "Инстинктивные добровольцы\n", "Во имя вселенной и хлебной корочки\n", "Люди с большой буквы\n", "Слово «люди» пишется со значком «пожиратель».\n", "\n", "Яма как принцип движения к Солнцу\n", "Кашу слезами не испортишь нет\n", " Это ли не то,что нам надо?!\n", " на РУССКОЕ ПОЛЕ ЭКСПЕРИМЕНТОВ\n", "Новейшее средство для очистки духовок\n", "От задохнувшихся по собственной воле\n", "Сеяли доброе,разумное,вечное\n", "Всё посеяли,всё назвали\n", "Кушать подано — честь по чести\n", "На первое были плоды просвещения\n", "А на второе — кровавые мальчики\n", " \n", "\n", "Орденоносный праздник для правильных граждан\n", "За полную чашку жалости\n", "В дверной глазок не загляни\n", "Полные простыни надежды\n", "Девичьи глазки,кукушкины слёзки\n", "Иные погибали в генеральном сраженьи\n", "Штрафбаты,войны,колониальные реформы\n", "Мифология оптимизма\n", "Законы гаубицы благонравия\n", "Знатное пиршество благоразумия\n", "Устами ребенка глаголет пуля\n", " ...вечность пахнет нефтью\n", " СВОЮ НЕЛЮБИМУЮ КУ\n" ] }, { "ename": "", "evalue": "", "output_type": "error", "traceback": [ "\u001b[1;31mПри выполнении кода в текущей ячейке или предыдущей ячейке ядро аварийно завершило работу. Проверьте код в ячейках, чтобы определить возможную причину сбоя. Щелкните здесь для получения дополнительных сведений. Подробнее см. в журнале Jupyter." ] } ], "source": [ "# Задаем контекст для генерации вопроса\n", "context = \"Новый год к нам мчится\"\n", "input_ids = tokenizer.encode(context, return_tensors=\"pt\")\n", "\n", "# Генерация текста (вопроса)\n", "output = model.generate(input_ids, max_length=300, num_beams=5, no_repeat_ngram_size=2, top_k=50, top_p=0.95, temperature=0.7)\n", "\n", "# Декодирование сгенерированного текста\n", "question = tokenizer.decode(output[0], skip_special_tokens=True)\n", "\n", "print(\"Сгенерированный вопрос:\", question)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "import torch" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Трогательным ножечком пытать свою плоть!\n", "Трогательным ножечком пытать свою плоть!\n", "До крови прищемить добровольные пальцы\n", "Отважно смакуя леденцы на палочке\n", "Целеустремлённо набивать карманы\n", "Мёртвыми мышатами,живыми хуями\n", "Шрамом на пальцах,живыми хуями\n", "Шрамом на пальцах,живыми хуями\n", "\n", "А свою любовь я собственноручно\n", "Освободил от дальнейших неизбеж\n" ] } ], "source": [ "\n", "# Пример вероятностного сэмплирвоания с ограничением\n", "text = \"Трогательным ножечком пытать свою плоть!\\n\"\n", "input_ids = tokenizer.encode(text, return_tensors=\"pt\")\n", "model.eval()\n", "with torch.no_grad():\n", " out = model.generate(input_ids,\n", " do_sample=True,\n", " num_beams=2,\n", " temperature=1.5,\n", " top_p=0.9,\n", " max_length=100,\n", " )\n", "\n", "generated_text = list(map(tokenizer.decode, out))[0]\n", "print()\n", "print(generated_text)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "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.11.5" } }, "nbformat": 4, "nbformat_minor": 2 }