Skill Tracer
Skills › Scientific Agent Skills › transformers › training.md

training.md

520 lines · skills/transformers/references/training.md at 5f2bc03

Open on GitHub
1# Training and Fine-Tuning
2
3Targets Transformers 5.18.0 / Datasets 5.0.1 / Accelerate 1.15.0 / PEFT 0.21.2. Tiny CPU training, evaluation, checkpoint resume, collators, and LoRA are tested locally; Hub dataset/model downloads, distributed runs, trackers, and hyperparameter services are illustrative. See [review evidence](review.md).
4

Training and Fine-Tuning

Targets Transformers 5.18.0 / Datasets 5.0.1 / Accelerate 1.15.0 / PEFT 0.21.2. Tiny CPU training, evaluation, checkpoint resume, collators, and LoRA are tested locally; Hub dataset/model downloads, distributed runs, trackers, and hyperparameter services are illustrative. See review evidence.

Raw lines 1 to 4
5## Overview
6
7Fine-tune pre-trained models on custom datasets using the Trainer API. The Trainer handles training loops, gradient accumulation, mixed precision, logging, and checkpointing.
8
9**Metrics:** `datasets.load_metric` is removed. Compute simple metrics locally; optional `evaluate.load("accuracy")` loads an external metric implementation, requires the Evaluate package/network or cache, and should be reviewed/pinned for reproducibility.
11**Hub uploads:** `trainer.push_to_hub()` requires authentication (`hf auth login` or `HF_TOKEN`).

Overview

Fine-tune pre-trained models on custom datasets using the Trainer API. The Trainer handles training loops, gradient accumulation, mixed precision, logging, and checkpointing.

Metrics: datasets.load_metric is removed. Compute simple metrics locally; optional evaluate.load("accuracy") loads an external metric implementation, requires the Evaluate package/network or cache, and should be reviewed/pinned for reproducibility.

Hub uploads: trainer.push_to_hub() requires authentication (hf auth login or HF_TOKEN).

Raw lines 5 to 12
13## Basic Fine-Tuning Workflow

Basic Fine-Tuning Workflow

Raw lines 13 to 14
15### Step 1: Load and Preprocess Data
17```python
18from datasets import load_dataset
20# Load dataset
21dataset = load_dataset("Yelp/yelp_review_full")
22# Tune only on a validation partition of training data, keeping test untouched.
23split = dataset["train"].train_test_split(test_size=0.1, seed=42, stratify_by_column="label")
24train_dataset = split["train"]
25eval_dataset = split["test"]
26test_dataset = dataset["test"]
28# Tokenize
29from transformers import AutoTokenizer
31tokenizer = AutoTokenizer.from_pretrained("google-bert/bert-base-uncased")
33def tokenize_function(examples):
34 return tokenizer(
35 examples["text"],
36 truncation=True,
37 max_length=512
38 )
40train_dataset = train_dataset.map(tokenize_function, batched=True)
41eval_dataset = eval_dataset.map(tokenize_function, batched=True)
42```

Step 1: Load and Preprocess Data

from datasets import load_dataset

# Load dataset
dataset = load_dataset("Yelp/yelp_review_full")
# Tune only on a validation partition of training data, keeping test untouched.
split = dataset["train"].train_test_split(test_size=0.1, seed=42, stratify_by_column="label")
train_dataset = split["train"]
eval_dataset = split["test"]
test_dataset = dataset["test"]

# Tokenize
from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("google-bert/bert-base-uncased")

def tokenize_function(examples):
    return tokenizer(
        examples["text"],
        truncation=True,
        max_length=512
    )

train_dataset = train_dataset.map(tokenize_function, batched=True)
eval_dataset = eval_dataset.map(tokenize_function, batched=True)
Raw lines 15 to 43
44### Step 2: Load Model
46```python
47from transformers import AutoModelForSequenceClassification
49model = AutoModelForSequenceClassification.from_pretrained(
50 "google-bert/bert-base-uncased",
51 num_labels=5 # Number of classes
53```

