huggingface/open-r1 · error
max_penalty {max_penalty} should not be positive
Error message
max_penalty {max_penalty} should not be positive What it means
get_repetition_penalty_reward requires max_penalty to be non-positive: it is the maximum (negative) penalty applied to repetitive completions. Passing a positive value is treated as a logic error and rejected with this ValueError before any reward computation.
Source
Thrown at src/open_r1/rewards.py:296
rewards.append(float(reward))
return rewards
return cosine_scaled_reward
def get_repetition_penalty_reward(ngram_size: int, max_penalty: float, language: str = "en"):
"""
Computes N-gram repetition penalty as described in Appendix C.2 of https://huggingface.co/papers/2502.03373.
Reference implementation from: https://github.com/eddycmu/demystify-long-cot/blob/release/openrlhf/openrlhf/reward/repetition.py
Args:
ngram_size: size of the n-grams
max_penalty: Maximum (negative) penalty for wrong answers
language: Language of the text, defaults to `en`. Used to choose the way to split the text into n-grams.
"""
if max_penalty > 0:
raise ValueError(f"max_penalty {max_penalty} should not be positive")
if language == "en":
def zipngram(text: str, ngram_size: int):
words = text.lower().split()
return zip(*[words[i:] for i in range(ngram_size)]), words
elif language == "zh":
from transformers.utils.import_utils import _is_package_available
if not _is_package_available("jieba"):
raise ValueError("Please install jieba to use Chinese language")
def zipngram(text: str, ngram_size: int):
import jieba
seg_list = list(jieba.cut(text))
return zip(*[seg_list[i:] for i in range(ngram_size)]), seg_listView on GitHub (pinned to 1416fa0cf2)
Solutions
- Pass a non-positive max_penalty, e.g. max_penalty=-1.0 for full repetition penalty.
- If you want a milder penalty, move closer to 0 from below, e.g. -0.5.
- Review the docstring: it is the 'Maximum (negative) penalty', so negate your intended magnitude.
Example fix
// before reward = get_repetition_penalty_reward(ngram_size=3, max_penalty=1.0) // after reward = get_repetition_penalty_reward(ngram_size=3, max_penalty=-1.0)
Defensive patterns
Strategy: validation
Validate before calling
if max_penalty > 0:
max_penalty = -abs(max_penalty) # or reject upstream Type guard
def is_valid_max_penalty(v) -> bool:
return isinstance(v, (int, float)) and v <= 0 Try / catch
try:
reward = get_repetition_penalty_reward(ngram_size=n, max_penalty=p, language=lang)
except ValueError as e:
if "should not be positive" in str(e):
reward = get_repetition_penalty_reward(ngram_size=n, max_penalty=-abs(p), language=lang)
else:
raise Prevention
- Remember the sign convention: penalties are negative
- Clamp/abs-negate config values before constructing reward funcs
- Add a unit test asserting max_penalty <= 0 in reward factory configs
When it happens
Trigger: get_repetition_penalty_reward(ngram_size=..., max_penalty=1.0, ...) — any max_penalty > 0, e.g. 0.5 or 1.0, often from copying a 'reward weight' style positive value.
Common situations: Misunderstanding the sign convention (thinking larger positive = stronger penalty); wiring a config value meant for a different reward function; inverting a scale during refactoring.
Understand the failure class
Background: "must be positive", "Invalid value": how libraries reject invalid parameter values (ValueError, ArgumentError, INVALID_PARAMETER_VALUE) — this error's family across 28 libraries.
Related errors
- Word splitting for language `{language}` is not yet implemen
- All verification_info must have the same language
- Either `dataset_name` or `dataset_mixture` must be provided
- Dataset Question Field Error: {prompt_column} is not support
- Please install jieba to use Chinese language
AI-assisted analysis of huggingface/open-r1@1416fa0cf2 (2026-08-30).
Data as JSON: /api/errors/381038f6b4c445ec.
Report an issue: GitHub.