-
-
Notifications
You must be signed in to change notification settings - Fork 23k
[Optimization] Return image_grid_thw in render response for disaggregated mRoPE #43608
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,7 @@ | |
| import msgspec | ||
| import numpy as np | ||
| import pybase64 as base64 | ||
| import torch | ||
| from fastapi import Request | ||
|
|
||
| from vllm.engine.protocol import EngineClient | ||
|
|
@@ -43,6 +44,8 @@ | |
| from vllm.logger import init_logger | ||
| from vllm.logprobs import Logprob | ||
| from vllm.multimodal.inputs import ( | ||
| MultiModalBatchedField, | ||
| MultiModalFieldElem, | ||
| MultiModalKwargsItem, | ||
| MultiModalKwargsItems, | ||
| PlaceholderRange, | ||
|
|
@@ -156,6 +159,23 @@ async def serve_tokens( | |
| decode_mm_kwargs_item(item) if item is not None else None | ||
| for item in items | ||
| ] | ||
| elif features.image_grid_thw is not None: | ||
| # Lightweight path: construct minimal items containing | ||
| # only grid metadata for mRoPE position computation. | ||
| for modality, grids in features.image_grid_thw.items(): | ||
| items_list: list[MultiModalKwargsItem | None] = [] | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. false positive |
||
| thw_key = f"{modality}_grid_thw" | ||
| for grid in grids: | ||
| if grid is not None: | ||
| tensor = torch.tensor(grid, dtype=torch.int64) | ||
| elem = MultiModalFieldElem( | ||
| data=tensor, | ||
| field=MultiModalBatchedField(keep_on_cpu=True), | ||
| ) | ||
| items_list.append(MultiModalKwargsItem({thw_key: elem})) | ||
| else: | ||
| items_list.append(None) | ||
| mm_kwargs[modality] = items_list | ||
| else: | ||
| for modality, hashes in features.mm_hashes.items(): | ||
| mm_kwargs[modality] = [None] * len(hashes) | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -2,10 +2,13 @@ | |||||
| # SPDX-FileCopyrightText: Copyright contributors to the vLLM project | ||||||
| from collections.abc import Sequence | ||||||
| from http import HTTPStatus | ||||||
| from typing import Any, cast | ||||||
| from typing import TYPE_CHECKING, Any, cast | ||||||
|
|
||||||
| from openai_harmony import Message as OpenAIMessage | ||||||
|
|
||||||
| if TYPE_CHECKING: | ||||||
| import torch | ||||||
|
|
||||||
| from vllm.config import ModelConfig | ||||||
| from vllm.entrypoints.chat_utils import ( | ||||||
| ChatTemplateContentFormatOption, | ||||||
|
|
@@ -380,18 +383,33 @@ def _extract_mm_features( | |||||
|
|
||||||
| # Serialize tensor data per modality. | ||||||
| kwargs_data: dict[str, list[str | None]] | None = None | ||||||
| image_grid_thw: dict[str, list[list[int] | None]] | None = None | ||||||
| if raw_mm_kwargs := mm_engine_input.get("mm_kwargs"): | ||||||
| kwargs_data = {} | ||||||
| image_grid_thw = {} | ||||||
| for modality, items in raw_mm_kwargs.items(): | ||||||
| kwargs_data[modality] = [ | ||||||
| encode_mm_kwargs_item(item) if item is not None else None | ||||||
| for item in items | ||||||
| ] | ||||||
| thw_key = f"{modality}_grid_thw" | ||||||
| grids: list[list[int] | None] = [] | ||||||
| for item in items: | ||||||
| if item is not None and thw_key in item: | ||||||
| thw_tensor = cast("torch.Tensor", item[thw_key].data) | ||||||
| grids.append(thw_tensor.tolist()) | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For models like Qwen2-VL,
Suggested change
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Per-item image_grid_thw.data is already 1-D shape (3,), not (1, 3). Evidence: MultiModalBatchedField.build_elems splits the batched tensor along dim 0 (so (N, 3) → N elems of shape (3,)), and Qwen2-VL itself unpacks per-item with t, h, w = mm_feature.data["image_grid_thw"].data.tolist() (qwen2_vl.py:1217). So tolist() already returns a flat [t, h, w], which is exactly what your test asserts (len(grid) == 3, all ints). No .view(-1) needed |
||||||
| else: | ||||||
| grids.append(None) | ||||||
| if any(g is not None for g in grids): | ||||||
| image_grid_thw[modality] = grids | ||||||
| if not image_grid_thw: | ||||||
| image_grid_thw = None | ||||||
|
|
||||||
| return MultiModalFeatures( | ||||||
| mm_hashes=mm_hashes, | ||||||
| mm_placeholders=mm_placeholders, | ||||||
| kwargs_data=kwargs_data, | ||||||
| image_grid_thw=image_grid_thw, | ||||||
| ) | ||||||
|
|
||||||
| def _make_request_with_harmony( | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The use of the
|operator for type unions (e.g.,list[int] | None) requires Python 3.10+ orfrom __future__ import annotations. Since vLLM supports Python 3.9, this will cause aTypeErrorat runtime. Please addfrom __future__ import annotationsat the top of this file to maintain compatibility.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
false positive
vLLM requires Python 3.10+ (pyproject.toml: requires-python = ">=3.10,<3.15")