Unsloth is a local UI for training and running Gemma 4, Qwen3.6, DeepSeek, Kimi, GLM and other models. https://unsloth.ai/docs
  • Python 71.5%
  • TypeScript 22.7%
  • Shell 1.9%
  • PowerShell 1.6%
  • Rust 1.5%
  • Other 0.7%
Find a file
oobabooga aefeb5821d
Studio: recover tool-enabled GGUF chats after llama-server exits (#7424)
* Fix GGUF tool chat server recovery

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

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

* Cover MTP precedence and loosen the replay assertion for PR #7424

Add a regression test for the MTP branch of the tool-loop respawn retry: the
file-wide _make_backend stub forces _maybe_recover_from_mtp_crash to False, so
nothing exercised the case where an MTP crash reload is already claimed and an
ordinary same-config respawn must not run on top of it. Cover both the next
tool-loop request and the final synthesis pass.

Replace the whole-payload equality assertions with a field-wise check. Comparing
the full dict pins max_tokens to the value derived from the dead server's
effective context, so a later fix that rebuilds server-derived defaults after a
respawn would read as a test failure rather than an improvement.

Document that the one-retry budget is per model request, not per chat turn.

* Recover from prefill-time deaths and stop respawn racing the MTP reload

Two gaps in the tool-loop respawn retry, both reproduced before fixing.

A child that exits during prefill has already accepted the socket, so httpx
raises ReadError, WriteError or RemoteProtocolError rather than ConnectError.
Those all arrive before the response opens, which is exactly the window where a
replay is safe, but the helper only caught ConnectError and gave up. Widen the
catch to NetworkError plus RemoteProtocolError. Timeouts stay excluded on
purpose: they mean the server is slow, not dead, and retrying one would spend
the 20 minute first-token budget twice. Windows resets connections where Linux
refuses them, so this also covers the common Windows presentation.

_maybe_recover_from_mtp_crash returns False both when the crash is not an MTP
crash and when an MTP-free reload is already in flight. Callers read that as
permission to respawn, so _respawn_if_dead replayed the crashing MTP kwargs and,
by replacing the process, made the in-flight reload abort on its own newer-load
check. Skip the respawn while that reload owns the corpse. The guard lives in
_respawn_if_dead so the plain chat path gets it too.

Regression tests for both, including a guard against retrying prefill timeouts.

* Release the MTP single-flight claim when the reload never starts

_mtp_runtime_fallback_in_progress is claimed before the reload thread exists, and
only that thread's finally clears it. Two statements ran in between with no unwind
path: re-reading _last_load_kwargs, which an unload can null underneath us, and
Thread.start(), which raises under the thread exhaustion that is exactly the
pressure killing llama-server in the first place. Nothing else ever resets the
flag, so a failure there latched it for the life of the process.

That was survivable before, since respawn ignored the flag. It is not now: the
guard added in db78184be keys off the flag alone, so a latch would silently
disable auto-respawn for every later model, including plain non-MTP ones. Read
the kwargs and process once before claiming, and release the claim if the thread
cannot start.

Restore the whole-payload equality assertions. Comparing field-wise was meant to
leave room for rebuilding server-derived defaults on replay, but the payload is
built once before the retry and re-sent unchanged, so the looser check only
dropped seven real keys and added a vacuous seed comparison.

Also correct the docstring: llama-server flushes its 200 at slot start, so a
death during decode arrives with the response already open. The pre-header window
this covers is an upload still in flight or a request waiting behind busy slots.

* Confirm the child exited before spending the retry

A closing llama-server can beat its own exit status: the socket error arrives while
poll() still reports the process running. _respawn_if_dead then took the alive
branch, handed back the stale _healthy, and the caller read that as a successful
respawn and spent its single retry on the same corpse. When that retry failed,
attempt was no longer 0, so no respawn ever happened and the turn died, with a log
line claiming a respawn that had not occurred. The window matters most for the
pre-header ReadError and RemoteProtocolError shutdowns the retry now covers.

Wait a bounded second for the exit status before calling the child alive. The same
race is already conceded in _maybe_recover_from_mtp_crash, whose recovery thread
polls for 5s because the error can arrive a beat early; 1s here because this runs
on the request path, and a genuinely live server, including one a concurrent caller
has just respawned, still returns promptly.

* Tighten the recovery comments

* Harden the respawn path around concurrent unloads and replacements

Two problems with the reap grace loop, both found by review.

Skip the grace when the server was already replaced. A caller queued on
_respawn_lock behind someone else's respawn woke holding the healthy replacement,
could not tell it from the child its own request had used, and waited out the full
grace. That sleep is under the lock, so the waits serialised: four concurrent
generations cost roughly three grace periods before any retry began. Capture the
process before taking the lock and return early once it has been swapped.

Do not respawn a server that is being torn down on purpose. unload_model() sets
_cancel_event and only clears _last_load_kwargs after the kill, so a request losing
its connection mid-unload could watch that deliberate exit through the grace loop,
read the stale kwargs and load the model straight back; a model switch landing
during the wait was reverted the same way. Re-check the cancel flag and the process
identity under _serial_load_lock before capturing the replay kwargs, matching what
the MTP-crash reload already does.

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

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

* Tighten the respawn comments

* Do not charge the reap grace to a server that is still serving

The grace loop added for the not-yet-reaped race waits on poll(), which for a
live child never returns, so every transient transport error paid the full
_RESPAWN_REAP_GRACE_S. That sleep is held under _respawn_lock, so the cost
serialised: measured 1002 ms for one caller and 8.02 s for eight concurrent ones,
against 0 ms on main. A working install pays this, not a broken one.

A llama-server's listening socket dies with the process, so a loopback connect
separates the two cases in microseconds. Probe it first and return immediately
when the port still accepts; fall through to the grace only when the port is
gone, which is the case the grace exists for. Back to 0.7 ms for one caller and
0.00 s for eight.

Cross-checked on real hardware over Qwen3.5-2B, Llama-3.2-1B, Gemma-3-4B with
mmproj and Qwen3-30B-A3B: decode throughput within noise of main (-0.06%, -3.71%,
+2.57%, +0.29%, against a 54-232% spread between rounds of a single run), output
byte-identical on every round, tool-path recovery restored on the three families
whose model calls the tool, and plain-chat recovery still working on all four.

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

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

* Make the respawn lose to a deliberate unload in every window

Two follow-ups on the respawn path, both reproduced first.

Check _cancel_event before the socket fast path. unload_model sets the flag before
it kills, so the child is still accepting when the probe runs; returning the stale
_healthy there aims the retry at a server that is deliberately going away.

Close the unload TOCTOU. The old cancel check sat under _serial_load_lock, which
unload_model never takes, so an unload could land entirely between that check and
load_model and the captured kwargs would restart a model the user had stopped.
Snapshot the kwargs, the flag and a new _unload_epoch together under _lock, the
lock unload does hold, so a teardown is either wholly before the snapshot or
wholly after it. load_model clears _cancel_event on the way in, so the epoch is
the only evidence that survives; when it moves during the reload the replacement
is unloaded again rather than left running.

_lock stays uncontended across load_model, which would deadlock a plain Lock and
block /status for the length of a load. Error-path latency is unchanged: 0.6 ms
for a live server and 0.00 s for eight concurrent callers.

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: danielhanchen <unslothai@gmail.com>
Co-authored-by: danielhanchen <danielhanchen@gmail.com>
2026-07-26 04:53:45 -07:00
.github AMD: CI coverage for recent fixes, plus three wrong gfx ids (#7431) 2026-07-25 18:58:02 -05:00
images images: use narrower Discord button and drop duplicate (#5552) 2026-05-18 05:00:59 -07:00
scripts fix: pin torchcodec for torch 2.10 and warn on ABI mismatch (#7299) 2026-07-23 19:12:52 -07:00
studio Studio: recover tool-enabled GGUF chats after llama-server exits (#7424) 2026-07-26 04:53:45 -07:00
tests Fix the CPU-only ROCm routing errors and two font-scale UI flakes (#7469) 2026-07-26 04:48:49 -07:00
unsloth studio: shard export checkpoint loads across all visible GPUs (#7215) 2026-07-26 04:16:36 -07:00
unsloth_cli fix(studio): support hostname-based enterprise proxies (#7416) 2026-07-26 02:53:00 +01:00
.gitattributes Replace standalone Studio wording with Unsloth (#7221) 2026-07-19 00:47:04 -07:00
.gitignore studio: tool calling for DeepSeek (R1/V3/V3.1), GLM 4.x, Kimi K2 on safetensors + MLX (#5624) 2026-07-06 15:40:46 -07:00
.pre-commit-ci.yaml pre-commit CI config (#3565) 2025-11-07 14:44:18 -08:00
.pre-commit-config.yaml [pre-commit.ci] pre-commit autoupdate (#6587) 2026-06-23 03:01:11 -07:00
build.sh Replace standalone Studio wording with Unsloth (#7221) 2026-07-19 00:47:04 -07:00
cli.py Rename cli/ to unsloth_cli/ to fix namespace collision with stringzilla (#4393) 2026-03-17 20:40:21 -07:00
CODE_OF_CONDUCT.md Update CODE_OF_CONDUCT.md 2025-10-25 19:31:05 -07:00
CONTRIBUTING.md docs: repository cleanup (#5617) 2026-06-12 11:07:04 +01:00
COPYING Rename cli/ to unsloth_cli/ to fix namespace collision with stringzilla (#4393) 2026-03-17 20:40:21 -07:00
install.ps1 AMD: CI coverage for recent fixes, plus three wrong gfx ids (#7431) 2026-07-25 18:58:02 -05:00
install.sh install.sh: do not assume sudo consent when there is no terminal (#7435) 2026-07-26 04:27:15 -07:00
LICENSE Rename cli/ to unsloth_cli/ to fix namespace collision with stringzilla (#4393) 2026-03-17 20:40:21 -07:00
pyproject.toml fix: pin torchcodec for torch 2.10 and warn on ABI mismatch (#7299) 2026-07-23 19:12:52 -07:00
README.md Unsloth start: add local subagents for Claude Code, Codex, OpenCode and Pi (#7326) 2026-07-22 04:34:58 -07:00
unsloth-cli.py feat(studio): add DoRA support to studio (#7315) 2026-07-24 03:24:16 -07:00

Unsloth logo

Unsloth Studio lets you run and train models locally.

FeaturesNewsQuickstartNotebooksDocumentation


unsloth studio ui homepage

Get started

macOS, Linux, WSL:

curl -fsSL https://unsloth.ai/install.sh | sh

Windows:

irm https://unsloth.ai/install.ps1 | iex

Community:

Features

Unsloth Studio (Beta) lets you run and train text, audio, embedding, vision models on Windows, Linux and macOS.

Inference

  • Search + download + run models including GGUF, LoRA adapters, safetensors
  • Export models: Save or export models to GGUF, 16-bit safetensors and other formats.
  • Tool calling: Support for self-healing tool calling and web search
  • Code execution: lets LLMs test code in Claude artifacts and sandbox environments
  • API inference endpoint: Deploy and run local LLMs in Claude Code, Codex tools with Unsloth
  • Auto set inference settings and customize chat templates.
  • We work directly with teams behind gpt-oss, Qwen3, Llama 4, Mistral, Gemma 1-3, and Phi-4, where weve fixed bugs that improve model accuracy.
  • Chat with images, audio, PDFs, code, DOCX and more. Connect API providers (OpenAI, Anthropic) or servers (vLLM, Ollama).
  • Compare any two models side by side with the same prompt.
  • OpenAI/Anthropic-compatible APIs: Serve local models through /v1/chat/completions, /v1/responses and /v1/messages.
  • Connect local models to agents: Use unsloth start with Claude Code, Codex, Hermes and more.
  • Web/PDF search can read PDF papers, manuals and other PDF results.
  • GGUF hardware controls: Choose GPUs/layers, offload MoE experts, use multi-GPU or Tensor Parallelism.
  • The opt-in MCP control endpoint lets AI clients manage models, training, recipes and exports.

Training

  • Train and RL 500+ models up to 2x faster with 70% less VRAM; MoE up to 12x faster.
  • Train and run RL on AMD GPUs across Windows, WSL and Linux.
  • Data Recipes: Auto-create datasets from PDF, CSV, DOCX etc. Edit data in a visual-node workflow.
  • Reinforcement Learning uses 80% less VRAM for GRPO, FP8 and vision RL, with 7x longer contexts.
  • Long-context training: 3x faster, 30% less VRAM and 500K+ context.
  • Supports LoRA/QLoRA, full fine-tuning, RL, pretraining, 4-bit, 16-bit and FP8.
  • Custom Triton and mathematical kernels built with PyTorch and Hugging Face.
  • Observability: Monitor training live, track loss and GPU usage and customize graphs.
  • Multi-GPU training is supported, with major improvements coming soon.

🚀 Unsloth Start

Unsloth Start connects Claude Code, Codex and other agents to local models with one command.

Start Unsloth, load a model, open your project folder, then run:

unsloth start claude

Replace claude with any supported agent:

Agent Command
Claude Code unsloth start claude
OpenAI Codex unsloth start codex
Hermes Agent unsloth start hermes
OpenClaw unsloth start openclaw
OpenCode unsloth start opencode
Pi Coding Agent unsloth start pi

Claude Code, Codex, OpenCode and Pi can keep their current model and use Unsloth as a local subagent:

unsloth start claude --as-subagent --model unsloth/model-GGUF:quant

📥 Install

Unsloth can be used in two ways: through Unsloth Studio, the web UI, or through Unsloth Core, the code-based version. Each has different requirements.

Unsloth Studio (web UI)

Unsloth Studio (Beta) works on Windows, Linux, WSL and macOS.

  • CPU: Supported for Chat and Data Recipes currently
  • NVIDIA: Training works on RTX 30/40/50, Blackwell, DGX Spark, Station and more
  • macOS: Training, MLX and GGUF inference are ALL supported.
  • AMD: Training, RL, chat and deployment work on Windows, WSL and Linux. Read the AMD guide.
  • Vulkan: GGUF inference is supported on compatible GPUs, including Intel GPUs.
  • Multi-GPU: Available now, with a major upgrade on the way

macOS, Linux, WSL:

curl -fsSL https://unsloth.ai/install.sh | sh

Use the same command to update.

Windows:

irm https://unsloth.ai/install.ps1 | iex

Use the same command to update.

Launch

unsloth studio -p 8888

For LAN or cloud access, add -H 0.0.0.0 (raw port only; add --cloudflare for a public URL). By default, Unsloth is accessible only locally.

To reach Unsloth over HTTPS, use unsloth studio --secure. Unsloth stays bound to localhost and is reached only through a free Cloudflare tunnel, which publishes it at a public https://*.trycloudflare.com URL (it fails closed if the tunnel can't start, so the raw port is never exposed). This makes Unsloth reachable from the internet, so anyone with the link and API key can use it and run code: keep your API key private (see Remote access below).

Docker

Use our Docker image unsloth/unsloth container. Run:

docker run -d -e JUPYTER_PASSWORD="mypassword" \
  -p 8888:8888 -p 8000:8000 -p 2222:22 \
  -v $(pwd)/work:/workspace/work \
  --gpus all \
  unsloth/unsloth

Developer, Nightly, Uninstall

To see developer, nightly and uninstallation etc. instructions, see advanced installation.

Unsloth Core (code-based)

Linux, WSL:

curl -LsSf https://astral.sh/uv/install.sh | sh
uv venv unsloth_env --python 3.13
source unsloth_env/bin/activate
uv pip install unsloth --torch-backend=auto

Windows:

winget install -e --id Python.Python.3.13
winget install --id=astral-sh.uv  -e
uv venv unsloth_env --python 3.13
.\unsloth_env\Scripts\activate
uv pip install unsloth --torch-backend=auto

For Windows, pip install unsloth works only if you have PyTorch installed. Read our Windows Guide. You can use the same Docker image as Unsloth Studio.

AMD, Intel:

For RTX 50x, B200, 6000 GPUs: uv pip install unsloth --torch-backend=auto. Read our guides for: Blackwell and DGX Spark.
To install Unsloth on AMD and Intel GPUs, follow our AMD Guide and Intel Guide.

📒 Free Notebooks

Train for free with our notebooks. You can use our new free Unsloth Studio notebook to run and train models for free in a web UI. Read our guide. Add dataset, run, then deploy your trained model.

Model Free Notebooks Performance Memory use
Gemma 4 (E2B) ▶️ Start for free 1.5x faster 50% less
Qwen3.5 (4B) ▶️ Start for free 1.5x faster 60% less
gpt-oss (20B) ▶️ Start for free 2x faster 70% less
Qwen3.5 GSPO ▶️ Start for free 2x faster 70% less
gpt-oss (20B): GRPO ▶️ Start for free 2x faster 80% less
Qwen3: Advanced GRPO ▶️ Start for free 2x faster 70% less
embeddinggemma (300M) ▶️ Start for free 2x faster 20% less
Mistral Ministral 3 (3B) ▶️ Start for free 1.5x faster 60% less
Llama 3.1 (8B) Alpaca ▶️ Start for free 2x faster 70% less
Llama 3.2 Conversational ▶️ Start for free 2x faster 70% less
Orpheus-TTS (3B) ▶️ Start for free 1.5x faster 50% less

🦥 Unsloth News

  • AMD training: Train, run RL, chat and deploy on AMD GPUs across Windows, WSL and Linux. Guide
  • GGUF hardware controls: Choose GPU/layer placement, offload MoE experts and use multi-GPU or Tensor Parallelism. #6414
  • Local models for any agent: Use unsloth start with Claude Code, Codex, Hermes, OpenCode, OpenClaw, Pi and more through Unsloth's OpenAI- and Anthropic-compatible APIs. Guide
  • MCP control endpoint: Let compatible clients manage models, training, recipes, checkpoints and exports. #7191
  • Local inference reliability: Resume long chats faster, recover stalled downloads and reuse existing GGUF files. #7204#6858#7209
  • New models: Qwen-AgentWorld, Ornith, Kimi K2.7 Code and MiniMax M3
  • GLM-5.2: Run Z.ai's 744B-parameter, 1M-context open model locally with Unsloth Dynamic GGUFs. Guide
  • DeepSeek-V4: Run DeepSeek-V4-Flash locally with corrected multi-turn and tool-calling behavior. Guide
  • DiffusionGemma: Run and fine-tune Google's diffusion language model with 1.8x faster inference in Unsloth Studio. Guide
  • Qwen3.6: Run and train Qwen3.6 with MTP for 1.4-2.2x faster inference and NVFP4 quants for supported GPUs. Guide
  • Gemma 4: Run and train Gemma 4 text, image and audio models with QAT, MTP, GGUF and MLX support. Guide
  • MCP servers: Connect local models to files, apps, databases and external tools through Model Context Protocol. Guide
  • Connections: Mix local models with API providers (OpenAI, Anthropic) or servers (vLLM, Ollama) in the same interface. Guide
  • Introducing Unsloth Studio: our new web UI for running and training LLMs. Blog
  • Train MoE LLMs 12x faster with 35% less VRAM - DeepSeek, GLM, Qwen and gpt-oss. Blog
  • Embedding models: Unsloth now supports ~1.8-3.3x faster embedding fine-tuning. BlogNotebooks
  • New 7x longer context RL vs. all other setups, via our new batching algorithms. Blog
  • New RoPE & MLP Triton Kernels & Padding Free + Packing: 3x faster training & 30% less VRAM. Blog
  • 500K Context: Training a 20B model with >500K context is now possible on an 80GB GPU. Blog
  • FP8 & Vision RL: You can now do FP8 & VLM GRPO on consumer GPUs. FP8 BlogVision RL

📥 Advanced Installation

The below advanced instructions are for Unsloth Studio. For Unsloth Core advanced installation, view our docs.

Developer / Nightly / Experimental installs: macOS, Linux, WSL:

The developer install builds from the main branch, which is the latest (nightly) source.

git clone https://github.com/unslothai/unsloth
cd unsloth
./install.sh --local
unsloth studio -p 8888

To install into an isolated location (its own virtual env, auth/, studio.db, cache and llama.cpp build), set UNSLOTH_STUDIO_HOME and pass it again at launch:

UNSLOTH_STUDIO_HOME="$PWD/.studio" ./install.sh --local
UNSLOTH_STUDIO_HOME="$PWD/.studio" unsloth studio -p 8888

Then to update :

cd unsloth && git pull
./install.sh --local
unsloth studio -p 8888

Developer / Nightly / Experimental installs: Windows PowerShell:

The developer install builds from the main branch, which is the latest (nightly) source.

git clone https://github.com/unslothai/unsloth.git
cd unsloth
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
.\install.ps1 --local
unsloth studio -p 8888

To install into an isolated location (its own virtual env, auth/, studio.db, cache and llama.cpp build), set UNSLOTH_STUDIO_HOME and pass it again at launch:

$env:UNSLOTH_STUDIO_HOME="$PWD\.studio"; .\install.ps1 --local
$env:UNSLOTH_STUDIO_HOME="$PWD\.studio"; unsloth studio -p 8888

Then to update :

cd unsloth; git pull
.\install.ps1 --local
unsloth studio -p 8888

Remote access: --secure (HTTPS tunnel) vs raw port

By default unsloth studio binds to 127.0.0.1 (this machine only). To reach it from another device, pick one of:

  • --secure (recommended): serve only through a free Cloudflare HTTPS link. Unsloth stays bound to localhost and the tunnel provides the public URL; it fails closed (does not start) if the tunnel can't come up, so the raw port is never exposed.
unsloth studio --secure -p 8888
  • -H 0.0.0.0: bind the raw port on all network interfaces, reachable from anywhere on the network (subject to your firewall). It does not create a public internet URL; add --cloudflare to also publish an internet-reachable https://*.trycloudflare.com link even behind a firewall. Only use this on a network you trust.
unsloth studio -H 0.0.0.0 -p 8888

The Cloudflare tunnel is off by default: -H 0.0.0.0 exposes the raw port only, not a public internet URL. Pair the wildcard bind with --cloudflare (unsloth studio -H 0.0.0.0 --cloudflare) to also publish a public https://*.trycloudflare.com link, or prefer --secure (above), which keeps the raw port private. --cloudflare has no effect on a loopback bind.

The first time Unsloth is published on a public URL (--secure or --cloudflare) with the auto-generated admin password still in place, it asks for a new admin password in the terminal (masked input with confirmation) before the public link goes up. Without an attached terminal it warns instead and keeps the bootstrap deadline: Unsloth shuts down after UNSLOTH_STUDIO_BOOTSTRAP_TIMEOUT (default 1 hour) unless the password is changed in the web UI.

For headless setups that cannot answer that prompt, set the initial admin password non-interactively with --password (only takes effect when no password is set yet; if one already exists it is a hard error, so rotate later with unsloth studio reset-password):

unsloth studio --secure --password 'your-strong-password'        # visible in `ps`/history
UNSLOTH_STUDIO_PASSWORD='your-strong-password' unsloth studio --secure   # via env var
printf '%s\n' 'your-strong-password' | unsloth studio --secure --password -   # via stdin

A literal --password VALUE is visible in the process list and shell history, so prefer the UNSLOTH_STUDIO_PASSWORD env var or --password - (stdin) for automation. This applies to any launch (public or a headless -H 0.0.0.0 bind), and the password is set in the parent before the server binds, so it never reaches a re-executed child process.

Server-side tools (web search, Python and terminal code execution) run as your user and are on by default. Anyone who can reach the server with the API key can run code on this machine, so keep your API key private and pass --disable-tools when exposing Unsloth.

Advanced launch options

Installer options can be passed as environment variables. On macOS, Linux and WSL place the variable after the pipe so the shell passes it to sh; on Windows set it with $env: before piping to iex.

Skip PyTorch (GGUF-only mode):

curl -fsSL https://unsloth.ai/install.sh | UNSLOTH_NO_TORCH=1 sh
$env:UNSLOTH_NO_TORCH=1; irm https://unsloth.ai/install.ps1 | iex

Skip the post-install prompt that starts Unsloth (useful for automated installs):

curl -fsSL https://unsloth.ai/install.sh | UNSLOTH_SKIP_AUTOSTART=1 sh
$env:UNSLOTH_SKIP_AUTOSTART=1; irm https://unsloth.ai/install.ps1 | iex

Pin the Python version:

curl -fsSL https://unsloth.ai/install.sh | UNSLOTH_PYTHON=3.12 sh
$env:UNSLOTH_PYTHON='3.12'; irm https://unsloth.ai/install.ps1 | iex

Install to a custom location with UNSLOTH_STUDIO_HOME:

curl -fsSL https://unsloth.ai/install.sh | UNSLOTH_STUDIO_HOME=/abs/path sh
$env:UNSLOTH_STUDIO_HOME='C:\path'; irm https://unsloth.ai/install.ps1 | iex

On macOS, the installer defaults to the system certificate store (UV_SYSTEM_CERTS=1) so uv trusts the CAs in your Keychain, needed behind TLS-inspecting proxies (Cisco Umbrella, Zscaler, etc.). Opt out with:

curl -fsSL https://unsloth.ai/install.sh | UV_SYSTEM_CERTS=0 sh

Point the frontend build at a corporate npm mirror/proxy with UNSLOTH_NPM_REGISTRY (for the developer install behind a firewall that blocks registry.npmjs.org):

UNSLOTH_NPM_REGISTRY=https://artifactory.example.com/api/npm/npm/ ./install.sh --local
$env:UNSLOTH_NPM_REGISTRY='https://artifactory.example.com/api/npm/npm/'; .\install.ps1 --local

It is threaded as --registry into the Unsloth frontend npm/bun installs; the supply-chain locks (7-day min-release-age, exact version pins) stay in force.

Cap Unsloth's native CPU thread pools on high-core hosts: UNSLOTH_CPU_THREADS=8 unsloth studio -p 8888.

Uninstall

The recommended way to fully remove Unsloth Studio is the matching uninstall script for your OS. It stops any running servers, removes the install dir, the launcher data dir, the desktop shortcut, and any platform-specific entries (macOS .app bundle + Launch Services on Mac; Start Menu, HKCU\Software\Unsloth registry key and user PATH entries on Windows):

  • MacOS, WSL, Linux: curl -fsSL https://raw.githubusercontent.com/unslothai/unsloth/main/scripts/uninstall.sh | sh
  • Windows (PowerShell): irm https://raw.githubusercontent.com/unslothai/unsloth/main/scripts/uninstall.ps1 | iex

If you only want to drop the install dir and keep the launcher/shortcut for a later reinstall, you can instead run rm -rf ~/.unsloth/studio (Mac/Linux/WSL) or Remove-Item -Recurse -Force "$HOME\.unsloth\studio" (Windows). The model cache at ~/.cache/huggingface is not touched by any of these.

For more info, see our docs.

Deleting model files

You can delete old model files either from the bin icon in model search or by removing the relevant cached model folder from the default Hugging Face cache directory. By default, HF uses:

  • MacOS, Linux, WSL: ~/.cache/huggingface/hub/
  • Windows: %USERPROFILE%\.cache\huggingface\hub\
Type Links
  Discord Join Discord server
  r/unsloth Reddit Join Reddit community
📚 Documentation & Wiki Read Our Docs
  Twitter (aka X) Follow us on X
🔮 Our Models Unsloth Catalog
✍️ Blog Read our Blogs

Citation

You can cite the Unsloth repo as follows:

@software{unsloth,
  author = {Daniel Han, Michael Han and Unsloth team},
  title = {Unsloth},
  url = {https://github.com/unslothai/unsloth},
  year = {2023}
}

If you trained a model with 🦥Unsloth, you can use this cool sticker!  

License

Unsloth uses a dual-licensing model of Apache 2.0 and AGPL-3.0. The core Unsloth package remains licensed under Apache 2.0, while certain optional components, such as the Unsloth Studio UI are licensed under the open-source license AGPL-3.0.

This structure helps support ongoing Unsloth development while keeping the project open source and enabling the broader ecosystem to continue growing.

Thank You to

  • The llama.cpp library that lets users run and save models with Unsloth
  • The Hugging Face team and their libraries: transformers and TRL
  • The Pytorch and Torch AO team for their contributions
  • NVIDIA for their NeMo DataDesigner library and their contributions
  • And of course for every single person who has contributed or has used Unsloth!