Skip to content

Commit 5f299f1

Browse files
committed
llama fp8: consolidate quant steps
1 parent 1073f5f commit 5f299f1

1 file changed

Lines changed: 37 additions & 78 deletions

File tree

candle-transformers/src/models/llama_fp8.rs

Lines changed: 37 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -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)]
529539
pub 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+
602617
impl 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-
632631
fn 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 {
677676
impl 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

Comments
 (0)