From 783ffef82c4574dff7e939e1a2147bf4a36faaf6 Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Wed, 17 Jul 2024 08:04:24 -0400 Subject: [PATCH] permanently fail on face detection errors --- .../lipsync/sad_talker/model_downloaders.rs | 2 +- .../categorize_live_portrait_error.rs | 52 +++++++++++++++++++ .../workflow/live_portrait/command_args.rs | 1 - .../job_types/workflow/live_portrait/mod.rs | 1 + .../process_live_portrait_job.rs | 36 +++++++++++-- 5 files changed, 85 insertions(+), 7 deletions(-) create mode 100644 crates/service/job/inference_job/src/job/job_types/workflow/live_portrait/categorize_live_portrait_error.rs diff --git a/crates/service/job/inference_job/src/job/job_types/lipsync/sad_talker/model_downloaders.rs b/crates/service/job/inference_job/src/job/job_types/lipsync/sad_talker/model_downloaders.rs index d512b8bee4..3d419f717d 100644 --- a/crates/service/job/inference_job/src/job/job_types/lipsync/sad_talker/model_downloaders.rs +++ b/crates/service/job/inference_job/src/job/job_types/lipsync/sad_talker/model_downloaders.rs @@ -117,7 +117,7 @@ mod test { use std::path::Path; use crate::job::job_types::lipsync::sad_talker::model_downloaders::{SadTalkerModelFirstMapping, SadTalkerModelSecondMapping}; - use crate::util::model_downloader::ModelDownloader; + use crate::util::downloaders::model_downloader::ModelDownloader; #[test] fn test_downloader_model_first_mapping() { diff --git a/crates/service/job/inference_job/src/job/job_types/workflow/live_portrait/categorize_live_portrait_error.rs b/crates/service/job/inference_job/src/job/job_types/workflow/live_portrait/categorize_live_portrait_error.rs new file mode 100644 index 0000000000..bc3c69924b --- /dev/null +++ b/crates/service/job/inference_job/src/job/job_types/workflow/live_portrait/categorize_live_portrait_error.rs @@ -0,0 +1,52 @@ +use crate::job::job_loop::process_single_job_error::ProcessSingleJobError; + +pub fn categorize_live_portrait_error(stderr_contents: &str) -> Option { + if stderr_contents.contains("No face detected in the source image!") { + return Some(ProcessSingleJobError::FaceDetectionFailure); + } + None +} + +#[cfg(test)] +mod tests { + use anyhow::bail; + + use errors::AnyhowResult; + + use crate::job::job_loop::process_single_job_error::ProcessSingleJobError; + use crate::job::job_types::workflow::live_portrait::categorize_live_portrait_error::categorize_live_portrait_error; + + fn assert_face_tracking_error(maybe_error: Option) -> AnyhowResult<()> { + // NB: We have to do this since ProcessSingleJobError can't derive `PartialEq` + match maybe_error { + Some(ProcessSingleJobError::FaceDetectionFailure) => Ok(()), + None => bail!("error is absent"), + Some(_) => bail!("error is wrong type"), + } + } + + #[test] + fn stack_trace_0() { + // Failure video: + // https://staging.fakeyou.com/media/m_xwphfcm7y8eh4dabva24sd5hwqm6z2 + let trace = r#" + FaceAnalysisDIY warmup time: 1.020s +Detecting and cropping..: 0%| | 0/170 [00:00 Result<(), ProcessSingleJobError> { + let contents = match read_to_string(stderr_output_file) { + Ok(contents) => { + warn!("Captured stderr output: {}", contents); + contents + }, + Err(err) => { + error!("Error reading stderr output: {:?}", err); + return Ok(()); + } + }; + + match categorize_live_portrait_error(&contents) { + Some(ProcessSingleJobError::FaceDetectionFailure) => { + warn!("Face not detected in source"); + Err(ProcessSingleJobError::FaceDetectionFailure) + } + _ => Ok(()) + } +}