95 lines
3.0 KiB
Python
95 lines
3.0 KiB
Python
# SPDX-License-Identifier: Apache-2.0
|
||
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
|
||
|
||
from vllm.config import VllmConfig
|
||
from vllm.renderers.chat_utils import (
|
||
ChatCompletionMessageParam,
|
||
ConversationMessage,
|
||
parse_chat_messages,
|
||
parse_chat_messages_async,
|
||
)
|
||
from vllm.tokenizers.deepseek_v4 import DeepseekV4Tokenizer
|
||
from vllm.utils.async_utils import make_async
|
||
|
||
from .base import BaseRenderer
|
||
from .inputs import DictPrompt
|
||
from .inputs.preprocess import parse_dec_only_prompt
|
||
from .params import ChatParams
|
||
|
||
_FIM_BEGIN = "<|fim▁begin|>"
|
||
_FIM_HOLE = "<|fim▁hole|>"
|
||
_FIM_END = "<|fim▁end|>"
|
||
|
||
|
||
class DeepseekV4Renderer(BaseRenderer[DeepseekV4Tokenizer]):
|
||
def __init__(
|
||
self,
|
||
config: VllmConfig,
|
||
tokenizer: DeepseekV4Tokenizer | None,
|
||
) -> None:
|
||
super().__init__(config, tokenizer)
|
||
|
||
self._apply_chat_template_async = make_async(
|
||
self._apply_chat_template, executor=self._executor
|
||
)
|
||
|
||
def _apply_chat_template(self, *args, **kwargs):
|
||
return self.get_tokenizer().apply_chat_template(*args, **kwargs)
|
||
|
||
def render_completion_suffix(self, prompt: str, suffix: str) -> str | None:
|
||
return f"{_FIM_BEGIN}{prompt}{_FIM_HOLE}{suffix}{_FIM_END}"
|
||
|
||
def render_messages(
|
||
self,
|
||
messages: list[ChatCompletionMessageParam],
|
||
params: ChatParams,
|
||
) -> tuple[list[ConversationMessage], DictPrompt]:
|
||
conversation, mm_data, mm_uuids = parse_chat_messages(
|
||
messages,
|
||
self.model_config,
|
||
content_format="openai",
|
||
media_io_kwargs=params.media_io_kwargs,
|
||
mm_processor_kwargs=params.mm_processor_kwargs,
|
||
)
|
||
|
||
prompt_raw = self._apply_chat_template(
|
||
conversation=conversation,
|
||
messages=messages,
|
||
**params.get_apply_chat_template_kwargs(),
|
||
)
|
||
|
||
prompt = parse_dec_only_prompt(prompt_raw)
|
||
if mm_data is not None:
|
||
prompt["multi_modal_data"] = mm_data
|
||
if mm_uuids is not None:
|
||
prompt["multi_modal_uuids"] = mm_uuids
|
||
|
||
return conversation, prompt
|
||
|
||
async def render_messages_async(
|
||
self,
|
||
messages: list[ChatCompletionMessageParam],
|
||
params: ChatParams,
|
||
) -> tuple[list[ConversationMessage], DictPrompt]:
|
||
conversation, mm_data, mm_uuids = await parse_chat_messages_async(
|
||
messages,
|
||
self.model_config,
|
||
content_format="openai",
|
||
media_io_kwargs=params.media_io_kwargs,
|
||
mm_processor_kwargs=params.mm_processor_kwargs,
|
||
)
|
||
|
||
prompt_raw = await self._apply_chat_template_async(
|
||
conversation=conversation,
|
||
messages=messages,
|
||
**params.get_apply_chat_template_kwargs(),
|
||
)
|
||
|
||
prompt = parse_dec_only_prompt(prompt_raw)
|
||
if mm_data is not None:
|
||
prompt["multi_modal_data"] = mm_data
|
||
if mm_uuids is not None:
|
||
prompt["multi_modal_uuids"] = mm_uuids
|
||
|
||
return conversation, prompt
|