unsloth/studio/backend/tests
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
..
__init__.py Final cleanup 2026-03-12 18:28:04 +00:00
conftest.py Studio: Expose openai and anthropic compatible external API end points (#4956) 2026-04-13 21:08:11 +04:00
test_anthropic_code_execution.py studio/chat: built-in code execution for OpenAI + Anthropic (#5461) 2026-05-15 23:39:06 +04:00
test_anthropic_messages.py Studio: support images on /v1/messages (Anthropic-compat) (#5128) 2026-04-22 03:25:07 +04:00
test_anthropic_thinking_translation.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
test_browse_folders_route.py Studio: add folder browser modal for Custom Folders (#5035) 2026-04-15 08:04:33 -07:00
test_cache_case_resolution.py Add tests for cache case resolution (from PR #4822) (#4823) 2026-04-03 13:58:26 -07:00
test_cached_gguf_routes.py Studio: support GGUF variant selection for non-suffixed repos (#5023) 2026-04-15 15:32:01 +04:00
test_data_recipe_github_progress.py Studio: add github_repo seed reader and GitHub Support Bot recipe (#5169) 2026-04-24 12:02:03 -07:00
test_data_recipe_seed.py fix(seed): disable remote code execution in seed inspect dataset loads (#4275) 2026-03-13 19:37:43 +04:00
test_desktop_auth.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
test_detect_mmproj_file.py fix(studio/mmproj): block cross-family projectors in flat local GGUF dirs (#5347) (#5350) 2026-05-14 20:31:20 -07:00
test_export_log_cursor.py studio: stream export worker output into the export dialog (#4897) 2026-04-14 08:55:43 -07:00
test_gguf_metadata.py fix(studio/mmproj): block cross-family projectors in flat local GGUF dirs (#5347) (#5350) 2026-05-14 20:31:20 -07:00
test_gpu_selection.py Update VRAM estimator to cater to broader model configs (#5175) 2026-05-05 04:12:36 -07:00
test_gpu_selection_sandbox.py [Studio] multi gpu finetuning/inference via "balanced_low0/sequential" device_map (#4602) 2026-03-30 02:33:15 -07:00
test_host_defaults.py Default Studio host to 127.0.0.1 and prompt before auto-start (#5267) 2026-05-04 13:03:16 +04:00
test_inference_model_validation.py Studio: Dark theme refactor, right sidebar redesign, and chat UI polish (#5150) 2026-05-07 14:33:31 +04:00
test_kv_cache_estimation.py fix KVCache estimates for gemma4 style sliding window models (#5225) 2026-05-05 04:06:46 -07:00
test_llama_cpp_cache_aware_disk_check.py Studio: make GGUF disk-space preflight cache-aware (#5012) 2026-04-14 08:53:37 -07:00
test_llama_cpp_context_fit.py Studio: pin GPU at 95% headroom and warn on silent CPU fallback (#5323) 2026-05-13 04:48:15 -07:00
test_llama_cpp_load_progress.py Studio: live model-load progress + rate/ETA on download and load (#5017) 2026-04-14 09:46:22 -07:00
test_llama_cpp_load_progress_live.py Studio: split model-load progress label across two rows (#5020) 2026-04-14 10:58:16 -07:00
test_llama_cpp_load_progress_matrix.py Studio: split model-load progress label across two rows (#5020) 2026-04-14 10:58:16 -07:00
test_llama_cpp_max_context_threshold.py fix KVCache estimates for gemma4 style sliding window models (#5225) 2026-05-05 04:06:46 -07:00
test_llama_cpp_no_context_shift.py Studio: hard-stop at n_ctx with a 'Context limit reached' toast (#5021) 2026-04-14 10:58:20 -07:00
test_llama_cpp_windows_nvidia_path.py Studio: add torch's pip nvidia DLL dirs to PATH on Windows (#5324) 2026-05-11 05:42:09 -07:00
test_llama_server_args.py Studio: forward llama-server args from unsloth studio run , activate unsloth run , and allow passing model:quant to load models (#5271) 2026-05-04 17:08:04 +04:00
test_log_filter_no_truncation.py Studio: stop truncating long log lines as suspected base64 (#5335) 2026-05-08 13:07:18 +04:00
test_middleware.py studio: security and hardening pass (auth rate-limit, sandbox, path containment, schema validation, headers) (#5375) 2026-05-13 06:12:18 -07:00
test_mlx_inference_backend.py MLX training support for Studio on Apple Silicon (#5340) 2026-05-14 05:24:20 -07:00
test_mlx_training_worker_config.py studio: skip flash-attn install on Blackwell GPUs (sm_100+) (#5420) 2026-05-14 18:13:50 +04:00
test_models_get_model_config_case_resolution.py Add tests for cache case resolution (from PR #4822) (#4823) 2026-04-03 13:58:26 -07:00
test_native_context_length.py Studio: Fix chat template disappearing after browser refresh (#5209) 2026-05-01 08:19:09 -07:00
test_openai_code_execution.py studio/chat: built-in code execution for OpenAI + Anthropic (#5461) 2026-05-15 23:39:06 +04:00
test_openai_container_crud.py tests/openai: patch httpx.AsyncClient ctor so delete tests hit mock (#5469) 2026-05-15 15:53:54 -07:00
test_openai_responses_translation.py Studio: o3 reasoning summary payload (#5426) 2026-05-15 17:13:28 +04:00
test_openai_tool_passthrough.py studio: security and hardening pass (auth rate-limit, sandbox, path containment, schema validation, headers) (#5375) 2026-05-13 06:12:18 -07:00
test_providers_api.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
test_pytorch_mirror.py Add configurable PyTorch mirror via UNSLOTH_PYTORCH_MIRROR env var (#5024) 2026-04-15 11:39:11 +04:00
test_responses_api.py Studio: Expose openai and anthropic compatible external API end points (#4956) 2026-04-13 21:08:11 +04:00
test_responses_tool_passthrough.py Studio: forward standard OpenAI tools / tool_choice on /v1/responses (Codex compat) (#5122) 2026-04-21 13:17:20 +04:00
test_sandbox_tools.py studio: security and hardening pass (auth rate-limit, sandbox, path containment, schema validation, headers) (#5375) 2026-05-13 06:12:18 -07:00
test_studio_api.py Studio: forward standard OpenAI tools / tool_choice to llama-server (#5099) 2026-04-18 12:53:23 +04:00
test_studio_train_validation.py studio: security and hardening pass (auth rate-limit, sandbox, path containment, schema validation, headers) (#5375) 2026-05-13 06:12:18 -07:00
test_tool_policy_gates.py unsloth run: add --enable-tools/--disable-tools server-side tool policy (#5277) 2026-05-05 12:45:15 +04:00
test_tool_policy_state.py unsloth run: add --enable-tools/--disable-tools server-side tool policy (#5277) 2026-05-05 12:45:15 +04:00
test_trained_model_scan.py studio: security and hardening pass (auth rate-limit, sandbox, path containment, schema validation, headers) (#5375) 2026-05-13 06:12:18 -07:00
test_training_history_update.py Studio: Dark theme refactor, right sidebar redesign, and chat UI polish (#5150) 2026-05-07 14:33:31 +04:00
test_training_raw_support.py studio: drop unused max_grad_value schema + route plumbing (#5424) 2026-05-14 05:43:58 -07:00
test_training_worker_flash_attn.py studio: address reviewer.py n=12 findings on the FLA hook path 2026-05-17 00:47:39 +00:00
test_transformers_version.py split venv_t5 into tiered 5.3.0/5.5.0 and fix trust_remote_code (#4878) 2026-04-07 20:05:01 +04:00
test_utils.py Add AMD ROCm/HIP support across installer and hardware detection (#4720) 2026-04-10 01:56:12 -07:00
test_vision_cache.py Studio: split vision-cache exception test to match transient vs permanent (#5145) 2026-04-23 00:22:40 -07:00
test_vram_estimation.py Update VRAM estimator to cater to broader model configs (#5175) 2026-05-05 04:12:36 -07:00