From f91ef8f9b048938dd22bb37e820855d7a97f7871 Mon Sep 17 00:00:00 2001 From: Roland Tannous <115670425+rolandtannous@users.noreply.github.com> Date: Fri, 3 Apr 2026 02:56:01 +0400 Subject: [PATCH] fix(studio): lazy-import transformers in model_config to fix 5.x version switch (#4806) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(studio): lazy-import AutoConfig in model_config.py to fix transformers 5.x version switch Move `from transformers import AutoConfig` from module level to inside load_model_config() where it is actually used. model_config.py is transitively imported at module load time via: core/inference/__init__ → llama_cpp → utils.models → model_config In inference subprocesses (mp.spawn), this chain runs before _activate_transformers_version() can prepend .venv_t5/ to sys.path. The eager import caches transformers 4.57.6 in sys.modules, and the subsequent sys.path change has no effect — Python always checks sys.modules before sys.path. Making the import lazy ensures transformers is not loaded until after version activation, so the subprocess picks up the correct version. * fix(studio): also lazy-import extract_model_size_b in llama_cpp.py Belt-and-suspenders: make the import that originally triggered the chain lazy as well, so future module-level AutoConfig additions in utils.models cannot reintroduce the problem. * [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> --- studio/backend/core/inference/llama_cpp.py | 10 ++++++++-- studio/backend/utils/models/model_config.py | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/studio/backend/core/inference/llama_cpp.py b/studio/backend/core/inference/llama_cpp.py index 44c700bf3d..d752500bf4 100644 --- a/studio/backend/core/inference/llama_cpp.py +++ b/studio/backend/core/inference/llama_cpp.py @@ -52,8 +52,14 @@ _REPROMPT_MAX_CHARS = 2000 _SHARD_FULL_RE = re.compile(r"^(.*)-(\d{5})-of-(\d{5})\.gguf$") _SHARD_RE = re.compile(r"^(.*)-\d{5}-of-\d{5}\.gguf$") -# Model size extraction (shared with routes/inference.py) -from utils.models import extract_model_size_b as _extract_model_size_b + +# Model size extraction — lazy import to avoid pulling in transformers +# at module level. See PR description for the full explanation. +def _extract_model_size_b(model_id: str): + from utils.models import extract_model_size_b + + return extract_model_size_b(model_id) + # ── Pre-compiled patterns for tool XML stripping ───────────── _TOOL_CLOSED_PATS = [ diff --git a/studio/backend/utils/models/model_config.py b/studio/backend/utils/models/model_config.py index df1058abf6..6cffc534aa 100644 --- a/studio/backend/utils/models/model_config.py +++ b/studio/backend/utils/models/model_config.py @@ -5,7 +5,6 @@ Model and LoRA configuration handling """ -from transformers import AutoConfig from dataclasses import dataclass from typing import Optional, Dict, Any from utils.paths import ( @@ -422,6 +421,7 @@ def load_model_config( """ Load model config with optional authentication control. """ + from transformers import AutoConfig if token: # Explicit token provided - use it