|
| 1 | +{ |
| 2 | + "cells": [ |
| 3 | + { |
| 4 | + "cell_type": "markdown", |
| 5 | + "metadata": { |
| 6 | + "tags": [] |
| 7 | + }, |
| 8 | + "source": [ |
| 9 | + "# Ray Data User Testing\n", |
| 10 | + "\n", |
| 11 | + "In this notebook, you will learn how to use Ray Data for distributed model training. Ray Data is used for data loading for model training. You are asked to fill in the missing code to finish the following 3 tasks:\n", |
| 12 | + "\n", |
| 13 | + "- Task 1: Read training data from S3\n", |
| 14 | + "- Task 2: Preprocess training data\n", |
| 15 | + "- Task 3: Run distributed training with 4 GPU workers\n", |
| 16 | + "\n", |
| 17 | + "You can refer to the Ray Data Documentation for user guides and APIs: https://docs.ray.io/en/master/data/data.html" |
| 18 | + ] |
| 19 | + }, |
| 20 | + { |
| 21 | + "cell_type": "markdown", |
| 22 | + "metadata": { |
| 23 | + "tags": [] |
| 24 | + }, |
| 25 | + "source": [ |
| 26 | + "## Task 1: Read training data from S3\n", |
| 27 | + "\n", |
| 28 | + "In this section, you will read training data from AWS S3 (https://aws.amazon.com/s3/). The training data consists of a list of files in Parquet format (https://parquet.apache.org/). The training data contains images and their labels.\n", |
| 29 | + "\n", |
| 30 | + "Success Criteria for this section:\n", |
| 31 | + "- Successfully create a Ray Dataset to read Parquet files from S3.\n", |
| 32 | + "- Successfully inspect metadata of Ray Dataset to get the names of columns, and the number of images." |
| 33 | + ] |
| 34 | + }, |
| 35 | + { |
| 36 | + "cell_type": "code", |
| 37 | + "execution_count": 1, |
| 38 | + "metadata": { |
| 39 | + "tags": [] |
| 40 | + }, |
| 41 | + "outputs": [], |
| 42 | + "source": [ |
| 43 | + "# Instruction: just run this cell.\n", |
| 44 | + "# Import required dependencies.\n", |
| 45 | + "import numpy as np\n", |
| 46 | + "from torchvision.transforms import Compose, Normalize, ToTensor\n", |
| 47 | + "from tqdm import tqdm\n", |
| 48 | + "import ray.train\n", |
| 49 | + "from ray.train import ScalingConfig\n", |
| 50 | + "from ray.train.torch import TorchTrainer\n", |
| 51 | + "from util import prepare_model\n", |
| 52 | + "\n", |
| 53 | + "path = \"s3://air-example-data/data-cuj/train\"" |
| 54 | + ] |
| 55 | + }, |
| 56 | + { |
| 57 | + "cell_type": "code", |
| 58 | + "execution_count": null, |
| 59 | + "metadata": {}, |
| 60 | + "outputs": [], |
| 61 | + "source": [ |
| 62 | + "# Instruction: add your code here.\n", |
| 63 | + "# Read from S3 bucket above: s3://air-example-data/data-cuj/train\n", |
| 64 | + "\n", |
| 65 | + "\n", |
| 66 | + "\n" |
| 67 | + ] |
| 68 | + }, |
| 69 | + { |
| 70 | + "cell_type": "markdown", |
| 71 | + "metadata": {}, |
| 72 | + "source": [ |
| 73 | + "Please fill in the blanks below:\n", |
| 74 | + "\n", |
| 75 | + "| | |\n", |
| 76 | + "|---------------------|----------------------|\n", |
| 77 | + "| Columns names | ___x___ |\n", |
| 78 | + "| Number of images | ___x___ |" |
| 79 | + ] |
| 80 | + }, |
| 81 | + { |
| 82 | + "cell_type": "markdown", |
| 83 | + "metadata": { |
| 84 | + "tags": [] |
| 85 | + }, |
| 86 | + "source": [ |
| 87 | + "## Task 2: Preprocess images\n", |
| 88 | + "\n", |
| 89 | + "In this section, we'll preprocess images to normalize them for training. You are given the preprocess code below to normalize a single image with TorchVision function. You are expected to use the Ray Data API to parallelize the preprocessing logic among all images. \n", |
| 90 | + "\n", |
| 91 | + "Success Criteria for this section:\n", |
| 92 | + "- Successfully use correct Ray Data API to run preprocessing for all images." |
| 93 | + ] |
| 94 | + }, |
| 95 | + { |
| 96 | + "cell_type": "code", |
| 97 | + "execution_count": null, |
| 98 | + "metadata": { |
| 99 | + "tags": [] |
| 100 | + }, |
| 101 | + "outputs": [], |
| 102 | + "source": [ |
| 103 | + "# Instruction: just run this cell.\n", |
| 104 | + "# The preprocessing function to be applied to every image.\n", |
| 105 | + "transform = Compose([ToTensor(), Normalize((0.5,), (0.5,))])\n", |
| 106 | + "\n", |
| 107 | + "# Example of running the preprocessing on a toy image.\n", |
| 108 | + "example_image = np.array([[1, 0, 1], [1, 1, 0.5]], np.double)\n", |
| 109 | + "transform(example_image)" |
| 110 | + ] |
| 111 | + }, |
| 112 | + { |
| 113 | + "cell_type": "code", |
| 114 | + "execution_count": 6, |
| 115 | + "metadata": { |
| 116 | + "tags": [] |
| 117 | + }, |
| 118 | + "outputs": [], |
| 119 | + "source": [ |
| 120 | + "# Instruction: add your code here.\n", |
| 121 | + "# Use Ray Data to parallelize the preprocessing logic above.\n", |
| 122 | + "# NOTE: Do not drop labels during preprocessing!\n", |
| 123 | + "\n", |
| 124 | + "\n", |
| 125 | + "\n", |
| 126 | + "\n" |
| 127 | + ] |
| 128 | + }, |
| 129 | + { |
| 130 | + "cell_type": "markdown", |
| 131 | + "metadata": {}, |
| 132 | + "source": [ |
| 133 | + "## Task 3: Run distributed training with 4 GPU workers\n", |
| 134 | + "\n", |
| 135 | + "In this section, let's do distributed model training for preprocessed images. To do distributed model training, you are given a script with everything working, except the part of data loading is missing. You are expected to fill in the data loading code and start training!\n", |
| 136 | + "\n", |
| 137 | + "Success Criteria for this section:\n", |
| 138 | + "- Successfully use correct Ray Data API to get shard of Dataset.\n", |
| 139 | + "- Successfully use correct Ray Data API to iterate the Dataset and pass batch of (images, labels) to model." |
| 140 | + ] |
| 141 | + }, |
| 142 | + { |
| 143 | + "cell_type": "code", |
| 144 | + "execution_count": 7, |
| 145 | + "metadata": { |
| 146 | + "tags": [] |
| 147 | + }, |
| 148 | + "outputs": [], |
| 149 | + "source": [ |
| 150 | + "# The function executed on each training worker.\n", |
| 151 | + "def train_func_per_worker():\n", |
| 152 | + " # Prepare model.\n", |
| 153 | + " model, loss_fn, optimizer = prepare_model()\n", |
| 154 | + "\n", |
| 155 | + " # Model training for 2 epochs.\n", |
| 156 | + " for epoch in range(2):\n", |
| 157 | + " # Instruction: add your code here to get Dataset.\n", |
| 158 | + " # NOTE: each training data batch should have 32 images and labels.\n", |
| 159 | + " # ...\n", |
| 160 | + " # train_data_iterator = ...\n", |
| 161 | + "\n", |
| 162 | + " model.train()\n", |
| 163 | + " # Model training for each batch.\n", |
| 164 | + " for batch in tqdm(train_data_iterator, desc=f\"Train Epoch {epoch}\"):\n", |
| 165 | + " images = batch[\"image\"]\n", |
| 166 | + " labels = batch[\"label\"]\n", |
| 167 | + " pred = model(images)\n", |
| 168 | + " loss = loss_fn(pred, labels)\n", |
| 169 | + "\n", |
| 170 | + " optimizer.zero_grad()\n", |
| 171 | + " loss.backward()\n", |
| 172 | + " optimizer.step()\n", |
| 173 | + "\n", |
| 174 | + " model.eval()" |
| 175 | + ] |
| 176 | + }, |
| 177 | + { |
| 178 | + "cell_type": "code", |
| 179 | + "execution_count": null, |
| 180 | + "metadata": { |
| 181 | + "tags": [] |
| 182 | + }, |
| 183 | + "outputs": [], |
| 184 | + "source": [ |
| 185 | + "# Initialize a Ray TorchTrainer\n", |
| 186 | + "trainer = TorchTrainer(\n", |
| 187 | + " train_loop_per_worker=train_func_per_worker,\n", |
| 188 | + " scaling_config=ScalingConfig(num_workers=1, use_gpu=True),\n", |
| 189 | + " # Instruction: add your code here to pass the Dataset variable.\n", |
| 190 | + " datasets={\"train\": ...}\n", |
| 191 | + ")\n", |
| 192 | + "\n", |
| 193 | + "# Start model training!\n", |
| 194 | + "result = trainer.fit()\n", |
| 195 | + "print(f\"Training result: {result}\")" |
| 196 | + ] |
| 197 | + }, |
| 198 | + { |
| 199 | + "cell_type": "markdown", |
| 200 | + "metadata": {}, |
| 201 | + "source": [ |
| 202 | + "Please fill in the blanks below:\n", |
| 203 | + "\n", |
| 204 | + "| | |\n", |
| 205 | + "|----------------------------|----------------------|\n", |
| 206 | + "| Number of epochs trained | ___x___ (epochs) |\n", |
| 207 | + "| End-to-end training time | ___x___ (seconds) |" |
| 208 | + ] |
| 209 | + } |
| 210 | + ], |
| 211 | + "metadata": { |
| 212 | + "kernelspec": { |
| 213 | + "display_name": "Python 3 (ipykernel)", |
| 214 | + "language": "python", |
| 215 | + "name": "python3" |
| 216 | + }, |
| 217 | + "language_info": { |
| 218 | + "codemirror_mode": { |
| 219 | + "name": "ipython", |
| 220 | + "version": 3 |
| 221 | + }, |
| 222 | + "file_extension": ".py", |
| 223 | + "mimetype": "text/x-python", |
| 224 | + "name": "python", |
| 225 | + "nbconvert_exporter": "python", |
| 226 | + "pygments_lexer": "ipython3", |
| 227 | + "version": "3.9.15" |
| 228 | + }, |
| 229 | + "vscode": { |
| 230 | + "interpreter": { |
| 231 | + "hash": "1a1af0ee75eeea9e2e1ee996c87e7a2b11a0bebd85af04bb136d915cefc0abce" |
| 232 | + } |
| 233 | + } |
| 234 | + }, |
| 235 | + "nbformat": 4, |
| 236 | + "nbformat_minor": 4 |
| 237 | +} |
0 commit comments