Commit graph

433 commits

Author SHA1 Message Date
pre-commit-ci[bot]
f4fbbcaec8 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-03-15 05:24:06 -07:00
Daniel Han
f4f69f16a6 studio: centralize cache directory for all downloads
Set HF_HOME, HF_HUB_CACHE, HF_XET_CACHE, UV_CACHE_DIR, and
VLLM_CACHE_ROOT to a unified location under ~/.unsloth/studio/cache/
on startup. This keeps all model downloads, datasets, and caches
in one place instead of scattered across ~/.cache/huggingface,
~/.cache/uv, etc.

Layout:
  ~/.unsloth/studio/cache/
    huggingface/       (HF_HOME)
      hub/             (HF_HUB_CACHE -- model/dataset downloads)
      xet/             (HF_XET_CACHE -- xet blob store)
    uv/                (UV_CACHE_DIR -- uv package cache)
    vllm/              (VLLM_CACHE_ROOT -- vllm compiled kernels)

Only sets variables that are not already in the environment, so
user overrides (e.g. HF_HOME=/data/models) are respected.

Cross-platform: uses Path.home() which resolves correctly on
Linux (~), macOS (~), and Windows (C:\Users\<user>).
2026-03-15 05:24:06 -07:00
Daniel Han
f1293fe7d8 studio: respect existing CUDA_VISIBLE_DEVICES in GPU selection
If CUDA_VISIBLE_DEVICES is already set in the environment (e.g.,
by the user or a wrapper script), only consider those GPUs when
selecting devices for llama-server. nvidia-smi reports all physical
GPUs regardless of CUDA_VISIBLE_DEVICES, so we filter its output
to match the allowed set.

