Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 40 additions & 4 deletions utils/bench_serving/benchmark_serving.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,44 @@ class BenchmarkMetrics:
_worker_tokenizer = None


def _load_tokenizer(tokenizer_id, tokenizer_mode, trust_remote_code):
"""Load tokenizer for random-prompt generation.

vLLM's get_tokenizer can raise AttributeError when transformers removes
LlamaTokenizer.all_special_tokens_extended (e.g. Qwen3.5 with newer
transformers). Prefer backend_request_func.get_tokenizer on fallback so
client tokenization stays aligned with the sglang server (#1381, #1428).
"""
try:
return get_tokenizer(
tokenizer_id,
tokenizer_mode=tokenizer_mode,
trust_remote_code=trust_remote_code,
)
except AttributeError as exc:
if "all_special_tokens_extended" not in str(exc):
raise
try:
from backend_request_func import get_tokenizer as _backend_get_tokenizer
return _backend_get_tokenizer(
tokenizer_id,
tokenizer_mode=tokenizer_mode,
trust_remote_code=trust_remote_code,
)
except ImportError:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fallback catches only ImportError, missing re-raised AttributeError

Low Severity

The inner except ImportError at line 122 only catches the import failure, not an AttributeError from _backend_get_tokenizer(...). The module-level get_tokenizer (lines 48–51) preferentially resolves to backend_request_func.get_tokenizer. If that function ever raises AttributeError with all_special_tokens_extended, the fallback re-imports and calls the same function, producing the same uncaught AttributeError. The AutoTokenizer.from_pretrained final fallback becomes unreachable. Catching (ImportError, AttributeError) would keep the full fallback chain intact.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit e74f133. Configure here.

from transformers import AutoTokenizer
use_fast = tokenizer_mode != "slow"
return AutoTokenizer.from_pretrained(
tokenizer_id,
trust_remote_code=trust_remote_code,
use_fast=use_fast,
)


def _init_tokenizer_worker(tokenizer_id, tokenizer_mode, trust_remote_code):
"""Initialize tokenizer once per worker process."""
global _worker_tokenizer
_worker_tokenizer = get_tokenizer(
_worker_tokenizer = _load_tokenizer(
tokenizer_id,
tokenizer_mode=tokenizer_mode,
trust_remote_code=trust_remote_code,
Expand Down Expand Up @@ -787,9 +821,11 @@ def main(args: argparse.Namespace):
api_url = f"http://{args.host}:{args.port}{args.endpoint}"
base_url = f"http://{args.host}:{args.port}"

tokenizer = get_tokenizer(tokenizer_id,
tokenizer_mode=tokenizer_mode,
trust_remote_code=args.trust_remote_code)
tokenizer = _load_tokenizer(
tokenizer_id,
tokenizer_mode=tokenizer_mode,
trust_remote_code=args.trust_remote_code,
)


if args.dataset_name == "random":
Expand Down