Как стать автором
Поиск
Написать публикацию
Обновить

Semantic Retrieval-Augmented Contrastive Learning (SRA-CL) для sequential рекомендательных систем: обзор

Уровень сложностиСредний
Время на прочтение5 мин
Количество просмотров315

👋 Привет, Хабр!

Меня зовут Никита Горячев, я Research Engineer в WB, последние несколько лет работаю на стыке RecSys, LLM и мультимодальных моделей. Каждый день мы обрабатываем миллиарды событий, а модели, которые мы внедряем, напрямую влияют на CTR, удержание и конверсию, принося немало дополнительной выручки.

До этого я успел поработать в AI-стартапе в Palo Alto, где занимался голосовыми агентами (ASR/TTS), и в МТС, где мы строили AI-экосистему. Ранее в Сбере я занимался созданием единого RecSys SDK для всей экосистемы (от SberMegaMarket до Okko и Zvuk), а ещё раньше — развивал персонализацию и ML в ритейле.

Сегодня я хотел бы поговорить о том, как большие языковые модели могут починить контрастивное обучение в рекомендательных системах. Контрастивные методы давно стали стандартом в NLP и CV, но в последовательных рекомендациях они работают далеко не идеально: данные разрежены, а аугментации часто искажают смысл вместо того, чтобы его сохранять. Авторы свежей статьи с arXiv — “Semantic Retrieval Augmented Contrastive Learning for Sequential Recommendation (SRA-CL)” — предлагают элегантное решение: использовать LLM для генерации семантически осмысленных позитивных пар. Звучит просто, но даёт заметный прирост качества — давайте разберёмся, как именно это работает.


📉 Проблема стандартного contrastive learning в рекомендациях

1. Разреженность данных

Поведение пользователей представлено в виде последовательностей из нескольких взаимодействий (обычно 5–50 событий). При этом пространство объектов (товаров) огромное. Простая кластеризация или соседство по ID даёт шумные результаты: два пользователя могут оказаться в одном кластере только из-за пересечения по одному товару.

2. Неподходящие аугментации

В NLP/vision аугментации сохраняют семантику (masking, cropping, dropout). В RS — нет:

  • Удаление случайного товара может полностью изменить смысл.

  • Перестановка событий ломает естественный порядок последовательности.

3. Семантический разрыв

Две последовательности могут быть эквивалентны по смыслу, но не иметь пересечения по ID.

Пример: один пользователь покупает «iPhone → AirPods → MacBook», другой — «Samsung Galaxy → Galaxy Buds → Windows Laptop». На уровне ID это совершенно разные последовательности, но семантически — обе показывают «технологический энтузиаст, покупающий экосистему бренда».

👉 Итог: позитивные пары в contrastive loss не отражают настоящего сходства → модель учится на шумных сигналах.


💡 Идея SRA-CL

SRA-CL решает проблему за счёт семантического ретривала на основе LLM. Вместо случайных аугментаций и кластеризации ID, метод строит позитивные пары, опираясь на осмысленные семантические представления.

Метод включает два компонента:

1️⃣ Cross-sequence Semantic Contrast

  • Каждую последовательность пользователя преобразуют в текстовое резюме с помощью LLM (в статье: DeepSeek-V3, temp=0, top-p=0.001).

  • Тексты кодируются моделью SimCSE-RoBERTa, чтобы получить семантические эмбеддинги.

  • Для каждого пользователя ищутся k ближайших соседей по косинусному сходству (через FAISS или аналогичные индексы).

  • Из соседей строится взвешенный attention-агрегат, который служит позитивной парой для contrastive learning.

2️⃣ Intra-sequence Semantic Contrast

  • Для каждого товара в последовательности ищется семантически близкий товар (через эмбеддинги описаний/атрибутов).

  • Составляются новые последовательности, где часть элементов заменена аналогами (например, «Nike running shoes» → «Adidas sports shoes»).

  • Две версии последовательности теперь отражают одного и того же пользователя, но с вариацией в деталях.

3️⃣ Итоговый лосс

Финальная функция потерь включает три компонента:

\mathcal{L} = \mathcal{L}{rec} + \alpha \cdot \mathcal{L}{cross} + \beta \cdot \mathcal{L}_{intra}

  • \mathcal{L}_{rec} — стандартный лосс для предсказания следующего элемента.

  • \mathcal{L}_{cross} — контрастивная часть для межпользовательских позитивов.

  • \mathcal{L}_{intra} — контрастивная часть для внутри-пользовательских позитивов.

