Merge branch 'main' into pip
This commit is contained in:
commit
07e2fccf38
8 changed files with 117 additions and 64 deletions
10
install.ps1
10
install.ps1
|
|
@ -1285,7 +1285,7 @@ shell.Run cmd, 0, False
|
|||
if ($SkipTorch) {
|
||||
# No-torch: install unsloth + unsloth-zoo with --no-deps, then
|
||||
# runtime deps (typer, safetensors, transformers, etc.) with --no-deps.
|
||||
$baseInstallExit = Invoke-InstallCommand { uv pip install --python $VenvPython --no-deps --reinstall-package unsloth --reinstall-package unsloth-zoo "unsloth>=2026.5.2" unsloth-zoo }
|
||||
$baseInstallExit = Invoke-InstallCommand { uv pip install --python $VenvPython --no-deps --reinstall-package unsloth --reinstall-package unsloth-zoo "unsloth>=2026.5.3" unsloth-zoo }
|
||||
if ($baseInstallExit -eq 0) {
|
||||
$NoTorchReq = Find-NoTorchRuntimeFile
|
||||
if ($NoTorchReq) {
|
||||
|
|
@ -1293,7 +1293,7 @@ shell.Run cmd, 0, False
|
|||
}
|
||||
}
|
||||
} else {
|
||||
$baseInstallExit = Invoke-InstallCommand { uv pip install --python $VenvPython --reinstall-package unsloth --reinstall-package unsloth-zoo "unsloth>=2026.5.2" unsloth-zoo }
|
||||
$baseInstallExit = Invoke-InstallCommand { uv pip install --python $VenvPython --reinstall-package unsloth --reinstall-package unsloth-zoo "unsloth>=2026.5.3" unsloth-zoo }
|
||||
}
|
||||
if ($baseInstallExit -ne 0) {
|
||||
Write-Host "[ERROR] Failed to install unsloth (exit code $baseInstallExit)" -ForegroundColor Red
|
||||
|
|
@ -1331,7 +1331,7 @@ shell.Run cmd, 0, False
|
|||
if ($SkipTorch) {
|
||||
# No-torch: install unsloth + unsloth-zoo with --no-deps, then
|
||||
# runtime deps (typer, safetensors, transformers, etc.) with --no-deps.
|
||||
$baseInstallExit = Invoke-InstallCommand { uv pip install --python $VenvPython --no-deps --upgrade-package unsloth --upgrade-package unsloth-zoo "unsloth>=2026.5.2" unsloth-zoo }
|
||||
$baseInstallExit = Invoke-InstallCommand { uv pip install --python $VenvPython --no-deps --upgrade-package unsloth --upgrade-package unsloth-zoo "unsloth>=2026.5.3" unsloth-zoo }
|
||||
if ($baseInstallExit -eq 0) {
|
||||
$NoTorchReq = Find-NoTorchRuntimeFile
|
||||
if ($NoTorchReq) {
|
||||
|
|
@ -1339,7 +1339,7 @@ shell.Run cmd, 0, False
|
|||
}
|
||||
}
|
||||
} elseif ($StudioLocalInstall) {
|
||||
$baseInstallExit = Invoke-InstallCommand { uv pip install --python $VenvPython --upgrade-package unsloth "unsloth>=2026.5.2" unsloth-zoo }
|
||||
$baseInstallExit = Invoke-InstallCommand { uv pip install --python $VenvPython --upgrade-package unsloth "unsloth>=2026.5.3" unsloth-zoo }
|
||||
} else {
|
||||
$baseInstallExit = Invoke-InstallCommand { uv pip install --python $VenvPython --upgrade-package unsloth -- "$PackageName" }
|
||||
}
|
||||
|
|
@ -1367,7 +1367,7 @@ shell.Run cmd, 0, False
|
|||
Write-TauriLog "STEP" "Installing unsloth"
|
||||
substep "installing unsloth (this may take a few minutes)..."
|
||||
if ($StudioLocalInstall) {
|
||||
$baseInstallExit = Invoke-InstallCommand { uv pip install --python $VenvPython unsloth-zoo "unsloth>=2026.5.2" --torch-backend=auto }
|
||||
$baseInstallExit = Invoke-InstallCommand { uv pip install --python $VenvPython unsloth-zoo "unsloth>=2026.5.3" --torch-backend=auto }
|
||||
if ($baseInstallExit -ne 0) {
|
||||
Write-Host "[ERROR] Failed to install unsloth (exit code $baseInstallExit)" -ForegroundColor Red
|
||||
return (Exit-InstallFailure "Failed to install unsloth (exit code $baseInstallExit)" $baseInstallExit)
|
||||
|
|
|
|||
10
install.sh
10
install.sh
|
|
@ -1849,7 +1849,7 @@ if [ "$_MIGRATED" = true ]; then
|
|||
# to prevent transitive torch resolution.
|
||||
run_install_cmd "install unsloth (migrated no-torch)" uv pip install --python "$_VENV_PY" --no-deps \
|
||||
--reinstall-package unsloth --reinstall-package unsloth-zoo \
|
||||
"unsloth>=2026.5.2" unsloth-zoo
|
||||
"unsloth>=2026.5.3" unsloth-zoo
|
||||
_NO_TORCH_RT="$(_find_no_torch_runtime)"
|
||||
if [ -n "$_NO_TORCH_RT" ]; then
|
||||
run_install_cmd "install no-torch runtime deps" uv pip install --python "$_VENV_PY" --no-deps -r "$_NO_TORCH_RT"
|
||||
|
|
@ -1857,7 +1857,7 @@ if [ "$_MIGRATED" = true ]; then
|
|||
else
|
||||
run_install_cmd "install unsloth (migrated)" uv pip install --python "$_VENV_PY" \
|
||||
--reinstall-package unsloth --reinstall-package unsloth-zoo \
|
||||
"unsloth>=2026.5.2" unsloth-zoo
|
||||
"unsloth>=2026.5.3" unsloth-zoo
|
||||
fi
|
||||
if [ "$STUDIO_LOCAL_INSTALL" = true ]; then
|
||||
substep "overlaying local repo (editable)..."
|
||||
|
|
@ -2025,7 +2025,7 @@ elif [ -n "$TORCH_INDEX_URL" ]; then
|
|||
# runtime deps (typer, safetensors, transformers, etc.) with --no-deps.
|
||||
run_install_cmd "install unsloth (no-torch)" uv pip install --python "$_VENV_PY" --no-deps \
|
||||
--upgrade-package unsloth --upgrade-package unsloth-zoo \
|
||||
"unsloth>=2026.5.2" unsloth-zoo
|
||||
"unsloth>=2026.5.3" unsloth-zoo
|
||||
_NO_TORCH_RT="$(_find_no_torch_runtime)"
|
||||
if [ -n "$_NO_TORCH_RT" ]; then
|
||||
run_install_cmd "install no-torch runtime deps" uv pip install --python "$_VENV_PY" --no-deps -r "$_NO_TORCH_RT"
|
||||
|
|
@ -2040,7 +2040,7 @@ elif [ -n "$TORCH_INDEX_URL" ]; then
|
|||
fi
|
||||
elif [ "$STUDIO_LOCAL_INSTALL" = true ]; then
|
||||
run_install_cmd "install unsloth (local)" uv pip install --python "$_VENV_PY" \
|
||||
--upgrade-package unsloth "unsloth>=2026.5.2" unsloth-zoo
|
||||
--upgrade-package unsloth "unsloth>=2026.5.3" unsloth-zoo
|
||||
substep "overlaying local repo (editable)..."
|
||||
run_install_cmd "overlay local repo" uv pip install --python "$_VENV_PY" -e "$_REPO_ROOT" --no-deps
|
||||
substep "overlaying unsloth-zoo from git main..."
|
||||
|
|
@ -2072,7 +2072,7 @@ else
|
|||
tauri_log "STEP" "Installing Unsloth"
|
||||
substep "installing unsloth (this may take a few minutes)..."
|
||||
if [ "$STUDIO_LOCAL_INSTALL" = true ]; then
|
||||
run_install_cmd "install unsloth (auto torch backend)" uv pip install --python "$_VENV_PY" unsloth-zoo "unsloth>=2026.5.2" --torch-backend=auto
|
||||
run_install_cmd "install unsloth (auto torch backend)" uv pip install --python "$_VENV_PY" unsloth-zoo "unsloth>=2026.5.3" --torch-backend=auto
|
||||
substep "overlaying local repo (editable)..."
|
||||
run_install_cmd "overlay local repo" uv pip install --python "$_VENV_PY" -e "$_REPO_ROOT" --no-deps
|
||||
substep "overlaying unsloth-zoo from git main..."
|
||||
|
|
|
|||
|
|
@ -6,15 +6,16 @@
|
|||
import utils.hardware.hardware as hw
|
||||
|
||||
DEFAULT_MODELS_GGUF = [
|
||||
"unsloth/Qwen3.6-27B-MTP-GGUF",
|
||||
"unsloth/Qwen3.6-35B-A3B-MTP-GGUF",
|
||||
"unsloth/gemma-4-E2B-it-GGUF",
|
||||
"unsloth/gemma-4-E4B-it-GGUF",
|
||||
"unsloth/gemma-4-31B-it-GGUF",
|
||||
"unsloth/gemma-4-26B-A4B-it-GGUF",
|
||||
"unsloth/Qwen3.6-35B-A3B-GGUF",
|
||||
"unsloth/Qwen3.5-4B-GGUF",
|
||||
"unsloth/Qwen3.5-9B-GGUF",
|
||||
"unsloth/Qwen3.5-35B-A3B-GGUF",
|
||||
"unsloth/Qwen3.5-0.8B-GGUF",
|
||||
"unsloth/Qwen3.5-4B-MTP-GGUF",
|
||||
"unsloth/Qwen3.5-9B-MTP-GGUF",
|
||||
"unsloth/Qwen3.5-35B-A3B-MTP-GGUF",
|
||||
"unsloth/Qwen3.5-0.8B-MTP-GGUF",
|
||||
"unsloth/Llama-3.2-1B-Instruct-GGUF",
|
||||
"unsloth/Llama-3.2-3B-Instruct-GGUF",
|
||||
"unsloth/Llama-3.1-8B-Instruct-GGUF",
|
||||
|
|
@ -24,15 +25,16 @@ DEFAULT_MODELS_GGUF = [
|
|||
]
|
||||
|
||||
DEFAULT_MODELS_STANDARD = [
|
||||
"unsloth/Qwen3.6-27B-MTP-GGUF",
|
||||
"unsloth/Qwen3.6-35B-A3B-MTP-GGUF",
|
||||
"unsloth/gemma-4-E2B-it-GGUF",
|
||||
"unsloth/gemma-4-E4B-it-GGUF",
|
||||
"unsloth/gemma-4-31B-it-GGUF",
|
||||
"unsloth/gemma-4-26B-A4B-it-GGUF",
|
||||
"unsloth/Qwen3.6-35B-A3B-GGUF",
|
||||
"unsloth/Qwen3.5-4B-GGUF",
|
||||
"unsloth/Qwen3.5-9B-GGUF",
|
||||
"unsloth/Qwen3.5-35B-A3B-GGUF",
|
||||
"unsloth/Qwen3.5-0.8B-GGUF",
|
||||
"unsloth/Qwen3.5-4B-MTP-GGUF",
|
||||
"unsloth/Qwen3.5-9B-MTP-GGUF",
|
||||
"unsloth/Qwen3.5-35B-A3B-MTP-GGUF",
|
||||
"unsloth/Qwen3.5-0.8B-MTP-GGUF",
|
||||
"unsloth/gemma-4-E2B-it",
|
||||
"unsloth/gemma-4-E4B-it",
|
||||
"unsloth/gemma-4-31B-it",
|
||||
|
|
|
|||
|
|
@ -2651,9 +2651,10 @@ class LlamaCppBackend:
|
|||
)
|
||||
user_owns_spec_type = _extra_args_set_spec_type(extra_args)
|
||||
# Auto-promote unset/"default" to draft-mtp on MTP GGUFs.
|
||||
# llama.cpp #22673: MTP is compatible with mmproj, so the
|
||||
# vision gate previously here was wrong.
|
||||
if (
|
||||
is_mtp_model
|
||||
and not effective_is_vision
|
||||
and not user_owns_spec_type
|
||||
and normalized_spec in (None, "", "default")
|
||||
):
|
||||
|
|
@ -2662,11 +2663,7 @@ class LlamaCppBackend:
|
|||
# User --spec-type wins (it accumulates if repeated).
|
||||
normalized_spec = None
|
||||
self._speculative_type = None
|
||||
if (
|
||||
normalized_spec
|
||||
and normalized_spec != "off"
|
||||
and not effective_is_vision
|
||||
):
|
||||
if normalized_spec and normalized_spec != "off":
|
||||
if normalized_spec == "default":
|
||||
cmd.append("--spec-default")
|
||||
self._speculative_type = "default"
|
||||
|
|
@ -3112,22 +3109,16 @@ class LlamaCppBackend:
|
|||
if _norm(self._cache_type_kv) != _norm(cache_type_kv):
|
||||
return False
|
||||
|
||||
# Vision GGUFs silently drop speculative decoding in
|
||||
# load_model (the spec gate is "not is_vision"); treat the
|
||||
# request's value as "off" so a vision load with
|
||||
# speculative_type="default" still matches.
|
||||
if self._is_vision or is_vision:
|
||||
req_spec = "off"
|
||||
else:
|
||||
raw_spec = _norm(speculative_type)
|
||||
req_spec = raw_spec or "off"
|
||||
# Mirror load_model's auto-promotion so repeat /load matches.
|
||||
if (
|
||||
raw_spec in (None, "default")
|
||||
and _is_mtp_model_name(model_identifier, gguf_path)
|
||||
and not _extra_args_set_spec_type(extra_args)
|
||||
):
|
||||
req_spec = "draft-mtp"
|
||||
# Mirror load_model's auto-promotion. Vision is no longer a
|
||||
# spec blocker (llama.cpp #22673: MTP is compatible with mmproj).
|
||||
raw_spec = _norm(speculative_type)
|
||||
req_spec = raw_spec or "off"
|
||||
if (
|
||||
raw_spec in (None, "default")
|
||||
and _is_mtp_model_name(model_identifier, gguf_path)
|
||||
and not _extra_args_set_spec_type(extra_args)
|
||||
):
|
||||
req_spec = "draft-mtp"
|
||||
backend_spec = _norm(self._speculative_type) or "off"
|
||||
if req_spec != backend_spec:
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -351,6 +351,67 @@ def test_already_in_target_state_local_file_mtp_match(tmp_path):
|
|||
)
|
||||
|
||||
|
||||
def test_already_in_target_state_vision_mtp_match():
|
||||
# llama.cpp #22673: MTP is compatible with mmproj. A vision MTP load
|
||||
# with auto/default spec must match a backend already running draft-mtp.
|
||||
backend = _mtp_backend(_is_vision = True)
|
||||
assert (
|
||||
backend._already_in_target_state(
|
||||
gguf_path = None,
|
||||
model_identifier = "unsloth/Qwen3.6-27B-MTP-GGUF",
|
||||
hf_variant = "Q4_K_M",
|
||||
n_ctx = 8192,
|
||||
cache_type_kv = None,
|
||||
speculative_type = None,
|
||||
chat_template_override = None,
|
||||
extra_args = None,
|
||||
is_vision = True,
|
||||
)
|
||||
is True
|
||||
)
|
||||
|
||||
|
||||
def test_already_in_target_state_vision_mtp_default_matches():
|
||||
backend = _mtp_backend(_is_vision = True)
|
||||
assert (
|
||||
backend._already_in_target_state(
|
||||
gguf_path = None,
|
||||
model_identifier = "unsloth/Qwen3.6-27B-MTP-GGUF",
|
||||
hf_variant = "Q4_K_M",
|
||||
n_ctx = 8192,
|
||||
cache_type_kv = None,
|
||||
speculative_type = "default",
|
||||
chat_template_override = None,
|
||||
extra_args = None,
|
||||
is_vision = True,
|
||||
)
|
||||
is True
|
||||
)
|
||||
|
||||
|
||||
def test_already_in_target_state_vision_non_mtp_unaffected():
|
||||
# Vision non-MTP repo (no -MTP marker) must still mismatch req=None
|
||||
# against a backend running draft-mtp.
|
||||
backend = _mtp_backend(
|
||||
_model_identifier = "unsloth/Qwen3-VL-4B-Instruct-GGUF",
|
||||
_is_vision = True,
|
||||
)
|
||||
assert (
|
||||
backend._already_in_target_state(
|
||||
gguf_path = None,
|
||||
model_identifier = "unsloth/Qwen3-VL-4B-Instruct-GGUF",
|
||||
hf_variant = "Q4_K_M",
|
||||
n_ctx = 8192,
|
||||
cache_type_kv = None,
|
||||
speculative_type = None,
|
||||
chat_template_override = None,
|
||||
extra_args = None,
|
||||
is_vision = True,
|
||||
)
|
||||
is False
|
||||
)
|
||||
|
||||
|
||||
# GGUF-metadata-based detection (nextn_predict_layers).
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -979,26 +979,25 @@ export function ChatSettingsPanel({
|
|||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
{!currentModelIsMultimodal && (
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<div className="flex min-w-0 items-center gap-1.5">
|
||||
<span className="min-w-0 text-[13px] font-medium leading-[1.25] tracking-nav text-nav-fg">
|
||||
Speculative Decoding
|
||||
</span>
|
||||
<InfoHint>
|
||||
N-gram speculation; faster generation with negligible
|
||||
VRAM overhead. Text-only models.
|
||||
</InfoHint>
|
||||
</div>
|
||||
<Switch
|
||||
className="panel-switch shrink-0"
|
||||
checked={speculativeType != null}
|
||||
onCheckedChange={(checked) => {
|
||||
setSpeculativeType(checked ? "default" : null);
|
||||
}}
|
||||
/>
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<div className="flex min-w-0 items-center gap-1.5">
|
||||
<span className="min-w-0 text-[13px] font-medium leading-[1.25] tracking-nav text-nav-fg">
|
||||
Speculative Decoding
|
||||
</span>
|
||||
<InfoHint>
|
||||
Faster generation with 0% accuracy hit.
|
||||
</InfoHint>
|
||||
</div>
|
||||
)}
|
||||
<Switch
|
||||
className="panel-switch shrink-0"
|
||||
checked={
|
||||
speculativeType !== "off" && speculativeType != null
|
||||
}
|
||||
onCheckedChange={(checked) => {
|
||||
setSpeculativeType(checked ? "default" : "off");
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{!isGguf && params.checkpoint && (
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
// Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
|
||||
|
||||
import { apiUrl } from "@/lib/api-base";
|
||||
import { authFetch } from "@/features/auth";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
export interface GpuInfo {
|
||||
|
|
@ -28,7 +28,7 @@ async function fetchGpuOnce(): Promise<GpuInfo> {
|
|||
|
||||
fetchPromise = (async () => {
|
||||
try {
|
||||
const res = await fetch(apiUrl("/api/system"));
|
||||
const res = await authFetch("/api/system");
|
||||
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
||||
const data = await res.json();
|
||||
const gpuData = data?.gpu;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
__version__ = "2026.5.3"
|
||||
__version__ = "2026.5.4"
|
||||
|
||||
__all__ = [
|
||||
"SUPPORTS_BFLOAT16",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue