포스트

다음에 구매할 상품을 추천하기 위해

다음에 구매할 상품을 추천하기 위해
  • Self-Attentive Sequential Recommendation, ICDM 2018.
  • Mamba4Rec: Towards Efficient Sequential Recommendation with Selective State Space Models, arXiv 2024.
  • RecRec: Latent Interests Recursive Reasoning for Sequential Recommendation, RecSys 2026.

이 글에서는 sequential recommendation의 기본 backbone인 SASRec을 먼저 자세히 살펴보고, 그 뒤 SASRec의 두 가지 한계를 각각 공략한 Mamba4Rec과 RecRec을 정리해요. Mamba4Rec은 attention의 계산 복잡도를 건드리고, RecRec은 단일 forward pass로 예측을 끝내는 구조 자체를 건드려요.

Sequential recommendation이란?

사용자 $u$의 상호작용 기록이 시간 순으로 $\mathcal{S}^u = (S^u_1, S^u_2, \dots, S^u_{|\mathcal{S}^u|})$처럼 주어져요. 태스크는 다음에 상호작용할 아이템 $S^u_{|\mathcal{S}^u|+1}$을 맞추는 것이에요.

일반 추천과의 차이는 구매 순서를 중요한 정보로 활용한다는 점이에요. 사용자가 무엇을 좋아하는지(long-term preference)뿐 아니라, 방금 무엇을 했는지(short-term context)가 다음 행동을 결정한다고 보는 관점이에요. 타임스탬프 자체를 모델링하는 temporal recommendation과도 구분돼요. Sequential recommendation은 행동의 순서만 쓰고 시각은 쓰지 않아요.

MC와 RNN은 접근이 달라요

SASRec 이전의 접근은 크게 두 갈래였어요.

Markov Chain(MC) 계열은 다음 행동이 직전 $L$개 행동에만 의존한다고 가정해요. FPMC(Factorized Personalized Markov Chains)는 matrix factorization으로 장기 선호를, factorized first-order MC로 아이템 간 전이를 각각 잡아요. 가정이 강한 대신 파라미터가 적어서, 사용자당 행동 수가 적은 sparse 데이터에서 잘 작동해요.

RNN 계열은 모든 과거 행동을 hidden state 하나로 요약해요. GRU4Rec이 대표적이에요. 표현력은 높지만 학습에 많은 데이터가 필요해서 dense 데이터에서 강해요.

두 방식은 서로 반대편 끝에 있어요. MC는 참조 범위를 사전에 고정하고, RNN은 범위를 넓히는 대신 파라미터를 늘려요. SASRec의 문제 설정은 여기서 출발해요. RNN처럼 시퀀스 전체를 볼 수 있으면서, MC처럼 소수의 행동만으로 예측을 만드는 모델을 만들 수 있을까요.

SASRec은 self-attention을 활용해요

Self-Attentive Sequential Recommendation, ICDM 2018.

SASRec의 학습 과정

SASRec의 답은 self-attention이에요. 각 시점마다 이전 아이템들에 adaptive한 가중치를 부여하니, 참조 범위가 학습으로 결정돼요. Sparse 데이터에서는 최근 아이템에 가중치가 몰리고 dense 데이터에서는 멀리까지 퍼지는 동작을 하나의 구조가 모두 커버해요.

모델은 embedding layer, self-attention block 여러 개, prediction layer로 구성돼요.

Embedding layer는 가변 길이 시퀀스를 고정 길이 $n$으로 맞춰요. 길면 최근 $n$개만 남기고, 짧으면 왼쪽에 padding item을 채워요. Item embedding matrix $M \in \mathbb{R}^{|\mathcal{I}| \times d}$에서 임베딩을 가져오고, 학습 가능한 positional embedding $P \in \mathbb{R}^{n \times d}$를 더해요.

\[\hat{E} = \begin{bmatrix} M_{s_1} + P_1 \\ M_{s_2} + P_2 \\ \vdots \\ M_{s_n} + P_n \end{bmatrix}\]

Padding item의 임베딩은 zero vector로 고정해요. Transformer의 sinusoidal fixed positional embedding도 시도했지만 학습 가능한 쪽이 더 좋았다고 보고해요.

Self-attention block에 대해

Scaled dot-product attention은 다음과 같아요.

\[\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^\top}{\sqrt{d}}\right)V\]

Self-attention layer는 같은 입력 $\hat{E}$를 세 개의 projection으로 나눠 query, key, value로 써요.

