THUDM / THUDM/slime

[Question] realign 使用本轮 response 长度判断

Open
#2,338 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

question
Dominant language
Python
Stars
8.5k
Forks
1.3k
Avg merge
5h 36m
Merged PRs (30d)
22

Description

Your Question

问题1: REALIGN 使用的是本轮 output_ids 的长度进行判断。但 REALIGN 是对上一轮的 response 进行 loss_mask 值零的操作,应该用上一轮的 len(response_ids) 吧?
classify_token_drift(slime/agent/trajectory.py:188) 中:

start = self.last_response_start_idx
if start is not None and realign_at >= start and len(turn.output_ids) < self._fork_threshold:
    return DriftKind.REALIGN
return DriftKind.FORK

问题2:REALIGN 从 last_response_start 覆盖,而非从分歧点 realign_at
_align_to_prompt(slime/agent/trajectory.py:216):

def _align_to_prompt(self, prompt_ids: list[int]) -> None:
    response_start = self.last_response_start_idx
    tail = prompt_ids[response_start:]
    self.tokens[response_start:] = tail
    self.loss_mask[response_start:] = [0] * len(tail)
    self.logprobs[response_start:] = [0.0] * len(tail)

这里从 realign_at 开始覆盖比较好吧?


我的实际运行例子(fork_threshold 默认 1024):
一个 3 轮片段:第 3 轮是 61 token 的小过渡句,第 2 轮的 output + tool_response 跨度 28404 token:

TMPDEBUG_DRIFT  kind=realign realign_at=39662 drift=18896 held_len=58558 prompt_len=58652
                resp_start=30154 held_div=47724(QQ) prompt_div=126724(QQ音乐)
TMPDEBUG_REALIGN resp_start=30154 zeroed_resp_tokens=28404 new_resp_len=61 builder_len_before=58558
  • zeroed_resp_tokens = 58558 - 30154 = 28404 == 上一轮 output + 其后 tool_response。
  • new_resp_len = 61(触发轮)< 1024 → REALIGN。
  • 分歧是单点 BPE 切分差异:模型侧 QQ(id 47724)vs 回传侧 QQ音乐(id 126724)。同文本、decode 一致。但 BPE 贪心合并使其后所有 token 边界错位,产生 drift=18896
  • _align_to_promptprompt_ids[30154:] 覆盖 [30154:58558],该范围包含分歧点之前的上一轮 output → 连带清零。

我在 builder 里统计了 REALIGN 清零范围内原有loss_mask 分布。4 次 REALIGN:

REALIGN resp_start=20503 zeroed=610  new_resp=730  realign_at=20740 innocent=237  killed_train_lm1=610  killed_masked_lm0=0
REALIGN resp_start=16167 zeroed=4435 new_resp=585  realign_at=16351 innocent=184  killed_train_lm1=4435 killed_masked_lm0=0
REALIGN resp_start=34362 zeroed=654  new_resp=175  realign_at=34694 innocent=332  killed_train_lm1=654  killed_masked_lm0=0
REALIGN resp_start=31995 zeroed=1061 new_resp=54   realign_at=32378 innocent=383  killed_train_lm1=1061 killed_masked_lm0=0
  1. killed_masked_lm0 == 0(全部)→ 清零范围里没有工具结果/历史,全是 loss_mask=1 模型生成,不是「工具调用结果长度」。
  2. killed_train_lm1 == zeroed_resp_tokens(完全相等)→ 清零区间就是上一轮完整 output 的一整段。
  3. pre_divergence_innocent = 184/237/332/383,均 > 0 → 清零从 resp_start 而非 realign_at 开始,分歧点前还有 184~383 个无辜 token 被一并清掉。
What I've Tried

我进行的改动:
问题1:

start = self.last_response_start_idx
if start is not None and realign_at >= start:
    sacrificed_len = len(self.tokens) - start
    both_short = (
        len(turn.output_ids) < self._fork_threshold
        and sacrificed_len < self._fork_threshold
    )
    kind = DriftKind.REALIGN if both_short else DriftKind.FORK
else:
    kind = DriftKind.FORK

加入了上一轮 response 长度的判断


问题2:

def _align_to_prompt(self, prompt_ids: list[int], realign_at: int) -> None:
    tail = prompt_ids[realign_at:]
    self.tokens[realign_at:] = tail
    self.loss_mask[realign_at:] = [0] * len(tail)
    self.logprobs[realign_at:] = [0.0] * len(tail)
Environment (if relevant)
  • slime version:
  • Python version:
  • PyTorch version:
  • CUDA/ROCm version:
  • GPU type and count:
  • OS:
Additional Context

No response

Pre-submission Checklist

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read slime/agent/trajectory.py at classify_token_drift (around line 188) and _align_to_prompt (around line 216). Reproduce the described multi-turn drift case, then inspect how response lengths and realign_at affect loss_mask and token replacement. Done means the realign decision uses the relevant response lengths and alignment no longer clears tokens before the divergence point, with the observed loss-mask behavior verified.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
machine-learning
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.