Step 2: Load Model

from transformers import AutoModelForSequenceClassification

model = AutoModelForSequenceClassification.from_pretrained(
    "google-bert/bert-base-uncased",
    num_labels=5  # Number of classes
)
Raw lines 44 to 54
55### Step 3: Define Metrics
57```python
58import numpy as np
60def compute_metrics(eval_pred):
61 logits, labels = eval_pred
62 predictions = np.argmax(logits, axis=-1)
63 return {"accuracy": float(np.mean(predictions == labels))}
64```

Step 3: Define Metrics

import numpy as np

def compute_metrics(eval_pred):
    logits, labels = eval_pred
    predictions = np.argmax(logits, axis=-1)
    return {"accuracy": float(np.mean(predictions == labels))}
Raw lines 55 to 65
66### Step 4: Configure Training
68```python
69from transformers import TrainingArguments
71training_args = TrainingArguments(
72 output_dir="./results",
73 eval_strategy="epoch",
74 save_strategy="epoch",
75 learning_rate=2e-5,
76 per_device_train_batch_size=8,
77 per_device_eval_batch_size=8,
78 num_train_epochs=3,
79 weight_decay=0.01,
80 report_to="none", # Opt in to external trackers explicitly.
81 logging_steps=10,
82 load_best_model_at_end=True,
83 metric_for_best_model="accuracy",
85```

Step 4: Configure Training

from transformers import TrainingArguments

training_args = TrainingArguments(
    output_dir="./results",
    eval_strategy="epoch",
    save_strategy="epoch",
    learning_rate=2e-5,
    per_device_train_batch_size=8,
    per_device_eval_batch_size=8,
    num_train_epochs=3,
    weight_decay=0.01,
    report_to="none",  # Opt in to external trackers explicitly.
    logging_steps=10,
    load_best_model_at_end=True,
    metric_for_best_model="accuracy",
)
Raw lines 66 to 86
87### Step 5: Create Trainer and Train
89```python
90from transformers import Trainer, DataCollatorWithPadding
92trainer = Trainer(
93 model=model,
94 args=training_args,
95 train_dataset=train_dataset,
96 eval_dataset=eval_dataset,
97 compute_metrics=compute_metrics,
98 processing_class=tokenizer,
99 data_collator=DataCollatorWithPadding(tokenizer),
102# Start training
103trainer.train()
105# Evaluate
106results = trainer.evaluate()
107print(results)
108```

Step 5: Create Trainer and Train

from transformers import Trainer, DataCollatorWithPadding

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=train_dataset,
    eval_dataset=eval_dataset,
    compute_metrics=compute_metrics,
    processing_class=tokenizer,
    data_collator=DataCollatorWithPadding(tokenizer),
)

# Start training
trainer.train()

# Evaluate
results = trainer.evaluate()
print(results)
Raw lines 87 to 109
110### Step 6: Save Model
112```python
113trainer.save_model("./fine_tuned_model")
114tokenizer.save_pretrained("./fine_tuned_model")
116# Optional external upload, only when intended:
117# Set hub_model_id="username/my-finetuned-model" in TrainingArguments first.
118# trainer.push_to_hub(commit_message="Upload fine-tuned model")
119```

Step 6: Save Model

trainer.save_model("./fine_tuned_model")
tokenizer.save_pretrained("./fine_tuned_model")

# Optional external upload, only when intended:
# Set hub_model_id="username/my-finetuned-model" in TrainingArguments first.
# trainer.push_to_hub(commit_message="Upload fine-tuned model")
Raw lines 110 to 120
121## TrainingArguments Parameters

TrainingArguments Parameters

Raw lines 121 to 122
123### Essential Parameters
125**output_dir**: Directory for checkpoints and logs
126```python
127output_dir="./results"
128```
130**num_train_epochs**: Number of training epochs
131```python
132num_train_epochs=3
133```
135**per_device_train_batch_size**: Batch size per GPU/CPU
136```python
137per_device_train_batch_size=8
138```
140**learning_rate**: Optimizer learning rate
141```python
142learning_rate=2e-5 # Common for BERT-style models
143learning_rate=5e-5 # Common for smaller models
144```
146**weight_decay**: Optimizer weight decay (AdamW decouples this from the gradient; it is not generally equivalent to adding an L2 loss penalty)
147```python
148weight_decay=0.01
149```

Essential Parameters

output_dir: Directory for checkpoints and logs

output_dir="./results"

num_train_epochs: Number of training epochs

num_train_epochs=3

per_device_train_batch_size: Batch size per GPU/CPU

per_device_train_batch_size=8

learning_rate: Optimizer learning rate

learning_rate=2e-5  # Common for BERT-style models
learning_rate=5e-5  # Common for smaller models

weight_decay: Optimizer weight decay (AdamW decouples this from the gradient; it is not generally equivalent to adding an L2 loss penalty)

weight_decay=0.01
Raw lines 123 to 150
151### Evaluation and Saving
153**eval_strategy**: When to evaluate ("no", "steps", "epoch")
154```python
155eval_strategy="epoch" # Evaluate after each epoch
156eval_strategy="steps" # Evaluate every eval_steps
157```
159**save_strategy**: When to save checkpoints
160```python
161save_strategy="epoch"
162save_strategy="steps"
163save_steps=500
164```
166**load_best_model_at_end**: Load best checkpoint after training
167```python
168load_best_model_at_end=True
169metric_for_best_model="accuracy" # Metric to compare
170```

Evaluation and Saving

eval_strategy: When to evaluate ("no", "steps", "epoch")

eval_strategy="epoch"  # Evaluate after each epoch
eval_strategy="steps"  # Evaluate every eval_steps

save_strategy: When to save checkpoints

save_strategy="epoch"
save_strategy="steps"
save_steps=500

load_best_model_at_end: Load best checkpoint after training

load_best_model_at_end=True
metric_for_best_model="accuracy"  # Metric to compare
Raw lines 151 to 171
172### Optimization
174**gradient_accumulation_steps**: Accumulate gradients over multiple steps
175```python
176gradient_accumulation_steps=4 # Effective batch = per-device batch * accumulation * data-parallel workers (except partial final groups)
177```
179**fp16**: Enable mixed precision (NVIDIA GPUs without native bfloat16)
180```python
181fp16=True
182```
184**bf16**: Enable bfloat16 (preferred on Ampere+ and newer GPUs when supported)
185```python
186bf16=True
187```
189**gradient_checkpointing**: Trade compute for memory
190```python
191gradient_checkpointing=True # Slower but uses less memory
192```
194**optim**: Optimizer choice
195```python
196optim="adamw_torch" # Explicit portable choice; current Torch>=2.8 default is adamw_torch_fused
197optim="adamw_8bit" # 8-bit Adam (requires bitsandbytes)
198optim="adafactor" # Memory-efficient alternative
199```

Optimization

gradient_accumulation_steps: Accumulate gradients over multiple steps

gradient_accumulation_steps=4  # Effective batch = per-device batch * accumulation * data-parallel workers (except partial final groups)

fp16: Enable mixed precision (NVIDIA GPUs without native bfloat16)

fp16=True

bf16: Enable bfloat16 (preferred on Ampere+ and newer GPUs when supported)

bf16=True

gradient_checkpointing: Trade compute for memory

gradient_checkpointing=True  # Slower but uses less memory

optim: Optimizer choice

optim="adamw_torch"  # Explicit portable choice; current Torch>=2.8 default is adamw_torch_fused
optim="adamw_8bit"    # 8-bit Adam (requires bitsandbytes)
optim="adafactor"     # Memory-efficient alternative
Raw lines 172 to 200
201### Learning Rate Scheduling
203**lr_scheduler_type**: Learning rate schedule
204```python
205lr_scheduler_type="linear" # Linear decay
206lr_scheduler_type="cosine" # Cosine annealing
207lr_scheduler_type="constant" # No decay
208lr_scheduler_type="constant_with_warmup"
209```
211**warmup_steps**: Integer step count or fractional ratio in [0, 1). `warmup_ratio` was removed in v5.
212```python
213warmup_steps=500
214# Or
215warmup_steps=0.1 # 10% of total steps
216```

Learning Rate Scheduling

lr_scheduler_type: Learning rate schedule

lr_scheduler_type="linear"       # Linear decay
lr_scheduler_type="cosine"       # Cosine annealing
lr_scheduler_type="constant"     # No decay
lr_scheduler_type="constant_with_warmup"

warmup_steps: Integer step count or fractional ratio in [0, 1). warmup_ratio was removed in v5.

warmup_steps=500
# Or
warmup_steps=0.1  # 10% of total steps
Raw lines 201 to 217
218### Logging
220**TensorBoard directory**: `logging_dir` was removed from TrainingArguments. Set `TENSORBOARD_LOGGING_DIR=./logs` in the environment before creating Trainer and install TensorBoard if using it.
222**logging_steps**: Log every N steps
223```python
224logging_steps=10
225```
227**report_to**: Logging integrations
228```python
229report_to="none" # Local-only default used here
230report_to=["tensorboard"]
231report_to=["wandb"]
232report_to=["tensorboard", "wandb"]
233```

Logging

TensorBoard directory: logging_dir was removed from TrainingArguments. Set TENSORBOARD_LOGGING_DIR=./logs in the environment before creating Trainer and install TensorBoard if using it.

logging_steps: Log every N steps

logging_steps=10

report_to: Logging integrations

report_to="none"  # Local-only default used here
report_to=["tensorboard"]
report_to=["wandb"]
report_to=["tensorboard", "wandb"]
Raw lines 218 to 234
235### Distributed Training
237**ddp_backend**: Distributed backend
238```python
239ddp_backend="nccl" # For multi-GPU
240```
242**deepspeed**: DeepSpeed config file
243```python
244deepspeed="ds_config.json"
245```

Distributed Training

ddp_backend: Distributed backend

ddp_backend="nccl"  # For multi-GPU

deepspeed: DeepSpeed config file

deepspeed="ds_config.json"
Raw lines 235 to 246
247## Data Collators
249Handle dynamic padding and special preprocessing:

Data Collators

Handle dynamic padding and special preprocessing:

Raw lines 247 to 250
251### DataCollatorWithPadding
253Pad sequences to longest in batch:
254```python
255from transformers import DataCollatorWithPadding
257data_collator = DataCollatorWithPadding(tokenizer=tokenizer)
259trainer = Trainer(
260 model=model,
261 args=training_args,
262 train_dataset=train_dataset,
263 data_collator=data_collator,
264 eval_dataset=eval_dataset,
265 processing_class=tokenizer,
267```

DataCollatorWithPadding

Pad sequences to longest in batch:

from transformers import DataCollatorWithPadding

data_collator = DataCollatorWithPadding(tokenizer=tokenizer)

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=train_dataset,
    data_collator=data_collator,
    eval_dataset=eval_dataset,
    processing_class=tokenizer,
)
Raw lines 251 to 268
269### DataCollatorForLanguageModeling
271For masked language modeling:
272```python
273from transformers import DataCollatorForLanguageModeling
275data_collator = DataCollatorForLanguageModeling(
276 tokenizer=tokenizer,
277 mlm=True,
278 mlm_probability=0.15
280```

DataCollatorForLanguageModeling

For masked language modeling:

from transformers import DataCollatorForLanguageModeling

data_collator = DataCollatorForLanguageModeling(
    tokenizer=tokenizer,
    mlm=True,
    mlm_probability=0.15
)
Raw lines 269 to 281
282### DataCollatorForSeq2Seq
284For sequence-to-sequence tasks:
285```python
286from transformers import DataCollatorForSeq2Seq
288data_collator = DataCollatorForSeq2Seq(
289 tokenizer=tokenizer,
290 model=model,
291 padding=True
293```

DataCollatorForSeq2Seq

