main
py 67 lines 2.46 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Backbone validation for Jina Embeddings V5.
4
5 The V5 family ships two backbones under one `architectures` entry: `-small` is
6 a Qwen3 decoder, while `-nano` is a bidirectional EuroBERT encoder. Upstream
7 ships a separate `configuration_*.py` per repository, so the only signal
8 distinguishing them is `is_decoder`, which the encoder variant sets to False.
9 `JinaEmbeddingsV5ModelConfig` uses it to enable bidirectional attention for the
10 encoder variant; `JinaEmbeddingsV5Model` then dispatches to the correct backbone.
11 """
12
13 from types import SimpleNamespace
14 from typing import cast
15
16 import pytest
17 from transformers import PreTrainedConfig
18
19 from vllm.config import ModelConfig
20 from vllm.model_executor.models.config import (
21 MODELS_CONFIG_MAP,
22 JinaEmbeddingsV5ModelConfig,
23 )
24
25
26 def _model_config(hf_config: PreTrainedConfig) -> ModelConfig:
27 """Minimal stand-in for ModelConfig; only hf_config is read."""
28 return cast(ModelConfig, SimpleNamespace(hf_config=hf_config))
29
30
31 @pytest.mark.cpu_test
32 def test_registered_for_the_architecture():
33 """The handler only runs if it is wired to the architecture name."""
34 assert MODELS_CONFIG_MAP["JinaEmbeddingsV5Model"] is JinaEmbeddingsV5ModelConfig
35
36
37 @pytest.mark.cpu_test
38 def test_encoder_backbone_enables_bidirectional_attention():
39 """An encoder checkpoint (is_decoder=False) is supported.
40
41 The handler sets is_causal=False so the Llama backbone uses
42 EncoderOnlyAttention; JinaEmbeddingsV5Model then dispatches to the encoder
43 implementation.
44 """
45 hf_config = PreTrainedConfig(is_decoder=False)
46
47 JinaEmbeddingsV5ModelConfig.verify_and_update_model_config(_model_config(hf_config))
48
49 assert hf_config.is_causal is False
50
51
52 @pytest.mark.cpu_test
53 def test_supported_decoder_backbone_is_accepted():
54 """The Qwen3-based variants must keep loading.
55
56 `-small` omits `is_decoder` entirely, so an absent attribute has to be
57 treated as a decoder. The first assertion pins that assumption: if
58 PreTrainedConfig ever gains an `is_decoder=False` default, this fails here
59 rather than silently rejecting a supported checkpoint.
60 """
61 absent = PreTrainedConfig()
62 assert not hasattr(absent, "is_decoder")
63
64 JinaEmbeddingsV5ModelConfig.verify_and_update_model_config(_model_config(absent))
65 JinaEmbeddingsV5ModelConfig.verify_and_update_model_config(
66 _model_config(PreTrainedConfig(is_decoder=True))
67 )