Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added docs/images/settings-refresh-preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions docs/user-guide/custom-models.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Using your own weights: base model / VAE / text encoder

In Settings → **Training Models**, every category of weights can be swapped out from the official download for a file you already have on disk:
In Settings → **Models**, every category of weights can be swapped out from the official download for a file you already have on disk:

| Weight | Form | Card |
|---|---|---|
Expand All @@ -14,7 +14,7 @@ In Settings → **Training Models**, every category of weights can be swapped ou
2. The selected path appears as a "local" candidate row below the official variant; click its radio button to make it the default.
3. To stop using it, click **Unregister** — this only removes it from the list, **the file on disk is left untouched**. If the unregistered entry was the currently selected one, the selection automatically falls back to the official weights.

> **The path is relative to the machine running Studio.** In local mode that's your own computer; in cloud modes like Colab / Kaggle, the file picker browses the container's disk, so a local `D:\...` path doesn't exist there — upload the weights to the cloud drive (or the Drive mount point) first, then select them. The gray text next to the button tells you which case you're in.
> **The path is relative to the machine running Studio.** In local mode that's your own computer; in cloud modes like Colab / Kaggle, the file picker browses the container's disk, so a local `D:\...` path doesn't exist there — upload the weights to the cloud drive (or the Drive mount point) first, then select them. Hover over the file or directory button for the hint about your current mode.

If a file is deleted or moved, resolution automatically falls back to the official location instead of writing a dead path into the training config; the corresponding row on the card is marked "file not found" and its radio button is grayed out.

Expand Down
15 changes: 3 additions & 12 deletions studio/web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,9 @@
<title>AnimaTrainHub</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link id="favicon" rel="icon" type="image/png" href="./icons/noal_smug.png" />
<script type="module">
// Picks a random favicon out of 10 noal expression icons on every refresh.
const icons = [
'noal_conf2.png', 'noal_confused.png', 'noal_emb.png',
'noal_heart.png', 'noal_sad.png', 'noal_shock.png',
'noal_shy_mad.png', 'noal_shy_mad2.png', 'noal_sleepy.png',
'noal_smug.png',
]
const pick = icons[Math.floor(Math.random() * icons.length)]
document.getElementById('favicon').href = `${import.meta.env.BASE_URL}icons/${pick}`
</script>
<link rel="icon" type="image/png" sizes="512x512" href="./icons/noal.png" />
<link rel="icon" href="./icons/noal.ico" sizes="any" />
<link rel="apple-touch-icon" href="./icons/noal-180.png" />
</head>
<body>
<div id="root"></div>
Expand Down
Binary file added studio/web/public/icons/noal-180.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added studio/web/public/icons/noal.ico
Binary file not shown.
Binary file added studio/web/public/icons/noal.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed studio/web/public/icons/noal_conf2.png
Binary file not shown.
Binary file removed studio/web/public/icons/noal_confused.png
Binary file not shown.
Binary file removed studio/web/public/icons/noal_emb.png
Binary file not shown.
Binary file removed studio/web/public/icons/noal_heart.png
Binary file not shown.
Binary file removed studio/web/public/icons/noal_sad.png
Binary file not shown.
Binary file removed studio/web/public/icons/noal_shock.png
Binary file not shown.
Binary file removed studio/web/public/icons/noal_shy_mad.png
Binary file not shown.
Binary file removed studio/web/public/icons/noal_shy_mad2.png
Binary file not shown.
Binary file removed studio/web/public/icons/noal_sleepy.png
Binary file not shown.
Binary file removed studio/web/public/icons/noal_smug.png
Binary file not shown.
32 changes: 10 additions & 22 deletions studio/web/src/components/LocalModelSources.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export function LocalModelRows({
}

return (
<ul className="list-none m-0 p-0 flex flex-col gap-1">
<>
{local.map((row) => (
<li
key={row.value}
Expand All @@ -112,31 +112,21 @@ export function LocalModelRows({
checked={row.is_current}
disabled={!row.exists || busy === row.value}
onChange={() => void onSelect(row.value)}
className="shrink-0"
style={{ accentColor: 'var(--accent)' }}
title={row.exists
? t('settings.selectLocalModel')
: t('settings.localModelMissing')}
/>
<code
className="font-mono text-fg-primary w-32 shrink-0 truncate"
title={row.value}
>{row.label}</code>
<span className="ds-badge ds-mute shrink-0">
{t('settings.localBaseModel')}
</span>
<code className="ds-model-name" title={row.value}>{row.label}</code>
<span className="ds-badge ds-mute">{t('settings.localBaseModel')}</span>
<span className={`ds-badge ds-mono ${row.exists ? 'ds-ok' : 'ds-err'}`}>
{row.exists ? `✓ ${fmtBytes(row.size)}` : t('settings.localModelMissing')}
</span>
<span style={{ flex: 1 }} />
{familyOptions && familyOptions.length > 1 && (
<select
value={domain}
disabled={busy === row.value}
onChange={(e) => void changeFamily(row, e.target.value)}
className="ds-inp ds-mono shrink-0"
// ds-inp is width:100%; narrowed here so the remove button stays on the row
style={{ height: 26, padding: '0 6px', width: 96 }}
className="ds-inp ds-mono ds-set-minisel"
title={t('settings.localModelFamilyHint')}
>
{familyOptions.map((f) => (
Expand All @@ -147,14 +137,14 @@ export function LocalModelRows({
<button
onClick={() => void unregister(row)}
disabled={busy === row.value}
className="ds-ctl ds-ghost ds-sm shrink-0"
className="ds-ctl ds-ghost ds-sm"
title={t('settings.localModelRemoveHint')}
>
{t('settings.localModelRemove')}
</button>
</li>
))}
</ul>
</>
)
}

Expand Down Expand Up @@ -194,23 +184,21 @@ export function AddLocalModelButton({
}

return (
<div className="flex items-center gap-2 mt-1.5">
<div>
<button
onClick={() => setPicking(true)}
disabled={saving}
className="ds-ctl ds-sm"
title={runtime?.mode === 'colab'
? t('settings.localModelPathHintColab')
: t('settings.localModelPathHintLocal')}
>
{saving
? t('common.saving')
: shape === 'dir'
? t('settings.addLocalModelDir')
: t('settings.addLocalModelFile')}
</button>
<span className="text-fg-tertiary text-xs">
{runtime?.mode === 'colab'
? t('settings.localModelPathHintColab')
: t('settings.localModelPathHintLocal')}
</span>
{picking && (
<PathPicker
initialPath={initialPath}
Expand Down
60 changes: 31 additions & 29 deletions studio/web/src/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1338,7 +1338,7 @@
"torch": "PyTorch",
"flashAttn": "Flash Attention",
"xformers": "xformers",
"trainingModels": "Training models",
"trainingModels": "Models",
"wandb": "Weights & Biases",
"intermediatePreview": "Intermediate preview",
"display": "Display",
Expand Down Expand Up @@ -1495,20 +1495,20 @@
"repoHelp": "{{desc}}. Repo: <code>{{repo}}</code>",
"animaModels": "Anima models",
"krea2Models": "Krea2 models",
"modelsRoot": "Model root (models_root)",
"modelsRoot": "Models folder",
"savePathConfig": "Save path config",
"notModified": "Not modified",
"savePath": "Save path",
"trainingParams": "Training parameters",
"autoSyncPathsLabel": "Auto-configure model paths",
"autoSyncPathsLabel": "Fill model paths into the config",
"autoSyncPathsHelp": "ON (default / most users): when forking a preset to a version, the model path fields (transformer / VAE / text encoder, varying by model family) are auto-overwritten from Settings; these fields are disabled in preset/project pages. OFF (custom-model users): fork respects the absolute paths stored in the preset; the fields become editable with a picker.",
"autoSyncPathsOn": "On · fork auto-syncs global",
"autoSyncPathsOff": "Off · fork respects preset values",
"defaultTransformerHelp": "The selected version becomes the default transformer for <strong>new versions</strong>.",
"downloadLogs": "Download logs ({{n}})",
"partialFiles": "Partial ({{exists}}/{{total}})",
"notDownloaded": "Not downloaded",
"downloadAction": "⤓ Download",
"downloadAction": "Download",
"upscalersPreprocess": "Upscalers (preprocess)",
"availableUpscalers": "Available upscalers",
"upscalersHelpPath": "Preprocess uses upscaling for small images. Files are stored in <code>{{path}}</code>.",
Expand All @@ -1533,8 +1533,8 @@
"onnxRestartRequired": "A new onnxruntime package is installed, but the current process is still using the old one. <strong>Restart Studio</strong> to apply EP changes.",
"saveFailedWithError": "Save failed: {{error}}",
"hfMirrorHint": "Recommended in China",
"hfOfficialHint": "Official source (default)",
"hfCustomHint": "Paste self-hosted proxy / sjtug / Tencent mirror, etc.",
"hfOfficialHint": "official",
"hfCustomHint": "mirror or your own proxy",
"modelDescriptions": {
"animaMain": "Cosmos transformer (~4 GB)",
"animaVae": "qwen_image_vae shared by Anima / Krea2 (~250 MB)",
Expand All @@ -1552,8 +1552,8 @@
"remacri": "Realistic-style community favorite",
"esrgan4x": "Generic ESRGAN baseline"
},
"downloadSourceHuggingface": "HuggingFace (including hf-mirror and other mirrors)",
"downloadSourceModelscope": "ModelScope (direct access in China)",
"downloadSourceHuggingface": "HuggingFace",
"downloadSourceModelscope": "ModelScope",
"confirmInstallOnnxAuto": "Platform + nvidia-smi detection chooses the best package (Windows + GPU → DirectML; Linux + GPU → CUDA; no GPU → CPU). Package installation takes a few minutes.\n\nNote: restart Studio after installation for it to take effect. Continue?",
"confirmInstallOnnxGpu": "The current onnxruntime package will be removed and onnxruntime-gpu (CUDA EP) installed. Package installation takes a few minutes.\n\nNote: restart Studio after installation for it to take effect. Continue?",
"confirmInstallOnnxCpu": "The current onnxruntime package will be removed and onnxruntime (CPU) installed. Package installation takes a few minutes.\n\nNote: restart Studio after installation for it to take effect. Continue?",
Expand Down Expand Up @@ -1601,9 +1601,9 @@
"autoSelect": "Auto-select: {{tag}}",
"noNvidiaDriverCannotCuda": "No NVIDIA driver detected; CUDA build cannot be installed",
"installing": "Installing...",
"reinstallCudaBuild": "⤓ Reinstall CUDA build ({{tag}})",
"reinstallAuto": "↻ Reinstall (auto: {{tag}})",
"advancedManualCuda": "Advanced (manual CUDA version)",
"reinstallCudaBuild": "Reinstall CUDA build ({{tag}})",
"reinstallAuto": "Reinstall ({{tag}})",
"advancedManualCuda": "Pick CUDA version",
"manualCudaHint": "Choose based on your driver / preference; auto is usually fine. The wrong version may fail on import and require choosing again.",
"installCpuBuildHint": "Install CPU build (very slow; diagnostics / no GPU only)",
"installCudaBuildHint": "Install {{tag}} build (PyTorch index: /whl/{{tag}})",
Expand All @@ -1619,23 +1619,23 @@
"noWheelForPython": "No prebuilt wheel was found for {{python}} (the current Python version may not be supported yet). Select another candidate below manually, or paste a URL from GitHub Releases.",
"flashAttnNeedsCudaTorch": "PyTorch is currently a CPU build (torch+cpu) and flash_attn cannot be installed on it. flash_attn is a CUDA C extension — go to the PyTorch section above to reinstall a CUDA build (cu128 / cu130), restart Studio, then come back here.",
"noWheelManual": "No usable wheel; select manually",
"reinstallAutoMatch": "↻ Reinstall (auto match)",
"autoMatchInstall": "⤓ Auto-match install",
"candidateWheels": "Candidate wheels ({{n}} usable)",
"reinstallAutoMatch": "Reinstall",
"autoMatchInstall": "Install",
"candidateWheels": "Builds ({{n}})",
"wheelQueryFailed": "Query failed or no match (check network connection)",
"installWheel": "Install this wheel",
"wheelAbiIncompatible": "Python ABI is incompatible; force install may fail",
"installAction": "⤓ Install",
"forceInstall": "Force install",
"manualUrl": "Paste URL manually:",
"manualUrl": "Wheel URL",
"install": "Install",
"confirmInstallXformers": "xformers will be installed with pip using the PyTorch index URL matching the current torch+cu.\nInstallation can take several to tens of minutes; restart Studio after installation. Continue?",
"xformersSubtitle": "attention acceleration (mutually exclusive with Flash Attention)",
"xformersHelp1": "xformers and Flash Attention are <strong>mutually exclusive</strong>; each training / generation task chooses one <code>attention_backend</code> value (none / xformers / flash_attn).",
"xformersHelp2": "xformers is more broadly compatible (sm_70+), while flash_attn is faster (sm_80+ Ampere and newer).",
"xformersHelp3": "Install failures usually mean upstream PyPI / PyTorch index has no wheel for this torch+cu combination (common for 5090 / new GPUs). The button toast shows the tail of stderr; use it to downgrade torch or wait for upstream coverage.",
"reinstallAutoMatchPlain": "Reinstall (auto match)",
"installAutoMatchPlain": "Install (auto match)",
"reinstallAutoMatchPlain": "Reinstall",
"installAutoMatchPlain": "Install",
"previewThrottle": "Throttle (preview every N steps)",
"previewThrottleDesc": "0 = off; recommended 3-5",
"taeFluxHelp": "The TAEFlux decode model is downloaded in the background when the server starts; no separate UI action is needed.",
Expand Down Expand Up @@ -1848,7 +1848,7 @@
"selectDefaultMainModel": "Use as default main model",
"trainingModelsOneClick": "Training models (one-click download)",
"allowGpuDuringTrainHint": "WD14 tagging with onnxruntime-gpu uses about ~2 GB; only enable if enough VRAM remains outside training, otherwise OOM may occur",
"redownload": "↻ Redownload",
"redownload": "Redownload",
"redownloadTitle": "Already downloaded, click to redownload",
"localBaseModel": "local",
"allowGpuDuringTrain": "Allow GPU tasks while training",
Expand All @@ -1860,7 +1860,7 @@
"purposeInference": "inference",
"selectDefaultTe": "Use as default text encoder",
"teSelected": "Text encoder set: {{name}}",
"trainingRuntime": "Training",
"trainingRuntime": "Training & queue",
"trainingRamGuard": "Memory / VRAM guard",
"trainingRamGuardHelp": "Before loading the base model for training or AI-prior regularization, budget system RAM and free VRAM against the actual weight file sizes and abort with an actionable error if either falls short.",
"trainingRamGuardDefaultHelp": "Off by default: the file-size estimate is conservative and turned out to reject often on machines that were in fact large enough. Turn it on if a training run has ever paged your whole machine to a halt. Block swap's pinned-memory guard is separate and always on — locked memory cannot be paged out, and its way out is a smaller blocks_to_swap.",
Expand Down Expand Up @@ -1895,7 +1895,9 @@
"krea2Main": "Krea 2 main model"
},
"sounds": "Interface sounds",
"soundsDesc": "Soft clicks on toggles and tabs, a chime when something finishes, a low tone on errors."
"soundsDesc": "Soft clicks on toggles and tabs, a chime when something finishes, a low tone on errors.",
"tokenLabel": "Token",
"endpointLabel": "Download endpoint"
},
"monitor": {
"taskLabel": "Task",
Expand Down Expand Up @@ -3839,7 +3841,7 @@
"switched": "Runtime mode set to {{mode}}. Restart the server for the bind address to take effect.",
"local": {
"name": "Local machine",
"summary": "Studio runs on this computer, on your own GPU.",
"summary": "Training runs on this computer.",
"bullets": [
"Binds to 127.0.0.1 — reachable only from this machine",
"Opens your browser automatically on start",
Expand All @@ -3849,7 +3851,7 @@
},
"colab": {
"name": "Colab / cloud notebook",
"summary": "Studio runs in a hosted notebook container (Colab, Kaggle, a rented GPU).",
"summary": "Hosted notebook: Colab, Kaggle, a rented GPU.",
"bullets": [
"Binds to 0.0.0.0 so the notebook port proxy can reach it",
"Never tries to open a browser inside the container",
Expand Down Expand Up @@ -3928,8 +3930,8 @@
"copy": "Copy",
"copied": "Copied",
"copyFailed": "Could not copy the link",
"shareWarning": "Anyone with this link has the same access to this machine as you do — it can browse files and start jobs. Send it only to yourself. If it leaks, press “New access key”.",
"notInstalled": "This needs cloudflared, a single small program from Cloudflare. It is not installed yet.",
"shareWarning": "The link gives full access to this computer. Keep it to yourself; if it leaks, press “New access key”.",
"notInstalled": "Needs the cloudflared utility, which is not installed.",
"install": "Download cloudflared",
"installing": "Downloading…",
"installManually": "There is no prebuilt cloudflared for this system. Install it yourself and it will be picked up automatically.",
Expand All @@ -3939,18 +3941,18 @@
"provider": {
"tailscale": {
"name": "Tailscale Funnel",
"hint": "Free, permanent https://<computer>.<name>.ts.net. Install Tailscale on this computer and sign in once; the phone needs nothing."
"hint": "Permanent address, free. Needs Tailscale on this computer."
},
"ngrok": {
"name": "ngrok",
"hint": "Free account, permanent address with the static domain ngrok gives every account. Needs your authtoken and that domain."
"hint": "Permanent address, free account. Needs an authtoken and a domain."
},
"cloudflare": {
"name": "Cloudflare quick tunnel",
"hint": "No account and no setup, but the address is random and changes every time the link is opened."
"hint": "No account, but the address changes on every start."
}
},
"tailscaleMissing": "Tailscale is not installed on this computer. Install it, sign in, then come back:",
"tailscaleMissing": "Tailscale is not installed. Install it and sign in:",
"tailscaleSteps": "The first start may ask you to allow Funnel for this computer — the error below will give you the link to open. After that the address never changes.",
"ngrokToken": "Authtoken",
"ngrokTokenPlaceholder": "paste your ngrok authtoken",
Expand All @@ -3959,7 +3961,7 @@
"ngrokHint": "Without a domain ngrok still works, but the address changes every start. ngrok may show a one-time “You are about to visit” page in the phone browser — tap Visit.",
"ngrokSaved": "ngrok settings saved",
"whereToGet": "where to get it",
"ngrokNotInstalled": "This needs the ngrok agent, a single small program. It is not installed yet.",
"ngrokNotInstalled": "Needs the ngrok agent, which is not installed.",
"installNgrok": "Download ngrok",
"autostart": "Open the link when the studio starts",
"autostartHintPermanent": "The link comes up by itself after every restart — keep it bookmarked on the phone.",
Expand Down
Loading
Loading