Skip to content

Unsloth start improvements: download progress, server reuse, and safe model switching - #7313

Merged
danielhanchen merged 17 commits into
unslothai:mainfrom
oobabooga:pr/daniel-unsloth-start-audit
Jul 22, 2026
Merged

Unsloth start improvements: download progress, server reuse, and safe model switching#7313
danielhanchen merged 17 commits into
unslothai:mainfrom
oobabooga:pr/daniel-unsloth-start-audit

Conversation

@oobabooga

@oobabooga oobabooga commented Jul 21, 2026

Copy link
Copy Markdown
Member

Summary

Show real download progress and clearer startup output

unsloth start now shows the download percentage, size, speed, and estimated time remaining using Studio's existing download state. Interactive terminals refresh one line, while redirected output prints occasional milestones. Cached models do not show a download bar. Startup output is shorter, and readiness always begins on a new line:

Starting Unsloth server
Model: unsloth/Qwen3-0.6B-GGUF:Q4_K_M
Downloading model [========================] 100% ...
Unsloth ready at http://127.0.0.1:8888 · model unsloth/Qwen3-0.6B-GGUF

Keep the server available after the agent exits

When unsloth start launches a local server, it now remains available after the agent exits so another terminal can reuse it. The CLI prints:

Unsloth Studio is still running at http://127.0.0.1:8888.
Stop it with: unsloth studio stop

The same instructions are shown for an existing local server. If the agent cannot be launched, an automatically started server is still cleaned up.

Reuse the same model and switch different models safely mirroring llama-swap

A second session requesting the same model and GGUF variant now prints:

Reusing loaded model: unsloth/Qwen3-0.6B-GGUF:Q4_K_M

When only the repository ID is given, the quant already loaded is reused. Requesting a specific different quant triggers a switch.

The server still has one model slot, so a different model does not start a second server. The CLI names the model being replaced and warns that every attached session is affected.

Switching now mirrors llama-swap: the new request waits for the current response to finish, then the old model is unloaded and the requested model is loaded. New responses wait until the switch completes, preventing an unload during generation. This also covers switches between GGUF and non-GGUF models. A deliberate manual unload remains immediate.

Keep four parallel slots as the default

--parallel 4 was already the default for unsloth run. A regression test locks that value, and a live launch confirmed it in the final llama-server command.

Checked without code changes

Claude and Codex startup

Automatic startup already works for Claude and Codex, so no separate hook is needed. Claude Code cannot use local Unsloth for one native subagent while the main agent remains on cloud Claude, and an MCP wrapper would not provide that native behavior.

XET and HTTP downloads

XET already falls back to HTTP on an error or full stall. Slow downloads that are still progressing are left alone because switching midway can discard useful work. HTTP can be forced with HF_HUB_DISABLE_XET=1.

Compaction, context size, and prompt caching

Claude receives the loaded model's context size through CLAUDE_CODE_AUTO_COMPACT_WINDOW and a 90% threshold through CLAUDE_AUTOCOMPACT_PCT_OVERRIDE. Claude Code calls /v1/messages/count_tokens when deciding when to compact; the endpoint formats messages the same way generation does and uses the loaded GGUF model's tokenizer.

OpenCode and Hermes also receive explicit context and compaction settings. OpenClaw and Pi receive the correct context size but use their own compaction defaults. llama-server reuses unchanged prompt prefixes for GGUF models; equivalent non-GGUF caching requires a separate inference change.

Nudging small models

The prompt Create an Unsloth finetuning run was tested with unsloth/Qwen3.6-27B-MTP-GGUF:BF16 and no nudge. The Claude Code request contained about 21,590 input tokens, so it could not fit in an 8K context. At 32K, the model used tools, inspected the repository and environment, wrote an 11 KB finetune.py, and continued validating it.

Limited context and small-model capability are therefore more likely explanations for models getting stuck than a missing instruction. A global nudge would also alter models that already use tools correctly, so none is added.

Validation

  • CLI tests: 302 passed
  • Auto-switch and lifecycle tests: 177 passed
  • Load, GPU selection, and unload tests: 107 passed, plus 4 subtests
  • Ruff, Python compilation, and git diff --check: passed
  • Live Q4 and Q5 downloads, same-model reuse, queued model switching, stop instructions, and --parallel 4: passed

