{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "Tce3stUlHN0L" }, "source": [ "##### Copyright 2019 The TensorFlow Authors." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "cellView": "form", "execution": { "iopub.execute_input": "2022-12-14T21:11:31.091694Z", "iopub.status.busy": "2022-12-14T21:11:31.091487Z", "iopub.status.idle": "2022-12-14T21:11:31.095209Z", "shell.execute_reply": "2022-12-14T21:11:31.094701Z" }, "id": "tuOe1ymfHZPu" }, "outputs": [], "source": [ "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", "# you may not use this file except in compliance with the License.\n", "# You may obtain a copy of the License at\n", "#\n", "# https://www.apache.org/licenses/LICENSE-2.0\n", "#\n", "# Unless required by applicable law or agreed to in writing, software\n", "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", "# See the License for the specific language governing permissions and\n", "# limitations under the License." ] }, { "cell_type": "markdown", "metadata": { "id": "qFdPvlXBOdUN" }, "source": [ "# 使用 tf.data API 提升性能" ] }, { "cell_type": "markdown", "metadata": { "id": "MfBg1C5NB3X0" }, "source": [ "\n", " \n", " \n", " \n", " \n", "
在 TensorFlow.org 上查看 在 Google Colab 中运行 在 GitHub 中查看源代码下载笔记本
" ] }, { "cell_type": "markdown", "metadata": { "id": "xHxb-dlhMIzW" }, "source": [ "## 概述\n", "\n", "GPU 和 TPU 能够极大缩短执行单个训练步骤所需的时间。为了达到最佳性能,需要高效的输入流水线,以在当前步骤完成之前为下一步提供数据。`tf.data` API 有助于构建灵活高效的输入流水线。本文档演示了如何使用 `tf.data` API 构建高性能的 TensorFlow 输入流水线。\n", "\n", "继续之前,请阅读“[构建 TensorFlow 输入流水线](https://render.githubusercontent.com/view/data.ipynb)”指南,了解如何使用 `tf.data` API。" ] }, { "cell_type": "markdown", "metadata": { "id": "UhNtHfuxCGVy" }, "source": [ "## 资源\n", "\n", "- [Build TensorFlow input pipelines](./data.ipynb)\n", "- `tf.data.Dataset` API\n", "- [Analyze `tf.data` performance with the TF Profiler](./data_performance_analysis.md)" ] }, { "cell_type": "markdown", "metadata": { "id": "MUXex9ctTuDB" }, "source": [ "## 设置" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:11:31.098740Z", "iopub.status.busy": "2022-12-14T21:11:31.098195Z", "iopub.status.idle": "2022-12-14T21:11:32.991837Z", "shell.execute_reply": "2022-12-14T21:11:32.991088Z" }, "id": "IqR2PQG4ZaZ0" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "2022-12-14 21:11:32.029129: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory\n", "2022-12-14 21:11:32.029242: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory\n", "2022-12-14 21:11:32.029253: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.\n" ] } ], "source": [ "import tensorflow as tf\n", "\n", "import time" ] }, { "cell_type": "markdown", "metadata": { "id": "QthTHCKF-jKD" }, "source": [ "在本指南中,您将对数据集进行迭代并衡量性能。制定可重现的性能基准可能很困难。影响重现性的不同因素包括:\n", "\n", "- 当前的 CPU 负载\n", "- 网络流量\n", "- 缓存等复杂机制\n", "\n", "要获得可重现的基准,需要构建人工样本。" ] }, { "cell_type": "markdown", "metadata": { "id": "3bU5gsSI-jKF" }, "source": [ "### 数据集\n", "\n", "定义一个继承自 `tf.data.Dataset` 的类,称为 `ArtificialDataset`。此数据集:\n", "\n", "- 生成 `num_samples` 个样本(默认数量为 3)\n", "- 会在第一项模拟打开文件之前休眠一段时间\n", "- 在生成每项之前休眠一段时间,以模拟从文件读取数据" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:11:32.996296Z", "iopub.status.busy": "2022-12-14T21:11:32.995541Z", "iopub.status.idle": "2022-12-14T21:11:33.000682Z", "shell.execute_reply": "2022-12-14T21:11:33.000069Z" }, "id": "zUQv4kCd-jKH" }, "outputs": [], "source": [ "class ArtificialDataset(tf.data.Dataset):\n", " def _generator(num_samples):\n", " # Opening the file\n", " time.sleep(0.03)\n", " \n", " for sample_idx in range(num_samples):\n", " # Reading data (line, record) from the file\n", " time.sleep(0.015)\n", " \n", " yield (sample_idx,)\n", " \n", " def __new__(cls, num_samples=3):\n", " return tf.data.Dataset.from_generator(\n", " cls._generator,\n", " output_types=tf.dtypes.int64,\n", " output_shapes=(1,),\n", " args=(num_samples,)\n", " )" ] }, { "cell_type": "markdown", "metadata": { "id": "O9y1WjNv-jKL" }, "source": [ "此数据集类似 `tf.data.Dataset.range`,在开头和每个样本之间添加了固定延迟。" ] }, { "cell_type": "markdown", "metadata": { "id": "FGK1Y4jn-jKM" }, "source": [ "### 训练循环\n", "\n", "接下来,编写一个虚拟的训练循环,以测量迭代数据集所用的时间。训练时间是模拟的。" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:11:33.003949Z", "iopub.status.busy": "2022-12-14T21:11:33.003385Z", "iopub.status.idle": "2022-12-14T21:11:33.007042Z", "shell.execute_reply": "2022-12-14T21:11:33.006385Z" }, "id": "MIaM3u00-jKP" }, "outputs": [], "source": [ "def benchmark(dataset, num_epochs=2):\n", " start_time = time.perf_counter()\n", " for epoch_num in range(num_epochs):\n", " for sample in dataset:\n", " # Performing a training step\n", " time.sleep(0.01)\n", " tf.print(\"Execution time:\", time.perf_counter() - start_time)" ] }, { "cell_type": "markdown", "metadata": { "id": "KK58SuXS-jKT" }, "source": [ "## 优化性能\n", "\n", "为了展示如何优化性能,下面我们将优化 `ArtificialDataset` 的性能。" ] }, { "cell_type": "markdown", "metadata": { "id": "Xi8t26y7-jKV" }, "source": [ "### 朴素的方法\n", "\n", "先从不使用任何技巧的朴素流水线开始,按原样迭代数据集。" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:11:33.010001Z", "iopub.status.busy": "2022-12-14T21:11:33.009755Z", "iopub.status.idle": "2022-12-14T21:11:36.698493Z", "shell.execute_reply": "2022-12-14T21:11:36.697888Z" }, "id": "_gP7J1y4-jKY" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Execution time: 0.23592574200029048\n" ] } ], "source": [ "benchmark(ArtificialDataset())" ] }, { "cell_type": "markdown", "metadata": { "id": "Lxeat5dH-jKf" }, "source": [ "从后台可以看到执行时间的花费情况:\n", "\n", "![Naive](https://tensorflow.google.cn/guide/images/data_performance/naive.svg)\n", "\n", "可以看到,执行一个训练步骤涉及以下操作:\n", "\n", "- 打开文件(如果尚未打开)\n", "- 从文件获取数据条目\n", "- 使用数据进行训练\n", "\n", "但是,在类似这里的朴素同步实现中,当流水线在获取数据时,模型会处于空闲状态。相反,当模型在进行训练时,输入流水线会处于空闲状态。因此,训练步骤的用时是打开、读取和训练时间的总和。\n", "\n", "接下来的各部分将基于此输入流水线,演示设计高效 TensorFlow 输入流水线的最佳做法。" ] }, { "cell_type": "markdown", "metadata": { "id": "mfukBGNz-jKh" }, "source": [ "### 预提取\n", "\n", "预提取会与训练步骤的预处理和模型执行重叠。在模型执行第 `s` 步训练的同时,输入流水线会读取第 `s+1` 步的数据。这样做能够最大程度减少训练的单步用时(而非总和),并减少提取数据所需的时间。\n", "\n", "`tf.data` API 提供了 `tf.data.Dataset.prefetch` 转换。它可以用来将生成数据的时间和使用数据的时间分离。特别是,该转换会使用后台线程和内部缓冲区在请求元素之前从输入数据集中预提取元素。要预提取的元素数量应等于(或可能大于)单个训练步骤使用的批次数。您可以手动调整这个值,或者将其设置为 `tf.data.AUTOTUNE`,这将提示 `tf.data` 运行时在运行期间动态调整该值。\n", "\n", "注意,只要有机会将“生产者”的工作和“使用者”的工作重叠,预提取转换就能带来好处。" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:11:36.702158Z", "iopub.status.busy": "2022-12-14T21:11:36.701906Z", "iopub.status.idle": "2022-12-14T21:11:36.961364Z", "shell.execute_reply": "2022-12-14T21:11:36.960760Z" }, "id": "DHpUVqH1-jKi" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Execution time: 0.23147455700018327\n" ] } ], "source": [ "benchmark(\n", " ArtificialDataset()\n", " .prefetch(tf.data.experimental.AUTOTUNE)\n", ")" ] }, { "cell_type": "markdown", "metadata": { "id": "h7z_kzo--jKn" }, "source": [ "![Prefetched](https://tensorflow.google.cn/guide/images/data_performance/prefetched.svg)\n", "\n", "这次您可以看到,在针对样本 0 运行训练步骤的同时,输入流水线正在读取样本 1 的数据,依此类推。" ] }, { "cell_type": "markdown", "metadata": { "id": "52QMKfaY-jKq" }, "source": [ "### 并行数据提取\n", "\n", "在实际设置中,输入数据可能会远程存储(例如,在 Google Cloud Storage 或 HDFS 上)。由于在本地存储空间和远程存储空间之间存在以下差异,在本地读取数据时运行良好的数据集流水线可能会在远程读取数据时成为 I/O 瓶颈:\n", "\n", "- **到达第一字节用时**:从远程存储空间中读取文件的第一个字节所花费的时间要比从本地存储空间中读取所花费的时间长几个数量级。\n", "- **读取吞吐量**:虽然远程存储空间通常提供较大的聚合带宽,但读取单个文件可能只能使用此带宽的一小部分。\n", "\n", "此外,将原始字节加载到内存中后,可能还需要对数据进行反序列化和/或解密(例如 [protobuf](https://developers.google.com/protocol-buffers/)),这需要进行额外计算。无论数据是本地存储还是远程存储,都会存在此开销,但如果没有高效地预提取数据,在远程情况下会更糟。\n", "\n", "为了减轻各种数据提取开销的影响,可以使用 `tf.data.Dataset.interleave` 转换来并行化数据加载步骤,从而交错其他数据集(如数据文件读取器)的内容。可以通过 `cycle_length` 参数指定想要重叠的数据集数量,并通过 `num_parallel_calls` 参数指定并行度级别。与 `prefetch` 转换类似,`interleave` 转换也支持 `tf.data.AUTOTUNE`,它将让 `tf.data` 运行时决定要使用的并行度级别。" ] }, { "cell_type": "markdown", "metadata": { "id": "gs8O8Vbu-jKu" }, "source": [ "#### 顺序交错\n", "\n", "`tf.data.Dataset.interleave` 转换的默认参数会使其按顺序交错两个数据集中的单个样本。" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:11:36.964891Z", "iopub.status.busy": "2022-12-14T21:11:36.964601Z", "iopub.status.idle": "2022-12-14T21:11:37.257456Z", "shell.execute_reply": "2022-12-14T21:11:37.256814Z" }, "id": "fDH12GiK-jKw" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "WARNING:tensorflow:From /tmpfs/tmp/ipykernel_89114/785647145.py:13: calling DatasetV2.from_generator (from tensorflow.python.data.ops.dataset_ops) with output_types is deprecated and will be removed in a future version.\n", "Instructions for updating:\n", "Use output_signature instead\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "WARNING:tensorflow:From /tmpfs/tmp/ipykernel_89114/785647145.py:13: calling DatasetV2.from_generator (from tensorflow.python.data.ops.dataset_ops) with output_shapes is deprecated and will be removed in a future version.\n", "Instructions for updating:\n", "Use output_signature instead\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Execution time: 0.2584234989999459\n" ] } ], "source": [ "benchmark(\n", " tf.data.Dataset.range(2)\n", " .interleave(ArtificialDataset)\n", ")" ] }, { "cell_type": "markdown", "metadata": { "id": "78CsSOnf-jK0" }, "source": [ "![Sequential interleave](https://tensorflow.google.cn/guide/images/data_performance/sequential_interleave.svg)\n", "\n", "此数据执行时间图可以展示 `interleave` 转换的行为,从两个可用的数据集中交替提取样本。但是,这里不涉及性能改进。" ] }, { "cell_type": "markdown", "metadata": { "id": "j3cqqmYl-jK2" }, "source": [ "#### 并行交错\n", "\n", "现在,使用 `interleave` 转换的 `num_parallel_calls` 参数。这样可以并行加载多个数据集,从而减少等待打开文件的时间。" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:11:37.260812Z", "iopub.status.busy": "2022-12-14T21:11:37.260521Z", "iopub.status.idle": "2022-12-14T21:11:37.500372Z", "shell.execute_reply": "2022-12-14T21:11:37.499616Z" }, "id": "a3FQcTPY-jK4" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Execution time: 0.2078962689997752\n" ] } ], "source": [ "benchmark(\n", " tf.data.Dataset.range(2)\n", " .interleave(\n", " ArtificialDataset,\n", " num_parallel_calls=tf.data.experimental.AUTOTUNE\n", " )\n", ")" ] }, { "cell_type": "markdown", "metadata": { "id": "RxRLPB6C-jLA" }, "source": [ "![Parallel interleave](https://tensorflow.google.cn/guide/images/data_performance/parallel_interleave.svg)\n", "\n", "这次,两个数据集的读取并行进行,从而减少了全局数据处理时间。" ] }, { "cell_type": "markdown", "metadata": { "id": "5ZCLFWyv-jLB" }, "source": [ "### 并行数据转换\n", "\n", "准备数据时,可能需要对输入元素进行预处理。为此,`tf.data` API 提供了 `tf.data.Dataset.map` 转换,该转换会将用户定义的函数应用于输入数据集的每个元素。由于输入元素彼此独立,可以在多个 CPU 核心之间并行预处理。为了实现这一点,类似 `prefetch` 和 `interleave` 转换,`map` 转换也提供了`num_parallel_calls` 参数来指定并行度级别。\n", "\n", "`num_parallel_calls` 参数最佳值的选择取决于您的硬件、训练数据的特性(如数据大小和形状)、映射函数的开销,以及同一时间在 CPU 上进行的其他处理。一个简单的试探法是使用可用的 CPU 核心数。但是,对于 `prefetch` 和 `interleave` 转换,`map` 转换支持 `tf.data.AUTOTUNE`,它将让 `tf.data` 运行时决定要使用的并行度级别。" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:11:37.503677Z", "iopub.status.busy": "2022-12-14T21:11:37.503346Z", "iopub.status.idle": "2022-12-14T21:11:37.506986Z", "shell.execute_reply": "2022-12-14T21:11:37.506390Z" }, "id": "GSkKetpx-jLD" }, "outputs": [], "source": [ "def mapped_function(s):\n", " # Do some hard pre-processing\n", " tf.py_function(lambda: time.sleep(0.03), [], ())\n", " return s" ] }, { "cell_type": "markdown", "metadata": { "id": "wiU7W_QC-jLI" }, "source": [ "#### 顺序映射\n", "\n", "首先使用不具有并行度的 `map` 转换作为基准示例。" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:11:37.510011Z", "iopub.status.busy": "2022-12-14T21:11:37.509748Z", "iopub.status.idle": "2022-12-14T21:11:37.988584Z", "shell.execute_reply": "2022-12-14T21:11:37.987847Z" }, "id": "ZSBvDpJG-jLL" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.9/site-packages/tensorflow/python/autograph/pyct/static_analysis/liveness.py:83: Analyzer.lamba_check (from tensorflow.python.autograph.pyct.static_analysis.liveness) is deprecated and will be removed after 2023-09-23.\n", "Instructions for updating:\n", "Lambda fuctions will be no more assumed to be used in the statement where they are used, or at least in the same block. https://github.com/tensorflow/tensorflow/issues/56089\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Execution time: 0.4232728860001771\n" ] } ], "source": [ "benchmark(\n", " ArtificialDataset()\n", " .map(mapped_function)\n", ")" ] }, { "cell_type": "markdown", "metadata": { "id": "ngwMTDb6-jLR" }, "source": [ "![Sequential mapping](https://tensorflow.google.cn/guide/images/data_performance/sequential_map.svg)\n", "\n", "对于[朴素方法](#The-naive-approach)来说,单次迭代的用时就是花费在打开、读取、预处理(映射)和训练步骤上的时间总和。" ] }, { "cell_type": "markdown", "metadata": { "id": "U-10PE1D-jLU" }, "source": [ "#### 并行映射\n", "\n", "现在,使用相同的预处理函数,但将其并行应用于多个样本。" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:11:37.991972Z", "iopub.status.busy": "2022-12-14T21:11:37.991721Z", "iopub.status.idle": "2022-12-14T21:11:38.323926Z", "shell.execute_reply": "2022-12-14T21:11:38.323147Z" }, "id": "F8AYLZbg-jLV" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Execution time: 0.30039678700040895\n" ] } ], "source": [ "benchmark(\n", " ArtificialDataset()\n", " .map(\n", " mapped_function,\n", " num_parallel_calls=tf.data.experimental.AUTOTUNE\n", " )\n", ")" ] }, { "cell_type": "markdown", "metadata": { "id": "-MoJklzP-jLe" }, "source": [ "![Parallel mapping](https://tensorflow.google.cn/guide/images/data_performance/parallel_map.svg)\n", "\n", "如数据图表所示,预处理步骤重叠,从而减少了单次迭代的总时间。" ] }, { "cell_type": "markdown", "metadata": { "id": "ZY1Q9kJO-jLh" }, "source": [ "### 缓存\n", "\n", "`tf.data.Dataset.cache` 转换可以在内存中或本地存储空间中缓存数据集。这样可以避免一些运算(如文件打开和数据读取)在每个周期都被执行。" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:11:38.327341Z", "iopub.status.busy": "2022-12-14T21:11:38.327066Z", "iopub.status.idle": "2022-12-14T21:11:38.715601Z", "shell.execute_reply": "2022-12-14T21:11:38.714849Z" }, "id": "xieLApaI-jLi" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Execution time: 0.35351189199991495\n" ] } ], "source": [ "benchmark(\n", " ArtificialDataset()\n", " .map( # Apply time consuming operations before cache\n", " mapped_function\n", " ).cache(\n", " ),\n", " 5\n", ")" ] }, { "cell_type": "markdown", "metadata": { "id": "KeMgW9XI-jLn" }, "source": [ "![Cached dataset](https://tensorflow.google.cn/guide/images/data_performance/cached_dataset.svg)\n", "\n", "缓存数据集时,仅在第一个周期执行一次 `cache` 之前的转换(如文件打开和数据读取)。后续周期将重用通过 `cache` 转换缓存的数据。\n", "\n", "如果传递到 `map` 转换的用户定义函数开销很大,可在 `map` 转换后应用 `cache` 转换,只要生成的数据集仍然可以放入内存或本地存储空间即可。如果用户定义函数增加了存储数据集所需的空间(超出缓存容量),在 `cache` 转换后应用该函数,或者考虑在训练作业之前对数据进行预处理以减少资源使用。" ] }, { "cell_type": "markdown", "metadata": { "id": "i3NtGI3r-jLp" }, "source": [ "### 向量化映射\n", "\n", "调用传递给 `map` 转换的用户定义函数会产生与调度和执行用户定义函数相关的开销。对用户定义函数进行向量化处理(即,让它一次运算一批输入)并在 `map` 转换*之前*应用 `batch` 转换。\n", "\n", "为了说明这种良好做法,不适合使用您的人工数据集。调度延迟大约为 10 微妙(10e-6 秒),远远小于 `ArtificialDataset` 中使用的数十毫秒,因此很难看出它的影响。\n", "\n", "在本示例中,我们使用基本 `tf.data.Dataset.range` 函数并将训练循环简化为最简形式。" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:11:38.719038Z", "iopub.status.busy": "2022-12-14T21:11:38.718791Z", "iopub.status.idle": "2022-12-14T21:11:38.724558Z", "shell.execute_reply": "2022-12-14T21:11:38.723888Z" }, "id": "xqtiYPmb-jLt" }, "outputs": [], "source": [ "fast_dataset = tf.data.Dataset.range(10000)\n", "\n", "def fast_benchmark(dataset, num_epochs=2):\n", " start_time = time.perf_counter()\n", " for _ in tf.data.Dataset.range(num_epochs):\n", " for _ in dataset:\n", " pass\n", " tf.print(\"Execution time:\", time.perf_counter() - start_time)\n", " \n", "def increment(x):\n", " return x+1" ] }, { "cell_type": "markdown", "metadata": { "id": "Fj2gmsMT-jL5" }, "source": [ "#### 标量映射" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:11:38.727503Z", "iopub.status.busy": "2022-12-14T21:11:38.727215Z", "iopub.status.idle": "2022-12-14T21:11:38.980988Z", "shell.execute_reply": "2022-12-14T21:11:38.980262Z" }, "id": "Imn3SslJ-jMA" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Execution time: 0.22000337100007528\n" ] } ], "source": [ "fast_benchmark(\n", " fast_dataset\n", " # Apply function one item at a time\n", " .map(increment)\n", " # Batch\n", " .batch(256)\n", ")" ] }, { "cell_type": "markdown", "metadata": { "id": "BWUNbPqv-jMF" }, "source": [ "![Scalar map](https://tensorflow.google.cn/guide/images/data_performance/scalar_map.svg)\n", "\n", "上图说明了正在发生的事情(样本较少)。您可以看到已将映射函数应用于每个样本。虽然此函数速度很快,但会产生一些开销影响时间性能。" ] }, { "cell_type": "markdown", "metadata": { "id": "tDVSM0A--jMG" }, "source": [ "#### 向量化映射" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:11:38.984356Z", "iopub.status.busy": "2022-12-14T21:11:38.984088Z", "iopub.status.idle": "2022-12-14T21:11:39.031185Z", "shell.execute_reply": "2022-12-14T21:11:39.030546Z" }, "id": "nAw1mDLw-jMI" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Execution time: 0.03476098400005867\n" ] } ], "source": [ "fast_benchmark(\n", " fast_dataset\n", " .batch(256)\n", " # Apply function on a batch of items\n", " # The tf.Tensor.__add__ method already handle batches\n", " .map(increment)\n", ")" ] }, { "cell_type": "markdown", "metadata": { "id": "DbMteMY9-jMO" }, "source": [ "![Vectorized map](https://tensorflow.google.cn/guide/images/data_performance/vectorized_map.svg)\n", "\n", "这次,映射函数被调用了一次,并被应用于一批样本。如数据执行时间图所示,虽然该函数可能需要花费更多时间执行,但开销仅出现了一次,从而改善了整体时间性能。" ] }, { "cell_type": "markdown", "metadata": { "id": "hfueG0Wj-jMR" }, "source": [ "### 减少内存占用\n", "\n", "许多转换(包括 `interleave`、`prefetch` 和 `shuffle`)会维护元素的内部缓冲区。如果传递给 `map` 转换的用户定义函数更改了元素大小,则映射转换和缓冲元素的转换的顺序会影响内存使用量。通常,我们建议选择能够降低内存占用的顺序,除非需要不同的顺序以提高性能。\n", "\n", "#### 缓存部分计算\n", "\n", "建议在 `map` 转换后缓存数据集,除非此转换会使数据过大而不适合放在内存中。如果映射函数可以分成两个部分,则能实现折衷:一个耗时的部分和一个消耗内存的部分。在这种情况下,您可以按如下方式将转换链接起来:\n", "\n", "```python\n", "dataset.map(time_consuming_mapping).cache().map(memory_consuming_mapping)\n", "```\n", "\n", "这样,耗时部分仅在第一个周期执行,从而避免了使用过多缓存空间。" ] }, { "cell_type": "markdown", "metadata": { "id": "MYOHG69M-jMT" }, "source": [ "## 最佳做法总结\n", "\n", "以下是设计高效 TensorFlow 输入流水线的最佳做法总结:\n", "\n", "- [使用 `prefetch` 转换](#Pipelining)使生产者和使用者的工作重叠。\n", "- 使用 `interleave` 转换实现[并行数据读取转换](#Parallelizing-data-extraction)\n", "- 通过设置 `num_parallel_calls` 参数实现[并行 `map` 转换](#Parallelizing-data-transformation)\n", "- 第一个周期[使用 `cache` 转换](#Caching)将数据缓存在内存中。\n", "- [向量化](#Map-and-batch)传递给 `map` 转换的用户定义函数\n", "- 应用 `interleave`、`prefetch` 和 `shuffle` 转换时[减少内存使用量](#Reducing-memory-footprint)" ] }, { "cell_type": "markdown", "metadata": { "id": "mP_EMFsQ-jMU" }, "source": [ "## 重现图表\n", "\n", "注:本笔记本的剩余部分是关于如何重现上述图表的,请随意使用以下代码,但请了解其并非本教程的主要内容。\n", "\n", "要更深入地了解 `tf.data.Dataset` API,您可以使用自己的流水线。下面是用来绘制本指南中图像的代码。这可以作为一个好的起点,展示了一些常见困难的解决方法,例如:\n", "\n", "- 执行时间的可重现性\n", "- 映射函数 Eager Execution\n", "- `interleave` 转换的可调用对象" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:11:39.034680Z", "iopub.status.busy": "2022-12-14T21:11:39.034434Z", "iopub.status.idle": "2022-12-14T21:11:39.377362Z", "shell.execute_reply": "2022-12-14T21:11:39.376684Z" }, "id": "7M_jFLer-jMV" }, "outputs": [], "source": [ "import itertools\n", "from collections import defaultdict\n", "\n", "import numpy as np\n", "import matplotlib as mpl\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "markdown", "metadata": { "id": "Z3pjnxtK-jMa" }, "source": [ "### 数据集\n", "\n", "与 `ArtificialDataset` 类似,您可以构建一个返回每步用时的数据集。" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:11:39.381412Z", "iopub.status.busy": "2022-12-14T21:11:39.381023Z", "iopub.status.idle": "2022-12-14T21:11:39.387831Z", "shell.execute_reply": "2022-12-14T21:11:39.387233Z" }, "id": "OgGl4U7t-jMc" }, "outputs": [], "source": [ "class TimeMeasuredDataset(tf.data.Dataset):\n", " # OUTPUT: (steps, timings, counters)\n", " OUTPUT_TYPES = (tf.dtypes.string, tf.dtypes.float32, tf.dtypes.int32)\n", " OUTPUT_SHAPES = ((2, 1), (2, 2), (2, 3))\n", " \n", " _INSTANCES_COUNTER = itertools.count() # Number of datasets generated\n", " _EPOCHS_COUNTER = defaultdict(itertools.count) # Number of epochs done for each dataset\n", " \n", " def _generator(instance_idx, num_samples):\n", " epoch_idx = next(TimeMeasuredDataset._EPOCHS_COUNTER[instance_idx])\n", " \n", " # Opening the file\n", " open_enter = time.perf_counter()\n", " time.sleep(0.03)\n", " open_elapsed = time.perf_counter() - open_enter\n", " \n", " for sample_idx in range(num_samples):\n", " # Reading data (line, record) from the file\n", " read_enter = time.perf_counter()\n", " time.sleep(0.015)\n", " read_elapsed = time.perf_counter() - read_enter\n", " \n", " yield (\n", " [(\"Open\",), (\"Read\",)],\n", " [(open_enter, open_elapsed), (read_enter, read_elapsed)],\n", " [(instance_idx, epoch_idx, -1), (instance_idx, epoch_idx, sample_idx)]\n", " )\n", " open_enter, open_elapsed = -1., -1. # Negative values will be filtered\n", " \n", " \n", " def __new__(cls, num_samples=3):\n", " return tf.data.Dataset.from_generator(\n", " cls._generator,\n", " output_types=cls.OUTPUT_TYPES,\n", " output_shapes=cls.OUTPUT_SHAPES,\n", " args=(next(cls._INSTANCES_COUNTER), num_samples)\n", " )" ] }, { "cell_type": "markdown", "metadata": { "id": "YQqDP4jk-jMj" }, "source": [ "此数据集会提供形状为 `[[2, 1], [2, 2], [2, 3]]` 且类型为 `[tf.dtypes.string, tf.dtypes.float32, tf.dtypes.int32]` 的样本。每个样本为:\n", "\n", "```\n", "( [(\"Open\"), (\"Read\")], [(t0, d), (t0, d)], [(i, e, -1), (i, e, s)] )\n", "```\n", "\n", "其中:\n", "\n", "- `Open` 和 `Read` 是步骤标识符\n", "- `t0` 是相应步骤开始时的时间戳\n", "- `d` 是在相应步骤中花费的时间\n", "- `i` 是实例索引\n", "- `e` 是周期索引(数据集被迭代的次数)\n", "- `s` 是样本索引" ] }, { "cell_type": "markdown", "metadata": { "id": "IQK913bB-jMm" }, "source": [ "### 迭代循环\n", "\n", "使迭代循环稍微复杂一点,以汇总所有计时。这仅适用于生成上述样本的数据集。" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:11:39.391300Z", "iopub.status.busy": "2022-12-14T21:11:39.390860Z", "iopub.status.idle": "2022-12-14T21:11:39.398136Z", "shell.execute_reply": "2022-12-14T21:11:39.397581Z" }, "id": "zAy-K_Cq-jMn" }, "outputs": [], "source": [ "def timelined_benchmark(dataset, num_epochs=2):\n", " # Initialize accumulators\n", " steps_acc = tf.zeros([0, 1], dtype=tf.dtypes.string)\n", " times_acc = tf.zeros([0, 2], dtype=tf.dtypes.float32)\n", " values_acc = tf.zeros([0, 3], dtype=tf.dtypes.int32)\n", " \n", " start_time = time.perf_counter()\n", " for epoch_num in range(num_epochs):\n", " epoch_enter = time.perf_counter()\n", " for (steps, times, values) in dataset:\n", " # Record dataset preparation informations\n", " steps_acc = tf.concat((steps_acc, steps), axis=0)\n", " times_acc = tf.concat((times_acc, times), axis=0)\n", " values_acc = tf.concat((values_acc, values), axis=0)\n", " \n", " # Simulate training time\n", " train_enter = time.perf_counter()\n", " time.sleep(0.01)\n", " train_elapsed = time.perf_counter() - train_enter\n", " \n", " # Record training informations\n", " steps_acc = tf.concat((steps_acc, [[\"Train\"]]), axis=0)\n", " times_acc = tf.concat((times_acc, [(train_enter, train_elapsed)]), axis=0)\n", " values_acc = tf.concat((values_acc, [values[-1]]), axis=0)\n", " \n", " epoch_elapsed = time.perf_counter() - epoch_enter\n", " # Record epoch informations\n", " steps_acc = tf.concat((steps_acc, [[\"Epoch\"]]), axis=0)\n", " times_acc = tf.concat((times_acc, [(epoch_enter, epoch_elapsed)]), axis=0)\n", " values_acc = tf.concat((values_acc, [[-1, epoch_num, -1]]), axis=0)\n", " time.sleep(0.001)\n", " \n", " tf.print(\"Execution time:\", time.perf_counter() - start_time)\n", " return {\"steps\": steps_acc, \"times\": times_acc, \"values\": values_acc}" ] }, { "cell_type": "markdown", "metadata": { "id": "jw_WSQC8-jMs" }, "source": [ "### 绘图方法\n", "\n", "最后,定义一个函数,根据 `timelined_benchmark` 函数返回的值绘制时间线。" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:11:39.401058Z", "iopub.status.busy": "2022-12-14T21:11:39.400832Z", "iopub.status.idle": "2022-12-14T21:11:39.411178Z", "shell.execute_reply": "2022-12-14T21:11:39.410604Z" }, "id": "1j73RxiP-jMw" }, "outputs": [], "source": [ "def draw_timeline(timeline, title, width=0.5, annotate=False, save=False):\n", " # Remove invalid entries (negative times, or empty steps) from the timelines\n", " invalid_mask = np.logical_and(timeline['times'] > 0, timeline['steps'] != b'')[:,0]\n", " steps = timeline['steps'][invalid_mask].numpy()\n", " times = timeline['times'][invalid_mask].numpy()\n", " values = timeline['values'][invalid_mask].numpy()\n", " \n", " # Get a set of different steps, ordered by the first time they are encountered\n", " step_ids, indices = np.stack(np.unique(steps, return_index=True))\n", " step_ids = step_ids[np.argsort(indices)]\n", "\n", " # Shift the starting time to 0 and compute the maximal time value\n", " min_time = times[:,0].min()\n", " times[:,0] = (times[:,0] - min_time)\n", " end = max(width, (times[:,0]+times[:,1]).max() + 0.01)\n", " \n", " cmap = mpl.cm.get_cmap(\"plasma\")\n", " plt.close()\n", " fig, axs = plt.subplots(len(step_ids), sharex=True, gridspec_kw={'hspace': 0})\n", " fig.suptitle(title)\n", " fig.set_size_inches(17.0, len(step_ids))\n", " plt.xlim(-0.01, end)\n", " \n", " for i, step in enumerate(step_ids):\n", " step_name = step.decode()\n", " ax = axs[i]\n", " ax.set_ylabel(step_name)\n", " ax.set_ylim(0, 1)\n", " ax.set_yticks([])\n", " ax.set_xlabel(\"time (s)\")\n", " ax.set_xticklabels([])\n", " ax.grid(which=\"both\", axis=\"x\", color=\"k\", linestyle=\":\")\n", " \n", " # Get timings and annotation for the given step\n", " entries_mask = np.squeeze(steps==step)\n", " serie = np.unique(times[entries_mask], axis=0)\n", " annotations = values[entries_mask]\n", " \n", " ax.broken_barh(serie, (0, 1), color=cmap(i / len(step_ids)), linewidth=1, alpha=0.66)\n", " if annotate:\n", " for j, (start, width) in enumerate(serie):\n", " annotation = \"\\n\".join([f\"{l}: {v}\" for l,v in zip((\"i\", \"e\", \"s\"), annotations[j])])\n", " ax.text(start + 0.001 + (0.001 * (j % 2)), 0.55 - (0.1 * (j % 2)), annotation,\n", " horizontalalignment='left', verticalalignment='center')\n", " if save:\n", " plt.savefig(title.lower().translate(str.maketrans(\" \", \"_\")) + \".svg\")" ] }, { "cell_type": "markdown", "metadata": { "id": "xto6GNdO-jM1" }, "source": [ "### 对映射函数使用封装容器\n", "\n", "要在 Eager 上下文中运行映射函数,必须将其封装在 `tf.py_function` 调用中。" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:11:39.413780Z", "iopub.status.busy": "2022-12-14T21:11:39.413573Z", "iopub.status.idle": "2022-12-14T21:11:39.417052Z", "shell.execute_reply": "2022-12-14T21:11:39.416507Z" }, "id": "39v7JD4L-jM2" }, "outputs": [], "source": [ "def map_decorator(func):\n", " def wrapper(steps, times, values):\n", " # Use a tf.py_function to prevent auto-graph from compiling the method\n", " return tf.py_function(\n", " func,\n", " inp=(steps, times, values),\n", " Tout=(steps.dtype, times.dtype, values.dtype)\n", " )\n", " return wrapper" ] }, { "cell_type": "markdown", "metadata": { "id": "7eJRCinb-jM5" }, "source": [ "### 流水线对比" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:11:39.419757Z", "iopub.status.busy": "2022-12-14T21:11:39.419513Z", "iopub.status.idle": "2022-12-14T21:11:39.422582Z", "shell.execute_reply": "2022-12-14T21:11:39.422052Z" }, "id": "YwX4ndHE-jM6" }, "outputs": [], "source": [ "_batch_map_num_items = 50\n", "\n", "def dataset_generator_fun(*args):\n", " return TimeMeasuredDataset(num_samples=_batch_map_num_items)" ] }, { "cell_type": "markdown", "metadata": { "id": "EwxJT2aR-jNA" }, "source": [ "#### 朴素流水线" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:11:39.425306Z", "iopub.status.busy": "2022-12-14T21:11:39.425076Z", "iopub.status.idle": "2022-12-14T21:11:52.493245Z", "shell.execute_reply": "2022-12-14T21:11:52.492517Z" }, "id": "wLKgurx_-jNC" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Execution time: 12.971360483000353\n" ] } ], "source": [ "@map_decorator\n", "def naive_map(steps, times, values):\n", " map_enter = time.perf_counter()\n", " time.sleep(0.001) # Time consuming step\n", " time.sleep(0.0001) # Memory consuming step\n", " map_elapsed = time.perf_counter() - map_enter\n", "\n", " return (\n", " tf.concat((steps, [[\"Map\"]]), axis=0),\n", " tf.concat((times, [[map_enter, map_elapsed]]), axis=0),\n", " tf.concat((values, [values[-1]]), axis=0)\n", " )\n", "\n", "naive_timeline = timelined_benchmark(\n", " tf.data.Dataset.range(2)\n", " .flat_map(dataset_generator_fun)\n", " .map(naive_map)\n", " .batch(_batch_map_num_items, drop_remainder=True)\n", " .unbatch(),\n", " 5\n", ")" ] }, { "cell_type": "markdown", "metadata": { "id": "EJqUMDsO-jNG" }, "source": [ "### 优化后的流水线" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:11:52.497287Z", "iopub.status.busy": "2022-12-14T21:11:52.496627Z", "iopub.status.idle": "2022-12-14T21:11:59.286049Z", "shell.execute_reply": "2022-12-14T21:11:59.285398Z" }, "id": "HYHcwabr-jNH" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Execution time: 6.721588949999841\n" ] } ], "source": [ "@map_decorator\n", "def time_consuming_map(steps, times, values):\n", " map_enter = time.perf_counter()\n", " time.sleep(0.001 * values.shape[0]) # Time consuming step\n", " map_elapsed = time.perf_counter() - map_enter\n", "\n", " return (\n", " tf.concat((steps, tf.tile([[[\"1st map\"]]], [steps.shape[0], 1, 1])), axis=1),\n", " tf.concat((times, tf.tile([[[map_enter, map_elapsed]]], [times.shape[0], 1, 1])), axis=1),\n", " tf.concat((values, tf.tile([[values[:][-1][0]]], [values.shape[0], 1, 1])), axis=1)\n", " )\n", "\n", "\n", "@map_decorator\n", "def memory_consuming_map(steps, times, values):\n", " map_enter = time.perf_counter()\n", " time.sleep(0.0001 * values.shape[0]) # Memory consuming step\n", " map_elapsed = time.perf_counter() - map_enter\n", "\n", " # Use tf.tile to handle batch dimension\n", " return (\n", " tf.concat((steps, tf.tile([[[\"2nd map\"]]], [steps.shape[0], 1, 1])), axis=1),\n", " tf.concat((times, tf.tile([[[map_enter, map_elapsed]]], [times.shape[0], 1, 1])), axis=1),\n", " tf.concat((values, tf.tile([[values[:][-1][0]]], [values.shape[0], 1, 1])), axis=1)\n", " )\n", "\n", "\n", "optimized_timeline = timelined_benchmark(\n", " tf.data.Dataset.range(2)\n", " .interleave( # Parallelize data reading\n", " dataset_generator_fun,\n", " num_parallel_calls=tf.data.experimental.AUTOTUNE\n", " )\n", " .batch( # Vectorize your mapped function\n", " _batch_map_num_items,\n", " drop_remainder=True)\n", " .map( # Parallelize map transformation\n", " time_consuming_map,\n", " num_parallel_calls=tf.data.experimental.AUTOTUNE\n", " )\n", " .cache() # Cache data\n", " .map( # Reduce memory usage\n", " memory_consuming_map,\n", " num_parallel_calls=tf.data.experimental.AUTOTUNE\n", " )\n", " .prefetch( # Overlap producer and consumer works\n", " tf.data.experimental.AUTOTUNE\n", " )\n", " .unbatch(),\n", " 5\n", ")" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:11:59.289829Z", "iopub.status.busy": "2022-12-14T21:11:59.289213Z", "iopub.status.idle": "2022-12-14T21:11:59.815270Z", "shell.execute_reply": "2022-12-14T21:11:59.814594Z" }, "id": "b_CSUbxL-jNK" }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAABVEAAAHkCAYAAAA3qG8GAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8o6BhiAAAACXBIWXMAAA9hAAAPYQGoP6dpAACE8UlEQVR4nO3deZyVdfn/8ffZ1xkEcQU0dwX7aakUWalJYmYmGi6puGGmkua4FGgJfA3UdEwbd9zIckHFLQ2F3B0d1DIDIcMFBjFFltnOdp9zfn/gjKIyzn1mhvu+4PV8PHg85Myc24vD+77mcz7c130C5XK5LAAAAAAAAADAFwp6XQAAAAAAAAAA+BmbqAAAAAAAAADQCTZRAQAAAAAAAKATbKICAAAAAAAAQCfYRAUAAAAAAACATrCJCgAAAAAAAACdYBMVAAAAAAAAADrBJioAAAAAAAAAdIJNVAAAAAAAAADoBJuoAAAAWKf23Xdf7bvvvl6XAQAAAHQZm6gAAAD4QrfddpsCgYDi8biWLFnyua/vu+++2nXXXT2oDAAAAFi32EQFAABAp3K5nC655JIeO97jjz+uxx9/vMeOBwAAAPQ2NlEBAADQqd1331033XST3nvvvR45XjQaVTQa7ZFjAQAAAOsCm6gAAADo1Pjx41UsFr/0atRbb71V3/ve97TpppsqFotp8ODBuu666z73fZ++J+r//vc/hcNhTZw48XPft2DBAgUCAdXV1XU8tnLlSv3yl7/UoEGDFIvFtP322+vSSy9VqVTq3h8SAAAA6ASbqAAAAOjUNttso9GjR3/p1ajXXXedtt56a40fP15XXHGFBg0apNNPP13XXHPNWp+z2WabaZ999tE999zzua/dfffdCoVCGjVqlCSpra1N++yzj+644w6NHj1aV199tfbee2+NGzdONTU13f+DAgAAAGsR9roAAAAA+N8FF1ygadOm6dJLL9VVV131hd/z9NNPK5FIdPx+7NixOvDAA1VbW6szzjhjrcc+8sgjdeqpp+rf//73Gh9Udffdd2ufffbRZpttJkmqra3VwoUL9Y9//EM77LCDJOnUU0/Vlltuqd///vc655xzNGjQoJ744wIAAABr4EpUAAAAfKltt91Wxx13nG688UYtXbr0C7/n0xuoq1at0rJly7TPPvvorbfe0qpVq9Z67MMOO0zhcFh33313x2P//ve/NW/ePB155JEdj02fPl3f+c531LdvXy1btqzj1/Dhw1UsFvXMM8/0wJ8UAAAA+Dw2UQEAANAlF154oRzHWeu9UZ9//nkNHz5cqVRKG220kTbZZBONHz9ekjrdRO3fv7/233//NUb67777boXDYR122GEdj7355pv629/+pk022WSNX8OHD5ckffDBBz3xxwQAAAA+h3F+AAAAdMm2226rY489VjfeeKN+/etfr/G1hQsXav/999fOO++s2tpaDRo0SNFoVI8++qiuvPLKL/3gp6OOOkonnnii/vnPf2r33XfXPffco/3331/9+/fv+J5SqaTvf//7Ov/887/wGDvuuGP3/5AAAADAF2ATFQAAAF124YUX6o477tCll166xuMPP/ywcrmcHnroIW211VYdjz/55JNdOu6hhx6qU089tWOk/z//+Y/GjRu3xvdst912amlp6bjyFAAAAFhXGOcHAABAl2233XY69thjdcMNN+j999/veDwUCkmSyuVyx2OrVq3Srbfe2qXjbrTRRhoxYoTuuece3XXXXYpGozr00EPX+J4jjjhC9fX1mjlz5ueev3LlSjmOU8GfCAAAAPhybKICAADAlQsuuECFQkELFizoeOyAAw5QNBrVj370I11zzTW69NJLtccee2jTTTft8nGPPPJIvfXWW7r22ms1YsQIbbTRRmt8/bzzztPXv/51HXzwwTrllFN0/fXX64orrtAJJ5yggQMHauXKlT30JwQAAADWxCYqAAAAXNl+++117LHHrvHYTjvtpHvvvVeBQEDnnnuurr/+ev3sZz/TWWed1eXjHnLIIUokEmpubtaRRx75ua8nk0k9/fTTOu+88/TUU0/prLPO0iWXXKI333xTEydOVJ8+fbr9ZwMAAAC+SKD86ZkrAAAAAAAAAMAauBIVAAAAAAAAADrBJioAAAAAAAAAdIJNVAAAAAAAAADoBJuoAAAAAAAAANAJNlEBAAAAAAAAoBNsogIAAAAAAABAJ9hEBQAAAAAAAIBOsIkKAAAAAAAAAJ1gExUAAAAAAAAAOsEmKgAAAAAAAAB0gk1UAAAAAAAAAOgEm6gAAAAAAAAA0Ak2UQEAAAAAAACgE2yiAgAAAAAAAEAn2EQFAAAAAAAAgE6wiQoAAAAAAAAAnWATFQAAAAAAAAA6wSYqAAAAAAAAAHSCTVQAAAAA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2EQFAABAr+jTp4+i0aiSyaQ233zzTr+3UCjouuuu69ik/MlPfqI//elP+t///qd0Oq3Bgwdrv/3205NPPqkjjzxSixYt0q233qpFixZpyy23lCSde+65+tvf/qZbb71VkydP/sL/z7vvvtvx/e0WLVqk8847TzvvvLMkfeEG7JZbbql3333X9WsAAACA9QObqAAAAPBcMplc4yrPzTbbTF/5yleUTqfXeOyDDz6QJL3++usqFovacccd1zhOLpfTxhtvvNb/TyaTWWOUX5Jqamo0ZswY/elPf9Lw4cM1atSoz11xmkgk1NbWVvGfDwAAALaxiQoAAADPfXp8XpICgcAXPlYqlSRJLS0tCoVCeuWVVxQKhdb4vk9vvH5W//79tWLFijUemzBhgn7605/qr3/9qx577DFddNFFuuuuuzRy5MiO71m+fLk22WSTiv5sAAAAsI9NVAAAAPSaaDS6xodB9ZSvfe1rKhaL+uCDD/Sd73zH1fPmzZv3ucd33HFH7bjjjjr77LN19NFH69Zbb+3YRM1ms1q4cKG+9rWv9Vj9AAAAsCXodQEAAABYf33lK1/RSy+9pHfeeUfLli3ruJK0u3bccUcdc8wxGj16tO6//369/fbbamho0JQpU/TXv/51rc8bMWKEnnvuuY7fZzIZjR07Vk899ZTeffddPf/885ozZ4522WWXju958cUXFYvFNGzYsB6pHQAAAPawiQoAAIBec+655yoUCmnw4MHaZJNNtGjRoh479q233qrRo0frnHPO0U477aRDDz1Uc+bM0VZbbbXW5xxzzDGaO3euFixYIEkKhUL66KOPNHr0aO2444464ogj9IMf/EATJ07seM6dd96pY445RslkssdqBwAAgC2Bcrlc9roIAAAAYF0577zz1NTUpBtuuOFLv3fZsmXaaaed9PLLL2ubbbZZB9UBAADAj7gSFQAAABuUCy64QFtvvXWXbi3wzjvv6Nprr2UDFQAAYAPHlagAAAAAAAAA0AmuRAUAAAAAAACATrCJCgAAAAAAAACdYBMVAAAAAAAAADrBJioAAAAAAAAAdIJNVAAAAAAAAADoBJuoAAAAAAAAANAJNlEBAAAAAAAAoBNsogIAAAAAAABAJ9hEBQAAAAAAAIBO/H9+4e/GSTMVdQAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "draw_timeline(naive_timeline, \"Naive\", 15)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:11:59.819200Z", "iopub.status.busy": "2022-12-14T21:11:59.818669Z", "iopub.status.idle": "2022-12-14T21:12:00.344860Z", "shell.execute_reply": "2022-12-14T21:12:00.344191Z" }, "id": "DoovY7qr-jNR" }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAABVEAAAI7CAYAAADlKNthAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8o6BhiAAAACXBIWXMAAA9hAAAPYQGoP6dpAAB9WklEQVR4nO3de5yUdd3/8ffM7M4eZ1YQMwU84ImjhxRyPZKamBqBupRhiIZ3ZoS6nkItkdugrJakjawwg+zWWhXUXyYGeSLXFrU8AEuGIuzKnQdgZ3d2zjO/P7xdRWTda2aX6/rI6/l47KN2ZufiA9fLdfh6fa/15XK5nAAAAAAAAAAAH8nv9gAAAAAAAAAA4GUsogIAAAAAAABAN1hEBQAAAAAAAIBusIgKAAAAAAAAAN1gERUAAAAAAAAAusEiKgAAAAAAAAB0g0VUAAAAAAAAAOgGi6gAAAAAAAAA0A0WUQEAAAAAAACgGyyiAgAAoCC//e1v5fP5tGHDhl475qxZs+Tz+XrteD3l8/k0a9asXf7rAgAAwNtYRAUAAPgEWr16tS644AINHDhQJSUl2nfffTV58mStXr0672POmTNHS5cu7b0hAQAAACN8uVwu5/YQAAAA6D3333+/zj//fPXv319f//rXdeCBB2rDhg2644479M477+iee+7RxIkTHR+3srJS5513nn77299u93gmk1EqlVJJSUmvXT2aTqeVTqdVWlraK8frKZ/Pp5tuuomrUQEAALCdIrcHAAAAQO9Zv369vva1r2nIkCF68skntddee3U9d/nll+vEE0/U1772Nb344osaMmRIr/yagUBAgUCgV471nqKiIhUV8VYVAAAA3sB2fgAAgE+QH/3oR+rs7NSvfvWr7RZQJWnAgAH65S9/qWg0qltvvVXS+/cebW5u1qRJkxQOh7Xnnnvq8ssvVzwe73qtz+dTNBrVokWL5PP55PP5NHXqVEkffU/UAw44QGeffbYef/xxHXPMMSorK9OoUaP0+OOPS3r3atlRo0aptLRURx99tP7xj39sN+uH74k6derUrl/3wx8fvGo0kUjopptu0sEHH6ySkhINHjxY1157rRKJxHbHTyQSuvLKK7XXXnspFApp/PjxamlpyfePHQAAAJ9w/Od9AACAT5CHHnpIBxxwgE488cSPfP6kk07SAQccoD/96U/bPT5p0iQdcMABmjt3rp555hnNnz9fW7du1eLFiyVJv/vd7zRt2jSNGTNG//Vf/yVJOuigg7qd5d///re++tWv6hvf+IYuuOAC/fjHP9YXv/hF3X777br++ut12WWXSZLmzp2rSZMmad26dfL7P/q/8X/jG9/Qaaedtt1jjzzyiH7/+9/rU5/6lCQpm81q/PjxWrlypf7rv/5Lw4YN00svvaR58+bpX//613b3c502bZruuusuffWrX9Vxxx2nv/71rzrrrLO6/f0AAABg98UiKgAAwCdEW1ub3njjDX3pS1/q9usOP/xwPfjgg2pvb+967MADD9QDDzwgSfrWt76lcDisBQsW6Oqrr9bhhx+uCy64QJdeeqmGDBmiCy64oEfzrFu3Tk8//bSqq6slScOHD9e4ceN0ySWXqLm5Wfvtt58kqV+/fvrGN76hJ598UmPHjv3IY1VXV3cdR3p3gXb69On6/Oc/r2984xuSpP/5n//R8uXL9cQTT+iEE07o+tqRI0fq0ksv1dNPP63jjjtOL7zwgu666y5ddtll+vnPf971e548ebJefPHFHv3eAAAAsHthOz8AAMAnxHuLoqFQqNuve+/5SCTS9di3vvWt7b7m29/+tiTp4Ycfznue4cOHb7fw+dnPflaSdMopp3QtoH7w8VdffbVHx41Go5o4caL69eunu+++u+t+rA0NDRo2bJiGDh2qt99+u+vjlFNOkSQ99thj2/2eZsyYsd1xr7jiijx+lwAAANgdcCUqAADAJ8R7i6MfvML0o3zUYushhxyy3dccdNBB8vv9293n1KkPLpRKUlVVlSRp8ODBH/n41q1be3TcSy65ROvXr9fTTz+tPffcs+vxV155RWvXrt3hXrDvefPNNyVJr7/+uvx+/w63IzjssMN69OsDAABg98MiKgAAwCdEVVWV9tlnn4/dkv7iiy9q4MCBCofDO/2aD/5Qp3y9d4VoTx/P5XIfe8zbbrtNd999t+666y4deeSR2z2XzWY1atQo1dXVfeRrP7x4CwAAAPQUi6gAAACfIGeffbZ+/etfa+XKldvdF/Q9Tz31lDZs2NB1H9H3vPLKKzrwwAO7Pv/3v/+tbDarAw44oOux3lhYLcRTTz2lq6++WldccYUmT568w/MHHXSQXnjhBZ166qndzrr//vsrm81q/fr12119um7duj6ZGwAAAPZxT1QAAIBP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hWX0C6tot2/lcjm1t7dr3333ld+/8115ntj75vf7NXDgu/fzCofDBAGz6BdW0S4so19YRbuwjH5hGf3CKtrtO1VVVR/7NTZuegYAAAAAAAAALmERFQAAAAAAAAC64ZlF1JKSEt10000qKSlxexTAMfqFVbQLy+gXVtEuLKNfWEa/sIp2vcETP1gKAAAAAAAAALzKM1eiAgAAAAAAAIAXsYgKAAAAAAAAAN1gERUAAAAAAAAAusEiKgAAAAAAAAB0g0VUAAAAAAAAAOgGi6gAAAAAAAAA0A0WUQEAAAAAAACgGyyiAgAAAAAAAEA3WEQFAAAAAAAAgG6wiAoAAIBd6vHHH5fP59O2bdtc+fVXrFihYcOGKZPJfOzXPvLIIzryyCOVzWZ3wWQAAADwKhZRAQAA0GfGjh2rK664YrvHjjvuOG3evFlVVVWuzHTttdfqxhtvVCAQ+NivPeOMM1RcXKzf//73u2AyAAAAeBWLqAAAANilgsGgPv3pT8vn8+3yX3vlypVav369zj333B6/ZurUqZo/f34fTgUAAACvYxEVAAAAfWLq1Kl64okndNttt8nn88nn82nDhg07bOf/7W9/qz322EP/7//9Px122GEqLy/Xeeedp87OTi1atEgHHHCA+vXrpxkzZmy3BT+RSOjqq6/WwIEDVVFRoc9+9rN6/PHHu53pnnvu0ec//3mVlpZ2PfbCCy/oc5/7nEKhkMLhsI4++mg9++yzXc9/8Ytf1LPPPqv169f36p8PAAAA7ChyewAAAAB8Mt12223617/+pZEjR2r27NmSpL322ksbNmzY4Ws7Ozs1f/583XPPPWpvb9c555yjiRMnao899tDDDz+sV199Veeee66OP/54ffnLX5YkTZ8+XWvWrNE999yjfffdV0uWLNEZZ5yhl156SYcccshHzvTUU0/pq1/96naPTZ48WUcddZR+8YtfKBAI6J///KeKi4u7nt9vv/20995766mnntJBBx3US386AAAAsIRFVAAAAPSJqqoqBYNBlZeX69Of/nS3X5tKpfSLX/yia5HyvPPO0+9+9zv95z//UWVlpYYPH67Pfe5zeuyxx/TlL39ZGzdu1J133qmNGzdq3333lSRdffXVeuSRR3TnnXdqzpw5H/nrvP76611f/56NGzfqmmuu0dChQyXpIxdg9913X73++uuO/wwAAADwycAiKgAAAFxXXl6+3VWee++9tw444ABVVlZu99ibb74pSXrppZeUyWR06KGHbnecRCKhPffcc6e/TiwW224rvyTV1tZq2rRp+t3vfqfTTjtNNTU1O1xxWlZWps7Ozrx/fwAAALCNRVQAAAC47oPb5yXJ5/N95GPZbFaS1NHRoUAgoOeee06BQGC7r/vgwuuHDRgwQFu3bt3usVmzZumrX/2q/vSnP+nPf/6zbrrpJt1zzz2aOHFi19ds2bJFe+21V16/NwAAANjHIioAAAD6TDAY3O6HQfWWo446SplMRm+++aZOPPFER69bs2bNDo8feuihOvTQQ3XllVfq/PPP15133tm1iBqPx7V+/XodddRRvTY/AAAAbPG7PQAAAAA+uQ444AD9/e9/14YNG/T22293XUlaqEMPPVSTJ0/WlClTdP/99+u1115TU1OT5s6dqz/96U87fd24ceO0cuXKrs9jsZimT5+uxx9/XK+//rr+9re/adWqVRo2bFjX1zzzzDMqKSlRdXV1r8wOAAAAe1hEBQAAQJ+5+uqrFQgENHz4cO21117auHFjrx37zjvv1JQpU3TVVVfpsMMO04QJE7Rq1Srtt99+O33N5MmTtXr1aq1bt06SFAgE9M4772jKlCk69NBDNWnSJH3hC1/QzTff3PWau+++W5MnT1Z5eXmvzQ4AAABbfLlcLuf2EAAAAMCucs011ygSieiXv/zlx37t22+/rcMOO0zPPvusDjzwwF0wHQAAALyIK1EBAACwW7nhhhu0//779+jWAhs2bNCCBQtYQAUAANjNcSUqAAAAAAAAAHSDK1EBAAAAAAAAoBssogIAAAAAAABAN1hEBQAAAAAAAIBusIgKAAAAAAAAAN1gERUAAAAAAAAAusEiKgAAAAAAAAB0g0VUAAAAAAAAAOgGi6gAAAAAAAAA0A0WUQEAAAAAAACgG/8fguouxuX07GwAAAAASUVORK5CYII=\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "draw_timeline(optimized_timeline, \"Optimized\", 15)" ] } ], "metadata": { "colab": { "collapsed_sections": [], "name": "data_performance.ipynb", "toc_visible": true }, "kernelspec": { "display_name": "Python 3", "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.9.16" } }, "nbformat": 4, "nbformat_minor": 0 }