1use std::collections::HashMap;
2
3use candle::{bail, Context, DType, Device, Module, Result, Tensor, D};
4use candle_nn::{
5 conv1d, embedding, layer_norm, Conv1d, Conv1dConfig, Embedding, LayerNorm, VarBuilder,
6};
7use serde::{Deserialize, Deserializer};
8
9pub const DTYPE: DType = DType::F32;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
13#[serde(rename_all = "lowercase")]
14pub enum HiddenAct {
15 Gelu,
16 GeluApproximate,
17 Relu,
18}
19
20pub struct HiddenActLayer {
21 act: HiddenAct,
22 span: tracing::Span,
23}
24
25impl HiddenActLayer {
26 fn new(act: HiddenAct) -> Self {
27 let span = tracing::span!(tracing::Level::TRACE, "hidden-act");
28 Self { act, span }
29 }
30
31 fn forward(&self, xs: &Tensor) -> Result<Tensor> {
32 let _enter = self.span.enter();
33 match self.act {
34 HiddenAct::Gelu => xs.gelu_erf(),
36 HiddenAct::GeluApproximate => xs.gelu(),
37 HiddenAct::Relu => xs.relu(),
38 }
39 }
40}
41
42pub type Id2Label = HashMap<u32, String>;
43pub type Label2Id = HashMap<String, u32>;
44
45#[derive(Debug, Clone, PartialEq, Deserialize)]
46pub struct Config {
47 pub vocab_size: usize,
48 pub hidden_size: usize,
49 pub num_hidden_layers: usize,
50 pub num_attention_heads: usize,
51 pub intermediate_size: usize,
52 pub hidden_act: HiddenAct,
53 pub hidden_dropout_prob: f64,
54 pub attention_probs_dropout_prob: f64,
55 pub max_position_embeddings: usize,
56 pub type_vocab_size: usize,
57 pub initializer_range: f64,
58 pub layer_norm_eps: f64,
59 pub relative_attention: bool,
60 pub max_relative_positions: isize,
61 pub pad_token_id: Option<usize>,
62 pub position_biased_input: bool,
63 #[serde(deserialize_with = "deserialize_pos_att_type")]
64 pub pos_att_type: Vec<String>,
65 pub position_buckets: Option<isize>,
66 pub share_att_key: Option<bool>,
67 pub attention_head_size: Option<usize>,
68 pub embedding_size: Option<usize>,
69 pub norm_rel_ebd: Option<String>,
70 pub conv_kernel_size: Option<usize>,
71 pub conv_groups: Option<usize>,
72 pub conv_act: Option<String>,
73 pub id2label: Option<Id2Label>,
74 pub label2id: Option<Label2Id>,
75 pub pooler_dropout: Option<f64>,
76 pub pooler_hidden_act: Option<HiddenAct>,
77 pub pooler_hidden_size: Option<usize>,
78 pub cls_dropout: Option<f64>,
79}
80
81fn deserialize_pos_att_type<'de, D>(deserializer: D) -> std::result::Result<Vec<String>, D::Error>
82where
83 D: Deserializer<'de>,
84{
85 #[derive(Deserialize, Debug)]
86 #[serde(untagged)]
87 enum StringOrVec {
88 String(String),
89 Vec(Vec<String>),
90 }
91
92 match StringOrVec::deserialize(deserializer)? {
93 StringOrVec::String(s) => Ok(s.split('|').map(String::from).collect()),
94 StringOrVec::Vec(v) => Ok(v),
95 }
96}
97
98pub struct StableDropout {
101 _drop_prob: f64,
102 _count: usize,
103}
104
105impl StableDropout {
106 pub fn new(drop_prob: f64) -> Self {
107 Self {
108 _drop_prob: drop_prob,
109 _count: 0,
110 }
111 }
112
113 pub fn forward(&self, x: &Tensor) -> Result<Tensor> {
114 Ok(x.clone())
115 }
116}
117
118pub struct DebertaV2Embeddings {
120 device: Device,
121 word_embeddings: Embedding,
122 position_embeddings: Option<Embedding>,
123 token_type_embeddings: Option<Embedding>,
124 layer_norm: LayerNorm,
125 dropout: StableDropout,
126 position_ids: Tensor,
127 config: Config,
128 embedding_size: usize,
129 embed_proj: Option<candle_nn::Linear>,
130}
131
132impl DebertaV2Embeddings {
133 pub fn load(vb: VarBuilder, config: &Config) -> Result<Self> {
134 let device = vb.device().clone();
135 let config = config.clone();
136
137 let embedding_size = config.embedding_size.unwrap_or(config.hidden_size);
138
139 let word_embeddings =
140 embedding(config.vocab_size, embedding_size, vb.pp("word_embeddings"))?;
141
142 let position_embeddings = if config.position_biased_input {
143 Some(embedding(
144 config.max_position_embeddings,
145 embedding_size,
146 vb.pp("position_embeddings"),
147 )?)
148 } else {
149 None
150 };
151
152 let token_type_embeddings: Option<Embedding> = if config.type_vocab_size > 0 {
153 Some(candle_nn::embedding(
154 config.type_vocab_size,
155 config.hidden_size,
156 vb.pp("token_type_embeddings"),
157 )?)
158 } else {
159 None
160 };
161
162 let embed_proj: Option<candle_nn::Linear> = if embedding_size != config.hidden_size {
163 Some(candle_nn::linear_no_bias(
164 embedding_size,
165 config.hidden_size,
166 vb.pp("embed_proj"),
167 )?)
168 } else {
169 None
170 };
171
172 let layer_norm = layer_norm(
173 config.hidden_size,
174 config.layer_norm_eps,
175 vb.pp("LayerNorm"),
176 )?;
177
178 let dropout = StableDropout::new(config.hidden_dropout_prob);
179
180 let position_ids =
181 Tensor::arange(0, config.max_position_embeddings as u32, &device)?.unsqueeze(0)?;
182
183 Ok(Self {
184 word_embeddings,
185 position_embeddings,
186 token_type_embeddings,
187 layer_norm,
188 dropout,
189 position_ids,
190 device,
191 config,
192 embedding_size,
193 embed_proj,
194 })
195 }
196
197 pub fn forward(
198 &self,
199 input_ids: Option<&Tensor>,
200 token_type_ids: Option<&Tensor>,
201 position_ids: Option<&Tensor>,
202 mask: Option<&Tensor>,
203 inputs_embeds: Option<&Tensor>,
204 ) -> Result<Tensor> {
205 let (input_shape, input_embeds) = match (input_ids, inputs_embeds) {
206 (Some(ids), None) => {
207 let embs = self.word_embeddings.forward(ids)?;
208 (ids.dims(), embs)
209 }
210 (None, Some(e)) => (e.dims(), e.clone()),
211 (None, None) => {
212 bail!("Must specify either input_ids or inputs_embeds")
213 }
214 (Some(_), Some(_)) => {
215 bail!("Can't specify both input_ids and inputs_embeds")
216 }
217 };
218
219 let seq_length = match input_shape.last() {
220 Some(v) => *v,
221 None => bail!("DebertaV2Embeddings invalid input shape"),
222 };
223
224 let position_ids = match position_ids {
225 Some(v) => v.clone(),
226 None => self.position_ids.narrow(1, 0, seq_length)?,
227 };
228
229 let token_type_ids = match token_type_ids {
230 Some(ids) => ids.clone(),
231 None => Tensor::zeros(input_shape, DType::U32, &self.device)?,
232 };
233
234 let position_embeddings = match &self.position_embeddings {
235 Some(emb) => emb.forward(&position_ids)?,
236 None => Tensor::zeros_like(&input_embeds)?,
237 };
238
239 let mut embeddings = input_embeds;
240
241 if self.config.position_biased_input {
242 embeddings = embeddings.add(&position_embeddings)?;
243 }
244
245 if self.config.type_vocab_size > 0 {
246 embeddings = self.token_type_embeddings.as_ref().map_or_else(
247 || bail!("token_type_embeddings must be set when type_vocab_size > 0"),
248 |token_type_embeddings| {
249 embeddings.add(&token_type_embeddings.forward(&token_type_ids)?)
250 },
251 )?;
252 }
253
254 if self.embedding_size != self.config.hidden_size {
255 embeddings = if let Some(embed_proj) = &self.embed_proj {
256 embed_proj.forward(&embeddings)?
257 } else {
258 bail!("embed_proj must exist if embedding_size != config.hidden_size");
259 }
260 }
261
262 embeddings = self.layer_norm.forward(&embeddings)?;
263
264 if let Some(mask) = mask {
265 let mut mask = mask.clone();
266 if mask.dims() != embeddings.dims() {
267 if mask.dims().len() == 4 {
268 mask = mask.squeeze(1)?.squeeze(1)?;
269 }
270 mask = mask.unsqueeze(2)?;
271 }
272
273 mask = mask.to_dtype(embeddings.dtype())?;
274 embeddings = embeddings.broadcast_mul(&mask)?;
275 }
276
277 self.dropout.forward(&embeddings)
278 }
279}
280
281struct XSoftmax {}
283
284impl XSoftmax {
285 pub fn apply(input: &Tensor, mask: &Tensor, dim: D, device: &Device) -> Result<Tensor> {
286 let mut rmask = mask.broadcast_as(input.shape())?.to_dtype(DType::F32)?;
288
289 rmask = rmask
290 .broadcast_lt(&Tensor::new(&[1.0_f32], device)?)?
291 .to_dtype(DType::U8)?;
292
293 let min_value_tensor = Tensor::new(&[f32::MIN], device)?.broadcast_as(input.shape())?;
294 let mut output = rmask.where_cond(&min_value_tensor, input)?;
295
296 output = candle_nn::ops::softmax(&output, dim)?;
297
298 let t_zeroes = Tensor::new(&[0f32], device)?.broadcast_as(input.shape())?;
299 output = rmask.where_cond(&t_zeroes, &output)?;
300
301 Ok(output)
302 }
303}
304
305pub struct DebertaV2DisentangledSelfAttention {
307 config: Config,
308 num_attention_heads: usize,
309 query_proj: candle_nn::Linear,
310 key_proj: candle_nn::Linear,
311 value_proj: candle_nn::Linear,
312 dropout: StableDropout,
313 device: Device,
314 relative_attention: bool,
315 pos_dropout: Option<StableDropout>,
316 position_buckets: isize,
317 max_relative_positions: isize,
318 pos_ebd_size: isize,
319 share_att_key: bool,
320 pos_key_proj: Option<candle_nn::Linear>,
321 pos_query_proj: Option<candle_nn::Linear>,
322}
323
324impl DebertaV2DisentangledSelfAttention {
325 pub fn load(vb: VarBuilder, config: &Config) -> Result<Self> {
326 let config = config.clone();
327 let vb = vb.clone();
328
329 if !config
330 .hidden_size
331 .is_multiple_of(config.num_attention_heads)
332 {
333 return Err(candle::Error::Msg(format!(
334 "The hidden size {} is not a multiple of the number of attention heads {}",
335 config.hidden_size, config.num_attention_heads
336 )));
337 }
338
339 let num_attention_heads = config.num_attention_heads;
340
341 let attention_head_size = config
342 .attention_head_size
343 .unwrap_or(config.hidden_size / config.num_attention_heads);
344
345 let all_head_size = num_attention_heads * attention_head_size;
346
347 let query_proj = candle_nn::linear(config.hidden_size, all_head_size, vb.pp("query_proj"))?;
348 let key_proj = candle_nn::linear(config.hidden_size, all_head_size, vb.pp("key_proj"))?;
349 let value_proj = candle_nn::linear(config.hidden_size, all_head_size, vb.pp("value_proj"))?;
350
351 let share_att_key = config.share_att_key.unwrap_or(false);
352 let relative_attention = config.relative_attention;
353 let mut max_relative_positions = config.max_relative_positions;
354
355 let mut pos_ebd_size: isize = 0;
356 let position_buckets = config.position_buckets.unwrap_or(-1);
357 let mut pos_dropout: Option<StableDropout> = None;
358 let mut pos_key_proj: Option<candle_nn::Linear> = None;
359 let mut pos_query_proj: Option<candle_nn::Linear> = None;
360
361 if relative_attention {
362 if max_relative_positions < 1 {
363 max_relative_positions = config.max_position_embeddings as isize;
364 }
365 pos_ebd_size = max_relative_positions;
366 if position_buckets > 0 {
367 pos_ebd_size = position_buckets
368 }
369
370 pos_dropout = Some(StableDropout::new(config.hidden_dropout_prob));
371
372 if !share_att_key {
373 if config.pos_att_type.iter().any(|s| s == "c2p") {
374 pos_key_proj = Some(candle_nn::linear(
375 config.hidden_size,
376 all_head_size,
377 vb.pp("pos_key_proj"),
378 )?);
379 }
380 if config.pos_att_type.iter().any(|s| s == "p2c") {
381 pos_query_proj = Some(candle_nn::linear(
382 config.hidden_size,
383 all_head_size,
384 vb.pp("pos_query_proj"),
385 )?);
386 }
387 }
388 }
389
390 let dropout = StableDropout::new(config.attention_probs_dropout_prob);
391 let device = vb.device().clone();
392
393 Ok(Self {
394 config,
395 num_attention_heads,
396 query_proj,
397 key_proj,
398 value_proj,
399 dropout,
400 device,
401 relative_attention,
402 pos_dropout,
403 position_buckets,
404 max_relative_positions,
405 pos_ebd_size,
406 share_att_key,
407 pos_key_proj,
408 pos_query_proj,
409 })
410 }
411
412 pub fn forward(
413 &self,
414 hidden_states: &Tensor,
415 attention_mask: &Tensor,
416 query_states: Option<&Tensor>,
417 relative_pos: Option<&Tensor>,
418 rel_embeddings: Option<&Tensor>,
419 ) -> Result<Tensor> {
420 let query_states = match query_states {
421 Some(qs) => qs,
422 None => hidden_states,
423 };
424
425 let query_layer = self.transpose_for_scores(&self.query_proj.forward(query_states)?)?;
426 let key_layer = self.transpose_for_scores(&self.key_proj.forward(query_states)?)?;
427 let value_layer = self.transpose_for_scores(&self.value_proj.forward(query_states)?)?;
428
429 let mut rel_att: Option<Tensor> = None;
430
431 let mut scale_factor: usize = 1;
432
433 if self.config.pos_att_type.iter().any(|s| s == "c2p") {
434 scale_factor += 1;
435 }
436
437 if self.config.pos_att_type.iter().any(|s| s == "p2c") {
438 scale_factor += 1;
439 }
440
441 let scale = {
442 let q_size = query_layer.dim(D::Minus1)?;
443 Tensor::new(&[(q_size * scale_factor) as f32], &self.device)?.sqrt()?
444 };
445
446 let mut attention_scores: Tensor = {
447 let key_layer_transposed = key_layer.t()?;
448 let div = key_layer_transposed
449 .broadcast_div(scale.to_dtype(query_layer.dtype())?.as_ref())?;
450 query_layer.matmul(&div)?
451 };
452
453 if self.relative_attention {
454 if let Some(rel_embeddings) = rel_embeddings {
455 let rel_embeddings = self
456 .pos_dropout
457 .as_ref()
458 .context("relative_attention requires pos_dropout")?
459 .forward(rel_embeddings)?;
460 rel_att = Some(self.disentangled_attention_bias(
461 query_layer,
462 key_layer,
463 relative_pos,
464 rel_embeddings,
465 scale_factor,
466 )?);
467 }
468 }
469
470 if let Some(rel_att) = rel_att {
471 attention_scores = attention_scores.broadcast_add(&rel_att)?;
472 }
473
474 attention_scores = attention_scores.reshape((
475 (),
476 self.num_attention_heads,
477 attention_scores.dim(D::Minus2)?,
478 attention_scores.dim(D::Minus1)?,
479 ))?;
480
481 let mut attention_probs =
482 XSoftmax::apply(&attention_scores, attention_mask, D::Minus1, &self.device)?;
483
484 attention_probs = self.dropout.forward(&attention_probs)?;
485
486 let mut context_layer = attention_probs
487 .reshape((
488 (),
489 attention_probs.dim(D::Minus2)?,
490 attention_probs.dim(D::Minus1)?,
491 ))?
492 .matmul(&value_layer)?;
493
494 context_layer = context_layer
495 .reshape((
496 (),
497 self.num_attention_heads,
498 context_layer.dim(D::Minus2)?,
499 context_layer.dim(D::Minus1)?,
500 ))?
501 .permute((0, 2, 1, 3))?
502 .contiguous()?;
503
504 let dims = context_layer.dims();
505
506 context_layer = match dims.len() {
507 2 => context_layer.reshape(())?,
508 3 => context_layer.reshape((dims[0], ()))?,
509 4 => context_layer.reshape((dims[0], dims[1], ()))?,
510 5 => context_layer.reshape((dims[0], dims[1], dims[2], ()))?,
511 _ => {
512 bail!(
513 "Invalid shape for DisentabgledSelfAttention context layer: {:?}",
514 dims
515 )
516 }
517 };
518
519 Ok(context_layer)
520 }
521
522 fn transpose_for_scores(&self, xs: &Tensor) -> Result<Tensor> {
523 let dims = xs.dims().to_vec();
524 match dims.len() {
525 3 => {
526 let reshaped = xs.reshape((dims[0], dims[1], self.num_attention_heads, ()))?;
527
528 reshaped.transpose(1, 2)?.contiguous()?.reshape((
529 (),
530 reshaped.dim(1)?,
531 reshaped.dim(D::Minus1)?,
532 ))
533 }
534 shape => {
535 bail!("Invalid shape for transpose_for_scores. Expected 3 dimensions, got {shape}")
536 }
537 }
538 }
539
540 fn disentangled_attention_bias(
541 &self,
542 query_layer: Tensor,
543 key_layer: Tensor,
544 relative_pos: Option<&Tensor>,
545 rel_embeddings: Tensor,
546 scale_factor: usize,
547 ) -> Result<Tensor> {
548 let mut relative_pos = relative_pos.map_or(
549 build_relative_position(
550 query_layer.dim(D::Minus2)?,
551 key_layer.dim(D::Minus2)?,
552 &self.device,
553 Some(self.position_buckets),
554 Some(self.max_relative_positions),
555 )?,
556 |pos| pos.clone(),
557 );
558
559 relative_pos = match relative_pos.dims().len() {
560 2 => relative_pos.unsqueeze(0)?.unsqueeze(0)?,
561 3 => relative_pos.unsqueeze(1)?,
562 other => {
563 bail!("Relative position ids must be of dim 2 or 3 or 4. Got dim of size {other}")
564 }
565 };
566
567 let att_span = self.pos_ebd_size;
568
569 let rel_embeddings = rel_embeddings
570 .narrow(0, 0, (att_span * 2) as usize)?
571 .unsqueeze(0)?;
572
573 let mut pos_query_layer: Option<Tensor> = None;
574 let mut pos_key_layer: Option<Tensor> = None;
575
576 let repeat_with = query_layer.dim(0)? / self.num_attention_heads;
577 if self.share_att_key {
578 pos_query_layer = Some(
579 self.transpose_for_scores(&self.query_proj.forward(&rel_embeddings)?)?
580 .repeat(repeat_with)?,
581 );
582
583 pos_key_layer = Some(
584 self.transpose_for_scores(&self.key_proj.forward(&rel_embeddings)?)?
585 .repeat(repeat_with)?,
586 )
587 } else {
588 if self.config.pos_att_type.iter().any(|s| s == "c2p") {
589 pos_key_layer = Some(
590 self.transpose_for_scores(
591 &self
592 .pos_key_proj
593 .as_ref()
594 .context(
595 "Need pos_key_proj when share_att_key is false or not specified",
596 )?
597 .forward(&rel_embeddings)?,
598 )?
599 .repeat(repeat_with)?,
600 )
601 }
602 if self.config.pos_att_type.iter().any(|s| s == "p2c") {
603 pos_query_layer = Some(self.transpose_for_scores(&self
604 .pos_query_proj
605 .as_ref()
606 .context("Need a pos_query_proj when share_att_key is false or not specified")?
607 .forward(&rel_embeddings)?)?.repeat(repeat_with)?)
608 }
609 }
610
611 let mut score = Tensor::new(&[0 as f32], &self.device)?;
612
613 if self.config.pos_att_type.iter().any(|s| s == "c2p") {
614 let pos_key_layer = pos_key_layer.context("c2p without pos_key_layer")?;
615
616 let scale = Tensor::new(
617 &[(pos_key_layer.dim(D::Minus1)? * scale_factor) as f32],
618 &self.device,
619 )?
620 .sqrt()?;
621
622 let mut c2p_att = query_layer.matmul(&pos_key_layer.t()?)?;
623
624 let c2p_pos = relative_pos
625 .broadcast_add(&Tensor::new(&[att_span as i64], &self.device)?)?
626 .clamp(0 as f32, (att_span * 2 - 1) as f32)?;
627
628 c2p_att = c2p_att.gather(
629 &c2p_pos
630 .squeeze(0)?
631 .expand(&[
632 query_layer.dim(0)?,
633 query_layer.dim(1)?,
634 relative_pos.dim(D::Minus1)?,
635 ])?
636 .contiguous()?,
637 D::Minus1,
638 )?;
639
640 score = score.broadcast_add(
641 &c2p_att.broadcast_div(scale.to_dtype(c2p_att.dtype())?.as_ref())?,
642 )?;
643 }
644
645 if self.config.pos_att_type.iter().any(|s| s == "p2c") {
646 let pos_query_layer = pos_query_layer.context("p2c without pos_key_layer")?;
647
648 let scale = Tensor::new(
649 &[(pos_query_layer.dim(D::Minus1)? * scale_factor) as f32],
650 &self.device,
651 )?
652 .sqrt()?;
653
654 let r_pos = {
655 if key_layer.dim(D::Minus2)? != query_layer.dim(D::Minus2)? {
656 build_relative_position(
657 key_layer.dim(D::Minus2)?,
658 key_layer.dim(D::Minus2)?,
659 &self.device,
660 Some(self.position_buckets),
661 Some(self.max_relative_positions),
662 )?
663 .unsqueeze(0)?
664 } else {
665 relative_pos
666 }
667 };
668
669 let p2c_pos = r_pos
670 .to_dtype(DType::F32)?
671 .neg()?
672 .broadcast_add(&Tensor::new(&[att_span as f32], &self.device)?)?
673 .clamp(0f32, (att_span * 2 - 1) as f32)?;
674
675 let p2c_att = key_layer
676 .matmul(&pos_query_layer.t()?)?
677 .gather(
678 &p2c_pos
679 .squeeze(0)?
680 .expand(&[
681 query_layer.dim(0)?,
682 key_layer.dim(D::Minus2)?,
683 key_layer.dim(D::Minus2)?,
684 ])?
685 .contiguous()?
686 .to_dtype(DType::U32)?,
687 D::Minus1,
688 )?
689 .t()?;
690
691 score =
692 score.broadcast_add(&p2c_att.broadcast_div(&scale.to_dtype(p2c_att.dtype())?)?)?;
693 }
694
695 Ok(score)
696 }
697}
698
699pub struct DebertaV2Attention {
701 dsa: DebertaV2DisentangledSelfAttention,
702 output: DebertaV2SelfOutput,
703}
704
705impl DebertaV2Attention {
706 pub fn load(vb: VarBuilder, config: &Config) -> Result<Self> {
707 let dsa = DebertaV2DisentangledSelfAttention::load(vb.pp("attention.self"), config)?;
708 let output = DebertaV2SelfOutput::load(vb.pp("attention.output"), config)?;
709 Ok(Self { dsa, output })
710 }
711
712 fn forward(
713 &self,
714 hidden_states: &Tensor,
715 attention_mask: &Tensor,
716 query_states: Option<&Tensor>,
717 relative_pos: Option<&Tensor>,
718 rel_embeddings: Option<&Tensor>,
719 ) -> Result<Tensor> {
720 let self_output = self.dsa.forward(
721 hidden_states,
722 attention_mask,
723 query_states,
724 relative_pos,
725 rel_embeddings,
726 )?;
727
728 self.output
729 .forward(&self_output, query_states.unwrap_or(hidden_states))
730 }
731}
732
733pub struct DebertaV2SelfOutput {
735 dense: candle_nn::Linear,
736 layer_norm: LayerNorm,
737 dropout: StableDropout,
738}
739
740impl DebertaV2SelfOutput {
741 pub fn load(vb: VarBuilder, config: &Config) -> Result<Self> {
742 let dense = candle_nn::linear(config.hidden_size, config.hidden_size, vb.pp("dense"))?;
743 let layer_norm = candle_nn::layer_norm(
744 config.hidden_size,
745 config.layer_norm_eps,
746 vb.pp("LayerNorm"),
747 )?;
748 let dropout = StableDropout::new(config.hidden_dropout_prob);
749 Ok(Self {
750 dense,
751 layer_norm,
752 dropout,
753 })
754 }
755
756 pub fn forward(&self, hidden_states: &Tensor, input_tensor: &Tensor) -> Result<Tensor> {
757 let mut hidden_states = self.dense.forward(hidden_states)?;
758 hidden_states = self.dropout.forward(&hidden_states)?;
759 self.layer_norm
760 .forward(&hidden_states.broadcast_add(input_tensor)?)
761 }
762}
763
764pub struct DebertaV2Intermediate {
766 dense: candle_nn::Linear,
767 intermediate_act: HiddenActLayer,
768}
769
770impl DebertaV2Intermediate {
771 pub fn load(vb: VarBuilder, config: &Config) -> Result<Self> {
772 let dense = candle_nn::linear(
773 config.hidden_size,
774 config.intermediate_size,
775 vb.pp("intermediate.dense"),
776 )?;
777 let intermediate_act = HiddenActLayer::new(config.hidden_act);
778 Ok(Self {
779 dense,
780 intermediate_act,
781 })
782 }
783
784 pub fn forward(&self, hidden_states: &Tensor) -> Result<Tensor> {
785 self.intermediate_act
786 .forward(&self.dense.forward(hidden_states)?)
787 }
788}
789
790pub struct DebertaV2Output {
792 dense: candle_nn::Linear,
793 layer_norm: LayerNorm,
794 dropout: StableDropout,
795}
796
797impl DebertaV2Output {
798 pub fn load(vb: VarBuilder, config: &Config) -> Result<Self> {
799 let dense = candle_nn::linear(
800 config.intermediate_size,
801 config.hidden_size,
802 vb.pp("output.dense"),
803 )?;
804 let layer_norm = candle_nn::layer_norm(
805 config.hidden_size,
806 config.layer_norm_eps,
807 vb.pp("output.LayerNorm"),
808 )?;
809 let dropout = StableDropout::new(config.hidden_dropout_prob);
810 Ok(Self {
811 dense,
812 layer_norm,
813 dropout,
814 })
815 }
816
817 pub fn forward(&self, hidden_states: &Tensor, input_tensor: &Tensor) -> Result<Tensor> {
818 let mut hidden_states = self.dense.forward(hidden_states)?;
819 hidden_states = self.dropout.forward(&hidden_states)?;
820 hidden_states = {
821 let to_norm = hidden_states.broadcast_add(input_tensor)?;
822 self.layer_norm.forward(&to_norm)?
823 };
824 Ok(hidden_states)
825 }
826}
827
828pub struct DebertaV2Layer {
830 attention: DebertaV2Attention,
831 intermediate: DebertaV2Intermediate,
832 output: DebertaV2Output,
833}
834
835impl DebertaV2Layer {
836 pub fn load(vb: VarBuilder, config: &Config) -> Result<Self> {
837 let attention = DebertaV2Attention::load(vb.clone(), config)?;
838 let intermediate = DebertaV2Intermediate::load(vb.clone(), config)?;
839 let output = DebertaV2Output::load(vb.clone(), config)?;
840 Ok(Self {
841 attention,
842 intermediate,
843 output,
844 })
845 }
846
847 fn forward(
848 &self,
849 hidden_states: &Tensor,
850 attention_mask: &Tensor,
851 query_states: Option<&Tensor>,
852 relative_pos: Option<&Tensor>,
853 rel_embeddings: Option<&Tensor>,
854 ) -> Result<Tensor> {
855 let attention_output = self.attention.forward(
856 hidden_states,
857 attention_mask,
858 query_states,
859 relative_pos,
860 rel_embeddings,
861 )?;
862
863 let intermediate_output = self.intermediate.forward(&attention_output)?;
864
865 let layer_output = self
866 .output
867 .forward(&intermediate_output, &attention_output)?;
868
869 Ok(layer_output)
870 }
871}
872
873pub struct ConvLayer {
876 _conv_act: String,
877 _conv: Conv1d,
878 _layer_norm: LayerNorm,
879 _dropout: StableDropout,
880 _config: Config,
881}
882
883impl ConvLayer {
884 pub fn load(vb: VarBuilder, config: &Config) -> Result<Self> {
885 let config = config.clone();
886 let kernel_size = config.conv_kernel_size.unwrap_or(3);
887 let groups = config.conv_groups.unwrap_or(1);
888 let conv_act: String = config.conv_act.clone().unwrap_or("tanh".to_string());
889
890 let conv_conf = Conv1dConfig {
891 padding: (kernel_size - 1) / 2,
892 groups,
893 ..Default::default()
894 };
895
896 let conv = conv1d(
897 config.hidden_size,
898 config.hidden_size,
899 kernel_size,
900 conv_conf,
901 vb.pp("conv"),
902 )?;
903
904 let layer_norm = layer_norm(
905 config.hidden_size,
906 config.layer_norm_eps,
907 vb.pp("LayerNorm"),
908 )?;
909
910 let dropout = StableDropout::new(config.hidden_dropout_prob);
911
912 Ok(Self {
913 _conv_act: conv_act,
914 _conv: conv,
915 _layer_norm: layer_norm,
916 _dropout: dropout,
917 _config: config,
918 })
919 }
920
921 pub fn forward(
922 &self,
923 _hidden_states: &Tensor,
924 _residual_states: &Tensor,
925 _input_mask: &Tensor,
926 ) -> Result<Tensor> {
927 todo!("Need a model that contains a conv layer to test against.")
928 }
929}
930
931pub struct DebertaV2Encoder {
933 layer: Vec<DebertaV2Layer>,
934 relative_attention: bool,
935 max_relative_positions: isize,
936 position_buckets: isize,
937 rel_embeddings: Option<Embedding>,
938 norm_rel_ebd: String,
939 layer_norm: Option<LayerNorm>,
940 conv: Option<ConvLayer>,
941 device: Device,
942}
943
944impl DebertaV2Encoder {
945 pub fn load(vb: VarBuilder, config: &Config) -> Result<Self> {
946 let layer = (0..config.num_hidden_layers)
947 .map(|index| DebertaV2Layer::load(vb.pp(format!("layer.{index}")), config))
948 .collect::<Result<Vec<_>>>()?;
949
950 let relative_attention = config.relative_attention;
951 let mut max_relative_positions = config.max_relative_positions;
952
953 let position_buckets = config.position_buckets.unwrap_or(-1);
954
955 let mut rel_embeddings: Option<Embedding> = None;
956
957 if relative_attention {
958 if max_relative_positions < 1 {
959 max_relative_positions = config.max_position_embeddings as isize;
960 }
961
962 let mut pos_ebd_size = max_relative_positions * 2;
963
964 if position_buckets > 0 {
965 pos_ebd_size = position_buckets * 2;
966 }
967
968 rel_embeddings = Some(embedding(
969 pos_ebd_size as usize,
970 config.hidden_size,
971 vb.pp("rel_embeddings"),
972 )?);
973 }
974
975 let norm_rel_ebd = match config.norm_rel_ebd.as_ref() {
978 Some(nre) => nre.trim().to_string(),
979 None => "none".to_string(),
980 };
981
982 let layer_norm: Option<LayerNorm> = if norm_rel_ebd == "layer_norm" {
983 Some(layer_norm(
984 config.hidden_size,
985 config.layer_norm_eps,
986 vb.pp("LayerNorm"),
987 )?)
988 } else {
989 None
990 };
991
992 let conv: Option<ConvLayer> = if config.conv_kernel_size.unwrap_or(0) > 0 {
993 Some(ConvLayer::load(vb.pp("conv"), config)?)
994 } else {
995 None
996 };
997
998 Ok(Self {
999 layer,
1000 relative_attention,
1001 max_relative_positions,
1002 position_buckets,
1003 rel_embeddings,
1004 norm_rel_ebd,
1005 layer_norm,
1006 conv,
1007 device: vb.device().clone(),
1008 })
1009 }
1010
1011 pub fn forward(
1012 &self,
1013 hidden_states: &Tensor,
1014 attention_mask: &Tensor,
1015 query_states: Option<&Tensor>,
1016 relative_pos: Option<&Tensor>,
1017 ) -> Result<Tensor> {
1018 let input_mask = if attention_mask.dims().len() <= 2 {
1019 attention_mask.clone()
1020 } else {
1021 attention_mask
1022 .sum_keepdim(attention_mask.rank() - 2)?
1023 .gt(0.)?
1024 };
1025
1026 let attention_mask = self.get_attention_mask(attention_mask.clone())?;
1027
1028 let relative_pos = self.get_rel_pos(hidden_states, query_states, relative_pos)?;
1029
1030 let mut next_kv: Tensor = hidden_states.clone();
1031 let rel_embeddings = self.get_rel_embedding()?;
1032 let mut output_states = next_kv.to_owned();
1033 let mut query_states: Option<Tensor> = query_states.cloned();
1034
1035 for (i, layer_module) in self.layer.iter().enumerate() {
1036 output_states = layer_module.forward(
1041 next_kv.as_ref(),
1042 &attention_mask,
1043 query_states.as_ref(),
1044 relative_pos.as_ref(),
1045 rel_embeddings.as_ref(),
1046 )?;
1047
1048 if i == 0 {
1049 if let Some(conv) = &self.conv {
1050 output_states = conv.forward(hidden_states, &output_states, &input_mask)?;
1051 }
1052 }
1053
1054 if query_states.is_some() {
1055 query_states = Some(output_states.clone());
1056 } else {
1057 next_kv = output_states.clone();
1058 }
1059 }
1060
1061 Ok(output_states)
1062 }
1063
1064 fn get_attention_mask(&self, mut attention_mask: Tensor) -> Result<Tensor> {
1065 match attention_mask.dims().len() {
1066 0..=2 => {
1067 let extended_attention_mask = attention_mask.unsqueeze(1)?.unsqueeze(2)?;
1068 attention_mask = extended_attention_mask.broadcast_mul(
1069 &extended_attention_mask
1070 .squeeze(D::Minus2)?
1071 .unsqueeze(D::Minus1)?,
1072 )?;
1073 }
1074 3 => attention_mask = attention_mask.unsqueeze(1)?,
1075 len => bail!("Unsupported attentiom mask size length: {len}"),
1076 }
1077
1078 Ok(attention_mask)
1079 }
1080
1081 fn get_rel_pos(
1082 &self,
1083 hidden_states: &Tensor,
1084 query_states: Option<&Tensor>,
1085 relative_pos: Option<&Tensor>,
1086 ) -> Result<Option<Tensor>> {
1087 if self.relative_attention && relative_pos.is_none() {
1088 let q = if let Some(query_states) = query_states {
1089 query_states.dim(D::Minus2)?
1090 } else {
1091 hidden_states.dim(D::Minus2)?
1092 };
1093
1094 return Ok(Some(build_relative_position(
1095 q,
1096 hidden_states.dim(D::Minus2)?,
1097 &self.device,
1098 Some(self.position_buckets),
1099 Some(self.max_relative_positions),
1100 )?));
1101 }
1102
1103 if relative_pos.is_some() {
1104 Ok(relative_pos.cloned())
1105 } else {
1106 Ok(None)
1107 }
1108 }
1109 fn get_rel_embedding(&self) -> Result<Option<Tensor>> {
1110 if !self.relative_attention {
1111 return Ok(None);
1112 }
1113
1114 let rel_embeddings = self
1115 .rel_embeddings
1116 .as_ref()
1117 .context("self.rel_embeddings not present when using relative_attention")?
1118 .embeddings()
1119 .clone();
1120
1121 if !self.norm_rel_ebd.contains("layer_norm") {
1122 return Ok(Some(rel_embeddings));
1123 }
1124
1125 let layer_normed_embeddings = self
1126 .layer_norm
1127 .as_ref()
1128 .context("DebertaV2Encoder layer_norm is None when norm_rel_ebd contains layer_norm")?
1129 .forward(&rel_embeddings)?;
1130
1131 Ok(Some(layer_normed_embeddings))
1132 }
1133}
1134
1135pub struct DebertaV2Model {
1137 embeddings: DebertaV2Embeddings,
1138 encoder: DebertaV2Encoder,
1139 z_steps: usize,
1140 pub device: Device,
1141}
1142
1143impl DebertaV2Model {
1144 pub fn load(vb: VarBuilder, config: &Config) -> Result<Self> {
1145 let vb = vb.clone();
1146 let embeddings = DebertaV2Embeddings::load(vb.pp("embeddings"), config)?;
1147 let encoder = DebertaV2Encoder::load(vb.pp("encoder"), config)?;
1148 let z_steps: usize = 0;
1149
1150 Ok(Self {
1151 embeddings,
1152 encoder,
1153 z_steps,
1154 device: vb.device().clone(),
1155 })
1156 }
1157
1158 pub fn forward(
1159 &self,
1160 input_ids: &Tensor,
1161 token_type_ids: Option<Tensor>,
1162 attention_mask: Option<Tensor>,
1163 ) -> Result<Tensor> {
1164 let input_ids_shape = input_ids.shape();
1165
1166 let attention_mask = match attention_mask {
1167 Some(mask) => mask,
1168 None => Tensor::ones(input_ids_shape, DType::I64, &self.device)?,
1169 };
1170
1171 let token_type_ids = match token_type_ids {
1172 Some(ids) => ids,
1173 None => Tensor::zeros(input_ids_shape, DType::U32, &self.device)?,
1174 };
1175
1176 let embedding_output = self.embeddings.forward(
1177 Some(input_ids),
1178 Some(&token_type_ids),
1179 None,
1180 Some(&attention_mask),
1181 None,
1182 )?;
1183
1184 let encoder_output =
1185 self.encoder
1186 .forward(&embedding_output, &attention_mask, None, None)?;
1187
1188 if self.z_steps > 1 {
1189 todo!("Complete DebertaV2Model forward() when z_steps > 1 -- Needs a model to test this situation.")
1190 }
1191
1192 Ok(encoder_output)
1193 }
1194}
1195
1196#[derive(Debug)]
1197pub struct NERItem {
1198 pub entity: String,
1199 pub word: String,
1200 pub score: f32,
1201 pub start: usize,
1202 pub end: usize,
1203 pub index: usize,
1204}
1205
1206#[derive(Debug)]
1207pub struct TextClassificationItem {
1208 pub label: String,
1209 pub score: f32,
1210}
1211
1212pub struct DebertaV2NERModel {
1213 pub device: Device,
1214 deberta: DebertaV2Model,
1215 dropout: candle_nn::Dropout,
1216 classifier: candle_nn::Linear,
1217}
1218
1219fn id2label_len(config: &Config, id2label: Option<HashMap<u32, String>>) -> Result<usize> {
1220 let id2label_len = match (&config.id2label, id2label) {
1221 (None, None) => bail!("Id2Label is either not present in the model configuration or not passed into DebertaV2NERModel::load as a parameter"),
1222 (None, Some(id2label_p)) => id2label_p.len(),
1223 (Some(id2label_c), None) => id2label_c.len(),
1224 (Some(id2label_c), Some(id2label_p)) => {
1225 if *id2label_c == id2label_p {
1226 id2label_c.len()
1227 } else {
1228 bail!("Id2Label is both present in the model configuration and provided as a parameter, and they are different.")
1229 }
1230 }
1231 };
1232 Ok(id2label_len)
1233}
1234
1235impl DebertaV2NERModel {
1236 pub fn load(vb: VarBuilder, config: &Config, id2label: Option<Id2Label>) -> Result<Self> {
1237 let id2label_len = id2label_len(config, id2label)?;
1238
1239 let deberta = DebertaV2Model::load(vb.clone(), config)?;
1240 let dropout = candle_nn::Dropout::new(config.hidden_dropout_prob as f32);
1241 let classifier: candle_nn::Linear = candle_nn::linear_no_bias(
1242 config.hidden_size,
1243 id2label_len,
1244 vb.root().pp("classifier"),
1245 )?;
1246
1247 Ok(Self {
1248 device: vb.device().clone(),
1249 deberta,
1250 dropout,
1251 classifier,
1252 })
1253 }
1254
1255 pub fn forward(
1256 &self,
1257 input_ids: &Tensor,
1258 token_type_ids: Option<Tensor>,
1259 attention_mask: Option<Tensor>,
1260 ) -> Result<Tensor> {
1261 let output = self
1262 .deberta
1263 .forward(input_ids, token_type_ids, attention_mask)?;
1264 let output = self.dropout.forward(&output, false)?;
1265 self.classifier.forward(&output)
1266 }
1267}
1268
1269pub struct DebertaV2SeqClassificationModel {
1270 pub device: Device,
1271 deberta: DebertaV2Model,
1272 dropout: StableDropout,
1273 pooler: DebertaV2ContextPooler,
1274 classifier: candle_nn::Linear,
1275}
1276
1277impl DebertaV2SeqClassificationModel {
1278 pub fn load(vb: VarBuilder, config: &Config, id2label: Option<Id2Label>) -> Result<Self> {
1279 let id2label_len = id2label_len(config, id2label)?;
1280 let deberta = DebertaV2Model::load(vb.clone(), config)?;
1281 let pooler = DebertaV2ContextPooler::load(vb.clone(), config)?;
1282 let output_dim = pooler.output_dim()?;
1283 let classifier = candle_nn::linear(output_dim, id2label_len, vb.root().pp("classifier"))?;
1284 let dropout = match config.cls_dropout {
1285 Some(cls_dropout) => StableDropout::new(cls_dropout),
1286 None => StableDropout::new(config.hidden_dropout_prob),
1287 };
1288
1289 Ok(Self {
1290 device: vb.device().clone(),
1291 deberta,
1292 dropout,
1293 pooler,
1294 classifier,
1295 })
1296 }
1297
1298 pub fn forward(
1299 &self,
1300 input_ids: &Tensor,
1301 token_type_ids: Option<Tensor>,
1302 attention_mask: Option<Tensor>,
1303 ) -> Result<Tensor> {
1304 let encoder_layer = self
1305 .deberta
1306 .forward(input_ids, token_type_ids, attention_mask)?;
1307 let pooled_output = self.pooler.forward(&encoder_layer)?;
1308 let pooled_output = self.dropout.forward(&pooled_output)?;
1309 self.classifier.forward(&pooled_output)
1310 }
1311}
1312
1313pub struct DebertaV2ContextPooler {
1314 dense: candle_nn::Linear,
1315 dropout: StableDropout,
1316 config: Config,
1317}
1318
1319impl DebertaV2ContextPooler {
1321 pub fn load(vb: VarBuilder, config: &Config) -> Result<Self> {
1322 let pooler_hidden_size = config
1323 .pooler_hidden_size
1324 .context("config.pooler_hidden_size is required for DebertaV2ContextPooler")?;
1325
1326 let pooler_dropout = config
1327 .pooler_dropout
1328 .context("config.pooler_dropout is required for DebertaV2ContextPooler")?;
1329
1330 let dense = candle_nn::linear(
1331 pooler_hidden_size,
1332 pooler_hidden_size,
1333 vb.root().pp("pooler.dense"),
1334 )?;
1335
1336 let dropout = StableDropout::new(pooler_dropout);
1337
1338 Ok(Self {
1339 dense,
1340 dropout,
1341 config: config.clone(),
1342 })
1343 }
1344
1345 pub fn forward(&self, hidden_states: &Tensor) -> Result<Tensor> {
1346 let context_token = hidden_states.narrow(1, 0, 1)?.squeeze(1)?;
1347 let context_token = self.dropout.forward(&context_token)?;
1348
1349 let pooled_output = self.dense.forward(&context_token.contiguous()?)?;
1350 let pooler_hidden_act = self
1351 .config
1352 .pooler_hidden_act
1353 .context("Could not obtain pooler hidden act from config")?;
1354
1355 HiddenActLayer::new(pooler_hidden_act).forward(&pooled_output)
1356 }
1357
1358 pub fn output_dim(&self) -> Result<usize> {
1359 self.config.pooler_hidden_size.context("DebertaV2ContextPooler cannot return output_dim (pooler_hidden_size) since it is not specified in the model config")
1360 }
1361}
1362
1363pub(crate) fn build_relative_position(
1365 query_size: usize,
1366 key_size: usize,
1367 device: &Device,
1368 bucket_size: Option<isize>,
1369 max_position: Option<isize>,
1370) -> Result<Tensor> {
1371 let q_ids = Tensor::arange(0, query_size as i64, device)?.unsqueeze(0)?;
1372 let k_ids: Tensor = Tensor::arange(0, key_size as i64, device)?.unsqueeze(D::Minus1)?;
1373 let mut rel_pos_ids = k_ids.broadcast_sub(&q_ids)?;
1374 let bucket_size = bucket_size.unwrap_or(-1);
1375 let max_position = max_position.unwrap_or(-1);
1376
1377 if bucket_size > 0 && max_position > 0 {
1378 rel_pos_ids = make_log_bucket_position(rel_pos_ids, bucket_size, max_position, device)?;
1379 }
1380
1381 rel_pos_ids = rel_pos_ids.to_dtype(DType::I64)?;
1382 rel_pos_ids = rel_pos_ids.narrow(0, 0, query_size)?;
1383 rel_pos_ids.unsqueeze(0)
1384}
1385
1386pub(crate) fn make_log_bucket_position(
1388 relative_pos: Tensor,
1389 bucket_size: isize,
1390 max_position: isize,
1391 device: &Device,
1392) -> Result<Tensor> {
1393 let sign = relative_pos.to_dtype(DType::F32)?.sign()?;
1394
1395 let mid = bucket_size / 2;
1396
1397 let lt_mid = relative_pos.lt(mid as i64)?;
1398 let gt_neg_mid = relative_pos.gt(-mid as i64)?;
1399
1400 let condition = lt_mid
1401 .to_dtype(candle::DType::F32)?
1402 .mul(>_neg_mid.to_dtype(candle::DType::F32)?)?
1403 .to_dtype(DType::U8)?;
1404
1405 let on_true = Tensor::new(&[(mid - 1) as u32], device)?
1406 .broadcast_as(relative_pos.shape())?
1407 .to_dtype(relative_pos.dtype())?;
1408
1409 let on_false = relative_pos
1410 .to_dtype(DType::F32)?
1411 .abs()?
1412 .to_dtype(DType::I64)?;
1413
1414 let abs_pos = condition.where_cond(&on_true, &on_false)?;
1415
1416 let mid_as_tensor = Tensor::from_slice(&[mid as f32], (1,), device)?;
1417
1418 let log_pos = {
1419 let first_log = abs_pos
1420 .to_dtype(DType::F32)?
1421 .broadcast_div(&mid_as_tensor)?
1422 .log()?;
1423
1424 let second_log =
1425 Tensor::from_slice(&[((max_position as f32 - 1.0) / mid as f32)], (1,), device)?
1426 .log()?;
1427
1428 let first_div_second = first_log.broadcast_div(&second_log)?;
1429
1430 let to_ceil = first_div_second
1431 .broadcast_mul(Tensor::from_slice(&[(mid - 1) as f32], (1,), device)?.as_ref())?;
1432
1433 let ceil = to_ceil.ceil()?;
1434
1435 ceil.broadcast_add(&mid_as_tensor)?
1436 };
1437
1438 Ok({
1439 let abs_pos_lte_mid = abs_pos.to_dtype(DType::F32)?.broadcast_le(&mid_as_tensor)?;
1440 let relative_pos = relative_pos.to_dtype(relative_pos.dtype())?;
1441 let log_pos_mul_sign = log_pos.broadcast_mul(&sign.to_dtype(DType::F32)?)?;
1442 abs_pos_lte_mid.where_cond(&relative_pos.to_dtype(DType::F32)?, &log_pos_mul_sign)?
1443 })
1444}