Compare commits

...
Sign in to create a new pull request.

1 commit

Author SHA1 Message Date
Roland Tannous
36bd2de0ed Studio: bump pinned transformers 5.5.0 → 5.5.2 in tiered venv
Renames the .venv_t5_550 / VENV_T5_550 / `"550"` tier identifiers to
_552 throughout setup.{sh,ps1}, transformers_version.py, model_config.py,
and the matching tests. Bumps pyproject.toml's transformers upper bound
to <=5.5.2 so the new pin resolves. Adds legacy .venv_t5_550 cleanup in
both setup scripts so existing installs migrate cleanly.
2026-05-04 22:12:23 +04:00
6 changed files with 124 additions and 112 deletions

View file

@ -83,7 +83,7 @@ huggingfacenotorch = [
"huggingface_hub>=0.34.0",
"hf_transfer",
"diffusers",
"transformers>=4.51.3,!=4.52.0,!=4.52.1,!=4.52.2,!=4.52.3,!=4.53.0,!=4.54.0,!=4.55.0,!=4.55.1,!=4.57.0,!=4.57.4,!=4.57.5,!=5.0.0,!=5.1.0,<=5.5.0",
"transformers>=4.51.3,!=4.52.0,!=4.52.1,!=4.52.2,!=4.52.3,!=4.53.0,!=4.54.0,!=4.55.0,!=4.55.1,!=4.57.0,!=4.57.4,!=4.57.5,!=5.0.0,!=5.1.0,<=5.5.2",
"trl>=0.18.2,!=0.19.0,<=0.24.0",
"sentence-transformers",
]
@ -582,7 +582,7 @@ colab-new = [
"unsloth_zoo>=2026.4.8",
"packaging",
"tyro",
"transformers>=4.51.3,!=4.52.0,!=4.52.1,!=4.52.2,!=4.52.3,!=4.53.0,!=4.54.0,!=4.55.0,!=4.55.1,!=4.57.0,!=4.57.4,!=4.57.5,!=5.0.0,!=5.1.0,<=5.5.0",
"transformers>=4.51.3,!=4.52.0,!=4.52.1,!=4.52.2,!=4.52.3,!=4.53.0,!=4.54.0,!=4.55.0,!=4.55.1,!=4.57.0,!=4.57.4,!=4.57.5,!=5.0.0,!=5.1.0,<=5.5.2",
"datasets>=3.4.1,!=4.0.*,!=4.1.0,<4.4.0",
"sentencepiece>=0.2.0",
"tqdm",

View file

@ -31,9 +31,9 @@ sys.modules.setdefault("loggers", _loggers_stub)
from utils.transformers_version import (
_resolve_base_model,
_check_tokenizer_config_needs_v5,
_check_config_needs_550,
_check_config_needs_552,
_tokenizer_class_cache,
_config_needs_550_cache,
_config_needs_552_cache,
needs_transformers_5,
get_transformers_tier,
)
@ -194,15 +194,15 @@ class TestNeedsTransformers5:
# ---------------------------------------------------------------------------
# _check_config_needs_550 — config.json architecture/model_type check
# _check_config_needs_552 — config.json architecture/model_type check
# ---------------------------------------------------------------------------
class TestCheckConfigNeeds550:
"""Tests for _check_config_needs_550() local config.json checks."""
class TestCheckConfigNeeds552:
"""Tests for _check_config_needs_552() local config.json checks."""
def setup_method(self):
_config_needs_550_cache.clear()
_config_needs_552_cache.clear()
def test_gemma4_architecture(self, tmp_path: Path):
"""config.json with Gemma4ForConditionalGeneration should return True."""
@ -212,28 +212,28 @@ class TestCheckConfigNeeds550:
}
(tmp_path / "config.json").write_text(json.dumps(cfg))
assert _check_config_needs_550(str(tmp_path)) is True
assert _check_config_needs_552(str(tmp_path)) is True
def test_gemma4_model_type_only(self, tmp_path: Path):
"""config.json with model_type=gemma4 (no architectures) should return True."""
cfg = {"model_type": "gemma4"}
(tmp_path / "config.json").write_text(json.dumps(cfg))
assert _check_config_needs_550(str(tmp_path)) is True
assert _check_config_needs_552(str(tmp_path)) is True
def test_llama_architecture(self, tmp_path: Path):
"""config.json with LlamaForCausalLM should return False."""
cfg = {"architectures": ["LlamaForCausalLM"], "model_type": "llama"}
(tmp_path / "config.json").write_text(json.dumps(cfg))
assert _check_config_needs_550(str(tmp_path)) is False
assert _check_config_needs_552(str(tmp_path)) is False
def test_no_config_json(self, tmp_path: Path):
"""Missing config.json should return False (fail-open)."""
# Patch network call to avoid real fetch
with patch("urllib.request.urlopen") as mock_urlopen:
mock_urlopen.side_effect = Exception("no network")
assert _check_config_needs_550(str(tmp_path)) is False
assert _check_config_needs_552(str(tmp_path)) is False
def test_result_is_cached(self, tmp_path: Path):
"""Subsequent calls should use the cache."""
@ -241,9 +241,9 @@ class TestCheckConfigNeeds550:
(tmp_path / "config.json").write_text(json.dumps(cfg))
key = str(tmp_path)
_check_config_needs_550(key)
assert key in _config_needs_550_cache
assert _config_needs_550_cache[key] is True
_check_config_needs_552(key)
assert key in _config_needs_552_cache
assert _config_needs_552_cache[key] is True
def test_local_file_skips_network(self, tmp_path: Path):
"""When local config.json exists, no network request should be made."""
@ -251,7 +251,7 @@ class TestCheckConfigNeeds550:
(tmp_path / "config.json").write_text(json.dumps(cfg))
with patch("urllib.request.urlopen") as mock_urlopen:
_check_config_needs_550(str(tmp_path))
_check_config_needs_552(str(tmp_path))
mock_urlopen.assert_not_called()
@ -265,34 +265,34 @@ class TestGetTransformersTier:
def setup_method(self):
_tokenizer_class_cache.clear()
_config_needs_550_cache.clear()
_config_needs_552_cache.clear()
def test_gemma4_substring_returns_550(self):
assert get_transformers_tier("google/gemma-4-E2B-it") == "550"
def test_gemma4_substring_returns_552(self):
assert get_transformers_tier("google/gemma-4-E2B-it") == "552"
def test_gemma4_alt_substring_returns_550(self):
assert get_transformers_tier("unsloth/gemma4-E4B-it") == "550"
def test_gemma4_alt_substring_returns_552(self):
assert get_transformers_tier("unsloth/gemma4-E4B-it") == "552"
def test_gemma4_config_json_returns_550(self, tmp_path: Path):
"""Local checkpoint with Gemma4 architecture → 550."""
def test_gemma4_config_json_returns_552(self, tmp_path: Path):
"""Local checkpoint with Gemma4 architecture → 552."""
cfg = {
"architectures": ["Gemma4ForConditionalGeneration"],
"model_type": "gemma4",
}
(tmp_path / "config.json").write_text(json.dumps(cfg))
assert get_transformers_tier(str(tmp_path)) == "550"
assert get_transformers_tier(str(tmp_path)) == "552"
def test_qwen35_returns_530(self):
with patch(
"utils.transformers_version._check_config_needs_550",
"utils.transformers_version._check_config_needs_552",
return_value = False,
):
assert get_transformers_tier("Qwen/Qwen3.5-9B") == "530"
def test_ministral_returns_530(self):
with patch(
"utils.transformers_version._check_config_needs_550",
"utils.transformers_version._check_config_needs_552",
return_value = False,
):
assert (
@ -302,7 +302,7 @@ class TestGetTransformersTier:
def test_llama_returns_default(self):
with (
patch(
"utils.transformers_version._check_config_needs_550",
"utils.transformers_version._check_config_needs_552",
return_value = False,
),
patch(
@ -312,22 +312,22 @@ class TestGetTransformersTier:
):
assert get_transformers_tier("meta-llama/Llama-3-8B") == "default"
def test_550_checked_before_530(self):
"""Ensure 5.5.0 is checked first — a model matching both should get 550."""
def test_552_checked_before_530(self):
"""Ensure 5.5.2 is checked first — a model matching both should get 552."""
# This shouldn't happen in practice, but verifies priority
assert get_transformers_tier("gemma-4-model") == "550"
assert get_transformers_tier("gemma-4-model") == "552"
def test_needs_transformers_5_compat(self):
"""needs_transformers_5 should return True for both 530 and 550 models."""
"""needs_transformers_5 should return True for both 530 and 552 models."""
assert needs_transformers_5("google/gemma-4-E2B-it") is True
with patch(
"utils.transformers_version._check_config_needs_550",
"utils.transformers_version._check_config_needs_552",
return_value = False,
):
assert needs_transformers_5("Qwen/Qwen3.5-9B") is True
with (
patch(
"utils.transformers_version._check_config_needs_550",
"utils.transformers_version._check_config_needs_552",
return_value = False,
),
patch(

View file

@ -499,8 +499,8 @@ _VLM_MODEL_TYPES = {
}
# Pre-computed .venv_t5 paths and backend dir for subprocess version switching.
# Vision check uses 5.5.0 (newest, recognizes all architectures).
_VENV_T5_DIR = str(Path.home() / ".unsloth" / "studio" / ".venv_t5_550")
# Vision check uses 5.5.2 (newest, recognizes all architectures).
_VENV_T5_DIR = str(Path.home() / ".unsloth" / "studio" / ".venv_t5_552")
_BACKEND_DIR = str(Path(__file__).resolve().parent.parent.parent)
# Inline script executed in a subprocess with transformers 5.x activated.

View file

@ -11,7 +11,7 @@ with Unsloth.
Two separate target directories are maintained:
- .venv_t5_530/ transformers 5.3.0 (Ministral-3, GLM, Qwen3 MoE, etc.)
- .venv_t5_550/ transformers 5.5.0 (Gemma 4)
- .venv_t5_552/ transformers 5.5.2 (Gemma 4)
When loading a LoRA adapter with a custom name, we resolve the base model from
``adapter_config.json`` and check *that* against the model list.
@ -61,7 +61,7 @@ TRANSFORMERS_5_MODEL_SUBSTRINGS: tuple[str, ...] = (
)
# Lowercase substrings for models that require transformers 5.5.0 (checked first).
TRANSFORMERS_550_MODEL_SUBSTRINGS: tuple[str, ...] = (
TRANSFORMERS_552_MODEL_SUBSTRINGS: tuple[str, ...] = (
"gemma-4", # Gemma-4 (E2B-it, E4B-it, 31B-it, 26B-A4B-it)
"gemma4", # Gemma-4 alternate naming
"qwen3.6",
@ -69,10 +69,10 @@ TRANSFORMERS_550_MODEL_SUBSTRINGS: tuple[str, ...] = (
# Architecture classes / model_type values that require transformers 5.5.0.
# Checked via config.json (local or HuggingFace).
_TRANSFORMERS_550_ARCHITECTURES: set[str] = {
_TRANSFORMERS_552_ARCHITECTURES: set[str] = {
"Gemma4ForConditionalGeneration",
}
_TRANSFORMERS_550_MODEL_TYPES: set[str] = {
_TRANSFORMERS_552_MODEL_TYPES: set[str] = {
"gemma4",
}
@ -85,21 +85,21 @@ _TRANSFORMERS_5_TOKENIZER_CLASSES: set[str] = {
_tokenizer_class_cache: dict[str, bool] = {}
# Cache for dynamic config.json lookups (architecture/model_type checks)
_config_needs_550_cache: dict[str, bool] = {}
_config_needs_552_cache: dict[str, bool] = {}
# Versions
TRANSFORMERS_550_VERSION = "5.5.0"
TRANSFORMERS_552_VERSION = "5.5.2"
TRANSFORMERS_530_VERSION = "5.3.0"
TRANSFORMERS_DEFAULT_VERSION = "4.57.6"
# Backwards-compat alias — points to 5.5.0 (the highest 5.x tier).
# Consumers should prefer TRANSFORMERS_530_VERSION / TRANSFORMERS_550_VERSION.
TRANSFORMERS_5_VERSION = TRANSFORMERS_550_VERSION
# Backwards-compat alias — points to 5.5.2 (the highest 5.x tier).
# Consumers should prefer TRANSFORMERS_530_VERSION / TRANSFORMERS_552_VERSION.
TRANSFORMERS_5_VERSION = TRANSFORMERS_552_VERSION
# Pre-installed directories — created by setup.sh / setup.ps1
_VENV_T5_530_DIR = str(Path.home() / ".unsloth" / "studio" / ".venv_t5_530")
_VENV_T5_550_DIR = str(Path.home() / ".unsloth" / "studio" / ".venv_t5_550")
_VENV_T5_552_DIR = str(Path.home() / ".unsloth" / "studio" / ".venv_t5_552")
# Backwards-compat alias
_VENV_T5_DIR = _VENV_T5_550_DIR
_VENV_T5_DIR = _VENV_T5_552_DIR
def activate_transformers_for_subprocess(model_name: str) -> None:
@ -115,17 +115,17 @@ def activate_transformers_for_subprocess(model_name: str) -> None:
resolved = _resolve_base_model(model_name)
tier = get_transformers_tier(resolved)
if tier == "550":
if not _ensure_venv_t5_550_exists():
if tier == "552":
if not _ensure_venv_t5_552_exists():
raise RuntimeError(
f"Cannot activate transformers 5.5.0: "
f".venv_t5_550 missing at {_VENV_T5_550_DIR}"
f"Cannot activate transformers 5.5.2: "
f".venv_t5_552 missing at {_VENV_T5_552_DIR}"
)
if _VENV_T5_550_DIR not in sys.path:
sys.path.insert(0, _VENV_T5_550_DIR)
logger.info("Activated transformers 5.5.0 from %s", _VENV_T5_550_DIR)
if _VENV_T5_552_DIR not in sys.path:
sys.path.insert(0, _VENV_T5_552_DIR)
logger.info("Activated transformers 5.5.2 from %s", _VENV_T5_552_DIR)
_pp = os.environ.get("PYTHONPATH", "")
os.environ["PYTHONPATH"] = _VENV_T5_550_DIR + (os.pathsep + _pp if _pp else "")
os.environ["PYTHONPATH"] = _VENV_T5_552_DIR + (os.pathsep + _pp if _pp else "")
elif tier == "530":
if not _ensure_venv_t5_530_exists():
raise RuntimeError(
@ -266,22 +266,22 @@ def _check_tokenizer_config_needs_v5(model_name: str) -> bool:
return False
def _check_config_needs_550(model_name: str) -> bool:
def _check_config_needs_552(model_name: str) -> bool:
"""Check ``config.json`` for architectures or model_type that require
transformers 5.5.0 (e.g. Gemma 4).
Checks locally first, then falls back to fetching from HuggingFace.
Results are cached in ``_config_needs_550_cache``.
Results are cached in ``_config_needs_552_cache``.
Returns False on any error (fail-open to lower tier).
"""
if model_name in _config_needs_550_cache:
return _config_needs_550_cache[model_name]
if model_name in _config_needs_552_cache:
return _config_needs_552_cache[model_name]
def _check_cfg(cfg: dict) -> bool:
archs = cfg.get("architectures", [])
if any(a in _TRANSFORMERS_550_ARCHITECTURES for a in archs):
if any(a in _TRANSFORMERS_552_ARCHITECTURES for a in archs):
return True
if cfg.get("model_type") in _TRANSFORMERS_550_MODEL_TYPES:
if cfg.get("model_type") in _TRANSFORMERS_552_MODEL_TYPES:
return True
return False
@ -301,7 +301,7 @@ def _check_config_needs_550(model_name: str) -> bool:
cfg.get("architectures", []),
cfg.get("model_type"),
)
_config_needs_550_cache[model_name] = result
_config_needs_552_cache[model_name] = result
return result
except Exception as exc:
logger.debug("Could not read %s: %s", local_cfg, exc)
@ -323,34 +323,34 @@ def _check_config_needs_550(model_name: str) -> bool:
cfg.get("architectures", []),
cfg.get("model_type"),
)
_config_needs_550_cache[model_name] = result
_config_needs_552_cache[model_name] = result
return result
except Exception as exc:
logger.debug("Could not fetch config.json for '%s': %s", model_name, exc)
_config_needs_550_cache[model_name] = False
_config_needs_552_cache[model_name] = False
return False
def get_transformers_tier(model_name: str) -> str:
"""Return the transformers tier required for *model_name*.
Returns ``"550"`` for models needing transformers 5.5.0 (e.g. Gemma 4),
Returns ``"552"`` for models needing transformers 5.5.0 (e.g. Gemma 4),
``"530"`` for models needing transformers 5.3.0 (e.g. Ministral-3, Qwen3 MoE),
or ``"default"`` for everything else (4.57.x).
The 5.5.0 check runs first, then 5.3.0.
The 5.5.2 check runs first, then 5.3.0.
"""
lowered = model_name.lower()
# --- Fast substring checks (no I/O) ------------------------------------
if any(sub in lowered for sub in TRANSFORMERS_550_MODEL_SUBSTRINGS):
return "550"
if any(sub in lowered for sub in TRANSFORMERS_552_MODEL_SUBSTRINGS):
return "552"
if any(sub in lowered for sub in TRANSFORMERS_5_MODEL_SUBSTRINGS):
return "530"
# --- Slow config fallbacks (local file first, then network) -----------
if _check_config_needs_550(model_name):
return "550"
if _check_config_needs_552(model_name):
return "552"
if _check_tokenizer_config_needs_v5(model_name):
return "530"
@ -424,15 +424,15 @@ _VENV_T5_530_PACKAGES = (
"tiktoken",
)
_VENV_T5_550_PACKAGES = (
f"transformers=={TRANSFORMERS_550_VERSION}",
_VENV_T5_552_PACKAGES = (
f"transformers=={TRANSFORMERS_552_VERSION}",
"huggingface_hub==1.8.0",
"hf_xet==1.4.2",
"tiktoken",
)
# Backwards-compat alias
_VENV_T5_PACKAGES = _VENV_T5_550_PACKAGES
_VENV_T5_PACKAGES = _VENV_T5_552_PACKAGES
def _venv_dir_is_valid(venv_dir: str, packages: tuple[str, ...]) -> bool:
@ -481,8 +481,8 @@ def _venv_dir_is_valid(venv_dir: str, packages: tuple[str, ...]) -> bool:
def _venv_t5_is_valid() -> bool:
"""Backwards-compat: check the 5.5.0 venv."""
return _venv_dir_is_valid(_VENV_T5_550_DIR, _VENV_T5_550_PACKAGES)
"""Backwards-compat: check the 5.5.2 venv."""
return _venv_dir_is_valid(_VENV_T5_552_DIR, _VENV_T5_552_PACKAGES)
def _install_to_dir(pkg: str, target_dir: str) -> bool:
@ -561,16 +561,16 @@ def _ensure_venv_t5_530_exists() -> bool:
)
def _ensure_venv_t5_550_exists() -> bool:
"""Ensure .venv_t5_550/ exists with transformers 5.5.0."""
def _ensure_venv_t5_552_exists() -> bool:
"""Ensure .venv_t5_552/ exists with transformers 5.5.2."""
return _ensure_venv_dir(
_VENV_T5_550_DIR, _VENV_T5_550_PACKAGES, "transformers 5.5.0"
_VENV_T5_552_DIR, _VENV_T5_552_PACKAGES, "transformers 5.5.2"
)
def _ensure_venv_t5_exists() -> bool:
"""Backwards-compat: ensure the 5.5.0 venv exists."""
return _ensure_venv_t5_550_exists()
"""Backwards-compat: ensure the 5.5.2 venv exists."""
return _ensure_venv_t5_552_exists()
def _activate_venv(venv_dir: str, label: str) -> None:
@ -589,7 +589,7 @@ def _activate_venv(venv_dir: str, label: str) -> None:
def _deactivate_5x() -> None:
"""Remove all .venv_t5_*/ dirs from sys.path, purge stale modules, reimport."""
for d in (_VENV_T5_530_DIR, _VENV_T5_550_DIR):
for d in (_VENV_T5_530_DIR, _VENV_T5_552_DIR):
while d in sys.path:
sys.path.remove(d)
logger.info("Removed venv_t5 dirs from sys.path")
@ -605,8 +605,8 @@ def _deactivate_5x() -> None:
def ensure_transformers_version(model_name: str) -> None:
"""Ensure the correct ``transformers`` version is active for *model_name*.
Uses sys.path with .venv_t5_530/ or .venv_t5_550/ (pre-installed by setup.sh):
Need 5.5.0 prepend .venv_t5_550/ to sys.path, purge modules.
Uses sys.path with .venv_t5_530/ or .venv_t5_552/ (pre-installed by setup.sh):
Need 5.5.2 prepend .venv_t5_552/ to sys.path, purge modules.
Need 5.3.0 prepend .venv_t5_530/ to sys.path, purge modules.
Need 4.x remove all .venv_t5_*/ from sys.path, purge modules.
@ -620,10 +620,10 @@ def ensure_transformers_version(model_name: str) -> None:
resolved = _resolve_base_model(model_name)
tier = get_transformers_tier(resolved)
if tier == "550":
target_version = TRANSFORMERS_550_VERSION
venv_dir = _VENV_T5_550_DIR
ensure_fn = _ensure_venv_t5_550_exists
if tier == "552":
target_version = TRANSFORMERS_552_VERSION
venv_dir = _VENV_T5_552_DIR
ensure_fn = _ensure_venv_t5_552_exists
elif tier == "530":
target_version = TRANSFORMERS_530_VERSION
venv_dir = _VENV_T5_530_DIR
@ -655,7 +655,7 @@ def ensure_transformers_version(model_name: str) -> None:
model_name,
)
return
# Different 5.x → need to switch (e.g. 5.3.0 loaded but need 5.5.0)
# Different 5.x → need to switch (e.g. 5.3.0 loaded but need 5.5.2)
in_memory_major = int(in_memory.split(".")[0])
if in_memory_major == target_major and venv_dir is None:
# Both are default (4.x) — close enough

View file

@ -1756,20 +1756,26 @@ if ($stackExit -ne 0) {
$ErrorActionPreference = $prevEAP
}
# ── Pre-install transformers 5.x into .venv_t5_530/ and .venv_t5_550/ ──
# ── Pre-install transformers 5.x into .venv_t5_530/ and .venv_t5_552/ ──
# Runs outside the deps fast-path gate so that upgrades from the legacy
# single .venv_t5 are always migrated to the tiered layout.
$VenvT5_530Dir = Join-Path $env:USERPROFILE ".unsloth\studio\.venv_t5_530"
$VenvT5_550Dir = Join-Path $env:USERPROFILE ".unsloth\studio\.venv_t5_550"
$VenvT5_552Dir = Join-Path $env:USERPROFILE ".unsloth\studio\.venv_t5_552"
$VenvT5Legacy = Join-Path $env:USERPROFILE ".unsloth\studio\.venv_t5"
$VenvT5_550Legacy = Join-Path $env:USERPROFILE ".unsloth\studio\.venv_t5_550"
$_NeedT5Install = $false
if (Test-Path $VenvT5Legacy) {
Remove-Item -Recurse -Force $VenvT5Legacy
$_NeedT5Install = $true
}
if (Test-Path $VenvT5_550Legacy) {
# Older 5.5.0 dir — supersede with .venv_t5_552
Remove-Item -Recurse -Force $VenvT5_550Legacy
$_NeedT5Install = $true
}
if (-not (Test-Path $VenvT5_530Dir)) { $_NeedT5Install = $true }
if (-not (Test-Path $VenvT5_550Dir)) { $_NeedT5Install = $true }
if (-not (Test-Path $VenvT5_552Dir)) { $_NeedT5Install = $true }
# Also reinstall when python deps were updated
if (-not $SkipPythonDeps) { $_NeedT5Install = $true }
@ -1812,39 +1818,39 @@ if ($tiktokenInstallExit -ne 0) {
}
step "transformers" "5.3.0 pre-installed"
# --- .venv_t5_550 (transformers 5.5.0) ---
substep "pre-installing transformers 5.5.0 for Gemma 4 support..."
if (Test-Path $VenvT5_550Dir) { Remove-Item -Recurse -Force $VenvT5_550Dir }
New-Item -ItemType Directory -Path $VenvT5_550Dir -Force | Out-Null
foreach ($pkg in @("transformers==5.5.0", "huggingface_hub==1.8.0", "hf_xet==1.4.2")) {
# --- .venv_t5_552 (transformers 5.5.2) ---
substep "pre-installing transformers 5.5.2 for Gemma 4 support..."
if (Test-Path $VenvT5_552Dir) { Remove-Item -Recurse -Force $VenvT5_552Dir }
New-Item -ItemType Directory -Path $VenvT5_552Dir -Force | Out-Null
foreach ($pkg in @("transformers==5.5.2", "huggingface_hub==1.8.0", "hf_xet==1.4.2")) {
if ($script:UnslothVerbose) {
Fast-Install --target $VenvT5_550Dir --no-deps $pkg
Fast-Install --target $VenvT5_552Dir --no-deps $pkg
$t5PkgExit = $LASTEXITCODE
$output = ""
} else {
$output = Fast-Install --target $VenvT5_550Dir --no-deps $pkg | Out-String
$output = Fast-Install --target $VenvT5_552Dir --no-deps $pkg | Out-String
$t5PkgExit = $LASTEXITCODE
}
if ($t5PkgExit -ne 0) {
Write-Host "[FAIL] Could not install $pkg into .venv_t5_550/" -ForegroundColor Red
Write-Host "[FAIL] Could not install $pkg into .venv_t5_552/" -ForegroundColor Red
Write-Host $output -ForegroundColor Red
$ErrorActionPreference = $prevEAP_t5
exit 1
}
}
if ($script:UnslothVerbose) {
Fast-Install --target $VenvT5_550Dir tiktoken
Fast-Install --target $VenvT5_552Dir tiktoken
$tiktokenInstallExit = $LASTEXITCODE
$output = ""
} else {
$output = Fast-Install --target $VenvT5_550Dir tiktoken | Out-String
$output = Fast-Install --target $VenvT5_552Dir tiktoken | Out-String
$tiktokenInstallExit = $LASTEXITCODE
}
if ($tiktokenInstallExit -ne 0) {
substep "Could not install tiktoken into .venv_t5_550/ -- Qwen tokenizers may fail" "Yellow"
substep "Could not install tiktoken into .venv_t5_552/ -- Qwen tokenizers may fail" "Yellow"
}
$ErrorActionPreference = $prevEAP_t5
step "transformers" "5.5.0 pre-installed"
step "transformers" "5.5.2 pre-installed"
} # end $_NeedT5Install

View file

@ -420,13 +420,14 @@ fi
STUDIO_HOME="$HOME/.unsloth/studio"
VENV_DIR="$STUDIO_HOME/unsloth_studio"
VENV_T5_530_DIR="$STUDIO_HOME/.venv_t5_530"
VENV_T5_550_DIR="$STUDIO_HOME/.venv_t5_550"
VENV_T5_552_DIR="$STUDIO_HOME/.venv_t5_552"
[ -d "$REPO_ROOT/.venv" ] && rm -rf "$REPO_ROOT/.venv"
[ -d "$REPO_ROOT/.venv_overlay" ] && rm -rf "$REPO_ROOT/.venv_overlay"
[ -d "$REPO_ROOT/.venv_t5" ] && rm -rf "$REPO_ROOT/.venv_t5"
[ -d "$REPO_ROOT/.venv_t5_530" ] && rm -rf "$REPO_ROOT/.venv_t5_530"
[ -d "$REPO_ROOT/.venv_t5_550" ] && rm -rf "$REPO_ROOT/.venv_t5_550"
[ -d "$REPO_ROOT/.venv_t5_552" ] && rm -rf "$REPO_ROOT/.venv_t5_552"
# Note: do NOT delete $STUDIO_HOME/.venv here — install.sh handles migration
_COLAB_NO_VENV=false
@ -534,7 +535,7 @@ else
verbose_substep "python deps check: installed=$_PKG_NAME@${INSTALLED_VER:-unknown} latest=${LATEST_VER:-unknown}"
fi
# ── 6b. Pre-install transformers 5.x into .venv_t5_530/ and .venv_t5_550/ ──
# ── 6b. Pre-install transformers 5.x into .venv_t5_530/ and .venv_t5_552/ ──
# Models like GLM-4.7-Flash, Qwen3 MoE need transformers>=5.3.0.
# Gemma 4 models need transformers>=5.5.0.
# Pre-install into separate directories to avoid runtime pip overhead.
@ -548,8 +549,13 @@ if [ -d "$STUDIO_HOME/.venv_t5" ]; then
rm -rf "$STUDIO_HOME/.venv_t5"
_NEED_T5_INSTALL=true
fi
if [ -d "$STUDIO_HOME/.venv_t5_550" ]; then
# Older 5.5.0 dir — supersede with .venv_t5_552
rm -rf "$STUDIO_HOME/.venv_t5_550"
_NEED_T5_INSTALL=true
fi
[ ! -d "$VENV_T5_530_DIR" ] && _NEED_T5_INSTALL=true
[ ! -d "$VENV_T5_550_DIR" ] && _NEED_T5_INSTALL=true
[ ! -d "$VENV_T5_552_DIR" ] && _NEED_T5_INSTALL=true
# Also reinstall when python deps were updated (packages may need rebuild)
[ "$_SKIP_PYTHON_DEPS" = false ] && _NEED_T5_INSTALL=true
@ -562,13 +568,13 @@ if [ "$_NEED_T5_INSTALL" = true ]; then
run_quiet "install tiktoken for t5_530" fast_install --target "$VENV_T5_530_DIR" "tiktoken"
step "transformers" "5.3.0 pre-installed"
[ -d "$VENV_T5_550_DIR" ] && rm -rf "$VENV_T5_550_DIR"
mkdir -p "$VENV_T5_550_DIR"
run_quiet "install transformers 5.5.0" fast_install --target "$VENV_T5_550_DIR" --no-deps "transformers==5.5.0"
run_quiet "install huggingface_hub for t5_550" fast_install --target "$VENV_T5_550_DIR" --no-deps "huggingface_hub==1.8.0"
run_quiet "install hf_xet for t5_550" fast_install --target "$VENV_T5_550_DIR" --no-deps "hf_xet==1.4.2"
run_quiet "install tiktoken for t5_550" fast_install --target "$VENV_T5_550_DIR" "tiktoken"
step "transformers" "5.5.0 pre-installed"
[ -d "$VENV_T5_552_DIR" ] && rm -rf "$VENV_T5_552_DIR"
mkdir -p "$VENV_T5_552_DIR"
run_quiet "install transformers 5.5.2" fast_install --target "$VENV_T5_552_DIR" --no-deps "transformers==5.5.2"
run_quiet "install huggingface_hub for t5_552" fast_install --target "$VENV_T5_552_DIR" --no-deps "huggingface_hub==1.8.0"
run_quiet "install hf_xet for t5_552" fast_install --target "$VENV_T5_552_DIR" --no-deps "hf_xet==1.4.2"
run_quiet "install tiktoken for t5_552" fast_install --target "$VENV_T5_552_DIR" "tiktoken"
step "transformers" "5.5.2 pre-installed"
fi
fi