@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 0d657e44dc
Fork 0

A high-throughput and memory-efficient inference and serving engine for LLMs

[Rust Frontend] Fix DeepSeek V3.2 continue_final_message rendering (#45155)

Signed-off-by: reidliu41 <reid201711@gmail.com>

Reid committed Jun 11, 2026 at 17:34 UTC 0d657e44dcca844499b7adcd03ec590f933dfd29
2 files changed +22 -3
rust/src/chat/src/renderer/deepseek_v32/encoding.rs
+4 -3
@@ -49,6 +49,7 @@ pub(super) fn render_request(request: &ChatRequest) -> Result<String> {
49 let last_user_render_index =
50 find_last_user_render_index(request.messages.as_slice(), render_offset);
51 let last_user_actual_index = find_last_user_actual_index(request.messages.as_slice());
52 + let continue_final_message = request.chat_options.continue_final_message();
53 let mut prompt = String::from(BOS_TOKEN);
54
55 if request.tool_parsing_enabled() {
@@ -66,6 +67,7 @@ pub(super) fn render_request(request: &ChatRequest) -> Result<String> {
67 last_user_actual_index,
68 thinking_mode,
69 drop_thinking,
70 + continue_final_message,
71 )?;
72 }
73
@@ -96,6 +98,7 @@ fn render_message(
98 last_user_actual_index: usize,
99 thinking_mode: ThinkingMode,
100 drop_thinking: bool,
101 + continue_final_message: bool,
102 ) -> Result<()> {
103 let render_index = message_index as isize + render_offset;
104 let opens_thinking = render_index == last_user_render_index;
@@ -125,9 +128,7 @@ fn render_message(
128 thinking_mode,
129 drop_thinking,
130 ),
128 - // TODO: Respect `continue_final_message` and map it to DeepSeek's
129 - // prefix-style final-assistant continuation behavior.
130 - false,
131 + continue_final_message && message_index + 1 == messages.len(),
132 ),
133 ChatMessage::ToolResponse { content, .. } => render_tool_message(
134 out,
rust/src/chat/src/renderer/deepseek_v32/tests.rs
+18
@@ -404,6 +404,24 @@ fn assistant_after_last_user_requires_reasoning_or_tool_calls() {
404 expect!["chat template error: invalid DeepSeek V3.2 assistant message after last user message: expected reasoning or tool calls"]
405 .assert_eq(&error.to_report_string());
406 }
407 +
408 +#[test]
409 +fn continue_final_assistant_omits_final_eos() {
410 + let mut request = ChatRequest {
411 + messages: vec![
412 + ChatMessage::user("write"),
413 + ChatMessage::assistant_text("partial answer"),
414 + ],
415 + ..ChatRequest::for_test()
416 + };
417 + request.chat_options.generation_prompt_mode = GenerationPromptMode::ContinueFinalAssistant;
418 +
419 + let rendered = render_request(&request);
420 +
421 + expect!["<|begin▁of▁sentence|><|User|>write<|Assistant|></think>partial answer"]
422 + .assert_eq(&rendered);
423 +}
424 +
425 #[test]
426 fn render_rejects_multimodal_input() {
427 let request = ChatRequest {