{ "cells": [ { "cell_type": "markdown", "id": "29e01e9a", "metadata": {}, "source": [ "# Scaling Up Training with GenTS\n", "\n", "GenTS is built on top of **PyTorch Lightning**, which means you can leverage all of Lightning's built-in features for scaling up training — including **mixed precision**, **Distributed Data Parallel (DDP)**, **gradient clipping**, **callbacks**, and more.\n", "\n", "This tutorial demonstrates how to use these features to speed up training and handle larger-scale experiments." ] }, { "cell_type": "code", "execution_count": 1, "id": "a04bbd08", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/wcx/anaconda3/envs/gents/lib/python3.10/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", "CUDA extension for cauchy multiplication not found. Install by going to extensions/cauchy/ and running `python setup.py install`. This should speed up end-to-end training by 10-50%\n", "Falling back on slow Cauchy kernel. Install at least one of pykeops or the CUDA extension for efficiency.\n", "Falling back on slow Vandermonde kernel. Install pykeops for improved memory efficiency.\n" ] } ], "source": [ "import time\n", "import torch\n", "import pandas as pd\n", "from lightning import Trainer\n", "from lightning.pytorch.callbacks import EarlyStopping, ModelCheckpoint, Timer\n", "\n", "from gents.dataset import SineND\n", "from gents.model import VanillaDDPM" ] }, { "cell_type": "markdown", "id": "a712d92c", "metadata": {}, "source": [ "## Setup\n", "\n", "We use a **SineND** dataset with moderate size for benchmarking. All experiments use the same model architecture (`VanillaDDPM`) so that we can focus on measuring the effect of different training strategies.\n", "\n", "> **Note:** To observe meaningful speedups from DDP and mixed precision, use a GPU machine. The relative improvements on CPU will be minimal." ] }, { "cell_type": "code", "execution_count": null, "id": "9c657709", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using GPU: NVIDIA GeForce RTX 3080 Ti, Available GPUs: 4\n" ] } ], "source": [ "# Common hyperparameters\n", "SEQ_LEN = 512 # Larger sequence length for more realistic time series data\n", "SEQ_DIM = 16 \n", "BATCH_SIZE = 64\n", "MAX_EPOCHS = 5\n", "NUM_SAMPLES = 10000 \n", "\n", "# Helper: create fresh dataset and model for each experiment\n", "def make_data_and_model():\n", " dm = SineND(\n", " seq_len=SEQ_LEN,\n", " seq_dim=SEQ_DIM,\n", " num_samples=NUM_SAMPLES,\n", " batch_size=BATCH_SIZE,\n", " data_dir=\"../data\",\n", " )\n", " model = VanillaDDPM(seq_len=SEQ_LEN, seq_dim=SEQ_DIM)\n", " return dm, model\n", "\n", "# Store results for comparison\n", "results = []\n", "\n", "# Detect available accelerator\n", "if torch.cuda.is_available():\n", " ACCELERATOR = \"gpu\"\n", " NUM_GPUS = torch.cuda.device_count()\n", " print(f\"Using GPU: {torch.cuda.get_device_name(0)}, Available GPUs: {NUM_GPUS}\")\n", "else:\n", " ACCELERATOR = \"cpu\"\n", " NUM_GPUS = 0\n", " print(\"Using CPU (GPU recommended for meaningful speedups)\")" ] }, { "cell_type": "markdown", "id": "b42cc2be", "metadata": {}, "source": [ "## 1. Baseline: Standard Training (FP32) \n", "\n", "This is the default training mode — single device, full 32-bit precision. We'll use this as the reference point for comparison." ] }, { "cell_type": "code", "execution_count": 3, "id": "029a4579", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "GPU available: True (cuda), used: True\n", "TPU available: False, using: 0 TPU cores\n", "HPU available: False, using: 0 HPUs\n", "You are using a CUDA device ('NVIDIA GeForce RTX 3080 Ti') that has Tensor Cores. To properly utilize them, you should set `torch.set_float32_matmul_precision('medium' | 'high')` which will trade-off precision for performance. For more details, read https://pytorch.org/docs/stable/generated/torch.set_float32_matmul_precision.html#torch.set_float32_matmul_precision\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Downloading SineND dataset in ../data/SineND.pt\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1,2,3]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Epoch 4: 100%|██████████| 110/110 [00:02<00:00, 45.24it/s, v_num=2, train_loss_step=0.0754, val_loss=0.0774, train_loss_epoch=0.0771]" ] }, { "name": "stderr", "output_type": "stream", "text": [ "`Trainer.fit` stopped: `max_epochs=5` reached.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Epoch 4: 100%|██████████| 110/110 [00:02<00:00, 44.44it/s, v_num=2, train_loss_step=0.0754, val_loss=0.0774, train_loss_epoch=0.0771]\n", "Baseline training time: 66.97s\n" ] } ], "source": [ "dm, model = make_data_and_model()\n", "\n", "trainer = Trainer(\n", " max_epochs=MAX_EPOCHS,\n", " accelerator=ACCELERATOR,\n", " devices=1, # Single device\n", " precision=\"32-true\", # Full FP32 precision (default)\n", " enable_progress_bar=True,\n", " enable_model_summary=False,\n", " default_root_dir=\"../lightning_logs/scale_up/baseline\",\n", ")\n", "\n", "start = time.time()\n", "trainer.fit(model, dm)\n", "elapsed_baseline = time.time() - start\n", "\n", "results.append({\n", " \"Strategy\": \"Baseline (FP32)\",\n", " \"Precision\": \"32-true\",\n", " \"Devices\": 1,\n", " \"Time (s)\": round(elapsed_baseline, 2),\n", " \"Speedup\": \"1.00x\",\n", "})\n", "print(f\"Baseline training time: {elapsed_baseline:.2f}s\")" ] }, { "cell_type": "markdown", "id": "19d31c6a", "metadata": {}, "source": [ "## 2. Mixed Precision Training \n", "\n", "Mixed precision uses **FP16** (or BF16) for forward/backward passes while keeping master weights in FP32. This reduces memory usage and can significantly speed up training on modern GPUs (Volta+).\n", "\n", "Lightning makes this a one-line change via the `precision` argument:\n", "\n", "| Precision | Description | Recommended Hardware |\n", "|-----------|-------------|---------------------|\n", "| `\"32-true\"` | Full FP32 (default) | Any |\n", "| `\"16-mixed\"` | FP16 mixed precision with dynamic loss scaling | NVIDIA Volta+ (V100, A100, RTX) |\n", "| `\"bf16-mixed\"` | BF16 mixed precision (no loss scaling needed) | NVIDIA Ampere+ (A100, RTX 30/40 series) |\n", "| `\"16-true\"` | Pure FP16 (less stable) | Not recommended for training |" ] }, { "cell_type": "code", "execution_count": 4, "id": "e584afd6", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Using 16bit Automatic Mixed Precision (AMP)\n", "GPU available: True (cuda), used: True\n", "TPU available: False, using: 0 TPU cores\n", "HPU available: False, using: 0 HPUs\n", "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1,2,3]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Epoch 4: 100%|██████████| 110/110 [00:02<00:00, 40.58it/s, v_num=1, train_loss_step=0.085, val_loss=0.0782, train_loss_epoch=0.0772] " ] }, { "name": "stderr", "output_type": "stream", "text": [ "`Trainer.fit` stopped: `max_epochs=5` reached.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Epoch 4: 100%|██████████| 110/110 [00:02<00:00, 40.03it/s, v_num=1, train_loss_step=0.085, val_loss=0.0782, train_loss_epoch=0.0772]\n", "FP16 mixed precision training time: 13.98s (Speedup: 4.79x)\n" ] } ], "source": [ "dm, model = make_data_and_model()\n", "\n", "# FP16 mixed precision — just change the `precision` argument\n", "trainer_fp16 = Trainer(\n", " max_epochs=MAX_EPOCHS,\n", " accelerator=ACCELERATOR,\n", " devices=1,\n", " precision=\"16-mixed\", # FP16 mixed precision\n", " enable_progress_bar=True,\n", " enable_model_summary=False,\n", " default_root_dir=\"../lightning_logs/scale_up/fp16\",\n", ")\n", "\n", "start = time.time()\n", "trainer_fp16.fit(model, dm)\n", "elapsed_fp16 = time.time() - start\n", "\n", "speedup = elapsed_baseline / elapsed_fp16 if elapsed_fp16 > 0 else float(\"inf\")\n", "results.append({\n", " \"Strategy\": \"FP16 Mixed Precision\",\n", " \"Precision\": \"16-mixed\",\n", " \"Devices\": 1,\n", " \"Time (s)\": round(elapsed_fp16, 2),\n", " \"Speedup\": f\"{speedup:.2f}x\",\n", "})\n", "print(f\"FP16 mixed precision training time: {elapsed_fp16:.2f}s (Speedup: {speedup:.2f}x)\")" ] }, { "cell_type": "markdown", "id": "4984acaf", "metadata": {}, "source": [ "### BF16 Mixed Precision (Ampere+ GPUs)\n", "\n", "If your GPU supports BF16 (NVIDIA A100, RTX 3090/4090, etc.), `bf16-mixed` is preferred over `16-mixed` because it has a wider dynamic range and doesn't require loss scaling." ] }, { "cell_type": "code", "execution_count": 5, "id": "46f02250", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Using bfloat16 Automatic Mixed Precision (AMP)\n", "GPU available: True (cuda), used: True\n", "TPU available: False, using: 0 TPU cores\n", "HPU available: False, using: 0 HPUs\n", "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1,2,3]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Epoch 4: 100%|██████████| 110/110 [00:02<00:00, 39.10it/s, v_num=1, train_loss_step=0.0777, val_loss=0.0762, train_loss_epoch=0.0768]" ] }, { "name": "stderr", "output_type": "stream", "text": [ "`Trainer.fit` stopped: `max_epochs=5` reached.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Epoch 4: 100%|██████████| 110/110 [00:02<00:00, 38.54it/s, v_num=1, train_loss_step=0.0777, val_loss=0.0762, train_loss_epoch=0.0768]\n", "BF16 mixed precision training time: 14.01s (Speedup: 4.78x)\n" ] } ], "source": [ "dm, model = make_data_and_model()\n", "\n", "# BF16 mixed precision — requires Ampere+ GPU\n", "trainer_bf16 = Trainer(\n", " max_epochs=MAX_EPOCHS,\n", " accelerator=ACCELERATOR,\n", " devices=1,\n", " precision=\"bf16-mixed\", # BF16 mixed precision\n", " enable_progress_bar=True,\n", " enable_model_summary=False,\n", " default_root_dir=\"../lightning_logs/scale_up/bf16\",\n", ")\n", "\n", "start = time.time()\n", "trainer_bf16.fit(model, dm)\n", "elapsed_bf16 = time.time() - start\n", "\n", "speedup = elapsed_baseline / elapsed_bf16 if elapsed_bf16 > 0 else float(\"inf\")\n", "results.append({\n", " \"Strategy\": \"BF16 Mixed Precision\",\n", " \"Precision\": \"bf16-mixed\",\n", " \"Devices\": 1,\n", " \"Time (s)\": round(elapsed_bf16, 2),\n", " \"Speedup\": f\"{speedup:.2f}x\",\n", "})\n", "print(f\"BF16 mixed precision training time: {elapsed_bf16:.2f}s (Speedup: {speedup:.2f}x)\")" ] }, { "cell_type": "markdown", "id": "6113eaea", "metadata": {}, "source": [ "## 3. Distributed Data Parallel (DDP) \n", "\n", "When you have multiple GPUs, **DDP (Distributed Data Parallel)** splits the dataset across GPUs, where each GPU processes a different mini-batch independently. Gradients are synchronized via all-reduce after each backward pass.\n", "\n", "Lightning handles DDP out of the box via the `strategy` and `devices` arguments:\n", "\n", "```python\n", "# Use all available GPUs with DDP\n", "trainer = Trainer(strategy=\"ddp\", devices=\"auto\")\n", "\n", "# Use specific GPUs\n", "trainer = Trainer(strategy=\"ddp\", devices=[0, 1])\n", "\n", "# Use N GPUs\n", "trainer = Trainer(strategy=\"ddp\", devices=2)\n", "```\n", "\n", "> **Important:** DDP spawns separate processes per GPU. In a Jupyter notebook, DDP may not work correctly because of how Python multiprocessing interacts with notebooks. **For DDP, use a standalone script** (see below). In this notebook we demonstrate the API, but you should run multi-GPU experiments via command line.\n", "\n", "### DDP Script Example\n", "\n", "Save the following as `train_ddp.py` and run with:\n", "```bash\n", "python train_ddp.py\n", "```\n", "\n", "Lightning will automatically handle process spawning for DDP." ] }, { "cell_type": "code", "execution_count": 6, "id": "f5ff034d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "import time\n", "import torch\n", "from lightning import Trainer\n", "from gents.dataset import SineND\n", "from gents.model import VanillaDDPM\n", "\n", "SEQ_LEN = 48\n", "SEQ_DIM = 2\n", "BATCH_SIZE = 64\n", "MAX_EPOCHS = 50\n", "NUM_SAMPLES = 5000\n", "\n", "dm = SineND(\n", " seq_len=SEQ_LEN, seq_dim=SEQ_DIM,\n", " num_samples=NUM_SAMPLES, batch_size=BATCH_SIZE,\n", " data_dir=\"../data\",\n", ")\n", "model = VanillaDDPM(seq_len=SEQ_LEN, seq_dim=SEQ_DIM)\n", "\n", "trainer = Trainer(\n", " max_epochs=MAX_EPOCHS,\n", " accelerator=\"gpu\",\n", " devices=2, # Use 2 GPUs\n", " strategy=\"ddp\", # Distributed Data Parallel\n", " enable_progress_bar=True,\n", " enable_model_summary=False,\n", " default_root_dir=\"../lightning_logs/scale_up/ddp\",\n", ")\n", "\n", "start = time.time()\n", "trainer.fit(model, dm)\n", "elapsed = time.time() - start\n", "\n", "if trainer.global_rank == 0:\n", " print(f\"DDP (2 GPUs) training time: {elapsed:.2f}s\")\n", "\n" ] } ], "source": [ "ddp_script = '''\n", "import time\n", "import torch\n", "from lightning import Trainer\n", "from gents.dataset import SineND\n", "from gents.model import VanillaDDPM\n", "\n", "SEQ_LEN = 48\n", "SEQ_DIM = 2\n", "BATCH_SIZE = 64\n", "MAX_EPOCHS = 50\n", "NUM_SAMPLES = 5000\n", "\n", "dm = SineND(\n", " seq_len=SEQ_LEN, seq_dim=SEQ_DIM,\n", " num_samples=NUM_SAMPLES, batch_size=BATCH_SIZE,\n", " data_dir=\"../data\",\n", ")\n", "model = VanillaDDPM(seq_len=SEQ_LEN, seq_dim=SEQ_DIM)\n", "\n", "trainer = Trainer(\n", " max_epochs=MAX_EPOCHS,\n", " accelerator=\"gpu\",\n", " devices=2, # Use 2 GPUs\n", " strategy=\"ddp\", # Distributed Data Parallel\n", " enable_progress_bar=True,\n", " enable_model_summary=False,\n", " default_root_dir=\"../lightning_logs/scale_up/ddp\",\n", ")\n", "\n", "start = time.time()\n", "trainer.fit(model, dm)\n", "elapsed = time.time() - start\n", "\n", "if trainer.global_rank == 0:\n", " print(f\"DDP (2 GPUs) training time: {elapsed:.2f}s\")\n", "'''\n", "\n", "print(ddp_script)\n", "ddp_time = 10.97 # Replace with actual timing result from running the above script\n", "speedup = elapsed_baseline / ddp_time if ddp_time > 0 else float(\"inf\") # Replace with actual timing result\n", "results.append({\n", " \"Strategy\": \"DDP (2 GPUs)\",\n", " \"Precision\": \"32-bit\",\n", " \"Devices\": 2,\n", " \"Time (s)\": ddp_time, # actual timing result in py script\n", " \"Speedup\": f\"{speedup:.2f}x\",\n", "})" ] }, { "cell_type": "markdown", "id": "7f861dbb", "metadata": {}, "source": [ "## 4. Gradient Accumulation \n", "\n", "Gradient accumulation simulates a larger batch size without requiring more GPU memory. Instead of updating weights every step, gradients are accumulated over `K` steps before an optimizer update.\n", "\n", "**Effective batch size** = `batch_size × accumulate_grad_batches`\n", "\n", "This is useful when:\n", "- Your GPU memory can't handle a large batch size directly\n", "- You want to experiment with larger effective batch sizes for stability" ] }, { "cell_type": "code", "execution_count": 7, "id": "601262a0", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "GPU available: True (cuda), used: True\n", "TPU available: False, using: 0 TPU cores\n", "HPU available: False, using: 0 HPUs\n", "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1,2,3]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Epoch 4: 100%|██████████| 110/110 [00:02<00:00, 49.00it/s, v_num=1, train_loss_step=0.0766, val_loss=0.0798, train_loss_epoch=0.0811]" ] }, { "name": "stderr", "output_type": "stream", "text": [ "`Trainer.fit` stopped: `max_epochs=5` reached.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Epoch 4: 100%|██████████| 110/110 [00:02<00:00, 48.16it/s, v_num=1, train_loss_step=0.0766, val_loss=0.0798, train_loss_epoch=0.0811]\n", "Gradient accumulation training time: 11.14s (vs baseline: 6.01x)\n" ] } ], "source": [ "dm, model = make_data_and_model()\n", "\n", "# Accumulate gradients over 4 batches → effective batch size = 64 × 4 = 256\n", "trainer_accum = Trainer(\n", " max_epochs=MAX_EPOCHS,\n", " accelerator=ACCELERATOR,\n", " devices=1,\n", " precision=\"32-true\",\n", " accumulate_grad_batches=4, # Gradient accumulation\n", " enable_progress_bar=True,\n", " enable_model_summary=False,\n", " default_root_dir=\"../lightning_logs/scale_up/grad_accum\",\n", ")\n", "\n", "start = time.time()\n", "trainer_accum.fit(model, dm)\n", "elapsed_accum = time.time() - start\n", "\n", "speedup = elapsed_baseline / elapsed_accum if elapsed_accum > 0 else float(\"inf\")\n", "results.append({\n", " \"Strategy\": \"Gradient Accumulation (4x)\",\n", " \"Precision\": \"32-true\",\n", " \"Devices\": 1,\n", " \"Time (s)\": round(elapsed_accum, 2),\n", " \"Speedup\": f\"{speedup:.2f}x\",\n", "})\n", "print(f\"Gradient accumulation training time: {elapsed_accum:.2f}s (vs baseline: {speedup:.2f}x)\")" ] }, { "cell_type": "markdown", "id": "52ce2ae6", "metadata": {}, "source": [ "## 6. Performance Comparison \n", "\n", "Let's visualize the results from all experiments." ] }, { "cell_type": "code", "execution_count": 8, "id": "31210083", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\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", "
StrategyPrecisionDevicesTime (s)Speedup
0Baseline (FP32)32-true166.971.00x
1FP16 Mixed Precision16-mixed113.984.79x
2BF16 Mixed Precisionbf16-mixed114.014.78x
3DDP (2 GPUs)32-bit210.976.11x
4Gradient Accumulation (4x)32-true111.146.01x
\n", "
" ], "text/plain": [ " Strategy Precision Devices Time (s) Speedup\n", "0 Baseline (FP32) 32-true 1 66.97 1.00x\n", "1 FP16 Mixed Precision 16-mixed 1 13.98 4.79x\n", "2 BF16 Mixed Precision bf16-mixed 1 14.01 4.78x\n", "3 DDP (2 GPUs) 32-bit 2 10.97 6.11x\n", "4 Gradient Accumulation (4x) 32-true 1 11.14 6.01x" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAABW8AAAHqCAYAAAB7mLz9AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAApQpJREFUeJzs3XdcVvX///HnBcgGtwIOUBy4w52aWpJguHPmNkep4fhkZZYrR1rmyNJcmGmuHJmapubOUjPK0twrxa2QCwTO7w9/nq+XgIKB16U+7rfbdbtxnfM+7/M6hwuu1/W63ud9LIZhGAIAAAAAAAAA2BUHWwcAAAAAAAAAAEiO4i0AAAAAAAAA2CGKtwAAAAAAAABghyjeAgAAAAAAAIAdongLAAAAAAAAAHaI4i0AAAAAAAAA2CGKtwAAAAAAAABghyjeAgAAAAAAAIAdongLAAAAAAAAAHaI4i0A2JmOHTsqICDgobYdMmSILBZLxgaUwQICAtSxY0dbh2Hq2LGjPD09bR0GAAAA7ITFYtGQIUNsHcZTqXbt2qpdu7b5/NixY7JYLJo1a5bNYgJsjeItAKSRxWJJ02Pjxo22DvWR2rhxY5rPzdMsPj5eEyZMUHBwsLy9vZUtWzaVKlVK3bp1099//222++mnnzRkyBBduXIlU+IYOXKkli1blil9AwAA3LFnzx41a9ZM/v7+cnV1Vb58+fTiiy/q008/tXVoT62U8vYcOXKoatWqmjt3rq3DA5AKJ1sHAACPi6+++srq+ezZs7V27dpky0uUKPGf9jNt2jQlJSU91Lbvvfee3nnnnf+0//QqUaJEsnMwYMAAeXp6auDAgcna79+/Xw4OT993hy+//LK+//57tW7dWl27dtWtW7f0999/a8WKFapWrZqCgoIk3S7eDh06VB07dlS2bNkyPI6RI0eqWbNmaty4cYb3DQAAIN3OZ55//nkVLFhQXbt2lY+Pj06ePKmff/5ZEyZM0BtvvGHrEJ9qERERqlSpkiTp4sWLWrBggdq2basrV66oZ8+eNo7Omr+/v27cuKEsWbLYOhTAZijeAkAatW3b1ur5zz//rLVr1yZbfq/r16/L3d09zfv5L4mJk5OTnJwe7b/2vHnzJjsHH374oXLlypXiuXFxcXlUodmNnTt3asWKFRoxYoTeffddq3WTJk166FG2SUlJio+Pl6urawZECQAAkDFGjBihrFmzaufOncm+jD537pxtgoLpueeeU7Nmzcznr7/+ugoXLqyvv/7a7oq3FouFXBdPvadv6BMAZKLatWurdOnS+vXXX1WzZk25u7ubxbpvv/1W4eHh8vPzk4uLiwIDA/XBBx8oMTHRqo9757y9M8/Txx9/rKlTpyowMFAuLi6qVKmSdu7cabVtSnPeWiwW9erVS8uWLVPp0qXl4uKiUqVKafXq1cni37hxoypWrChXV1cFBgbqiy++yPB5dO+d83bWrFmyWCzaunWrIiIilDt3bmXLlk3du3dXfHy8rly5ovbt2yt79uzKnj273nrrLRmGYdVnUlKSxo8fr1KlSsnV1VV58+ZV9+7ddfny5TTHdeTIEYWGhsrDw0N+fn4aNmyYuR/DMBQQEKBGjRol2+7mzZvKmjWrunfvnmrfhw8fliRVr1492TpHR0flzJlT0u3fX//+/SVJhQoVMi9nO3bsmKT/+13OnTtXpUqVkouLi/l7/Pjjj1WtWjXlzJlTbm5uqlChgr755hurfVksFl27dk1ffvml2ffdv4tTp06pc+fOyps3r/k6mTlzZrKYjx8/roYNG8rDw0N58uRR3759tWbNGqtpQwYPHqwsWbLo/Pnzybbv1q2bsmXLpps3b6Z6zgAAwOPr8OHDKlWqVIpXEeXJk8fq+d35TfHixeXq6qoKFSpo8+bNybZNa64SFxenwYMHq0iRInJxcVGBAgX01ltvKS4uLlm7vn37Knfu3PLy8lLDhg31zz//JOsvtXtS3C/3Tsvx3O3s2bNycnLS0KFDk63bv3+/LBaLJk2aJEm6deuWhg4dqqJFi8rV1VU5c+ZUjRo1tHbt2vvuIzXOzs7Knj17skEgkZGReuGFF5QnTx65uLioZMmSmjx5crLtd+3apdDQUOXKlUtubm4qVKiQOnfubNXmYfP1lOa8vXPPilOnTqlx48by9PRU7ty59eabbyb7bJURnxMAW2PkLQBksIsXL6pevXpq1aqV2rZtq7x580q6XaT09PRUv3795OnpqR9//FGDBg1SbGysPvroowf2+/XXX+vff/9V9+7dZbFYNGbMGDVt2lRHjhx54GjdrVu3asmSJerRo4e8vLw0ceJEvfzyyzpx4oRZOPztt98UFhYmX19fDR06VImJiRo2bJhy5879309KGrzxxhvy8fHR0KFD9fPPP2vq1KnKli2bfvrpJxUsWFAjR47UqlWr9NFHH6l06dJq3769uW337t01a9YsderUSRERETp69KgmTZqk3377Tdu2bXvg+UlMTFRYWJiqVq2qMWPGaPXq1Ro8eLASEhI0bNgwWSwWtW3bVmPGjNGlS5eUI0cOc9vvvvtOsbGx9x2B7e/vL0maO3euqlevnuro6KZNm+rAgQOaN2+exo0bp1y5ckmS1e/gxx9/1MKFC9WrVy/lypXL/CAxYcIENWzYUG3atFF8fLzmz5+v5s2ba8WKFQoPD5d0e+qPLl26qHLlyurWrZskKTAwUNLtDwxVq1Y1P3Dkzp1b33//vV599VXFxsaqT58+kqRr167phRdeUHR0tHr37i0fHx99/fXX2rBhg9WxtGvXTsOGDdOCBQvUq1cvc3l8fLy++eYbvfzyy4yiAADgCeXv76/t27frzz//VOnSpR/YftOmTVqwYIEiIiLk4uKizz//XGFhYdqxY4e5fVpzlaSkJDVs2FBbt25Vt27dVKJECe3Zs0fjxo3TgQMHrOb+79Kli+bMmaNXXnlF1apV048//mjmTf9FWo7nXnnz5lWtWrW0cOFCDR482GrdggUL5OjoqObNm0u6XTQeNWqUmdfFxsZq165d2r17t1588cUHxvfvv//qwoULkqRLly7p66+/1p9//qkZM2ZYtZs8ebJKlSqlhg0bysnJSd9995169OihpKQkc4TuuXPnVLduXeXOnVvvvPOOsmXLpmPHjmnJkiVWff3XfP1eiYmJCg0NVZUqVfTxxx9r3bp1Gjt2rAIDA/X6669n2n4BmzAAAA+lZ8+exr3/RmvVqmVIMqZMmZKs/fXr15Mt6969u+Hu7m7cvHnTXNahQwfD39/ffH706FFDkpEzZ07j0qVL5vJvv/3WkGR899135rLBgwcni0mS4ezsbBw6dMhc9vvvvxuSjE8//dRc1qBBA8Pd3d04deqUuezgwYOGk5NTsj4fpFSpUkatWrVSXOfv72906NDBfB4ZGWlIMkJDQ42kpCRz+bPPPmtYLBbjtddeM5clJCQY+fPnt+p7y5YthiRj7ty5VvtZvXp1isvv1aFDB0OS8cYbb5jLkpKSjPDwcMPZ2dk4f/68YRiGsX//fkOSMXnyZKvtGzZsaAQEBFjFfq+kpCTztZE3b16jdevWxmeffWYcP348WduPPvrIkGQcPXo02TpJhoODg/HXX38lW3fv6ys+Pt4oXbq08cILL1gt9/DwsDr/d7z66quGr6+vceHCBavlrVq1MrJmzWr2P3bsWEOSsWzZMrPNjRs3jKCgIEOSsWHDBnP5s88+a1SpUsWqvyVLliRrBwAAniw//PCD4ejoaDg6OhrPPvus8dZbbxlr1qwx4uPjk7WVZEgydu3aZS47fvy44erqajRp0sRcltZc5auvvjIcHByMLVu2WLWbMmWKIcnYtm2bYRiGERUVZUgyevToYdXulVdeMSQZgwcPNpfdm5/fkVrunZbjSckXX3xhSDL27NljtbxkyZJWOV25cuWM8PDw+/aVkg0bNpjx3f1wcHAwRowYkax9Sp9fQkNDjcKFC5vPly5dakgydu7cmep+05Ov16pVyyrXv/NZKDIy0lx2J38fNmyYVX/BwcFGhQoVHmq/gD1j2gQAyGAuLi7q1KlTsuVubm7mz3e+7X7uued0/fp1/f333w/st2XLlsqePbv5/LnnnpN0+3L/BwkJCTFHWEpS2bJl5e3tbW6bmJiodevWqXHjxvLz8zPbFSlSRPXq1Xtg/xnh1VdftbrsrEqVKjIMQ6+++qq5zNHRURUrVrQ65kWLFilr1qx68cUXdeHCBfNRoUIFeXp6JhsRmpq7R4feGdERHx+vdevWSZKKFSumKlWqWN2J99KlS/r+++/Vpk2b+04tYbFYtGbNGg0fPlzZs2fXvHnz1LNnT/n7+6tly5bpmvO2Vq1aKlmyZLLld7++Ll++rJiYGD333HPavXv3A/s0DEOLFy9WgwYNZBiG1XkMDQ1VTEyM2c/q1auVL18+NWzY0Nze1dVVXbt2TdZv+/bt9csvv5jTRki3Rx8XKFBAtWrVSvMxAwCAx8uLL76o7du3q2HDhvr99981ZswYhYaGKl++fFq+fHmy9s8++6wqVKhgPi9YsKAaNWqkNWvWKDExMV25yqJFi1SiRAkFBQVZtXvhhRckycwNV61aJen2zbvudmcE73/xoONJTdOmTeXk5KQFCxaYy/7880/t3btXLVu2NJdly5ZNf/31lw4ePPhQ8Q0aNEhr167V2rVrtWDBArVu3VoDBw7UhAkTrNrdnV/GxMTowoULqlWrlo4cOaKYmBgzFklasWKFbt26leL+Mipfv9drr71m9fy5557LlM8JgK1RvAWADJYvXz45OzsnW/7XX3+pSZMmypo1q7y9vZU7d27zUvs7yc/9FCxY0Or5nUJuWuZrunfbO9vf2fbcuXO6ceOGihQpkqxdSssyw70xZs2aVZJUoECBZMvvPuaDBw8qJiZGefLkUe7cua0eV69eTdNNMRwcHFS4cGGrZcWKFZMkc75Z6XYxctu2bTp+/Lik2wnhrVu31K5duwfuw8XFRQMHDtS+fft0+vRpzZs3T1WrVjWnQEirQoUKpbh8xYoVqlq1qlxdXZUjRw7lzp1bkydPTtNr6/z587py5YqmTp2a7Bze+SLiznk8fvy4AgMDkxWrU3qdtGzZUi4uLmbBOyYmRitWrHhgsRsAADz+KlWqpCVLlujy5cvasWOHBgwYoH///VfNmjXT3r17rdoWLVo02fbFihXT9evXdf78+XTlKgcPHtRff/2VrN2d3O7unMbBwcFqgIMkFS9e/D8f+4OOJzW5cuVSnTp1tHDhQnPZggUL5OTkpKZNm5rLhg0bpitXrqhYsWIqU6aM+vfvrz/++CPN8ZUpU0YhISEKCQlRixYtNGfOHNWvX1/vvPOOVXzbtm1TSEiIPDw8lC1bNuXOndu8n8edHLNWrVp6+eWXNXToUOXKlUuNGjVSZGSk1fzCGZGv38vV1TXZ9G53f77JrP0CtsCctwCQwe7+hvqOK1euqFatWvL29tawYcMUGBgoV1dX7d69W2+//baSkpIe2K+jo2OKy417bt6V0ds+KqnFmNLyu+NOSkpSnjx5rEbE3i0j5+xt1aqV+vbtq7lz5+rdd9/VnDlzVLFixXQn+b6+vmrVqpVefvlllSpVSgsXLtSsWbNSnQv3bim9vrZs2aKGDRuqZs2a+vzzz+Xr66ssWbIoMjJSX3/99QP7vPP6a9u2rTp06JBim7Jlyz6wn3tlz55d9evX19y5czVo0CB98803iouLu+/8wAAA4Mni7OysSpUqqVKlSipWrJg6deqkRYsWJZvX9X7Sk6skJSWpTJky+uSTT1Jsd+/AgLRI7Uvn+42ifVitWrVSp06dFBUVpWeeeUYLFy5UnTp1zHshSFLNmjV1+PBhffvtt/rhhx80ffp0jRs3TlOmTFGXLl0ear916tTRihUrtGPHDoWHh+vw4cOqU6eOgoKC9Mknn6hAgQJydnbWqlWrNG7cOPN3YrFY9M033+jnn3/Wd999pzVr1qhz584aO3asfv75Z3l6emZKvp7aZ4e7PcrPCUBmongLAI/Axo0bdfHiRS1ZskQ1a9Y0lx89etSGUf2fPHnyyNXVVYcOHUq2LqVl9iQwMFDr1q1T9erVUyxspkVSUpKOHDlijsiQpAMHDkiS1Z2Fc+TIofDwcM2dO1dt2rTRtm3bNH78+IeOPUuWLCpbtqwOHjyoCxcuyMfH56FGpC5evFiurq5as2aNXFxczOWRkZHJ2qbU/507LCcmJiokJOS++/L399fevXtlGIZVX6m9Ttq3b69GjRpp586dmjt3roKDg1WqVKm0HhoAAHiCVKxYUZIUHR1ttTyly/8PHDggd3d3s8CW1lwlMDBQv//+u+rUqXPfvMrf319JSUk6fPiw1Rfx+/fvT9Y2e/bsKU5zdedqrHul5XhS07hxY3Xv3t2cOuHAgQMaMGBAsnY5cuRQp06d1KlTJ129elU1a9bUkCFDHrp4m5CQIEm6evWqpNs35Y2Li9Py5cutrpBLbaqBqlWrqmrVqhoxYoS+/vprtWnTRvPnz1eXLl0yJF9/GLbaL5DRmDYBAB6BO98M3z1iND4+Xp9//rmtQrLi6OiokJAQLVu2TKdPnzaXHzp0SN9//70NI3uwFi1aKDExUR988EGydQkJCWmeT3bSpEnmz4ZhaNKkScqSJYvq1Klj1a5du3bau3ev+vfvL0dHR7Vq1eqBfR88eFAnTpxItvzKlSvavn27smfPbibyHh4e5rq0cnR0lMVisRr9cezYMau7Kd/h4eGRrG9HR0e9/PLLWrx4sf78889k29x9+VxoaKhOnTplNV/dzZs3NW3atBRjq1evnnLlyqXRo0dr06ZNjLoFAOApsGHDhhSv8Lozz+y9Vy1t377dap7+kydP6ttvv1XdunXl6OiYrlylRYsWOnXqVIq5yY0bN3Tt2jVJMu/rMHHiRKs2KX0xHxgYqJiYGKupCaKjo7V06dJkbdNyPPeTLVs2hYaGauHChZo/f76cnZ3VuHFjqzYXL160eu7p6akiRYpYTVWQXitWrJAklStXTlLKn19iYmKSDQ64fPlyst/1M888I0lmPBmVr6eXrfYLZDRG3gLAI1CtWjVlz55dHTp0UEREhCwWi7766iu7mrZgyJAh+uGHH1S9enW9/vrrSkxM1KRJk1S6dGlFRUXZOrxU1apVS927d9eoUaMUFRWlunXrKkuWLDp48KAWLVqkCRMmqFmzZvftw9XVVatXr1aHDh1UpUoVff/991q5cqXefffdZKMjwsPDlTNnTi1atEj16tVTnjx5Hhjj77//rldeeUX16tXTc889pxw5cujUqVP68ssvdfr0aY0fP95MkO/c3GLgwIFq1aqVsmTJogYNGphF3ZSEh4frk08+UVhYmF555RWdO3dOn332mYoUKZJs/rMKFSpo3bp1+uSTT+Tn56dChQqpSpUq+vDDD7VhwwZVqVJFXbt2VcmSJXXp0iXt3r1b69at06VLlyRJ3bt316RJk9S6dWv17t1bvr6+mjt3rlxdXSUlH9mbJUsWtWrVSpMmTZKjo6Nat279wPMFAAAeb2+88YauX7+uJk2aKCgoSPHx8frpp5+0YMECBQQEJLu5b+nSpRUaGqqIiAi5uLiYAxyGDh1qtklrrtKuXTstXLhQr732mjZs2KDq1asrMTFRf//9txYuXKg1a9aoYsWKeuaZZ9S6dWt9/vnniomJUbVq1bR+/foUryZq1aqV3n77bTVp0kQRERG6fv26Jk+erGLFiqV4c9i0HM/9tGzZUm3bttXnn3+u0NBQ86Zgd5QsWVK1a9dWhQoVlCNHDu3atUvffPNNmu+jsGXLFt28eVPS7RvwLl++XJs2bVKrVq0UFBQkSapbt66cnZ3VoEEDde/eXVevXtW0adOUJ08eq5HTX375pT7//HM1adJEgYGB+vfffzVt2jR5e3vrpZdekpQx+frDsNV+gQxnAAAeSs+ePY17/43WqlXLKFWqVIrtt23bZlStWtVwc3Mz/Pz8jLfeestYs2aNIcnYsGGD2a5Dhw6Gv7+/+fzo0aOGJOOjjz5K1qckY/DgwebzwYMHJ4tJktGzZ89k2/r7+xsdOnSwWrZ+/XojODjYcHZ2NgIDA43p06cb//vf/wxXV9dUzkLKSpUqZdSqVSvFdffuNzIy0pBk7Ny506rdnWM5f/681fIOHToYHh4eyfqdOnWqUaFCBcPNzc3w8vIyypQpY7z11lvG6dOn7xvrnf4OHz5s1K1b13B3dzfy5s1rDB482EhMTExxmx49ehiSjK+//vq+fd9x9uxZ48MPPzRq1apl+Pr6Gk5OTkb27NmNF154wfjmm2+Stf/ggw+MfPnyGQ4ODoYk4+jRo4ZhpP67NAzDmDFjhlG0aFHDxcXFCAoKMiIjI1N8Pfz9999GzZo1DTc3N0OS1e/i7NmzRs+ePY0CBQoYWbJkMXx8fIw6deoYU6dOterjyJEjRnh4uOHm5mbkzp3b+N///mcsXrzYkGT8/PPPyWLbsWOHIcmoW7dums4XAAB4vH3//fdG586djaCgIMPT09NwdnY2ihQpYrzxxhvG2bNnrdreyW/mzJlj5jLBwcFW+fEdac1V4uPjjdGjRxulSpUyXFxcjOzZsxsVKlQwhg4dasTExJjtbty4YURERBg5c+Y0PDw8jAYNGhgnT55MlmMbhmH88MMPRunSpQ1nZ2ejePHixpw5c+6be6fleFITGxtr5mpz5sxJtn748OFG5cqVjWzZshlubm5GUFCQMWLECCM+Pv6+/W7YsMGQZPVwdnZOdfvly5cbZcuWNVxdXY2AgABj9OjRxsyZM63y0927dxutW7c2ChYsaLi4uBh58uQx6tevb+zatSvZ/tOSr9eqVcvqc8Sdz0KRkZHmstQ+D6T0+0jrfgF7ZjEMOxr2BQCwO40bN9Zff/2V4txdT6u+fftqxowZOnPmjNzd3W0djl0YP368+vbtq3/++Uf58uWzWvf777/rmWee0ezZs9WuXTsbRQgAAOyRxWJRz549raawepw9accDwPaY8xYAYLpx44bV84MHD2rVqlWqXbu2bQKyQzdv3tScOXP08ssvP7WF23tfJzdv3tQXX3yhokWLJivcStK0adPk6emppk2bPqoQAQAAAOCJwJy3AABT4cKF1bFjRxUuXFjHjx/X5MmT5ezsrLfeesvWodncuXPntG7dOn3zzTe6ePGievfubeuQbKZp06YqWLCgnnnmGcXExGjOnDn6+++/NXfuXKt23333nfbu3aupU6eqV69e9523FwAAAACQHMVbAIApLCxM8+bN05kzZ+Ti4qJnn31WI0eOVNGiRW0dms3t3btXbdq0UZ48eTRx4kTzLrpPo9DQUE2fPl1z585VYmKiSpYsqfnz56tly5ZW7d544w2dPXtWL730Uppv0AEAAAAA+D/MeQsAAAAAAAAAdog5bwEAAAAAAADADlG8BQAAAAAAAAA7xJy3QAZJSkrS6dOn5eXlJYvFYutwAACwGcMw9O+//8rPz08ODowVAB5n5LgAAPwfW+S5FG+BDHL69GkVKFDA1mEAAGA3Tp48qfz589s6DAD/ATkuAADJPco8l+ItkEG8vLwk3f4D9vb2tnE0AADYTmxsrAoUKGC+NwJ4fJHjpiwhIUFLly6VJDVp0kROTny0BoCngS3yXN5hgAxy5zIyb29vElsAACQusQaeAOS4KUtISJC7u7uk2+eG4i0APF0eZZ7LJGQAAAAAAAAAYIco3gIAAAAAAACAHaJ4CwAAAAAAAAB2iOItAAAAAAAAANghZlUHAAAAACAdHBwcVLp0afNnAAAyC8VbAAAAAADSwcHBQWXKlLF1GACApwBfEQIAAAAAAACAHWLkLQAAAAAA6WAYhmJjYyVJ3t7eslgsNo4IAPCkYuQtAAAAAADpkJiYqFWrVmnVqlVKTEy0dTgAgCcYxVsAAAAAAAAAsEMUbwEAAAAAAADADlG8BQAAAAAAAAA7RPEWAAAAAAAAAOwQxVsAAAAAAAAAsEMUbwEAAAAAAADADjnZOgAAAAAAAB4nDg4OCgoKMn8GACCzULwFMliLd1cqi4u7rcMAACDNvhvbyNYhALBz5Lgp4/8nACCz8RUhAAAAAAAAANghircAAAAAAKSLISfLLV27dk2GYdg6GADAE4ziLQAAAAAA6WCRoQDXk1q+fLkSExNtHQ4A4AlG8RYAAAAAAAAA7BDFWwAAAAAAAACwQxRvAQAAAAAAAMAOUbwFAAAAAAAAADtE8RYAAAAAAAAA7BDFWwAAAAAAAACwQxRvAQAAAABIF4tiErxVpEgRWSwWWwcDAHiCOdk6AAAAAAAAHieGLDp/K5cqVapk61AAAE84Rt4CAAAAAAAAgB2ieAsAAAAAQLoYclSibt68KcMwbB0MAOAJRvEWAAAAAIB0sMhQIbfjWrp0qRITE20dDgDgCUbxFgAAAAAAAADsEMVbAAAAAAAAALBDFG8BAAAAAAAAwA5RvAUAAAAAAAAAO0TxFgAAAAAAAADsEMVbAAAAAAAAALBDFG8BAAAAAEgXi2ITPVWoUCFZLBZbBwMAeII52ToAAAAAAAAeJ4YsOhefR1WrVrV1KACAJxwjbwEAAAAAAADADlG8BQAAQDKnTp1S27ZtlTNnTrm5ualMmTLatWuXVZt9+/apYcOGypo1qzw8PFSpUiWdOHEi1T5v3bqlYcOGKTAwUK6uripXrpxWr15t1SYgIEAWiyXZo2fPnplynADwcAxZlKSEhAQZhiFJ2rx5sxo0aCA/Pz9ZLBYtW7bsgb1s3LhR5cuXl4uLi4oUKaJZs2Yla/PZZ58pICBArq6uqlKlinbs2JHBxwIAsGcUb6GAgACNHz/efJ7WRCMj1KxZU19//fUj2VdaXbhwQXny5NE///xj61AAALCJy5cvq3r16sqSJYu+//577d27V2PHjlX27NnNNocPH1aNGjUUFBSkjRs36o8//tD7778vV1fXVPt977339MUXX+jTTz/V3r179dprr6lJkyb67bffzDY7d+5UdHS0+Vi7dq0kqXnz5pl3wHgikeNaI8fNWBYZCnQ7pkWLFikxMVGSdO3aNZUrV06fffZZmvo4evSowsPD9fzzzysqKkp9+vRRly5dtGbNGrPNggUL1K9fPw0ePFi7d+9WuXLlFBoaqnPnzmXKcQEA7A/FWxvq2LGj1YiSnDlzKiwsTH/88YdN44qOjla9evUyfT/Lly/X2bNn1apVK3NZSqNt8ufPn+J6Dw8PlS9fXosWLTLXL1myRBUrVlS2bNnk4eGhZ555Rl999ZW5/tatW3r77bdVpkwZeXh4yM/PT+3bt9fp06fNNrly5VL79u01ePDgTD4DAADYp9GjR6tAgQKKjIxU5cqVVahQIdWtW1eBgYFmm4EDB+qll17SmDFjFBwcrMDAQDVs2FB58uRJtd+vvvpK7777rl566SUVLlxYr7/+ul566SWNHTvWbJM7d275+PiYjxUrVigwMFC1atWSJBmGoSFDhqhgwYJycXGRn5+fIiIiMu9kIN3Icclxn1b16tXT8OHD1aRJkzS1nzJligoVKqSxY8eqRIkS6tWrl5o1a6Zx48aZbT755BN17dpVnTp1UsmSJTVlyhS5u7tr5syZkm6P3HV2dtaWLVvMbcaMGaM8efLo7NmzGXuAAACboHhrY2FhYebIkvXr18vJyUn169e3aUw+Pj5ycXHJ9P1MnDhRnTp1koOD9ctw2LBhViNu7h6Nc/f63377TZUqVVLLli31008/SZJy5MihgQMHavv27frjjz/UqVMnderUyfz2+vr169q9e7fef/997d69W0uWLNH+/fvVsGFDq3106tRJc+fO1aVLlzLxDAAAYJ+WL1+uihUrqnnz5sqTJ4+Cg4M1bdo0c31SUpJWrlypYsWKKTQ0VHny5FGVKlUeOKoxLi4u2chcNzc3bd26NcX28fHxmjNnjjp37mzezX3x4sUaN26cvvjiCx08eFDLli1TmTJl/tsBI8OR45Lj4sG2b9+ukJAQq2WhoaHavn27pNv/A3/99VerNg4ODgoJCTHb1K5dW3369FG7du0UExOj3377Te+//76mT5+uvHnzPrqDAQBkGoq3Nubi4mKOLHnmmWf0zjvv6OTJkzp//rzZ5u2331axYsXk7u6uwoUL6/3339etW7fM9b///ruef/55eXl5ydvbWxUqVLCak27r1q167rnn5ObmpgIFCigiIkLXrl1LNaa7Lyk7duyYLBaLlixZoueff17u7u4qV66cmSw87D7Onz+vH3/8UQ0aNEi2zsvLy2rETe7cuVNcX6xYMX322Wdyc3PTd999J+l28tKkSROVKFFCgYGB6t27t8qWLWt+KMyaNavWrl2rFi1aqHjx4qpataomTZqkX3/91WqOvlKlSsnPz09Lly5N9RgAAHhSHTlyRJMnT1bRokW1Zs0avf7664qIiNCXX34pSTp37pyuXr2qDz/8UGFhYfrhhx/UpEkTNW3aVJs2bUq139DQUH3yySc6ePCgkpKStHbtWi1ZskTR0dEptl+2bJmuXLmijh07mstOnDghHx8fhYSEqGDBgqpcubK6du2aoceP/44clxwXD3bmzJlkBda8efMqNjZWN27c0IULF5SYmJhimzNnzpjPhw8fruzZs6tbt25q27atOnTokKxwDwB4fFG8tSNXr17VnDlzVKRIEeXMmdNc7uXlpVmzZmnv3r2aMGGCpk2bZnUpTZs2bZQ/f37t3LlTv/76q9555x1lyZJF0u356MLCwvTyyy/rjz/+0IIFC7R161b16tUrXbENHDhQb775pqKiolSsWDG1bt1aCQkJD72PrVu3yt3dXSVKlEhXHPdycnJSlixZFB8fn2ydYRhav3699u/fr5o1a6baR0xMjCwWi7Jly2a1vHLlylaXH90rLi5OsbGxVg8AAJ4ESUlJKl++vEaOHKng4GB169ZNXbt21ZQpU8z1ktSoUSP17dvXLM7Vr1/fbJOSCRMmqGjRogoKCpKzs7N69eqV4gjFO2bMmKF69erJz8/PXNa8eXPduHFDhQsXVteuXbV06VIzJ4F9IsdNP3JcpIezs7Pmzp2rxYsX6+bNm1Z/RwCAxx/FWxtbsWKFPD095enpKS8vLy1fvlwLFiyw+hDz3nvvqVq1agoICFCDBg305ptvauHCheb6EydOKCQk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duwD470Th4+Pj/z8/FSvXj1FRERo3bp1unHjhmbNmqVs2bJp+fLlKlmypFxcXHTixAnFxcXpzTffVL58+eTh4aEqVapo48aNVv1u27ZNtWvXlru7u7Jnz67Q0FBdvnxZUvLLxD7//HMVLVpUrq6uyps3r5o1a2auu7ft5cuX1b59e2XPnl3u7u6qV6+e1Xm7E/OaNWtUokQJeXp6mh+I8GRISkpSu3bt1L9/f5UqVeqB7ePj4/Xrr78qJCTEXObg4KCQkBBt3749zfudOHGili9froULF2r//v2aO3euAgICHuYQAACwQo5LjkuOCwCPp549eyo8PNzq82ZazZgxQ61atbL6IrRatWpavny5Tp06JcMwtGHDBh04cEB169aV9H/vH+3atVNMTIx+++03vf/++5o+fbry5s2bYceFzPFUFG/vdvXqVc2ZM0dFihRRzpw5M6zftWvXKikpSadOnVKJEiWUP39+tWjRwipZTU3evHkVGhqqL7/8UtLty7AXLFigzp0733e79u3b66WXXlKbNm2UkJCglStXavr06Zo7d67c3d115coVvfDCCwoODtauXbu0evVqnT17Vi1atDD76N+/vzZt2qRvv/1WP/zwgzZu3Kjdu3en+/jd3NyUlJSkhIQE8xhGjx6t6dOn66+//lKePHnUq1cvbd++XfPnz9cff/yh5s2bKywszEwwo6KiVKdOHZUsWVLbt2/X1q1b1aBBAyUmJr8RwK5duxQREaFhw4Zp//79Wr16tWrWrJlqfB07dtSuXbu0fPlybd++XYZh6KWXXtKtW7fMNtevX9fHH3+sr776Sps3b9aJEyf05ptvpvtcwD6NHj1aTk5OioiISFP7CxcuKDExMdkbWd68eXXmzJk07/fEiRMqWrSoatSoIX9/f9WoUUOtW7dOV+wAADwIOS45LjkuADwe5s+fr927dz/UFZk7duzQn3/+qS5dulgt//TTT1WyZEnlz59fzs7OCgsL02effWb1HjJ8+HBlz55d3bp1U9u2bdWhQ4c0fRkL23N6cJPH34oVK+Tp6Snp9rfwvr6+WrFihRwcrGvXrVu3lqOjo/l8zpw5aty4cZr2ceTIESUlJWnkyJGaMGGCsmbNqvfee08vvvii/vjjDzk7O993+86dO+t///ufBg4cqG+++UaBgYF65plnHrjfO/OjREREaMmSJRoy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WaOrV6+qXr16unLlSqpxTJw4UZ06dZKDw+2X0enTp3X69Gl9/PHH+vPPPzVr1iytXr1ar7766n2PZ8eOHSpfvrz27dunzz77TH/++ac2btyoLl26aPLkyfrrr7+s2kdGRio6Olrbtm1Trly5VL9+fR05ciSNZ+/BnJ2d9corr2jixIkZ1ifS5+jRozpz5oxCQkLMZVmzZlWVKlW0ffv2FLdJSEhQYmKiXF1drZa7ublp69atKW5z9uxZrVy50uo1OnHiRC1fvlwLFy7U/v37NXfuXAUEBPz3gwIAAA9Enkue+7hIslj0d8F8+rtgPiVZLLYOBwDwAMuXL1fFihXVvHlz5cmTR8HBwZo2bVqm7zd37tyaOXOmhgwZol27dunff/9Vu3bt1KtXL9WpUydNfXDDsseQi4uLORQ7X758Kl++vKpWrao6depo1qxZ6tKli9nWy8vLbFuwYEHVrFlTvr6+GjRokJo1a6bixYubbXPmzGmORvz4449VvXp1/fLLLwoNDU0Ww/nz5/Xjjz9qwoQJ5rLSpUtr8eLF5vPAwECNGDFCbdu2VUJCgpyckr/cDMNQx44dVaxYMW3bts1MkCWpaNGiat26tYx7bgCQLVs2M87JkycrX758Wrt2rbp3757mc7hx40a99dZb+uuvv5QlSxaVKlVKX3/9tfz9/SVJDRo00IsvvqgbN27Izc0tzf0iY5w5c0aSlDdvXqvlefPmNdfdy8vLS88++6w++OADlShRQnnz5tW8efO0fft2FSlSJMVtvvzyS3l5ealp06bmshMnTqho0aKqUaOGLBaL+ZoAAACZjzyXPBcAgMxw5MgRTZ48Wf369dO7776rnTt3KiIiQs7OzurQoUOm7vull15S165d1aZNG1WsWFEeHh7pusKXkbdPiBdeeEHlypXTkiVLHti2d+/eMgxD3377bapt7iRy8fHxKa7funWr3N3dVaJEifvuKyYmRt7e3ikmtJIUFRWlffv26c0337RKaO9muc832Q+KMyUJCQlq3LixatWqpT/++EPbt29Xt27drPZTsWJFJSQk6Jdffkm1n7i4OMXGxlo9YFtfffWVDMNQvnz55OLiookTJ6p169apvrZmzpypNm3aWI3W7dixo6KiolS8eHFFRETohx9+eFThAwCAFJDnPto8lxwXAPAkSkpKUvny5TVy5EgFBwerW7du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5bcvUeO/hKGB8VOJpSmZvaj2b7+IiKhpqfybWFJSAjMzM3WHQ/TCYY5LRETUMM+71qCOPLdR0yYQaZo33ngDZ8+exaVLl2Bvb/9U9llYWIjp06c3KqklIiIiInpamOMSERFRJRZv6YU3efLkp7q/ypuBEBERERGpC3NczSagAgx/f/jk/sucOoGIiJ4ZFm+JiIiIiIiIGkvx9G5GQ0REVBt+PUhERERERERERESkgVi8JSIiIiIiIiIiItJALN4SERERERERERERaSAWb4mIiIiIiIiIiIg0EIu3RERERERERERERBpIT90BEBEREREREb1wBP+dJiKiZ49/bYiIiIiIiIgaQQEd4L6TusMgIiItwGkTiIiIiIiIiIiIiDQQi7dEREREREREREREGojTJhARERERERE1goAKMLj08MmDVg+nUSAiInoGWLwlIiIiIiIiaiydB+qOgIiItAC/HiQiIiIiIiIiIiLSQCzeEhEREREREREREWkgFm+JiIiIiIiIiIiINBCLt0REREREREREREQaiMVbIiIiIiIiIiIiIg2kp+4AiIiIiIiIiF48uuoOgIiItACLt0RERERERESNoIAOcK+1usMgIiItwGkTiIiIiIiIiIiIiDQQi7dEREREREREREREGkghhBDqDoKoKbh16xaUSiVKSkpgZmam7nCIiIjUhn8TiZoO/j7XrKKiAvv37wcAvPrqq9DV5fy3RETaQB1/FznnLREREREREVEjCCFw9epV6WciIqJnhdMmEBEREREREREREWkgFm+JiIiIiIiIiIiINBCLt0REREREREREREQaiMVbIiIiIiIiIiIiIg3E4i0RERERERERERGRBtJTdwBERERERERELxpdXV11h0BERFqAxVsiIiIiIiKiRtDT00NQUJC6wyAiIi3AaROIiIiIiIiIiIiINBCLt0REREREREREREQaiNMmEBERERERETVCRUUFMjMzAQDdu3fn/LdERPTMsHhLRERERERE1AhCCBQVFUk/ExERPSucNoGIiIiIiIiIiIhIA7F4S0RERERERERERKSBWLwlIiIiIiIiIiIi0kAs3hIRERERERERERFpIBZviYiIiIiIiIiIiDSQnroDIGoqKu8ye+vWLTVHQkREpF6Vfwt5B3aiFx9z3JqVl5fj7t27AB6OjZ4e/7UmItIG6shz+ReG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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "\n", "df = pd.DataFrame(results)\n", "# print(df.to_markdown(index=False))\n", "display(df)\n", "\n", "fig, axes = plt.subplots(1, 2, figsize=(14, 5))\n", "\n", "# Training time comparison\n", "colors = [\"#4C72B0\", \"#DD8452\", \"#55A868\", \"#C44E52\", \"#8172B3\"]\n", "bars = axes[0].barh(df[\"Strategy\"], df[\"Time (s)\"], color=colors[: len(df)])\n", "axes[0].set_xlabel(\"Training Time (seconds)\")\n", "axes[0].set_title(\"Training Time by Strategy\")\n", "axes[0].invert_yaxis()\n", "for bar, t in zip(bars, df[\"Time (s)\"]):\n", " axes[0].text(bar.get_width() + 0.5, bar.get_y() + bar.get_height() / 2,\n", " f\"{t}s\", va=\"center\", fontsize=10)\n", "\n", "# Speedup comparison\n", "speedup_vals = [float(s.replace(\"x\", \"\")) for s in df[\"Speedup\"]]\n", "bars2 = axes[1].barh(df[\"Strategy\"], speedup_vals, color=colors[: len(df)])\n", "axes[1].set_xlabel(\"Speedup (x)\")\n", "axes[1].set_title(\"Speedup vs Baseline\")\n", "axes[1].axvline(x=1.0, color=\"gray\", linestyle=\"--\", alpha=0.7)\n", "axes[1].invert_yaxis()\n", "for bar, s in zip(bars2, df[\"Speedup\"]):\n", " axes[1].text(bar.get_width() + 0.02, bar.get_y() + bar.get_height() / 2,\n", " s, va=\"center\", fontsize=10)\n", "\n", "plt.tight_layout()\n", "# plt.savefig(\"scale_up_comparison.png\", dpi=150, bbox_inches=\"tight\")\n", "plt.show()" ] } ], "metadata": { "kernelspec": { "display_name": "gents", "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.10.19" } }, "nbformat": 4, "nbformat_minor": 5 }