[Dataset] [Tool call] Add Hermes function-calling dataset#771
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughChangesHermes function-calling dataset registration
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
731bd12 to
a7a2d19
Compare
orestis-z
left a comment
There was a problem hiding this comment.
LGTM. Clean, minimal config addition — follows existing patterns in both registries, and _normalize_conversation already handles the from/value schema (including tool turns) natively. Recommend approving.
🤖 Generated with Claude Code using the /pr-review skill
…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>
|
This pull request has merge conflicts that must be resolved before it can be |
a7a2d19 to
49ba4a4
Compare
Register NousResearch/hermes-function-calling-v1 (func_calling 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`. Hermes func_calling is a function-calling SFT dataset (Apache-2.0) already in ShareGPT from/value form, so it needs no normalizer (like the existing sharegpt preset). Each row is a single user request followed by a multi-step agentic trajectory: system -> human -> gpt -> tool -> gpt in the common case. Tool calls and results are text-encoded (<tool_call>/<tool_response>) inline; the parallel `tools` column carries the JSON schemas as a JSON string. 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>
49ba4a4 to
65a2b5e
Compare
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>
Purpose
Add the Hermes function-calling dataset (
NousResearch/hermes-function-calling-v1,func_callingconfig) as a predefined preset — a function-calling SFT set (Apache-2.0) originally for post-training.why:
func_callingis the canonical function-calling SFT dataset (used to train Hermes 2 Pro) — genuine tool-call → tool-result → answer trajectories.nvidia/SPEED-Bencheval set (SPEED-Bench contains no function-calling data; Hermes is not among its 24 sources).Rebased onto
mainafter #777, the followup that collapsed the two dataset registries into one. This is now a single entry insrc/speculators/data_generation/configs.py— since #777 the regeneration script consumes that same registry, so the preset reaches both pipelines (prepare-dataand--dataset) by construction, with no change toscripts/response_regeneration/script.py.docs/cli/response_regeneration.mdgains the matching row.Notes for reviewers
conversations/ ShareGPTfrom,valueform (same shape as the existingsharegptpreset), so it needs nonormalize_fn— the offline_normalize_conversationmapsfrom/value→ canonical roles natively (system → user → assistant → tool → assistant, verified).func-calling.json: each row is a single user request followed by a multi-step agentic trajectory. Rawfromsequences: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 onehumanturn. "Multi-turn" here means the agentic exchange, not multiple user turns.<tool_call>/<tool_response>) inside the turn value, not structuredtool_callsfields. Offline training on this is self-consistent (the system turn embeds<tools>; the assistant emits<tool_call>text). The structured tool-aware path ([Regen][tool call] Support tool calls in on-policy response regeneration #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.toolscolumn is a single JSON string, which_parse_conv_toolsconsumes viajson.loads.--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 [Regen][tool call] Support tool calls in on-policy response regeneration #750. This is the difference from [Dataset] [Tool call] Add When2Call single-turn tool-use dataset #769, which is held as draft: When2Call keeps its tool schemas outside the conversation (a paralleltoolscolumn), 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.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_callingconfig →trainsplit, Apache-2.0).hermes-fcentry is bare (normalize_fn is None); the offline_normalize_conversationmaps a real Hermes tool conversation tosystem/user/assistant/tool/assistantwith the<tool_call>text preserved;prepare_row()on a real row yields[system, user]with the<tools>schemas intact;hermes-fcappears in the--datasetCLI choices withscript.pybyte-identical tomain.Checklist
I have filled in: