{ "cells": [ { "cell_type": "code", "execution_count": null, "id": "7e8f8491", "metadata": {}, "outputs": [], "source": [ "from collections.abc import Mapping\n", "\n", "import torch\n", "import torch.nn.functional as F\n", "from torch import nn\n", "import torchvision.transforms.functional as TF\n", "\n", "from datasets import load_dataset,load_dataset_builder\n", "\n", "from miniai.datasets import *\n", "from miniai.learner import *" ] }, { "cell_type": "markdown", "id": "8f5eea66", "metadata": {}, "source": [ "## Setup Learner as in `07`" ] }, { "cell_type": "code", "execution_count": null, "id": "b22868a9", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Found cached dataset fashion_mnist (/home/pedro/.cache/huggingface/datasets/fashion_mnist/fashion_mnist/1.0.0/8d6c32399aa01613d96e2cbc9b13638f359ef62bb33612b077b4c247f6ef99c1)\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "13073e4bbf8843abbbbbc0de72592c55", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/2 [00:00\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", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "1.156 :: 0.614

0.823 :: 0.693" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "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\n", "text/plain": [ "

" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "cbs = [TrainCB(), CudaCB(), MetricsCB(Accuracy()), ProgressCB(plot=True)]\n", "learn = Learner(model, dls, F.cross_entropy, lr=0.2, cbs=cbs)\n", "learn.fit(1)" ] }, { "cell_type": "markdown", "id": "69d9e90c", "metadata": {}, "source": [ "## Mixed Precision – Callback Exercise" ] }, { "cell_type": "markdown", "id": "132af5c1", "metadata": {}, "source": [ "We'll use mixed-precision training as a more complex example to exercise our callback mechanism.\n", "\n", "If we take a look at the [previous implementation](https://github.com/fastai/fastai/blob/master/fastai/callback/fp16.py#L17) from `fastai 2`, we see that mixed precision requires injecting code at various stages during the training process. We'd like to do this as a callback, but training is a callback itself! We don't have enough places to hook on.\n", "\n", "More concretely, we'd need callback events for `after_pred`, `after_loss` and others. This is a simplified version of the code, without grad scaling.\n", "\n", "```Python\n", "class MixedPrecision(Callback):\n", " order = 10\n", " def before_fit(self): \n", " self.autocast = autocast()\n", " def before_batch(self): self.autocast.__enter__()\n", " def after_pred(self):\n", " if next(flatten(self.pred)).dtype==torch.float16: self.learn.pred = to_float(self.pred)\n", " def after_loss(self): self.autocast.__exit__(None, None, None)\n", "```\n", "\n" ] }, { "cell_type": "markdown", "id": "5fb14eb3", "metadata": {}, "source": [ "We have `before_fit` and `before_batch` callbacks in our `Learner` class, but `predict` and `get_loss` are part of `TrainCB`, and we don't have `before_` or `after_` hooks for them.\n", "\n", "What could we do?\n", "\n", "- Incorporate those functions inside the `Learner` class and create callbacks for them. This is the obvious and possibly easiest solution, but it kind of forces us to use inheritance as our main abstraction.\n", "- Subclass `TrainCB` creating a specialized version like `MixedPrecisionTrainCB`.\n", "\n", "We'll explore something else here, which is a way to **compose callbacks** without tightly coupling them together." ] }, { "cell_type": "markdown", "id": "b0fb6e26", "metadata": {}, "source": [ "Let's start by looking at the code we'd like to be able to see without worrying about how to do it:\n", "\n", "```Python\n", "cbs = [MixedPrecision(TrainCB()), MetricsCB(Accuracy()), ProgressCB()]\n", "learn = Learner(model, dls, F.cross_entropy, lr=0.001, cbs=cbs)\n", "learn.fit(1)\n", "```\n", "\n", "So `MixedPrecision` is a callback that wraps (or delegates to) `TrainCB`.\n", "\n", "(Side thought: this could potentially be a way to sort out callback ordering for tasks that need to occur in specific order)." ] }, { "cell_type": "markdown", "id": "6d2eccd6", "metadata": {}, "source": [ "To achieve this, we create a `CallbackWrapper` (not a very good name) that automatically creates callbacks for the public methods of a `wrapped` Callback object. It leverages the `with_cbs` decorator to create the new callbacks. There are some Python gymnastics involved, but the basic idea is just to create those `before_` and `after_` hooks without having to modify anything in the target callback. Perhaps there's a better way to achieve the same, but this helped me better understand Python decorators." ] }, { "cell_type": "code", "execution_count": null, "id": "388d4d30", "metadata": {}, "outputs": [], "source": [ "import inspect\n", "import types\n", "\n", "class CallbackWrapper(Callback):\n", " def __init__(self, wrapped): \n", " self.wrapped = wrapped\n", " self.wrapped.callback = self.callback\n", " for name, fn in inspect.getmembers(wrapped.__class__, predicate=inspect.isfunction):\n", " if name.startswith(\"_\"): continue\n", " # TODO: maybe ignore already wrapped?\n", " # TODO: provide name mapping so `after_get_loss` -> `after_loss` if we want\n", " setattr(wrapped, name, types.MethodType(with_cbs(name)(fn), wrapped))\n", " \n", " def __getattr__(self, name):\n", " if name[0]=='_': raise AttributeError(name)\n", " return getattr(self.wrapped, name)\n", " \n", " def __setattr__(self, name, value):\n", " # Magic name\n", " if name == \"wrapped\":\n", " super().__setattr__(name, value)\n", " else:\n", " setattr(self.wrapped, name, value)\n", " \n", " def callback(self, method_nm):\n", " getattr(self, method_nm, identity)()" ] }, { "cell_type": "markdown", "id": "efba2827", "metadata": {}, "source": [ "With this in place we can now implement a simple tracing callback to see if it works." ] }, { "cell_type": "code", "execution_count": null, "id": "041804a9", "metadata": {}, "outputs": [], "source": [ "class Tracer(CallbackWrapper):\n", " def after_predict(self): print(\"after_predict\")\n", " def after_get_loss(self): print(\"after_get_loss\")" ] }, { "cell_type": "code", "execution_count": null, "id": "c43bda72", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "0.780 :: 0.708

0.775 :: 0.706" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n", "after_predict\n", "after_get_loss\n" ] } ], "source": [ "cbs = [Tracer(TrainCB()), CudaCB(), MetricsCB(Accuracy()), ProgressCB()]\n", "learn = Learner(model, dls, F.cross_entropy, lr=0.001, cbs=cbs)\n", "learn.fit(1)" ] }, { "cell_type": "markdown", "id": "eee9724f", "metadata": {}, "source": [ "And then we can implement a very basic mixed precision callback." ] }, { "cell_type": "code", "execution_count": null, "id": "0ca2a3b3", "metadata": {}, "outputs": [], "source": [ "from itertools import chain\n", "def flatten(lists): return chain.from_iterable(lists)\n", "\n", "# TODO: copy from fastai implementation to deal with lists, dicts, etc.\n", "def to_float(x):\n", " return x.float() if torch.is_floating_point(x) else x" ] }, { "cell_type": "code", "execution_count": null, "id": "643a0ffe", "metadata": {}, "outputs": [], "source": [ "class MixedPrecision(CallbackWrapper):\n", " def before_fit(self): self.autocast = torch.autocast(\"cuda\")\n", " def before_batch(self): self.autocast.__enter__()\n", " def after_predict(self): self.learn.preds = to_float(self.learn.preds)\n", " def after_get_loss(self): self.autocast.__exit__(None, None, None)" ] }, { "cell_type": "code", "execution_count": null, "id": "bf6f6076", "metadata": {}, "outputs": [], "source": [ "model = nn.Sequential(nn.Linear(m,nh), nn.ReLU(), nn.Linear(nh,10))" ] }, { "cell_type": "code", "execution_count": null, "id": "62af7e8d", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "1.152 :: 0.629

0.811 :: 0.704" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "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\n", "text/plain": [ "

" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "cbs = [MixedPrecision(TrainCB()), CudaCB(), MetricsCB(Accuracy()), ProgressCB(plot=True)]\n", "learn = Learner(model, dls, F.cross_entropy, lr=0.2, cbs=cbs)\n", "learn.fit(1)" ] }, { "cell_type": "markdown", "id": "d62206eb", "metadata": {}, "source": [ "The method feels fragile. Should we do something simpler?" ] }, { "cell_type": "markdown", "id": "ddf6a718", "metadata": {}, "source": [ "## Accelerate" ] }, { "cell_type": "code", "execution_count": null, "id": "546e9999", "metadata": {}, "outputs": [], "source": [ "from accelerate import Accelerator" ] }, { "cell_type": "code", "execution_count": null, "id": "d6dc584c", "metadata": {}, "outputs": [], "source": [ "model = nn.Sequential(nn.Linear(m,nh), nn.ReLU(), nn.Linear(nh,10))" ] }, { "cell_type": "code", "execution_count": null, "id": "38473de8", "metadata": {}, "outputs": [], "source": [ "class Distributed(CallbackWrapper):\n", " def __init__(self, wrapped):\n", " super().__init__(wrapped)\n", " self.accelerator = Accelerator()\n", "\n", " def before_fit(self):\n", " self.learn.model, self.learn.opt, self.learn.dls = self.accelerator.prepare(\n", " self.learn.model, self.learn.opt, self.learn.dls\n", " )\n", "\n", " # Replaces TrainCB.backward\n", " def backward(self): self.accelerator.backward(self.learn.loss)" ] }, { "cell_type": "code", "execution_count": null, "id": "9422b3f2", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "1.176 :: 0.609

0.815 :: 0.684" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "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\n", "text/plain": [ "

" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "cbs = [Distributed(TrainCB()), CudaCB(), MetricsCB(Accuracy()), ProgressCB(plot=True)]\n", "learn = Learner(model, dls, F.cross_entropy, lr=0.2, cbs=cbs)\n", "learn.fit(1)" ] }, { "cell_type": "markdown", "id": "56e042d7", "metadata": {}, "source": [ "----" ] }, { "cell_type": "markdown", "id": "ca534664", "metadata": {}, "source": [ "However, chaining multiple callbacks together doesn't work." ] }, { "cell_type": "code", "execution_count": null, "id": "671883fe", "metadata": {}, "outputs": [], "source": [ "model = nn.Sequential(nn.Linear(m,nh), nn.ReLU(), nn.Linear(nh,10))" ] }, { "cell_type": "code", "execution_count": null, "id": "d80a1621", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "2.323 :: 0.102

2.322 :: 0.101" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "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\n", "text/plain": [ "

" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "cbs = [MixedPrecision(Distributed(TrainCB())), CudaCB(), MetricsCB(Accuracy()), ProgressCB(plot=True)]\n", "learn = Learner(model, dls, F.cross_entropy, lr=0.2, cbs=cbs)\n", "learn.fit(1)" ] }, { "cell_type": "code", "execution_count": null, "id": "221ccf06", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "\n", "
\n", " \n", " 0.00% [0/1 00:00<?]\n", "
\n", " \n", "\n", "\n", "
\n", " \n", " 0.00% [0/59 00:00<?]\n", "
\n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
╭──────────────────────────── Traceback (most recent call last) ────────────────────────────╮\n",
       "                                                                                           \n",
       " /tmp/ipykernel_157780/2990819097.py:3 in <cell line: 3>                                   \n",
       "                                                                                           \n",
       " [Errno 2] No such file or directory: '/tmp/ipykernel_157780/2990819097.py'                \n",
       " /home/pedro/code/hf/diffusers/fastai/course22p2/nbs/miniai/learner.py:145 in fit          \n",
       "                                                                                           \n",
       "   142 │   │   self.n_epochs = n_epochs                                                    \n",
       "   143 │   │   self.epochs = range(n_epochs)                                               \n",
       "   144 │   │   self.opt = self.opt_func(self.model.parameters(), self.lr)                  \n",
       " 145 │   │   self._fit()                                                                 \n",
       "   146 │                                                                                   \n",
       "   147 │   @with_cbs('fit')                                                                \n",
       "   148 │   def _fit(self):                                                                 \n",
       "                                                                                           \n",
       " /home/pedro/code/hf/diffusers/fastai/course22p2/nbs/miniai/learner.py:112 in _f           \n",
       "                                                                                           \n",
       "   109 │   │   def _f(o, *args, **kwargs):                                                 \n",
       "   110 │   │   │   try:                                                                    \n",
       "   111 │   │   │   │   o.callback(f'before_{self.nm}')                                     \n",
       " 112 │   │   │   │   f(o, *args, **kwargs)                                               \n",
       "   113 │   │   │   │   o.callback(f'after_{self.nm}')                                      \n",
       "   114 │   │   │   except globals()[f'Cancel{self.nm.title()}Exception']: pass             \n",
       "   115 │   │   return _f                                                                   \n",
       "                                                                                           \n",
       " /home/pedro/code/hf/diffusers/fastai/course22p2/nbs/miniai/learner.py:150 in _fit         \n",
       "                                                                                           \n",
       "   147 │   @with_cbs('fit')                                                                \n",
       "   148 │   def _fit(self):                                                                 \n",
       "   149 │   │   for self.epoch in self.epochs:                                              \n",
       " 150 │   │   │   self.one_epoch(True)                                                    \n",
       "   151 │   │   │   self.one_epoch(False)                                                   \n",
       "   152 │                                                                                   \n",
       "   153 │   def __getattr__(self, name):                                                    \n",
       "                                                                                           \n",
       " /home/pedro/code/hf/diffusers/fastai/course22p2/nbs/miniai/learner.py:135 in one_epoch    \n",
       "                                                                                           \n",
       "   132 │   def one_epoch(self, train):                                                     \n",
       "   133 │   │   self.model.train(train)                                                     \n",
       "   134 │   │   self.dl = self.dls.train if train else self.dls.valid                       \n",
       " 135 │   │   self._one_epoch()                                                           \n",
       "   136 │                                                                                   \n",
       "   137 │   @with_cbs('epoch')                                                              \n",
       "   138 │   def _one_epoch(self):                                                           \n",
       "                                                                                           \n",
       " /home/pedro/code/hf/diffusers/fastai/course22p2/nbs/miniai/learner.py:112 in _f           \n",
       "                                                                                           \n",
       "   109 │   │   def _f(o, *args, **kwargs):                                                 \n",
       "   110 │   │   │   try:                                                                    \n",
       "   111 │   │   │   │   o.callback(f'before_{self.nm}')                                     \n",
       " 112 │   │   │   │   f(o, *args, **kwargs)                                               \n",
       "   113 │   │   │   │   o.callback(f'after_{self.nm}')                                      \n",
       "   114 │   │   │   except globals()[f'Cancel{self.nm.title()}Exception']: pass             \n",
       "   115 │   │   return _f                                                                   \n",
       "                                                                                           \n",
       " /home/pedro/code/hf/diffusers/fastai/course22p2/nbs/miniai/learner.py:139 in _one_epoch   \n",
       "                                                                                           \n",
       "   136 │                                                                                   \n",
       "   137 │   @with_cbs('epoch')                                                              \n",
       "   138 │   def _one_epoch(self):                                                           \n",
       " 139 │   │   for self.iter,self.batch in enumerate(self.dl): self.one_batch()            \n",
       "   140 │                                                                                   \n",
       "   141 │   def fit(self, n_epochs):                                                        \n",
       "   142 │   │   self.n_epochs = n_epochs                                                    \n",
       "                                                                                           \n",
       " /home/pedro/code/hf/diffusers/fastai/course22p2/nbs/miniai/learner.py:111 in _f           \n",
       "                                                                                           \n",
       "   108 │   def __call__(self, f):                                                          \n",
       "   109 │   │   def _f(o, *args, **kwargs):                                                 \n",
       "   110 │   │   │   try:                                                                    \n",
       " 111 │   │   │   │   o.callback(f'before_{self.nm}')                                     \n",
       "   112 │   │   │   │   f(o, *args, **kwargs)                                               \n",
       "   113 │   │   │   │   o.callback(f'after_{self.nm}')                                      \n",
       "   114 │   │   │   except globals()[f'Cancel{self.nm.title()}Exception']: pass             \n",
       "                                                                                           \n",
       " /home/pedro/code/hf/diffusers/fastai/course22p2/nbs/miniai/learner.py:158 in callback     \n",
       "                                                                                           \n",
       "   155 │   │   raise AttributeError(name)                                                  \n",
       "   156 │                                                                                   \n",
       "   157 │   def callback(self, method_nm):                                                  \n",
       " 158 │   │   for cb in sorted(self.cbs, key=attrgetter('order')): getattr(cb, method_nm, \n",
       "   159                                                                                     \n",
       "   160 # %% ../nbs/07_learner.ipynb 23                                                     \n",
       "   161 class Callback(): order = 0                                                         \n",
       "                                                                                           \n",
       " /tmp/ipykernel_157780/96949510.py:3 in before_batch                                       \n",
       "                                                                                           \n",
       " [Errno 2] No such file or directory: '/tmp/ipykernel_157780/96949510.py'                  \n",
       "                                                                                           \n",
       " /tmp/ipykernel_157780/1942522594.py:16 in __getattr__                                     \n",
       "                                                                                           \n",
       " [Errno 2] No such file or directory: '/tmp/ipykernel_157780/1942522594.py'                \n",
       "╰───────────────────────────────────────────────────────────────────────────────────────────╯\n",
       "AttributeError: 'TrainCB' object has no attribute 'autocast'\n",
       "
\n" ], "text/plain": [ "\u001b[31m╭─\u001b[0m\u001b[31m─────────────────────────── \u001b[0m\u001b[1;31mTraceback \u001b[0m\u001b[1;2;31m(most recent call last)\u001b[0m\u001b[31m ───────────────────────────\u001b[0m\u001b[31m─╮\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2;33m/tmp/ipykernel_157780/\u001b[0m\u001b[1;33m2990819097.py\u001b[0m:\u001b[94m3\u001b[0m in \u001b[92m\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[3;31m[Errno 2] No such file or directory: '/tmp/ipykernel_157780/2990819097.py'\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2;33m/home/pedro/code/hf/diffusers/fastai/course22p2/nbs/miniai/\u001b[0m\u001b[1;33mlearner.py\u001b[0m:\u001b[94m145\u001b[0m in \u001b[92mfit\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m142 \u001b[0m\u001b[2m│ │ \u001b[0m\u001b[96mself\u001b[0m.n_epochs = n_epochs \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m143 \u001b[0m\u001b[2m│ │ \u001b[0m\u001b[96mself\u001b[0m.epochs = \u001b[96mrange\u001b[0m(n_epochs) \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m144 \u001b[0m\u001b[2m│ │ \u001b[0m\u001b[96mself\u001b[0m.opt = \u001b[96mself\u001b[0m.opt_func(\u001b[96mself\u001b[0m.model.parameters(), \u001b[96mself\u001b[0m.lr) \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m❱ \u001b[0m145 \u001b[2m│ │ \u001b[0m\u001b[96mself\u001b[0m._fit() \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m146 \u001b[0m\u001b[2m│ \u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m147 \u001b[0m\u001b[2m│ \u001b[0m\u001b[1;95m@with_cbs\u001b[0m(\u001b[33m'\u001b[0m\u001b[33mfit\u001b[0m\u001b[33m'\u001b[0m) \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m148 \u001b[0m\u001b[2m│ \u001b[0m\u001b[94mdef\u001b[0m \u001b[92m_fit\u001b[0m(\u001b[96mself\u001b[0m): \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2;33m/home/pedro/code/hf/diffusers/fastai/course22p2/nbs/miniai/\u001b[0m\u001b[1;33mlearner.py\u001b[0m:\u001b[94m112\u001b[0m in \u001b[92m_f\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m109 \u001b[0m\u001b[2m│ │ \u001b[0m\u001b[94mdef\u001b[0m \u001b[92m_f\u001b[0m(o, *args, **kwargs): \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m110 \u001b[0m\u001b[2m│ │ │ \u001b[0m\u001b[94mtry\u001b[0m: \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m111 \u001b[0m\u001b[2m│ │ │ │ \u001b[0mo.callback(\u001b[33mf\u001b[0m\u001b[33m'\u001b[0m\u001b[33mbefore_\u001b[0m\u001b[33m{\u001b[0m\u001b[96mself\u001b[0m.nm\u001b[33m}\u001b[0m\u001b[33m'\u001b[0m) \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m❱ \u001b[0m112 \u001b[2m│ │ │ │ \u001b[0mf(o, *args, **kwargs) \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m113 \u001b[0m\u001b[2m│ │ │ │ \u001b[0mo.callback(\u001b[33mf\u001b[0m\u001b[33m'\u001b[0m\u001b[33mafter_\u001b[0m\u001b[33m{\u001b[0m\u001b[96mself\u001b[0m.nm\u001b[33m}\u001b[0m\u001b[33m'\u001b[0m) \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m114 \u001b[0m\u001b[2m│ │ │ \u001b[0m\u001b[94mexcept\u001b[0m \u001b[96mglobals\u001b[0m()[\u001b[33mf\u001b[0m\u001b[33m'\u001b[0m\u001b[33mCancel\u001b[0m\u001b[33m{\u001b[0m\u001b[96mself\u001b[0m.nm.title()\u001b[33m}\u001b[0m\u001b[33mException\u001b[0m\u001b[33m'\u001b[0m]: \u001b[94mpass\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m115 \u001b[0m\u001b[2m│ │ \u001b[0m\u001b[94mreturn\u001b[0m _f \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2;33m/home/pedro/code/hf/diffusers/fastai/course22p2/nbs/miniai/\u001b[0m\u001b[1;33mlearner.py\u001b[0m:\u001b[94m150\u001b[0m in \u001b[92m_fit\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m147 \u001b[0m\u001b[2m│ \u001b[0m\u001b[1;95m@with_cbs\u001b[0m(\u001b[33m'\u001b[0m\u001b[33mfit\u001b[0m\u001b[33m'\u001b[0m) \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m148 \u001b[0m\u001b[2m│ \u001b[0m\u001b[94mdef\u001b[0m \u001b[92m_fit\u001b[0m(\u001b[96mself\u001b[0m): \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m149 \u001b[0m\u001b[2m│ │ \u001b[0m\u001b[94mfor\u001b[0m \u001b[96mself\u001b[0m.epoch \u001b[95min\u001b[0m \u001b[96mself\u001b[0m.epochs: \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m❱ \u001b[0m150 \u001b[2m│ │ │ \u001b[0m\u001b[96mself\u001b[0m.one_epoch(\u001b[94mTrue\u001b[0m) \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m151 \u001b[0m\u001b[2m│ │ │ \u001b[0m\u001b[96mself\u001b[0m.one_epoch(\u001b[94mFalse\u001b[0m) \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m152 \u001b[0m\u001b[2m│ \u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m153 \u001b[0m\u001b[2m│ \u001b[0m\u001b[94mdef\u001b[0m \u001b[92m__getattr__\u001b[0m(\u001b[96mself\u001b[0m, name): \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2;33m/home/pedro/code/hf/diffusers/fastai/course22p2/nbs/miniai/\u001b[0m\u001b[1;33mlearner.py\u001b[0m:\u001b[94m135\u001b[0m in \u001b[92mone_epoch\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m132 \u001b[0m\u001b[2m│ \u001b[0m\u001b[94mdef\u001b[0m \u001b[92mone_epoch\u001b[0m(\u001b[96mself\u001b[0m, train): \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m133 \u001b[0m\u001b[2m│ │ \u001b[0m\u001b[96mself\u001b[0m.model.train(train) \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m134 \u001b[0m\u001b[2m│ │ \u001b[0m\u001b[96mself\u001b[0m.dl = \u001b[96mself\u001b[0m.dls.train \u001b[94mif\u001b[0m train \u001b[94melse\u001b[0m \u001b[96mself\u001b[0m.dls.valid \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m❱ \u001b[0m135 \u001b[2m│ │ \u001b[0m\u001b[96mself\u001b[0m._one_epoch() \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m136 \u001b[0m\u001b[2m│ \u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m137 \u001b[0m\u001b[2m│ \u001b[0m\u001b[1;95m@with_cbs\u001b[0m(\u001b[33m'\u001b[0m\u001b[33mepoch\u001b[0m\u001b[33m'\u001b[0m) \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m138 \u001b[0m\u001b[2m│ \u001b[0m\u001b[94mdef\u001b[0m \u001b[92m_one_epoch\u001b[0m(\u001b[96mself\u001b[0m): \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2;33m/home/pedro/code/hf/diffusers/fastai/course22p2/nbs/miniai/\u001b[0m\u001b[1;33mlearner.py\u001b[0m:\u001b[94m112\u001b[0m in \u001b[92m_f\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m109 \u001b[0m\u001b[2m│ │ \u001b[0m\u001b[94mdef\u001b[0m \u001b[92m_f\u001b[0m(o, *args, **kwargs): \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m110 \u001b[0m\u001b[2m│ │ │ \u001b[0m\u001b[94mtry\u001b[0m: \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m111 \u001b[0m\u001b[2m│ │ │ │ \u001b[0mo.callback(\u001b[33mf\u001b[0m\u001b[33m'\u001b[0m\u001b[33mbefore_\u001b[0m\u001b[33m{\u001b[0m\u001b[96mself\u001b[0m.nm\u001b[33m}\u001b[0m\u001b[33m'\u001b[0m) \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m❱ \u001b[0m112 \u001b[2m│ │ │ │ \u001b[0mf(o, *args, **kwargs) \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m113 \u001b[0m\u001b[2m│ │ │ │ \u001b[0mo.callback(\u001b[33mf\u001b[0m\u001b[33m'\u001b[0m\u001b[33mafter_\u001b[0m\u001b[33m{\u001b[0m\u001b[96mself\u001b[0m.nm\u001b[33m}\u001b[0m\u001b[33m'\u001b[0m) \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m114 \u001b[0m\u001b[2m│ │ │ \u001b[0m\u001b[94mexcept\u001b[0m \u001b[96mglobals\u001b[0m()[\u001b[33mf\u001b[0m\u001b[33m'\u001b[0m\u001b[33mCancel\u001b[0m\u001b[33m{\u001b[0m\u001b[96mself\u001b[0m.nm.title()\u001b[33m}\u001b[0m\u001b[33mException\u001b[0m\u001b[33m'\u001b[0m]: \u001b[94mpass\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m115 \u001b[0m\u001b[2m│ │ \u001b[0m\u001b[94mreturn\u001b[0m _f \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2;33m/home/pedro/code/hf/diffusers/fastai/course22p2/nbs/miniai/\u001b[0m\u001b[1;33mlearner.py\u001b[0m:\u001b[94m139\u001b[0m in \u001b[92m_one_epoch\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m136 \u001b[0m\u001b[2m│ \u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m137 \u001b[0m\u001b[2m│ \u001b[0m\u001b[1;95m@with_cbs\u001b[0m(\u001b[33m'\u001b[0m\u001b[33mepoch\u001b[0m\u001b[33m'\u001b[0m) \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m138 \u001b[0m\u001b[2m│ \u001b[0m\u001b[94mdef\u001b[0m \u001b[92m_one_epoch\u001b[0m(\u001b[96mself\u001b[0m): \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m❱ \u001b[0m139 \u001b[2m│ │ \u001b[0m\u001b[94mfor\u001b[0m \u001b[96mself\u001b[0m.iter,\u001b[96mself\u001b[0m.batch \u001b[95min\u001b[0m \u001b[96menumerate\u001b[0m(\u001b[96mself\u001b[0m.dl): \u001b[96mself\u001b[0m.one_batch() \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m140 \u001b[0m\u001b[2m│ \u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m141 \u001b[0m\u001b[2m│ \u001b[0m\u001b[94mdef\u001b[0m \u001b[92mfit\u001b[0m(\u001b[96mself\u001b[0m, n_epochs): \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m142 \u001b[0m\u001b[2m│ │ \u001b[0m\u001b[96mself\u001b[0m.n_epochs = n_epochs \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2;33m/home/pedro/code/hf/diffusers/fastai/course22p2/nbs/miniai/\u001b[0m\u001b[1;33mlearner.py\u001b[0m:\u001b[94m111\u001b[0m in \u001b[92m_f\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m108 \u001b[0m\u001b[2m│ \u001b[0m\u001b[94mdef\u001b[0m \u001b[92m__call__\u001b[0m(\u001b[96mself\u001b[0m, f): \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m109 \u001b[0m\u001b[2m│ │ \u001b[0m\u001b[94mdef\u001b[0m \u001b[92m_f\u001b[0m(o, *args, **kwargs): \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m110 \u001b[0m\u001b[2m│ │ │ \u001b[0m\u001b[94mtry\u001b[0m: \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m❱ \u001b[0m111 \u001b[2m│ │ │ │ \u001b[0mo.callback(\u001b[33mf\u001b[0m\u001b[33m'\u001b[0m\u001b[33mbefore_\u001b[0m\u001b[33m{\u001b[0m\u001b[96mself\u001b[0m.nm\u001b[33m}\u001b[0m\u001b[33m'\u001b[0m) \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m112 \u001b[0m\u001b[2m│ │ │ │ \u001b[0mf(o, *args, **kwargs) \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m113 \u001b[0m\u001b[2m│ │ │ │ \u001b[0mo.callback(\u001b[33mf\u001b[0m\u001b[33m'\u001b[0m\u001b[33mafter_\u001b[0m\u001b[33m{\u001b[0m\u001b[96mself\u001b[0m.nm\u001b[33m}\u001b[0m\u001b[33m'\u001b[0m) \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m114 \u001b[0m\u001b[2m│ │ │ \u001b[0m\u001b[94mexcept\u001b[0m \u001b[96mglobals\u001b[0m()[\u001b[33mf\u001b[0m\u001b[33m'\u001b[0m\u001b[33mCancel\u001b[0m\u001b[33m{\u001b[0m\u001b[96mself\u001b[0m.nm.title()\u001b[33m}\u001b[0m\u001b[33mException\u001b[0m\u001b[33m'\u001b[0m]: \u001b[94mpass\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2;33m/home/pedro/code/hf/diffusers/fastai/course22p2/nbs/miniai/\u001b[0m\u001b[1;33mlearner.py\u001b[0m:\u001b[94m158\u001b[0m in \u001b[92mcallback\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m155 \u001b[0m\u001b[2m│ │ \u001b[0m\u001b[94mraise\u001b[0m \u001b[96mAttributeError\u001b[0m(name) \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m156 \u001b[0m\u001b[2m│ \u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m157 \u001b[0m\u001b[2m│ \u001b[0m\u001b[94mdef\u001b[0m \u001b[92mcallback\u001b[0m(\u001b[96mself\u001b[0m, method_nm): \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m❱ \u001b[0m158 \u001b[2m│ │ \u001b[0m\u001b[94mfor\u001b[0m cb \u001b[95min\u001b[0m \u001b[96msorted\u001b[0m(\u001b[96mself\u001b[0m.cbs, key=attrgetter(\u001b[33m'\u001b[0m\u001b[33morder\u001b[0m\u001b[33m'\u001b[0m)): \u001b[96mgetattr\u001b[0m(cb, method_nm, \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m159 \u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m160 \u001b[0m\u001b[2m# %% ../nbs/07_learner.ipynb 23\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2m161 \u001b[0m\u001b[94mclass\u001b[0m \u001b[4;92mCallback\u001b[0m(): order = \u001b[94m0\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2;33m/tmp/ipykernel_157780/\u001b[0m\u001b[1;33m96949510.py\u001b[0m:\u001b[94m3\u001b[0m in \u001b[92mbefore_batch\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[3;31m[Errno 2] No such file or directory: '/tmp/ipykernel_157780/96949510.py'\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[2;33m/tmp/ipykernel_157780/\u001b[0m\u001b[1;33m1942522594.py\u001b[0m:\u001b[94m16\u001b[0m in \u001b[92m__getattr__\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m│\u001b[0m \u001b[3;31m[Errno 2] No such file or directory: '/tmp/ipykernel_157780/1942522594.py'\u001b[0m \u001b[31m│\u001b[0m\n", "\u001b[31m╰───────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n", "\u001b[1;91mAttributeError: \u001b[0m\u001b[32m'TrainCB'\u001b[0m object has no attribute \u001b[32m'autocast'\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "cbs = [Distributed(MixedPrecision(TrainCB())), CudaCB(), MetricsCB(Accuracy()), ProgressCB(plot=True)]\n", "learn = Learner(model, dls, F.cross_entropy, lr=0.2, cbs=cbs)\n", "learn.fit(1)" ] }, { "cell_type": "code", "execution_count": null, "id": "e9e1ed6d", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" } }, "nbformat": 4, "nbformat_minor": 5 }