From 1430bbc6040ad755720632dfc342bcc1f8ee9e05 Mon Sep 17 00:00:00 2001 From: Roland Tannous Date: Tue, 10 Mar 2026 17:39:35 +0000 Subject: [PATCH 1/3] fix: uncheck train_on_completions for audio models Pure audio models (orpheus, sparktts, whisper, sesame-csm) now always have trainOnCompletions auto-unchecked when selected. Gemma3n (audio_vlm) only unchecks when the dataset is audio. - Add is_audio to frontend ModelConfigResponse (backend already returns it) - Add isAudioModel state to training config store - Auto-set trainOnCompletions=false for pure audio models on model load - Auto-set trainOnCompletions=false for audio VLMs when dataset is audio - Respect manual user override via existing _trainOnCompletionsManuallySet flag --- .../src/features/training/api/models-api.ts | 2 +- .../training/stores/training-config-store.ts | 20 ++++++++++++++++++- .../src/features/training/types/config.ts | 1 + 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/studio/frontend/src/features/training/api/models-api.ts b/studio/frontend/src/features/training/api/models-api.ts index f40f29fda2..cbf203d05a 100644 --- a/studio/frontend/src/features/training/api/models-api.ts +++ b/studio/frontend/src/features/training/api/models-api.ts @@ -61,8 +61,8 @@ export interface ModelConfigResponse { model_name?: string | null; config?: BackendModelConfig | null; is_vision: boolean; + is_audio: boolean; is_lora: boolean; - is_audio?: boolean; base_model?: string | null; model_type?: "text" | "vision" | "audio" | "embeddings" | null; } diff --git a/studio/frontend/src/features/training/stores/training-config-store.ts b/studio/frontend/src/features/training/stores/training-config-store.ts index 502889ee1e..d029761f73 100644 --- a/studio/frontend/src/features/training/stores/training-config-store.ts +++ b/studio/frontend/src/features/training/stores/training-config-store.ts @@ -36,6 +36,7 @@ const initialState: TrainingConfigState = { uploadedFile: null, isCheckingVision: false, isVisionModel: false, + isAudioModel: false, isLoadingModelDefaults: false, modelDefaultsError: null, modelDefaultsAppliedFor: null, @@ -58,6 +59,7 @@ let _trainOnCompletionsManuallySet = false; const NON_PERSISTED_STATE_KEYS: ReadonlySet = new Set([ "modelType", "isCheckingVision", + "isAudioModel", "isLoadingModelDefaults", "modelDefaultsError", "modelDefaultsAppliedFor", @@ -127,6 +129,16 @@ export const useTrainingConfigStore = create()( patch.trainOnCompletions = false; } + const isAudio = !!modelDetails.is_audio; + // Pure audio model → always uncheck trainOnCompletions. + if (isAudio && !modelDetails.is_vision) { + patch.trainOnCompletions = false; + } + // Audio-capable vision model (e.g. gemma3n) + audio dataset → uncheck. + if (isAudio && modelDetails.is_vision && get().isDatasetAudio) { + patch.trainOnCompletions = false; + } + // Use backend-provided model_type when available, otherwise // infer from is_vision (temporary until backend ships model_type). const inferredModelType: ModelType = modelDetails.model_type @@ -136,6 +148,7 @@ export const useTrainingConfigStore = create()( ...patch, modelType: inferredModelType, isVisionModel: modelDetails.is_vision, + isAudioModel: isAudio, isLoadingModelDefaults: false, isCheckingVision: false, modelDefaultsError: null, @@ -194,10 +207,13 @@ export const useTrainingConfigStore = create()( isCheckingDataset: false, }; if (!_trainOnCompletionsManuallySet) { - const { isVisionModel } = get(); + const { isVisionModel, isAudioModel } = get(); if (isVisionModel && isImage) { updates.trainOnCompletions = false; } + if (isAudioModel && isAudio) { + updates.trainOnCompletions = false; + } } set(updates); }) @@ -233,6 +249,7 @@ export const useTrainingConfigStore = create()( selectedModel: null, isCheckingVision: false, isVisionModel: false, + isAudioModel: false, isDatasetAudio: false, isLoadingModelDefaults: false, modelDefaultsError: null, @@ -249,6 +266,7 @@ export const useTrainingConfigStore = create()( set({ isCheckingVision: false, isVisionModel: false, + isAudioModel: false, isDatasetAudio: false, isLoadingModelDefaults: false, modelDefaultsError: null, diff --git a/studio/frontend/src/features/training/types/config.ts b/studio/frontend/src/features/training/types/config.ts index bc8305430b..5a427dd153 100644 --- a/studio/frontend/src/features/training/types/config.ts +++ b/studio/frontend/src/features/training/types/config.ts @@ -60,6 +60,7 @@ export interface TrainingConfigState { logFrequency: number; isCheckingVision: boolean; isVisionModel: boolean; + isAudioModel: boolean; isLoadingModelDefaults: boolean; modelDefaultsError: string | null; modelDefaultsAppliedFor: string | null; From d9f2d0826765af2c6b6676c0a0b0b68c895560c9 Mon Sep 17 00:00:00 2001 From: Roland Tannous Date: Tue, 10 Mar 2026 19:00:56 +0000 Subject: [PATCH 2/3] fix: reset isAudioModel on model config fetch failure Clear stale isAudioModel in the fallback path when getModelConfig fails, preventing a previously-selected audio model's flag from leaking into the next model selection. --- .../src/features/training/stores/training-config-store.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/studio/frontend/src/features/training/stores/training-config-store.ts b/studio/frontend/src/features/training/stores/training-config-store.ts index d029761f73..3a182b73ec 100644 --- a/studio/frontend/src/features/training/stores/training-config-store.ts +++ b/studio/frontend/src/features/training/stores/training-config-store.ts @@ -161,6 +161,7 @@ export const useTrainingConfigStore = create()( set({ isLoadingModelDefaults: false, + isAudioModel: false, modelDefaultsError: error instanceof Error ? error.message @@ -174,12 +175,13 @@ export const useTrainingConfigStore = create()( set({ modelType: isVision ? "vision" : "text", isVisionModel: isVision, + isAudioModel: false, isCheckingVision: false, }); }) .catch(() => { if (get().selectedModel !== modelName) return; - set({ isCheckingVision: false }); + set({ isCheckingVision: false, isAudioModel: false }); }); }); }; From 846cc2cf2a4ebac1938035a89462de7e8c7e68a0 Mon Sep 17 00:00:00 2001 From: Roland Tannous Date: Tue, 10 Mar 2026 19:02:49 +0000 Subject: [PATCH 3/3] fix: always force-uncheck trainOnCompletions for pure audio models in dataset check Separate pure-audio from audio-VLM logic in runDatasetCheck so pure audio models are always forced to trainOnCompletions=false regardless of dataset type, while audio VLMs (gemma3n) only uncheck when the dataset is audio. --- .../src/features/training/stores/training-config-store.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/studio/frontend/src/features/training/stores/training-config-store.ts b/studio/frontend/src/features/training/stores/training-config-store.ts index 3a182b73ec..30d03e7fc5 100644 --- a/studio/frontend/src/features/training/stores/training-config-store.ts +++ b/studio/frontend/src/features/training/stores/training-config-store.ts @@ -213,7 +213,12 @@ export const useTrainingConfigStore = create()( if (isVisionModel && isImage) { updates.trainOnCompletions = false; } - if (isAudioModel && isAudio) { + // Pure audio model → always uncheck regardless of dataset. + if (isAudioModel && !isVisionModel) { + updates.trainOnCompletions = false; + } + // Audio-capable vision model (e.g. gemma3n) + audio dataset → uncheck. + if (isAudioModel && isVisionModel && isAudio) { updates.trainOnCompletions = false; } }