A high-throughput and memory-efficient inference and serving engine for LLMs
Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git
Synced Nov 15, 13:30 UTC
[Core] Remove prompt string from engine core data structures (#17214)
Signed-off-by: Nick Hill <nhill@redhat.com>
Nick Hill committed
Apr 25, 2025 at 23:41 UTC
df6f3ce883bbfb1884b040f178496a3da33209b9
21 files changed
+40
-76
tests/tokenization/test_detokenize.py
+2
-2
@@ -60,8 +60,8 @@ def _run_incremental_decode(tokenizer,
60
skip_special_tokens=skip_special_tokens,
61
spaces_between_special_tokens=spaces_between_special_tokens,
62
)
63
- request = EngineCoreRequest("", "", prompt_token_ids, None, None, None,
64
- params, None, 0.0, None)
63
+ request = EngineCoreRequest("", prompt_token_ids, None, None, None, params,
64
+ None, 0.0, None)
65
66
if fast is None:
67
detokenizer = IncrementalDetokenizer.from_new_request(
tests/v1/core/test_kv_cache_utils.py
-1
@@ -37,7 +37,6 @@ def make_request(request_id,
37
38
return Request(
39
request_id=request_id,
40
- prompt=None,
40
prompt_token_ids=prompt_token_ids,
41
multi_modal_inputs=multi_modal_inputs,
42
multi_modal_hashes=mm_hashes,
tests/v1/core/test_prefix_caching.py
-1
@@ -29,7 +29,6 @@ def make_request(request_id,
29
30
return Request(
31
request_id=request_id,
32
- prompt=None,
32
prompt_token_ids=prompt_token_ids,
33
multi_modal_inputs=multi_modal_inputs,
34
multi_modal_hashes=mm_hashes,
tests/v1/core/test_scheduler.py
-1
@@ -132,7 +132,6 @@ def create_requests(num_requests: int,
132
mm_inputs = None
133
request = Request(
134
request_id=f"{i}",
135
- prompt=None,
135
prompt_token_ids=[i] * num_tokens,
136
sampling_params=sampling_params,
137
multi_modal_inputs=mm_inputs,
tests/v1/engine/test_engine_core.py
+1
-2
@@ -31,8 +31,7 @@ PROMPT_TOKENS = TOKENIZER(PROMPT).input_ids
31
32
def make_request() -> EngineCoreRequest:
33
return EngineCoreRequest(
34
- request_id=uuid.uuid4(),
35
- prompt=PROMPT,
34
+ request_id=str(uuid.uuid4()),
35
prompt_token_ids=PROMPT_TOKENS,
36
mm_inputs=None,
37
mm_hashes=None,
tests/v1/engine/test_engine_core_client.py
-1
@@ -35,7 +35,6 @@ PROMPT_TOKENS = TOKENIZER(PROMPT).input_ids
35
def make_request(params: SamplingParams) -> EngineCoreRequest:
36
return EngineCoreRequest(
37
request_id=str(uuid.uuid4()),
38
- prompt=PROMPT,
38
prompt_token_ids=PROMPT_TOKENS,
39
mm_inputs=None,
40
mm_hashes=None,
tests/v1/engine/test_output_processor.py
+16
-26
@@ -50,7 +50,6 @@ def test_incremental_detokenization(request_output_kind: RequestOutputKind,
50
# Make N requests.
51
requests = [
52
EngineCoreRequest(request_id=f"request-{idx}",
53
- prompt=prompt,
53
prompt_token_ids=prompt_tokens,
54
arrival_time=0,
55
mm_inputs=None,
@@ -64,14 +63,13 @@ def test_incremental_detokenization(request_output_kind: RequestOutputKind,
63
output_kind=request_output_kind,
64
stop=[],
65
include_stop_str_in_output=False,
67
- )) for idx, (prompt, prompt_tokens) in enumerate(
68
- zip(dummy_test_vectors.prompt_strings,
69
- dummy_test_vectors.prompt_tokens))
66
+ ))
67
+ for idx, prompt_tokens in enumerate(dummy_test_vectors.prompt_tokens)
68
]
69
70
# Add requests to the detokenizer.
73
- for request in requests:
74
- output_processor.add_request(request)
71
+ for request, prompt in zip(requests, dummy_test_vectors.prompt_strings):
72
+ output_processor.add_request(request, prompt)
73
74
gen_strings = {}
75
gen_tokens = {}
@@ -398,7 +396,6 @@ def test_logprobs_processor(request_output_kind: RequestOutputKind,
396
]
397
requests = [
398
EngineCoreRequest(request_id=request_id_list[idx],
401
- prompt=prompt,
399
prompt_token_ids=prompt_tokens,
400
arrival_time=0,
401
mm_inputs=None,
@@ -414,14 +411,13 @@ def test_logprobs_processor(request_output_kind: RequestOutputKind,
411
include_stop_str_in_output=False,
412
logprobs=num_sample_logprobs,
413
prompt_logprobs=num_prompt_logprobs,
417
- )) for idx, (prompt, prompt_tokens) in enumerate(
418
- zip(dummy_test_vectors.prompt_strings,
419
- dummy_test_vectors.prompt_tokens))
414
+ ))
415
+ for idx, prompt_tokens in enumerate(dummy_test_vectors.prompt_tokens)
416
]
417
418
# Add requests to the detokenizer.
423
- for request in requests:
424
- output_processor.add_request(request)
419
+ for request, prompt in zip(requests, dummy_test_vectors.prompt_strings):
420
+ output_processor.add_request(request, prompt)
421
422
gen_tokens = {}
423
gen_logprobs = {}
@@ -562,7 +558,6 @@ def test_stop_token(include_stop_str_in_output: bool,
558
request_id = "request-0"
559
request = EngineCoreRequest(
560
request_id=request_id,
565
- prompt=prompt_string,
561
prompt_token_ids=prompt_tokens,
562
arrival_time=0,
563
mm_inputs=None,
@@ -583,7 +578,7 @@ def test_stop_token(include_stop_str_in_output: bool,
578
))
579
580
# Add request to the detokenizer.
586
- output_processor.add_request(request)
581
+ output_processor.add_request(request, prompt_string)
582
583
# Loop over engine core steps; run output processor
584
gen_string = ""
@@ -659,7 +654,6 @@ def test_stop_string(include_stop_str_in_output: bool,
654
requests = [
655
EngineCoreRequest(
656
request_id=request_id_list[idx],
662
- prompt=prompt,
657
prompt_token_ids=prompt_tokens,
658
arrival_time=0,
659
mm_inputs=None,
@@ -675,14 +669,13 @@ def test_stop_string(include_stop_str_in_output: bool,
669
include_stop_str_in_output=include_stop_str_in_output,
670
logprobs=num_sample_logprobs,
671
prompt_logprobs=None,
678
- )) for idx, (prompt, prompt_tokens) in enumerate(
679
- zip(dummy_test_vectors.prompt_strings,
680
- dummy_test_vectors.prompt_tokens))
672
+ ))
673
+ for idx, prompt_tokens in enumerate(dummy_test_vectors.prompt_tokens)
674
]
675
676
# Add requests to the detokenizer.
684
- for request in requests:
685
- output_processor.add_request(request)
677
+ for request, prompt in zip(requests, dummy_test_vectors.prompt_strings):
678
+ output_processor.add_request(request, prompt)
679
680
gen_strings = {}
681
gen_tokens = {}
@@ -774,7 +767,6 @@ def test_iteration_stats(dummy_test_vectors):
767
requests = [
768
EngineCoreRequest(
769
request_id=f"request-{idx}",
777
- prompt=prompt,
770
prompt_token_ids=prompt_tokens,
771
arrival_time=0,
772
mm_inputs=None,
@@ -783,15 +775,13 @@ def test_iteration_stats(dummy_test_vectors):
775
eos_token_id=None,
776
lora_request=None,
777
sampling_params=SamplingParams(),
786
- ) for idx, (prompt, prompt_tokens) in enumerate(
787
- zip(dummy_test_vectors.prompt_strings,
788
- dummy_test_vectors.prompt_tokens))
778
+ ) for idx, prompt_tokens in enumerate(dummy_test_vectors.prompt_tokens)
779
]
780
781
# Add all requests except one to the OutputProcessor.
782
num_active = len(dummy_test_vectors.generation_tokens) - 1
783
for request in requests[:num_active]:
794
- output_processor.add_request(request)
784
+ output_processor.add_request(request, None)
785
inactive_request = requests[num_active]
786
787
# First iteration has 2 prefills.
@@ -817,7 +807,7 @@ def test_iteration_stats(dummy_test_vectors):
807
assert iteration_stats.num_generation_tokens == num_active
808
809
# Add a new request - prefill and 2 decodes in this step.
820
- output_processor.add_request(inactive_request)
810
+ output_processor.add_request(inactive_request, None)
811
num_active += 1
812
outputs = engine_core.get_outputs()[:num_active]
813
iteration_stats = IterationStats()
tests/v1/tpu/worker/test_tpu_model_runner.py
-1
@@ -77,7 +77,6 @@ def _schedule_new_request(*req_ids: str) -> SchedulerOutput:
77
NewRequestData(
78
req_id=req_id,
79
prompt_token_ids=[1, 2, 3],
80
- prompt="test",
80
mm_inputs=[],
81
mm_hashes=[],
82
mm_positions=[],
tests/v1/worker/test_gpu_input_batch.py
-1
@@ -195,7 +195,6 @@ def _construct_cached_request_state(req_id_suffix: int):
195
return CachedRequestState(
196
req_id=f"req_id_{req_id_suffix}",
197
prompt_token_ids=prompt_token_ids,
198
- prompt=None,
198
sampling_params=_create_sampling_params(),
199
mm_inputs=[],
200
mm_positions=[],
tests/v1/worker/test_gpu_model_runner.py
-1
@@ -50,7 +50,6 @@ def _schedule_new_request(*req_ids: str) -> SchedulerOutput:
50
NewRequestData(
51
req_id=req_id,
52
prompt_token_ids=[1, 2, 3],
53
- prompt="test",
53
mm_inputs=[],
54
mm_hashes=[],
55
mm_positions=[],
vllm/v1/core/sched/output.py
-2
@@ -22,7 +22,6 @@ class NewRequestData:
22
23
req_id: str
24
prompt_token_ids: list[int]
25
- prompt: Optional[str]
25
mm_inputs: list[MultiModalKwargs]
26
mm_hashes: list[str]
27
mm_positions: list[PlaceholderRange]
@@ -40,7 +39,6 @@ class NewRequestData:
39
return cls(
40
req_id=request.request_id,
41
prompt_token_ids=request.prompt_token_ids,
43
- prompt=request.prompt,
42
mm_inputs=request.mm_inputs,
43
mm_hashes=request.mm_hashes,
44
mm_positions=request.mm_positions,
vllm/v1/engine/__init__.py
-3
@@ -49,9 +49,6 @@ class EngineCoreRequest(
49
# due to circular imports and typing we have in data.py
50
51
request_id: str
52
- # NOTE(ywang96): original text prompt is needed when a request is added to
53
- # Detokenizer, but set to None when it is added to EngineCoreClient.
54
- prompt: Optional[str]
52
prompt_token_ids: list[int]
53
mm_inputs: Optional[Sequence[Optional[MultiModalKwargs]]]
54
mm_hashes: Optional[list[str]]
vllm/v1/engine/async_llm.py
+9
-8
@@ -217,14 +217,12 @@ class AsyncLLM(EngineClient):
217
queue = RequestOutputCollector(output_kind=params.output_kind)
218
219
# Convert Input --> Request.
220
- request = self.processor.process_inputs(request_id, prompt, params,
221
- arrival_time, lora_request,
222
- trace_headers,
223
- prompt_adapter_request,
224
- priority)
220
+ prompt_str, request = self.processor.process_inputs(
221
+ request_id, prompt, params, arrival_time, lora_request,
222
+ trace_headers, prompt_adapter_request, priority)
223
224
if params.n == 1:
227
- await self._add_request(request, None, 0, queue)
225
+ await self._add_request(request, prompt_str, None, 0, queue)
226
return queue
227
228
# Fan out child requests (for n>1).
@@ -234,15 +232,18 @@ class AsyncLLM(EngineClient):
232
child_request = request if idx == params.n - 1 else copy(request)
233
child_request.request_id = request_id
234
child_request.sampling_params = params
237
- await self._add_request(child_request, parent_request, idx, queue)
235
+ await self._add_request(child_request, prompt_str, parent_request,
236
+ idx, queue)
237
return queue
238
239
async def _add_request(self, request: EngineCoreRequest,
240
+ prompt: Optional[str],
241
parent_req: Optional[ParentRequest], index: int,
242
queue: RequestOutputCollector):
243
244
# Add the request to OutputProcessor (this process).
245
- self.output_processor.add_request(request, parent_req, index, queue)
245
+ self.output_processor.add_request(request, prompt, parent_req, index,
246
+ queue)
247
248
# Add the EngineCoreRequest to EngineCore (separate process).
249
await self.engine_core.add_request_async(request)
vllm/v1/engine/core_client.py
-9
@@ -583,9 +583,6 @@ class SyncMPClient(MPClient):
583
return future.result()
584
585
def add_request(self, request: EngineCoreRequest) -> None:
586
- # NOTE: text prompt is not needed in the core engine as it has been
587
- # tokenized.
588
- request.prompt = None
586
self._send_input(EngineCoreRequestType.ADD, request)
587
588
def abort_requests(self, request_ids: list[str]) -> None:
@@ -772,9 +769,6 @@ class AsyncMPClient(MPClient):
769
return await future
770
771
async def add_request_async(self, request: EngineCoreRequest) -> None:
775
- # NOTE: text prompt is not needed in the core engine as it has been
776
- # tokenized.
777
- request.prompt = None
772
await self._send_input(EngineCoreRequestType.ADD, request)
773
self._ensure_output_queue_task()
774
@@ -867,9 +861,6 @@ class DPAsyncMPClient(AsyncMPClient):
861
]))[0]
862
863
async def add_request_async(self, request: EngineCoreRequest) -> None:
870
- # NOTE: text prompt is not needed in the core engine as it has been
871
- # tokenized.
872
- request.prompt = None
864
request.current_wave = self.current_wave
865
866
chosen_engine = self.get_core_engine_for_request()
vllm/v1/engine/llm_engine.py
+6
-7
@@ -180,17 +180,15 @@ class LLMEngine:
180
priority: int = 0,
181
) -> None:
182
# Process raw inputs into the request.
183
- request = self.processor.process_inputs(request_id, prompt, params,
184
- arrival_time, lora_request,
185
- trace_headers,
186
- prompt_adapter_request,
187
- priority)
183
+ prompt_str, request = self.processor.process_inputs(
184
+ request_id, prompt, params, arrival_time, lora_request,
185
+ trace_headers, prompt_adapter_request, priority)
186
187
n = params.n if isinstance(params, SamplingParams) else 1
188
189
if n == 1:
190
# Make a new RequestState and queue.
193
- self.output_processor.add_request(request, None, 0)
191
+ self.output_processor.add_request(request, prompt_str, None, 0)
192
# Add the request to EngineCore.
193
self.engine_core.add_request(request)
194
return
@@ -204,7 +202,8 @@ class LLMEngine:
202
child_request.sampling_params = params
203
204
# Make a new RequestState and queue.
207
- self.output_processor.add_request(child_request, parent_req, idx)
205
+ self.output_processor.add_request(child_request, prompt_str,
206
+ parent_req, idx)
207
# Add the request to EngineCore.
208
self.engine_core.add_request(child_request)
209
vllm/v1/engine/output_processor.py
+4
-1
@@ -109,6 +109,7 @@ class RequestState:
109
cls,
110
tokenizer: AnyTokenizer,
111
request: EngineCoreRequest,
112
+ prompt: Optional[str],
113
parent_req: Optional[ParentRequest],
114
request_index: int,
115
queue: Optional[RequestOutputCollector],
@@ -123,7 +124,7 @@ class RequestState:
124
lora_name=(request.lora_request.name
125
if request.lora_request is not None else None),
126
output_kind=request.sampling_params.output_kind,
126
- prompt=request.prompt,
127
+ prompt=prompt,
128
prompt_token_ids=request.prompt_token_ids,
129
logprobs_processor=LogprobsProcessor.from_new_request(
130
tokenizer=tokenizer,
@@ -267,6 +268,7 @@ class OutputProcessor:
268
def add_request(
269
self,
270
request: EngineCoreRequest,
271
+ prompt: Optional[str],
272
parent_req: Optional[ParentRequest] = None,
273
request_index: int = 0,
274
queue: Optional[RequestOutputCollector] = None,
@@ -278,6 +280,7 @@ class OutputProcessor:
280
req_state = RequestState.from_new_request(
281
tokenizer=self.tokenizer.get_lora_tokenizer(request.lora_request),
282
request=request,
283
+ prompt=prompt,
284
parent_req=parent_req,
285
request_index=request_index,
286
queue=queue,
vllm/v1/engine/processor.py
+2
-3
@@ -202,7 +202,7 @@ class Processor:
202
trace_headers: Optional[Mapping[str, str]] = None,
203
prompt_adapter_request: Optional[PromptAdapterRequest] = None,
204
priority: int = 0,
205
- ) -> EngineCoreRequest:
205
+ ) -> tuple[Optional[str], EngineCoreRequest]:
206
207
# TODO(woosuk): Support pooling models.
208
# TODO(woosuk): Support encoder-decoder models.
@@ -306,9 +306,8 @@ class Processor:
306
else:
307
sorted_mm_inputs = orig_sorted_mm_inputs
308
309
- return EngineCoreRequest(
309
+ return decoder_inputs.get("prompt"), EngineCoreRequest(
310
request_id=request_id,
311
- prompt=decoder_inputs.get("prompt"),
311
prompt_token_ids=decoder_inputs["prompt_token_ids"],
312
mm_inputs=sorted_mm_inputs,
313
mm_hashes=sorted_mm_hashes,
vllm/v1/request.py
-3
@@ -20,7 +20,6 @@ class Request:
20
def __init__(
21
self,
22
request_id: str,
23
- prompt: Optional[str],
23
prompt_token_ids: list[int],
24
multi_modal_inputs: Optional[list[MultiModalKwargs]],
25
multi_modal_hashes: Optional[list[str]],
@@ -46,7 +45,6 @@ class Request:
45
assert sampling_params.max_tokens is not None
46
self.max_tokens = sampling_params.max_tokens
47
49
- self.prompt = prompt
48
self.prompt_token_ids = prompt_token_ids
49
self.num_prompt_tokens = len(self.prompt_token_ids)
50
self._output_token_ids: list[int] = []
@@ -81,7 +79,6 @@ class Request:
79
80
return cls(
81
request_id=request.request_id,
84
- prompt=request.prompt,
82
prompt_token_ids=request.prompt_token_ids,
83
multi_modal_inputs=request.mm_inputs,
84
multi_modal_hashes=request.mm_hashes,
vllm/v1/worker/gpu_input_batch.py
-1
@@ -24,7 +24,6 @@ class CachedRequestState:
24
25
req_id: str
26
prompt_token_ids: list[int]
27
- prompt: Optional[str]
27
mm_inputs: list[MultiModalKwargs]
28
mm_positions: list[PlaceholderRange]
29
sampling_params: SamplingParams
vllm/v1/worker/gpu_model_runner.py
-1
@@ -347,7 +347,6 @@ class GPUModelRunner(LoRAModelRunnerMixin):
347
self.requests[req_id] = CachedRequestState(
348
req_id=req_id,
349
prompt_token_ids=new_req_data.prompt_token_ids,
350
- prompt=new_req_data.prompt,
350
mm_inputs=new_req_data.mm_inputs,
351
mm_positions=new_req_data.mm_positions,
352
sampling_params=sampling_params,
vllm/v1/worker/tpu_model_runner.py
-1
@@ -356,7 +356,6 @@ class TPUModelRunner:
356
self.requests[req_id] = CachedRequestState(
357
req_id=req_id,
358
prompt_token_ids=new_req_data.prompt_token_ids,
359
- prompt=new_req_data.prompt,
359
mm_inputs=new_req_data.mm_inputs,
360
mm_positions=new_req_data.mm_positions,
361
sampling_params=sampling_params,