Skip to content

[Dataset] [Tool call] Add When2Call single-turn tool-use dataset#769

Closed
WindChimeRan wants to merge 1 commit into
vllm-project:mainfrom
WindChimeRan:add-when2call-dataset
Closed

[Dataset] [Tool call] Add When2Call single-turn tool-use dataset#769
WindChimeRan wants to merge 1 commit into
vllm-project:mainfrom
WindChimeRan:add-when2call-dataset

Conversation

@WindChimeRan

@WindChimeRan WindChimeRan commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Purpose

Add the When2Call dataset (nvidia/When2Call, train_sft config) as a predefined preset, to support tool-use / function-calling speculator training.

why:

  • We're adding on-policy tool-call regeneration; a single-turn tool-use dataset is the natural training fixture for it.
  • When2Call is a single-turn function-calling SFT dataset (originally for post-training) that also teaches when not to call a tool — useful signal for a draft model.
  • License CC-BY-4.0 (permissive). Verified no overlap with the nvidia/SPEED-Bench eval set — SPEED-Bench contains no function-calling data, and When2Call is not among its 24 source datasets.

Rebased onto main after #777, the followup that collapsed the two dataset registries into one. This is now a single entry in src/speculators/data_generation/configs.py — since #777 the regeneration script consumes that same registry, so the preset reaches both pipelines (prepare-data and --dataset) by construction, with no change to scripts/response_regeneration/script.py. docs/cli/response_regeneration.md gains the matching row.

Warning

Draft: on-policy regeneration is the wrong signal for this preset.

Because #777 makes every registry preset a valid --dataset by construction, this entry also enables --dataset when2call. That is not usable yet: When2Call rows are exactly [user, assistant] with no system turn, and the tool schemas live in a parallel tools column that never enters the conversation. On-policy regeneration would therefore send the model a bare user prompt with no tools attached and regenerate a prose answer — precisely the wrong supervision for a dataset whose purpose is teaching when not to call a tool. Off-policy prepare-data is unaffected.

