Field Log · Entry

monoT5·duoT5·RankT5·ListT5: 생성형 Reranker의 계보 (4/14)

monoT5의 relevance token, duoT5의 문서 쌍 비교, RankT5의 scalar loss, ListT5의 후보 목록 비교로 이어지는 T5 reranker 계보

이번 글의 결론

  • monoT5는 답변을 길게 생성하는 model이 아니라, query-document 입력에서 truefalse label token logit을 relevance score로 사용합니다.
  • duoT5는 두 후보를 직접 비교하는 pairwise stage이고, RankT5는 T5 representation에서 scalar score를 내 ranking loss로 학습합니다. 이름이 비슷해도 objective가 다릅니다.
  • ListT5는 여러 후보를 함께 encode해 후보 간 context를 활용합니다. Pointwise T5를 단순히 큰 prompt로 바꾼 것이 아닙니다.
  • “생성형 reranker”에는 label 생성, 문서 ID 순열 생성, query likelihood 등 서로 다른 방식이 포함됩니다. Output protocol을 확인해야 합니다.
  • Decoder가 있다고 항상 긴 autoregressive decoding이 필요한 것은 아닙니다. 실제 생성 token 수와 score extraction path를 profiler에서 확인합니다.

앞 글의 encoder-only Cross-Encoder는 대표 token에서 relevance logit을 냈습니다. T5 계열은 text-to-text pretraining을 ranking에 옮기면서 여러 갈래로 발전했습니다.

monoT5   (q, d)       → "true" / "false" token logit
duoT5    (q, d₁, d₂)  → d₁ > d₂ preference token
RankT5   (q, d)       → scalar score + ranking loss
ListT5   (q, d₁...dₙ) → list-aware candidate selection/order

이 네 model을 “T5 reranker” 한 칸에 넣으면 구조와 비용을 잘못 추론하게 됩니다.


1. Text-to-Text로 Ranking을 표현한다

T5는 다양한 task를 text input과 text target으로 통일했습니다. monoT5는 query-document relevance도 text label prediction으로 표현했습니다.

Input:
Query: Orion S2 emergency shutdown temperature
Document: The approved S2 manual specifies shutdown at 88°C.
Relevant:

Target:
true

Negative example은 target이 false입니다.

Input:
Query: Orion S2 emergency shutdown temperature
Document: The S2 shutdown pressure threshold is 2.4 bar.
Relevant:

Target:
false

Fine-tuning은 일반적인 teacher forcing으로 target token likelihood를 높입니다.

L = -log P("true" | q, d)       if relevant
L = -log P("false" | q, d)      otherwise

2. monoT5 Score는 자유 생성 문장이 아니다

Inference에서 “이 문서가 왜 관련 있는지 설명하라”는 긴 문장을 생성할 필요가 없습니다. 첫 target position의 vocabulary logit 중 label token을 읽습니다.

z_true  = decoder logit for token "true"
z_false = decoder logit for token "false"

score = exp(z_true) / (exp(z_true) + exp(z_false))

전체 vocabulary softmax의 P(true)를 쓸 수도 있지만, 두 label logit만 다시 normalize하면 ranking label 사이의 상대 확률에 집중합니다. 구현과 checkpoint 관례를 확인해야 합니다.

Token 문자열을 눈으로 추측하지 않는다

Tokenizer에서 true, ▁true, 앞 공백이 있는 true가 서로 다른 token일 수 있습니다. Label이 한 token인지도 확인합니다.

from transformers import AutoModelForSeq2SeqLM, AutoTokenizer


MODEL_ID = "castorini/monot5-base-msmarco"
tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
model = AutoModelForSeq2SeqLM.from_pretrained(MODEL_ID)


def one_token_id(label: str) -> int:
    token_ids = tokenizer.encode(label, add_special_tokens=False)
    if len(token_ids) != 1:
        raise ValueError(f"{label!r} is not one token: {token_ids}")
    return token_ids[0]


true_id = one_token_id("true")
false_id = one_token_id("false")

Model card의 training template이 대문자 True를 썼다면 그대로 따라야 합니다. Label 문자열은 semantic decoration이 아니라 learned class ID입니다.

3. 첫 Decoder Step에서 Score 읽기

개념을 보여 주는 최소 구현입니다. Production에서는 batch, attention mask, dtype, device, tokenizer template을 추가합니다.

import torch


@torch.inference_mode()
def monot5_score(query: str, document: str) -> float:
    text = f"Query: {query} Document: {document} Relevant:"
    inputs = tokenizer(
        text,
        return_tensors="pt",
        max_length=512,
        truncation=True,
    )

    decoder_start = model.config.decoder_start_token_id
    decoder_input_ids = torch.tensor([[decoder_start]])

    outputs = model(
        **inputs,
        decoder_input_ids=decoder_input_ids,
    )
    first_step_logits = outputs.logits[0, 0]
    label_logits = first_step_logits[[true_id, false_id]]
    label_probs = torch.softmax(label_logits, dim=0)
    return float(label_probs[0])

