Recommender Systems with Generative Retrieval

预备知识

核心思想

20250316175829

20250316175859

20250316180725

注: 这里省略了避免 ID 碰撞的细节.

个人测试


# %%


import pandas as pd
import torch
import numpy as np
import os
import pickle
from tqdm import tqdm

# Load model directly
from transformers import AutoTokenizer, AutoModelForCausalLM
from sentence_transformers import SentenceTransformer

os.environ["CUDA_VISIBLE_DEVICES"] = "3"

# %%


item_df = pd.read_csv('../data/Processed/Amazon2014Beauty_550_LOU/item.txt', sep='\t')

fields = ('TITLE', 'CATEGORIES', 'BRAND')
# fields = ('TITLE',)
for field in fields:
    item_df[field] = item_df[field].fillna('')

item_df['TEXT'] = item_df.apply(
    lambda row: "\n".join([f"{field}: {row[field]}." for field in fields]),
    axis=1
)

print(item_df['TEXT'].head(5))

# %%


def export_pickle(data, file: str):
    r"""
    Export data into pickle format.

    data: Any
    file: str
        The file (path/filename) to be saved
    """
    fh = None
    try:
        fh = open(file, "wb")
        pickle.dump(data, fh, pickle.HIGHEST_PROTOCOL)
    except (EnvironmentError, pickle.PicklingError) as err:
        ExportError_ = type("ExportError", (Exception,), dict())
        raise ExportError_(f"Export Error: {err}")
    finally:
        if fh is not None:
            fh.close()


def encode_by_llama(
    item_df: pd.DataFrame,
    model_dir: str = "./models",
    model: str = "Llama-2-7b-hf",
    batch_size: int = 32
):
    saved_filename = f"{model}_{'_'.join(fields)}.pkl".lower()
    model_path = os.path.join(model_dir, model)
    tokenizer = AutoTokenizer.from_pretrained(model_path, device_map = 'cuda')
    model = AutoModelForCausalLM.from_pretrained(model_path, device_map = 'cuda')

    tokenizer.padding_side = "left"
    tokenizer.pad_token = tokenizer.eos_token

    for i in tqdm(range(0, len(item_df), batch_size)):
        # print(i)
        item_names = item_df['TEXT'][i:i+batch_size]
        # 生成输出
        inputs = tokenizer(item_names.tolist(), return_tensors="pt", padding=True, truncation=True, max_length=128).to(model.device)
        with torch.no_grad():
            output = model(**inputs, output_hidden_states=True)
        seq_embeds = output.hidden_states[-1][:, -1, :].detach().cpu().numpy()
        # break
        if i == 0:
            tFeats = seq_embeds
        else:
            tFeats = np.concatenate((tFeats, seq_embeds), axis=0)
    tFeats = torch.from_numpy(tFeats).float()

    export_pickle(
        tFeats,
        saved_filename
    )

    return tFeats


def encode_textual_modality(
    item_df: pd.DataFrame,
    model: str = "all-MiniLM-L12-v2", model_dir: str = "./models",
    batch_size: int = 128
):
    saved_filename = f"{model}_{'_'.join(fields)}.pkl".lower()
    sentences = item_df['TEXT']
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    encoder = SentenceTransformer(
        os.path.join(model_dir, model),
        device=device
    ).eval()

    with torch.no_grad():
        tFeats = encoder.encode(
            sentences, 
            convert_to_tensor=True,
            batch_size=batch_size, show_progress_bar=True
        ).cpu()
    assert tFeats.size(0) == len(item_df), f"Unknown errors happen ..."

    export_pickle(
        tFeats,
        saved_filename
    )

    return tFeats


# %%

encode_by_llama(item_df)
encode_textual_modality(item_df)

SASRec

Blocks

20250707105044

Quantization

HR@1HR@5HR@10NDCG@5NDCG@10
Random0.00250.00800.01140.00520.0063
KMeans (random; iters=10)0.00390.01460.02330.00920.0120
KMeans (random; iters=100)0.00380.01540.02460.00960.0126
KMeans (points; iters=10)0.00320.01190.02190.00740.0107
KMeans (points; iters=100)0.00430.01440.02390.00920.0123
STE0.00230.01110.01880.00670.0091
Rotation-trick0.00410.01220.01950.00830.0106
Rotation-trick w/o KMeans init0.00250.01050.01780.00640.0087
SimVQ0.00290.00920.01640.00600.0083

Commit Weight

20250814201818

PPL -> Performance

20250818202549

20250818203151

Epochs

20250821192533

20250821192549

参考文献

  1. Rajput S., Mehta N., Singh A., Keshavan R., Vu T., Heldt L., Hong L., Tay Y., Tran V. Q., Samost J., Kula M., Chi E. H. and Sathiamoorthy M. Recommender Systems with Generative Retrieval. NeurIPS, 2023. [PDF] [Code]