class_docstr: 用来初始化 `Driver` 的基类，所有定制的 `driver` 都需要继承此类；
  **fastNLP** 提供的 driver 实例都会同时被 :class:`~fastNLP.core.controllers.Trainer` 和 :class:`~fastNLP.core.controllers.Evaluator` 调用。
  
  :param model: 训练或者评测的模型，需要注意该模型可能为用户已经使用类似 :class:`torch.nn.DataParallel` 或者
      :class:`torch.nn.parallel.DistributedDataParallel` 包裹过的模型。
class_docstr_tok: ["\u7528\u6765\u521d\u59cb\u5316","`","Driver","`","\u7684\u57fa\u7c7b\uff0c\u6240\u6709\u5b9a\u5236\u7684","`","driver","`","\u90fd\u9700\u8981\u7ee7\u627f\u6b64\u7c7b\uff1b","*","*","fastNLP","*","*","\u63d0\u4f9b\u7684","driver","\u5b9e\u4f8b\u90fd\u4f1a\u540c\u65f6\u88ab",":","class",":","`","~fastNLP.core.controllers.Trainer","`","\u548c",":","class",":","`","~fastNLP.core.controllers.Evaluator","`","\u8c03\u7528\u3002",":","param","model",":","\u8bad\u7ec3\u6216\u8005\u8bc4\u6d4b\u7684\u6a21\u578b\uff0c\u9700\u8981\u6ce8\u610f\u8be5\u6a21\u578b\u53ef\u80fd\u4e3a\u7528\u6237\u5df2\u7ecf\u4f7f\u7528\u7c7b\u4f3c",":","class",":","`","torch.nn.DataParallel","`","\u6216\u8005",":","class",":","`","torch.nn.parallel.DistributedDataParallel","`","\u5305\u88f9\u8fc7\u7684\u6a21\u578b\u3002"]
docstr: 根据输入的 ``dataloader`` 得到一个 支持分布式 （**distributed**） 与 可复现的 (**reproducible**) 的 dataloader。
  
  :param dataloader: 根据 ``dataloader`` 设置其对应的分布式版本以及可复现版本。
  :param dist: 应当为一个字符串，其值应当为以下之一：``[None, "dist", "unrepeatdist"]``，并且根据在 :class:`~fastNLP.core.controllers.Trainer`
      和 :class:`~fastNLP.core.controllers.Evaluator` 中 *kwargs* 的参数 ``use_dist_sampler`` 和调用时机不同，对应不同的值：
  
      * 当 ``use_dist_sampler`` 为 ``False`` ，且在 :class:`~fastNLP.core.controllers.Trainer` 或 :class:`~fastNLP.core.controllers.Evaluator`
        **初始化** 中被调用时，参数值为 ``None`` ，表示不需要考虑当前 ``dataloader`` 切换为分布式状态；
      * 当 ``use_dist_sampler`` 为 ``True`` ，且在 :class:`~fastNLP.core.controllers.Trainer` **初始化** 中被调用时，参数值为 ``"dist"`` ，表示该
        ``dataloader`` 应该保证每个 gpu 上返回的 batch 的数量是一样多的，允许出现少量 sample 在不同 gpu 上出现重复；
      * 当 ``use_dist_sampler`` 为 ``True`` ，且在 :class:`~fastNLP.core.controllers.Evaluator` **初始化** 中被调用时，参数值为 ``"unrepeatdist"`` ，
        表示该 ``dataloader`` 应该保证所有 gpu 上迭代出来的数据合并起来应该刚好等于原始的数据，允许不同 gpu 上 batch 的数量不一致；
      * 当 **断点重训加载** 中调用 :meth:`load_checkpoint` 时，该函数也会被调用，且 ``dist`` 值为 :class:`~fastNLP.core.samplers.ReproducibleSampler`
        或 :class:`~fastNLP.core.samplers.ReproducibleBatchSampler` ，此时表示需要用 ``dist`` 代表的 sampler 或 batch_sampler 重新实例化一个新的 dataloader；
  
  :param reproducible: 如果为 ``False``，不要做任何考虑；如果为 ``True``，需要保证返回的 dataloader 可以保存当前的迭代状态，使得
      该状态可以加载到一个全新的 dataloader 中然后恢复其状态。
  :return: 应当返回一个被替换 sampler 后的 **新的** dataloader 对象 (注意此处一定需要返回一个新的 dataloader 对象) ；此外，
      如果传入的 ``dataloader`` 中是 :class:`~fastNLP.core.samplers.ReproducibleSampler` 或者 :class:`~fastNLP.core.samplers.ReproducibleBatchSampler`
      需要 **重新初始化** 一个放入返回的 dataloader 中。如果 ``dist`` 为空，且 ``reproducible`` 为 ``False``，可直接返回原对象。
