|
76 | 76 |
|
77 | 77 | TokenizerType = PreTrainedTokenizerBase |
78 | 78 |
|
| 79 | +_REWARD_PENALTY_METRICS = { |
| 80 | + "duplicated_reasoning": ( |
| 81 | + "penalize_duplicated_reasoning", |
| 82 | + "reasoning_equal_to_final_answer_rate", |
| 83 | + ), |
| 84 | + "empty_final_answer": ( |
| 85 | + "penalize_empty_final_answer", |
| 86 | + "empty_final_answer_rate", |
| 87 | + ), |
| 88 | + "unwanted_token": ("penalize_unwanted_tokens", "unwanted_token_rate"), |
| 89 | + "malformed_think_tag": ( |
| 90 | + "penalize_malformed_think_tag", |
| 91 | + "malformed_think_tag_rate", |
| 92 | + ), |
| 93 | +} |
| 94 | + |
79 | 95 |
|
80 | 96 | def attach_initial_nemo_gym_image_payloads( |
81 | 97 | batch: BatchedDataDict[DatumSpec], |
@@ -1875,6 +1891,22 @@ def _get_reward_penalty_config_value( |
1875 | 1891 | return getattr(reward_penalty_config, key, None) |
1876 | 1892 |
|
1877 | 1893 |
|
| 1894 | +def compute_reward_penalty_metrics( |
| 1895 | + penalty_counts: dict[str, int], |
| 1896 | + num_results: int, |
| 1897 | + reward_penalty_config: dict[str, Any] | BaseModel | None, |
| 1898 | +) -> dict[str, float]: |
| 1899 | + """Return enabled penalty rates using the legacy NeMo-Gym metric names.""" |
| 1900 | + if reward_penalty_config is None or not num_results: |
| 1901 | + return {} |
| 1902 | + |
| 1903 | + return { |
| 1904 | + metric_name: penalty_counts[count_key] / num_results |
| 1905 | + for count_key, (flag, metric_name) in _REWARD_PENALTY_METRICS.items() |
| 1906 | + if _get_reward_penalty_config_value(reward_penalty_config, flag) |
| 1907 | + } |
| 1908 | + |
| 1909 | + |
1878 | 1910 | def _get_reward_penalty_token_id( |
1879 | 1911 | reward_penalty_config: dict[str, Any] | BaseModel, |
1880 | 1912 | key: str, |
@@ -2823,26 +2855,13 @@ def _postprocess_single_nemo_gym_group( |
2823 | 2855 |
|
2824 | 2856 | rollout_metrics.update(_effort_shaping_metrics(shaping)) |
2825 | 2857 |
|
2826 | | - # Penalty metrics — map count keys to (config flag, metric name) |
2827 | | - _PENALTY_METRICS = { |
2828 | | - "duplicated_reasoning": ( |
2829 | | - "penalize_duplicated_reasoning", |
2830 | | - "reasoning_equal_to_final_answer_rate", |
2831 | | - ), |
2832 | | - "empty_final_answer": ( |
2833 | | - "penalize_empty_final_answer", |
2834 | | - "empty_final_answer_rate", |
2835 | | - ), |
2836 | | - "unwanted_token": ("penalize_unwanted_tokens", "unwanted_token_rate"), |
2837 | | - "malformed_think_tag": ( |
2838 | | - "penalize_malformed_think_tag", |
2839 | | - "malformed_think_tag_rate", |
2840 | | - ), |
2841 | | - } |
2842 | | - if resolved_reward_penalty_config and results: |
2843 | | - for key, (flag, metric_name) in _PENALTY_METRICS.items(): |
2844 | | - if _get_reward_penalty_config_value(resolved_reward_penalty_config, flag): |
2845 | | - rollout_metrics[metric_name] = penalty_counts[key] / len(results) |
| 2858 | + rollout_metrics.update( |
| 2859 | + compute_reward_penalty_metrics( |
| 2860 | + penalty_counts, |
| 2861 | + len(results), |
| 2862 | + resolved_reward_penalty_config, |
| 2863 | + ) |
| 2864 | + ) |
2846 | 2865 |
|
2847 | 2866 | # Expose per-component rewards as `reward/<name>` batch keys for multi-reward NeMo |
2848 | 2867 | # Gym environments so GDPO can compute per-component advantages; single-reward envs |
|
0 commit comments