For sequence-to-sequence tasks:

from transformers import DataCollatorForSeq2Seq

data_collator = DataCollatorForSeq2Seq(
    tokenizer=tokenizer,
    model=model,
    padding=True
)
Raw lines 282 to 294
295## Custom Training

Custom Training

Raw lines 295 to 296
297### Custom Trainer
299Accept `num_items_in_batch` in the current override signature. This example uses a per-microbatch weighted mean and explicitly disables automatic loss-kwargs normalization; use accumulation=1 for its direct weighted-batch interpretation. Unequal microbatch weights/sizes need a deliberately derived accumulated denominator.
301```python
302import torch
303from transformers import Trainer
305class WeightedTrainer(Trainer):
306 def __init__(self, *args, class_weights, **kwargs):
307 super().__init__(*args, **kwargs)
308 self.class_weights = torch.as_tensor(class_weights, dtype=torch.float32)
309 self.model_accepts_loss_kwargs = False
311 def compute_loss(self, model, inputs, return_outputs=False, num_items_in_batch=None):
312 labels = inputs["labels"]
313 outputs = model(**{key: value for key, value in inputs.items() if key != "labels"})
314 logits = outputs.logits
315 loss = torch.nn.functional.cross_entropy(
316 logits, labels, weight=self.class_weights.to(device=logits.device, dtype=logits.dtype)
317 )
318 return (loss, outputs) if return_outputs else loss
319```

Custom Trainer

Accept num_items_in_batch in the current override signature. This example uses a per-microbatch weighted mean and explicitly disables automatic loss-kwargs normalization; use accumulation=1 for its direct weighted-batch interpretation. Unequal microbatch weights/sizes need a deliberately derived accumulated denominator.

import torch
from transformers import Trainer

class WeightedTrainer(Trainer):
    def __init__(self, *args, class_weights, **kwargs):
        super().__init__(*args, **kwargs)
        self.class_weights = torch.as_tensor(class_weights, dtype=torch.float32)
        self.model_accepts_loss_kwargs = False

    def compute_loss(self, model, inputs, return_outputs=False, num_items_in_batch=None):
        labels = inputs["labels"]
        outputs = model(**{key: value for key, value in inputs.items() if key != "labels"})
        logits = outputs.logits
        loss = torch.nn.functional.cross_entropy(
            logits, labels, weight=self.class_weights.to(device=logits.device, dtype=logits.dtype)
        )
        return (loss, outputs) if return_outputs else loss
Raw lines 297 to 320
321### Custom Callbacks
323Monitor and control training:
325```python
326from transformers import TrainerCallback
328class CustomCallback(TrainerCallback):
329 def on_epoch_end(self, args, state, control, **kwargs):
330 print(f"Epoch {state.epoch} completed")
331 # Custom logic here
332 return control
334trainer = Trainer(
335 model=model,
336 args=training_args,
337 train_dataset=train_dataset,
338 eval_dataset=eval_dataset,
339 processing_class=tokenizer,
340 data_collator=DataCollatorWithPadding(tokenizer),
341 callbacks=[CustomCallback],
343```

Custom Callbacks

Monitor and control training:

from transformers import TrainerCallback

class CustomCallback(TrainerCallback):
    def on_epoch_end(self, args, state, control, **kwargs):
        print(f"Epoch {state.epoch} completed")
        # Custom logic here
        return control

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=train_dataset,
    eval_dataset=eval_dataset,
    processing_class=tokenizer,
    data_collator=DataCollatorWithPadding(tokenizer),
    callbacks=[CustomCallback],
)
Raw lines 321 to 344
345## Advanced Training Techniques

Advanced Training Techniques

