Add Metal execution preferences
This commit is contained in:
@@ -6,8 +6,74 @@ pub(crate) const REASONING_MODES: [ReasoningMode; 3] = [
|
||||
ReasoningMode::Max,
|
||||
ReasoningMode::Direct,
|
||||
];
|
||||
|
||||
const THINK_MAX_MIN_CONTEXT: i32 = 393_216;
|
||||
const MAX_CPU_THREADS: u32 = 32;
|
||||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
||||
pub(crate) struct ExecutionPreferences {
|
||||
pub(crate) cpu_threads: Option<u32>,
|
||||
pub(crate) power_percent: Option<u8>,
|
||||
pub(crate) prefill_chunk: Option<u32>,
|
||||
pub(crate) quality: bool,
|
||||
pub(crate) warm_weights: bool,
|
||||
}
|
||||
|
||||
impl ExecutionPreferences {
|
||||
pub(crate) fn validate(&self, model: ModelChoice) -> Result<(), String> {
|
||||
if self.cpu_threads == Some(0) {
|
||||
return Err("CPU helper threads must be a positive whole number.".into());
|
||||
}
|
||||
if self
|
||||
.cpu_threads
|
||||
.is_some_and(|threads| threads > i32::MAX as u32)
|
||||
{
|
||||
return Err("CPU helper threads is too large.".into());
|
||||
}
|
||||
if self
|
||||
.power_percent
|
||||
.is_some_and(|power| !(1..=100).contains(&power))
|
||||
{
|
||||
return Err("GPU power must be between 1 and 100 percent.".into());
|
||||
}
|
||||
if self.prefill_chunk == Some(0) {
|
||||
return Err("Prefill chunk must be a positive whole number.".into());
|
||||
}
|
||||
if self
|
||||
.prefill_chunk
|
||||
.is_some_and(|chunk| chunk > i32::MAX as u32)
|
||||
{
|
||||
return Err("Prefill chunk is too large.".into());
|
||||
}
|
||||
if model == ModelChoice::Glm52 {
|
||||
if self.power_percent.is_some_and(|power| power != 100) {
|
||||
return Err("GLM 5.2 currently requires 100% GPU power.".into());
|
||||
}
|
||||
if self.prefill_chunk.is_some() {
|
||||
return Err("GLM 5.2 selects its prefill chunk automatically.".into());
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn engine_settings(&self) -> EngineExecutionSettings {
|
||||
EngineExecutionSettings {
|
||||
cpu_threads: self.cpu_threads.unwrap_or(0).min(MAX_CPU_THREADS),
|
||||
power_percent: self.power_percent.unwrap_or(0),
|
||||
prefill_chunk: self.prefill_chunk.unwrap_or(0),
|
||||
quality: self.quality,
|
||||
warm_weights: self.warm_weights,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub(crate) struct EngineExecutionSettings {
|
||||
pub(crate) cpu_threads: u32,
|
||||
pub(crate) power_percent: u8,
|
||||
pub(crate) prefill_chunk: u32,
|
||||
pub(crate) quality: bool,
|
||||
pub(crate) warm_weights: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
|
||||
pub(crate) enum ReasoningMode {
|
||||
@@ -156,4 +222,27 @@ mod tests {
|
||||
assert_eq!((effective.top_p, effective.min_p), (0.4, 0.2));
|
||||
assert_eq!(effective.reasoning_mode, ReasoningMode::High);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn execution_settings_keep_ds4_automatic_values_and_glm_rules() {
|
||||
let defaults = ExecutionPreferences::default().engine_settings();
|
||||
assert_eq!(
|
||||
(
|
||||
defaults.cpu_threads,
|
||||
defaults.power_percent,
|
||||
defaults.prefill_chunk
|
||||
),
|
||||
(0, 0, 0)
|
||||
);
|
||||
|
||||
let tuned = ExecutionPreferences {
|
||||
cpu_threads: Some(100),
|
||||
power_percent: Some(50),
|
||||
prefill_chunk: Some(4096),
|
||||
..ExecutionPreferences::default()
|
||||
};
|
||||
assert!(tuned.validate(ModelChoice::DeepSeekV4Flash).is_ok());
|
||||
assert!(tuned.validate(ModelChoice::Glm52).is_err());
|
||||
assert_eq!(tuned.engine_settings().cpu_threads, MAX_CPU_THREADS);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user