__init__.py 3.2 KB
Newer Older
1
2
# SPDX-License-Identifier: Apache-2.0

3
4
import enum
from dataclasses import dataclass
5
from typing import TYPE_CHECKING, List, Optional, Union
6
7
8

import msgspec

9
from vllm.v1.metrics.stats import SchedulerStats
10
from vllm.v1.outputs import LogprobsLists, LogprobsTensors
11

12
13
14
15
16
if TYPE_CHECKING:
    from vllm.lora.request import LoRARequest
    from vllm.multimodal import MultiModalKwargs
    from vllm.multimodal.inputs import PlaceholderRange
    from vllm.sampling_params import SamplingParams
17

18
19
20
# These are possible values of RequestOutput.finish_reason,
# so form part of the external API.
FINISH_REASON_STRINGS = ("stop", "length", "abort")
21

22
23

class FinishReason(enum.IntEnum):
24
25
26
    """
    Reason a request finished - stop, length, or abort.

27
28
    Int rather than Str for more compact serialization.

29
30
31
32
33
34
35
36
37
38
    stop - a stop string was emitted
    length - max_tokens was consumed, or max_model_len was reached
    abort - aborted for another reason

    """
    STOP = 0
    LENGTH = 1
    ABORT = 2

    def __str__(self):
39
        return FINISH_REASON_STRINGS[self.value]
40
41


42
43
@dataclass
class EngineCoreRequest:
44
45
46
47
48
49

    # NOTE: prompt and prompt_token_ids should be DecoderOnlyInput,
    # but this object is currently not playing well with msgspec
    # due to circular imports and typing we have in data.py

    request_id: str
50
51
    # NOTE(ywang96): original text prompt is needed when a request is added to
    # Detokenizer, but set to None when it is added to EngineCoreClient.
52
53
    prompt: Optional[str]
    prompt_token_ids: List[int]
54
    mm_inputs: Optional[List[Optional["MultiModalKwargs"]]]
55
    mm_hashes: Optional[List[str]]
56
57
    mm_placeholders: Optional[List["PlaceholderRange"]]
    sampling_params: "SamplingParams"
58
59
    eos_token_id: Optional[int]
    arrival_time: float
60
    lora_request: Optional["LoRARequest"]
61
62


63
64
65
66
67
class EngineCoreOutput(
        msgspec.Struct,
        array_like=True,  # type: ignore[call-arg]
        omit_defaults=True,  # type: ignore[call-arg]
        gc=False):  # type: ignore[call-arg]
68
69
70

    request_id: str
    new_token_ids: List[int]
71
72
73
74

    new_logprobs: Optional[LogprobsLists] = None
    new_prompt_logprobs_tensors: Optional[LogprobsTensors] = None

75
    finish_reason: Optional[FinishReason] = None
76
77
    stop_reason: Union[int, str, None] = None

78
79
80
81
    @property
    def finished(self) -> bool:
        return self.finish_reason is not None

82

83
84
85
86
87
class EngineCoreOutputs(
        msgspec.Struct,
        array_like=True,  # type: ignore[call-arg]
        omit_defaults=True,  # type: ignore[call-arg]
        gc=False):  # type: ignore[call-arg]
88
89

    #NOTE(Nick): We could consider ways to make this more compact,
90
    # e.g. columnwise layout
91
92
93

    # [num_reqs]
    outputs: List[EngineCoreOutput]
94
    scheduler_stats: SchedulerStats
95
96


97
98
99
100
101
@dataclass
class EngineCoreProfile:
    is_start: bool


102
103
104
105
106
@dataclass
class EngineCoreResetPrefixCache:
    pass


107
108
109
110
111
112
113
class EngineCoreRequestType(enum.Enum):
    """
    Request types defined as hex byte strings, so it can be sent over sockets
    without separate encoding step.
    """
    ADD = b'\x00'
    ABORT = b'\x01'
114
    PROFILE = b'\x02'
115
    RESET_PREFIX_CACHE = b'\x03'
116
117


118
119
EngineCoreRequestUnion = Union[EngineCoreRequest, EngineCoreProfile,
                               EngineCoreResetPrefixCache, List[str]]