@@ -280,9 +280,10 @@ impl CausalSelfAttention {
280280 ) -> Result < Tensor > {
281281 let _enter = self . span . enter ( ) ;
282282 let ( b_sz, seq_len, hidden_size) = x. dims3 ( ) ?;
283- let q = self . q_proj . forward ( x) ?;
284- let k = self . k_proj . forward ( x) ?;
285- let v = self . v_proj . forward ( x) ?;
283+ let ( x_scale, x) = quantize_fp8_scalar_gpu ( x) ?;
284+ let q = self . q_proj . forward_fp8 ( & x, & x_scale) ?;
285+ let k = self . k_proj . forward_fp8 ( & x, & x_scale) ?;
286+ let v = self . v_proj . forward_fp8 ( & x, & x_scale) ?;
286287
287288 let q = q
288289 . reshape ( ( b_sz, seq_len, self . num_attention_heads , self . head_dim ) ) ?
@@ -525,6 +526,15 @@ pub enum LlamaLinear {
525526 Candle ( super :: with_tracing:: Linear ) ,
526527}
527528
529+ impl LlamaLinear {
530+ fn forward_fp8 ( & self , xs : & Tensor , scale : & Tensor ) -> Result < Tensor > {
531+ match self {
532+ LlamaLinear :: CublasLt ( ln) => ln. forward_fp8 ( xs, scale) ,
533+ LlamaLinear :: Candle ( ln) => candle:: bail!( "candle linear does not support fp8" ) ,
534+ }
535+ }
536+ }
537+
528538#[ derive( Debug , Clone ) ]
529539pub struct CublasLtLinearFp8 {
530540 pub prefix : String ,
@@ -534,12 +544,14 @@ pub struct CublasLtLinearFp8 {
534544 pub cublas_lt : CublasLt ,
535545}
536546
537- impl candle:: Module for CublasLtLinearFp8 {
538- fn forward ( & self , x : & Tensor ) -> Result < Tensor > {
547+ impl CublasLtLinearFp8 {
548+ fn forward_fp8 ( & self , x : & Tensor , scale : & Tensor ) -> Result < Tensor > {
549+ if x. dtype ( ) != DType :: F8E4M3 {
550+ candle:: bail!( "input tensor must be fp8, got {:?}" , x. dtype( ) ) ;
551+ }
552+
539553 let dims = x. dims ( ) ;
540554 let w_in = * self . weight . dims ( ) . last ( ) . unwrap ( ) ;
541- // let x = x.t()?;
542- // let in_dims = x.dims();
543555
544556 match * dims {
545557 // ----------------------------------------------------------------
@@ -568,18 +580,13 @@ impl candle::Module for CublasLtLinearFp8 {
568580 [ b, s, k] if k == w_in => {
569581 let m = b * s;
570582 let x = x. reshape ( ( m, k) ) ?;
571- let ( a_scale , a_fp8 ) = quantize_fp8_scalar ( & x ) ? ;
583+
572584 let out_dim = self . weight . dims ( ) [ 0 ] ;
573- let b_scale = self
574- . weight_scale
575- . to_dtype ( DType :: F32 ) ?
576- . reshape ( ( ) ) ?
577- . to_vec0 :: < f32 > ( ) ?; //TODO leave on cuda device
578585 let y = candle_cublaslt:: fp8_scalar_fused_matmul (
579- & a_fp8 ,
580- a_scale ,
586+ & x ,
587+ & scale ,
581588 & self . weight ,
582- b_scale ,
589+ & self . weight_scale ,
583590 None ,
584591 DType :: F16 ,
585592 None ,
@@ -599,6 +606,14 @@ impl candle::Module for CublasLtLinearFp8 {
599606 }
600607}
601608
609+ impl candle:: Module for CublasLtLinearFp8 {
610+ fn forward ( & self , xs : & Tensor ) -> Result < Tensor > {
611+ let ( x_scale, x_fp8) = quantize_fp8_scalar_gpu ( & xs) ?;
612+ let y = self . forward_fp8 ( & x_fp8, & x_scale) ?;
613+ Ok ( y)
614+ }
615+ }
616+
602617impl candle:: Module for LlamaLinear {
603618 fn forward ( & self , xs : & Tensor ) -> Result < Tensor > {
604619 match self {
@@ -613,22 +628,6 @@ pub fn linear(d1: usize, d2: usize, vb: VarBuilder) -> Result<LlamaLinear> {
613628 Ok ( LlamaLinear :: Candle ( ln) )
614629}
615630
616- fn quantize_fp8_scalar ( x : & Tensor ) -> Result < ( f32 , Tensor ) > {
617- let max_abs = x. abs ( ) ?. max_all ( ) ?. to_dtype ( DType :: F32 ) ?. to_vec0 :: < f32 > ( ) ?;
618- let eps = 1e-6f32 ;
619-
620- let scale = if max_abs > eps {
621- max_abs / ( float8:: F8E4M3 :: MAX . to_f32 ( ) - eps)
622- } else {
623- 1.0f32
624- } ;
625-
626- let scale_b = Tensor :: from_vec ( vec ! [ scale] , ( ) , x. device ( ) ) ?. to_dtype ( x. dtype ( ) ) ?;
627- let y = x. broadcast_div ( & scale_b) ?. to_dtype ( DType :: F8E4M3 ) ?;
628-
629- Ok ( ( scale, y) )
630- }
631-
632631fn quantize_fp8_scalar_gpu ( x : & Tensor ) -> Result < ( Tensor /*scale_f32*/ , Tensor /*x_fp8*/ ) > {
633632 // 0-D tensor on device
634633 let amax = x. abs ( ) ?. max_all ( ) ?. to_dtype ( DType :: F32 ) ?; // 1 pass (reduce)
@@ -677,7 +676,12 @@ struct Mlp {
677676impl Mlp {
678677 fn forward ( & self , x : & Tensor ) -> Result < Tensor > {
679678 let _enter = self . span . enter ( ) ;
680- let x = ( candle_nn:: ops:: silu ( & self . gate_proj . forward ( x) ?) ? * self . up_proj . forward ( x) ?) ?;
679+
680+ let ( x_scale, x_fp8) = quantize_fp8_scalar_gpu ( x) ?;
681+
682+ let x = ( candle_nn:: ops:: silu ( & self . gate_proj . forward_fp8 ( & x_fp8, & x_scale) ?) ?
683+ * self . up_proj . forward_fp8 ( & x_fp8, & x_scale) ?) ?;
684+
681685 self . down_proj . forward ( & x)
682686 }
683687
@@ -697,48 +701,3 @@ impl Mlp {
697701 } )
698702 }
699703}
700-
701- // pub struct LlamaMlp {
702- // gate_proj: LlamaLinear,
703- // up_proj: LlamaLinear,
704- // down_proj: LlamaLinear,
705- // span: tracing::Span,
706- // }
707-
708- // impl LlamaMlp {
709- // fn forward(&self, x: &Tensor) -> Result<Tensor> {
710- // let _enter = self.span.enter();
711-
712- // // SiLU(gate)
713- // let gate = self.gate_proj.forward(x)?.silu()?;
714-
715- // // linear(up)
716- // let up = self.up_proj.forward(x)?;
717-
718- // // element-wise product
719- // let hidden = (&gate * &up)?;
720-
721- // // final linear
722- // let y = self.down_proj.forward(&hidden)?;
723-
724- // Ok(y)
725- // }
726-
727- // fn load(cublas_lt: CublasLt, vb: VarBuilder, cfg: &Config) -> Result<Self> {
728- // let span = tracing::span!(tracing::Level::TRACE, "mlp");
729-
730- // let h_size = cfg.hidden_size;
731- // let i_size = cfg.intermediate_size;
732-
733- // let gate_proj = cublas_linear(cublas_lt.clone(), h_size, i_size, vb.pp("gate_proj"))?;
734- // let up_proj = cublas_linear(cublas_lt.clone(), h_size, i_size, vb.pp("up_proj"))?;
735- // let down_proj = cublas_linear(cublas_lt.clone(), i_size, h_size, vb.pp("down_proj"))?;
736-
737- // Ok(Self {
738- // gate_proj,
739- // up_proj,
740- // down_proj,
741- // span,
742- // })
743- // }
744- // }
0 commit comments