Add Metal execution preferences
This commit is contained in:
100
src/app.rs
100
src/app.rs
@@ -4,7 +4,7 @@ pub(crate) use view::app_theme;
|
||||
|
||||
use crate::database::{AppPreferences, Database, ProjectWithSessions};
|
||||
use crate::model::{self, DownloadOutcome, DownloadProgress, ManagedArtifactId, ModelChoice};
|
||||
use crate::settings::{GenerationPreferences, ReasoningMode};
|
||||
use crate::settings::{ExecutionPreferences, GenerationPreferences, ReasoningMode};
|
||||
use iced::{Size, Subscription, Task, keyboard, window};
|
||||
use rfd::AsyncFileDialog;
|
||||
use std::fs;
|
||||
@@ -30,6 +30,11 @@ struct PreferenceDraft {
|
||||
min_p: String,
|
||||
seed: String,
|
||||
reasoning_mode: ReasoningMode,
|
||||
cpu_threads: String,
|
||||
power_percent: String,
|
||||
prefill_chunk: String,
|
||||
quality: bool,
|
||||
warm_weights: bool,
|
||||
}
|
||||
|
||||
impl PreferenceDraft {
|
||||
@@ -37,6 +42,8 @@ impl PreferenceDraft {
|
||||
let model = ModelChoice::from_id(&preferences.selected_model)
|
||||
.ok_or_else(|| format!("Unsupported model: {}", preferences.selected_model))?;
|
||||
let generation = preferences.generation()?;
|
||||
let execution = preferences.execution()?;
|
||||
execution.validate(model)?;
|
||||
Ok(Self {
|
||||
model,
|
||||
dspark_enabled: model.supports_dspark() && preferences.dspark_enabled,
|
||||
@@ -57,6 +64,17 @@ impl PreferenceDraft {
|
||||
.seed
|
||||
.map_or_else(String::new, |value| value.to_string()),
|
||||
reasoning_mode: generation.reasoning_mode,
|
||||
cpu_threads: execution
|
||||
.cpu_threads
|
||||
.map_or_else(String::new, |value| value.to_string()),
|
||||
power_percent: execution
|
||||
.power_percent
|
||||
.map_or_else(String::new, |value| value.to_string()),
|
||||
prefill_chunk: execution
|
||||
.prefill_chunk
|
||||
.map_or_else(String::new, |value| value.to_string()),
|
||||
quality: execution.quality,
|
||||
warm_weights: execution.warm_weights,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -80,6 +98,7 @@ impl PreferenceDraft {
|
||||
|
||||
fn reset(&mut self) {
|
||||
let defaults = GenerationPreferences::default();
|
||||
let execution = ExecutionPreferences::default();
|
||||
self.model = ModelChoice::default();
|
||||
self.dspark_enabled = false;
|
||||
self.idle_timeout_minutes = "10".into();
|
||||
@@ -91,6 +110,21 @@ impl PreferenceDraft {
|
||||
self.min_p.clear();
|
||||
self.seed.clear();
|
||||
self.reasoning_mode = defaults.reasoning_mode;
|
||||
self.cpu_threads.clear();
|
||||
self.power_percent.clear();
|
||||
self.prefill_chunk.clear();
|
||||
self.quality = execution.quality;
|
||||
self.warm_weights = execution.warm_weights;
|
||||
}
|
||||
|
||||
fn execution(&self) -> Result<ExecutionPreferences, String> {
|
||||
Ok(ExecutionPreferences {
|
||||
cpu_threads: parse_optional_u32("CPU helper threads", &self.cpu_threads)?,
|
||||
power_percent: parse_optional_u8("GPU power", &self.power_percent)?,
|
||||
prefill_chunk: parse_optional_u32("Prefill chunk", &self.prefill_chunk)?,
|
||||
quality: self.quality,
|
||||
warm_weights: self.warm_weights,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,6 +161,29 @@ fn parse_optional_u64(name: &str, value: &str) -> Result<Option<u64>, String> {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_optional_u32(name: &str, value: &str) -> Result<Option<u32>, String> {
|
||||
parse_optional_number(name, value)
|
||||
}
|
||||
|
||||
fn parse_optional_u8(name: &str, value: &str) -> Result<Option<u8>, String> {
|
||||
parse_optional_number(name, value)
|
||||
}
|
||||
|
||||
fn parse_optional_number<T: std::str::FromStr>(
|
||||
name: &str,
|
||||
value: &str,
|
||||
) -> Result<Option<T>, String> {
|
||||
let value = value.trim();
|
||||
if value.is_empty() {
|
||||
Ok(None)
|
||||
} else {
|
||||
value
|
||||
.parse()
|
||||
.map(Some)
|
||||
.map_err(|_| format!("{name} must be a positive whole number or left blank."))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct App {
|
||||
main_window: window::Id,
|
||||
pub(super) model_manager_window: Option<window::Id>,
|
||||
@@ -196,6 +253,11 @@ pub(crate) enum Message {
|
||||
PreferenceMinPChanged(String),
|
||||
PreferenceSeedChanged(String),
|
||||
PreferenceReasoningChanged(ReasoningMode),
|
||||
PreferenceCpuThreadsChanged(String),
|
||||
PreferencePowerChanged(String),
|
||||
PreferencePrefillChunkChanged(String),
|
||||
PreferenceQualityChanged(bool),
|
||||
PreferenceWarmWeightsChanged(bool),
|
||||
ResetPreferences,
|
||||
SavePreferences,
|
||||
DownloadArtifact(ManagedArtifactId),
|
||||
@@ -327,6 +389,10 @@ impl App {
|
||||
if !model.supports_dspark() {
|
||||
self.preference_draft.dspark_enabled = false;
|
||||
}
|
||||
if model == ModelChoice::Glm52 {
|
||||
self.preference_draft.power_percent.clear();
|
||||
self.preference_draft.prefill_chunk.clear();
|
||||
}
|
||||
self.preference_error = None;
|
||||
}
|
||||
Message::PreferenceDsparkChanged(enabled) => {
|
||||
@@ -370,6 +436,26 @@ impl App {
|
||||
self.preference_draft.reasoning_mode = value;
|
||||
self.preference_error = None;
|
||||
}
|
||||
Message::PreferenceCpuThreadsChanged(value) => {
|
||||
self.preference_draft.cpu_threads = value;
|
||||
self.preference_error = None;
|
||||
}
|
||||
Message::PreferencePowerChanged(value) => {
|
||||
self.preference_draft.power_percent = value;
|
||||
self.preference_error = None;
|
||||
}
|
||||
Message::PreferencePrefillChunkChanged(value) => {
|
||||
self.preference_draft.prefill_chunk = value;
|
||||
self.preference_error = None;
|
||||
}
|
||||
Message::PreferenceQualityChanged(value) => {
|
||||
self.preference_draft.quality = value;
|
||||
self.preference_error = None;
|
||||
}
|
||||
Message::PreferenceWarmWeightsChanged(value) => {
|
||||
self.preference_draft.warm_weights = value;
|
||||
self.preference_error = None;
|
||||
}
|
||||
Message::ResetPreferences => {
|
||||
self.preference_draft.reset();
|
||||
self.preference_error = None;
|
||||
@@ -610,6 +696,17 @@ impl App {
|
||||
};
|
||||
|
||||
let model = self.preference_draft.model;
|
||||
let execution = match self.preference_draft.execution() {
|
||||
Ok(execution) => execution,
|
||||
Err(error) => {
|
||||
self.preference_error = Some(error);
|
||||
return;
|
||||
}
|
||||
};
|
||||
if let Err(error) = execution.validate(model) {
|
||||
self.preference_error = Some(error);
|
||||
return;
|
||||
}
|
||||
let dspark_enabled = model.supports_dspark() && self.preference_draft.dspark_enabled;
|
||||
let Some(database) = &mut self.database else {
|
||||
return;
|
||||
@@ -619,6 +716,7 @@ impl App {
|
||||
dspark_enabled,
|
||||
idle_timeout_minutes,
|
||||
&generation,
|
||||
&execution,
|
||||
) {
|
||||
Ok(preferences) => {
|
||||
self.preferences = preferences;
|
||||
|
||||
Reference in New Issue
Block a user