Holding this as draft until the tool-aware regeneration path (#750) lands, or the preset is gated off-policy-only the way #777 gates sharegpt4v_coco.

Notes for reviewers

Tests

  • make quality (ruff check, ruff format, mdformat, mypy): clean.
  • pytest tests/unit/scripts tests/unit/data_generation: 49 passed.
  • Schema verified against the real data file — 2485 rows parsed from train/when2call_train_sft.jsonl: every row is exactly [user, assistant] (role/content) alongside a parallel tools column. No multi-turn rows, no system turns. Config/split resolve confirmed against the Hub API (train_sft config → train split, CC-BY-4.0).
  • Registry sanity: _normalize_when2call maps a real When2Call row to conversations while the tools column survives the map; prepare_row() on that row yields [user]; when2call appears in the --dataset CLI choices with script.py byte-identical to main.

Checklist

I have filled in:

  • The purpose of the PR, such as "Fix some issue (link existing issues this PR will resolve)".
  • The test plan/results, such as providing test command and pasting the results.
  • (Optional) The necessary documentation update.
  • I (a human) have written or reviewed the code in this pr to the best of my ability.

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

When2Call dataset support

Layer / File(s) Summary
When2Call normalization and registry
src/speculators/data_generation/configs.py
Adds When2Call normalization from messages to conversations and registers nvidia/When2Call with the train_sft subset and train split.
Regeneration CLI integration
scripts/response_regeneration/script.py
Adds when2call as a supported dataset using the existing regeneration pipeline configuration.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main change: adding the When2Call single-turn tool-use dataset preset.
Description check ✅ Passed The description is directly related to the changes and explains the new When2Call preset and its intended use.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@WindChimeRan WindChimeRan force-pushed the add-when2call-dataset branch from fc6b198 to a915d3b Compare July 10, 2026 23:03
@WindChimeRan WindChimeRan changed the title [Dataset] Add When2Call multi-turn tool-use dataset [Dataset] [Tool call] Add When2Call multi-turn tool-use dataset Jul 10, 2026
@WindChimeRan WindChimeRan marked this pull request as ready for review July 10, 2026 23:04

@orestis-z orestis-z left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM. Clean, well-scoped addition that follows the existing dataset preset patterns. Config matches the actual HuggingFace dataset schema (train_sft subset, train split, messages + tools columns). Recommend approving.

🤖 Generated with Claude Code using the /pr-review skill

@WindChimeRan WindChimeRan marked this pull request as draft July 11, 2026 03:25
@WindChimeRan WindChimeRan marked this pull request as ready for review July 11, 2026 19:32
@dsikka dsikka mentioned this pull request Jul 13, 2026
2 tasks
rahul-tuli pushed a commit that referenced this pull request Jul 14, 2026
…f-policy (#777)

## Purpose

Dataset-registry half of RFC #702. The regen script kept its own 3-entry
dataset dict alongside the shared registry in
`data_generation/configs.py`, so adding a dataset means editing both
files in two formats (e.g. #769, #771). Unblocked since #716: the script
already imports the package.

- **Commit 1 (pure refactor):** the script consumes the shared registry;
`DatasetConfig` gains `prompt_field`, the bare-prompt fallback column.
No behavior change.
- **Commit 2:** new `prepare_row()` applies a preset's
`filter_fn`/`normalize_fn` the same way prepare-data does, so every
registry preset is a valid `--dataset` — datasets work in both pipelines
by construction. `--resume` identity and the original three presets'
extracted turns are unchanged. Multimodal payloads (sharegpt4v_coco) and
tool-call regen semantics are follow-ups.

## Tests

- `pytest tests/unit/scripts tests/unit/data_generation`: 48 passed
(new: nemotron normalize-parity, filter_fn, map-merge fallback)
- `ruff check`, `ruff format --check`, `mypy --check-untyped-defs`:
clean
- CLI: `--help` offers all presets; `--dataset sharegpt` flows through
endpoint auto-detection

## Checklist

I have filled in:

- [x] The purpose of the PR, such as "Fix some issue (link existing
issues this PR will resolve)".
- [x] The test plan/results, such as providing test command and pasting
the results.
- [x] (Optional) The necessary documentation update.
- [x] I (a human) have written or reviewed the code in this pr to the
best of my ability.

---------

Signed-off-by: Ranran Haoran Zhang <ranzhang@redhat.com>
@mergify

mergify Bot commented Jul 14, 2026

Copy link
Copy Markdown

This pull request has merge conflicts that must be resolved before it can be
merged. Please rebase the PR, @WindChimeRan.

https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify mergify Bot added the needs-rebase label Jul 14, 2026
@WindChimeRan WindChimeRan force-pushed the add-when2call-dataset branch from a915d3b to 8868e41 Compare July 14, 2026 15:04
@WindChimeRan WindChimeRan marked this pull request as draft July 14, 2026 15:04
@mergify mergify Bot added the documentation Improvements or additions to documentation label Jul 14, 2026
Register nvidia/When2Call (train_sft config) in the shared dataset registry.
Since vllm-project#777 that registry is the single source of presets, so the entry serves
both pipelines: off-policy `prepare-data` and the on-policy regeneration
script's `--dataset`.

When2Call is a function-calling SFT dataset (CC-BY-4.0) that also teaches when
NOT to call a tool. Every row is a single user/assistant exchange with no system
turn; the conversation uses the OpenAI `messages` schema (normalized to
`conversations`), and the tool schemas ride along in a parallel `tools` column.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LRRGNt2T9ktWyFRboNUZNU
Signed-off-by: Ranran Haoran Zhang <ranzhang@redhat.com>
@WindChimeRan WindChimeRan force-pushed the add-when2call-dataset branch from 8868e41 to b59019d Compare July 14, 2026 15:06
@WindChimeRan WindChimeRan changed the title [Dataset] [Tool call] Add When2Call multi-turn tool-use dataset [Dataset] [Tool call] Add When2Call single-turn tool-use dataset Jul 14, 2026
@mergify mergify Bot removed the needs-rebase label Jul 14, 2026
@WindChimeRan

Copy link
Copy Markdown
Contributor Author

close as low value to speculator training.

shanjiaz added a commit that referenced this pull request Jul 14, 2026
## Purpose

Add the **Hermes function-calling** dataset
(`NousResearch/hermes-function-calling-v1`, `func_calling` config) as a
predefined preset — a function-calling SFT set (Apache-2.0) originally
for post-training.

why:

- Tool-use training fixture for the tool-call speculator work, alongside
When2Call (#769).
- Hermes `func_calling` is the canonical function-calling SFT dataset
(used to train Hermes 2 Pro) — genuine tool-call → tool-result → answer
trajectories.
- License **Apache-2.0**. Verified **no overlap** with the
`nvidia/SPEED-Bench` eval set (SPEED-Bench contains no function-calling
data; Hermes is not among its 24 sources).

Rebased onto `main` after #777, the followup that collapsed the two
dataset registries into one. This is now a **single** entry in
`src/speculators/data_generation/configs.py` — since #777 the
regeneration script consumes that same registry, so the preset reaches
both pipelines (`prepare-data` and `--dataset`) by construction, with no
change to `scripts/response_regeneration/script.py`.
`docs/cli/response_regeneration.md` gains the matching row.

### Notes for reviewers

- The dataset is already in `conversations` / ShareGPT `from,value` form
(same shape as the existing `sharegpt` preset), so it needs **no
`normalize_fn`** — the offline `_normalize_conversation` maps
`from/value` → canonical roles natively (`system → user → assistant →
tool → assistant`, verified).
- **Shape**, measured over 1299 rows parsed from `func-calling.json`:
each row is a *single* user request followed by a multi-step agentic
trajectory. Raw `from` sequences: `system → human → gpt → tool → gpt`
(927), `system → human → gpt` (199), `system → human → gpt → tool`
(163), `system → human → tool → gpt` (10). 1100/1299 rows carry a
tool-result turn; **no** row has more than one `human` turn.
"Multi-turn" here means the agentic exchange, not multiple user turns.
- Tool calls/results are **text-encoded** (`<tool_call>` /
`<tool_response>`) inside the turn value, not structured `tool_calls`
fields. Offline training on this is self-consistent (the system turn
embeds `<tools>`; the assistant emits `<tool_call>` text). The
structured tool-aware path (#750) will additionally need `<tool_call>`
parsing, and must avoid double-injecting the tool schema (the system
turn already contains `<tools>`) — out of scope here.
- The `tools` column is a single JSON string, which `_parse_conv_tools`
consumes via `json.loads`.
- **On-policy note.** #777 makes every registry preset a valid
`--dataset`, so this entry also enables `--dataset hermes-fc`. That is
coherent here: `prepare_row()` yields `[system, user]` and the system
turn still carries the `<tools>` schemas, so the model *does* see the
tools and can emit a `<tool_call>`. The tool-result rounds are dropped,
so only the first assistant turn is regenerated; full tool-call regen
semantics are #750. This is the difference from #769, which is held as
draft: When2Call keeps its tool schemas *outside* the conversation (a
parallel `tools` column), so on-policy regen there would see no tools at
all.

## Tests

- `make quality` (ruff check, ruff format, mdformat, mypy): clean.
- `pytest tests/unit/scripts tests/unit/data_generation`: **49 passed**.
- Schema verified against the real data file — 1299 rows parsed from
`func-calling.json`: `id` / `conversations` (from/value) / `tools` (JSON
string) / `category` / `subcategory` / `task`, with `<tool_call>` and
`<tool_response>` markup present inline. Config/split resolve confirmed
against the Hub API (`func_calling` config → `train` split, Apache-2.0).
- Registry sanity: `hermes-fc` entry is bare (`normalize_fn is None`);
the offline `_normalize_conversation` maps a real Hermes tool
conversation to `system/user/assistant/tool/assistant` with the
`<tool_call>` text preserved; `prepare_row()` on a real row yields
`[system, user]` with the `<tools>` schemas intact; `hermes-fc` appears
in the `--dataset` CLI choices with `script.py` byte-identical to
`main`.

## Checklist

I have filled in:

- [x] The purpose of the PR, such as "Fix some issue (link existing
issues this PR will resolve)".
- [x] The test plan/results, such as providing test command and pasting
the results.
- [x] (Optional) The necessary documentation update.
- [x] I (a human) have written or reviewed the code in this pr to the
best of my ability.

Signed-off-by: Ranran Haoran Zhang <ranzhang@redhat.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: shanjiaz <zsjwpianpian@gmail.com>
WindChimeRan added a commit to WindChimeRan/speculators that referenced this pull request Jul 15, 2026
When2Call (vllm-project#769) is closed, leaving Hermes (vllm-project#771) as the only tool dataset the
regenerator targets. Hermes' `tools` column is a JSON string of already
OpenAI-wrapped entries (verified: 3582 wrapped / 0 bare / 0 stringified across
all 1893 func_calling rows), so the per-entry coercion and the legacy `functions`
path had no live consumer.

Remove `_normalize_tool` (bare-spec wrapping + per-entry JSON-string decode, only
ever needed for When2Call's stringified bare specs) and the `functions` legacy
path. `extract_tools` now just reads the `tools` list (decoding a JSON-string
column) and keeps the fail-loud guard for a present-but-unusable field. Behaviour
is unchanged for Hermes, whose wrapped dicts already passed straight through.

Drop the now-dead stringified/bare test; the list-vs-non-list fail-loud cases
stay covered.

Signed-off-by: Ranran Haoran Zhang <ranzhang@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants