55
66@triton .jit
77def _copy_linear_att_state_to_kv_buffer (
8- gpu_conv_ptr , # [linear_layer_num, size_num, xdim]
8+ gpu_conv_ptr , # [linear_layer_num, size_num, conv_dim * gpu_widened_width] (uint8 tail)
99 gpu_ssm_ptr , # [linear_layer_num, size_num, xxdim]
10- cpu_kv_conv_ptr , # [size, linear_layer_num, xdim]
10+ cpu_kv_conv_ptr , # [size, linear_layer_num, conv_dim * width_narrow] (uint8 tail)
1111 cpu_kv_ssm_ptr , # [size, linear_layer_num, xxdim]
1212 b_req_idx , # [batch_size,]
1313 big_page_buffer_ids , # [batch_size,]
14+ num_accepted_tokens_ptr , # [batch_size,]
1415 gpu_conv_stride_l ,
1516 gpu_conv_stride_s ,
1617 gpu_conv_stride_d ,
@@ -24,7 +25,9 @@ def _copy_linear_att_state_to_kv_buffer(
2425 cpu_kv_ssm_stride_l ,
2526 cpu_kv_ssm_stride_d ,
2627 mtp_step ,
27- gpu_conv_tail_dim ,
28+ conv_dim , # number of conv rows (the d dimension)
29+ gpu_conv_row_bytes , # widened per-row byte length: gpu_widened_width * itemsize
30+ conv_narrow_row_bytes , # narrow per-row byte length: width_narrow * itemsize
2831 gpu_ssm_tail_dim ,
2932 BLOCK : tl .constexpr ,
3033):
@@ -40,28 +43,26 @@ def _copy_linear_att_state_to_kv_buffer(
4043 return
4144
4245 cur_req_idx = tl .load (b_req_idx + cur_batch ).to (tl .int64 )
43- cur_state_req_idx = (cur_req_idx * (mtp_step + 1 )).to (tl .int64 )
46+ accept_len = tl .load (num_accepted_tokens_ptr + cur_batch ).to (tl .int64 )
47+ canonical_off = accept_len - 1
4448
45- for i in range (tl .cdiv (gpu_conv_tail_dim , BLOCK )):
46- gpu_start_off = i * BLOCK + tl .arange (0 , BLOCK )
47- mask = gpu_start_off < gpu_conv_tail_dim
48- conv_data = tl .load (
49- gpu_conv_ptr + cur_layer * gpu_conv_stride_l + cur_state_req_idx * gpu_conv_stride_s + gpu_start_off ,
50- mask = mask ,
51- )
52- dest_conv_ptr = (
53- cpu_kv_conv_ptr
54- + big_page_buffer_idx * cpu_kv_conv_stride_s
55- + cur_layer * cpu_kv_conv_stride_l
56- + gpu_start_off
57- )
58- tl .store (dest_conv_ptr , conv_data , mask = mask )
49+ conv_src_slot = cur_req_idx
50+ conv_off_bytes = canonical_off * gpu_conv_stride_d
51+ gpu_conv_base = gpu_conv_ptr + cur_layer * gpu_conv_stride_l + conv_src_slot * gpu_conv_stride_s + conv_off_bytes
52+ cpu_conv_base = cpu_kv_conv_ptr + big_page_buffer_idx * cpu_kv_conv_stride_s + cur_layer * cpu_kv_conv_stride_l
53+ for d in range (conv_dim ):
54+ for i in range (tl .cdiv (conv_narrow_row_bytes , BLOCK )):
55+ off = i * BLOCK + tl .arange (0 , BLOCK )
56+ mask = off < conv_narrow_row_bytes
57+ conv_data = tl .load (gpu_conv_base + d * gpu_conv_row_bytes + off , mask = mask )
58+ tl .store (cpu_conv_base + d * cpu_kv_conv_stride_d + off , conv_data , mask = mask )
5959
60+ ssm_src_slot = (cur_req_idx * (mtp_step + 1 ) + canonical_off ).to (tl .int64 )
6061 for i in range (tl .cdiv (gpu_ssm_tail_dim , BLOCK )):
6162 gpu_start_off = i * BLOCK + tl .arange (0 , BLOCK )
6263 mask = gpu_start_off < gpu_ssm_tail_dim
6364 ssm_data = tl .load (
64- gpu_ssm_ptr + cur_layer * gpu_ssm_stride_l + cur_state_req_idx * gpu_ssm_stride_s + gpu_start_off ,
65+ gpu_ssm_ptr + cur_layer * gpu_ssm_stride_l + ssm_src_slot * gpu_ssm_stride_s + gpu_start_off ,
6566 mask = mask ,
6667 )
6768 dest_ssm_ptr = (
@@ -75,32 +76,51 @@ def _copy_linear_att_state_to_kv_buffer(
7576def copy_linear_att_state_to_kv_buffer (
7677 b_req_idx : torch .Tensor ,
7778 big_page_buffer_ids : torch .Tensor ,
78- gpu_conv_state : torch .Tensor , # [linear_layer_num, s, ... ]
79- gpu_ssm_state : torch .Tensor , # [linear_layer_num, s , ...]
80- cpu_kv_conv_state : torch .Tensor , # [s , linear_layer_num, ... ]
81- cpu_kv_ssm_state : torch .Tensor , # [s , linear_layer_num, ...]
79+ gpu_conv_state : torch .Tensor , # [linear_layer_num, s_widened, conv_dim, gpu_widened_width ]
80+ gpu_ssm_state : torch .Tensor , # [linear_layer_num, s_block , ...]
81+ cpu_kv_conv_state : torch .Tensor , # [size , linear_layer_num, conv_dim, width_narrow ]
82+ cpu_kv_ssm_state : torch .Tensor , # [size , linear_layer_num, ...]
8283 mtp_step : int ,
84+ b_num_accepted_tokens : torch .Tensor , # [batch_size,] per-req post-accept count (>=1)
8385):
8486 assert len (b_req_idx ) == big_page_buffer_ids .shape [0 ]
87+ assert len (b_req_idx ) == b_num_accepted_tokens .shape [0 ]
8588 BLOCK = 4096
86- gpu_conv_state = gpu_conv_state .view (gpu_conv_state .shape [0 ], gpu_conv_state .shape [1 ], - 1 ).view (dtype = torch .uint8 )
87- gpu_ssm_state = gpu_ssm_state .view (gpu_ssm_state .shape [0 ], gpu_ssm_state .shape [1 ], - 1 ).view (dtype = torch .uint8 )
88- cpu_kv_conv_state = cpu_kv_conv_state .view (cpu_kv_conv_state .shape [0 ], cpu_kv_conv_state .shape [1 ], - 1 ).view (
89- dtype = torch .uint8
89+
90+ assert gpu_conv_state .dim () >= 4 , "gpu_conv_state must be [layer, s, conv_dim, widened_width]"
91+ assert cpu_kv_conv_state .dim () >= 4 , "cpu_kv_conv_state must be [size, layer, conv_dim, width_narrow]"
92+ # #6: the byte snapshot hardcodes gpu_conv_stride_d=conv_itemsize, which is only valid when the
93+ # widened-width axis is element-contiguous (stride 1). Fail fast instead of snapshotting wrong bytes.
94+ assert gpu_conv_state .stride (3 ) == 1 , (
95+ "gpu_conv_state widened-width axis must be element-contiguous (stride 1); "
96+ "gpu_conv_stride_d=conv_itemsize assumes it"
97+ )
98+ # #18: canonical_off = accept_len - 1 indexes into the widened slot; bound it to [0, mtp_step]
99+ # (accept_len in [1, mtp_step+1]) so a stale/oversized accept-count can't slice past the slot.
100+ assert int (b_num_accepted_tokens .min ()) >= 1 and int (b_num_accepted_tokens .max ()) <= mtp_step + 1 , (
101+ f"b_num_accepted_tokens out of range [1, { mtp_step + 1 } ]: "
102+ f"min={ int (b_num_accepted_tokens .min ())} max={ int (b_num_accepted_tokens .max ())} "
90103 )
104+ conv_itemsize = gpu_conv_state .element_size ()
105+ gpu_conv_state = gpu_conv_state .view (
106+ gpu_conv_state .shape [0 ], gpu_conv_state .shape [1 ], gpu_conv_state .shape [2 ], - 1
107+ ).view (dtype = torch .uint8 )
108+ cpu_kv_conv_state = cpu_kv_conv_state .view (
109+ cpu_kv_conv_state .shape [0 ], cpu_kv_conv_state .shape [1 ], cpu_kv_conv_state .shape [2 ], - 1
110+ ).view (dtype = torch .uint8 )
111+
112+ gpu_ssm_state = gpu_ssm_state .view (gpu_ssm_state .shape [0 ], gpu_ssm_state .shape [1 ], - 1 ).view (dtype = torch .uint8 )
91113 cpu_kv_ssm_state = cpu_kv_ssm_state .view (cpu_kv_ssm_state .shape [0 ], cpu_kv_ssm_state .shape [1 ], - 1 ).view (
92114 dtype = torch .uint8
93115 )
94- assert gpu_conv_state .shape [- 1 ] == cpu_kv_conv_state .shape [- 1 ]
116+
117+ assert gpu_conv_state .shape [2 ] == cpu_kv_conv_state .shape [2 ], "conv_dim mismatch between gpu and cpu conv buffers"
95118 assert gpu_ssm_state .shape [- 1 ] == cpu_kv_ssm_state .shape [- 1 ]
96- assert (
97- gpu_conv_state .stride (- 1 )
98- == gpu_ssm_state .stride (- 1 )
99- == cpu_kv_conv_state .stride (- 1 )
100- == cpu_kv_ssm_state .stride (- 1 )
101- )
102119
103- gpu_conv_tail_dim = gpu_conv_state .shape [- 1 ]
120+ conv_dim = gpu_conv_state .shape [2 ]
121+ gpu_conv_row_bytes = gpu_conv_state .shape [- 1 ] # widened per-row byte length
122+ conv_narrow_row_bytes = cpu_kv_conv_state .shape [- 1 ] # narrow per-row byte length
123+ assert conv_narrow_row_bytes <= gpu_conv_row_bytes
104124 gpu_ssm_tail_dim = gpu_ssm_state .shape [- 1 ]
105125
106126 layer_num = gpu_conv_state .shape [0 ]
@@ -114,9 +134,10 @@ def copy_linear_att_state_to_kv_buffer(
114134 cpu_kv_ssm_ptr = cpu_kv_ssm_state ,
115135 b_req_idx = b_req_idx ,
116136 big_page_buffer_ids = big_page_buffer_ids ,
137+ num_accepted_tokens_ptr = b_num_accepted_tokens ,
117138 gpu_conv_stride_l = gpu_conv_state .stride (0 ),
118139 gpu_conv_stride_s = gpu_conv_state .stride (1 ),
119- gpu_conv_stride_d = gpu_conv_state . stride ( 2 ) ,
140+ gpu_conv_stride_d = conv_itemsize ,
120141 gpu_ssm_stride_l = gpu_ssm_state .stride (0 ),
121142 gpu_ssm_stride_s = gpu_ssm_state .stride (1 ),
122143 gpu_ssm_stride_d = gpu_ssm_state .stride (2 ),
@@ -127,7 +148,9 @@ def copy_linear_att_state_to_kv_buffer(
127148 cpu_kv_ssm_stride_l = cpu_kv_ssm_state .stride (1 ),
128149 cpu_kv_ssm_stride_d = cpu_kv_ssm_state .stride (2 ),
129150 mtp_step = mtp_step ,
130- gpu_conv_tail_dim = gpu_conv_tail_dim ,
151+ conv_dim = conv_dim ,
152+ gpu_conv_row_bytes = gpu_conv_row_bytes ,
153+ conv_narrow_row_bytes = conv_narrow_row_bytes ,
131154 gpu_ssm_tail_dim = gpu_ssm_tail_dim ,
132155 BLOCK = BLOCK ,
133156 )
0 commit comments