janitor

janitor
git clone https://git.prime8.dev/janitor.git
Log | Files | Refs | README | LICENSE

model.rs (1912B)


      1 use anyhow::Result;
      2 use serde::Serialize;
      3 use std::path::Path;
      4 use tch::{autocast, no_grad, CModule, Device, Tensor};
      5 
      6 #[derive(Debug, Clone, Copy, Serialize)]
      7 pub enum Label {
      8     Speech,
      9     Music,
     10     Noise,
     11 }
     12 
     13 pub struct Model {
     14     model: CModule,
     15 }
     16 
     17 impl Model {
     18     pub fn new<T>(model_path: T) -> Result<Model>
     19     where
     20         T: AsRef<Path>,
     21     {
     22         let device = Device::cuda_if_available();
     23         println!("Running model on {:?}", device);
     24         Ok(Self {
     25             model: CModule::load_on_device(model_path, device)?,
     26         })
     27     }
     28 
     29     pub fn label(&self, tensor: &Tensor) -> Result<Box<[Label]>> {
     30         let raw_output = Vec::try_from(
     31             no_grad(|| autocast(true, || tensor.apply(&self.model)))
     32                 .f_sigmoid()?
     33                 .flatten(0, -1),
     34         )?;
     35 
     36         let labels = raw_output
     37             .chunks(527)
     38             .map(|chunk| {
     39                 if chunk.len() != 527 {
     40                     return Ok(Label::Noise);
     41                 }
     42                 let output: [f32; 527] = chunk
     43                     .try_into()
     44                     .map_err(|_| anyhow::anyhow!("Failed to convert chunk to fixed-size array"))?;
     45 
     46                 let results = [
     47                     (Label::Speech, output[0]),
     48                     (Label::Music, output[137]),
     49                     (Label::Noise, output[513]),
     50                 ];
     51 
     52                 let label = if results[0].1 < 0.5 && results[1].1 < 0.5 {
     53                     Label::Noise
     54                 } else {
     55                     results
     56                         .iter()
     57                         .max_by(|a, b| a.1.total_cmp(&b.1))
     58                         .map(|(label, _)| *label)
     59                         .unwrap_or(Label::Noise)
     60                 };
     61 
     62                 Ok::<_, anyhow::Error>(label)
     63             })
     64             .collect::<Result<Vec<_>>>()?
     65             .into_boxed_slice();
     66 
     67         Ok(labels)
     68     }
     69 }