Skip to content

Commit 0765d03

Browse files
authored
[data] fix: Handle Qwen3-Next custom chat data (#5012)
Signed-off-by: Yu Yao <yaoyu.094@gmail.com>
1 parent ecbdfc8 commit 0765d03

2 files changed

Lines changed: 51 additions & 2 deletions

File tree

examples/models/qwen/qwen3_next/finetune_qwen3_next_80b_a3b.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949

5050
from omegaconf import OmegaConf
5151

52-
from megatron.bridge.data.builders import GPTSFTDatasetConfig, HFDatasetSourceConfig
52+
from megatron.bridge.data.builders import ChatSFTPreprocessingConfig, GPTSFTDatasetConfig, HFDatasetSourceConfig
5353
from megatron.bridge.recipes.qwen.qwen3_next import qwen3_next_80b_a3b_sft_config
5454
from megatron.bridge.training.config import ConfigContainer
5555
from megatron.bridge.training.pretrain import pretrain
@@ -78,6 +78,7 @@ def _replace_with_custom_data_path(config: ConfigContainer, data_path: str) -> N
7878
),
7979
hf_validation_dataset=None,
8080
hf_test_dataset=None,
81+
preprocessing=ChatSFTPreprocessingConfig(),
8182
)
8283

8384

tests/unit_tests/examples/test_qwen3_next_finetune.py

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
# Copyright (c) 2026, NVIDIA CORPORATION. All rights reserved.
22

33
import importlib.util
4+
import json
45
import pathlib
56
import sys
67
from types import SimpleNamespace
78

89
import pytest
910

10-
from megatron.bridge.data.builders import GPTSFTDatasetConfig, HFDatasetSourceConfig
11+
import megatron.bridge.data.builders.gpt_sft as gpt_sft_builder
12+
from megatron.bridge.data.builders import (
13+
GPTSFTDatasetConfig,
14+
HFDatasetSourceConfig,
15+
PromptCompletionSFTPreprocessingConfig,
16+
)
1117

1218

1319
pytestmark = pytest.mark.unit
@@ -47,3 +53,45 @@ def test_data_path_replaces_named_source_with_custom_json_source():
4753
assert config.dataset.hf_validation_proportion == 0.1
4854
finally:
4955
sys.modules.pop(name, None)
56+
57+
58+
def test_data_path_materializes_advertised_messages_schema(monkeypatch, tmp_path):
59+
name = "qwen3_next_finetune_messages_data"
60+
try:
61+
module = _load_example_module(name)
62+
config = SimpleNamespace(
63+
dataset=GPTSFTDatasetConfig(
64+
seq_length=2048,
65+
hf_dataset=HFDatasetSourceConfig(dataset_name="squad"),
66+
hf_validation_proportion=0.1,
67+
do_test=False,
68+
preprocessing=PromptCompletionSFTPreprocessingConfig(
69+
prompt_column="input",
70+
completion_column="output",
71+
separator=" ",
72+
),
73+
)
74+
)
75+
messages_rows = [
76+
{
77+
"id": index,
78+
"messages": [
79+
{"role": "user", "content": f"Question {index}"},
80+
{"role": "assistant", "content": f"Answer {index}"},
81+
],
82+
}
83+
for index in range(10)
84+
]
85+
monkeypatch.setattr(gpt_sft_builder, "load_and_adapt_hf_dataset", lambda _: messages_rows)
86+
87+
module._replace_with_custom_data_path(config, "/data/custom.jsonl")
88+
gpt_sft_builder.materialize_hf_dataset(config.dataset, tmp_path)
89+
90+
materialized_rows = []
91+
for split in ("training", "validation"):
92+
with (tmp_path / f"{split}.jsonl").open(encoding="utf-8") as input_file:
93+
materialized_rows.extend(json.loads(line) for line in input_file)
94+
assert len(materialized_rows) == len(messages_rows)
95+
assert all("conversation" in row and "messages" not in row for row in materialized_rows)
96+
finally:
97+
sys.modules.pop(name, None)

0 commit comments

Comments
 (0)