base_IIXIV / fla /modules /conv /causal_conv1d.py
mainline777's picture
Duplicate from silx-ai/Quasar-Preview
41865df
Raw
History Blame Contribute Delete
4.41 kB
# Copyright (c) 2023-2025, Songlin Yang, Yu Zhang
"""Main interface for causal 1D convolution operations."""
import torch
from fla.ops.cp import FLACPContext
from fla.utils import input_guard
@input_guard(no_guard_contiguous=["x"])
def causal_conv1d(
x: torch.Tensor,
weight: torch.Tensor | None = None,
bias: torch.Tensor | None = None,
residual: torch.Tensor | None = None,
initial_state: torch.Tensor | None = None,
output_final_state: bool | None = False,
activation: str | None = None,
backend: str | None = 'triton',
cu_seqlens: torch.Tensor | None = None,
cu_seqlens_cpu: torch.LongTensor | None = None,
chunk_indices: torch.LongTensor | None = None,
cp_context: FLACPContext | None = None,
**kwargs,
):
"""
A causal 1D convolution implementation that powers Mamba/Mamba2 and DeltaNet architectures.
When a residual connection is provided, this implements the Canon operation
described in the paper at https://papers.ssrn.com/sol3/papers.cfm?abstract_id=5240330.
Args:
x (torch.Tensor):
Input tensor of shape [B, T, D].
weight (Optional[torch.Tensor]):
Weight tensor of shape [D, W]. Default: `None`.
bias (Optional[torch.Tensor]):
Bias tensor of shape [D]. Default: `None`.
residual (Optional[torch.Tensor]):
Residual tensor of shape [B, T, D]. Default: `None`.
initial_state (Optional[torch.Tensor]):
Initial state tensor of shape [N, D, W],
where `N` is the number of sequences in the batch and `W` is the kernel size.
If provided, the initial state is used to initialize the cache. Default: `None`.
output_final_state (Optional[bool]):
Whether to output the final state of shape [N, D, W]. Default: `False`.
activation (Optional[str]):
Activations applied to output, only `swish`/`silu` or `None` (i.e., no activation) are supported.
Default: `None`.
backend (Optional[str]):
Specifies the backend to use for the convolution operation. Supported values are `'cuda'` 、 `'triton'` and `'mix'`.
Default: `'triton'`.
cu_seqlens (Optional[torch.Tensor]):
Cumulative sequence lengths (optional)
chunk_indices (Optional[torch.LongTensor]):
Chunk indices for variable-length sequences (optional)
Returns:
Tuple of (output, final_state).
If `output_final_state` is `False`, the final state is `None`.
"""
# Import here to avoid circular dependencies
from fla.modules.conv.cp import causal_conv1d_cp
from fla.modules.conv.cuda import causal_conv1d_cuda, fast_causal_conv1d_fn
from fla.modules.conv.triton import CausalConv1dFunction
if cp_context is not None:
assert initial_state is None, "Initial state is not supported for CP"
assert output_final_state is False, "Output final state is not supported for CP"
output = causal_conv1d_cp(
x=x,
weight=weight,
bias=bias,
activation=activation,
chunk_indices=chunk_indices,
cp_context=cp_context,
)
return output, None
if backend == 'triton':
y, final_state = CausalConv1dFunction.apply(
x,
weight,
bias,
residual,
initial_state,
output_final_state,
activation,
cu_seqlens,
cu_seqlens_cpu,
chunk_indices,
)
return y, final_state
elif backend == 'mix':
seq_idx = kwargs.get('seq_idx')
return fast_causal_conv1d_fn(
x,
weight,
bias,
residual,
initial_state,
output_final_state,
activation,
cu_seqlens,
cu_seqlens_cpu=cu_seqlens_cpu,
chunk_indices=chunk_indices,
seq_idx=seq_idx,
)
elif backend == 'cuda':
return causal_conv1d_cuda(
x,
weight,
bias,
residual,
initial_state,
output_final_state,
activation,
cu_seqlens,
cu_seqlens_cpu=cu_seqlens_cpu,
**kwargs,
)
else:
raise ValueError(f"Unsupported backend: {backend}")