Transformers 4.37 中文文档(七)(3)https://developer.aliyun.com/article/1564150
Trainer
Trainer 是在 Transformers 库中实现的 PyTorch 模型的完整训练和评估循环。您只需要传递训练所需的必要部分(模型、分词器、数据集、评估函数、训练超参数等),Trainer 类会处理其余部分。这使得更容易开始训练,而无需手动编写自己的训练循环。但同时,Trainer 非常可定制,并提供大量的训练选项,因此您可以根据自己的训练需求进行定制。
除了 Trainer 类外,Transformers 还提供了一个 Seq2SeqTrainer 类,用于序列到序列任务,如翻译或摘要。还有来自TRL库的SFTTrainer类,它包装了 Trainer 类,并针对使用自回归技术的 Llama-2 和 Mistral 等语言模型进行了优化。SFTTrainer还支持序列打包、LoRA、量化和 DeepSpeed 等功能,以有效地扩展到任何模型大小。
随时查看 API 参考以了解其他 Trainer 类型类的更多信息,以便了解何时使用哪种。一般来说,Trainer 是最通用的选择,适用于广泛的任务。Seq2SeqTrainer 专为序列到序列任务设计,而SFTTrainer专为训练语言模型设计。
在开始之前,请确保已安装Accelerate - 一个用于在分布式环境中启用和运行 PyTorch 训练的库。
pip install accelerate # upgrade pip install accelerate --upgrade
这个指南提供了 Trainer 类的概述。
基本用法
Trainer 包含在基本训练循环中找到的所有代码:
- 执行训练步骤来计算损失
- 使用backward方法计算梯度
- 根据梯度更新权重
- 重复这个过程,直到达到预定的 epoch 数量
Trainer 类将所有这些代码抽象化,因此您无需每次手动编写训练循环,或者如果您刚开始使用 PyTorch 和训练时担心。您只需要提供训练所需的基本组件,如模型和数据集,Trainer 类会处理其他一切。
如果要指定任何训练选项或超参数,您可以在 TrainingArguments 类中找到它们。例如,让我们定义在output_dir
中保存模型的位置,并在训练后使用push_to_hub=True
将模型推送到 Hub。
from transformers import TrainingArguments training_args = TrainingArguments( output_dir="your-model", learning_rate=2e-5, per_device_train_batch_size=16, per_device_eval_batch_size=16, num_train_epochs=2, weight_decay=0.01, evaluation_strategy="epoch", save_strategy="epoch", load_best_model_at_end=True, push_to_hub=True, )
将training_args
传递给 Trainer,以及一个模型、数据集、用于预处理数据集的内容(根据数据类型可能是令牌化器、特征提取器或图像处理器)、数据整理器和一个函数来计算您想要在训练过程中跟踪的指标。
最后,调用 train()开始训练!
from transformers import Trainer trainer = Trainer( model=model, args=training_args, train_dataset=dataset["train"], eval_dataset=dataset["test"], tokenizer=tokenizer, data_collator=data_collator, compute_metrics=compute_metrics, ) trainer.train()
检查点
Trainer 类将您的模型检查点保存到 TrainingArguments 中指定的目录中的output_dir
参数。您将在checkpoint-000
子文件夹中找到保存的检查点,其中末尾的数字对应训练步骤。保存检查点对于稍后恢复训练很有用。
# resume from latest checkpoint trainer.train(resume_from_checkpoint=True) # resume from specific checkpoint saved in output directory trainer.train(resume_from_checkpoint="your-model/checkpoint-1000")
您可以通过在 TrainingArguments 中设置push_to_hub=True
将检查点保存到 Hub 以提交和推送它们(默认情况下不保存优化器状态)。设置如何保存检查点的其他选项在hub_strategy
参数中设置:
hub_strategy="checkpoint"
将最新的检查点推送到名为“last-checkpoint”的子文件夹,您可以从中恢复训练hug_strategy="all_checkpoints"
将所有检查点推送到output_dir
中定义的目录(您将在模型存储库中看到每个文件夹中的一个检查点)
当您从检查点恢复训练时,Trainer 会尝试保持 Python、NumPy 和 PyTorch RNG 状态与保存检查点时相同。但由于 PyTorch 具有各种非确定性的默认设置,RNG 状态不能保证相同。如果要启用完全确定性,请查看控制随机性源指南,了解您可以启用哪些内容以使您的训练完全确定性。请记住,通过使某些设置确定性,训练可能会变慢。
自定义 Trainer
虽然 Trainer 类旨在易于访问和使用,但也为更有冒险精神的用户提供了许多可定制性。许多 Trainer 的方法可以被子类化和重写,以支持您想要的功能,而无需重写整个训练循环以适应它。这些方法包括:
- get_train_dataloader() 创建一个训练 DataLoader
- get_eval_dataloader() 创建一个评估 DataLoader
- get_test_dataloader() 创建一个测试 DataLoader
- log() 记录监视训练的各种对象的信息
- create_optimizer_and_scheduler() 在
__init__
中没有传入优化器和学习率调度器时创建它们;也可以使用 create_optimizer()和 create_scheduler()进行单独定制 - compute_loss() 计算一批训练输入的损失
- training_step() 执行训练步骤
- prediction_step() 执行预测和测试步骤
- evaluate() 评估模型并返回评估指标
- predict() 在测试集上进行预测(如果有标签,则带有指标)
例如,如果您想要自定义 compute_loss()方法以使用加权损失。
from torch import nn from transformers import Trainer class CustomTrainer(Trainer): def compute_loss(self, model, inputs, return_outputs=False): labels = inputs.pop("labels") # forward pass outputs = model(**inputs) logits = outputs.get("logits") # compute custom loss for 3 labels with different weights loss_fct = nn.CrossEntropyLoss(weight=torch.tensor([1.0, 2.0, 3.0], device=model.device)) loss = loss_fct(logits.view(-1, self.model.config.num_labels), labels.view(-1)) return (loss, outputs) if return_outputs else loss
回调
自定义 Trainer 的另一个选项是使用 callbacks。回调不会改变训练循环中的任何内容。它们检查训练循环状态,然后根据状态执行某些操作(提前停止、记录结果等)。换句话说,回调不能用于实现类似自定义损失函数的内容,您需要子类化并重写 compute_loss()方法。
例如,如果您想在训练循环中的 10 步后添加一个提前停止回调。
from transformers import TrainerCallback class EarlyStoppingCallback(TrainerCallback): def __init__(self, num_steps=10): self.num_steps = num_steps def on_step_end(self, args, state, control, **kwargs): if state.global_step >= self.num_steps: return {"should_training_stop": True} else: return {}
然后将其传递给 Trainer 的callback
参数。
from transformers import Trainer trainer = Trainer( model=model, args=training_args, train_dataset=dataset["train"], eval_dataset=dataset["test"], tokenizer=tokenizer, data_collator=data_collator, compute_metrics=compute_metrics, callback=[EarlyStoppingCallback()], )
日志
查看 logging API 参考以获取有关不同日志级别的更多信息。
默认情况下,Trainer 设置为logging.INFO
,报告错误、警告和其他基本信息。在分布式环境中,Trainer 的副本设置为logging.WARNING
,仅报告错误和警告。您可以使用 TrainingArguments 中的log_level
和log_level_replica
参数更改日志级别。
要为每个节点配置日志级别设置,请使用log_on_each_node
参数来确定是在每个节点上使用日志级别还是仅在主节点上使用。
Trainer 在Trainer.__init__()
方法中为每个节点单独设置日志级别,因此如果您在创建 Trainer 对象之前使用其他 Transformers 功能,可能需要考虑更早设置这个。
例如,要根据每个节点设置主代码和模块使用相同的日志级别:
logger = logging.getLogger(__name__) logging.basicConfig( format="%(asctime)s - %(levelname)s - %(name)s - %(message)s", datefmt="%m/%d/%Y %H:%M:%S", handlers=[logging.StreamHandler(sys.stdout)], ) log_level = training_args.get_process_log_level() logger.setLevel(log_level) datasets.utils.logging.set_verbosity(log_level) transformers.utils.logging.set_verbosity(log_level) trainer = Trainer(...)
使用不同组合的log_level
和log_level_replica
来配置每个节点上记录什么。
单节点多节点
my_app.py ... --log_level warning --log_level_replica error
NEFTune
NEFTune是一种通过在训练过程中向嵌入向量添加噪音来提高性能的技术。要在 Trainer 中启用它,设置 TrainingArguments 中的neftune_noise_alpha
参数来控制添加多少噪音。
from transformers import TrainingArguments, Trainer training_args = TrainingArguments(..., neftune_noise_alpha=0.1) trainer = Trainer(..., args=training_args)
训练后禁用 NEFTune,以恢复原始嵌入层,避免任何意外行为。
加速和 Trainer
Trainer 类由Accelerate支持,这是一个用于在分布式环境中轻松训练 PyTorch 模型的库,支持集成如FullyShardedDataParallel (FSDP)和DeepSpeed。
在 Trainer 的 Fully Sharded Data Parallel 指南中了解更多关于 FSDP 分片策略、CPU 卸载等内容。
使用 Trainer 与 Accelerate,运行accelerate.config
命令来设置您的训练环境。这个命令会创建一个config_file.yaml
,在您启动训练脚本时会用到。例如,您可以设置一些示例配置:
DistributedDataParallelFSDPDeepSpeedDeepSpeed 与 Accelerate 插件
compute_environment: LOCAL_MACHINE distributed_type: MULTI_GPU downcast_bf16: 'no' gpu_ids: all machine_rank: 0 #change rank as per the node main_process_ip: 192.168.20.1 main_process_port: 9898 main_training_function: main mixed_precision: fp16 num_machines: 2 num_processes: 8 rdzv_backend: static same_network: true tpu_env: [] tpu_use_cluster: false tpu_use_sudo: false use_cpu: false
accelerate_launch
命令是在分布式系统上启动您的训练脚本的推荐方式,使用 Accelerate 和 Trainer 中在config_file.yaml
中指定的参数。这个文件保存在 Accelerate 缓存文件夹中,并在运行accelerate_launch
时自动加载。
例如,使用 FSDP 配置运行run_glue.py训练脚本:
accelerate launch \ ./examples/pytorch/text-classification/run_glue.py \ --model_name_or_path bert-base-cased \ --task_name $TASK_NAME \ --do_train \ --do_eval \ --max_seq_length 128 \ --per_device_train_batch_size 16 \ --learning_rate 5e-5 \ --num_train_epochs 3 \ --output_dir /tmp/$TASK_NAME/ \ --overwrite_output_dir
您也可以直接在命令行中指定来自config_file.yaml
文件的参数:
accelerate launch --num_processes=2 \ --use_fsdp \ --mixed_precision=bf16 \ --fsdp_auto_wrap_policy=TRANSFORMER_BASED_WRAP \ --fsdp_transformer_layer_cls_to_wrap="BertLayer" \ --fsdp_sharding_strategy=1 \ --fsdp_state_dict_type=FULL_STATE_DICT \ ./examples/pytorch/text-classification/run_glue.py --model_name_or_path bert-base-cased \ --task_name $TASK_NAME \ --do_train \ --do_eval \ --max_seq_length 128 \ --per_device_train_batch_size 16 \ --learning_rate 5e-5 \ --num_train_epochs 3 \ --output_dir /tmp/$TASK_NAME/ \ --overwrite_output_dir
查看启动您的 Accelerate 脚本教程,了解更多关于accelerate_launch
和自定义配置的内容。
在 Amazon SageMaker 上运行训练
文档已移至 hf.co/docs/sagemaker。此页面将在 transformers
5.0 中被移除。
目录
- 使用 SageMaker Python SDK 在 Amazon SageMaker 上训练 Hugging Face 模型
- 使用 SageMaker Python SDK 将 Hugging Face 模型部署到 Amazon SageMaker
导出为 ONNX
原始文本:
huggingface.co/docs/transformers/v4.37.2/en/serialization
在生产环境中部署🤗 Transformers 模型通常需要将模型导出为可以在专用运行时和硬件上加载和执行的序列化格式。
🤗 Optimum 是 Transformers 的扩展,通过其exporters
模块使得可以将模型从 PyTorch 或 TensorFlow 导出为 ONNX 和 TFLite 等序列化格式。🤗 Optimum 还提供了一套性能优化工具,以在目标硬件上以最大效率训练和运行模型。
本指南演示了如何使用🤗 Optimum 将🤗 Transformers 模型导出为 ONNX,有关将模型导出为 TFLite 的指南,请参考导出到 TFLite 页面。
导出为 ONNX
ONNX(Open Neural Network eXchange)是一个开放标准,定义了一组通用操作符和一种通用文件格式,用于在各种框架中表示深度学习模型,包括 PyTorch 和 TensorFlow。当模型导出为 ONNX 格式时,这些操作符用于构建计算图(通常称为中间表示),表示数据通过神经网络的流动。
通过公开具有标准化操作符和数据类型的图,ONNX 使得在不同框架之间轻松切换变得容易。例如,在 PyTorch 中训练的模型可以导出为 ONNX 格式,然后在 TensorFlow 中导入(反之亦然)。
将模型导出为 ONNX 格式后,可以:
- 通过诸如图优化和量化等技术进行推理优化。
- 使用 ONNX Runtime 运行,通过
ORTModelForXXX
类,其遵循与🤗 Transformers 中您习惯的AutoModel
API 相同。 - 使用优化推理流水线运行,其 API 与🤗 Transformers 中的 pipeline()函数相同。
🤗 Optimum 通过利用配置对象提供对 ONNX 导出的支持。这些配置对象已经为许多模型架构准备好,并且设计为易于扩展到其他架构。
有关现成配置列表,请参阅🤗 Optimum 文档。
有两种将🤗 Transformers 模型导出为 ONNX 的方法,这里我们展示两种:
- 通过 CLI 使用🤗 Optimum 导出。
- 使用
optimum.onnxruntime
与🤗 Optimum 导出。
使用 CLI 将🤗 Transformers 模型导出为 ONNX
要将🤗 Transformers 模型导出为 ONNX,首先安装额外的依赖项:
pip install optimum[exporters]
要查看所有可用参数,请参考🤗 Optimum 文档,或在命令行中查看帮助:
optimum-cli export onnx --help
要从🤗 Hub 导出模型的检查点,例如distilbert-base-uncased-distilled-squad
,请运行以下命令:
optimum-cli export onnx --model distilbert-base-uncased-distilled-squad distilbert_base_uncased_squad_onnx/
您应该看到指示进度并显示结果model.onnx
保存位置的日志,如下所示:
Validating ONNX model distilbert_base_uncased_squad_onnx/model.onnx... -[✓] ONNX model output names match reference model (start_logits, end_logits) - Validating ONNX Model output "start_logits": -[✓] (2, 16) matches (2, 16) -[✓] all values close (atol: 0.0001) - Validating ONNX Model output "end_logits": -[✓] (2, 16) matches (2, 16) -[✓] all values close (atol: 0.0001) The ONNX export succeeded and the exported model was saved at: distilbert_base_uncased_squad_onnx • 9
上面的示例说明了从 🤗 Hub 导出检查点。在导出本地模型时,首先确保您将模型的权重和分词器文件保存在同一个目录中(local_path
)。在使用 CLI 时,将 local_path
传递给 model
参数,而不是在 🤗 Hub 上提供检查点名称,并提供 --task
参数。您可以在 🤗 Optimum 文档 中查看支持的任务列表。如果未提供 task
参数,它将默认为没有任何特定任务头的模型架构。
optimum-cli export onnx --model local_path --task question-answering distilbert_base_uncased_squad_onnx/
导出的 model.onnx
文件可以在支持 ONNX 标准的 许多加速器 中运行。例如,我们可以使用 ONNX Runtime 加载和运行模型如下:
>>> from transformers import AutoTokenizer >>> from optimum.onnxruntime import ORTModelForQuestionAnswering >>> tokenizer = AutoTokenizer.from_pretrained("distilbert_base_uncased_squad_onnx") >>> model = ORTModelForQuestionAnswering.from_pretrained("distilbert_base_uncased_squad_onnx") >>> inputs = tokenizer("What am I using?", "Using DistilBERT with ONNX Runtime!", return_tensors="pt") >>> outputs = model(**inputs)
这个过程对于 Hub 上的 TensorFlow 检查点是相同的。例如,这里是如何从 Keras 组织 导出一个纯 TensorFlow 检查点的:
optimum-cli export onnx --model keras-io/transformers-qa distilbert_base_cased_squad_onnx/
使用 optimum.onnxruntime 将 🤗 Transformers 模型导出到 ONNX
与 CLI 的替代方法是,您可以像这样以编程方式将 🤗 Transformers 模型导出到 ONNX:
>>> from optimum.onnxruntime import ORTModelForSequenceClassification >>> from transformers import AutoTokenizer >>> model_checkpoint = "distilbert_base_uncased_squad" >>> save_directory = "onnx/" >>> # Load a model from transformers and export it to ONNX >>> ort_model = ORTModelForSequenceClassification.from_pretrained(model_checkpoint, export=True) >>> tokenizer = AutoTokenizer.from_pretrained(model_checkpoint) >>> # Save the onnx model and tokenizer >>> ort_model.save_pretrained(save_directory) >>> tokenizer.save_pretrained(save_directory)
将模型导出到不受支持的架构
如果您希望通过为当前无法导出的模型添加支持来做出贡献,您应该首先检查它是否在 optimum.exporters.onnx
中受支持,如果不是,可以直接 为 🤗 Optimum 做出贡献。
使用 transformers.onnx 导出模型
tranformers.onnx
不再维护,请按照上述使用 🤗 Optimum 导出模型的方法。这一部分将在未来版本中被移除。
要使用 transformers.onnx
将 🤗 Transformers 模型导出到 ONNX,需要安装额外的依赖:
pip install transformers[onnx]
使用 transformers.onnx
包作为 Python 模块,使用现成的配置导出检查点:
python -m transformers.onnx --model=distilbert-base-uncased onnx/
这将导出由 --model
参数定义的检查点的 ONNX 图。传递任何在 🤗 Hub 上或本地存储的检查点。导出的 model.onnx
文件可以在支持 ONNX 标准的许多加速器中运行。例如,加载并使用 ONNX Runtime 运行模型如下:
>>> from transformers import AutoTokenizer >>> from onnxruntime import InferenceSession >>> tokenizer = AutoTokenizer.from_pretrained("distilbert-base-uncased") >>> session = InferenceSession("onnx/model.onnx") >>> # ONNX Runtime expects NumPy arrays as input >>> inputs = tokenizer("Using DistilBERT with ONNX Runtime!", return_tensors="np") >>> outputs = session.run(output_names=["last_hidden_state"], input_feed=dict(inputs))
所需的输出名称(如 ["last_hidden_state"]
)可以通过查看每个模型的 ONNX 配置来获得。例如,对于 DistilBERT,我们有:
>>> from transformers.models.distilbert import DistilBertConfig, DistilBertOnnxConfig >>> config = DistilBertConfig() >>> onnx_config = DistilBertOnnxConfig(config) >>> print(list(onnx_config.outputs.keys())) ["last_hidden_state"]
这个过程对于 Hub 上的 TensorFlow 检查点是相同的。例如,像这样导出一个纯 TensorFlow 检查点:
python -m transformers.onnx --model=keras-io/transformers-qa onnx/
要导出存储在本地的模型,请将模型的权重和分词器文件保存在同一个目录中(例如 local-pt-checkpoint
),然后通过将 transformers.onnx
包的 --model
参数指向所需目录来将其导出到 ONNX:
python -m transformers.onnx --model=local-pt-checkpoint onnx/
导出到 TFLite
TensorFlow Lite 是一个轻量级框架,用于在资源受限的设备上部署机器学习模型,例如移动电话、嵌入式系统和物联网(IoT)设备。TFLite 旨在优化并在这些计算能力、内存和功耗有限的设备上高效运行模型。TensorFlow Lite 模型以一种特殊的高效可移植格式表示,通过 .tflite
文件扩展名进行识别。
🤗 Optimum 提供了通过 exporters.tflite
模块将 🤗 Transformers 模型导出到 TFLite 的功能。有关支持的模型架构列表,请参考 🤗 Optimum 文档。
要将模型导出到 TFLite,请安装所需的依赖项:
pip install optimum[exporters-tf]
要查看所有可用参数,请参考 🤗 Optimum 文档,或在命令行中查看帮助:
optimum-cli export tflite --help
例如,要从 🤗 Hub 导出模型的检查点,比如 bert-base-uncased
,请运行以下命令:
optimum-cli export tflite --model bert-base-uncased --sequence_length 128 bert_tflite/
您应该看到指示进度并显示结果 model.tflite
保存位置的日志。
Validating TFLite model... -[✓] TFLite model output names match reference model (logits) - Validating TFLite Model output "logits": -[✓] (1, 128, 30522) matches (1, 128, 30522) -[x] values not close enough, max diff: 5.817413330078125e-05 (atol: 1e-05) The TensorFlow Lite export succeeded with the warning: The maximum absolute difference between the output of the reference model and the TFLite exported model is not within the set tolerance 1e-05: - logits: max diff = 5.817413330078125e-05. The exported model was saved at: bert_tflite
上面的示例说明了从 🤗 Hub 导出检查点。在导出本地模型时,首先确保您将模型的权重和分词器文件保存在同一个目录(local_path
)中。在使用 CLI 时,将 local_path
传递给 model
参数,而不是在 🤗 Hub 上的检查点名称。
Transformers 4.37 中文文档(七)(5)https://developer.aliyun.com/article/1564153