(&self, q: &Tensor, k: &Tensor, v: &Tensor, scale: f32, causal: bool)
| 378 | } |
| 379 | |
| 380 | fn attention(&self, q: &Tensor, k: &Tensor, v: &Tensor, scale: f32, causal: bool) -> Result<Tensor> { |
| 381 | let orig = q.dtype(); |
| 382 | let (qf, kf, vf); |
| 383 | let (q, k, v) = if orig == DType::F32 { (q, k, v) } |
| 384 | else { qf = q.to_dtype(DType::F32)?; kf = k.to_dtype(DType::F32)?; vf = v.to_dtype(DType::F32)?; (&qf, &kf, &vf) }; |
| 385 | let kt = k.t()?; |
| 386 | let attn = (self.tensor_matmul(q, &kt)? * scale as f64)?; |
| 387 | let attn = if causal { |
| 388 | let (sl, kl) = (q.dim(2)?, k.dim(2)?); |
| 389 | let mut mask = vec![0u8; sl*kl]; |
| 390 | for i in 0..sl { for j in 0..=kl.saturating_sub(sl)+i { if j<kl { mask[i*kl+j]=1; } } } |
| 391 | let m = Tensor::from_vec(mask, (1,1,sl,kl), q.device())?; |
| 392 | let ni = Tensor::full(f32::NEG_INFINITY, attn.shape(), q.device())?; |
| 393 | m.broadcast_as(attn.shape())?.where_cond(&attn, &ni)? |
| 394 | } else { attn }; |
| 395 | self.tensor_matmul(&candle_nn::ops::softmax_last_dim(&attn)?, v)?.to_dtype(orig) |
| 396 | } |
| 397 | |
| 398 | fn silu_mul(&self, g: &Tensor, u: &Tensor) -> Result<Tensor> { (candle_nn::ops::silu(&g.contiguous()?)? * u.contiguous()?)?.contiguous() } |
| 399 | fn stable_softplus(&self, x: &Tensor) -> Result<Tensor> { let t=Tensor::full(88f32,x.shape(),x.device())?.to_dtype(x.dtype())?; x.maximum(&(x.minimum(&t)?.exp()?+1.0)?.log()?) } |
nothing calls this directly
no test coverage detected