Гиперпараметры \alpha, \beta контролируют вклад семантического CL.


📊 Эксперименты

Датасеты

  • Yelp

  • Sports (Amazon)

  • Beauty (Amazon)

  • Office (Amazon)

Бейзлайны (12 моделей)

GRU4Rec, BERT4Rec, SASRec, DuoRec и др.

Результаты

  • Максимальное улучшение: +11.82% относительно SOTA (p < 0.01).

  • При интеграции в SASRec:

    • HR@20: +8.3% → +27.3%

    • NDCG@20: +9.7% → +25.5%

  • Важно: инференс не усложняется — LLM используется только для предобработки на этапе обучения.


⚙️ Как реализовать SRA-CL

Установка

pip install faiss-cpu transformers sentence-transformers torch

1. Получение семантических эмбеддингов пользователей

from sentence_transformers import SentenceTransformer
import faiss

# Модель SimCSE
model = SentenceTransformer("princeton-nlp/sup-simcse-roberta-base")

user_summaries = [
    "User buys Apple ecosystem products (iPhone, MacBook, AirPods)",
    "User prefers Samsung Galaxy devices and accessories",
    "User frequently purchases fitness and sports equipment"
]

embeddings = model.encode(user_summaries)

# FAISS индекс для поиска соседей
index = faiss.IndexFlatL2(embeddings.shape[1])
index.add(embeddings)

# Ищем top-k соседей
D, I = index.search(embeddings[:1], k=3)
print("Top semantic neighbors:", I[0])

2. Семантические замены внутри последовательности

item_texts = [
    "iPhone 14 Pro smartphone",
    "Samsung Galaxy S23 smartphone",
    "Nike running shoes",
    "Adidas sports shoes"
]

item_embeddings = model.encode(item_texts)
index_items = faiss.IndexFlatL2(item_embeddings.shape[1])
index_items.add(item_embeddings)

# Найдём аналоги для iPhone
D, I = index_items.search(item_embeddings[:1], k=2)
print("Semantically similar items:", [item_texts[j] for j in I[0]])

3. Контрастивный лосс

import torch
import torch.nn as nn

class NTXentLoss(nn.Module):
    def __init__(self, temperature=0.1):
        super().__init__()
        self.temperature = temperature

    def forward(self, z_i, z_j):
        # z_i, z_j — эмбеддинги позитивных пар
        sim_matrix = torch.mm(z_i, z_j.T) / self.temperature
        labels = torch.arange(z_i.size(0)).long()
        loss = nn.CrossEntropyLoss()(sim_matrix, labels)
        return loss

# Пример
z_i = torch.randn(32, 128)  # эмбеддинги оригинальных пользователей
z_j = torch.randn(32, 128)  # эмбеддинги соседей
loss_fn = NTXentLoss()
print("Loss:", loss_fn(z_i, z_j).item())

📌 Практические выводы

  1. SRA-CL улучшает contrastive learning в условиях разреженности и семантического разрыва.

  2. Метод универсален: можно встроить в любую последовательную RS (GRU4Rec, SASRec, DuoRec).

  3. Стоимость инференса не меняется: LLM и SimCSE нужны только для построения позитивов при обучении.

  4. Прирост качества значим: до +11.82% HR@20/NDCG@20 на стандартных датасетах.

  5. Рекомендация для практиков: если работаете с long-tail, cold-start или sparse данными — SRA-CL может дать существенный буст.


📖 Заключение

Работа над SRA-CL вписывается в более широкий тренд: использование LLM не на инференсе, а как «семантических учителей» при обучении моделей. Это позволяет объединить богатую семантику языковых моделей и эффективность классических рекомендательных архитектур.

Скорее всего, мы будем видеть всё больше подобных подходов, где LLM помогают «структурировать» данные на этапе обучения, а не выполняют дорогие онлайн-запросы.


📄 Оригинальная статья: Semantic Retrieval Augmented Contrastive Learning for Sequential Recommendation (SRA-CL)

🔗 arXiv:2503.04162

Теги:
Хабы:
0
Комментарии0

Публикации

Ближайшие события