diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..1d74e21965c4f858f5f818a270e64e1bfad7d843 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vscode/ diff --git a/doc/fluid/api/api_guides/low_level/cluster/cluster_train_data_cn.rst b/doc/fluid/api/api_guides/low_level/cluster/cluster_train_data_cn.rst new file mode 100644 index 0000000000000000000000000000000000000000..ded49d5c60b312d2f578ea38dbcb83e71d89ad0a --- /dev/null +++ b/doc/fluid/api/api_guides/low_level/cluster/cluster_train_data_cn.rst @@ -0,0 +1,64 @@ +.. _api_guide_cluster_train_data: + +#################### +分布式训练数据准备 +#################### + +一个数据并行的分布式训练任务通常会含有多个训练进程,每个训练进程处理整个数据集中的一部分,根据当前进程的唯一序号(trainer_id)以及训练进程总数(trainers)可以决定当前训练进程应该读取哪一部分数据。 + +实现 cluster_reader 来读取分布式训练数据集 +---------------------------------------- + +比较通用的方法,可以实现一个 cluster_reader, 根据训练进程数量以及进程序号决定读取哪些 example: + + .. code-block:: python + + def cluster_reader(reader, trainers, trainer_id): + def reader_creator(): + for idx, data in enumerate(reader()): + if idx % trainers == trainer_id: + yield data + return reader + + trainers = int(os.getenv("PADDLE_TRAINERS", "1")) + trainer_id = int(os.getenv("PADDLE_TRAINER_ID", "0")) + train_reader = cluster_reader(paddle.dataset.mnist.train(), trainers, trainer_id) + +上述代码中,`trainers` 和 `trainer_id` 分别是训练进程总数和当前训练进程的序号,可以通过环境变量或者参数的方式传递给 Python 程序。 + +预先切分训练文件 +----------------- + +由于使用 `cluster_reader` 依然会读取全量数据,对于训练进程比较多的任务,会造成IO资源的浪费、影响训练性能。另一种方法是可以将训练数据切分成多个小文件,每个进程处理其中的一部分文件, +例如在 Linux 系统中可以使用 `split `_ 命令将训练数据切分成多个小文件: + + .. code-block:: bash + $ split -d -a 4 -d -l 100 housing.data cluster/housing.data. + $ find ./cluster + cluster/ + cluster/housing.data.0002 + cluster/housing.data.0003 + cluster/housing.data.0004 + cluster/housing.data.0000 + cluster/housing.data.0001 + cluster/housing.data.0005 + +数据切分好以后, 可以实现一个 file_dispatcher 函数,根据训练进程数量以及序号决定需要读取哪些文件: + + .. code-block:: python + + def file_dispatcher(files_pattern, trainers, trainer_id): + file_list = glob.glob(files_pattern) + ret_list = [] + for idx, f in enumerate(file_list): + if (idx + trainers) % trainers == trainer_id: + ret_list.append(f) + return ret_list + + trainers = int(os.getenv("PADDLE_TRAINERS", "1")) + trainer_id = int(os.getenv("PADDLE_TRAINER_ID", "0")) + files_pattern = "cluster/housing.data.*" + + my_files = file_dispatcher(files_pattern, triners, trainer_id) + +在上述例子中,`files_pattern` 是训练文件的 `glob 表达式 `_,一般可以用通配符来表示。 \ No newline at end of file