class_docstr: :param model: 训练使用的模型。
  
      * 如果不想自己初始化分布式环境，类型应为 :class:`paddle.nn.Layer`；
      * 如果已经在外面初始化了分布式环境，类型应为 :class:`paddle.DataParallel`；
  
  :param parallel_device: 多卡训练时使用的设备，必须是一个列表。
      当使用 ``python -m paddle.distributed.launch`` 启动时，该参数无效。
  :param is_pull_by_paddle_run: 标记当前进程是否为通过 ``python -m paddle.distributed.launch`` 启动的。
      这个参数仅在 :class:`~fastNLP.core.Trainer` 中初始化 driver 时使用
  :param fp16: 是否开启混合精度训练
  :param paddle_kwargs:
      * *fleet_kwargs* -- 用于在使用 ``PaddleFleetDriver`` 时指定 ``DataParallel`` 和 ``fleet`` 初始化时的参数，包括：
          
          * *is_collective* -- 是否使用 paddle 集群式的分布式训练方法，目前仅支持为 ``True`` 的情况。
          * *role_maker* -- 初始化 ``fleet`` 分布式训练 API 时使用的 ``RoleMaker``。
          * 其它用于初始化 ``DataParallel`` 的参数。
      * *gradscaler_kwargs* -- 用于 ``fp16=True`` 时，提供给 :class:`paddle.amp.GradScaler` 的参数
  
  :kwargs:
      * *wo_auto_param_call* (``bool``) -- 是否关闭在训练时调用我们的 ``auto_param_call`` 函数来自动匹配 batch 和前向函数的参数的行为
  
      .. note::
  
          关于该参数的详细说明，请参见 :class:`~fastNLP.core.controllers.Trainer` 中的描述；函数 ``auto_param_call`` 详见 :func:`fastNLP.core.utils.auto_param_call`。
code: def __init__(
      self,
      model,
      parallel_device: Optional[Union[List[str], str]],
      is_pull_by_paddle_run: bool = False,
      fp16: bool = False,
      paddle_kwargs: Dict = None,
      **kwargs,
  ):
      if USER_CUDA_VISIBLE_DEVICES not in os.environ:
          raise RuntimeError(
              "To run paddle distributed training, please set `FASTNLP_BACKEND` to 'paddle' before using fastNLP."
          )
      super(PaddleFleetDriver, self).__init__(
          model, fp16=fp16, paddle_kwargs=paddle_kwargs, **kwargs
      )
  
      # 如果不是通过 launch 启动，要求用户必须传入 parallel_device
      if not is_pull_by_paddle_run:
          if parallel_device is None:
              raise ValueError(
                  "Parameter `parallel_device` can not be None when using `PaddleFleetDriver`. This error is caused "
                  "when your value of parameter `device` is `None` in your `Trainer` instance."
              )
          if not isinstance(parallel_device, List):
              raise ValueError(
                  "Parameter `parallel_device`'s type must be List when using `PaddleFleetDriver`, "
                  f"not {type(parallel_device)}."
              )
          if get_paddle_device_id(parallel_device[0]) != 0:
              raise ValueError(
                  "The first device of `parallel_device` must be 'gpu:0' in fastNLP."
              )
  
      # 如果用户自己初始化了 paddle 的分布式训练那么一定是通过 launch 拉起的
      # 这个参数会在 initialize_paddle_drvier 中设置。
      self.is_pull_by_paddle_run = is_pull_by_paddle_run
      self.parallel_device = parallel_device
      # 在初始化时，如果发现 is_pull_by_paddle_run ，则将 parallel_device 设置成当前进程的gpu
      if is_pull_by_paddle_run:
          self.model_device = parallel_device
      else:
          self.model_device = parallel_device[self.local_rank]
  
      # 如果用户自己在外面初始化了并行模型；
      self.outside_fleet = False
      if (
          parallel_helper._is_parallel_ctx_initialized()
          and FASTNLP_DISTRIBUTED_CHECK not in os.environ
          and "fastnlp_paddle_launch_not_fleet" not in os.environ
      ):
          # 如果用户自己在外面初始化了 Fleet，那么我们要求用户传入的模型一定是已经由 DistributedDataParallel 包裹后的模型；
          if not isinstance(model, DataParallel):
              raise RuntimeError(
                  "It is not allowed to input a normal model instead of `paddle.DataParallel` when"
                  "you initialize the paddle distribued process out of our control."
              )
  
          self.outside_fleet = True
  
      self.world_size = None
      self.global_rank = 0
      self.gloo_rendezvous_dir = None
  
      self._fleet_kwargs = self._paddle_kwargs.get("fleet_kwargs", {})
      check_user_specific_params(
          self._fleet_kwargs,
          DataParallel.__init__,
          DataParallel.__name__,
      )
      # fleet.init 中对于分布式策略的设置，详情可以参考 PaddlePaddle 的官方文档
      self.strategy = self._fleet_kwargs.get(
          "strategy", fleet.DistributedStrategy()
      )
      self.is_collective = self._fleet_kwargs.pop("is_collective", True)
      if not self.is_collective:
          raise NotImplementedError(
              "fastNLP only support `collective` for distributed training now."
          )
      self.role_maker = self._fleet_kwargs.pop("role_maker", None)
  
      self.output_from_new_proc = kwargs.get(
          "output_from_new_proc", "only_error"
      )
      assert isinstance(
          self.output_from_new_proc, str
      ), "Parameter `output_from_new_proc` can only be `str` type."
      if self.output_from_new_proc not in {
          "all",
          "ignore",
          "only_error",
      }:
          os.makedirs(name=self.output_from_new_proc, exist_ok=True)
          self.output_from_new_proc = os.path.abspath(
              self.output_from_new_proc
          )
  
      self._has_setup = (
          False  # 设置这一参数是因为 evaluator 中也会进行 setup 操作，但是显然是不需要的也不应该的；
      )
      self._has_fleetwrapped = False
  
imports: import os
  from typing import List, Union, Optional, Dict, Tuple, Callable
  from .paddle_driver import PaddleDriver
  from .fleet_launcher import FleetLauncher
  from .utils import _FleetWrappingModel, replace_sampler, replace_batch_sampler, _check_dataloader_args_for_distributed
  from .dist_utils import fastnlp_paddle_all_gather, fastnlp_paddle_broadcast_object
  from fastNLP.envs.imports import _NEED_IMPORT_PADDLE
  from fastNLP.core.utils import auto_param_call, check_user_specific_params, is_in_paddle_dist, get_paddle_device_id
  from fastNLP.core.utils.paddle_utils import _convert_data_device
  from fastNLP.envs.distributed import rank_zero_rm
  from fastNLP.core.samplers import ReproduceBatchSampler, ReproducibleSampler, ReproducibleBatchSampler, RandomSampler, UnrepeatedSampler, UnrepeatedSequentialSampler, re_instantiate_sampler, conversion_between_reproducible_and_unrepeated_sampler
  from fastNLP.envs.env import FASTNLP_DISTRIBUTED_CHECK, FASTNLP_GLOBAL_SEED, FASTNLP_NO_SYNC, USER_CUDA_VISIBLE_DEVICES
  from fastNLP.core.log import logger
label_desc: Use image node_id 1 to create a new PaddleFleetDriver object from inherited base classes: PaddleDriver with example: obj = PaddleFleetDriver(model, parallel_device, is_pull_by_paddle_run, fp16, paddle_kwargs)