diff --git a/fastembed/common/preprocessor_utils.py b/fastembed/common/preprocessor_utils.py index fcd8acaa..fb853924 100644 --- a/fastembed/common/preprocessor_utils.py +++ b/fastembed/common/preprocessor_utils.py @@ -113,8 +113,10 @@ def load_tokenizer(model_dir: Path) -> tuple[Tokenizer, dict[str, int]]: # Padding is always normalized to batch-longest. A serialized fixed length shorter than the # truncation limit leaves longer encodings untouched, which produces ragged batches, and a - # fixed length equal to it pads every batch to the maximum. Direction and pad token metadata - # are taken from the serialized settings, since some models pad on the left. + # fixed length equal to it pads every batch to the maximum. Pad token metadata is taken from + # the serialized settings. The direction follows transformers: `padding_side` from + # tokenizer_config.json wins over the serialized direction, since some models pad on the left + # and set it only in the config. padding = tokenizer.padding or {} pad_token = padding.get("pad_token") or tokenizer_config.get("pad_token") if pad_token is None: @@ -129,7 +131,7 @@ def load_tokenizer(model_dir: Path) -> tuple[Tokenizer, dict[str, int]]: raise ValueError(f"Could not resolve an id for the pad token {pad_token!r} in {model_dir}") tokenizer.enable_padding( - direction=padding.get("direction", "right"), + direction=tokenizer_config.get("padding_side") or padding.get("direction", "right"), pad_id=pad_id, pad_type_id=padding.get("pad_type_id", 0), pad_token=pad_token, diff --git a/tests/test_preprocessor_utils.py b/tests/test_preprocessor_utils.py index b9f718a8..d04f0312 100644 --- a/tests/test_preprocessor_utils.py +++ b/tests/test_preprocessor_utils.py @@ -236,6 +236,30 @@ def test_truncation_direction_resolution( assert tokenizer.truncation["direction"] == expected +@pytest.mark.parametrize( + "serialized_direction,padding_side,expected", + [ + (None, None, "right"), + ("left", None, "left"), + (None, "left", "left"), + ("left", "right", "right"), # tokenizer_config.json wins, as in transformers + ], +) +def test_padding_direction_resolution( + make_model_dir, serialized_direction, padding_side, expected +) -> None: + model_dir = make_model_dir( + tokenizer_config={"padding_side": padding_side}, + padding=None + if serialized_direction is None + else {"pad_id": 0, "pad_token": "[PAD]", "direction": serialized_direction}, + ) + + tokenizer, _ = load_tokenizer(model_dir) + + assert tokenizer.padding["direction"] == expected + + @pytest.mark.parametrize( "model_max_length,max_length", [