Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 4 additions & 9 deletions install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -1302,13 +1302,9 @@ shell.Run cmd, 0, False
# 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.6" unsloth-zoo }
if ($baseInstallExit -eq 0) {
# Install pydantic WITH deps so pip pins pydantic-core to
# the exact version pydantic's metadata requires. The
# --no-deps install of no-torch-runtime.txt below would
# otherwise pick the latest of each independently and
# trip pydantic's _ensure_pydantic_core_version check.
# pydantic's deps (annotated-types, pydantic-core,
# typing-extensions, typing-inspection) are torch-free.
# Resolve pydantic WITH deps so pip pins pydantic-core
# to the matching version (no-torch-runtime.txt below
# is --no-deps). All transitive deps are torch-free.
$baseInstallExit = Invoke-InstallCommand { uv pip install --python $VenvPython pydantic }
}
if ($baseInstallExit -eq 0) {
Expand Down Expand Up @@ -1358,8 +1354,7 @@ shell.Run cmd, 0, False
# 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.6" unsloth-zoo }
if ($baseInstallExit -eq 0) {
# Install pydantic WITH deps so pip pins pydantic-core to
# the matching version (see migrated branch above).
# Same pydantic-with-deps trick as the migrated branch.
$baseInstallExit = Invoke-InstallCommand { uv pip install --python $VenvPython pydantic }
}
if ($baseInstallExit -eq 0) {
Expand Down
13 changes: 4 additions & 9 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1866,13 +1866,9 @@ if [ "$_MIGRATED" = true ]; then
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.6" unsloth-zoo
# Install pydantic WITH deps so pip pins pydantic-core to the
# exact version pydantic's own metadata requires. The --no-deps
# install below would otherwise pick the latest of each
# independently and trip pydantic's _ensure_pydantic_core_version
# check on the next import. pydantic's deps (annotated-types,
# pydantic-core, typing-extensions, typing-inspection) are
# torch-free, so this is safe on the no-torch path.
# Resolve pydantic WITH deps so pip pins pydantic-core to the
# matching version (no-torch-runtime.txt below is --no-deps).
# All transitive deps are torch-free.
run_install_cmd "install pydantic (with deps for compatible core)" \
uv pip install --python "$_VENV_PY" pydantic
_NO_TORCH_RT="$(_find_no_torch_runtime)"
Expand Down Expand Up @@ -2051,8 +2047,7 @@ elif [ -n "$TORCH_INDEX_URL" ]; then
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.6" unsloth-zoo
# Install pydantic WITH deps so pip pins pydantic-core to the
# exact version pydantic requires (see migrated branch above).
# Same pydantic-with-deps trick as the migrated branch.
run_install_cmd "install pydantic (with deps for compatible core)" \
uv pip install --python "$_VENV_PY" pydantic
_NO_TORCH_RT="$(_find_no_torch_runtime)"
Expand Down
18 changes: 5 additions & 13 deletions studio/backend/requirements/no-torch-runtime.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,11 @@ rich>=13.0
markdown-it-py>=3.0
mdurl>=0.1
pygments>=2.0
# pydantic is intentionally NOT installed via this --no-deps file.
# install.sh / install.ps1 / install_python_stack.py run a separate
# `pip install pydantic` (with deps) just before this file is
# applied, so pip resolves `pydantic-core` to the exact version
# pydantic's `_ensure_pydantic_core_version` check expects. Listing
# pydantic + pydantic-core unpinned here and resolving them under
# --no-deps used to pick the latest of each independently and trip
# `SystemError: pydantic-core 2.X.Y is incompatible with the current
# pydantic version` on the first import (Windows fresh-venv repro
# was the canonical case). pydantic's transitive deps
# (annotated-types, pydantic-core, typing-extensions,
# typing-inspection) are torch-free, so installing it WITH deps
# does not pull torch.
# pydantic is intentionally NOT pinned here. install.sh / install.ps1
# / install_python_stack.py run `pip install pydantic` WITH deps just
# before this --no-deps file is applied, so pip resolves pydantic-core
# to the exact version pydantic's _ensure_pydantic_core_version check
# expects. Pinning both under --no-deps used to drift them apart.
pyyaml
nest-asyncio

Expand Down
35 changes: 8 additions & 27 deletions studio/install_llama_prebuilt.py
Original file line number Diff line number Diff line change
Expand Up @@ -3827,37 +3827,18 @@ def paired_runtime_dll_patterns(choice: AssetChoice) -> list[str]:


def runtime_patterns_for_choice(choice: AssetChoice) -> list[str]:
# Broad shared-library glob + explicit binary names. Lets upstream
# repackage the SO/DLL set (e.g. ggml-org/llama.cpp#23462 split the
# per-binary entry code into paired ``lib<binary>-impl.so`` shared
# libraries between b9279 and b9283) without us re-enumerating
# every new file. Studio only invokes llama-server and llama-quantize;
# other CLIs upstream ships (llama-cli, llama-bench, ...) are skipped.
if choice.install_kind in {"linux-cpu", "linux-cuda", "linux-rocm"}:
return [
"llama-server",
"llama-quantize",
"libllama-common.so*",
"libllama.so*",
# Upstream llama.cpp split the per-binary entry code into
# paired ``libllama-<binary>-impl.so`` shared libraries
# around release b9261. ``llama-server`` and
# ``llama-quantize`` are NEEDED-linked against
# ``libllama-server-impl.so`` / ``libllama-quantize-impl.so``
# respectively, with RUNPATH ``$ORIGIN``. Without copying
# the impl ``.so`` files alongside the binaries, ldd
# reports them missing, preflight rejects the install, and
# the installer falls back to a source build on a fresh
# Linux install. Glob the whole family so future bundles
# that split additional binaries (e.g. ``llama-cli``,
# ``llama-bench``) keep working.
"libllama-*-impl.so*",
"libggml.so*",
"libggml-base.so*",
"libmtmd.so*",
"libggml-cpu-*.so*",
"libggml-cuda.so*",
"libggml-hip.so*",
"libggml-rpc.so*",
]
return ["llama-server", "llama-quantize", "lib*.so*"]
if choice.install_kind in {"macos-arm64", "macos-x64"}:
return ["llama-server", "llama-quantize", "lib*.dylib"]
if choice.install_kind in {"windows-cpu", "windows-cuda", "windows-hip"}:
return ["*.exe", "*.dll"]
return ["llama-server.exe", "llama-quantize.exe", "*.dll"]
raise PrebuiltFallback(
f"unsupported install kind for runtime overlay: {choice.install_kind}"
)
Expand Down
21 changes: 5 additions & 16 deletions studio/install_python_stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -979,22 +979,11 @@ def install_python_stack() -> int:
package_name,
"unsloth-zoo",
)
# Pydantic ships its core as a separate compiled wheel
# (pydantic-core), and pydantic's ``_ensure_pydantic_core_version``
# checks the installed core matches the exact version pinned in
# its own metadata. With ``--no-deps`` plus an unpinned
# ``pydantic`` / ``pydantic-core`` pair in no-torch-runtime.txt,
# pip resolved each to the newest available version and the two
# drifted (pydantic 2.13.4 pins pydantic-core==2.46.4 today, but
# pydantic-core 2.47.0 was the latest). On a fresh Windows venv
# the next ``import pydantic`` raised ``SystemError: ...
# incompatible with the current pydantic version``.
#
# Resolve them WITH deps in a focused pip call so pip picks a
# compatible pair. pydantic's own deps are
# ``annotated-types``, ``pydantic-core``, ``typing-extensions``,
# ``typing-inspection`` -- none of which transitively pull
# torch, so this is safe for the no-torch path.
# Resolve pydantic WITH deps so pip pins pydantic-core to the
# exact version pydantic's metadata declares. Under --no-deps
# alone pip picks the latest of each and trips pydantic's
# _ensure_pydantic_core_version check. Transitive deps are
# torch-free.
pip_install(
"Installing pydantic (with deps for compatible core)",
"--no-cache-dir",
Expand Down
23 changes: 12 additions & 11 deletions tests/studio/install/test_rocm_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,28 +346,26 @@ def test_linux_cpu_patterns(self):
patterns = runtime_patterns_for_choice(choice)
assert "llama-server" in patterns
assert "llama-quantize" in patterns
# Upstream split entry code into ``libllama-<binary>-impl.so``
# shared libraries (b9261+). llama-server and llama-quantize
# are NEEDED-linked against ``libllama-server-impl.so`` and
# ``libllama-quantize-impl.so`` respectively with RUNPATH
# ``$ORIGIN``, so the prebuilt overlay MUST copy them
# alongside the binaries or ldd reports them missing and
# preflight forces a source-build fallback.
assert "libllama-*-impl.so*" in patterns
# Broad lib*.so* covers libllama, libggml, libmtmd, libggml-cpu-*,
# plus the libllama-<binary>-impl.so split that ggml-org/llama.cpp
# #23462 introduced between b9279 and b9283.
assert "lib*.so*" in patterns

def test_linux_cuda_patterns(self):
choice = AssetChoice(
repo = "", tag = "", name = "", url = "", source_label = "", install_kind = "linux-cuda"
)
patterns = runtime_patterns_for_choice(choice)
assert "libggml-cuda.so*" in patterns
# libggml-cuda.so is matched by lib*.so* now.
assert "lib*.so*" in patterns

def test_linux_rocm_patterns(self):
choice = AssetChoice(
repo = "", tag = "", name = "", url = "", source_label = "", install_kind = "linux-rocm"
)
patterns = runtime_patterns_for_choice(choice)
assert "libggml-hip.so*" in patterns
# libggml-hip.so is matched by lib*.so* now.
assert "lib*.so*" in patterns
assert "llama-server" in patterns

def test_windows_hip_patterns(self):
Expand All @@ -380,7 +378,10 @@ def test_windows_hip_patterns(self):
install_kind = "windows-hip",
)
patterns = runtime_patterns_for_choice(choice)
assert "*.exe" in patterns
# Narrowed from "*.exe" to the two binaries Studio actually
# invokes, mirroring the Linux/macOS pattern style.
assert "llama-server.exe" in patterns
assert "llama-quantize.exe" in patterns
assert "*.dll" in patterns

def test_macos_patterns(self):
Expand Down
Loading