Skip to content

Commit 1928a66

Browse files
author
Akash kaothalkar
committed
combine causal_conv1d_fn_cpu
Signed-off-by: Akash kaothalkar <akash.kaothalkar@ibm.com>
1 parent e9b6c3c commit 1928a66

1 file changed

Lines changed: 42 additions & 88 deletions

File tree

vllm/model_executor/layers/mamba/ops/cpu/causal_conv1d.py

Lines changed: 42 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -24,56 +24,59 @@ def causal_conv1d_fn_cpu(
2424
"""CPU implementation for causal_conv1d_fwd."""
2525
if isinstance(activation, bool) and activation:
2626
activation = "silu"
27+
elif isinstance(activation, bool):
28+
activation = None
2729

2830
original_x_dtype = x.dtype
2931
x = x.to(conv_states.dtype)
3032

31-
dim, cu_seqlen = x.shape
32-
_, width = weight.shape
33-
state_len = width - 1
34-
35-
out = torch.zeros_like(x)
36-
37-
batch = query_start_loc.size(0) - 1
38-
39-
for b in range(batch):
40-
seq_start = query_start_loc[b].item()
41-
seq_end = query_start_loc[b + 1].item()
42-
seq_len = seq_end - seq_start
33+
out = torch.empty_like(x)
34+
state_len = weight.shape[1] - 1
35+
assert activation in {None, "silu", "swish"}
4336

44-
if seq_len == 0:
37+
seq_begin_end_idx = [
38+
(int(query_start_loc[idx].item()), int(query_start_loc[idx + 1].item()))
39+
for idx in range(query_start_loc.shape[0] - 1)
40+
]
41+
weight = weight.unsqueeze(1)
42+
43+
for seq_idx, (bos, eos) in enumerate(seq_begin_end_idx):
44+
if bos == eos:
4545
continue
46-
47-
cache_idx = cache_indices[b].item() if cache_indices is not None else b
48-
49-
if cache_idx == pad_slot_id:
46+
47+
slot = int(cache_indices[seq_idx].item()) if cache_indices is not None else seq_idx
48+
49+
if slot == pad_slot_id:
5050
continue
5151

52-
x_seq = x[:, seq_start:seq_end] # (dim, seq_len)
53-
54-
if has_initial_state is not None and has_initial_state[b]:
55-
state = conv_states[cache_idx].clone() # (dim, state_len)
52+
seq_x = x[:, bos:eos].unsqueeze(0)
53+
54+
if has_initial_state is not None and bool(has_initial_state[seq_idx].item()):
55+
initial_state = conv_states[slot, :, :state_len].unsqueeze(0)
5656
else:
57-
state = torch.zeros((dim, state_len), dtype=x.dtype, device=x.device)
58-
59-
for t in range(seq_len):
60-
x_t = x_seq[:, t] # (dim,)
61-
62-
window = torch.cat([state, x_t.unsqueeze(1)], dim=1) # (dim, width)
63-
val = (window * weight).sum(dim=1) # (dim,)
64-
65-
if bias is not None:
66-
val = val + bias
67-
if activation in ["silu", "swish"]:
68-
val = val * torch.sigmoid(val)
69-
70-
out[:, seq_start + t] = val
57+
initial_state = torch.zeros(
58+
1,
59+
weight.shape[0],
60+
state_len,
61+
device=seq_x.device,
62+
dtype=seq_x.dtype,
63+
)
7164

72-
if state_len > 1:
73-
state[:, :-1] = state[:, 1:].clone()
74-
state[:, -1] = x_t
65+
conv_input = torch.cat([initial_state, seq_x], dim=-1).to(weight.dtype)
66+
seq_out = F.conv1d(
67+
conv_input,
68+
weight,
69+
bias,
70+
padding=0,
71+
groups=weight.shape[0],
72+
)
73+
seq_out = seq_out[..., -seq_x.shape[-1] :].to(dtype=x.dtype)
74+
75+
if activation in ("silu", "swish"):
76+
seq_out = F.silu(seq_out)
7577

76-
conv_states[cache_idx].copy_(state)
78+
out[:, bos:eos] = seq_out.squeeze(0)
79+
conv_states[slot, :, :state_len].copy_(conv_input[..., -state_len:].squeeze(0))
7780

7881
return out.to(original_x_dtype)
7982

@@ -179,56 +182,7 @@ def causal_conv1d_update_cpu(
179182
return out.to(original_x_dtype)
180183

181184

182-
def causal_conv1d_torch(
183-
x: torch.Tensor,
184-
weight: torch.Tensor,
185-
bias: torch.Tensor | None,
186-
conv_states: torch.Tensor,
187-
query_start_loc: torch.Tensor,
188-
cache_indices: torch.Tensor,
189-
has_initial_state: torch.Tensor,
190-
activation: str | None = "silu",
191-
) -> torch.Tensor:
192-
out = torch.empty_like(x)
193-
state_len = weight.shape[1] - 1
194-
assert activation in {None, "silu", "swish"}
195-
196-
seq_begin_end_idx = [
197-
(int(query_start_loc[idx].item()), int(query_start_loc[idx + 1].item()))
198-
for idx in range(query_start_loc.shape[0] - 1)
199-
]
200-
weight = weight.unsqueeze(1)
201-
for seq_idx, (bos, eos) in enumerate(seq_begin_end_idx):
202-
slot = int(cache_indices[seq_idx].item())
203-
204-
seq_x = x[:, bos:eos].unsqueeze(0)
205-
if bool(has_initial_state[seq_idx].item()):
206-
initial_state = conv_states[slot, :, :state_len].unsqueeze(0)
207-
else:
208-
initial_state = torch.zeros(
209-
1,
210-
weight.shape[0],
211-
state_len,
212-
device=seq_x.device,
213-
dtype=seq_x.dtype,
214-
)
215-
216-
conv_input = torch.cat([initial_state, seq_x], dim=-1).to(weight.dtype)
217-
seq_out = F.conv1d(
218-
conv_input,
219-
weight,
220-
bias,
221-
padding=0,
222-
groups=weight.shape[0],
223-
)
224-
seq_out = seq_out[..., -seq_x.shape[-1] :].to(dtype=x.dtype)
225-
if activation in ("silu", "swish"):
226-
seq_out = F.silu(seq_out)
227-
228-
out[:, bos:eos] = seq_out.squeeze(0)
229-
conv_states[slot, :, :state_len].copy_(conv_input[..., -state_len:].squeeze(0))
230185

231-
return out
232186

233187

234188
def causal_conv1d_update_torch(

0 commit comments

Comments
 (0)