burn_train/learner/
sequence.rs1use crate::metric::{AccuracyInput, PerplexityInput, TopKAccuracyInput};
2use crate::metric::{Adaptor, CerInput, LossInput, WerInput, processor::ItemLazy};
3use burn_core::tensor::{Int, Tensor};
4use burn_std::ExecutionError;
5
6#[derive(new)]
16pub struct SequenceOutput {
17 pub loss: Tensor<1>,
19
20 pub logits: Tensor<3>,
22
23 pub predictions: Option<Tensor<2, Int>>,
26
27 pub targets: Tensor<2, Int>,
29}
30
31impl SequenceOutput {
32 fn predicted_tokens(&self) -> Tensor<2, Int> {
33 match &self.predictions {
34 Some(preds) => preds.clone(),
35 None => self.logits.clone().argmax(2).squeeze_dim::<2>(2),
36 }
37 }
38
39 fn flat_logits(&self) -> Tensor<2> {
40 let [batch_size, seq_len, vocab_size] = self.logits.dims();
41 self.logits
42 .clone()
43 .reshape([batch_size * seq_len, vocab_size])
44 }
45
46 fn flat_targets(&self) -> Tensor<1, Int> {
47 let [batch_size, seq_len] = self.targets.dims();
48 self.targets.clone().reshape([batch_size * seq_len])
49 }
50}
51
52impl ItemLazy for SequenceOutput {
53 fn sync(self) -> Result<Self, ExecutionError> {
54 self.loss.device().flush()?;
62
63 Ok(SequenceOutput {
64 logits: self.logits.without_autodiff(),
65 loss: self.loss.without_autodiff(),
66 targets: self.targets.without_autodiff(),
67 predictions: self.predictions.map(|tensor| tensor.without_autodiff()),
68 })
69 }
70}
71
72impl Adaptor<LossInput> for SequenceOutput {
73 fn adapt(&self) -> LossInput {
74 LossInput::new(self.loss.clone())
75 }
76}
77
78impl Adaptor<CerInput> for SequenceOutput {
79 fn adapt(&self) -> CerInput {
80 CerInput::new(self.predicted_tokens(), self.targets.clone())
81 }
82}
83
84impl Adaptor<WerInput> for SequenceOutput {
85 fn adapt(&self) -> WerInput {
86 WerInput::new(self.predicted_tokens(), self.targets.clone())
87 }
88}
89
90impl Adaptor<AccuracyInput> for SequenceOutput {
91 fn adapt(&self) -> AccuracyInput {
92 AccuracyInput::new(self.flat_logits(), self.flat_targets())
93 }
94}
95
96impl Adaptor<TopKAccuracyInput> for SequenceOutput {
97 fn adapt(&self) -> TopKAccuracyInput {
98 TopKAccuracyInput::new(self.flat_logits(), self.flat_targets())
99 }
100}
101
102impl Adaptor<PerplexityInput> for SequenceOutput {
103 fn adapt(&self) -> PerplexityInput {
104 PerplexityInput::new(self.flat_logits(), self.flat_targets())
105 }
106}