huggingface/transformers · error · ValueError
`penalty` has to be a strictly positive float, but is {penal
Error message
`penalty` has to be a strictly positive float, but is {penalty} What it means
Thrown by RepetitionPenaltyLogitsProcessor.__init__ when penalty is not a Python float or is <= 0. The penalty multiplies/divides logits of already-seen tokens, so a non-positive value has no valid meaning. The strict isinstance(penalty, float) check rejects ints even if positive (e.g. penalty=1 as int fails, 1.0 passes).
Source
Thrown at src/transformers/generation/logits_process.py:360
I'm not going to be able to do that. I'll just have to go out and play
>>> # We can also exclude the input prompt by creating an instance of this class
>>> # with a `prompt_ignore_length` and passing it as a custom logit processor
>>> rep_pen_processor = RepetitionPenaltyLogitsProcessor(
... penalty=1.1,
... prompt_ignore_length=inputs["input_ids"].shape[-1]
... )
>>> penalized_ids = model.generate(**inputs, logits_processor=[rep_pen_processor])
>>> print(tokenizer.batch_decode(penalized_ids, skip_special_tokens=True)[0])
I'm not going to be able to do that. I'm going to have to go through a lot of things, and
```
"""
supports_continuous_batching = False
def __init__(self, penalty: float, prompt_ignore_length: int | None = None):
if not isinstance(penalty, float) or not (penalty > 0):
raise ValueError(f"`penalty` has to be a strictly positive float, but is {penalty}")
if prompt_ignore_length is not None and (
not isinstance(prompt_ignore_length, int) or prompt_ignore_length < 0
):
raise ValueError(f"`prompt_ignore_length` has to be a positive integer, but is {prompt_ignore_length}")
self.penalty = penalty
self.prompt_ignore_length = prompt_ignore_length
self.logits_indices = None
self.cu_seq_lens_q = None
@add_start_docstrings(LOGITS_PROCESSOR_INPUTS_DOCSTRING)
def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> torch.FloatTensor:
if self.prompt_ignore_length:
input_ids = input_ids[:, self.prompt_ignore_length :]
if scores.dim() == 3:
if self.logits_indices is not None and self.cu_seq_lens_q is not None:View on GitHub (pinned to a597f97485)
Solutions
- Pass a positive float literal: RepetitionPenaltyLogitsProcessor(1.2)
- Wrap config-sourced values: RepetitionPenaltyLogitsProcessor(float(penalty)) after asserting penalty > 0
- If penalty == 1.0, skip adding the processor entirely — it is a mathematical no-op
Example fix
# before proc = RepetitionPenaltyLogitsProcessor(1) # int -> ValueError # after proc = RepetitionPenaltyLogitsProcessor(1.0) # or skip when neutral: procs = [] if penalty == 1 else [RepetitionPenaltyLogitsProcessor(float(penalty))]
Defensive patterns
Strategy: validation
Validate before calling
def valid_penalty(p):
return isinstance(p, float) and p > 0.0 Type guard
def is_valid_penalty(p) -> bool:
return type(p) is float and p > 0.0 Try / catch
try:
proc = RepetitionPenaltyLogitsProcessor(float(p))
except ValueError as e:
raise ValueError(f'Bad repetition_penalty={p!r}: {e}') from e Prevention
- Serialize repetition_penalty as float in configs (1.2, not 1)
- Skip the processor when penalty == 1.0 — it is a no-op
- Convert numpy scalars with float() before passing
When it happens
Trigger: RepetitionPenaltyLogitsProcessor(1) with an int (isinstance check fails); penalty=0.0 or a negative float; building this processor indirectly via model.generate(repetition_penalty=...) after generation config loads an int-typed value.
Common situations: Config files that store repetition_penalty: 1 (int) which some YAML loaders keep as int; intending penalty=1.0 (a no-op) but writing it as int; programmatic sweeps that step penalty in numpy int or int values.
Related errors
- `temperature` (={temperature}) has to be a strictly positive
- `prompt_ignore_length` has to be a positive integer, but is
- `top_k` has to be a strictly positive integer, but is {top_k
- `min_p` has to be a float in the [0, 1] interval, but is {mi
- `top_p` has to be a float > 0 and < 1, but is {top_p}
AI-assisted analysis of huggingface/transformers@a597f97485 (2026-08-14).
Data as JSON: /api/errors/ebfbdcba80914af6.
Report an issue: GitHub.