A high-throughput and memory-efficient inference and serving engine for LLMs
Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git
Synced Nov 10, 22:45 UTC
[Mistral common] Ensure all functions are imported from the top & only use public methods (#31138)
Signed-off-by: Patrick von Platen <patrick.v.platen@gmail.com> Co-authored-by: Julien Denize <40604584+juliendenize@users.noreply.github.com> Co-authored-by: Cyrus Leung <tlleungac@connect.ust.hk>
Patrick von Platen committed
Dec 26, 2025 at 13:48 UTC
48e744976cf4deb889998ff82813efdf34c21589
5 files changed
+24
-57
requirements/common.txt
+1
-1
@@ -31,7 +31,7 @@ partial-json-parser # used for parsing partial JSON outputs
31
pyzmq >= 25.0.0
32
msgspec
33
gguf >= 0.17.0
34
-mistral_common[image] >= 1.8.5
34
+mistral_common[image] >= 1.8.8
35
opencv-python-headless >= 4.11.0 # required for video IO
36
pyyaml
37
six>=1.16.0; python_version > '3.11' # transitive dependency of pandas that needs to be the latest version for python 3.12
requirements/nightly_torch_test.txt
+1
-1
@@ -23,7 +23,7 @@ jiwer # required for audio tests
23
timm # required for internvl test
24
transformers_stream_generator # required for qwen-vl test
25
matplotlib # required for qwen-vl test
26
-mistral_common[image,audio] >= 1.8.5 # required for voxtral test
26
+mistral_common[image,audio] >= 1.8.8 # required for voxtral test
27
num2words # required for smolvlm test
28
opencv-python-headless >= 4.11.0 # required for video test
29
datamodel_code_generator # required for minicpm3 test
requirements/test.in
+1
-1
@@ -29,7 +29,7 @@ torchaudio==2.9.1
29
torchvision==0.24.1
30
transformers_stream_generator # required for qwen-vl test
31
matplotlib # required for qwen-vl test
32
-mistral_common[image,audio] >= 1.8.5 # required for voxtral test
32
+mistral_common[image,audio] >= 1.8.8 # required for voxtral test
33
num2words # required for smolvlm test
34
open_clip_torch==2.32.0 # Required for nemotron_vl test
35
opencv-python-headless >= 4.11.0 # required for video test
requirements/test.txt
+1
-1
@@ -482,7 +482,7 @@ mbstrdecoder==1.1.3
482
# typepy
483
mdurl==0.1.2
484
# via markdown-it-py
485
-mistral-common==1.8.5
485
+mistral-common==1.8.8
486
# via -r requirements/test.in
487
mlflow==2.22.0
488
# via terratorch
vllm/tokenizers/mistral.py
+20
-53
@@ -3,6 +3,21 @@
3
from pathlib import Path
4
from typing import TYPE_CHECKING, Any, cast
5
6
+from mistral_common.protocol.instruct.request import (
7
+ ChatCompletionRequest as MistralChatCompletionRequest,
8
+)
9
+from mistral_common.protocol.instruct.tool_calls import Function, Tool
10
+from mistral_common.protocol.instruct.validator import ValidationMode
11
+from mistral_common.tokens.tokenizers.base import (
12
+ SpecialTokenPolicy,
13
+ SpecialTokens,
14
+)
15
+from mistral_common.tokens.tokenizers.instruct import InstructTokenizerV13
16
+from mistral_common.tokens.tokenizers.sentencepiece import (
17
+ SentencePieceTokenizer,
18
+)
19
+from mistral_common.tokens.tokenizers.tekken import Tekkenizer
20
+
21
from vllm.entrypoints.chat_utils import ChatCompletionMessageParam
22
from vllm.entrypoints.openai.protocol import ChatCompletionRequest
23
from vllm.logger import init_logger
@@ -10,10 +25,6 @@ from vllm.logger import init_logger
25
from .protocol import TokenizerLike
26
27
if TYPE_CHECKING:
13
- from mistral_common.protocol.instruct.request import (
14
- ChatCompletionRequest as MistralChatCompletionRequest,
15
- )
16
- from mistral_common.tokens.tokenizers.tekken import Tekkenizer
28
from transformers import BatchEncoding
29
30
try:
@@ -101,8 +112,6 @@ def _prepare_apply_chat_template_tools_and_messages(
112
continue_final_message: bool = False,
113
add_generation_prompt: bool = False,
114
) -> tuple[list["ChatCompletionMessageParam"], list[dict[str, Any]] | None]:
104
- from mistral_common.protocol.instruct.tool_calls import Function, Tool
105
-
115
if add_generation_prompt and continue_final_message:
116
raise ValueError(
117
"Cannot set both `add_generation_prompt` and "
@@ -181,8 +190,6 @@ def validate_request_params(request: "ChatCompletionRequest"):
190
191
192
def _tekken_token_to_id(tokenizer: "Tekkenizer", t: str | bytes) -> int:
184
- from mistral_common.tokens.tokenizers.tekken import Tekkenizer
185
-
193
assert isinstance(tokenizer, Tekkenizer), type(tokenizer)
194
195
t_bytes = t.encode("utf-8") if not isinstance(t, bytes) else t
@@ -210,8 +217,6 @@ class MistralTokenizer(TokenizerLike):
217
download_dir: str | None = None,
218
**kwargs,
219
) -> "MistralTokenizer":
213
- from mistral_common.protocol.instruct.validator import ValidationMode
214
-
220
try:
221
# Transformers v5
222
from transformers.tokenization_mistral_common import MistralCommonBackend
@@ -235,12 +240,6 @@ class MistralTokenizer(TokenizerLike):
240
def __init__(self, tokenizer: "MistralCommonBackend") -> None:
241
super().__init__()
242
238
- from mistral_common.protocol.instruct.validator import ValidationMode
239
- from mistral_common.tokens.tokenizers.sentencepiece import (
240
- SentencePieceTokenizer,
241
- )
242
- from mistral_common.tokens.tokenizers.tekken import Tekkenizer
243
-
243
self.transformers_tokenizer = tokenizer
244
self.mistral = tokenizer.tokenizer
245
self.instruct = self.mistral.instruct_tokenizer
@@ -270,37 +269,20 @@ class MistralTokenizer(TokenizerLike):
269
# Sort the dict for convenience
270
self._vocab_dict = dict(sorted(self._vocab_dict.items(), key=lambda x: x[1]))
271
272
+ # Vocab sorted by token id.
273
+ self._vocab = self.tokenizer.vocab()
274
+ self._max_token_id = self.vocab_size - 1
275
+
276
# Cache special tokens for faster access.
277
self._special_token_ids = self._get_special_token_ids()
278
self._special_token_ids_set = set(self._special_token_ids)
279
self._special_tokens = self._get_special_tokens(self._special_token_ids)
280
self._special_tokens_set = set(self._special_tokens)
281
279
- # Vocab sorted by token id.
280
- self._vocab = self.tokenizer._vocab
281
- self._max_token_id = self.vocab_size - 1
282
-
282
def _get_special_token_ids(self) -> list[int]:
284
- from mistral_common.tokens.tokenizers.sentencepiece import (
285
- SentencePieceTokenizer,
286
- )
287
- from mistral_common.tokens.tokenizers.tekken import Tekkenizer
288
-
289
- if self.is_tekken:
290
- assert isinstance(self.tokenizer, Tekkenizer), type(self.tokenizer)
291
- special_ids = {t["rank"] for t in self.tokenizer._all_special_tokens}
292
- elif self.is_spm:
293
- assert isinstance(self.tokenizer, SentencePieceTokenizer), type(
294
- self.tokenizer
295
- )
296
- special_ids = self.tokenizer._control_tokens
297
- else:
298
- raise ValueError(f"Unknown tokenizer type: {type(self.tokenizer)}")
299
- return sorted(special_ids)
283
+ return [i for i in range(len(self._vocab)) if self.tokenizer.is_special(i)]
284
285
def _get_special_tokens(self, all_special_ids: list[int]) -> list[str]:
302
- from mistral_common.tokens.tokenizers.base import SpecialTokenPolicy
303
-
286
return [
287
self.tokenizer.decode([i], special_token_policy=SpecialTokenPolicy.KEEP)
288
for i in all_special_ids
@@ -460,15 +442,6 @@ class MistralTokenizer(TokenizerLike):
442
)
443
444
def convert_tokens_to_string(self, tokens: list[str]) -> str:
463
- from mistral_common.tokens.tokenizers.base import (
464
- SpecialTokenPolicy,
465
- SpecialTokens,
466
- )
467
- from mistral_common.tokens.tokenizers.sentencepiece import (
468
- SentencePieceTokenizer,
469
- )
470
- from mistral_common.tokens.tokenizers.tekken import Tekkenizer
471
-
445
to_decode_special_tokens = {SpecialTokens.tool_calls}
446
if self.is_tekken:
447
assert isinstance(self.tokenizer, Tekkenizer), type(self.tokenizer)
@@ -523,12 +496,6 @@ class MistralTokenizer(TokenizerLike):
496
ids: list[int],
497
skip_special_tokens: bool = False,
498
) -> list[str]:
526
- from mistral_common.tokens.tokenizers.base import (
527
- SpecialTokenPolicy,
528
- SpecialTokens,
529
- )
530
- from mistral_common.tokens.tokenizers.instruct import InstructTokenizerV13
531
-
499
if not skip_special_tokens:
500
return [self.tokenizer.id_to_piece(token_id) for token_id in ids]
501