hankcs/HanLP · error · ValueError

Got average f , expected one of None, 'token', or 'batch

Error message

Got average f{average}, expected one of None, 'token', or 'batch'

What it means

sequence_cross_entropy validates its `average` argument, which controls how the per-token loss is aggregated (None = sum, 'token' = per-token mean, 'batch' = per-sequence mean). Any other string (e.g. 'sentence', 'sample', or a typo like 'Batch') is rejected. This mirrors AllenNLP's sequence_cross_entropy_with_logits helper that HanLP vendors for the UD parser (udify).

Solutions

  1. Set average to one of None, 'token', or 'batch' (default is 'batch')
  2. If you need per-sentence normalization, use 'batch'; for per-token use 'token'; for unnormalized sum use None
  3. Check for typos in the value passed by your config/CLI

Example fix

// before
loss = sequence_cross_entropy(log_probs, targets, weights, average='samples')
// after
loss = sequence_cross_entropy(log_probs, targets, weights, average='batch')
Defensive patterns

Strategy: validation

Validate before calling

assert average in (None, 'token', 'batch'), f"bad average: {average!r}"

Prevention

When it happens

Trigger: Calling sequence_cross_entropy (directly or via udify's _adaptive_loss) with average set to anything outside {None, 'token', 'batch'}, e.g. passing a config value like 'epoch' or a misspelled 'tokem'.

Common situations: Customizing the loss aggregation in a copied udify training script; passing an aggregation string from another library (e.g. Keras 'auto' or sklearn conventions) into this function.

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


AI-assisted analysis of hankcs/HanLP@ddb1299bdd (2026-08-27). Data as JSON: /api/errors/2c1cf47d1658bca6. Report an issue: GitHub.

Appendix: source

Thrown at hanlp/components/parsers/ud/udify_util.py:70

        train_file = [file for file in conllu_files if file.endswith("train.conllu")]
        dev_file = [file for file in conllu_files if file.endswith("dev.conllu")]
        test_file = [file for file in conllu_files if file.endswith("test.conllu")]

        train_file = os.path.join(treebank_path, train_file[0]) if train_file else None
        dev_file = os.path.join(treebank_path, dev_file[0]) if dev_file else None
        test_file = os.path.join(treebank_path, test_file[0]) if test_file else None

        datasets[treebank] = (train_file, dev_file, test_file)
    return datasets


def sequence_cross_entropy(log_probs: torch.FloatTensor,
                           targets: torch.LongTensor,
                           weights: torch.FloatTensor,
                           average: str = "batch",
                           label_smoothing: float = None) -> torch.FloatTensor:
    if average not in {None, "token", "batch"}:
        raise ValueError("Got average f{average}, expected one of "
                         "None, 'token', or 'batch'")
    # shape : (batch * sequence_length, num_classes)
    log_probs_flat = log_probs.view(-1, log_probs.size(2))
    # shape : (batch * max_len, 1)
    targets_flat = targets.view(-1, 1).long()

    if label_smoothing is not None and label_smoothing > 0.0:
        num_classes = log_probs.size(-1)
        smoothing_value = label_smoothing / num_classes
        # Fill all the correct indices with 1 - smoothing value.
        one_hot_targets = torch.zeros_like(log_probs_flat).scatter_(-1, targets_flat, 1.0 - label_smoothing)
        smoothed_targets = one_hot_targets + smoothing_value
        negative_log_likelihood_flat = - log_probs_flat * smoothed_targets
        negative_log_likelihood_flat = negative_log_likelihood_flat.sum(-1, keepdim=True)
    else:
        # Contribution to the negative log likelihood only comes from the exact indices
        # of the targets, as the target distributions are one-hot. Here we use torch.gather
        # to extract the indices of the num_classes dimension which contribute to the loss.

View on GitHub (pinned to ddb1299bdd)