PaddlePaddle/PaddleOCR · error · ValueError
The mode.lower() if KLJSLoss should be one of ['kl', 'js']
Error message
The mode.lower() if KLJSLoss should be one of ['kl', 'js']
What it means
KLJSLoss implements only two divergence modes: 'kl' (symmetrized KL, first branch) and 'js' (Jensen-Shannon, second branch). The comparison is done on self.mode.lower(), so case is irrelevant, but any other string (e.g. 'JS ' with whitespace, 'kl_div', 'JSdiv') falls into the else and raises ValueError at forward time.
Source
Thrown at ppocr/losses/basic_loss.py:81
"JS",
], "mode can only be one of ['kl', 'KL', 'js', 'JS']"
self.mode = mode
def __call__(self, p1, p2, reduction="mean", eps=1e-5):
if self.mode.lower() == "kl":
loss = paddle.multiply(p2, paddle.log((p2 + eps) / (p1 + eps) + eps))
loss += paddle.multiply(p1, paddle.log((p1 + eps) / (p2 + eps) + eps))
loss *= 0.5
elif self.mode.lower() == "js":
loss = paddle.multiply(
p2, paddle.log((2 * p2 + eps) / (p1 + p2 + eps) + eps)
)
loss += paddle.multiply(
p1, paddle.log((2 * p1 + eps) / (p1 + p2 + eps) + eps)
)
loss *= 0.5
else:
raise ValueError(
"The mode.lower() if KLJSLoss should be one of ['kl', 'js']"
)
if reduction == "mean":
loss = paddle.mean(loss, axis=[1, 2])
elif reduction == "none" or reduction is None:
return loss
else:
loss = paddle.sum(loss, axis=[1, 2])
return loss
class DMLLoss(nn.Layer):
"""
DMLLoss
"""
View on GitHub (pinned to 2661c7c0ef)
Solutions
- Set the loss mode to exactly 'kl' or 'js' (case-insensitive) in the config/constructor
- Check the distillation config block that instantiates KLJSLoss and fix the mode key's value
- Strip/normalize the string if it comes from user input: mode.strip().lower() before passing
Example fix
# before KLJSLoss(mode='jsd') # ValueError at forward # after KLJSLoss(mode='js')
Defensive patterns
Strategy: validation
Validate before calling
mode = mode.strip().lower()
assert mode in ('kl', 'js'), f"KLJSLoss mode must be 'kl' or 'js', got {mode!r}"
loss = KLJSLoss(mode=mode) Type guard
def is_kljs_mode(m: str) -> bool:
return isinstance(m, str) and m.strip().lower() in ('kl', 'js') Prevention
- Validate loss-mode strings in your config loader against a whitelist per loss class
- Linter/schema-validate YAML loss blocks (allowed values per loss name) before training
- Remember comparison is case-insensitive but whitespace-sensitive
When it happens
Trigger: Constructing KLJSLoss(mode='kd') or any string other than 'kl'/'js' (in any casing) and calling its forward; typical in distillation configs where mode is chosen per loss item.
Common situations: Typo in a distillation YAML (model_name/loss config under Loss for DistillationModel), copying a mode name from another framework ('kld', 'jsd'), or trailing whitespace in the config string.
Related errors
- main_loss_type in BalanceLoss() can only be one of {}
- [DBLoss]: Unrecognized main loss type!
- error!!!!!!
- {} is not supported in MultiLoss yet
- mode[{mode}_model] is not implemented!
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/ffb31420d58e0bb7.
Report an issue: GitHub.