@@ -182,6 +182,8 @@ class _VisionCacheEntry:
182182 num_img_embeddings_per_tile : int
183183 imgs_sizes : Optional [Tensor ]
184184 num_frames : Optional [Tensor ]
185+ video_frame_indices : Optional [List [List [int ]]] = None
186+ video_fps : Optional [List [float ]] = None
185187
186188
187189def format_mem_bytes (mem_bytes ):
@@ -733,6 +735,14 @@ def _refresh_vlm_request_data(self, request: DynamicVLMInferenceRequest) -> None
733735 expansion_kwargs = {"num_tiles" : num_tiles , "imgs_sizes" : imgs_sizes }
734736 if num_frames is not None :
735737 expansion_kwargs ["num_frames" ] = num_frames
738+ prompt_config = wrapper .multimodal_prompt_config
739+ if (
740+ prompt_config is not None
741+ and prompt_config .video_spec .expansion_mode == "temporal_patch"
742+ ):
743+ expansion_kwargs ["tokenizer" ] = self .controller .tokenizer
744+ expansion_kwargs ["video_frame_indices" ] = request .video_frame_indices
745+ expansion_kwargs ["video_fps" ] = request .video_fps
736746 _ , mask_list = wrapper .expand_image_tokens (
737747 [request .compact_prompt_tokens .tolist ()],
738748 image_token_id = media_token_id ,
@@ -776,6 +786,8 @@ def _refresh_vlm_request_data(self, request: DynamicVLMInferenceRequest) -> None
776786 num_img_embeddings_per_tile = request .num_img_embeddings_per_tile ,
777787 imgs_sizes = imgs_sizes ,
778788 num_frames = num_frames ,
789+ video_frame_indices = request .video_frame_indices ,
790+ video_fps = request .video_fps ,
779791 )
780792 self .context .add_vlm_request_data (
781793 request .request_id , image_embeddings = embeddings , image_token_mask = mask
@@ -812,6 +824,8 @@ def _cache_vision_embedding(
812824 num_img_embeddings_per_tile : int = 0 ,
813825 imgs_sizes : Optional [Tensor ] = None ,
814826 num_frames : Optional [Tensor ] = None ,
827+ video_frame_indices : Optional [List [List [int ]]] = None ,
828+ video_fps : Optional [List [float ]] = None ,
815829 ) -> None :
816830 if not cache_key or self .vision_embedding_cache_max_bytes == 0 :
817831 return
@@ -823,6 +837,8 @@ def _cache_vision_embedding(
823837 num_img_embeddings_per_tile = num_img_embeddings_per_tile ,
824838 imgs_sizes = imgs_sizes ,
825839 num_frames = num_frames ,
840+ video_frame_indices = video_frame_indices ,
841+ video_fps = video_fps ,
826842 )
827843 cache_entry_bytes = self ._vision_cache_entry_nbytes (entry )
828844 if cache_entry_bytes > self .vision_embedding_cache_max_bytes :
@@ -1570,12 +1586,27 @@ def _serialize_finished_request(
15701586 finished_metadata = finished_metadata ,
15711587 offload_params = request .offload_params ,
15721588 )
1573- return request .serialize (
1589+ serialized = request .serialize (
15741590 payload_offloaded = stage_result is not None ,
15751591 payload_stage_metadata = (
15761592 stage_result .response_metadata if stage_result is not None else None
15771593 ),
15781594 )
1595+ if isinstance (request , DynamicVLMInferenceRequest ):
1596+ # Active VLM requests retain these inputs for refresh/cache bookkeeping,
1597+ # but completion replies must not echo large input-only tensors.
1598+ for key in (
1599+ "imgs" ,
1600+ "num_tiles" ,
1601+ "imgs_sizes" ,
1602+ "num_frames" ,
1603+ "video_frame_indices" ,
1604+ "video_fps" ,
1605+ "image_embeddings" ,
1606+ "image_token_mask" ,
1607+ ):
1608+ serialized [key ] = None
1609+ return serialized
15791610
15801611 def _handle_failed_request (self , request_id : int ):
15811612 """Handle a failed request by sending the reply immediately.
@@ -1842,6 +1873,8 @@ def add_request(
18421873 num_img_embeddings_per_tile : int = 0 ,
18431874 imgs_sizes : Optional [Tensor ] = None ,
18441875 num_frames : Optional [Tensor ] = None ,
1876+ video_frame_indices : Optional [List [List [int ]]] = None ,
1877+ video_fps : Optional [List [float ]] = None ,
18451878 media_tokens_preexpanded : bool = False ,
18461879 offload_params : Optional [Dict ] = None ,
18471880 media_cache_key : Optional [str ] = None ,
@@ -1875,6 +1908,9 @@ def add_request(
18751908 imgs_sizes (Optional[Tensor]): Per-image sizes [N, 2] with [H, W].
18761909 Dynamic resolution.
18771910 num_frames (Optional[Tensor]): Number of frames per image/video item.
1911+ video_frame_indices (Optional[List[List[int]]]): Source indices for
1912+ each sampled video frame.
1913+ video_fps (Optional[List[float]]): Source FPS for each video item.
18781914 media_tokens_preexpanded (bool): Whether prompt token IDs already contain
18791915 one model token per projected media embedding.
18801916 offload_params (Optional[Dict]): Opaque metadata forwarded to the payload stager.
@@ -1952,6 +1988,8 @@ def add_request(
19521988 imgs_sizes = imgs_sizes ,
19531989 precomputed_block_hashes = precomputed_block_hashes ,
19541990 num_frames = num_frames ,
1991+ video_frame_indices = video_frame_indices ,
1992+ video_fps = video_fps ,
19551993 media_tokens_preexpanded = media_tokens_preexpanded ,
19561994 offload_params = offload_params ,
19571995 media_cache_key = media_cache_key ,
@@ -2016,6 +2054,8 @@ def _build_vlm_request(
20162054 imgs_sizes : Optional [Tensor ],
20172055 precomputed_block_hashes : Optional [List [int ]] = None ,
20182056 num_frames : Optional [Tensor ] = None ,
2057+ video_frame_indices : Optional [List [List [int ]]] = None ,
2058+ video_fps : Optional [List [float ]] = None ,
20192059 media_tokens_preexpanded : bool = False ,
20202060 offload_params : Optional [Dict ] = None ,
20212061 media_cache_key : Optional [str ] = None ,
@@ -2031,6 +2071,8 @@ def _build_vlm_request(
20312071 num_img_embeddings_per_tile = cached_vision_entry .num_img_embeddings_per_tile
20322072 imgs_sizes = cached_vision_entry .imgs_sizes
20332073 num_frames = cached_vision_entry .num_frames
2074+ video_frame_indices = cached_vision_entry .video_frame_indices
2075+ video_fps = cached_vision_entry .video_fps
20342076 elif num_frames is not None :
20352077 modality = "video"
20362078 missing = [
@@ -2084,6 +2126,8 @@ def _build_vlm_request(
20842126 ("num_tiles" , num_tiles ),
20852127 ("imgs_sizes" , imgs_sizes ),
20862128 ("num_frames" , num_frames ),
2129+ ("video_frame_indices" , video_frame_indices ),
2130+ ("video_fps" , video_fps ),
20872131 ):
20882132 if value is not None :
20892133 media_inputs [name ] = value
@@ -2132,6 +2176,14 @@ def _build_vlm_request(
21322176 expansion_kwargs = {"num_tiles" : num_tiles , "imgs_sizes" : imgs_sizes }
21332177 if num_frames is not None :
21342178 expansion_kwargs ["num_frames" ] = num_frames
2179+ prompt_config = inference_wrapper .multimodal_prompt_config
2180+ if (
2181+ prompt_config is not None
2182+ and prompt_config .video_spec .expansion_mode == "temporal_patch"
2183+ ):
2184+ expansion_kwargs ["tokenizer" ] = self .controller .tokenizer
2185+ expansion_kwargs ["video_frame_indices" ] = video_frame_indices
2186+ expansion_kwargs ["video_fps" ] = video_fps
21352187 expanded_tokens_list , mask_list = inference_wrapper .expand_image_tokens (
21362188 token_list , image_token_id = media_token_id , ** expansion_kwargs
21372189 )
@@ -2188,6 +2240,8 @@ def _build_vlm_request(
21882240 num_img_embeddings_per_tile = num_img_embeddings_per_tile ,
21892241 imgs_sizes = imgs_sizes ,
21902242 num_frames = num_frames ,
2243+ video_frame_indices = video_frame_indices ,
2244+ video_fps = video_fps ,
21912245 )
21922246
21932247 self .context .add_vlm_request_data (
@@ -2223,6 +2277,8 @@ def _build_vlm_request(
22232277 num_tiles = num_tiles ,
22242278 imgs_sizes = imgs_sizes ,
22252279 num_frames = num_frames ,
2280+ video_frame_indices = video_frame_indices ,
2281+ video_fps = video_fps ,
22262282 media_tokens_preexpanded = media_tokens_preexpanded ,
22272283 media_cache_key = media_cache_key ,
22282284 decoder_seq_length = 0 ,
0 commit comments