-
-
Notifications
You must be signed in to change notification settings - Fork 6.3k
studio: install flash-linear-attention and tilelang for Qwen3.5 family #5434
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
c07cdda
0bb03e0
57afa62
92f9d4b
bbd715e
1ff38ae
49a0db9
b92afb7
d079859
a9982a0
6a1a215
9e9c3ac
b399247
d7f3a3e
453c31a
39559cc
994688d
4454608
e7aeb32
1f32279
d56313e
f9b3d26
a8a15f7
2f9a6b0
6760682
17d4213
ec9e643
6681421
a415f6b
1a4df61
5ed13a9
fc2ee99
3fde343
d137a67
0f246a6
27dc546
66dface
6ce495a
d2d758d
8e7859d
29e9f31
6981149
78b07a2
85cdafc
3913a66
800fc98
d73935c
379cbb2
10b50c8
038906c
a4e63ec
73f7e32
c358b05
5c2511d
bb0e0b2
a68acdc
3e60db3
a68c078
f505f73
1844402
dcfb47c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -52,6 +52,14 @@ def _output_dir_from_resume_checkpoint( | |
| _MAMBA_SSM_PACKAGE_VERSION = "2.3.1" | ||
| _FLASH_ATTN_RUNTIME_MIN_SEQ_LEN = 32768 | ||
| _FLASH_ATTN_SKIP_ENV = "UNSLOTH_STUDIO_SKIP_FLASHATTN_INSTALL" | ||
| # tilelang 0.1.9+ pairs with apache-tvm-ffi >=0.1.10 by default, but | ||
| # apache-tvm-ffi 0.1.10/0.1.11 has an alignment regression that crashes | ||
| # subsequent Triton kernels with "CUDA: misaligned address" on sm_100 | ||
| # (Blackwell). 0.1.9 is the last known-good. mamba_ssm 2.3.2 also pins | ||
| # apache-tvm-ffi<=0.1.9, which is the original source of this pin. | ||
| _TILELANG_PACKAGE_VERSION = "0.1.8" | ||
| _APACHE_TVM_FFI_PACKAGE_VERSION = "0.1.9" | ||
| _TILELANG_SKIP_ENV = "UNSLOTH_STUDIO_SKIP_TILELANG_INSTALL" | ||
|
|
||
|
|
||
| def _model_wants_causal_conv1d(model_name: str) -> bool: | ||
|
|
@@ -275,6 +283,34 @@ def _ensure_causal_conv1d_fast_path(event_queue: Any, model_name: str) -> None: | |
| ) | ||
|
|
||
|
|
||
| def _ensure_flash_linear_attention(event_queue: Any, model_name: str) -> None: | ||
| """Install ``flash-linear-attention`` from PyPI for models that need it. | ||
|
|
||
| Qwen3.5 / Qwen3.6 / Qwen3-Next (and the SSM hybrids covered by | ||
| ``_model_wants_causal_conv1d``) gate their fast path on FLA's | ||
| ``chunk_gated_delta_rule`` / ``fused_recurrent_gated_delta_rule`` | ||
| being importable. Without FLA, transformers falls back to a pure | ||
| Python torch loop (~2.35x slower in our Qwen3.5-2B-Vision bench). | ||
|
|
||
| FLA ships as a universal py3-none-any wheel on PyPI (Triton kernels | ||
| JIT-compile at runtime), so no wheel-matching dance is needed. | ||
| """ | ||
| if not _model_wants_causal_conv1d(model_name): | ||
| return | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When Useful? React with 👍 / 👎. |
||
|
|
||
| _install_package_wheel_first( | ||
| event_queue = event_queue, | ||
| import_name = "fla", | ||
| display_name = "flash-linear-attention", | ||
| pypi_name = "flash-linear-attention", | ||
| wheel_url_builder = lambda env: None, | ||
| pypi_spec = "flash-linear-attention", | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When a Studio install is on one of the supported torch 2.4/2.5/2.6 environments (for example Useful? React with 👍 / 👎. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When a Qwen3.5-family job runs on a ROCm runtime image where Useful? React with 👍 / 👎. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
For Studio runs under Python 3.9, which this project still declares as supported in Useful? React with 👍 / 👎. |
||
| pypi_status_message = ( | ||
| "Installing flash-linear-attention from PyPI for the fast path..." | ||
| ), | ||
| ) | ||
|
|
||
|
|
||
| _SSM_MODEL_SUBSTRINGS = ( | ||
| "nemotron_h", | ||
| "nemotron-h", | ||
|
|
@@ -303,6 +339,111 @@ def _ensure_mamba_ssm(event_queue: Any, model_name: str) -> None: | |
| ) | ||
|
|
||
|
|
||
| # Linear-attention models that benefit from FLA's TileLang backend. | ||
| # FLA dispatches `chunk_bwd_dqkwg` / `parallel_attn_fwd` / `parallel_attn_bwd` | ||
| # to TileLang when both `tilelang` and `apache-tvm-ffi` are importable; | ||
| # this gives ~26% additional speedup on Qwen3.5-2B-Vision on B200 in our | ||
| # bench, on top of the FLA-Triton fast path. | ||
| # | ||
| # Restricted to GDN architectures (Qwen3.5 family). True SSM models | ||
| # (Nemotron-H, Falcon-H1, Granite-H, LFM2) take their own path and do not | ||
| # go through FLA's gated_delta_rule, so we do NOT install tilelang for them. | ||
| _TILELANG_MODEL_SUBSTRINGS = ( | ||
| "qwen3.5", | ||
| "qwen3_5", | ||
| "qwen3.6", | ||
| "qwen3_6", | ||
| "qwen3-next", | ||
| "qwen3_next", | ||
| ) | ||
|
|
||
|
|
||
| def _model_wants_tilelang(model_name: str) -> bool: | ||
| name = model_name.lower() | ||
| return any(sub in name for sub in _TILELANG_MODEL_SUBSTRINGS) | ||
|
|
||
|
|
||
| def _ensure_tilelang_backend(event_queue: Any, model_name: str) -> None: | ||
| """Install ``tilelang`` + pinned ``apache-tvm-ffi`` for FLA's TileLang backend. | ||
|
|
||
| The combined pin is important: `tilelang` declares | ||
| ``apache-tvm-ffi>=0.1.2,~=0.1.0`` which lets pip pull the latest 0.1.10/ | ||
| 0.1.11, but those versions hit a "CUDA: misaligned address" crash in | ||
| Triton kernels on sm_100 (Blackwell). Pinning to 0.1.9 (the upper bound | ||
| that ``mamba_ssm 2.3.2`` itself uses) avoids the regression. | ||
|
|
||
| Both packages are pure-Python wheels on PyPI; no wheel-matching dance | ||
| is needed. | ||
|
|
||
| Set ``UNSLOTH_STUDIO_SKIP_TILELANG_INSTALL=1`` to bypass. | ||
| """ | ||
| if os.getenv(_TILELANG_SKIP_ENV) == "1": | ||
| return | ||
| if not _model_wants_tilelang(model_name): | ||
| return | ||
|
|
||
| try: | ||
| import tilelang # noqa: F401 | ||
| import tvm_ffi # noqa: F401 | ||
|
|
||
| logger.info("tilelang + apache-tvm-ffi already installed") | ||
| return | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
For Qwen3.5-family jobs on a machine that already has Useful? React with 👍 / 👎. |
||
| except ImportError: | ||
| pass | ||
|
|
||
| _send_status( | ||
| event_queue, | ||
| ( | ||
| f"Installing TileLang backend (" | ||
| f"apache-tvm-ffi=={_APACHE_TVM_FFI_PACKAGE_VERSION}, " | ||
| f"tilelang=={_TILELANG_PACKAGE_VERSION}) for FLA fast path..." | ||
| ), | ||
| ) | ||
|
|
||
| # Install both in one pip resolve so the apache-tvm-ffi pin wins over | ||
| # tilelang's `>=0.1.2,~=0.1.0` constraint. | ||
| specs = [ | ||
| f"apache-tvm-ffi=={_APACHE_TVM_FFI_PACKAGE_VERSION}", | ||
| f"tilelang=={_TILELANG_PACKAGE_VERSION}", | ||
| ] | ||
| if shutil.which("uv"): | ||
| pypi_cmd = [ | ||
| "uv", | ||
| "pip", | ||
| "install", | ||
| "--python", | ||
| sys.executable, | ||
| *specs, | ||
| ] | ||
| else: | ||
| pypi_cmd = [ | ||
| sys.executable, | ||
| "-m", | ||
| "pip", | ||
| "install", | ||
| *specs, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
For Qwen3.5-family training on Windows or any platform without a Useful? React with 👍 / 👎. |
||
| ] | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
|
|
||
| result = _sp.run( | ||
| pypi_cmd, | ||
| stdout = _sp.PIPE, | ||
| stderr = _sp.STDOUT, | ||
| text = True, | ||
| ) | ||
| if result.returncode != 0: | ||
| logger.warning( | ||
| "TileLang backend install failed (continuing without it):\n%s", | ||
| result.stdout, | ||
| ) | ||
| _send_status( | ||
| event_queue, | ||
| "TileLang backend install failed; continuing on the FLA Triton path", | ||
| ) | ||
| return | ||
|
|
||
| logger.info("Installed TileLang backend for FLA fast path") | ||
|
|
||
|
|
||
| def _should_try_runtime_flash_attn_install(max_seq_length: int) -> bool: | ||
| if os.getenv(_FLASH_ATTN_SKIP_ENV) == "1": | ||
| return False | ||
|
|
@@ -1111,10 +1252,20 @@ def run_training_process( | |
| model_name, | ||
| ) | ||
|
|
||
| # ── 1b. Set up causal-conv1d first, then install mamba-ssm if needed ── | ||
| # ── 1b. Install fast-path kernel libraries for the chosen model. | ||
| # Order: | ||
| # 1) causal-conv1d (gates transformers' qwen3_5 / qwen3_next fast path) | ||
| # 2) flash-linear-attention (the other half of that gate; without it | ||
| # the conv kernel alone gives ~no measurable speedup) | ||
| # 3) mamba-ssm (true SSM families only: Nemotron-H, Falcon-H1, etc.) | ||
| # 4) tilelang + apache-tvm-ffi (FLA's TileLang backend, optional but | ||
| # adds ~26% on Qwen3.5 GDN layers on Hopper+) | ||
| # 5) flash-attn (only for max_seq_length >= 32k, separate concern) | ||
| try: | ||
| _ensure_causal_conv1d_fast_path(event_queue, model_name) | ||
| _ensure_flash_linear_attention(event_queue, model_name) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
On machines where Useful? React with 👍 / 👎. |
||
| _ensure_mamba_ssm(event_queue, model_name) | ||
|
Comment on lines
+1779
to
1781
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When Useful? React with 👍 / 👎. |
||
| _ensure_tilelang_backend(event_queue, model_name) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Gatekeeping for Useful? React with 👍 / 👎. |
||
| _ensure_flash_attn_for_long_context( | ||
| event_queue, | ||
| int(config.get("max_seq_length", 2048)), | ||
|
|
@@ -1125,7 +1276,9 @@ def run_training_process( | |
| "type": "error", | ||
| "error": ( | ||
| f"Please choose another model to train, since " | ||
| f"causal-conv1d / mamba-ssm failed to install " | ||
| f"a fast-path kernel library " | ||
| f"(causal-conv1d / flash-linear-attention / " | ||
| f"mamba-ssm / tilelang) failed to install " | ||
| f"with error: {exc}" | ||
| ), | ||
| "stack": traceback.format_exc(limit = 20), | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For a fresh Qwen3.5-family Studio job this pins
tilelangto 0.1.8, but the unpinnedflash-linear-attentionbeing installed just above currently declares its TileLang extra astilelang>=0.1.9in upstreampyproject.toml. That leaves the new TileLang backend on a version FLA does not claim to support, so the intendedchunk_bwd_dqkwg/parallel_attn_*TileLang dispatch can fail or silently fall back despite the helper reporting the backend installed; pin a compatible TileLang release while separately constrainingapache-tvm-ffito the safe version.Useful? React with 👍 / 👎.