Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions src/megatron/bridge/data/conversation_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -578,8 +578,9 @@ def normalize_chat_conversation(
"""Normalize supported text-chat schemas to OpenAI-style messages.

Rows may use ``messages``, singular ``conversation``, or legacy plural
``conversations`` with ``from``/``value`` keys. Null OpenAI message content
is converted to an empty string before chat-template rendering.
``conversations`` with ``from``/``value`` keys. Null message content is
converted to an empty string before chat-template rendering, in either
supported schema.
"""
if isinstance(example_or_conversation, Mapping):
source = example_or_conversation
Expand Down Expand Up @@ -611,7 +612,13 @@ def normalize_chat_conversation(
continue
if "from" in turn and "value" in turn:
role = str(turn["from"]).lower()
normalized.append({"role": _LEGACY_CHAT_ROLE_ALIASES.get(role, role), "content": turn["value"]})
value = turn["value"]
normalized.append(
{
"role": _LEGACY_CHAT_ROLE_ALIASES.get(role, role),
"content": "" if value is None else value,
}
)
continue
raise ValueError("Chat turns must contain role/content or legacy from/value fields.")

Expand Down
31 changes: 31 additions & 0 deletions tests/unit_tests/data/test_conversation_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -1439,6 +1439,37 @@ def test_shared_chat_preprocessing_normalizes_sharegpt_roles_before_templating()
assert tokenized.assistant_mask.any()


def test_normalize_chat_conversation_converts_null_legacy_value_to_empty_content():
row = {
"conversations": [
{"from": "human", "value": "question"},
{"from": "gpt", "value": None},
]
}

assert normalize_chat_conversation(row) == [
{"role": "user", "content": "question"},
{"role": "assistant", "content": ""},
]


def test_normalize_chat_conversation_matches_null_and_empty_spellings_across_schemas():
def sharegpt(value):
return {"conversations": [{"from": "human", "value": "question"}, {"from": "gpt", "value": value}]}

openai_null = {
"messages": [
{"role": "user", "content": "question"},
{"role": "assistant", "content": None},
]
}

normalized = normalize_chat_conversation(sharegpt(None))

assert normalized == normalize_chat_conversation(sharegpt(""))
assert normalized == normalize_chat_conversation(openai_null)


def test_normalize_chat_conversation_normalizes_openai_tool_calls_without_mutating_input():
row = {
"messages": [
Expand Down
Loading