main
py 421 lines 13.6 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 # adapted from https://huggingface.co/OpenGVLab/InternVL2-4B/blob/main/modeling_intern_vit.py
5 # --------------------------------------------------------
6 # InternVL
7 # Copyright (c) 2023 OpenGVLab
8 # Licensed under The MIT License [see LICENSE for details]
9 # --------------------------------------------------------
10 from collections.abc import Iterable
11 from functools import partial
12
13 import torch
14 import torch.nn as nn
15 import torch.nn.functional as F
16 from transformers import PreTrainedConfig
17
18 from vllm.compilation.decorators import (
19 should_torch_compile_mm_encoder,
20 support_torch_compile,
21 )
22 from vllm.distributed import (
23 divide,
24 get_tensor_model_parallel_rank,
25 get_tensor_model_parallel_world_size,
26 split_tensor_along_last_dim,
27 tensor_model_parallel_all_gather,
28 )
29 from vllm.model_executor.layers.activation import get_act_fn
30 from vllm.model_executor.layers.attention import MMEncoderAttention
31 from vllm.model_executor.layers.conv import Conv2dLayer
32 from vllm.model_executor.layers.layernorm import RMSNorm
33 from vllm.model_executor.layers.linear import (
34 ColumnParallelLinear,
35 QKVParallelLinear,
36 RowParallelLinear,
37 )
38 from vllm.model_executor.layers.quantization import QuantizationConfig
39
40 from .utils import AutoWeightsLoader
41 from .vision import is_vit_use_data_parallel, run_dp_sharded_vision_model
42
43 NORM2FN = {
44 "rms_norm": RMSNorm,
45 "layer_norm": nn.LayerNorm,
46 }
47
48
49 class InternVisionEmbeddings(nn.Module):
50 def __init__(self, config: PreTrainedConfig):
51 super().__init__()
52 self.config = config
53 self.embed_dim = config.hidden_size
54 self.image_size = config.image_size
55 self.patch_size = config.patch_size
56
57 self.class_embedding = nn.Parameter(torch.randn(1, 1, self.embed_dim))
58
59 self.patch_embedding = Conv2dLayer(
60 in_channels=3,
61 out_channels=self.embed_dim,
62 kernel_size=self.patch_size,
63 stride=self.patch_size,
64 )
65
66 self.num_patches = (self.image_size // self.patch_size) ** 2
67 self.num_positions = self.num_patches + 1
68
69 self.position_embedding = nn.Parameter(
70 torch.randn(1, self.num_positions, self.embed_dim)
71 )
72
73 def _get_pos_embed(self, pos_embed: torch.Tensor, H: int, W: int):
74 target_dtype = pos_embed.dtype
75 pos_embed = (
76 pos_embed.float()
77 .reshape(
78 1,
79 self.image_size // self.patch_size,
80 self.image_size // self.patch_size,
81 -1,
82 )
83 .permute(0, 3, 1, 2)
84 )
85 pos_embed = F.interpolate(
86 pos_embed, size=(H, W), mode="bicubic", align_corners=False
87 )
88 return pos_embed.reshape(1, -1, H * W).permute(0, 2, 1).to(target_dtype)
89
90 def _get_position_embedding(self, H: int, W: int) -> torch.Tensor:
91 position_embedding = self.position_embedding
92 if self.num_patches == H * W:
93 return position_embedding
94
95 return torch.cat(
96 [
97 position_embedding[:, :1, :],
98 self._get_pos_embed(position_embedding[:, 1:, :], H, W),
99 ],
100 dim=1,
101 )
102
103 def forward(self, pixel_values: torch.FloatTensor) -> torch.Tensor:
104 target_dtype = self.patch_embedding.weight.dtype
105 patch_embeds = self.patch_embedding(
106 pixel_values.to(target_dtype)
107 ) # shape = [*, channel, width, height]
108 batch_size, _, height, width = patch_embeds.shape
109 patch_embeds = patch_embeds.flatten(2).transpose(1, 2)
110 class_embeds = self.class_embedding.expand(batch_size, 1, -1).to(target_dtype)
111 embeddings = torch.cat([class_embeds, patch_embeds], dim=1)
112 position_embedding = self._get_position_embedding(height, width)
113 embeddings = embeddings + position_embedding.to(target_dtype)
114 return embeddings
115
116
117 class InternParallelAttention(nn.Module):
118 """Multi-headed attention from 'Attention Is All You Need' paper."""
119
120 def __init__(
121 self,
122 config: PreTrainedConfig,
123 quant_config: QuantizationConfig | None = None,
124 *,
125 num_dummy_heads: int = 0,
126 prefix: str = "",
127 ) -> None:
128 super().__init__()
129
130 self.config = config
131 self.embed_dim = config.hidden_size
132 self.num_heads = config.num_attention_heads
133 self.head_dim = self.embed_dim // self.num_heads
134 if self.head_dim * self.num_heads != self.embed_dim:
135 raise ValueError(
136 f"embed_dim must be divisible by num_heads "
137 f"(got `embed_dim`: {self.embed_dim} and `num_heads`:"
138 f" {self.num_heads})."
139 )
140
141 use_data_parallel = is_vit_use_data_parallel()
142 # if the number of heads is not divisible by tp_size,
143 # we also disable Attention's TP
144 tp_size = 1 if use_data_parallel else get_tensor_model_parallel_world_size()
145 use_data_parallel = (
146 use_data_parallel or (self.num_heads + num_dummy_heads) % tp_size != 0
147 )
148 self.tp_size = 1 if use_data_parallel else tp_size
149 self.tp_rank = 0 if use_data_parallel else get_tensor_model_parallel_rank()
150
151 # Additional dummy heads are used to enable TP for common GPU counts.
152 self.dummy_dim = (num_dummy_heads + self.num_heads) * self.head_dim
153 self.num_heads_per_partition = divide(
154 num_dummy_heads + self.num_heads, self.tp_size
155 )
156
157 self.scale = self.head_dim**-0.5
158 self.qkv = QKVParallelLinear(
159 self.embed_dim,
160 self.head_dim,
161 num_dummy_heads + self.num_heads,
162 bias=config.qkv_bias,
163 quant_config=quant_config,
164 prefix=f"{prefix}.qkv",
165 disable_tp=use_data_parallel,
166 )
167
168 self.qk_normalization = config.qk_normalization
169
170 if self.qk_normalization:
171 self.q_norm = RMSNorm(
172 self.dummy_dim,
173 eps=config.layer_norm_eps,
174 var_hidden_size=self.embed_dim,
175 )
176 self.k_norm = RMSNorm(
177 self.dummy_dim,
178 eps=config.layer_norm_eps,
179 var_hidden_size=self.embed_dim,
180 )
181
182 self.proj = RowParallelLinear(
183 self.dummy_dim,
184 self.embed_dim,
185 quant_config=quant_config,
186 prefix=f"{prefix}.proj",
187 disable_tp=use_data_parallel,
188 )
189
190 self.attn = MMEncoderAttention(
191 self.num_heads_per_partition,
192 self.head_dim,
193 self.scale,
194 prefix=f"{prefix}.attn",
195 )
196
197 def _apply_qk_norm(self, q: torch.Tensor, k: torch.Tensor):
198 if self.tp_size > 1:
199 q = tensor_model_parallel_all_gather(q.contiguous())
200 k = tensor_model_parallel_all_gather(k.contiguous())
201 q = self.q_norm(q)
202 k = self.k_norm(k)
203 if self.tp_size > 1:
204 splitter = partial(split_tensor_along_last_dim, num_partitions=self.tp_size)
205 q = splitter(q)[self.tp_rank]
206 k = splitter(k)[self.tp_rank]
207 return q, k
208
209 def forward(self, x: torch.Tensor) -> torch.Tensor:
210 B, N, _ = x.shape
211 qkv, _ = self.qkv(x)
212 q, k, v = qkv.chunk(3, dim=-1)
213
214 if self.qk_normalization:
215 q, k = self._apply_qk_norm(q, k)
216
217 out = self.attn(q, k, v)
218 out, _ = self.proj(out)
219 return out
220
221
222 class InternMLP(nn.Module):
223 def __init__(
224 self,
225 config: PreTrainedConfig,
226 quant_config: QuantizationConfig | None = None,
227 prefix: str = "",
228 ) -> None:
229 super().__init__()
230
231 self.config = config
232 self.activation_fn = get_act_fn(config.hidden_act)
233 use_data_parallel = is_vit_use_data_parallel()
234 self.fc1 = ColumnParallelLinear(
235 config.hidden_size,
236 config.intermediate_size,
237 bias=True,
238 quant_config=quant_config,
239 prefix=f"{prefix}.fc1",
240 disable_tp=use_data_parallel,
241 )
242 self.fc2 = RowParallelLinear(
243 config.intermediate_size,
244 config.hidden_size,
245 bias=True,
246 quant_config=quant_config,
247 prefix=f"{prefix}.fc2",
248 disable_tp=use_data_parallel,
249 )
250
251 def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
252 hidden_states, _ = self.fc1(hidden_states)
253 hidden_states = self.activation_fn(hidden_states)
254 hidden_states, _ = self.fc2(hidden_states)
255
256 return hidden_states
257
258
259 @support_torch_compile(
260 dynamic_arg_dims={"hidden_states": 0},
261 enable_if=should_torch_compile_mm_encoder,
262 is_encoder=True,
263 )
264 class InternVisionEncoderLayer(nn.Module):
265 def __init__(
266 self,
267 config: PreTrainedConfig,
268 quant_config: QuantizationConfig | None = None,
269 *,
270 num_dummy_heads: int = 0,
271 prefix: str = "",
272 attn_cls: type[InternParallelAttention] = InternParallelAttention,
273 ) -> None:
274 super().__init__()
275 self.embed_dim = config.hidden_size
276 self.intermediate_size = config.intermediate_size
277 self.norm_type = config.norm_type
278 self.attn_cls = attn_cls
279
280 self.attn = self._init_attn(
281 config,
282 quant_config,
283 num_dummy_heads=num_dummy_heads,
284 prefix=f"{prefix}.attn",
285 )
286
287 self.mlp = InternMLP(
288 config,
289 quant_config=quant_config,
290 prefix=f"{prefix}.mlp",
291 )
292 self.norm1 = NORM2FN[self.norm_type](self.embed_dim, eps=config.layer_norm_eps)
293 self.norm2 = NORM2FN[self.norm_type](self.embed_dim, eps=config.layer_norm_eps)
294
295 self.ls1 = nn.Parameter(config.initializer_factor * torch.ones(self.embed_dim))
296 self.ls2 = nn.Parameter(config.initializer_factor * torch.ones(self.embed_dim))
297
298 def _init_attn(
299 self,
300 config: PreTrainedConfig,
301 quant_config: QuantizationConfig | None,
302 *,
303 num_dummy_heads: int,
304 prefix: str = "",
305 ):
306 return self.attn_cls(
307 config,
308 quant_config=quant_config,
309 num_dummy_heads=num_dummy_heads,
310 prefix=prefix,
311 )
312
313 def forward(
314 self,
315 hidden_states: torch.Tensor,
316 ):
317 hidden_states = hidden_states + self.attn(self.norm1(hidden_states)) * self.ls1
318
319 hidden_states = hidden_states + self.mlp(self.norm2(hidden_states)) * self.ls2
320
321 return hidden_states
322
323
324 class InternVisionEncoder(nn.Module):
325 def __init__(
326 self,
327 config: PreTrainedConfig,
328 quant_config: QuantizationConfig | None = None,
329 *,
330 num_hidden_layers_override: int | None = None,
331 num_dummy_heads: int = 0,
332 prefix: str = "",
333 layer_cls: type[InternVisionEncoderLayer] = InternVisionEncoderLayer,
334 ):
335 super().__init__()
336
337 self.config = config
338 self.layer_cls = layer_cls
339
340 if num_hidden_layers_override is None:
341 num_hidden_layers = config.num_hidden_layers
342 else:
343 num_hidden_layers = num_hidden_layers_override
344
345 self.layers = nn.ModuleList(
346 [
347 self.layer_cls(
348 config=config,
349 quant_config=quant_config,
350 num_dummy_heads=num_dummy_heads,
351 prefix=f"{prefix}.layers.{layer_idx}",
352 )
353 for layer_idx in range(num_hidden_layers)
354 ]
355 )
356
357 def forward(self, inputs_embeds: torch.Tensor):
358 hidden_states = inputs_embeds
359 for encoder_layer in self.layers:
360 hidden_states = encoder_layer(hidden_states)
361
362 return hidden_states
363
364
365 class InternVisionModel(nn.Module):
366 packed_modules_mapping = {
367 "qkv": ["qkv"],
368 }
369
370 def __init__(
371 self,
372 config: PreTrainedConfig,
373 quant_config: QuantizationConfig | None = None,
374 *,
375 num_hidden_layers_override: int | None = None,
376 num_dummy_heads: int = 0,
377 prefix: str = "",
378 ) -> None:
379 super().__init__()
380
381 self.config = config
382 self.use_data_parallel = is_vit_use_data_parallel()
383
384 self.embeddings = InternVisionEmbeddings(config)
385 self.encoder = InternVisionEncoder(
386 config=config,
387 quant_config=quant_config,
388 num_hidden_layers_override=num_hidden_layers_override,
389 num_dummy_heads=num_dummy_heads,
390 prefix=f"{prefix}.encoder",
391 )
392
393 def get_input_embeddings(self):
394 return self.embeddings
395
396 def forward(
397 self,
398 pixel_values: torch.Tensor | None = None,
399 pixel_embeds: torch.Tensor | None = None,
400 ) -> torch.FloatTensor:
401 if pixel_values is None and pixel_embeds is None:
402 raise ValueError("You have to specify pixel_values or pixel_embeds")
403
404 if pixel_embeds is not None:
405 hidden_states = pixel_embeds
406 elif pixel_values is not None:
407 if pixel_values.ndim == 4:
408 hidden_states = self.embeddings(pixel_values)
409 else:
410 raise ValueError(f"wrong pixel_values size: {pixel_values.shape}")
411
412 if self.use_data_parallel:
413 encoder_outputs = run_dp_sharded_vision_model(hidden_states, self.encoder)
414 else:
415 encoder_outputs = self.encoder(inputs_embeds=hidden_states)
416
417 return encoder_outputs
418
419 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
420 loader = AutoWeightsLoader(self)
421 return loader.load_weights(weights)