一、Trainer

  1. Trainer 类提供了一个 API,用于在 PyTorch 中对大多数标准的 use case 进行 feature-complete training 。在实例化 Trainer 之前,请创建一个 TrainingArguments。该 API 支持在多个GPU/TPU 上进行分布式训练、也支持通过 NVIDIA ApexNative AMP 从而针对 PyTorch 的混合精度训练。

  2. Trainer 类包含 basic training loop 。为了注入自定义行为,你可以对 Trainer进行子类化,并重写以下方法:

    下面是一个对 Trainer 子类化的例子,其中使用一个带权重的损失函数:

    对于 PyTorch,另一种定制化 training loop 行为的方法是采用 callbacks,它可以检查 training loop state (用于进度报告、向 TensorBoard 写日志)并作出决定(如 early stopping )。

  3. Trainer 类是针对 Transformers 模型进行了优化。如果你在其他模型上使用 Trainer,可能会有意想不到的行为。当你在其他模型上使用时,要确保:

    • 你的模型总是返回元组、或者 ModelOutput 的子类。
    • 如果提供了一个 labels 参数,那么你的模型可以计算损失,并且该损失作为元组的第一个元素被模型返回(如果你的模型返回元组)。
    • 你的模型可以接受多个 label 参数(使用 TrainingArguments 中的 label_names 来向 Trainer 指定它们的名称),但是它们全都不应该被命名为 "label"

1.1 API

