Edit TTS model with text pipeline type

This commit is contained in:
Brandon Thomas committed 2022-07-06 01:51:08 -04:00
1 parent f75f55fa22
commit b801f7c19e
7 files changed
+54 -40

No files matched your search

@@ -14,6 +14,7 @@ pub async fn edit_tts_model_details_as_author(
ietf_primary_language_subtag: &str,
creator_set_visibility: RecordVisibility,
maybe_default_pretrained_vocoder: Option<VocoderType>,
text_pipeline_type: Option<&str>,
// Author fields
author_ip_address: &str,
) -> Result<MySqlQueryResult, sqlx::Error> {
@@ -23,6 +24,7 @@ pub async fn edit_tts_model_details_as_author(
UPDATE tts_models
SET
maybe_default_pretrained_vocoder = ?,
text_pipeline_type = ?,
title = ?,
description_markdown = ?,
description_rendered_html = ?,
@@ -35,6 +37,7 @@ WHERE token = ?
LIMIT 1
"#,
maybe_default_pretrained_vocoder.map(|v| v.to_str()),
text_pipeline_type,
title,
description_markdown,
description_html,
@@ -58,6 +61,7 @@ pub async fn edit_tts_model_details_as_mod(
ietf_primary_language_subtag: &str,
creator_set_visibility: RecordVisibility,
maybe_default_pretrained_vocoder: Option<VocoderType>,
text_pipeline_type: Option<&str>,
// moderator fields
moderator_user_token: &str,
) -> Result<MySqlQueryResult, sqlx::Error> {
@@ -67,6 +71,7 @@ pub async fn edit_tts_model_details_as_mod(
UPDATE tts_models
SET
maybe_default_pretrained_vocoder = ?,
text_pipeline_type = ?,
title = ?,
description_markdown = ?,
description_rendered_html = ?,
@@ -79,6 +84,7 @@ WHERE token = ?
LIMIT 1
"#,
maybe_default_pretrained_vocoder.map(|v| v.to_str()),
text_pipeline_type,
title,
description_markdown,
description_html,
@@ -1,7 +1,7 @@
use std::ops::Deref;
use chrono::{DateTime, Utc};
use once_cell::sync::Lazy;
use crate::text_pipelines::text_pipeline::TtsTextPipeline;
use crate::text_pipelines::text_pipeline_type::TextPipelineType;
const ENGLISH_V1_EPOCH_STR : &'static str = "2022-05-01T00:00:00.00Z";
@@ -20,28 +20,28 @@ static ENGLISH_V1_EPOCH : Lazy<DateTime<Utc>> = Lazy::new(|| {
/// There will always be a guess returned.
///
/// maybe_model_created_at - `created_at` timestamp from database
pub fn guess_text_pipeline_heuristic(maybe_model_created_at: Option<DateTime<Utc>>) -> TtsTextPipeline {
pub fn guess_text_pipeline_heuristic(maybe_model_created_at: Option<DateTime<Utc>>) -> TextPipelineType {
// TODO: Use language to infer as well.
if let Some(created_at) = maybe_model_created_at {
if created_at < *ENGLISH_V1_EPOCH {
return TtsTextPipeline::LegacyFakeYou;
return TextPipelineType::LegacyFakeYou;
}
}
TtsTextPipeline::EnglishV1
TextPipelineType::EnglishV1
}
#[cfg(test)]
mod tests {
use chrono::{DateTime, Utc};
use crate::text_pipelines::guess_pipeline::guess_text_pipeline_heuristic;
use crate::text_pipelines::text_pipeline::TtsTextPipeline;
use crate::text_pipelines::text_pipeline_type::TextPipelineType;
#[test]
fn new_models_just_created_with_no_date_use_english_v1() {
assert_eq!(guess_text_pipeline_heuristic(None), TtsTextPipeline::EnglishV1);
assert_eq!(guess_text_pipeline_heuristic(None), TextPipelineType::EnglishV1);
}
#[test]
@@ -49,7 +49,7 @@ mod tests {
let datetime = DateTime::parse_from_rfc3339("2022-07-01T00:00:00.00Z")
.expect("should parse")
.with_timezone(&Utc);
assert_eq!(guess_text_pipeline_heuristic(Some(datetime)), TtsTextPipeline::EnglishV1);
assert_eq!(guess_text_pipeline_heuristic(Some(datetime)), TextPipelineType::EnglishV1);
}
#[test]
@@ -57,6 +57,6 @@ mod tests {
let datetime = DateTime::parse_from_rfc3339("2022-01-01T00:00:00.00Z")
.expect("should parse")
.with_timezone(&Utc);
assert_eq!(guess_text_pipeline_heuristic(Some(datetime)), TtsTextPipeline::LegacyFakeYou);
assert_eq!(guess_text_pipeline_heuristic(Some(datetime)), TextPipelineType::LegacyFakeYou);
}
}
@@ -1,2 +1,2 @@
pub mod guess_pipeline;
pub mod text_pipeline;
pub mod text_pipeline_type;
@@ -7,7 +7,7 @@ use container_common::anyhow_result::AnyhowResult;
/// This is *not* a database enum, but the text serializations get stored in the database in a
/// varchar field and communicated over the API.
#[derive(Clone, Copy, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub enum TtsTextPipeline {
pub enum TextPipelineType {
// TODO: Introduce old vocodes models.
//#[serde(rename = "legacy_vocodes")]
@@ -46,7 +46,7 @@ const ENGLISH_V1 : &'static str = "english_v1";
const SPANISH_V1 : &'static str = "spanish_v1";
const SPANISH_V2 : &'static str = "spanish_v2";
impl TtsTextPipeline {
impl TextPipelineType {
/// Check if the text pipeline name is valid and supported.
pub fn is_valid_name(tts_text_pipeline: &str) -> bool {
@@ -57,10 +57,10 @@ impl TtsTextPipeline {
// `serde_variant` looks like a fix, but it's GPL3.
pub fn to_str(&self) -> &'static str {
match self {
TtsTextPipeline::LegacyFakeYou => LEGACY_FAKEYOU,
TtsTextPipeline::EnglishV1 => ENGLISH_V1,
TtsTextPipeline::SpanishV1 => SPANISH_V1,
TtsTextPipeline::SpanishV2 => SPANISH_V2,
TextPipelineType::LegacyFakeYou => LEGACY_FAKEYOU,
TextPipelineType::EnglishV1 => ENGLISH_V1,
TextPipelineType::SpanishV1 => SPANISH_V1,
TextPipelineType::SpanishV2 => SPANISH_V2,
}
}
@@ -77,36 +77,36 @@ impl TtsTextPipeline {
#[cfg(test)]
mod tests {
use crate::text_pipelines::text_pipeline::TtsTextPipeline;
use crate::text_pipelines::text_pipeline_type::TextPipelineType;
#[test]
fn valid_text_pipeline_names() {
assert!(TtsTextPipeline::is_valid_name("legacy_fakeyou"));
assert!(TtsTextPipeline::is_valid_name("english_v1"));
assert!(TtsTextPipeline::is_valid_name("spanish_v1"));
assert!(TtsTextPipeline::is_valid_name("spanish_v2"));
assert!(TextPipelineType::is_valid_name("legacy_fakeyou"));
assert!(TextPipelineType::is_valid_name("english_v1"));
assert!(TextPipelineType::is_valid_name("spanish_v1"));
assert!(TextPipelineType::is_valid_name("spanish_v2"));
}
#[test]
fn invalid_text_pipeline_names() {
// Garbage
assert!(!TtsTextPipeline::is_valid_name(""));
assert!(!TtsTextPipeline::is_valid_name("asdf"));
assert!(!TextPipelineType::is_valid_name(""));
assert!(!TextPipelineType::is_valid_name("asdf"));
// NB: Must be lower case
assert!(!TtsTextPipeline::is_valid_name("LEGACY_FAKEYOU"));
assert!(!TtsTextPipeline::is_valid_name("ENGLISH_V1"));
assert!(!TtsTextPipeline::is_valid_name("SPANISH_V1"));
assert!(!TtsTextPipeline::is_valid_name("SPANISH_V2"));
assert!(!TextPipelineType::is_valid_name("LEGACY_FAKEYOU"));
assert!(!TextPipelineType::is_valid_name("ENGLISH_V1"));
assert!(!TextPipelineType::is_valid_name("SPANISH_V1"));
assert!(!TextPipelineType::is_valid_name("SPANISH_V2"));
// NB: Not yet supported
assert!(!TtsTextPipeline::is_valid_name("legacy_vocodes"));
assert!(!TtsTextPipeline::is_valid_name("spanish_v3"));
assert!(!TtsTextPipeline::is_valid_name("english_v2"));
assert!(!TextPipelineType::is_valid_name("legacy_vocodes"));
assert!(!TextPipelineType::is_valid_name("spanish_v3"));
assert!(!TextPipelineType::is_valid_name("english_v2"));
// Wrong names
assert!(!TtsTextPipeline::is_valid_name("english"));
assert!(!TtsTextPipeline::is_valid_name("spanish"));
assert!(!TtsTextPipeline::is_valid_name("vocodes"));
assert!(!TextPipelineType::is_valid_name("english"));
assert!(!TextPipelineType::is_valid_name("spanish"));
assert!(!TextPipelineType::is_valid_name("vocodes"));
}
}
@@ -27,6 +27,7 @@ use std::fmt;
use std::sync::Arc;
use database_queries::queries::tts::tts_models::edit_tts_model_details::{edit_tts_model_details_as_author, edit_tts_model_details_as_mod};
use database_queries::queries::tts::tts_models::edit_tts_model_moderator_details::edit_tts_model_moderator_details;
use tts_common::text_pipelines::text_pipeline_type::TextPipelineType;
use user_input_common::check_for_slurs::contains_slurs;
const DEFAULT_IETF_LANGUAGE_TAG : &'static str = "en-US";
@@ -47,11 +48,13 @@ pub struct EditTtsModelRequest {
pub creator_set_visibility: Option<String>,
pub maybe_default_pretrained_vocoder: Option<VocoderType>,
// Text pipeline won't be set by default on model upload (for now),
// and a lot of existing models will have null values.
pub text_pipeline_type: Option<TextPipelineType>,
// NB: We calculate 'ietf_primary_language_subtag' from this value.
pub ietf_language_tag: Option<String>,
pub text_pipeline_type: Option<String>,
//pub updatable_slug: Option<String>,
//pub tts_model_type: Option<String>,
//pub vocoder_token: Option<String>,
@@ -245,6 +248,9 @@ pub async fn edit_tts_model_handler(
maybe_default_pretrained_vocoder = Some(vocoder);
}
let text_pipeline_type = request.text_pipeline_type
.map(|pipeline_type| pipeline_type.to_str());
let ip_address = get_request_ip(&http_request);
let query_result = if is_author {
@@ -259,6 +265,7 @@ pub async fn edit_tts_model_handler(
&ietf_primary_language_subtag,
creator_set_visibility,
maybe_default_pretrained_vocoder,
text_pipeline_type,
&ip_address,
).await
} else {
@@ -273,6 +280,7 @@ pub async fn edit_tts_model_handler(
&ietf_primary_language_subtag,
creator_set_visibility,
maybe_default_pretrained_vocoder,
text_pipeline_type,
&user_session.user_token,
).await
};
@@ -22,7 +22,7 @@ use sqlx::mysql::MySqlDatabaseError;
use std::fmt;
use std::sync::Arc;
use tts_common::text_pipelines::guess_pipeline::guess_text_pipeline_heuristic;
use tts_common::text_pipelines::text_pipeline::TtsTextPipeline;
use tts_common::text_pipelines::text_pipeline_type::TextPipelineType;
// =============== Request ===============
@@ -50,8 +50,8 @@ pub struct TtsModelInfo {
///
/// >> NB: text_pipeline_type may not always be present in the database, but if absent we'll
/// inform the frontend (and inference pipeline) of our best guess according to a heuristic.
pub text_pipeline_type: Option<TtsTextPipeline>,
pub text_pipeline_type_guess: TtsTextPipeline,
pub text_pipeline_type: Option<TextPipelineType>,
pub text_pipeline_type_guess: TextPipelineType,
pub maybe_default_pretrained_vocoder: Option<VocoderType>,
pub text_preprocessing_algorithm: String,
@@ -187,7 +187,7 @@ pub async fn get_tts_model_handler(
// If there's an error deserializing, turn it to None.
let text_pipeline_type = model.text_pipeline_type
.as_deref()
.and_then(|pipeline_type| TtsTextPipeline::from_str(pipeline_type).ok());
.and_then(|pipeline_type| TextPipelineType::from_str(pipeline_type).ok());
// TODO: Use language to infer as well.
let text_pipeline_type_guess =
@@ -51,7 +51,7 @@ use storage_buckets_common::bucket_path_unifier::BucketPathUnifier;
use tempdir::TempDir;
use tts_common::clean_symbols::clean_symbols;
use tts_common::text_pipelines::guess_pipeline::guess_text_pipeline_heuristic;
use tts_common::text_pipelines::text_pipeline::TtsTextPipeline;
use tts_common::text_pipelines::text_pipeline_type::TextPipelineType;
#[derive(Deserialize, Default)]
struct FileMetadata {
@@ -327,7 +327,7 @@ pub async fn process_single_job(
let text_pipeline_type_or_guess = model_record.text_pipeline_type
.as_deref()
.and_then(|pipeline_type|
TtsTextPipeline::from_str(pipeline_type).ok())// NB: If there's an error deserializing, turn it to None.
TextPipelineType::from_str(pipeline_type).ok())// NB: If there's an error deserializing, turn it to None.
.unwrap_or_else(||
guess_text_pipeline_heuristic(Some(model_record.created_at)));