\[S = \text{SA}(\hat{E}) = \text{Attention}(\hat{E}W^Q, \hat{E}W^K, \hat{E}W^V)\]

세 개의 projection matrix $W^Q, W^K, W^V \in \mathbb{R}^{d \times d}$를 따로 두는 이유는 비대칭 관계를 표현하기 위해서예요. $\langle$query $i$, key $j\rangle$와 $\langle$query $j$, key $i\rangle$의 값이 달라질 수 있어요.

Causality가 중요해요. $t+1$번째 아이템을 예측할 때 모델은 앞의 $t$개만 봐야 하는데, self-attention의 $t$번째 출력은 뒤쪽 아이템 정보까지 담아요. 그래서 $j > i$인 모든 $Q_i$와 $K_j$의 연결을 마스킹해요.

Point-wise feed-forward network는 비선형성을 넣어요. Self-attention은 값들의 가중합이라 여전히 선형 모델이에요.

\[F_i = \text{FFN}(S_i) = \text{ReLU}(S_i W^{(1)} + b^{(1)}) W^{(2)} + b^{(2)}\]

각 위치에 동일한 파라미터를 적용하고 위치 간 상호작용은 없어요. 정보가 뒤에서 앞으로 새는 것을 막기 위한 설계예요.

블록을 쌓을 때는 다음 형태를 사용해요.

\[g(x) = x + \text{Dropout}(g(\text{LayerNorm}(x)))\]

Residual connection이 특히 중요해요. 블록을 여러 개 통과하면 마지막 아이템의 임베딩이 이전 아이템들과 섞여 버리는데, 다음 아이템 예측에서는 직전 아이템이 가장 중요한 신호예요. Residual connection이 이 정보를 마지막 층까지 그대로 전달해요.

예측과 학습은 하나의 embedding table

$b$개 블록을 통과한 뒤 $t$시점의 표현 $F^{(b)}_t$로 아이템 $i$의 점수를 계산해요.

\[r_{i,t} = F^{(b)}_t M_i^\top\]

일반적인 형태는 예측 전용 item embedding matrix $N \in \mathbb{R}^{|\mathcal{I}| \times d}$를 따로 두고 $r_{i,t} = F^{(b)}_t N_i^\top$로 계산하는 것이에요. 입력용 $M$과 출력용 $N$, 즉 아이템 하나가 임베딩 두 개를 갖는 구조예요. FPMC(Factorized Personalized Markov Chains) 같은 기존 방법이 이렇게 하는 이유는 비대칭 전이 때문이에요. 아이템 $j$가 $i$ 다음에 자주 오지만 그 반대는 아닌 관계를 표현하려면, 임베딩이 하나일 때 $M_i^\top M_j = M_j^\top M_i$가 되어 방향을 구분할 수 없어요.

SASRec은 $M$ 하나만 쓰는 shared item embedding을 택했어요. FFN이라는 비선형 변환을 거치므로 $\text{FFN}(M_i)M_j^\top \neq \text{FFN}(M_j)M_i^\top$가 성립해, 임베딩이 하나여도 비대칭성이 확보돼요. Ablation에서 unshared 구조($M$과 $N$을 따로 학습)는 네 데이터셋 모두에서 10% 이상 떨어져요. 파라미터가 두 배가 되면서 overfitting이 생긴 것으로 해석해요.

Explicit user embedding은 넣지 않아요. $F^{(b)}_t$가 이미 사용자의 모든 행동을 반영하기 때문에, $U_u$를 더해도 성능이 오르지 않았어요.

학습은 binary cross entropy를 쓰고, 각 시점마다 negative item 하나를 랜덤 샘플링해요.

\[-\sum_{\mathcal{S}^u \in \mathcal{S}} \sum_{t=1}^{n} \left[\log(\sigma(r_{o_t, t})) + \sum_{j \notin \mathcal{S}^u} \log(1 - \sigma(r_{j,t}))\right]\]

여기서 $o_t$는 $t$시점의 정답이고, padding 위치의 항은 무시해요.

복잡도는 space가 $O(|\mathcal{I}|d + nd + d^2)$, time이 $O(n^2 d + n d^2)$예요. $O(n^2 d)$가 지배적이지만 self-attention은 시점 간 의존성이 없어 GPU에서 병렬화돼요. RNN은 $t$시점 계산이 $t-1$의 결과를 기다려야 해서 sequential operation이 $O(n)$이에요. 이 차이가 SASRec이 GRU4Rec+보다 epoch당 18배 빠른 이유예요.

SASRec은 기존 모델들을 특수한 경우에요

논문은 SASRec이 고전 모델의 일반화라는 점을 보여요.

Self-attention block을 0개로 두고 unshared item embedding을 쓰고 positional embedding을 제거하면 FMC(Factorized Markov Chains)가 돼요. 여기에 explicit user embedding을 concatenate하면 FPMC가 돼요.

Self-attention layer 하나만 두고 FFN을 빼고 attention weight를 $1/|\mathcal{S}^u|$로 균등하게 고정하면 FISM(Factored Item Similarity Models)이 돼요. 즉 SASRec은 adaptive하고 hierarchical한 sequential item similarity model로 볼 수 있어요.

Maximum path length 관점도 짚어볼 만해요. RNN은 입력 노드에서 관련 출력 노드까지 거리가 $O(n)$인데 self-attention은 $O(1)$이에요. 장기 의존성 학습에 유리한 성질이에요.

SASRec의 attention은 데이터 밀도에 적응한다

SASRec 성능 비교

실험은 Amazon Beauty, Amazon Games, Steam, MovieLens-1M 네 데이터셋에서 진행했어요. 사용자당 negative item 100개를 샘플링해 정답과 함께 랭킹하는 sampled evaluation을 쓰고 Hit@10과 NDCG@10을 보고해요. 최고 baseline 대비 평균 Hit Rate 6.9%, NDCG 9.6% 개선을 얻었어요.

SASRec ablation

Ablation에서 나온 결론을 정리하면 다음과 같아요. Unshared item embedding, residual connection 제거, dropout 제거는 모두 큰 폭의 하락을 일으켜요. Block 수는 2개가 기본이고 3개로 늘려도 비슷해요. Multi-head attention은 오히려 조금 나빴는데, 추천에서 쓰는 $d$가 Transformer의 $d=512$보다 훨씬 작아 subspace로 쪼갤 여유가 없기 때문으로 해석해요. Positional embedding 제거는 가장 sparse한 Beauty에서만 이득이었어요.

position에 대한 attention weight

Attention weight를 시각화한 결과가 이 논문의 핵심 관찰이에요. Sparse한 Beauty에서는 최근 위치에 가중치가 몰리고, dense한 ML-1M에서는 먼 위치까지 퍼져요. Positional embedding을 빼면 가중치가 위치와 무관하게 균등해져요. 상위 layer일수록 최근 위치에 집중하는데, 첫 블록에서 이미 모든 과거를 봤기 때문이에요. 아이템 간 attention을 카테고리별로 묶어 보면 block diagonal에 가까운 형태가 나와요. 카테고리 정보를 주지 않았는데도 유사한 아이템끼리 큰 가중치를 주고받는다는 뜻이에요.

SASRec에서 Mamba4Rec으로

SASRec 이후 Transformer 계열이 sequential recommendation의 기본 backbone이 됐어요. BERT4Rec은 bidirectional self-attention과 masked item prediction으로 확장했고, 여러 변형이 이어졌어요.

남는 문제는 $O(n^2)$이에요. 학습에서는 병렬화로 가릴 수 있지만 서빙에서는 그대로 드러나요. 사용자 행동 시퀀스가 길어지거나 아이템 수가 많아지면 추론 지연과 메모리가 함께 늘어나요. 성능과 효율 사이의 이 tradeoff가 Mamba4Rec의 출발점이에요.

State space model은 선형 시간으로 시퀀스를 처리한다

Mamba4Rec: Towards Efficient Sequential Recommendation with Selective State Space Models, 2024.

State space model(SSM)은 선형 미분방정식으로 시퀀스를 모델링해요. 입력 $x(t) \in \mathbb{R}^D$를 latent state $h(t) \in \mathbb{R}^N$을 거쳐 출력 $y(t)$로 보내요.

\[h'(t) = \boldsymbol{A}h(t) + \boldsymbol{B}x(t), \quad y(t) = \boldsymbol{C}h(t)\]

이산 시퀀스에 적용하려면 step size $\Delta$로 discretize해야 해요.

\[h_t = \overline{\boldsymbol{A}}h_{t-1} + \overline{\boldsymbol{B}}x_t, \quad y_t = \boldsymbol{C}h_t\] \[\overline{\boldsymbol{A}} = \exp(\Delta\boldsymbol{A}), \quad \overline{\boldsymbol{B}} = (\Delta\boldsymbol{A})^{-1}(\exp(\Delta\boldsymbol{A}) - \boldsymbol{I}) \cdot \Delta\boldsymbol{B}\]

이 형태는 linear recurrence로 계산되므로 시퀀스 길이에 선형이에요. S4는 여기에 HiPPO 초기화로 state matrix $\boldsymbol{A}$에 구조를 부여해 장기 의존성을 개선했어요.

Mamba는 두 가지를 더해요. 하나는 selection mechanism으로, $\boldsymbol{B}$, $\boldsymbol{C}$, $\Delta$를 입력의 함수로 만들어요. 기존 SSM은 파라미터가 입력과 무관해서 어떤 정보를 기억하고 버릴지 데이터에 따라 조절하지 못했어요. 다른 하나는 hardware-aware parallel algorithm으로, 파라미터가 입력에 의존해 convolution으로 접을 수 없게 된 계산을 GPU 메모리 계층을 고려한 scan으로 처리해요.

Mamba에 대한 자세한 내용은 “Language Model은 잠을 자야 할까“를 참고해 주세요.

Mamba4Rec은 Mamba block 위에 layer를 설계한다

Mamba4Rec 구조

Mamba4Rec의 embedding layer는 item ID를 $\boldsymbol{E} \in \mathbb{R}^{|\mathcal{V}| \times D}$로 매핑한 뒤 dropout과 layer normalization을 적용해요.

\[H = \text{LayerNorm}(\text{Dropout}(\mathcal{S}^u \boldsymbol{E})) \in \mathbb{R}^{n_u \times D}\]

Mamba block은 입력 $H_i \in \mathbb{R}^{B \times L \times D}$에 대해 다음 순서로 동작해요. 먼저 linear projection으로 $H_x$와 $H_z$를 만들고(hidden 차원을 $E$배 확장), $H_x$에 1D convolution과 SiLU를 적용해 $H’_x$를 얻어요. $\boldsymbol{B}$, $\boldsymbol{C}$, $\Delta$를 $H’_x$의 linear projection으로 계산하고 discretize한 뒤 selective SSM을 통과시켜 $H_y$를 얻어요. 마지막으로 $H_z$의 gating을 곱하고 projection해요.

\[H'_y = H_y \otimes \text{SiLU}(H_z), \quad H_o = \text{Linear}(H'_y)\]

하이퍼파라미터는 SSM state expansion factor $N$, convolution kernel size $K$, block expansion factor $E$ 세 개예요. 논문 기본값은 $N = 32$, $K = 4$, $E = 2$예요.

이 논문의 실제 기여는 Mamba block을 그대로 쌓지 않고 Mamba layer를 정의한 데 있어요. Mamba layer는 Mamba block 뒤에 position-wise feed-forward network를 붙인 단위예요.

\[\text{PFFN}(H) = \text{GELU}(H\boldsymbol{W}^{(1)} + \boldsymbol{b}^{(1)})\boldsymbol{W}^{(2)} + \boldsymbol{b}^{(2)}\]

$\boldsymbol{W}^{(1)} \in \mathbb{R}^{D \times 4D}$, $\boldsymbol{W}^{(2)} \in \mathbb{R}^{4D \times D}$이고, 각 Mamba block과 FFN 뒤에 dropout과 layer normalization을 넣어요.

Layer를 하나만 쓸 때는 residual connection 없이 layer normalization만 적용하고, 쌓을 때는 residual connection이 필수가 돼요. 기본 설정은 single layer예요.

예측은 마지막 위치의 표현 $h$로 전체 아이템에 대한 분포를 만들어요.

\[\hat{y} = \text{Softmax}(h\boldsymbol{E}^\top) \in \mathbb{R}^{|\mathcal{V}|}\]

SASRec의 negative sampling BCE와 달리 full softmax cross entropy를 쓰는 점이 다른 부분이에요.

Mamba4Rec은 성능과 효율을 동시에 가져간다

Mamba4Rec 성능 비교

ML-1M, Amazon Beauty, Amazon Video-Games에서 실험했어요. NDCG@10과 MRR@10은 세 데이터셋 모두에서 Mamba4Rec이 가장 높아요. HR@10만 보면 Beauty와 Video-Games에서 SASRec이 앞서요. 랭킹 품질은 개선되지만 상위 10개 안에 정답을 넣는 비율 자체는 sparse 데이터에서 SASRec과 비슷하다는 의미로 읽을 수 있어요.

Mamba4Rec 효율 비교

효율 쪽 차이는 훨씬 커요. ML-1M에서 GPU 메모리는 SASRec 14.98GB 대비 5.01GB, epoch당 학습 시간은 131.24초 대비 56.13초, batch당 추론 시간은 0.27초 대비 0.11초예요. 수렴도 빨라서 best validation 성능에 epoch 50 근처에서 도달해요.

