Skip to content

fix: dolci_tool_use transform for Dolci-Instruct-SFT tool rows - #64

Merged
Neonkraft merged 6 commits into
mainfrom
feat/dolci-tool-call-transform-for-qwen
Oct 24, 2026
Merged

Neonkraft merged 6 commits into
mainfrom
feat/dolci-tool-call-transform-for-qwen

Conversation

@Neonkraft

Copy link
Copy Markdown
Collaborator

Summary

This PR introduces transforms required to adapt the tool call rows from the Dolci-Instruct dataset. Without it, the tool call rows are rendered incorrectly.

Fixes #63

Type of change

  • Bug fix
  • New feature
  • Refactor
  • Performance
  • Documentation
  • Maintenance

Validation

New tests are written and a small run (~20 steps) was tried on LUMI.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved parser defects can alter tool arguments, discard convertible rows, or abort dataset loading.

4 open issues
What changed in this PR

This PR adds a dolci_tool_use transform to preserve Dolci-Instruct-SFT tool data in the standard SFT pipeline, addressing the Qwen3 rendering loss described in #63.

Changes:

  • Converts Dolci tool definitions, calls, and environment responses into standard tool fields.
  • Preserves tool_calls through the SFT dataset schema.
  • Adds parsing, rejection, and Qwen3 rendering tests.
File Description
tests/​test_transforms.py Tests Dolci conversion and tool-data preservation through rendering.
src/​post_training/​methods/​sft.py Adds tool-call fields to the messages schema.
src/​post_training/​data/​transforms.py Implements Dolci tool-use parsing and conversion.

Review effort: Balanced

Comment thread src/post_training/data/transforms.py Outdated
Comment thread src/post_training/data/transforms.py Outdated
Comment thread src/post_training/data/transforms.py Outdated
Comment thread src/post_training/data/transforms.py

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved evaluation safety, argument corruption, and template compatibility issues can disrupt preprocessing or produce incorrect training data.

4 open issues
2 previously missed issues

In code that hasn't changed since last review

Medium severity Prevent keyword-rename collisions and preserve original names

src/​post_training/​data/​transforms.py:701

A valid argument named _kw_from is not rewritten by _rename_keyword_args, but these lines still rename it to from. A call containing both from="EUR" and _kw_from="USD" also collapses the two arguments into one, silently losing a value. Use a collision-free rename mapping and restore only argument names that were actually rewritten.

Medium severity Reject non-finite values during JSON round-trip validation

src/​post_training/​data/​transforms.py:703

The round-trip check still accepts infinity: wx.get(value=1e309) produces {"value": Infinity}, and Python's permissive json.loads returns the same infinite float. Qwen3 inserts this string verbatim, so the training target contains an invalid JSON tool call. Set allow_nan=False so non-finite values follow the existing rejection path.

4 resolved since last review

Review effort: Balanced

Comment thread src/post_training/data/transforms.py Outdated
Comment thread src/post_training/data/transforms.py Outdated
"tool_calls": List(
{
"type": Value("string"),
"function": {"name": Value("string"), "arguments": Value("string")},
Comment thread src/post_training/data/transforms.py Outdated
Neonkraft and others added 2 commits October 24, 2026 11:22
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved allocation-limit, dataset-mixing, and conversion correctness issues can disrupt preprocessing or corrupt tool-call training data.

3 open issues
4 previously missed issues

In code that hasn't changed since last review

Medium severity Restore only keyword names actually rewritten

src/​post_training/​data/​transforms.py:761

This strips _kw_ from legitimate parameter names, not just names introduced by _rename_keyword_args. For example, wx.get(_kw_from="EUR") is accepted but becomes arguments {"from": "EUR"}, changing the tool invocation and potentially colliding with a separate from parameter. Track which argument names were actually rewritten, using collision-free temporary names, and restore only those.

Medium severity Reject non-finite values during round-trip validation

src/​post_training/​data/​transforms.py:763

The round-trip check accepts infinity: wx.get(q=1e309) serializes to {"q": Infinity}, which Python's JSON decoder reads back as the same float. Qwen3 inserts this string verbatim, so the row trains an invalid JSON tool call instead of being rejected. Set allow_nan=False so non-finite values follow the existing ValueError rejection path.

Medium severity Preserve valid tool names during carriage-return repair

src/​post_training/​data/​transforms.py:786

A bare carriage-return separator is treated as a lost initial r: wx.get(q='a')\rwx.get(q='b') becomes calls to wx.get and rwx.get. This silently changes the tool invocation and retains the unknown name. Consult the declared tool names before inserting a letter, preserving names that are already valid.

Medium severity Restrict newline repair to separators outside strings

src/​post_training/​data/​transforms.py:811

When a block contains both a literal \n separator and a string argument containing )\n, the original block fails tokenization and this global substitution rewrites both occurrences. For example, the raw block wx.get(q="a)\nb")\nwx.get(q="b") gains a real newline inside the quoted argument, so the entire otherwise-convertible row is dropped. Restrict this repair to separators outside string literals, including when the original block does not tokenize successfully.

3 resolved since last review

Review effort: Balanced

Comment thread src/post_training/data/transforms.py
Comment thread src/post_training/methods/sft.py
Neonkraft and others added 2 commits October 24, 2026 17:40
Refactor condition to improve readability and maintainability.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Dataset expressions can bypass the allocation guard and exhaust preprocessing worker memory.

3 open issues
1 resolved since last review

Review effort: Balanced

Comment on lines +657 to +661
elif isinstance(n, ast.Call) and isinstance(n.func, ast.Name) and n.func.id == "range":
bounds = [_small_int(a) for a in n.args]
if n.keywords or not 1 <= len(bounds) <= 3 or None in bounds or bounds[2:] == [0]:
return False
items *= max(len(range(*bounds)), 1)
@Neonkraft
Neonkraft merged commit 8f89db0 into main Oct 24, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

qwen3 template drops the tool-use fields of Dolci-Instruct-SFT

2 participants