use std::collections::HashMap;
use rand::Rng;
use rustc_hash::FxHashMap;
use super::config::KvRouterConfig;
use super::filter::{RoutingEligibility, WorkerEligibilityError};
use super::types::{KvSchedulerError, SchedulingRequest};
use crate::protocols::{WorkerConfigLike, WorkerId, WorkerSelectionResult, WorkerWithDpRank};
pub trait WorkerSelector<C: WorkerConfigLike> {
fn select_worker(
&self,
workers: &HashMap<WorkerId, C>,
request: &SchedulingRequest,
eligibility: RoutingEligibility<'_>,
block_size: u32,
) -> Result<WorkerSelectionResult, KvSchedulerError>;
}
fn softmax_sample(
logits: &FxHashMap<WorkerWithDpRank, f64>,
temperature: f64,
) -> (WorkerWithDpRank, f64) {
let mut rng = rand::rng();
softmax_sample_with_sample(logits, temperature, rng.random())
}
fn softmax_sample_with_sample(
logits: &FxHashMap<WorkerWithDpRank, f64>,
temperature: f64,
sample: f64,
) -> (WorkerWithDpRank, f64) {
assert!(!logits.is_empty(), "Empty logits for softmax sampling");
if temperature == 0.0 {
let (worker, logit) = logits
.iter()
.min_by(|a, b| a.1.total_cmp(b.1))
.expect("logits non-empty");
return (*worker, *logit);
}
let entries: Vec<(WorkerWithDpRank, f64)> = logits.iter().map(|(w, l)| (*w, *l)).collect();
let (min_val, max_val) = entries
.iter()
.fold((f64::INFINITY, f64::NEG_INFINITY), |(lo, hi), (_, v)| {
(lo.min(*v), hi.max(*v))
});
let mut probs = if min_val == max_val {
vec![1.0 / entries.len() as f64; entries.len()]
} else {
let scale = -1.0 / ((max_val - min_val) * temperature);
let max_scaled = min_val * scale;
entries
.iter()
.map(|(_, v)| (v * scale - max_scaled).exp())
.collect::<Vec<f64>>()
};
let sum: f64 = probs.iter().sum();
probs.iter_mut().for_each(|p| *p /= sum);
let mut cumsum = 0.0;
for (i, &prob) in probs.iter().enumerate() {
cumsum += prob;
if sample <= cumsum {
return entries[i];
}
}
*entries.last().unwrap()
}
#[derive(Debug, Clone)]
pub struct DefaultWorkerSelector {
pub kv_router_config: KvRouterConfig,
pub worker_type: &'static str,
}
#[derive(Debug, Clone, Copy)]
struct LogitWeights {
overlap_score_credit: f64,
overlap_score_credit_decay: f64,
prefill_load_scale: f64,
shared_cache_multiplier: f64,
}
impl DefaultWorkerSelector {
pub fn new(kv_router_config: Option<KvRouterConfig>, worker_type: &'static str) -> Self {
Self {
kv_router_config: kv_router_config.unwrap_or_default(),
worker_type,
}
}
fn worker_logit(
&self,
request: &SchedulingRequest,
worker: WorkerWithDpRank,
block_size: u32,
min_active_prefill_tokens: usize,
weights: LogitWeights,
formula_name: &'static str,
) -> f64 {
let block_size_f64 = block_size as f64;
let effective_overlap_blocks = request.effective_overlap_blocks_for(worker);
let has_tier_overlap_blocks = !request.overlap.tier_overlap_blocks.device.is_empty()
|| !request.overlap.tier_overlap_blocks.host_pinned.is_empty()
|| !request.overlap.tier_overlap_blocks.disk.is_empty();
let device_overlap_blocks = request
.overlap
.tier_overlap_blocks
.device
.get(&worker)
.copied()
.map(|blocks| blocks as f64)
.unwrap_or_else(|| {
if has_tier_overlap_blocks {
0.0
} else {
effective_overlap_blocks
}
});
let device_overlap_blocks_u32 = device_overlap_blocks.round().max(0.0) as u32;
let worker_load = request.worker_loads.get(&worker).copied();
let raw_prefill_tokens = if request.track_prefill_tokens {
match worker_load {
Some(load) => {
let cached_tokens = request.effective_cached_tokens_for(worker);
let uncached_tokens = super::prefill_load::effective_prefill_tokens(
request.isl_tokens,
cached_tokens,
);
let projected_tokens = load.active_prefill_tokens + uncached_tokens;
projected_tokens.saturating_add(cached_tokens)
}
None => request.isl_tokens,
}
} else {
0
} as f64;
let host_overlap_blocks = request
.overlap
.tier_overlap_blocks
.host_pinned
.get(&worker)
.copied()
.unwrap_or(0) as f64;
let disk_overlap_blocks = request
.overlap
.tier_overlap_blocks
.disk
.get(&worker)
.copied()
.unwrap_or(0) as f64;
let (shared_overlap_blocks, shared_beyond) =
if let Some(ref shared_hits) = request.shared_cache_hits {
let beyond = shared_hits.hits_beyond(device_overlap_blocks_u32);
(weights.shared_cache_multiplier * (beyond as f64), beyond)
} else {
(0.0, 0)
};
let raw_prefill_blocks = raw_prefill_tokens / block_size_f64;
let overlap_credit_decay =
if request.track_prefill_tokens && weights.overlap_score_credit_decay > 0.0 {
let active_prefill_tokens = worker_load.unwrap_or_default().active_prefill_tokens;
let excess_active_prefill_blocks =
active_prefill_tokens.saturating_sub(min_active_prefill_tokens) as f64
/ block_size_f64;
let normalized_prefill_load =
excess_active_prefill_blocks / request.request_blocks(block_size) as f64;
1.0 / (1.0 + weights.overlap_score_credit_decay * normalized_prefill_load)
} else {
1.0
};
let effective_overlap_score_credit = weights.overlap_score_credit * overlap_credit_decay;
let overlap_credit_blocks = effective_overlap_score_credit * device_overlap_blocks
+ self.kv_router_config.host_cache_hit_weight * host_overlap_blocks
+ self.kv_router_config.disk_cache_hit_weight * disk_overlap_blocks
+ shared_overlap_blocks;
let adjusted_prefill_blocks = (raw_prefill_blocks - overlap_credit_blocks).max(0.0);
let prefill_cost_blocks = weights.prefill_load_scale * adjusted_prefill_blocks;
let worker_load = worker_load.unwrap_or_default();
let decode_cost_blocks = worker_load.potential_decode_blocks() as f64;
let logit = prefill_cost_blocks + decode_cost_blocks;
if shared_beyond > 0 {
tracing::debug!(
"{formula_name} for worker_id={} dp_rank={:?} with {effective_overlap_blocks:.2} effective cached blocks, \
{shared_beyond} shared blocks beyond device (multiplier={shared_cache_multiplier:.2}): {logit:.3} \
= prefill_load_scale * adjusted_prefill_blocks + decode_blocks \
= {prefill_load_scale:.3} * {adjusted_prefill_blocks:.3} + {decode_cost_blocks:.3} \
(raw_prefill_blocks: {raw_prefill_blocks:.3}, overlap_credit_blocks: {overlap_credit_blocks:.3}, \
overlap_credit_decay: {overlap_credit_decay:.3})",
worker.worker_id,
worker.dp_rank,
shared_cache_multiplier = weights.shared_cache_multiplier,
prefill_load_scale = weights.prefill_load_scale
);
} else {
tracing::debug!(
"{formula_name} for worker_id={} dp_rank={:?} with {effective_overlap_blocks:.2} effective cached blocks: {logit:.3} \
= prefill_load_scale * adjusted_prefill_blocks + decode_blocks \
= {prefill_load_scale:.3} * {adjusted_prefill_blocks:.3} + {decode_cost_blocks:.3} \
(raw_prefill_blocks: {raw_prefill_blocks:.3}, overlap_credit_blocks: {overlap_credit_blocks:.3}, \
overlap_credit_decay: {overlap_credit_decay:.3})",
worker.worker_id,
worker.dp_rank,
prefill_load_scale = weights.prefill_load_scale
);
}
logit
}
}
impl<C: WorkerConfigLike> WorkerSelector<C> for DefaultWorkerSelector {
fn select_worker(
&self,
workers: &HashMap<WorkerId, C>,
request: &SchedulingRequest,
eligibility: RoutingEligibility<'_>,
block_size: u32,
) -> Result<WorkerSelectionResult, KvSchedulerError> {
assert!(request.isl_tokens > 0);
eligibility.validate_pinned_worker_allowed()?;
let pinned_worker = eligibility.pinned_worker();
if pinned_worker.is_none()
&& !eligibility.has_eligible_worker(
workers
.iter()
.map(|(&worker_id, config)| (worker_id, config)),
)
{
if eligibility.has_eligible_worker_ignoring_overload(
workers
.iter()
.map(|(&worker_id, config)| (worker_id, config)),
) {
return Err(KvSchedulerError::AllEligibleWorkersOverloaded);
}
return Err(KvSchedulerError::NoEndpoints);
}
let request_blocks = request.request_blocks(block_size);
let weights = LogitWeights {
overlap_score_credit: request
.router_config_override
.as_ref()
.and_then(|cfg| cfg.overlap_score_credit)
.unwrap_or(self.kv_router_config.overlap_score_credit),
overlap_score_credit_decay: self.kv_router_config.overlap_score_credit_decay,
prefill_load_scale: request
.router_config_override
.as_ref()
.and_then(|cfg| cfg.prefill_load_scale)
.unwrap_or(self.kv_router_config.prefill_load_scale),
shared_cache_multiplier: request
.router_config_override
.as_ref()
.and_then(|cfg| cfg.shared_cache_multiplier)
.unwrap_or(self.kv_router_config.shared_cache_multiplier),
};
if let Some(worker) = pinned_worker {
match eligibility.validate_worker_rank(workers, worker) {
Ok(_) => {}
Err(WorkerEligibilityError::WorkerOverloaded { .. }) => {
return Err(KvSchedulerError::PinnedWorkerOverloaded {
worker_id: worker.worker_id,
});
}
Err(_) => return Err(KvSchedulerError::NoEndpoints),
}
let min_active_prefill_tokens = request.worker_load_for(worker).active_prefill_tokens;
let logit = self.worker_logit(
request,
worker,
block_size,
min_active_prefill_tokens,
weights,
"Pinned formula",
);
let effective_overlap_blocks = request.effective_overlap_blocks_for(worker);
let cached_tokens = request.effective_cached_tokens_for(worker);
tracing::info!(
"Selected pinned worker: worker_type={}, worker_id={} dp_rank={:?}, logit: {:.3}, effective cached blocks: {:.2}",
self.worker_type,
worker.worker_id,
worker.dp_rank,
logit,
effective_overlap_blocks,
);
return Ok(WorkerSelectionResult {
worker,
required_blocks: request_blocks,
effective_overlap_blocks,
cached_tokens,
});
}
let temperature = request
.router_config_override
.as_ref()
.and_then(|cfg| cfg.router_temperature)
.unwrap_or(self.kv_router_config.router_temperature);
let min_active_prefill_tokens =
if request.track_prefill_tokens && weights.overlap_score_credit_decay > 0.0 {
let mut minimum = usize::MAX;
eligibility.for_each_eligible_worker_rank(workers, |worker, _| {
minimum = minimum.min(request.worker_load_for(worker).active_prefill_tokens);
});
debug_assert_ne!(minimum, usize::MAX);
minimum
} else {
0
};
let get_score = |worker: WorkerWithDpRank| -> f64 {
let base_score = self.worker_logit(
request,
worker,
block_size,
min_active_prefill_tokens,
weights,
"Formula",
);
let Some(config) = workers.get(&worker.worker_id) else {
return base_score;
};
match request
.routing_constraints
.preferred_taint_multiplier(config.taints())
{
Some(multiplier) => base_score * multiplier,
None => base_score,
}
};
let (best_worker, best_logit) = if temperature == 0.0 {
let mut best_worker = None;
let mut best_logit = f64::INFINITY;
let mut tie_count = 0usize;
let mut rng = rand::rng();
eligibility.for_each_eligible_worker_rank(workers, |worker, _| {
let score = get_score(worker);
if score < best_logit {
best_worker = Some(worker);
best_logit = score;
tie_count = 1;
return;
}
if score == best_logit {
tie_count += 1;
if rng.random_range(0..tie_count) == 0 {
best_worker = Some(worker);
}
}
});
(
best_worker.expect("eligible worker rank non-empty"),
best_logit,
)
} else {
let mut worker_logits = FxHashMap::default();
eligibility.for_each_eligible_worker_rank(workers, |worker, _| {
let score = get_score(worker);
worker_logits.insert(worker, score);
});
softmax_sample(&worker_logits, temperature)
};
let best_host_pinned_overlap_blocks = request
.overlap
.tier_overlap_blocks
.host_pinned
.get(&best_worker)
.copied()
.unwrap_or(0);
let best_disk_overlap_blocks = request
.overlap
.tier_overlap_blocks
.disk
.get(&best_worker)
.copied()
.unwrap_or(0);
if self.worker_type == "decode" {
tracing::info!(
router_mode = "kv",
worker_id = best_worker.worker_id,
worker_type = %self.worker_type,
dp_rank = ?best_worker.dp_rank,
logit = best_logit,
host_pinned_blocks = best_host_pinned_overlap_blocks,
disk_blocks = best_disk_overlap_blocks,
"Selected worker"
);
let effective_overlap_blocks = request.effective_overlap_blocks_for(best_worker);
let cached_tokens = request.effective_cached_tokens_for(best_worker);
return Ok(WorkerSelectionResult {
worker: best_worker,
required_blocks: request_blocks,
effective_overlap_blocks,
cached_tokens,
});
}
let best_overlap = request.effective_overlap_blocks_for(best_worker);
let best_cached_tokens = request.effective_cached_tokens_for(best_worker);
let total_kv_blocks = workers
.get(&best_worker.worker_id)
.and_then(|cfg| cfg.total_kv_blocks());
tracing::info!(
router_mode = "kv",
worker_id = best_worker.worker_id,
worker_type = %self.worker_type,
dp_rank = ?best_worker.dp_rank,
logit = best_logit,
effective_cached_blocks = best_overlap,
host_pinned_blocks = best_host_pinned_overlap_blocks,
disk_blocks = best_disk_overlap_blocks,
total_kv_blocks = ?total_kv_blocks,
"Selected worker"
);
Ok(WorkerSelectionResult {
worker: best_worker,
required_blocks: request_blocks,
effective_overlap_blocks: best_overlap,
cached_tokens: best_cached_tokens,
})
}
}
#[cfg(test)]
mod tests {
use std::collections::HashSet;
use super::*;
use crate::protocols::{SharedCacheHits, WorkerConfigLike};
use crate::scheduling::{OverlapSignals, ScheduleMode};
#[derive(Clone, Default)]
struct TaintedWorkerConfig {
taints: HashSet<String>,
}
impl WorkerConfigLike for TaintedWorkerConfig {
fn data_parallel_start_rank(&self) -> u32 {
0
}
fn data_parallel_size(&self) -> u32 {
1
}
fn max_num_batched_tokens(&self) -> Option<u64> {
None
}
fn total_kv_blocks(&self) -> Option<u64> {
None
}
fn taints(&self) -> &HashSet<String> {
&self.taints
}
}
fn base_request(isl_tokens: usize) -> SchedulingRequest {
SchedulingRequest {
mode: ScheduleMode::QueryOnly {
request_id: Some("test".into()),
},
token_seq: None,
isl_tokens,
overlap: OverlapSignals {
tier_overlap_blocks: Default::default(),
effective_overlap_blocks: HashMap::default(),
effective_cached_tokens: HashMap::default(),
},
worker_loads: FxHashMap::default(),
track_prefill_tokens: true,
router_config_override: None,
lora_name: None,
priority_jump: 0.0,
strict_priority: 0,
policy_class: None,
expected_output_tokens: None,
pinned_worker: None,
allowed_worker_ids: None,
routing_constraints: crate::protocols::RoutingConstraints::default(),
shared_cache_hits: None,
resp_tx: None,
}
}
fn worker_loads_with_active_decode(
decode_blocks: FxHashMap<WorkerWithDpRank, usize>,
) -> FxHashMap<WorkerWithDpRank, crate::sequences::WorkerLoadProjection> {
decode_blocks
.into_iter()
.map(|(worker, active_decode_blocks)| {
(
worker,
crate::sequences::WorkerLoadProjection {
active_decode_blocks,
..Default::default()
},
)
})
.collect()
}
#[test]
fn test_softmax_sample_single_key() {
let mut logits = FxHashMap::default();
let worker = WorkerWithDpRank::from_worker_id(42);
for (logit, temperature) in [
(0.5, 0.1),
(0.5, 1.0),
(0.5, 10.0),
(-100.0, 1.0),
(100.0, 1.0),
(0.0, 1.0),
(0.0, 0.0),
] {
logits.clear();
logits.insert(worker, logit);
let result = softmax_sample(&logits, temperature);
assert_eq!(result.0, worker, "Should return the only available worker");
assert_eq!(result.1, logit, "Should return the selected worker's logit");
}
}
#[test]
fn test_softmax_sample_zero_temperature() {
let mut logits = FxHashMap::default();
let worker1 = WorkerWithDpRank::from_worker_id(1);
let worker2 = WorkerWithDpRank::from_worker_id(2);
let worker3 = WorkerWithDpRank::from_worker_id(3);
let worker4 = WorkerWithDpRank::from_worker_id(4);
logits.insert(worker1, 5.0);
logits.insert(worker2, 3.0);
logits.insert(worker3, 7.0);
logits.insert(worker4, 3.5);
let result = softmax_sample(&logits, 0.0);
assert_eq!(
result.0, worker2,
"Should return worker with smallest logit when temperature is 0"
);
assert_eq!(
result.1, 3.0,
"Should return the smallest logit when temperature is 0"
);
logits.clear();
let worker5 = WorkerWithDpRank::from_worker_id(5);
let worker6 = WorkerWithDpRank::from_worker_id(6);
logits.insert(worker1, 5.0);
logits.insert(worker2, 3.0);
logits.insert(worker5, 3.0);
logits.insert(worker6, 7.0);
let result = softmax_sample(&logits, 0.0);
assert!(
result.0 == worker2 || result.0 == worker5,
"Should return one of the workers tied for the smallest logit"
);
assert_eq!(result.1, 3.0, "Should return the tied minimum logit");
logits.clear();
let worker10 = WorkerWithDpRank::from_worker_id(10);
let worker20 = WorkerWithDpRank::from_worker_id(20);
let worker30 = WorkerWithDpRank::from_worker_id(30);
logits.insert(worker10, -1.0);
logits.insert(worker20, -5.0);
logits.insert(worker30, 0.0);
let result = softmax_sample(&logits, 0.0);
assert_eq!(
result.0, worker20,
"Should handle negative logits correctly"
);
assert_eq!(result.1, -5.0, "Should return the minimum negative logit");
}
#[test]
fn test_softmax_sample_with_sample_returns_selected_logit() {
let worker1 = WorkerWithDpRank::from_worker_id(1);
let worker2 = WorkerWithDpRank::from_worker_id(2);
let worker3 = WorkerWithDpRank::from_worker_id(3);
let logits = FxHashMap::from_iter([(worker1, 0.0), (worker2, 3.0), (worker3, 9.0)]);
let entries: Vec<_> = logits
.iter()
.map(|(worker, logit)| (*worker, *logit))
.collect();
let values: Vec<_> = entries.iter().map(|(_, logit)| *logit).collect();
let min_val = values.iter().fold(f64::INFINITY, |a, &b| a.min(b));
let max_val = values.iter().fold(f64::NEG_INFINITY, |a, &b| a.max(b));
let temperature = 1.0;
let range = max_val - min_val;
let scaled: Vec<f64> = values.iter().map(|&v| -(v / range) / temperature).collect();
let max_scaled = scaled.iter().fold(f64::NEG_INFINITY, |a, &b| a.max(b));
let mut probabilities: Vec<f64> = scaled.iter().map(|&v| (v - max_scaled).exp()).collect();
let sum: f64 = probabilities.iter().sum();
probabilities.iter_mut().for_each(|p| *p /= sum);
let target_idx = entries
.iter()
.position(|(_, logit)| *logit > min_val)
.expect("expected at least one non-minimum logit");
let cumsum_before: f64 = probabilities.iter().take(target_idx).sum();
let sample = cumsum_before + probabilities[target_idx] / 2.0;
let result = softmax_sample_with_sample(&logits, temperature, sample);
assert_eq!(result, entries[target_idx]);
}
#[test]
fn test_default_selector_randomizes_zero_temperature_ties() {
use crate::test_utils::SimpleWorkerConfig;
let config = KvRouterConfig {
router_temperature: 0.0,
..Default::default()
};
let selector = DefaultWorkerSelector::new(Some(config), "test");
let workers = HashMap::from([
(10, SimpleWorkerConfig::default()),
(20, SimpleWorkerConfig::default()),
(30, SimpleWorkerConfig::default()),
]);
let request = SchedulingRequest {
mode: ScheduleMode::QueryOnly {
request_id: Some("test".into()),
},
token_seq: None,
isl_tokens: 16,
overlap: OverlapSignals {
tier_overlap_blocks: Default::default(),
effective_overlap_blocks: HashMap::default(),
effective_cached_tokens: HashMap::default(),
},
worker_loads: FxHashMap::default(),
track_prefill_tokens: true,
router_config_override: None,
lora_name: None,
priority_jump: 0.0,
strict_priority: 0,
policy_class: None,
expected_output_tokens: None,
pinned_worker: None,
allowed_worker_ids: None,
routing_constraints: crate::protocols::RoutingConstraints::default(),
shared_cache_hits: None,
resp_tx: None,
};
let mut selected = [false; 3];
for _ in 0..120 {
let result = selector
.select_worker(&workers, &request, request.eligibility(), 16)
.unwrap();
match result.worker.worker_id {
10 => selected[0] = true,
20 => selected[1] = true,
30 => selected[2] = true,
worker_id => panic!("unexpected worker id: {worker_id}"),
}
}
let selected_count = selected.into_iter().filter(|seen| *seen).count();
assert!(
selected_count > 1,
"zero-temperature tie-breaking should not always select the same worker"
);
}
#[test]
fn test_overloaded_high_overlap_worker_is_skipped() {
use crate::test_utils::SimpleWorkerConfig;
let selector = DefaultWorkerSelector::new(
Some(KvRouterConfig {
overlap_score_credit: 1.0,
router_temperature: 0.0,
..Default::default()
}),
"test",
);
let workers = HashMap::from([
(0, SimpleWorkerConfig::default()),
(1, SimpleWorkerConfig::default()),
]);
let worker0 = WorkerWithDpRank::from_worker_id(0);
let mut request = base_request(64);
request
.overlap
.effective_overlap_blocks
.insert(worker0, 4.0);
request.overlap.effective_cached_tokens.insert(worker0, 64);
let overloaded_worker_ids = HashSet::from([0]);
let result = selector
.select_worker(
&workers,
&request,
request.eligibility_with_overloaded(Some(&overloaded_worker_ids)),
16,
)
.unwrap();
assert_eq!(result.worker.worker_id, 1);
}
#[test]
fn test_all_eligible_workers_overloaded_returns_overload_error() {
use crate::test_utils::SimpleWorkerConfig;
let selector = DefaultWorkerSelector::new(Some(KvRouterConfig::default()), "test");
let workers = HashMap::from([
(0, SimpleWorkerConfig::default()),
(1, SimpleWorkerConfig::default()),
]);
let request = base_request(16);
let overloaded_worker_ids = HashSet::from([0, 1]);
let result = selector.select_worker(
&workers,
&request,
request.eligibility_with_overloaded(Some(&overloaded_worker_ids)),
16,
);
assert!(matches!(
result,
Err(KvSchedulerError::AllEligibleWorkersOverloaded)
));
}
#[test]
fn test_overloaded_pinned_worker_is_not_rerouted() {
use crate::test_utils::SimpleWorkerConfig;
let selector = DefaultWorkerSelector::new(Some(KvRouterConfig::default()), "test");
let workers = HashMap::from([
(0, SimpleWorkerConfig::default()),
(1, SimpleWorkerConfig::default()),
]);
let mut request = base_request(16);
request.pinned_worker = Some(WorkerWithDpRank::from_worker_id(0));
let overloaded_worker_ids = HashSet::from([0]);
let result = selector.select_worker(
&workers,
&request,
request.eligibility_with_overloaded(Some(&overloaded_worker_ids)),
16,
);
assert!(matches!(
result,
Err(KvSchedulerError::PinnedWorkerOverloaded { worker_id: 0 })
));
}
#[test]
fn test_required_taints_return_no_endpoints_when_no_worker_matches() {
let selector = DefaultWorkerSelector::new(Some(KvRouterConfig::default()), "test");
let workers = HashMap::from([(
10,
TaintedWorkerConfig {
taints: HashSet::from(["mdc-a".to_string()]),
},
)]);
let request = SchedulingRequest {
mode: ScheduleMode::QueryOnly {
request_id: Some("test".into()),
},
token_seq: None,
isl_tokens: 16,
overlap: OverlapSignals {
tier_overlap_blocks: Default::default(),
effective_overlap_blocks: HashMap::default(),
effective_cached_tokens: HashMap::default(),
},
worker_loads: FxHashMap::default(),
track_prefill_tokens: true,
router_config_override: None,
lora_name: None,
priority_jump: 0.0,
strict_priority: 0,
policy_class: None,
expected_output_tokens: None,
pinned_worker: None,
allowed_worker_ids: None,
routing_constraints: crate::protocols::RoutingConstraints {
required_taints: HashSet::from(["mdc-b".to_string()]),
preferred_taints: HashMap::new(),
},
shared_cache_hits: None,
resp_tx: None,
};
let result = selector.select_worker(&workers, &request, request.eligibility(), 16);
assert!(matches!(result, Err(KvSchedulerError::NoEndpoints)));
}
#[test]
fn test_required_taints_filter_out_incompatible_workers() {
let selector = DefaultWorkerSelector::new(Some(KvRouterConfig::default()), "test");
let workers = HashMap::from([
(
10,
TaintedWorkerConfig {
taints: HashSet::from(["mdc-a".to_string()]),
},
),
(
20,
TaintedWorkerConfig {
taints: HashSet::from(["mdc-b".to_string()]),
},
),
]);
let request = SchedulingRequest {
mode: ScheduleMode::QueryOnly {
request_id: Some("test".into()),
},
token_seq: None,
isl_tokens: 16,
overlap: OverlapSignals {
tier_overlap_blocks: Default::default(),
effective_overlap_blocks: HashMap::default(),
effective_cached_tokens: HashMap::default(),
},
worker_loads: FxHashMap::default(),
track_prefill_tokens: true,
router_config_override: None,
lora_name: None,
priority_jump: 0.0,
strict_priority: 0,
policy_class: None,
expected_output_tokens: None,
pinned_worker: None,
allowed_worker_ids: None,
routing_constraints: crate::protocols::RoutingConstraints {
required_taints: HashSet::from(["mdc-b".to_string()]),
preferred_taints: HashMap::new(),
},
shared_cache_hits: None,
resp_tx: None,
};
let result = selector
.select_worker(&workers, &request, request.eligibility(), 16)
.unwrap();
assert_eq!(result.worker.worker_id, 20);
}
#[test]
fn test_required_taints_switch_matching_worker_sets_by_label() {
let selector = DefaultWorkerSelector::new(Some(KvRouterConfig::default()), "test");
let name_a = "mdc-a".to_string();
let name_b = "mdc-b".to_string();
let name_c = "mdc-c".to_string();
let taint_a = TaintedWorkerConfig {
taints: HashSet::from([name_a.clone()]),
};
let taint_b = TaintedWorkerConfig {
taints: HashSet::from([name_b.clone()]),
};
let taint_c = TaintedWorkerConfig {
taints: HashSet::from([name_c.clone()]),
};
let workers = HashMap::from([
(10, taint_a.clone()),
(11, taint_a),
(20, taint_b.clone()),
(21, taint_b),
(30, taint_c.clone()),
(31, taint_c),
]);
for (required_taint, expected_worker_id, noisy_worker_id) in [
(name_a, 10_u64, 11_u64),
(name_b, 20_u64, 21_u64),
(name_c, 30_u64, 31_u64),
] {
let mut decode_blocks = FxHashMap::default();
decode_blocks.insert(WorkerWithDpRank::from_worker_id(expected_worker_id), 0);
decode_blocks.insert(WorkerWithDpRank::from_worker_id(noisy_worker_id), 400_000);
let request = SchedulingRequest {
mode: ScheduleMode::QueryOnly {
request_id: Some("test".into()),
},
token_seq: None,
isl_tokens: 16,
overlap: OverlapSignals {
tier_overlap_blocks: Default::default(),
effective_overlap_blocks: HashMap::default(),
effective_cached_tokens: HashMap::default(),
},
worker_loads: worker_loads_with_active_decode(decode_blocks),
track_prefill_tokens: true,
router_config_override: None,
lora_name: None,
priority_jump: 0.0,
strict_priority: 0,
policy_class: None,
expected_output_tokens: None,
pinned_worker: None,
allowed_worker_ids: None,
routing_constraints: crate::protocols::RoutingConstraints {
required_taints: HashSet::from([required_taint.clone()]),
preferred_taints: HashMap::new(),
},
shared_cache_hits: None,
resp_tx: None,
};
let result = selector
.select_worker(&workers, &request, request.eligibility(), 16)
.unwrap();
assert_eq!(
result.worker.worker_id, expected_worker_id,
"required taint {required_taint} should route only within its compatible worker set"
);
}
}
#[test]
fn test_preferred_taints_prefer_matching_worker() {
let selector = DefaultWorkerSelector::new(
Some(KvRouterConfig {
router_temperature: 0.0,
..Default::default()
}),
"test",
);
let workers = HashMap::from([
(
10,
TaintedWorkerConfig {
taints: HashSet::from(["mdc-a".to_string()]),
},
),
(
20,
TaintedWorkerConfig {
taints: HashSet::from(["mdc-b".to_string()]),
},
),
]);
let mut decode_blocks = FxHashMap::default();
decode_blocks.insert(WorkerWithDpRank::from_worker_id(10), 100);
decode_blocks.insert(WorkerWithDpRank::from_worker_id(20), 90);
let request = SchedulingRequest {
mode: ScheduleMode::QueryOnly {
request_id: Some("test".into()),
},
token_seq: None,
isl_tokens: 16,
overlap: OverlapSignals {
tier_overlap_blocks: Default::default(),
effective_overlap_blocks: HashMap::default(),
effective_cached_tokens: HashMap::default(),
},
worker_loads: worker_loads_with_active_decode(decode_blocks),
track_prefill_tokens: true,
router_config_override: None,
lora_name: None,
priority_jump: 0.0,
strict_priority: 0,
policy_class: None,
expected_output_tokens: None,
pinned_worker: None,
allowed_worker_ids: None,
routing_constraints: crate::protocols::RoutingConstraints {
required_taints: HashSet::new(),
preferred_taints: HashMap::from([("mdc-a".to_string(), 0.85)]),
},
shared_cache_hits: None,
resp_tx: None,
};
let result = selector
.select_worker(&workers, &request, request.eligibility(), 16)
.unwrap();
assert_eq!(result.worker.worker_id, 10);
}
#[test]
fn test_negative_preferred_taints_avoid_matching_worker() {
let selector = DefaultWorkerSelector::new(
Some(KvRouterConfig {
router_temperature: 0.0,
..Default::default()
}),
"test",
);
let workers = HashMap::from([
(
10,
TaintedWorkerConfig {
taints: HashSet::from(["mdc-a".to_string()]),
},
),
(
20,
TaintedWorkerConfig {
taints: HashSet::from(["mdc-b".to_string()]),
},
),
]);
let mut decode_blocks = FxHashMap::default();
decode_blocks.insert(WorkerWithDpRank::from_worker_id(10), 90);
decode_blocks.insert(WorkerWithDpRank::from_worker_id(20), 100);
let request = SchedulingRequest {
mode: ScheduleMode::QueryOnly {
request_id: Some("test".into()),
},
token_seq: None,
isl_tokens: 16,
overlap: OverlapSignals {
tier_overlap_blocks: Default::default(),
effective_overlap_blocks: HashMap::default(),
effective_cached_tokens: HashMap::default(),
},
worker_loads: worker_loads_with_active_decode(decode_blocks),
track_prefill_tokens: true,
router_config_override: None,
lora_name: None,
priority_jump: 0.0,
strict_priority: 0,
policy_class: None,
expected_output_tokens: None,
pinned_worker: None,
allowed_worker_ids: None,
routing_constraints: crate::protocols::RoutingConstraints {
required_taints: HashSet::new(),
preferred_taints: HashMap::from([("mdc-a".to_string(), -0.25)]),
},
shared_cache_hits: None,
resp_tx: None,
};
let result = selector
.select_worker(&workers, &request, request.eligibility(), 16)
.unwrap();
assert_eq!(result.worker.worker_id, 20);
}
#[test]
fn test_shared_cache_hits_scoring() {
use crate::test_utils::SimpleWorkerConfig;
let block_size = 1u32;
let isl = 4usize;
let worker0 = WorkerWithDpRank::from_worker_id(0);
let mut effective_overlap_blocks = HashMap::new();
effective_overlap_blocks.insert(worker0, 2.0);
let mut effective_cached_tokens = HashMap::new();
effective_cached_tokens.insert(worker0, 2);
let mut tier_overlap_blocks = crate::scheduling::TierOverlapBlocks::default();
tier_overlap_blocks.device.insert(worker0, 2);
#[allow(clippy::single_range_in_vec_init)]
let shared_hits = SharedCacheHits::from_ranges(vec![0..4]);
let config = KvRouterConfig {
overlap_score_credit: 1.0,
shared_cache_multiplier: 0.5,
router_temperature: 0.0,
..Default::default()
};
let selector = DefaultWorkerSelector::new(Some(config), "test");
let mut workers = HashMap::new();
workers.insert(0, SimpleWorkerConfig::default());
workers.insert(1, SimpleWorkerConfig::default());
let (tx, _rx) = tokio::sync::oneshot::channel();
let request = SchedulingRequest {
mode: ScheduleMode::QueryOnly {
request_id: Some("test".into()),
},
token_seq: None,
isl_tokens: isl,
overlap: OverlapSignals {
tier_overlap_blocks,
effective_overlap_blocks,
effective_cached_tokens,
},
worker_loads: FxHashMap::default(),
track_prefill_tokens: true,
router_config_override: None,
lora_name: None,
priority_jump: 0.0,
strict_priority: 0,
policy_class: None,
expected_output_tokens: None,
pinned_worker: None,
allowed_worker_ids: None,
routing_constraints: crate::protocols::RoutingConstraints::default(),
shared_cache_hits: Some(shared_hits),
resp_tx: Some(tx),
};
let result = selector
.select_worker(&workers, &request, request.eligibility(), block_size)
.unwrap();
assert_eq!(
result.worker, worker0,
"Worker 0 should be selected (lower logit due to device and shared cache)"
);
}
#[test]
fn test_prefill_load_scale_applies_after_overlap_credits() {
use crate::test_utils::SimpleWorkerConfig;
let block_size = 16u32;
let isl = 64usize;
let worker0 = WorkerWithDpRank::from_worker_id(0);
let worker1 = WorkerWithDpRank::from_worker_id(1);
let mut effective_cached_tokens = HashMap::new();
effective_cached_tokens.insert(worker0, 32);
let mut tier_overlap_blocks = crate::scheduling::TierOverlapBlocks::default();
tier_overlap_blocks.device.insert(worker0, 2);
let config = KvRouterConfig {
overlap_score_credit: 1.0,
prefill_load_scale: 2.0,
router_temperature: 0.0,
..Default::default()
};
let selector = DefaultWorkerSelector::new(Some(config), "test");
let mut workers = HashMap::new();
workers.insert(0, SimpleWorkerConfig::default());
workers.insert(1, SimpleWorkerConfig::default());
let mut decode_blocks = FxHashMap::default();
decode_blocks.insert(worker0, 3);
decode_blocks.insert(worker1, 0);
let (tx, _rx) = tokio::sync::oneshot::channel();
let request = SchedulingRequest {
mode: ScheduleMode::QueryOnly {
request_id: Some("test".into()),
},
token_seq: None,
isl_tokens: isl,
overlap: OverlapSignals {
tier_overlap_blocks,
effective_overlap_blocks: HashMap::new(),
effective_cached_tokens,
},
worker_loads: worker_loads_with_active_decode(decode_blocks),
track_prefill_tokens: true,
router_config_override: None,
lora_name: None,
priority_jump: 0.0,
strict_priority: 0,
policy_class: None,
expected_output_tokens: None,
pinned_worker: None,
allowed_worker_ids: None,
routing_constraints: crate::protocols::RoutingConstraints::default(),
shared_cache_hits: None,
resp_tx: Some(tx),
};
let result = selector
.select_worker(&workers, &request, request.eligibility(), block_size)
.unwrap();
assert_eq!(
result.worker, worker0,
"prefill load scale should apply before adding decode block load"
);
}
#[test]
fn test_worker_logit_preserves_prefill_accounting_edges() {
let worker = WorkerWithDpRank::from_worker_id(0);
let mut request = base_request(64);
request.overlap.effective_cached_tokens.insert(worker, 96);
request.overlap.tier_overlap_blocks.device.insert(worker, 6);
request.worker_loads.insert(
worker,
crate::sequences::WorkerLoadProjection {
active_prefill_tokens: 16,
active_decode_blocks: 2,
additional_active_blocks: 3,
},
);
let selector = DefaultWorkerSelector::new(Some(KvRouterConfig::default()), "test");
let weights = LogitWeights {
overlap_score_credit: 1.0,
overlap_score_credit_decay: 0.0,
prefill_load_scale: 2.0,
shared_cache_multiplier: 0.0,
};
assert_eq!(
selector.worker_logit(&request, worker, 16, 0, weights, "test"),
7.0
);
request.track_prefill_tokens = false;
assert_eq!(
selector.worker_logit(&request, worker, 16, 0, weights, "test"),
5.0
);
}
#[test]
fn test_overlap_credit_decay_can_prefer_less_loaded_cold_worker() {
use crate::test_utils::SimpleWorkerConfig;
let block_size = 16u32;
let warm_worker = WorkerWithDpRank::from_worker_id(0);
let cold_worker = WorkerWithDpRank::from_worker_id(1);
let workers = HashMap::from([
(warm_worker.worker_id, SimpleWorkerConfig::default()),
(cold_worker.worker_id, SimpleWorkerConfig::default()),
]);
let mut request = base_request(64);
request
.overlap
.tier_overlap_blocks
.device
.insert(warm_worker, 4);
request
.overlap
.effective_cached_tokens
.insert(warm_worker, 64);
request.worker_loads.insert(
warm_worker,
crate::sequences::WorkerLoadProjection {
active_prefill_tokens: 48,
..Default::default()
},
);
let no_decay = DefaultWorkerSelector::new(
Some(KvRouterConfig {
overlap_score_credit_decay: 0.0,
..Default::default()
}),
"test",
);
let with_decay = DefaultWorkerSelector::new(
Some(KvRouterConfig {
overlap_score_credit_decay: 1.0,
..Default::default()
}),
"test",
);
assert_eq!(
no_decay
.select_worker(&workers, &request, request.eligibility(), block_size)
.unwrap()
.worker,
warm_worker
);
assert_eq!(
with_decay
.select_worker(&workers, &request, request.eligibility(), block_size)
.unwrap()
.worker,
cold_worker
);
}
#[test]
fn test_effective_overlap_falls_back_when_tier_blocks_are_absent() {
use crate::test_utils::SimpleWorkerConfig;
let block_size = 16u32;
let isl = 64usize;
let worker0 = WorkerWithDpRank::from_worker_id(0);
let worker1 = WorkerWithDpRank::from_worker_id(1);
let mut effective_overlap_blocks = HashMap::new();
effective_overlap_blocks.insert(worker0, 4.0);
let config = KvRouterConfig {
overlap_score_credit: 1.0,
router_temperature: 0.0,
..Default::default()
};
let selector = DefaultWorkerSelector::new(Some(config), "test");
let mut workers = HashMap::new();
workers.insert(0, SimpleWorkerConfig::default());
workers.insert(1, SimpleWorkerConfig::default());
let mut decode_blocks = FxHashMap::default();
decode_blocks.insert(worker0, 1);
decode_blocks.insert(worker1, 0);
let (tx, _rx) = tokio::sync::oneshot::channel();
let request = SchedulingRequest {
mode: ScheduleMode::QueryOnly {
request_id: Some("test".into()),
},
token_seq: None,
isl_tokens: isl,
overlap: OverlapSignals {
tier_overlap_blocks: Default::default(),
effective_overlap_blocks,
effective_cached_tokens: HashMap::new(),
},
worker_loads: worker_loads_with_active_decode(decode_blocks),
track_prefill_tokens: true,
router_config_override: None,
lora_name: None,
priority_jump: 0.0,
strict_priority: 0,
policy_class: None,
expected_output_tokens: None,
pinned_worker: None,
allowed_worker_ids: None,
routing_constraints: crate::protocols::RoutingConstraints::default(),
shared_cache_hits: None,
resp_tx: Some(tx),
};
let result = selector
.select_worker(&workers, &request, request.eligibility(), block_size)
.unwrap();
assert_eq!(
result.worker, worker0,
"effective overlap should still credit older callers without tier maps"
);
}
#[test]
fn test_no_shared_cache_unchanged() {
use crate::test_utils::SimpleWorkerConfig;
let block_size = 16u32;
let isl = 64usize;
let worker0 = WorkerWithDpRank::from_worker_id(0);
let mut effective_overlap_blocks = HashMap::new();
effective_overlap_blocks.insert(worker0, 2.0);
let config = KvRouterConfig::default();
let selector = DefaultWorkerSelector::new(Some(config), "test");
let mut workers = HashMap::new();
workers.insert(0, SimpleWorkerConfig::default());
let (tx, _rx) = tokio::sync::oneshot::channel();
let request = SchedulingRequest {
mode: ScheduleMode::QueryOnly {
request_id: Some("test".into()),
},
token_seq: None,
isl_tokens: isl,
overlap: OverlapSignals {
tier_overlap_blocks: Default::default(),
effective_overlap_blocks,
effective_cached_tokens: HashMap::new(),
},
worker_loads: FxHashMap::default(),
track_prefill_tokens: true,
router_config_override: None,
lora_name: None,
priority_jump: 0.0,
strict_priority: 0,
policy_class: None,
expected_output_tokens: None,
pinned_worker: None,
allowed_worker_ids: None,
routing_constraints: crate::protocols::RoutingConstraints::default(),
shared_cache_hits: None,
resp_tx: Some(tx),
};
let result = selector
.select_worker(&workers, &request, request.eligibility(), block_size)
.unwrap();
assert_eq!(result.worker, worker0);
}
}