@oobabooga
oobabooga requested a review from danielhanchen as a code owner July 21, 2026 20:33
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e43304a1b9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread unsloth_cli/commands/studio.py Outdated
@oobabooga

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 36f896a528

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread studio/backend/routes/inference.py
@oobabooga
oobabooga marked this pull request as draft July 21, 2026 21:48
@oobabooga
oobabooga marked this pull request as ready for review July 21, 2026 22:28
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@oobabooga

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: edea3ef5de

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread unsloth_cli/commands/start.py Outdated
@oobabooga

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

Reviewed commit: a598409f88

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

…r PR unslothai#7313

- Redact minted sk-unsloth keys from the startup-failure log tail: the early
  key marker lands in the server log before the model load finishes, so a
  load-phase crash printed a live key to the terminal
- Deregister a finished switch waiter before releasing the swap gate so a
  swap on another event loop cannot count it as still queued and unload the
  model the finished request is about to generate against
- Warn on same-repo quant switches: an explicit variant replaces the resident
  weights for every attached session, but the repo ids match so no switch
  warning was printed
- Note the agent exit code when it is nonzero so the server keep-alive
  message does not read as a successful session
- Use taskkill /T in unsloth studio stop so llama-server children stop too
@danielhanchen

Copy link
Copy Markdown
Member

Pushed db37a7c with fixes from a review pass:

  • _start_studio_server now redacts minted sk-unsloth- keys from the failure log tail. The early key marker is written to the server log before the model load finishes, so a crash during download or load printed a live key to the terminal or CI output. The raw tail is still used internally for marker parsing.
  • The completed switch waiter in _maybe_auto_switch_model is now deregistered before the process-wide swap gate is released. A swap on another event loop could acquire the gate in that window, count the finished request as still queued, pass the drain early, and unload the model that request was about to generate against.
  • Requesting a different quant of the resident repo now prints the switch warning. The repo ids match in that case, so the "unloads the current model for every attached session" notice was silently skipped; the CLI asks /api/inference/status for the resident variant when an explicit variant is given.
  • A nonzero agent exit now prints "The agent exited with code N." before the keep-alive message, so a failed session does not read as a successful one. The server intentionally stays up either way so a retry does not pay the model load again.
  • unsloth studio stop on Windows now uses taskkill /T /F, matching the start-side shutdown; without /T the llama-server child kept the GPU and port.

One design note, no change made: _wait_for_model_switch_idle has no deadline while the lifecycle gate is held, so a stream that never ends blocks a queued switch and all later inference. Client disconnects unwind it and this matches the llama-swap semantics the PR describes, so I left it as is; a bounded wait with a 409 fallback is an easy follow-up if it ever bites.

Validation: 532 CLI tests and 178 auto-switch tests pass with 5 new regression tests; ruff, compileall, and git diff --check are clean. The two pre-existing test failures in this environment reproduce identically on main.

@danielhanchen

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

Reviewed commit: f80e1d840b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@danielhanchen

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

