Skip to content

[reward] feat: expose valid_response_length and max_resp_len in extra_info - #7063

Open
Secbone wants to merge 5 commits into
verl-project:mainfrom
Secbone:feat/extra-info-valid-response-length
Open

[reward] feat: expose valid_response_length and max_resp_len in extra_info#7063
Secbone wants to merge 5 commits into
verl-project:mainfrom
Secbone:feat/extra-info-valid-response-length

Conversation

@Secbone

@Secbone Secbone commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Expose valid_response_length and max_resp_len in the reward_extra_info dict of DAPORewardManager. These values were already computed internally but were not written to the batch output, making them inaccessible to downstream consumers for logging and analysis.

Checklist Before Starting

  • Search for similar PRs. Paste at least one query link here: gh pr list --search "extra_info valid_response_length" — no duplicates found.
  • Format the PR title as [{modules}] {type}: {description} (This will be checked by the CI)
    • {modules} include fsdp, megatron, veomni, sglang, vllm, rollout, trainer, ci, training_utils, recipe, hardware, deployment, ray, worker, single_controller, misc, perf, model, algo, env, tool, ckpt, doc, data, cfg, reward, fully_async, one_step_off
    • If this PR involves multiple modules, separate them with , like [megatron, fsdp, doc]
    • {type} is in feat, fix, refactor, chore, test
    • If this PR breaks any API (CLI arguments, config, function signature, etc.), add [BREAKING] to the beginning of the title.
    • Example: [BREAKING][fsdp, megatron] feat: dynamic batching

Test

pytest tests/workers/reward_manager/test_dapo_on_cpu.py::test_call_return_dict_includes_valid_response_and_max_resp_len -v

Unit test verifies that valid_response_length and max_resp_len appear in reward_extra_info when return_dict=True.

API and Usage Example

# Values are now available in the output batch
reward_extra_info["valid_response_length"]  # list of per-sample response lengths
reward_extra_info["max_resp_len"]           # list of per-sample max response lengths

Design & Code Changes

  • verl/workers/reward_manager/dapo.py: 2 lines changed — write valid_response_length and max_resp_len to reward_extra_info (which is explicitly returned to the caller) instead of the non-persistent extra_info dict.
  • tests/workers/reward_manager/test_dapo_on_cpu.py: Add unit test verifying the new keys appear in reward_extra_info.

Checklist Before Submitting

Important

Please check all the following items before requesting a review, otherwise the reviewer might deprioritize this PR for review.

…_info

Add valid_response_length and max_resp_len to extra_info dict in
DAPORewardManager so downstream consumers have access to per-sample
response lengths for logging and analysis.

These values were already computed internally but not exposed.

Co-authored-by: Claude
Signed-off-by: Secbone <secbone@gmail.com>

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request adds valid_response_length and max_resp_len to extra_info in the DAPO reward manager. However, modifying extra_info in-place is problematic because it may not write back to the batch and will be lost in distributed environments due to Ray actor isolation. It is recommended to append these metrics to reward_extra_info instead.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread verl/workers/reward_manager/dapo.py Outdated
Comment on lines +132 to +133
extra_info["valid_response_length"] = valid_response_length
extra_info["max_resp_len"] = self.max_resp_len

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.

high

Modifying extra_info in-place here has two major issues that prevent downstream consumers from accessing these values:

  1. No Write-Back: extra_info is retrieved via data_item.non_tensor_batch.get("extra_info", {}). If "extra_info" is not present in non_tensor_batch, a new dictionary is created. Modifying this dictionary in-place does not write it back to data_item.non_tensor_batch.
  2. Ray Actor Isolation: In a distributed training setup, DAPORewardManager typically runs as a Ray actor. Since arguments and return values are serialized/deserialized (passed by value), any in-place modifications to data or data_item inside the actor are lost and not propagated back to the caller.

To correctly expose these metrics to downstream consumers (e.g., for logging), they should be appended to reward_extra_info, which is returned to the caller when return_dict=True.

Suggested change
extra_info["valid_response_length"] = valid_response_length
extra_info["max_resp_len"] = self.max_resp_len
reward_extra_info["valid_response_length"].append(valid_response_length)
reward_extra_info["max_resp_len"].append(self.max_resp_len)

…d of extra_info

extra_info from non_tensor_batch.get() may not persist across Ray
serialization boundaries. reward_extra_info is explicitly returned to
the caller, making it the correct channel for per-sample metrics.

Co-authored-by: Claude
Signed-off-by: Secbone <secbone@gmail.com>
@Secbone
Secbone force-pushed the feat/extra-info-valid-response-length branch from d65e64c to 26e08c7 Compare July 16, 2026 07:28
Secbone added 2 commits July 17, 2026 11:44
…ward_extra_info

Co-authored-by: Claude

Signed-off-by: Secbone <secbone@gmail.com>
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.

1 participant