Mamba4Rec ablation

Ablation에서 눈여겨볼 결과는 positional embedding이에요. 학습 가능한 positional embedding을 추가하면 성능이 오히려 떨어져요. SSM은 recurrent 구조라 순서 정보를 이미 내재하고 있어서, positional embedding이 중복 신호가 돼요. Self-attention에서 positional embedding이 필수였던 것과 대비되는 지점이에요.

PFFN은 시퀀스가 긴 ML-1M에서 특히 효과가 커요. Mamba block만 남기면 계산은 빨라지지만 성능이 떨어져요. Layer 2개를 쌓으면 ML-1M에서 성능이 조금 오르지만 효율을 잃어요.

한 번의 forward pass는 예측을 되돌릴 수 없다

SASRec과 Mamba4Rec은 backbone이 다르지만 예측 방식은 같아요. 시퀀스를 한 번 통과시켜 얻은 마지막 위치의 $d$차원 벡터 하나로 랭킹을 만들어요. 사용자의 잠재 관심사를 다시 들여다보고 수정할 기회가 없어요.

LLM에서는 chain-of-thought와 latent reasoning이 이 문제를 다뤄요. 입력과 최종 답 사이에 연산을 더 배분하면, 한 번에 확정했을 오류를 중간 단계에서 고칠 수 있어요. 이 아이디어를 sequential recommendation에 가져온 시도가 ReaRec과 LARES예요.

ReaRec은 backbone을 여러 번 통과시키면서 마지막 hidden state를 reasoning position embedding과 함께 입력 시퀀스에 append해요. Reasoning이 행동 기록과 같은 공간을 쓰고, reasoning token이 쌓이면서 step당 attention 비용이 늘어요. Reasoning position embedding을 고정 개수만 할당하므로 추론 시 학습보다 적은 step은 쓸 수 있어도 더 많은 step은 못 써요.

LARES는 공유 core block을 전체 $L$개 hidden state에 $k$번 반복 적용해요. 학습 중 $k$를 랜덤하게 뽑아 추론 시 depth를 바꿀 수 있게 만들지만, self-supervised pre-training과 GRPO 기반 RL post-training까지 3단계 파이프라인이 필요해요.

두 방법 모두 refine하는 상태와 예측하는 상태가 같아요. Reasoning을 얼마나 하든 최종 예측은 $d$차원 벡터 하나로 수렴해요.

RecRec은 reasoning 공간과 prediction 공간을 분리한다

RecRec: Latent Interests Recursive Reasoning for Sequential Recommendation, RecSys 2026.

reasoning 공간과 prediction 공간 비교

RecRec은 세 공간을 명시적으로 나눠요. 사용자 행동 기록(backbone의 hidden state $H$), 중간 reasoning 상태 $S$, 예측에 쓰이는 latent interest $M$이에요. Reasoning은 $S$에서만 일어나고 $S$는 직접 디코딩되지 않아요. 예측은 $R$개의 latent interest에서 나오므로 단일 $d$차원 병목이 사라져요.

이 설계는 Tiny Recursion Model(TRM)에서 왔어요. TRM은 공유 가중치 블록 하나로 두 상태를 갱신해요. Answer state $y$는 출력으로 매핑되고 scratchpad state $z$는 중간 계산만 담아요. RecRec의 $M$이 $y$에, $S$가 $z$에 대응해요.

TRM에 대한 자세한 설명은 “Less is more, Reasoning Model의 등장“을 참고해주세요.

RecRec 학습 파이프라인

RecRec은 backbone에 독립적인 framework예요. SASRec이나 BERT4Rec을 그대로 backbone으로 쓰고 그 위에 Context Compressor와 Recursive Reasoner를 올려요.

Context Compressor는 hidden state를 latent interest로 압축한다

Backbone의 마지막 layer hidden state $H \in \mathbb{R}^{L \times d}$를 $R$개의 latent interest $M_0 \in \mathbb{R}^{R \times d}$로 줄여요. $R$개의 learned query가 $H$에 cross-attention하는 Perceiver 계열 설계예요.

입력을 한 번 정규화한 $\bar{H} = \text{LN}_{\text{input}}(H)$를 모든 layer에서 공유하고, 각 layer는 pre-norm residual 세 단계를 적용해요.

