Как fine-tune'ить предобученную трансформер-модель?

Fine-tuning трансформерной модели — это процесс дообучения предобученного трансформера (например, BERT, RoBERTa, DistilBERT, GPT) на конкретной задаче с помощью добавления специализированного «головного» слоя и адаптации весов модели под задачу. Это основной способ использовать трансформеры в прикладных задачах NLP: классификации, NER, извлечении отношений, QA и др.

Общая схема fine-tuning'а

  1. **Выбор предобученной модели
    **
  2. **Добавление выходной головы
    **
  3. **Подготовка данных под формат модели
    **
  4. **Определение функции потерь и метрик
    **
  5. **Обучение с использованием оптимизатора
    **
  6. **Оценка и сохранение модели
    **

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 — это адаптация мощной предобученной модели под узкую задачу. Он требует тщательной подготовки данных, настройки головы модели и стратегии обучения, но существенно повышает производительность по сравнению с обучением с нуля.