Summary
An explicit until: null generation setting is normalized to [None] instead
of an empty stop-sequence list. Shared generation paths can then pass that
invalid element to a backend or crash during generated-text post-processing.
This is especially relevant when a task author wants generation to rely on the
model's native end-of-sequence token without adding a task-specific stop string.
Reproduction
Use a generation task containing:
generation_kwargs:
until: null
The underlying behavior can be reproduced without loading a model:
from lm_eval.models.utils import normalize_gen_kwargs, postprocess_generated_text
kwargs = normalize_gen_kwargs({"until": None})
print(kwargs["until"])
postprocess_generated_text("answer", kwargs["until"], None)
Observed behavior
Normalization produces:
Post-processing then raises:
TypeError: object of type 'NoneType' has no len()
Expected behavior
An explicit None should use the same semantics already supported by the stop
sequence helper: no task-provided stop strings, represented as []. Individual
backends can still add the model EOS token where appropriate.
Root cause and impact
YAML null becomes Python None. Because the until key is present, task
configuration preserves that explicit value. The shared generation-argument
normalizer wraps every non-list value in a list, so None becomes [None].
Downstream code treats list members as strings; for example, text
post-processing calls len() on each member.
The normalizer is shared by multiple model backends, so this is not limited to
one integration. Depending on the backend, the invalid value can fail before
inference or after generation has already completed.
Proposed resolution
Handle None before the generic scalar-to-list conversion and normalize it to
an empty list. Preserve the existing behavior for strings, lists, and omitted
values, and add regression coverage for explicit None.
Related to the native-EOS configuration discussion in #1837, but this report is
specifically about the invalid [None] normalization and resulting crash.
Summary
An explicit
until: nullgeneration setting is normalized to[None]insteadof an empty stop-sequence list. Shared generation paths can then pass that
invalid element to a backend or crash during generated-text post-processing.
This is especially relevant when a task author wants generation to rely on the
model's native end-of-sequence token without adding a task-specific stop string.
Reproduction
Use a generation task containing:
The underlying behavior can be reproduced without loading a model:
Observed behavior
Normalization produces:
Post-processing then raises:
Expected behavior
An explicit
Noneshould use the same semantics already supported by the stopsequence helper: no task-provided stop strings, represented as
[]. Individualbackends can still add the model EOS token where appropriate.
Root cause and impact
YAML
nullbecomes PythonNone. Because theuntilkey is present, taskconfiguration preserves that explicit value. The shared generation-argument
normalizer wraps every non-list value in a list, so
Nonebecomes[None].Downstream code treats list members as strings; for example, text
post-processing calls
len()on each member.The normalizer is shared by multiple model backends, so this is not limited to
one integration. Depending on the backend, the invalid value can fail before
inference or after generation has already completed.
Proposed resolution
Handle
Nonebefore the generic scalar-to-list conversion and normalize it toan empty list. Preserve the existing behavior for strings, lists, and omitted
values, and add regression coverage for explicit
None.Related to the native-EOS configuration discussion in #1837, but this report is
specifically about the invalid
[None]normalization and resulting crash.