9 minute read

Meta info.
  • Authors: Han Luo, Zhan Zhuang, Xu He, Jujia Zhao, Yu Li, Suqin Yuan, Dong Li, Lei Feng
  • Affiliation: Southeast University, The University of Sydney
  • Paper: https://arxiv.org/abs/2610.13277
  • Published: October 9, 2026 (arXiv preprint)

Slide 1

TL; DR

memory retrieval의 손실은 encoder가 아니라 vector 하나로 퉁치는 scoring 단계에서 발생하며, 이미 계산된 token state를 memory끼리 경쟁시키기만 해도 학습 없이 성능 이득 (검색되지 않은 매칭을 어떻게 채우느냐가 관건이다.)

Local evidence from existing token representations (Fig 1) Sparse token matching for memory retrieval (Fig 2) Retrieval performance (Tab 1) Cross-backbone retrieval (Tab 2) Downstream question answering (Tab 3) Component analysis (Tab 4) Sensitivity analyses (Fig 3, 4, 5) Retrieval quality, storage, and latency (Tab 5)

Background

  • memory-augmented assistant: 과거 대화와 저장 문서에서 evidence를 꺼내 질의에 답함 (Maharana et al., 2024; Wu et al., 2025)
    • 답에 필요한 정보는 memory의 일부에만 있고, query마다 필요한 부분이 다름 (e.g. Fig 1)
      • “지난주 오래된 노트에서 무엇을 발견했나”→긴 발화 안의 한 문장(“Last week, I found these old notebooks …”)만 있으면 됨
  • Single-vector retrieval: query와 memory를 각각 embedding 하나로 압축하고 cosine similarity로 ranking (Karpukhin et al., 2020; Zhang et al., 2025)
    • encoder 내부에서는 token마다 contextual state를 계산하지만, 마지막에 pooling해서 vector 하나만 남기고 나머지는 버림
    • $s_{\text{pool}}(q, m) = z_q^\top z_m$: memory 전체를 한 점으로 비교하므로, 단위 기준 전체의 일부만 맞는 memory는 순위가 밀릴 수 밖에
    • memory당 vector 하나라 index가 작고 검색이 빠르나 표현력의 이론적 한계 보고 (Weller et al., 2026)
  • Late interaction 계열: token state를 버리지 않고 query token과 memory token을 직접 비교
    • ColBERT, ColBERTv2 (Khattab & Zaharia, 2020; Santhanam et al., 2022): MaxSim으로 score 계산

      \[s_{\text{MaxSim}}(q, m) = \frac{1}{n_q} \sum_i \max_j h_{q,i}^\top h_{m,j}\]
      • query token마다 memory 안에서 가장 비슷한 token 하나를 찾고, 그 similarity를 query token에 대해 평균
    • memory마다 그 안의 모든 token과 비교하므로 비교량과 index 크기가 token 수에 비례
    • ColBERT는 이를 위해 encoder를 별도 학습; SMART (Zhang et al., 2026a)는 기존 single-vector encoder의 frozen hidden state에 MaxSim을 붙이고 pooled score와 합침
  • XTR (Lee et al., 2023): memory별로 전부 비교하지 않고 token부터 검색
    • query token마다 모든 memory의 token을 한데 모은 pool에서 top-$k$ token만 검색하고, 검색된 token으로만 memory score를 계산
    • 검색되지 않은 token의 similarity는 알 수 없으므로 top-$k$ 중 가장 낮은 값으로 추정 (missing-similarity estimation)
    • 본 논문의 sparse matching이 이 방식을 frozen encoder 위로 가져옴
  • 그 밖의 방향: final embedding을 개선하거나 그 위에 가벼운 mapping을 얹는 접근

