THUDM / THUDM/slime

[Agent RL] Qwen3.5 history re-templating causes false trajectory forks

Open
#2,288 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

Context

This issue is specific to multi-turn agent RL with Qwen3.5 and a Claude Code-compatible Anthropic adapter. Claude Code sends the full structured message history on each turn, while Slime currently re-applies the model chat template to that history before every SGLang request.

For an RL trajectory, the required invariant is stricter than semantic equivalence:

next_prompt_ids[:len(previous_prompt_ids + previous_output_ids)]
    == previous_prompt_ids + previous_output_ids

Without that exact prefix relationship, the stored action tokens and rollout log probabilities no longer describe the next prompt.

Observed behavior

In a real Qwen3.5-35B-A3B + Claude Code + TMax run:

8 environment rollouts
-> 64 training Samples
-> 1,825,684 trajectory tokens

Adjacent segments first diverged at historical assistant output, so TrajectoryManager classified many ordinary turns as forks. The duplicated prefixes then substantially increased packing and critic memory pressure.

Root cause

Two message-to-token round trips are not lossless:

  1. The Qwen3/3.5 chat template normally removes reasoning from assistant turns before the latest user/tool message. Claude Code may also omit earlier thinking blocks when it replays history.
  2. Parsed model output passes through Claude's structured message representation. Text, whitespace, and tool-call argument formatting may be normalized before the next request.

Slime already owns the exact prompt_ids, output_ids, and rollout log probabilities generated by SGLang, but the adapter reconstructs old assistant tokens from the client replay instead of continuing from those canonical token IDs.

Fully-async rollout does not create the mismatch. It makes the impact more visible because the false forked Samples enter the asynchronous training queue and inflate token volume.

Expected behavior

For this adapter/model combination:

  1. The adapter server keeps an exact per-session token ledger.
  2. Historical assistant tokens come from the server's previous prompt_ids + output_ids, not from re-tokenizing the client echo.
  3. Only new user/tool observations and the next generation prompt are rendered and appended.
  4. A non-append-only continuation fails explicitly instead of silently becoming a trajectory fork.
  5. Reasoning remains enabled and trainable; this must not be fixed by disabling the Qwen <think> generation prefix.

Validated result

With canonical token continuation implemented in #2287, the same eight-task rollout produced:

8 environment rollouts
-> 8 training Samples
-> 265,001 trajectory tokens

All 128 assistant action segments retained reasoning through </think>, with aligned loss_mask, rollout_log_probs, and response_length. Critic forward and backward also completed without the previous memory failure.

Scope

This issue tracks the Qwen3.5/Claude Code history-alignment bug only. It does not claim that fully-async rollout itself creates forks, and it does not cover legitimate context compaction, sub-agent branching, generic nested fan-out, group reward models, or GRPO normalization.

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

No specific files or tests are named. Start with the Claude Code-compatible adapter server and TrajectoryManager, then inspect the canonical token continuation implemented in #2287. Done means each session preserves the exact prompt/output token prefix, rejects non-append-only continuation explicitly, and keeps reasoning and rollout metadata aligned.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
ai, machine-learning
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.