[Edge][CPU] KV-cached code predictor, int8-dynamic CPU fast path, model-side CPU sampler
Measured on a Xeon 8480C (12+4 threads, 0.6B): the 15 residual-codebook sub-steps re-ran the 5-layer predictor over the whole prefix each time (97 ms per frame of the 134 ms talker step) and vLLM's stock sampler spent 9 ms per step in its torch.compile'd random-sample kernel on CPU. - code predictor: forward_cached (KV cache per layer, 2-token prefill then one token per sub-step) and a shape-static forward_static_step (tensor position + boolean mask) that torch.compile handles as one graph; incremental decoding is the default on CPU (VLLM_OMNI_PREDICTOR_INCREMENTAL), optional compile (VLLM_OMNI_PREDICTOR_COMPILE=step), optional thread cap. - CPU fast path: dynamic int8 Linear layers (fp32 activations) for the predictor and its lm heads (VLLM_OMNI_PREDICTOR_INT8, default on; micro-benchmark 70 -> 36 ms per frame for the 15 sub-steps); VLLM_OMNI_PREDICTOR_PARITY_CHECK=1 records top-1 agreement / max logit diff against the bf16 model in situ. - Qwen3-TTS talker: prefer_model_sampler on CPU with a sample() that mirrors vLLM's Sampler (logits processors + penalties, temperature, top-k/top-p, exponential-noise sampling with per-request generators) without the compiled kernel (VLLM_OMNI_CPU_FAST_SAMPLER, default on). - step_stats: sampler phase timers and sample-metadata timers. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
936c10be4b
commit
6ce8de1b28
6 files changed
+604
-8
No files matched your search
@@ -1394,10 +1394,13 @@ class GPUARModelRunner(OmniGPUModelRunner, OmniConnectorModelRunnerMixin, Duplex
|
||||
fallthrough is load-bearing, not an error path; it is logged once per
|
||||
model for visibility.
|
||||
"""
|
||||
sampling_metadata = self.input_batch.sampling_metadata
|
||||
_stats = _step_stats()
|
||||
with _stats.timed("model.sample_meta_ms"):
|
||||
sampling_metadata = self.input_batch.sampling_metadata
|
||||
if spec_decode_metadata is None:
|
||||
model_sample = getattr(self.model, "sample", None)
|
||||
self.input_batch.update_async_output_token_ids()
|
||||
with _stats.timed("model.sample_async_ids_ms"):
|
||||
self.input_batch.update_async_output_token_ids()
|
||||
if logits is not None and callable(model_sample) and getattr(self.model, "prefer_model_sampler", False):
|
||||
# Apply logit bias (min_tokens, allowed_token_ids) before
|
||||
# the custom model sampler — the standard GPU sampler does
|
||||
@@ -1422,10 +1425,15 @@ class GPUARModelRunner(OmniGPUModelRunner, OmniConnectorModelRunnerMixin, Duplex
|
||||
"prefer_model_sampler model %s returned None from sample(); falling back to the default sampler.",
|
||||
type(self.model).__name__,
|
||||
)
|
||||
return self.sampler(
|
||||
logits=logits,
|
||||
sampling_metadata=sampling_metadata,
|
||||
)
|
||||
if _stats.enabled:
|
||||
from vllm_omni.edge.step_stats import instrument_sampler
|
||||
|
||||
instrument_sampler(self.sampler)
|
||||
with _stats.timed("model.sampler_call_ms", sync_device=self.device):
|
||||
return self.sampler(
|
||||
logits=logits,
|
||||
sampling_metadata=sampling_metadata,
|
||||
)
|
||||
|
||||
return super()._sample(logits, spec_decode_metadata)
|
||||
|
||||
|
||||
Reference in new issue
Block a user