Problem States

  • encoder는 token 단위 state를 이미 계산하는데, single-vector scoring은 이를 버린다.
    • frozen state 위의 late interaction(SMART)도 memory마다 따로 비교할 뿐,
      XTR식으로 memory끼리 token 단위로 경쟁시키고 whole-memory score와 합친 시도는 없었다.
  • 같은 encoder 안에 local evidence를 잡을 정보가 있는데 scoring에서 쓰지 않음
  • token 단위로 매칭하려면 기존 late interaction은 encoder를 재학습 or memory마다 모든 token 비교해야
    • 반면 local 매칭만으로는 memory 전체의 주제 관련성을 놓칠 수도
  • supervision으로 더 맞추고 싶어도 encoder나 memory 쪽 표현을 바꾸면 전체 memory 재encoding해야
  1. [저장] 버려지던 token별 벡터를 memory ID와 함께 남긴다
  2. [매칭] query token마다 전체 memory에서 비슷한 token을 찾아, 그 token이 속한 memory에 score를 준다
  3. [결합] 이 token score를 기존 vector score와 섞어 최종 순위를 매긴다
  4. [적응] (선택) memory는 그대로 두고 query 쪽 token 벡터만 학습해 매칭을 다듬는다

Suggestions

  • Fig 2: “When did Alice move to Paris?”
    • memory 6 (Alice): “I signed the lease in March. I moved to Paris in May. My job started in June.” → 정답
    • memory 13 (Bob): “Our office moved to Paris in June. Alice visited in July.”
    • memory 전체를 vector 하나로 보면 둘 다 Alice, Paris, 이사, 월이 섞인 이야기라 구분이 어려움
    • token 단위로 보면 query의 “move”가 memory 6의 “moved to Paris in May”와 직접 맞음 → 이 신호를 score로 쓰자
  • memory 전체를 vector 하나로 비교하는 기존 scoring 방식에 “query의 token이 그 memory 안의 token과 직접 맞는가”를 더하는 방식
    • 새로 학습 없이: token별 벡터는 embedding 모델이 vector 하나를 만들기 직전에 이미 계산해 둔 것을 활용하며
    • 최종 score는 두 score의 가중 평균 (아래 단계는 결국 이 식의 둘째 항 $s_{\text{sparse}}$을 어떻게 계산하는지)

      \[s_{\text{fused}}(q, m) = \alpha\ \hat s_{\text{pool}}(q, m) + (1 - \alpha)\ \hat s_{\text{sparse}}(q, m)\]
      • $s_{\text{pool}}$: 기존 scoring (query vector와 memory vector 하나끼리 비교)
      • $s_{\text{sparse}}$: 새로 더하는 scoring (query token과 memory token끼리 비교)

[저장] token 벡터를 memory ID와 함께 저장

  • memory를 embedding 모델(frozen encoder)에 한 번 넣을 때, 예의 1개의 vector 외에 token별 벡터도 함께 저장
    • $z_m$: 평소 쓰던 memory vector (pooling 결과)
    • $H_m = [h_{m,1}, \dots, h_{m,n_m}]$: 마지막 layer의 token별 벡터 (padding, special token 제외)
    • (query도 똑같이 $z_q$와 $H_q$를 구하도록)
  • token 벡터마다 출처 memory ID 부여 : 다음 단계에서 token 단위로 검색시 최종적 순위의 대상은 token이 아니라 memory이기에
    • e.g. 검색된 “moved” 벡터에 “memory 6”이라는 단서가 있어야 memory 6에 가점 가능
  • memory는 query와 무관하게 1 회만 저장하면 되므로, 대가는 저장량이 token 수만큼 늘어난다는 것 정도

