unsloth/studio/backend/utils
Daniel Han 26e246d407
Studio: Developer mode opt-in for experimental CPU video generation (#14247)
Closes #9458.

Video stays hidden on hosts without a supported GPU by default. This
adds an owner-only Developer mode in Settings > General with one switch,
"Allow video generation on CPU (experimental)".
`UNSLOTH_VIDEO_ALLOW_CPU` overrides the saved setting in either
direction.

## What changes

- `video_capability()` admits only the plain CPU-only case (reason
`no_accelerator`) when the opt-in is on, marked
`video_cpu_experimental`. Detection failures, missing or broken PyTorch,
Intel Macs and GPUs PyTorch cannot reach stay blocked.
- The setting lives in the owner's store (`PUT
/api/settings/developer-mode`, owner only, 403 for managed accounts; any
account can read it).
- `/api/health` carries `video_cpu_opt_in` so the sidebar keeps the
Video row enabled once opted in.
- Enabling opens a confirm dialog: "CPU video generation may take hours,
consume large amounts of RAM, and may freeze your system. Continue at
your own risk.", plus host RAM against a 32 GB minimum and a measured
speed estimate. Disabling restores the GPU gate at once.
- The Video page shows a persistent "CPU (experimental)" banner while it
is in effect.

The backend video pipelines already resolve to a float32 CPU target when
no accelerator is visible (the routes on `main` already render on CPU;
only the capability gate and the UI blocked it), so no inference code
changes.

## Testing

- Wan2.1-T2V-1.3B with no GPU visible, through `/video/load` and
`/video/generate` on a real Studio server: 832x480, 5 frames, 3 steps,
generate 228 s on 16 threads, peak RSS 24.5 GiB (this sets the 32 GB
minimum). After the owner PUT, `/api/system` moved from `no_accelerator`
to `video_supported: true, video_cpu_experimental: true`, and the load
reported device `cpu`, float32. The output matches the base tree's frame
for frame (mean 141.29).
- Tiny Wan pipelines render on CPU for `wan2.1-t2v-1.3b`,
`wan2.2-ti2v-5b` and `wan2.2-t2v-a14b`.
- Backend: 34 new tests (capability matrix, every other refusal reason
staying blocked with the opt-in on, env and setting precedence,
owner-only PUT, health wiring); the related suites pass (145 in the
capability, developer-mode and account settings files).
- Frontend: 8 new tests (RAM check, confirm flow, gate wiring); `tsc`
and the strict i18n parity check pass.

Not verified on CPU: LTX-2 / 2.5, HunyuanVideo 1.5 and MiniMax-H3 (no
tiny repos; MiniMax-H3 already runs through the CPU sd.cpp build on such
hosts). A default-length clip (33 frames, 30 steps) was not timed;
"hours" is extrapolated from about 27 s per denoise step at 832x480.

## Screenshots

Studio started with no GPU visible (`/api/system` reports
`no_accelerator` on both sides).

Settings > General: AFTER adds the Developer mode section with the
switch, off by default.

![Settings General before and
after](https://raw.githubusercontent.com/danielhanchen/unsloth-staging-2/pr-media/pr/14247/pr14247_pr14247_pair_00-fa6e90d9e49c.png)

Turning the switch on asks first (the issue's warning, host RAM against
the minimum, and the measured speed):

![Confirm
dialog](https://raw.githubusercontent.com/danielhanchen/unsloth-staging-2/pr-media/pr/14247/pr14247_after_confirm_dialog-7e0880129f76.png)

After confirming, `/api/system` reports `video_supported: true,
video_cpu_experimental: true` without a restart, and the Video page
opens with the CPU (experimental) banner. BEFORE, the same host keeps
the no-accelerator block:

![Video page before and
after](https://raw.githubusercontent.com/danielhanchen/unsloth-staging-2/pr-media/pr/14247/pr14247_pr14247_pair_01-8545de3f46ec.png)
2026-10-19 06:16:30 -07:00
..
datasets Studio: keep a dataset's thinking text when training Qwen models (#14016) 2026-10-18 06:39:01 -07:00
hardware Studio: Developer mode opt-in for experimental CPU video generation (#14247) 2026-10-19 06:16:30 -07:00
inference Studio: give API clients the same Qwen thinking sampling as Chat (#12791) 2026-10-05 22:19:36 -07:00
models fix(studio): load audio GGUFs selected from custom folders (#13897) 2026-10-16 18:50:22 +13:00
paths Keep uv, its cache and the uv-managed Python inside a custom UNSLOTH_STUDIO_HOME (#13373) 2026-10-12 08:50:31 -07:00
prebuilt Studio: default to the Vulkan llama.cpp bundle when a CPU-bound host has a Vulkan GPU (#13599) 2026-10-18 07:36:02 -07:00
security Studio: a managed account's Hub dataset card may not make the server dial an http(s) URL (#14091) 2026-10-18 02:47:27 -07:00
.gitkeep
__init__.py
_studio_release_build.py
account_context.py Studio: per-account isolation for shared installs and the desktop app (#10588) 2026-09-13 03:42:10 -07:00
allocator_conf.py Studio: stop crashing on a lowercase boolean in PYTORCH_ALLOC_CONF (#12976) 2026-10-08 16:27:21 +13:00
api_errors.py Studio: serve the Jev API locally with Laya (#11603) 2026-09-25 10:51:41 -07:00
audio_cpp_freshness.py Studio: install the newest audio.cpp release and offer it in updates (#13589) 2026-10-14 13:20:43 -07:00
audio_cpp_update.py Studio: clearer audio.cpp errors, cleaner Speak/Clone, reproducible takes (#14075) 2026-10-18 17:32:46 -07:00
audio_tokens.py Studio: load the speech model an audio API request asks for (#10217) 2026-09-07 17:18:12 +03:00
auth_safe.py studio: protect authenticated release redirects (#11339) 2026-09-20 03:19:03 -07:00
cache_cleanup.py Reduce comment volume across the installers, CLI, unsloth package and backend utilities (#10504) 2026-09-10 05:57:33 -07:00
cache_inventory.py Studio: add audio.cpp as a native engine for speech, music and dictation (#12342) 2026-10-02 09:32:09 -07:00
chat_preferences_settings.py Studio: persist model disclaimer across instances (#9835) 2026-08-27 00:21:31 -07:00
child_stdio.py Trim comments in studio/backend routes, utils and installers (#10112) 2026-09-02 03:55:07 -07:00
client_ip.py Studio: add a Sandbox settings tab with a Windows MXC opt-in and one-click host preparation (#12215) 2026-10-05 06:53:54 -07:00
code_integrity.py Recognise Windows code integrity blocks, and require the runtime we ship (#10404) 2026-09-08 03:08:33 -07:00
coding_agents.py Studio: list VS Code and Pi as coding agents and reorder the agent picker (#13547) 2026-10-13 03:09:52 -07:00
cpu_threads.py Studio: make OpenBLAS thread limits work on Windows ROCm, and default numpy to up to 8 threads instead of 1 (#13048) 2026-10-09 23:34:10 -07:00
current_date_prompt_settings.py Studio: tell Gemma 4 with Think off and GLM today's date (#14013) 2026-10-18 05:37:58 -07:00
debug_log_export.py Studio: add a Download all logs button to Settings > Logs (#10719) 2026-09-13 09:02:38 -07:00
debug_log_reader.py Trim comments in studio/backend routes, utils and installers (#10112) 2026-09-02 03:55:07 -07:00
debug_log_sources.py Studio: say why a generation or a model load failed, and offer the log (#8804) 2026-09-28 11:55:31 -07:00
desktop_shell_env.py Studio Desktop: stop the launch-time PATH probe from rewriting shell history (#12846) 2026-10-06 06:55:01 -07:00
diffusers_repair.py Studio: FLUX.3 Image Klein (distilled and base), with INT8 / FP8 / GGUF support (#13933) 2026-10-18 09:31:25 -07:00
download_transport_settings.py Studio: let the download transport be picked in Settings > General (#9272) 2026-08-25 03:50:40 -07:00
downsample.py
embedding_model_settings.py Studio: re-embed documents after switching the embedding model (#13702) 2026-10-14 12:23:21 -07:00
first_token_timeout.py Studio: make the first-token waiting limit configurable (#13390) 2026-10-14 14:32:01 +08:00
gguf_archs.py Studio: add audio.cpp as a native engine for speech, music and dictation (#12342) 2026-10-02 09:32:09 -07:00
gpu_memory_events.py Studio: cache and coalesce nvidia-smi reads in the backend (#11995) 2026-09-27 05:29:46 -07:00
happy_eyeballs.py Studio: race address families on sync connects (RFC 8305 Happy Eyeballs) (#10803) 2026-10-05 07:58:14 -07:00
helper_precache_settings.py
hf_cache_settings.py Studio: add a Download to folder for model downloads (#13557) 2026-10-13 05:23:50 -07:00
hf_dataset_options.py
hf_endpoint.py feat(studio): ModelScope as a model source and a custom Hugging Face endpoint (#11761) 2026-09-26 01:18:48 -07:00
hf_probe.py Studio: read public Hub repos without a saved token the Hub rejects (#12158) 2026-09-28 02:28:35 -07:00
hf_token_validation.py feat(studio): ModelScope as a model source and a custom Hugging Face endpoint (#11761) 2026-09-26 01:18:48 -07:00
hf_xet_fallback.py Studio: show a download start the moment it is requested, and serialise the first zoo import with the media import window (#13738) 2026-10-15 08:37:29 -07:00
hidden_models.py Studio: add audio.cpp as a native engine for speech, music and dictation (#12342) 2026-10-02 09:32:09 -07:00
host_memory.py Studio: fit MiniMax-H3 GGUF to a Vulkan host's GTT pool before rendering (#13531) 2026-10-13 07:28:38 -07:00
host_policy.py Studio: leave a bracketed IPv6 host unchanged in dial_host (#12733) 2026-10-08 15:28:37 +08:00
hub_settings.py Studio: gate auth.db and rag.db opens and closes against the SQLite 3.51.0-3.51.1 deadlock (#13307) 2026-10-11 15:56:53 -07:00
igpu_carveout_notice_settings.py Studio: advise raising the iGPU memory allocation when a model overflows it (#10486) 2026-09-08 18:07:18 -07:00
kernel_install.py Studio: restore Qwen causal-conv1d on demand, narrow fatal mamba-ssm, provision SSM kernels in export (#13971) 2026-10-19 04:32:13 -07:00
keyless_api_access.py Studio: Open WebUI llama.cpp residency and explicit load/unload (#10610) (#10693) 2026-10-12 17:22:18 -07:00
lan_access_settings.py Studio: serve HTTPS from your own certificate (--ssl-certfile / --ssl-keyfile) (#13447) 2026-10-12 20:45:01 -07:00
lifespan_shutdown.py
llama_cpp_changelog.py Studio: keep working when GitHub rate limits or is down (#10670) 2026-09-29 10:30:23 -07:00
llama_cpp_freshness.py Reduce comment volume across the installers, CLI, unsloth package and backend utilities (#10504) 2026-09-10 05:57:33 -07:00
llama_cpp_path_settings.py Repair a quarantined llama.cpp runtime at launch instead of failing at model load (#10494) 2026-09-22 00:08:50 -07:00
llama_cpp_source.py GGUF adapter export and llama.cpp installer: use unslothai/llama.cpp releases only, no git (#13056) 2026-10-08 16:11:58 -07:00
llama_cpp_update.py Studio: FLUX.3 prompt upsampling (Enhance prompt) through a llama.cpp sidecar (#14137) 2026-10-18 13:44:32 -07:00
llm_compressor_export.py Studio: consent dialog before FP8/FP4 llm-compressor install (Phase 2) (#9554) 2026-10-03 08:45:08 -07:00
log_redaction.py Studio: read public Hub repos without a saved token the Hub rejects (#12158) 2026-09-28 02:28:35 -07:00
log_retention.py Trim comments in studio/backend routes, utils and installers (#10112) 2026-09-02 03:55:07 -07:00
managed_provider_url_settings.py Studio: let the owner allow managed accounts private provider base URLs (#11436) 2026-09-21 07:00:33 -07:00
mcp_access.py Studio: let coding agents use Unsloth Studio over MCP with API keys (#13118) 2026-10-13 05:06:16 -07:00
media_generation_preset_settings.py
mlx_repair.py Studio: install the S3 SDK on demand (#14157) 2026-10-19 02:42:07 -07:00
model_aliases.py Studio: model aliases for the OpenAI-compatible API (#13361) 2026-10-15 06:18:34 -07:00
model_memory_settings.py fix(studio): avoid resident GGUF mappings for Windows no-reserve loads (#10618) 2026-09-13 17:48:33 -07:00
multi_model_settings.py Studio: add an Always choice to Keep multiple models loaded, track every model on the GPU, and report every model a load unloads (#14088) 2026-10-18 18:16:32 -07:00
mxc_isolation_settings.py Studio: add a Sandbox settings tab with a Windows MXC opt-in and one-click host preparation (#12215) 2026-10-05 06:53:54 -07:00
native_path_leases.py Studio: Library page for files, media and fine-tunes (#11770) 2026-09-25 12:55:03 -07:00
native_tls.py Reduce comment volume across the installers, CLI, unsloth package and backend utilities (#10504) 2026-09-10 05:57:33 -07:00
node_runtime.py Keep the regenerable caches inside the Studio root (#10597) 2026-09-20 06:20:41 -07:00
openai_auto_switch_settings.py Studio: choose Off, When they fit or Always in Model memory, and keep the chat context when an image or video model takes the GPU (#14108) 2026-10-18 18:24:47 -07:00
origin_policy.py Studio: let coding agents use Unsloth Studio over MCP with API keys (#13118) 2026-10-13 05:06:16 -07:00
parent_watchdog.py Trim comments in studio/backend routes, utils and installers (#10112) 2026-09-02 03:55:07 -07:00
personalization_settings.py Studio: rework Appearance settings and add flavor color themes (#12030) 2026-09-26 23:47:27 -07:00
preview_rate_limit.py
preview_sharing_settings.py Studio: per-account isolation for shared installs and the desktop app (#10588) 2026-09-13 03:42:10 -07:00
preview_token.py Studio: per-account isolation for shared installs and the desktop app (#10588) 2026-09-13 03:42:10 -07:00
proactor_self_pipe.py Studio: stop the Windows event loop spinning when its self-pipe is closed (#12665) 2026-10-04 02:48:24 -07:00
process_lifetime.py Studio: stop llama-server crashing on macOS on Ctrl+C (#13782) 2026-10-15 05:48:42 -07:00
reasoning_budget.py add reasoning budget controls for llama.cpp models 2026-09-16 11:32:20 +12:00
region.py feat(studio): default the model source to ModelScope where Hugging Face is restricted (#12197) 2026-09-29 10:52:58 +13:00
release_notes.py Studio: keep working when GitHub rate limits or is down (#10670) 2026-09-29 10:30:23 -07:00
remote_access_settings.py Studio: serve HTTPS from your own certificate (--ssl-certfile / --ssl-keyfile) (#13447) 2026-10-12 20:45:01 -07:00
s3_runtime.py Studio: install the S3 SDK on demand (#14157) 2026-10-19 02:42:07 -07:00
sandbox_memory_limit.py Studio: add a sandbox memory limit setting to Settings > Sandbox (#13194) 2026-10-09 20:31:16 -07:00
sentencepiece_guard.py Never import sentencepiece on Windows (#10593) 2026-09-09 02:50:41 -07:00
ssm_runtime.py Studio: restore Qwen causal-conv1d on demand, narrow fatal mamba-ssm, provision SSM kernels in export (#13971) 2026-10-19 04:32:13 -07:00
stall_watchdog.py studio: dump the backend's own thread stacks while a stall is in progress (#9715) 2026-10-05 05:24:21 -07:00
studio_tls.py Studio: serve HTTPS from your own certificate (--ssl-certfile / --ssl-keyfile) (#13447) 2026-10-12 20:45:01 -07:00
studio_version.py
subprocess_compat.py
system_disk.py Studio: show the models drive in the Live Monitor when it is not the system disk (#12724) 2026-10-05 02:37:13 -07:00
systemone_settings.py MLX: Clef Omni in Unsloth Studio, with audio in the Decision API and decision training (#13538) 2026-10-14 09:10:59 -07:00
tegra.py Studio (Jetson): keep JetPack's CUDA ahead of pip CUDA in llama-server and backend loader paths (#13191) 2026-10-10 05:14:41 -07:00
third_party_source.py Pin the DeepSeek OCR module fetch and import it from that fetch (#12454) 2026-10-01 12:49:03 -07:00
tool_result_limit.py Studio: add a tool output length setting to Settings > Chat (#13228) 2026-10-10 21:34:06 -07:00
torch_device_probe.py Reduce comment volume across the installers, CLI, unsloth package and backend utilities (#10504) 2026-09-10 05:57:33 -07:00
torch_warmup.py Studio: show a download start the moment it is requested, and serialise the first zoo import with the media import window (#13738) 2026-10-15 08:37:29 -07:00
training_runs.py Keep the transcribed repo id rule ASCII, as the Hub's is (#11204) 2026-09-17 08:19:16 -07:00
transformers_dtype.py Trim comments in studio/backend routes, utils and installers (#10112) 2026-09-02 03:55:07 -07:00
transformers_latest.py Studio: train and chat with every text-diffusion LM family (#13342) 2026-10-13 11:14:43 -07:00
transformers_version.py Studio: train and chat with every text-diffusion LM family (#13342) 2026-10-13 11:14:43 -07:00
update_status.py Studio: make UNSLOTH_DISABLE_UPDATE_CHECK also stop the llama.cpp and whisper.cpp checks (#11155) 2026-09-17 17:24:45 +08:00
upload_limits.py Studio: upload files straight into a chat's folder (#13366) 2026-10-11 23:50:53 -07:00
utils.py Studio: restore Qwen causal-conv1d on demand, narrow fatal mamba-ssm, provision SSM kernels in export (#13971) 2026-10-19 04:32:13 -07:00
uv_path_safety.py Trim comments in studio/backend routes, utils and installers (#10112) 2026-09-02 03:55:07 -07:00
uvicorn_h11_shutdown.py Reduce comment volume across the installers, CLI, unsloth package and backend utilities (#10504) 2026-09-10 05:57:33 -07:00
video_cpu_settings.py Studio: Developer mode opt-in for experimental CPU video generation (#14247) 2026-10-19 06:16:30 -07:00
vram_budget_settings.py Studio: per-account isolation for shared installs and the desktop app (#10588) 2026-09-13 03:42:10 -07:00
wheel_utils.py Studio: restore Qwen causal-conv1d on demand, narrow fatal mamba-ssm, provision SSM kernels in export (#13971) 2026-10-19 04:32:13 -07:00
whisper_cpp_freshness.py Reduce comment volume across the installers, CLI, unsloth package and backend utilities (#10504) 2026-09-10 05:57:33 -07:00
whisper_cpp_update.py Studio: make UNSLOTH_DISABLE_UPDATE_CHECK also stop the llama.cpp and whisper.cpp checks (#11155) 2026-09-17 17:24:45 +08:00
worker_stderr.py Studio: keep the exit code and the crash reason when training dies (#11574) 2026-10-05 06:00:23 -07:00
xet_notice_settings.py Use Unsloth for bare Studio product references (#9732) 2026-08-26 01:55:49 -07:00