Reviewed commit: 8da5a3abb9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@danielhanchen
danielhanchen merged commit 8b3c372 into unslothai:main Jul 22, 2026
48 of 49 checks passed
danielhanchen added a commit that referenced this pull request Jul 22, 2026
…nd Pi (#7326)

Bring the local-subagent support onto main. The original change (#7316) merged
into the stacked pr/daniel-unsloth-start-audit branch rather than main, and #7313
reached main via squash, so these files never landed on main.

Adds --as-subagent for claude, codex, opencode and pi: the parent agent keeps its
own cloud model while a locally served GGUF is registered as a delegated subagent,
using ephemeral per-session config that never touches the user's real agent config.
Imagineer99 pushed a commit to Imagineer99/unsloth that referenced this pull request Jul 22, 2026
… model switching (unslothai#7313)

* Improve unsloth start runtime lifecycle

* Remove speculative Gemma prompt override

* Polish model download progress output

* Refine unsloth start status output

* Clarify unsloth readiness banner

* Clarify model reuse and switching output

* Queue model switches behind active inference

* Tighten unsloth start model switching

* Reduce model switch bookkeeping

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Fix Studio re-exec compatibility

* Recheck sidecar reservation after inference drain

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Pass start marker through child environment

* Fix key redaction, switch-waiter ordering, and stop/messaging gaps for PR unslothai#7313

- Redact minted sk-unsloth keys from the startup-failure log tail: the early
  key marker lands in the server log before the model load finishes, so a
  load-phase crash printed a live key to the terminal
- Deregister a finished switch waiter before releasing the swap gate so a
  swap on another event loop cannot count it as still queued and unload the
  model the finished request is about to generate against
- Warn on same-repo quant switches: an explicit variant replaces the resident
  weights for every attached session, but the repo ids match so no switch
  warning was printed
- Note the agent exit code when it is nonzero so the server keep-alive
  message does not read as a successful session
- Use taskkill /T in unsloth studio stop so llama-server children stop too

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Tighten comments in start, studio, and inference changes

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Daniel Han <danielhanchen@gmail.com>
Imagineer99 pushed a commit to Imagineer99/unsloth that referenced this pull request Jul 22, 2026
…nd Pi (unslothai#7326)

Bring the local-subagent support onto main. The original change (unslothai#7316) merged
into the stacked pr/daniel-unsloth-start-audit branch rather than main, and unslothai#7313
reached main via squash, so these files never landed on main.

Adds --as-subagent for claude, codex, opencode and pi: the parent agent keeps its
own cloud model while a locally served GGUF is registered as a delegated subagent,
using ephemeral per-session config that never touches the user's real agent config.
danielhanchen added a commit that referenced this pull request Jul 27, 2026
* Add Agents settings tab for unsloth start

Adds a Settings > Agents tab documenting the `unsloth start` command:
quickstart, supported agents with click-to-copy commands, model
selection, common options, remote Studio setup, argument pass-through,
and a dry-run preview. Agent CLIs found on PATH are badged as installed.

Also removes the "New" badge from the System and Chat tabs.

* Use official brand logos for agents, invert Ollama and OpenRouter in dark mode

Claude Code and OpenAI Codex now use the Anthropic and OpenAI logos from
the provider-logos registry; agents without an official asset keep the
monogram tile. Also inverts the Ollama and OpenRouter logos in dark mode
so their monochrome marks stay visible.

* Title Agents tab "Agents (unsloth start)" and move it below Connections

The in-tab header now reads "Agents (unsloth start)" while the sidebar
label stays "Agents". Reorders the tab to sit below Connections.

* Address review: guard PATH detection, fix copy timeout, OS-aware remote snippet

- Only probe agent PATH in the desktop app on a loopback backend, so
  Installed badges are not driven by a remote server's environment.
- Show the "none found" note only when detection actually ran and
  returned empty, not when the call failed.
- Share one copy hook that resets its timeout on rapid clicks and clears
  it on unmount.
- Render the Remote Studio snippet with PowerShell syntax on Windows.
- Note that --no-launch can still load a model when --model is set.
- Drop unused quickstart translation keys.

* Add interactive Agents command builder

* Add local subagent command guidance

* Add official coding agent icons

* Use client OS for remote commands, fix copy a11y and model wording (#7303)

- Pick the remote snippet shell from the client platform, not the server deviceType
- Single-line the model examples so they paste in POSIX, PowerShell and cmd
- Split the pass-through block into independent one-command copies
- Derive detection visibility instead of clearing state in the effect
- Announce copy success to assistive tech
- Correct the quickstart/model copy: bare start uses the loaded model

* Shell-quote the model, forward the HF token, and fix the quant placeholder

- Quote the --model value in the generated and subagent commands so a local
  path with spaces or metacharacters stays a single argument (client-OS aware)
- Pass the saved Hugging Face token to listGgufVariants so gated repos resolve
- Show 'No separate quantization' instead of a stuck 'Loading quantizations...'
  when a model has no variants; clear the failure once a later request succeeds

* Fix Agents command discovery and routing

* Unsloth start improvements: download progress, server reuse, and safe model switching (#7313)

* Improve unsloth start runtime lifecycle

* Remove speculative Gemma prompt override

* Polish model download progress output

* Refine unsloth start status output

* Clarify unsloth readiness banner

* Clarify model reuse and switching output

* Queue model switches behind active inference

* Tighten unsloth start model switching

* Reduce model switch bookkeeping

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Fix Studio re-exec compatibility

* Recheck sidecar reservation after inference drain

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Pass start marker through child environment

* Fix key redaction, switch-waiter ordering, and stop/messaging gaps for PR #7313

- Redact minted sk-unsloth keys from the startup-failure log tail: the early
  key marker lands in the server log before the model load finishes, so a
  load-phase crash printed a live key to the terminal
- Deregister a finished switch waiter before releasing the swap gate so a
  swap on another event loop cannot count it as still queued and unload the
  model the finished request is about to generate against
- Warn on same-repo quant switches: an explicit variant replaces the resident
  weights for every attached session, but the repo ids match so no switch
  warning was printed
- Note the agent exit code when it is nonzero so the server keep-alive
  message does not read as a successful session
- Use taskkill /T in unsloth studio stop so llama-server children stop too

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Tighten comments in start, studio, and inference changes

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Daniel Han <danielhanchen@gmail.com>

* Unsloth start: add local subagents for Claude Code, Codex, OpenCode and Pi (#7326)

Bring the local-subagent support onto main. The original change (#7316) merged
into the stacked pr/daniel-unsloth-start-audit branch rather than main, and #7313
reached main via squash, so these files never landed on main.

Adds --as-subagent for claude, codex, opencode and pi: the parent agent keeps its
own cloud model while a locally served GGUF is registered as a delegated subagent,
using ephemeral per-session config that never touches the user's real agent config.

* Fix Agents builder defaults and flag validation

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Fix Agents variant and provider fallbacks

* Fix local model and Pi subagent edge cases

* Agents tab: flag the Codex row when the loaded model is not GGUF

* Agents tab: target the active Studio server, wrap narrow rows, index the tab's search terms

* Agents tab: build copied commands from the browser-reachable Studio and show the key placeholder

* Preserve cache load ids and path variants in built commands for PR #7312

A GGUF outside the active Hugging Face cache only loads by its snapshot
path, so keep that load_id for --model while still listing the row by repo
id. Path based models carry their quant in --gguf-variant rather than a
":variant" suffix, and the active selection now keeps the variant inference
status reports for them.

* Agents tab: index the intro for agent-name searches and keep long commands inside the panel

* List GGUF variants from the cache the command loads from for PR #7312

A snapshot outside the active Hugging Face cache was offering the remote
variant list, so a quant absent from that snapshot could be selected and
the generated command would fail to load it.

* Agents tab: omit --api-key so the CLI can replay a saved key for the base

* Agents tab: label the indexed heading rows and fall back to the active desktop API base

* Agents tab: name every supported agent in the indexed intro for PR #7303

* Send the cached GGUF load path and fix the agents tab search targets for PR #7312

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Tighten the agents tab comments for PR #7303

* Build the agents tab example commands from the active Studio base for PR #7303

* Keep the resident model on its active cache load for PR #7312

* Tighten the agents tab and cached GGUF comments for PR #7312

* Take the agent command shell from the Studio host for PR #7303

* Stop emitting snapshot paths as --model and keep unsloth start searchable for PR #7312

* Pick the command shell from where the CLI runs for PR #7303

* Match a path load by its advertised id and follow the resident model for PR #7312

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Keep an explicit quantization and retire superseded native-grant labels for PR #7312

* Scope the remembered quant, stop following unloaded models and keep local GGUF paths for PR #7312

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Stop shadowing the path classifier, match snapshot ordering and sequence status polls for PR #7312

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Release stale native-grant picks, keep local GGUF identities and index snapshot aliases for PR #7312

* Index inactive-cache snapshots, widen local GGUF detection and clear retired quants for PR #7312

* Classify cached repos by snapshot, merge repo ids case-insensitively and keep loose GGUFs variantless for PR #7312

* Fix snapshot alias, partial split and mmproj-only handling for PR #7312

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Trust scanned model_format and drop incomplete snapshot ids for PR #7312

* Exclude mmproj and partial downloads, keep path case and drop duplicate scan for PR #7312

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Restrict revision aliases and require complete snapshot variants for PR #7312

* Index revisions individually and hide partial variants for PR #7312

---------

Co-authored-by: shimmyshimmer <107991372+shimmyshimmer@users.noreply.github.com>
Co-authored-by: Daniel Han <danielhanchen@gmail.com>
Co-authored-by: oobabooga <oobabooga4@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants