huggingface/transformers · error · NotImplementedError

{self.__class__} is an abstract class. Only classes inheriti

Error message

{self.__class__} is an abstract class. Only classes inheriting this class can be called.

What it means

LogitsProcessor is an abstract base class; calling its __call__ directly raises NotImplementedError. Every concrete processor overrides __call__; instantiating the base class (or a subclass that forgot to override) and invoking it is a programming error.

Source

Thrown at src/transformers/generation/logits_process.py:58

            Prediction scores of a language modeling head. These can be logits for each vocabulary when not using beam
            search or log softmax for each vocabulary token when using beam search

    Return:
        `torch.FloatTensor` of shape `(batch_size, config.vocab_size)`: The processed prediction scores.

"""


class LogitsProcessor:
    """Abstract base class for all logit processors that can be applied during generation."""

    # Whether the logit processor is supported by continuous batching.
    # True if it is, False if it is not, None if it is not yet known.
    supports_continuous_batching: bool | None = None

    @add_start_docstrings(LOGITS_PROCESSOR_INPUTS_DOCSTRING)
    def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> torch.FloatTensor:
        raise NotImplementedError(
            f"{self.__class__} is an abstract class. Only classes inheriting this class can be called."
        )


class LogitsProcessorList(list):
    """
    This class can be used to create a list of [`LogitsProcessor`] to subsequently process a `scores` input tensor.
    This class inherits from list and adds a specific *__call__* method to apply each [`LogitsProcessor`] to the
    inputs.
    """

    def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor, **kwargs) -> torch.FloatTensor:
        r"""
        Args:
            input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`):
                Indices of input sequence tokens in the vocabulary. [What are input IDs?](../glossary#input-ids)
            scores (`torch.FloatTensor` of shape `(batch_size, config.vocab_size)`):
                Prediction scores of a language modeling head. These can be logits for each vocabulary when not using

View on GitHub (pinned to a597f97485)

Solutions

  1. Instantiate a concrete processor (e.g. TemperatureLogitsProcessor) instead of the base class
  2. In custom subclasses, implement __call__(self, input_ids, scores) with the exact signature
  3. For pass-through behavior, implement __call__ returning scores unchanged

Example fix

# before
processors = LogitsProcessorList([LogitsProcessor()])

# after
class NoopProcessor(LogitsProcessor):
    def __call__(self, input_ids, scores):
        return scores
processors = LogitsProcessorList([NoopProcessor()])
Defensive patterns

Strategy: type-guard

Validate before calling

from transformers.generation.logits_process import LogitsProcessor
for p in my_processors:
    assert type(p) is not LogitsProcessor, 'base class instantiated'
    assert p.__call__ is not LogitsProcessor.__call__, f'{type(p).__name__} does not override __call__'

Type guard

def is_concrete_processor(p) -> bool:
    return isinstance(p, LogitsProcessor) and LogitsProcessor.__call__ is not type(p).__call__

Prevention

When it happens

Trigger: lp = LogitsProcessor(); lp(input_ids, scores). Also a custom subclass that defines process() instead of __call__, or one whose __call__ is shadowed/renamed during refactoring.

Common situations: Placeholder processors added to a LogitsProcessorList in scaffolding code; copy-paste of a processor skeleton without implementing __call__; metaprogramming that instantiates the base class dynamically.

Related errors


AI-assisted analysis of huggingface/transformers@a597f97485 (2026-08-14). Data as JSON: /api/errors/cd0a30ca9d5872df. Report an issue: GitHub.