vacancy-fit-lora-rubert-tiny2

LoRA-адаптер (PEFT) для cointegrated/rubert-tiny2: предсказывает, откликнется ли конкретный кандидат (я) на вакансию hh.ru. Учебный проект: цель — отработать LoRA-дообучение и честную оценку на маленьком несбалансированном датасете, а не получить лучший классификатор.

Данные

414 вакансий (заголовок + описание, до 2500 символов) из моего журнала поиска работы. Метка 1 — был отклик (49 шт., 11.8%), 0 — вакансия просмотрена и пропущена (365). Датасет не публикуется: тексты вакансий принадлежат работодателям.

Обучение

LoRA r=16, alpha=32, dropout=0.1 на query/value, обучаемая голова классификатора; взвешенный cross-entropy под дисбаланс классов, AdamW lr=5e-4, max_len=256, до 10 эпох, выбор эпохи по PR-AUC на валидации. Обучено на CPU. Код — train.py.

Оценка (5-fold CV, out-of-fold, порог подбирается на валидации внутри фолда)

Модель ROC-AUC PR-AUC Precision Recall F1
Случайный классификатор 0.5 0.118 — — —
TF-IDF (1–2-граммы) + логистическая регрессия 0.917 0.582 0.537 0.592 0.563
LoRA rubert-tiny2 (этот адаптер) 0.863 0.427 0.425 0.694 0.527

Вывод: на 49 положительных примерах LoRA не обошла простой TF-IDF-бейзлайн. Решение «откликаться или нет» во многом зависит от конкретных слов (стек, «гибрид», город, «аутстафф»), которые TF-IDF ловит напрямую. Разброс между фолдами большой (val PR-AUC 0.43–0.86), то есть данных мало для устойчивого дообучения. Что можно попробовать: больше данных, модель крупнее (ruBERT-base), признаки из метаданных (формат работы, город) отдельно от текста.

Ограничения

  • Вероятности плохо откалиброваны и сжаты около 0.4–0.5: полезно ранжирование и порог 0.47, а не само число.
  • Все отрицательные примеры — IT-вакансии, которые я пропустил (формат, город, стек). На вакансиях совсем не из IT модель не училась и ведёт себя непредсказуемо.
  • Модель отражает решения одного человека, это не универсальный фильтр вакансий.

Использование

from peft import AutoPeftModelForSequenceClassification
from transformers import AutoTokenizer
import torch
model = AutoPeftModelForSequenceClassification.from_pretrained("MrAlexGov/vacancy-fit-lora-rubert-tiny2")
tok = AutoTokenizer.from_pretrained("MrAlexGov/vacancy-fit-lora-rubert-tiny2")
x = tok("Python-разработчик AI-агентов. Удалённо. FastAPI, MCP, LLM...", return_tensors="pt", truncation=True, max_length=256)
p = torch.softmax(model(**x).logits, -1)[0, 1].item()
print(p >= 0.47)  # порог из metrics.json
Downloads last month
12
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for MrAlexGov/vacancy-fit-lora-rubert-tiny2

Adapter
(1)
this model