在 Hugging Face Transformers 中,TrainingArguments
描述训练规则,Trainer
将模型、数据、批处理与评估逻辑组织成训练流程。两者配合可以减少重复代码,但数据格式、评估设计和硬件配置仍需要使用者负责。
先看各组件的分工
| 组件 | 职责 |
|---|---|
| tokenizer | 把文本转换成模型输入 |
| Dataset | 提供样本与标签 |
| data collator | 将样本整理为 batch,执行 padding 等操作 |
| model | 前向计算,结合标签计算损失 |
| TrainingArguments | 配置批大小、学习率、评估、保存等行为 |
| compute_metrics | 将预测转换为可解释的评估指标 |
| Trainer | 协调训练、评估、预测与保存 |
官方接口当前使用 eval_strategy 和
processing_class;旧教程中的
evaluation_strategy 和 tokenizer=
需要对照所安装版本检查。Trainer
官方文档
一个完整的教学示例
下面用极小的中文情感数据演示接口连接。它不是有效的模型质量评测;实际项目应准备有代表性且互不泄漏的训练、验证和测试数据。
python -m pip install transformers datasets accelerate torch numpy
import numpy as np
from datasets import Dataset
from transformers import (
AutoTokenizer, AutoModelForSequenceClassification,
DataCollatorWithPadding, Trainer, TrainingArguments, set_seed,
)
set_seed(42)
model_name = "bert-base-chinese"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(
model_name, num_labels=2,
id2label={0: "negative", 1: "positive"},
label2id={"negative": 0, "positive": 1},
)
train_data = Dataset.from_dict({
"text": ["这门课讲得很清楚", "我很喜欢这个例子", "课程很有帮助",
"这个解释难以理解", "体验令人失望", "内容太混乱了"],
"labels": [1, 1, 1, 0, 0, 0],
})
eval_data = Dataset.from_dict({
"text": ["老师讲解得很好", "这次学习体验很差"],
"labels": [1, 0],
})
def tokenize(batch):
return tokenizer(batch["text"], truncation=True, max_length=128)
train_data = train_data.map(tokenize, batched=True, remove_columns=["text"])
eval_data = eval_data.map(tokenize, batched=True, remove_columns=["text"])
def compute_metrics(prediction):
predicted = np.argmax(prediction.predictions, axis=-1)
return {"accuracy": float(np.mean(predicted == prediction.label_ids))}
args = TrainingArguments(
output_dir="./trainer-demo-output",
num_train_epochs=1,
per_device_train_batch_size=2,
per_device_eval_batch_size=2,
gradient_accumulation_steps=1,
learning_rate=5e-5,
weight_decay=0.01,
warmup_steps=0,
optim="adamw_torch",
lr_scheduler_type="linear",
eval_strategy="epoch",
save_strategy="epoch",
load_best_model_at_end=True,
metric_for_best_model="accuracy",
greater_is_better=True,
save_total_limit=2,
logging_steps=1,
max_grad_norm=1.0,
fp16=False,
bf16=False,
report_to="none",
seed=42,
)
trainer = Trainer(
model=model,
args=args,
train_dataset=train_data,
eval_dataset=eval_data,
processing_class=tokenizer,
data_collator=DataCollatorWithPadding(tokenizer=tokenizer),
compute_metrics=compute_metrics,
)
trainer.train()
print(trainer.evaluate())
trainer.save_model("./trainer-demo-final")
tokenizer.save_pretrained("./trainer-demo-final")
运行需要下载模型并具备足够内存。分类头随机初始化的提示通常意味着需要训练该任务头;不能将未经训练的输出直接解释为可靠预测。
批大小与梯度累积
在常规数据并行设定下,有效批大小约为:
每设备训练批大小 × 设备数 × 梯度累积步数
例如
2×4×8=64。梯度累积降低单次前向/反向需要容纳的样本数,但不会让每个微批的计算消失,也不保证在所有模型和随机操作下与一次大批训练完全等价。
动态 padding
将每批样本补齐到该批最大长度,可以避免把所有短文本固定填充到统一最大长度。这里
tokenize 只做截断,padding 交给 DataCollatorWithPadding。
评估与保存要配套
启用 load_best_model_at_end
时,需要让保存与评估策略兼容。本文都按 epoch 执行;按 steps
配置时,还要检查保存间隔与评估间隔的约束。
“最佳模型”是根据验证指标选出的,不是根据训练 loss
最低自动认定的。Accuracy
也不是所有任务的最佳选择;类别不均衡时,需要进一步检查各类召回和
F1。
早停耐心值通常按评估次数理解,不能一概等同于训练轮数。实际训练还应记录依赖版本、随机种子、数据划分与模型版本;设置
seed 本身并不保证所有硬件上的逐位复现。
示例关闭混合精度以避免假定硬件能力。若要启用 fp16 或
bf16,应先核对设备和框架支持情况。