* Studio: detect transformers 5.3.0 tier from config.json for local checkpoints
A local safetensors folder whose config.json did not match the Gemma4 (510/550)
architecture signals short-circuited get_transformers_tier() to "default"
(transformers 4.57.x), never reaching the name-substring check that routes
Qwen3.5 to the 5.3.0 sidecar. So a local Qwen3.5 checkpoint (model_type
"qwen3_5", needs transformers >= 5.2.0) loaded with 4.57.x and failed with
"does not support Qwen3.5". The same model as a remote HF id worked, because it
has no local config.json to trigger the short-circuit.
Detect the 5.3.0 tier from config.json (model_type "qwen3_5" / architecture
Qwen3_5ForCausalLM) in the local-config branch, mirroring the existing Gemma4
510/550 handling. This is a positive config signal, so it fixes local Qwen3.5
without weakening the directory-name false-positive guard (a llama checkpoint
under a "gemma-4-12b-*" parent still resolves to default).
Adds tests for the config-based 530 detection and local-folder tier resolution.
* Studio: suppress false warning when config.json parse fails for sidecar-tier models
* Studio: generalize local-checkpoint tier detection for all 5.3.0 families
Expands the config.json-based tier detection to cover all known 5.3.0-tier
model families (Qwen3 MoE, GLM-4.7-Flash, LFM2.5-VL) and adds a _name_or_path
fallback so renamed local checkpoints with unrecognised model_type values still
route correctly via the HF ID embedded in their config.json.
- Expand _TRANSFORMERS_530_ARCHITECTURES / _MODEL_TYPES with verified entries
from Qwen3MoeForCausalLM, Glm4MoeLiteForCausalLM, Lfm2VlForConditionalGeneration,
and Qwen3_5ForConditionalGeneration (confirmed from local Qwen3.5-2B config.json)
- Extract _tier_from_name() helper, deduplicating the fast-substring logic used
by both the remote-path branch and the new config _name_or_path fallback
- In the local-config branch: after architecture checks, resolve the tier from
cfg._name_or_path / cfg.model_name before returning "default", preserving the
existing directory-name false-positive guard
- 79 tests passing
* Studio: match 510/550 style for 530 config sets (no inline comments)
* Studio: use _resolve_base_model instead of reinlining _name_or_path lookup
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Studio: recurse into get_transformers_tier for resolved base model (Gemini suggestion)
* Studio: use _tier_from_name in local-config fallback to avoid network probes
Using get_transformers_tier(resolved) on the _name_or_path fallback would
trigger up to 3 network fetches (config.json + tokenizer_config.json, 10s
each) for every ordinary checkpoint whose _name_or_path is a plain HF ID
like meta-llama/Llama-3-8B. The fallback's purpose is name-based detection
on the resolved HF ID, _tier_from_name covers all known cases without I/O.
* Studio: add _check_config_needs_530 to slow HF-ID fallback path
Private or renamed HF repos whose model IDs lack a 5.3 substring were
silently routed to the default tier. _check_config_needs_530 mirrors the
existing 510/550 pattern: fetches config.json once, caches the result, and
is called after the 550 check in the slow path. Includes 5 unit tests.
* Studio: guard _tier_from_name fallback against local-path false positives
When _name_or_path in config.json is an absolute path to the same checkpoint
passed as a relative path, the textual resolved != model_name check passes
and _tier_from_name would scan the directory path for substrings. Split the
fallback: local directories recurse into get_transformers_tier (config check,
no network I/O); HF Hub IDs use _tier_from_name (name-based, no network).
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Studio: separator-norm aliases, model_name/_name_or_path fallback, tests
- _norm_separators(): collapse _ . whitespace to - so underscore/dot model
ID variants (Qwen3_5, Qwen3_Next) match the canonical substring list
- _tier_from_name(): apply norm to both name and each substring so aliases
resolve without duplicating the substring lists
- _resolve_base_model(): try model_name then _name_or_path separately so a
self-referential Unsloth model_name doesn't hide the useful HF ID in
_name_or_path
- Gate get_base_model_from_lora on adapter_cfg_path.is_file() to avoid
eagerly importing transformers before the sidecar venv is on sys.path
- 17 new tests covering _norm_separators, separator-insensitive
_tier_from_name, and the model_name/_name_or_path fallback
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Studio: only pre-resolve LoRA adapters in activation callers
activate_transformers_for_subprocess and ensure_transformers_version were
pre-resolving all local checkpoints via _resolve_base_model before calling
get_transformers_tier. After the model_name/_name_or_path fix, a full
checkpoint with a private/offline _name_or_path and no tier substring would
resolve to that HF ID, which can't be probed, bypassing the local config.json
model_type check entirely. Gate pre-resolution on adapter_config.json so full
checkpoints go straight to get_transformers_tier, which reads config.json
directly. LoRA adapters still pre-resolve as before.
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Studio: fix Qwen3.5 MoE/Qwen3.6 tier detection and dot-version false positives
- Add Qwen3.5 MoE (qwen3_5_moe / Qwen3_5MoeForConditionalGeneration) and
Qwen3-Next to the 5.3.0 config sets, so renamed local checkpoints route to
the sidecar instead of default transformers
- Let a 510/550 name match override a 530 config match, so Qwen3.6 (which
reuses qwen3_5 / qwen3_5_moe config ids) still routes to the 5.5.0 sidecar
- Stop normalizing version dots to hyphens so size names like Qwen3-5B and
Qwen3-6B are not promoted to a 5.x sidecar; underscore aliases still match
- Skip name matching for resolved values that look like stale local paths
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Studio: close remaining codex P2s: adapter-only LoRA + 530-override path-hint guard
- adapter_model-only LoRA: add import-light _is_lora_adapter_dir/_has_adapter_weights
and gate activation/export pre-resolve on them, so LoRA dirs with
adapter_model*.safetensors but no adapter_config.json still resolve to their base
model (via _resolve_base_model's new unsloth_<model>_<ts> directory-name parse)
instead of tiering off the adapter folder.
- 530 override: only treat a resolved value as a name hint when it is a real Hub id;
a stale/renamed local path in model_name/_name_or_path can no longer flip a correct
530 config to 550. Current folder basename still allowed.
Added 7 regression tests; suite at 116 passing.
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Studio: address review feedback on tier detection
- Add Qwen3.5 text-tower model types (qwen3_5_text / qwen3_5_moe_text) to the
5.3.0 config set so text-only configs with stripped architectures still route
to the sidecar
- Apply the Qwen3.6 name override on the remote slow path too, so a renamed or
private repo whose config reuses qwen3_5 ids but names Qwen3.6 in
_name_or_path selects 5.5.0 instead of 5.3.0
- Treat an existing local path (or empty value) as a path, not a Hub id, in
_looks_like_hf_id so a real local checkpoint folder is not name matched
- Guard _resolve_base_model against non-string config values and compare paths
by realpath so relative or absolute self references resolve correctly
- Keep the LoRA adapter is_file check inside the OSError guard
* Studio: harden tier detection against malformed configs and bad paths
- _config_matches_tier no longer raises TypeError when a malformed config.json
carries a non-string model_type (e.g. a list) or non-list architectures; it
fails open to no-match
- guard the model_name-derived is_file/is_dir probes with _safe_is_file /
_safe_is_dir so a pathological or over-long path (e.g. a Windows long path)
fails open to the default tier instead of raising OSError
No routing changes for any valid model; purely defensive. Verified by a
cross-platform simulation (POSIX + NT path semantics) and a before/after tier
matrix that is unchanged for all previously supported models.
* Studio: trim verbose comments in tier detection
Shorten/remove over-long comments and docstrings, mainly on internal helpers,
without changing behavior. Verified code-only via comment_tools.py check; suite
unchanged at 128 passing.
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Lee Jackson <130007945+Imagineer99@users.noreply.github.com>
Co-authored-by: Daniel Han <danielhanchen@gmail.com>