[VLM] Enable per-image ViT cache and avoid TP CUDA context creation for Kimi-K2.5 (#22858)
This commit is contained in:
@@ -42,7 +42,6 @@ from sglang.srt.multimodal.mm_utils import run_dp_sharded_mrope_vision_model
|
|||||||
from sglang.srt.server_args import get_global_server_args
|
from sglang.srt.server_args import get_global_server_args
|
||||||
from sglang.srt.utils import add_prefix, is_npu
|
from sglang.srt.utils import add_prefix, is_npu
|
||||||
|
|
||||||
KIMIV_VT_INFER_MAX_PATCH_NUM = 16328
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
from sglang.srt.layers.dp_attention import is_dp_attention_enabled
|
from sglang.srt.layers.dp_attention import is_dp_attention_enabled
|
||||||
@@ -622,59 +621,6 @@ def mm_projection_auto(
|
|||||||
return proj_out
|
return proj_out
|
||||||
|
|
||||||
|
|
||||||
@torch.inference_mode()
|
|
||||||
def vision_tower_forward_auto(
|
|
||||||
vision_tower: torch.nn.Module,
|
|
||||||
pixel_values: torch.Tensor,
|
|
||||||
grid_thw: torch.Tensor,
|
|
||||||
mm_projector: torch.nn.Module | None = None,
|
|
||||||
) -> list[torch.Tensor]:
|
|
||||||
"""Auto-batched vision tower forward."""
|
|
||||||
assert isinstance(
|
|
||||||
pixel_values, torch.Tensor
|
|
||||||
), "expect pixel_values to be a tensor, get {}".format(type(pixel_values))
|
|
||||||
n = grid_thw.shape[0]
|
|
||||||
n_patches_each_media = grid_thw.prod(-1)
|
|
||||||
max_infer_batch = max(n_patches_each_media.max(), KIMIV_VT_INFER_MAX_PATCH_NUM)
|
|
||||||
logger.debug(
|
|
||||||
"vt max_infer_batch: %s, KIMIV_VT_INFER_MAX_PATCH_NUM: %s",
|
|
||||||
max_infer_batch,
|
|
||||||
KIMIV_VT_INFER_MAX_PATCH_NUM,
|
|
||||||
)
|
|
||||||
tensors = []
|
|
||||||
pre_sum = 0
|
|
||||||
current_group_start = 0
|
|
||||||
current_group_patches = 0
|
|
||||||
|
|
||||||
for i in range(n):
|
|
||||||
current_media_patches = n_patches_each_media[i].item()
|
|
||||||
if current_group_patches + current_media_patches <= max_infer_batch:
|
|
||||||
current_group_patches += current_media_patches
|
|
||||||
else:
|
|
||||||
if current_group_start < i:
|
|
||||||
group_grid_thw = grid_thw[current_group_start:i]
|
|
||||||
group_n_patches = n_patches_each_media[current_group_start:i].sum()
|
|
||||||
group_input = pixel_values[pre_sum : pre_sum + group_n_patches]
|
|
||||||
group_output = vision_tower(group_input, group_grid_thw)
|
|
||||||
proj_out = mm_projection_auto(mm_projector, group_output)
|
|
||||||
tensors.extend(proj_out)
|
|
||||||
pre_sum += group_n_patches
|
|
||||||
|
|
||||||
current_group_start = i
|
|
||||||
current_group_patches = current_media_patches
|
|
||||||
|
|
||||||
# Process the last group
|
|
||||||
if current_group_start < n:
|
|
||||||
group_grid_thw = grid_thw[current_group_start:n]
|
|
||||||
group_n_patches = n_patches_each_media[current_group_start:n].sum()
|
|
||||||
group_input = pixel_values[pre_sum : pre_sum + group_n_patches]
|
|
||||||
group_output = vision_tower(group_input, group_grid_thw)
|
|
||||||
proj_out = mm_projection_auto(mm_projector, group_output)
|
|
||||||
tensors.extend(proj_out)
|
|
||||||
|
|
||||||
return tensors
|
|
||||||
|
|
||||||
|
|
||||||
class KimiK25ForConditionalGeneration(nn.Module):
|
class KimiK25ForConditionalGeneration(nn.Module):
|
||||||
# Support nvidia/Kimi-K2.5-NVFP4 naming: language_model.layers.*.
|
# Support nvidia/Kimi-K2.5-NVFP4 naming: language_model.layers.*.
|
||||||
# Ref: HF config.json for nvidia/Kimi-K2.5-NVFP4
|
# Ref: HF config.json for nvidia/Kimi-K2.5-NVFP4
|
||||||
@@ -733,7 +679,9 @@ class KimiK25ForConditionalGeneration(nn.Module):
|
|||||||
pixel_values = torch.cat([item.feature for item in items], dim=0).to(
|
pixel_values = torch.cat([item.feature for item in items], dim=0).to(
|
||||||
device=device, dtype=target_dtype
|
device=device, dtype=target_dtype
|
||||||
)
|
)
|
||||||
grid_thws = torch.concat([item.grid_thws for item in items], dim=0).to(device)
|
grid_thws = torch.concat([item.image_grid_thw for item in items], dim=0).to(
|
||||||
|
device
|
||||||
|
)
|
||||||
|
|
||||||
if self.use_data_parallel:
|
if self.use_data_parallel:
|
||||||
image_embeds = run_dp_sharded_mrope_vision_model(
|
image_embeds = run_dp_sharded_mrope_vision_model(
|
||||||
@@ -745,14 +693,9 @@ class KimiK25ForConditionalGeneration(nn.Module):
|
|||||||
image_features = self.mm_projector(image_embeds)
|
image_features = self.mm_projector(image_embeds)
|
||||||
return image_features
|
return image_features
|
||||||
|
|
||||||
image_features = vision_tower_forward_auto(
|
image_embeds = self.vision_tower(pixel_values, grid_thws)
|
||||||
self.vision_tower,
|
proj_out = mm_projection_auto(self.mm_projector, image_embeds)
|
||||||
pixel_values,
|
return torch.cat(proj_out, dim=0)
|
||||||
grid_thws,
|
|
||||||
mm_projector=self.mm_projector,
|
|
||||||
)
|
|
||||||
image_features = torch.cat(image_features, dim=0)
|
|
||||||
return image_features
|
|
||||||
|
|
||||||
def pad_input_ids(self, input_ids: List[int], mm_inputs: MultimodalInputs):
|
def pad_input_ids(self, input_ids: List[int], mm_inputs: MultimodalInputs):
|
||||||
pattern = MultiModalityDataPaddingPatternMultimodalTokens()
|
pattern = MultiModalityDataPaddingPatternMultimodalTokens()
|
||||||
|
|||||||
@@ -285,10 +285,14 @@ class KimiGPUProcessorWrapper:
|
|||||||
images, resize_configs, image_mean, image_std_inv, self._patch_size
|
images, resize_configs, image_mean, image_std_inv, self._patch_size
|
||||||
)
|
)
|
||||||
|
|
||||||
|
grid_thws = grid_thws.cpu()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"input_ids": text_inputs["input_ids"],
|
"input_ids": text_inputs["input_ids"],
|
||||||
"pixel_values": pixel_values,
|
"pixel_values": pixel_values,
|
||||||
"grid_thws": grid_thws,
|
# Use SGL-standard key so get_new_expanded_mm_items() can split
|
||||||
|
# per-image for cache granularity (it looks up 'image_grid_thw').
|
||||||
|
"image_grid_thw": grid_thws,
|
||||||
}
|
}
|
||||||
|
|
||||||
def _cpu_call(self, text, images, **kwargs):
|
def _cpu_call(self, text, images, **kwargs):
|
||||||
|
|||||||
Reference in New Issue
Block a user