Raw lines 345 to 346
347### Parameter-Efficient Fine-Tuning (PEFT)
349Use LoRA for efficient fine-tuning. The `query`/`value` targets below match BERT, not every architecture; inspect `named_modules()` and confirm trainable parameters. Adapter checkpoints require the correct base checkpoint and revision to reload.
351```python
352from peft import LoraConfig, get_peft_model
354lora_config = LoraConfig(
355 r=16,
356 lora_alpha=32,
357 target_modules=["query", "value"],
358 lora_dropout=0.05,
359 bias="none",
360 task_type="SEQ_CLS"
363model = get_peft_model(model, lora_config)
364model.print_trainable_parameters() # Shows reduced parameter count
366# Train normally with Trainer
367trainer = Trainer(model=model, args=training_args, train_dataset=train_dataset,
368 eval_dataset=eval_dataset, processing_class=tokenizer,
369 data_collator=DataCollatorWithPadding(tokenizer))
370trainer.train()
371```

Parameter-Efficient Fine-Tuning (PEFT)

Use LoRA for efficient fine-tuning. The query/value targets below match BERT, not every architecture; inspect named_modules() and confirm trainable parameters. Adapter checkpoints require the correct base checkpoint and revision to reload.

from peft import LoraConfig, get_peft_model

lora_config = LoraConfig(
    r=16,
    lora_alpha=32,
    target_modules=["query", "value"],
    lora_dropout=0.05,
    bias="none",
    task_type="SEQ_CLS"
)

model = get_peft_model(model, lora_config)
model.print_trainable_parameters()  # Shows reduced parameter count

# Train normally with Trainer
trainer = Trainer(model=model, args=training_args, train_dataset=train_dataset,
                  eval_dataset=eval_dataset, processing_class=tokenizer,
                  data_collator=DataCollatorWithPadding(tokenizer))
trainer.train()
Raw lines 347 to 372
373### Gradient Checkpointing
375Reduce memory at cost of speed:
377```python
378model.gradient_checkpointing_enable()
380training_args = TrainingArguments(
381 output_dir="./checkpointed-results",
382 gradient_checkpointing=True,
383 report_to="none",
385```

Gradient Checkpointing

Reduce memory at cost of speed:

model.gradient_checkpointing_enable()

training_args = TrainingArguments(
    output_dir="./checkpointed-results",
    gradient_checkpointing=True,
    report_to="none",
)
Raw lines 373 to 386
387### Mixed Precision Training
389```python
390training_args = TrainingArguments(
391 output_dir="./mixed-precision-results",
392 bf16=True, # Only on a backend that supports it; use fp16=True as an alternative.
393 report_to="none",
395```

Mixed Precision Training

training_args = TrainingArguments(
    output_dir="./mixed-precision-results",
    bf16=True,  # Only on a backend that supports it; use fp16=True as an alternative.
    report_to="none",
)
Raw lines 387 to 396
397### DeepSpeed Integration
399Optional backend-dependent path, not run on this CPU audit. Save the following as `ds_config.json`; install a compatible DeepSpeed build and launch under its distributed runner. Auto fields let Trainer supply matching values. `device_map="auto"` is not a replacement for distributed training.
401```json
403 "train_batch_size": "auto",
404 "train_micro_batch_size_per_gpu": "auto",
405 "gradient_accumulation_steps": "auto",
406 "optimizer": {"type": "AdamW", "params": {"lr": "auto"}},
407 "bf16": {"enabled": "auto"},
408 "zero_optimization": {"stage": 2}
410```
412```python
413training_args = TrainingArguments(
414 output_dir="./distributed-results",
415 deepspeed="ds_config.json",
416 report_to="none",
418```

DeepSpeed Integration

Optional backend-dependent path, not run on this CPU audit. Save the following as ds_config.json; install a compatible DeepSpeed build and launch under its distributed runner. Auto fields let Trainer supply matching values. device_map="auto" is not a replacement for distributed training.

{
  "train_batch_size": "auto",
  "train_micro_batch_size_per_gpu": "auto",
  "gradient_accumulation_steps": "auto",
  "optimizer": {"type": "AdamW", "params": {"lr": "auto"}},
  "bf16": {"enabled": "auto"},
  "zero_optimization": {"stage": 2}
}
training_args = TrainingArguments(
    output_dir="./distributed-results",
    deepspeed="ds_config.json",
    report_to="none",
)
Raw lines 397 to 419
420## Training Tips
422### Hyperparameter Tuning
424Common starting points:
425- **Learning rate**: 2e-5 to 5e-5 for BERT-like models, 1e-4 to 1e-3 for smaller models
426- **Batch size**: 8-32 depending on GPU memory
427- **Epochs**: 2-4 for fine-tuning, more for domain adaptation
428- **Warmup**: 10% of total steps
430Illustrative local Optuna search (`uv pip install optuna`); do not tune against the held-out test dataset:
432```python
433def model_init():
434 return AutoModelForSequenceClassification.from_pretrained(
435 "google-bert/bert-base-uncased",
436 num_labels=5
437 )
439def optuna_hp_space(trial):
440 return {
441 "learning_rate": trial.suggest_float("learning_rate", 1e-5, 5e-5, log=True),
442 "per_device_train_batch_size": trial.suggest_categorical("per_device_train_batch_size", [8, 16, 32]),
443 "num_train_epochs": trial.suggest_int("num_train_epochs", 2, 5),
444 }
446trainer = Trainer(model_init=model_init, args=training_args, train_dataset=train_dataset,
447 eval_dataset=eval_dataset, compute_metrics=compute_metrics,
448 processing_class=tokenizer, data_collator=DataCollatorWithPadding(tokenizer))
449best_trial = trainer.hyperparameter_search(
450 direction="maximize",
451 backend="optuna",
452 hp_space=optuna_hp_space,
453 n_trials=10,
455```

Hyperparameter Tuning

Common starting points:

  • Learning rate: 2e-5 to 5e-5 for BERT-like models, 1e-4 to 1e-3 for smaller models
  • Batch size: 8-32 depending on GPU memory
  • Epochs: 2-4 for fine-tuning, more for domain adaptation
  • Warmup: 10% of total steps

Illustrative local Optuna search (uv pip install optuna); do not tune against the held-out test dataset:

def model_init():
    return AutoModelForSequenceClassification.from_pretrained(
        "google-bert/bert-base-uncased",
        num_labels=5
    )

def optuna_hp_space(trial):
    return {
        "learning_rate": trial.suggest_float("learning_rate", 1e-5, 5e-5, log=True),
        "per_device_train_batch_size": trial.suggest_categorical("per_device_train_batch_size", [8, 16, 32]),
        "num_train_epochs": trial.suggest_int("num_train_epochs", 2, 5),
    }

trainer = Trainer(model_init=model_init, args=training_args, train_dataset=train_dataset,
                  eval_dataset=eval_dataset, compute_metrics=compute_metrics,
                  processing_class=tokenizer, data_collator=DataCollatorWithPadding(tokenizer))
best_trial = trainer.hyperparameter_search(
    direction="maximize",
    backend="optuna",
    hp_space=optuna_hp_space,
    n_trials=10,
)
Raw lines 422 to 456
457### Monitoring Training
459Use TensorBoard:
460```bash
461tensorboard --logdir ./logs # Match TENSORBOARD_LOGGING_DIR used by training
462```
464Optional Weights & Biases integration (`uv pip install wandb`); this sends run metadata to the configured service unless explicitly configured offline:
465```python
466import wandb
467wandb.init(project="my-project")
469training_args = TrainingArguments(
470 output_dir="./tracked-results",
471 report_to=["wandb"],
473```

Monitoring Training

Use TensorBoard:

tensorboard --logdir ./logs  # Match TENSORBOARD_LOGGING_DIR used by training

Optional Weights & Biases integration (uv pip install wandb); this sends run metadata to the configured service unless explicitly configured offline:

import wandb
wandb.init(project="my-project")

training_args = TrainingArguments(
    output_dir="./tracked-results",
    report_to=["wandb"],
)
Raw lines 457 to 474
475### Resume Training
477Resume from checkpoint:
478```python
479trainer.train(resume_from_checkpoint="./results/checkpoint-1000")
480```

Resume Training

Resume from checkpoint:

trainer.train(resume_from_checkpoint="./results/checkpoint-1000")
Raw lines 475 to 481
482## Common Issues
484**CUDA out of memory:**
485- Reduce batch size
486- Enable gradient checkpointing
487- Use gradient accumulation
488- Use 8-bit optimizers
490**Overfitting:**
491- Increase weight_decay
492- Add dropout
493- Use early stopping
494- Reduce model size or training epochs
496**Slow training:**
497- Increase batch size
498- Enable mixed precision (fp16/bf16)
499- Use multiple GPUs
500- Optimize data loading

Common Issues

CUDA out of memory:

  • Reduce batch size
  • Enable gradient checkpointing
  • Use gradient accumulation
  • Use 8-bit optimizers

Overfitting:

  • Increase weight_decay
  • Add dropout
  • Use early stopping
  • Reduce model size or training epochs

Slow training:

  • Increase batch size
  • Enable mixed precision (fp16/bf16)
  • Use multiple GPUs
  • Optimize data loading
Raw lines 482 to 501
502## Best Practices
5041. **Start small**: Test on small dataset subset first
5052. **Use evaluation**: Monitor validation metrics
5063. **Save checkpoints**: Enable save_strategy
5074. **Log extensively**: Use TensorBoard or W&B
5085. **Try different learning rates**: Start with 2e-5
5096. **Use warmup**: Helps training stability
5107. **Enable mixed precision**: Faster training
5118. **Consider PEFT**: For large models with limited resources

Best Practices

  1. Start small: Test on small dataset subset first
  2. Use evaluation: Monitor validation metrics
  3. Save checkpoints: Enable save_strategy
  4. Log extensively: Use TensorBoard or W&B
  5. Try different learning rates: Start with 2e-5
  6. Use warmup: Helps training stability
  7. Enable mixed precision: Faster training
  8. Consider PEFT: For large models with limited resources
Raw lines 502 to 512
513## Label and evaluation checks
515- Preserve the dataset's integer-label mapping in `model.config.id2label`/`label2id`; a resized/random classification head requires training before meaningful predictions.
516- For token classification, align words/subtokens and mask ignored positions with -100. For seq2seq, tokenize targets with `text_target` and pad labels with -100 through `DataCollatorForSeq2Seq`.
517- `DataCollatorForLanguageModeling(mlm=False)` masks every occurrence of `pad_token_id` in labels. If EOS doubles as PAD, genuine EOS labels are lost; use a distinct pad token (resize embeddings) or mask by `attention_mask` in a task-specific collator.
518- Best-checkpoint loading requires compatible evaluation/save schedules; for step schedules, `save_steps` must be a multiple of `eval_steps`.
519- A model/tokenizer export is not a resumable Trainer checkpoint with optimizer/scheduler/RNG state. Resume from an actual `checkpoint-*` directory with matching data and training settings.
520- Report class-specific metrics/calibration and leakage controls as appropriate; one tiny successful training step is only a mechanics check.

Label and evaluation checks

  • Preserve the dataset's integer-label mapping in model.config.id2label/label2id; a resized/random classification head requires training before meaningful predictions.
  • For token classification, align words/subtokens and mask ignored positions with -100. For seq2seq, tokenize targets with text_target and pad labels with -100 through DataCollatorForSeq2Seq.
  • DataCollatorForLanguageModeling(mlm=False) masks every occurrence of pad_token_id in labels. If EOS doubles as PAD, genuine EOS labels are lost; use a distinct pad token (resize embeddings) or mask by attention_mask in a task-specific collator.
  • Best-checkpoint loading requires compatible evaluation/save schedules; for step schedules, save_steps must be a multiple of eval_steps.
  • A model/tokenizer export is not a resumable Trainer checkpoint with optimizer/scheduler/RNG state. Resume from an actual checkpoint-* directory with matching data and training settings.
  • Report class-specific metrics/calibration and leakage controls as appropriate; one tiny successful training step is only a mechanics check.
Raw lines 513 to 520