Without this, the GPU selector could pick a GPU outside the user's
allowed set, overriding their restriction.
2026-03-15 05:24:06 -07:00
pre-commit-ci[bot]
e885d7308e [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-03-15 05:24:06 -07:00
Daniel Han
12183e0656 studio: smart GPU allocation for GGUF inference
Automatically select the best GPU(s) for a GGUF model based on
file size and available VRAM, instead of relying on hardcoded
-ngl -1 or letting llama-server guess.

Logic:
1. Measure total GGUF file size (including split shards)
2. Query free memory per GPU via nvidia-smi
3. If the model fits in 70% of the most-free GPU's memory,
   pin to that single GPU (CUDA_VISIBLE_DEVICES=X, no --fit)
4. If it needs multiple GPUs, pick the N most-free GPUs
   (CUDA_VISIBLE_DEVICES=X,Y, no --fit)
5. If it's too large for all GPUs combined, omit
   CUDA_VISIBLE_DEVICES and use --fit on to let llama-server
   handle partial offloading

The 70% threshold accounts for KV cache and compute buffers
that sit on top of the model weights.

Removed the -ngl parameter (was hardcoded to -1). llama-server's
default of "auto" handles layer offloading correctly, especially
with --fit on for oversized models.

Tested on 8x B200:
  - 1B model (0.75 GB):  picks 1 GPU, no --fit
  - 27B model (17 GB):   picks 1 GPU, no --fit
  - 405B model (230 GB): picks 2 GPUs, no --fit
  - 2TB model:           all GPUs, --fit on
2026-03-15 05:24:06 -07:00
pre-commit-ci[bot]
7202f81985 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-03-15 05:24:06 -07:00
Daniel Han
80d84a5b5f studio: optimize llama-server flags for single-user studio
Refactor command building (deduplicate HF/local paths) and add
flags for better performance:

- --parallel 1: studio is single-user, so only 1 inference slot
  is needed. The previous auto-detect picked 4 slots, wasting
  VRAM on 3 unused KV caches.
- --flash-attn on: force flash attention for faster inference.
  Default is "auto" which may not always enable it.
- --fit on: auto-adjust parameters to fit in available device
  memory. Already the default but now explicit.

Also cleaned up the duplicated command building for HF vs local
mode into a single block.
2026-03-15 05:24:06 -07:00
Daniel Han
887e7a31c4 studio: don't cap max_tokens for GGUF inference
Remove the hard max_tokens=2048 default and le=4096 cap for GGUF
chat completions. When max_tokens is not set (None), the field is
omitted from the llama-server payload entirely, letting the model
generate until it produces an EOS token or hits the context limit.

This is critical for thinking/reasoning models (Qwen3.5, DeepSeek-R1,
etc.) where the thinking phase alone can consume 1000+ tokens before
the actual answer. With the previous 2048 default, simple questions
like "What is 2+2?" used all tokens on thinking and produced empty
visible responses.

Changes:
- llama_cpp.py: max_tokens default None, only include in payload
  when explicitly set
- models/inference.py: default None, remove le=4096 cap
- routes/inference.py: pass max_tokens directly, no "or 2048" fallback

llama-server handles omitted max_tokens gracefully (generates until
EOS or context limit). The context size (-c flag, default 4096) acts
as the hard upper bound.
2026-03-15 05:24:06 -07:00
Daniel Han
961720c1b1 studio: handle reasoning_content in GGUF streaming
llama-server sends thinking/reasoning tokens as "reasoning_content"
in the SSE delta (separate from "content"). The studio was only
reading delta.content, so all reasoning tokens from models like
Qwen3.5, Qwen3-Thinking, DeepSeek-R1, etc. were silently dropped.

This caused "replies with nothing" for thinking models: the model
would spend its entire token budget on reasoning, produce zero
content tokens, and the user would see an empty response.

Fix: read reasoning_content from the delta and wrap it in
<think>...</think> tags. The frontend already has full support
for these tags (parse-assistant-content.ts splits them into
reasoning parts, reasoning.tsx renders a collapsible "Thinking..."
indicator).

Verified with Qwen3.5-27B-GGUF (UD-Q4_K_XL):
  - Before: "What is 2+2?" -> empty response (all tokens in reasoning)
  - After: shows collapsible thinking + answer "4"
2026-03-15 05:24:06 -07:00
Roland Tannous
477e68675b
Fix: Compare Mode Deadlock, Cancel Event Poisoning & IPC Optimization (#4303)
* fix: resolve compare mode deadlock, cancel_event poisoning, and add dispatcher-based IPC optimization

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

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

* revert to 2048 tokens

* refactor: extract dispatcher timeout values into named constants

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

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

* fix: guard dispatcher shutdown against active compare mailboxes

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-03-15 16:11:44 +04:00
Wasim Yousef Said
e280b0bebc
miscallenous studio (#4293)
* miscallenous studio

* chore: upload dataset misc

* chore: redudancy studio cleanup

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

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

* fix: adress the pr comments

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

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

* fix: adress comments about recipes

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

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

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-03-15 14:42:11 +04:00
Wasim Yousef Said
629199e3a6
fix: remove old comments (#4292)
* fix: quotation marks

* diceware passphrase generation

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

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

---------

Co-authored-by: Roland Tannous <rolandtannous@gravityq.ai>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-03-14 16:50:13 +04:00
Daniel Han
1f99dee027
fix(seed): disable remote code execution in seed inspect dataset loads (#4275)
* fix(seed): disable remote code execution for seed inspect loads

* fix(test): use __file__-relative path in seed test

The test used a CWD-relative path (`studio/backend/routes/...`) which
only resolved when pytest was invoked from the repo root. Use
`Path(__file__).resolve()` so the test passes regardless of CWD.

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

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

---------

Co-authored-by: Test <test@test.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-03-13 19:37:43 +04:00
Daniel Han
88c7b08faa
fix: prevent ai-assist model config RCE via untrusted Hugging Face repos (#4274)
* fix: disable remote code loading for ai-assist model hint lookup

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

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

---------

Co-authored-by: Roland Tannous <115670425+rolandtannous@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-03-13 19:29:11 +04:00
Roland Tannous
e539965740 fix error for chat template 2026-03-13 15:18:04 +00:00
Daniel Han
51bf500f57
Remove Blackwell flex attention disable workaround from studio (#4273)
The studio was disabling flex attention entirely on Blackwell+ GPUs
(sm_120 and above) by setting UNSLOTH_ENABLE_FLEX_ATTENTION=0 at
startup. This was a workaround for the flex_attention backward kernel
exceeding shared memory limits on these GPUs.

The root cause is now fixed in unsloth-zoo (PR #542) which patches the
backward kernel config selection to generate safe fallback configs that
fit within the GPU's shared memory limit. With that fix, flex attention
works correctly on Blackwell GPUs and provides a ~1.3x speedup over
the SDPA fallback.
2026-03-13 01:35:17 -07:00
Daniel Han
96ff5c5f61
Update CODEOWNERS for studio and cli (#4266)
* Update CODEOWNERS for studio and cli

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

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

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-03-12 15:16:38 -07:00
Roland Tannous
47654cb91c Final cleanup 2026-03-12 18:28:04 +00:00
Roland Tannous
a2baf80511 Update license headers 2026-03-12 17:23:10 +00:00
Roland Tannous
11e74b2dc5 resolved conflicts 2026-03-11 20:58:25 +00:00
Roland Tannous
1087216cb5 Merge branch 'fix/pre-merge-cleanup' into feature/merge-build-final 2026-03-11 20:56:49 +00:00
Roland Tannous
6f77c63229 refactor: remove project_root passing, use self-resolved paths and ~/.unsloth/studio
- Workers now compute backend_path and venv_t5 locally via Path(__file__)
- Moved .venv_t5 to ~/.unsloth/studio/.venv_t5
- Added ensure_studio_directories() call on server startup
- Expanded CLI studio command into sub-app with setup subcommand
2026-03-11 20:32:18 +00:00
Shine1i
bbb4cd0f0b feat(studio): add auth-specific paths and integrate auth database location 2026-03-11 20:19:52 +00:00
Shine1i
7012b8396f fix(studio): update temporary directory path to use system temp dir 2026-03-11 20:19:52 +00:00
Shine1i
904e440513 feat(studio): studio storage roots path utilities 2026-03-11 20:19:52 +00:00
Roland Tannous
d6e4a0644f resolved format_conversion conflict 2026-03-11 19:53:53 +00:00
Roland Tannous
6926a8b091 fix: prefer tabular files over archives in Tier 1 dataset preview
Tier 1 check-format was picking images.zip over testmini.parquet,
causing wrong columns (image/label) and broken VLM mapping.
Also log first VLM conversion failure instead of swallowing silently.
2026-03-11 19:13:11 +00:00
Roland Tannous
a63196c93e updated on completion response markers for qwen3.5 2026-03-11 19:00:29 +00:00
Roland Tannous
e455b307be add fmpeg system support for linux and windows 2026-03-11 18:50:11 +00:00
Roland Tannous
0e3ac91e2a feat: target AI Assist mapping prompts for audio & embedding models 2026-03-11 16:55:43 +00:00
Roland Tannous
9dac1bedf9 Merge remote-tracking branch 'origin/nightly' into feature/llm-assist-detection 2026-03-11 16:23:09 +00:00
Roland Tannous
7862e70211 fix: lowercase remote Hugging Face model IDs in ModelConfig and routes to prevent caching mismatches with Unsloth 2026-03-11 14:20:25 +00:00
Roland Tannous
817f2e8dcc feat: integrate structlog, configure workers for prod logging, and migrate print statements 2026-03-11 12:33:16 +00:00
Roland Tannous
ee063c5910 Merge pull request #367 from unslothai/fix/yaml-syntax
Modified to fix the yaml syntax for unsloth_Qwen3-14B-Base-unsloth-bnb-4bit
2026-03-11 13:39:48 +04:00
Samit
379bbbdbdd fixed string concatenation in model mapping 2026-03-11 00:07:26 -07:00
Samit
822050bf57 modified to fix the yaml syntax 2026-03-10 23:58:51 -07:00
Manan Shah
2aa9322167 Merge pull request #365 from unslothai/fix/gguf-gemma-with-text
fixing gguf export for gemma with text
2026-03-10 17:59:22 -07:00
Manan17
5ca623a166 fixing gguf export for gemma with text 2026-03-11 00:58:22 +00:00
Shine1i
4a8a96b1af chat seq slider 2026-03-11 01:41:25 +01:00
Manan17
983c20bbb2 local model's embedding nature check 2026-03-10 21:58:45 +00:00
Manan17
bc5a72dd8c fix: local directory dataset loading 2026-03-10 21:29:51 +00:00
Manan Shah
f696ef81e8 Merge branch 'nightly' into feat/embedding-models 2026-03-10 14:16:05 -07:00
Roland Tannous
08d9c84f1f Merge pull request #359 from unslothai/fix/stream-manual-slice-dataset
fix: stream HF dataset when manual slice is specified
2026-03-11 01:13:51 +04:00
Manan17
3b0b002b34 fixing logging for each step 2026-03-10 20:32:40 +00:00
Roland Tannous
21ef22a9ff fix: skip streaming when dataset_slice_start > dataset_slice_end
Prevents training on the wrong row range when start exceeds end by
falling back to full download where existing clamping handles it.
2026-03-10 20:21:34 +00:00
Roland Tannous
226f251589 fix: guard against negative dataset_slice_end before streaming
Fall back to full download when dataset_slice_end is negative,
avoiding an empty stream.take(0) that would produce a broken dataset.
2026-03-10 20:12:42 +00:00
Roland Tannous
970a029108 fix: stream HF dataset when manual slice is specified
Instead of downloading the full dataset and then slicing, use
streaming mode to only fetch the rows needed (up to slice_end + 1)
when a manual dataset slice is configured.
2026-03-10 19:50:53 +00:00
Roland Tannous
c986174c56 fix: preserve zero-valued dataset slice boundaries in embedding worker
Use explicit None checks instead of falsy `or` for slice_start and
slice_end so that a valid slice_end=0 is not replaced with the full
dataset length.
2026-03-10 19:33:10 +00:00
Roland Tannous
b84202e8db fix: restrict shard siblings to exact basename and total count
startswith(prefix) could match unrelated split variants whose names
extend the selected file's prefix (e.g. model-Q8_0-v2-00001-of-...).
Now builds an exact regex from the chosen file's base prefix and shard
total so only true siblings are downloaded.
2026-03-10 19:28:26 +00:00
Roland Tannous
b8678a3ed6 fix: pass hf_token for gated embedding models and key cache by token
- Forward hf_token to FastSentenceTransformer.from_pretrained() so
  private/gated embedding repos authenticate correctly
- Key _embedding_detection_cache by (model_name, hf_token) tuple so
  unauthenticated lookups don't shadow subsequent authenticated ones
2026-03-10 19:20:12 +00:00