diff --git a/pyproject.toml b/pyproject.toml index 5687ea12f8..35a32f9998 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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", diff --git a/studio/backend/tests/test_transformers_version.py b/studio/backend/tests/test_transformers_version.py index c031c2fea3..b7e9728081 100644 --- a/studio/backend/tests/test_transformers_version.py +++ b/studio/backend/tests/test_transformers_version.py @@ -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( diff --git a/studio/backend/utils/models/model_config.py b/studio/backend/utils/models/model_config.py index 16f6d21edb..93fa46b595 100644 --- a/studio/backend/utils/models/model_config.py +++ b/studio/backend/utils/models/model_config.py @@ -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. diff --git a/studio/backend/utils/transformers_version.py b/studio/backend/utils/transformers_version.py index 17af40f663..16c72a20db 100644 --- a/studio/backend/utils/transformers_version.py +++ b/studio/backend/utils/transformers_version.py @@ -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 diff --git a/studio/setup.ps1 b/studio/setup.ps1 index 3d082aa70d..dc0d860f42 100644 --- a/studio/setup.ps1 +++ b/studio/setup.ps1 @@ -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 diff --git a/studio/setup.sh b/studio/setup.sh index 3e875eed30..cff62a1cce 100755 --- a/studio/setup.sh +++ b/studio/setup.sh @@ -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