Модель изнутри
pipeline удобен, но прячет главное. Посмотрим, что происходит внутри: какие числа выдаёт модель и как из них получаются ответы.
Модель и её выход
import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification
name = "distilbert/distilbert-base-uncased-finetuned-sst-2-english"
tok = AutoTokenizer.from_pretrained(name)
model = AutoModelForSequenceClassification.from_pretrained(name)
enc = tok(["What a great day!", "Worst film ever"], padding=True, return_tensors="pt")
with torch.no_grad():
outputs = model(**enc)
outputs.logits # tensor([[-4.2, 4.5], [4.6, -3.8]])
model.config.id2label # {0: 'NEGATIVE', 1: 'POSITIVE'}
Auto…-классы сами выбирают нужную архитектуру по имени модели:AutoModelForSequenceClassification— классификатор,AutoModel— «голая» модель без головы;- модель вызывают с результатом токенизатора:
model(**enc); на время предсказаний —torch.no_grad(); - выход — объект с полями: у классификатора
logitsформы (тексты, классы).
Логиты → ответ
probs = torch.softmax(outputs.logits, dim=-1) # вероятности по классам
conf, best = probs.max(dim=-1)
[(model.config.id2label[i], p) for i, p in zip(best.tolist(), conf.tolist())]
Ровно это и делает pipeline("sentiment-analysis"). dim=-1 — последнее измерение, то есть классы.
Векторы текстов
«Голая» модель возвращает last_hidden_state — вектор на каждый токен, форма (тексты, токены, размер вектора). Чтобы получить один вектор на текст (эмбеддинг), векторы токенов усредняют — но только настоящих, без [PAD]:
h = outputs.last_hidden_state
m = enc["attention_mask"].unsqueeze(-1).float() # (N, L) → (N, L, 1)
vectors = (h * m).sum(dim=1) / m.sum(dim=1)
Близость по смыслу
Похожие по смыслу тексты дают векторы, смотрящие в одну сторону. Сравнивают их косинусной близостью — от −1 до 1, длина векторов на неё не влияет:
sim = torch.nn.functional.cosine_similarity(query, vectors, dim=-1)
sim.argmax() # самый похожий текст
Так работает смысловой поиск: «доставка задержалась» найдёт «курьер опоздал», хотя общих слов нет.
Итог
AutoTokenizer+AutoModelForSequenceClassification/AutoModel,model(**enc)вno_grad;outputs.logits→softmax(dim=-1)→config.id2label;last_hidden_stateи усреднение сattention_mask;- косинусная близость для поиска похожих текстов.