실제 checkpoint는 tokenizer와 model을 같은 device로 옮겨야 합니다. 또한 decoder_start_token_id, label casing, template이 checkpoint마다 다를 수 있으므로 이 코드를 model-agnostic wrapper라고 생각하면 안 됩니다.

generate()가 꼭 필요한가

Label 한 token의 logit만 필요하면 일반적인 beam search나 여러 token decoding은 낭비일 수 있습니다.

needed: encoder forward + decoder first-step logits
not necessarily needed: free-form autoregressive generation

Framework wrapper가 내부에서 실제로 몇 token을 decode하는지 trace합니다.

4. monoT5도 Interaction 관점에서는 Cross-Encoder다

monoT5는 query와 document를 같은 encoder input에 넣습니다. 따라서 broad architecture taxonomy에서는 full-interaction reranker입니다.

query + document

T5 encoder joint self-attention

decoder cross-attention

label token logits

BERT Cross-Encoder와 차이는 주로 pretrained architecture와 output formulation입니다.

항목BERT-style Cross-EncodermonoT5
Backboneencoder-onlyencoder-decoder
Inputquery + documentquery + document + task prefix
Outputclassification·regression headlabel token logits
Typical lossBCE·CE·ranking losstoken cross-entropy
Document precompute불가불가

5. duoT5: 두 후보의 상대 선호를 묻는다

Pointwise monoT5로 넓은 후보를 줄인 뒤 pairwise duoT5로 더 작은 목록을 정렬하는 design이 제안됐습니다.

BM25 top-1000
→ monoT5 top-50
→ duoT5 pairwise comparisons
→ final top-10

입력은 query와 document 두 개를 포함합니다.

Query: {q}
Document0: {d_i}
Document1: {d_j}
Relevant:

Output token은 d_i가 더 관련 있는지 d_j가 더 관련 있는지를 나타냅니다. 정확한 template과 label은 checkpoint 구현을 따라야 합니다.

Pairwise Preference를 List로 바꾸기

후보 ij보다 낫다는 확률을 p_ij라고 하면 aggregate score를 만들 수 있습니다.

s_i = Σ_{j ≠ i} p_ij

하지만 pairwise preference가 항상 transitive하다는 보장은 없습니다.

d₁ > d₂
d₂ > d₃
d₃ > d₁

모든 pair 비교는 O(n²)입니다. 작은 top-k에만 쓰거나 sorting algorithm, sparse comparison graph를 사용합니다.

6. Expando-Mono-Duo는 Model 하나가 아니라 Pipeline Pattern이다

Expando-Mono-Duo design은 세 단계를 뜻합니다.

Expando
  document expansion으로 lexical representation 강화
  → inverted index first stage

Mono
  query-document pointwise reranking

Duo
  top candidates pairwise refinement

이 이름을 “T5 model family 세 종류”로 이해하면 안 됩니다. Candidate generation, pointwise reranking, pairwise reranking을 연결한 multi-stage pattern입니다.

7. RankT5: Text Label 대신 Ranking Score를 직접 낸다

RankT5는 T5를 ranking에 쓰되 true/false text generation에 꼭 묶이지 않습니다. Encoder-decoder 또는 encoder-only 변형에서 scalar score를 내고 ranking loss로 fine-tuning합니다.

T5 representation
  → projection
  → scalar score s(q, d)

그리고 2편의 loss를 적용할 수 있습니다.

pointwise classification
pairwise logistic
listwise softmax cross-entropy

RankT5 연구는 ranking loss를 쓴 model이 classification loss model보다 여러 dataset에서 좋은 성능을 보였고, 일부 listwise-loss 설정에서 out-of-domain zero-shot generalization도 더 좋았다고 보고했습니다. 이것은 모든 domain의 보편 법칙이 아니라 해당 실험 설정의 결과이므로 target corpus에서 재검증해야 합니다.

monoT5 Checkpoint를 RankT5처럼 읽지 않는다

monoT5 checkpoint
  expects label token scoring

RankT5 checkpoint
  may expose a scalar scoring head

둘 다 T5 backbone이라는 이유로 동일한 inference code를 쓰면 score가 틀릴 수 있습니다.

8. ListT5: 후보 여러 개를 함께 읽는다

Pointwise model은 후보마다 독립적으로 score합니다.

f(q, d₁), f(q, d₂), ..., f(q, dₙ)

ListT5는 Fusion-in-Decoder, FiD 구조를 이용해 후보를 따로 encode하고 decoder에서 후보 정보를 함께 사용합니다.

encode(q, d₁) ─┐
encode(q, d₂) ─┼─ decoder cross-attends to candidates
...            │
encode(q, dₙ) ─┘

이 구조는 긴 후보 text를 하나의 flat sequence로 concat하는 것과 다릅니다.

  • 각 query-passage pair를 개별 encoder input으로 처리합니다.
  • Decoder가 여러 candidate representation을 함께 봅니다.
  • 후보 간 global comparison이 가능합니다.
  • Candidate 수와 길이에 따라 encoder work와 decoder memory가 늘어납니다.

ListT5는 m-ary tournament sorting과 output caching으로 listwise inference를 구성했습니다. 논문은 BEIR zero-shot 평가에서 RankT5 baseline 대비 평균 nDCG@10 개선과 pointwise에 가까운 효율을 보고했지만, corpus·first-stage·hardware가 바뀌면 절대 효과는 다시 측정해야 합니다.

9. Pointwise·Pairwise·Listwise가 T5 안에서도 교차한다

Model한 번에 보는 후보Output대표 학습·추론 형태
monoT51relevance label token logitpointwise
duoT52preference labelpairwise
RankT5주로 1 pair inputscalarpairwise·listwise loss 가능
ListT5여러 후보list-aware decisionlistwise

여기서 다시 확인할 점은 input scope와 loss scope가 다를 수 있다는 것입니다. RankT5는 pair input을 하나씩 encode해도 같은 query의 score를 listwise loss로 묶을 수 있습니다.

10. “Generative Reranker”라는 말의 세 가지 의미

Label Generation

(q, d) → "true"

monoT5가 대표적입니다. 실제로는 label token logit을 score로 씁니다.

Permutation Generation

(q, [d1, d2, d3]) → [d2, d1, d3]

RankGPT·RankZephyr 같은 LLM listwise 방식입니다. 6편에서 다룹니다.

Query Likelihood

Document를 조건으로 query를 얼마나 잘 생성할 수 있는지 점수화할 수도 있습니다.

score(q, d) = log P(q | d)

UPR 같은 unsupervised passage reranking이 이 방향을 사용합니다. “Document가 query를 생성할 만한가?”라는 역방향 relevance proxy입니다.

세 방식은 output, token cost, calibration, failure가 다릅니다.

11. Label Token Scoring의 함정

Label Prior

Model이 true token을 원래 더 자주 생성하는 prior가 있을 수 있습니다. Query-document evidence보다 label prior가 score에 섞입니다.

Verbalizer Sensitivity

true/false, yes/no, relevant/irrelevant가 같은 결과를 보장하지 않습니다. Fine-tuned checkpoint는 training verbalizer를 사용합니다.

Multi-token Label

Label이 여러 token이면 sequence probability와 length normalization 문제가 생깁니다.

Score Saturation

Probability가 0이나 1 근처에 몰리면 ranking tie와 calibration이 나빠질 수 있습니다. Raw logit margin을 함께 분석합니다.

margin = z_true - z_false
prob   = sigmoid(margin)

두 label만 normalize할 때 위 식과 같습니다.

12. Long Document와 Template Budget

Task prefix와 field label도 token budget을 씁니다.

Query: ...
Document Title: ...
Status: ...
Effective Date: ...
Document: ...
Relevant:

Metadata를 많이 넣으면 body가 더 잘릴 수 있습니다. 모든 field를 넣기보다 query와 policy에 필요한 field를 보존합니다.

T5 tokenizer 기준으로 다음을 기록합니다.

  • prefix token 수
  • query token 수
  • metadata token 수
  • body token 수
  • truncated body 비율
  • answer span retained 여부

Cross-Encoder 글의 windowing 전략은 T5 pair reranker에도 적용됩니다.

13. 어떤 T5 계열을 언제 고려할까

요구고려할 방식확인할 것
강한 재현 baselinemonoT5label token, template, latency
Top 후보 간 미세 비교mono → duo cascadepair count, cycle, aggregate
Ranking loss를 직접 실험RankT5checkpoint head, query grouping
후보 간 global contextListT5list size, memory, position robustness
Label 없이 zero-shot proxyquery likelihooddomain transfer, query length bias

Encoder-only Cross-Encoder보다 무조건 낫다는 순서는 없습니다. 다음을 같은 candidate set에서 비교합니다.

quality gain
÷
(latency + memory + implementation risk + maintenance)

14. 재현 가능한 실험 Manifest

reranker:
  family: monot5
  checkpoint: castorini/monot5-base-msmarco
  revision: PINNED_COMMIT
  template: "Query: {query} Document: {document} Relevant:"
  positive_label: "true"
  negative_label: "false"
  score: two_label_softmax
  max_input_tokens: 512
  max_output_tokens: 1
  dtype: bf16

evaluation:
  frozen_candidates: hybrid-v4-top100.jsonl
  candidate_depths: [20, 50, 100]
  metrics: [mrr_at_10, ndcg_at_10, p95_ms]

Model ID만 기록하면 label·template·score extraction 변경을 재현할 수 없습니다.

스스로 확인하기

  1. monoT5가 자유로운 자연어 답변을 생성하지 않아도 reranking할 수 있는 이유는 무엇인가?
  2. true label이 tokenizer에서 한 token인지 확인해야 하는 이유는 무엇인가?
  3. duoT5의 모든 pair 비교가 candidate 수에 대해 어떤 복잡도를 갖는가?
  4. RankT5가 monoT5와 다른 핵심은 backbone보다 무엇인가?
  5. ListT5의 FiD 방식과 후보 전체를 하나의 flat prompt로 넣는 방식은 어떻게 다른가?

다음 글에서는 single-vector Bi-Encoder와 full Cross-Encoder 사이에서 token vector를 보존하는 ColBERT late interaction을 다룹니다.

참고자료