main
py 88 lines 3.03 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from transformers import BaseImageProcessor, BatchFeature, TensorType
4 from transformers.processing_utils import ProcessorMixin
5
6 from vllm.multimodal.inputs import VisionChunk
7 from vllm.tokenizers.hf import HfTokenizer
8
9
10 class KimiK25Processor(ProcessorMixin):
11 attributes = ["image_processor", "tokenizer"]
12
13 def __init__(
14 self,
15 image_processor: BaseImageProcessor,
16 tokenizer: HfTokenizer,
17 media_token_id: int,
18 ) -> None:
19 self.image_processor = image_processor
20 self.tokenizer = tokenizer
21
22 self.media_token_id = media_token_id
23
24 def __call__(
25 self,
26 text: str | list[str] | None = None,
27 vision_chunks: list[VisionChunk] | None = None,
28 return_tensors: str | TensorType | None = None,
29 **kwargs,
30 ) -> BatchFeature:
31 """Args:
32 text: The text to be field to the model.
33 vision_chunks: List of `VisionChunk` items to be processed.
34 For image: `VisionChunkImage` with
35 `type='image', image=PIL.Image`
36 For video_chunk: `VisionChunkVideo` with
37 `type='video_chunk', video_chunk=list[PIL.Image]`
38 Returns:
39 [`BatchFeature`]: A [`BatchFeature`] with the following fields:
40
41 - **input_ids** -- list of token ids to be fed to a model.
42 - **pixel_values** -- Pixel values to be fed to a model.
43 Returned when `vision_chunks` is not `None`.
44 - **grid_thws** -- list of image 3D grid in LLM.
45 Returned when `vision_chunks` is not `None`.
46
47 """
48 if vision_chunks is not None:
49 mm_inputs = self.image_processor.preprocess(
50 vision_chunks,
51 return_tensors=return_tensors,
52 )
53 else:
54 mm_inputs = {}
55
56 if text is not None:
57 if not isinstance(text, list):
58 text = [text]
59
60 text_inputs = self.tokenizer(text)
61
62 # Note: Modify in-place
63 input_ids: list[list[int]] = text_inputs["input_ids"] # type: ignore
64
65 if vision_chunks is not None:
66 num_tokens_per_chunk = [
67 self.image_processor.media_tokens_calculator(chunk)
68 for chunk in vision_chunks
69 ]
70
71 for i in range(len(input_ids)):
72 new_input_ids = []
73 for token in input_ids[i]:
74 if token == self.media_token_id:
75 new_input_ids.extend(
76 [self.media_token_id] * num_tokens_per_chunk.pop(0)
77 )
78 else:
79 new_input_ids.append(token)
80
81 input_ids[i] = new_input_ids
82 else:
83 text_inputs = {}
84
85 return BatchFeature(
86 data={**text_inputs, **mm_inputs},
87 tensor_type=return_tensors,
88 )