{ "cells": [ { "cell_type": "markdown", "id": "213d538c", "metadata": {}, "source": [ "# T3. dataloader 的内部结构和基本使用\n", "\n", "  1   fastNLP 中的 dataloader\n", " \n", "    1.1   dataloader 的基本介绍\n", "\n", "    1.2   dataloader 的函数创建\n", "\n", "  2   fastNLP 中 dataloader 的延伸\n", "\n", "    2.1   collator 的概念与使用\n", "\n", "    2.2   sampler 的概念与使用" ] }, { "cell_type": "markdown", "id": "85857115", "metadata": {}, "source": [ "## 1. fastNLP 中的 dataloader\n", "\n", "### 1.1 dataloader 的基本介绍\n", "\n", "在`fastNLP 0.8`的开发中,最关键的开发目标就是**实现`fastNLP`对当前主流机器学习框架**,例如\n", "\n", "  **较为火热的`pytorch`**,以及**国产的`paddle`和`jittor`的兼容**,扩大受众的同时,也是助力国产\n", "\n", "本着分而治之的思想,我们可以将`fastNLP 0.8`对`pytorch`、`paddle`、`jittor`框架的兼容,划分为\n", "\n", "    **对数据预处理**、**批量`batch`的划分与补齐**、**模型训练**、**模型评测**,**四个部分的兼容**\n", "\n", "  针对数据预处理,我们已经在`tutorial-1`中介绍了`dataset`和`vocabulary`的使用\n", "\n", "    而结合`tutorial-0`,我们可以发现**数据预处理环节本质上是框架无关的**\n", "\n", "    因为在不同框架下,读取的原始数据格式都差异不大,彼此也很容易转换\n", "\n", "只有涉及到张量、模型,不同框架才展现出其各自的特色:**`pytorch`中的`tensor`和`nn.Module`**\n", "\n", "    **在`paddle`中称为`tensor`和`nn.Layer`**,**在`jittor`中则称为`Var`和`Module`**\n", "\n", "    因此,**模型训练、模型评测**,**是兼容的重难点**,我们将会在`tutorial-5`中详细介绍\n", "\n", "  针对批量`batch`的处理,作为`fastNLP 0.8`中框架无关部分想框架相关部分的过渡\n", "\n", "    就是`dataloader`模块的职责,这也是本篇教程`tutorial-3`讲解的重点\n", "\n", "**`dataloader`模块的职责**,详细划分可以包含以下三部分,**采样划分、补零对齐、框架匹配**\n", "\n", "    第一,确定`batch`大小,确定采样方式,划分后通过迭代器即可得到`batch`序列\n", "\n", "    第二,对于序列处理,这也是`fastNLP`主要针对的,将同个`batch`内的数据对齐\n", "\n", "    第三,**`batch`内数据格式要匹配框架**,**但`batch`结构需保持一致**,**参数匹配机制**\n", "\n", "  对此,`fastNLP 0.8`给出了 **`TorchDataLoader`、`PaddleDataLoader`和`JittorDataLoader`**\n", "\n", "    分别针对并匹配不同框架,但彼此之间参数名、属性、方法仍然类似,前两者大致如下表所示\n", "\n", "|
名称
|
参数
|
属性
|
功能
|
内容
|\n", "|:--|:--:|:--:|:--|:--|\n", "| **`dataset`** | √ | √ | 指定`dataloader`的数据内容 | |\n", "| `batch_size` | √ | √ | 指定`dataloader`的`batch`大小 | 默认`16` |\n", "| `shuffle` | √ | √ | 指定`dataloader`的数据是否打乱 | 默认`False` |\n", "| `collate_fn` | √ | √ | 指定`dataloader`的`batch`打包方法 | 视框架而定 |\n", "| `sampler` | √ | √ | ? | 默认`None` |\n", "| `batch_sampler` | √ | √ | ? | 默认`None` |\n", "| `drop_last` | √ | √ | 指定`dataloader`划分`batch`时是否丢弃剩余的 | 默认`False` |\n", "| `cur_batch_indices` | | √ | 记录`dataloader`当前遍历批量序号 | |\n", "| `num_workers` | √ | √ | 指定`dataloader`开启子进程数量 | 默认`0` |\n", "| `worker_init_fn` | √ | √ | 指定`dataloader`子进程初始方法 | 默认`None` |\n", "| `generator` | √ | √ | 指定`dataloader`子进程随机种子 | 默认`None` |\n", "| `prefetch_factor` | | √ | 指定为每个`worker`装载的`sampler`数量 | 默认`2` |" ] }, { "cell_type": "markdown", "id": "60a8a224", "metadata": {}, "source": [ "  论及`dataloader`的函数,其中,`get_batch_indices`用来获取当前遍历到的`batch`序号,其他函数\n", "\n", "    包括`set_ignore`、`set_pad`和`databundle`类似,请参考`tutorial-2`,此处不做更多介绍\n", "\n", "    以下是`tutorial-2`中已经介绍过的数据预处理流程,接下来是对相关数据进行`dataloader`处理" ] }, { "cell_type": "code", "execution_count": 5, "id": "aca72b49", "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Processing: 0%| | 0/4 [00:00