Skip to content

Commit c621af1

Browse files
authored
[BugFix] Fix prompt_embeds for multimodal models (#45383)
Signed-off-by: ruinan ma <r7ma3088@gmail.com>
1 parent e2bf2b3 commit c621af1

2 files changed

Lines changed: 53 additions & 7 deletions

File tree

vllm/config/vllm.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -966,6 +966,15 @@ def __post_init__(self):
966966
"Async scheduling is not compatible with "
967967
"disable_padded_drafter_batch=True."
968968
)
969+
if (
970+
self.model_config is not None
971+
and self.model_config.enable_prompt_embeds
972+
and self.model_config.is_multimodal_model
973+
):
974+
raise ValueError(
975+
"Async scheduling is not yet supported with prompt embeds "
976+
"for multimodal models."
977+
)
969978
if not executor_supports_async_sched:
970979
raise ValueError(
971980
f"`{executor_backend}` does not support async scheduling yet."
@@ -1009,6 +1018,16 @@ def __post_init__(self):
10091018
executor_backend,
10101019
)
10111020
self.scheduler_config.async_scheduling = False
1021+
elif (
1022+
self.model_config is not None
1023+
and self.model_config.enable_prompt_embeds
1024+
and self.model_config.is_multimodal_model
1025+
):
1026+
logger.warning_once(
1027+
"Async scheduling is not yet supported with prompt embeds "
1028+
"for multimodal models and will be disabled."
1029+
)
1030+
self.scheduler_config.async_scheduling = False
10121031
else:
10131032
self.scheduler_config.async_scheduling = True
10141033

vllm/v1/worker/gpu_model_runner.py

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3452,14 +3452,41 @@ def _preprocess(
34523452
# NOTE(woosuk): To unify token ids and soft tokens (vision
34533453
# embeddings), we always use embeddings (rather than token ids)
34543454
# as input to the multimodal model, even when the input is text.
3455-
inputs_embeds_scheduled = self.model.embed_input_ids(
3456-
self.input_ids.gpu[:num_scheduled_tokens],
3457-
multimodal_embeddings=mm_embeds,
3458-
is_multimodal=is_mm_embed,
3459-
)
3455+
if self.enable_prompt_embeds and self.input_batch.req_prompt_embeds:
3456+
# Some positions carry precomputed prompt_embeds: they are
3457+
# already in self.inputs_embeds and marked is_token_ids=False.
3458+
# Embed only the token-id positions (zeroing the placeholder ids
3459+
# at prompt_embeds positions so the embedding gather cannot read
3460+
# out-of-range ids), and write them back without clobbering the
3461+
# prompt_embeds positions.
3462+
is_token_ids = self.is_token_ids.gpu[:num_scheduled_tokens]
3463+
safe_input_ids = torch.where(
3464+
is_token_ids,
3465+
self.input_ids.gpu[:num_scheduled_tokens],
3466+
0,
3467+
)
3468+
inputs_embeds_scheduled = self.model.embed_input_ids(
3469+
safe_input_ids,
3470+
multimodal_embeddings=mm_embeds,
3471+
is_multimodal=is_mm_embed,
3472+
)
3473+
target = self.inputs_embeds.gpu[:num_scheduled_tokens]
3474+
self.inputs_embeds.gpu[:num_scheduled_tokens] = torch.where(
3475+
is_token_ids.unsqueeze(-1),
3476+
inputs_embeds_scheduled,
3477+
target,
3478+
)
3479+
else:
3480+
inputs_embeds_scheduled = self.model.embed_input_ids(
3481+
self.input_ids.gpu[:num_scheduled_tokens],
3482+
multimodal_embeddings=mm_embeds,
3483+
is_multimodal=is_mm_embed,
3484+
)
34603485

3461-
# TODO(woosuk): Avoid the copy. Optimize.
3462-
self.inputs_embeds.gpu[:num_scheduled_tokens].copy_(inputs_embeds_scheduled)
3486+
# TODO(woosuk): Avoid the copy. Optimize.
3487+
self.inputs_embeds.gpu[:num_scheduled_tokens].copy_(
3488+
inputs_embeds_scheduled
3489+
)
34633490

34643491
input_ids, inputs_embeds = self._prepare_mm_inputs(num_input_tokens)
34653492
model_kwargs = {

0 commit comments

Comments
 (0)