Skip to content
Closed
Show file tree
Hide file tree
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
6 changes: 6 additions & 0 deletions components/src/dynamo/sglang/_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,12 @@ def supports_external_mm_hashes(engine: Any) -> bool:
return False

tokenizer_manager = getattr(engine, "tokenizer_manager", None)
# Kimi K2.5 and K3 derive each image identity from the image bytes and
# reject caller hashes with a ValueError (sgl-project/sglang#43043).
mm_processor = getattr(tokenizer_manager, "mm_processor", None)
if getattr(mm_processor, "uses_wide_image_identity", False):
return False

tokenize_one = getattr(tokenizer_manager, "_tokenize_one_request", None)
if tokenize_one is None or getattr(
tokenize_one, "_dynamo_rebuilds_external_mm_padding", False
Expand Down
18 changes: 18 additions & 0 deletions components/src/dynamo/sglang/tests/test_sglang_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -1112,6 +1112,24 @@ async def async_generate(self, mm_hashes=None):
assert engine.tokenizer_manager._tokenize_one_request is patched


def test_external_mm_hashes_are_disabled_when_processor_owns_image_identity():
class TokenizerManager:
mm_processor = SimpleNamespace(uses_wide_image_identity=True)

async def _tokenize_one_request(self, obj):
return obj

class KimiEngine:
tokenizer_manager = TokenizerManager()

async def async_generate(self, mm_hashes=None):
return None

engine = KimiEngine()
assert not supports_external_mm_hashes(engine)
assert "_tokenize_one_request" not in vars(engine.tokenizer_manager)


def test_external_mm_hashes_are_disabled_when_engine_lacks_kwarg():
class LegacyEngine:
async def async_generate(self):
Expand Down
Loading