main
py 137 lines 4.27 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from collections.abc import Callable, Set
4 from typing import TypeAlias
5
6 import torch
7
8 from vllm.config import PoolerConfig, get_current_vllm_config
9 from vllm.model_executor.layers.pooler import ClassifierFn, PoolingParamsUpdate
10 from vllm.model_executor.layers.pooler.abstract import Pooler
11 from vllm.model_executor.layers.pooler.activations import (
12 PoolerActivation,
13 PoolerNormalize,
14 resolve_classifier_act_fn,
15 )
16 from vllm.model_executor.models.adapters import _load_st_projector
17 from vllm.tasks import POOLING_TASKS, PoolingTask
18 from vllm.v1.pool.metadata import PoolingMetadata
19
20 from .heads import (
21 ClassifierPoolerHead,
22 EmbeddingPoolerHead,
23 SequencePoolerHead,
24 SequencePoolerHeadOutput,
25 )
26 from .methods import (
27 SequencePoolingMethod,
28 SequencePoolingMethodOutput,
29 get_seq_pooling_method,
30 )
31
32 SequencePoolingFn: TypeAlias = Callable[
33 [torch.Tensor, PoolingMetadata],
34 SequencePoolingMethodOutput,
35 ]
36 SequencePoolingHeadFn: TypeAlias = Callable[
37 [SequencePoolingMethodOutput, PoolingMetadata],
38 SequencePoolerHeadOutput,
39 ]
40
41 SequencePoolerOutput: TypeAlias = torch.Tensor | list[torch.Tensor]
42
43
44 class SequencePooler(Pooler):
45 """A layer that pools specific information from hidden states.
46
47 This layer does the following:
48 1. Extracts specific tokens or aggregates data based on pooling method.
49 2. Postprocesses the output based on pooling head.
50 3. Returns structured results as `PoolerOutput`.
51 """
52
53 def __init__(
54 self,
55 pooling: SequencePoolingMethod | SequencePoolingFn,
56 head: SequencePoolerHead | SequencePoolingHeadFn,
57 ) -> None:
58 super().__init__()
59
60 self.pooling = pooling
61 self.head = head
62
63 def extra_repr(self) -> str:
64 return (
65 f"pooling={self.pooling.__class__.__name__}, "
66 f"head={self.head.__class__.__name__}"
67 )
68
69 def get_supported_tasks(self) -> Set[PoolingTask]:
70 tasks = set(POOLING_TASKS)
71
72 if isinstance(self.pooling, SequencePoolingMethod):
73 tasks &= self.pooling.get_supported_tasks()
74 if isinstance(self.head, SequencePoolerHead):
75 tasks &= self.head.get_supported_tasks()
76
77 return tasks
78
79 def get_pooling_updates(self, task: PoolingTask) -> PoolingParamsUpdate:
80 updates = PoolingParamsUpdate()
81
82 if isinstance(self.pooling, SequencePoolingMethod):
83 updates |= self.pooling.get_pooling_updates(task)
84
85 return updates
86
87 def forward(
88 self,
89 hidden_states: torch.Tensor,
90 pooling_metadata: PoolingMetadata,
91 ) -> SequencePoolerOutput:
92 pooled_data = self.pooling(hidden_states, pooling_metadata)
93 pooled_data = self.head(pooled_data, pooling_metadata)
94 return pooled_data
95
96
97 def pooler_for_embed(pooler_config: PoolerConfig) -> SequencePooler:
98 pooling = get_seq_pooling_method(pooler_config.get_seq_pooling_type())
99
100 vllm_config = get_current_vllm_config()
101 model_config = vllm_config.model_config
102 head = EmbeddingPoolerHead(
103 head_dtype=model_config.head_dtype,
104 projector=_load_st_projector(model_config),
105 activation=PoolerNormalize(),
106 )
107
108 return SequencePooler(pooling=pooling, head=head)
109
110
111 def pooler_for_classify(
112 pooler_config: PoolerConfig,
113 *,
114 pooling: SequencePoolingMethod | SequencePoolingFn | None = None,
115 classifier: ClassifierFn | None = None,
116 act_fn: PoolerActivation | None = None,
117 ) -> SequencePooler:
118 if pooling is None:
119 pooling = get_seq_pooling_method(pooler_config.get_seq_pooling_type())
120
121 vllm_config = get_current_vllm_config()
122 model_config = vllm_config.model_config
123 if model_config.pooler_config is None:
124 raise ValueError(
125 "model_config.pooler_config must be set for classification pooling"
126 )
127 head = ClassifierPoolerHead(
128 head_dtype=model_config.head_dtype,
129 classifier=classifier,
130 logit_mean=model_config.pooler_config.logit_mean,
131 logit_sigma=model_config.pooler_config.logit_sigma,
132 activation=resolve_classifier_act_fn(
133 model_config, static_num_labels=False, act_fn=act_fn
134 ),
135 )
136
137 return SequencePooler(pooling=pooling, head=head)