[매칭] query token마다 전체 memory에서 비슷한 token 찾기 (Global Sparse Token Matching)

  • query token 하나씩, 모든 후보 memory의 token을 한데 모은 pool에서 가장 비슷한 token $k = 64$개를 찾음 (이 집합이 $R_i$)
    • 걸린 token의 memory ID를 보고, 그 memory에 similarity만큼 score를 줌; 한 memory에서 여러 token이 걸리면 가장 높은 것 하나만 씀
    • e.g. query token “move”로 검색하면 memory 6의 “moved”, memory 13의 “moved” 등이 함께 걸림
  • k개 안에 token이 하나도 안 걸린 memory?
    • 0으로 두면 “아깝게 65등 한 memory”와 “전혀 관련 없는 memory”가 같아지는 문제
    • 그래서 64등의 similarity $t_i$를 바닥값(floor)로 filling: k 안에 들지 못한 memory는 최소한 k등보다는 덜 비슷할 것이므로 (XTR의 missing-similarity estimation)
    • $t_i = \big[\min_{h \in R_i} h_{q,i}^\top h\big]_+$ (음수면 0)
  • memory score = query token마다 “그 memory가 받은 score와 floor 중 큰 값”을 구해 평균
    • floor는 모든 memory에 똑같이 부여되므로, memory 사이의 순위를 가르는 건 floor를 넘어선 score들 뿐
    \[s_{\text{sparse}}(q, m) = \frac{1}{n_q} \sum_i \max\Big(t_i,\ \max_{j:\ h_{m,j} \in R_i} h_{q,i}^\top h_{m,j}\Big)\]
  • 왜 memory마다 MaxSim(하나씩 비교)하지 않고 전체에서 찾나
    • MaxSim: memory마다 “그 안에서 query token과 가장 비슷한 token”을 고름 → memory 내부 경쟁
    • 이 방법: query token 하나가 전체 memory를 상대로 k개만 고름 → memory 간 경쟁
    • (추측) token이 흔할수록 floor가 높아져 영향력이 사라짐 → IDF와 비슷한 효과
      • 흔한 token(“Alice”): k개 전부가 여러 memory의 “Alice”(similarity 약 0.9)로 채워져 floor도 약 0.89 → Alice가 없는 memory까지 0.89를 받아, 이 token은 memory 간 차이를 거의 만들지 못함
      • 드문 token(“notebooks”): 실제로 나오는 memory는 한두 개뿐이라 나머지 자리는 애매하게 비슷한 token으로 채워짐 → floor가 약 0.4로 낮아, 해당 memory만 0.9로 크게 앞서감
      • MaxSim은 memory마다 따로 최댓값을 구하므로 “Alice”가 있는 memory(0.9)와 없는 memory(0.3)의 차이가 계속 남음; 한 사람의 대화처럼 Alice가 거의 모든 memory에 나오면 이 차이는 정답과 무관한 noise
      • 단, token이 k개보다 많은 memory에 나올 때만 성립 (LoCoMo는 query당 후보 memory 약 570개, k = 64)
      • 실제로 MaxSim으로 바꾸면 성능이 떨어짐 (Effects의 원인분석)

[결합] Local–Global Fusion

  • token score와 기존 vector score fusion
    • token-only: token 몇 개만 우연히 겹친 엉뚱한 memory가 올라올 여지
    • vector-only: 일부만 query와 맞는 memory(memory 6 같은)가 밀릴 여지
  • 두 score는 범위가 달라 그대로 더할 수는 없으므로 query마다 후보 memory들 안에서 평균 0, 표준편차 1로 정규화($\hat s$), $s_{\text{fused}}$ 계산, $\alpha = 0.5$

