PaddlePaddle/PaddleOCR · error · ValueError
Cannot use sin/cos positional encoding with odd dimension (g
Error message
Cannot use sin/cos positional encoding with odd dimension (got dim={:d}) What it means
positionalencoding2d in TBSRN builds sine/cos positional encodings by splitting d_model into two halves and then stepping by 2, which requires d_model % 4 == 0. Odd or non-multiple-of-4 dims would break the arithmetic, so the function raises ValueError up front.
Source
Thrown at ppocr/modeling/transforms/tbsrn.py:47
from .stn import STN as STNHead
from .tsrn import GruBlock, mish, UpsampleBLock
from ppocr.modeling.heads.sr_rensnet_transformer import (
Transformer,
LayerNorm,
PositionwiseFeedForward,
MultiHeadedAttention,
)
def positionalencoding2d(d_model, height, width):
"""
:param d_model: dimension of the model
:param height: height of the positions
:param width: width of the positions
:return: d_model*height*width position matrix
"""
if d_model % 4 != 0:
raise ValueError(
"Cannot use sin/cos positional encoding with "
"odd dimension (got dim={:d})".format(d_model)
)
pe = paddle.zeros([d_model, height, width])
# Each dimension use half of d_model
d_model = int(d_model / 2)
div_term = paddle.exp(
paddle.arange(0.0, d_model, 2, dtype="int64") * -(math.log(10000.0) / d_model)
)
pos_w = paddle.arange(0.0, width, dtype="float32").unsqueeze(1)
pos_h = paddle.arange(0.0, height, dtype="float32").unsqueeze(1)
pe[0:d_model:2, :, :] = (
paddle.sin(pos_w * div_term).transpose([1, 0]).unsqueeze(1).tile([1, height, 1])
)
pe[1:d_model:2, :, :] = (
paddle.cos(pos_w * div_term).transpose([1, 0]).unsqueeze(1).tile([1, height, 1])
)View on GitHub (pinned to 2661c7c0ef)
Solutions
- Set d_model in the TBSRN config to a multiple of 4 (e.g. 384, 512)
- If a custom dim is mandatory, pad the embedding to the next multiple of 4 before encoding
Example fix
# before Transform: name: TBSRN d_model: 386 # after Transform: name: TBSRN d_model: 384
Defensive patterns
Strategy: validation
Validate before calling
assert cfg['d_model'] % 4 == 0, f"d_model must be a multiple of 4 for sin/cos 2D PE, got {cfg['d_model']}" Type guard
def valid_pe_dim(d_model: int) -> bool:
return isinstance(d_model, int) and d_model > 0 and d_model % 4 == 0 Prevention
- Choose model widths from multiples of 4 (and of num_heads) by convention
- Add a config-time divisibility assert for TBSRN d_model
When it happens
Trigger: Constructing/running TBSRN with d_model not divisible by 4 (e.g. 386, 390, or an odd value), typically from the Transform config's d_model or hidden dim.
Common situations: Editing TBSRN configs to tune model width; reusing the function elsewhere with an arbitrary embedding dim; merging configs from different text recognition models.
Related errors
- OCR pipeline config text must decode to an object.
- OCR pipeline config must be an object or YAML text.
- ${modulePath}.model_dir must be null or an asset descriptor
- Unsupported pipeline_name "${pipelineName}". PaddleOCR.js cu
- OCR pipeline config must define both "SubModules.TextDetecti
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/4b113d55daaef10e.
Report an issue: GitHub.