Trainer
类提供了一个 API
,用于在 PyTorch
中对大多数标准的 use case
进行 feature-complete training
。在实例化 Trainer
之前,请创建一个 TrainingArguments
。该 API
支持在多个GPU/TPU
上进行分布式训练、也支持通过 NVIDIA Apex
和Native AMP
从而针对 PyTorch
的混合精度训练。
Trainer
类包含 basic training loop
。为了注入自定义行为,你可以对 Trainer
进行子类化,并重写以下方法:
get_train_dataloader; get_eval_dataloader; get_test_dataloader; log; create_optimizer_and_scheduler;
create_optimizer; create_scheduler; compute_loss; training_step; prediction_step; evaluate; predict
下面是一个对 Trainer
子类化的例子,其中使用一个带权重的损失函数:
xfrom torch import nn
from transformers import Trainer
class CustomTrainer(Trainer):
def compute_loss(self, model, inputs, return_outputs=False):
labels = inputs.get("labels")
# forward pass
outputs = model(**inputs)
logits = outputs.get("logits")
# compute custom loss (suppose one has 3 labels with different weights)
loss_fct = nn.CrossEntropyLoss(weight=torch.tensor([1.0, 2.0, 3.0]))
loss = loss_fct(logits.view(-1, self.model.config.num_labels), labels.view(-1))
return (loss, outputs) if return_outputs else loss
对于 PyTorch
,另一种定制化 training loop
行为的方法是采用 callbacks
,它可以检查 training loop state
(用于进度报告、向 TensorBoard
写日志)并作出决定(如 early stopping
)。
Trainer
类是针对 Transformers
模型进行了优化。如果你在其他模型上使用 Trainer
,可能会有意想不到的行为。当你在其他模型上使用时,要确保:
ModelOutput
的子类。labels
参数,那么你的模型可以计算损失,并且该损失作为元组的第一个元素被模型返回(如果你的模型返回元组)。label
参数(使用 TrainingArguments
中的 label_names
来向 Trainer
指定它们的名称),但是它们全都不应该被命名为 "label"
。class transformers.TrainingArguments
:用于 Trainer
的参数(和 training loop
相关)。
通过使用 class transformers.HfArgumentParser
,我们可以将 TrainingArguments
实例转换为 argparse
参数(可以在命令行中指定)。
xxxxxxxxxx
class transformers.TrainingArguments(
output_dir: str,
overwrite_output_dir: bool = False,
do_train: bool = False,
do_eval: bool = False,
do_predict: bool = False,
evaluation_strategy: typing.Union[transformers.trainer_utils.IntervalStrategy, str] = 'no',
prediction_loss_only: bool = False,
per_device_train_batch_size: int = 8,
per_device_eval_batch_size: int = 8,
per_gpu_train_batch_size: typing.Optional[int] = None,
per_gpu_eval_batch_size: typing.Optional[int] = None,
gradient_accumulation_steps: int = 1,
eval_accumulation_steps: typing.Optional[int] = None,
eval_delay: typing.Optional[float] = 0,
learning_rate: float = 5e-05,
weight_decay: float = 0.0,
adam_beta1: float = 0.9,
adam_beta2: float = 0.999,
adam_epsilon: float = 1e-08,
max_grad_norm: float = 1.0,
num_train_epochs: float = 3.0,
max_steps: int = -1,
lr_scheduler_type: typing.Union[transformers.trainer_utils.SchedulerType, str] = 'linear',
warmup_ratio: float = 0.0,
warmup_steps: int = 0,
log_level: typing.Optional[str] = 'passive',
log_level_replica: typing.Optional[str] = 'passive',
log_on_each_node: bool = True,
logging_dir: typing.Optional[str] = None,
logging_strategy: typing.Union[transformers.trainer_utils.IntervalStrategy, str] = 'steps',
logging_first_step: bool = False,
logging_steps: int = 500,
logging_nan_inf_filter: bool = True,
save_strategy: typing.Union[transformers.trainer_utils.IntervalStrategy, str] = 'steps',
save_steps: int = 500,
save_total_limit: typing.Optional[int] = None,
save_on_each_node: bool = False,
no_cuda: bool = False,
use_mps_device: bool = False,
seed: int = 42,
data_seed: typing.Optional[int] = None,
jit_mode_eval: bool = False,
use_ipex: bool = False,
bf16: bool = False,
fp16: bool = False,
fp16_opt_level: str = 'O1',
half_precision_backend: str = 'auto',
bf16_full_eval: bool = False,
fp16_full_eval: bool = False,
tf32: typing.Optional[bool] = None,
local_rank: int = -1,
xpu_backend: typing.Optional[str] = None,
tpu_num_cores: typing.Optional[int] = None,
tpu_metrics_debug: bool = False,
debug: str = '',
dataloader_drop_last: bool = False,
eval_steps: typing.Optional[int] = None,
dataloader_num_workers: int = 0,
past_index: int = -1,
run_name: typing.Optional[str] = None,
disable_tqdm: typing.Optional[bool] = None,
remove_unused_columns: typing.Optional[bool] = True,
label_names: typing.Optional[typing.List[str]] = None,
load_best_model_at_end: typing.Optional[bool] = False,
metric_for_best_model: typing.Optional[str] = None,
greater_is_better: typing.Optional[bool] = None,
ignore_data_skip: bool = False,
sharded_ddp: str = '',
fsdp: str = '',
fsdp_min_num_params: int = 0,
fsdp_transformer_layer_cls_to_wrap: typing.Optional[str] = None,
deepspeed: typing.Optional[str] = None,
label_smoothing_factor: float = 0.0,
optim: typing.Union[transformers.training_args.OptimizerNames, str] = 'adamw_hf',
optim_args: typing.Optional[str] = None,
adafactor: bool = False,
group_by_length: bool = False,
length_column_name: typing.Optional[str] = 'length',
report_to: typing.Optional[typing.List[str]] = None,
ddp_find_unused_parameters: typing.Optional[bool] = None,
ddp_bucket_cap_mb: typing.Optional[int] = None,
dataloader_pin_memory: bool = True,
skip_memory_metrics: bool = True,
use_legacy_prediction_loop: bool = False,
push_to_hub: bool = False,
resume_from_checkpoint: typing.Optional[str] = None,
hub_model_id: typing.Optional[str] = None,
hub_strategy: typing.Union[transformers.trainer_utils.HubStrategy, str] = 'every_save',
hub_token: typing.Optional[str] = None,
hub_private_repo: bool = False,
gradient_checkpointing: bool = False,
include_inputs_for_metrics: bool = False,
fp16_backend: str = 'auto',
push_to_hub_model_id: typing.Optional[str] = None,
push_to_hub_organization: typing.Optional[str] = None,
push_to_hub_token: typing.Optional[str] = None,
mp_parameters: str = '',
auto_find_batch_size: bool = False,
full_determinism: bool = False,
torchdynamo: typing.Optional[str] = None,
ray_scope: typing.Optional[str] = 'last',
ddp_timeout: typing.Optional[int] = 1800
)
参数:
output_dir
:一个字符串,指定 model prediction
和 model 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/CPU
的 batch size
。
per_device_eval_batch_size
:一个整数,指定用于评估的每个 GPU/TPU core/CPU
的 batch 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
:一个浮点数,指定在执行第一次评估之前需要等待多少个 epochs
或 steps
(根据 evaluation_strategy
的不同来选择 epochs
或 steps
)。
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_level
来 log
、或者仅在主节点上 log
。
logging_dir
:一个字符串,指定 TensorBoard log
目录,默认为 output_dir/runs/CURRENT_DATETIME_HOSTNAME
。
logging_strategy
:一个字符串或 IntervalStrategy
,指定训练期间的 logging
策略。可以为:
"no"
:不做任何 logging
。"epoch"
:在每个 epoch
结束时 logging
。"steps"
:每隔 logging_steps
就 logging
。logging_first_step
:一个布尔值,指定是否 log
和 evaluate
第一个 global_step
。
logging_steps
:一个整数,指定当 logging_strategy="steps"
时每两次 logging
之间的 update steps
数量。
logging_nan_inf_filter
:一个布尔值,指定是否要过滤 nan
和 inf
的损失从而用于 logging
。如果为 True
,那么每个 step
的 nan
或 inf
的损失都会被过滤掉从而仅选取当前 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
:一个布尔值,指定是否使用 bf16
的 16
位(混合)精度训练,而不是 fp32
的 32
位训练。需要 Ampere
或更高的 NVIDIA
架构、或使用 CPU
(no_cuda
)。这是一个实验性的API
,它可能会发生变化。
fp16
:一个布尔值,指定是否使用 fp16
的 16
位(混合)精度训练而不是 fp32
的 32
位训练。
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 AMP
或 APEX
,而其他选择将强制使用所对应的后端。
bf16_full_eval
:一个布尔值,指定是否使用 full bfloat16
评估,而不是使用 fp32
的 32
位进行评估。这将会更快并节省内存,但会损害评估指标。这是一个实验性的 API
,它可能会改变。
f16_full_eval
:一个布尔值,指定是否使用 full float16
评估,而不是使用 fp32
的 32
位进行评估。这将会更快并节省内存,但会损害评估指标。
tf32
:一个布尔值,指定是否启用 TF32
模式,在 Ampere
和较新的GPU架构中可用。默认值取决于 PyTorch
的torch.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
:一个整数,有些模型如 TransformerXL
或 XLNet
可以利用 past hidden states
进行预测。如果这个参数被设置为一个正整数,训练器将使用相应的输出(通常是 index 2
)作为 past state
,并在下一个 training step
中根据关键字参数ems
将其馈入模型。
run_name
:一个字符串,指定一个当前 run
的描述文本,通常用于 wandb
和 mlflow
日志。
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_strategy
和 evaluation_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_end
和 metric_for_best_model
一起使用。
如果 metric_for_best_model
被设置为既不是 "loss"
也不是 "eval_loss"
,那么默认为 True
;如果 metric_for_best_model
没有被设置、或者是 "loss"
、或者是 "eval_loss"
,那么默认为 False
。
ignore_data_skip
:一个布尔值,指定在恢复训练时,是否跳过 epochs
和 batches
从而获得与 previous training
相同阶段的 data loading
。如果设置为 True
,训练将更快开始(因为 skipping step
可能需要很长时间),但不会产生与被中断的训练相同的结果。
sharded_ddp
:一个布尔值或字符串或关于 ShardedDDPOption
的列表,指定使用来自 FairScale
的 Sharded 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_labels
;label 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
:一个布尔值,指定当使用分布式训练时,传递给 DistributedDataParallel
的 find_unused_parameters
的值。
如果使用 gradient checkpointing
,那么默认值为 False
;否则默认值为 True
。
ddp_bucket_cap_mb
:一个整数,指定当使用分布式训练时,传递给 DistributedDataParallel
的 bucket_cap_mb
的值。
dataloader_pin_memory
:一个布尔值,指定在 data loaders
中是否要 pin memory
。
skip_memory_metrics
:一个布尔值,指定是否跳过向 metrics
添加 memory profiler
报告。默认情况下跳过(即,True
),因为这会减慢训练和评估的速度。
push_to_hub
:一个布尔值,指定每次保存模型时是否将模型推送到 Hub
。
如果为 True
,output_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
:一个字符串,指定用来推送模型到 Hub
的 token
。将默认为通过 huggingface-cli
登录获得的缓存文件夹中的token
。
hub_private_repo
:一个布尔值,指定是否将 Hub repo
设为私有。
gradient_checkpointing
:一个布尔值,指定是否使用 gradient checkpointing
来节省内存。如果为 True
,则会降低反向传播的速度。
include_inputs_for_metrics
:一个布尔值,指定 inputs
是否会被传递给 compute_metrics
函数。这适用于需要 inputs
、predictions
和 references
的指标的计算。
auto_find_batch_size
:一个布尔值,指定是否通过指数衰减自动寻找适合内存的 batch size
,以避免 CUDA Out-of-Memory
的错误。需要安装 accelerate
(pip 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 Silicon
的 mps
设备。
方法:
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
则表示 first
是 node rank 0
的 rank 0
进程。
在共享文件系统的多节点环境中,你很可能想使用 local=False
,这样只有第一个节点的主进程会进行处理。然而,如果文件系统不是共享的,那么每个节点的主进程将需要做处理,这是默认行为(即,默认为 True
)。
desc
:一个字符串,指定 work
描述文本从而用于调试日志。
to_dict()
:序列化该实例到一个字典,同时用枚举的值来代替 Enum
对象。
to_json_string()
:序列化该实例到一个 json
字符串。
to_sanitized_dict()
:采用 TensorBoard
的 hparams
来序列化该实例。
class transformers.Seq2SeqTrainingArguments
:
xxxxxxxxxx
class transformers.Seq2SeqTrainingArguments(
output_dir: str,
overwrite_output_dir: bool = False,
do_train: bool = False,
do_eval: bool = False,
do_predict: bool = False,
evaluation_strategy: typing.Union[transformers.trainer_utils.IntervalStrategy, str] = 'no',
prediction_loss_only: bool = False,
per_device_train_batch_size: int = 8,
per_device_eval_batch_size: int = 8,
per_gpu_train_batch_size: typing.Optional[int] = None,
per_gpu_eval_batch_size: typing.Optional[int] = None,
gradient_accumulation_steps: int = 1,
eval_accumulation_steps: typing.Optional[int] = None,
eval_delay: typing.Optional[float] = 0,
learning_rate: float = 5e-05,
weight_decay: float = 0.0,
adam_beta1: float = 0.9,
adam_beta2: float = 0.999,
adam_epsilon: float = 1e-08,
max_grad_norm: float = 1.0,
num_train_epochs: float = 3.0,
max_steps: int = -1,
lr_scheduler_type: typing.Union[transformers.trainer_utils.SchedulerType, str] = 'linear',
warmup_ratio: float = 0.0,
warmup_steps: int = 0,
log_level: typing.Optional[str] = 'passive',
log_level_replica: typing.Optional[str] = 'passive',
log_on_each_node: bool = True,
logging_dir: typing.Optional[str] = None,
logging_strategy: typing.Union[transformers.trainer_utils.IntervalStrategy, str] = 'steps',
logging_first_step: bool = False,
logging_steps: int = 500,
logging_nan_inf_filter: bool = True,
save_strategy: typing.Union[transformers.trainer_utils.IntervalStrategy, str] = 'steps',
save_steps: int = 500,
save_total_limit: typing.Optional[int] = None,
save_on_each_node: bool = False,
no_cuda: bool = False,
use_mps_device: bool = False,
seed: int = 42,
data_seed: typing.Optional[int] = None,
jit_mode_eval: bool = False,
use_ipex: bool = False,
bf16: bool = False,
fp16: bool = False,
fp16_opt_level: str = 'O1',
half_precision_backend: str = 'auto',
bf16_full_eval: bool = False,
fp16_full_eval: bool = False,
tf32: typing.Optional[bool] = None,
local_rank: int = -1xpu_backend: typing.Optional[str] = None,
tpu_num_cores: typing.Optional[int] = None,
tpu_metrics_debug: bool = False,
debug: str = '',
dataloader_drop_last: bool = False,
eval_steps: typing.Optional[int] = None,
dataloader_num_workers: int = 0,
past_index: int = -1,
run_name: typing.Optional[str] = None,
disable_tqdm: typing.Optional[bool] = None,
remove_unused_columns: typing.Optional[bool] = True,
label_names: typing.Optional[typing.List[str]] = None,
load_best_model_at_end: typing.Optional[bool] = False,
metric_for_best_model: typing.Optional[str] = None,
greater_is_better: typing.Optional[bool] = None,
ignore_data_skip: bool = False,
sharded_ddp: str = '',
fsdp: str = '',
fsdp_min_num_params: int = 0,
fsdp_transformer_layer_cls_to_wrap: typing.Optional[str] = None,
deepspeed: typing.Optional[str] = None,
label_smoothing_factor: float = 0.0,
optim: typing.Union[transformers.training_args.OptimizerNames, str] = 'adamw_hf',
optim_args: typing.Optional[str] = None,
adafactor: bool = False,
group_by_length: bool = False,
length_column_name: typing.Optional[str] = 'length',
report_to: typing.Optional[typing.List[str]] = None,
ddp_find_unused_parameters: typing.Optional[bool] = None,
ddp_bucket_cap_mb: typing.Optional[int] = None,
dataloader_pin_memory: bool = True,
skip_memory_metrics: bool = True,
use_legacy_prediction_loop: bool = False,
push_to_hub: bool = False,
resume_from_checkpoint: typing.Optional[str] = None,
hub_model_id: typing.Optional[str] = None,
hub_strategy: typing.Union[transformers.trainer_utils.HubStrategy, str] = 'every_save',
hub_token: typing.Optional[str] = None,
hub_private_repo: bool = False,
gradient_checkpointing: bool = False,
include_inputs_for_metrics: bool = False,
fp16_backend: str = 'auto',
push_to_hub_model_id: typing.Optional[str] = None,
push_to_hub_organization: typing.Optional[str] = None,
push_to_hub_token: typing.Optional[str] = None,
mp_parameters: str = '',
auto_find_batch_size: bool = False,
full_determinism: bool = False,
torchdynamo: typing.Optional[str] = None,
ray_scope: typing.Optional[str] = 'last',
ddp_timeout: typing.Optional[int] = 1800,
sortish_sampler: bool = False,
predict_with_generate: bool = False,
generation_max_length: typing.Optional[int] = None,
generation_num_beams: typing.Optional[int] = None
)
参数:
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
值。class transformers.Trainer
:Trainer
是针对 PyTorch
的一个简单的、但是特征完备 feature-complete
的 training
和 eval loop
,并且针对 Transformers
进行了优化。
xxxxxxxxxx
class transformers.Trainer(
model: typing.Union[transformers.modeling_utils.PreTrainedModel, torch.nn.modules.module.Module] = None,
args: TrainingArguments = None,
data_collator: typing.Optional[DataCollator] = None,
train_dataset: typing.Optional[torch.utils.data.dataset.Dataset] = None,
eval_dataset: typing.Optional[torch.utils.data.dataset.Dataset] = None,
tokenizer: typing.Optional[transformers.tokenization_utils_base.PreTrainedTokenizerBase] = None,
model_init: typing.Callable[[], transformers.modeling_utils.PreTrainedModel] = None,
compute_metrics: typing.Union[typing.Callable[[transformers.trainer_utils.EvalPrediction], typing.Dict], NoneType] = None,
callbacks: typing.Optional[typing.List[transformers.trainer_callback.TrainerCallback]] = None,
optimizers: typing.Tuple[torch.optim.optimizer.Optimizer, torch.optim.lr_scheduler.LambdaLR] = (None, None),
preprocess_logits_for_metrics: typing.Callable[[torch.Tensor, torch.Tensor], torch.Tensor] = None
)
参数:
model
:一个 PreTrainedModel
或 torch.nn.Module
对象,指定用于训练、评估、或预测的模型。如果未提供,则必须传入 model_init
参数。
Trainer
被优化为与 PreTrainedModel
一起工作。但是你仍然可以使用自定义的 torch.nn.Module
的模型,只要模型的工作方式与 Transformers
模型相同。
args
:一个 TrainingArguments
,指定训练时的参数。如果未提供,则默认为 TrainingArguments
的 basic instance
,其中 output_dir
设置为当前目录下叫做 tmp_trainer
的目录。
data_collator
:一个 DataCollator
,指定用于从 train_dataset
或 eval_dataset
的元素列表中构建一个 batch
的函数。如果没有提供 tokenizer
,则默认的 DataCollator
为 default_data_collator()
,否则默认的 DataCollator
为 DataCollatorWithPadding
的一个实例。
train_dataset
:一个 torch.utils.data.Dataset
或 torch.utils.data.IterableDataset
,指定训练集。如果它是 HuggingFace
的 Dataset
,那么 model.forward()
方法不需要的列则会被自动移除。
注意,如果它是一个带有一些随机性的 torch.utils.data.IterableDataset
,并且你是以分布式方式进行训练的,你的 iterable dataset
要么使用一个内部的 attribute generator
,该generator
是一个 torch.Generator
用于随机化,且在所有进程上必须是相同的(并且 Trainer
将在每个 epoch
手动设置该 generator
的种子);要么有一个 set_epoch()
方法,在该方法内部设置所用随机数生成器的种子。
eval_dataset
:一个 torch.utils.data.Dataset
或 torch.utils.data.IterableDataset
,指定验证集。如果它是 HuggingFace
的 Dataset
,那么 model.forward()
方法不需要的列则会被自动移除。
如果它是一个字典(键为数据集名称、值为数据集),它将在每个数据集上进行评估,并将数据集名称添加到指标名称之前作为前缀。
tokenizer
:一个 PreTrainedTokenizerBase
,指定用于预处理数据的 tokenizer
。如果提供了该参数,将用于在 batching input
时自动将 input
填充到最大长度,并且它将与模型一起保存,以便更容易重新运行中断的训练、或复用微调后的模型。
model_init
:一个可调用对象,它实例化将要被使用的模型。如果提供的话,对 train()
的每次调用将从这个函数给出的模型的一个新实例开始。
该函数可以有零个参数,也可以有一个包含 optuna/Ray Tune/SigOpt
的 trial 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
:一个可调用对象,它在每个评估 step
中 caching logits
之前对 logits
进行预处理。
preprocess_logits_for_metrics
必须接受两个张量(即, logits
和 labels
),并在按需要处理后返回 logits
。preprocess_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_wrapped
和 self.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
的一个草稿。
xxxxxxxxxx
create_model_card(
language: Optional[str] = None,
license: Optional[str] = None,
tags: Union[str, List[str], None] = None,
model_name: Optional[str] = None,
finetuned_from: Optional[str] = None,
tasks: Union[str, List[str], None] = None,
dataset_tags: Union[str, List[str], None] = None,
dataset: Union[str, List[str], None] = None,
dataset_args: Union[str, List[str], None] = None
)
参数:
language
:一个字符串,指定模型的语言。license
:一个字符串,指定模型的 license
。tags
:一个字符串或关于字符串的列表,指定模型卡片的 tag
。model_name
:一个字符串,指定模型的名称。finetuned_from
:一个字符串,指定当前模型从哪个模型微调而来。tasks
:一个字符串或关于字符串的列表,指定当前模型用于哪些任务。dataset_tags
:一个字符串或关于字符串的列表,指定数据集的 tag
。dataset
:一个字符串或关于字符串的列表,指定数据集的 identifier
。dataset_args
:一个字符串或关于字符串的列表,指定数据集参数。create_optimizer()
:创建优化器 optimizer
。
我们提供了一个合理的默认值,运行良好。如果你想使用自定义的优化器,你可以通过 optimizers
参数在 Trainer
的 init
方法中传递一个元组,或者在子类中重写这个方法。
create_optimizer_and_scheduler(num_training_steps: int )
:创建优化器和学习率调度器 scheduler
。
参数:num_training_steps
:一个整数,指定总的 training step
数量。
我们提供了一个合理的默认值,运行良好。如果你想使用自定义的优化器和调度器,你可以通过 optimizers
参数在 Trainer
的 init
方法中传递一个元组,或者在子类中重写这个方法。
create_scheduler( num_training_steps: int, optimizer: Optimizer = None)
:创建学习率调度器 scheduler
。
参数:参考 create_optimizer_and_scheduler()
。
我们提供了一个合理的默认值,运行良好。如果你想使用自定义的调度器,你可以通过 optimizers
参数在 Trainer
的 init
方法中传递一个元组,或者在子类中重写这个方法。
evaluate()
:评估模型并返回评估指标。注意,需要使用者提供一个方法来计算指标(通过 Training
的 init
方法中的 compute_metrics
参数)。
xxxxxxxxxx
evaluate(
eval_dataset: Optional[Dataset] = None, ignore_keys: Optional[List[str]] = None,
metric_key_prefix: str = "eval" ) -> Dict[str, float]
参数:
eval_dataset
:一个 Dataset
,指定验证集。如果非 None
,那么它将覆盖 self.eval_dataset
。它必须实现 __len__()
方法。对于前向传播不需要的列,都会被自动移除。ignore_keys
:一个关于字符串的列表,指定需要忽略 model output
中的哪些 key
(如果 model output
是一个字典)。metric_key_prefix
:一个字符串,指定添加到指标名称的前缀。默认为 eval
。evaluation_loop()
:prediction/evaluation
的 loop
,由 Trainer.evaluate()
和 Trainer.predict()
所使用。
xxxxxxxxxx
evaluation_loop(
dataloader: DataLoader, description: str, prediction_loss_only: Optional[bool] = None,
ignore_keys: Optional[List[str]] = None, metric_key_prefix: str = "eval" ) -> EvalLoopOutput
参数:
dataloader
:一个 DataLoader
。description
:一个字符串,指定描述文本。prediction_loss_only
:一个布尔值,指定是否仅计算损失函数。evaluate()
。floating_point_ops( inputs: typing.Dict[str, typing.Union[torch.Tensor, typing.Any]] ) -> int
:返回模型的浮点操作的数量。
参数:inputs
:一个字典,键为字符串、值为 torch.Tensor
或其他对象,指定模型的 inputs
和 targets
。浮点运算数量就是在它之上统计的。
对于继承自 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()
:使用 optuna
或 Ray Tune
或 SigOpt
启动一个超参数搜索。
被优化的量由 compute_objective
决定:当没有提供指标时默认为一个返回 evaluation loss
的函数;否则,为所有指标的 sum
。
xxxxxxxxxx
hyperparameter_search(
hp_space: Optional[Callable[["optuna.Trial"], Dict[str, float]]] = None,
compute_objective: Optional[Callable[[Dict[str, float]], float]] = None,
n_trials: int = 20,
direction: str = "minimize",
backend: Optional[Union["str", HPSearchBackend]] = None,
hp_name: Optional[Callable[["optuna.Trial"], str]] = None,
**kwargs,
) -> BestRun
要使用这个方法,你需要在初始化你的 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
:一个字符串,指定超参数搜索的后端。默认为 optuna
、Ray Tune
、或者 SigOpt
,取决于哪一个被安装。如果都安装了,那么默认为 optuna
。hp_name
:一个可调用对象,对它调用的返回值给出了 trial/run
的名称。默认为 None
。kwargs
:传递给 optuna.create_study
或 ray.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
名称,如 train
、eval
、test
。metrics
:一个字典,指定需要被记录的指标值。注意:在分布式环境下,这只对 rank = 0
的进程进行记录。
关于内存报告的说明:为了获得内存使用报告,你需要安装psutil
(pip install psutil
)。然后,当 log_metrics()
运行时你将看到如下的报告:
xxxxxxxxxx
init_mem_cpu_alloc_delta = 1301MB
init_mem_cpu_peaked_delta = 154MB
init_mem_gpu_alloc_delta = 230MB
init_mem_gpu_peaked_delta = 0MB
train_mem_cpu_alloc_delta = 1345MB
train_mem_cpu_peaked_delta = 0MB
train_mem_gpu_alloc_delta = 693MB
train_mem_gpu_peaked_delta = 7MB
其中:
第一个字段(如 train_
)告诉你指标是针对哪个 stage
的。以init_
开头的报告将被添加到第一个 stage
。因此,如果只运行模型评估,init_
的内存使用量将与 eval_
的指标一起被报告。
第三个字段是 cpu
或 gpu
,告诉你这是通用 RAM
指标、还是 GPU0
的内存指标。
alloc_delta
是 stage
结束和 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
的峰值内存是用一个采样线程测量的。由于 python
的GIL
,如果该线程在最高内存使用时没有机会运行,它可能会错过一些峰值内存。因此,这个报告可能比实际情况要少。使用 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.5
到 2GB
的 GPU
内存。
请注意,这个 tracker
并不考虑Trainer
的 __init__
、训练、评估、以及预测的调用之外的内存分配。
因为 evaluation
调用可能发生在训练过程中,我们无法处理嵌套调用,因为 torch.cuda.max_memory_allocated
是一个单一的计数器,所以如果它被一个嵌套的 evaluation
调用重置,train
的 tracker
将报告错误的信息。如果这个 pytorch
问题得到解决,就有可能把这个类改成可重入的。在那之前,我们将只追踪外层的 train
、evaluation
和 predict
方法。这意味着如果 eval
在 train
过程中被调用,那么将 train
阶段统计的内存报告其实是 eval
的。
这也意味着,如果任何其他与 Trainer
一起使用的工具调用 torch.cuda.reset_peak_memory_stats
,gpu
峰值内存统计可能是无效的。而且 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()
那样返回指标。
如果你的 predictions
或 labels
有不同的序列长度(例如,在 token
分类任务中做动态填充), predictions
将被填充(右填充),以允许拼接成一个数组。 padding index = -100
。
prediction_loop()
:prediction/evaluation
的 loop
,由 Trainer.evaluate()
和 Trainer.predict()
所使用。
xxxxxxxxxx
prediction_loop(
dataloader: DataLoader, description: str, prediction_loss_only: Optional[bool] = None,
ignore_keys: Optional[List[str]] = None, metric_key_prefix: str = "eval" ) -> PredictionOutput
参数:参考 evaluation_loop()
。
prediction_step()
:在模型上使用 inputs
执行单个 evaluation step
。
xxxxxxxxxx
prediction_step(
model: nn.Module, inputs: Dict[str, Union[torch.Tensor, Any]],prediction_loss_only: bool,
ignore_keys: Optional[List[str]] = None
) -> Tuple[Optional[torch.Tensor], Optional[torch.Tensor], Optional[torch.Tensor]]
参数:
model
:一个 nn.Module
对象,指定被使用的模型。inputs
:一个字典,键为字符串、值为 torch.Tensor
或其他对象,指定模型的 inputs
和 targets
。evaluation_loop
。返回一个元组,分别为 loss, logits, labels
(可能有的项没有)。
push_to_hub(commit_message: Optional[str] = "End of training", blocking: bool = True, **kwargs) -> str
:将 self.model
和 self.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()
:训练模型。
xxxxxxxxxx
train(
resume_from_checkpoint: Optional[Union[str, bool]] = None,
trial: Union[optuna.Trial, Dict[str, Any]] = None,
ignore_keys_for_eval: Optional[List[str]] = None, **kwargs)
参数:
resume_from_checkpoint
:一个字符串或布尔值。
Trainer
前一个实例所保存的 checkpoint
的 local path
。训练将从这个 checkpoint
开始继续。True
,那么加载 args.output_dir
中的最近一个 checkpoint
,该checkpoint
由 Trainer
的前一个实例保存。训练将从这个 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
上的训练损失。
class transformers.Seq2SeqTrainer
:
xxxxxxxxxx
class transformers.Seq2SeqTrainer(
model: typing.Union[transformers.modeling_utils.PreTrainedModel, torch.nn.modules.module.Module] = None,
args: TrainingArguments = None,
data_collator: typing.Optional[DataCollator] = None,
train_dataset: typing.Optional[torch.utils.data.dataset.Dataset] = None,
eval_dataset: typing.Optional[torch.utils.data.dataset.Dataset] = None,
tokenizer: typing.Optional[transformers.tokenization_utils_base.PreTrainedTokenizerBase] = None,
model_init: typing.Callable[[], transformers.modeling_utils.PreTrainedModel] = None,
compute_metrics: typing.Union[typing.Callable[[transformers.trainer_utils.EvalPrediction], typing.Dict], NoneType] = None,
callbacks: typing.Optional[typing.List[transformers.trainer_callback.TrainerCallback]] = None,
optimizers: typing.Tuple[torch.optim.optimizer.Optimizer, torch.optim.lr_scheduler.LambdaLR] = (None, None),
preprocess_logits_for_metrics: typing.Callable[[torch.Tensor, torch.Tensor], torch.Tensor] = None
)
参数参考 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 search
的 beam size
。 1
意味着不使用 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()
。
默认情况下,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
。你可以将 TrainingArguments
的 hub-strategy
值调整为如下两种:
"checkpoint"
:latest checkpoint
也被推送到一个名为 last-checkpoint
的子文件夹中,允许你用trainer.train(resume_from_checkpoint="output_dir/last-checkpoint")
轻松恢复训练。"all_checkpoints"
:所有 checkpoints
都被推送到输出文件夹中(所以你会在 final repo
的每个文件夹中得到一个 checkpoint
文件夹)。默认情况下,Trainer
将对主进程使用 logging.INFO
、对副本使用 logging.WARNING
(如果有副本的话)。这些默认值可以通过TrainingArguments
的参数被覆盖,以使用 5
个 logging level
中的任何一个:
log_level
参数:用于主进程的 logging level
设置。log_level_replica
参数:用于副本进程的 logging level
设置。此外,如果 TrainingArguments
的 log_on_each_node = False
,只有主节点会使用其主进程的 log level setting
,所有其他节点将使用副本的 log level setting
。
注意,Trainer
将在其 Trainer.__init__()
中为每个节点单独设置 transformers
的 log level
。因此,如果你在创建 Trainer
对象之前就调用了 transformers
的函数,你可能希望在 Trainer
创建之前就为 transformers
设置 log level
。示例:
xxxxxxxxxx
[...]
logger = logging.getLogger(__name__)
# Setup logging
logging.basicConfig(
format="%(asctime)s - %(levelname)s - %(name)s - %(message)s",
datefmt="%m/%d/%Y %H:%M:%S",
handlers=[logging.StreamHandler(sys.stdout)],
)
# set the main code and the modules it uses to the same log-level according to the node
log_level = training_args.get_process_log_level()
logger.setLevel(log_level)
datasets.utils.logging.set_verbosity(log_level)
transformers.utils.logging.set_verbosity(log_level)
trainer = Trainer(...)
如果你只想看到主节点上的警告,而所有其他节点不打印任何很可能是重复的警告,你可以这样运行:
xxxxxxxxxx
my_app.py ... --log_level warning --log_level_replica error
在多节点环境中,如果你也不希望每个节点的主进程的日志重复,你要把上面的内容改为:
xxxxxxxxxx
my_app.py ... --log_level warning --log_level_replica error --log_on_each_node 0
如果你需要你的应用程序尽可能的安静,你可以这样做:
xxxxxxxxxx
my_app.py ... --log_level error --log_level_replica error --log_on_each_node 0
当从 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
。
这里讨论一下:如何告诉你的程序哪些 GPU
要被使用、以及按照什么顺序来使用。
当使用 DistributedDataParallel
并且只使用 GPU
的一个子集时,你只需指定要使用的 GPU
的数量。例如,如果你有 4
个GPU
,但你希望使用前两个,你可以这样做:
xxxxxxxxxx
python -m torch.distributed.launch --nproc_per_node=2 trainer-program.py ...
如果你已经安装了 accelerate
或 deepspeed
,你也可以通过使用以下方法之一来完成同样的工作:
xxxxxxxxxx
accelerate launch --num_processes 2 trainer-program.py ...
deepspeed --num_gpus 2 trainer-program.py ...
你不需要使用 Accelerate
或 Deepspeed
的 integration features
来使用这些 launchers
。
到目前为止,我们可以告诉程序要使用多少个 GPU
。现在讨论一下如何选择特定的 GPU
并控制其顺序。
CUDA_VISIBLE_DEVICES
环境变量可以帮助你控制使用哪些GPU
、以及GPU
的顺序,方法是:将环境变量 CUDA_VISIBLE_DEVICES
设置为将要使用的 GPU
的列表。例如,假设有4
个 GPU
:0, 1, 2, 3
。为了只在物理 GPU 0
和 GPU 2
上运行,你可以这样做:
xxxxxxxxxx
CUDA_VISIBLE_DEVICES=0,2 python -m torch.distributed.launch trainer-program.py ...
所以现在 pytorch
将只看到 2
个 GPU
,其中你的物理 GPU 0
和 GPU 2
分别映射到 cuda:0
和 cuda:1
。
你甚至可以改变它们的顺序:
xxxxxxxxxx
CUDA_VISIBLE_DEVICES=2,0 python -m torch.distributed. launch trainer-program.py ...
现在你的物理 GPU 0
和 GPU 2
被映射到 cuda:1
和 cuda:0
上。
上面的例子都是针对 DistributedDataParallel
的使用模式,但同样的方法也适用于DataParallel
:
xxxxxxxxxx
CUDA_VISIBLE_DEVICES=2,0 python trainer-program.py ...
要模拟一个没有 GPU
的环境,只需将这个环境变量设置为空值,像这样:
xxxxxxxxxx
CUDA_VISIBLE_DEVICES= python trainer-program.py ...
与任何环境变量一样,你也可以导出这些环境变量,而不是将这些环境变量添加到命令行中,例如:
xxxxxxxxxx
export CUDA_VISIBLE_DEVICES=0,2
python -m torch.distributed.launch trainer-program.py ...
但这种方法可能会让人困惑,因为你可能会忘记你之前设置的环境变量,不明白为什么会使用错误的 GPU
。因此,通常的做法是在同一命令行中只为特定的运行设置环境变量。
有一个额外的环境变量 CUDA_DEVICE_ORDER
用于控制物理设备的排序方式。两个选择是:
根据 PCIe
总线 ID
排序(与 nvidia-smi
的顺序一致)。这是默认的方式。
xxxxxxxxxx
export CUDA_DEVICE_ORDER=PCI_BUS_ID
根据 GPU
的计算能力排序。
xxxxxxxxxx
export CUDA_DEVICE_ORDER=FASTEST_FIRST
大多数情况下,你不需要关心这个环境变量。但是,假如你有一个旧且慢的 GPU
显卡、以及一个新且快的 GPU
显卡,并且不恰当的插入方式使得旧显卡看起来是第一位的,那么这个环境变量就非常有用。
解决这个问题的方法之一是交换显卡的插入位置。或者设置 CUDA_DEVICE_ORDER=FASTEST_FIRST
将总是把较快的新卡放在第一位。不过这将会有些混乱,因为 nvidia-smi
仍然会按照 PCIe
顺序报告它们。
交换顺序的另一个解决方案是使用:
xxxxxxxxxx
export CUDA_VISIBLE_DEVICES=1,0
Trainer
已经被扩展到支持一些库,这些库可能会极大地改善你的训练时间并适应更大的模型。
目前,它支持第三方解决方案,如 DeepSpeed, PyTorch FSDP, FairScale
,它们实现了论文 《ZeRO: Memory Optimizations Toward Training Trillion Parameter Models》
的一部分。
截至本文写作时,这种提供的支持是新的和实验性的。虽然对 DeepSpeed
和 PyTorch FSDP
的支持是活跃的,我们也欢迎围绕它们的问题,但我们不再支持 FairScale
的集成,因为 FairScale
已经集成到 PyTorch
主系统中。
CUDA Extension
安装:截至目前,FairScale
和 Deepspeed
都需要编译 CUDA C++
代码才能使用。
虽然所有的安装问题都应该通过 FairScale
和 Deepspeed
的相应 GitHub issue
来处理,但在构建任何需要构建 CUDA Extension
的 PyTorch extension
时,可能会遇到一些常见的问题。因此,如果你在执行如下指令时遇到了与 CUDA
相关的 build issue
:
xxxxxxxxxx
pip install fairscale
pip install deepspeed
那么请阅读以下说明。在这些说明中,我们举例说明了当 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
环境变量中时,可以通过以下操作找到安装位置:
xxxxxxxxxx
which nvcc
如果你的系统中没有安装 CUDA
,请先安装它。
可能的问题 2
:你可能在系统中安装了不止一个 CUDA toolkit
,如:
xxxxxxxxxx
/usr/local/cuda-10.2
/usr/local/cuda-11.0
现在,在这种情况下,你需要确保你的 PATH
和 LD_LIBRARY_PATH
环境变量包含所需 CUDA
版本的正确路径。通常情况下,软件包安装程序会将这些设置为包含最仅安装的任何版本。如果你遇到这样的问题,即尽管你已经在全系统安装了 CUDA
,但由于找不到正确的 CUDA
版本而导致 package
构建失败,这意味着你需要调整上述两个环境变量:
xxxxxxxxxx
export PATH=/usr/local/cuda-10.2/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda-10.2/lib64:$LD_LIBRARY_PATH
可能的问题 3
:一些旧的 CUDA
版本可能会拒绝使用较新的编译器进行编译。例如,你有 gcc-9
,但它想要 gcc-7
。有多种方法可以解决这个问题:
如果你能安装最新的CUDA toolkit
,它通常应该支持较新的编译器。
另外,你可以在你已经有的编译器之外再安装低版本的编译器;或者,你已经有了低版本的编译器但它不是默认的,所以构建系统看不到它。下面的方法可能会有帮助:
xxxxxxxxxx
sudo ln -s /usr/bin/gcc-7 /usr/local/cuda-10.2/bin/gcc
sudo ln -s /usr/bin/g++-7 /usr/local/cuda-10.2/bin/g++
这里,我们从 /usr/local/cuda-10.2/bin/gcc
建立了一个指向 gcc-7
的符号链接,由于 /usr/local/cuda-10.2/bin/
应该在 PATH
环境变量中(见前面问题的解决方案),它应该找到 gcc-7
(和 g++7
),然后构建就会成功。
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
:
xxxxxxxxxx
python -m torch.distributed. launch --nproc_per_node=NUMBER_OF_GPUS_YOU_HAVE ...
分片策略:
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
。要将 parameters
和 gradients
卸载到 CPU
,请在命令行参数中添加:
xxxxxxxxxx
--fsdp "full_shard offload" # or --fsdp "shard_grad_op offload"
要使用 default_auto_wrap_policy
来采用 FSDP
自动递归地 wrap layers
,请在命令行参数中添加:
xxxxxxxxxx
--fsdp "full_shard auto_wrap" # or --fsdp "shard_grad_op auto_wrap"。
要同时启用 CPU
卸载和 auto wrapping
,请在命令行参数中添加:
xxxxxxxxxx
--fsdp "full_shard offload auto_wrap" # or --fsdp "shard_grad_op offload auto_wrap"
如果启用了 auto wrapping
,你可以使用 transformer based auto wrap policy
或 size based auto wrap policy
。
对于 transformer based auto wrap policy
,请在命令行参数中加入:
xxxxxxxxxx
--fsdp_transformer_layer_cls_to_wrap <value>
这指定了要包装的 transformer layer class name
(区分大小写),例如,BertLayer, GPTJBlock, T5Block,...
。这很重要,因为共享权重的子模块(例如,embedding layer
)不应该最终出现在不同的 FSDP wrapped units
中。
使用这个策略,每个包含 Multi-Head Attention followed by couple of MLP layers
的 block
都会发生包装。其余的层,包括 shared embeddings
,都方便地被包裹在同一个最外层的 FSDP unit
中。因此,对于 transformer based
的模型,可以使用这个策略。
对于 size based auto wrap policy
,请在命令行参数中加入:
xxxxxxxxxx
--fsdp_min_num_params <number>
它指定了 FSDP auto wrapping
的最少的 parameters
数量。
一些注意事项:
FSDP
目前不支持混合精度,因为我们在等待 PyTorch
修复对混合精度的支持。FSDP
目前不支持multiple parameter groups
。callbacks
是一种对象,它可以自定义 PyTorch Trainer
中 training loop
(TensorFlow
中尚未实现此功能)。例如,检查 training loop
状态(用于进度报告、在 TensorBoard
或其他 ML
平台上进行 logging
)并做出决定(如 early stopping
)。
callbacks
是 "read only"
的代码,除了它们返回的 TrainerControl
对象外,它们不能改变 training loop
中的任何东西。如果需要改变 training loop
,那么你应该对 Trainer
进行子类化并覆盖你想要改变的方法。
默认情况下,Trainer
将使用以下 callbacks
:
DefaultFlowCallback
:处理 logging, saving, evaluation
的默认 callback
。PrinterCallback
或 ProgressCallback
:显示训练进度,或打印日志。如果你通过 TrainingArguments
禁用 tqdm
,那么Trainer
就使用 PrinterCallback
;否则就使用 ProgressCallback
。TensorBoardCallback
:如果 tensorboard
可用(安装了 PyTorch >= 1.4
或 tensorboardX
),则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
。实现 callbacks
的主要类是 TrainerCallback
。它获得用于实例化 Trainer
的 TrainingArguments
,可以通过 TrainerState
访问该 Trainer
的内部状态,并且可以通过 TrainerControl
对 training loop
采取一些行动。
class transformers.TrainerCallback
:TrainerCallback
,它将在一些事件中检查 training loop
的状态并作出一些决定。
初始化参数:
args
:一个 TrainingArguments
,指定用于实例化 Trainer
的训练参数。
state
:一个 TrainerState
,指定训练器的当前状态。
control
:一个 TrainerControl
,指定返回给训练器的对象,它可以用来做一些决定。
model
:一个 PreTrainedModel
或 torch.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
你需要的关键字参数。例如:xxxxxxxxxx
class PrinterCallback(TrainerCallback):
def on_log(self, args, state, control, logs=None, **kwargs):
_ = logs.pop("total_flos", None)
if state.is_local_process_zero:
print(logs)
将一个自定义的 callback
注册到 PyTorch Trainer
的例子:
xxxxxxxxxx
class MyCallback(TrainerCallback):
def on_train_begin(self, args, state, control, **kwargs):
print("Starting training")
trainer = Trainer(model,args,train_dataset=train_dataset,eval_dataset=eval_dataset,
callbacks=[MyCallback], # 可以传入一个类,也可以传入一个 callback 对象
)
也可以通过如下的方式注册:
xxxxxxxxxx
trainer = Trainer(...)
trainer.add_callback(MyCallback) # 或者 trainer.add_callback(MyCallback())
library
中目前可用的 TrainerCallback
:
xxxxxxxxxx
class transformers.integrations.CometCallback() # send logs to CometML
def setup(args, state, model)
class transformers.DefaultFlowCallback() # default callback for logging, saving, evaluation
class transformers.PrinterCallback() # just prints the logs
class transformers.ProgressCallback() # displays the progress of training or evaluation
class transformers.EarlyStoppingCallback( # handles early stopping, Use with TrainingArguments metric_for_best_model
early_stopping_patience: int = 1,
early_stopping_threshold: typing.Optional[float] = 0.0)
class transformers.integrations.TensorBoardCallback( tb_writer = None ) # sends the logs to TensorBoard
class transformers.integrations.WandbCallback() # sends the logs to Weight and Biases
def setup(args, state, model, **kwargs )
class transformers.integrations.MLflowCallback() # sends the logs to MLflow
def setup(args, state, model)
class transformers.integrations.AzureMLCallback(azureml_run = None) # sends the logs to AzureML
class transformers.integrations.CodeCarbonCallback() # tracks the CO2 emission of training
class transformers.integrations.NeptuneCallback( # sends the logs to Neptune
api_token: typing.Optional[str] = None,
project: typing.Optional[str] = None,
name: typing.Optional[str] = None,
base_namespace: str = 'finetuning',
run: typing.Optional[ForwardRef('Run')] = None,
log_parameters: bool = True,
log_checkpoints: typing.Optional[str] = None,
**neptune_run_kwargs
)
class transformers.integrations.ClearMLCallback() # sends the logs to ClearML
class transformers.TrainerState
:一个包含Trainer
内部状态的类,在 checkpointing
时将伴随着模型和优化器保存并传递给 TrainerCallback
。
xxxxxxxxxx
class transformers.TrainerState(
epoch: typing.Optional[float] = None,
global_step: int = 0,
max_steps: int = 0,
num_train_epochs: int = 0,
total_flos: float = 0,
log_history: typing.List[typing.Dict[str, float]] = None,
best_metric: typing.Optional[float] = None,
best_model_checkpoint: typing.Optional[str] = None,
is_local_process_zero: bool = True,
is_world_process_zero: bool = True,
is_hyper_param_search: bool = False,
trial_name: str = None,
trial_params: typing.Dict[str, typing.Union[str, float, int, bool]] = None
)
参数:
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
需要经过 batch
。
方法:
load_from_json(json_path: str )
:从 json_path
的内容创建一个 TrainerState
实例。save_to_json(json_path: str )
:将当前实例的内容以 JSON
格式存储到 json_path
。class class transformers.TrainerControl
:一个处理 Trainer
控制流的类。这个类被 TrainerCallback
用来激活 training loop
中的一些开关。
xxxxxxxxxx
class transformers.TrainerControl(
should_training_stop: bool = False,
should_epoch_stop: bool = False,
should_save: bool = False,
should_evaluate: bool = False,
should_log: bool = False
)
参数:
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
。class transformers.KerasMetricCallback
:用于 keras
的 callback
,用于在每个 epoch
结束时计算指标。
与普通的 Keras
指标不同,这些指标不需要由 TF
来编译。它对于像 BLEU
和 ROUGE
这样需要字符串操作或 generation loop
的常见 NLP
指标特别有用,这些指标不能被编译。预测(或生成)将在 eval_dataset
上计算,然后以 np.ndarray
格式传递给metric_fn
。metric_fn
应该计算指标并返回一个字典,字典的键为指标名、值为指标值。
xxxxxxxxxx
class transformers.KerasMetricCallback(
metric_fn: typing.Callable,
eval_dataset: typing.Union[tensorflow.python.data.ops.dataset_ops.DatasetV2, numpy.ndarray, tensorflow.python.framework.ops.Tensor, tuple, dict],
output_cols: typing.Optional[typing.List[str]] = None,
label_cols: typing.Optional[typing.List[str]] = None,
batch_size: typing.Optional[int] = None,
predict_with_generate: bool = False,
use_xla_generation: bool = False,
generate_kwargs: typing.Optional[dict] = None
)
参数:
metric_fn
:一个可调用对象,指定度量函数。调用metric_fn
时需要提供两个参数:predictions
和 labels
,它们分别对应了模型的输出结果、以及 ground-truth label
。metric_fn
函数需要返回一个字典,字典的键为指标名、值为指标值。
下面是一个摘要模型计算 ROUGE
分数的 metric_fn
的示例:
xxxxxxxxxx
from datasets import load_metric
rouge_metric = load_metric("rouge")
def rouge_fn(predictions, labels):
decoded_predictions = tokenizer.batch_decode(predictions, skip_special_tokens=True)
decoded_labels = tokenizer.batch_decode(labels, skip_special_tokens=True)
result = rouge_metric.compute(predictions=decoded_predictions, references=decoded_labels)
return {key: value.mid.fmeasure * 100 for key, value in result.items()}
eval_dataset
:一个 tf.data.Dataset
或字典或元组或 np.ndarray
或 tf.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
时,最好将你的输入填充到相同的大小,或者在你的 tokenizer
或 DataCollator
中使用 pad_to_multiple_of
参数,这将减少 unique input shape
的数量,并节省大量的编译时间。
如果 predict_with_generate = False
,该参数没有影响。
generate_kwargs
:关键字参数,用于 generating
时传递给 model.generate()
的关键字参数。
如果 predict_with_generate = False
,该参数没有影响。
class transformers.PushToHubCallback
:用于 keras
的 callback
,用于定期保存和推送模型到 Hub
。
xxxxxxxxxx
class transformers.PushToHubCallback(
output_dir: typing.Union[str, pathlib.Path],
save_strategy: typing.Union[str, transformers.trainer_utils.IntervalStrategy] = 'epoch',
save_steps: typing.Optional[int] = None,
tokenizer: typing.Optional[transformers.tokenization_utils_base.PreTrainedTokenizerBase] = None,
hub_model_id: typing.Optional[str] = None,
hub_token: typing.Optional[str] = None,
checkpoint: bool = False,
**model_card_args
)
参数:
output_dir
:一个字符串,指定输出目录,model predictions
和 model checkpoints
将被写入该目录并与 Hub
上的 repo
同步。save_strategy/save_steps
:参考 transformers.TrainingArguments
。tokenizer
:一个 PreTrainedTokenizerBase
,指定模型使用的 tokenizer
。如果提供,将与模型权重一起上传到 repo
。hub_model_id/hub_token
:参考 transformers.TrainingArguments
。checkpoint
:一个布尔值,指定是否保存完整的 training checkpoints
(包括 epoch
和 optimizer state
)以允许恢复训练。只在 save_strategy="epoch"
时可用。示例:
xxxxxxxxxx
from transformers.keras_callbacks import PushToHubCallback
push_to_hub_callback = PushToHubCallback(
output_dir="./model_save",
tokenizer=tokenizer,
hub_model_id="gpt5-7xlarge",
)
model.fit(train_dataset, callbacks=[push_to_hub_callback])
Transformers
有一个集中化的日志系统,默认的 verbosity level
是 WARNING
。有多种方式可以改变 verbosity level
:
可以在代码中直接指定:
xxxxxxxxxx
from transformers.utils import logging
logging.set_verbosity_info()
# 然后使用 logger
logger = logging.get_logger("transformers")
logger.info("INFO")
logger.warning("WARN")
可以通过环境变量指定:
xxxxxxxxxx
TRANSFORMERS_VERBOSITY=error ./myprogram.py
verbosity level
(从最少的日志到最多的日志)为:
transformers.logging.CRITICAL
或 transformers.logging.FATAL
(整数值 50
):仅报告最关键的错误。transformers.logging.ERROR
(整数值 40
):仅报告错误。transformers.logging.WARNING
或 transformers.logging.WARN
(整数值 30
):仅报告错误和警告。这是默认级别。transformers.logging.INFO
(整数值 20
):报告错误、警告和基本信息。transformers.logging.DEBUG
(整数值 10
):报告所有信息。默认情况下,在模型下载过程中会显示 tqdm
进度条。logging.disable_progress_bar()
和 logging.enable_progress_bar()
可以用来禁止或开启这种行为。
获取和配置 verbosity level
:
xxxxxxxxxx
transformers.utils.logging.set_verbosity_warning()
transformers.utils.logging.set_verbosity_info()
transformers.utils.logging.set_verbosity_debug()
transformers.utils.logging.get_verbosity() -> int
transformers.utils.logging.set_verbosity(verbosity: int )
transformers.utils.logging.get_logger(name: typing.Optional[str] = None )
:获取指定名字的 logger
。
这个函数不应该被直接访问,除非你正在编写一个自定义的 transformers module
。
开启和禁用 HuggingFace Transformers’s root logger
的默认 handler
:
xxxxxxxxxx
transformers.utils.logging.enable_default_handler()
transformers.utils.logging.disable_default_handler()
transformers.utils.logging.enable_explicit_format()
:为每个 HuggingFace Transformers
的 logger
启用显式格式化。显式格式化的内容如下:
xxxxxxxxxx
[LEVELNAME|FILENAME|LINE NUMBER] TIME >> MESSAGE
当前与 root logger
绑定的所有 handler
都受此方法影响。
transformers.utils.logging.reset_format()
:为每个 HuggingFace Transformers
的 logger
重设格式化。
当前与 root logger
绑定的所有 handler
都受此方法影响。
开启和禁用 tqdm
进度条:
xxxxxxxxxx
transformers.utils.logging.enable_progress_bar()
transformers.utils.logging.disable_progress_bar()
optimization
模块提供如下功能:
optimizer
,可用于对模型进行微调。schedule
,它们是以继承自 _LRSchedule
的 schedule
对象的形式提供。gradient accumulation
类,用于累积多个 batch
的梯度。class transformers.AdamW
:具有固定的 weight decay
的 Adam
。
xxxxxxxxxx
class transformers.AdamW(
params: typing.Iterable[torch.nn.parameter.Parameter],
lr: float = 0.001,
betas: typing.Tuple[float, float] = (0.9, 0.999),
eps: float = 1e-06,
weight_decay: float = 0.0,
correct_bias: bool = True,
no_deprecation_warning: bool = False
)
参数:
params
:一个 nn.parameter.Parameter
可迭代对象或字典,指定需要被优化的 parameters
或 parameter groups
。lr
:一个浮点数,指定初始学习率。betas
:一个 Tuple[float,float]
元组,指定 Adam
的参数 eps
:一个浮点数,用于数值稳定。weight_decay
:一个浮点数,指定权重衰减。correct_bias
:一个布尔值,指定是否在 Adam
中 correct bias
。例如,在 BERT TF repo
中,他们使用 False
。no_deprecation_warning
:一个布尔值,指定是否屏蔽 deprecation warning
。方法:
step( closure: typing.Callable = None)
:指定单个 optimization step
。
参数:closure
:一个可调用对象,用于重新评估模型并返回 loss
。
class transformers.Adafactor(PyTorch)
:Adafactor
优化器。
xxxxxxxxxx
class transformers.Adafactor(
paramslr = None,
eps = (1e-30, 0.001),
clip_threshold = 1.0,
decay_rate = -0.8,
beta1 = None,
weight_decay = 0.0,
scale_parameter = True,
relative_step = True,
warmup_init = False
)
参数:
params
:参考 AdamW
。lr
:external
的学习率。eps
:一个 Tuple[float, float]
元组,指定正则化系数,分别用于 square gradient
和 parameter 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
。
class transformers.AdamWeightDecay(TensorFlow)
:在梯度上启用了 L2
权重衰减和 clip_by_global_norm
的 Adam
。
xxxxxxxxxx
class transformers.AdamWeightDecay(
learning_rate: typing.Union[float, keras.optimizers.schedules.learning_rate_schedule.LearningRateSchedule] = 0.001,
beta_1: float = 0.9,
beta_2: float = 0.999,
epsilon: float = 1e-07,
amsgrad: bool = False,
weight_decay_rate: float = 0.0,
include_in_weight_decay: typing.Optional[typing.List[str]] = None,
exclude_from_weight_decay: typing.Optional[typing.List[str]] = None,
name: str = 'AdamWeightDecay',
**kwargs
)
参数:
learning_rate
:一个浮点数或 tf.keras.optimizers.schedules.LearningRateSchedule
,指定学习率或学习率调度。
beta_1
:一个浮点数,指定 Adam
的
beta_2
:一个浮点数,指定 Adam
的
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_decay
和 exclude_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
。transformers.create_optimizer()
:创建一个 optimizer
。
xxxxxxxxxx
transformers.create_optimizer(
init_lr: float,
num_train_steps: int,
num_warmup_steps: int,
min_lr_ratio: float = 0.0,
adam_beta1: float = 0.9,
adam_beta2: float = 0.999,
adam_epsilon: float = 1e-08,
adam_clipnorm: typing.Optional[float] = None,
adam_global_clipnorm: typing.Optional[float] = None,
weight_decay_rate: float = 0.0,
power: float = 1.0,
include_in_weight_decay: typing.Optional[typing.List[str]] = None )
参数:
init_lr
:一个浮点数,指定 warmup
阶段结束时的期望学习率。num_train_steps
:一个整数,指定总的训练 step
数。num_warmup_steps
:一个整数,指定 warmup step
数。min_lr_ratio
:一个浮点数,学习率线性衰减结束时的最终学习率为 init_lr * min_lr_ratio
。adam_beta1
:一个浮点数,指定 Adam
的 adam_beta2
:一个浮点数,指定 Adam
的 adam_epsilon
:一个浮点数,指定 Adam
中的 adam_clipnorm
:一个浮点数,如果不是None
,指定每个权重梯度范数的裁剪值。adam_global_clipnorm
:一个浮点数,如果不是None
,把所有权重梯度拼接起来,然后这个拼接结果的范数的裁剪值。weight_decay_rate
:一个浮点数,指定权重衰减系数。power
:一个浮点数,指定多项式衰减的幂次。include_in_weight_decay
:参考 AdamWeightDecay
。class transformers.SchedulerType
:一个枚举类型。
xxxxxxxxxx
class transformers.SchedulerType(
value, names = None, module = None, qualname = None, type = None, start = 1
)
transformers.get_scheduler()
:一个统一的 API
,根据 scheduler name
来获取 scheduler
。
xxxxxxxxxx
transformers.get_scheduler(
name: typing.Union[str, transformers.trainer_utils.SchedulerType],
optimizer: Optimizer,
num_warmup_steps: typing.Optional[int] = None,
num_training_steps: typing.Optional[int] = None
)
参数:
name
:一个字符串或 SchedulerType
,指定 scheduler
的名字。optimizer
:一个 torch.optim.Optimizer
对象,指定优化器。num_warmup_steps
:一个整数,指定需要的 warmup step
的数量。不是所有的 scheduler
都需要这个参数(因此这个参数是可选的)。如果这个参数没有设置,而 scheduler
需要这个参数,则将引发一个错误。num_training_steps
:一个整数,指定需要的 training step
的数量。不是所有的 scheduler
都需要这个参数(因此这个参数是可选的)。如果这个参数没有设置,而 scheduler
需要这个参数,则将引发一个错误。transformers.get_constant_schedule( optimizer: Optimizer, last_epoch: int = -1)
:创建一个常数学习率的调度器。
参数:
optimizer
:一个 torch.optim.Optimizer
对象,指定优化器。last_epoch
:一个整数,指定 last epoch
的索引,用于恢复训练。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()
。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()
。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()
。transformers.get_linear_schedule_with_warmup( optimizer, num_warmup_steps, num_training_steps, last_epoch = -1)
:创建一个带 warmup
的线性调度器。
参数:参考 get_constant_schedule_with_warmup()
。
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()
。class transformers.WarmUp(TensorFlow)
:在一个给定的 learning rate decay schedule
上应用一个 warmup
。
xxxxxxxxxx
class transformers.WarmUp(
initial_learning_rate: float,
decay_schedule_fn: typing.Callable,
warmup_steps: int,
power: float = 1.0,
name: str = None
)
参数:
initial_learning_rate
:一个浮点数,指定 warmup
结束时的学习率。decay_schedule_fn
:一个可调用对象,指定在 warmup
之后所采用的 schedule
函数。warmup_steps
:一个整数,指定 warmup
阶段的 step
数。power
:一个浮点数,指定用于多项式 warmup
的指数因子(默认为线性 warmup
)。name
:一个字符串,指定在 schedule
阶段返回的张量的 name prefix
。class transformers.GradientAccumulator(TensorFlow)
:gradient accumulation
工具函数。
当用于分布式训练时,应在副本上下文中调用该 accumulator
。梯度将在每个副本上局部地累积,不需要同步。然后用户应该调用 .gradients
,如果需要的话则 scale
梯度,并将结果传递给 apply_gradients
。
方法:
reset()
:在当前 replica
上 reset
被累计的梯度。任何多模态模型都需要一个对象来编码或解码数据。该数据分组了几种模态(文本、视频、音频)。这由被称为 processor
的对象处理,processor
将两个或更多的 processing
对象组合在一起,如 tokenizer
(用于文本模态)、image processors
(用于视觉)和 feature extractors
(用于音频)。
class transformers.ProcessorMixin(*args, **kwargs )
:所有 processor
的 mixin
,用于保存和加载。
方法:
from_pretrained(pretrained_model_name_or_path, **kwargs )
:用一个预训练模型来初始化一个 processor
。
参数:参考 PreTrainedTokenizerBase.from_pretrained()
。
push_to_hub()
:将 processor
上传到 Model Hub
(对应于本地 repo clone
的远程 repo path
或 repo name
)。
xxxxxxxxxx
push_to_hub(repo_id: str, use_temp_dir: typing.Optional[bool] = None, commit_message: typing.Optional[str] = None, private: typing.Optional[bool] = None, use_auth_token: typing.Union[bool, str, NoneType] = None, max_shard_size: typing.Union[int, str, NoneType] = '10GB', create_pr: bool = False, **deprecated_kwargs )
参数:参考 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()
。
feature extractor
负责为音频模型或视觉模型准备输入特征。这包括:
Log-Mel Spectrogram
特征)。padding, normalization, conversion to Numpy/PyTorch/TensorFlow tensors
。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()
。class transformers.SequenceFeatureExtractor
:用于语音识别的通用的feature extraction
类。
xxxxxxxxxx
class transformers.SequenceFeatureExtractor(
feature_size: int, sampling_rate: int, padding_value: float, **kwargs
)
参数:
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_side
、self.padding_value
)。
xxxxxxxxxx
pad(
processed_features: typing.Union[transformers.feature_extraction_utils.BatchFeature, typing.List[transformers.feature_extraction_utils.BatchFeature], typing.Dict[str, transformers.feature_extraction_utils.BatchFeature], typing.Dict[str, typing.List[transformers.feature_extraction_utils.BatchFeature]], typing.List[typing.Dict[str, transformers.feature_extraction_utils.BatchFeature]]],
padding: typing.Union[bool, str, transformers.utils.generic.PaddingStrategy] = True,
max_length: typing.Optional[int] = None,
truncation: bool = False,
pad_to_multiple_of: typing.Optional[int] = None,
return_attention_mask: typing.Optional[bool] = None,
return_tensors: typing.Union[str, transformers.utils.generic.TensorType, NoneType] = None
)
参数:
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
对象。class transformers.BatchFeature
:持有 pad()
、以及 feature extractor
的 __call__()
方法的 output
。它是 Python
字典的派生类,可以作为一个字典来使用。
xxxxxxxxxx
class transformers.BatchFeature(
data: typing.Union[typing.Dict[str, typing.Any], NoneType] = None,
tensor_type: typing.Union[NoneType, str, transformers.utils.generic.TensorType] = None
)
参数:
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
,指定设备。
class transformers.ImageFeatureExtractionMixin
:用于准备图片特征的 mixin
。
方法:
center_crop(image, size ) -> new_image
:使用中心裁剪的方式将图像裁剪到指定的尺寸。注意,如果图像太小而无法裁剪到指定的尺寸,它将被填充(所以返回的结果具有指定的尺寸)。
参数:
image
:一个 PIL.Image.Image
或 np.ndarray
或 torch.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.Image
或 np.ndarray
或 torch.Tensor
,指定输入图像。
flip_channel_order(image) -> new_image
:将 image
的通道顺序从 RGB
翻转为 BGR
、或从 BGR
翻转为 RGB
。注意,如果 image
是一个 PIL Image
,则会将 image
转换到 numpy array
。
参数:image
:一个 PIL.Image.Image
或 np.ndarray
或 torch.Tensor
,指定输入图像。
normalize( image, mean, std, rescale = False ) -> new_image
:将 image
归一化到均值 mean
、标准差 std
。注意,如果 image
是一个 PIL Image
,则会将 image
转换到 numpy array
。
参数:
image
:一个 PIL.Image.Image
或 np.ndarray
或 torch.Tensor
,指定输入图像。mean
:一个 List[float]
或 np.ndarray
或 torch.Tensor
,指定每个通道的均值。std
:一个 List[float]
或 np.ndarray
或 torch.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_image
:reisze
图片。会强制将 image
转换为 PIL.Image
,最终返回结果是 PIL.Image
。
参数:
image
:一个 PIL.Image.Image
或 np.ndarray
或 torch.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
:一个整数,指定用于 resampling
的 filter
,默认为 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.Image
或 np.ndarray
或 torch.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.Image
或 np.ndarray
或 torch.Tensor
,指定输入图像。rescale
:一个布尔值,指定是否将 image
重新缩放到 0 ~ 255
之间。如果 image
是浮点类型的 array/tensor
,则默认为 True
。image processor
负责为视觉模型准备输入特征,并对其输出进行后处理。这包括 transformations
(如 resizing
、normalization
、以及转换为 PyTorch/TensorFlow/Flax/Numpy
张量)。还可能包括特定模型的后处理,如将 logits
转换为 segmentation masks
。
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()
。创建新的 model repository
的方法有以下三种:使用 push_to_hub API
、使用 huggingface_hub
的 Python
库、使用 web
界面。
创建 repository
后,你可以通过 git
和 git-lfs
将文件上传到其中。
首先登录 Hugging Face
。
如果在notebook
中,可以使用以下函数登录:
xxxxxxxxxx
from huggingface_hub import notebook_login
notebook_login()
如果你在终端中,可以运行命令:
xxxxxxxxxx
huggingface-cli login
在这两种情况下,系统都会提示你输入用户名和密码。
如果你使用 Trainer API
来训练一个模型,将其上传到 Hub
的最简单方法是:当定义 TrainingArguments
时设置 push_to_hub=True
:
xxxxxxxxxx
from transformers import TrainingArguments
training_args = TrainingArguments(
"bert-finetuned-mrpc", save_strategy="epoch", 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()
上传模型的最新版本。它还将生成包含所有相关元数据的模型卡,报告使用的超参数和评估结果!以下是你可能会在此类模型卡中找到的内容示例:
在 lower level
,可以通过模型、tokenizer
和配置对象的 push_to_hub()
方法直接访问 Model Hub
。此方法负责创建 repository
并将模型和 tokenizer
文件直接推送到 repository
。如:
xxxxxxxxxx
from transformers import AutoModelForMaskedLM, AutoTokenizer
checkpoint = "camembert-base"
model = AutoModelForMaskedLM.from_pretrained(checkpoint)
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
...
model.push_to_hub("dummy-model")
tokenizer.push_to_hub("dummy-model")
# tokenizer.push_to_hub("dummy-model", organization="huggingface")
如果你属于一个组织,只需指定 organization
参数 。
如果你希望使用特定的 Hugging Face token
,你可以自由地将其指定给 push_to_hub()
方法 :
xxxxxxxxxx
tokenizer.push_to_hub("dummy-model", organization="huggingface", use_auth_token="<TOKEN>")
类似于使用push_to_hub API
,首先要求你将API token
保存在缓存中。为此,需要在终端中运行命令 huggingface-cli login
。
huggingface_hub package
提供了几种对我们有用的方法和类。首先,有几种方法可以管理存储库的创建、删除等:
xxxxxxxxxx
from huggingface_hub import (
# User management
login,
logout,
whoami,
# Repository creation and management
create_repo,
delete_repo,
update_repo_visibility,
# And some methods to retrieve/change information about the content
list_models,
list_datasets,
list_metrics,
list_repo_files,
upload_file,
delete_file,
)
此外,它还提供了非常强大的 Repository
类用于管理本地 repository
。
create_repo
用于创建位于 hub
上的新 repository
:
xxxxxxxxxx
from huggingface_hub import create_repo
create_repo("dummy-model")
# create_repo("dummy-model", organization="huggingface")
创建 repository
后,我们应该向其中添加文件。
Web
界面提供了直接在 Hub
中管理 repo
的工具。使用该界面,你可以轻松创建 repo
、添加文件(甚至是大文件)、探索模型、可视化差异等等。
要创建新的 repo
,请访问https://huggingface.co/new
。
上传模型文件:Hugging Face Hub
上的文件管理系统基于用于常规文件的 gi
t 和 git-lfs
。可以通过 huggingface_hub
、以及通过 git
命令来上传文件到 Hub
。
通过 huggingface_hub
:使用 upload_file
不需要系统上安装 git
和 git-lfs
。它使用 HTTP POST
请求将文件直接推送到 Hub
。这种方法的一个限制是它不能处理大于 5GB
的文件。
xxxxxxxxxx
from huggingface_hub import upload_file
upload_file(
"<path_to_file>/config.json",
path_in_repo="config.json",
repo_id="<namespace>/dummy-model",
)
这将位于 <path_to_file>
下的 config.json
上传到 repository
(由 <namespace>/dummy-model
指定)根目录下的 config.json
。
其他可能有用的参数是:
token
,如果您想用给定的token
覆盖存储在缓存中的token
。repo_type
, 如果你想要上传一个 dataset
或一个 space
而不是模型。 接受的值为 "dataset"
和 "space"
。Repository
类:以类似 git
的方式管理本地 repository
。它抽象了 git
可能遇到的大部分痛点,以提供我们需要的所有功能。使用这个类需要安装 git
和 git-lfs
,所以确保你已经安装了 git-lfs
。
我们可以通过克隆远程 repo
将其初始化到本地文件夹开始:
xxxxxxxxxx
from huggingface_hub import Repository
repo = Repository("<path_to_dummy_folder>", clone_from="<namespace>/dummy-model")
这将在当前目录创建文件夹 <path_to_dummy_folder>
。接下来我们可以运行一些传统的 git
方法:
xxxxxxxxxx
repo.git_pull()
repo.git_add()
repo.git_commit()
repo.git_push()
repo.git_tag()
git-based
方法:这是上传文件的非常简单的方法:我们将直接使用 git
和 git-lfs
来完成。
首先从初始化 git-lfs
开始:
xxxxxxxxxx
git lfs install
完成后,第一步是克隆您的模型 repository
:
xxxxxxxxxx
git clone https://huggingface.co/<namespace>/<your-model-id>
接下来运行 Python
代码并保存模型或 tokenizer
,然后执行 git add, git commit, git push
从而上传模型文件。
Model Card
:模型卡片是一个配置文件,可以说与模型和tokenizer
文件一样重要。它包含了模型的核心定义,确保了社区成员可以复现模型的结果,并提供一个其他成员可以在这个模型基础上构建他们的组件的平台。
记录训练和评估过程有助于其他人了解模型的预期效果,并且提供有关所使用的数据以及预处理/后处理的足够信息,可确保能够识别和了解模型的局限性、 bias
以及 context
。
创建模型卡片是通过 README.md
来实现的。模型卡片通常以非常简短的概述开始,说明模型的用途,然后是模型卡片需要的其他信息:模型描述、预期用途和限制、如何使用、局限性和 bias
、训练数据、训练程序、评价结果。
使用 Trainer API
微调模型:
xxxxxxxxxx
### 加载数据集 ###
from datasets import load_dataset
from transformers import AutoTokenizer, DataCollatorWithPadding
raw_datasets = load_dataset("glue", "mrpc")
checkpoint = "bert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
def tokenize_function(example):
return tokenizer(example["sentence1"], example["sentence2"], truncation=True)
tokenized_datasets = raw_datasets.map(tokenize_function, batched=True)
data_collator = DataCollatorWithPadding(tokenizer=tokenizer)
### 定义 TrainingArguments ###
from transformers import TrainingArguments
training_args = TrainingArguments("test-trainer", evaluation_strategy="epoch")
### 定义模型 ###
from transformers import AutoModelForSequenceClassification
model = AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=2)
### 定义 Trainer ###
from transformers import Trainer
import evaluate
def compute_metrics(eval_preds): # 评估函数
metric = evaluate.load("glue", "mrpc")
logits, labels = eval_preds
predictions = np.argmax(logits, axis=-1)
return metric.compute(predictions=predictions, references=labels)
trainer = Trainer(
model,
training_args,
train_dataset=tokenized_datasets["train"],
eval_dataset=tokenized_datasets["validation"],
data_collator=data_collator,
tokenizer=tokenizer,
compute_metrics=compute_metrics,
)
### 训练 ###
trainer.train()
不使用 Trainer API
来训练,纯人工实现:
xxxxxxxxxx
### 加载数据集 ###
from datasets import load_dataset
from transformers import AutoTokenizer, DataCollatorWithPadding
raw_datasets = load_dataset("glue", "mrpc")
checkpoint = "bert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
def tokenize_function(example):
return tokenizer(example["sentence1"], example["sentence2"], truncation=True)
tokenized_datasets = raw_datasets.map(tokenize_function, batched=True)
data_collator = DataCollatorWithPadding(tokenizer=tokenizer)
tokenized_datasets = tokenized_datasets.remove_columns(["sentence1", "sentence2", "idx"]) # 删除不必要的列
tokenized_datasets = tokenized_datasets.rename_column("label", "labels") # 重命名列
tokenized_datasets.set_format("torch") # 设置数据集的格式
tokenized_datasets["train"].column_names
# ["attention_mask", "input_ids", "labels", "token_type_ids"]
from torch.utils.data import DataLoader
train_dataloader = DataLoader(
tokenized_datasets["train"], shuffle=True, batch_size=8, collate_fn=data_collator
)
eval_dataloader = DataLoader(
tokenized_datasets["validation"], batch_size=8, collate_fn=data_collator
)
### 定义模型 ###
from transformers import AutoModelForSequenceClassification
model = AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=2)
### 定义优化器和调度器 ###
from transformers import AdamW
from transformers import get_scheduler
optimizer = AdamW(model.parameters(), lr=5e-5)
num_epochs = 3
num_training_steps = num_epochs * len(train_dataloader)
lr_scheduler = get_scheduler(
"linear",
optimizer=optimizer,
num_warmup_steps=0,
num_training_steps=num_training_steps,
)
### 定义 training loop ###
import torch
device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")
model.to(device)
from tqdm.auto import tqdm
progress_bar = tqdm(range(num_training_steps))
model.train()
for epoch in range(num_epochs):
for batch in train_dataloader:
batch = {k: v.to(device) for k, v in batch.items()}
outputs = model(**batch)
loss = outputs.loss
loss.backward()
optimizer.step()
lr_scheduler.step()
optimizer.zero_grad()
progress_bar.update(1)
### 评估 ###
import evaluate
metric = evaluate.load("glue", "mrpc")
model.eval()
for batch in eval_dataloader:
batch = {k: v.to(device) for k, v in batch.items()}
with torch.no_grad():
outputs = model(**batch)
logits = outputs.logits
predictions = torch.argmax(logits, dim=-1)
metric.add_batch(predictions=predictions, references=batch["labels"])
metric.compute()
使用 Accelerate
加速训练:使用Accelerate
库,只需进行一些调整,我们就可以在多个 GPU
或TPU
上启用分布式训练,以下是改动的部分:
xxxxxxxxxx
+ from accelerate import Accelerator
from transformers import AdamW, AutoModelForSequenceClassification, get_scheduler
+ accelerator = Accelerator()
model = AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=2)
optimizer = AdamW(model.parameters(), lr=3e-5)
- device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")
- model.to(device)
+ train_dataloader, eval_dataloader, model, optimizer = accelerator.prepare(
+ train_dataloader, eval_dataloader, model, optimizer
+ )
num_epochs = 3
num_training_steps = num_epochs * len(train_dataloader)
lr_scheduler = get_scheduler(
"linear",
optimizer=optimizer,
num_warmup_steps=0,
num_training_steps=num_training_steps
)
progress_bar = tqdm(range(num_training_steps))
model.train()
for epoch in range(num_epochs):
for batch in train_dataloader:
- batch = {k: v.to(device) for k, v in batch.items()}
outputs = model(**batch)
loss = outputs.loss
- loss.backward()
+ accelerator.backward(loss)
optimizer.step()
lr_scheduler.step()
optimizer.zero_grad()
progress_bar.update(1)
要添加的第一行是导入Accelerator
。第二行实例化一个 Accelerator
对象 ,它将查看环境并初始化适当的分布式设置。 Accelerate
为你处理数据在设备间的传递,因此你可以删除将模型放在设备上的那行代码(或者,也可以使用 accelerator.device
代替 device
)。
要在分布式设置中使用它,请运行以下命令:
xxxxxxxxxx
accelerate config
这将询问你几个配置的问题并将你的回答转储到如下命令使用的配置文件中:
xxxxxxxxxx
accelerate launch train.py
这将启动分布式训练。
为了使云端 TPU
提供的加速发挥最大的效益,我们建议使用tokenizer
的 padding=max_length
和 max_length
参数将你的样本填充到固定长度。