训练器的实用工具
本页面列出了Trainer使用的所有实用函数。
大多数这些内容只有在您研究库中的Trainer代码时才有用。
工具
类 transformers.EvalPrediction
< source >( predictions: typing.Union[numpy.ndarray, typing.Tuple[numpy.ndarray]] label_ids: typing.Union[numpy.ndarray, typing.Tuple[numpy.ndarray]] inputs: typing.Union[numpy.ndarray, typing.Tuple[numpy.ndarray], NoneType] = None losses: typing.Union[numpy.ndarray, typing.Tuple[numpy.ndarray], NoneType] = None )
评估输出(始终包含标签),用于计算指标。
类 transformers.IntervalStrategy
< source >( value names = 无 module = 无 qualname = 无 type = 无 start = 1 )
一个枚举。
用于在分布式训练期间实现可重复行为的辅助函数。参见
transformers.set_seed
< source >( seed: int deterministic: bool = False )
用于可重复行为的辅助函数,用于在random
、numpy
、torch
和/或tf
(如果已安装)中设置种子。
transformers.torch_distributed_zero_first
< source >( local_rank: int )
装饰器,用于使分布式训练中的所有进程等待每个本地主节点执行某些操作。
回调内部机制
类 transformers.trainer_callback.CallbackHandler
< source >( callbacks model processing_class optimizer lr_scheduler )
内部类,按顺序调用回调列表。
分布式评估
类 transformers.trainer_pt_utils.DistributedTensorGatherer
< source >( world_size num_samples make_multiple_of = None padding_index = -100 )
一个负责通过分块在CPU上正确收集张量(或张量的嵌套列表/元组)的类。
如果我们的数据集有16个样本,在3个进程上批量大小为2,并且我们在每一步都收集然后传输到CPU,我们的采样器将生成以下索引:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1]
获取大小为3的倍数的内容(以便每个进程获得相同的数据集长度)。然后,进程0、1和2将负责对以下样本进行预测:
- P0:
[0, 1, 2, 3, 4, 5]
- P1:
[6, 7, 8, 9, 10, 11]
- P2:
[12, 13, 14, 15, 0, 1]
每个进程上处理的第一批将是
- P0:
[0, 1]
- P1:
[6, 7]
- P2:
[12, 13]
因此,如果我们在第一批结束时聚集,我们将得到一个对应于以下索引的张量(嵌套列表/元组的张量):
[0, 1, 6, 7, 12, 13]
如果我们直接连接我们的结果而不采取任何预防措施,用户将在预测循环结束时按此顺序获得索引的预测:
[0, 1, 6, 7, 12, 13, 2, 3, 8, 9, 14, 15, 4, 5, 10, 11, 0, 1]
出于某种原因,这不会让他们感兴趣。这个类的存在就是为了解决这个问题。
将arrays
添加到内部存储中,将在第一次传递数组时将存储初始化为完整大小,以便如果我们可能会遇到内存不足(OOM)的情况,它会在开始时发生。
返回正确收集的数组并截断到样本数量(因为采样器添加了一些额外的样本以使每个进程获得相同长度的数据集)。
训练器参数解析器
类 transformers.HfArgumentParser
< source >( dataclass_types: typing.Union[transformers.hf_argparser.DataClassType, typing.Iterable[transformers.hf_argparser.DataClassType]] **kwargs )
这个argparse.ArgumentParser
的子类使用数据类上的类型提示来生成参数。
该类设计为与原生argparse良好配合。特别是,您可以在初始化后向解析器添加更多(非数据类支持的)参数,并且在解析后您将获得额外的命名空间作为输出。可选:要创建子参数组,请在数据类中使用_argument_group_name
属性。
parse_args_into_dataclasses
< source >( args = None return_remaining_strings = False look_for_args_file = True args_filename = None args_file_flag = None ) → 由以下组成的元组
参数
- args — 要解析的字符串列表。默认值取自 sys.argv。(与 argparse.ArgumentParser 相同)
- return_remaining_strings — 如果为真,还返回剩余参数字符串的列表。
- look_for_args_file — 如果为真,将查找与此进程的入口点脚本同名的“.args”文件,并将其可能的内容附加到命令行参数中。
- args_filename — 如果不是None,将使用此文件而不是前一个参数中指定的“.args”文件。
- args_file_flag — 如果不是None,将在命令行参数中查找使用此标志指定的文件。该标志可以 多次指定,优先级由顺序决定(最后一个获胜)。
返回
由以下组成的元组
- 数据类实例的顺序与它们传递给初始化器的顺序相同。abspath
- 如果适用,初始化后添加到解析器的更多(非数据类支持的)参数的额外命名空间。
- 剩余参数字符串的潜在列表。(与argparse.ArgumentParser.parse_known_args相同)
将命令行参数解析为指定数据类类型的实例。
这依赖于argparse的ArgumentParser.parse_known_args
。请参阅文档:
docs.python.org/3.7/library/argparse.html#argparse.ArgumentParser.parse_args
parse_dict
< source >( args: typing.Dict[str, typing.Any] allow_extra_keys: bool = False ) → 由以下组成的元组
不使用argparse
的替代辅助方法,而是使用字典并填充数据类类型。
parse_json_file
< source >( json_file: typing.Union[str, os.PathLike] allow_extra_keys: bool = False ) → 由以下组成的元组
不使用argparse
的替代辅助方法,而是加载一个json文件并填充数据类类型。
parse_yaml_file
< source >( yaml_file: typing.Union[str, os.PathLike] allow_extra_keys: bool = False ) → 由以下组成的元组
不使用argparse
的替代辅助方法,而是加载一个yaml文件并填充数据类类型。
调试工具
类 transformers.debug_utils.DebugUnderflowOverflow
< source >( model max_frames_to_save = 21 trace_batch_nums = [] abort_after_batch_num = None )
这个调试类有助于检测和理解模型在何处开始变得非常大或非常小,更重要的是nan
或inf
权重和激活元素。
有2种工作模式:
- 下溢/溢出检测(默认)
- 特定批次的绝对最小/最大值追踪,无需检测
模式1:下溢/溢出检测
然后正常运行训练,如果在至少一个权重、输入或输出元素中检测到nan
或inf
,此模块将抛出异常并打印导致此事件的max_frames_to_save
帧,每帧报告
- 完全限定的模块名称加上其
forward
方法被运行的类名 - 每个模块权重的所有元素的绝对最小值和最大值,以及输入和输出
例如,这里是在fp16模式下运行的google/mt5-small
的检测报告中的头部和最后几帧。
混合精度:
Detected inf/nan during batch_number=0
Last 21 forward frames:
abs min abs max metadata
[...]
encoder.block.2.layer.1.DenseReluDense.wi_0 Linear
2.17e-07 4.50e+00 weight
1.79e-06 4.65e+00 input[0]
2.68e-06 3.70e+01 output
encoder.block.2.layer.1.DenseReluDense.wi_1 Linear
8.08e-07 2.66e+01 weight
1.79e-06 4.65e+00 input[0]
1.27e-04 2.37e+02 output
encoder.block.2.layer.1.DenseReluDense.wo Linear
1.01e-06 6.44e+00 weight
0.00e+00 9.74e+03 input[0]
3.18e-04 6.27e+04 output
encoder.block.2.layer.1.DenseReluDense T5DenseGatedGeluDense
1.79e-06 4.65e+00 input[0]
3.18e-04 6.27e+04 output
encoder.block.2.layer.1.dropout Dropout
3.18e-04 6.27e+04 input[0]
0.00e+00 inf output
你可以在这里看到,T5DenseGatedGeluDense.forward
导致了输出激活,其绝对最大值约为62.7K,非常接近fp16的上限64K。在下一帧中,我们有Dropout
,它在将一些元素置零后重新归一化权重,这将绝对最大值推到了64K以上,从而导致溢出。
正如你所看到的,当数字开始变得非常大时,我们需要查看之前的帧,特别是对于fp16数字。
跟踪是在前向钩子中完成的,该钩子在forward
完成后立即被调用。
默认情况下,最后21帧会被打印出来。您可以根据需要更改默认设置。例如:
debug_overflow = DebugUnderflowOverflow(model, max_frames_to_save=100)
为了验证您已正确设置此调试功能,并且您打算在可能需要数小时才能完成的训练中使用它,首先按照下一节的说明,在启用正常跟踪的情况下运行它,仅针对几个批次。
模式2. 特定批次绝对最小/最大值追踪,无需检测
第二种工作模式是每批次跟踪,关闭下溢/上溢检测功能。
假设你想观察每个forward
调用中所有成分的绝对最小值和最大值
给定的批次,并且只对批次1和3执行此操作。然后你实例化这个类为:
debug_overflow = DebugUnderflowOverflow(model, trace_batch_nums=[1, 3])
现在,批次1和批次3将使用与上述相同的格式进行追踪。批次是从0开始索引的。
如果您知道程序在某个批次号后开始出现问题,这将非常有用,因此您可以快速跳转到该区域。
早停:
你也可以指定在哪个批次后停止训练,使用:
debug_overflow = DebugUnderflowOverflow(model, trace_batch_nums=[1, 3], abort_after_batch_num=3)
此功能在追踪模式下特别有用,但你可以在任何模式下使用它。
性能:
由于此模块在每次前向传播时都会测量模型中每个权重的绝对min
/`max
,因此会减慢训练速度。因此,请记住在满足调试需求后将其关闭。