reasoning.py 3.01 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project

from dataclasses import field

from vllm.config.model import ModelConfig
from vllm.config.utils import config
from vllm.tokenizers import cached_tokenizer_from_config


@config
class ReasoningConfig:
    """Configuration for reasoning models.

15
    Set `reasoning_start_str` and `reasoning_end_str` to the strings that delimit
16
17
18
19
20
21
22
    the reasoning block (e.g. `"<think>"` and `"</think>"`).  The
    corresponding token IDs are derived automatically via
    `initialize_token_ids` and are not intended to be set directly.
    """

    # NOTE: These parameters are temporary, the intent is to derive them
    # automatically from the reasoning parser in a future version.
23
    reasoning_start_str: str = "<think>"
24
    """String that indicates the start of reasoning."""
25
    reasoning_end_str: str = "</think>"
26
27
    """String that indicates the end of reasoning content."""

28
    _reasoning_start_token_ids: list[int] | None = field(
29
30
        default=None, init=False, repr=False
    )
31
    """Private backing field for `reasoning_start_token_ids`. Set by
32
    `initialize_token_ids`. Not intended to be configured directly."""
33
34
35
36
    _reasoning_end_token_ids: list[int] | None = field(
        default=None, init=False, repr=False
    )
    """Private backing field for `reasoning_end_token_ids`. Set by
37
38
39
    `initialize_token_ids`. Not intended to be configured directly."""

    @property
40
41
    def reasoning_start_token_ids(self) -> list[int] | None:
        """Token IDs derived from `reasoning_start_str`. Set automatically by
42
        `initialize_token_ids`. Not intended to be configured directly."""
43
        return self._reasoning_start_token_ids
44
45

    @property
46
47
    def reasoning_end_token_ids(self) -> list[int] | None:
        """Token IDs derived from `reasoning_end_str`. Set automatically by
48
        `initialize_token_ids`. Not intended to be configured directly."""
49
        return self._reasoning_end_token_ids
50
51
52
53

    def initialize_token_ids(self, model_config: ModelConfig) -> None:
        """Initialize reasoning token IDs from strings using the tokenizer."""
        if (
54
55
            self._reasoning_start_token_ids is not None
            and self._reasoning_end_token_ids is not None
56
57
58
59
60
        ):
            return

        tokenizer = cached_tokenizer_from_config(model_config=model_config)

61
62
        self._reasoning_start_token_ids = tokenizer.encode(
            self.reasoning_start_str, add_special_tokens=False
63
        )
64
65
        self._reasoning_end_token_ids = tokenizer.encode(
            self.reasoning_end_str, add_special_tokens=False
66
67
        )

68
        if not self._reasoning_start_token_ids or not self._reasoning_end_token_ids:
69
70
            raise ValueError(
                f"ReasoningConfig: failed to tokenize reasoning strings: "
71
72
                f"reasoning_start_str='{self.reasoning_start_str}', "
                f"reasoning_end_str='{self.reasoning_end_str}'. "
73
74
                "Ensure the strings are valid tokens in the model's vocabulary."
            )