@@ -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
234188def causal_conv1d_update_torch (
0 commit comments