训练器
原始文本:
huggingface.co/docs/transformers/v4.37.2/en/main_classes/trainer
Trainer 类提供了一个用于在 PyTorch 中进行完整特征训练的 API,并支持在多个 GPU/TPU 上进行分布式训练,支持NVIDIA GPUs的混合精度,AMD GPUs,以及 PyTorch 的torch.amp
。Trainer 与 TrainingArguments 类相辅相成,后者提供了广泛的选项来自定义模型的训练方式。这两个类一起提供了一个完整的训练 API。
Seq2SeqTrainer 和 Seq2SeqTrainingArguments 继承自 Trainer 和TrainingArgument
类,它们适用于用于序列到序列任务(如摘要或翻译)的模型训练。
Trainer 类针对🤗 Transformers 模型进行了优化,当与其他模型一起使用时可能会有一些意外行为。在使用自己的模型时,请确保:
- 您的模型始终返回元组或 ModelOutput 的子类
- 如果提供了
labels
参数并且该损失作为元组的第一个元素返回(如果您的模型返回元组),则您的模型可以计算损失 - 您的模型可以接受多个标签参数(在 TrainingArguments 中使用
label_names
指示它们的名称给 Trainer),但它们中没有一个应该被命名为"label"
训练器
class transformers.Trainer
( model: Union = None args: TrainingArguments = None data_collator: Optional = None train_dataset: Optional = None eval_dataset: Union = None tokenizer: Optional = None model_init: Optional = None compute_metrics: Optional = None callbacks: Optional = None optimizers: Tuple = (None, None) preprocess_logits_for_metrics: Optional = None )
参数
model
(PreTrainedModel 或torch.nn.Module
, 可选) — 用于训练、评估或用于预测的模型。如果未提供,则必须传递一个model_init
。
Trainer 被优化为与库提供的 PreTrainedModel 一起使用。只要您的模型与🤗 Transformers 模型的工作方式相同,您仍然可以使用自己定义的torch.nn.Module
模型。args
(TrainingArguments, 可选) — 用于调整训练的参数。如果未提供,将默认为一个基本的 TrainingArguments 实例,其中output_dir
设置为当前目录中名为tmp_trainer的目录。data_collator
(DataCollator
, 可选) — 用于从train_dataset
或eval_dataset
的元素列表中形成批次的函数。如果未提供tokenizer
,将默认为 default_data_collator(),否则将默认为 DataCollatorWithPadding 的实例。train_dataset
(torch.utils.data.Dataset
或torch.utils.data.IterableDataset
,可选)— 用于训练的数据集。如果是Dataset,则不被model.forward()
方法接受的列将自动删除。
请注意,如果是带有一些随机化的torch.utils.data.IterableDataset
,并且您正在以分布式方式进行训练,您的可迭代数据集应该使用一个内部属性generator
,该属性是一个torch.Generator
,用于在所有进程上保持相同的随机化(并且 Trainer 将在每个 epoch 手动设置此generator
的种子),或者具有一个在内部设置用于随机数生成器的种子的set_epoch()
方法。eval_dataset
(Union[torch.utils.data.Dataset
,Dict[str,torch.utils.data.Dataset
]),可选)— 用于评估的数据集。如果是Dataset,则不被model.forward()
方法接受的列将自动删除。如果是字典,则将在每个数据集上评估,并在度量名称之前添加字典键。tokenizer
(PreTrainedTokenizerBase,可选)— 用于预处理数据的分词器。如果提供,将用于在批处理输入时自动填充输入到最大长度,并将保存在模型中,以便更容易重新运行中断的训练或重用微调的模型。model_init
(Callable[[], PreTrainedModel]
,可选)— 用于实例化要使用的模型的函数。如果提供,每次调用 train()都将从此函数给出的模型的新实例开始。
该函数可能没有参数,或者包含一个参数,其中包含 optuna/Ray Tune/SigOpt 试验对象,以便根据超参数(例如层计数、内部层大小、丢失概率等)选择不同的架构。compute_metrics
(Callable[[EvalPrediction], Dict]
,可选)— 用于在评估时计算指标的函数。必须接受 EvalPrediction 并返回一个字符串字典以表示指标值。callbacks
(TrainerCallback 列表,可选)— 用于自定义训练循环的回调列表。将添加到此处详细说明的默认回调列表中。
如果要删除使用的默认回调之一,请使用 Trainer.remove_callback()方法。optimizers
(Tuple[torch.optim.Optimizer, torch.optim.lr_scheduler.LambdaLR]
,可选,默认为(None, None)
)— 包含要使用的优化器和调度器的元组。将默认为您的模型上的 AdamW 实例和由 get_linear_schedule_with_warmup()控制的调度器,由args
指定。preprocess_logits_for_metrics
(Callable[[torch.Tensor, torch.Tensor], torch.Tensor]
,可选)— 用于在每个评估步骤之前预处理 logits 的函数。必须接受两个张量,logits 和标签,并根据需要返回处理后的 logits。此函数所做的修改将反映在compute_metrics
接收到的预测中。
请注意,如果数据集没有标签,标签(第二个参数)将为None
。
Trainer 是一个简单但功能完备的 PyTorch 训练和评估循环,专为🤗 Transformers 优化。
重要属性:
model
- 始终指向核心模型。如果使用 transformers 模型,它将是一个 PreTrainedModel 子类。model_wrapped
- 始终指向最外部的模型,以防一个或多个其他模块包装原始模型。这是应该用于前向传递的模型。例如,在DeepSpeed
下,内部模型被包装在DeepSpeed
中,然后再次包装在torch.nn.DistributedDataParallel
中。如果内部模型没有被包装,那么self.model_wrapped
与self.model
相同。is_model_parallel
- 模型是否已切换到模型并行模式(与数据并行不同,这意味着一些模型层在不同的 GPU 上分割)。place_model_on_device
- 是否自动将模型放置在设备上 - 如果使用模型并行或 deepspeed,或者如果默认的TrainingArguments.place_model_on_device
被覆盖为返回False
,则将其设置为False
。is_in_train
- 模型当前是否在运行train
(例如,在train
中调用evaluate
时)
add_callback
( callback )
参数
callback
(type
或 TrainerCallback)- 一个 TrainerCallback 类或 TrainerCallback 的实例。在第一种情况下,将实例化该类的成员。
向当前的 TrainerCallback 列表中添加一个回调。
autocast_smart_context_manager
( cache_enabled: Optional = True )
一个帮助器包装器,为autocast
创建适当的上下文管理器,并根据情况提供所需的参数。
compute_loss
( model inputs return_outputs = False )
Trainer 如何计算损失。默认情况下,所有模型都在第一个元素中返回损失。
子类和覆盖以进行自定义行为。
compute_loss_context_manager
( )
一个帮助器包装器,用于将上下文管理器组合在一起。
create_model_card
( language: Optional = None license: Optional = None tags: Union = None model_name: Optional = None finetuned_from: Optional = None tasks: Union = None dataset_tags: Union = None dataset: Union = None dataset_args: Union = None )
参数
language
(str
,可选)- 模型的语言(如果适用)license
(str
,可选)- 模型的许可证。如果原始模型给定给Trainer
来自 Hub 上的 repo,则将默认为使用的预训练模型的许可证。tags
(str
或List[str]
,可选)- 要包含在模型卡元数据中的一些标签。model_name
(str
,可选)- 模型的名称。finetuned_from
(str
,可选)- 用于微调此模型的模型的名称(如果适用)。如果原始模型给定给Trainer
来自 Hub,则将默认为原始模型的 repo 的名称。tasks
(str
或List[str]
,可选)- 一个或多个任务标识符,将包含在模型卡的元数据中。dataset_tags
(str
或List[str]
,可选)- 一个或多个数据集标签,将包含在模型卡的元数据中。dataset
(str
或List[str]
,可选)- 一个或多个数据集标识符,将包含在模型卡的元数据中。dataset_args
(str
或List[str]
, 可选) — 一个或多个数据集参数,将包含在模型卡的元数据中。
使用Trainer
可用的信息创建一个模型卡的草稿。
create_optimizer
( )
设置优化器。
我们提供了一个合理的默认值,效果很好。如果您想使用其他内容,可以通过optimizers
在 Trainer 的 init 中传递一个元组,或者在子类中重写此方法。
创建优化器和调度器
( num_training_steps: int )
设置优化器和学习率调度器。
我们提供了一个合理的默认值,效果很好。如果您想使用其他内容,可以通过optimizers
在 Trainer 的 init 中传递一个元组,或者在子类中重写此方法(或create_optimizer
和/或create_scheduler
)。
create_scheduler
( num_training_steps: int optimizer: Optimizer = None )
参数
num_training_steps
(int) — 要执行的训练步骤数。
设置调度器。训练器的优化器必须在调用此方法之前设置好,或者作为参数传递。
evaluate
( eval_dataset: Union = None ignore_keys: Optional = None metric_key_prefix: str = 'eval' )
参数
eval_dataset
(Union[Dataset
, Dict[str,Dataset
]), 可选) — 如果要覆盖self.eval_dataset
,请传递一个数据集。如果是一个Dataset,则model.forward()
方法不接受的列将自动删除。如果是一个字典,它将对每个数据集进行评估,并在度量名称前加上字典键。数据集必须实现__len__
方法。
如果您传递一个以数据集名称为键、数据集为值的字典,评估将在每个数据集上单独运行。这对于监视训练如何影响其他数据集或仅仅获得更精细的评估很有用。当与load_best_model_at_end
一起使用时,请确保metric_for_best_model
引用确切地一个数据集。例如,如果为两个数据集data1
和data2
传递{"data1": data1, "data2": data2}
,则可以指定metric_for_best_model="eval_data1_loss"
来使用data1
上的损失,以及metric_for_best_model="eval_data1_loss"
来使用data2
上的损失。ignore_keys
(List[str]
, 可选) — 在模型输出中应该被忽略的键的列表(如果它是一个字典)。metric_key_prefix
(str
, 可选, 默认为"eval"
) — 用作指标键前缀的可选前缀。例如,如果前缀是"eval"
(默认),则指标“bleu”将被命名为“eval_bleu”。
运行评估并返回指标。
调用脚本将负责提供计算指标的方法,因为它们是任务相关的(将其传递给compute_metrics
参数进行初始化)。
您也可以子类化并重写此方法以注入自定义行为。
evaluation_loop
( dataloader: DataLoader description: str prediction_loss_only: Optional = None ignore_keys: Optional = None metric_key_prefix: str = 'eval' )
预测/评估循环,由Trainer.evaluate()
和Trainer.predict()
共享。
可以使用带有或不带有标签的工作。
floating_point_ops
( inputs: Dict ) → export const metadata = 'undefined';int
参数
inputs
(Dict[str, Union[torch.Tensor, Any]]
) — 模型的输入和目标。
返回
int
浮点运算的数量。
对于继承自 PreTrainedModel 的模型,使用该方法计算每次反向+前向传递的浮点运算次数。如果使用另一个模型,要么在模型中实现这样的方法,要么子类化并重写此方法。
get_decay_parameter_names
( model )
获取将应用权重衰减的所有参数名称
请注意,一些模型实现了自己的 layernorm 而不是调用 nn.LayerNorm,因此这个函数只过滤出 nn.LayerNorm 的实例
get_eval_dataloader
( eval_dataset: Optional = None )
参数
eval_dataset
(torch.utils.data.Dataset
, 可选) — 如果提供,将覆盖self.eval_dataset
。如果它是一个Dataset,那些model.forward()
方法不接受的列将被自动移除。它必须实现__len__
。
返回评估~torch.utils.data.DataLoader
。
如果您想要注入一些自定义行为,请子类化并重写此方法。
get_optimizer_cls_and_kwargs
( args: TrainingArguments )
参数
args
(transformers.training_args.TrainingArguments
) — 训练会话的训练参数。
根据训练参数返回优化器类和优化器参数。
get_test_dataloader
( test_dataset: Dataset )
参数
test_dataset
(torch.utils.data.Dataset
, 可选) — 要使用的测试数据集。如果它是一个Dataset,那些model.forward()
方法不接受的列将被自动移除。它必须实现__len__
。
返回测试~torch.utils.data.DataLoader
。
如果您想要注入一些自定义行为,请子类化并重写此方法。
get_train_dataloader
( )
返回训练~torch.utils.data.DataLoader
。
如果train_dataset
不实现__len__
,则不使用采样器,否则使用随机采样器(必要时适应分布式训练)。
如果您想要注入一些自定义行为,请子类化并重写此方法。
hyperparameter_search
( hp_space: Optional = None compute_objective: Optional = None n_trials: int = 20 direction: Union = 'minimize' backend: Union = None hp_name: Optional = None **kwargs ) → export const metadata = 'undefined';[trainer_utils.BestRun or List[trainer_utils.BestRun]]
参数
hp_space
(Callable[["optuna.Trial"], Dict[str, float]]
, 可选) — 定义超参数搜索空间的函数。将根据您的后端默认为default_hp_space_optuna()
或default_hp_space_ray()
或default_hp_space_sigopt()
。compute_objective
(Callable[[Dict[str, float]], float]
, 可选) — 一个计算要最小化或最大化的目标的函数,从evaluate
方法返回的指标中计算。将默认为default_compute_objective()
。n_trials
(int
, 可选, 默认为 100) — 测试运行的次数。direction
(str
或List[str]
, 可选, 默认为"minimize"
) — 如果是单目标优化,方向是str
,可以是"minimize"
或"maximize"
,当优化验证损失时应选择"minimize"
,当优化一个或多个指标时应选择"maximize"
。如果是多目标优化,方向是List[str]
,可以是"minimize"
和"maximize"
的列表,当优化验证损失时应选择"minimize"
,当优化一个或多个指标时应选择"maximize"
。backend
(str
或~training_utils.HPSearchBackend
,可选)—用于超参数搜索的后端。将默认为 optuna、Ray Tune 或 SigOpt,取决于安装了哪个。如果所有都安装了,将默认为 optuna。hp_name
(Callable[["optuna.Trial"], str]
,可选)—定义试验/运行名称的函数。默认为 None。kwargs
(Dict[str, Any]
,可选)—传递给optuna.create_study
或ray.tune.run
的其他关键字参数。更多信息请参见:
返回
[trainer_utils.BestRun
或List[trainer_utils.BestRun]
]
有关多目标优化的最佳运行或最佳运行的所有信息。实验摘要可以在 Ray 后端的run_summary
属性中找到。
使用optuna
、Ray Tune
或SigOpt
启动超参数搜索。优化的数量由compute_objective
确定,默认情况下,当没有提供指标时返回评估损失的函数,否则返回所有指标的总和。
要使用这种方法,您需要在初始化 Trainer 时提供一个model_init
:我们需要在每次新运行时重新初始化模型。这与optimizers
参数不兼容,因此您需要子类化 Trainer 并重写方法 create_optimizer_and_scheduler()以获得自定义优化器/调度器。
init_hf_repo
( )
在self.args.hub_model_id
中初始化 git 存储库。
is_local_process_zero
( )
此进程是否为本地(例如,在多台机器上以分布式方式进行训练时,如果是主要进程,则为一台机器上的进程)。
is_world_process_zero
( )
此进程是否为全局主进程(在多台机器上以分布式方式进行训练时,只有一个进程会是True
)。
log
( logs: Dict )
参数
logs
(Dict[str, float]
)—要记录的值。
记录logs
在观察训练的各种对象。
子类化并重写此方法以注入自定义行为。
log_metrics
( split metrics )
参数
split
(str
)—模式/分割名称:train
、eval
、test
之一metrics
(Dict[str, float]
)—来自 train/evaluate/predictmetrics 的指标:指标字典
以特殊格式记录指标
在分布式环境下,这仅针对排名为 0 的进程执行。
关于内存报告的注意事项:
为了获得内存使用报告,您需要安装psutil
。您可以使用pip install psutil
来安装。
现在当运行此方法时,您将看到一个包含的报告::
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__
,告诉您指标所属的阶段。以init_
开头的报告将添加到运行的第一个阶段。因此,如果只运行评估,则将报告__init__
的内存使用情况以及eval_
指标。 - 第三部分,是
cpu
或gpu
,告诉您它是通用 RAM 还是 gpu0 内存指标。 *_alloc_delta
- 是阶段结束和开始时使用/分配内存计数器之间的差异 - 如果函数释放的内存多于分配的内存,则可能为负数。*_peaked_delta
- 是任何额外消耗然后释放的内存 - 相对于当前分配的内存计数器 - 它永远不会是负数。当您查看任何阶段的指标时,您将alloc_delta
+peaked_delta
相加,就知道完成该阶段需要多少内存。
仅对 rank 0 和 gpu 0 的进程进行报告(如果有 gpu)。通常这已经足够了,因为主进程完成大部分工作,但如果使用模型并行,情况可能不太一样,其他 GPU 可能使用不同数量的 gpu 内存。在 DataParallel 下也不同,因为 gpu0 可能需要比其他 GPU 更多的内存,因为它存储了所有参与 GPU 的梯度和优化器状态。也许在未来,这些报告将发展到测量这些内容。
CPU RAM 指标测量 RSS(Resident Set Size),包括进程独有的内存和与其他进程共享的内存。重要的是要注意,它不包括被交换出的内存,因此报告可能不够精确。
CPU 峰值内存是使用采样线程测量的。由于 python 的 GIL,如果该线程在使用最高内存时没有运行的机会,它可能会错过一些峰值内存。因此,这份报告可能小于实际情况。使用tracemalloc
将报告准确的峰值内存,但它不会报告 python 之外的内存分配。因此,如果某个 C++ CUDA 扩展分配了自己的内存,它将不会被报告。因此,它被放弃,以支持内存采样方法,该方法读取当前进程的内存使用情况。
GPU 分配和峰值内存报告是通过torch.cuda.memory_allocated()
和torch.cuda.max_memory_allocated()
完成的。这个指标仅报告 pytorch 特定分配的“增量”,因为torch.cuda
内存管理系统不跟踪 pytorch 之外分配的任何内存。例如,第一个 cuda 调用通常加载 CUDA 内核,可能占用 0.5 到 2GB 的 GPU 内存。
请注意,此跟踪器不考虑 Trainer 的__init__
、train
、evaluate
和predict
调用之外的内存分配。
因为evaluation
调用可能发生在train
期间,我们无法处理嵌套调用,因为torch.cuda.max_memory_allocated
是一个计数器,所以如果它被嵌套的 eval 调用重置,train
的跟踪器将报告不正确的信息。如果这个pytorch 问题得到解决,将有可能将这个类改为可重入。在那之前,我们只会跟踪train
、evaluate
和predict
方法的外层级别。这意味着如果在train
期间调用eval
,后者将记录其内存使用情况以及前者的内存使用情况。
这也意味着如果在 Trainer 调用期间使用任何其他工具torch.cuda.reset_peak_memory_stats
,则 gpu 峰值内存统计数据可能无效。而且 Trainer 将破坏任何依赖于自己调用torch.cuda.reset_peak_memory_stats
的工具的正常行为。
为了获得最佳性能,您可能希望在生产运行中关闭内存分析。
metrics_format
( metrics: Dict ) → export const metadata = 'undefined';metrics (Dict[str, float])
参数
metrics
(Dict[str, float]
) — 训练/评估/预测返回的指标
返回
metrics (Dict[str, float]
)
重格式化的指标
将 Trainer 指标值重新格式化为人类可读的格式
num_examples
( dataloader: DataLoader )
通过访问其数据集来获取~torch.utils.data.DataLoader
中样本数的帮助程序。当数据加载器数据集不存在或没有长度时,尽可能估计
num_tokens
( train_dl: DataLoader max_steps: Optional = None )
通过枚举数据加载器来获取~torch.utils.data.DataLoader
中的标记数的帮助程序。
pop_callback
( callback ) → export const metadata = 'undefined';TrainerCallback
参数
callback
(type
或 TrainerCallback)- TrainerCallback 类或 TrainerCallback 的实例。在第一种情况下,将弹出在回调列表中找到的该类的第一个成员。
返回
TrainerCallback
如果找到,将删除回调。
从当前的 TrainerCallback 列表中删除回调并返回它。
如果未找到回调,则返回None
(不会引发错误)。
predict
( test_dataset: Dataset ignore_keys: Optional = None metric_key_prefix: str = 'test' )
参数
test_dataset
(Dataset
)- 要在其上运行预测的数据集。如果它是datasets.Dataset
,则不被model.forward()
方法接受的列将自动删除。必须实现方法__len__
ignore_keys
(List[str]
,可选)- 模型输出中应忽略的键列表(如果它是字典)。metric_key_prefix
(str
,可选,默认为"test"
)- 用作指标键前缀的可选前缀。例如,如果前缀是"test"
(默认),则指标“bleu”将被命名为“test_bleu”。
运行预测并返回预测和潜在指标。
根据数据集和用例,您的测试数据集可能包含标签。在这种情况下,此方法还将返回指标,就像在evaluate()
中一样。
如果您的预测或标签具有不同的序列长度(例如,因为您在标记分类任务中进行动态填充),则预测将被填充(在右侧),以允许连接到一个数组中。填充索引为-100。
返回:NamedTuple 具有以下键的命名元组:
- 预测(
np.ndarray
):在test_dataset
上的预测。 - label_ids(
np.ndarray
,可选):标签(如果数据集包含)。 - 指标(
Dict[str, float]
,可选):潜在的指标字典(如果数据集包含标签)。
prediction_loop
( dataloader: DataLoader description: str prediction_loss_only: Optional = None ignore_keys: Optional = None metric_key_prefix: str = 'eval' )
预测/评估循环,由Trainer.evaluate()
和Trainer.predict()
共享。
无论是否有标签,都可以使用。
prediction_step
( model: Module inputs: Dict prediction_loss_only: bool ignore_keys: Optional = None ) → export const metadata = 'undefined';Tuple[Optional[torch.Tensor], Optional[torch.Tensor], Optional[torch.Tensor]]
参数
model
(nn.Module
)- 要评估的模型。inputs
(Dict[str, Union[torch.Tensor, Any]]
)- 模型的输入和目标。
在馈送模型之前,字典将被解包。大多数模型希望目标在参数labels
下。检查您模型的文档以获取所有接受的参数。prediction_loss_only
(bool
)- 是否仅返回损失。ignore_keys
(List[str]
,可选)- 模型输出中应忽略的键列表(如果它是字典)。
返回
Tuple[Optional[torch.Tensor], Optional[torch.Tensor], Optional[torch.Tensor]]
一个包含损失、logits 和标签的元组(每个都是可选的)。
使用 inputs
在 model
上执行评估步骤。
子类和覆盖以注入自定义行为。
propagate_args_to_deepspeed
( auto_find_batch_size = False )
根据 Trainer 参数在 deepspeed 插件中设置值
Transformers 4.37 中文文档(十九)(2)https://developer.aliyun.com/article/1564923