Merge branch 'main' into patches

Signed-off-by: MOVZX <movzx@yahoo.com>
This commit is contained in:
2026-10-16 17:35:42 +07:00
347 changed files with 29531 additions and 3472 deletions
+1
View File
@@ -12,6 +12,7 @@ For two-tower vision encoders (e.g., DeepSeek-OCR's SAM + CLIP with dynamic tili
| Architecture | Models | CG for Image | CG for Video | Multi-Path Graph |
| ------------ | ------ | ------------ | ------------ | --------------- |
| `DeepseekOCRForCausalLM` | `DeepSeek-OCR` | ✅︎ | ❌︎ | ✅︎ |
| `DeepseekVLV2ForCausalLM` | `DeepSeek-VL2` | ✅︎ | ❌︎ | ❌︎ |
| `DeepseekV41ForCausalLM` | `DeepSeek-V4.1-Flash` | ✅︎ | ❌︎ | ❌︎ |
| `Ernie4_5_VLMoeForConditionalGeneration` | `ERNIE-4.5-VL` | ✅︎ | ❌︎ | ❌︎ |
| `Gemma3ForConditionalGeneration` | `Gemma3` | ✅︎ | ❌︎ | ❌︎ |
@@ -74,3 +74,12 @@ vllm serve XiaomiMiMo/MiMo-7B-Base \
is a good default to start with.
- If your model does not support MTP, use another method such as EAGLE or draft
model speculation.
- When the MTP head shares the target's unquantized lm_head (most MTP models),
`"draft_lm_head_quantization": "fp8"` or `"nvfp4"` in `--speculative-config`
gives the drafter a quantized copy of that head (Model Runner V2). The target
still verifies with its own head, so outputs are unchanged; only the
acceptance length can move. It helps most on bandwidth-bound GPUs with a
large vocabulary. The copy costs about one byte (FP8) or 0.56 bytes (NVFP4)
per lm_head weight, e.g. 0.6 or 0.35 GiB for a 248k x 2560 head; it is
counted in the model weights, so with `--kv-cache-memory-bytes` leave room
for it.
+4 -2
View File
@@ -125,8 +125,10 @@ generation.
## Speculative decoding
Watermarking requires speculative decoding to use probabilistic draft sampling,
standard rejection sampling, and an autoregressive model-based method (`dspark`,
`eagle`, `eagle3`, or `mtp`). Parallel drafting is supported only by `dspark`.
standard rejection sampling, and a model-based method (`dflash`, `dspark`,
`eagle`, `eagle3`, or `mtp`). Parallel drafting is supported only by `dflash`
and `dspark`. DFlash drafters with a candidate head (`DFlash2DraftModel`,
`LiLiCorrDraftModel`) are not supported.
A watermarking algorithm without native speculative-decoding support is
rejected before model loading. Set
+10 -6
View File
@@ -304,12 +304,16 @@ vllm serve Cloudflare/clef-omni
### Decision 3.0
The Decision 3.0 models ([`vllm-sr/d3`](https://huggingface.co/vllm-sr/d3) and
its smaller variants such as `vllm-sr/d3-mini` and `vllm-sr/d3-edge`) are a
Qwen3.5 backbone with an answer-code readout: one forward pass per question,
and the readout scores the question's options at the last token. vLLM detects
the checkpoint's `decision_config.json` and serves it as a classification
model.
The Decision 3.0 models are a Qwen3.5 backbone with an answer-code readout:
one forward pass per question, and the readout scores the question's options
at the last token. vLLM detects the checkpoint's `decision_config.json` and
serves it as a classification model. All six sizes take the same command:
[`vllm-sr/d3`](https://huggingface.co/vllm-sr/d3) (27B),
[`vllm-sr/d3-flash`](https://huggingface.co/vllm-sr/d3-flash) (9B),
[`vllm-sr/d3-mini`](https://huggingface.co/vllm-sr/d3-mini) (4B),
[`vllm-sr/d3-nano`](https://huggingface.co/vllm-sr/d3-nano) (2B),
[`vllm-sr/d3-lite`](https://huggingface.co/vllm-sr/d3-lite) (0.8B) and
[`vllm-sr/d3-edge`](https://huggingface.co/vllm-sr/d3-edge) (0.6B).
```bash
vllm serve vllm-sr/d3
+2 -2
View File
@@ -89,7 +89,7 @@ The derenderer builds its tool and reasoning parsers from its own server flags p
A mismatch doesn't fail. The parser just splits `reasoning`, `content` and `tool_calls` differently from what `vllm serve` would return.
`/v1/completions/derender` only detokenizes. It never runs tool or reasoning parsers, the same as `/v1/completions` on `vllm serve`. It only reads `skip_special_tokens` from `completion_request`.
`/v1/completions/derender` only detokenizes. It never runs tool or reasoning parsers, the same as `/v1/completions` on `vllm serve`. From `completion_request` it reads `skip_special_tokens`, and `logprobs` and `logprob_token_ids` to cut `top_logprobs` the way `/v1/completions` does.
## Streaming
@@ -105,7 +105,7 @@ The server keeps no state between calls. Everything the next call needs is in `s
- **Send `prompt_token_ids` on the first chunk, even without a parser.** It seeds detokenization so the first token's leading space matches the coupled endpoint (see [Request format](#request-format)). Later chunks already carry that context in `stream_state`.
- **Don't forward `[DONE]`.** It marks the end of the generate stream and isn't a chunk.
`/inference/v1/generate` returns `GenerateLogProbs` with integer `token_id`s (the generate server has no tokenizer), and derender turns those into `ChatCompletionLogProbs` / `CompletionLogProbs`, filling `token` and `bytes` from the tokenizer with the usual U+FFFD byte-fallback correction. Streaming derender does the same per chunk on the plain detokenization path (see [Streaming state and logprobs](#streaming-state-and-logprobs)). The parser path doesn't resolve them yet and drops them.
`/inference/v1/generate` returns `GenerateLogProbs` with integer `token_id`s (the generate server has no tokenizer), and derender turns those into `ChatCompletionLogProbs` / `CompletionLogProbs`, filling `token` and `bytes` from the tokenizer with the usual U+FFFD byte-fallback correction. Generate returns every top-k candidate the engine produced; derender keeps the ones the coupled endpoint would, with the same helpers: the first `top_logprobs` on chat (all of them for `top_logprobs=-1`) and the first `logprobs + 1` on completions (all of them for `logprobs=-1`). It reads those values from `chat_request` / `completion_request`, so without the original request, or with one that does not ask for logprobs, it returns every candidate. Requests that use `logprob_token_ids` get no output logprobs from generate (their `sampling_params.logprobs` is unset), so derender has none to return for them either. Streaming derender does the same per chunk on the plain detokenization path (see [Streaming state and logprobs](#streaming-state-and-logprobs)). The parser path doesn't resolve them yet and drops them.
## Streaming cost
+17 -4
View File
@@ -108,10 +108,13 @@ choice carries a `GenerateLogProbs`; `output_mode: "text"` returns decoded
- `content` has one entry per generated token, in generation order.
- `top_logprobs` is a list, not a dict: JSON turns dict keys into strings and
the ordering would be implicit. It follows the engine's order: the sampled
token first, then the remaining candidates in rank order. With non-greedy
sampling the sampled token can sit outside the top k (for example ranks
`[5, 1, 2]` at `logprobs=2`); it then takes one of the `logprobs` slots and
the rank-k candidate is left out, as on the OpenAI endpoints.
token first, then the remaining candidates in rank order. It holds every
candidate the engine returned and is not cut to `logprobs`: k entries when
the sampled token is in the top k, k + 1 when non-greedy sampling picked a
token outside it (for example ranks `[5, 1, 2]` at `logprobs=2`). The OpenAI
endpoints cut this differently (`/v1/chat/completions` keeps the first k,
`/v1/completions` the first k + 1), so [derender](derenderer.md) applies the
cut of the endpoint it renders for.
- `rank` is the token's rank in the vocabulary distribution (1 = most likely)
on every entry, the sampled one included; a top-k candidate's rank is its
top-k position. The list is not sorted by it, so sort by `rank` if you need
@@ -132,6 +135,16 @@ choice carries a `GenerateLogProbs`; `output_mode: "text"` returns decoded
`return_tokens_as_token_ids` on `/v1/chat/completions` and `/v1/completions`
is unchanged: it is a user-facing OpenAI option and still uses the
`token_id:N` format.
`top_logprobs` is no longer cut to `max(logprobs, 1)` entries, in either
`output_mode`: it now holds every candidate the engine returned, which is
`logprobs + 1` entries when the sampled token is outside the top
`logprobs`. Clients that assume `len(top_logprobs) == logprobs` should
take the first `logprobs` entries after sorting by `rank`.
Derender applies each endpoint's cut from the original request, so send
`chat_request` / `completion_request` to derender whenever logprobs are
requested: without it derender returns every candidate, which on chat is
`top_logprobs + 1` entries where `/v1/chat/completions` returns
`top_logprobs`.
## Multimodal Render Features