Senior DS в команду персонализации главной: трансформеры, рекомендательные системы и полный цикл от статьи до A/B-теста на миллионах пользователей
Фишка: Полный цикл ML в проде: от чтения RecSys/KDD-статей до ONNX, A/B-теста на десятках миллионов пользователей. Команда рекомендаций работает с Semantic ID, генеративными моделями (OneRec, TIGER), multi-GPU кластерами H100 и доставкой эмбеддингов через Redis + Sphinx + ANN.
| Этап | Длительность | Что проверяют |
|---|---|---|
| HR-скрининг | 30–45 мин | Мотивация, опыт, формат работы (удалёнка/офис), зарплатные ожидания, соответствие уровню Senior (5–10 лет) |
| Техническое интервью (ML) | 60–90 мин | Классический ML, метрики, ансамбли, нейросети, трансформеры, эмбеддинги; вопросы с привязкой к продукту Авито (модерация, ранжирование, рекомендации) |
| Практика / live coding | 60–90 мин | Python, PyTorch, работа с данными, реализация алгоритма или разбор ML-задачи; воспроизводимость эксперимента |
| System design (ML) | 60 мин | Архитектура рекомендательной системы: recall → ranking → serving, ANN-поиск, A/B-тестирование, мониторинг |
| Финал с командой | 45–60 мин | Глубокий разбор проектов, опыт production ML, культурный fit, вопросы к команде |
Обязательный минимум
Плюсом будет
Что такое ROC-AUC?
Площадь под ROC-кривой (TPR vs FPR при переборе порога). 0.5 — случайный классификатор, 1.0 — идеал. Не зависит от порога, но не учитывает дисбаланс классов.
Что такое precision и recall?
Precision = TP/(TP+FP) — доля верных среди предсказанных положительных. Recall = TP/(TP+FN) — доля найденных среди всех положительных.
Что значит, если ROC-AUC равно 0.5 или 0.1?
0.5 — модель не лучше случайного угадывания. 0.1 — модель систематически ранжирует хуже случайного (можно инвертировать scores).
Что важнее — precision или recall для автоотклонения объявления?
Precision: ложное отклонение дорого (теряем контент). Нужен высокий precision — отклоняем только когда уверены.
Что важнее — precision или recall для отправки на ручную модерацию?
Recall: пропустить нарушение дороже, чем лишняя ручная проверка. Нужен высокий recall — ловим максимум нарушений.
Что такое accuracy и когда она бесполезна?
Доля верных ответов. Бесполезна при сильном дисбалансе классов (99% negative → accuracy 99% у константной модели).
Фишка: В Авито часто спрашивают trade-off precision/recall в контексте модерации объявлений — это прямой продуктовый кейс компании.
Ловушка: Не путайте offline ROC-AUC с online-бизнес-метриками (CTR, конверсия в сделку) — для рекомендаций нужны обе линии оценки.
Что такое бустинг?
Последовательное обучение слабых моделей, каждая исправляет ошибки предыдущей. Финальный предикт — взвешенная сумма.
Как обучается бустинг?
На каждом шаге вычисляют residual/gradient loss, обучают новую модель на negative gradient, добавляют с learning rate.
Для чего нужен градиент в бустинге?
Gradient boosting: каждая новая модель аппроксимирует negative gradient функции потерь — направление на уменьшение loss.
Что такое бэггинг и как он снижает дисперсию?
Bootstrap aggregating: обучают модели на случайных подвыборках с replacement, усредняют. Дисперсия ансамбля ≈ σ²/M при некоррелированных моделях.
Можно ли использовать бэггинг над линейными моделями?
Можно, но бессмысленно: линейные модели стабильны, бэггинг линейных → снова линейная модель (усреднение весов).
Как устроен Random Forest?
Бэггинг деревьев + random feature subset на каждом split. Снижает variance, сохраняет bias. Feature importance через impurity decrease.
Что такое bias и variance, и что уменьшает Random Forest?
Bias — систематическая ошибка модели, variance — чувствительность к данным. RF снижает variance за счёт усреднения, bias деревьев сохраняется.
Совет: CatBoost — часть стека команды поиска и рекомендаций. Будьте готовы сравнить с LightGBM/XGBoost и объяснить, когда GBDT лучше нейросетей (tabular features, мало данных, latency).
Ловушка: На Senior ждут не определения, а опыт: когда бустинг победил DL в проде и почему.
Как обучается дерево?
Рекурсивное разбиение: выбирают признак и порог, максимизирующие reduction impurity (Gini/entropy). Стоп по глубине, min samples, min gain.
Как делается split в вершине дерева?
Перебор всех признаков и порогов, выбор split с max Δ impurity = impurity(parent) − weighted impurity(children).
Что такое критерий Джини и критерий информативности?
Gini = 1 − Σpᵢ² — мера «нечистоты». Entropy = −Σpᵢlog(pᵢ). Оба используются для выбора split; чем меньше — тем чище листья.
Какое разбиение в дереве считается хорошим?
Максимально уменьшает impurity, создаёт однородные листья, не переобучается (достаточно samples в листьях).
Совет: Деревья — база для понимания GBDT. На собесе могут пойти от дерева к бустингу как естественное усложнение.
Как регуляризация помогает бороться с переобучением?
Добавляет penalty к loss (L1/L2/dropout/early stopping), ограничивает сложность модели, снижает variance.
В чём разница между L1 и L2 регуляризацией?
L1 (Lasso) — sparse weights, feature selection. L2 (Ridge) — shrinkage всех весов, smooth solution. L1 → нули, L2 → малые значения.
Как работает градиентный спуск?
w ← w − η·∇L(w). Итеративное движение к минимуму loss по направлению antigradient.
Как работает стохастический градиентный спуск?
Gradient по mini-batch вместо full dataset. Быстрее, шум помогает escape local minima, нужен learning rate schedule.
Какие знаешь модификации градиентного спуска?
Momentum, Nesterov, Adam, AdamW, RMSprop, AdaGrad. Adam — adaptive lr per parameter + momentum.
Что такое momentum?
v ← βv + ∇L; w ← w − ηv. Накапливает «инерцию» градиентов, ускоряет сходимость в ravines.
Как работает dropout на обучении и на инференсе?
Train: случайно обнуляет нейроны с p, масштабирует оставшиеся на 1/(1−p). Inference: все нейроны активны, веса scaled (или inverted dropout).
Как обучаться на большом батче при ограниченной памяти?
Gradient accumulation, mixed precision (FP16/BF16), gradient checkpointing, smaller batch + more steps, data streaming.
Ловушка: Для Senior важно связать регуляризацию с конкретным кейсом: dropout в трансформере vs weight decay в AdamW.
Как устроена BERT?
Transformer encoder, bidirectional self-attention, MLM + NSP pretraining. [CLS] token для classification, subword tokenization.
Что такое residual block и skip connection?
y = F(x) + x. Прямой путь градиента через skip, решает vanishing gradient, позволяет обучать глубокие сети (ResNet).
Что такое свёрточный слой?
Локальный фильтр скользит по входу, извлекает spatial features. Параметры: kernel size, stride, padding, channels.
Какие знаешь способы эмбеддинга?
Word2Vec (CBOW/Skip-gram), GloVe, FastText, ELMo, BERT embeddings, item2vec, two-tower user/item embeddings, learned lookup tables.
Фишка: Вакансия явно требует опыт с трансформерами, Seq2Seq и двухбашенками в проде — готовьте кейс end-to-end: данные → обучение → ONNX → A/B.
Совет: Прочитайте статью Авито про трансформерную персонализацию рекомендаций (avito.tech) — покажет актуальный стек команды.
Как устроена двухбашенная модель (two-tower)?
User tower + Item tower → embeddings в общем пространстве. Recall: ANN-поиск ближайших item по user embedding. Ranking — отдельная модель.
Как быстро отранжировать вектора по близости к запросу?
ANN: FAISS, HNSW, IVF, LSH. Exact brute force O(n·d) не масштабируется; ANN — sub-linear с trade-off recall.
Какое свойство cosine similarity делает его предпочтительным для ANN?
Инвариантность к масштабу вектора (направление важнее длины). Нормализованные embeddings → cosine ≈ dot product.
Какие метрики для рекомендаций?
Offline: NDCG@K, MAP@K, Hit Rate, MRR. Online: CTR, conversion, time spent, revenue. Следите за position bias.
Что такое position bias и как с ним бороться?
Пользователи кликают верхние позиции независимо от релевантности. IPS, counterfactual evaluation, randomization, cascade models.
Фишка: Команда строит Semantic ID (RQ-VAE), generative recsys (OneRec, TIGER), multimodal энкодеры — будьте готовы обсудить generative vs discriminative подходы.
Совет: Посмотрите видео Авито «Как мы перешли от марковской цепочки к SASRec» — хороший контекст эволюции их recsys.
Как спланировать A/B-тест для ML-модели?
Гипотеза → primary metric → MDE → sample size → duration → guardrail metrics → статистический тест (t-test, CUPED, sequential testing).
Что такое CUPED?
Controlled-experiment Using Pre-Experiment Data: variance reduction через ковариату (pre-period metric). Уменьшает нужный sample size.
Когда offline-метрика не коррелирует с online?
Distribution shift, position bias, feedback loop, proxy metric mismatch. Нужна online validation даже при хорошем offline NDCG.
Фишка: Авито активно использует split-тесты для ML — в DS-матрице компетенций A/B есть уже с DS2, самостоятельный запуск — с DS3.
Ловушка: Peeking problem: не останавливайте тест рано при первом значимом результате — используйте fixed horizon или sequential methods.
Top-K рекомендации по cosine similarity
Даны user embedding u (dim=d) и матрица item embeddings V (n×d). Верните top-K item_id с наибольшим cosine similarity к u. n до 10⁷, K=100.
import numpy as np
def top_k_cosine(u, V, K):
u_norm = u / (np.linalg.norm(u) + 1e-9)
V_norm = V / (np.linalg.norm(V, axis=1, keepdims=True) + 1e-9)
scores = V_norm @ u_norm # O(n·d)
top_idx = np.argpartition(-scores, K)[:K]
return top_idx[np.argsort(-scores[top_idx])]
# Production: FAISS IndexFlatIP / HNSW с нормализованными векторамиСложность: O(n·d) brute force; ANN — O(log n) amortized
Расчёт sample size для A/B-теста
Baseline CTR = 5%, ожидаемый uplift +2% относительных (→ 5.1%), α=0.05, power=0.8. Оцените минимальный sample size на группу.
from scipy import stats import numpy as np p1, p2 = 0.05, 0.051 p_pooled = (p1 + p2) / 2 effect = p2 - p1 z_alpha = stats.norm.ppf(0.975) z_beta = stats.norm.ppf(0.8) n = (2 * p_pooled * (1 - p_pooled) * (z_alpha + z_beta)**2) / effect**2 # n ≈ 780 000 на группу # На практике: CUPED, stratification, longer duration
Сложность: O(1)
Negative sampling для two-tower
Реализуйте in-batch negative sampling для two-tower модели: batch size B, user embeddings U (B×d), item embeddings I (B×d). Positive pair — диагональ (uᵢ, iᵢ).
import torch
import torch.nn.functional as F
def in_batch_loss(U, I, temperature=0.05):
# U, I: (B, d), L2-normalized
U = F.normalize(U, dim=-1)
I = F.normalize(I, dim=-1)
logits = U @ I.T / temperature # (B, B)
labels = torch.arange(U.size(0), device=U.device)
return F.cross_entropy(logits, labels)
# B-1 negatives per positive, бесплатно из batchСложность: O(B²·d) для logits
Каркас ответа
3 дня
7 дней
14 дней
| Блок | Готов, если... |
|---|---|
| Метрики | можете объяснить ROC-AUC, precision/recall и выбрать приоритетную метрику для модерации/рекомендаций |
| Ансамбли | можете описать бустинг, RF и когда GBDT лучше DL |
| Трансформеры | можете объяснить BERT, residual block и свой опыт с transformers в проде |
| Recsys | можете нарисовать two-tower → ANN → ranking pipeline с latency budget |
| A/B | можете спланировать тест: MDE, sample size, guardrails, CUPED |
| System design | можете спроектировать recsys для 70M MAU с мониторингом и rollback |
| Live coding | можете за 20 мин написать top-K similarity или in-batch loss на PyTorch |
В день собеседования