Skip to content

qwen35: add adaptive decode-priority scheduling for mixed prefill/decode load #727

Description

@CAICAIIs

Summary

Qwen3.5 currently uses a fixed scheduling rule when active decode requests and pending prefill work coexist. This can protect throughput in some cases, but it can also create active-decode stalls under mixed workloads where long cold prefills arrive while existing requests are decoding.

This issue tracks an adaptive scheduler policy for Qwen3.5 that can reduce mixed prefill/decode ITL stalls without making the default serving path pay a broad TTFT or throughput regression.

Motivation

The current fixed policy is too coarse for a default latency policy:

  • Always prioritizing prefill can stall active decode behind long prompt work.
  • Always overlapping or shrinking prefill can improve ITL tail, but may regress TTFT and/or throughput.
  • Static request fields such as max_tokens are not enough to decide whether a request should trigger decode protection.

A default policy should react to runtime state, not just a single CLI mode or fixed threshold.

Evidence

On a single RTX 5090 Qwen3.5 serving setup, opt-in stream overlap showed that active-decode stalls can be reduced, but it also exposed why the behavior should not simply become the default:

  • Mixed-load ITL p99 improved substantially when overlap was enabled.
  • Standard HTTP serving cells remained sensitive to TTFT and throughput tradeoffs.
  • A max_tokens >= 1024 gate preserved short-output cells better, but still regressed median TTFT on a long-output concurrency cell.
  • Active-only smaller prefill chunks improved some mixed-load tail metrics, but regressed c16 / QPS serving throughput and TTFT.

These results suggest the bottleneck is schedulable, but the current policies are not yet a safe default.

Proposed Direction

Add an adaptive Qwen3.5 scheduler policy that decides per scheduler tick how to balance decode and prefill work. Candidate signals include:

  • active decode batch size
  • pending prefill token count
  • pending request queue age
  • active request generated tokens / remaining budget
  • recent ITL stall history
  • prefill chunk size and estimated stall cost
  • starvation/fairness limits for pending prefill

The policy should be able to choose among existing execution options, such as:

  • normal prefill / decode / unified execution
  • smaller prefill chunks while decode is active
  • decode-priority ticks
  • opt-in stream overlap as an execution mechanism when the runtime state justifies it

Acceptance Criteria

A default auto policy should meet all of the following before becoming the default:

  • No material regression on standard HTTP serving cells such as 1024/256 c1 and c16.
  • No material regression on QPS pressure cells such as 1024/128 QPS 8/12/16.
  • Clear mixed-load ITL tail improvement when long cold prefills arrive during active decode.
  • Long-output concurrency cells do not show a large TTFT regression.
  • Failed, timeout, OOM, unsupported, and zero-output cases remain explicitly recorded.
  • Output lengths and output sanity/hash checks are retained for every benchmark cell.
  • The policy remains disableable with an explicit off mode.

Non-goals

  • This issue does not claim vLLM parity.
  • This issue does not make stream overlap the default by itself.
  • This issue does not require kernel profiling unless scheduler-level evidence shows GPU step time is the dominant remaining bottleneck.
  • This issue does not change prefix-cache behavior.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

enhancementNew feature or requesthw:1-gpuNeeds one consumer GPU to verifyqwen35Qwen3.5 model crate (pegainfer-qwen35)

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions