Text Generation
Transformers
Safetensors
English
Arabic
quasar_long
silx-ai
quasar-preview
quasar
foundation-model
Mixture of Experts
18b
2b-active
long-context
bittensor
sn24
decentralized-training
distillation
hybrid-transformer
loop-transformer
safe-nope
drope
conversational
custom_code
Instructions to use mainline777/base_IIXIV with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use mainline777/base_IIXIV with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="mainline777/base_IIXIV", trust_remote_code=True) messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# Load model directly from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained("mainline777/base_IIXIV", trust_remote_code=True, dtype="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use mainline777/base_IIXIV with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "mainline777/base_IIXIV" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "mainline777/base_IIXIV", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/mainline777/base_IIXIV
- SGLang
How to use mainline777/base_IIXIV with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "mainline777/base_IIXIV" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "mainline777/base_IIXIV", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "mainline777/base_IIXIV" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "mainline777/base_IIXIV", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use mainline777/base_IIXIV with Docker Model Runner:
docker model run hf.co/mainline777/base_IIXIV
| import torch | |
| import triton | |
| import triton.language as tl | |
| from einops import rearrange | |
| from fla.utils import IS_AMD, autotune_cache_kwargs, input_guard | |
| NUM_WARPS_AUTOTUNE = [2, 4, 8, 16] if IS_AMD else [4, 8, 16, 32] | |
| STATIC_WARPS = 32 if not IS_AMD else 16 | |
| def causal_conv1d_fwd_kernel( | |
| x, | |
| y, | |
| weight, | |
| bias, | |
| residual, | |
| cu_seqlens, | |
| initial_state, | |
| chunk_indices, | |
| B, | |
| T, | |
| stride_x_n, | |
| stride_x_t, | |
| stride_x_d, | |
| D: tl.constexpr, | |
| W: tl.constexpr, | |
| BT: tl.constexpr, | |
| BW: tl.constexpr, | |
| BD: tl.constexpr, | |
| NB: tl.constexpr, | |
| ACTIVATION: tl.constexpr, | |
| HAS_WEIGHT: tl.constexpr, | |
| HAS_BIAS: tl.constexpr, | |
| HAS_RESIDUAL: tl.constexpr, | |
| USE_INITIAL_STATE: tl.constexpr, | |
| IS_VARLEN: tl.constexpr, | |
| ): | |
| i_d, i_t, i_b = tl.program_id(0), tl.program_id(1), tl.program_id(2) | |
| if IS_VARLEN: | |
| i_n, i_t = tl.load(chunk_indices + i_t * 2).to(tl.int32), tl.load(chunk_indices + i_t * 2 + 1).to(tl.int32) | |
| bos, eos = tl.load(cu_seqlens + i_n).to(tl.int64), tl.load(cu_seqlens + i_n + 1).to(tl.int64) | |
| T = eos - bos | |
| p_x = x + bos * stride_x_t | |
| else: | |
| i_n = i_b | |
| bos, eos = (i_b * T).to(tl.int64), (i_b * T + T).to(tl.int64) | |
| p_x = x + tl.cast(i_b, tl.int64) * stride_x_n | |
| o_d = i_d * BD + tl.arange(0, BD) | |
| o_w = tl.arange(0, BW) + W - BW | |
| m_d = o_d < D | |
| m_w = o_w >= 0 | |
| if HAS_WEIGHT: | |
| # [BD, BW] | |
| b_w = tl.load(weight + o_d[:, None] * W + o_w, mask=m_d[:, None] & m_w, other=0).to(tl.float32) | |
| b_y = tl.zeros((BT, BD), dtype=tl.float32) | |
| if not USE_INITIAL_STATE: | |
| for i_w in tl.static_range(-W + 1, 1): | |
| p_yi = tl.make_block_ptr(p_x, (T, D), (stride_x_t, stride_x_d), (i_t * BT + i_w, i_d * BD), (BT, BD), (1, 0)) | |
| # [BT, BD] | |
| b_yi = tl.load(p_yi, boundary_check=(0, 1)).to(tl.float32) | |
| if HAS_WEIGHT: | |
| b_yi *= tl.sum(b_w * (o_w == (i_w + W - 1)), 1) | |
| b_y += b_yi | |
| elif i_t * BT >= W: | |
| # to make Triton compiler happy, we need to copy codes | |
| for i_w in tl.static_range(-W + 1, 1): | |
| p_yi = tl.make_block_ptr(p_x, (T, D), (stride_x_t, stride_x_d), (i_t * BT + i_w, i_d * BD), (BT, BD), (1, 0)) | |
| # [BT, BD] | |
| b_yi = tl.load(p_yi, boundary_check=(0, 1)).to(tl.float32) | |
| if HAS_WEIGHT: | |
| b_yi *= tl.sum(b_w * (o_w == (i_w + W - 1)), 1) | |
| b_y += b_yi | |
| else: | |
| o_t = i_t * BT + tl.arange(0, BT) | |
| for i_w in tl.static_range(-W + 1, 1): | |
| o_x = o_t + i_w | |
| m_x = ((o_x >= 0) & (o_x < T))[:, None] & m_d | |
| m_c = ((o_x + W >= 0) & (o_x < 0))[:, None] & m_d | |
| b_yi = tl.load( | |
| p_x + o_x[:, None] * stride_x_t + o_d * stride_x_d, | |
| mask=m_x, | |
| other=0 | |
| ).to(tl.float32) | |
| b_yi += tl.load(initial_state + i_n * D*W + o_d * W + (o_x + W)[:, None], mask=m_c, other=0).to(tl.float32) | |
| if HAS_WEIGHT: | |
| b_yi *= tl.sum(b_w * (o_w == (i_w + W - 1)), 1) | |
| b_y += b_yi | |
| if HAS_BIAS: | |
| b_y += tl.load(bias + o_d, mask=m_d).to(tl.float32) | |
| if ACTIVATION == 'swish' or ACTIVATION == 'silu': | |
| b_y = b_y * tl.sigmoid(b_y) | |
| if HAS_RESIDUAL: | |
| p_residual = tl.make_block_ptr(residual + bos * D, (T, D), (D, 1), (i_t * BT, i_d * BD), (BT, BD), (1, 0)) | |
| b_residual = tl.load(p_residual, boundary_check=(0, 1)) | |
| b_y += b_residual | |
| p_y = tl.make_block_ptr(y + bos * D, (T, D), (D, 1), (i_t * BT, i_d * BD), (BT, BD), (1, 0)) | |
| tl.store(p_y, tl.cast(b_y, dtype=p_y.dtype.element_ty, fp_downcast_rounding='rtne'), boundary_check=(0, 1)) | |
| def causal_conv1d_bwd_kernel( | |
| x, | |
| y, | |
| weight, | |
| initial_state, | |
| dht, | |
| dy, | |
| dx, | |
| dw, | |
| db, | |
| cu_seqlens, | |
| chunk_indices, | |
| B, | |
| T, | |
| stride_x_n, # x batch stride | |
| stride_x_t, # x time stride | |
| stride_x_d, # x dim stride | |
| stride_dx_n, # dx batch stride | |
| stride_dx_t, # dx time stride | |
| stride_dx_d, # dx dim stride | |
| D: tl.constexpr, | |
| W: tl.constexpr, | |
| BT: tl.constexpr, | |
| BW: tl.constexpr, | |
| BD: tl.constexpr, | |
| NB: tl.constexpr, | |
| ACTIVATION: tl.constexpr, | |
| HAS_WEIGHT: tl.constexpr, | |
| HAS_BIAS: tl.constexpr, | |
| USE_INITIAL_STATE: tl.constexpr, | |
| USE_FINAL_STATE: tl.constexpr, | |
| IS_VARLEN: tl.constexpr, | |
| ): | |
| i_d, i_t, i_b = tl.program_id(0), tl.program_id(1), tl.program_id(2) | |
| if IS_VARLEN: | |
| i_tg = i_t | |
| i_n, i_t = tl.load(chunk_indices + i_t * 2).to(tl.int32), tl.load(chunk_indices + i_t * 2 + 1).to(tl.int32) | |
| bos, eos = tl.load(cu_seqlens + i_n).to(tl.int64), tl.load(cu_seqlens + i_n + 1).to(tl.int64) | |
| T = eos - bos | |
| p_x = x + bos * stride_x_t | |
| else: | |
| i_tg = i_b * tl.num_programs(1) + i_t | |
| i_n = i_b | |
| bos, eos = (i_b * T).to(tl.int64), (i_b * T + T).to(tl.int64) | |
| p_x = x + tl.cast(i_b, tl.int64) * stride_x_n | |
| o_d = i_d * BD + tl.arange(0, BD) | |
| o_w = tl.arange(0, BW) + W - BW | |
| m_d = o_d < D | |
| m_w = o_w >= 0 | |
| if HAS_WEIGHT: | |
| p_x = tl.make_block_ptr(p_x, (T, D), (stride_x_t, stride_x_d), (i_t * BT, i_d * BD), (BT, BD), (1, 0)) | |
| b_x = tl.load(p_x, boundary_check=(0, 1)) | |
| # [BD, BW] | |
| b_w = tl.load(weight + o_d[:, None] * W + o_w, mask=m_d[:, None] & m_w, other=0) | |
| b_dx = tl.zeros((BT, BD), dtype=tl.float32) | |
| if HAS_BIAS: | |
| b_db = tl.zeros((BD,), dtype=tl.float32) | |
| if not USE_FINAL_STATE and not USE_INITIAL_STATE: | |
| for i_w in tl.static_range(0, W): | |
| p_dy = tl.make_block_ptr(dy + bos * D, (T, D), (D, 1), (i_t * BT + i_w, i_d * BD), (BT, BD), (1, 0)) | |
| # [BT, BD] | |
| b_dy = tl.load(p_dy, boundary_check=(0, 1)).to(tl.float32) | |
| if ACTIVATION == 'swish' or ACTIVATION == 'silu': | |
| p_y = tl.make_block_ptr(y + bos * D, (T, D), (D, 1), (i_t * BT + i_w, i_d * BD), (BT, BD), (1, 0)) | |
| b_y = tl.load(p_y, boundary_check=(0, 1)).to(tl.float32) | |
| b_ys = tl.sigmoid(b_y) | |
| b_dy = b_dy * b_ys * (1 + b_y * (1 - b_ys)) | |
| b_wdy = b_dy | |
| if HAS_WEIGHT: | |
| # [BT, BD] | |
| b_wdy = b_wdy * tl.sum(b_w * (o_w == (W - i_w - 1)), 1) | |
| # [BD] | |
| b_dw = tl.sum(b_dy * b_x, 0) | |
| tl.store(dw + i_tg * D*W + o_d * W + W - i_w - 1, b_dw.to(dw.dtype.element_ty), mask=m_d) | |
| if HAS_BIAS and i_w == 0: | |
| b_db += tl.sum(b_dy, 0) | |
| b_dx += b_wdy | |
| elif i_t * BT >= W: | |
| # to make Triton compiler happy, we need to copy codes | |
| for i_w in tl.static_range(0, W): | |
| p_dy = tl.make_block_ptr(dy + bos * D, (T, D), (D, 1), (i_t * BT + i_w, i_d * BD), (BT, BD), (1, 0)) | |
| # [BT, BD] | |
| b_dy = tl.load(p_dy, boundary_check=(0, 1)).to(tl.float32) | |
| if ACTIVATION == 'swish' or ACTIVATION == 'silu': | |
| p_y = tl.make_block_ptr(y + bos * D, (T, D), (D, 1), (i_t * BT + i_w, i_d * BD), (BT, BD), (1, 0)) | |
| b_y = tl.load(p_y, boundary_check=(0, 1)).to(tl.float32) | |
| b_ys = tl.sigmoid(b_y) | |
| b_dy = b_dy * b_ys * (1 + b_y * (1 - b_ys)) | |
| b_wdy = b_dy | |
| if HAS_WEIGHT: | |
| # [BT, BD] | |
| b_wdy = b_wdy * tl.sum(b_w * (o_w == (W - i_w - 1)), 1) | |
| # [BD] | |
| b_dw = tl.sum(b_dy * b_x, 0) | |
| tl.store(dw + i_tg * D*W + o_d * W + W - i_w - 1, b_dw.to(dw.dtype.element_ty), mask=m_d) | |
| if HAS_BIAS and i_w == 0: | |
| b_db += tl.sum(b_dy, 0) | |
| b_dx += b_wdy | |
| else: | |
| # which may use initial state | |
| o_t = i_t * BT + tl.arange(0, BT) | |
| for i_w in tl.static_range(0, W): | |
| p_dy = tl.make_block_ptr(dy + bos * D, (T, D), (D, 1), (i_t * BT + i_w, i_d * BD), (BT, BD), (1, 0)) | |
| b_dy_shift = tl.load(p_dy, boundary_check=(0, 1)).to(tl.float32) | |
| if ACTIVATION == 'swish' or ACTIVATION == 'silu': | |
| p_y = tl.make_block_ptr(y + bos * D, (T, D), (D, 1), (i_t * BT + i_w, i_d * BD), (BT, BD), (1, 0)) | |
| b_y_shift = tl.load(p_y, boundary_check=(0, 1)).to(tl.float32) | |
| b_ys = tl.sigmoid(b_y_shift) | |
| b_dy_shift = b_dy_shift * b_ys * (1 + b_y_shift * (1 - b_ys)) | |
| if HAS_WEIGHT: | |
| # gradient comes from x:sum_t dy[t+i_w] * x[t] | |
| b_dw = tl.sum(b_dy_shift * b_x, 0) | |
| # index of cache:c = W - i_w + t | |
| if USE_INITIAL_STATE: | |
| mask_head_rows = (o_t < i_w) & (o_t < T) | |
| # dy_head = dy[t] | |
| b_dy_head = tl.load(dy + bos * D + o_t[:, None] * D + o_d, mask=(mask_head_rows[:, None] & m_d[None, :]), | |
| other=0.0).to(tl.float32) | |
| if ACTIVATION == 'swish' or ACTIVATION == 'silu': | |
| # use y[t] (not y[t+i_w]) | |
| b_y_head = tl.load(y + bos * D + o_t[:, None] * D + o_d, | |
| mask=(mask_head_rows[:, None] & m_d[None, :]), other=0.0).to(tl.float32) | |
| b_ys_head = tl.sigmoid(b_y_head) | |
| b_dy_head = b_dy_head * b_ys_head * (1 + b_y_head * (1 - b_ys_head)) | |
| o_c = W - i_w + o_t | |
| # index 0 is padding 0 | |
| mask_c = (mask_head_rows & (o_c >= 1) & (o_c < W)) | |
| b_xc = tl.load(initial_state + i_n * D * W + o_d[None, :] * W + o_c[:, None], | |
| mask=(mask_c[:, None] & m_d[None, :]), other=0.0).to(tl.float32) | |
| # add the gradient comes from initial_state | |
| b_dw += tl.sum(b_dy_head * b_xc, 0) | |
| tl.store(dw + i_tg * D * W + o_d * W + W - i_w - 1, b_dw.to(dw.dtype.element_ty), mask=m_d) | |
| if HAS_BIAS and i_w == 0: | |
| b_db += tl.sum(b_dy_shift, 0) | |
| b_wdy = b_dy_shift if not HAS_WEIGHT else (b_dy_shift * tl.sum(b_w * (o_w == (W - i_w - 1)), 1)) | |
| b_dx += b_wdy | |
| if HAS_BIAS: | |
| b_db = tl.cast(b_db, dtype=db.dtype.element_ty, fp_downcast_rounding='rtne') | |
| tl.store(db + i_tg * D + o_d, b_db, mask=m_d) | |
| if USE_FINAL_STATE: | |
| if i_t * BT + BT >= T-W: | |
| start_tok = max(0, T - (W - 1)) | |
| offset = i_t * BT + tl.arange(0, BT) | |
| tok_idx = offset - start_tok | |
| mask = (offset >= start_tok) & (offset < T) | |
| w_idx = 1 + tok_idx | |
| dht_off = i_n * D * W + o_d[None, :] * W + w_idx[:, None] | |
| b_dht = tl.load(dht + dht_off, mask=mask[:, None] & m_d[None, :], other=0.).to(tl.float32) | |
| b_dx += b_dht | |
| if IS_VARLEN: | |
| p_dx = dx + bos * stride_dx_t | |
| else: | |
| p_dx = dx + tl.cast(i_b, tl.int64) * stride_dx_n | |
| p_dx = tl.make_block_ptr(p_dx, (T, D), (stride_dx_t, stride_dx_d), (i_t * BT, i_d * BD), (BT, BD), (1, 0)) | |
| tl.store(p_dx, tl.cast(b_dx, dtype=p_dx.dtype.element_ty, fp_downcast_rounding='rtne'), boundary_check=(0, 1)) | |
| def causal_conv1d_update_kernel( | |
| x, | |
| cache, | |
| residual, | |
| y, | |
| weight, | |
| bias, | |
| stride_x_n, # batch stride | |
| stride_x_d, # dim stride | |
| stride_y_n, # batch stride | |
| stride_y_d, # dim stride | |
| D: tl.constexpr, | |
| W: tl.constexpr, | |
| BD: tl.constexpr, | |
| BW: tl.constexpr, | |
| ACTIVATION: tl.constexpr, | |
| USE_INITIAL_STATE: tl.constexpr, | |
| HAS_WEIGHT: tl.constexpr, | |
| HAS_BIAS: tl.constexpr, | |
| HAS_RESIDUAL: tl.constexpr, | |
| ): | |
| i_d, i_n = tl.program_id(0), tl.program_id(1) | |
| o_d = i_d * BD + tl.arange(0, BD) | |
| o_w = tl.arange(0, BW) | |
| m_d = o_d < D | |
| m_w = o_w < W | |
| # [BD] | |
| b_x = tl.load(x + i_n * stride_x_n + o_d * stride_x_d, mask=m_d, other=0).to(tl.float32) | |
| b_cache = tl.zeros((BD, BW), dtype=tl.float32) | |
| if USE_INITIAL_STATE: | |
| # 2. Shift Cache (Read [1:]) | |
| p_cache_read = tl.make_block_ptr( | |
| cache + i_n * D*W, | |
| shape=(D, W), | |
| strides=(W, 1), | |
| offsets=(i_d * BD, 1), | |
| block_shape=(BD, BW), | |
| order=(1, 0) | |
| ) | |
| b_cache = tl.load(p_cache_read, boundary_check=(0, 1)).to(tl.float32) | |
| # 3. Fill x to the last position | |
| m_update = o_w == (W - 1) | |
| b_cache = tl.where(m_update[None, :], b_x[:, None], b_cache) | |
| if HAS_WEIGHT: | |
| b_w = tl.load(weight + o_d[:, None] * W + o_w, mask=m_d[:, None] & m_w, other=0) | |
| b_y = tl.sum(b_cache * b_w, 1) | |
| else: | |
| b_y = tl.sum(b_cache, 1) | |
| if HAS_BIAS: | |
| b_y += tl.load(bias + o_d, mask=m_d) | |
| if ACTIVATION == 'swish' or ACTIVATION == 'silu': | |
| b_y = b_y * tl.sigmoid(b_y) | |
| if HAS_RESIDUAL: | |
| b_y += tl.load(residual + i_n * D + o_d, mask=m_d, other=0) | |
| tl.store(y + i_n * stride_y_n + o_d * stride_y_d, tl.cast(b_y, | |
| dtype=y.dtype.element_ty, fp_downcast_rounding='rtne'), mask=m_d) | |
| if USE_INITIAL_STATE: | |
| p_cache_write = tl.make_block_ptr( | |
| cache + i_n * D*W, | |
| shape=(D, W), | |
| strides=(W, 1), | |
| offsets=(i_d * BD, 0), | |
| block_shape=(BD, BW), | |
| order=(1, 0) | |
| ) | |
| tl.store(p_cache_write, tl.cast(b_cache, dtype=cache.dtype.element_ty, | |
| fp_downcast_rounding='rtne'), boundary_check=(0, 1)) | |
| def compute_dh0_kernel( | |
| dy, | |
| y, | |
| weight, | |
| dh0, | |
| cu_seqlens, | |
| stride_dy_n, | |
| stride_dy_t, | |
| T, | |
| D: tl.constexpr, | |
| W: tl.constexpr, | |
| BD: tl.constexpr, | |
| USE_ACTIVATION: tl.constexpr, | |
| IS_VARLEN: tl.constexpr, | |
| ): | |
| """ | |
| Compute dh0 (gradient w.r.t. initial_state) in a separate kernel. | |
| This avoids Triton compiler bugs on some architectures (e.g., GB200). | |
| Grid: (cdiv(D, BD), N) | |
| """ | |
| i_d, i_n = tl.program_id(0), tl.program_id(1) | |
| # Get sequence boundaries | |
| if IS_VARLEN: | |
| bos = tl.load(cu_seqlens + i_n).to(tl.int64) | |
| eos = tl.load(cu_seqlens + i_n + 1).to(tl.int64) | |
| seq_len = eos - bos | |
| # For varlen, dy is [1, total_T, D], offset by bos | |
| dy_base = dy + bos * stride_dy_t | |
| else: | |
| seq_len = T | |
| # For non-varlen, dy is [B, T, D], offset by i_n * stride_dy_n | |
| dy_base = dy + tl.cast(i_n, tl.int64) * stride_dy_n | |
| o_d = i_d * BD + tl.arange(0, BD) | |
| m_d = o_d < D | |
| # For each i_w in [1, W), compute dh0[i_n, :, i_w] | |
| for i_w in tl.static_range(1, W): | |
| b_dh0 = tl.zeros([BD], dtype=tl.float32) | |
| # Accumulate contributions from t = 0 to min(i_w, seq_len) - 1 | |
| for t in tl.static_range(0, W - 1): | |
| if t < i_w: | |
| w_idx = i_w - 1 - t | |
| # Load dy[t, :] relative to dy_base | |
| p_dy = dy_base + t * stride_dy_t + o_d | |
| m_t = (t < seq_len) & m_d | |
| b_dy = tl.load(p_dy, mask=m_t, other=0).to(tl.float32) | |
| if USE_ACTIVATION: | |
| if IS_VARLEN: | |
| p_y = y + bos * stride_dy_t + t * stride_dy_t + o_d | |
| else: | |
| p_y = y + tl.cast(i_n, tl.int64) * stride_dy_n + t * stride_dy_t + o_d | |
| b_y = tl.load(p_y, mask=m_t, other=0).to(tl.float32) | |
| b_ys = tl.sigmoid(b_y) | |
| b_dy = b_dy * b_ys * (1 + b_y * (1 - b_ys)) | |
| # Get weight[:, w_idx] | |
| b_w_col = tl.load(weight + o_d * W + w_idx, mask=m_d, other=0).to(tl.float32) | |
| # Accumulate | |
| b_dh0 += tl.where(m_t, b_dy * b_w_col, 0) | |
| # Store dh0[i_n, :, i_w] | |
| p_dh0 = dh0 + i_n * D * W + o_d * W + i_w | |
| tl.store(p_dh0, b_dh0.to(dh0.dtype.element_ty), mask=m_d) | |
| def causal_conv1d_states_fwd_kernel( | |
| x, | |
| initial_state, | |
| final_state, | |
| cu_seqlens, | |
| T, | |
| D, | |
| W, | |
| stride_x_n, | |
| stride_x_t, | |
| stride_x_d, | |
| BD: tl.constexpr, | |
| BW: tl.constexpr, | |
| USE_INITIAL_STATE: tl.constexpr, | |
| IS_VARLEN: tl.constexpr, | |
| ): | |
| i_d, i_n = tl.program_id(0), tl.program_id(1) | |
| # o_d Shape: [BD] | |
| o_d = i_d * BD + tl.arange(0, BD) | |
| m_d = o_d < D | |
| if IS_VARLEN: | |
| bos = tl.load(cu_seqlens + i_n).to(tl.int64) | |
| eos = tl.load(cu_seqlens + i_n + 1).to(tl.int64) | |
| seq_len = (eos - bos).to(tl.int32) | |
| p_x = x + bos * stride_x_t | |
| else: | |
| seq_len = T | |
| p_x = x + tl.cast(i_n, tl.int64) * stride_x_n | |
| p_x = tl.make_block_ptr(p_x, (seq_len, D), (stride_x_t, stride_x_d), (seq_len - BW, i_d * BD), (BW, BD), (1, 0)) | |
| # b_x Shape: [BW, BD] | |
| b_x = tl.load(p_x, boundary_check=(0, 1), padding_option="zero").to(tl.float32) | |
| if USE_INITIAL_STATE: | |
| if seq_len < BW: | |
| o_c = W - (BW - seq_len) + tl.arange(0, BW) | |
| m_c = (o_c >= 0) & (o_c < W) | |
| p_init = initial_state + i_n * D*W + o_d[None, :] * W + o_c[:, None] | |
| mask_init = m_d[None, :] & m_c[:, None] | |
| b_cache = tl.load(p_init, mask=mask_init, other=0) | |
| b_x += b_cache | |
| # final_state: [N, D, W] (Channel Major inside sample) | |
| # o_w Shape: [BW] | |
| o_w = W - BW + tl.arange(0, BW) | |
| # o_d[:, None] -> [BD, 1] | |
| # o_w[None, :] -> [1, BW] | |
| # p_final Shape -> [BD, BW] | |
| p_final = final_state + tl.cast(i_n, tl.int64) * D*W + o_d[:, None] * W + o_w[None, :] | |
| # m_final Shape -> [BD, BW] | |
| m_final = m_d[:, None] & (o_w[None, :] >= 0) | |
| tl.store(p_final, tl.trans(b_x).to(final_state.dtype.element_ty), mask=m_final) | |
| def causal_conv1d_update_states( | |
| x: torch.Tensor, | |
| state_len: int, | |
| initial_state: torch.Tensor | None = None, | |
| cu_seqlens: torch.Tensor | None = None, | |
| ) -> torch.Tensor: | |
| if cu_seqlens is not None: | |
| N = len(cu_seqlens) - 1 | |
| if x.dim() == 2: | |
| stride_x_n = 0 | |
| stride_x_t, stride_x_d = x.stride() | |
| T = x.shape[0] | |
| else: | |
| stride_x_n = x.stride(0) | |
| stride_x_t, stride_x_d = x.stride(1), x.stride(2) | |
| T = x.shape[1] | |
| D = x.shape[-1] | |
| else: | |
| B, T, D = x.shape | |
| N = B | |
| stride_x_n, stride_x_t, stride_x_d = x.stride() | |
| W = state_len | |
| final_state = torch.empty(N, D, W, dtype=x.dtype, device=x.device) | |
| BD = min(triton.next_power_of_2(D), 256) | |
| BW = triton.next_power_of_2(W) | |
| grid = (triton.cdiv(D, BD), N) | |
| causal_conv1d_states_fwd_kernel[grid]( | |
| x=x, | |
| initial_state=initial_state, | |
| final_state=final_state, | |
| cu_seqlens=cu_seqlens, | |
| T=T, | |
| D=D, | |
| W=W, | |
| stride_x_n=stride_x_n, | |
| stride_x_t=stride_x_t, | |
| stride_x_d=stride_x_d, | |
| BW=BW, | |
| BD=BD, | |
| ) | |
| return final_state | |
| def causal_conv1d_update( | |
| x: torch.Tensor, | |
| cache: torch.Tensor, | |
| residual: torch.Tensor | None = None, | |
| weight: torch.Tensor | None = None, | |
| bias: torch.Tensor | None = None, | |
| activation: str | None = None, | |
| ) -> torch.Tensor: | |
| shape = x.shape | |
| if weight is not None and x.shape[-1] != weight.shape[0]: | |
| x = rearrange(x, 'b t ... -> b t (...)') | |
| D = x.shape[-1] | |
| N = x.numel() // D | |
| W = weight.shape[1] if weight is not None else None | |
| BD = 8 | |
| BW = triton.next_power_of_2(W) | |
| if x.dim() == 2: | |
| # Case: (N, D) | |
| stride_x_n = x.stride(0) | |
| stride_x_d = x.stride(1) | |
| elif x.dim() == 3 and x.shape[0] == 1: | |
| # Case: (1, N, D) -> Time=1, Batch=N, Dim=D | |
| # Batch 在 dim 1 | |
| stride_x_n = x.stride(1) | |
| stride_x_d = x.stride(2) | |
| elif x.dim() == 3: | |
| # Case: (N, 1, D) -> Batch=N, Time=1, Dim=D | |
| # Batch 在 dim 0 | |
| stride_x_n = x.stride(0) | |
| stride_x_d = x.stride(2) | |
| else: | |
| # Fallback / Error case | |
| raise ValueError(f"Unsupported input shape: {x.shape}") | |
| y = torch.empty_like(x, memory_format=torch.contiguous_format) | |
| if y.dim() == 2: | |
| stride_y_n, stride_y_d = y.stride(0), y.stride(1) | |
| elif y.dim() == 3 and y.shape[0] == 1: | |
| stride_y_n, stride_y_d = y.stride(1), y.stride(2) | |
| elif y.dim() == 3: | |
| stride_y_n, stride_y_d = y.stride(0), y.stride(2) | |
| def grid(meta): return (triton.cdiv(D, meta['BD']), N) | |
| causal_conv1d_update_kernel[grid]( | |
| x=x, | |
| cache=cache, | |
| residual=residual, | |
| y=y, | |
| weight=weight, | |
| bias=bias, | |
| stride_x_n=stride_x_n, | |
| stride_x_d=stride_x_d, | |
| stride_y_n=stride_y_n, | |
| stride_y_d=stride_y_d, | |
| D=D, | |
| W=W, | |
| BD=BD, | |
| BW=BW, | |
| ACTIVATION=activation, | |
| num_warps=STATIC_WARPS, | |
| ) | |
| return y.view(shape), cache | |