hankcs/HanLP · error · ValueError
invalid reduction: {reduction}
Error message
invalid reduction: {reduction} What it means
CRF.forward (used for compute_loss) reduces the total log-likelihood according to `reduction`, which must be one of 'none' (per-sequence), 'sum', 'mean' (batch mean), or 'token_mean' (mean per real token using the mask). Any other string raises ValueError.
Source
Thrown at hanlp/layers/crf/crf.py:111
``(seq_length, batch_size, num_tags)`` if ``batch_first`` is ``False``,
``(batch_size, seq_length, num_tags)`` otherwise.
tags (`~torch.LongTensor`): Sequence of tags tensor of size
``(seq_length, batch_size)`` if ``batch_first`` is ``False``,
``(batch_size, seq_length)`` otherwise.
mask (`~torch.ByteTensor`): Mask tensor of size ``(seq_length, batch_size)``
if ``batch_first`` is ``False``, ``(batch_size, seq_length)`` otherwise.
reduction: Specifies the reduction to apply to the output:
``none|sum|mean|token_mean``. ``none``: no reduction will be applied.
``sum``: the output will be summed over batches. ``mean``: the output will be
averaged over batches. ``token_mean``: the output will be averaged over tokens.
Returns:
`~torch.Tensor`: The log likelihood. This will have size ``(batch_size,)`` if
reduction is ``none``, ``()`` otherwise.
"""
self._validate(emissions, tags=tags, mask=mask)
if reduction not in ('none', 'sum', 'mean', 'token_mean'):
raise ValueError(f'invalid reduction: {reduction}')
if mask is None:
mask = torch.ones_like(tags, dtype=torch.uint8)
if self.batch_first:
emissions = emissions.transpose(0, 1)
tags = tags.transpose(0, 1)
mask = mask.transpose(0, 1)
# shape: (batch_size,)
numerator = self._compute_score(emissions, tags, mask)
# shape: (batch_size,)
denominator = self._compute_normalizer(emissions, mask)
# shape: (batch_size,)
llh = numerator - denominator
if reduction == 'none':
return llh
if reduction == 'sum':View on GitHub (pinned to ddb1299bdd)
Solutions
- Use 'none', 'sum', 'mean', or 'token_mean'
- For per-token normalization with padding, 'token_mean' is what you want (not a custom 'token' string)
Example fix
# before loss = crf(emissions, tags, mask, reduction='batch') # after loss = crf(emissions, tags, mask, reduction='token_mean')
Defensive patterns
Strategy: validation
Validate before calling
assert reduction in ('none', 'sum', 'mean', 'token_mean'), f'bad reduction {reduction!r}' Prevention
- Validate reduction strings at config load
When it happens
Trigger: Calling crf(emissions, tags, mask, reduction=...) with an unsupported value like 'batch_mean', 'avg', or None; often from custom training loops choosing their own normalization.
Common situations: Writing a custom criterion around the CRF; copying reduction names from other loss APIs (e.g. 'mean'/'sum' from CrossEntropyLoss are fine but extras like 'batch' are not).
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- invalid number of tags: {num_tags}
- Got average f{average}, expected one of None, 'token', or 'b
- activation must be callable: type={}
- DataParallel not supported when CRF is used
- emissions must have dimension of 3, got {emissions.dim()}
AI-assisted analysis of hankcs/HanLP@ddb1299bdd (2026-08-27).
Data as JSON: /api/errors/83004253627a8499.
Report an issue: GitHub.