\[Z \leftarrow Z + \text{CrossAttn}(\text{LN}_{\text{crossattn}}(Z), \bar{H}, \bar{H})\] \[Z \leftarrow Z + \text{SelfAttn}(\text{LN}_{\text{selfattn}}(Z))\] \[M_0 = Z + \text{FFN}(\text{LN}_{\text{ffn}}(Z))\]

$R$개의 latent interest는 순서 없는 집합이므로 positional encoding도, causal mask도 쓰지 않아요.

문제는 collapse예요. $R$개 query가 모두 같은 $H$를 보므로 규제가 없으면 거의 동일한 벡터로 수렴해요. 실제로 interest 간 cosine similarity가 0.8을 넘어요. Interest Diversity Regularizer(IDR)는 off-diagonal cosine similarity의 평균을 최소화해요.

\[\mathcal{L}_{\text{IDR}} = \frac{1}{R(R-1)}\sum_{r \neq r'} \hat{m}_r^\top \hat{m}_{r'}\]

$\hat{m}_r = m_r / |m_r|$은 L2 정규화된 interest예요. IDR을 켜면 cosine similarity가 데이터셋에 따라 0.14에서 0.75 범위로 내려가요.

Recursive Reasoner는 두 상태를 번갈아 갱신한다

Recursive Reasoner 구조

Reasoner는 Transformer block 하나예요. Pre-norm layer normalization, bias 없는 multi-head attention, SwiGLU feed-forward network로 구성돼요. Query와 key-value는 각각 다른 LayerNorm을 거쳐요.

