#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TensorClass {
Token_embd,
Output,
Attn_norm,
Ffn,
Exps,
Cache_k,
Attn_k_norm,
}
impl TensorClass {
pub fn llama_key(&self) -> &'static str {
match self {
TensorClass::Token_embd => "token_embd",
TensorClass::Output => "output",
TensorClass::Attn_norm => "attn_norm",
TensorClass::Ffn => "ffn",
TensorClass::Exps => "exps",
TensorClass::Cache_k => "cache_k",
TensorClass::Attn_k_norm => "attn_k_norm",
}
}
}
pub const DEFAULT_ROUTING: &[(TensorClass, &str)] = &[
(TensorClass::Token_embd, "CPU"),
(TensorClass::Output, "CPU"),
(TensorClass::Attn_norm, "CPU"),
(TensorClass::Cache_k, "CPU"),
(TensorClass::Attn_k_norm, "CPU"),
(TensorClass::Ffn, "RPC"),
(TensorClass::Exps, "RPC"),
];
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Placement {
Local,
Remote,
NotWorthIt,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct LatencyProfile {
pub peer_rtt_ms: f32,
pub local_cpu_penalty_ms: f32,
}
impl Default for LatencyProfile {
fn default() -> Self {
Self {
peer_rtt_ms: 0.5,
local_cpu_penalty_ms: 1.0,
}
}
}
pub fn plan_tensor_classes(
local_vram_gb: f32,
model_size_gb: f32,
remote_vram_gb: f32,
latency: LatencyProfile,
) -> Vec<(TensorClass, Placement)> {
let mut plan = Vec::with_capacity(DEFAULT_ROUTING.len());
let local_is_tight = model_size_gb > 0.0 && model_size_gb + 1.0 > local_vram_gb;
let peer_has_room = remote_vram_gb > 0.0;
for (class, default_route) in DEFAULT_ROUTING {
let remote_by_default = *default_route == "RPC";
let placement = if !remote_by_default {
Placement::Local
} else if !peer_has_room {
Placement::NotWorthIt
} else if !local_is_tight {
Placement::NotWorthIt
} else if latency.peer_rtt_ms > latency.local_cpu_penalty_ms {
Placement::NotWorthIt
} else {
Placement::Remote
};
plan.push((*class, placement));
}
plan
}
pub fn override_flag_value(plan: &[(TensorClass, Placement)], buffer_type: &str) -> String {
let remote: Vec<String> = plan
.iter()
.filter(|(_, p)| *p == Placement::Remote)
.map(|(c, _)| format!("{}={buffer_type}", c.llama_key()))
.collect();
if remote.is_empty() {
String::new()
} else {
remote.join(",")
}
}
pub fn rpc_buffer_type(endpoint: &str) -> String {
format!("RPC0[{endpoint}]")
}
#[cfg(test)]
mod tests {
use super::*;
fn remote_classes(plan: &[(TensorClass, Placement)]) -> Vec<TensorClass> {
plan.iter()
.filter(|(_, p)| *p == Placement::Remote)
.map(|(c, _)| *c)
.collect()
}
#[test]
fn ffn_and_experts_are_the_remote_candidates() {
let plan = plan_tensor_classes(8.0, 16.0, 24.0, LatencyProfile::default());
let remote = remote_classes(&plan);
assert!(remote.contains(&TensorClass::Ffn));
assert!(remote.contains(&TensorClass::Exps));
}
#[test]
fn latency_sensitive_classes_stay_local() {
let plan = plan_tensor_classes(8.0, 16.0, 24.0, LatencyProfile::default());
let remote = remote_classes(&plan);
for c in [
TensorClass::Cache_k,
TensorClass::Output,
TensorClass::Token_embd,
TensorClass::Attn_norm,
TensorClass::Attn_k_norm,
] {
assert!(
!remote.contains(&c),
"{c:?} must stay local; it is per-token latency, not bulk data"
);
}
}
#[test]
fn nothing_goes_remote_when_the_model_fits_locally() {
let plan = plan_tensor_classes(24.0, 3.0, 48.0, LatencyProfile::default());
assert!(
remote_classes(&plan).is_empty(),
"a fitting model must stay entirely local"
);
}
#[test]
fn nothing_goes_remote_when_the_peer_has_no_vram() {
let plan = plan_tensor_classes(8.0, 30.0, 0.0, LatencyProfile::default());
assert!(remote_classes(&plan).is_empty());
}
#[test]
fn a_slow_peer_is_not_given_latency_sensitive_work() {
let slow = LatencyProfile {
peer_rtt_ms: 12.0,
local_cpu_penalty_ms: 0.5,
};
let plan = plan_tensor_classes(8.0, 30.0, 24.0, slow);
assert!(
remote_classes(&plan).is_empty(),
"a 12ms peer must not receive any tensor class"
);
}
#[test]
fn a_fast_peer_is_given_work_when_the_model_does_not_fit() {
let fast = LatencyProfile {
peer_rtt_ms: 0.2,
local_cpu_penalty_ms: 0.5,
};
let plan = plan_tensor_classes(8.0, 30.0, 24.0, fast);
assert!(!remote_classes(&plan).is_empty());
}
#[test]
fn the_plan_covers_every_class() {
let plan = plan_tensor_classes(8.0, 16.0, 24.0, LatencyProfile::default());
assert_eq!(plan.len(), DEFAULT_ROUTING.len());
for (class, _) in DEFAULT_ROUTING {
assert!(
plan.iter().any(|(c, _)| c == class),
"{class:?} missing from the plan"
);
}
}
#[test]
fn an_empty_override_is_rendered_as_an_empty_string() {
let plan = plan_tensor_classes(24.0, 3.0, 48.0, LatencyProfile::default());
assert_eq!(override_flag_value(&plan, "RPC0[127.0.0.1:50052]"), "");
}
#[test]
fn the_override_names_ffn_and_exps() {
let plan = plan_tensor_classes(
8.0,
30.0,
24.0,
LatencyProfile {
peer_rtt_ms: 0.2,
local_cpu_penalty_ms: 0.5,
},
);
let flag = override_flag_value(&plan, "RPC0[127.0.0.1:50052]");
assert!(
flag.contains("ffn=RPC0[127.0.0.1:50052]"),
"flag was {flag}"
);
assert!(
flag.contains("exps=RPC0[127.0.0.1:50052]"),
"flag was {flag}"
);
assert!(
!flag.contains("cache_k=RPC"),
"KV must not be routed: {flag}"
);
}
#[test]
fn the_default_override_matches_the_value_the_existing_test_asserts() {
let plan = plan_tensor_classes(8.0, 16.0, 24.0, LatencyProfile::default());
assert_eq!(
override_flag_value(&plan, "RPC0[127.0.0.1:50052]"),
"ffn=RPC0[127.0.0.1:50052],exps=RPC0[127.0.0.1:50052]"
);
}
#[test]
fn the_buffer_type_matches_ggml_rpc_naming() {
assert_eq!(rpc_buffer_type("127.0.0.1:50052"), "RPC0[127.0.0.1:50052]");
}
#[test]
fn the_bare_word_rpc_is_never_emitted() {
let plan = plan_tensor_classes(
8.0,
16.0,
24.0,
LatencyProfile {
peer_rtt_ms: 0.2,
local_cpu_penalty_ms: 0.5,
},
);
let flag = override_flag_value(&plan, &rpc_buffer_type("10.0.0.5:50052"));
assert!(flag.contains("RPC0[10.0.0.5:50052]"), "flag was {flag}");
assert!(
!flag.contains("=RPC,") && !flag.ends_with("=RPC"),
"a bare RPC value would be rejected by llama-server: {flag}"
);
}
}