a. TrainingArguments

  1. class transformers.TrainingArguments:用于 Trainer 的参数(和 training loop 相关)。

    通过使用 class transformers.HfArgumentParser,我们可以将 TrainingArguments 实例转换为 argparse 参数(可以在命令行中指定)。

    参数:

    • output_dir:一个字符串,指定 model predictionmodel checkpoint 输出的目录。

    • overwrite_output_dir:一个布尔值,如果为 True 则覆盖 output_dir 的内容。如果 output_dir 指向一个 checkpoint 目录,则使用该参数来继续训练。

    • do_train:一个布尔值,指定是否执行训练。该参数不是由 Trainer 直接使用,而是由你的 training/evaluation 脚本来使用。

    • do_eval:一个布尔值,指定是否在验证集上执行评估。如果 evaluation_strategy 不是 "no",那么该参数将被设置为 True 。该参数不是由 Trainer 直接使用,而是由你的 training/evaluation 脚本来使用。

    • do_predict:一个布尔值,指定是否在测试集上执行预测。如果 evaluation_strategy 不是 "no",那么该参数将被设置为 True 。该参数不是由 Trainer 直接使用,而是由你的 training/evaluation 脚本来使用。

    • evaluation_strategy:一个字符串、或 IntervalStrategy ,指定训练过程中要采用的评估策略。可以为:

      • "no":训练期间不进行评估。
      • "steps":每隔 eval_steps 训练步进行评估(并且记录日志)。
      • "epoch":在每个 epoch 结束时进行评估。
    • prediction_loss_only:一个布尔值,指定当执行评估和生成预测时是否仅返回 loss

    • per_device_train_batch_size:一个整数,指定用于训练的每个 GPU/TPU core/CPUbatch size

    • per_device_eval_batch_size:一个整数,指定用于评估的每个 GPU/TPU core/CPUbatch size

    • gradient_accumulation_steps:一个整数,指定在进行反向传播(即,梯度更新)之前,用于累积梯度的 updates steps 的数量。当使用 gradient accumulation,一个 step 指的是执行一次反向传播。因此,logging, evaluation, save 将在每隔 gradient_accumulation_steps * xxx_step 的训练样本之后进行。

      它相当于扩大了 batch size

    • eval_accumulation_steps:一个整数,指定在将结果移动到 CPU 之前,对输出张量进行累积的 predictions steps 的数量。如果未设置,则整个预测结果在移动到 CPU 之前会在 GPU/TPU 上累积(速度更快,但是需要更多的显存)。

    • eval_delay:一个浮点数,指定在执行第一次评估之前需要等待多少个 epochssteps(根据 evaluation_strategy 的不同来选择 epochssteps)。

    • learning_rate:一个浮点数,指定 AdamW 优化器的初始学习率。

    • weight_decay:一个浮点数,指定 AdamW 优化器中适用于所有层的权重衰减,除了所有的 bias、以及 LayerNorm weights

    • adam_beta1:一个浮点数,指定 AdamW 优化器的 beta1 超参数。

    • adam_beta2:一个浮点数,指定 AdamW 优化器的 beta2 超参数。

    • adam_epsilon:一个浮点数,指定 AdamW 优化器的 epsilon 超参数。

    • max_grad_norm:一个浮点数,指定最大梯度范数(用于梯度裁剪)。

    • num_train_epochs:一个浮点数,指定训练的 epoch 数量。如果不是整数,那么在停止训练之前执行最后一个 epoch 的小数部分的百分比。

    • max_steps:一个整数,如果设置为正数,则指定训练的 step 总数,它会覆盖 num_train_epochs 。如果使用有限的可迭代数据集,那么当所有数据耗尽时,可能会在 max_steps 之前就结束训练。

    • lr_scheduler_type:一个字符串或 SchedulerType,指定学习率调度器的类型。

    • warmup_ratio:一个浮点数,指定从 0 到峰值学习率(通常就是 learning_rate 指定的)的线性预热所使用的训练步占 total training steps 的比例。

    • warmup_steps:一个浮点数,指定从 0 到峰值学习率(通常就是 learning_rate 指定的)的线性预热所使用的训练步的数量。它覆盖 warmup_ratio

    • log_level:一个字符串,指定主进程中使用的 logger log level 。可以为:'debug', 'info', 'warning', 'error', 'critical', 'passive' 。其中 'passive' 表示不设置任何级别而是让 application 来设置。

    • log_level_replica:一个字符串,指定在副本进程中使用的 logger log level 。参考 log_level

    • log_on_each_node:一个布尔值,指定在多节点分布式训练中,是否在每个节点使用 log_levellog、或者仅在主节点上 log

    • logging_dir:一个字符串,指定 TensorBoard log 目录,默认为 output_dir/runs/CURRENT_DATETIME_HOSTNAME

    • logging_strategy:一个字符串或 IntervalStrategy,指定训练期间的 logging 策略。可以为:

      • "no":不做任何 logging
      • "epoch":在每个 epoch 结束时 logging
      • "steps":每隔 logging_stepslogging
    • logging_first_step:一个布尔值,指定是否 logevaluate 第一个 global_step

    • logging_steps:一个整数,指定当 logging_strategy="steps" 时每两次 logging 之间的 update steps 数量。

    • logging_nan_inf_filter:一个布尔值,指定是否要过滤 naninf 的损失从而用于 logging 。如果为 True,那么每个 stepnaninf 的损失都会被过滤掉从而仅选取当前 logging window 的平均损失。

      注意,该参数仅影响 logging,不影响梯度的计算或模型的预测。

    • save_strategy:一个字符串或 IntervalStrategy,指定训练时采用的 checkpoint save 策略。可以为:

      • "no":不做保存。
      • "epoch":在每个 epoch 结束时保存。
      • "steps":每隔 save_steps 就保存。
    • save_steps:一个整数,指定当 save_strategy="steps" 时每两次 checkpoint save 之间的 update steps 数量。

    • save_total_limit:一个整数,如果传入一个值,那么指定 checkpoint 总的保存数量。这可能会删除 output_dir 中的 older checkpoints

    • save_on_each_node:一个布尔值,指定当进行多节点分布式训练时,是否在每个节点上保存模型和 checkpoint、还是仅在主节点上保存。

      当不同的节点使用相同的 storage 时,这个能力应该禁用,因为每个节点的文件都将被保存为相同的名称。

    • no_cuda:一个布尔值,指定是否禁用 CUDA

    • seed:一个整数,指定随机数种子,它在训练开始时设置。

      为了确保不同运行的可重复性,如果模型有一些随机初始化的参数,请使用 Trainer.model_init() 函数将模型其实例化。

    • data_seed:一个整数,指定用于 data samplers 的随机数种子。如果未设置,数据采样的随机数生成器将使用与 seed 相同的种子。这可以用来确保数据采样的可重复性,与 model seed 无关。

    • jit_mode_eval:一个布尔值,指定是否使用 PyTorch jit trace 进行推断。

    • use_ipex:一个布尔值,指定当 Intel extension for PyTorch: IPEX 可用时是否使用 IPEX。如果启用,则要求安装 IPEX

    • bf16:一个布尔值,指定是否使用 bf1616 位(混合)精度训练,而不是 fp3232 位训练。需要 Ampere 或更高的 NVIDIA 架构、或使用 CPUno_cuda)。这是一个实验性的API,它可能会发生变化。

    • fp16:一个布尔值,指定是否使用 fp1616位(混合)精度训练而不是 fp3232 位训练。

    • fp16_opt_level:一个字符串,指定 Apex AMP 优化等级('O0', 'O1', 'O2', 'O3)从而用于 fp16 训练。

    • fp16_backend:目前已被废弃,建议使用 half_precision_backend

    • half_precision_backend:一个字符串,指定 用于混合精度训练的后端。必须是 "auto", "cuda_amp", "apex", "cpu_amp"中的一个。"auto" 将根据检测到的 PyTorch 版本使用 CPU/CUDA AMPAPEX ,而其他选择将强制使用所对应的后端。

    • bf16_full_eval:一个布尔值,指定是否使用 full bfloat16 评估,而不是使用 fp3232 位进行评估。这将会更快并节省内存,但会损害评估指标。这是一个实验性的 API,它可能会改变。

    • f16_full_eval:一个布尔值,指定是否使用 full float16 评估,而不是使用 fp3232 位进行评估。这将会更快并节省内存,但会损害评估指标。

    • tf32:一个布尔值,指定是否启用 TF32 模式,在 Ampere 和较新的GPU架构中可用。默认值取决于 PyTorchtorch.backends.cuda.matmul.allow_tf32 的默认版本。这是一个实验性的 API ,它可能会改变。

    • local_rank:一个整数,指定分布式训练中进程的 rank

    • xpu_backend:一个字符串,指定 xpu 分布式训练要使用的后端。必须是 "mpi", "ccl", "gloo" 中的一个。

    • dataloader_drop_last:一个布尔值,指定是否放弃最后一个 incomplete batch (如果数据集的长度不能被 batch size 所整除)。

    • eval_steps:一个整数,指定如果 evaluation_strategy="steps" 则两次评估之间的 update steps 的数量。如果没有设置,将默认为与 logging_steps 相同。

    • dataloader_num_workers:一个整数,指定用于加载数据集的子进程的数量(仅限 PyTorch )。0表示数据将在主进程中加载。

    • past_index:一个整数,有些模型如 TransformerXLXLNet 可以利用 past hidden states 进行预测。如果这个参数被设置为一个正整数,训练器将使用相应的输出(通常是 index 2 )作为 past state ,并在下一个 training step 中根据关键字参数ems 将其馈入模型。

    • run_name:一个字符串,指定一个当前 run 的描述文本,通常用于 wandbmlflow 日志。

    • disable_tqdm:一个布尔值,指定是否禁用 tqdm 进度条和 table of metrics

      如果 logging level 被设置为 warn 或更低(默认),将默认为True,否则为False

    • remove_unused_columns:一个布尔值,指定是否自动删除未被使用的列(指的是在模型的前向传播中未被使用)。

      注意,这个行为尚未在 TFTrainer 中实现。

    • label_names:一个关于字符串的列表,指定 inputs 的字典中对应于 label 的键的列表。

      默认值是 ["labels"],但是如果是 XxxForQuestionAnswering 模型则默认值是 ["start_positions", "end_positions"]

    • load_best_model_at_end:一个布尔值,指定是否在训练结束时加载训练中发现的最佳模型。

      如果是 True ,那么 save_strategy 需要和 evaluation_strategy 相同;并且如果 save_strategyevaluation_strategy 都是 "step",那么 save_steps 必须是 eval_steps 的整数倍。

    • metric_for_best_model:一个字符串,指定评估最佳模型的指标,与 load_best_model_at_end 配合使用。

      它必须是模型评估所返回的指标的名字。如果 load_best_model_at_end=True 且该参数未指定,则默认为 "loss"

      注意,greater_is_better 默认为 True;如果评估指标越低越好,则需要将 greater_is_better 设置为 False

    • greater_is_better:一个布尔值,指定更好的模型是否具有更大的指标值,与 load_best_model_at_endmetric_for_best_model 一起使用。

      如果 metric_for_best_model 被设置为既不是 "loss" 也不是 "eval_loss",那么默认为 True ;如果 metric_for_best_model 没有被设置、或者是 "loss"、或者是 "eval_loss",那么默认为 False

    • ignore_data_skip:一个布尔值,指定在恢复训练时,是否跳过 epochsbatches 从而获得与 previous training 相同阶段的 data loading 。如果设置为 True ,训练将更快开始(因为 skipping step 可能需要很长时间),但不会产生与被中断的训练相同的结果。

    • sharded_ddp:一个布尔值或字符串或关于 ShardedDDPOption 的列表,指定使用来自 FairScaleSharded DDP 训练(仅在分布式训练中)。这是一个实验性的功能。可选的参数为:

      • "simple" :使用由 fairscale 发布的 sharded DDP 的第一个实例(ShardedDDP),类似于 ZeRO-2
      • "zero_dp_2":以 Zero-2 (采用 reshard_after_forward=False )使用由 fairscale 发布的 sharded DDP 的第二个实例(FullyShardedDDP)。
      • "zero_dp_3":以 Zero-3 (采用 reshard_after_forward=True )使用由 fairscale 发布的 sharded DDP 的第二个实例(FullyShardedDDP)。
      • "offload":添加 ZeRO-offload (只与 "zero_dp_2""zero_dp_3" 兼容)。

      如果传递的是一个字符串,它将在空格处被拆分。如果传递的是一个布尔值,如果是 True 则代表 ["simple"],如果是 False 则代表 []

    • fsdp:一个布尔值或字符串或关于FSDPOption 的列表,指定使用 PyTorch Distributed Parallel Training 训练(仅在分布式训练中)。可选的参数为:

      • "full_shard":对 parameters, gradients, optimizer states 进行分片。
      • "shard_grad_op":对 optimizer states, gradients 进行分片。
      • "offload":将 parameters, gradients 卸载到 CPU (仅与 "full_shard", "shard_grad_op" 兼容)。
      • "auto_wrap":使用 default_auto_wrap_policy 从而利用 FSDP 来自动递归地 wrap layers
    • fsdp_min_num_params:一个整数,指定 FSDP 的默认的最少的 parameters 数量从而用于 Default Auto Wrapping 。仅当 fsdp 参数有效时 fsdp_min_num_params 才有意义。

    • deepspeed:一个字符串或字典,指定使用 Deepspeed

      这是一个实验性的功能,其 API 可能会在未来演变。该值是 DeepSpeed json 配置文件的位置(例如 ds_config.json )或者是一个代表已加载 json 文件的字典。

    • label_smoothing_factor:一个浮点数,指定 label smoothing 因子。零代表没有标签平滑。

      否则, label 0 变成:label_smoothing_factor/num_labelslabel 1 变成 1 - label_smoothing_factor + label_smoothing_factor/num_labels

    • debug:一个字符串或者关于 DebugOption 的列表,指定启用一个或多个 debug 特性。这是一个实验性的功能。可选的参数有:

      • "underflow_overflow":检测模型的 input/outputs 中的溢出,并报告导致该事件的最后一帧。
      • "tpu_metrics_debug":打印 TPU 的调试指标。

      如果是字符串,那么用空格拆分。

    • optim:一个字符串或者 training_args.OptimizerNames,指定使用的优化器。可以为:adamw_hf, adamw_torch, adamw_apex_fused, adamw_anyprecision, adafactor

    • optim_args:一个字符串,指定提供给 AnyPrecisionAdamW 的可选参数。

    • adafactor:被废弃,推荐使用 optim="adafactor" 来代替。

    • group_by_length:一个布尔值,指定是否将训练数据集中长度大致相同的样本分组(从而尽量减少填充的使用,使之更有效)。只有在应用动态填充时才有用。

    • length_column_name:一个字符串,指定预计算的长度的列名。如果该列存在,group_by_length 将使用这些值,而不是在训练启动时计算它们。除非 group_by_lengt = True 并且数据集是 Dataset 的一个实例,否则会被忽略。

    • report_to:一个字符串或关于字符串的列表,指定要报告结果和日志的集成商的列表。支持的集成商有:"azure_ml", "comet_ml", "mlflow", "neptune", "tensorboard","clearml", "wandb""all" 表示报告所有的集成商;"none" 表示都不报告。

    • ddp_find_unused_parameters:一个布尔值,指定当使用分布式训练时,传递给 DistributedDataParallelfind_unused_parameters 的值。

      如果使用 gradient checkpointing,那么默认值为 False;否则默认值为 True

    • ddp_bucket_cap_mb:一个整数,指定当使用分布式训练时,传递给 DistributedDataParallelbucket_cap_mb 的值。

    • dataloader_pin_memory:一个布尔值,指定在 data loaders 中是否要 pin memory

    • skip_memory_metrics:一个布尔值,指定是否跳过向 metrics 添加 memory profiler 报告。默认情况下跳过(即,True),因为这会减慢训练和评估的速度。

    • push_to_hub:一个布尔值,指定每次保存模型时是否将模型推送到 Hub

      如果为 Trueoutput_dir 是一个 git 目录(这个 git 目录与 repo 同步),目录内容将在每次触发保存时被推送(取决于你的 save_strategy )。调用 save_model()也会触发一次推送。 如果 output_dir 存在,则该目录必须是 repo 的一个 local clone ,这个 repo 就是 Trainer 将被推送到的地方。

    • resume_from_checkpoint:一个字符串,指定有效 checkpoint 的文件夹的路径。

      这个参数不直接被 Trainer 使用,而是由 training/evaluation 脚本使用。

    • hub_model_id:一个字符串,指定 repo 的名字从而与 local output_dir 保持同步。默认为 output_dir 的名称。

    • hub_strategy:一个字符串或 HubStrategy,指定推送到 Hub 的范围和时间。可以为:

      • "end":在调用 save_model() 方法时,推送模型、模型配置、tokenizer (如果传递给 Trainer )和模型卡的草稿。
      • "every_save":每次有模型保存时,推送模型、模型配置、tokenizer (如果传递给 Trainer )和模型卡的草稿。推送是异步的,从而避免阻碍训练,而且如果保存非常频繁,只有在前一次完成后才会尝试新的推送。最后一次推送是在训练结束后用最后的模型进行的。
      • "checkpoint":和 "every_save " 一样,但最 latest checkpoint 也会被推送到一个名为 last-checkpoint 的子文件夹中,这样你就可以用 trainer.train(resume_from_checkpoint="last-checkpoint") 轻松恢复训练。
      • "all_checkpoints":和 "checkpoint " 一样,但是所有的 checkpoint 都会被推送(所以你会在 final repo 的每个文件夹中得到一个 checkpoint 文件夹)。
    • hub_token:一个字符串,指定用来推送模型到 Hubtoken 。将默认为通过 huggingface-cli 登录获得的缓存文件夹中的token

    • hub_private_repo:一个布尔值,指定是否将 Hub repo 设为私有。

    • gradient_checkpointing:一个布尔值,指定是否使用 gradient checkpointing 来节省内存。如果为 True,则会降低反向传播的速度。

    • include_inputs_for_metrics:一个布尔值,指定 inputs 是否会被传递给 compute_metrics 函数。这适用于需要 inputspredictionsreferences 的指标的计算。

    • auto_find_batch_size:一个布尔值,指定是否通过指数衰减自动寻找适合内存的 batch size ,以避免 CUDA Out-of-Memory 的错误。需要安装 acceleratepip install accelerate )。

    • full_determinism:一个布尔值,如果为 True 则调用 enable_full_determinism() 而不是 set_seed() ,从而确保分布式训练的结果可重复。

    • torchdynamo:一个字符串,用于 TorchDynamo 的后端编译器。可以为: "eager", "aot_eager", "inductor", "nvfuser", "aot_nvfuser", "aot_cudagraphs", "ofi", "fx2trt", "onnxrt", "ipex"

    • ray_scope:一个字符串,指定使用 Ray 进行超参数搜索时使用的范围。默认情况下,将使用 "last" 。然后,Ray 将使用所有试验的最后一个 checkpoint ,比较这些 checkpoint 并选择最佳 checkpoint 。然而,也有其他选项。更多选项见 Ray 文档。

    • ddp_timeout:一个整数,指定 torch.distributed.init_process_group 调用的超时时间。

    • use_mps_device:一个布尔值,指定是否使用基于 Apple Siliconmps 设备。

    方法:

    • get_process_log_level():返回 log level ,具体结果取决于是否是 node 0 的主进程、node non-0 的主进程、以及非主进程。

      • 对于主进程, log level 默认为 logging.INFO ,除非被 log_level 参数覆盖。
      • 对于非主进程,除非被 log_level_replica 参数覆盖,否则 log level 默认为 logging.warning

      主进程和非主进程的 setting 是根据 should_log 的返回值进行选择的。

    • get_warmup_steps( num_training_steps: int):返回用于线性预热的 step 数量。

    • main_process_first(local = True, desc = 'work' ):一个用于 Torch 分布式环境的上下文管理器,它需要在主进程上做一些事情,同时 block 副本,当它完成后再 release 副本。

      其中一个用途是数据集的 map 特性:为了提高效率,应该在主进程上运行一次,完成后保存一个 cached 版本数据集的结果,然后由副本自动加载。

      参数:

      • local:一个布尔值,如果为 True 则表示 first 是每个节点的 rakn 0 进程;如果为 False 则表示 firstnode rank 0rank 0 进程。

        在共享文件系统的多节点环境中,你很可能想使用 local=False ,这样只有第一个节点的主进程会进行处理。然而,如果文件系统不是共享的,那么每个节点的主进程将需要做处理,这是默认行为(即,默认为 True)。

      • desc:一个字符串,指定 work 描述文本从而用于调试日志。

    • to_dict():序列化该实例到一个字典,同时用枚举的值来代替 Enum 对象。

    • to_json_string():序列化该实例到一个 json 字符串。

    • to_sanitized_dict():采用 TensorBoardhparams 来序列化该实例。

  2. class transformers.Seq2SeqTrainingArguments

    参数:

    • sortish_sampler:一个布尔值,指定是否使用 sortish 采样器。目前只有在底层数据集是 Seq2SeqDataset 的情况下才有可能,但在不久的将来会变得普遍可用。 它根据长度对输入进行排序从而最小化 padding 的大小,其中对训练集有一点随机性。
    • predict_with_generate:一个布尔值,指定是否使用 generate 来计算生成指标(ROUGE, BLEU )。
    • generation_max_length:一个整数,指定当 predict_with_generate=True 时,在每个 evaluation loop 中使用的最大长度。默认为模型配置的 max_length 值。
    • generation_num_beams:一个布尔值,指定当 predict_with_generate=True 时,在每个 evaluation loop 使用的 beams 数量。将默认为模型配置中的 num_beams 值。

