Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions rust/src/cmd/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,19 @@ pub struct SharedRuntimeArgs {
#[serde(default)]
pub chat_template_content_format: ChatTemplateContentFormatOption,

/// When `--max-logprobs` is specified, represents single tokens as
/// strings of the form 'token_id:{token_id}' so that tokens that are not
/// JSON-encodable can be identified.
///
/// A request's own `return_tokens_as_token_ids` overrides this default.
#[arg(
long,
default_missing_value = "true",
num_args = 0..=1
)]
#[serde(default)]
pub return_tokens_as_token_ids: bool,

/// Log a summary line for each completed request, including prompt/output
/// token counts and finish reason.
#[arg(long)]
Expand Down Expand Up @@ -766,6 +779,7 @@ impl SharedRuntimeArgs {
ApiServerOptions {
enable_log_requests: self.enable_log_requests,
enable_prompt_tokens_details: self.enable_prompt_tokens_details,
default_return_tokens_as_token_ids: self.return_tokens_as_token_ids,
enable_per_request_metrics: self.enable_per_request_metrics,
enable_request_id_headers: self.enable_request_id_headers,
enable_scale_out: self.enable_scale_out,
Expand Down
23 changes: 23 additions & 0 deletions rust/src/cmd/src/cli/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ fn serve_args_forward_python_flags_with_separator() {
limit_mm_per_prompt: {},
lora_modules: [],
chat_template_content_format: Auto,
return_tokens_as_token_ids: false,
enable_log_requests: false,
enable_prompt_tokens_details: false,
enable_per_request_metrics: false,
Expand Down Expand Up @@ -733,6 +734,23 @@ fn serve_passes_enable_prompt_tokens_details_into_config() {
assert!(config.api_server_options.enable_prompt_tokens_details);
}

#[test]
fn serve_passes_return_tokens_as_token_ids_into_config() {
let cli = Cli::try_parse_from([
"vllm-rs",
"serve",
"Qwen/Qwen3-0.6B",
"--return-tokens-as-token-ids",
])
.unwrap();

let Command::Serve(args) = cli.command else {
panic!("expected serve args");
};
let config = args.to_frontend_config("tcp://127.0.0.1:62100".to_string());
assert!(config.api_server_options.default_return_tokens_as_token_ids);
}

#[test]
fn serve_passes_tls_into_config() {
let cli = Cli::try_parse_from([
Expand Down Expand Up @@ -1235,6 +1253,7 @@ fn frontend_args_accept_json() {
limit_mm_per_prompt: {},
lora_modules: [],
chat_template_content_format: Auto,
return_tokens_as_token_ids: false,
enable_log_requests: false,
enable_prompt_tokens_details: false,
enable_per_request_metrics: false,
Expand Down Expand Up @@ -2150,6 +2169,7 @@ fn serve_args_accept_handshake_aliases() {
limit_mm_per_prompt: {},
lora_modules: [],
chat_template_content_format: Auto,
return_tokens_as_token_ids: false,
enable_log_requests: false,
enable_prompt_tokens_details: false,
enable_per_request_metrics: false,
Expand Down Expand Up @@ -2320,6 +2340,7 @@ fn serve_frontend_config_uses_dp_address_as_advertised_host() {
api_server_options: ApiServerOptions {
enable_log_requests: false,
enable_prompt_tokens_details: false,
default_return_tokens_as_token_ids: false,
enable_per_request_metrics: false,
enable_request_id_headers: false,
enable_scale_out: false,
Expand Down Expand Up @@ -2427,6 +2448,7 @@ fn serve_frontend_config_keeps_tcp_transport_for_non_local_only_topology() {
api_server_options: ApiServerOptions {
enable_log_requests: false,
enable_prompt_tokens_details: false,
default_return_tokens_as_token_ids: false,
enable_per_request_metrics: false,
enable_request_id_headers: false,
enable_scale_out: false,
Expand Down Expand Up @@ -2622,6 +2644,7 @@ fn frontend_config_uses_external_coordinator_when_coordinator_address_is_present
api_server_options: ApiServerOptions {
enable_log_requests: false,
enable_prompt_tokens_details: false,
default_return_tokens_as_token_ids: false,
enable_per_request_metrics: false,
enable_request_id_headers: false,
enable_scale_out: false,
Expand Down
11 changes: 0 additions & 11 deletions rust/src/cmd/src/cli/unsupported.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,17 +413,6 @@ pub struct ServerUnsupportedArgs {
#[arg(long)]
pub response_role: Option<Unsupported>,

/// When `--max-logprobs` is specified, represents single tokens as
/// strings of the form 'token_id:{token_id}' so that tokens that are not
/// JSON-encodable can be identified.
#[arg(
long,
visible_alias = "no-return-tokens-as-token-ids",
default_missing_value = "true",
num_args = 0..=1
)]
pub return_tokens_as_token_ids: Option<Unsupported>,

/// Enable auto tool choice for supported models. Use `--tool-call-parser`
/// to specify which parser to use.
#[arg(
Expand Down
3 changes: 3 additions & 0 deletions rust/src/server/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ pub struct ApiServerOptions {
pub enable_log_requests: bool,
/// When `true`, include prompt token cache details in response usage.
pub enable_prompt_tokens_details: bool,
/// Format logprob tokens as `token_id:{id}` unless the request sets
/// `return_tokens_as_token_ids` itself.
pub default_return_tokens_as_token_ids: bool,
/// Include request timing metrics in OpenAI chat and completion responses.
pub enable_per_request_metrics: bool,
/// When `true`, set `X-Request-Id` on every HTTP response.
Expand Down
6 changes: 6 additions & 0 deletions rust/src/server/src/routes/openai/chat_completions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ async fn collect_chat_completion(
ApiServerOptions {
enable_log_requests,
enable_prompt_tokens_details,
default_return_tokens_as_token_ids,
enable_per_request_metrics,
..
}: ApiServerOptions,
Expand All @@ -147,6 +148,8 @@ async fn collect_chat_completion(
is_named_tool_choice,
}: ResponseOptions,
) -> Result<ChatCompletionResponse, ApiError> {
let return_tokens_as_token_ids =
return_tokens_as_token_ids.unwrap_or(default_return_tokens_as_token_ids);
let collected = stream.collect_message().await.map_err(|error| {
server_error!(
"failed to collect chat completion response: {}",
Expand Down Expand Up @@ -260,6 +263,7 @@ async fn chat_completion_chunk_stream(
ApiServerOptions {
enable_log_requests,
enable_prompt_tokens_details,
default_return_tokens_as_token_ids,
enable_per_request_metrics,
..
}: ApiServerOptions,
Expand All @@ -278,6 +282,8 @@ async fn chat_completion_chunk_stream(
}: ResponseOptions,
mut y: TryYielder<ChatCompletionStreamResponse, ApiError>,
) -> Result<(), ApiError> {
let return_tokens_as_token_ids =
return_tokens_as_token_ids.unwrap_or(default_return_tokens_as_token_ids);
let envelope = Arc::new(StreamResponseEnvelope::new(
request_id,
"chat.completion.chunk",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ pub(super) struct ResponseOptions {
pub echo: Option<String>,
/// Whether to include token IDs alongside generated text.
pub return_token_ids: bool,
/// Whether to format logprob tokens as `token_id:{id}`.
pub return_tokens_as_token_ids: bool,
/// The request's `return_tokens_as_token_ids`; `None` falls back to the
/// server's `--return-tokens-as-token-ids`.
pub return_tokens_as_token_ids: Option<bool>,
/// Whether the request forces one named function tool.
pub is_named_tool_choice: bool,
}
Expand Down Expand Up @@ -226,7 +227,7 @@ pub(super) fn prepare_chat_request(
include_reasoning,
echo,
return_token_ids: request.return_token_ids.unwrap_or(false),
return_tokens_as_token_ids: request.return_tokens_as_token_ids.unwrap_or(false),
return_tokens_as_token_ids: request.return_tokens_as_token_ids,
is_named_tool_choice,
},
chat_request,
Expand Down Expand Up @@ -974,7 +975,7 @@ mod tests {

assert!(prepared.options.include_usage);
assert!(prepared.options.include_continuous_usage);
assert!(prepared.options.return_tokens_as_token_ids);
assert_eq!(prepared.options.return_tokens_as_token_ids, Some(true));
}

#[test]
Expand Down
6 changes: 6 additions & 0 deletions rust/src/server/src/routes/openai/completions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ async fn collect_completion(
ApiServerOptions {
enable_log_requests,
enable_prompt_tokens_details,
default_return_tokens_as_token_ids,
enable_per_request_metrics,
..
}: ApiServerOptions,
Expand All @@ -157,6 +158,8 @@ async fn collect_completion(
return_tokens_as_token_ids,
}: ResponseOptions,
) -> Result<CompletionResponse, ApiError> {
let return_tokens_as_token_ids =
return_tokens_as_token_ids.unwrap_or(default_return_tokens_as_token_ids);
let collected = stream
.collect_output()
.await
Expand Down Expand Up @@ -247,6 +250,7 @@ async fn completion_chunk_stream(
ApiServerOptions {
enable_log_requests,
enable_prompt_tokens_details,
default_return_tokens_as_token_ids,
enable_per_request_metrics,
..
}: ApiServerOptions,
Expand All @@ -263,6 +267,8 @@ async fn completion_chunk_stream(
}: ResponseOptions,
mut y: TryYielder<CompletionSseChunk, ApiError>,
) -> Result<(), ApiError> {
let return_tokens_as_token_ids =
return_tokens_as_token_ids.unwrap_or(default_return_tokens_as_token_ids);
pin_mut!(stream);
let envelope = Arc::new(StreamResponseEnvelope::new(
request_id,
Expand Down
9 changes: 5 additions & 4 deletions rust/src/server/src/routes/openai/completions/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ pub(super) struct ResponseOptions {
pub include_prompt_logprobs: bool,
/// Whether to include token IDs alongside generated text.
pub return_token_ids: bool,
/// Whether to format logprob tokens as `token_id:{id}`.
pub return_tokens_as_token_ids: bool,
/// The request's `return_tokens_as_token_ids`; `None` falls back to the
/// server's `--return-tokens-as-token-ids`.
pub return_tokens_as_token_ids: Option<bool>,
}

/// Validate and lower one OpenAI completions request into the internal
Expand Down Expand Up @@ -184,7 +185,7 @@ pub(super) fn prepare_completion_request(
requested_logprobs: request.logprobs,
include_prompt_logprobs,
return_token_ids: request.return_token_ids.unwrap_or(false),
return_tokens_as_token_ids: request.return_tokens_as_token_ids.unwrap_or(false),
return_tokens_as_token_ids: request.return_tokens_as_token_ids,
},
text_request,
})
Expand Down Expand Up @@ -506,7 +507,7 @@ mod tests {

assert!(prepared.options.include_usage);
assert!(prepared.options.include_continuous_usage);
assert!(prepared.options.return_tokens_as_token_ids);
assert_eq!(prepared.options.return_tokens_as_token_ids, Some(true));
}

#[test]
Expand Down
Loading