Skip to content

Commit 1968bea

Browse files
committed
[data] fix: preserve GLM historical answer loss
Signed-off-by: Yu Yao <yaoyu.094@gmail.com>
1 parent d0debd0 commit 1968bea

2 files changed

Lines changed: 43 additions & 0 deletions

File tree

‎src/megatron/bridge/data/conversation_processing.py‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,6 +1101,11 @@ def infer_assistant_mask_boundary_config(processor: Any) -> AssistantMaskBoundar
11011101
processor,
11021102
assistant_start="<|assistant|>",
11031103
assistant_end=None,
1104+
role_start_markers={
1105+
"system": "<|system|>",
1106+
"user": "<|user|>",
1107+
"tool": "<|observation|>",
1108+
},
11041109
rendered_turn_end_roles=(CHATML_ASSISTANT_ROLE,),
11051110
)
11061111

@@ -1440,6 +1445,18 @@ def _assistant_mask_from_conversation_turns(
14401445

14411446
if role in rendered_turn_end_roles:
14421447
content_end = after_end = turn_limit
1448+
if turn_index + 1 < len(conversation):
1449+
boundary_tokens_in_payload = _conversation_contains_boundary_tokens(
1450+
example_or_conversation, tokenizer, boundary_config
1451+
)
1452+
if boundary_tokens_in_payload is not False:
1453+
return None
1454+
next_role = conversation[turn_index + 1].get("role")
1455+
next_role_start_tokens = role_start_tokens.get(next_role, [])
1456+
next_role_start, _ = find_token_span(rendered_ids, next_role_start_tokens, content_start)
1457+
if next_role_start < 0:
1458+
return None
1459+
content_end = after_end = next_role_start
14431460
else:
14441461
candidate_ends: list[tuple[int, int, int, list[int]]] = []
14451462
for priority, pattern in enumerate(end_patterns):

‎tests/unit_tests/models/test_glm52_kimi_k3_minimax_m3_chat.py‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ def encode(self, text: str, add_special_tokens: bool = False) -> list[int]:
6969
assert add_special_tokens is False
7070
marker_ids = {
7171
"<|assistant|>": [ASSISTANT_START],
72+
"<|system|>": [40],
73+
"<|user|>": [USER_START],
74+
"<|observation|>": [TOOL_RESULT],
7275
'<|open|>message role="assistant"<|sep|>': [ASSISTANT_START],
7376
"<|close|>message<|sep|><|end_of_msg|>": [TURN_END],
7477
"]~b]ai\n": [ASSISTANT_START],
@@ -268,6 +271,29 @@ def test_model_chat_four_way_rendering_and_loss_boundaries(model: str, tools: bo
268271
assert all("enable_thinking" not in entry for entry in semantic_kwargs)
269272

270273

274+
def test_glm_history_thinking_truncation_preserves_historical_answer_loss() -> None:
275+
tokenizer = _ModelChatTokenizer("glm")
276+
example = {
277+
"messages": _messages(tools=False, thinking=True),
278+
"chat_template_kwargs": {
279+
"enable_thinking": True,
280+
"truncate_history_thinking": True,
281+
},
282+
}
283+
284+
tokenized = tokenize_chat_example(example, tokenizer, warn_on_all_masked=False)
285+
286+
assert tokenized.input_ids[tokenized.assistant_mask].tolist() == [
287+
THINK_OPEN,
288+
THINK_CLOSE,
289+
TEXT_IDS["answer one"],
290+
THINK_OPEN,
291+
TEXT_IDS["reason two"],
292+
THINK_CLOSE,
293+
TEXT_IDS["answer two"],
294+
]
295+
296+
271297
@pytest.mark.parametrize("model", ["glm", "kimi", "minimax"])
272298
def test_model_chat_right_truncation_and_padding_preserve_loss_alignment(model: str) -> None:
273299
tokenizer = _ModelChatTokenizer(model)

0 commit comments

Comments
 (0)