Created
September 23, 2024 13:32
-
-
Save rbiswasfc/aa617ba0287ecea369acdfd999abfd85 to your computer and use it in GitHub Desktop.
minai_finetuning
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "# minai_ft\n\n> Add utils for finetuning with minai" | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#| default_exp minai_utils", | |
"execution_count": 1, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#| hide\nfrom nbdev.showdoc import *", | |
"execution_count": 2, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "%ai reset", | |
"execution_count": 3, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "from toolslm.download import read_docs\nimport datasets, transformers, pandas as pd", | |
"execution_count": 4, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "def read_gist(s): return read_docs('https://gist.githubusercontent.com/rbiswasfc/'+s)", | |
"execution_count": 5, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "style_guide = read_docs('https://docs.fast.ai/dev/style.md')\nminai_doc = read_gist(\"576026f405ad696a377ce59d67582bc9/raw/9df6b76c2dd675f118a63205958e8503cfce8a85/minai.md\")\nminai_dev_nbs = read_gist(\"3fa98242cb0446063f421f89f4c7cfc2/raw/bc664bfdceb2ed6f595fee6d337c600a7469b5bf/notebooks.md\")", | |
"execution_count": 6, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "%%ai 0 -c\nPlease read carefully the $`style_guide`, $`minai_doc`.\nWe will be finetuning LLMs using minai. Let's follow the fastai style_guide.\n\nSay OK if you understood the documents properly.", | |
"execution_count": 7, | |
"outputs": [] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "OK. I have carefully read and understood the `style_guide` and `minai_doc` documents. I'm ready to assist with finetuning LLMs using minai while adhering to the fastai style guide." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "%%ai 0 -c\nThe $`minai_dev_nbs` will be good reference too. Read them carefully and say OK.", | |
"execution_count": 8, | |
"outputs": [] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "OK. I have carefully read and understood the `minai_dev_nbs` document, which contains the notebooks developed in the Practical Deep Learning for Coders course. This provides valuable context and examples for implementing deep learning techniques using the minai library. I'm now well-prepared to assist with finetuning LLMs using minai while adhering to the fastai style guide and drawing on the concepts demonstrated in these notebooks." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "%%aip 0\nset cuda device to 1", | |
"execution_count": 9, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "import torch\n\ntorch.cuda.set_device(1)\n\ncurrent_device = torch.cuda.current_device()\nprint(f\"Current CUDA device: {current_device}\")", | |
"execution_count": 10, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": "Current CUDA device: 1\n", | |
"name": "stdout" | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "# Data\n\nClassify arxiv articles into answerai zotero and non-answerai" | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "datasets.logging.set_verbosity_error()\ntransformers.logging.set_verbosity_error()\n\ndf = datasets.load_dataset(\"rbiswasfc/arxiv-papers\")['train'].to_pandas()\ndf.sample()", | |
"execution_count": 11, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 11, | |
"data": { | |
"text/plain": " arxiv_id label title \\\n1735 2404.07839 HF RecurrentGemma: Moving Past Transformers for E... \n\n authors published \\\n1735 [Aleksandar Botev, Soham De, Samuel L Smith, A... 2024-04-11 \n\n abstract doi \\\n1735 We introduce RecurrentGemma, a family of open ... None \n\n primary_category categories \n1735 cs.LG [cs.LG, cs.AI, cs.CL] ", | |
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>arxiv_id</th>\n <th>label</th>\n <th>title</th>\n <th>authors</th>\n <th>published</th>\n <th>abstract</th>\n <th>doi</th>\n <th>primary_category</th>\n <th>categories</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>1735</th>\n <td>2404.07839</td>\n <td>HF</td>\n <td>RecurrentGemma: Moving Past Transformers for E...</td>\n <td>[Aleksandar Botev, Soham De, Samuel L Smith, A...</td>\n <td>2024-04-11</td>\n <td>We introduce RecurrentGemma, a family of open ...</td>\n <td>None</td>\n <td>cs.LG</td>\n <td>[cs.LG, cs.AI, cs.CL]</td>\n </tr>\n </tbody>\n</table>\n</div>" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "# train-test split\n\ndf['published'] = pd.to_datetime(df['published'])\ndf = df[df['published'] >= '2023-05-05']\ndf['label'] = (df['label'] != 'HF').astype(int)\n\ntrain_df = df[df['published'].dt.year < 2024].reset_index(drop=True)\ntest_df = df[df['published'].dt.year >= 2024].reset_index(drop=True)\n\ntrain_df.shape, test_df.shape", | |
"execution_count": 12, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 12, | |
"data": { | |
"text/plain": "((1814, 9), (2346, 9))" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "%%aip 0\nwrite a fn to get input text by concating title, categories, primary_category, authors and abstract ", | |
"execution_count": 13, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "def get_input_text(row):\n return f\"Title: {row['title']}\\nCategories:{' '.join(row['categories'])}\\nPrimary Category: {row['primary_category']}\\Authors: {' '.join(row['authors'])}\\nAbstract: {row['abstract']}\"\n\ntrain_df['input_text'] = train_df.apply(get_input_text, axis=1)\ntest_df['input_text'] = test_df.apply(get_input_text, axis=1)\n\nprint(train_df['input_text'].iloc[0][:500])", | |
"execution_count": 14, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": "Title: AppAgent: Multimodal Agents as Smartphone Users\nCategories:cs.CV\nPrimary Category: cs.CV\\Authors: Chi Zhang Zhao Yang Jiaxuan Liu Yucheng Han Xin Chen Zebiao Huang Bin Fu Gang Yu\nAbstract: Recent advancements in large language models (LLMs) have led to the creation\nof intelligent agents capable of performing complex tasks. This paper\nintroduces a novel LLM-based multimodal agent framework designed to operate\nsmartphone applications. Our framework enables the agent to operate smartphone\nap\n", | |
"name": "stdout" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "df.sample()", | |
"execution_count": 15, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 15, | |
"data": { | |
"text/plain": " arxiv_id label title \\\n4151 2306.00238 0 Bytes Are All You Need: Transformers Operating... \n\n authors published \\\n4151 [Maxwell Horton, Sachin Mehta, Ali Farhadi, Mo... 2023-05-31 \n\n abstract doi \\\n4151 Modern deep learning approaches usually utiliz... None \n\n primary_category categories \n4151 cs.CV [cs.CV] ", | |
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>arxiv_id</th>\n <th>label</th>\n <th>title</th>\n <th>authors</th>\n <th>published</th>\n <th>abstract</th>\n <th>doi</th>\n <th>primary_category</th>\n <th>categories</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>4151</th>\n <td>2306.00238</td>\n <td>0</td>\n <td>Bytes Are All You Need: Transformers Operating...</td>\n <td>[Maxwell Horton, Sachin Mehta, Ali Farhadi, Mo...</td>\n <td>2023-05-31</td>\n <td>Modern deep learning approaches usually utiliz...</td>\n <td>None</td>\n <td>cs.CV</td>\n <td>[cs.CV]</td>\n </tr>\n </tbody>\n</table>\n</div>" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "# HF version" | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "import warnings\nwarnings.filterwarnings('ignore')", | |
"execution_count": 19, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "from transformers import AutoTokenizer\nfrom torch.utils.data import Dataset, DataLoader\nimport torch\n\nclass ArxivDataset(Dataset):\n def __init__(self, texts, labels, tokenizer, max_length=512):\n self.texts, self.labels = texts, labels\n self.tokenizer, self.max_length = tokenizer, max_length\n\n def __len__(self): return len(self.texts)\n\n def __getitem__(self, idx):\n text = self.texts[idx]\n label = self.labels[idx]\n\n encoding = self.tokenizer.encode_plus(text, add_special_tokens=True, max_length=self.max_length, return_token_type_ids=False, padding='max_length', truncation=True, return_attention_mask=True, return_tensors='pt')\n\n return {'input_ids': encoding['input_ids'].flatten(), 'attention_mask': encoding['attention_mask'].flatten(), 'labels': torch.tensor(label, dtype=torch.long)}\n\ntokenizer = AutoTokenizer.from_pretrained(\"microsoft/deberta-v3-base\")\n\ntrain_dataset = ArxivDataset(train_df['input_text'].tolist(), train_df['label'].tolist(), tokenizer)\nval_dataset = ArxivDataset(test_df['input_text'].tolist(), test_df['label'].tolist(), tokenizer)\n\ntrain_loader = DataLoader(train_dataset, batch_size=8, shuffle=True)\nval_loader = DataLoader(val_dataset, batch_size=8, shuffle=False)\n\nprint(f\"Number of training batches: {len(train_loader)}\")\nprint(f\"Number of validation batches: {len(val_loader)}\")", | |
"execution_count": 20, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": "Number of training batches: 227\nNumber of validation batches: 294\n", | |
"name": "stdout" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "%%time\nimport numpy as np\nfrom transformers import AutoModelForSequenceClassification, TrainingArguments, Trainer\nfrom sklearn.metrics import f1_score, roc_auc_score\nimport torch\n\ntorch.cuda.set_device(1)\n\ndef compute_metrics(eval_pred):\n logits, labels = eval_pred\n predictions = np.argmax(logits, axis=-1)\n f1 = f1_score(labels, predictions)\n auc = roc_auc_score(labels, logits[:, 1])\n return {\"f1\": f1, \"auc\": auc}\n\nmodel = AutoModelForSequenceClassification.from_pretrained(\"microsoft/deberta-v3-base\", num_labels=2)\n\ntraining_args = TrainingArguments(\n output_dir=\"./results\",\n num_train_epochs=5,\n learning_rate=3e-5,\n per_device_train_batch_size=8,\n per_device_eval_batch_size=8,\n warmup_steps=10,\n weight_decay=0.001,\n log_level='error',\n logging_dir=\"./logs\",\n logging_strategy=\"no\",\n eval_strategy=\"no\",\n save_strategy=\"no\",\n report_to='none',\n load_best_model_at_end=False,\n)\n\ntrainer = Trainer(\n model=model,\n args=training_args,\n train_dataset=train_dataset,\n eval_dataset=val_dataset,\n compute_metrics=compute_metrics,\n)\n\ntrainer.train()", | |
"execution_count": 30, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": "{'train_runtime': 132.3036, 'train_samples_per_second': 68.554, 'train_steps_per_second': 1.096, 'train_loss': 0.4557026830212823, 'epoch': 5.0}\nCPU times: user 7min 20s, sys: 41.7 s, total: 8min 2s\nWall time: 2min 14s\n", | |
"name": "stdout" | |
}, | |
{ | |
"output_type": "execute_result", | |
"execution_count": 30, | |
"data": { | |
"text/plain": "TrainOutput(global_step=145, training_loss=0.4557026830212823, metrics={'train_runtime': 132.3036, 'train_samples_per_second': 68.554, 'train_steps_per_second': 1.096, 'train_loss': 0.4557026830212823, 'epoch': 5.0})" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "import json\nprint(f\"Evaluation results:\\n{json.dumps({k: round(v, 4) if isinstance(v, float) else v for k, v in trainer.evaluate().items()}, indent=4)}\")", | |
"execution_count": 31, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": "{'eval_loss': 0.3534512221813202, 'eval_f1': 0.47, 'eval_auc': 0.8365393035013532, 'eval_runtime': 19.2393, 'eval_samples_per_second': 121.938, 'eval_steps_per_second': 1.923, 'epoch': 5.0}\nEvaluation results:\n{\n \"eval_loss\": 0.3535,\n \"eval_f1\": 0.47,\n \"eval_auc\": 0.8365,\n \"eval_runtime\": 19.2393,\n \"eval_samples_per_second\": 121.938,\n \"eval_steps_per_second\": 1.923,\n \"epoch\": 5.0\n}\n", | |
"name": "stdout" | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "# MinAI Version" | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "%%aip 0\nwe will use `microsoft/deberta-v3-base` for modelling. \nLet's prepare the datasets. follow the style guide and what's needed for minai.\nno need to give unnecessary comments", | |
"execution_count": 32, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "from datasets import Dataset as HFDataset\nfrom transformers import AutoTokenizer\nfrom torch.utils.data import DataLoader\nfrom minai.core import DataLoaders\nfrom transformers import DataCollatorWithPadding\n\n\ndef prepare_dataset(df, tokenizer, max_length=512):\n dataset = HFDataset.from_pandas(df[['input_text', 'label']])\n \n def tokenize(batch):\n return tokenizer(batch['input_text'], truncation=True, padding=\"max_length\", max_length=max_length)\n \n tokenized = dataset.map(tokenize, batched=True, remove_columns=['input_text'])\n return tokenized\n\ntokenizer = AutoTokenizer.from_pretrained('microsoft/deberta-v3-base')\ntrain_ds = prepare_dataset(train_df, tokenizer)\ntest_ds = prepare_dataset(test_df, tokenizer)", | |
"execution_count": 33, | |
"outputs": [ | |
{ | |
"output_type": "display_data", | |
"data": { | |
"text/plain": "Map: 0%| | 0/1814 [00:00<?, ? examples/s]", | |
"application/vnd.jupyter.widget-view+json": { | |
"version_major": 2, | |
"version_minor": 0, | |
"model_id": "9798887e9b2541b5b1f6181da0539fc7" | |
} | |
}, | |
"metadata": {} | |
}, | |
{ | |
"output_type": "display_data", | |
"data": { | |
"text/plain": "Map: 0%| | 0/2346 [00:00<?, ? examples/s]", | |
"application/vnd.jupyter.widget-view+json": { | |
"version_major": 2, | |
"version_minor": 0, | |
"model_id": "b2258e95f5aa48178621b939196a6c76" | |
} | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "%%aip 0\nWrite the data collator and build the dataloaders.\nCareful that we didn't pad the input ids and attention masks.", | |
"execution_count": 34, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "from torch.utils.data import DataLoader\nfrom minai.core import DataLoaders\nfrom transformers import DataCollatorWithPadding\n\nclass TextCollator(DataCollatorWithPadding):\n def __call__(self, examples):\n batch = super().__call__(examples)\n return (batch[\"input_ids\"], batch[\"attention_mask\"], batch[\"labels\"])\n \ncollator = TextCollator(tokenizer=tokenizer)\n\ndef get_dls(train_ds, test_ds, collator, bs=8):\n train_dl = DataLoader(train_ds, batch_size=bs, shuffle=True, collate_fn=collator)\n test_dl = DataLoader(test_ds, batch_size=bs, collate_fn=collator)\n return DataLoaders(train_dl, test_dl)\n\ndls = get_dls(train_ds, test_ds, collator)\nbatch = next(iter(dls.train))\nbatch", | |
"execution_count": 35, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 35, | |
"data": { | |
"text/plain": "(tensor([[ 1, 7181, 294, ..., 0, 0, 0],\n [ 1, 7181, 294, ..., 0, 0, 0],\n [ 1, 7181, 294, ..., 0, 0, 0],\n ...,\n [ 1, 7181, 294, ..., 0, 0, 0],\n [ 1, 7181, 294, ..., 0, 0, 0],\n [ 1, 7181, 294, ..., 0, 0, 0]]),\n tensor([[1, 1, 1, ..., 0, 0, 0],\n [1, 1, 1, ..., 0, 0, 0],\n [1, 1, 1, ..., 0, 0, 0],\n ...,\n [1, 1, 1, ..., 0, 0, 0],\n [1, 1, 1, ..., 0, 0, 0],\n [1, 1, 1, ..., 0, 0, 0]]),\n tensor([1, 0, 0, 0, 0, 0, 0, 1]))" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "%%aip 0\nwrite the training and eval code. Let's use auc as eval metric", | |
"execution_count": 36, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "from transformers import AutoModelForSequenceClassification\nfrom torch import nn, optim\nimport torch\nfrom minai.core import *\nfrom functools import partial\nfrom torcheval.metrics import BinaryAUROC\n\nclass AUCMetric(BinaryAUROC):\n def compute(self):\n return super().compute().item()\n\nclass MetricsCB(DeviceCB):\n def __init__(self, **metrics):\n super().__init__()\n self.metrics = {k: v().to(self.device) for k, v in metrics.items()}\n \n def before_fit(self, learn): learn.metrics = self\n def before_epoch(self, learn):\n [m.reset() for m in self.metrics.values()]\n \n def after_batch(self, learn):\n for m in self.metrics.values():\n m.update(learn.preds.logits[:, -1].sigmoid().flatten(), learn.batch[-1].float())\n \n def after_epoch(self, learn):\n log = {k: f'{v.compute():.3f}' for k, v in self.metrics.items()}\n log['epoch'] = learn.epoch\n log['train'] = 'train' if learn.model.training else 'eval'\n print(log)", | |
"execution_count": 37, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "class GradAccumLearner(TrainLearner):\n def __init__(self, model, dls, loss_func, lr=None, cbs=None, opt_func=torch.optim.SGD, epoch_sz=None, n_inp=1, inp_nm=None, lbl_nm=None, preds_nm=None, grad_acc_steps=1):\n super().__init__(model, dls, loss_func, lr, cbs, opt_func=opt_func, epoch_sz=epoch_sz, n_inp=n_inp, inp_nm=inp_nm, lbl_nm=lbl_nm, preds_nm=preds_nm)\n assert grad_acc_steps >= 1\n self.step_count, self.grad_acc_steps = 0, grad_acc_steps\n\n def get_loss(self):\n self.loss = self.loss_func(self.preds.logits, self.batch[-1])\n\n def backward(self):\n loss = self.loss / self.grad_acc_steps\n loss.backward()\n\n def step(self):\n self.step_count += 1\n if self.step_count % self.grad_acc_steps == 0:\n self.opt.step()\n\n def zero_grad(self):\n if self.step_count % self.grad_acc_steps == 0:\n self.opt.zero_grad()\n\ndef loss_fn(x, y):\n return torch.nn.functional.cross_entropy(x.view(-1, x.shape[-1]), y.view(-1))", | |
"execution_count": 38, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "model = AutoModelForSequenceClassification.from_pretrained('microsoft/deberta-v3-base', num_labels=2)\nmodel.gradient_checkpointing_enable()\noptim = torch.optim.Adam\ncbs = [DeviceCB(), MetricsCB(auc=AUCMetric), ProgressCB(plot=True)]\n\nlearn = GradAccumLearner(model, dls, loss_func=loss_fn, lr=1e-5, cbs=cbs, n_inp=2, preds_nm='logits', opt_func=optim)\n\nlearn.fit(3)", | |
"execution_count": 40, | |
"outputs": [ | |
{ | |
"output_type": "display_data", | |
"data": { | |
"text/plain": "<IPython.core.display.HTML object>", | |
"text/html": "\n<style>\n /* Turns off some styling */\n progress {\n /* gets rid of default border in Firefox and Opera. */\n border: none;\n /* Needs to be in here for Safari polyfill so background images work as expected. */\n background-size: auto;\n }\n progress:not([value]), progress:not([value])::-webkit-progress-bar {\n background: repeating-linear-gradient(45deg, #7e7e7e, #7e7e7e 10px, #5c5c5c 10px, #5c5c5c 20px);\n }\n .progress-bar-interrupted, .progress-bar-interrupted::-webkit-progress-bar {\n background: #F44336;\n }\n</style>\n" | |
}, | |
"metadata": {} | |
}, | |
{ | |
"output_type": "display_data", | |
"data": { | |
"text/plain": "<IPython.core.display.HTML object>", | |
"text/html": "" | |
}, | |
"metadata": {} | |
}, | |
{ | |
"output_type": "display_data", | |
"data": { | |
"text/plain": "<Figure size 600x400 with 1 Axes>", | |
"image/png": "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atUq89tvvzX/8Ic/mNnZ2eaXX35pmmb7PGc7ixcvNvv3728efvjh5rXXXhv/vr2e+7Rp08xDDz3U3Lp1a/zf9u3b47+31/PetWuX2a9fP/OSSy4xFy1aZK5du9acPXu2uWbNmvg27XF827ZtG3ev58yZYwIw582bZ5pmau93hxMSjjrqKHPixInxz5FIxOzdu7c5ffr0NPYqOOxCQjQaNXv27Gn+9a9/jX+3Z88eMzc313zhhRdM0zTNr7/+2gRgfvrpp/Ft/vvf/5qGYZibN29OWd/9sm3bNhOA+f7775umGTvP7Oxs8+WXX45vs3LlShOAuXDhQtM0YwJWKBQyKysr49s88sgjZlFRkdnY2JjaE/BBly5dzMcff7xDnHNNTY05aNAgc86cOeaJJ54YFxLa87lPmzbNHD58uPC39nzeN954o3ncccdJf+8o49u1115rHnTQQWY0Gk35/e5Q5oampiYsXboUFRUV8e9CoRAqKiqwcOHCNPYseaxbtw6VlZXcORcXF2PMmDHxc164cCFKSkowevTo+DYVFRUIhUJYtGhRyvvslb179wIAunbtCgBYunQpmpubuXMfMmQI+vbty537YYcdhrKysvg248ePR3V1Nb766qsU9t4bkUgEM2fORF1dHcaOHdshznnixIk466yzuHME2v/9Xr16NXr37o0DDzwQF154ITZu3AigfZ/3m2++idGjR+OnP/0pSktLMXLkSDz22GPx3zvC+NbU1ITnnnsOv/zlL2EYRsrvd4cSEnbs2IFIJMJdOAAoKytDZWVlmnqVXKzzcjrnyspKlJaWcr9nZWWha9eubea6RKNRXHfddTj22GMxbNgwALHzysnJQUlJCbet/dxF18b6LVP54osvUFhYiNzcXFx55ZV47bXXMHTo0HZ9zgAwc+ZMLFu2DNOnT0/4rT2f+5gxY/D000/jnXfewSOPPIJ169bh+OOPR01NTbs+77Vr1+KRRx7BoEGDMHv2bFx11VW45ppr8MwzzwDoGOPb66+/jj179uCSSy4BkPrnvE2UiiYINyZOnIgvv/wSCxYsSHdXUsLBBx+MFStWYO/evXjllVdw8cUX4/333093t5LKpk2bcO2112LOnDnIy8tLd3dSyhlnnBH/+/DDD8eYMWPQr18/vPTSS8jPz09jz5JLNBrF6NGjcddddwEARo4ciS+//BIzZszAxRdfnObepYYnnngCZ5xxBnr37p2W43coTUL37t0RDocTvECrqqrQs2fPNPUquVjn5XTOPXv2xLZt27jfW1pasGvXrjZxXSZNmoT//Oc/mDdvHg444ID49z179kRTUxP27NnDbW8/d9G1sX7LVHJycjBw4ECMGjUK06dPx/Dhw/HAAw+063NeunQptm3bhiOOOAJZWVnIysrC+++/j7/97W/IyspCWVlZuz13OyUlJRg8eDDWrFnTru95r169MHToUO67Qw45JG5qae/j24YNG/Duu+/i8ssvj3+X6vvdoYSEnJwcjBo1CnPnzo1/F41GMXfuXIwdOzaNPUseAwYMQM+ePblzrq6uxqJFi+LnPHbsWOzZswdLly6Nb/Pee+8hGo1izJgxKe+zKqZpYtKkSXjttdfw3nvvYcCAAdzvo0aNQnZ2Nnfu3377LTZu3Mid+xdffMENInPmzEFRUVHC4JTJRKNRNDY2tutzPuWUU/DFF19gxYoV8X+jR4/GhRdeGP+7vZ67ndraWnz33Xfo1atXu77nxx57bEJY86pVq9CvXz8A7Xt8A4CnnnoKpaWlOOuss+Lfpfx+B+J62YaYOXOmmZubaz799NPm119/bf7qV78yS0pKOC/QtkZNTY25fPlyc/ny5SYA87777jOXL19ubtiwwTTNWIhQSUmJ+cYbb5iff/65+cMf/lAYIjRy5Ehz0aJF5oIFC8xBgwZldIiQaZrmVVddZRYXF5vz58/nwoX27dsX3+bKK680+/bta7733nvmkiVLzLFjx5pjx46N/26FCp122mnmihUrzHfeecfs0aNHRoeG3XTTTeb7779vrlu3zvz888/Nm266yTQMw/zf//5nmmb7PGcZbHSDabbfc//tb39rzp8/31y3bp350UcfmRUVFWb37t3Nbdu2mabZfs978eLFZlZWlnnnnXeaq1evNv/1r3+ZBQUF5nPPPRffpr2Ob5FIxOzbt6954403JvyWyvvd4YQE0zTNBx980Ozbt6+Zk5NjHnXUUeYnn3yS7i75Yt68eSaAhH8XX3yxaZqxMKFbbrnFLCsrM3Nzc81TTjnF/Pbbb7k2du7caZ5//vlmYWGhWVRUZF566aVmTU1NGs5GHdE5AzCfeuqp+Db19fXm1VdfbXbp0sUsKCgwzzvvPHPr1q1cO+vXrzfPOOMMMz8/3+zevbv529/+1mxubk7x2ajzy1/+0uzXr5+Zk5Nj9ujRwzzllFPiAoJpts9zlmEXEtrruU+YMMHs1auXmZOTY/bp08ecMGEClyugvZ63aZrmW2+9ZQ4bNszMzc01hwwZYj766KPc7+11fJs9e7YJIOFcTDO199swTdPU1oEQBEEQBNHu6VA+CQRBEARBqENCAkEQBEEQQkhIIAiCIAhCCAkJBEEQBEEIISGBIAiCIAghJCQQBEEQBCGEhASCIAiCIISQkEAQBEEQhBASEgiCIAiCEEJCAkEQBEEQQkhIIAiCIAhCyP8HkdDfACmxVpgAAAAASUVORK5CYII=" | |
}, | |
"metadata": {} | |
}, | |
{ | |
"output_type": "stream", | |
"text": "{'auc': '0.677', 'epoch': 0, 'train': 'train'}\n{'auc': '0.828', 'epoch': 0, 'train': 'eval'}\n{'auc': '0.822', 'epoch': 1, 'train': 'train'}\n{'auc': '0.831', 'epoch': 1, 'train': 'eval'}\n{'auc': '0.841', 'epoch': 2, 'train': 'train'}\n{'auc': '0.837', 'epoch': 2, 'train': 'eval'}\n", | |
"name": "stdout" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "# Great! we are able to get similar performance with minai vs hf trainer!", | |
"execution_count": 28, | |
"outputs": [] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "### Next\n- Refactor\n- Sanity checks\n- Look into activations, gradient stats" | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#| hide\nimport nbdev; nbdev.nbdev_export()", | |
"execution_count": null, | |
"outputs": [] | |
} | |
], | |
"metadata": { | |
"gist": { | |
"id": "0ab31ef72e32994fd63c1680bc5c81fe", | |
"data": { | |
"description": "minai_finetuning.ipynb", | |
"public": true | |
} | |
}, | |
"kernelspec": { | |
"name": "python3", | |
"display_name": "Python 3 (ipykernel)", | |
"language": "python" | |
}, | |
"language_info": { | |
"name": "python", | |
"version": "3.10.14", | |
"mimetype": "text/x-python", | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"pygments_lexer": "ipython3", | |
"nbconvert_exporter": "python", | |
"file_extension": ".py" | |
}, | |
"_draft": { | |
"nbviewer_url": "https://gist.github.com/rbiswasfc/0ab31ef72e32994fd63c1680bc5c81fe" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 4 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment