[Rust Frontend] Stamp arrival_time at the frontend entry (#47787)

Signed-off-by: Tahsin Tunan <tahsintunan@gmail.com>
This commit is contained in:
Tahsin Tunan
2026-07-07 03:27:10 +00:00
committed by GitHub
parent 39a1d32b59
commit 34e6dfced8
10 changed files with 63 additions and 12 deletions
+4
View File
@@ -172,6 +172,9 @@ impl ChatLlm {
pub async fn chat(&self, mut request: ChatRequest) -> Result<ChatEventStream> {
request.validate()?;
// Stamp before rendering so render and tokenize count toward TTFT/e2e.
let arrival_time = vllm_llm::current_unix_timestamp_secs();
let output_processor = self.backend.new_chat_output_processor(
&mut request,
NewChatOutputProcessorOptions {
@@ -210,6 +213,7 @@ impl ChatLlm {
data_parallel_rank: request.data_parallel_rank,
reasoning_parser_kwargs,
lora_request: request.lora_request,
arrival_time: Some(arrival_time),
};
let decoded_stream = self.text.generate(text_request).await?.map_err(Error::from).boxed();
+1
View File
@@ -14,6 +14,7 @@ pub use output::{
GenerateOutputStreamExt, GeneratePromptInfo, TokenUsage,
};
pub use request::GenerateRequest;
pub use request_metrics::current_unix_timestamp_secs;
pub use vllm_engine_core_client::protocol::logprobs::{Logprobs, PositionLogprobs, TokenLogprob};
use crate::inflight::InflightRequests;
+4 -10
View File
@@ -1,5 +1,4 @@
use std::collections::BTreeMap;
use std::time::{SystemTime, UNIX_EPOCH};
use uuid::Uuid;
use vllm_engine_core_client::protocol::lora::LoraRequest;
@@ -8,6 +7,7 @@ use vllm_engine_core_client::protocol::request::{EngineCoreRequest, ReasoningPar
use vllm_engine_core_client::protocol::sampling::EngineCoreSamplingParams;
use crate::error::{Error, Result};
use crate::request_metrics::current_unix_timestamp_secs;
/// Tokenized decoder-only generate request accepted by [`crate::Llm`].
///
@@ -30,8 +30,9 @@ pub struct GenerateRequest {
pub mm_features: Option<MmFeatures>,
/// Unix timestamp, in seconds, when this request arrived at the frontend.
///
/// When omitted, the Rust frontend fills it immediately before sending the
/// request to engine-core, matching Python's default arrival-time behavior.
/// Stamped at the frontend entry, before render and tokenization, to match
/// Python's renderer-entry arrival_time. When omitted, it is filled as a
/// fallback before the request is sent to engine-core.
pub arrival_time: Option<f64>,
/// Optional salt used to partition prefix-cache entries for this request.
pub cache_salt: Option<String>,
@@ -122,13 +123,6 @@ impl PreparedGenerateRequest {
}
}
fn current_unix_timestamp_secs() -> f64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("system clock is before unix epoch")
.as_secs_f64()
}
#[cfg(test)]
mod tests {
use std::collections::BTreeMap;
+1 -1
View File
@@ -330,7 +330,7 @@ fn diff_or_zero(end: f64, start: f64) -> f64 {
///
/// Original Python request timestamp source:
/// <https://github.com/vllm-project/vllm/blob/bc2c0c86efb28e77677a3cfb8687e976914a313a/vllm/v1/metrics/stats.py#L206-L216>
pub(crate) fn current_unix_timestamp_secs() -> f64 {
pub fn current_unix_timestamp_secs() -> f64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("system clock is before unix epoch")
+1
View File
@@ -94,6 +94,7 @@ pub fn to_text_request(
data_parallel_rank: None,
reasoning_parser_kwargs: None,
lora_request: None,
arrival_time: None,
})
}
@@ -70,6 +70,7 @@ pub(super) fn prepare_generate_request(
data_parallel_rank: ctx.data_parallel_rank,
reasoning_parser_kwargs: None,
lora_request: lora_resolution.lora_request.clone(),
arrival_time: None,
};
Ok(PreparedRequest {
@@ -144,6 +144,7 @@ pub(super) fn prepare_completion_request(
data_parallel_rank: ctx.data_parallel_rank,
reasoning_parser_kwargs: None,
lora_request: lora_resolution.lora_request.clone(),
arrival_time: None,
};
Ok(PreparedRequest {
+4
View File
@@ -132,6 +132,10 @@ impl TextLlm {
) -> Result<(TextRequest, GenerateOutputStream)> {
request.validate()?;
if request.arrival_time.is_none() {
request.arrival_time = Some(vllm_llm::current_unix_timestamp_secs());
}
let tokenizer = self.backend.tokenizer();
let prompt_token_ids = match take(&mut request.prompt) {
Prompt::Text(text) => tokenizer.encode(&text, request.add_special_tokens)?,
+39 -1
View File
@@ -56,7 +56,7 @@ pub fn lower_text_request(
data_parallel_rank: request.data_parallel_rank,
reasoning_parser_kwargs: request.reasoning_parser_kwargs.clone(),
lora_request: request.lora_request.clone(),
arrival_time: None,
arrival_time: request.arrival_time,
trace_headers: None,
};
@@ -1143,6 +1143,44 @@ mod tests {
assert_eq!(prepared.generate_request.request_id, "text-1");
}
#[test]
fn lower_text_request_passes_arrival_time_through() {
let request = TextRequest {
arrival_time: Some(42.5),
..sample_request()
};
let prepared = lower_text_request(
request,
vec![1, 2, 3],
sample_sampling_hints(),
sample_sampling_limits(),
&stub_tokenizer(),
)
.unwrap();
assert_eq!(prepared.generate_request.arrival_time, Some(42.5));
}
#[test]
fn lower_text_request_leaves_arrival_time_unset_when_absent() {
let request = TextRequest {
arrival_time: None,
..sample_request()
};
let prepared = lower_text_request(
request,
vec![1, 2, 3],
sample_sampling_hints(),
sample_sampling_limits(),
&stub_tokenizer(),
)
.unwrap();
assert_eq!(prepared.generate_request.arrival_time, None);
}
#[test]
fn resolve_max_tokens_user_smaller_than_model_limit() {
let result = resolve_max_tokens(Some(50), None, 200, 100);
+7
View File
@@ -187,6 +187,12 @@ pub struct TextRequest {
/// LoRA adapter selected for this request.
#[serde(default)]
pub lora_request: Option<LoraRequest>,
/// Wall-clock unix timestamp (seconds) when this request arrived at the
/// frontend, stamped before render/tokenize to match Python's
/// renderer-entry arrival_time. When unset, it is stamped before
/// tokenization.
#[serde(default)]
pub arrival_time: Option<f64>,
}
impl TextRequest {
@@ -205,6 +211,7 @@ impl TextRequest {
data_parallel_rank: None,
reasoning_parser_kwargs: None,
lora_request: None,
arrival_time: None,
}
}