docstr_tok: ["\u6839\u636e\u8f93\u5165\u7684","``","dataloader","``","\u5f97\u5230\u4e00\u4e2a","\u652f\u6301\u5206\u5e03\u5f0f","\uff08","*","*","distributed","*","*","\uff09","\u4e0e","\u53ef\u590d\u73b0\u7684","(","*","*","reproducible","*","*",")","\u7684","dataloader\u3002",":","param","dataloader",":","\u6839\u636e","``","dataloader","``","\u8bbe\u7f6e\u5176\u5bf9\u5e94\u7684\u5206\u5e03\u5f0f\u7248\u672c\u4ee5\u53ca\u53ef\u590d\u73b0\u7248\u672c\u3002",":","param","dist",":","\u5e94\u5f53\u4e3a\u4e00\u4e2a\u5b57\u7b26\u4e32\uff0c\u5176\u503c\u5e94\u5f53\u4e3a\u4ee5\u4e0b\u4e4b\u4e00\uff1a","``","[","None",",","``","dist","''",",","``","unrepeatdist","''","]","``","\uff0c\u5e76\u4e14\u6839\u636e\u5728",":","class",":","`","~fastNLP.core.controllers.Trainer","`","\u548c",":","class",":","`","~fastNLP.core.controllers.Evaluator","`","\u4e2d","*","kwargs","*","\u7684\u53c2\u6570","``","use_dist_sampler","``","\u548c\u8c03\u7528\u65f6\u673a\u4e0d\u540c\uff0c\u5bf9\u5e94\u4e0d\u540c\u7684\u503c\uff1a","*","\u5f53","``","use_dist_sampler","``","\u4e3a","``","False","``","\uff0c\u4e14\u5728",":","class",":","`","~fastNLP.core.controllers.Trainer","`","\u6216",":","class",":","`","~fastNLP.core.controllers.Evaluator","`","*","*","\u521d\u59cb\u5316","*","*","\u4e2d\u88ab\u8c03\u7528\u65f6\uff0c\u53c2\u6570\u503c\u4e3a","``","None","``","\uff0c\u8868\u793a\u4e0d\u9700\u8981\u8003\u8651\u5f53\u524d","``","dataloader","``","\u5207\u6362\u4e3a\u5206\u5e03\u5f0f\u72b6\u6001\uff1b","*","\u5f53","``","use_dist_sampler","``","\u4e3a","``","True","``","\uff0c\u4e14\u5728",":","class",":","`","~fastNLP.core.controllers.Trainer","`","*","*","\u521d\u59cb\u5316","*","*","\u4e2d\u88ab\u8c03\u7528\u65f6\uff0c\u53c2\u6570\u503c\u4e3a","``","``","dist","''","``","\uff0c\u8868\u793a\u8be5","``","dataloader","``","\u5e94\u8be5\u4fdd\u8bc1\u6bcf\u4e2a","gpu","\u4e0a\u8fd4\u56de\u7684","batch","\u7684\u6570\u91cf\u662f\u4e00\u6837\u591a\u7684\uff0c\u5141\u8bb8\u51fa\u73b0\u5c11\u91cf","sample","\u5728\u4e0d\u540c","gpu","\u4e0a\u51fa\u73b0\u91cd\u590d\uff1b","*","\u5f53","``","use_dist_sampler","``","\u4e3a","``","True","``","\uff0c\u4e14\u5728",":","class",":","`","~fastNLP.core.controllers.Evaluator","`","*","*","\u521d\u59cb\u5316","*","*","\u4e2d\u88ab\u8c03\u7528\u65f6\uff0c\u53c2\u6570\u503c\u4e3a","``","``","unrepeatdist","''","``","\uff0c","\u8868\u793a\u8be5","``","dataloader","``","\u5e94\u8be5\u4fdd\u8bc1\u6240\u6709","gpu","\u4e0a\u8fed\u4ee3\u51fa\u6765\u7684\u6570\u636e\u5408\u5e76\u8d77\u6765\u5e94\u8be5\u521a\u597d\u7b49\u4e8e\u539f\u59cb\u7684\u6570\u636e\uff0c\u5141\u8bb8\u4e0d\u540c","gpu","\u4e0a","batch","\u7684\u6570\u91cf\u4e0d\u4e00\u81f4\uff1b","*","\u5f53","*","*","\u65ad\u70b9\u91cd\u8bad\u52a0\u8f7d","*","*","\u4e2d\u8c03\u7528",":","meth",":","`","load_checkpoint","`","\u65f6\uff0c\u8be5\u51fd\u6570\u4e5f\u4f1a\u88ab\u8c03\u7528\uff0c\u4e14","``","dist","``","\u503c\u4e3a",":","class",":","`","~fastNLP.core.samplers.ReproducibleSampler","`","\u6216",":","class",":","`","~fastNLP.core.samplers.ReproducibleBatchSampler","`","\uff0c\u6b64\u65f6\u8868\u793a\u9700\u8981\u7528","``","dist","``","\u4ee3\u8868\u7684","sampler","\u6216","batch_sampler","\u91cd\u65b0\u5b9e\u4f8b\u5316\u4e00\u4e2a\u65b0\u7684","dataloader\uff1b",":","param","reproducible",":","\u5982\u679c\u4e3a","``","False","``","\uff0c\u4e0d\u8981\u505a\u4efb\u4f55\u8003\u8651\uff1b\u5982\u679c\u4e3a","``","True","``","\uff0c\u9700\u8981\u4fdd\u8bc1\u8fd4\u56de\u7684","dataloader","\u53ef\u4ee5\u4fdd\u5b58\u5f53\u524d\u7684\u8fed\u4ee3\u72b6\u6001\uff0c\u4f7f\u5f97","\u8be5\u72b6\u6001\u53ef\u4ee5\u52a0\u8f7d\u5230\u4e00\u4e2a\u5168\u65b0\u7684","dataloader","\u4e2d\u7136\u540e\u6062\u590d\u5176\u72b6\u6001\u3002",":","return",":","\u5e94\u5f53\u8fd4\u56de\u4e00\u4e2a\u88ab\u66ff\u6362","sampler","\u540e\u7684","*","*","\u65b0\u7684","*","*","dataloader","\u5bf9\u8c61","(","\u6ce8\u610f\u6b64\u5904\u4e00\u5b9a\u9700\u8981\u8fd4\u56de\u4e00\u4e2a\u65b0\u7684","dataloader","\u5bf9\u8c61",")","\uff1b\u6b64\u5916\uff0c","\u5982\u679c\u4f20\u5165\u7684","``","dataloader","``","\u4e2d\u662f",":","class",":","`","~fastNLP.core.samplers.ReproducibleSampler","`","\u6216\u8005",":","class",":","`","~fastNLP.core.samplers.ReproducibleBatchSampler","`","\u9700\u8981","*","*","\u91cd\u65b0\u521d\u59cb\u5316","*","*","\u4e00\u4e2a\u653e\u5165\u8fd4\u56de\u7684","dataloader","\u4e2d\u3002\u5982\u679c","``","dist","``","\u4e3a\u7a7a\uff0c\u4e14","``","reproducible","``","\u4e3a","``","False","``","\uff0c\u53ef\u76f4\u63a5\u8fd4\u56de\u539f\u5bf9\u8c61\u3002"]
code: def set_dist_repro_dataloader(
      self, dataloader, dist=None, reproducible: bool = False
  ):
      r"""
      根据输入的 ``dataloader`` 得到一个 支持分布式 （**distributed**） 与 可复现的 (**reproducible**) 的 dataloader。
  
      :param dataloader: 根据 ``dataloader`` 设置其对应的分布式版本以及可复现版本。
      :param dist: 应当为一个字符串，其值应当为以下之一：``[None, "dist", "unrepeatdist"]``，并且根据在 :class:`~fastNLP.core.controllers.Trainer`
          和 :class:`~fastNLP.core.controllers.Evaluator` 中 *kwargs* 的参数 ``use_dist_sampler`` 和调用时机不同，对应不同的值：
  
          * 当 ``use_dist_sampler`` 为 ``False`` ，且在 :class:`~fastNLP.core.controllers.Trainer` 或 :class:`~fastNLP.core.controllers.Evaluator`
            **初始化** 中被调用时，参数值为 ``None`` ，表示不需要考虑当前 ``dataloader`` 切换为分布式状态；
          * 当 ``use_dist_sampler`` 为 ``True`` ，且在 :class:`~fastNLP.core.controllers.Trainer` **初始化** 中被调用时，参数值为 ``"dist"`` ，表示该
            ``dataloader`` 应该保证每个 gpu 上返回的 batch 的数量是一样多的，允许出现少量 sample 在不同 gpu 上出现重复；
          * 当 ``use_dist_sampler`` 为 ``True`` ，且在 :class:`~fastNLP.core.controllers.Evaluator` **初始化** 中被调用时，参数值为 ``"unrepeatdist"`` ，
            表示该 ``dataloader`` 应该保证所有 gpu 上迭代出来的数据合并起来应该刚好等于原始的数据，允许不同 gpu 上 batch 的数量不一致；
          * 当 **断点重训加载** 中调用 :meth:`load_checkpoint` 时，该函数也会被调用，且 ``dist`` 值为 :class:`~fastNLP.core.samplers.ReproducibleSampler`
            或 :class:`~fastNLP.core.samplers.ReproducibleBatchSampler` ，此时表示需要用 ``dist`` 代表的 sampler 或 batch_sampler 重新实例化一个新的 dataloader；
  
      :param reproducible: 如果为 ``False``，不要做任何考虑；如果为 ``True``，需要保证返回的 dataloader 可以保存当前的迭代状态，使得
          该状态可以加载到一个全新的 dataloader 中然后恢复其状态。
      :return: 应当返回一个被替换 sampler 后的 **新的** dataloader 对象 (注意此处一定需要返回一个新的 dataloader 对象) ；此外，
          如果传入的 ``dataloader`` 中是 :class:`~fastNLP.core.samplers.ReproducibleSampler` 或者 :class:`~fastNLP.core.samplers.ReproducibleBatchSampler`
          需要 **重新初始化** 一个放入返回的 dataloader 中。如果 ``dist`` 为空，且 ``reproducible`` 为 ``False``，可直接返回原对象。
      """
      if dist is None and reproducible is False:
          return dataloader
      raise NotImplementedError(
          f"Driver:{self.__class__.__name__} does not support `set_dist_repro_dataloader` "
          f"function."
      )
  
imports: import os
  import signal
  import sys
  from typing import Sequence, List, Optional, Callable, Dict, Union, Tuple
  from abc import ABC, abstractmethod
  from datetime import datetime
  from pathlib import Path
  from io import BytesIO
  import json
  from fastNLP.core.utils import nullcontext
label_desc: Use image node_id 3 for calling the Driver obj's underlying member method code with example usage: obj.set_dist_repro_dataloader(dataloader, dist, reproducible) and returns: dataloader