main
py 94 lines 3.03 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from vllm.config import VllmConfig
5 from vllm.entrypoints.chat_utils import (
6 ChatCompletionMessageParam,
7 ConversationMessage,
8 parse_chat_messages,
9 parse_chat_messages_async,
10 )
11 from vllm.tokenizers.deepseek_v4 import DeepseekV4Tokenizer
12 from vllm.utils.async_utils import make_async
13
14 from .base import BaseRenderer
15 from .inputs import DictPrompt
16 from .inputs.preprocess import parse_dec_only_prompt
17 from .params import ChatParams
18
19 _FIM_BEGIN = "<|fim▁begin|>"
20 _FIM_HOLE = "<|fim▁hole|>"
21 _FIM_END = "<|fim▁end|>"
22
23
24 class DeepseekV4Renderer(BaseRenderer[DeepseekV4Tokenizer]):
25 def __init__(
26 self,
27 config: VllmConfig,
28 tokenizer: DeepseekV4Tokenizer | None,
29 ) -> None:
30 super().__init__(config, tokenizer)
31
32 self._apply_chat_template_async = make_async(
33 self._apply_chat_template, executor=self._executor
34 )
35
36 def _apply_chat_template(self, *args, **kwargs):
37 return self.get_tokenizer().apply_chat_template(*args, **kwargs)
38
39 def render_completion_suffix(self, prompt: str, suffix: str) -> str | None:
40 return f"{_FIM_BEGIN}{prompt}{_FIM_HOLE}{suffix}{_FIM_END}"
41
42 def render_messages(
43 self,
44 messages: list[ChatCompletionMessageParam],
45 params: ChatParams,
46 ) -> tuple[list[ConversationMessage], DictPrompt]:
47 conversation, mm_data, mm_uuids = parse_chat_messages(
48 messages,
49 self.model_config,
50 content_format="openai",
51 media_io_kwargs=params.media_io_kwargs,
52 mm_processor_kwargs=params.mm_processor_kwargs,
53 )
54
55 prompt_raw = self._apply_chat_template(
56 conversation=conversation,
57 messages=messages,
58 **params.get_apply_chat_template_kwargs(),
59 )
60
61 prompt = parse_dec_only_prompt(prompt_raw)
62 if mm_data is not None:
63 prompt["multi_modal_data"] = mm_data
64 if mm_uuids is not None:
65 prompt["multi_modal_uuids"] = mm_uuids
66
67 return conversation, prompt
68
69 async def render_messages_async(
70 self,
71 messages: list[ChatCompletionMessageParam],
72 params: ChatParams,
73 ) -> tuple[list[ConversationMessage], DictPrompt]:
74 conversation, mm_data, mm_uuids = await parse_chat_messages_async(
75 messages,
76 self.model_config,
77 content_format="openai",
78 media_io_kwargs=params.media_io_kwargs,
79 mm_processor_kwargs=params.mm_processor_kwargs,
80 )
81
82 prompt_raw = await self._apply_chat_template_async(
83 conversation=conversation,
84 messages=messages,
85 **params.get_apply_chat_template_kwargs(),
86 )
87
88 prompt = parse_dec_only_prompt(prompt_raw)
89 if mm_data is not None:
90 prompt["multi_modal_data"] = mm_data
91 if mm_uuids is not None:
92 prompt["multi_modal_uuids"] = mm_uuids
93
94 return conversation, prompt