unsloth/studio/backend
danielhanchen 29e9f318dd studio: address reviewer.py n=12 findings on the FLA hook path
Eight issues reproduced by parallel reviewers against 6ce495a; all
fixed and covered by regression tests. 45 pytest cases pass (was 36);
end-to-end Qwen3.5_MoE modeling-import drill still loads all five
fast-path symbols.

P1 fixes:

1. TileLang loses the Qwen-family guard on the normal FLA hook path
   (10/12 reviewers, reproduced with allenai/OLMo-Hybrid-1B). The
   hook unconditionally installed tilelang for any FLA-using model.
   - Threaded `model_name` through `_install_fast_path_hooks(event_queue,
     model_name)`.
   - `_fla_install` now gates tilelang on
     `_model_wants_tilelang(model_name)` AND a successful FLA install.

2. TileLang repair `--force-reinstall` (without `--no-deps`) could
   replace `torch==2.12.0+cu130` with `torch==2.12.0`. Split repair
   into TWO steps:
     step 1: `--force-reinstall --no-deps apache-tvm-ffi==0.1.9`
     step 2: regular install of tilelang + apache-tvm-ffi
   Step 1 surgically downgrades the broken package; step 2 resolves
   missing transitive deps (z3-solver, ml-dtypes) without
   --force-reinstall, so it never replaces torch.

3. Hook could return True after the installer's deep import probe
   failed: when pip exits 0 but `import fla.modules` raises, the old
   wrapper re-called `original()` (transformers' metadata check) and
   trusted it. Refactored:
     - `_ensure_flash_linear_attention_unconditional(...) -> bool`
     - `_ensure_tilelang_backend_unconditional(...) -> bool`
   The wrapper now uses the installer's bool directly.

4. SSM models (Nemotron-H, Falcon-H1, Granite-H) use
   `lazy_load_kernel("causal-conv1d")` and never call
   `is_causal_conv1d_available()`, so the hook never fires for them.
   The orchestrator now always runs `_ensure_causal_conv1d_fast_path`
   outside the hook-mode if/else.

P2 fixes:

5. `_rebind_in_already_imported_modules` invoked transformers' lazy
   module `__getattr__` (hundreds of "Accessing X from .models..."
   warnings, ~3.4s overhead). Switched to `module.__dict__.get(...)`
   which only sees real module-level bindings.

6. TileLang installed even when FLA was skipped (Torch <2.7) or
   failed (timeout, post-install probe failed). Now gated on the
   installer's bool return.

7. TileLang repair was skipped when FLA was already True but tilelang
   missing or apache-tvm-ffi on the broken list. Added an optional
   `post_available_fn` to the wrapper; the FLA hook's
   `_fla_post_available` runs `_ensure_tilelang_backend_unconditional`
   when (model wants tilelang) AND (tilelang missing OR tvm-ffi broken).

8. `_flash_linear_attention_importable()` only checks deep import,
   not version. Added `_flash_linear_attention_current()` that
   compares against the pinned `flash-linear-attention==0.5.0` /
   `fla-core==0.5.0`; older versions trigger `--force-reinstall
   --no-deps` so torch stays untouched.

Helpers extracted to keep the surface tight:
  - `_pip_install_cmd(*args)` builds `uv pip install` or
    `python -m pip install` depending on uv availability.
  - `_run_pip(cmd, event_queue, label)` runs a pip command with
    timeout / failure handling and a status emission.

Regression tests added:

  - test_hook_does_not_install_tilelang_for_non_qwen_fla_model
  - test_hook_does_install_tilelang_for_qwen35
  - test_tilelang_repair_does_not_touch_torch_cuda_stack
  - test_hook_trusts_installer_bool_not_metadata
  - test_rebind_does_not_trigger_module_getattr
  - test_hook_skips_tilelang_when_fla_install_is_skipped
  - test_hook_runs_tilelang_repair_when_fla_already_true
  - test_fla_installer_force_reinstalls_when_older_version_present
  - test_run_training_process_eagerly_installs_causal_conv1d_in_normal_mode

Existing tests updated for the new `_install_fast_path_hooks` signature
and the two-step tilelang repair flow.

End-to-end re-verified against transformers.models.qwen3_5_moe:
PRE_STATE fla=False, hook fires for both gates, FLA + tilelang +
causal-conv1d install, all 5 fast-path symbols non-None.
2026-05-17 00:47:39 +00:00
..
assets Add Qwen3.6 inference defaults for Studio (#5065) 2026-04-16 11:42:42 -07:00
auth studio: security and hardening pass (auth rate-limit, sandbox, path containment, schema validation, headers) (#5375) 2026-05-13 06:12:18 -07:00
core studio: address reviewer.py n=12 findings on the FLA hook path 2026-05-17 00:47:39 +00:00
loggers Studio: stop truncating long log lines as suspected base64 (#5335) 2026-05-08 13:07:18 +04:00
models studio/chat: OpenAI container picker delete reliability (#5466) 2026-05-16 01:53:13 +04:00
plugins fix(gh_client): fail fast on 401/403 auth errors instead of retrying forever (#5325) (#5329) 2026-05-08 21:57:41 +04:00
requirements studio: API external provider support for chat (OpenAI, Mistral, Gemini, Cohere, Anthropic, OpenRouter, DeepSeek, custom providers) (#4706) 2026-05-14 16:13:59 +04:00
routes studio/chat: OpenAI container picker delete reliability (#5466) 2026-05-16 01:53:13 +04:00
state unsloth run: add --enable-tools/--disable-tools server-side tool policy (#5277) 2026-05-05 12:45:15 +04:00
storage studio: API external provider support for chat (OpenAI, Mistral, Gemini, Cohere, Anthropic, OpenRouter, DeepSeek, custom providers) (#4706) 2026-05-14 16:13:59 +04:00
tests studio: address reviewer.py n=12 findings on the FLA hook path 2026-05-17 00:47:39 +00:00
utils studio/mmproj: skip unwanted GGUF values via seek instead of read (#5431) 2026-05-14 21:57:04 -07:00
__init__.py Final cleanup 2026-03-12 18:28:04 +00:00
_platform_compat.py Fix Studio crash on Anaconda/conda-forge Python (#4484) 2026-03-22 05:36:55 -07:00
colab.py Fix/studio colab button message: Add fallback message for Colab Studio button when proxy URL fails (#4866) 2026-04-05 21:57:45 -07:00
main.py studio: API external provider support for chat (OpenAI, Mistral, Gemini, Cohere, Anthropic, OpenRouter, DeepSeek, custom providers) (#4706) 2026-05-14 16:13:59 +04:00
run.py studio: security and hardening pass (auth rate-limit, sandbox, path containment, schema validation, headers) (#5375) 2026-05-13 06:12:18 -07:00
startup_banner.py studio: unify Windows installer/setup logging style, verbosity controls, and startup messaging (#4651) 2026-03-30 00:53:23 -07:00