b. Trainer

  1. class transformers.TrainerTrainer 是针对 PyTorch 的一个简单的、但是特征完备 feature-completetrainingeval loop ,并且针对 Transformers 进行了优化。

    参数:

    • model:一个 PreTrainedModeltorch.nn.Module 对象,指定用于训练、评估、或预测的模型。如果未提供,则必须传入 model_init 参数。

      Trainer 被优化为与 PreTrainedModel 一起工作。但是你仍然可以使用自定义的 torch.nn.Module 的模型,只要模型的工作方式与 Transformers 模型相同。

    • args:一个 TrainingArguments,指定训练时的参数。如果未提供,则默认为 TrainingArgumentsbasic instance,其中 output_dir 设置为当前目录下叫做 tmp_trainer 的目录。

    • data_collator:一个 DataCollator,指定用于从 train_dataseteval_dataset 的元素列表中构建一个 batch 的函数。如果没有提供 tokenizer ,则默认的 DataCollatordefault_data_collator() ,否则默认的 DataCollatorDataCollatorWithPadding 的一个实例。

    • train_dataset:一个 torch.utils.data.Datasettorch.utils.data.IterableDataset,指定训练集。如果它是 HuggingFaceDataset,那么 model.forward() 方法不需要的列则会被自动移除。

      注意,如果它是一个带有一些随机性的 torch.utils.data.IterableDataset ,并且你是以分布式方式进行训练的,你的 iterable dataset 要么使用一个内部的 attribute generator ,该generator 是一个 torch.Generator 用于随机化,且在所有进程上必须是相同的(并且 Trainer 将在每个 epoch 手动设置该 generator 的种子);要么有一个 set_epoch() 方法,在该方法内部设置所用随机数生成器的种子。

    • eval_dataset:一个 torch.utils.data.Datasettorch.utils.data.IterableDataset,指定验证集。如果它是 HuggingFaceDataset,那么 model.forward() 方法不需要的列则会被自动移除。

      如果它是一个字典(键为数据集名称、值为数据集),它将在每个数据集上进行评估,并将数据集名称添加到指标名称之前作为前缀。

    • tokenizer:一个 PreTrainedTokenizerBase,指定用于预处理数据的 tokenizer 。如果提供了该参数,将用于在 batching input 时自动将 input 填充到最大长度,并且它将与模型一起保存,以便更容易重新运行中断的训练、或复用微调后的模型。

    • model_init:一个可调用对象,它实例化将要被使用的模型。如果提供的话,对 train() 的每次调用将从这个函数给出的模型的一个新实例开始。

      该函数可以有零个参数,也可以有一个包含 optuna/Ray Tune/SigOpttrial object 的单个参数,以便能够根据超参数(如层数、层的维度、dropout rate 等)选择不同的架构。该函数返回一个 PreTrainedModel 对象。

    • compute_metrics:一个可调用对象,指定评估时用来计算指标的函数。

      compute_metrics 必须接受一个 EvalPrediction ,并返回一个关于各种指标的字典。

    • callbacks:一个关于 TrainerCallback 的列表,指定用于 training loop 的自定义 callback 列表。Trainer 将把这些添加到 default callbacks 的列表中。

      如果你想删除其中一个 default callback ,请使用 Trainer.remove_callback() 方法。

    • optimizers:一个元组 Tuple[torch.optimizer, torch.optim.lr_scheduler.LambdaLR] ,指定要使用的优化器和调度器。

      默认为作用在你的模型上的 AdamW 实例、以及由 args 控制的 get_linear_schedule_with_warmup() 给出的调度器。

    • preprocess_logits_for_metrics:一个可调用对象,它在每个评估 stepcaching logits 之前对 logits 进行预处理。

      preprocess_logits_for_metrics 必须接受两个张量(即, logitslabels ),并在按需要处理后返回 logitspreprocess_logits_for_metrics 所做的修改将反映在 compute_metrics 所收到的预测结果中。 注意,如果数据集没有 labels ,则 labels 参数(元组的第二个位置)将是 None

    重要的属性:

    • model:始终指向core model 。如果使用 transformers 模型,它将是一个 PreTrainedModel 的子类。

    • model_wrapped:始终指向最外层的模型,因为有的时候有一个或多个其他模块来 wrap 原始模型。 model_wrapped 就是被用来前向传播的模型。例如,在 DeepSpeed 下,内层模型被包裹在 DeepSpeed 中、然后又被包裹在torch.nn.DistributedDataParallel 中。

      如果内层模型还没有被 wrap ,那么 self.model_wrappedself.model 是一样的。

    • is_model_parallel:一个模型是否被切换到模型并行 model parallel 模式(与数据并行 data parallelism 不同,这意味着一些 model layers 被分割到不同的GPU上)。

    • place_model_on_device: 是否自动将模型放置在设备上。如果使用模型并行或 deepspeed 则默认为 False ,或者默认的TrainingArguments.place_model_on_device 被重写为返回 False 则这里的默认值也是 False

    • is_in_train:模型当前是否正在运行训练(例如,当在训练中调用 evaluation 时)。

    方法:

    • add_callback(callback: transformer.TrainerCallback): 添加一个 callback 到当前的 transformer.TrainerCallback 列表。

      参数:callback:一个 transformer.TrainerCallback 类、或者transformer.TrainerCallback 的实例。如果是类,那么Trainer 将会实例化它。

    • autocast_smart_context_manager( cache_enabled: typing.Optional[bool] = True ):一个辅助的 wrapper,它为 autocast 创建一个适当的上下文管理器,同时根据情况给它馈入所需的参数。

      它用于混合精度训练,即 torch.cuda.amp.autocast()

    • compute_loss(model, inputs, return_outputs=False): 作为 Trainer 的计算损失的函数。默认情况下,所有的模型通过 output 返回损失(output 的第一个元素)。

    • compute_loss_context_manager():一个 helper wrapper,用于聚合针对 compute_loss 的上下文管理器(如,混合精度训练)。

    • create_model_card():创建 model card 的一个草稿。

      参数:

      • language:一个字符串,指定模型的语言。
      • license:一个字符串,指定模型的 license
      • tags:一个字符串或关于字符串的列表,指定模型卡片的 tag
      • model_name:一个字符串,指定模型的名称。
      • finetuned_from:一个字符串,指定当前模型从哪个模型微调而来。
      • tasks:一个字符串或关于字符串的列表,指定当前模型用于哪些任务。
      • dataset_tags:一个字符串或关于字符串的列表,指定数据集的 tag
      • dataset:一个字符串或关于字符串的列表,指定数据集的 identifier
      • dataset_args:一个字符串或关于字符串的列表,指定数据集参数。
    • create_optimizer():创建优化器 optimizer

      我们提供了一个合理的默认值,运行良好。如果你想使用自定义的优化器,你可以通过 optimizers 参数在 Trainerinit 方法中传递一个元组,或者在子类中重写这个方法。

    • create_optimizer_and_scheduler(num_training_steps: int ):创建优化器和学习率调度器 scheduler

      参数:num_training_steps:一个整数,指定总的 training step 数量。

      我们提供了一个合理的默认值,运行良好。如果你想使用自定义的优化器和调度器,你可以通过 optimizers 参数在 Trainerinit 方法中传递一个元组,或者在子类中重写这个方法。

    • create_scheduler( num_training_steps: int, optimizer: Optimizer = None):创建学习率调度器 scheduler

      参数:参考 create_optimizer_and_scheduler()

      我们提供了一个合理的默认值,运行良好。如果你想使用自定义的调度器,你可以通过 optimizers 参数在 Trainerinit 方法中传递一个元组,或者在子类中重写这个方法。

    • evaluate():评估模型并返回评估指标。注意,需要使用者提供一个方法来计算指标(通过 Traininginit 方法中的 compute_metrics 参数)。

      参数:

      • eval_dataset:一个 Dataset,指定验证集。如果非 None,那么它将覆盖 self.eval_dataset 。它必须实现 __len__() 方法。对于前向传播不需要的列,都会被自动移除。
      • ignore_keys:一个关于字符串的列表,指定需要忽略 model output 中的哪些 key (如果 model output 是一个字典)。
      • metric_key_prefix:一个字符串,指定添加到指标名称的前缀。默认为 eval
    • evaluation_loop()prediction/evaluationloop,由 Trainer.evaluate()Trainer.predict() 所使用。

      参数:

      • dataloader:一个 DataLoader
      • description:一个字符串,指定描述文本。
      • prediction_loss_only:一个布尔值,指定是否仅计算损失函数。
      • 其它参数参考 evaluate()
    • floating_point_ops( inputs: typing.Dict[str, typing.Union[torch.Tensor, typing.Any]] ) -> int:返回模型的浮点操作的数量。

      参数:inputs:一个字典,键为字符串、值为 torch.Tensor 或其他对象,指定模型的 inputstargets 。浮点运算数量就是在它之上统计的。

      对于继承自 PreTrainedModel 的模型,使用该方法来计算每次反向传播+前向传播的浮点运算数量。如果使用其他模型,要么在模型中实现这样的方法,要么在子类中覆盖这个方法。

    • get_eval_dataloader( eval_dataset: Optional[Dataset] = None) -> DataLoader:返回评估时的 dataloader

      参数:eval_dataset:一个 torch.utils.data.Dataset,如果提供该参数,则覆盖 self.eval_dataset 。如果它是一个 Transformer Dataset 类,那么model.forward() 不需要的列将被自动移除。

    • get_test_dataloader( test_dataset: Dataset) -> DataLoader:返回测试时的 dataloader

      参数:参考 get_eval_dataloader

    • get_train_dataloader() -> DataLoader:返回训练时的 dataloader

      如果 train_dataset 没有实现 __len__ 方法,那么将不使用 sampler;否则使用一个 random sampler (适配分布式训练,如果有必要的话)。

    • get_optimizer_cls_and_kwargs(args: TrainingArguments ) -> Tuple[Any, Any]:基于 training arguments,返回优化器的 class 和优化器的参数。

    • hyperparameter_search():使用 optunaRay TuneSigOpt 启动一个超参数搜索。

      被优化的量由 compute_objective 决定:当没有提供指标时默认为一个返回 evaluation loss 的函数;否则,为所有指标的 sum

      要使用这个方法,你需要在初始化你的 Trainer 时提供一个 model_init :我们需要在每次 new run 时重新初始化模型。这与 optimizer argument 不兼容,所以你需要对 Trainer 进行子类化,并重写 create_optimizer_and_scheduler() 方法从而用于自定义 optimizer/scheduler

      参数:

      • hp_space:一个可调用对象,它定义了超参数搜索空间。默认为 default_hp_space_optuna()default_hp_space_ray()、或 default_hp_space_sigopt(),取决于你的后端。
      • compute_objective:一个可调用对象,它计算目标的函数,这个目标就是我们需要最大化或最小化的。默认为 default_compute_objective()
      • n_trials:一个整数,指定要测试的 trial runs 的数量。
      • direction:一个字符串,指定是最大化还是最小化目标。可以为 "minimize""maximize"
      • backend:一个字符串,指定超参数搜索的后端。默认为 optunaRay Tune、或者 SigOpt ,取决于哪一个被安装。如果都安装了,那么默认为 optuna
      • hp_name:一个可调用对象,对它调用的返回值给出了 trial/run 的名称。默认为 None
      • kwargs:传递给 optuna.create_studyray.tune.run 的额外关键字参数。

      返回 trainer_utils.BestRun ,它包含 best run 的所有信息。

    • init_git_repo(at_init: bool = False):在 self.args.hub_model_id 中初始化一个 git repo

      参数:

      • at_init:一个布尔值,指定该函数是否在任何训练之前被调用。如果 self.args.overwrite_output_dir = True ,并且 at_init=True,那么 repo 的路径(也就是 self.args.output_dir )可能会被抹去。
    • is_local_process_zero() -> bool:返回当前进程是否是 local 的主进程。

      local 指的是分布式训练环境中的 local 机器。

    • is_world_process_zero() -> bool:返回当前进程是否是 global 的主进程。

      当在机台机器上执行分布式训练时,只有一个进程是 global 主进程,但是可能有多个进程是 local 主进程。

    • log( logs: Dict[str, float]):记录日志。

      参数:logs:需要被记录的内容。

    • log_metrics(split: str, metrics: Dict[str, float]):以一种特殊的格式记录指标。

      参数:

      • split:一个字符串,指定split 名称,如 trainevaltest
      • metrics:一个字典,指定需要被记录的指标值。

      注意:在分布式环境下,这只对 rank = 0 的进程进行记录。

      关于内存报告的说明:为了获得内存使用报告,你需要安装psutilpip install psutil)。然后,当 log_metrics() 运行时你将看到如下的报告:

      其中:

      • 第一个字段(如 train_)告诉你指标是针对哪个 stage 的。以init_ 开头的报告将被添加到第一个 stage 。因此,如果只运行模型评估,init_ 的内存使用量将与 eval_ 的指标一起被报告。

      • 第三个字段是 cpugpu,告诉你这是通用 RAM 指标、还是 GPU0 的内存指标。

      • alloc_deltastage 结束和 state 开始之间所使用/分配的内存计数器的差值。如果一个函数释放的内存比分配的内存更多,那么它可以是负数。

      • peaked_delta 是额外的内存,这些内存被消费然后被释放掉。它永远不会是负数。

        当你看任何 stage 的内存指标时,你把alloc_delta + peaked_delta 加起来,你就知道完成该 stage 需要多少内存了。

      报告只发生在 rank = 0 的进程、以及 gpu 0(如果有gpu)。通常这就足够了,因为主进程做了大部分工作,但如果使用模型并行,那么其他 GPU 可能会使用不同数量的 gpu 内存 。这在 DataParallel 下也是不一样的,gpu0 可能需要比其他 gpu 多得多的内存,因为它为所有参与的 GPU存储梯度和 optimizer states。也许在未来,这些报告也会发展到测量这些指标。

      CPU RAM 指标 RSS (常驻集大小Resident Set Size )包括进程特有的内存、以及与其他进程共享的内存。值得注意的是,它不包括交换出来的内存 swapped out memory ,所以报告可能不精确。

      CPU 的峰值内存是用一个采样线程测量的。由于 pythonGIL,如果该线程在最高内存使用时没有机会运行,它可能会错过一些峰值内存。因此,这个报告可能比实际情况要少。使用 tracemalloc 会报告准确的峰值内存,但它并不报告 python 以外的内存分配情况。因此,如果某个 C++ CUDA extension 分配了自己的内存,就不会被报告。因此,它被放弃了,而采用了内存采样的方法,即读取当前进程的内存使用量。

      GPU 分配的内存和峰值内存的报告是通过 torch.cuda.memory_allocated()torch.cuda.max_memory_allocated() 完成的。这个指标只报告 pytorch-specific allocation"deltas" ,因为 torch.cuda 内存管理系统并不跟踪 pytorch 以外分配的任何内存。例如,第一个 cuda 调用通常加载 CUDA kernel ,这可能需要 0.52GBGPU 内存。

      请注意,这个 tracker 并不考虑Trainer__init__ 、训练、评估、以及预测的调用之外的内存分配。

      因为 evaluation 调用可能发生在训练过程中,我们无法处理嵌套调用,因为 torch.cuda.max_memory_allocated 是一个单一的计数器,所以如果它被一个嵌套的 evaluation 调用重置,traintracker 将报告错误的信息。如果这个 pytorch 问题得到解决,就有可能把这个类改成可重入的。在那之前,我们将只追踪外层的 trainevaluationpredict 方法。这意味着如果 evaltrain 过程中被调用,那么将 train 阶段统计的内存报告其实是 eval 的。

      这也意味着,如果任何其他与 Trainer 一起使用的工具调用 torch.cuda.reset_peak_memory_statsgpu 峰值内存统计可能是无效的。而且 Trainer 会扰乱任何依赖调用 torch.cuda.reset_peak_memory_stats 的工具的正常行为。

      为了获得最佳性能,你可能要考虑在生产运行中关闭 memory profiling 功能。

    • metrics_format(metrics: Dict[str, float]) -> Dict[str, float]):格式化 Trainer 指标值到人类可阅读的格式。

      参数:metrics:一个字典,指定需要被格式化的指标值。

    • num_examples(dataloader: DataLoader) -> int:返回数据集中的样本数量。

      如果 dataloader.dataset 不存在,或者 dataloader.dataset 没有长度,那么该方法尽力估算一个数量。

    • pop_callback(callback) -> transformer.TrainerCallback:从当前的 TrainerCallback 列表中移除一个 callback 并返回它。

      参数:参考 add_callback()

    • predict(test_dataset: Dataset, ignore_keys: Optional[List[str]] = None, metric_key_prefix: str = "test") -> PredictionOutput:执行预测。

      参数:

      • test_dataset:一个 Dataset,指定测试集。
      • 其它参数参考 evaluate()

      返回一个命名元组,它包含以下字段:

      • predictions:一个 np.ndarray,包含测试集的预测结果。
      • label_ids:一个 np.ndarray,包含 labels(如果测试集有的话)。
      • metrics:一个字典,给出测试集上的预测结果的指标(如果测试集有 labels 的话)。

      如果测试集包含 labels,那么该方法也会像 evaluate() 那样返回指标。

      如果你的 predictionslabels 有不同的序列长度(例如,在 token 分类任务中做动态填充), predictions 将被填充(右填充),以允许拼接成一个数组。 padding index = -100

    • prediction_loop()prediction/evaluationloop,由 Trainer.evaluate()Trainer.predict() 所使用。

      参数:参考 evaluation_loop()

    • prediction_step():在模型上使用 inputs 执行单个 evaluation step

      参数:

      • model:一个 nn.Module 对象,指定被使用的模型。
      • inputs:一个字典,键为字符串、值为 torch.Tensor 或其他对象,指定模型的 inputstargets
      • 其它参数参考 evaluation_loop

      返回一个元组,分别为 loss, logits, labels (可能有的项没有)。

    • push_to_hub(commit_message: Optional[str] = "End of training", blocking: bool = True, **kwargs) -> str:将 self.modelself.tokenizer 上传到 model hub 上的 self.args.hub_model.id 所对应的 repo

    • remove_callback(callback):从当前的 TrainerCallback 列表中移除一个 callback

      参数:参考 add_callback()

    • save_metrics(split, metrics, combined=True):为指定的 split 保存指标到 json 文件,如 train_results.json

      参数:

      • combined:一个布尔值,指定是否创建一个汇总所有 split 的指标到 all_results.json
      • 其它参数参考 log_metrics()

      注意:在分布式环境下,这只对 rank = 0 的进程进行保存。

    • save_model(output_dir: Optional[str] = None, _internal_call: bool = False):保存模型,使得接下来可以采用 from_pretrained() 方法来加载模型。

      注意:仅仅从主进程保存;另外除了保存模型之外还会保存模型相应的 tokenizer

    • save_state():保存 Trainer state

      注意:在分布式环境下,这只对 rank = 0 的进程进行保存。

    • train():训练模型。

      参数:

      • resume_from_checkpoint:一个字符串或布尔值。

        • 如果是一个字符串,那么该字符串为 Trainer 前一个实例所保存的 checkpointlocal path 。训练将从这个 checkpoint 开始继续。
        • 如果是一个布尔值且为 True,那么加载 args.output_dir 中的最近一个 checkpoint ,该checkpointTrainer 的前一个实例保存。训练将从这个 checkpoint 开始继续。

        对于这两种情况,训练将从这里加载的 model/optimizer/scheduler states 恢复。

      • trial:一个optuna.Trial 或者字典,指定用于超参数搜索的 trial run、或超参数字典。

      • ignore_keys_for_eval:一个关于字符串的列表,指定当在训练期间进行 evaluation 时,需要忽略 model output 中的哪些 key (如果 model output 是一个字典)。

      • kwargs:关键字参数。

    • training_step( model: nn.Module, inputs: Dict[str, Union[torch.Tensor, Any]]) -> torch.Tensor :训练一个 batch

      参数:参考 prediction_step()

      返回值:这个 batch 上的训练损失。

  2. class transformers.Seq2SeqTrainer

    参数参考 class transformers.Trainer

    方法:

    • evaluate(eval_dataset: Optional[Dataset] = None, ignore_keys: Optional[List[str]] = None, metric_key_prefix: str = "eval", **gen_kwargs) -> Dict[str, float]:评估模型并返回评估指标,参考 Trainer.evaluate()

      参数:

      • max_length:一个整数,指定生成的目标序列的最大长度。
      • num_beams:一个整数,指定用于 beam searchbeam size1 意味着不使用 beam search
      • 其它参数参考 Trainer.evaluate()
    • predict(test_dataset: Dataset, ignore_keys: Optional[List[str]] = None, metric_key_prefix: str = "test", **gen_kwargs) -> PredictionOutput:执行预测,参考 Trainer.predict()

      参数:参考 evaluate()Trainer.predict()

1.2 注意事项

a. Checkpoints

  1. 默认情况下,Trainer 会将所有 checkpoints 保存在 TrainingArguments 中设置的 output_dir 。这些 checkpoints 将被放在名为 checkpoint-xxx 的子文件夹中,xxx 是训练所处的 step

    可以通过在调用 Trainer.train() 使用如下的方式,从而从 checkpoints 恢复训练:

    • resume_from_checkpoint=True:这将从 latest checkpoint 恢复训练。
    • resume_from_checkpoint=checkpoint_dir:这将从指定目录中的 specific checkpoint 恢复训练。

    此外,当使用 push_to_hub=True 时,你可以轻松地将 checkpoints 保存在 Model Hub 。默认情况下,所有保存在 intermediate checkpoints 的模型被保存在不同的 commits 中,但不包括 optimizer state 。你可以将 TrainingArgumentshub-strategy 值调整为如下两种:

    • "checkpoint"latest checkpoint 也被推送到一个名为 last-checkpoint 的子文件夹中,允许你用trainer.train(resume_from_checkpoint="output_dir/last-checkpoint") 轻松恢复训练。
    • "all_checkpoints":所有 checkpoints 都被推送到输出文件夹中(所以你会在 final repo 的每个文件夹中得到一个 checkpoint 文件夹)。

b. Logging

  1. 默认情况下,Trainer 将对主进程使用 logging.INFO 、对副本使用 logging.WARNING (如果有副本的话)。这些默认值可以通过TrainingArguments 的参数被覆盖,以使用 5logging level 中的任何一个:

    • log_level 参数:用于主进程的 logging level 设置。
    • log_level_replica 参数:用于副本进程的 logging level 设置。

    此外,如果 TrainingArgumentslog_on_each_node = False ,只有主节点会使用其主进程的 log level setting ,所有其他节点将使用副本的 log level setting

    注意,Trainer 将在其 Trainer.__init__() 中为每个节点单独设置 transformerslog level 。因此,如果你在创建 Trainer 对象之前就调用了 transformers 的函数,你可能希望在 Trainer 创建之前就为 transformers 设置 log level 。示例:

  2. 如果你只想看到主节点上的警告,而所有其他节点不打印任何很可能是重复的警告,你可以这样运行:

    在多节点环境中,如果你也不希望每个节点的主进程的日志重复,你要把上面的内容改为:

    如果你需要你的应用程序尽可能的安静,你可以这样做:

c. 随机性

  1. 当从 Trainer 生成的 checkpoint 恢复训练时,所有的努力都是为了将 python, numpy, pytorch RNG 的状态恢复到保存该 checkpoint 时的状态,这应该使 "stop and resume" 的训练方式尽可能地接近于 non-stop training

    然而,由于各种默认的 non-deterministic pytorch settings ,这可能不完全有效。如果你想要完全的确定性,请参考 https://pytorch.org/docs/stable/notes/randomness。正如文档中所解释的,那些让事情变得确定的一些settings(如 torch.backends.cudnn.deterministic )可能会让事情变慢,因此这不能在默认情况下进行。但如果需要,你可以自己启用这些settings

d. 指定 GPU

  1. 这里讨论一下:如何告诉你的程序哪些 GPU 要被使用、以及按照什么顺序来使用。

  2. 当使用 DistributedDataParallel 并且只使用 GPU 的一个子集时,你只需指定要使用的 GPU 的数量。例如,如果你有 4GPU,但你希望使用前两个,你可以这样做:

    如果你已经安装了 acceleratedeepspeed ,你也可以通过使用以下方法之一来完成同样的工作:

    你不需要使用 AccelerateDeepspeedintegration features 来使用这些 launchers

  3. 到目前为止,我们可以告诉程序要使用多少个 GPU 。现在讨论一下如何选择特定的 GPU 并控制其顺序。

    CUDA_VISIBLE_DEVICES 环境变量可以帮助你控制使用哪些GPU 、以及GPU 的顺序,方法是:将环境变量 CUDA_VISIBLE_DEVICES 设置为将要使用的 GPU 的列表。例如,假设有4GPU0, 1, 2, 3。为了只在物理 GPU 0GPU 2 上运行,你可以这样做:

    所以现在 pytorch 将只看到 2GPU ,其中你的物理 GPU 0GPU 2 分别映射到 cuda:0cuda:1

    • 你甚至可以改变它们的顺序:

      现在你的物理 GPU 0GPU 2 被映射到 cuda:1cuda:0 上。

    • 上面的例子都是针对 DistributedDataParallel 的使用模式,但同样的方法也适用于DataParallel

    • 要模拟一个没有 GPU 的环境,只需将这个环境变量设置为空值,像这样:

    • 与任何环境变量一样,你也可以导出这些环境变量,而不是将这些环境变量添加到命令行中,例如:

      但这种方法可能会让人困惑,因为你可能会忘记你之前设置的环境变量,不明白为什么会使用错误的 GPU。因此,通常的做法是在同一命令行中只为特定的运行设置环境变量。

  4. 有一个额外的环境变量 CUDA_DEVICE_ORDER 用于控制物理设备的排序方式。两个选择是:

    • 根据 PCIe 总线 ID 排序(与 nvidia-smi 的顺序一致)。这是默认的方式。

    • 根据 GPU 的计算能力排序。

    大多数情况下,你不需要关心这个环境变量。但是,假如你有一个旧且慢的 GPU 显卡、以及一个新且快的 GPU 显卡,并且不恰当的插入方式使得旧显卡看起来是第一位的,那么这个环境变量就非常有用。

    解决这个问题的方法之一是交换显卡的插入位置。或者设置 CUDA_DEVICE_ORDER=FASTEST_FIRST 将总是把较快的新卡放在第一位。不过这将会有些混乱,因为 nvidia-smi 仍然会按照 PCIe 顺序报告它们。

    交换顺序的另一个解决方案是使用:

e. Trainer 集成

  1. Trainer 已经被扩展到支持一些库,这些库可能会极大地改善你的训练时间并适应更大的模型。

    目前,它支持第三方解决方案,如 DeepSpeed, PyTorch FSDP, FairScale ,它们实现了论文 《ZeRO: Memory Optimizations Toward Training Trillion Parameter Models》 的一部分。

    截至本文写作时,这种提供的支持是新的和实验性的。虽然对 DeepSpeedPyTorch FSDP 的支持是活跃的,我们也欢迎围绕它们的问题,但我们不再支持 FairScale 的集成,因为 FairScale 已经集成到 PyTorch 主系统中。

  2. CUDA Extension 安装:截至目前,FairScaleDeepspeed 都需要编译 CUDA C++ 代码才能使用。

    虽然所有的安装问题都应该通过 FairScaleDeepspeed 的相应 GitHub issue 来处理,但在构建任何需要构建 CUDA ExtensionPyTorch extension 时,可能会遇到一些常见的问题。因此,如果你在执行如下指令时遇到了与 CUDA 相关的 build issue

    那么请阅读以下说明。在这些说明中,我们举例说明了当 pytorch 是用 CUDA 10.2 构建的时候应该怎么做。如果你的情况不一样,请记得把版本号调整为你所需要的版本。

    • 可能的问题 1:虽然,Pytorch 带有自己的 CUDA toolkit ,但要构建这两个项目(即,fairscale, deepspeed),你必须在全系统安装相同版本的 CUDA

      例如,如果你在 Python 环境下安装了 pytorch ,并使用 cudatoolkit==10.2 ,你也需要在全系统安装CUDA 10.2

      具体位置可能因系统而异,但 /usr/local/cuda-10.2 是许多 Unix 系统上最常见的位置。当 CUDA 被正确设置并添加到PATH环境变量中时,可以通过以下操作找到安装位置:

      如果你的系统中没有安装 CUDA,请先安装它。

    • 可能的问题 2:你可能在系统中安装了不止一个 CUDA toolkit ,如:

      现在,在这种情况下,你需要确保你的 PATHLD_LIBRARY_PATH 环境变量包含所需 CUDA 版本的正确路径。通常情况下,软件包安装程序会将这些设置为包含最仅安装的任何版本。如果你遇到这样的问题,即尽管你已经在全系统安装了 CUDA ,但由于找不到正确的 CUDA 版本而导致 package 构建失败,这意味着你需要调整上述两个环境变量:

    • 可能的问题 3:一些旧的 CUDA 版本可能会拒绝使用较新的编译器进行编译。例如,你有 gcc-9 ,但它想要 gcc-7 。有多种方法可以解决这个问题:

      • 如果你能安装最新的CUDA toolkit,它通常应该支持较新的编译器。

      • 另外,你可以在你已经有的编译器之外再安装低版本的编译器;或者,你已经有了低版本的编译器但它不是默认的,所以构建系统看不到它。下面的方法可能会有帮助:

        这里,我们从 /usr/local/cuda-10.2/bin/gcc 建立了一个指向 gcc-7 的符号链接,由于 /usr/local/cuda-10.2/bin/ 应该在 PATH 环境变量中(见前面问题的解决方案),它应该找到 gcc-7(和 g++7 ),然后构建就会成功。

  3. PyTorch Fully Sharded Data Parallel: FSDP:为了在更大的 batch size 上加速训练巨大的模型,我们可以使用一个 fully sharded data parallel model 。这种类型的数据并行范式通过分片 optimizer states 、梯度、以及parameters,能够适应更多的数据和更大的模型。我们已经集成了最新 PyTorch’s Fully Sharded Data Parallel: FSDP 训练特性。你只需通过配置将其启用即可。

    注意,必须从 PyTorch 1.12.0 及其以后的版本才可以使用 FSDP 的能力。

    用法:

    • 确保你已经添加了distributed launcher

    • 分片策略:

      • FULL_SHARD:将 optimizer states + gradients + model parameters 分片到 data parallel workers/GPUs 中。为此,在命令行参数中添加 -fsdp full_shard
      • SHARD_GRAD_OP:将 optimizer states + gradients 分片到 data parallel workers/GPUs 中。为此,在命令行参数中添加 -fsdp shard_grad_op
      • NO_SHARD:不分片。为此,在命令行参数中添加 -fsdp no_shard
    • 要将 parametersgradients 卸载到 CPU ,请在命令行参数中添加:

    • 要使用 default_auto_wrap_policy 来采用 FSDP 自动递归地 wrap layers ,请在命令行参数中添加:

    • 要同时启用 CPU 卸载和 auto wrapping,请在命令行参数中添加:

    • 如果启用了 auto wrapping,你可以使用 transformer based auto wrap policysize based auto wrap policy

      • 对于 transformer based auto wrap policy ,请在命令行参数中加入:

        这指定了要包装的 transformer layer class name(区分大小写),例如,BertLayer, GPTJBlock, T5Block,... 。这很重要,因为共享权重的子模块(例如,embedding layer)不应该最终出现在不同的 FSDP wrapped units 中。

        使用这个策略,每个包含 Multi-Head Attention followed by couple of MLP layersblock 都会发生包装。其余的层,包括 shared embeddings ,都方便地被包裹在同一个最外层的 FSDP unit 中。因此,对于 transformer based 的模型,可以使用这个策略。

      • 对于 size based auto wrap policy,请在命令行参数中加入:

        它指定了 FSDP auto wrapping 的最少的 parameters 数量。

    • 一些注意事项:

      • FSDP 目前不支持混合精度,因为我们在等待 PyTorch 修复对混合精度的支持。
      • FSDP 目前不支持multiple parameter groups

二、Callbacks

  1. callbacks 是一种对象,它可以自定义 PyTorch Trainertraining loopTensorFlow 中尚未实现此功能)。例如,检查 training loop 状态(用于进度报告、在 TensorBoard 或其他 ML 平台上进行 logging)并做出决定(如 early stopping )。

    callbacks"read only" 的代码,除了它们返回的 TrainerControl 对象外,它们不能改变 training loop 中的任何东西。如果需要改变 training loop ,那么你应该对 Trainer 进行子类化并覆盖你想要改变的方法。

  2. 默认情况下,Trainer 将使用以下 callbacks

    • DefaultFlowCallback:处理 logging, saving, evaluation 的默认 callback
    • PrinterCallbackProgressCallback:显示训练进度,或打印日志。如果你通过 TrainingArguments 禁用 tqdm,那么Trainer 就使用 PrinterCallback;否则就使用 ProgressCallback
    • TensorBoardCallback:如果 tensorboard可用(安装了 PyTorch >= 1.4tensorboardX ),则Trainer 就使用 TensorBoardCallback
    • WandbCallback:如果 wandb 已安装,则 Trainer 使用 WandbCallback
    • CometCallback:如果 comet_ml 已安装,则 Trainer 使用 CometCallback
    • MLflowCallback:如果 mlflow 已安装,则 Trainer 使用 MLflowCallback
    • NeptuneCallback:如果 neptune 已安装,则 Trainer 使用 NeptuneCallback
    • AzureMLCallback:如果 azureml-sdk 已安装,则 Trainer 使用 AzureMLCallback
    • CodeCarbonCallback:如果 codecarbon 已安装,则 Trainer 使用 CodeCarbonCallback
    • ClearMLCallback:如果 clearml 已安装,则 Trainer 使用 ClearMLCallback
  3. 实现 callbacks 的主要类是 TrainerCallback 。它获得用于实例化 TrainerTrainingArguments ,可以通过 TrainerState 访问该 Trainer 的内部状态,并且可以通过 TrainerControltraining loop 采取一些行动。