[적응] (Optional) query 쪽 token 벡터만 학습 (Query Adaptation)

  • 정답 memory 라벨이 있을 때 매칭 학습: query token 벡터에만 작용, query vector $z_q$와 저장된 memory는 고정
    • 저장된 memory는 건드리지 않되, (memory 재encoding 필요x) query 쪽 token 벡터에만 보정 (LoRA-st low-rank residual)

      \[T_\theta(h) = \frac{\lVert h \rVert_2 (h + BAh)}{\max(\lVert h + BAh \rVert_2, \epsilon)}, \qquad \tilde h_{q,i} = T_\theta(h_{q,i})\]
      • $A \in \mathbb{R}^{r \times d}$, $B \in \mathbb{R}^{d \times r}$: 모든 query 위치에서 공유하는 bias 없는 행렬, rank $r = 32$, parameter는 $2dr$개 (0.6B 기준 약 65K)
      • 분자와 분모의 norm 비율: 변환 후에도 입력 norm을 그대로 유지 → similarity를 키우려고 벡터 크기만 부풀리는 꼼수를 막음
      • $B$를 0으로 초기화하므로 학습 시작 시점에는 원래 query와 동일
  • objective: top-$k$ 검색은 이산적 선택이라 미분 불가, 학습 때는 MaxSim을 미분 가능한 대리 score로 사용
    • $s^\theta_{\text{MaxSim}}$: MaxSim의 $h_{q,i}$를 $\tilde h_{q,i}$로 바꾼 score
    • 정답 memory가 여러 개일 수 있는 contrastive loss: $\mathcal{L} = -\log \frac{\sum_{m \in G_q} \exp(s^\theta_{\text{MaxSim}}(q,m)/\tau)}{\sum_{m \in C_q} \exp(s^\theta_{\text{MaxSim}}(q,m)/\tau)}$
      • $C_q$: 학습 후보 집합, $G_q$: 정답 memory 집합, $\tau = 0.07$
    • inference 때는 보정된 query token으로 2단계 매칭을 하고, 3단계에서 그대로 섞음
  • 효과는 미미: 학습 없는 버전 위에 소폭 더하는 수준, backbone에 따라 효과가 없기도 (하기 참고)

