"""Single launch CUDA decode of the four layer W4A16 Kimi Linear motif.""" from __future__ import annotations import torch import torch.nn as nn from torch.utils.cpp_extension import load_inline class QuantLinear(nn.Module): def __init__(self, k, n): super().__init__() self.register_buffer("w_q", torch.zeros(k // 2, n, dtype=torch.uint8)) self.register_buffer("scales", torch.zeros(k // 128, n, dtype=torch.bfloat16)) self.register_buffer("zeros", torch.zeros(k // 128, n, dtype=torch.bfloat16)) class QuantExperts(nn.Module): def __init__(self, e, k, n): super().__init__() self.register_buffer("w_q", torch.zeros(e, k // 2, n, dtype=torch.uint8)) self.register_buffer("scales", torch.zeros(e, k // 128, n, dtype=torch.bfloat16)) self.register_buffer("zeros", torch.zeros(e, k // 128, n, dtype=torch.bfloat16)) class KDA(nn.Module): def __init__(self, cfg): super().__init__() d, c = cfg.hidden, cfg.kda_heads * cfg.kda_head_dim self.q_proj = QuantLinear(d, c) self.k_proj = QuantLinear(d, c) self.v_proj = QuantLinear(d, c) self.g_proj = QuantLinear(d, c) self.beta_proj = nn.Linear(d, cfg.kda_heads, bias=False, dtype=cfg.dtype) self.conv_w = nn.Parameter(torch.empty(3, c, cfg.short_conv, dtype=cfg.dtype)) self.o_proj = QuantLinear(c, d) class MLA(nn.Module): def __init__(self, cfg): super().__init__() d, h = cfg.hidden, cfg.mla_heads self.q_proj = QuantLinear(d, h * (cfg.qk_nope + cfg.qk_rope)) self.kv_a = QuantLinear(d, cfg.kv_lora + cfg.qk_rope) self.kv_b = QuantLinear(cfg.kv_lora, h * (cfg.qk_nope + cfg.v_head)) self.o_proj = QuantLinear(h * cfg.v_head, d) class MoE(nn.Module): def __init__(self, cfg): super().__init__() d, m, e = cfg.hidden, cfg.moe_inter, cfg.n_experts self.router = nn.Linear(d, e, bias=False, dtype=cfg.dtype) self.gate = QuantExperts(e, d, m) self.up = QuantExperts(e, d, m) self.down = QuantExperts(e, m, d) self.s_gate = QuantExperts(cfg.n_shared, d, m) self.s_up = QuantExperts(cfg.n_shared, d, m) self.s_down = QuantExperts(cfg.n_shared, m, d) class Block(nn.Module): def __init__(self, cfg, kind): super().__init__() self.kind = kind self.attn_norm = nn.Parameter(torch.ones(cfg.hidden, dtype=cfg.dtype)) self.moe_norm = nn.Parameter(torch.ones(cfg.hidden, dtype=cfg.dtype)) self.attn = KDA(cfg) if kind == "K" else MLA(cfg) self.moe = MoE(cfg) CPP_SRC = r''' #include #include #include #include #include using bf = __nv_bfloat16; struct W { const unsigned char* q; const bf* s; const bf* z; int K; int N; }; struct A { W w[44]; const bf *norm[4], *mn[4], *conv[3], *beta[3], *router[4]; float *S[3]; bf *cq[3], *ck[3], *cv[3]; const bf *oldc, *oldr; bf *newc, *newr; const bf *input; bf *output; float *t; int L; }; void launch(A, cudaStream_t); void run(std::vector ts, int L) { A a{};a.input=(const bf*)ts[0].data_ptr();a.output=(bf*)ts[1].data_ptr();a.t=(float*)ts[2].data_ptr();a.L=L; for(int i=0;i<3;i++) {int p=3+i*4;a.S[i]=(float*)ts[p].data_ptr();a.cq[i]=(bf*)ts[p+1].data_ptr();a.ck[i]=(bf*)ts[p+2].data_ptr();a.cv[i]=(bf*)ts[p+3].data_ptr();} a.oldc=(const bf*)ts[15].data_ptr();a.oldr=(const bf*)ts[16].data_ptr();a.newc=(bf*)ts[17].data_ptr();a.newr=(bf*)ts[18].data_ptr(); for(int i=0;i<4;i++) {int p=19+i*5;a.norm[i]=(const bf*)ts[p].data_ptr();a.mn[i]=(const bf*)ts[p+1].data_ptr();if(i<3) {a.conv[i]=(const bf*)ts[p+2].data_ptr();a.beta[i]=(const bf*)ts[p+3].data_ptr();}a.router[i]=(const bf*)ts[p+4].data_ptr();} for(int i=0;i<44;i++) {int p=39+i*3;a.w[i].q=(const unsigned char*)ts[p].data_ptr();a.w[i].s=(const bf*)ts[p+1].data_ptr();a.w[i].z=(const bf*)ts[p+2].data_ptr();a.w[i].K=ts[p].size(ts[p].dim()-2)*2;a.w[i].N=ts[p].size(ts[p].dim()-1);} launch(a, at::cuda::getCurrentCUDAStream()); }''' CUDA_SRC = r''' #include #include #include #include #define GID (blockIdx.x*blockDim.x+threadIdx.x) #define GSTRIDE (blockDim.x*gridDim.x) using bf = __nv_bfloat16; struct W { const unsigned char* q; const bf* s; const bf* z; int K; int N; }; struct A { W w[44]; const bf *norm[4], *mn[4], *conv[3], *beta[3], *router[4]; float *S[3]; bf *cq[3], *ck[3], *cv[3]; const bf *oldc, *oldr; bf *newc, *newr; const bf *input; bf *output; float *t; int L; }; __device__ __forceinline__ float B(const bf v) { return __bfloat162float(v); } __device__ __forceinline__ float R(float v) { return B(__float2bfloat16_rn(v)); } __device__ __forceinline__ float sigmoid(float v) { return 1.f / (1.f + expf(-v)); } __device__ __forceinline__ float silu(float v) { return v * sigmoid(v); } __device__ __noinline__ void gemv(const A& a, int wi, const float* x, float* y, int e, bool round_out) { const W& w = a.w[wi]; int K=w.K,N=w.N,eo=e<0?0:e; int tile_width=N<=1024?8:16; int ksplit=128/tile_width; int lane_n=threadIdx.x&(tile_width-1),lane_k=threadIdx.x/(tile_width); __shared__ float part[128]; int tiles=(N+tile_width-1)/tile_width; for(int tile=blockIdx.x;tile>4)-zero)*scale,sum); } } } part[threadIdx.x]=sum; __syncthreads(); if(lane_k==0 && nbest) { best=t[88000+e]; bi=e; } chosen[bi]=true; ix[j]=bi; val[j]=best; } float mx=val[0],den=0.f; for(int j=0;j<8;j++) den+=expf(val[j]-mx); for(int j=0;j<8;j++) {t[900200+j]=float(ix[j]);t[900208+j]=2.446f*expf(val[j]-mx)/den;} } cooperative_groups::this_grid().sync(); for(int n=GID;n<2304;n+=GSTRIDE) t[65536+n]=0.f; cooperative_groups::this_grid().sync(); for(int j=0;j<9;j++) { int e=j<8 ? int(t[900200+j]) : 0; int wi=base+(j<8 ? 5 : 8); gemv(a,wi,x,t+73728,e,false); gemv(a,wi+1,x,t+76800,e,false); for(int n=GID;n<1024;n+=GSTRIDE) t[79872+n]=silu(t[73728+n])*t[76800+n]; cooperative_groups::this_grid().sync(); gemv(a,wi+2,t+79872,t+82944,e,false); float weight=j<8 ? t[900208+j] : 1.f; for(int n=GID;n<2304;n+=GSTRIDE) t[65536+n]+=weight*t[82944+n]; cooperative_groups::this_grid().sync(); } for(int n=GID;n<2304;n+=GSTRIDE) out[n]=R(out[n]+R(t[65536+n])); cooperative_groups::this_grid().sync(); } __device__ __forceinline__ float deq(const W& w,int k,int n) { unsigned char q=w.q[(k/2)*w.N+n]; float z=B(w.z[(k/128)*w.N+n]),s=B(w.s[(k/128)*w.N+n]); return R(R(float((k&1)?q>>4:q&15)-z)*s); } __device__ __noinline__ void mla(const A& a,int layer,const float* x,float* attn_out) { float* t=a.t; int wi=layer*11; gemv(a,wi+0,x,t+16384,-1,true); gemv(a,wi+1,x,t+24576,-1,true); for(int j=GID;j<32;j+=GSTRIDE) { float ang=float(a.L)*powf(10000.f,-float(2*j)/64.f), co=cosf(ang),si=sinf(ang); float e=t[24576+512+2*j],o=t[24576+512+2*j+1]; a.newr[a.L*64+2*j]=__float2bfloat16_rn(e*co-o*si); a.newr[a.L*64+2*j+1]=__float2bfloat16_rn(o*co+e*si); for(int h=0;h<32;h++) { int ix=16384+h*192+128+2*j; e=t[ix];o=t[ix+1];t[ix]=R(e*co-o*si);t[ix+1]=R(o*co+e*si); } } for(int j=GID;j<512;j+=GSTRIDE) a.newc[a.L*512+j]=__float2bfloat16_rn(t[24576+j]); for(int j=GID;j