\[X' = X + \text{Attn}(\text{LN}_q(X), [\text{LN}_q(X); \text{LN}_{kv}(C)])\] \[\text{Reasoner}(X, C) = X' + \text{FFN}(\text{LN}_{\text{ffn}}(X'))\]

Attention output projection과 FFN 출력 layer를 zero-init해서 Reasoner가 identity mapping으로 시작해요. Context Compressor가 만든 표현을 망가뜨리지 않고 조금씩 수정하도록 학습을 안정화하는 장치예요.

Reasoning step 하나는 두 단계로 나뉘어요. 먼저 $S$가 $n$번의 inner pass 동안 backbone hidden state $H$와 현재 $M$을 함께 참조해요.

\[S \leftarrow \text{Reasoner}(S, [H; M]) \quad (n\text{ times})\]

이 동안 $M$은 고정이에요. 현재 관심사를 기준으로 사용자 기록을 다시 읽는 과정이에요. 그다음 $M$이 정제된 $S$를 읽어 후보 갱신 $\hat{M}$을 만들고, GRU gate로 이전 값과 섞어요.

\[\hat{M} = \text{Reasoner}(M, S), \quad M \leftarrow \text{GRU}(\hat{M}, M_{\text{prev}})\]

$\hat{M}$으로 덮어쓰면 step마다 변화 폭이 커져요. Slot Attention에서 가져온 GRU gate가 step당 변화량을 학습으로 조절해요. Gate 입력은 layer normalization을 거치므로 표현 크기에 따라 갱신 비율이 흔들리지 않아요.

두 상태를 나누는 이유는 스케일에 있어요. $M$은 item embedding과 내적해 점수를 만들어야 하므로 embedding과 호환되는 크기를 유지해야 해요. $S$는 예측에 쓰이지 않으니 자유롭게 변할 수 있어요.

$S$의 출발값 $S_0$는 빈 scratchpad에 해당해요. 모델을 만들 때 truncated normal에서 한 번 뽑아 두는 $R \times d$ 크기의 고정 텐서이고, 사용자나 배치가 달라져도 같은 값을 써요. 학습되는 파라미터가 아니라 상수예요. 첫 supervision round의 $S$가 여기서 시작하고, 이후 round는 앞 round에서 detach된 $S$를 물려받아요.

학습 가능하게 두지 않는 이유는 gradient가 닿지 않기 때문이에요. 뒤에서 볼 deep supervision에서 각 round의 앞 $T-1$ step은 gradient 없이 도는데, $S_0$가 관여하는 구간이 정확히 여기예요. 학습 가능한 파라미터로 선언해도 갱신 신호를 한 번도 받지 못해요.

$S_0$의 shape가 $M$과 같은 $R \times d$인 것도 설계상 선택이에요. Reasoner block 하나가 두 상태를 모두 처리하려면 query 차원이 맞아야 해요.

예측은 $R$개 interest 각각의 점수를 log-mean-exp로 모아요.

\[s_r(v) = \frac{m_r^\top e_v}{\tau}, \quad s(v) = \log\left(\frac{1}{R}\sum_{r=1}^{R}\exp(s_r(v))\right)\]

Soft maximum이라 가장 관련 있는 interest가 예측을 주도하면서도, gradient는 $R$개 전체로 흘러요.

Deep supervision이 추론 시 depth를 자유롭게 만든다

학습은 두 단계로 나뉘어요.

Stage 1에서는 backbone과 Context Compressor를 함께 학습해요. Reasoner는 쓰지 않고 $M_0$에서 바로 예측해요. Loss는 cross entropy에 IDR을 더한 형태예요.

\[\mathcal{L}_1 = -\log \hat{y}_{v^+}(M_0) + \lambda_{\text{IDR}} \cdot \mathcal{L}_{\text{IDR}}\]

Stage 2에서는 backbone을 freeze하고 Context Compressor도 freeze하되 dropout은 켜 둬요. Compressor의 출력이 매번 조금씩 달라져 Reasoner에 대한 regularizer로 작동해요. 학습되는 것은 Reasoner뿐이에요.

핵심은 deep supervision이에요. 전체 reasoning이 끝난 뒤 loss를 한 번 계산하는 대신, $K$번의 supervision round마다 loss를 계산하고 round 사이에서 $S$와 $M$을 detach해요.

\[\mathcal{L}_2^{(k)} = -\log \hat{y}_{v^+}(M^{(k)}) + \lambda_{\text{IDR}} \cdot \mathcal{L}_{\text{IDR}}(M^{(k)})\]

각 round는 $T$개의 reasoning step을 실행하고, 그중 마지막 step만 backpropagation을 거쳐요(1-step BPTT). 앞의 $T-1$ step은 gradient 없이 돌면서 좋은 시작점을 만들어요. 학습 시 총 depth는 $N = K \times T$예요.

Detach가 만드는 효과가 이 설계의 요점이에요. 각 round는 이전 round와 gradient로 연결되지 않으므로 “주어진 상태를 더 좋게 만든다”는 동일한 목표를 독립적으로 학습해요. 논문 기본 설정은 $T = 3$, $K = 3$, $n = 3$이라 학습 depth는 $N = 9$예요.

여기서 “추론 시 학습보다 많은 step을 써도 된다”는 주장이 어떻게 성립하는지 짚어볼 만해요. 추론에는 supervision이 없는데 상태가 더 좋아질 이유가 없어 보이니까요.

답은 Reasoner가 학습한 것이 무엇인가에 있어요. Round $k$가 받는 입력의 품질이 round마다 달라요. Round 1은 Compressor가 막 뽑은 $M_0$를, round 2는 이미 한 번 개선된 $M^{(1)}$을, round 3은 $M^{(2)}$를 받아요. 그런데 세 round의 목적함수가 전부 같아요. 가중치도 공유해요. 그래서 Reasoner는 “9-step 프로그램의 $k$번째 단계”가 아니라 품질이 제각각인 상태를 받아 한 단계 개선하는 연산자 $f$를 학습해요.

연산자를 배웠으니 추론에서 $f$를 몇 번 적용할지는 자유예요. $f^{10}(M_0)$은 학습에서 본 적 없는 조합이지만, 10번째 호출이 받는 입력은 9번째 출력이고, 그 품질은 학습 중 본 범위 안에 있어요. 새 지도가 필요한 게 아니라 이미 배운 규칙을 한 번 더 쓰는 것이에요. Gradient descent에서 step rule을 정해 두면 몇 번을 밟든 되는 것과 비슷해요.

Detach가 없으면 이게 깨져요. Round들이 하나의 gradient chain으로 이어지면 각 round가 서로의 오차를 보정하도록 co-adapt해서, 특정 위치에서만 잘 동작하는 함수가 돼요.

물론 무한정 좋아지지는 않아요. $f$가 개선 연산자라는 보장은 loss 어디에도 없고, 언제 멈출지 판단하는 halting mechanism도 없어요. 실제로 MicroLens에서는 $N \approx 4$ 이후 성능이 떨어져요. 논문의 주장은 “계속 좋아진다”가 아니라 “depth를 늘려도 무너지지 않고, 네 데이터셋 중 셋에서 소폭 더 오른다” 정도로 읽는 게 정확해요.

RecRec의 어떤 요소가 성능을 낼까

RecRec 성능 비교

S-Shop, V-Shop, MicroLens, Steam 네 데이터셋에서 실험했어요. 평가는 sampled negative가 아닌 full ranking이고 NDCG@$K$, Recall@$K$를 $K = 10, 20$으로 보고해요. SASRec 논문의 sampled evaluation과 프로토콜이 다르므로 절대 수치를 직접 비교하면 안 돼요.

학습 depth $N = 9$로 고정한 결과에서 RecRec이 네 데이터셋 모두 최고예요. SASRec backbone 기준 NDCG@10은 최고 reasoning baseline 대비 Steam에서 14.8%, MicroLens에서 9.3%, V-Shop에서 8.2%, S-Shop에서 4.3% 올랐어요. RecRec(S)가 RecRec(B)보다 대체로 높은데, BERT4Rec의 양방향 문맥을 생각하면 예상과 반대되는 결과예요. NDCG 개선폭이 Recall 개선폭 이상이라는 점도 관찰돼요. Recall set을 넓히는 게 아니라 정답을 더 위로 올리는 방향으로 작동한다는 의미예요.

inference 시 reasoning depth에 따른 성능

추론 시 $N$을 0에서 16까지 바꾼 실험에서 두 패턴이 보여요. 첫째, $N = 0$에서 $N = 1$로 갈 때 가장 큰 상승이 일어나요. S-Shop에서 0.0966에서 0.103, Steam에서 0.0496에서 0.058이에요. 둘째, $N$을 9 이상으로 늘려도 S-Shop, V-Shop, Steam에서 성능이 유지되거나 조금 더 올라요(최적 $N$은 각각 15, 12, 16). MicroLens는 $N \approx 4$에서 포화한 뒤 떨어져요.

RecRec ablation

Ablation 결과는 이래요. Reasoner를 빼면 Stage 1 수준으로 내려가요. IDR을 빼면 비슷한 수준까지 떨어지는데, interest들이 거의 같은 방향으로 collapse해 여러 개를 두는 의미가 사라지기 때문이에요. $S$를 $S_0$에 고정하면($n = 0$) 중간 정도의 하락이 생겨요. Dual-state 설계가 $M$만 진화하는 구조로 퇴화하는 셈이에요. GRU gate를 제거하고 덮어쓰기로 바꾸면 하락 폭이 그보다 작아요. S-Shop에서는 gate를 뺐을 때 Recall@20이 오히려 조금 높아요(0.2483 vs 0.2432). Gate가 recall coverage를 약간 내주고 랭킹을 날카롭게 만든다고 해석해요.

$R$ sweep에서는 $R = 1$이 네 데이터셋 모두에서 가장 나빠요. 예측 상태가 벡터 하나 이상을 들고 있어야 한다는 가장 직접적인 근거예요. $R \geq 2$부터는 최적값이 데이터셋마다 달라요(V-Shop과 MicroLens는 4, Steam은 8, S-Shop은 16). 기본값 8은 데이터셋별 최적 대비 5% 이내예요.

세 모델을 나란히 두면

  SASRec Mamba4Rec RecRec
시퀀스 연산 Self-attention Selective SSM Backbone에 위임
시간 복잡도 $O(n^2 d + nd^2)$ 시퀀스 길이에 선형 Backbone + reasoning step
Positional embedding 필요(학습 가능) 불필요(오히려 하락) Backbone 설정을 따름
예측 상태 $d$차원 벡터 1개 $d$차원 벡터 1개 $R \times d$ latent interest
학습 목적함수 Sampled negative BCE Full softmax CE Full softmax CE + IDR
학습 단계 1단계 1단계 2단계(backbone freeze)
추론 연산량 고정 고정 조절 가능

SASRec은 self-attention으로 참조 범위를 데이터에 맡기면서 MC와 RNN의 절충점을 찾았고, 지금도 대부분의 후속 연구가 backbone으로 쓰는 모델이에요. Mamba4Rec은 selective SSM으로 그 참조 방식을 선형 시간으로 바꿔 효율 축에서 개선했어요. RecRec은 backbone을 그대로 두고 예측 직전에 연산을 더 배분하는 축을 열었어요.

세 논문을 순서대로 읽으면 개선의 축이 세 번 바뀌는 게 보여요. 참조 범위를 어떻게 정할 것인가, 그 계산을 얼마나 싸게 할 것인가, 그리고 예측 상태를 몇 번 고쳐 쓸 것인가예요. RecRec의 결론은 마지막 축이 backbone 개선과 직교한다는 것이에요. Reasoning state를 prediction state에서 떼어내고, 예측을 벡터 하나가 아닌 집합에서 만드는 두 선택 모두 backbone에 무관하게 적용돼요.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.