fix: fix mm processor double bos (#26505)

This commit is contained in:
Yihao Wang
2026-07-11 07:53:08 +08:00
committed by GitHub
parent 649ce5dd3d
commit 7de33ce806
2 changed files with 57 additions and 0 deletions
@@ -138,6 +138,8 @@ class TestProcessMmDataKwargs(unittest.TestCase):
proc.disable_fast_image_processor = server_args.disable_fast_image_processor
proc.skip_tokenizer_init = server_args.skip_tokenizer_init
proc._processor = mock_processor
proc._tokenizer = MagicMock()
proc._tokenizer_auto_adds_specials = False
proc.image_config = mm_process_config.get("image", {})
proc.video_config = mm_process_config.get("video", {})
proc.audio_config = mm_process_config.get("audio", {})
@@ -296,5 +298,48 @@ class TestOverrideProcessorsConfigInjection(unittest.TestCase):
self.assertTrue(audio_kw.get("truncation"))
class TestDoubleBosGuard(unittest.TestCase):
"""Regression test for the multimodal double-BOS bug.
Repro condition (Cohere2 / Llama3-LLaVA-Next family):
- tokenizer.encode("") returns [bos_id] (auto-adds specials), AND
- chat template renders the BOS string as a literal at the start.
Without the guard in BaseMultimodalProcessor, the inner processor.__call__
on the rendered prompt would auto-prepend a second BOS, producing 2 leading
BOS tokens vs the HF reference's 1.
"""
def test_guard_passes_add_special_tokens_false_on_bug_condition(self):
from sglang.srt.multimodal.processors.base_processor import (
BaseMultimodalProcessor,
)
server_args = MagicMock()
server_args.mm_process_config = {}
server_args.disable_fast_image_processor = True
server_args.keep_mm_feature_on_device = True
mock_hf_processor = MagicMock()
mock_hf_processor.__class__.__name__ = "TestProcessor"
mock_hf_processor.__call__ = MagicMock(return_value={})
mock_hf_processor.tokenizer.encode = MagicMock(return_value=[2])
mock_hf_processor.tokenizer.bos_token = "<BOS>"
with patch.object(BaseMultimodalProcessor, "__abstractmethods__", set()):
proc = BaseMultimodalProcessor(
hf_config=MagicMock(),
server_args=server_args,
_processor=mock_hf_processor,
transport_mode=None,
)
proc.FEATURE_NAMES = []
proc.process_mm_data("<BOS>hello", images=["img1"])
call_kwargs = mock_hf_processor.__call__.call_args.kwargs
self.assertEqual(call_kwargs.get("add_special_tokens"), False)
if __name__ == "__main__":
unittest.main()