Effects

  • Experimental setup
    • benchmark: LMEB (Zhao et al., 2026), 8개 benchmark 5,873 query
      • conversational memory: LoCoMo, LongMemEval, REALTALK (Lee et al., 2025)
      • document: ESG-Reports (재무 보고서), QASPER, PeerQA (논문), CovidQA (의생명), MLDR (장문서)
      • metric: 상위 10개 안에 정답이 든 비율(Recall@10)과 순위까지 반영한 NDCG@10, benchmark별 동일 가중 평균
    • baselines
      • 같은 backbone: Original embedding, Search-Adaptor, Chunk-MaxP (512-token chunk별 embedding 중 최댓값), MaxSim (frozen token에 ColBERT식 비교), BM25 + Original (같은 정규화로 동일 가중 결합)
      • 독립 시스템: BM25, ColBERTv2, XTR, ConstBERT
        • 각자 고유 encoder를 쓰므로 같은 backbone끼리의 비교는 아님
      • backbone 8종 (모두 frozen): Qwen3-Embedding 0.6B/4B/8B, NVIDIA Llama 계열 1B/3B/8B, EmbeddingGemma-300M, Jina-Embeddings-v5-text-nano
    • 구현: token budget $k = 64$, $\alpha = 0.5$, token state는 FP16 저장
      • query adapter와 Search-Adaptor는 EvoTrain-180K에서 뽑은 1,024개로만 학습 (평가 benchmark 데이터 미사용), 3 seed 평균
    • downstream QA: 답변 모델 Qwen3-30B-A3B-Instruct, judge GPT-4o-mini, memory 10개 retrieval
      • LoCoMo 1,540문항, LongMemEval 500문항, accuracy와 F1
      • Original과 query adapter 버전 둘만 비교 (training-free 버전이나 ColBERTv2 등은 QA에서 비교하지 않음)
  • Results
    • 학습 없이도 gain, 대화형 memory에서 특히 압도적 Tab 1
      • 이득의 출처는 학습이 아니라 이미 있던 token state: training-free만으로 Original 대비 크게 향상
        • query adapter는 그 위에 소폭 더하는 수준
      • 같은 backbone에 MaxSim을 붙인 경우 혹은 별도 학습한 ColBERTv2보다도 높은 평균 달성
      • 대화형 memory: LoCoMo, LongMemEval 등에서 큰 gain
        • 한 memory가 여러 발화를 담고 query는 그중 한 문장만 묻는 구조라 pooling 손실이 가장 큰 곳이므로
      • 문서형 memory: benchmark별로 상이. PeerQA는 ColBERTv2, 장문서(MLDR)는 BM25가 오히려 우세
      • Fig 1) 정답 memory가 28위 → 1위, LoCoMo 에서 Top-10에 정답이 새로 들어온 query가 빠진 query보다 훨씬 많음
        • 단 open-domain 유형은 빠진 쪽이 더 많기도
    • backbone이 강할수록 gain이 줄어듦 Tab 2
      • 8개 backbone 모두 개선, Original이 이미 강한 Llama 계열에서는 이득이 작고 Original이 약한 Qwen3-4B에서 가장 큼
      • query adapter 효과도 backbone에 따라 다름: 일부는 변화가 없거나 소폭 하락 → 따라서 말 그대로 optional
    • retrieval 개선이 QA 정확도로 이어지나, preference 에서는 불안정 Tab 3
      • LoCoMo) 8개 backbone 모두, LongMemEval) 8개 중 7개 성능 향상
        • 질문 유형별로 보면 single-hop과 knowledge update 질문에서 gain 뚜렷
      • 반면 preference 유형은 backbone에 따라 상이
    • (원인분석) 이득은 memory 간 경쟁 및 k개에 안 든 경우의 처리에서 발생 Tab 4, Tab 10, App D
      • chunk를 32 token까지 잘게 나눠 따로 embedding해도 Original과 동일
        • 비교 단위를 작게 만드는 것만으로는 이득 xx
      • sparse matching을 memory별 MaxSim으로 교체시 성능 하락
        • 더 많이 비교하는 것보다 memory끼리 경쟁시키는 편이 낫다
      • floor를 0으로 바꾸면 크게 하락하는데, 근사 검색을 정확한 검색으로 바꿔도 거의 변화 없음
        • 검색 정확도보다 검색되지 않은 매칭을 어떻게 채우느냐가 더 중요한 요인
      • whole-memory score를 빼도 하락
        • local과 global score가 서로 보완
    • (sensitivity) hyperparam. 에 강건 Fig 3, 4, 5
      • 넘겨주는 memory 수 $K$, query token당 검색 개수 $k$, vector score 비중 $\alpha$를 바꿔도 Original보다 우세
    • (efficiency) 저장량은 Original의 약 70배지만, 4-bit로 줄이면 10배 남짓에 성능 유지 Tab 5
      • 검색 시간 증가는 약 5 ms 수준
    • 🤔
      • Qwen3-4B 기준을 대표로 언급하면서 내세운 Recall@10 +13.3pp, Original 성능이 너무너무 낮음.. (0.6B보다도 낮음, 특히 LongMemEval 59.2 vs 84.8)
        • → 유독 취약했던 baseline의 gain이라 상대적으로 큰 backbone에서의 gain은 +1.6~+4.5pp 수준
      • BM25 score와 섞기만 해도 4B 기준 이득의 절반 이상(55~60%)이 회복되나, 본문에서는 딱히 강조 없음
      • sparse matching이 MaxSim보다 나은 이유 설명되지 않음
      • LongMemEval F1은 모든 조건에서 12~13 근처로 거의 같아 정보가 없고,
        preference 유형은 30문항이라 1문항이 3.3pp
        • → 사실 등락을 해석하기 어렵다고 보고 유의성 검정도 없음

Personal note. memory도 잘써보자는 측면의 retrieval 논문이긴 한데, memory를 vector 하나로 접어서 비교하는 순간 정작 필요한 local evidence가 scoring에서 사라진다는 문제 의식이 좀 고전적인 것 같기는 해도, 그 고전 방식을 최신식으로 하면 PRefine 식의 abstraction인가 싶기도 하더라고요. 해석을 저장 시점이 아니라 꺼내는 시점으로 미룬다고 볼 수도 있을 것 같고, raw context를 직접 읽을 수 있다면 굳이 추상화해야 하는가?라는 질문에 retrieval 측면으로 봐도 역시 그렇다는 결론이 나지 않나 싶습니다.

논문에서는 대화형 memory에서의 이득이 크다고 보고하고는 있는데, 이 방법은 query와 memory가 token 수준에서 겹친다는 가정 위에 있으므로 요청과 겹치는 단어가 거의 없는 personalized한 상황에서 쓰기는 어렵지 않나 싶습니다. preference 유형 QA에서 이득이 들쭉날쭉한 것도 같은 근거로 해석할 수 있지 않나 싶고요.