[2/N][reward] feat: add pointwise audio HTTP reward support - #528
Conversation
Mechanically extracted from verl-project#428 at 06de576. Co-authored-by: GitHub Copilot Signed-off-by: dongbo910220 <1275604947@qq.com>
Keep the public transport test independent of the SpeechJudge integration that remains in verl-project#428. Co-authored-by: GitHub Copilot Signed-off-by: dongbo910220 <1275604947@qq.com>
Validate numeric scores and custom scorer selection, keep blocking waveform work off the event loop, and fail closed on cross-loop session reuse. Co-authored-by: OpenAI Codex <noreply@openai.com> Signed-off-by: dongbo910220 <1275604947@qq.com>
There was a problem hiding this comment.
🟡 Changes recommended
There are confirmed functional bugs in async scorer detection (partial-wrapped async functions) and waveform serialization (silently flattening non-1D waveforms) that can break real configurations.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR adds a model-agnostic audio reward path to verl-omni by introducing an AudioRewardManager that validates decoded waveforms from rollout extra_info, plus an async JSON-over-HTTP client for sending waveforms to an external scorer and retrieving a single finite scalar score. It also updates public docs and adds CPU tests covering key validation and retry behaviors.
Changes:
- Added
AudioRewardManagerto validate/route(waveform, sample_rate)to custom reward functions (sync or async). - Added
audio_http_scorer_clientimplementing a strict JSON protocol, connection reuse, and bounded retry logic for transient failures. - Added CPU tests and updated reward/HTTP scorer documentation to cover the new audio scoring pathway.
File summaries
| File | Description |
|---|---|
| verl_omni/utils/reward_score/audio_http_scorer_client.py | New async JSON HTTP client for pointwise audio reward scoring, with strict request/response validation and retries. |
| verl_omni/reward_loop/reward_manager/audio.py | New reward manager that extracts/validates waveforms from rollout data and calls a custom scorer per sample. |
| verl_omni/reward_loop/reward_manager/init.py | Exports AudioRewardManager from the reward_manager package. |
| tests/utils/reward_score/test_audio_http_scorer_client_on_cpu.py | CPU tests for audio HTTP client protocol validation, retry behavior, session reuse, and thread offloading. |
| tests/reward_loop/test_audio_reward_manager_on_cpu.py | CPU tests for waveform validation/extraction, sync+async scorers, and failure modes. |
| docs/start/http_scorer.md | Documents the audio HTTP scorer client JSON protocol and retry/fail-closed behavior. |
| docs/api/reward.rst | Adds AudioRewardManager and audio_http_scorer_client to public reward API documentation. |
Review details
- Files reviewed: 7/7 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| super().__init__(config, tokenizer, compute_score) | ||
| self.is_async_reward_score = inspect.iscoroutinefunction(compute_score) | ||
| self.reward_router_address = reward_router_address |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Ruihang Li <162420497+ruihanglix@users.noreply.github.com>
Apply the repository formatter to the collaborator-added guard and add a regression case for rejecting multidimensional waveforms. Co-authored-by: GitHub Copilot Signed-off-by: dongbo910220 <1275604947@qq.com>
|
approvable after the evidence line is fixed; nothing unnecessary or fallback-shaped found — dual-layout audio extraction matches what the agent loop and
AI assistance (ZCode) was used for this review. |
Pass the optional reward router address, reward model tokenizer, and model name to audio custom scorers, matching the visual reward manager contract. Co-authored-by: GitHub Copilot Signed-off-by: dongbo910220 <1275604947@qq.com>
|
@zhtmike Thanks for the review.
|
|
All CI green, thanks for the work |
Merge the latest upstream main containing PRs verl-project#527 and verl-project#528, keep their public utility implementations unchanged, and update the Qwen3-TTS CPU contract tests for the finalized rollout API. Co-authored-by: GitHub Copilot Signed-off-by: dongbo910220 <1275604947@qq.com>
Preserve the public hooks and audio reward implementation merged through PRs verl-project#527 and verl-project#528 while integrating the latest upstream main. Fail closed on malformed Qwen3-TTS decoder waveforms and document the tiny-random GPU smoke fixture accurately. Co-authored-by: GitHub Copilot <copilot@github.com> Signed-off-by: dongbo910220 <1275604947@qq.com>
What does this PR do?
This PR adds generic pointwise audio reward support for rollouts that already contain a decoded waveform:
AudioRewardManagervalidates and forwards one waveform and sample rate per sample to a custom reward function;audio_http_scorer_clientsends a strict JSON request to an external scorer and returns one finite scalar score;This does not duplicate #282. That PR implements a Qwen3-TTS-specific training pipeline with reward-side codec decoding and multiple reward modes. This PR is model-agnostic: it accepts an already-decoded waveform and implements only the pointwise reward-manager and HTTP transport boundary.
Checklist Before Starting
[{modules}] {type}: {description}(This will be checked by the CI)Test
all passed
API and Usage Example
The scorer receives JSON with a base64-encoded float32 waveform, sample rate, prompt, and scalar metadata. It must return
{"score": <finite number>}.Design & Code Changes
audioandaudio_sample_ratein rolloutextra_infoand reject malformed, empty, multi-sample, or non-finite waveforms.aiohttp.ClientSessionper event loop and retry only transient network, timeout, HTTP 408/429, and 5xx failures.Checklist Before Submitting
pre-commit install && pre-commit run --all-files --show-diff-on-failure --color=always