2.1 API

  1. class transformers.TrainerCallbackTrainerCallback ,它将在一些事件中检查 training loop 的状态并作出一些决定。

    初始化参数:

    • args:一个 TrainingArguments,指定用于实例化 Trainer 的训练参数。

    • state:一个 TrainerState,指定训练器的当前状态。

    • control:一个 TrainerControl,指定返回给训练器的对象,它可以用来做一些决定。

    • model:一个 PreTrainedModeltorch.nn.Module,指定正在训练的模型。

    • tokenizer:一个 PreTrainedTokenizer,指定用于对数据进行编码的 tokenizer

    • optimizer:一个 torch.optim.Optimizer,指定用于训练的优化器。

    • lr_scheduler:一个 torch.optim.lr_scheduler.LambdaLR,指定用于训练的学习率调度器。

    • train_dataloader:一个 torch.utils.data.DataLoader,指定 training dataloader

    • eval_dataloader:一个 torch.utils.data.DataLoader,指定 evaluation dataloader

    • metrics:一个字典 Dict[str, float],指定由上一次 evaluation 阶段计算得到的指标。

      它仅在 on_evaluate 事件中才能访问。

    • logs:一个字典 Dict[str, float],指定需要 log 的内容。

      它只能在事件 on_log 中访问。

    方法(这些参数参考初始化参数):

    • on_epoch_begin(args: TrainingArguments, state: TrainerState, control: TrainerControl, **kwargs):在一个 epoch 的开始时被调用的事件。

    • on_epoch_end(args: TrainingArguments, state: TrainerState, control: TrainerControl, **kwargs):在一个 epoch 的结束时被调用的事件。

    • on_evaluate(args: TrainingArguments, state: TrainerState, control: TrainerControl, **kwargs):在 evaluation 阶段之后被调用的事件。

    • on_init_end(args: TrainingArguments, state: TrainerState, control: TrainerControl, **kwargs):在 Trainer 的初始化结束之后被调用的事件。

    • on_log(args: TrainingArguments, state: TrainerState, control: TrainerControl, **kwargs):在 logging last logs 之后被调用的事件。

    • on_predict(args: TrainingArguments, state: TrainerState, control: TrainerControl, metrics, **kwargs) :在一个成功的预测之后被调用的事件。

    • on_prediction_step(args: TrainingArguments, state: TrainerState, control: TrainerControl, **kwargs):在一个 prediction step 之后被调用的事件。

    • on_save(args: TrainingArguments, state: TrainerState, control: TrainerControl, **kwargs):在一个 checkpoint save 之后被调用的事件。

    • on_step_begin(args: TrainingArguments, state: TrainerState, control: TrainerControl, **kwargs):在一个 training step 之前被调用的事件。

      如果使用梯度累积gradient accumulation,那么一个 training step 可能需要若干个 inputs

    • on_step_end(args: TrainingArguments, state: TrainerState, control: TrainerControl, **kwargs):在一个 training step 之后被调用的事件。

      如果使用梯度累积gradient accumulation,那么一个 training step 可能需要若干个 inputs

    • on_substep_end(args: TrainingArguments, state: TrainerState, control: TrainerControl, **kwargs):在 gradient accumulation 期间的每个 training substep 之后被调用的事件。

    • on_train_begin(args: TrainingArguments, state: TrainerState, control: TrainerControl, **kwargs):在训练开始时被调用的事件。

    • on_train_end(args: TrainingArguments, state: TrainerState, control: TrainerControl, **kwargs):在训练结束时被调用的事件。

    在每个事件中,都有以下参数:

    • control 对象:是唯一可以被 callback 改变的对象,在这种情况下,改变它的事件应该返回修改后的版本。
    • args, state, control 是所有事件中的位置参数,而其他参数都位于 kwargs 关键字参数。你可以 unpack 你需要的关键字参数。例如:
  2. 将一个自定义的 callback 注册到 PyTorch Trainer 的例子:

    也可以通过如下的方式注册:

  3. library 中目前可用的 TrainerCallback

  4. class transformers.TrainerState:一个包含Trainer 内部状态的类,在 checkpointing 时将伴随着模型和优化器保存并传递给 TrainerCallback

    参数:

    • epoch:一个浮点数,仅用于训练期间,指定当前训练所处的 epoch(小数部分代表当前 epoch 完成的百分比)。
    • global_step:一个整数,仅用于训练期间,指定已经完成的 update steps 数量。
    • max_steps:一个整数,指定当前训练需要执行的 update steps 数量。
    • total_flos:一个浮点数,指定从训练开始以来,模型所做的浮点预算的总和。以浮点形式存储,避免溢出。
    • log_history:一个关于字典的列表 List[Dict[str, float]],指定自训练开始以来完成的日志列表。
    • best_metric:一个浮点数,指定当 tracking best model 时,到目前为止遇到的最佳指标值。
    • best_model_checkpoint:一个浮点数,指定当 tracking best model 时,到目前为止遇到的最佳模型的 checkpoint 的名称。
    • is_local_process_zero:一个布尔值,指定当前进程是否是 local 的主进程(用于分布式训练的场景)。
    • is_world_process_zero:一个布尔值,指定当前进程是否是 global 的主进程。当以分布式的方式在几台机器上进行训练时,只有一个进程为 True
    • is_hyper_param_search:一个布尔值,指定我们是否正在使用 Trainer.hyperparameter_search 进行超参数搜索。这将影响数据在 TensorBoard 中的记录方式。

    注意,在 TrainerState 中,一个 step 应理解为一个 update step 。当使用 gradient accumulation 时,一个 update step 可能需要几个前向和反向传播:如果你使用 gradient_accumulation_steps=n ,那么一个 update step 需要经过 nbatch

    方法:

    • load_from_json(json_path: str ):从 json_path 的内容创建一个 TrainerState 实例。
    • save_to_json(json_path: str ):将当前实例的内容以 JSON 格式存储到 json_path
  5. class class transformers.TrainerControl:一个处理 Trainer 控制流的类。这个类被 TrainerCallback 用来激活 training loop 中的一些开关。

    参数:

    • should_training_stop:一个布尔值,指定训练是否应该被中断。如果为 True,那么这个变量将没有机会被设置为 False,因为训练将直接停止。
    • should_epoch_stop:一个布尔值,指定当前的 epoch 是否应该被中断。如果是 True ,这个变量将在下一个 epoch 的开始被设置为 False
    • should_save:一个布尔值,指定当前 step 是否应该保存模型。如果是 True ,这个变量将在下一个 step 开始时被设置为False
    • should_evaluate:一个布尔值,指定当前 step 是否应该评估模型。如果是 True ,这个变量将在下一个 step 开始时被设置为False
    • should_log:一个布尔值,指定当前 step 是否应该上报日志。如果是 True ,这个变量将在下一个 step 开始时被设置为False

三、Keras callbacks

3.1 API

  1. class transformers.KerasMetricCallback:用于 kerascallback,用于在每个 epoch 结束时计算指标。

    与普通的 Keras 指标不同,这些指标不需要由 TF 来编译。它对于像 BLEUROUGE 这样需要字符串操作或 generation loop 的常见 NLP 指标特别有用,这些指标不能被编译。预测(或生成)将在 eval_dataset 上计算,然后以 np.ndarray 格式传递给metric_fnmetric_fn应该计算指标并返回一个字典,字典的键为指标名、值为指标值。

    参数:

    • metric_fn:一个可调用对象,指定度量函数。调用metric_fn 时需要提供两个参数:predictionslabels,它们分别对应了模型的输出结果、以及 ground-truth labelmetric_fn 函数需要返回一个字典,字典的键为指标名、值为指标值。

      下面是一个摘要模型计算 ROUGE 分数的 metric_fn 的示例:

    • eval_dataset:一个 tf.data.Dataset 或字典或元组或 np.ndarraytf.Tensor,指定验证数据集。

    • output_cols:一个关于字符串的列表,指定模型输出中的哪些列作为 predictions 。默认为所有列。

    • label_cols:一个关于字符串的列表,指定验证集中的哪些列作为 label 列。如果未提供,则自动检测。

    • batch_size:一个整数,指定 batch size 。只有在验证集不是 pre-batched tf.data.Dataset 时才起作用。

    • predict_with_generate:一个布尔值,指定是否应该使用 model.generate() 来获取模型的输出。

    • use_xla_generation:一个布尔值,如果我们要执行 generating ,是否要用 XLA 来编译 model generation 。这可以极大地提高生成的速度(最多可以提高 100 倍),但是需要对每个 input shape 进行新的 XLA 编译。当使用 XLA generation 时,最好将你的输入填充到相同的大小,或者在你的 tokenizerDataCollator 中使用 pad_to_multiple_of 参数,这将减少 unique input shape 的数量,并节省大量的编译时间。

      如果 predict_with_generate = False ,该参数没有影响。

    • generate_kwargs:关键字参数,用于 generating 时传递给 model.generate() 的关键字参数。

      如果 predict_with_generate = False ,该参数没有影响。

  2. class transformers.PushToHubCallback:用于 kerascallback,用于定期保存和推送模型到 Hub

    参数:

    • output_dir:一个字符串,指定输出目录,model predictionsmodel checkpoints 将被写入该目录并与 Hub 上的 repo 同步。
    • save_strategy/save_steps:参考 transformers.TrainingArguments
    • tokenizer:一个 PreTrainedTokenizerBase,指定模型使用的 tokenizer 。如果提供,将与模型权重一起上传到 repo
    • hub_model_id/hub_token:参考 transformers.TrainingArguments
    • checkpoint:一个布尔值,指定是否保存完整的 training checkpoints (包括 epochoptimizer state )以允许恢复训练。只在 save_strategy="epoch" 时可用。

    示例:

四、Logger

  1. Transformers 有一个集中化的日志系统,默认的 verbosity levelWARNING 。有多种方式可以改变 verbosity level

    • 可以在代码中直接指定:

    • 可以通过环境变量指定:

  2. verbosity level (从最少的日志到最多的日志)为:

    • transformers.logging.CRITICALtransformers.logging.FATAL(整数值 50):仅报告最关键的错误。
    • transformers.logging.ERROR(整数值 40):仅报告错误。
    • transformers.logging.WARNINGtransformers.logging.WARN(整数值 30):仅报告错误和警告。这是默认级别。
    • transformers.logging.INFO(整数值 20):报告错误、警告和基本信息。
    • transformers.logging.DEBUG(整数值 10):报告所有信息。
  3. 默认情况下,在模型下载过程中会显示 tqdm 进度条。logging.disable_progress_bar()logging.enable_progress_bar() 可以用来禁止或开启这种行为。

  4. 获取和配置 verbosity level

  5. transformers.utils.logging.get_logger(name: typing.Optional[str] = None ):获取指定名字的 logger

    这个函数不应该被直接访问,除非你正在编写一个自定义的 transformers module

  6. 开启和禁用 HuggingFace Transformers’s root logger 的默认 handler

  7. transformers.utils.logging.enable_explicit_format():为每个 HuggingFace Transformerslogger 启用显式格式化。显式格式化的内容如下:

    当前与 root logger 绑定的所有 handler 都受此方法影响。

  8. transformers.utils.logging.reset_format():为每个 HuggingFace Transformerslogger 重设格式化。

    当前与 root logger 绑定的所有 handler 都受此方法影响。

  9. 开启和禁用 tqdm 进度条:

五、Optimization

  1. optimization 模块提供如下功能:

    • 一个具有固定权重衰减的 optimizer,可用于对模型进行微调。
    • 几个 schedule,它们是以继承自 _LRScheduleschedule 对象的形式提供。
    • 一个 gradient accumulation 类,用于累积多个 batch 的梯度。

5.1 Optimizer API

  1. class transformers.AdamW:具有固定的 weight decayAdam

    参数:

    • params:一个 nn.parameter.Parameter 可迭代对象或字典,指定需要被优化的 parametersparameter groups
    • lr:一个浮点数,指定初始学习率。
    • betas:一个 Tuple[float,float] 元组,指定 Adam 的参数 (β1,β2)
    • eps:一个浮点数,用于数值稳定。
    • weight_decay:一个浮点数,指定权重衰减。
    • correct_bias:一个布尔值,指定是否在 Adamcorrect bias 。例如,在 BERT TF repo 中,他们使用 False
    • no_deprecation_warning:一个布尔值,指定是否屏蔽 deprecation warning

    方法:

    • step( closure: typing.Callable = None):指定单个 optimization step

      参数:closure:一个可调用对象,用于重新评估模型并返回 loss

  2. class transformers.Adafactor(PyTorch)Adafactor 优化器。

    参数:

    • params:参考 AdamW
    • lrexternal 的学习率。
    • eps:一个 Tuple[float, float] 元组,指定正则化系数,分别用于 square gradientparameter scale
    • clip_threshold:一个浮点数,指定 final gradient update 的均方根阈值。
    • decay_rate:一个浮点数,指定用于计算 running averages of square 的系数。
    • beta1:一个浮点数,指定用于计算 running averages of gradient 的系数。
    • weight_decay:一个浮点数,指定权重衰减(L2 正则化)。
    • scale_parameter:一个布尔值,如果为 True,则学习率通过 root mean square 来缩放。
    • relative_step:一个布尔值,如果为 True,则计算 time-dependent 学习率而不是 external 学习率。
    • warmup_init:一个布尔值,指定 time-dependent 学习率是否启用 warm-up 初始化。

    方法:参考 AdamW

  3. class transformers.AdamWeightDecay(TensorFlow):在梯度上启用了 L2 权重衰减和 clip_by_global_normAdam

    参数:

    • learning_rate:一个浮点数或 tf.keras.optimizers.schedules.LearningRateSchedule,指定学习率或学习率调度。

    • beta_1:一个浮点数,指定 Adamβ1 参数。

    • beta_2:一个浮点数,指定 Adamβ2 参数。

    • epsilon:一个浮点数,是 Adam 中的 ϵ 参数,用于数值稳定性。

    • amsgrad:一个布尔值,指定是否应该使用算法的 AMSGrad 变体。

    • weight_decay_rate:一个浮点数,指定权重衰减的系数。

    • include_in_weight_decay:一个关于字符串的列表,指定对哪些 parameters 应用权重衰减。如果未传递该参数,则默认应用于所有的 parameters(除非它们位于 exclude_from_weight_decay 中)。

    • exclude_from_weight_decay:一个关于字符串的列表,指定对哪些 parameters 排除权重衰减。如果一个 parameter name 同时位于 include_in_weight_decayexclude_from_weight_decay,那么以 include_in_weight_decay 优先级最高。

    • name:一个字符串,指定权重衰减操作的名称。

    • kwargs:关键字操作,可以为 clipnorm, clipvalue, lr, decay

      • clipnorm:基于梯度范数来裁剪梯度。
      • clipvalue:基于梯度的取值来裁剪梯度。
      • decay:用于后向兼容性,从而允许学习率的时间逆向衰减 time inverse decay
      • lr:用于后向兼容性,建议使用 learning_rate

    方法:

    • from_config(config) :从配置文件中创建一个 AdamWeightDecay
  4. transformers.create_optimizer():创建一个 optimizer

    参数:

    • init_lr:一个浮点数,指定 warmup 阶段结束时的期望学习率。
    • num_train_steps:一个整数,指定总的训练 step 数。
    • num_warmup_steps:一个整数,指定 warmup step 数。
    • min_lr_ratio:一个浮点数,学习率线性衰减结束时的最终学习率为 init_lr * min_lr_ratio
    • adam_beta1:一个浮点数,指定 Adamβ1 参数。
    • adam_beta2:一个浮点数,指定 Adamβ2 参数。
    • adam_epsilon:一个浮点数,指定 Adam 中的 ϵ 参数,用于数值稳定性。
    • adam_clipnorm:一个浮点数,如果不是None ,指定每个权重梯度范数的裁剪值。
    • adam_global_clipnorm:一个浮点数,如果不是None ,把所有权重梯度拼接起来,然后这个拼接结果的范数的裁剪值。
    • weight_decay_rate:一个浮点数,指定权重衰减系数。
    • power:一个浮点数,指定多项式衰减的幂次。
    • include_in_weight_decay:参考 AdamWeightDecay

5.2 Schedule API

  1. class transformers.SchedulerType:一个枚举类型。

  2. transformers.get_scheduler():一个统一的 API,根据 scheduler name 来获取 scheduler

    参数:

    • name:一个字符串或 SchedulerType,指定 scheduler 的名字。
    • optimizer:一个 torch.optim.Optimizer 对象,指定优化器。
    • num_warmup_steps:一个整数,指定需要的 warmup step 的数量。不是所有的 scheduler 都需要这个参数(因此这个参数是可选的)。如果这个参数没有设置,而 scheduler 需要这个参数,则将引发一个错误。
    • num_training_steps:一个整数,指定需要的 training step 的数量。不是所有的 scheduler 都需要这个参数(因此这个参数是可选的)。如果这个参数没有设置,而 scheduler 需要这个参数,则将引发一个错误。
  3. transformers.get_constant_schedule( optimizer: Optimizer, last_epoch: int = -1) :创建一个常数学习率的调度器。

    参数:

    • optimizer:一个 torch.optim.Optimizer 对象,指定优化器。
    • last_epoch:一个整数,指定 last epoch 的索引,用于恢复训练。
  4. transformers.get_constant_schedule_with_warmup(optimizer: Optimizer, num_warmup_steps: int, last_epoch: int = -1):创建一个带 warmup 的常数学习率的调度器。

    参数:

    • num_warmup_steps:一个整数,指定 warmup 阶段的 step 数。
    • 其它参数参考 get_constant_schedule()
  5. transformers.get_cosine_schedule_with_warmup(optimizer: Optimizer, num_warmup_steps: int, num_training_steps: int, num_cycles: float = 0.5, last_epoch: int = -1):创建一个带 warmup 的余弦学习率的调度器。

    参数:

    • num_training_steps:一个整数,指定总的训练 step 数。
    • num_cycles:一个浮点数,指定余弦调度中的波数,默认为 0.5,表示半个余弦(从最大值下降到零)。
    • 其它参数参考 get_constant_schedule_with_warmup()
  6. transformers.get_cosine_with_hard_restarts_schedule_with_warmup(optimizer: Optimizer, num_warmup_steps: int, num_training_steps: int, num_cycles: float = 0.5, last_epoch: int = -1):创建一个带 warmup 的、且若干个硬重启的余弦学习率的调度器

    参数:

    • num_cycles:一个整数,指定 hard restart 的数量。
    • 其它参数参考 get_cosine_schedule_with_warmup()
  7. transformers.get_linear_schedule_with_warmup( optimizer, num_warmup_steps, num_training_steps, last_epoch = -1):创建一个带 warmup 的线性调度器。

    参数:参考 get_constant_schedule_with_warmup()

  8. transformers.get_polynomial_decay_schedule_with_warmup(optimizer, num_warmup_steps, num_training_steps, lr_end = 1e-07, power = 1.0, last_epoch = -1):创建一个带 warmup 的多项式衰减调度器。

    参数:

    • lr_end:一个浮点数,制定结束时的学习率。
    • power:一个浮点数,指定指数因子。
    • 其它参数参考 get_constant_schedule_with_warmup()
  9. class transformers.WarmUp(TensorFlow):在一个给定的 learning rate decay schedule 上应用一个 warmup

    参数:

    • initial_learning_rate:一个浮点数,指定 warmup 结束时的学习率。
    • decay_schedule_fn:一个可调用对象,指定在 warmup 之后所采用的 schedule 函数。
    • warmup_steps:一个整数,指定 warmup 阶段的 step 数。
    • power:一个浮点数,指定用于多项式 warmup 的指数因子(默认为线性 warmup )。
    • name:一个字符串,指定在 schedule 阶段返回的张量的 name prefix

5.3 Gradient Strategies API

  1. class transformers.GradientAccumulator(TensorFlow)gradient accumulation 工具函数。

    当用于分布式训练时,应在副本上下文中调用该 accumulator 。梯度将在每个副本上局部地累积,不需要同步。然后用户应该调用 .gradients ,如果需要的话则 scale 梯度,并将结果传递给 apply_gradients

    方法:

    • reset():在当前 replicareset 被累计的梯度。

六、Processors

  1. 任何多模态模型都需要一个对象来编码或解码数据。该数据分组了几种模态(文本、视频、音频)。这由被称为 processor 的对象处理,processor 将两个或更多的 processing 对象组合在一起,如 tokenizer (用于文本模态)、image processors (用于视觉)和 feature extractors (用于音频)。

  2. class transformers.ProcessorMixin(*args, **kwargs ):所有 processormixin ,用于保存和加载。

    方法:

    • from_pretrained(pretrained_model_name_or_path, **kwargs ):用一个预训练模型来初始化一个 processor

      参数:参考 PreTrainedTokenizerBase.from_pretrained()

    • push_to_hub():将 processor 上传到 Model Hub (对应于本地 repo clone 的远程 repo pathrepo name)。

      参数:参考 PreTrainedTokenizerBase.push_to_hub()

    • register_for_auto_class( auto_class = 'AutoProcessor' ):以给定的 auto class 来注册该类。

      参数:参考 PreTrainedTokenizerBase.register_for_auto_class()

    • save_pretrained( save_directory: typing.Union[str, os.PathLike], push_to_hub: bool = False, **kwargs ):保存 processor

      参数:参考 PreTrainedTokenizerBase.save_pretrained()

6.1 Feature Extractor

  1. feature extractor 负责为音频模型或视觉模型准备输入特征。这包括:

    • 从序列中抽取特征(如将音频文件预处理为 Log-Mel Spectrogram 特征)。
    • 从图像中抽取特征(如裁剪图像文件)。
    • 以及 padding, normalization, conversion to Numpy/PyTorch/TensorFlow tensors
  2. class transformers.FeatureExtractionMixin(**kwargs)feature extraction mixin ,用于为 sequential and image feature extractors 提供保存和加载的能力。

    方法:

    • from_pretrained(pretrained_model_name_or_path, **kwargs ) :参考 ProcessorMixin.from_pretrained()
    • save_pretrained(save_directory: typing.Union[str, os.PathLike], push_to_hub: bool = False, **kwargs ):参考 ProcessorMixin.save_pretrained()
  3. class transformers.SequenceFeatureExtractor:用于语音识别的通用的feature extraction 类。

    参数:

    • feature_size:一个整数,指定被抽取特征的特征维度。
    • sampling_rate:一个整数,指定音频文件应该被数字化的采样率,以赫兹/秒(Hz)表示。
    • padding_value:一个浮点数,指定 padding value

    方法:

    • pad():填充 input values/input vectors (或者它们的 batch 版本),从而达到预定义的长度或 batch 中的最大序列长度。

      padding side(左侧/右侧)、padding values 是定义在 feature extractor level(通过 self.padding_sideself.padding_value)。

      参数:

      • processed_features:表示被处理的特征,可以是一个输入,也可以是 batch 的输入。

      • padding/max_length/truncation/pad_to_multiple_of/return_attention_mask:参考 PreTrainedTokenizerBase.__call__() 方法。

      • return_tensors:一个字符串或 TensorType,指定返回的数据类型。如果设置了,则返回张量类型而不是 Python 的整数列表。

        • 'tf':返回的是 TensorFlow tf.constant 对象。
        • 'pt':返回的是 PyTorch torch.Tensor 对象。
        • 'np':返回的是 Numpy np.ndarray 对象。
  4. class transformers.BatchFeature:持有 pad() 、以及 feature extractor__call__() 方法的 output 。它是 Python 字典的派生类,可以作为一个字典来使用。

    参数:

    • data:一个字典,是由 __call__()/pad() 方法返回的值。
    • tensor_type:一个字符串或 TensorType,指定张量类型。

    方法:

    • convert_to_tensors( tensor_type: typing.Union[str, transformers.utils.generic.TensorType, NoneType] = None):将内部内容转换为指定的张量类型。

      参数:tensor_type:一个字符串或 TensorType,指定张量类型。

    • to(device: typing.Union[str, ForwardRef('torch.device')]) -> BatchFeature:将所有的值都移动到指定设备上(仅用于 PyTorch )。

      参数:device:一个字符串或 torch.device,指定设备。

  5. class transformers.ImageFeatureExtractionMixin:用于准备图片特征的 mixin

    方法:

    • center_crop(image, size ) -> new_image:使用中心裁剪的方式将图像裁剪到指定的尺寸。注意,如果图像太小而无法裁剪到指定的尺寸,它将被填充(所以返回的结果具有指定的尺寸)。

      参数:

      • image:一个 PIL.Image.Imagenp.ndarraytorch.Tensor (形状为 (n_channels, height, width) or (height, width, n_channels) ),表示输入的图像。
      • size:一个整数或 Tuple[int, int] 元组,指定目标尺寸。

      返回一个新的图像,类型和 image 相同。

    • convert_rgb(image) -> new_image:将 PIL.Image.Image 转换为 RGB 格式。

      参数:image:一个 PIL.Image.Image,指定被转换的图片。

    • expand_dims(image) -> new_image:将二维图像扩展为三维。

      参数:image:一个 PIL.Image.Imagenp.ndarraytorch.Tensor,指定输入图像。

    • flip_channel_order(image) -> new_image:将 image 的通道顺序从 RGB 翻转为 BGR、或从 BGR 翻转为 RGB 。注意,如果 image 是一个 PIL Image,则会将 image 转换到 numpy array

      参数:image:一个 PIL.Image.Imagenp.ndarraytorch.Tensor,指定输入图像。

    • normalize( image, mean, std, rescale = False ) -> new_image:将 image 归一化到均值 mean、标准差 std。注意,如果 image 是一个 PIL Image,则会将 image 转换到 numpy array

      参数:

      • image:一个 PIL.Image.Imagenp.ndarraytorch.Tensor,指定输入图像。
      • mean:一个 List[float]np.ndarraytorch.Tensor,指定每个通道的均值。
      • std:一个 List[float]np.ndarraytorch.Tensor,指定每个通道的标准差。
      • rescale:一个布尔值,指定是否将 image 重新缩放到 0.0 ~ 1.0 之间。如果 image 是一个 PIL Image ,则自动执行缩放。
    • rescale(image: ndarray, scale: typing.Union[float, int] ) -> new_image:缩放一个 numpy image

    • resize(image, size, resample = None, default_to_square = True, max_size = None) -> new_imagereisze 图片。会强制将 image 转换为 PIL.Image,最终返回结果是 PIL.Image

      参数:

      • image:一个 PIL.Image.Imagenp.ndarraytorch.Tensor,指定输入图像。

      • size:一个整数或 Tuple[int, int],指定目标尺寸。

        • 如果 size 是一个元组,那么输出尺寸将与之匹配。
        • 如果 size 是一个整数且 default_to_square = True,则输出尺寸为 (size, size)
        • 如果 size 是一个整数且 default_to_square = False,那么图像的较短的边将与 size 相匹配。即,如果 height > width ,那么图像将被调整为 (size * height / width, size)
      • resample:一个整数,指定用于 resamplingfilter,默认为 PILImageResampling.BILINEAR

      • default_to_square:一个布尔值,指定当 size 是一个整数时是否调整为正方形。

      • max_size:一个整数,指定被调整之后的图像的 longer edge 的最大值。如果超出了这个 max_size,则图像被再次调整,使得 longer edge 等于 max_size 。仅在 default_to_square = False 时有效。

    • rotate(image, angle, resample = None, expand = 0, center = None, translate = None, fillcolor = None ) -> new_image:旋转图像,返回一个 PIL.Image.Image

    • to_numpy_array(image, rescale = None, channel_first = True):将图片转换为 numpy array

      参数:

      • image:一个 PIL.Image.Imagenp.ndarraytorch.Tensor,指定输入图像。
      • rescale:一个布尔值,指定是否将 image 重新缩放到 0.0 ~ 1.0 之间。如果 image 是一个 PIL Image 或整数的 array/tensor,则默认为 True
      • channel_first:一个布尔值,指定是否 channel dimension first
    • to_pil_image( image, rescale = None ):将图片转换为 PIL Image

      • image:一个 PIL.Image.Imagenp.ndarraytorch.Tensor,指定输入图像。
      • rescale:一个布尔值,指定是否将 image 重新缩放到 0 ~ 255 之间。如果 image 是浮点类型的 array/tensor,则默认为 True

6.2 Image Processor

  1. image processor 负责为视觉模型准备输入特征,并对其输出进行后处理。这包括 transformations (如 resizingnormalization 、以及转换为 PyTorch/TensorFlow/Flax/Numpy 张量)。还可能包括特定模型的后处理,如将 logits 转换为 segmentation masks

  2. class transformers.ImageProcessingMixin(** kwargs)image processor mixin

    方法:

    • from_pretrained(pretrained_model_name_or_path, **kwargs ) :参考 ProcessorMixin.from_pretrained()
    • save_pretrained(save_directory: typing.Union[str, os.PathLike], push_to_hub: bool = False, **kwargs ):参考 ProcessorMixin.save_pretrained()

七、分享预训练的模型

  1. 创建新的 model repository 的方法有以下三种:使用 push_to_hub API 、使用 huggingface_hubPython 库、使用 web 界面。

    创建 repository 后,你可以通过 gitgit-lfs 将文件上传到其中。

7.1 使用 push_to_hub API

  1. 首先登录 Hugging Face

    如果在notebook 中,可以使用以下函数登录:

    如果你在终端中,可以运行命令:

    在这两种情况下,系统都会提示你输入用户名和密码。

  2. 如果你使用 Trainer API 来训练一个模型,将其上传到 Hub 的最简单方法是:当定义 TrainingArguments 时设置 push_to_hub=True

    当你调用 trainer.train() 时,Trainer 将在每次保存模型时,同时将模型上传到 Hub 中你的命名空间中的 repository。该repository 将命名为你选择的输出目录(此处 bert-finetuned-mrpc ) ,但是你也可以选择不同的名称,通过设置 hub_model_id = "a_different_name" 参数。

    要将模型上传到你所属的组织,只需将其传递给 hub_model_id = my_organization/my_repo_name

    训练结束后,你应该做最后的 trainer.push_to_hub() 上传模型的最新版本。它还将生成包含所有相关元数据的模型卡,报告使用的超参数和评估结果!以下是你可能会在此类模型卡中找到的内容示例:

  3. lower level ,可以通过模型、tokenizer 和配置对象的 push_to_hub() 方法直接访问 Model Hub 。此方法负责创建 repository 并将模型和 tokenizer 文件直接推送到 repository 。如:

    如果你属于一个组织,只需指定 organization 参数 。

    如果你希望使用特定的 Hugging Face token ,你可以自由地将其指定给 push_to_hub() 方法 :

7.2 使用 huggingface_hub 的 Python 库

  1. 类似于使用push_to_hub API,首先要求你将API token 保存在缓存中。为此,需要在终端中运行命令 huggingface-cli login

  2. huggingface_hub package 提供了几种对我们有用的方法和类。首先,有几种方法可以管理存储库的创建、删除等:

    此外,它还提供了非常强大的 Repository 类用于管理本地 repository

    create_repo 用于创建位于 hub 上的新 repository

    创建 repository 后,我们应该向其中添加文件。

7.3 使用 Web 界面

  1. Web 界面提供了直接在 Hub 中管理 repo 的工具。使用该界面,你可以轻松创建 repo 、添加文件(甚至是大文件)、探索模型、可视化差异等等。

    要创建新的 repo ,请访问https://huggingface.co/new

7.4 其它

  1. 上传模型文件:Hugging Face Hub 上的文件管理系统基于用于常规文件的 git 和 git-lfs 。可以通过 huggingface_hub 、以及通过 git命令来上传文件到 Hub

    • 通过 huggingface_hub :使用 upload_file 不需要系统上安装 gitgit-lfs。它使用 HTTP POST 请求将文件直接推送到 Hub。这种方法的一个限制是它不能处理大于 5GB 的文件。

      这将位于 <path_to_file> 下的 config.json 上传到 repository (由 <namespace>/dummy-model 指定)根目录下的 config.json

      其他可能有用的参数是:

      • token ,如果您想用给定的token 覆盖存储在缓存中的token
      • repo_type , 如果你想要上传一个 dataset 或一个 space 而不是模型。 接受的值为 "dataset""space"
    • Repository 类:以类似 git 的方式管理本地 repository 。它抽象了 git 可能遇到的大部分痛点,以提供我们需要的所有功能。使用这个类需要安装 gitgit-lfs,所以确保你已经安装了 git-lfs

      我们可以通过克隆远程 repo 将其初始化到本地文件夹开始:

      这将在当前目录创建文件夹 <path_to_dummy_folder> 。接下来我们可以运行一些传统的 git 方法:

    • git-based 方法:这是上传文件的非常简单的方法:我们将直接使用 gitgit-lfs 来完成。

      首先从初始化 git-lfs 开始:

      完成后,第一步是克隆您的模型 repository

      接下来运行 Python 代码并保存模型或 tokenizer,然后执行 git add, git commit, git push 从而上传模型文件。

  2. Model Card:模型卡片是一个配置文件,可以说与模型和tokenizer 文件一样重要。它包含了模型的核心定义,确保了社区成员可以复现模型的结果,并提供一个其他成员可以在这个模型基础上构建他们的组件的平台。

    记录训练和评估过程有助于其他人了解模型的预期效果,并且提供有关所使用的数据以及预处理/后处理的足够信息,可确保能够识别和了解模型的局限性、 bias 以及 context

    创建模型卡片是通过 README.md 来实现的。模型卡片通常以非常简短的概述开始,说明模型的用途,然后是模型卡片需要的其他信息:模型描述、预期用途和限制、如何使用、局限性和 bias 、训练数据、训练程序、评价结果。

八、示例

  1. 使用 Trainer API微调模型:

  2. 不使用 Trainer API 来训练,纯人工实现:

  3. 使用 Accelerate 加速训练:使用Accelerate 库,只需进行一些调整,我们就可以在多个 GPUTPU 上启用分布式训练,以下是改动的部分:

    要添加的第一行是导入Accelerator。第二行实例化一个 Accelerator对象 ,它将查看环境并初始化适当的分布式设置。 Accelerate 为你处理数据在设备间的传递,因此你可以删除将模型放在设备上的那行代码(或者,也可以使用 accelerator.device 代替 device )。

    要在分布式设置中使用它,请运行以下命令:

    这将询问你几个配置的问题并将你的回答转储到如下命令使用的配置文件中:

    这将启动分布式训练。

    为了使云端 TPU提供的加速发挥最大的效益,我们建议使用tokenizerpadding=max_lengthmax_length 参数将你的样本填充到固定长度。