Как fine-tune'ить предобученную трансформер-модель?
Fine-tuning трансформерной модели — это процесс дообучения предобученного трансформера (например, BERT, RoBERTa, DistilBERT, GPT) на конкретной задаче с помощью добавления специализированного «головного» слоя и адаптации весов модели под задачу. Это основной способ использовать трансформеры в прикладных задачах NLP: классификации, NER, извлечении отношений, QA и др.
Общая схема fine-tuning'а
- **Выбор предобученной модели
** - **Добавление выходной головы
** - **Подготовка данных под формат модели
** - **Определение функции потерь и метрик
** - **Обучение с использованием оптимизатора
** - **Оценка и сохранение модели
**
1. Выбор предобученной модели
Можно использовать модели из библиотеки HuggingFace Transformers, например:
-
bert-base-uncased
-
distilbert-base-uncased
-
roberta-base
-
xlm-roberta-base
-
gpt2 (для генерации)
from transformers import AutoTokenizer, AutoModelForSequenceClassification
model_name = "bert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=2)
2. Подготовка данных
Тексты нужно токенизировать в формат, понятный трансформеру: ids, attention mask, optionally token type ids.
def tokenize_function(examples):
return tokenizer(examples\["text"\], truncation=True, padding="max_length", max_length=128)
С помощью datasets из HuggingFace:
from datasets import load_dataset
dataset = load_dataset("imdb")
tokenized_dataset = dataset.map(tokenize_function, batched=True)
3. Добавление головы под задачу
В зависимости от задачи:
Задача | Головной слой |
---|---|
Классификация | Linear → Softmax |
--- | --- |
Регрессия | Linear → без softmax |
--- | --- |
NER | Linear на каждый токен |
--- | --- |
Множественный выбор | Linear → reshaping на n_choices |
--- | --- |
Seq2Seq (T5, BART) | Декодер + LM Head |
--- | --- |
Пример:
from transformers import BertForSequenceClassification
model = BertForSequenceClassification.from_pretrained(model_name, num_labels=2)
4. Обучающий цикл с Trainer API (вариант с HuggingFace)
from transformers import Trainer, TrainingArguments
training_args = TrainingArguments(
output_dir="./results",
evaluation_strategy="epoch",
per_device_train_batch_size=16,
num_train_epochs=3,
logging_dir="./logs",
save_strategy="epoch"
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized_dataset\["train"\],
eval_dataset=tokenized_dataset\["test"\]
)
trainer.train()
5. Loss-функции и метрики
Трансформерные модели уже включают нужную loss-функцию:
-
CrossEntropyLoss для классификации
-
MSELoss для регрессии
-
TokenClassificationLoss для NER
Для расчёта метрик:
from sklearn.metrics import accuracy_score
def compute_metrics(pred):
labels = pred.label_ids
preds = pred.predictions.argmax(-1)
acc = accuracy_score(labels, preds)
return {"accuracy": acc}
Добавляется в Trainer.
6. Оптимизатор и Scheduler
Используется AdamW с весовым распадом и warm-up шагами:
from transformers import AdamW
optimizer = AdamW(model.parameters(), lr=5e-5, weight_decay=0.01)
Для понижения LR:
from transformers import get_scheduler
lr_scheduler = get_scheduler(
name="linear",
optimizer=optimizer,
num_warmup_steps=100,
num_training_steps=total_steps,
)
7. Альтернативный способ: ручной PyTorch-тренинг
model.train()
for epoch in range(num_epochs):
for batch in dataloader:
outputs = model(\*\*batch)
loss = outputs.loss
loss.backward()
optimizer.step()
lr_scheduler.step()
optimizer.zero_grad()
8. Заморозка слоёв (частичный fine-tuning)
Чтобы не обновлять веса всей модели:
for param in model.bert.parameters():
param.requires_grad = False
Можно дообучать только последние слои — эффективно при ограниченном объёме данных.
9. Сохранение модели
model.save_pretrained("./my_model")
tokenizer.save_pretrained("./my_model")
Загрузка:
from transformers import AutoModelForSequenceClassification
model = AutoModelForSequenceClassification.from_pretrained("./my_model")
10. Поддерживаемые задачи в Transformers
Модель и соответствующий класс для fine-tuning:
Задача | Класс модели |
---|---|
Sequence Classification | AutoModelForSequenceClassification |
--- | --- |
Token Classification (NER) | AutoModelForTokenClassification |
--- | --- |
Question Answering | AutoModelForQuestionAnswering |
--- | --- |
Language Modeling | AutoModelForMaskedLM |
--- | --- |
Text Generation (GPT) | AutoModelForCausalLM |
--- | --- |
Seq2Seq (T5, BART) | AutoModelForSeq2SeqLM |
--- | --- |
Multiple Choice | AutoModelForMultipleChoice |
--- | --- |
11. Примеры задач
Задача | Вход | Выход |
---|---|---|
Классификация | Текст | Метка |
--- | --- | --- |
NER | Последовательность токенов | Метки токенов |
--- | --- | --- |
QA (SQuAD) | Вопрос + контекст | Старт/конец ответа |
--- | --- | --- |
Генерация | Префикс | Завершённый текст |
--- | --- | --- |
Перевод | Англ. текст | Текст на другом языке |
--- | --- | --- |
12. Советы и оптимизации
-
Используйте fp16 для ускорения (в TrainingArguments).
-
Применяйте gradient accumulation при ограниченной памяти.
-
Используйте early stopping по валидации.
-
Применяйте learning rate warmup.
-
Проверяйте переобучение через метрики и потери.
Таким образом, fine-tuning — это адаптация мощной предобученной модели под узкую задачу. Он требует тщательной подготовки данных, настройки головы модели и стратегии обучения, но существенно повышает производительность по сравнению с обучением с нуля.