原始文本:
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 模型进行了优化,当与其他模型一起使用时可能会有一些意外行为。在使用自己的模型时,请确保:
labels
参数并且该损失作为元组的第一个元素返回(如果您的模型返回元组),则您的模型可以计算损失
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
上的预测。
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 插件中设置值
push_to_hub
( commit_message: Optional = 'End of training' blocking: bool = True **kwargs )
参数
commit_message
(str
, 可选, 默认为 "End of training"
) — 推送时要提交的消息。
blocking
(bool
, 可选, 默认为 True
) — 函数是否应该在 git push
完成后才返回。
kwargs
(Dict[str, Any]
, 可选) — 传递给 create_model_card() 的额外关键字参数。
将 self.model
和 self.tokenizer
上传到 🤗 模型中心,存储库为 self.args.hub_model_id
。
remove_callback
( callback )
参数
回调
(类型
或 TrainerCallback) — 一个 TrainerCallback 类或一个 TrainerCallback 的实例。在第一种情况下,将删除在回调列表中找到的该类的第一个成员。从当前的 TrainerCallback 列表中删除一个回调。
save_metrics
( split metrics combined = True )
参数
split
(str
) — 模式/拆分名称:train
, eval
, test
, all
中的一个
metrics
(Dict[str, float]
) — 从训练/评估/预测返回的指标
combined
(bool
, 可选, 默认为 True
) — 通过更新 all_results.json
创建组合指标,其中包括此调用的指标。
将指标保存到一个 json 文件中,例如 train_results.json
。
在分布式环境下,这仅适用于秩为 0 的进程。
要了解指标,请阅读 log_metrics() 的文档字符串。唯一的区别是原始未格式化的数字保存在当前方法中。
save_model
( output_dir: Optional = None _internal_call: bool = False )
将保存模型,因此您可以使用 from_pretrained()
重新加载它。
仅从主进程保存。
save_state
( )
保存 Trainer 状态,因为 Trainer.save_model 仅保存了模型的 tokenizer
在分布式环境下,这仅适用于秩为 0 的进程。
train
( resume_from_checkpoint: Union = None trial: Union = None ignore_keys_for_eval: Optional = None **kwargs )
参数
resume_from_checkpoint
(str
或 bool
, 可选) — 如果是 str
,则是由之前的 Trainer 实例保存的本地路径的检查点。如果是 bool
并且等于 True
,则加载由之前的 Trainer 实例保存在 args.output_dir 中的最后一个检查点。如果存在,训练将从此处加载的模型/优化器/调度器状态恢复。
trial
(optuna.Trial
或 Dict[str, Any]
, 可选) — 运行试验或用于超参数搜索的超参数字典。
ignore_keys_for_eval
(List[str]
, 可选) — 您的模型输出中应在评估期间忽略的键的列表(如果它是一个字典)。
kwargs
(Dict[str, Any]
, 可选) — 用于隐藏已弃用参数的附加关键字参数
主要训练入口。
training_step
( model: Module inputs: Dict ) → export const metadata = 'undefined';torch.Tensor
参数
model
(nn.Module
) — 要训练的模型。
inputs
(Dict[str, Union[torch.Tensor, Any]]
) — 模型的输入和目标。
字典将在馈送到模型之前解包。大多数模型期望目标在参数labels
下。检查您模型的文档以获取所有接受的参数。
返回
torch.Tensor
这批次的训练损失的张量。
对一批输入执行训练步骤。
子类和覆盖以注入自定义行为。
class transformers.Seq2SeqTrainer
( 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 )
evaluate
( eval_dataset: Optional = None ignore_keys: Optional = None metric_key_prefix: str = 'eval' **gen_kwargs )
参数
eval_dataset
(Dataset
, 可选) — 如果要覆盖self.eval_dataset
,请传递一个数据集。如果它是一个Dataset,则不被model.forward()
方法接受的列将自动删除。它必须实现__len__
方法。
ignore_keys
(List[str]
, 可选) — 您的模型输出中应在收集预测时忽略的键的列表。
metric_key_prefix
(str
, 可选, 默认为"eval"
) — 用作指标键前缀的可选前缀。例如,如果前缀是"eval"
(默认),则指标“bleu”将被命名为“eval_bleu”。
max_length
(int
, 可选) — 在使用generate
方法进行预测时使用的最大目标长度。
num_beams
(int
, 可选) — 在使用generate
方法进行预测时将用于束搜索的束数。1 表示没有束搜索。gen_kwargs — 附加的generate
特定 kwargs。
运行评估并返回指标。
调用脚本将负责提供计算指标的方法,因为它们是任务相关的(将其传递给 init compute_metrics
参数)。
您还可以子类化并覆盖此方法以注入自定义行为。
predict
( test_dataset: Dataset ignore_keys: Optional = None metric_key_prefix: str = 'test' **gen_kwargs )
参数
test_dataset
(Dataset
) — 要在其上运行预测的数据集。如果它是一个Dataset,则不被model.forward()
方法接受的列将自动删除。必须实现__len__
方法
ignore_keys
(List[str]
, 可选) — 您的模型输出中应在收集预测时忽略的键的列表。
metric_key_prefix
(str
, 可选, 默认为"eval"
) — 用作指标键前缀的可选前缀。例如,如果前缀是"eval"
(默认),则指标“bleu”将被命名为“eval_bleu”。
max_length
(int
, 可选) — 在使用generate
方法进行预测时使用的最大目标长度。
num_beams
(int
, 可选) — 在使用generate
方法进行预测时将用于束搜索的束数。1 表示没有束搜索。gen_kwargs — 附加的generate
特定 kwargs。
运行预测并返回预测和潜在指标。
根据数据集和您的用例,您的测试数据集可能包含标签。在这种情况下,此方法还将返回指标,就像在evaluate()
中一样。
如果您的预测或标签具有不同的序列长度(例如,因为您在标记分类任务中进行动态填充),则预测将被填充(在右侧)以允许连接成一个数组。填充索引为 -100。
返回: NamedTuple 具有以下键的命名元组:
np.ndarray
): 在 test_dataset
上的预测。
np.ndarray
, optional): 标签(如果数据集包含标签)。
Dict[str, float]
, optional): 潜在的指标字典(如果数据集包含标签)。
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: Union = '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: Optional = None per_gpu_eval_batch_size: Optional = None gradient_accumulation_steps: int = 1 eval_accumulation_steps: Optional = None eval_delay: Optional = 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: Union = 'linear' lr_scheduler_kwargs: Optional = <factory> warmup_ratio: float = 0.0 warmup_steps: int = 0 log_level: Optional = 'passive' log_level_replica: Optional = 'warning' log_on_each_node: bool = True logging_dir: Optional = None logging_strategy: Union = 'steps' logging_first_step: bool = False logging_steps: float = 500 logging_nan_inf_filter: bool = True save_strategy: Union = 'steps' save_steps: float = 500 save_total_limit: Optional = None save_safetensors: Optional = True save_on_each_node: bool = False save_only_model: bool = False no_cuda: bool = False use_cpu: bool = False use_mps_device: bool = False seed: int = 42 data_seed: Optional = 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: Optional = None local_rank: int = -1 ddp_backend: Optional = None tpu_num_cores: Optional = None tpu_metrics_debug: bool = False debug: Union = '' dataloader_drop_last: bool = False eval_steps: Optional = None dataloader_num_workers: int = 0 past_index: int = -1 run_name: Optional = None disable_tqdm: Optional = None remove_unused_columns: Optional = True label_names: Optional = None load_best_model_at_end: Optional = False metric_for_best_model: Optional = None greater_is_better: Optional = None ignore_data_skip: bool = False fsdp: Union = '' fsdp_min_num_params: int = 0 fsdp_config: Optional = None fsdp_transformer_layer_cls_to_wrap: Optional = None deepspeed: Optional = None label_smoothing_factor: float = 0.0 optim: Union = 'adamw_torch' optim_args: Optional = None adafactor: bool = False group_by_length: bool = False length_column_name: Optional = 'length' report_to: Optional = None ddp_find_unused_parameters: Optional = None ddp_bucket_cap_mb: Optional = None ddp_broadcast_buffers: Optional = None dataloader_pin_memory: bool = True dataloader_persistent_workers: bool = False skip_memory_metrics: bool = True use_legacy_prediction_loop: bool = False push_to_hub: bool = False resume_from_checkpoint: Optional = None hub_model_id: Optional = None hub_strategy: Union = 'every_save' hub_token: Optional = None hub_private_repo: bool = False hub_always_push: bool = False gradient_checkpointing: bool = False gradient_checkpointing_kwargs: Optional = None include_inputs_for_metrics: bool = False fp16_backend: str = 'auto' push_to_hub_model_id: Optional = None push_to_hub_organization: Optional = None push_to_hub_token: Optional = None mp_parameters: str = '' auto_find_batch_size: bool = False full_determinism: bool = False torchdynamo: Optional = None ray_scope: Optional = 'last' ddp_timeout: Optional = 1800 torch_compile: bool = False torch_compile_backend: Optional = None torch_compile_mode: Optional = None dispatch_batches: Optional = None split_batches: Optional = False include_tokens_per_second: Optional = False include_num_input_tokens_seen: Optional = False neftune_noise_alpha: float = None )
参数
output_dir
(str
) — 模型预测和检查点将被写入的输出目录。
overwrite_output_dir
(bool
, optional, 默认为 False
) — 如果为 True
,则覆盖输出目录的内容。使用此选项继续训练,如果 output_dir
指向检查点目录。
do_train
(bool
, optional, 默认为 False
) — 是否运行训练。此参数不会直接被 Trainer 使用,而是用于您的训练/评估脚本。查看 示例脚本 获取更多详细信息。
do_eval
(bool
, optional) — 是否在验证集上运行评估。如果 evaluation_strategy
与 "no"
不同,则将设置为 True
。此参数不会直接被 Trainer 使用,而是用于您的训练/评估脚本。查看 示例脚本 获取更多详细信息。
do_predict
(bool
, optional, 默认为 False
) — 是否在测试集上运行预测。此参数不会直接被 Trainer 使用,而是用于您的训练/评估脚本。查看 示例脚本 获取更多详细信息。
evaluation_strategy
(str
或 IntervalStrategy, optional, 默认为 "no"
) — 训练期间采用的评估策略。可能的值为:
"no"
: 训练期间不进行评估。
"steps"
: 每 eval_steps
次进行评估(并记录日志)。
"epoch"
: 每个时期结束时进行评估。
prediction_loss_only
(bool
, optional, 默认为 False
) — 在进行评估和生成预测时,仅返回损失。
per_device_train_batch_size
(int
, optional, 默认为 8) — 用于训练的每个 GPU/XPU/TPU/MPS/NPU 核心/CPU 的批处理大小。
per_device_eval_batch_size
(int
, optional, 默认为 8) — 用于评估的每个 GPU/XPU/TPU/MPS/NPU 核心/CPU 的批处理大小。
gradient_accumulation_steps
(int
, optional, 默认为 1) — 累积梯度的更新步数,然后执行反向/更新传递。
使用梯度累积时,一个步骤被计为一个带有反向传递的步骤。因此,每 gradient_accumulation_steps * xxx_step
训练示例将进行日志记录、评估和保存。
eval_accumulation_steps
(int
, optional) — 在将结果移动到 CPU 之前,累积输出张量的预测步数。如果未设置,整个预测将在 GPU/NPU/TPU 上累积后再移动到 CPU(速度更快但需要更多内存)。
eval_delay
(float
, optional) — 在进行第一次评估之前等待的时期或步数,取决于 evaluation_strategy
。
learning_rate
(float
, optional, defaults to 5e-5) — AdamW 优化器的初始学习率。
weight_decay
(float
, optional, defaults to 0) — 应用的权重衰减(如果不为零)到 AdamW 优化器中的所有层,除了所有偏置和 LayerNorm 权重。
adam_beta1
(float
, optional, defaults to 0.9) — AdamW 优化器的 beta1 超参数。
adam_beta2
(float
, optional, defaults to 0.999) — AdamW 优化器的 beta2 超参数。
adam_epsilon
(float
, optional, defaults to 1e-8) — AdamW 优化器的 epsilon 超参数。
max_grad_norm
(float
, optional, defaults to 1.0) — 最大梯度范数(用于梯度裁剪)。
num_train_epochs(float,
optional, defaults to 3.0) — 执行的总训练时代数(如果不是整数,则在停止训练之前执行最后一个时代的小数部分百分比)。
max_steps
(int
, optional, defaults to -1) — 如果设置为正数,则执行的总训练步数。覆盖 num_train_epochs
。对于有限的数据集,训练通过数据集(如果所有数据都用完)重复进行,直到达到 max_steps
。
lr_scheduler_type
(str
or SchedulerType, optional, defaults to "linear"
) — 要使用的调度器类型。查看 SchedulerType 的文档以获取所有可能的值。
lr_scheduler_kwargs
(‘dict’, optional, defaults to {}) — lr_scheduler 的额外参数。查看每个调度器的文档以获取可能的值。
warmup_ratio
(float
, optional, defaults to 0.0) — 用于从 0 线性预热到 learning_rate
的总训练步数的比率。
warmup_steps
(int
, optional, defaults to 0) — 用于从 0 线性预热到 learning_rate
的步骤数。覆盖 warmup_ratio
的任何效果。
log_level
(str
, optional, defaults to passive
) — 主进程使用的记录器日志级别。可能的选择是字符串形式的日志级别:‘debug’、‘info’、‘warning’、‘error’和’critical’,以及一个’passive’级别,它不设置任何内容,并保持 Transformers 库的当前日志级别(默认为"warning"
)。
log_level_replica
(str
, optional, defaults to "warning"
) — 副本使用的记录器日志级别。与 log_level
相同的选择。
log_on_each_node
(bool
, optional, defaults to True
) — 在多节点分布式训练中,是否每个节点使用 log_level
进行日志记录,还是仅在主节点上进行。
logging_dir
(str
, optional) — TensorBoard 日志目录。默认为 output_dir/runs/CURRENT_DATETIME_HOSTNAME。
logging_strategy
(str
or IntervalStrategy, optional, defaults to "steps"
) — 训练期间采用的日志记录策略。可能的值有:
"no"
: 训练期间不进行日志记录。
"epoch"
: 每个时代结束时进行日志记录。
"steps"
: 每 logging_steps
进行日志记录。
logging_first_step
(bool
, optional, defaults to False
) — 是否记录和评估第一个 global_step
。
logging_steps
(int
or float
, optional, defaults to 500) — 如果 logging_strategy="steps"
,则在两个日志之间的更新步骤数。应为整数或范围为 0,1)
的浮点数。如果小于 1,将被解释为总训练步骤的比率。
logging_nan_inf_filter
(bool
, optional, defaults to True
) — 是否过滤用于记录的 nan
和 inf
损失。如果设置为 True
,则会过滤每个步骤的损失,如果为 nan
或 inf
,则取当前日志窗口的平均损失。
logging_nan_inf_filter
仅影响损失值的记录,不会改变梯度的计算或应用于模型的行为。
save_strategy
(str
or [IntervalStrategy, optional, defaults to "steps"
) — 训练期间采用的检查点保存策略。可能的值有:
"no"
: 训练期间不进行保存。
"epoch"
: 在每个时期结束时保存。
"steps"
: 每 save_steps
保存一次。
save_steps
(int
or float
, optional, defaults to 500) — 如果 save_strategy="steps"
,在两次检查点保存之前的更新步骤数。应为整数或范围为 [0,1)
的浮点数。如果小于 1,将被解释为总训练步骤的比率。
save_total_limit
(int
, optional) — 如果传递了一个值,将限制检查点的总量。删除 output_dir
中的旧检查点。当启用 load_best_model_at_end
时,根据 metric_for_best_model
的“最佳”检查点将始终保留在最近的检查点之外。例如,对于 save_total_limit=5
和 load_best_model_at_end
,最后四个检查点将始终与最佳模型一起保留。当 save_total_limit=1
和 load_best_model_at_end
时,可能保存两个检查点:最后一个和最佳一个(如果它们不同)。
save_safetensors
(bool
, optional, defaults to True
) — 使用 safetensors 保存和加载状态字典,而不是默认的 torch.load
和 torch.save
。
save_on_each_node
(bool
, optional, defaults to False
) — 在进行多节点分布式训练时,是否在每个节点上保存模型和检查点,还是只在主节点上保存。
当不同节点使用相同存储时,不应激活此选项,因为文件将以相同名称保存在每个节点上。
save_only_model
(bool
, optional, defaults to False
) — 在进行检查点时,是否仅保存模型,还是同时保存优化器、调度器和 rng 状态。请注意,当此选项为 true 时,您将无法从检查点恢复训练。这样可以通过不存储优化器、调度器和 rng 状态来节省存储空间。您只能使用 from_pretrained
加载模型,并将此选项设置为 True
。
use_cpu
(bool
, optional, defaults to False
) — 是否使用 cpu。如果设置为 False,将使用 cuda 或 mps 设备(如果可用)。
seed
(int
, optional, defaults to 42) — 在训练开始时设置的随机种子。为了确保多次运行的可重现性,请使用 ~Trainer.model_init
函数来实例化模型,如果模型具有一些随机初始化的参数。
data_seed
(int
, optional) — 用于数据采样器的随机种子。如果未设置,用于数据采样的随机生成器将使用与 seed
相同的种子。这可用于确保数据采样的可重现性,独立于模型种子。
jit_mode_eval
(bool
, optional, defaults to False
) — 是否使用 PyTorch jit trace 进行推断。
use_ipex
(bool
, optional, defaults to False
) — 在可用时使用 PyTorch 的 Intel 扩展。IPEX 安装。
bf16
(bool
, optional, defaults to False
) — 是否使用 bf16 16 位(混合)精度训练,而不是 32 位训练。需要安培或更高的 NVIDIA 架构,或者使用 CPU(use_cpu)或 Ascend NPU。这是一个实验性 API,可能会更改。
fp16
(bool
, optional, defaults to False
) — 是否使用 fp16 16 位(混合)精度训练,而不是 32 位训练。
fp16_opt_level
(str
, optional, defaults to ‘O1’) — 对于fp16
训练,选择在[‘O0’, ‘O1’, ‘O2’, 和 ‘O3’]中的 Apex AMP 优化级别。有关详细信息,请参阅Apex 文档。
fp16_backend
(str
, optional, defaults to "auto"
) — 此参数已弃用。请改用half_precision_backend
。
half_precision_backend
(str
, optional, defaults to "auto"
) — 用于混合精度训练的后端。必须是"auto", "apex", "cpu_amp"
之一。"auto"
将根据检测到的 PyTorch 版本使用 CPU/CUDA AMP 或 APEX,而其他选择将强制使用请求的后端。
bf16_full_eval
(bool
, optional, defaults to False
) — 是否使用完整的 bfloat16 评估,而不是 32 位。这将更快,节省内存,但可能会损害指标值。这是一个实验性 API,可能会更改。
fp16_full_eval
(bool
, optional, defaults to False
) — 是否使用完整的 float16 评估,而不是 32 位。这将更快,节省内存,但可能会损害指标值。
tf32
(bool
, optional) — 是否启用 TF32 模式,适用于安培和更新的 GPU 架构。默认值取决于 PyTorch 版本的torch.backends.cuda.matmul.allow_tf32
默认值。有关更多详细信息,请参阅TF32文档。这是一个实验性 API,可能会更改。
local_rank
(int
, optional, defaults to -1`) — 分布式训练过程中进程的排名。
ddp_backend
(str
, optional) — 用于分布式训练的后端。必须是"nccl"
, "mpi"
, "ccl"
, "gloo"
, "hccl"
之一。
tpu_num_cores
(int
, optional) — 在 TPU 上训练时,TPU 核心的数量(由启动脚本自动传递)。
dataloader_drop_last
(bool
, optional, defaults to False
) — 是否丢弃最后一个不完整的批次(如果数据集的长度不是批次大小的整数倍)。
eval_steps
(int
or float
, optional) — 如果evaluation_strategy="steps"
,则两次评估之间的更新步数。如果未设置,将默认为与logging_steps
相同的值。应为范围为0,1)
的整数或浮点数。如果小于 1,则将解释为总训练步数的比率。
dataloader_num_workers
(int
, optional, defaults to 0) — 用于数据加载的子进程数(仅适用于 PyTorch)。0 表示数据将在主进程中加载。
past_index
(int
, optional, defaults to -1) — 一些模型(如[TransformerXL 或 XLNet)可以利用过去的隐藏状态进行预测。如果将此参数设置为正整数,则
Trainer将使用相应的输出(通常为索引 2)作为过去状态,并在下一个训练步骤中将其作为关键字参数
mems`提供给模型。
run_name
(str
, optional) — 运行的描述符。通常用于wandb和mlflow日志记录。
disable_tqdm
(bool
, optional) — 是否禁用 Jupyter 笔记本中由~notebook.NotebookTrainingTracker
生成的 tqdm 进度条和指标表。如果日志级别设置为 warn 或更低(默认值),则默认为True
,否则为False
。
remove_unused_columns
(bool
, optional, defaults to True
) — 是否自动删除模型前向方法未使用的列。
label_names
(List[str]
, 可选) — 您的输入字典中与标签对应的键列表。
最终将默认为模型接受的参数名称列表,其中包含单词“label”,除非使用的模型是 XxxForQuestionAnswering
之一,那么还将包括 ["start_positions", "end_positions"]
键。
load_best_model_at_end
(bool
, 可选, 默认为 False
) — 是否在训练结束时加载找到的最佳模型。启用此选项时,将始终保存最佳检查点。有关更多信息,请参阅 save_total_limit
。
当设置为 True
时,参数 save_strategy
需要与 evaluation_strategy
相同,并且在其为 “steps” 的情况下,save_steps
必须是 eval_steps
的整数倍。
metric_for_best_model
(str
, 可选) — 与 load_best_model_at_end
结合使用,指定用于比较两个不同模型的指标。必须是评估返回的指标的名称,带有或不带有前缀 "eval_"
。如果未指定且 load_best_model_at_end=True
,将默认为 "loss"
(使用评估损失)。
如果设置了此值,greater_is_better
将默认为 True
。不要忘记,如果您的指标在较低时更好,则将其设置为 False
。
greater_is_better
(bool
, 可选) — 与 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
(bool
, 可选, 默认为 False
) — 在恢复训练时,是否跳过批次以使数据加载与先前训练中的阶段相同。如果设置为 True
,训练将更快开始(因为跳过步骤可能需要很长时间),但不会产生与中断训练相同的结果。
fsdp
(bool
, str
或 FSDPOption
列表, 可选, 默认为 ''
) — 使用 PyTorch 分布式并行训练(仅在分布式训练中)。
以下是一系列选项:
"full_shard"
: 分片参数、梯度和优化器状态。
"shard_grad_op"
: 分片优化器状态和梯度。
"hybrid_shard"
: 在节点内应用 FULL_SHARD
,并在节点之间复制参数。
"hybrid_shard_zero2"
: 在节点内应用 SHARD_GRAD_OP
,并在节点之间复制参数。
"offload"
: 将参数和梯度卸载到 CPU(仅与 "full_shard"
和 "shard_grad_op"
兼容)。
"auto_wrap"
: 使用 default_auto_wrap_policy
自动递归包装层与 FSDP。
fsdp_config
(str
或 dict
, 可选) — 用于 fsdp(Pytorch 分布式并行训练)的配置。该值可以是 fsdp json 配置文件的位置(例如,fsdp_config.json
)或已加载的 json 文件作为 dict
。
配置及其选项列表:
int
, 可选, 默认为 0
): FSDP 默认自动包装的参数最小数量。 (仅在传递 fsdp
字段时有用)。
List[str]
, 可选): 要包装的 transformer 层类名称列表(区分大小写),例如,BertLayer
、GPTJBlock
、T5Block
…(仅在传递 fsdp
标志时有用)。
str
, 可选) FSDP 的后向预取模式。控制何时预取下一组参数(仅在传递 fsdp
字段时有用)。
以下是一系列选项:
"backward_pre"
: 在当前参数的梯度计算之前,预取下一组参数。
"backward_post"
: 在当前参数的梯度计算之后,预取下一组参数。
bool
,可选,默认为False
)FSDP 的前向预取模式(仅在传递fsdp
字段时有用)。如果为"True"
,则 FSDP 在执行前向传递时明确预取下一个即将到来的全聚集。
bool
,可选,默认为False
)FSDP 的 limit_all_gathers(仅在传递fsdp
字段时有用)。如果为"True"
,FSDP 明确同步 CPU 线程,以防止太多的 in-flight all-gathers。
bool
,可选,默认为True
)如果为"True"
,允许在初始化期间使用非均匀的requires_grad
,这意味着支持交替冻结和可训练的参数。在参数高效微调等情况下很有用。请参考这个博客
bool
,可选,默认为True
)如果为"True"
,每个单独包装的 FSDP 单元将从 rank 0 广播模块参数,以确保它们在初始化后在所有 rank 中是相同的
bool
,可选,默认为False
):如果为"True"
,激活检查点是一种通过清除某些层的激活并在向后传递期间重新计算它们来减少内存使用的技术。实际上,这是以额外的计算时间换取减少内存使用。
bool
,可选,默认为False
):是否使用 PyTorch/XLA 完全分片数据并行训练。这是一个实验性功能,其 API 可能会在未来发生变化。
dict
,可选)该值是一个存储 XLA FSDP 包装参数的字典。
有关完整的选项列表,请参见这里。
bool
,可选,默认为False
):将在每个嵌套的 XLA FSDP 包装层上使用梯度检查点。此设置仅在将 xla 标志设置为 true 并通过 fsdp_min_num_params 或 fsdp_transformer_layer_cls_to_wrap 指定自动包装策略时才能使用。
deepspeed
(str
或dict
,可选)— 使用Deepspeed。这是一个实验性功能,其 API 可能会在未来发生变化。该值可以是 DeepSpeed json 配置文件的位置(例如,ds_config.json
)或已加载的 json 文件作为dict
”
label_smoothing_factor
(float
,可选,默认为 0.0)— 要使用的标签平滑因子。零表示不进行标签平滑,否则底层的 onehot 编码标签将从 0 和 1 更改为label_smoothing_factor/num_labels
和1 - label_smoothing_factor + label_smoothing_factor/num_labels
。
debug
(str
或DebugOption
列表,可选,默认为""
)— 启用一个或多个调试功能。这是一个实验性功能。
可能的选项包括:
"underflow_overflow"
:检测模型输入/输出中的溢出并报告导致事件的最后帧
"tpu_metrics_debug"
:在 TPU 上打印调试指标
选项应该用空格分隔。
optim
(str
或training_args.OptimizerNames
,可选,默认为"adamw_torch"
)— 要使用的优化器:adamw_hf、adamw_torch、adamw_torch_fused、adamw_apex_fused、adamw_anyprecision 或 adafactor。
optim_args
(str
,可选)— 供 AnyPrecisionAdamW 提供的可选参数。
group_by_length
(bool
,可选,默认为False
)— 是否在训练数据集中将大致相同长度的样本分组在一起(以最小化应用的填充并提高效率)。仅在应用动态填充时有用。
length_column_name
(str
, optional, defaults to "length"
) — 预先计算长度的列名。如果该列存在,按长度分组将使用这些值而不是在训练启动时计算它们。仅在 group_by_length
为 True
且数据集是 Dataset
的实例时才会被忽略。
report_to
(str
or List[str]
, optional, defaults to "all"
) — 报告结果和日志的集成列表。支持的平台有 "azure_ml"
、"clearml"
、"codecarbon"
、"comet_ml"
、"dagshub"
、"dvclive"
、"flyte"
、"mlflow"
、"neptune"
、"tensorboard"
和 "wandb"
。使用 "all"
报告到所有已安装的集成,使用 "none"
不报告到任何集成。
ddp_find_unused_parameters
(bool
, optional) — 在使用分布式训练时,传递给 DistributedDataParallel
的 find_unused_parameters
标志的值。如果使用了梯度检查点,则默认为 False
,否则为 True
。
ddp_bucket_cap_mb
(int
, optional) — 在使用分布式训练时,传递给 DistributedDataParallel
的 bucket_cap_mb
标志的值。
ddp_broadcast_buffers
(bool
, optional) — 在使用分布式训练时,传递给 DistributedDataParallel
的 broadcast_buffers
标志的值。如果使用了梯度检查点,则默认为 False
,否则为 True
。
dataloader_pin_memory
(bool
, optional, defaults to True
) — 是否要在数据加载器中固定内存。默认为 True
。
dataloader_persistent_workers
(bool
, optional, defaults to False
) — 如果为 True,则数据加载器在数据集被消耗一次后不会关闭工作进程。这允许保持工作进程的数据集实例处于活动状态。可能会加快训练速度,但会增加内存使用量。默认为 False
。
skip_memory_metrics
(bool
, optional, defaults to True
) — 是否跳过将内存分析器报告添加到指标中。默认情况下会跳过这一步,因为它会减慢训练和评估速度。
push_to_hub
(bool
, optional, defaults to False
) — 是否在每次保存模型时将模型推送到 Hub。如果激活了此选项,output_dir
将开始一个与仓库同步的 git 目录(由 hub_model_id
确定),并且每次触发保存时都会推送内容(取决于您的 save_strategy
)。调用 save_model() 也会触发推送。
如果 output_dir
存在,则它需要是将 Trainer 将要推送到的仓库的本地克隆。
resume_from_checkpoint
(str
, optional) — 您的模型的有效检查点所在文件夹的路径。这个参数不会直接被 Trainer 使用,而是打算由您的训练/评估脚本使用。查看 示例脚本 以获取更多详细信息。
hub_model_id
(str
, optional) — 要与本地 output_dir 保持同步的仓库名称。它可以是一个简单的模型 ID,此时模型将被推送到您的命名空间。否则,它应该是整个仓库名称,例如 "user_name/model"
,这样您就可以推送到您所属的组织,如 "organization_name/model"
。默认为 user_name/output_dir_name
,其中 output_dir_name 是 output_dir
的名称。
默认为 output_dir
的名称。
hub_strategy
(str
or HubStrategy
, optional, defaults to "every_save"
) — 定义推送到 Hub 的范围和时间。可能的值有:
"end"
: 当调用 save_model() 方法时,会推送模型、其配置、分词器(如果传递给 Trainer)以及模型卡的草稿。
"every_save"
: 每次保存模型时,都会推送模型、其配置、分词器(如果传递给 Trainer)以及模型卡的草稿。推送是异步的,以避免阻塞训练,如果保存非常频繁,则只有在上一个推送完成后才会尝试新的推送。在训练结束时,会使用最终模型进行最后一次推送。
"checkpoint"
: 类似于 "every_save"
,但最新的检查点也会被推送到名为 last-checkpoint 的子文件夹中,使您可以通过 trainer.train(resume_from_checkpoint="last-checkpoint")
轻松恢复训练。
"all_checkpoints"
: 类似于 "checkpoint"
,但所有检查点都像它们出现在输出文件夹中一样被推送(因此您将在最终存储库中获得一个检查点文件夹)。
hub_token
(str
, optional) — 用于将模型推送到 Hub 的令牌。将默认使用通过 huggingface-cli login
获取的缓存文件夹中的令牌。
hub_private_repo
(bool
, optional, 默认为 False
) — 如果为 True,则 Hub 存储库将设置为私有。
hub_always_push
(bool
, optional, 默认为 False
) — 除非为 True
,否则当上一个推送未完成时,Trainer
将跳过推送检查点。
gradient_checkpointing
(bool
, optional, 默认为 False
) — 如果为 True,则使用梯度检查点来节省内存,但会导致反向传播速度变慢。
gradient_checkpointing_kwargs
(dict
, optional, 默认为 None
) — 要传递给 gradient_checkpointing_enable
方法的关键字参数。
include_inputs_for_metrics
(bool
, optional, 默认为 False
) — 是否将输入传递给 compute_metrics
函数。这适用于需要输入、预测和参考值进行评分计算的指标类。
auto_find_batch_size
(bool
, optional, 默认为 False
) — 是否通过指数衰减自动找到适合内存的批处理大小,避免 CUDA 内存不足错误。需要安装 accelerate (pip install accelerate
)。
full_determinism
(bool
, optional, 默认为 False
) — 如果为 True
,将调用 enable_full_determinism() 而不是 set_seed() 以确保在分布式训练中获得可重现的结果。重要提示:这将对性能产生负面影响,因此仅用于调试目的。
torchdynamo
(str
, optional) — 如果设置,TorchDynamo 的后端编译器。可能的选择包括 "eager"
, "aot_eager"
, "inductor"
, "nvfuser"
, "aot_nvfuser"
, "aot_cudagraphs"
, "ofi"
, "fx2trt"
, "onnxrt"
和 "ipex"
。
ray_scope
(str
, optional, 默认为 "last"
) — 在使用 Ray 进行超参数搜索时要使用的范围。默认情况下,将使用 "last"
。然后,Ray 将使用所有试验的最后一个检查点,比较它们,并选择最佳的一个。但是,也有其他选项可用。有关更多选项,请参阅 Ray 文档。
ddp_timeout
(int
, 可选, 默认为 1800) — torch.distributed.init_process_group
调用的超时时间,用于避免在分布式运行中执行缓慢操作时出现 GPU 套接字超时。请参考[PyTorch 文档] (pytorch.org/docs/stable/distributed.html#torch.distributed.init_process_group
) 获取更多信息。
use_mps_device
(bool
, 可选, 默认为 False
) — 此参数已弃用。如果可用,将使用mps
设备,类似于cuda
设备。
torch_compile
(bool
, 可选, 默认为 False
) — 是否使用 PyTorch 2.0 torch.compile
编译模型。
这将使用torch.compile
API的最佳默认值。您可以使用参数torch_compile_backend
和torch_compile_mode
自定义默认值,但我们不能保证它们中的任何一个会起作用,因为支持逐渐在 PyTorch 中推出。
这个标志和整个编译 API 是实验性的,并可能在未来版本中发生变化。
torch_compile_backend
(str
, 可选) — 在torch.compile
中使用的后端。如果设置为任何值,torch_compile
将设置为True
。
请参考 PyTorch 文档以获取可能的值,并注意它们可能会随着 PyTorch 版本的变化而改变。
这个标志是实验性的,并可能在未来版本中发生变化。
torch_compile_mode
(str
, 可选) — 在torch.compile
中使用的模式。如果设置为任何值,torch_compile
将设置为True
。
请参考 PyTorch 文档以获取可能的值,并注意它们可能会随着 PyTorch 版本的变化而改变。
这个标志是实验性的,并可能在未来版本中发生变化。
split_batches
(bool
, 可选) — 是否加速器在分布式训练期间应该将数据加载器产生的批次分配到设备上。如果
设置为True
,实际使用的批量大小将在任何类型的分布式进程上相同,但必须是
将使用您正在使用的进程数量的倍数(例如 GPU)进行四舍五入。
include_tokens_per_second
(bool
, 可选) — 是否计算每个设备每秒的标记数以获取训练速度指标。
这将在事先迭代整个训练数据加载器一次,
并且会减慢整个过程。
include_num_input_tokens_seen
(bool
, 可选) — 是否跟踪整个训练过程中看到的输入标记数。
在分布式训练中可能会较慢,因为必须调用 gather 操作。
neftune_noise_alpha
(Optional[float]
) — 如果不是None
,这将激活 NEFTune 噪声嵌入。这可以极大地提高指令微调的模型性能。查看原始论文和原始代码。支持 transformers PreTrainedModel
和PeftModel
。
TrainingArguments 是我们在示例脚本中使用的与训练循环本身相关的参数的子集。
使用 HfArgumentParser,我们可以将这个类转换为可以在命令行上指定的argparse参数。
get_process_log_level
( )
根据这个进程是节点 0 的主进程、非 0 节点的主进程还是非主进程,返回要使用的日志级别。
对于主进程,日志级别默认为设置的日志级别(如果您没有做任何操作,则为logging.WARNING
),除非被log_level
参数覆盖。
对于副本进程,默认的日志级别为logging.WARNING
,除非被log_level_replica
参数覆盖。
根据should_log
的返回值来选择主进程和副本进程的设置。
get_warmup_steps
( num_training_steps: int )
获取用于线性预热的步数。
main_process_first
( local = True desc = 'work' )
参数
local
(bool
, optional, defaults to True
) — 如果为True
,则首先处理每个节点的排名为 0 的进程,如果为False
,则首先处理排名为 0 的节点 0 的进程。在具有共享文件系统的多节点环境中,您很可能会想要使用local=False
,以便只有第一个节点的主进程会进行处理。但是,如果文件系统不共享,则每个节点的主进程将需要进行处理,这是默认行为。
desc
(str
, optional, defaults to "work"
) — 用于调试日志中的工作描述
用于 torch 分布式环境的上下文管理器,在主进程上需要执行某些操作,同时阻塞副本,完成后释放副本。
其中一种用法是用于datasets
的map
功能,为了有效率,应该在主进程上运行一次,完成后保存结果的缓存版本,然后副本会自动加载。
set_dataloader
( train_batch_size: int = 8 eval_batch_size: int = 8 drop_last: bool = False num_workers: int = 0 pin_memory: bool = True persistent_workers: bool = False auto_find_batch_size: bool = False ignore_data_skip: bool = False sampler_seed: Optional = None )
参数
drop_last
(bool
, optional, defaults to False
) — 是否丢弃最后一个不完整的批次(如果数据集的长度不可被批次大小整除)。
num_workers
(int
, optional, defaults to 0) — 用于数据加载的子进程数量(仅适用于 PyTorch)。0 表示数据将在主进程中加载。
pin_memory
(bool
, optional, defaults to True
) — 是否要在数据加载器中固定内存。默认为True
。
persistent_workers
(bool
, optional, defaults to False
) — 如果为 True,则数据加载器在数据集被消耗一次后不会关闭工作进程。这允许保持工作进程的数据集实例保持活动状态。可能会加快训练速度,但会增加内存使用量。默认为False
。
auto_find_batch_size
(bool
, optional, defaults to False
) — 是否通过指数衰减自动找到适合内存的批次大小,避免 CUDA 内存不足错误。需要安装 accelerate(pip install accelerate
)
ignore_data_skip
(bool
, optional, defaults to False
) — 在恢复训练时,是否跳过批次和轮次以使数据加载处于与先前训练相同阶段。如果设置为True
,训练将更快开始(因为跳过步骤可能需要很长时间),但不会产生与中断训练相同的结果。
sampler_seed
(int
, optional) — 用于数据采样器的随机种子。如果未设置,则数据采样的随机生成器将使用与self.seed
相同的种子。这可用于确保数据采样的可重复性,独立于模型种子。
将所有与数据加载器创建相关的参数重新组合的方法。
示例:
>>> from transformers import TrainingArguments
>>> args = TrainingArguments("working_dir")
>>> args = args.set_dataloader(train_batch_size=16, eval_batch_size=64)
>>> args.per_device_train_batch_size
16
set_evaluate
( strategy: Union = 'no' steps: int = 500 batch_size: int = 8 accumulation_steps: Optional = None delay: Optional = None loss_only: bool = False jit_mode: bool = False )
参数
strategy
(str
或 IntervalStrategy, optional, defaults to "no"
) — 训练过程中采用的评估策略。可能的值为:
"no"
: 训练过程中不进行评估。
"steps"
: 每steps
进行评估(并记录日志)。
"epoch"
: 每个时代结束时进行评估。
设置与"no"
不同的strategy
将self.do_eval
设置为True
。
steps
(int
, optional, 默认为 500) — 如果strategy="steps"
,两次评估之间的更新步数。
batch_size
(int
optional, 默认为 8) — 用于评估的每个设备(GPU/TPU 核心/CPU…)的批量大小。
accumulation_steps
(int
, optional) — 在将结果移动到 CPU 之前,累积输出张量的预测步数。如果未设置,整个预测将在 GPU/TPU 上累积后移至 CPU(速度更快但需要更多内存)。
delay
(float
, optional) — 等待进行第一次评估的周期数或步数,取决于评估策略。
loss_only
(bool
, optional, 默认为False
) — 仅忽略损失以外的所有输出。
jit_mode
(bool
, optional) — 是否使用 PyTorch jit 跟踪进行推断。
将所有与评估相关的参数分组的方法。
示例:
>>> from transformers import TrainingArguments
>>> args = TrainingArguments("working_dir")
>>> args = args.set_evaluate(strategy="steps", steps=100)
>>> args.eval_steps
100
set_logging
( strategy: Union = 'steps' steps: int = 500 report_to: Union = 'none' level: str = 'passive' first_step: bool = False nan_inf_filter: bool = False on_each_node: bool = False replica_level: str = 'passive' )
参数
strategy
(str
或 IntervalStrategy, optional, 默认为"steps"
) — 训练期间采用的日志记录策略。可能的值有:
"no"
: 训练期间不保存。
"epoch"
: 在每个周期结束时保存。
"steps"
: 每save_steps
保存一次。
steps
(int
, optional, 默认为 500) — 如果strategy="steps"
,两次日志记录之间的更新步数。
level
(str
, optional, 默认为"passive"
) — 用于主进程的记录器日志级别。可能的选择是字符串形式的日志级别:"debug"
、"info"
、"warning"
、"error"
和"critical"
,以及一个不设置任何内容并让应用程序设置级别的"passive"
级别。
report_to
(str
或 List[str]
, optional, 默认为"all"
) — 报告结果和日志的集成列表。支持的平台有"azure_ml"
、"clearml"
、"codecarbon"
、"comet_ml"
、"dagshub"
、"dvclive"
、"flyte"
、"mlflow"
、"neptune"
、"tensorboard"
和"wandb"
。使用"all"
报告所有已安装的集成,使用"none"
不报告任何集成。
first_step
(bool
, optional, 默认为False
) — 是否记录和评估第一个global_step
。
nan_inf_filter
(bool
, optional, 默认为True
) — 是否过滤用于日志记录的nan
和inf
损失。如果设置为True
,则过滤每个步骤的nan
或inf
损失,并取代当前日志窗口的平均损失。
nan_inf_filter
仅影响损失值的日志记录,不会改变计算梯度或将梯度应用于模型的行为。
on_each_node
(bool
, optional, 默认为True
) — 在多节点分布式训练中,是否每个节点仅使用log_level
一次进行日志记录,或仅在主节点上进行日志记录。
replica_level
(str
, optional, 默认为"passive"
) — 用于副本的记录器日志级别。与log_level
相同的选择。
将所有与日志记录相关的参数分组的方法。
示例:
>>> from transformers import TrainingArguments
>>> args = TrainingArguments("working_dir")
>>> args = args.set_logging(strategy="steps", steps=100)
>>> args.logging_steps
100
set_lr_scheduler
( name: Union = 'linear' num_epochs: float = 3.0 max_steps: int = -1 warmup_ratio: float = 0 warmup_steps: int = 0 )
参数
name
(str
或 SchedulerType, optional, 默认为"linear"
) — 要使用的调度程序类型。查看 SchedulerType 的文档以获取所有可能的值。
num_epochs(float,
optional, 默认为 3.0) — 要执行的总训练周期数(如果不是整数,则在停止训练之前执行最后一个周期的小数部分百分比)。
max_steps
(int
, 可选, 默认为 -1) — 如果设置为正数,则执行的总训练步数。覆盖num_train_epochs
。对于有限的数据集,如果所有数据都用完,则通过数据集重复训练,直到达到max_steps
。
warmup_ratio
(float
, 可选, 默认为 0.0) — 用于从 0 到learning_rate
进行线性预热的总训练步骤的比率。
warmup_steps
(int
, 可选, 默认为 0) — 用于从 0 到learning_rate
进行线性预热的步骤数。覆盖warmup_ratio
的任何效果。
一个将所有与学习率调度器及其超参数相关联的参数重新分组的方法。
示例:
>>> from transformers import TrainingArguments
>>> args = TrainingArguments("working_dir")
>>> args = args.set_lr_scheduler(name="cosine", warmup_ratio=0.05)
>>> args.warmup_ratio
0.05
set_optimizer
( name: Union = 'adamw_torch' learning_rate: float = 5e-05 weight_decay: float = 0 beta1: float = 0.9 beta2: float = 0.999 epsilon: float = 1e-08 args: Optional = None )
参数
name
(str
或 training_args.OptimizerNames
, 可选, 默认为 "adamw_torch"
) — 要使用的优化器:“adamw_hf”、“adamw_torch”、“adamw_torch_fused”、“adamw_apex_fused”、“adamw_anyprecision"或"adafactor”。
learning_rate
(float
, 可选, 默认为 5e-5) — 初始学习率。
weight_decay
(float
, 可选, 默认为 0) — 应用的权重衰减(如果不为零)到所有层,除了所有偏置和 LayerNorm 权重。
beta1
(float
, 可选, 默认为 0.9) — Adam 优化器或其变种的 beta1 超参数。
beta2
(float
, 可选, 默认为 0.999) — Adam 优化器或其变种的 beta2 超参数。
epsilon
(float
, 可选, 默认为 1e-8) — Adam 优化器或其变种的 epsilon 超参数。
args
(str
, 可选) — 提供给 AnyPrecisionAdamW 的可选参数(仅在optim="adamw_anyprecision"
时有用)。
一个将所有与优化器及其超参数相关联的参数重新分组的方法。
示例:
>>> from transformers import TrainingArguments
>>> args = TrainingArguments("working_dir")
>>> args = args.set_optimizer(name="adamw_torch", beta1=0.8)
>>> args.optim
'adamw_torch'
set_push_to_hub
( model_id: str strategy: Union = 'every_save' token: Optional = None private_repo: bool = False always_push: bool = False )
参数
model_id
(str
) — 与本地output_dir同步的存储库的名称。它可以是一个简单的模型 ID,此时模型将被推送到您的命名空间。否则,它应该是整个存储库名称,例如"user_name/model"
,这样您就可以将其推送到您是成员的组织中,例如"organization_name/model"
。
strategy
(str
或 HubStrategy
, 可选, 默认为 "every_save"
) — 定义推送到 Hub 的范围和时间。可能的值为:
"end"
: 当调用 save_model()方法时,推送模型、其配置、分词器(如果传递给 Trainer)以及模型卡的草稿。
"every_save"
: 每次保存模型时,推送模型、其配置、分词器(如果传递给 Trainer)以及模型卡的草稿。推送是异步的,以避免阻塞训练,如果保存非常频繁,则只有在上一个推送完成后才会尝试新的推送。在训练结束时,使用最终模型进行最后一次推送。
"checkpoint"
: 类似于"every_save"
,但最新的检查点也被推送到名为 last-checkpoint 的子文件夹中,这样您可以轻松地使用trainer.train(resume_from_checkpoint="last-checkpoint")
恢复训练。
"all_checkpoints"
: 类似于"checkpoint"
,但所有检查点都像它们出现在输出文件夹中一样被推送(因此您将在最终存储库中的每个文件夹中获得一个检查点文件夹)。
token
(str
, 可选) — 用于将模型推送到 Hub 的令牌。将默认使用通过huggingface-cli login
获得的缓存文件夹中的令牌。
private_repo
(bool
, 可选, 默认为 False
) — 如果为 True,则 Hub 存储库将设置为私有。
bool
,可选,默认为False
)— 除非为True
,否则当上一次推送未完成时,Trainer
将跳过推送检查点。
将所有与与 Hub 同步检查点相关的参数进行分组的方法。
调用此方法将设置self.push_to_hub
为True
,这意味着output_dir
将开始一个与存储库同步的 git 目录(由model_id
确定),并且每次触发保存时将推送内容(取决于self.save_strategy
)。调用 save_model()也将触发推送。
示例:
>>> from transformers import TrainingArguments
>>> args = TrainingArguments("working_dir")
>>> args = args.set_push_to_hub("me/awesome-model")
>>> args.hub_model_id
'me/awesome-model'
set_save
( strategy: Union = 'steps' steps: int = 500 total_limit: Optional = None on_each_node: bool = False )
参数
str
或 IntervalStrategy,可选,默认为"steps"
)— 训练期间采用的检查点保存策略。可能的值为:
"no"
:在训练期间不进行保存。
"epoch"
:在每个时代结束时保存。
"steps"
:每save_steps
保存一次。
steps
(int
,可选,默认为 500)— 如果strategy="steps"
,则在两个检查点保存之前的更新步骤数。
int
,可选)— 如果传递了一个值,将限制检查点的总量。删除output_dir
中的旧检查点。
bool
,可选,默认为False
)— 在进行多节点分布式训练时,是否在每个节点上保存模型和检查点,还是仅在主节点上保存。
当不同节点使用相同存储时,不应激活此选项,因为文件将以每个节点相同的名称保存。
将所有与检查点保存相关的参数进行分组的方法。
示例:
>>> from transformers import TrainingArguments
>>> args = TrainingArguments("working_dir")
>>> args = args.set_save(strategy="steps", steps=100)
>>> args.save_steps
100
set_testing
( batch_size: int = 8 loss_only: bool = False jit_mode: bool = False )
参数
int
可选,默认为 8)— 用于测试的每个设备(GPU/TPU 核心/CPU…)的批量大小。
bool
,可选,默认为False
)— 除了损失之外,忽略所有输出。
bool
,可选)— 是否使用 PyTorch jit 跟踪进行推断。
将所有与在保留数据集上进行测试相关的基本参数进行分组的方法。
调用此方法将自动将self.do_predict
设置为True
。
示例:
>>> from transformers import TrainingArguments
>>> args = TrainingArguments("working_dir")
>>> args = args.set_testing(batch_size=32)
>>> args.per_device_eval_batch_size
32
set_training
( learning_rate: float = 5e-05 batch_size: int = 8 weight_decay: float = 0 num_epochs: float = 3 max_steps: int = -1 gradient_accumulation_steps: int = 1 seed: int = 42 gradient_checkpointing: bool = False )
参数
float
,可选,默认为 5e-5)— 优化器的初始学习率。
int
可选,默认为 8)— 用于训练的每个设备(GPU/TPU 核心/CPU…)的批量大小。
float
,可选,默认为 0)— 应用的权重衰减(如果不为零)到优化器中除所有偏置和 LayerNorm 权重之外的所有层。
int
,可选,默认为-1)— 如果设置为正数,则执行的总训练步数。覆盖num_train_epochs
。对于有限的数据集,如果所有数据都用完,则通过数据集重复训练,直到达到max_steps
。
int
,可选,默认为 1)— 在执行向后/更新传递之前,累积梯度的更新步骤数。
在使用梯度累积时,一个步骤被计为一个带有向后传递的步骤。因此,每gradient_accumulation_steps * xxx_step
个训练示例将进行日志记录、评估和保存。
seed
(int
, optional, 默认为 42) — 将在训练开始时设置的随机种子。为了确保在不同运行之间的可重现性,请使用 ~Trainer.model_init
函数来实例化模型,如果模型有一些随机初始化的参数。
gradient_checkpointing
(bool
, optional, 默认为 False
) — 如果为 True,则使用梯度检查点来节省内存,但会降低向后传递的速度。
将所有与训练相关的基本参数重新组合的方法。
调用此方法将自动将 self.do_train
设置为 True
。
示例:
>>> from transformers import TrainingArguments
>>> args = TrainingArguments("working_dir")
>>> args = args.set_training(learning_rate=1e-4, batch_size=32)
>>> args.learning_rate
1e-4
to_dict
( )
将此实例序列化,同时用它们的值替换 Enum
(用于 JSON 序列化支持)。通过删除它们的值来混淆令牌值。
to_json_string
( )
将此实例序列化为 JSON 字符串。
to_sanitized_dict
( )
经过清理的序列化,可与 TensorBoard 的 hparams 一起使用
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: Union = '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: Optional = None per_gpu_eval_batch_size: Optional = None gradient_accumulation_steps: int = 1 eval_accumulation_steps: Optional = None eval_delay: Optional = 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: Union = 'linear' lr_scheduler_kwargs: Optional = <factory> warmup_ratio: float = 0.0 warmup_steps: int = 0 log_level: Optional = 'passive' log_level_replica: Optional = 'warning' log_on_each_node: bool = True logging_dir: Optional = None logging_strategy: Union = 'steps' logging_first_step: bool = False logging_steps: float = 500 logging_nan_inf_filter: bool = True save_strategy: Union = 'steps' save_steps: float = 500 save_total_limit: Optional = None save_safetensors: Optional = True save_on_each_node: bool = False save_only_model: bool = False no_cuda: bool = False use_cpu: bool = False use_mps_device: bool = False seed: int = 42 data_seed: Optional = 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: Optional = None local_rank: int = -1 ddp_backend: Optional = None tpu_num_cores: Optional = None tpu_metrics_debug: bool = False debug: Union = '' dataloader_drop_last: bool = False eval_steps: Optional = None dataloader_num_workers: int = 0 past_index: int = -1 run_name: Optional = None disable_tqdm: Optional = None remove_unused_columns: Optional = True label_names: Optional = None load_best_model_at_end: Optional = False metric_for_best_model: Optional = None greater_is_better: Optional = None ignore_data_skip: bool = False fsdp: Union = '' fsdp_min_num_params: int = 0 fsdp_config: Optional = None fsdp_transformer_layer_cls_to_wrap: Optional = None deepspeed: Optional = None label_smoothing_factor: float = 0.0 optim: Union = 'adamw_torch' optim_args: Optional = None adafactor: bool = False group_by_length: bool = False length_column_name: Optional = 'length' report_to: Optional = None ddp_find_unused_parameters: Optional = None ddp_bucket_cap_mb: Optional = None ddp_broadcast_buffers: Optional = None dataloader_pin_memory: bool = True dataloader_persistent_workers: bool = False skip_memory_metrics: bool = True use_legacy_prediction_loop: bool = False push_to_hub: bool = False resume_from_checkpoint: Optional = None hub_model_id: Optional = None hub_strategy: Union = 'every_save' hub_token: Optional = None hub_private_repo: bool = False hub_always_push: bool = False gradient_checkpointing: bool = False gradient_checkpointing_kwargs: Optional = None include_inputs_for_metrics: bool = False fp16_backend: str = 'auto' push_to_hub_model_id: Optional = None push_to_hub_organization: Optional = None push_to_hub_token: Optional = None mp_parameters: str = '' auto_find_batch_size: bool = False full_determinism: bool = False torchdynamo: Optional = None ray_scope: Optional = 'last' ddp_timeout: Optional = 1800 torch_compile: bool = False torch_compile_backend: Optional = None torch_compile_mode: Optional = None dispatch_batches: Optional = None split_batches: Optional = False include_tokens_per_second: Optional = False include_num_input_tokens_seen: Optional = False neftune_noise_alpha: float = None sortish_sampler: bool = False predict_with_generate: bool = False generation_max_length: Optional = None generation_num_beams: Optional = None generation_config: Union = None )
参数
output_dir
(str
) — 模型预测和检查点将被写入的输出目录。
overwrite_output_dir
(bool
, optional, 默认为 False
) — 如果为 True
,则覆盖输出目录的内容。如果 output_dir
指向一个检查点目录,则使用此选项继续训练。
do_train
(bool
, optional, 默认为 False
) — 是否运行训练。此参数不会直接被 Trainer 使用,而是打算由您的训练/评估脚本使用。有关更多详细信息,请参阅示例脚本。
do_eval
(bool
, optional) — 是否在验证集上运行评估。如果 evaluation_strategy
与 "no"
不同,则将设置为 True
。此参数不会直接被 Trainer 使用,而是打算由您的训练/评估脚本使用。有关更多详细信息,请参阅示例脚本。
do_predict
(bool
, optional, 默认为 False
) — 是否在测试集上运行预测。此参数不会直接被 Trainer 使用,而是打算由您的训练/评估脚本使用。有关更多详细信息,请参阅示例脚本。
evaluation_strategy
(str
或 IntervalStrategy, optional, 默认为 "no"
) — 训练期间采用的评估策略。可能的值有:
"no"
: 在训练期间不进行评估。
"steps"
: 每 eval_steps
进行一次评估(并记录)。
"epoch"
: 在每个时代结束时进行评估。
prediction_loss_only
(bool
, optional, 默认为 False
) — 在进行评估和生成预测时,仅返回损失。
per_device_train_batch_size
(int
, optional, 默认为 8) — 训练时每个 GPU/XPU/TPU/MPS/NPU 核心/CPU 的批量大小。
per_device_eval_batch_size
(int
, optional, 默认为 8) — 评估时每个 GPU/XPU/TPU/MPS/NPU 核心/CPU 的批量大小。
gradient_accumulation_steps
(int
, optional, 默认为 1) — 在执行向后/更新传递之前,累积梯度的更新步骤数。
在使用梯度累积时,一个步骤被计为一个带有反向传播的步骤。因此,每 gradient_accumulation_steps * xxx_step
训练示例将进行记录、评估、保存。
eval_accumulation_steps
(int
, 可选) — 在将结果移动到 CPU 之前,累积输出张量的预测步数。如果未设置,整个预测将在 GPU/NPU/TPU 上累积后再移动到 CPU(更快但需要更多内存)。
eval_delay
(float
, 可选) — 在进行第一次评估之前等待的周期数或步数,具体取决于 evaluation_strategy。
learning_rate
(float
, 可选, 默认为 5e-5) — AdamW 优化器的初始学习率。
weight_decay
(float
, 可选, 默认为 0) — 要应用的权重衰减(如果不为零)到所有层,除了 AdamW 优化器中的所有偏置和 LayerNorm 权重。
adam_beta1
(float
, 可选, 默认为 0.9) — AdamW 优化器的 beta1 超参数。
adam_beta2
(float
, 可选, 默认为 0.999) — AdamW 优化器的 beta2 超参数。
adam_epsilon
(float
, 可选, 默认为 1e-8) — AdamW 优化器的 epsilon 超参数。
max_grad_norm
(float
, 可选, 默认为 1.0) — 最大梯度范数(用于梯度裁剪)。
num_train_epochs(float,
可选, 默认为 3.0) — 要执行的总训练周期数(如果不是整数,则在停止训练之前执行最后一个周期的小数部分百分比)。
max_steps
(int
, 可选, 默认为 -1) — 如果设置为正数,则执行的总训练步数。覆盖 num_train_epochs
。对于有限的数据集,如果所有数据都用完,则通过数据集重新进行训练,直到达到 max_steps
。
lr_scheduler_type
(str
或 SchedulerType, 可选, 默认为 "linear"
) — 要使用的调度器类型。查看 SchedulerType 的文档以获取所有可能的值。
lr_scheduler_kwargs
(‘dict’, 可选, 默认为 {}) — lr_scheduler 的额外参数。查看每个调度器的文档以获取可能的值。
warmup_ratio
(float
, 可选, 默认为 0.0) — 用于从 0 到 learning_rate
进行线性预热的总训练步数的比率。
warmup_steps
(int
, 可选, 默认为 0) — 用于从 0 到 learning_rate
进行线性预热的步数。覆盖任何 warmup_ratio
的效果。
log_level
(str
, 可选, 默认为 passive
) — 要在主进程上使用的记录器日志级别。可能的选择是字符串形式的日志级别:‘debug’、‘info’、"warning"
、‘error’ 和 ‘critical’,以及一个passive
级别,它不设置任何内容并保持 Transformers 库的当前日志级别(默认为 "warning"
)。
log_level_replica
(str
, 可选, 默认为 "warning"
) — 用于副本的记录器日志级别。与 log_level
相同的选择”
log_on_each_node
(bool
, 可选, 默认为 True
) — 在多节点分布式训练中,是否每个节点使用 log_level
进行记录,或仅在主节点上进行记录。
logging_dir
(str
, 可选) — TensorBoard 日志目录。将默认为 output_dir/runs/CURRENT_DATETIME_HOSTNAME。
logging_strategy
(str
或 IntervalStrategy,可选,默认为 "steps"
) — 训练过程中采用的日志记录策略。可能的取值有:
"no"
: 训练过程中不进行日志记录。
"epoch"
: 每个时代结束时进行日志记录。
"steps"
: 每 logging_steps
步进行日志记录。
logging_first_step
(bool
,可选,默认为 False
) — 是否记录和评估第一个 global_step
。
logging_steps
(int
或 float
,可选,默认为 500) — 如果 logging_strategy="steps"
,则在两次日志之间的更新步数。应为整数或范围为 0,1)
的浮点数。如果小于 1,则将被解释为总训练步数的比率。
logging_nan_inf_filter
(bool
,可选,默认为 True
) — 是否过滤用于记录的 nan
和 inf
损失。如果设置为 True
,则会过滤每个步骤的损失值为 nan
或 inf
,并取当前日志窗口的平均损失值。
logging_nan_inf_filter
仅影响损失值的记录,不会改变梯度的计算或应用于模型的行为。
save_strategy
(str
或 [IntervalStrategy,可选,默认为 "steps"
) — 训练过程中采用的检查点保存策略。可能的取值有:
"no"
: 训练过程中不进行保存。
"epoch"
: 每个时代结束时保存。
"steps"
: 每 save_steps
步保存一次。
save_steps
(int
或 float
,可选,默认为 500) — 如果 save_strategy="steps"
,则在两次检查点保存之间的更新步数。应为整数或范围为 [0,1)
的浮点数。如果小于 1,则将被解释为总训练步数的比率。
save_total_limit
(int
,可选) — 如果传递了一个值,将限制检查点的总量。删除 output_dir
中的旧检查点。当启用 load_best_model_at_end
时,“最佳”检查点始终会保留,而且还会保留最近的检查点。例如,对于 save_total_limit=5
和 load_best_model_at_end
,最后四个检查点将始终与最佳模型一起保留。当 save_total_limit=1
和 load_best_model_at_end
时,可能保存两个检查点:最后一个和最佳一个(如果它们不同)。
save_safetensors
(bool
,可选,默认为 True
) — 使用 safetensors 保存和加载状态字典,而不是默认的 torch.load
和 torch.save
。
save_on_each_node
(bool
,可选,默认为 False
) — 在进行多节点分布式训练时,是否在每个节点上保存模型和检查点,还是仅在主节点上保存。
当不同节点使用相同存储时,不应激活此选项,因为文件将以相同名称保存在每个节点上。
save_only_model
(bool
,可选,默认为 False
) — 在检查点时,是否仅保存模型,还是同时保存优化器、调度器和 RNG 状态。请注意,当此选项为真时,您将无法从检查点恢复训练。这样可以通过不存储优化器、调度器和 RNG 状态来节省存储空间。您只能使用 from_pretrained
加载模型,并将此选项设置为 True
。
use_cpu
(bool
,可选,默认为 False
) — 是否使用 CPU。如果设置为 False,将使用 cuda 或 mps 设备(如果可用)。
seed
(int
,可选,默认为 42) — 在训练开始时设置的随机种子。为了确保跨运行的可重现性,请使用 ~Trainer.model_init
函数来实例化模型,如果模型具有一些随机初始化的参数。
data_seed
(int
, optional) — 用于数据采样的随机种子。如果未设置,数据采样的随机生成器将使用与seed
相同的种子。这可用于确保数据采样的可重现性,与模型种子无关。
jit_mode_eval
(bool
, optional, defaults to False
) — 是否使用 PyTorch jit 跟踪进行推断。
use_ipex
(bool
, optional, defaults to False
) — 在 PyTorch 可用时使用 Intel 扩展。IPEX 安装。
bf16
(bool
, optional, defaults to False
) — 是否使用 bf16 16 位(混合)精度训练,而不是 32 位训练。需要安普尔或更高的 NVIDIA 架构或使用 CPU(use_cpu)或 Ascend NPU。这是一个实验性的 API,可能会发生变化。
fp16
(bool
, optional, defaults to False
) — 是否使用 fp16 16 位(混合)精度训练,而不是 32 位训练。
fp16_opt_level
(str
, optional, defaults to ‘O1’) — 对于fp16
训练,选择在[‘O0’, ‘O1’, ‘O2’, 和 ‘O3’]中的 Apex AMP 优化级别。有关详细信息,请参阅Apex 文档。
fp16_backend
(str
, optional, defaults to "auto"
) — 此参数已弃用。请改用half_precision_backend
。
half_precision_backend
(str
, optional, defaults to "auto"
) — 用于混合精度训练的后端。必须是"auto", "apex", "cpu_amp"
之一。"auto"
将根据检测到的 PyTorch 版本使用 CPU/CUDA AMP 或 APEX,而其他选择将强制使用请求的后端。
bf16_full_eval
(bool
, optional, defaults to False
) — 是否使用完整的 bfloat16 评估,而不是 32 位。这将更快,节省内存,但可能会损害指标值。这是一个实验性的 API,可能会发生变化。
fp16_full_eval
(bool
, optional, defaults to False
) — 是否使用完整的 float16 评估,而不是 32 位。这将更快,节省内存,但可能会损害指标值。
tf32
(bool
, optional) — 是否启用 TF32 模式,适用于 Ampere 和更新的 GPU 架构。默认值取决于 PyTorch 的版本默认值torch.backends.cuda.matmul.allow_tf32
。有关更多详细信息,请参阅TF32文档。这是一个实验性的 API,可能会发生变化。
local_rank
(int
, optional, defaults to -1) — 分布式训练期间进程的排名。
ddp_backend
(str
, optional) — 用于分布式训练的后端。必须是"nccl"
, "mpi"
, "ccl"
, "gloo"
, "hccl"
之一。
tpu_num_cores
(int
, optional) — 在 TPU 上训练时,TPU 核心的数量(由启动脚本自动传递)。
dataloader_drop_last
(bool
, optional, defaults to False
) — 是否丢弃最后一个不完整的批次(如果数据集的长度不能被批次大小整除)。
eval_steps
(int
or float
, optional) — 如果evaluation_strategy="steps"
,则两次评估之间的更新步数。如果未设置,将默认为与logging_steps
相同的值。应为范围在0,1)
的整数或浮点数。如果小于 1,将被解释为总训练步数的比率。
dataloader_num_workers
(int
, optional, defaults to 0) — 用于数据加载的子进程数(仅适用于 PyTorch)。0 表示数据将在主进程中加载。
past_index
(int
, optional, defaults to -1) — 一些模型(如[TransformerXL 或 XLNet)可以利用过去的隐藏状态进行预测。如果将此参数设置为正整数,则Trainer
将使用相应的输出(通常为索引 2)作为过去状态,并在下一个训练步骤中将其作为关键字参数mems
提供给模型。
run_name
(str
, optional) — 运行的描述符。通常用于wandb和mlflow日志记录。
disable_tqdm
(bool
, optional) — 是否禁用 Jupyter 笔记本中~notebook.NotebookTrainingTracker
生成的 tqdm 进度条和指标表。如果日志级别设置为 warn 或更低(默认),则默认为True
,否则为False
。
remove_unused_columns
(bool
, optional, defaults to True
) — 是否自动删除模型前向方法未使用的列。
label_names
(List[str]
, optional) — 您的输入字典中对应于标签的键列表。
最终将默认为模型接受的参数名称列表,其中包含单词“label”,除非使用的模型是XxxForQuestionAnswering
之一,在这种情况下还将包括["start_positions", "end_positions"]
键。
load_best_model_at_end
(bool
, optional, defaults to False
) — 是否在训练结束时加载训练过程中找到的最佳模型。启用此选项时,最佳检查点将始终被保存。更多信息请参见save_total_limit
。
设置为True
时,参数save_strategy
需要与evaluation_strategy
相同,如果是“steps”,则save_steps
必须是eval_steps
的整数倍。
metric_for_best_model
(str
, optional) — 与load_best_model_at_end
一起使用,指定用于比较两个不同模型的度量标准。必须是评估返回的度量的名称,带有或不带有前缀"eval_"
。如果未指定且load_best_model_at_end=True
(使用评估损失),将默认为"loss"
。
如果设置了此值,greater_is_better
将默认为True
。如果您的度量标准较低时更好,请不要忘记将其设置为False
。
greater_is_better
(bool
, optional) — 与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
(bool
, optional, defaults to False
) — 恢复训练时,是否跳过批次和轮次以使数据加载与先前训练的阶段相同。如果设置为True
,训练将更快开始(因为跳过步骤可能需要很长时间),但不会产生与中断训练相同的结果。
fsdp
(bool
, str
or list of FSDPOption
, optional, defaults to ''
) — 使用 PyTorch 分布式并行训练(仅在分布式训练中)。
以下选项列表:
"full_shard"
: 分片参数、梯度和优化器状态。
"shard_grad_op"
: 分片优化器状态和梯度。
"hybrid_shard"
: 在节点内应用FULL_SHARD
,并在节点之间复制参数。
"hybrid_shard_zero2"
: 在节点内应用SHARD_GRAD_OP
,并在节点之间复制参数。
"offload"
: 将参数和梯度卸载到 CPU(仅与"full_shard"
和"shard_grad_op"
兼容)。
"auto_wrap"
: 使用default_auto_wrap_policy
自动递归包装层与 FSDP。
fsdp_config
(str
or dict
, optional) — 用于 fsdp(Pytorch 分布式并行训练)的配置。该值可以是 fsdp json 配置文件的位置(例如,fsdp_config.json
)或已加载的 json 文件作为dict
。
配置及其选项列表:
int
, optional, defaults to 0
): FSDP 的默认自动包装的参数最小数量。(仅在传递fsdp
字段时有用)。
List[str]
,可选):要包装的 transformer 层类名称列表(区分大小写),例如,BertLayer
,GPTJBlock
,T5Block
…(仅在传递fsdp
标志时有用)。
str
,可选)FSDP 的后向预取模式。控制何时预取下一组参数(仅在传递fsdp
字段时有用)。
以下是一系列选项:
"backward_pre"
:在当前参数梯度计算之前预取下一组参数。
"backward_post"
:在当前参数梯度计算之后预取下一组参数。
bool
,可选,默认为False
)FSDP 的前向预取模式(仅在传递fsdp
字段时有用)。如果为"True"
,则 FSDP 会在前向传递中显式预取下一个即将到来的 all-gather。
bool
,可选,默认为False
)FSDP 的 limit_all_gathers(仅在传递fsdp
字段时有用)。如果为"True"
,FSDP 会显式同步 CPU 线程,以防止太多的 in-flight all-gathers。
bool
,可选,默认为True
)如果为"True"
,允许在初始化期间使用非均匀的requires_grad
,这意味着支持交替冻结和可训练参数。在参数高效微调等情况下非常有用。请参考此[博客](dev-discuss.pytorch.org/t/rethinking-pytorch-fully-sharded-data-parallel-fsdp-from-first-principles/1019
bool
,可选,默认为True
)如果为"True"
,每个单独包装的 FSDP 单元将从 rank 0 广播模块参数,以确保在初始化后所有 rank 中的参数相同
bool
,可选,默认为False
):如果为"True"
,激活检查点是一种通过清除某些层的激活并在反向传递期间重新计算它们来减少内存使用的技术。实际上,这是以额外的计算时间换取减少内存使用。
bool
,可选,默认为False
):是否使用 PyTorch/XLA 完全分片数据并行训练。这是一个实验性功能,其 API 可能会在未来发生变化。
dict
,可选)该值是一个存储 XLA FSDP 包装参数的字典。
有关所有选项的完整列表,请参见此处。
bool
,可选,默认为False
):将在每个嵌套的 XLA FSDP 包装层上使用梯度检查点。只有在将 xla 标志设置为 true,并通过 fsdp_min_num_params 或 fsdp_transformer_layer_cls_to_wrap 指定了自动包装策略时才能使用此设置。
deepspeed
(str
或dict
,可选)—使用Deepspeed。这是一个实验性功能,其 API 可能会在未来发生变化。该值可以是 DeepSpeed json 配置文件的位置(例如,ds_config.json
)或已加载的 json 文件作为dict
”
label_smoothing_factor
(float
,可选,默认为 0.0)—要使用的标签平滑因子。零表示不进行标签平滑,否则基础的 onehot 编码标签将从 0 和 1 更改为label_smoothing_factor/num_labels
和1 - label_smoothing_factor + label_smoothing_factor/num_labels
。
debug
(str
或DebugOption
列表,可选,默认为""
)—启用一个或多个调试功能。这是一个实验性功能。
可能的选项有:
"underflow_overflow"
:检测模型输入/输出中的溢出并报告导致事件的最后帧
"tpu_metrics_debug"
:在 TPU 上打印调试指标
选项应该用空格分隔。
optim
(str
or training_args.OptimizerNames
, optional, defaults to "adamw_torch"
) — 要使用的优化器:adamw_hf、adamw_torch、adamw_torch_fused、adamw_apex_fused、adamw_anyprecision 或 adafactor。
optim_args
(str
, optional) — 提供给 AnyPrecisionAdamW 的可选参数。
group_by_length
(bool
, optional, defaults to False
) — 是否在训练数据集中将大致相同长度的样本分组在一起(以最小化填充并提高效率)。仅在应用动态填充时有用。
length_column_name
(str
, optional, defaults to "length"
) — 预先计算长度的列名。如果该列存在,则按长度分组将使用这些值而不是在训练启动时计算它们。仅在 group_by_length
为 True
且数据集是 Dataset
的实例时才会被忽略。
report_to
(str
or List[str]
, optional, defaults to "all"
) — 报告结果和日志的集成列表。支持的平台有 "azure_ml"
、"clearml"
、"codecarbon"
、"comet_ml"
、"dagshub"
、"dvclive"
、"flyte"
、"mlflow"
、"neptune"
、"tensorboard"
和 "wandb"
。使用 "all"
报告到所有已安装的集成,使用 "none"
不报告到任何集成。
ddp_find_unused_parameters
(bool
, optional) — 在使用分布式训练时,传递给 DistributedDataParallel
的标志 find_unused_parameters
的值。如果使用了梯度检查点,则默认为 False
,否则为 True
。
ddp_bucket_cap_mb
(int
, optional) — 在使用分布式训练时,传递给 DistributedDataParallel
的标志 bucket_cap_mb
的值。
ddp_broadcast_buffers
(bool
, optional) — 在使用分布式训练时,传递给 DistributedDataParallel
的标志 broadcast_buffers
的值。如果使用了梯度检查点,则默认为 False
,否则为 True
。
dataloader_pin_memory
(bool
, optional, defaults to True
) — 是否要在数据加载器中固定内存。默认为 True
。
dataloader_persistent_workers
(bool
, optional, defaults to False
) — 如果为 True,则数据加载器在数据集被消耗一次后不会关闭工作进程。这允许保持工作人员数据集实例的活动状态。可能会加快训练速度,但会增加 RAM 使用量。默认为 False
。
skip_memory_metrics
(bool
, optional, defaults to True
) — 是否跳过将内存分析报告添加到指标中。默认跳过此步骤,因为它会减慢训练和评估速度。
push_to_hub
(bool
, optional, defaults to False
) — 每次保存模型时是否将模型推送到 Hub。如果激活了此选项,output_dir
将开始一个与存储库同步的 git 目录(由 hub_model_id
确定),并且每次触发保存时都会推送内容(取决于您的 save_strategy
)。调用 save_model() 也会触发推送。
如果 output_dir
存在,则需要是将 Trainer 推送到的存储库的本地克隆。
resume_from_checkpoint
(str
, optional) — 您的模型的有效检查点所在文件夹的路径。此参数不会直接被 Trainer 使用,而是打算由您的训练/评估脚本使用。有关更多详细信息,请参阅 示例脚本。
hub_model_id
(str
, optional) — 与本地 output_dir 同步的存储库的名称。它可以是一个简单的模型 ID,此时模型将被推送到您的命名空间。否则,它应该是整个存储库名称,例如 "user_name/model"
,这样您就可以推送到您所属的组织,例如 "organization_name/model"
。将默认为 user_name/output_dir_name
,其中 output_dir_name 是 output_dir
的名称。
将默认为 output_dir
的名称。
hub_strategy
(str
或 HubStrategy
, optional, 默认为 "every_save"
) — 定义推送到 Hub 的范围和时间。可能的值有:
"end"
: 当调用 save_model() 方法时,推送模型、其配置、分词器(如果传递给 Trainer)以及模型卡片的草稿。
"every_save"
: 每次保存模型时,推送模型、其配置、分词器(如果传递给 Trainer)以及模型卡片的草稿。推送是异步的,以避免阻塞训练,如果保存非常频繁,则只有在上一个推送完成后才会尝试新的推送。在训练结束时,使用最终模型进行最后一次推送。
"checkpoint"
: 类似于 "every_save"
,但最新的检查点也会被推送到名为 last-checkpoint 的子文件夹中,这样您可以轻松地使用 trainer.train(resume_from_checkpoint="last-checkpoint")
恢复训练。
"all_checkpoints"
: 类似于 "checkpoint"
,但所有检查点都像它们出现在输出文件夹中一样被推送(因此您将在最终存储库中获得一个检查点文件夹)。
hub_token
(str
, optional) — 用于将模型推送到 Hub 的令牌。将默认为使用 huggingface-cli login
获取的缓存文件夹中的令牌。
hub_private_repo
(bool
, optional, 默认为 False
) — 如果为 True,则 Hub 存储库将设置为私有。
hub_always_push
(bool
, optional, 默认为 False
) — 除非为 True
,否则 Trainer
在上一个推送未完成时将跳过推送检查点。
gradient_checkpointing
(bool
, optional, 默认为 False
) — 如果为 True,则使用梯度检查点来节省内存,但会导致反向传播速度变慢。
gradient_checkpointing_kwargs
(dict
, optional, 默认为 None
) — 要传递给 gradient_checkpointing_enable
方法的关键字参数。
include_inputs_for_metrics
(bool
, optional, 默认为 False
) — 是否将输入传递给 compute_metrics
函数。这适用于需要输入、预测和参考值进行评分计算的指标类。
auto_find_batch_size
(bool
, optional, 默认为 False
) — 是否通过指数衰减自动找到适合内存的批量大小,避免 CUDA 内存不足错误。需要安装 accelerate (pip install accelerate
)。
full_determinism
(bool
, optional, 默认为 False
) — 如果为 True
,将调用 enable_full_determinism() 而不是 set_seed() 来确保在分布式训练中获得可重现的结果。重要提示:这会对性能产生负面影响,因此只能用于调试目的。
torchdynamo
(str
, optional) — 如果设置,TorchDynamo 的后端编译器。可能的选择是 "eager"
, "aot_eager"
, "inductor"
, "nvfuser"
, "aot_nvfuser"
, "aot_cudagraphs"
, "ofi"
, "fx2trt"
, "onnxrt"
和 "ipex"
。
ray_scope
(str
,可选,默认为"last"
)— 在使用 Ray 进行超参数搜索时要使用的范围。默认情况下,将使用"last"
。然后,Ray 将使用所有试验的最后一个检查点,进行比较并选择最佳的一个。但也有其他选项可用。查看Ray 文档以获取更多选项。
ddp_timeout
(int
,可选,默认为 1800)— torch.distributed.init_process_group
调用的超时时间,用于避免在分布式运行中执行缓慢操作时发生 GPU 套接字超时。请参考 PyTorch 文档)以获取更多信息。
use_mps_device
(bool
,可选,默认为False
)— 此参数已弃用。如果可用,将使用mps
设备,类似于cuda
设备。
torch_compile
(bool
,可选,默认为False
)— 是否使用 PyTorch 2.0 torch.compile
编译模型。
这将使用torch.compile
API的最佳默认值。您可以使用参数torch_compile_backend
和torch_compile_mode
自定义默认值,但我们不能保证它们中的任何一个会起作用,因为支持逐步在 PyTorch 中推出。
此标志和整个编译 API 是实验性的,可能会在未来的版本中发生变化。
torch_compile_backend
(str
,可选)— 在torch.compile
中要使用的后端。如果设置为任何值,torch_compile
将被设置为True
。
请参考 PyTorch 文档以获取可能的值,并注意它们可能会随着 PyTorch 版本的变化而改变。
此标志是实验性的,可能会在未来的版本中发生变化。
torch_compile_mode
(str
,可选)— 在torch.compile
中要使用的模式。如果设置为任何值,torch_compile
将被设置为True
。
请参考 PyTorch 文档以获取可能的值,并注意它们可能会随着 PyTorch 版本的变化而改变。
此标志是实验性的,可能会在未来的版本中发生变化。
split_batches
(bool
,可选)— 在分布式训练期间,加速器是否应该在设备之间分割数据加载器产生的批次。如果
设置为True
,实际使用的批量大小将在任何类型的分布式进程上相同,但必须是
将多个进程的数量(例如 GPU)的倍数四舍五入。
include_tokens_per_second
(bool
,可选)— 是否计算每个设备每秒的标记数,用于训练速度指标。
这将在训练数据加载器之前迭代整个训练数据加载器一次,
并且会减慢整个过程。
include_num_input_tokens_seen
(bool
,可选)— 是否要跟踪整个训练过程中看到的输入标记数量。
在分布式训练中可能会较慢,因为必须调用 gather 操作。
neftune_noise_alpha
(Optional[float]
)— 如果不是None
,将激活 NEFTune 噪声嵌入。这可以极大地提高指导微调的模型性能。查看原始论文和原始代码。支持 transformers 的PreTrainedModel
和 peft 的PeftModel
。
sortish_sampler
(bool
,可选,默认为False
)— 是否使用sortish sampler。目前仅在底层数据集为Seq2SeqDataset时才可能,但将在不久的将来普遍可用。
根据长度对输入进行排序,以最小化填充大小,并在训练集中加入一些随机性。
predict_with_generate
(bool
,可选,默认为False
)— 是否使用生成来计算生成指标(ROUGE,BLEU)。
generation_max_length
(int
, optional) — 在predict_with_generate=True
时,在每个评估循环中使用的max_length
。将默认为模型配置的max_length
值。
generation_num_beams
(int
, optional) — 在predict_with_generate=True
时,在每个评估循环中使用的num_beams
。将默认为模型配置的num_beams
值。
generation_config
(str
或Path
或 GenerationConfig, optional) — 允许从from_pretrained
方法加载一个 GenerationConfig。这可以是:
bert-base-uncased
,或者在用户或组织名称下命名空间化,如dbmdz/bert-base-german-cased
。
./my_model_directory/
。
TrainingArguments 是我们在示例脚本中使用的与训练循环本身相关的参数的子集。
使用 HfArgumentParser,我们可以将这个类转换为可以在命令行上指定的argparse参数。
to_dict
( )
将此实例序列化,将Enum
替换为它们的值,将GenerationConfig
替换为字典(用于 JSON 序列化支持)。通过删除其值来混淆标记值。
原文链接:
huggingface.co/docs/transformers/v4.37.2/en/main_classes/deepspeed
DeepSpeed 实现了 ZeRO 论文 中描述的所有内容。目前,它完全支持:
ZeRO-Offload 有自己的专用论文:ZeRO-Offload: Democratizing Billion-Scale Model Training。NVMe 支持在论文 ZeRO-Infinity: Breaking the GPU Memory Wall for Extreme Scale Deep Learning 中有描述。
DeepSpeed ZeRO-2 主要仅用于训练,因为其特性对推断无用。
DeepSpeed ZeRO-3 也可以用于推断,因为它允许将庞大的模型加载到多个 GPU 上,这在单个 GPU 上是不可能的。
🤗 Transformers 通过 2 个选项集成了 DeepSpeed:
from_pretrained
和 from_config
包括 DeepSpeed 的关键部分集成,如 ZeRO 阶段 3 及更高版本的 zero.Init
。要使用此功能,请阅读关于 非 Trainer DeepSpeed 集成 的文档。
集成内容:
训练:
推断:
还有 DeepSpeed 推断 - 这是一种完全不同的技术,它使用张量并行而不是 ZeRO(即将推出)。
通过 pypi 安装库:
pip install deepspeed
或通过 transformers
的 extras
:
pip install transformers[deepspeed]
或在 DeepSpeed 的 GitHub 页面 和 高级安装 上找到更多详细信息。
如果您仍在努力构建,请首先确保阅读 CUDA 扩展安装说明。
如果您没有预先构建扩展并依赖于运行时构建它们,并且尝试了以上所有解决方案仍无效,下一步尝试的是在安装之前预先构建模块。
要为 DeepSpeed 进行本地构建:
git clone https://github.com/microsoft/DeepSpeed/
cd DeepSpeed
rm -rf build
TORCH_CUDA_ARCH_LIST="8.6" DS_BUILD_CPU_ADAM=1 DS_BUILD_UTILS=1 pip install . \
--global-option="build_ext" --global-option="-j8" --no-cache -v \
--disable-pip-version-check 2>&1 | tee build.log
如果您打算使用 NVMe 卸载,还需要在上述说明中包含 DS_BUILD_AIO=1
(并在系统范围内安装 libaio-dev)。
编辑 TORCH_CUDA_ARCH_LIST
,插入您打算使用的 GPU 显卡的架构代码。假设所有显卡都相同,您可以通过以下方式获取架构:
CUDA_VISIBLE_DEVICES=0 python -c "import torch; print(torch.cuda.get_device_capability())"
如果您获得8, 6
,那么请使用TORCH_CUDA_ARCH_LIST="8.6"
。如果您有多张不同的显卡,可以列出所有显卡,例如TORCH_CUDA_ARCH_LIST="6.1;8.6"
。
如果您需要在多台机器上使用相同的设置,请制作一个二进制 wheel:
git clone https://github.com/microsoft/DeepSpeed/
cd DeepSpeed
rm -rf build
TORCH_CUDA_ARCH_LIST="8.6" DS_BUILD_CPU_ADAM=1 DS_BUILD_UTILS=1 \
python setup.py build_ext -j8 bdist_wheel
它将生成类似于dist/deepspeed-0.3.13+8cd046f-cp38-cp38-linux_x86_64.whl
的内容,现在您可以在本地或任何其他机器上安装为pip install deepspeed-0.3.13+8cd046f-cp38-cp38-linux_x86_64.whl
。
再次提醒确保调整TORCH_CUDA_ARCH_LIST
以匹配目标架构。
您可以在此处找到 NVIDIA GPU 的完整列表及其对应的计算能力(在此上下文中与架构相同)。
您可以使用以下命令检查 PyTorch 构建时使用的架构:
python -c "import torch; print(torch.cuda.get_arch_list())"
以下是如何查找已安装 GPU 之一的架构。例如,对于 GPU 0:
CUDA_VISIBLE_DEVICES=0 python -c "import torch; \
print(torch.cuda.get_device_properties(torch.device('cuda')))"
如果输出是:
_CudaDeviceProperties(name='GeForce RTX 3090', major=8, minor=6, total_memory=24268MB, multi_processor_count=82)
那么您就知道这张卡的架构是8.6
。
您也可以完全不使用TORCH_CUDA_ARCH_LIST
,然后构建程序将自动查询构建所在的 GPU 的架构。这可能与目标机器上的 GPU 不匹配,因此最好明确指定所需的架构。
如果尝试了所有建议的方法仍然遇到构建问题,请继续进行Deepspeed的 GitHub 问题处理,
要部署 DeepSpeed 集成,请调整 Trainer 命令行参数,包括一个新参数--deepspeed ds_config.json
,其中ds_config.json
是 DeepSpeed 配置文件,如此处所述。文件命名由您决定。建议使用 DeepSpeed 的add_config_arguments
实用程序向您的代码添加必要的命令行参数。有关更多信息,请参阅DeepSpeed 的参数解析文档。
您可以在此处使用您选择的启动器。您可以继续使用 pytorch 启动器:
torch.distributed.run --nproc_per_node=2 your_program.py <normal cl args> --deepspeed ds_config.json
或者使用deepspeed
提供的启动器:
deepspeed --num_gpus=2 your_program.py <normal cl args> --deepspeed ds_config.json
正如您所看到的参数不同,但对于大多数需求,任何一个都可以。有关如何配置各个节点和 GPU 的完整详细信息,请参阅此处。
当您使用deepspeed
启动器并且希望使用所有可用的 GPU 时,您可以只省略--num_gpus
标志。
以下是在 DeepSpeed 下部署所有可用 GPU 运行run_translation.py
的示例:
deepspeed examples/pytorch/translation/run_translation.py \
--deepspeed tests/deepspeed/ds_config_zero3.json \
--model_name_or_path t5-small --per_device_train_batch_size 1 \
--output_dir output_dir --overwrite_output_dir --fp16 \
--do_train --max_train_samples 500 --num_train_epochs 1 \
--dataset_name wmt16 --dataset_config "ro-en" \
--source_lang en --target_lang ro
请注意,在 DeepSpeed 文档中,您可能会看到--deepspeed --deepspeed_config ds_config.json
- 即两个与 DeepSpeed 相关的参数,但为了简单起见,并且已经有很多参数要处理,我们将两者合并为一个参数。
有关一些实际用例示例,请参阅此帖子。
使用单个 GPU 部署 DeepSpeed 时,请调整 Trainer 命令行参数如下:
deepspeed --num_gpus=1 examples/pytorch/translation/run_translation.py \
--deepspeed tests/deepspeed/ds_config_zero2.json \
--model_name_or_path t5-small --per_device_train_batch_size 1 \
--output_dir output_dir --overwrite_output_dir --fp16 \
--do_train --max_train_samples 500 --num_train_epochs 1 \
--dataset_name wmt16 --dataset_config "ro-en" \
--source_lang en --target_lang ro
这与多 GPU 几乎相同,但在这里我们明确告诉 DeepSpeed 仅使用一个 GPU 通过--num_gpus=1
。默认情况下,DeepSpeed 部署给定节点上可以看到的所有 GPU。如果您一开始只有 1 个 GPU,则不需要此参数。以下文档讨论了启动器选项。
为什么要仅使用一个 GPU 来使用 DeepSpeed?
虽然我们将在接下来详细讨论配置,但在 DeepSpeed 中获得单个 GPU 上的巨大改进的关键是至少在配置文件中具有以下配置:
{
"zero_optimization": {
"stage": 2,
"offload_optimizer": {
"device": "cpu",
"pin_memory": true
},
"allgather_partitions": true,
"allgather_bucket_size": 2e8,
"reduce_scatter": true,
"reduce_bucket_size": 2e8,
"overlap_comm": true,
"contiguous_gradients": true
}
}
它可以启用优化器卸载和一些其他重要功能。您可以尝试不同的缓冲区大小,在下面的讨论中会找到更多细节。
有关此类型部署的实际使用示例,请参见此帖子。
您还可以尝试使用 CPU 和 NVMe 卸载的 ZeRO-3,如本文档中进一步解释的那样。
注:
如果需要在特定 GPU 上运行,而不是 GPU 0,您不能使用CUDA_VISIBLE_DEVICES
来限制可用 GPU 的可见范围。相反,您必须使用以下语法:
deepspeed --include localhost:1 examples/pytorch/translation/run_translation.py ...
在此示例中,我们告诉 DeepSpeed 使用 GPU 1(第二个 GPU)。
本节中的信息不是特定于 DeepSpeed 集成的,适用于任何多节点程序。但 DeepSpeed 提供了一个比其他启动器更容易使用的deepspeed
启动器,除非您在 SLURM 环境中。
在本节的持续时间内,让我们假设您有 2 个每个 8 个 GPU 的节点。您可以通过ssh hostname1
到达第一个节点,通过ssh hostname2
到达第二个节点,并且两个节点必须能够通过本地 ssh 无密码地相互到达。当然,您需要将这些主机(节点)名称重命名为您正在使用的实际主机名称。
例如,要使用torch.distributed.run
,您可以这样做:
python -m torch.distributed.run --nproc_per_node=8 --nnode=2 --node_rank=0 --master_addr=hostname1 \
--master_port=9901 your_program.py <normal cl args> --deepspeed ds_config.json
您必须 ssh 到每个节点并在每个节点上运行相同的命令!不用着急,启动器会等待直到两个节点同步。
有关更多信息,请参见torchrun。顺便说一句,这也是几个 pytorch 版本前替代了torch.distributed.launch
的启动器。
要使用deepspeed
启动器,您首先需要创建一个hostfile
文件:
hostname1 slots=8
hostname2 slots=8
然后您可以这样启动:
deepspeed --num_gpus 8 --num_nodes 2 --hostfile hostfile --master_addr hostname1 --master_port=9901 \
your_program.py <normal cl args> --deepspeed ds_config.json
与torch.distributed.run
启动器不同,deepspeed
将自动在两个节点上启动此命令!
有关更多信息,请参见资源配置(多节点)。
在 SLURM 环境中可以使用以下方法。以下是一个 slurm 脚本launch.slurm
,您需要根据您特定的 SLURM 环境进行调整。
#SBATCH --job-name=test-nodes # name
#SBATCH --nodes=2 # nodes
#SBATCH --ntasks-per-node=1 # crucial - only 1 task per dist per node!
#SBATCH --cpus-per-task=10 # number of cores per tasks
#SBATCH --gres=gpu:8 # number of gpus
#SBATCH --time 20:00:00 # maximum execution time (HH:MM:SS)
#SBATCH --output=%x-%j.out # output file name
export GPUS_PER_NODE=8
export MASTER_ADDR=$(scontrol show hostnames $SLURM_JOB_NODELIST | head -n 1)
export MASTER_PORT=9901
srun --jobid $SLURM_JOBID bash -c 'python -m torch.distributed.run \
--nproc_per_node $GPUS_PER_NODE --nnodes $SLURM_NNODES --node_rank $SLURM_PROCID \
--master_addr $MASTER_ADDR --master_port $MASTER_PORT \
your_program.py <normal cl args> --deepspeed ds_config.json'
剩下的就是安排它运行:
sbatch launch.slurm
srun
将负责同时在所有节点上启动程序。
默认情况下,DeepSpeed 期望多节点环境使用共享存储。如果不是这种情况,每个节点只能看到本地文件系统,您需要调整配置文件以包含一个checkpoint
_section,设置如下:
{
"checkpoint": {
"use_node_local_storage": true
}
}
或者,您还可以使用 Trainer 的--save_on_each_node
参数,上述配置将自动添加给您。
将笔记本单元格作为脚本运行的问题在于没有正常的deepspeed
启动器可供依赖,因此在某些设置下,我们必须模拟它。
如果您只使用 1 个 GPU,以下是您必须调整笔记本中的训练代码以使用 DeepSpeed 的方式。
# DeepSpeed requires a distributed environment even when only one process is used.
# This emulates a launcher in the notebook
import os
os.environ["MASTER_ADDR"] = "localhost"
os.environ["MASTER_PORT"] = "9994" # modify if RuntimeError: Address already in use
os.environ["RANK"] = "0"
os.environ["LOCAL_RANK"] = "0"
os.environ["WORLD_SIZE"] = "1"
# Now proceed as normal, plus pass the deepspeed config file
training_args = TrainingArguments(..., deepspeed="ds_config_zero3.json")
trainer = Trainer(...)
trainer.train()
注意:...
代表您将传递给函数的常规参数。
如果要使用多个 GPU,必须使用多进程环境才能使 DeepSpeed 正常工作。也就是说,您必须使用该目的的启动器,而不能通过模拟本节开头介绍的分布式环境来实现。
如果您想在当前目录的笔记本中即时创建配置文件,可以使用专用单元格:
%%bash
cat <<'EOT' > ds_config_zero3.json
{
"fp16": {
"enabled": "auto",
"loss_scale": 0,
"loss_scale_window": 1000,
"initial_scale_power": 16,
"hysteresis": 2,
"min_loss_scale": 1
},
"optimizer": {
"type": "AdamW",
"params": {
"lr": "auto",
"betas": "auto",
"eps": "auto",
"weight_decay": "auto"
}
},
"scheduler": {
"type": "WarmupLR",
"params": {
"warmup_min_lr": "auto",
"warmup_max_lr": "auto",
"warmup_num_steps": "auto"
}
},
"zero_optimization": {
"stage": 3,
"offload_optimizer": {
"device": "cpu",
"pin_memory": true
},
"offload_param": {
"device": "cpu",
"pin_memory": true
},
"overlap_comm": true,
"contiguous_gradients": true,
"sub_group_size": 1e9,
"reduce_bucket_size": "auto",
"stage3_prefetch_bucket_size": "auto",
"stage3_param_persistence_threshold": "auto",
"stage3_max_live_parameters": 1e9,
"stage3_max_reuse_distance": 1e9,
"stage3_gather_16bit_weights_on_model_save": true
},
"gradient_accumulation_steps": "auto",
"gradient_clipping": "auto",
"steps_per_print": 2000,
"train_batch_size": "auto",
"train_micro_batch_size_per_gpu": "auto",
"wall_clock_breakdown": false
}
EOT
如果训练脚本在普通文件中而不是在笔记本单元格中,您可以从单元格中正常启动deepspeed
。例如,要使用run_translation.py
,您可以这样启动它:
!git clone https://github.com/huggingface/transformers
!cd transformers; deepspeed examples/pytorch/translation/run_translation.py ...
或者使用%%bash
魔术,您可以编写多行代码供 shell 程序运行:
%%bash
git clone https://github.com/huggingface/transformers
cd transformers
deepspeed examples/pytorch/translation/run_translation.py ...
在这种情况下,您不需要本节开头呈现的任何代码。
注意:虽然%%bash
魔术很好,但目前它会缓冲输出,因此在进程完成之前您看不到日志。
有关 DeepSpeed 配置文件中可用的 DeepSpeed 配置选项的完整指南,请参阅以下文档。
您可以在DeepSpeedExamples 存储库中找到数十个解决各种实际需求的 DeepSpeed 配置示例:
git clone https://github.com/microsoft/DeepSpeedExamples
cd DeepSpeedExamples
find . -name '*json'
继续上面的代码,假设您想配置 Lamb 优化器。因此,您可以搜索示例.json
文件:
grep -i Lamb $(find . -name '*json')
在主存储库中还可以找到更多示例。
使用 DeepSpeed 时,您始终需要提供一个 DeepSpeed 配置文件,但是某些配置参数必须通过命令行进行配置。您将在本指南的其余部分中找到细微差别。
要了解 DeepSpeed 配置文件的外观,这里有一个激活 ZeRO 阶段 2 功能的示例,包括优化器状态 cpu 卸载,使用AdamW
优化器和WarmupLR
调度程序,并且如果传递了--fp16
,将启用混合精度训练:
{
"fp16": {
"enabled": "auto",
"loss_scale": 0,
"loss_scale_window": 1000,
"initial_scale_power": 16,
"hysteresis": 2,
"min_loss_scale": 1
},
"optimizer": {
"type": "AdamW",
"params": {
"lr": "auto",
"betas": "auto",
"eps": "auto",
"weight_decay": "auto"
}
},
"scheduler": {
"type": "WarmupLR",
"params": {
"warmup_min_lr": "auto",
"warmup_max_lr": "auto",
"warmup_num_steps": "auto"
}
},
"zero_optimization": {
"stage": 2,
"offload_optimizer": {
"device": "cpu",
"pin_memory": true
},
"allgather_partitions": true,
"allgather_bucket_size": 2e8,
"overlap_comm": true,
"reduce_scatter": true,
"reduce_bucket_size": 2e8,
"contiguous_gradients": true
},
"gradient_accumulation_steps": "auto",
"gradient_clipping": "auto",
"train_batch_size": "auto",
"train_micro_batch_size_per_gpu": "auto",
}
当您执行程序时,DeepSpeed 将记录从 Trainer 接收到的配置到控制台,因此您可以看到最终传递给它的配置。
如本文所述,通常将 DeepSpeed 配置作为 json 文件的路径传递,但如果您不使用命令行界面配置训练,而是通过 TrainingArguments 实例化 Trainer,那么对于deepspeed
参数,您可以传递一个嵌套的dict
。这允许您即时创建配置,而无需将其写入文件系统后再传递给 TrainingArguments。
总结一下,您可以执行以下操作:
TrainingArguments(..., deepspeed="/path/to/ds_config.json")
或者:
ds_config_dict = dict(scheduler=scheduler_params, optimizer=optimizer_params)
TrainingArguments(..., deepspeed=ds_config_dict)
这一部分是必读的
某些配置值对于 Trainer 和 DeepSpeed 的正确运行都是必需的,因此,为了防止冲突的定义,可能导致难以检测的错误,我们选择通过 Trainer 命令行参数进行配置。
此外,一些配置值是根据模型的配置自动派生的,因此,与其记住手动调整多个值,不如让 Trainer 为您完成大部分配置。
因此,在本指南的其余部分中,您将找到一个特殊的配置值:auto
,设置后将自动替换为正确或最有效的值。请随意选择忽略此建议并显式设置值,在这种情况下,请非常小心,确保您的 Trainer 参数和 DeepSpeed 配置一致。例如,您是否使用相同的学习率、批量大小或梯度累积设置?如果这些不匹配,训练可能会以非常难以检测的方式失败。您已经被警告了。
还有多个其他值是专门针对 DeepSpeed 的,您将需要手动设置以满足您的需求。
在您自己的程序中,如果您想要以主控的方式修改 DeepSpeed 配置并基于此配置 TrainingArguments ,您也可以使用以下方法。步骤如下:
请注意,一些值,例如scheduler.params.total_num_steps
是由 Trainer 在train
期间计算的,但您当然也可以自己进行计算。
Zero Redundancy Optimizer (ZeRO) 是 DeepSpeed 的主要工具。它支持 3 个不同级别(阶段)的优化。第一个对于可伸缩性目的并不太有趣,因此本文档侧重于阶段 2 和 3。阶段 3 通过最新的 ZeRO-Infinity 进一步改进。您可以在 DeepSpeed 文档中找到更详细的信息。
配置文件中的zero_optimization
部分是最重要的部分(文档),因为在那里您定义了要启用哪些 ZeRO 阶段以及如何配置它们。您可以在 DeepSpeed 文档中找到每个参数的解释。
此部分必须通过 DeepSpeed 配置进行独占配置 - Trainer 不提供等效的命令行参数。
注意:目前 DeepSpeed 不验证参数名称,因此如果您拼写错误,它将使用拼写错误的参数的默认设置。您可以查看 DeepSpeed 引擎启动日志消息,以查看它将使用哪些值。
以下是 ZeRO 阶段 2 的配置示例:
{
"zero_optimization": {
"stage": 2,
"offload_optimizer": {
"device": "cpu",
"pin_memory": true
},
"allgather_partitions": true,
"allgather_bucket_size": 5e8,
"overlap_comm": true,
"reduce_scatter": true,
"reduce_bucket_size": 5e8,
"contiguous_gradients": true
}
}
性能调优:
offload_optimizer
应该减少 GPU RAM 的使用(需要"stage": 2
)
"overlap_comm": true
通过增加 GPU RAM 使用量来降低全局归约延迟。overlap_comm
使用 4.5 倍的allgather_bucket_size
和reduce_bucket_size
值。因此,如果它们设置为 5e8,这将需要 9GB 的占用空间(5e8 x 2 字节 x 2 x 4.5
)。因此,如果您的 GPU 具有 8GB 或更少的 RAM,为了避免出现 OOM 错误,您需要将这些参数减少到约2e8
,这将需要 3.6GB。如果您的 GPU 容量更大,但开始出现 OOM 错误,您也需要做同样的操作。
此外,deepspeed==0.4.4
添加了一个新选项round_robin_gradients
,您可以通过以下方式启用:
{
"zero_optimization": {
"round_robin_gradients": true
}
}
这是用于 CPU 卸载的阶段 2 优化,通过细粒度梯度分区将梯度复制到 CPU 内存中,以在等级之间并行化。性能收益随着梯度累积步骤(在优化器步骤之间的更多复制)或 GPU 数量(增加并行性)而增加。
以下是 ZeRO 阶段 3 的配置示例:
{
"zero_optimization": {
"stage": 3,
"offload_optimizer": {
"device": "cpu",
"pin_memory": true
},
"offload_param": {
"device": "cpu",
"pin_memory": true
},
"overlap_comm": true,
"contiguous_gradients": true,
"sub_group_size": 1e9,
"reduce_bucket_size": "auto",
"stage3_prefetch_bucket_size": "auto",
"stage3_param_persistence_threshold": "auto",
"stage3_max_live_parameters": 1e9,
"stage3_max_reuse_distance": 1e9,
"stage3_gather_16bit_weights_on_model_save": true
}
}
如果您遇到 OOM,因为您的模型或激活不适合 GPU 内存,并且您有未使用的 CPU 内存,将优化器状态和参数卸载到 CPU 内存并使用"device": "cpu"
可能解决此限制。如果您不想卸载到 CPU 内存,请在device
条目中使用none
而不是cpu
。有关卸载到 NVMe 的更多信息,请参阅下文。
通过将pin_memory
设置为true
启用了固定内存。这个功能可以提高吞吐量,但会减少其他进程可用的内存。固定内存被保留给请求它的特定进程,通常比普通 CPU 内存访问速度快得多。
性能调优:
stage3_max_live_parameters
:1e9
stage3_max_reuse_distance
:1e9
如果遇到 OOM,请减少stage3_max_live_parameters
和stage3_max_reuse_distance
。除非进行激活检查点,否则它们对性能影响很小。1e9
将消耗约 2GB。内存由stage3_max_live_parameters
和stage3_max_reuse_distance
共享,因此不是累加的,而是总共 2GB。
stage3_max_live_parameters
是您希望在任何给定时间保留在 GPU 上的完整参数的上限。"重用距离"是我们使用的度量标准,用于确定参数在未来何时再次使用,我们使用stage3_max_reuse_distance
来决定是丢弃参数还是保留参数。如果参数将在不久的将来(小于stage3_max_reuse_distance
)再次使用,则我们保留它以减少通信开销。当启用激活检查点时,这非常有帮助,我们在前向重计算和反向传递中以单层粒度执行操作,并希望在前向重计算中保留参数直到反向传递。
以下配置值取决于模型的隐藏大小:
reduce_bucket_size
:hidden_size*hidden_size
stage3_prefetch_bucket_size
:0.9 * hidden_size * hidden_size
stage3_param_persistence_threshold
:10 * hidden_size
因此将这些值设置为auto
,Trainer 将自动分配推荐值。当然,您也可以显式设置这些值。
stage3_gather_16bit_weights_on_model_save
在模型保存时启用模型 fp16 权重合并。对于大型模型和多个 GPU,这是一项昂贵的操作,无论是在内存还是速度方面。如果您计划恢复训练,则目前需要这样做。请注意未来的更新将消除此限制并使事情更加灵活。
如果您正在从 ZeRO-2 配置迁移,请注意allgather_partitions
、allgather_bucket_size
和reduce_scatter
配置参数在 ZeRO-3 中不使用。如果您将这些保留在配置文件中,它们将被忽略。
sub_group_size
:1e9
sub_group_size
控制参数在优化器步骤中更新的粒度。参数被分组到sub_group_size
的桶中,每个桶依次更新。在 ZeRO-Infinity 中与 NVMe 卸载一起使用时,sub_group_size
因此控制模型状态在优化器步骤期间从 NVMe 移入和移出 CPU 内存的粒度。这可以防止极大型模型耗尽 CPU 内存。
如果不使用 NVMe 卸载,可以将sub_group_size
保留为默认值1e9。在以下情况下,您可能需要更改其默认值:
sub_group_size
以减少临时缓冲区的内存利用
sub_group_size
以提高带宽利用率,因为数据缓冲区增加。
请注意,我们将阶段 0 和 1 列在最后,因为它们很少被使用。
阶段 0 是禁用所有类型的分片,只使用 DeepSpeed 作为 DDP。您可以通过以下方式打开它:
{
"zero_optimization": {
"stage": 0
}
}
这将基本上禁用 ZeRO,而无需更改其他任何内容。
阶段 1 是阶段 2 减去梯度分片。您可以尝试将优化器状态分片,以加快速度:
{
"zero_optimization": {
"stage": 1
}
}
ZeRO-Infinity 通过使用 NVMe 内存扩展 GPU 和 CPU 内存,允许训练非常大的模型。由于智能分区和平铺算法,每个 GPU 在卸载期间需要发送和接收非常少量的数据,因此现代 NVMe 被证明适合允许更大的总内存池可用于您的训练过程。ZeRO-Infinity 需要启用 ZeRO-3。
以下配置示例启用了 NVMe 以卸载优化器状态和参数:
{
"zero_optimization": {
"stage": 3,
"offload_optimizer": {
"device": "nvme",
"nvme_path": "/local_nvme",
"pin_memory": true,
"buffer_count": 4,
"fast_init": false
},
"offload_param": {
"device": "nvme",
"nvme_path": "/local_nvme",
"pin_memory": true,
"buffer_count": 5,
"buffer_size": 1e8,
"max_in_cpu": 1e9
},
"aio": {
"block_size": 262144,
"queue_depth": 32,
"thread_count": 1,
"single_submit": false,
"overlap_events": true
},
"overlap_comm": true,
"contiguous_gradients": true,
"sub_group_size": 1e9,
"reduce_bucket_size": "auto",
"stage3_prefetch_bucket_size": "auto",
"stage3_param_persistence_threshold": "auto",
"stage3_max_live_parameters": 1e9,
"stage3_max_reuse_distance": 1e9,
"stage3_gather_16bit_weights_on_model_save": true
},
}
您可以选择将优化器状态和参数都卸载到 NVMe,或者只卸载其中一个或两者都不卸载。例如,如果您有大量的 CPU 内存可用,尽管将其仅卸载到 CPU 内存,因为这样会更快(提示:“device”: “cpu”)。
确保您的nvme_path
实际上是一个 NVMe,因为它可以与普通硬盘或固态硬盘一起使用,但速度会慢得多。快速可扩展的训练是根据现代 NVMe 传输速度设计的(截至本文撰写时,读取速度约为 3.5GB/s,写入速度约为 3GB/s)。
为了找出最佳的aio
配置块,您必须在目标设置上运行基准测试,如此处所述。
如果一切配置相同,ZeRO-3 可能比 ZeRO-2 慢,因为前者需要收集模型权重以外的内容。如果 ZeRO-2 满足您的需求,并且您不需要扩展到几个 GPU 之外,那么您可以选择坚持使用它。重要的是要了解,ZeRO-3 在速度上的代价是实现更高的可伸缩性容量。
可以调整 ZeRO-3 配置,使其性能接近 ZeRO-2:
stage3_param_persistence_threshold
设置为一个非常大的数字 - 大于最大参数,例如6 * hidden_size * hidden_size
。这将使参数保留在 GPU 上。
offload_params
,因为 ZeRO-2 没有该选项。
即使您不更改stage3_param_persistence_threshold
,只要关闭offload_params
,性能可能会显着提高。当然,这些更改将影响您可以训练的模型大小。因此,这些帮助您根据需要在可伸缩性和速度之间进行权衡。
这里是一个完整的 ZeRO-2 自动配置文件ds_config_zero2.json
:
{
"fp16": {
"enabled": "auto",
"loss_scale": 0,
"loss_scale_window": 1000,
"initial_scale_power": 16,
"hysteresis": 2,
"min_loss_scale": 1
},
"optimizer": {
"type": "AdamW",
"params": {
"lr": "auto",
"betas": "auto",
"eps": "auto",
"weight_decay": "auto"
}
},
"scheduler": {
"type": "WarmupLR",
"params": {
"warmup_min_lr": "auto",
"warmup_max_lr": "auto",
"warmup_num_steps": "auto"
}
},
"zero_optimization": {
"stage": 2,
"offload_optimizer": {
"device": "cpu",
"pin_memory": true
},
"allgather_partitions": true,
"allgather_bucket_size": 2e8,
"overlap_comm": true,
"reduce_scatter": true,
"reduce_bucket_size": 2e8,
"contiguous_gradients": true
},
"gradient_accumulation_steps": "auto",
"gradient_clipping": "auto",
"steps_per_print": 2000,
"train_batch_size": "auto",
"train_micro_batch_size_per_gpu": "auto",
"wall_clock_breakdown": false
}
这里是一个完整的 ZeRO-2 全启用手动设置的配置文件。这里主要是让您看看典型值是什么样的,但我们强烈建议使用其中带有多个auto
设置的配置文件。
{
"fp16": {
"enabled": true,
"loss_scale": 0,
"loss_scale_window": 1000,
"initial_scale_power": 16,
"hysteresis": 2,
"min_loss_scale": 1
},
"optimizer": {
"type": "AdamW",
"params": {
"lr": 3e-5,
"betas": [0.8, 0.999],
"eps": 1e-8,
"weight_decay": 3e-7
}
},
"scheduler": {
"type": "WarmupLR",
"params": {
"warmup_min_lr": 0,
"warmup_max_lr": 3e-5,
"warmup_num_steps": 500
}
},
"zero_optimization": {
"stage": 2,
"offload_optimizer": {
"device": "cpu",
"pin_memory": true
},
"allgather_partitions": true,
"allgather_bucket_size": 2e8,
"overlap_comm": true,
"reduce_scatter": true,
"reduce_bucket_size": 2e8,
"contiguous_gradients": true
},
"steps_per_print": 2000,
"wall_clock_breakdown": false
}
这里是一个完整的 ZeRO-3 自动配置文件ds_config_zero3.json
:
{
"fp16": {
"enabled": "auto",
"loss_scale": 0,
"loss_scale_window": 1000,
"initial_scale_power": 16,
"hysteresis": 2,
"min_loss_scale": 1
},
"optimizer": {
"type": "AdamW",
"params": {
"lr": "auto",
"betas": "auto",
"eps": "auto",
"weight_decay": "auto"
}
},
"scheduler": {
"type": "WarmupLR",
"params": {
"warmup_min_lr": "auto",
"warmup_max_lr": "auto",
"warmup_num_steps": "auto"
}
},
"zero_optimization": {
"stage": 3,
"offload_optimizer": {
"device": "cpu",
"pin_memory": true
},
"offload_param": {
"device": "cpu",
"pin_memory": true
},
"overlap_comm": true,
"contiguous_gradients": true,
"sub_group_size": 1e9,
"reduce_bucket_size": "auto",
"stage3_prefetch_bucket_size": "auto",
"stage3_param_persistence_threshold": "auto",
"stage3_max_live_parameters": 1e9,
"stage3_max_reuse_distance": 1e9,
"stage3_gather_16bit_weights_on_model_save": true
},
"gradient_accumulation_steps": "auto",
"gradient_clipping": "auto",
"steps_per_print": 2000,
"train_batch_size": "auto",
"train_micro_batch_size_per_gpu": "auto",
"wall_clock_breakdown": false
}
这里是一个完整的 ZeRO-3 全启用手动设置的配置文件。这里主要是让您看看典型值是什么样的,但我们强烈建议使用其中带有多个auto
设置的配置文件。
{
"fp16": {
"enabled": true,
"loss_scale": 0,
"loss_scale_window": 1000,
"initial_scale_power": 16,
"hysteresis": 2,
"min_loss_scale": 1
},
"optimizer": {
"type": "AdamW",
"params": {
"lr": 3e-5,
"betas": [0.8, 0.999],
"eps": 1e-8,
"weight_decay": 3e-7
}
},
"scheduler": {
"type": "WarmupLR",
"params": {
"warmup_min_lr": 0,
"warmup_max_lr": 3e-5,
"warmup_num_steps": 500
}
},
"zero_optimization": {
"stage": 3,
"offload_optimizer": {
"device": "cpu",
"pin_memory": true
},
"offload_param": {
"device": "cpu",
"pin_memory": true
},
"overlap_comm": true,
"contiguous_gradients": true,
"sub_group_size": 1e9,
"reduce_bucket_size": 1e6,
"stage3_prefetch_bucket_size": 0.94e6,
"stage3_param_persistence_threshold": 1e4,
"stage3_max_live_parameters": 1e9,
"stage3_max_reuse_distance": 1e9,
"stage3_gather_16bit_weights_on_model_save": true
},
"steps_per_print": 2000,
"wall_clock_breakdown": false
}
现在您知道有所有这些不同的阶段。如何决定使用其中哪一个?本节将尝试回答这个问题。
一般来说,以下内容适用:
阶段 0(DDP)> 阶段 1 > 阶段 2 > 阶段 2 + 卸载 > 阶段 3 > 阶段 3 + 卸载
阶段 0(DDP)<阶段 1<阶段 2<阶段 2 +卸载<阶段 3<阶段 3 +卸载
因此,当您希望在最少数量的 GPU 中获得最快的执行时,请按照以下过程进行。我们从最快的方法开始,如果遇到 GPU OOM,则转向下一个较慢的方法,但将使用更少的 GPU 内存。依此类推。
首先将批处理大小设置为 1(您始终可以使用梯度累积来获得任何所需的有效批处理大小)。
--gradient_checkpointing 1
(HF Trainer)或直接model.gradient_checkpointing_enable()
-如果 OOM,则
offload_optimizer
-如果 OOM,则
offload_param
到cpu
-如果 OOM,则
offload_optimizer
到cpu
-如果 OOM,则
generate
,并且不使用宽搜索光束,请将其变窄,因为这将占用大量内存。
offload_param
和offload_optimizer
到nvme
。您需要确保它是一个非常快速的 nvme。作为一个轶事,我能够在一个小型 GPU 上推断 BLOOM-176B,使用 ZeRO-Infinity,只是速度极慢。但它有效!
当然,您可以通过从最 GPU 内存高效的配置开始,然后向后进行,或者尝试二分法来逆向执行这些步骤。
一旦您的批处理大小为 1 不会导致 OOM,请测量您的有效吞吐量。
接下来尝试将批处理大小增加到尽可能大,因为批处理大小越大,GPU 的效率就越高,因为它们在乘法矩阵很大时表现最佳。
现在性能优化游戏开始了。您可以关闭一些卸载功能或降低 ZeRO 阶段,并增加/减少批处理大小,然后再测量您的有效吞吐量。反复进行,直到满意为止。
不要花太多时间在上面,但如果您即将开始为期 3 个月的培训-请花几天时间找到最有效的吞吐量设置。这样,您的培训成本将最低,您将更快地完成培训。在当前快节奏的 ML 世界中,如果您需要额外一个月来训练某些内容,您很可能会错过一个绝佳的机会。当然,这只是我分享的一个观察,我绝不会催促您。在开始训练 BLOOM-176B 之前,我花了 2 天时间进行这个过程,并且能够将吞吐量从 90 提高到 150 TFLOPs!这一努力为我们节省了一个多月的培训时间。
这些注意事项主要是针对训练模式编写的,但它们在推断方面也应该大多适用。例如,在推断期间,梯度检查点是无效的,因为它只在训练期间有用。此外,我们发现,如果您正在进行多 GPU 推断并且不使用DeepSpeed-Inference,Accelerate应该提供更优越的性能。
其他快速相关的性能注意事项:
激活检查点和梯度检查点是指同一方法的两个不同术语。这很令人困惑,但事实就是如此。
梯度检查点允许将速度换成 GPU 内存,这样可以克服 GPU OOM,或者增加批量大小,通常会带来更好的性能。
HF Transformers 模型对 DeepSpeed 的激活检查点一无所知,因此如果您尝试在 DeepSpeed 配置文件中启用该功能,将不会发生任何事情。
因此,您有两种方法可以利用这个非常有益的功能:
model.gradient_checkpointing_enable()
或在 HF Trainer 中使用 --gradient_checkpointing
,这将自动为您启用此功能。在那里使用 torch.utils.checkpoint
。
torch.utils.checkpoint
替换为 DeepSpeed 的 API。后者更灵活,因为它允许您将前向激活卸载到 CPU 内存,而不是重新计算它们。
只要不启用 offload_optimizer
,您可以混合使用 DeepSpeed 和 HuggingFace 调度器和优化器。
在启用 offload_optimizer
时,可以使用非 DeepSpeed 优化器,只要它具有 CPU 和 GPU 实现(除了 LAMB)。
DeepSpeed 的主要优化器是 Adam、AdamW、OneBitAdam 和 Lamb。这些已经通过 ZeRO 进行了彻底测试,因此建议使用它们。但是,它可以从 torch
导入其他优化器。完整文档在这里。
如果您在配置文件中不配置 optimizer
条目,Trainer 将自动将其设置为 AdamW
,并将使用提供的值或以下命令行参数的默认值:--learning_rate
、--adam_beta1
、--adam_beta2
、--adam_epsilon
和 --weight_decay
。
这是 AdamW
的自动配置的 optimizer
条目的示例:
{
"optimizer": {
"type": "AdamW",
"params": {
"lr": "auto",
"betas": "auto",
"eps": "auto",
"weight_decay": "auto"
}
}
}
请注意,命令行参数将设置配置文件中的值。这样一来,就有了一个明确的值来源,避免了例如学习率在不同地方设置为不同值时难以找到的错误。命令行规则。被覆盖的值包括:
lr
的值为 --learning_rate
betas
的值为 --adam_beta1 --adam_beta2
eps
的值为 --adam_epsilon
weight_decay
的值为 --weight_decay
因此,请记住在命令行上调整共享的超参数。
您还可以显式设置这些值:
{
"optimizer": {
"type": "AdamW",
"params": {
"lr": 0.001,
"betas": [0.8, 0.999],
"eps": 1e-8,
"weight_decay": 3e-7
}
}
}
但是,您需要自行同步 Trainer 命令行参数和 DeepSpeed 配置。
如果要使用上面未列出的其他优化器,则必须添加到顶级配置。
{
"zero_allow_untested_optimizer": true
}
与 AdamW
类似,您可以配置其他官方支持的优化器。只需记住,这些可能具有不同的配置值。例如,对于 Adam,您将希望 weight_decay
大约为 0.01
。
此外,当与 Deepspeed 的 CPU Adam 优化器一起使用时,卸载效果最佳。如果要使用不同的优化器进行卸载,自 deepspeed==0.8.3
以来,您还需要添加:
{
"zero_force_ds_cpu_optimizer": false
}
到顶级配置。
DeepSpeed 支持 LRRangeTest
、OneCycle
、WarmupLR
和 WarmupDecayLR
学习率调度器。完整文档在这里。
这是🤗 Transformers 和 DeepSpeed 之间调度器重叠的地方:
--lr_scheduler_type constant_with_warmup
实现的 WarmupLR
--lr_scheduler_type linear
配置WarmupDecayLR
。这也是--lr_scheduler_type
的默认值,因此,如果您没有配置调度程序,则默认将配置此调度程序。
如果您没有在配置文件中配置scheduler
条目,Trainer 将使用--lr_scheduler_type
、--learning_rate
和--warmup_steps
或--warmup_ratio
的值来配置其🤗 Transformers 版本。
以下是WarmupLR
的自动配置scheduler
条目示例:
{
"scheduler": {
"type": "WarmupLR",
"params": {
"warmup_min_lr": "auto",
"warmup_max_lr": "auto",
"warmup_num_steps": "auto"
}
}
}
由于使用了*“auto”*,Trainer 参数将在配置文件中设置正确的值。这样一来,数值就有了一个明确的来源,避免了例如学习率在不同地方设置为不同值时难以找到的错误。命令行规则。设置的值包括:
warmup_min_lr
,其值为0
。
warmup_max_lr
,其值为--learning_rate
。
--warmup_steps
,则warmup_num_steps
的值为--warmup_steps
。否则,将使用--warmup_ratio
乘以训练步数并四舍五入。
total_num_steps
,其值为--max_steps
或者如果未提供,则在运行时根据环境和数据集大小以及其他命令行参数自动推导(对于WarmupDecayLR
是必需的)。
当然,您可以接管任何或所有配置值,并自行设置:
{
"scheduler": {
"type": "WarmupLR",
"params": {
"warmup_min_lr": 0,
"warmup_max_lr": 0.001,
"warmup_num_steps": 1000
}
}
}
但是,您需要自行同步 Trainer 命令行参数和 DeepSpeed 配置。
例如,对于WarmupDecayLR
,您可以使用以下条目:
{
"scheduler": {
"type": "WarmupDecayLR",
"params": {
"last_batch_iteration": -1,
"total_num_steps": "auto",
"warmup_min_lr": "auto",
"warmup_max_lr": "auto",
"warmup_num_steps": "auto"
}
}
}
total_num_steps
、warmup_max_lr
、warmup_num_steps
和total_num_steps
将在加载时设置。
Deepspeed 支持完整的 fp32 和 fp16 混合精度。
由于使用 fp16 混合精度可以大大减少内存需求并提高速度,唯一不使用它的情况是当您使用的模型在这种训练模式下表现不佳时。通常情况下,这种情况发生在模型没有在 fp16 混合精度下进行预训练时(例如,bf16 预训练模型经常出现这种情况)。这样的模型可能会溢出或下溢,导致NaN
损失。如果您遇到这种情况,那么您需要使用完整的 fp32 模式,通过显式禁用默认的 fp16 混合精度模式:
{
"fp16": {
"enabled": false,
}
}
如果您使用基于 Ampere 架构的 GPU,pytorch 版本 1.7 及更高版本将自动切换到使用更高效的 tf32 格式进行某些操作,但结果仍将是 fp32。有关详细信息和基准,请参阅TensorFloat-32(TF32) on Ampere devices。该文档包括如何在某种情况下禁用此自动转换的说明。
使用🤗 Trainer,您可以使用--tf32
来启用它,或者使用--tf32 0
或--no_tf32
来禁用它。默认情况下使用 PyTorch 默认值。
您可以使用类似于 pytorch 的 AMP 方式或类似于 apex 的方式进行自动混合精度:
要配置带有 fp16(float16)的 pytorch AMP 模式,请设置:
{
"fp16": {
"enabled": "auto",
"loss_scale": 0,
"loss_scale_window": 1000,
"initial_scale_power": 16,
"hysteresis": 2,
"min_loss_scale": 1
}
}
Trainer 将根据args.fp16_backend
的值自动启用或禁用它。其余的配置值由您决定。
当传递--fp16 --fp16_backend amp
或--fp16_full_eval
命令行参数时,此模式将被启用。
您还可以显式启用/禁用此模式:
{
"fp16": {
"enabled": true,
"loss_scale": 0,
"loss_scale_window": 1000,
"initial_scale_power": 16,
"hysteresis": 2,
"min_loss_scale": 1
}
}
但是,您需要自行同步 Trainer 命令行参数和 DeepSpeed 配置。
这是文档。
如果希望使用 bf16(bfloat16)而不是 fp16,则应使用以下配置部分:
{
"bf16": {
"enabled": "auto"
}
}
bf16 具有与 fp32 相同的动态范围,因此不需要损失缩放。
当传递--bf16
或--bf16_full_eval
命令行参数时,将启用此模式。
您也可以显式启用/禁用此模式:
{
"bf16": {
"enabled": true
}
}
截至deepspeed==0.6.0
,bf16 支持是新的实验性功能。
如果您在启用 bf16 的情况下使用梯度累积,您需要注意它将在 bf16 中累积梯度,这可能不是您想要的,因为这种格式的低精度可能导致损失的累积。
正在进行修复工作,并提供使用更高精度dtype
(fp16 或 fp32)的选项。
这是训练制度的dtype
,还有一个用于通信集合的dtype
。
所有收集/散布操作都以相同的dtype
执行,因此如果您使用 bf16 训练制度,则会以 bf16 进行收集-收集是一个非损失操作。
各种减少操作可能会导致很大的损失,例如当梯度在多个 GPU 上平均时,如果通信使用 fp16 或 bf16,则结果可能会有损失-因为在低精度下相加多个数字时结果并不精确。bf16 的精度比 fp16 低,因此更容易出现这种情况。通常情况下,fp16 足够好,因为在平均梯度时损失很小。因此,默认情况下,对于半精度训练,减少操作的默认值是使用 fp16。但是您可以完全控制此功能,如果选择,可以增加一些开销,并确保减少操作将使用 fp32 作为累积 dtype,仅当结果准备就绪时才会将其降级为您正在训练的半精度dtype
。
要覆盖默认设置,只需添加一个新的配置条目:
{
"communication_data_type": "fp32"
}
截至目前,有效值为“fp16”,“bfp16”,“fp32”。
注意:stage zero 3 存在关于 bf16 comm dtype 的错误,已在deepspeed==0.8.1
中修复。
要配置 apex AMP 类似模式,请设置:
"amp": {
"enabled": "auto",
"opt_level": "auto"
}
训练器将根据args.fp16_backend
和args.fp16_opt_level
的值自动配置。
当传递--fp16 --fp16_backend apex --fp16_opt_level 01
命令行参数时,将启用此模式。
您也可以显式配置此模式:
{
"amp": {
"enabled": true,
"opt_level": "O1"
}
}
但是,您需要自行同步 Trainer 命令行参数和 DeepSpeed 配置。
这是文档。
要配置批量大小,请使用:
{
"train_batch_size": "auto",
"train_micro_batch_size_per_gpu": "auto"
}
训练器将自动将train_micro_batch_size_per_gpu
设置为args.per_device_train_batch_size
的值,将train_batch_size
设置为args.world_size * args.per_device_train_batch_size * args.gradient_accumulation_steps
的值。
您也可以显式设置这些值:
{
"train_batch_size": 12,
"train_micro_batch_size_per_gpu": 4
}
但是,您需要自行同步 Trainer 命令行参数和 DeepSpeed 配置。
要配置梯度累积,请设置:
{
"gradient_accumulation_steps": "auto"
}
训练器将自动将其设置为args.gradient_accumulation_steps
的值。
您也可以显式设置值:
{
"gradient_accumulation_steps": 3
}
但是,您需要自行同步 Trainer 命令行参数和 DeepSpeed 配置。
配置梯度裁剪设置:
{
"gradient_clipping": "auto"
}
Trainer 将自动将其设置为args.max_grad_norm
的值。
您还可以显式设置该值:
{
"gradient_clipping": 1.0
}
但是,您需要自行同步 Trainer 命令行参数和 DeepSpeed 配置。
只要您继续使用 DeepSpeed 进行训练和恢复,您就不必担心任何事情。DeepSpeed 将 fp32 主权重存储在其自定义检查点优化器文件中,这些文件是global_step*/*optim_states.pt
(这是通配符),并保存在正常检查点下。
FP16 权重:
当模型保存在 ZeRO-2 下时,您最终会得到带有模型权重的正常pytorch_model.bin
文件,但它们只是权重的 fp16 版本。
在 ZeRO-3 下,情况要复杂得多,因为模型权重被分区到多个 GPU 上,因此需要"stage3_gather_16bit_weights_on_model_save": true
来让Trainer
保存权重的 fp16 版本。如果此设置为False
,将不会创建pytorch_model.bin
。这是因为默认情况下 DeepSpeed 的state_dict
包含一个占位符而不是真正的权重。如果我们保存这个state_dict
,将无法加载回来。
{
"zero_optimization": {
"stage3_gather_16bit_weights_on_model_save": true
}
}
FP32 权重:
虽然 fp16 权重适用于恢复训练,但如果您完成了微调模型并希望将其上传到models hub或传递给其他人,您很可能希望获取 fp32 权重。最好不要在训练过程中执行此操作,因为这是一个需要大量内存的过程,因此最好在训练完成后离线执行。但如果需要并且您有足够的空闲 CPU 内存,可以在相同的训练脚本中执行。以下部分将讨论这两种方法。
在线 FP32 权重恢复:
如果您的模型很大且剩余的 CPU 内存很少,这种方法可能不起作用。
如果您至少保存了一个检查点,并且想要使用最新的检查点,可以执行以下操作:
from transformers.trainer_utils import get_last_checkpoint
from deepspeed.utils.zero_to_fp32 import load_state_dict_from_zero_checkpoint
checkpoint_dir = get_last_checkpoint(trainer.args.output_dir)
fp32_model = load_state_dict_from_zero_checkpoint(trainer.model, checkpoint_dir)
如果您正在使用--load_best_model_at_end
类:~transformers.TrainingArguments参数(用于跟踪最佳检查点),那么您可以通过首先显式保存最终模型,然后执行与上述相同的操作来完成训练:
from deepspeed.utils.zero_to_fp32 import load_state_dict_from_zero_checkpoint
checkpoint_dir = os.path.join(trainer.args.output_dir, "checkpoint-final")
trainer.deepspeed.save_checkpoint(checkpoint_dir)
fp32_model = load_state_dict_from_zero_checkpoint(trainer.model, checkpoint_dir)
请注意,一旦运行了load_state_dict_from_zero_checkpoint
,model
将不再在相同应用程序的 DeepSpeed 上下文中可用。即您需要重新初始化 deepspeed 引擎,因为model.load_state_dict(state_dict)
将从中删除所有 DeepSpeed 的魔法。因此,只在训练的最后阶段执行此操作。
当然,您不必使用类:~transformers.Trainer,您可以根据自己的训练器调整上面的示例。
如果出于某种原因您想要更多的细化,您还可以提取权重的 fp32state_dict
并按照以下示例自行应用:
from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint
state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir) # already on cpu
model = model.cpu()
model.load_state_dict(state_dict)
离线 FP32 权重恢复:
DeepSpeed 创建了一个特殊的转换脚本zero_to_fp32.py
,并将其放在检查点文件夹的顶层。使用此脚本,您可以在任何时候提取权重。该脚本是独立的,您不再需要配置文件或Trainer
来执行提取。
假设您的检查点文件夹如下所示:
$ ls -l output_dir/checkpoint-1/
-rw-rw-r-- 1 stas stas 1.4K Mar 27 20:42 config.json
drwxrwxr-x 2 stas stas 4.0K Mar 25 19:52 global_step1/
-rw-rw-r-- 1 stas stas 12 Mar 27 13:16 latest
-rw-rw-r-- 1 stas stas 827K Mar 27 20:42 optimizer.pt
-rw-rw-r-- 1 stas stas 231M Mar 27 20:42 pytorch_model.bin
-rw-rw-r-- 1 stas stas 623 Mar 27 20:42 scheduler.pt
-rw-rw-r-- 1 stas stas 1.8K Mar 27 20:42 special_tokens_map.json
-rw-rw-r-- 1 stas stas 774K Mar 27 20:42 spiece.model
-rw-rw-r-- 1 stas stas 1.9K Mar 27 20:42 tokenizer_config.json
-rw-rw-r-- 1 stas stas 339 Mar 27 20:42 trainer_state.json
-rw-rw-r-- 1 stas stas 2.3K Mar 27 20:42 training_args.bin
-rwxrw-r-- 1 stas stas 5.5K Mar 27 13:16 zero_to_fp32.py*
在这个例子中只有一个 DeepSpeed 检查点子文件夹global_step1。因此,要重建 fp32 权重,只需运行:
python zero_to_fp32.py . pytorch_model.bin
就是这样。pytorch_model.bin
现在将包含从多个 GPU 中整合的完整 fp32 模型权重。
脚本将自动处理 ZeRO-2 或 ZeRO-3 检查点。
python zero_to_fp32.py -h
将为您提供使用详细信息。
脚本将使用文件latest
的内容自动发现 deepspeed 子文件夹,当前示例中将包含global_step1
。
注意:当前脚本需要最终 fp32 模型权重的 2 倍通用 RAM。
ZeRO-3 与 ZeRO-2 非常不同,因为它具有参数分片功能。
ZeRO-Infinity 进一步扩展了 ZeRO-3,以支持 NVMe 内存和多项其他速度和可伸缩性改进。
尽管我们已经尽力使事情能够正常工作,而无需对您的模型进行任何特殊更改,但在某些情况下,您可能会发现需要以下信息。
DeepSpeed/ZeRO-3 可以处理具有数万亿参数的模型,这些参数可能无法适应现有的 RAM。在这种情况下,但也如果您希望初始化速度更快,请使用*deepspeed.zero.Init()*上下文管理器(也是函数装饰器)初始化模型,如下所示:
from transformers import T5ForConditionalGeneration, T5Config
import deepspeed
with deepspeed.zero.Init():
config = T5Config.from_pretrained("t5-small")
model = T5ForConditionalGeneration(config)
正如您所看到的,这为您提供了一个随机初始化的模型。
如果要使用预训练模型,只要is_deepspeed_zero3_enabled()
返回True
,model_class.from_pretrained
将激活此功能,当前情况下,这是由 TrainingArguments 对象设置的,如果传递的 DeepSpeed 配置文件包含 ZeRO-3 配置部分。因此,您必须在调用from_pretrained
之前创建 TrainingArguments 对象之前。以下是可能的顺序示例:
from transformers import AutoModel, Trainer, TrainingArguments
training_args = TrainingArguments(..., deepspeed=ds_config)
model = AutoModel.from_pretrained("t5-small")
trainer = Trainer(model=model, args=training_args, ...)
如果您正在使用官方示例脚本,并且您的命令行参数包括--deepspeed ds_config.json
并启用了 ZeRO-3 配置,则一切都已经为您完成,因为示例脚本是这样编写的。
注意:如果模型的 fp16 权重无法适应单个 GPU 的内存,则必须使用此功能。
有关此方法和其他相关功能的详细信息,请参阅构建大型模型。
此外,当加载 fp16 预训练模型时,您将希望告诉from_pretrained
使用torch_dtype=torch.float16
。有关详细信息,请参见 from_pretrained-torch-dtype。
在多个 GPU 上的 ZeRO-3 中,除了当前执行层的参数外,没有单个 GPU 拥有所有参数。因此,如果您需要一次访问所有层的所有参数,有一种特定的方法可以做到。您很可能不需要它,但如果需要,请参阅收集参数。
然而,我们在几个地方内部使用它,一个例子是在from_pretrained
中加载预训练模型权重时。我们一次加载一层,然后立即将其分区到所有参与的 GPU 上,因为对于非常大的模型,将其加载到一个 GPU 上然后分散到多个 GPU 上是不可能的,由于内存限制。
此外,在 ZeRO-3 下,如果您编写自己的代码并遇到看起来像模型参数权重的问题:
tensor([1.0], device="cuda:0", dtype=torch.float16, requires_grad=True)
强调tensor([1.])
,或者如果出现错误,指出参数大小为1
,而不是某个更大的多维形状,这意味着参数被分区,您看到的是 ZeRO-3 占位符。
ZeRO 推理使用与 ZeRO-3 训练相同的配置。您只需要不需要优化器和调度程序部分。实际上,如果要与训练共享相同的配置文件,可以将这些部分保留在配置文件中。它们将被忽略。
否则,您只需要传递通常的 TrainingArguments 参数。例如:
deepspeed --num_gpus=2 your_program.py <normal cl args> --do_eval --deepspeed ds_config.json
唯一重要的是您需要使用 ZeRO-3 配置,因为 ZeRO-2 对推理没有任何好处,因为只有 ZeRO-3 执行参数分片,而 ZeRO-1 执行梯度和优化器状态的分片。
以下是在使用所有可用 GPU 部署 DeepSpeed 时运行run_translation.py
的示例:
deepspeed examples/pytorch/translation/run_translation.py \
--deepspeed tests/deepspeed/ds_config_zero3.json \
--model_name_or_path t5-small --output_dir output_dir \
--do_eval --max_eval_samples 50 --warmup_steps 50 \
--max_source_length 128 --val_max_target_length 128 \
--overwrite_output_dir --per_device_eval_batch_size 4 \
--predict_with_generate --dataset_config "ro-en" --fp16 \
--source_lang en --target_lang ro --dataset_name wmt16 \
--source_prefix "translate English to Romanian: "
由于在推理中不需要额外大内存用于优化器状态和梯度,您应该能够在相同的硬件上适应更大的批次和/或序列长度。
此外,DeepSpeed 目前正在开发一个名为 Deepspeed-Inference 的相关产品,它与 ZeRO 技术没有关系,而是使用张量并行性来扩展无法适应单个 GPU 的模型。这是一个正在进行的工作,一旦该产品完成,我们将提供集成。
由于 Deepspeed ZeRO 可以将内存卸载到 CPU(和 NVMe),该框架提供了一些实用程序,允许您根据使用的 GPU 数量告诉需要多少 CPU 和 GPU 内存。
让我们估计在单个 GPU 上对“bigscience/T0_3B”进行微调所需的内存:
$ python -c 'from transformers import AutoModel; \
from deepspeed.runtime.zero.stage3 import estimate_zero3_model_states_mem_needs_all_live; \
model = AutoModel.from_pretrained("bigscience/T0_3B"); \
estimate_zero3_model_states_mem_needs_all_live(model, num_gpus_per_node=1, num_nodes=1)'
[...]
Estimated memory needed for params, optim states and gradients for a:
HW: Setup with 1 node, 1 GPU per node.
SW: Model with 2783M total params, 65M largest layer params.
per CPU | per GPU | Options
70.00GB | 0.25GB | offload_param=cpu , offload_optimizer=cpu , zero_init=1
70.00GB | 0.25GB | offload_param=cpu , offload_optimizer=cpu , zero_init=0
62.23GB | 5.43GB | offload_param=none, offload_optimizer=cpu , zero_init=1
62.23GB | 5.43GB | offload_param=none, offload_optimizer=cpu , zero_init=0
0.37GB | 46.91GB | offload_param=none, offload_optimizer=none, zero_init=1
15.56GB | 46.91GB | offload_param=none, offload_optimizer=none, zero_init=0
因此,您可以将其放在单个 80GB GPU 上,不使用 CPU 卸载,或者使用一个小型的 8GB GPU,但是需要大约 60GB 的 CPU 内存。请记住,这只是参数、优化器状态和梯度的内存 - 您将需要更多内存用于 cuda 内核、激活和临时存储。
然后就是成本与速度的权衡。购买/租用较小的 GPU(或较少的 GPU,因为您可以使用 Deepspeed ZeRO 来使用多个 GPU)。但这样会更慢,所以即使您不关心某件事情会多快完成,减速也会直接影响使用 GPU 的持续时间,从而增加成本。因此,请进行实验并比较哪种方法最好。
如果您有足够的 GPU 内存,请确保禁用 CPU/NVMe 卸载,因为这将使一切更快。
例如,让我们重复使用 2 个 GPU:
$ python -c 'from transformers import AutoModel; \
from deepspeed.runtime.zero.stage3 import estimate_zero3_model_states_mem_needs_all_live; \
model = AutoModel.from_pretrained("bigscience/T0_3B"); \
estimate_zero3_model_states_mem_needs_all_live(model, num_gpus_per_node=2, num_nodes=1)'
[...]
Estimated memory needed for params, optim states and gradients for a:
HW: Setup with 1 node, 2 GPUs per node.
SW: Model with 2783M total params, 65M largest layer params.
per CPU | per GPU | Options
70.00GB | 0.25GB | offload_param=cpu , offload_optimizer=cpu , zero_init=1
70.00GB | 0.25GB | offload_param=cpu , offload_optimizer=cpu , zero_init=0
62.23GB | 2.84GB | offload_param=none, offload_optimizer=cpu , zero_init=1
62.23GB | 2.84GB | offload_param=none, offload_optimizer=cpu , zero_init=0
0.74GB | 23.58GB | offload_param=none, offload_optimizer=none, zero_init=1
31.11GB | 23.58GB | offload_param=none, offload_optimizer=none, zero_init=0
因此,您可能需要 2 个 32GB 或更高内存的 GPU,而不需要将内存卸载到 CPU。
有关完整信息,请参阅memory estimators。
以下是如何提交问题,以便我们可以快速找到问题的根源并帮助您解除工作阻塞。
在您的报告中,请始终包括:
在报告中提供完整的 Deepspeed 配置文件
如果您使用的是 Trainer 的命令行参数,或者如果您自己编写了 Trainer 设置,则使用 TrainingArguments 参数。请不要转储 TrainingArguments,因为它有数十个与问题无关的条目。
输出:
python -c 'import torch; print(f"torch: {torch.__version__}")'
python -c 'import transformers; print(f"transformers: {transformers.__version__}")'
python -c 'import deepspeed; print(f"deepspeed: {deepspeed.__version__}")'
如果可能的话,请包含一个链接到一个 Google Colab 笔记本,我们可以用它来重现问题。您可以使用这个notebook作为起点。
除非不可能,请始终使用我们可以使用的标准数据集,而不是自定义数据集。
如果可能,请尝试使用现有的examples之一来重现问题。
需要考虑的事项:
如果deepspeed
进程在启动时被终止,没有回溯,通常意味着程序尝试分配比您的系统具有的 CPU 内存更多的内存,或者您的进程被允许分配的内存,而操作系统内核终止了该进程。这是因为您的配置文件很可能已经配置了offload_optimizer
或offload_param
或两者都配置为转移到cpu
。如果您有 NVMe,尝试将其转移到 NVMe,如果您正在运行 ZeRO-3。这是如何估算特定模型所需内存量的方法。
当一个以 bf16 混合精度模式预训练的模型尝试在 fp16 下使用时,通常会发生这种情况(无论是否使用混合精度)。大多数在 TPU 上训练的模型,通常是由 Google 发布的模型都属于这一类(例如,几乎所有基于 t5 的模型)。在这种情况下,解决方案是要么使用 fp32,要么使用 bf16,如果您的硬件支持的话(TPU、Ampere GPU 或更新)。
另一个问题可能与使用 fp16 有关。当您配置此部分时:
{
"fp16": {
"enabled": "auto",
"loss_scale": 0,
"loss_scale_window": 1000,
"initial_scale_power": 16,
"hysteresis": 2,
"min_loss_scale": 1
}
}
并且您在日志中看到 Deepspeed 报告OVERFLOW!
如下:
0%| | 0/189 [00:00<?, ?it/s]
[deepscale] OVERFLOW! Rank 0 Skipping step. Attempted loss scale: 262144, reducing to 262144
1%|▌ | 1/189 [00:00<01:26, 2.17it/s]
[deepscale] OVERFLOW! Rank 0 Skipping step. Attempted loss scale: 262144, reducing to 131072.0
1%|█▏
[...]
[deepscale] OVERFLOW! Rank 0 Skipping step. Attempted loss scale: 1, reducing to 1
14%|████████████████▌ | 27/189 [00:14<01:13, 2.21it/s]
[deepscale] OVERFLOW! Rank 0 Skipping step. Attempted loss scale: 1, reducing to 1
15%|█████████████████▏ | 28/189 [00:14<01:13, 2.18it/s]
[deepscale] OVERFLOW! Rank 0 Skipping step. Attempted loss scale: 1, reducing to 1
15%|█████████████████▊ | 29/189 [00:15<01:13, 2.18it/s]
[deepscale] OVERFLOW! Rank 0 Skipping step. Attempted loss scale: 1, reducing to 1
[...]
这意味着 Deepspeed 损失缩放器无法找到一个缩放系数来克服损失溢出。
(此处的日志已经过处理,以便更易阅读。)
在这种情况下,通常需要提高initial_scale_power
的值。将其设置为"initial_scale_power": 32
通常会解决问题。
HfDeepSpeedConfig 用于将 Deepspeed 集成到🤗 Transformers 核心功能中,当未使用 Trainer 时。它唯一要做的就是处理 Deepspeed ZeRO-3 参数收集,并在from_pretrained
调用期间自动将模型分割到多个 GPU 上。其他所有事情都需要您自己来做。
使用 Trainer 时,一切都会自动处理。
当不使用 Trainer 时,为了有效部署 DeepSpeed ZeRO-3,您必须在实例化模型之前实例化 HfDeepSpeedConfig 对象,并保持该对象处于活动状态。
如果您正在使用 Deepspeed ZeRO-1 或 ZeRO-2,则根本不需要使用HfDeepSpeedConfig
。
例如,对于预训练模型:
from transformers.integrations import HfDeepSpeedConfig
from transformers import AutoModel
import deepspeed
ds_config = {...} # deepspeed config object or path to the file
# must run before instantiating the model to detect zero 3
dschf = HfDeepSpeedConfig(ds_config) # keep this object alive
model = AutoModel.from_pretrained("gpt2")
engine = deepspeed.initialize(model=model, config_params=ds_config, ...)
或对于非预训练模型:
from transformers.integrations import HfDeepSpeedConfig
from transformers import AutoModel, AutoConfig
import deepspeed
ds_config = {...} # deepspeed config object or path to the file
# must run before instantiating the model to detect zero 3
dschf = HfDeepSpeedConfig(ds_config) # keep this object alive
config = AutoConfig.from_pretrained("gpt2")
model = AutoModel.from_config(config)
engine = deepspeed.initialize(model=model, config_params=ds_config, ...)
请注意,如果您没有使用 Trainer 集成,您将完全独立。基本上遵循Deepspeed网站上的文档。此外,您必须明确配置配置文件 - 不能使用"auto"
值,而必须使用实际值。
class transformers.integrations.HfDeepSpeedConfig
( config_file_or_dict )
参数
config_file_or_dict
(Union[str, Dict]
)— DeepSpeed 配置文件或字典的路径。此对象包含一个 DeepSpeed 配置字典,可以快速查询诸如零阶段之类的内容。
此对象的weakref
存储在模块的全局变量中,以便能够从 Trainer 对象不可用的区域访问配置(例如from_pretrained
和_get_resized_embeddings
)。因此,在程序仍在运行时,这个对象保持活动是很重要的。
Trainer 使用HfTrainerDeepSpeedConfig
子类。该子类具有将配置与 TrainingArguments 的值同步的逻辑,通过替换特殊占位符值:"auto"
。如果没有这种特殊逻辑,DeepSpeed 配置将不会以任何方式修改。
以下是一个示例,演示如何在无法将模型放入单个 GPU 的情况下进行 DeepSpeed ZeRO 推理,而不使用 Trainer。解决方案包括使用额外的 GPU 和/或将 GPU 内存转移到 CPU 内存。
这里需要理解的重要细微差别是,ZeRO 的设计方式使您可以并行处理不同 GPU 上的不同输入。
示例有大量注释并且是自我记录的。
确保:
#!/usr/bin/env python
# This script demonstrates how to use Deepspeed ZeRO in an inference mode when one can't fit a model
# into a single GPU
#
# 1\. Use 1 GPU with CPU offload
# 2\. Or use multiple GPUs instead
#
# First you need to install deepspeed: pip install deepspeed
#
# Here we use a 3B "bigscience/T0_3B" model which needs about 15GB GPU RAM - so 1 largish or 2
# small GPUs can handle it. or 1 small GPU and a lot of CPU memory.
#
# To use a larger model like "bigscience/T0" which needs about 50GB, unless you have an 80GB GPU -
# you will need 2-4 gpus. And then you can adapt the script to handle more gpus if you want to
# process multiple inputs at once.
#
# The provided deepspeed config also activates CPU memory offloading, so chances are that if you
# have a lot of available CPU memory and you don't mind a slowdown you should be able to load a
# model that doesn't normally fit into a single GPU. If you have enough GPU memory the program will
# run faster if you don't want offload to CPU - so disable that section then.
#
# To deploy on 1 gpu:
#
# deepspeed --num_gpus 1 t0.py
# or:
# python -m torch.distributed.run --nproc_per_node=1 t0.py
#
# To deploy on 2 gpus:
#
# deepspeed --num_gpus 2 t0.py
# or:
# python -m torch.distributed.run --nproc_per_node=2 t0.py
from transformers import AutoTokenizer, AutoConfig, AutoModelForSeq2SeqLM
from transformers.integrations import HfDeepSpeedConfig
import deepspeed
import os
import torch
os.environ["TOKENIZERS_PARALLELISM"] = "false" # To avoid warnings about parallelism in tokenizers
# distributed setup
local_rank = int(os.getenv("LOCAL_RANK", "0"))
world_size = int(os.getenv("WORLD_SIZE", "1"))
torch.cuda.set_device(local_rank)
deepspeed.init_distributed()
model_name = "bigscience/T0_3B"
config = AutoConfig.from_pretrained(model_name)
model_hidden_size = config.d_model
# batch size has to be divisible by world_size, but can be bigger than world_size
train_batch_size = 1 * world_size
# ds_config notes
#
# - enable bf16 if you use Ampere or higher GPU - this will run in mixed precision and will be
# faster.
#
# - for older GPUs you can enable fp16, but it'll only work for non-bf16 pretrained models - e.g.
# all official t5 models are bf16-pretrained
#
# - set offload_param.device to "none" or completely remove the `offload_param` section if you don't
# - want CPU offload
#
# - if using `offload_param` you can manually finetune stage3_param_persistence_threshold to control
# - which params should remain on gpus - the larger the value the smaller the offload size
#
# For indepth info on Deepspeed config see
# https://huggingface.co/docs/transformers/main/main_classes/deepspeed
# keeping the same format as json for consistency, except it uses lower case for true/false
# fmt: off
ds_config = {
"fp16": {
"enabled": False
},
"bf16": {
"enabled": False
},
"zero_optimization": {
"stage": 3,
"offload_param": {
"device": "cpu",
"pin_memory": True
},
"overlap_comm": True,
"contiguous_gradients": True,
"reduce_bucket_size": model_hidden_size * model_hidden_size,
"stage3_prefetch_bucket_size": 0.9 * model_hidden_size * model_hidden_size,
"stage3_param_persistence_threshold": 10 * model_hidden_size
},
"steps_per_print": 2000,
"train_batch_size": train_batch_size,
"train_micro_batch_size_per_gpu": 1,
"wall_clock_breakdown": False
}
# fmt: on
# next line instructs transformers to partition the model directly over multiple gpus using
# deepspeed.zero.Init when model's `from_pretrained` method is called.
#
# **it has to be run before loading the model AutoModelForSeq2SeqLM.from_pretrained(model_name)**
#
# otherwise the model will first be loaded normally and only partitioned at forward time which is
# less efficient and when there is little CPU RAM may fail
dschf = HfDeepSpeedConfig(ds_config) # keep this object alive
# now a model can be loaded.
model = AutoModelForSeq2SeqLM.from_pretrained(model_name)
# initialise Deepspeed ZeRO and store only the engine object
ds_engine = deepspeed.initialize(model=model, config_params=ds_config)[0]
ds_engine.module.eval() # inference
# Deepspeed ZeRO can process unrelated inputs on each GPU. So for 2 gpus you process 2 inputs at once.
# If you use more GPUs adjust for more.
# And of course if you have just one input to process you then need to pass the same string to both gpus
# If you use only one GPU, then you will have only rank 0.
rank = torch.distributed.get_rank()
if rank == 0:
text_in = "Is this review positive or negative? Review: this is the best cast iron skillet you will ever buy"
elif rank == 1:
text_in = "Is this review positive or negative? Review: this is the worst restaurant ever"
tokenizer = AutoTokenizer.from_pretrained(model_name)
inputs = tokenizer.encode(text_in, return_tensors="pt").to(device=local_rank)
with torch.no_grad():
outputs = ds_engine.module.generate(inputs, synced_gpus=True)
text_out = tokenizer.decode(outputs[0], skip_special_tokens=True)
print(f"rank{rank}:\n in={text_in}\n out={text_out}")
让我们将其保存为t0.py
并运行:
$ deepspeed --num_gpus 2 t0.py
rank0:
in=Is this review positive or negative? Review: this is the best cast iron skillet you will ever buy
out=Positive
rank1:
in=Is this review positive or negative? Review: this is the worst restaurant ever
out=negative
这是一个非常基本的示例,您将希望根据自己的需求进行调整。
使用多个 GPU 与 ZeRO Stage-3 一起使用时,必须通过调用generate(..., synced_gpus=True)
来同步 GPU。如果不这样做,如果一个 GPU 在其他 GPU 之前完成生成,整个系统将挂起,因为其他 GPU 将无法接收停止生成的 GPU 的权重片段。
从transformers>=4.28
开始,如果未明确指定synced_gpus
,则在检测到这些条件时,它将自动设置为True
。但是,如果需要,仍然可以覆盖synced_gpus
的值。
如果您提交涉及 DeepSpeed 集成的 PR,请注意我们的 CircleCI PR CI 设置没有 GPU,因此我们只在另一个 CI 每晚运行需要 GPU 的测试。因此,如果您在 PR 中收到绿色 CI 报告,这并不意味着 DeepSpeed 测试通过。
要运行 DeepSpeed 测试,请至少运行:
RUN_SLOW=1 pytest tests/deepspeed/test_deepspeed.py
如果更改了建模或 pytorch 示例代码中的任何内容,则还要运行模型动物园测试。以下将运行所有 DeepSpeed 测试:
RUN_SLOW=1 pytest tests/deepspeed
论文:
最后,请记住,HuggingFace Trainer 只集成了 DeepSpeed,因此如果您在使用 DeepSpeed 方面遇到任何问题或疑问,请在 DeepSpeed GitHub 上提交问题。