feat(ml): default to SigLIP 2 (new installs) + model dropdown, no free-text (#1203)
- Migration 0069: new installs default to SigLIP 2 (so400m, 512px, 1152-d drop-in) — UPDATE applies ONLY where no image is embedded yet (fresh install), so an existing library is NOT silently invalidated; it switches deliberately via the dropdown → Re-embed → Retrain. Column server_defaults moved to SigLIP 2. - GET /api/ml/embedder-models: server-authoritative supported list (SigLIP 2 512 recommended / 384 faster / SigLIP 1 384 original) so the UI never free-types. - GpuAgentCard: the two name/version text fields → a single model dropdown; Save sets name+version from the picked option (the current model is always selectable even if off-list). - embedder.py DEFAULT_MODEL_NAME unchanged (stays the baked local-dir SigLIP 1) to avoid a local-dir/weights mismatch; SigLIP 2 loads by HF name, cached on the ml-worker's persistent HF_HOME. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ttrj5P7upUTueSfoJcxEqa
This commit is contained in:
@@ -117,15 +117,12 @@
|
||||
the suggest cut; 0.92 recommended.
|
||||
</p>
|
||||
|
||||
<!-- Embedding model (advanced) -->
|
||||
<div v-if="ml.settings" class="fc-section-h mt-5 mb-1">Embedding model (advanced)</div>
|
||||
<!-- Embedding model -->
|
||||
<div v-if="ml.settings" class="fc-section-h mt-5 mb-1">Embedding model</div>
|
||||
<div v-if="ml.settings">
|
||||
<v-text-field
|
||||
v-model="modelName" label="HF model name" density="compact" hide-details
|
||||
variant="outlined" class="mb-2"
|
||||
/>
|
||||
<v-text-field
|
||||
v-model="modelVersion" label="Version stamp" density="compact" hide-details
|
||||
<v-select
|
||||
v-model="selectedModel" :items="modelItems" item-title="label"
|
||||
item-value="name" label="Model" density="compact" hide-details
|
||||
variant="outlined"
|
||||
/>
|
||||
<div class="d-flex mt-3" style="gap:8px">
|
||||
@@ -139,12 +136,11 @@
|
||||
>Re-embed library (GPU)</v-btn>
|
||||
</div>
|
||||
<p class="fc-muted text-caption mt-2 mb-0">
|
||||
Changing the model means a DIFFERENT embedding space. After saving a new
|
||||
model + version, run <b>Re-embed library</b> (the GPU agent re-embeds
|
||||
whole images + concept crops), then <b>Retrain heads</b>. Suggestions
|
||||
degrade until both finish. SigLIP 2 (<code>google/siglip2-so400m-patch16-512</code>,
|
||||
version <code>siglip2-so400m-patch16-512</code>) is a 1152-d drop-in at
|
||||
512px — no schema change.
|
||||
Switching the model is a DIFFERENT embedding space. After <b>Save model</b>,
|
||||
run <b>Re-embed library</b> (the GPU agent re-embeds whole images + concept
|
||||
crops), then <b>Retrain heads</b> — suggestions degrade until both finish.
|
||||
SigLIP 2 (512px) is a 1152-d drop-in over SigLIP 1; new installs default to
|
||||
it. Your existing library stays on its current model until you re-embed.
|
||||
</p>
|
||||
</div>
|
||||
</MaintenanceTile>
|
||||
@@ -173,8 +169,8 @@ const savingThreshold = ref(false)
|
||||
const autoApply = ref(true)
|
||||
const autoThreshold = ref(0.92)
|
||||
const savingAuto = ref(false)
|
||||
const modelName = ref('')
|
||||
const modelVersion = ref('')
|
||||
const modelItems = ref([])
|
||||
const selectedModel = ref(null)
|
||||
const savingModel = ref(false)
|
||||
const reembedding = ref(false)
|
||||
const queue = ref({ pending: 0, leased: 0, done: 0, error: 0 })
|
||||
@@ -204,18 +200,26 @@ onMounted(async () => {
|
||||
autoThreshold.value = ml.settings.ccip_auto_apply_threshold
|
||||
}
|
||||
if (ml.settings?.embedder_model_name != null) {
|
||||
modelName.value = ml.settings.embedder_model_name
|
||||
modelVersion.value = ml.settings.embedder_model_version
|
||||
const items = await ml.embedderModels()
|
||||
// Make sure the current model is selectable even if it's not in the list.
|
||||
const cur = ml.settings.embedder_model_name
|
||||
if (!items.some((m) => m.name === cur)) {
|
||||
items.push({ name: cur, version: ml.settings.embedder_model_version, label: `${cur} (current)` })
|
||||
}
|
||||
modelItems.value = items
|
||||
selectedModel.value = cur
|
||||
}
|
||||
} catch { /* non-fatal */ }
|
||||
})
|
||||
|
||||
async function onSaveModel() {
|
||||
const opt = modelItems.value.find((m) => m.name === selectedModel.value)
|
||||
if (!opt) return
|
||||
savingModel.value = true
|
||||
try {
|
||||
await ml.patchSettings({
|
||||
embedder_model_name: modelName.value.trim(),
|
||||
embedder_model_version: modelVersion.value.trim(),
|
||||
embedder_model_name: opt.name,
|
||||
embedder_model_version: opt.version,
|
||||
})
|
||||
toast({ text: 'Embedding model saved — now Re-embed library, then Retrain heads', type: 'success' })
|
||||
} catch (e) {
|
||||
|
||||
Reference in New Issue
Block a user