@@ -2613,8 +2613,12 @@ def _post_residual_gate_bwd_kernel_for(
26132613 g_dim = g_heads * v_dim
26142614 g_offset = projected_dim - g_dim
26152615 features = total_heads * v_dim
2616- lanes = batch * seq * features
2617- threads = _threads_for (features )
2616+ dy_lanes = batch * seq * features
2617+ dconv_lanes = batch * seq * conv_dim
2618+ dD_lanes = total_heads * v_dim
2619+ dprojected_lanes = batch * seq * projected_dim
2620+ lanes = dy_lanes + dconv_lanes + dD_lanes + dprojected_lanes
2621+ threads = _threads_for (max (features , conv_dim , projected_dim ))
26182622 accum_dtype = "float32"
26192623
26202624 @T .prim_func
@@ -2633,51 +2637,106 @@ def bwd(
26332637 tid = T .get_thread_binding (0 )
26342638 lane = bx * threads + tid
26352639 if lane < lanes :
2636- feature = lane % features
2637- t = (lane // features ) % seq
2638- b = lane // (features * seq )
2639- h = feature // v_dim
2640- vv = feature % v_dim
2641- v_src = h // v_group
2642- v_index = v_offset + v_src * v_dim + vv
2643- g_flat = feature // g_repeat
2644- g_index = g_offset + g_flat
2645- dpost_val = T .cast (dpost [b , t , feature ], accum_dtype )
2646- g_val = T .cast (projected [b , t , g_index ], accum_dtype )
2647- sig_g = T .alloc_var (T .float32 , init = 0.0 )
2648- if g_val >= 0.0 :
2649- sig_g = 1.0 / (1.0 + T .exp (- g_val ))
2640+ if lane < dy_lanes :
2641+ feature = lane % features
2642+ t = (lane // features ) % seq
2643+ b = lane // (features * seq )
2644+ h = feature // v_dim
2645+ vv = feature % v_dim
2646+ g_flat = feature // g_repeat
2647+ g_index = g_offset + g_flat
2648+ dpost_val = T .cast (dpost [b , t , feature ], accum_dtype )
2649+ g_val = T .cast (projected [b , t , g_index ], accum_dtype )
2650+ sig_g = T .alloc_var (T .float32 , init = 0.0 )
2651+ if g_val >= 0.0 :
2652+ sig_g = 1.0 / (1.0 + T .exp (- g_val ))
2653+ else :
2654+ sig_g = T .exp (g_val )
2655+ sig_g = sig_g / (1.0 + sig_g )
2656+ dy_recurrent [b , t , h , vv ] = T .cast (
2657+ dpost_val * g_val * sig_g ,
2658+ grad_dtype ,
2659+ )
2660+ elif lane < dy_lanes + dconv_lanes :
2661+ local = lane - dy_lanes
2662+ c = local % conv_dim
2663+ t = (local // conv_dim ) % seq
2664+ b = local // (conv_dim * seq )
2665+ acc = T .alloc_var (T .float32 , init = 0.0 )
2666+ if c >= v_offset and c < v_offset + v_heads * v_dim :
2667+ v_rel = c - v_offset
2668+ v_src = v_rel // v_dim
2669+ vv = v_rel % v_dim
2670+ for local_h in T .serial (v_group ):
2671+ h = v_src * v_group + local_h
2672+ feature = h * v_dim + vv
2673+ g_flat = feature // g_repeat
2674+ g_index = g_offset + g_flat
2675+ dpost_val = T .cast (dpost [b , t , feature ], accum_dtype )
2676+ g_val = T .cast (projected [b , t , g_index ], accum_dtype )
2677+ sig_g = T .alloc_var (T .float32 , init = 0.0 )
2678+ if g_val >= 0.0 :
2679+ sig_g = 1.0 / (1.0 + T .exp (- g_val ))
2680+ else :
2681+ sig_g = T .exp (g_val )
2682+ sig_g = sig_g / (1.0 + sig_g )
2683+ dskipped = dpost_val * g_val * sig_g
2684+ d_val = T .cast (D [h , vv ], accum_dtype )
2685+ acc = acc + dskipped * d_val
2686+ dconv_input [b , t , c ] = T .cast (acc , grad_dtype )
2687+ elif lane < dy_lanes + dconv_lanes + dD_lanes :
2688+ local = lane - dy_lanes - dconv_lanes
2689+ h = local // v_dim
2690+ vv = local % v_dim
2691+ v_src = h // v_group
2692+ v_index = v_offset + v_src * v_dim + vv
2693+ acc = T .alloc_var (T .float32 , init = 0.0 )
2694+ for b in T .serial (batch ):
2695+ for t in T .serial (seq ):
2696+ feature = h * v_dim + vv
2697+ g_flat = feature // g_repeat
2698+ g_index = g_offset + g_flat
2699+ dpost_val = T .cast (dpost [b , t , feature ], accum_dtype )
2700+ g_val = T .cast (projected [b , t , g_index ], accum_dtype )
2701+ sig_g = T .alloc_var (T .float32 , init = 0.0 )
2702+ if g_val >= 0.0 :
2703+ sig_g = 1.0 / (1.0 + T .exp (- g_val ))
2704+ else :
2705+ sig_g = T .exp (g_val )
2706+ sig_g = sig_g / (1.0 + sig_g )
2707+ dskipped = dpost_val * g_val * sig_g
2708+ v_val = T .cast (conv_input [b , t , v_index ], accum_dtype )
2709+ acc = acc + dskipped * v_val
2710+ dD [h , vv ] = T .cast (acc , grad_dtype )
26502711 else :
2651- sig_g = T .exp (g_val )
2652- sig_g = sig_g / (1.0 + sig_g )
2653- silu_g = g_val * sig_g
2654- silu_dg = sig_g * (1.0 + g_val * (1.0 - sig_g ))
2655- y_val = T .cast (y [b , t , h , vv ], accum_dtype )
2656- v_val = T .cast (conv_input [b , t , v_index ], accum_dtype )
2657- d_val = T .cast (D [h , vv ], accum_dtype )
2658- skipped = y_val + v_val * d_val
2659- dskipped = dpost_val * silu_g
2660-
2661- T .atomic_add (
2662- dy_recurrent [b , t , h , vv ],
2663- dskipped ,
2664- memory_order = "relaxed" ,
2665- )
2666- T .atomic_add (
2667- dconv_input [b , t , v_index ],
2668- dskipped * d_val ,
2669- memory_order = "relaxed" ,
2670- )
2671- T .atomic_add (
2672- dD [h , vv ],
2673- dskipped * v_val ,
2674- memory_order = "relaxed" ,
2675- )
2676- T .atomic_add (
2677- dprojected [b , t , g_index ],
2678- dpost_val * skipped * silu_dg ,
2679- memory_order = "relaxed" ,
2680- )
2712+ local = lane - dy_lanes - dconv_lanes - dD_lanes
2713+ p = local % projected_dim
2714+ t = (local // projected_dim ) % seq
2715+ b = local // (projected_dim * seq )
2716+ acc = T .alloc_var (T .float32 , init = 0.0 )
2717+ if p >= g_offset and p < g_offset + g_dim :
2718+ g_flat = p - g_offset
2719+ g_val = T .cast (projected [b , t , p ], accum_dtype )
2720+ sig_g = T .alloc_var (T .float32 , init = 0.0 )
2721+ if g_val >= 0.0 :
2722+ sig_g = 1.0 / (1.0 + T .exp (- g_val ))
2723+ else :
2724+ sig_g = T .exp (g_val )
2725+ sig_g = sig_g / (1.0 + sig_g )
2726+ silu_dg = sig_g * (1.0 + g_val * (1.0 - sig_g ))
2727+ for r in T .serial (g_repeat ):
2728+ feature = g_flat * g_repeat + r
2729+ h = feature // v_dim
2730+ vv = feature % v_dim
2731+ v_src = h // v_group
2732+ v_index = v_offset + v_src * v_dim + vv
2733+ dpost_val = T .cast (dpost [b , t , feature ], accum_dtype )
2734+ y_val = T .cast (y [b , t , h , vv ], accum_dtype )
2735+ v_val = T .cast (conv_input [b , t , v_index ], accum_dtype )
2736+ d_val = T .cast (D [h , vv ], accum_dtype )
2737+ skipped = y_val + v_val * d_val
2738+ acc = acc + dpost_val * skipped * silu_dg
2739+ dprojected [b , t , p ] = T .cast (acc , grad_dtype )
26812740
26822741 bwd = _with_global_symbol (
26832742 bwd ,
0 commit comments