Compare commits

..
Author SHA1 Message Date
ArEnSc 168afd72cd Fixed GDrive download check. 2024-01-27 01:29:57 -05:00
ArEnSc 3415ad4e80 loRA's work 2024-01-26 04:01:37 -05:00
ArEnSc 1238f95af8 Merge branch 'master' into feature/sd_finalstand 2024-01-25 16:31:25 -05:00
ArEnSc 69e6a73ef4 Fixing issues and testing. 2024-01-25 13:46:30 -05:00
ArEnSc 51ce0c29cb It should work kasisnu will help 2024-01-25 05:59:14 -05:00
ArEnSc e45ee58cdf Uploads should work testing required... 2024-01-25 05:12:11 -05:00
Brandon Thomas d80b883ce7 a few more clippylints 2024-01-24 23:16:36 -05:00
Brandon Thomas 0743684f0d cookie samesite policy for netlify branch deploys 2024-01-23 22:37:04 -05:00
Brandon Thomas 2a2b08d711 moderators don't want to see deleted files 2024-01-23 21:57:20 -05:00
ArEnSc 06feb58d83 commiting env as well to fix problem with the local dev env 2024-01-23 16:05:40 -05:00
ArEnSc e91f57944e fixed bugs in sql mapping and loRA pathing. 2024-01-23 16:05:20 -05:00
Brandon Thomas 126ed66232 enqueue tts - work with model_weights 2024-01-23 14:19:48 -05:00
Brandon Thomas af8fb02078 comments 2024-01-23 12:50:06 -05:00
ArEnSc 968af24ccc builds again adding the metadata. 2024-01-22 21:41:51 -05:00
Brandon Thomas 2c8e9ff823 fix lint issues 2024-01-22 21:01:06 -05:00
Brandon Thomas 403529c83d codegen db 2024-01-22 20:55:05 -05:00
Brandon Thomas ea85dbc6e6 rename types to be better self-documenting 2024-01-22 20:54:19 -05:00
Brandon Thomas 0ee62b64fe Merge pull request #289 from storytold/brandon-migrate-tts-inference
migrate TTS inference to weights
2024-01-22 20:45:25 -05:00
Brandon Thomas d2d295c12f migrate TTS inference to weights 2024-01-22 20:44:38 -05:00
ArEnSc edb2a7f95a It builds again. 2024-01-22 19:18:27 -05:00
ArEnSc f37c04ee07 Merge pull request #287 from storytold/feature/media-seed-tool
make seed tool for media uploads
2024-01-22 15:07:45 -05:00
saltacc 93f8a95298 make seed tool for media uploads 2024-01-22 12:01:45 -08:00
ArEnSc 957b68f679 Fixed insert generic. 2024-01-21 23:47:50 -05:00
Brandon Thomas cb6feaaa46 disable tts edit/delete when migrated 2024-01-21 03:21:00 -05:00
Brandon Thomas c7bc5e3686 fix import errors; codegen db 2024-01-21 01:16:09 -05:00
Brandon Thomas 0811e12c0b port legacy GET TTS endpoint to model weights 2024-01-21 01:10:20 -05:00
Brandon Thomas 65c5138533 document index 2024-01-20 21:30:51 -05:00
Brandon Thomas 20ced958e6 Merge pull request #286 from storytold/brandon-port-tts-queries
port TTS enqueue to weights
2024-01-20 19:58:30 -05:00
Brandon Thomas 22026977d9 port TTS enqueue to weights 2024-01-20 19:56:26 -05:00
Brandon Thomas f812fbb4e6 rust lint: unused mut 2024-01-20 18:40:15 -05:00
ArEnSc 20832a9af9 Almost there need to test that one endpoint 2024-01-20 09:15:25 -05:00
Brandon Thomas 7558a4edc9 fix lint and test failures 2024-01-19 21:00:21 -05:00
ArEnSc 59745551ce Merge pull request #285 from storytold/feature/comfyui
ComfyUI Support
2024-01-19 16:27:46 -05:00
saltacc 3e875fb6fa uncomment 2024-01-19 13:08:58 -08:00
saltacc da2ea13524 Merge remote-tracking branch 'origin/master' into feature/comfyui 2024-01-19 12:41:56 -08:00
saltacc 550a11c493 make it work 🔥 2024-01-19 12:40:19 -08:00
Brandon Thomas a4b549af19 allow larger file uploads 2024-01-19 02:56:46 -05:00
ArEnSc 7eb93c7600 Builds on inference for batch creation of entries. 2024-01-19 00:17:53 -05:00
Brandon Thomas c44cc5671f ES cleanup, additional param 2024-01-18 22:53:17 -05:00
Brandon Thomas 380933d1aa much cleaner queries 2024-01-18 22:36:04 -05:00
ArEnSc 5298c028e0 Fix small bug. 2024-01-18 20:50:16 -05:00
ArEnSc ad32bdb119 Fixing routing for inference jobs to support uploads properly. 2024-01-18 20:26:19 -05:00
Brandon Thomas 3318067cb5 hide deleted files from mods/admins - it's just clutter 2024-01-18 19:24:39 -05:00
Brandon Thomas c15360ddb3 ElasticSearch test 2024-01-18 18:17:21 -05:00
saltacc e741951630 update 2024-01-18 09:22:30 -08:00
Brandon Thomas c91f548878 hack elasticsearch options 2024-01-18 01:58:36 -05:00
Brandon Thomas 35231e5f82 fix last test failures 2024-01-17 23:13:47 -05:00
saltacc 7f1173956a comfyui 2024-01-17 17:39:31 -08:00
Brandon Thomas f6da4f3247 fix lints 2024-01-17 20:34:13 -05:00
Brandon Thomas 8dc7c81a78 fix tests 2024-01-17 19:48:03 -05:00
ArEnSc 387dbbeed9 Merge pull request #266 from storytold/feature/image_generation
Feature/image generation
2024-01-17 19:27:23 -05:00
ArEnSc cecd3dd6df Update .env 2024-01-17 18:03:20 -05:00
ArEnSc 7b90b11ce6 Fixed build issues ready to merge to master after review. 2024-01-17 17:33:55 -05:00
ArEnSc fc154c4a31 Merge branch 'master' into feature/image_generation 2024-01-17 15:22:53 -05:00
ArEnSc 24818f8ecf Ok this builds inference job. Fixes still needed 2024-01-17 03:06:09 -05:00
Brandon Thomas 2d91504eb5 test to show usage 2024-01-17 02:21:23 -05:00
Brandon Thomas 67a8bb739b Merge pull request #279 from storytold/brandon-insert-batch-generations
insert batch generation records
2024-01-16 23:01:10 -05:00
Brandon Thomas 33613cb5d8 insert batch generation records 2024-01-16 23:00:17 -05:00
Brandon Thomas 2487a8d646 refactor query modules 2024-01-16 21:03:56 -05:00
Brandon Thomas 1771e1dffe fix lint/test failures 2024-01-16 20:52:11 -05:00
Brandon Thomas 2d4d2c667f reference schemas 2024-01-16 19:49:08 -05:00
Brandon Thomas 0c99852dfd Merge pull request #278 from storytold/brandon-new-tables
new tables: idempotency_tokens, batch_generations; new column
2024-01-16 19:11:36 -05:00
Brandon Thomas 7cc310764e new tables: idempotency_tokens, batch_generations; new column 2024-01-16 19:10:23 -05:00
Kasisnu b66b04d86c Merge pull request #277 from storytold/jan-16-mithoo
bugfix: ignore more than one samples for zs
2024-01-16 13:06:48 +05:30
Kasisnu 18d46a0f57 bugfix: ignore more than one samples for zs 2024-01-16 13:06:29 +05:30
Kasisnu 97795fac22 Merge pull request #276 from storytold/jan-16-mithoo
codegen & styletts2 downloader cleanup
2024-01-16 11:40:30 +05:30
Kasisnu cec0cfc907 remove misleading downloaders from styletts2 2024-01-16 11:39:46 +05:30
Kasisnu d516058802 codegen 2024-01-16 11:36:28 +05:30
Kasisnu b77810cd29 Merge pull request #268 from storytold/jan-04-mithoo
adds styletts2 as voice designer model
2024-01-16 10:52:06 +05:30
Brandon Thomas 2507cf0332 analysis of AI streamer bug reports 2024-01-15 21:48:45 -05:00
Brandon Thomas cf4c335d41 migration tool for tts models 2024-01-15 21:27:44 -05:00
Kasisnu 5e98049c50 switch from vallex -> styletts2 for zero shot 2024-01-15 17:44:29 +05:30
ArEnSc eebedbce07 Runs inference but the checkpoint is corrupt? 2024-01-14 18:39:33 -05:00
ArEnSc f4497a4aee Fixed build errors inference job should be good to run now. 2024-01-13 02:27:12 -05:00
ArEnSc 447a457dff image gen should build. 2024-01-13 00:26:51 -05:00
Kasisnu ea3a6d3c0b pass appropriate arguments to styletts inference command 2024-01-12 17:58:12 +05:30
Kasisnu c6a6676f08 adds styletts2 as voice designer model 2024-01-12 14:53:55 +05:30
ArEnSc 7f65014d6d Almost done inference. 2024-01-12 02:33:36 -05:00
ArEnSc c4681937b3 Image generation on it's way... 2024-01-12 00:19:09 -05:00
ArEnSc 2d52ac0fa9 Removed some components,
also added the command env variables, now going to run inference.
2024-01-11 21:24:38 -05:00
ArEnSc 8709fa9c8a enqueue is there. testing inference side. 2024-01-11 16:43:04 -05:00
ArEnSc 4250469fd3 enqueue_image_generation
fixes added checks and changes to the interface.
Will document the api as well.
2024-01-10 20:35:53 -05:00
ArEnSc e5ed4d986f downloading works. 2024-01-05 17:20:21 -05:00
ArEnSc ea84b009a8 Fix compile issues 2024-01-05 16:01:42 -05:00
ArEnSc aa202172a2 uploading models and then reseed. 2024-01-04 21:46:25 -05:00
ArEnSc 1b4e3cccb5 Fixed over sight in the cloud file remote_file_manager,
where the metadata didn't include the bucket path for the file.
Then we didn't pass the correct upload path with the file name
2024-01-04 17:28:00 -05:00
ArEnSc 796e8b5aee Compile fix switching to rust rover since less mapping is required now. 2024-01-04 09:57:45 -05:00
ArEnSc 1614cba2f8 properties added 2024-01-03 23:16:00 -05:00
ArEnSc dbe989c5a1 rebuilds on the routes in storyteller web. 2024-01-03 22:32:25 -05:00
ArEnSc a2cad0b289 getting the args for inference working. 2024-01-03 14:57:49 -05:00
ArEnSc 74db1683b1 unwraped the args 2024-01-03 11:01:37 -05:00
ArEnSc 6e5e326d0e Ok it builds time to fillout the inference command. 2024-01-02 23:06:12 -05:00
ArEnSc bcd806e7f0 Some boilerplate done. 2024-01-02 17:50:22 -05:00
ArEnSc 20b95c090e Now testing the end point. 2024-01-02 16:16:51 -05:00
ArEnSc 87b2f4a113 Args are tested 2024-01-02 12:55:34 -05:00
ArEnSc a7799be70e Merge branch 'master' into feature/image_generation 2024-01-02 12:36:18 -05:00
ArEnSc 7d858d2c19 Payload almost ready need to migrate the db and write unit tests. 2024-01-02 12:24:13 -05:00
ArEnSc 733c24aebb Working on enqueuing image generation 2024-01-02 10:50:24 -05:00
217 changed files with 10318 additions and 554 deletions
+3 -1
View File
@@ -64,6 +64,8 @@ HIFIGAN_ROOT_CODE_DIRECTORY=/home/bt/dev/storyteller/storyteller-ml/tts
HIFIGAN_VIRTUAL_ENV_ACTIVATION_COMMAND="source python/bin/activate"
HIFIGAN_MODEL_CHECK_SCRIPT_NAME="vocodes_model_check_hifigan.py"
DOWNLOAD_SCRIPT="/home/tensor/code/storyteller/web-downloader/.venv/bin/python3.11 /home/tensor/code/storyteller/web-downloader/download_internet_file.py"
TTS_INFERENCE_SIDECAR_HOSTNAME=localhost:8000
#TTS_WAVEGLOW_VOCODER_MODEL_FILENAME=waveglow_256channels_universal_v5.pt # THIS SOUNDS HORRID
@@ -76,4 +78,4 @@ TTS_HIFIGAN_SUPERRES_VOCODER_MODEL_FILENAME=hifigan_superres_twilight_33000.pt
# Development key. Permissible to check in.
NEWRELIC_API_KEY=c402be1c4c4216ec83d0cfc0851520cfFFFFNRAL
#STORYTELLER_ROOT="/home/tensor/code/storyteller/" # Put this in .env-secrets so that not everyone gets this setting.
STORYTELLER_ROOT="/home/tensor/code/storyteller/" # Put this in .env-secrets so that not everyone gets this setting.
-1
View File
@@ -17,7 +17,6 @@ production_database_voice_clone_report_download.sh
secrets.toml
secrets.yaml
twitch_secrets.toml
.DS_Store
# Old env secrets
.*-secrets
@@ -0,0 +1,12 @@
{
"db_name": "MySQL",
"query": "\nINSERT INTO model_weights_extension_tts_details\nSET\n model_weights_token = ?,\n ietf_language_tag = ?,\n ietf_primary_language_subtag = ?,\n text_pipeline_type = ?,\n use_default_mel_multiply_factor = ?,\n maybe_custom_mel_multiply_factor = ?,\n maybe_default_pretrained_vocoder = ?,\n maybe_custom_vocoder_token = ?\nON DUPLICATE KEY UPDATE\n ietf_language_tag = ?,\n ietf_primary_language_subtag = ?,\n text_pipeline_type = ?,\n use_default_mel_multiply_factor = ?,\n maybe_custom_mel_multiply_factor = ?,\n maybe_default_pretrained_vocoder = ?,\n maybe_custom_vocoder_token = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 15
},
"nullable": []
},
"hash": "1ce9219b8f05fe54adaa6841acb708e165e1c7855b441b9623a2151197578929"
}
@@ -0,0 +1,465 @@
{
"db_name": "MySQL",
"query": "\n SELECT\n wt.token as `token: tokens::tokens::model_weights::ModelWeightToken`,\n wt.title,\n wt.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n wt.weights_category as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n wt.maybe_description_markdown,\n wt.maybe_description_rendered_html,\n\n wt.creator_user_token as `creator_user_token: tokens::tokens::users::UserToken`,\n users.username as creator_username,\n users.display_name as creator_display_name,\n users.email_gravatar_hash AS creator_gravatar_hash,\n\n wt.creator_ip_address,\n wt.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n wt.maybe_last_update_user_token as `maybe_last_update_user_token: tokens::tokens::users::UserToken`,\n wt.original_download_url,\n wt.original_filename,\n wt.file_size_bytes,\n wt.file_checksum_sha2,\n\n wt.public_bucket_hash,\n wt.maybe_public_bucket_prefix,\n wt.maybe_public_bucket_extension,\n\n cover_image.public_bucket_directory_hash as maybe_cover_image_public_bucket_hash,\n cover_image.maybe_public_bucket_prefix as maybe_cover_image_public_bucket_prefix,\n cover_image.maybe_public_bucket_extension as maybe_cover_image_public_bucket_extension,\n\n entity_stats.ratings_positive_count as maybe_ratings_positive_count,\n entity_stats.ratings_negative_count as maybe_ratings_negative_count,\n entity_stats.bookmark_count as maybe_bookmark_count,\n\n w_extension.ietf_language_tag as maybe_ietf_language_tag,\n w_extension.ietf_primary_language_subtag as maybe_ietf_primary_language_subtag,\n w_extension.maybe_default_pretrained_vocoder,\n w_extension.text_pipeline_type as maybe_text_pipeline_type,\n w_extension.use_default_mel_multiply_factor,\n w_extension.maybe_custom_mel_multiply_factor,\n\n w_extension.maybe_custom_vocoder_token,\n\n vocoder.vocoder_type as `maybe_custom_vocoder_type: enums::common::vocoder_type::VocoderType`,\n vocoder.title as maybe_custom_vocoder_title,\n vocoder.private_bucket_hash as maybe_custom_vocoder_private_bucket_hash,\n\n wt.version,\n wt.created_at,\n wt.updated_at,\n wt.user_deleted_at,\n wt.mod_deleted_at\n\n FROM model_weights as wt\n JOIN users\n ON users.token = wt.creator_user_token\n LEFT OUTER JOIN media_files as cover_image\n ON cover_image.token = wt.maybe_cover_image_media_file_token\n LEFT OUTER JOIN entity_stats\n ON entity_stats.entity_type = \"model_weight\"\n AND entity_stats.entity_token = wt.token\n\n LEFT OUTER JOIN model_weights_extension_tts_details as w_extension\n ON w_extension.model_weights_token = wt.token\n\n LEFT OUTER JOIN vocoder_models AS vocoder\n ON vocoder.token = w_extension.maybe_custom_vocoder_token\n\n WHERE\n wt.token = ?\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "token: tokens::tokens::model_weights::ModelWeightToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "title",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 2,
"name": "weights_type: enums::by_table::model_weights::weights_types::WeightsType",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 3,
"name": "weights_category: enums::by_table::model_weights::weights_category::WeightsCategory",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 4,
"name": "maybe_description_markdown",
"type_info": {
"type": "Blob",
"flags": "BLOB | BINARY",
"char_set": 224,
"max_size": 262140
}
},
{
"ordinal": 5,
"name": "maybe_description_rendered_html",
"type_info": {
"type": "Blob",
"flags": "BLOB | BINARY",
"char_set": 224,
"max_size": 262140
}
},
{
"ordinal": 6,
"name": "creator_user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 7,
"name": "creator_username",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 8,
"name": "creator_display_name",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 9,
"name": "creator_gravatar_hash",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 10,
"name": "creator_ip_address",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 160
}
},
{
"ordinal": 11,
"name": "creator_set_visibility: enums::common::visibility::Visibility",
"type_info": {
"type": "String",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 12,
"name": "maybe_last_update_user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 13,
"name": "original_download_url",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 2048
}
},
{
"ordinal": 14,
"name": "original_filename",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 15,
"name": "file_size_bytes",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 16,
"name": "file_checksum_sha2",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 256
}
},
{
"ordinal": 17,
"name": "public_bucket_hash",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 18,
"name": "maybe_public_bucket_prefix",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 19,
"name": "maybe_public_bucket_extension",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 20,
"name": "maybe_cover_image_public_bucket_hash",
"type_info": {
"type": "VarString",
"flags": "BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 21,
"name": "maybe_cover_image_public_bucket_prefix",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 22,
"name": "maybe_cover_image_public_bucket_extension",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 23,
"name": "maybe_ratings_positive_count",
"type_info": {
"type": "Long",
"flags": "UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 24,
"name": "maybe_ratings_negative_count",
"type_info": {
"type": "Long",
"flags": "UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 25,
"name": "maybe_bookmark_count",
"type_info": {
"type": "Long",
"flags": "UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 26,
"name": "maybe_ietf_language_tag",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 256
}
},
{
"ordinal": 27,
"name": "maybe_ietf_primary_language_subtag",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 48
}
},
{
"ordinal": 28,
"name": "maybe_default_pretrained_vocoder",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 256
}
},
{
"ordinal": 29,
"name": "maybe_text_pipeline_type",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 256
}
},
{
"ordinal": 30,
"name": "use_default_mel_multiply_factor",
"type_info": {
"type": "Tiny",
"flags": "",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 31,
"name": "maybe_custom_mel_multiply_factor",
"type_info": {
"type": "Double",
"flags": "",
"char_set": 63,
"max_size": 22
}
},
{
"ordinal": 32,
"name": "maybe_custom_vocoder_token",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 33,
"name": "maybe_custom_vocoder_type: enums::common::vocoder_type::VocoderType",
"type_info": {
"type": "VarString",
"flags": "BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 34,
"name": "maybe_custom_vocoder_title",
"type_info": {
"type": "VarString",
"flags": "BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 35,
"name": "maybe_custom_vocoder_private_bucket_hash",
"type_info": {
"type": "String",
"flags": "MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 256
}
},
{
"ordinal": 36,
"name": "version",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 11
}
},
{
"ordinal": 37,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 38,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 39,
"name": "user_deleted_at",
"type_info": {
"type": "Timestamp",
"flags": "BINARY",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 40,
"name": "mod_deleted_at",
"type_info": {
"type": "Timestamp",
"flags": "BINARY",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
true,
true,
false,
false,
false,
false,
false,
false,
true,
true,
true,
false,
false,
false,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
false,
false,
false,
true,
true
]
},
"hash": "6c0a2cb31a3241fc6cd0b6738901a31bd91298f131d3b87744c698e92eaec34b"
}
@@ -0,0 +1,399 @@
{
"db_name": "MySQL",
"query": "\n SELECT\n wt.token as `token: tokens::tokens::model_weights::ModelWeightToken`,\n wt.title,\n wt.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n wt.weights_category as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n wt.maybe_description_markdown,\n wt.maybe_description_rendered_html,\n\n wt.creator_user_token as `creator_user_token: tokens::tokens::users::UserToken`,\n users.username as creator_username,\n users.display_name as creator_display_name,\n users.email_gravatar_hash AS creator_gravatar_hash,\n\n wt.creator_ip_address,\n wt.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n wt.maybe_last_update_user_token as `maybe_last_update_user_token: tokens::tokens::users::UserToken`,\n wt.original_download_url,\n wt.original_filename,\n wt.file_size_bytes,\n wt.file_checksum_sha2,\n\n wt.public_bucket_hash,\n wt.maybe_public_bucket_prefix,\n wt.maybe_public_bucket_extension,\n\n cover_image.public_bucket_directory_hash as maybe_cover_image_public_bucket_hash,\n cover_image.maybe_public_bucket_prefix as maybe_cover_image_public_bucket_prefix,\n cover_image.maybe_public_bucket_extension as maybe_cover_image_public_bucket_extension,\n\n entity_stats.ratings_positive_count as maybe_ratings_positive_count,\n entity_stats.ratings_negative_count as maybe_ratings_negative_count,\n entity_stats.bookmark_count as maybe_bookmark_count,\n\n w_extension.ietf_language_tag as maybe_ietf_language_tag,\n w_extension.ietf_primary_language_subtag as maybe_ietf_primary_language_subtag,\n w_extension.maybe_default_pretrained_vocoder as `maybe_default_pretrained_vocoder: crate::column_types::vocoder_type::VocoderType`,\n w_extension.text_pipeline_type as maybe_text_pipeline_type,\n\n wt.version,\n wt.created_at,\n wt.updated_at,\n wt.user_deleted_at,\n wt.mod_deleted_at\n\n FROM model_weights as wt\n JOIN users\n ON users.token = wt.creator_user_token\n LEFT OUTER JOIN media_files as cover_image\n ON cover_image.token = wt.maybe_cover_image_media_file_token\n LEFT OUTER JOIN entity_stats\n ON entity_stats.entity_type = \"model_weight\"\n AND entity_stats.entity_token = wt.token\n\n LEFT OUTER JOIN model_weights_extension_tts_details as w_extension\n ON w_extension.model_weights_token = wt.token\n\n WHERE\n wt.token = ?\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "token: tokens::tokens::model_weights::ModelWeightToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "title",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 2,
"name": "weights_type: enums::by_table::model_weights::weights_types::WeightsType",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 3,
"name": "weights_category: enums::by_table::model_weights::weights_category::WeightsCategory",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 4,
"name": "maybe_description_markdown",
"type_info": {
"type": "Blob",
"flags": "BLOB | BINARY",
"char_set": 224,
"max_size": 262140
}
},
{
"ordinal": 5,
"name": "maybe_description_rendered_html",
"type_info": {
"type": "Blob",
"flags": "BLOB | BINARY",
"char_set": 224,
"max_size": 262140
}
},
{
"ordinal": 6,
"name": "creator_user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 7,
"name": "creator_username",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 8,
"name": "creator_display_name",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 9,
"name": "creator_gravatar_hash",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 10,
"name": "creator_ip_address",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 160
}
},
{
"ordinal": 11,
"name": "creator_set_visibility: enums::common::visibility::Visibility",
"type_info": {
"type": "String",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 12,
"name": "maybe_last_update_user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 13,
"name": "original_download_url",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 2048
}
},
{
"ordinal": 14,
"name": "original_filename",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 15,
"name": "file_size_bytes",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 16,
"name": "file_checksum_sha2",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 256
}
},
{
"ordinal": 17,
"name": "public_bucket_hash",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 18,
"name": "maybe_public_bucket_prefix",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 19,
"name": "maybe_public_bucket_extension",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 20,
"name": "maybe_cover_image_public_bucket_hash",
"type_info": {
"type": "VarString",
"flags": "BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 21,
"name": "maybe_cover_image_public_bucket_prefix",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 22,
"name": "maybe_cover_image_public_bucket_extension",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 23,
"name": "maybe_ratings_positive_count",
"type_info": {
"type": "Long",
"flags": "UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 24,
"name": "maybe_ratings_negative_count",
"type_info": {
"type": "Long",
"flags": "UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 25,
"name": "maybe_bookmark_count",
"type_info": {
"type": "Long",
"flags": "UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 26,
"name": "maybe_ietf_language_tag",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 256
}
},
{
"ordinal": 27,
"name": "maybe_ietf_primary_language_subtag",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 48
}
},
{
"ordinal": 28,
"name": "maybe_default_pretrained_vocoder: crate::column_types::vocoder_type::VocoderType",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 256
}
},
{
"ordinal": 29,
"name": "maybe_text_pipeline_type",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 256
}
},
{
"ordinal": 30,
"name": "version",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 11
}
},
{
"ordinal": 31,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 32,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 33,
"name": "user_deleted_at",
"type_info": {
"type": "Timestamp",
"flags": "BINARY",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 34,
"name": "mod_deleted_at",
"type_info": {
"type": "Timestamp",
"flags": "BINARY",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
true,
true,
false,
false,
false,
false,
false,
false,
true,
true,
true,
false,
false,
false,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
false,
false,
false,
true,
true
]
},
"hash": "8bd7ddec0966c742754a278000902c7d5059237ef312c638817a465dcb1979de"
}
@@ -0,0 +1,399 @@
{
"db_name": "MySQL",
"query": "\n SELECT\n wt.token as `token: tokens::tokens::model_weights::ModelWeightToken`,\n wt.title,\n wt.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n wt.weights_category as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n wt.maybe_description_markdown,\n wt.maybe_description_rendered_html,\n wt.creator_ip_address,\n wt.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n\n wt.creator_user_token as `creator_user_token: tokens::tokens::users::UserToken`,\n users.username as creator_username,\n users.display_name as creator_display_name,\n users.email_gravatar_hash AS creator_gravatar_hash,\n\n wt.maybe_last_update_user_token as `maybe_last_update_user_token: tokens::tokens::users::UserToken`,\n wt.original_download_url,\n wt.original_filename,\n wt.file_size_bytes,\n wt.file_checksum_sha2,\n wt.public_bucket_hash,\n wt.maybe_public_bucket_prefix,\n wt.maybe_public_bucket_extension,\n\n cover_image.public_bucket_directory_hash as maybe_cover_image_public_bucket_hash,\n cover_image.maybe_public_bucket_prefix as maybe_cover_image_public_bucket_prefix,\n cover_image.maybe_public_bucket_extension as maybe_cover_image_public_bucket_extension,\n\n entity_stats.ratings_positive_count as maybe_ratings_positive_count,\n entity_stats.ratings_negative_count as maybe_ratings_negative_count,\n entity_stats.bookmark_count as maybe_bookmark_count,\n\n w_extension.ietf_language_tag as maybe_ietf_language_tag,\n w_extension.ietf_primary_language_subtag as maybe_ietf_primary_language_subtag,\n w_extension.maybe_default_pretrained_vocoder as `maybe_default_pretrained_vocoder: crate::column_types::vocoder_type::VocoderType`,\n w_extension.text_pipeline_type as maybe_text_pipeline_type,\n\n wt.version,\n wt.created_at,\n wt.updated_at,\n wt.user_deleted_at,\n wt.mod_deleted_at\n\n FROM model_weights as wt\n JOIN users\n ON users.token = wt.creator_user_token\n LEFT OUTER JOIN media_files as cover_image\n ON cover_image.token = wt.maybe_cover_image_media_file_token\n LEFT OUTER JOIN entity_stats\n ON entity_stats.entity_type = \"model_weight\"\n AND entity_stats.entity_token = wt.token\n\n LEFT OUTER JOIN model_weights_extension_tts_details as w_extension\n ON w_extension.model_weights_token = wt.token\n\n WHERE\n wt.token = ?\n AND wt.user_deleted_at IS NULL\n AND wt.mod_deleted_at IS NULL\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "token: tokens::tokens::model_weights::ModelWeightToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "title",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 2,
"name": "weights_type: enums::by_table::model_weights::weights_types::WeightsType",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 3,
"name": "weights_category: enums::by_table::model_weights::weights_category::WeightsCategory",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 4,
"name": "maybe_description_markdown",
"type_info": {
"type": "Blob",
"flags": "BLOB | BINARY",
"char_set": 224,
"max_size": 262140
}
},
{
"ordinal": 5,
"name": "maybe_description_rendered_html",
"type_info": {
"type": "Blob",
"flags": "BLOB | BINARY",
"char_set": 224,
"max_size": 262140
}
},
{
"ordinal": 6,
"name": "creator_ip_address",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 160
}
},
{
"ordinal": 7,
"name": "creator_set_visibility: enums::common::visibility::Visibility",
"type_info": {
"type": "String",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 8,
"name": "creator_user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 9,
"name": "creator_username",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 10,
"name": "creator_display_name",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 11,
"name": "creator_gravatar_hash",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 12,
"name": "maybe_last_update_user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 13,
"name": "original_download_url",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 2048
}
},
{
"ordinal": 14,
"name": "original_filename",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 15,
"name": "file_size_bytes",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 16,
"name": "file_checksum_sha2",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 256
}
},
{
"ordinal": 17,
"name": "public_bucket_hash",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 18,
"name": "maybe_public_bucket_prefix",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 19,
"name": "maybe_public_bucket_extension",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 20,
"name": "maybe_cover_image_public_bucket_hash",
"type_info": {
"type": "VarString",
"flags": "BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 21,
"name": "maybe_cover_image_public_bucket_prefix",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 22,
"name": "maybe_cover_image_public_bucket_extension",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 23,
"name": "maybe_ratings_positive_count",
"type_info": {
"type": "Long",
"flags": "UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 24,
"name": "maybe_ratings_negative_count",
"type_info": {
"type": "Long",
"flags": "UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 25,
"name": "maybe_bookmark_count",
"type_info": {
"type": "Long",
"flags": "UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 26,
"name": "maybe_ietf_language_tag",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 256
}
},
{
"ordinal": 27,
"name": "maybe_ietf_primary_language_subtag",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 48
}
},
{
"ordinal": 28,
"name": "maybe_default_pretrained_vocoder: crate::column_types::vocoder_type::VocoderType",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 256
}
},
{
"ordinal": 29,
"name": "maybe_text_pipeline_type",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 256
}
},
{
"ordinal": 30,
"name": "version",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 11
}
},
{
"ordinal": 31,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 32,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 33,
"name": "user_deleted_at",
"type_info": {
"type": "Timestamp",
"flags": "BINARY",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 34,
"name": "mod_deleted_at",
"type_info": {
"type": "Timestamp",
"flags": "BINARY",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
true,
true,
false,
false,
false,
false,
false,
false,
true,
true,
true,
false,
false,
false,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
false,
false,
false,
true,
true
]
},
"hash": "a3cf13dd4272af3b8fbcddba1f1ea711e64f57fb114886d60d4ae2937c56841d"
}
@@ -0,0 +1,12 @@
{
"db_name": "MySQL",
"query": "\nUPDATE tts_models\nSET\n maybe_migration_new_model_weights_token = ?\nWHERE token = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 2
},
"nullable": []
},
"hash": "aa7ec1c1e32f773212b264f34173f99db1e515e370c47065f932aaec56f89112"
}
@@ -0,0 +1,91 @@
{
"db_name": "MySQL",
"query": "\n SELECT\n wt.token as `token: tokens::tokens::model_weights::ModelWeightToken`,\n wt.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n wt.weights_category as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n\n wt.creator_user_token as `creator_user_token: tokens::tokens::users::UserToken`,\n wt.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n\n wt.user_deleted_at,\n wt.mod_deleted_at\n\n FROM model_weights as wt\n WHERE\n wt.token = ?\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "token: tokens::tokens::model_weights::ModelWeightToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "weights_type: enums::by_table::model_weights::weights_types::WeightsType",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 2,
"name": "weights_category: enums::by_table::model_weights::weights_category::WeightsCategory",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 3,
"name": "creator_user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 4,
"name": "creator_set_visibility: enums::common::visibility::Visibility",
"type_info": {
"type": "String",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 5,
"name": "user_deleted_at",
"type_info": {
"type": "Timestamp",
"flags": "BINARY",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 6,
"name": "mod_deleted_at",
"type_info": {
"type": "Timestamp",
"flags": "BINARY",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
true,
true
]
},
"hash": "be70e3bd4a946da7bd66a29a94e659b25f40a33ef5973a8ff34bfabe08db4051"
}
@@ -0,0 +1,91 @@
{
"db_name": "MySQL",
"query": "\n SELECT\n wt.token as `token: tokens::tokens::model_weights::ModelWeightToken`,\n wt.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,\n wt.weights_category as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,\n\n wt.creator_user_token as `creator_user_token: tokens::tokens::users::UserToken`,\n wt.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n\n wt.user_deleted_at,\n wt.mod_deleted_at\n\n FROM model_weights as wt\n WHERE\n wt.token = ?\n AND wt.user_deleted_at IS NULL\n AND wt.mod_deleted_at IS NULL\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "token: tokens::tokens::model_weights::ModelWeightToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "weights_type: enums::by_table::model_weights::weights_types::WeightsType",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 2,
"name": "weights_category: enums::by_table::model_weights::weights_category::WeightsCategory",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 3,
"name": "creator_user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 4,
"name": "creator_set_visibility: enums::common::visibility::Visibility",
"type_info": {
"type": "String",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 5,
"name": "user_deleted_at",
"type_info": {
"type": "Timestamp",
"flags": "BINARY",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 6,
"name": "mod_deleted_at",
"type_info": {
"type": "Timestamp",
"flags": "BINARY",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
true,
true
]
},
"hash": "d243270734f48fce2f5072ddbde224abf24858c6484995949c98382aa58840a7"
}
Generated
+37 -17
View File
@@ -1259,6 +1259,24 @@ dependencies = [
"my-workspace-hack",
]
[[package]]
name = "composite_identifiers"
version = "0.0.1"
dependencies = [
"enums",
"my-workspace-hack",
"serde",
"serde_derive",
"serde_json",
"sqlx",
"sqlx-core",
"sqlx-mysql",
"strum",
"tokens",
"toml 0.5.11",
"utoipa",
]
[[package]]
name = "concurrency"
version = "0.0.1"
@@ -2131,6 +2149,7 @@ dependencies = [
"errors",
"log",
"my-workspace-hack",
"regex",
"serde",
"serde_json",
"tokens",
@@ -3052,6 +3071,7 @@ dependencies = [
"chrono",
"cloud_storage",
"collections",
"composite_identifiers",
"concurrency",
"config",
"dotenv",
@@ -3059,11 +3079,13 @@ dependencies = [
"enums",
"errors",
"filesys",
"google_drive_common",
"hashing",
"hostname",
"hyper",
"images",
"jobs_common",
"jsonpath_lib",
"lfu",
"log",
"media",
@@ -3074,7 +3096,6 @@ dependencies = [
"my-workspace-hack",
"mysql_queries",
"once_cell",
"opentelemetry",
"r2d2_redis",
"rand 0.8.5",
"redis_common",
@@ -3206,6 +3227,17 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "jsonpath_lib"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eaa63191d68230cccb81c5aa23abd53ed64d83337cacbb25a7b8c7979523774f"
dependencies = [
"log",
"serde",
"serde_json",
]
[[package]]
name = "jwt"
version = "0.13.0"
@@ -3858,6 +3890,7 @@ dependencies = [
"anyhow",
"buckets",
"chrono",
"composite_identifiers",
"config",
"container_common",
"dotenv",
@@ -4162,22 +4195,6 @@ dependencies = [
"vcpkg",
]
[[package]]
name = "opentelemetry"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e32339a5dc40459130b3bd269e9892439f55b33e772d2a9d402a789baaf4e8a"
dependencies = [
"futures-core",
"futures-sink",
"indexmap",
"js-sys",
"once_cell",
"pin-project-lite",
"thiserror",
"urlencoding",
]
[[package]]
name = "ordered-multimap"
version = "0.4.3"
@@ -5397,6 +5414,7 @@ version = "1.0.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
dependencies = [
"indexmap",
"itoa 1.0.9",
"ryu",
"serde",
@@ -6023,6 +6041,7 @@ dependencies = [
"buckets",
"chrono",
"cloud_storage",
"composite_identifiers",
"config",
"container_common",
"cookies",
@@ -6085,6 +6104,7 @@ dependencies = [
"sha2 0.9.9",
"speculoos",
"sqlx",
"strum",
"symphonia",
"time 0.3.30",
"tokens",
+1
View File
@@ -5,6 +5,7 @@ members = [
# Types: common strongly-typed tokens, ids, payloads, etc.
# Also common cloud buckets and other "strongly typed" configs.
"crates/_types/buckets",
"crates/_types/composite_identifiers",
"crates/_types/enums",
"crates/_types/reusable_types", # TODO(bt, 2022-12-21): Deprecate
"crates/_types/tokens",
+5 -2
View File
@@ -18,6 +18,9 @@ deny = [
"clippy::borrow_as_ptr",
"clippy::borrow_deref_ref",
# Clippy async
"clippy::await_holding_lock",
# Clippy - performance
"clippy::cmp_owned",
"clippy::useless_vec",
@@ -43,12 +46,12 @@ deny = [
"unused_imports", # These are easy to automatically cull
"unused_parens", # Unused parens are ugly
"unused_variables", # Don't leave cruft
#"unused_mut", # Be strict about mutability (TODO)
"unused_mut", # Be strict about mutability
# Possible:
# "clippy::ptr_arg",
# "clippy::too_many_lines" (note: this is configurable)
# "clippy::clone_on_copy", # Don't use clone() on Copy types
]
warn = [
+14
View File
@@ -2,6 +2,20 @@
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Find jobs that are broken for a given user
select id, last_assigned_worker, internal_debugging_failure_reason,created_at
from tts_inference_jobs
where maybe_creator_user_token IN (
select token
from users
where username IN ('knifecat ', 'rewritten_code', 'johnloberger')
)
and attempt_count > 1
and status IN ('complete_failure', 'dead', 'attempt_failed')
and created_at > ( CURDATE() - INTERVAL 5 DAY );
-- Total pending jobs
select count(*)
from tts_inference_jobs
@@ -0,0 +1,5 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
drop table idempotency_tokens;
@@ -0,0 +1,19 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- A form of optimistic locking
CREATE TABLE idempotency_tokens (
-- Not used for anything except replication.
id BIGINT(20) NOT NULL AUTO_INCREMENT,
-- This can be a UUID or any entropic value.
idempotency_value VARCHAR(36) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- INDICES --
PRIMARY KEY (id),
UNIQUE KEY (idempotency_value)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
@@ -0,0 +1,5 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
drop table batch_generations;
@@ -0,0 +1,42 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Batch generations
CREATE TABLE batch_generations (
-- Not used for anything except replication.
id BIGINT(20) NOT NULL AUTO_INCREMENT,
-- The batch token
-- This is **NOT** a unique token.
token VARCHAR(32) NOT NULL,
-- ========== ENTITY LINKAGE ==========
-- The type of record this is attached to
-- Currently supported values:
-- * 'model_weight'
-- * 'media_file'
-- * 'comment'
entity_type VARCHAR(32) NOT NULL,
-- The token for the record.
entity_token VARCHAR(32) NOT NULL,
-- ========== TIMESTAMPS ==========
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-- INDICES --
PRIMARY KEY (id),
UNIQUE KEY (token, entity_type, entity_token),
KEY index_token (token),
KEY index_entity_token (entity_token)
-- NB: Realistically, we probably don't need this index until we have a lot of entity types, and the entity_token
-- entropy is probably sufficient enough as-is.
-- KEY index_entity_type_and_token (entity_type, entity_token),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
@@ -0,0 +1,5 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE media_files DROP COLUMN is_batch_generated;
@@ -0,0 +1,7 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE media_files
ADD COLUMN is_batch_generated BOOLEAN NOT NULL DEFAULT FALSE
AFTER maybe_origin_filename;
@@ -0,0 +1,42 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Batch generations
CREATE TABLE batch_generations (
-- Not used for anything except replication.
id BIGINT(20) NOT NULL AUTO_INCREMENT,
-- The batch token
-- This is **NOT** a unique token.
token VARCHAR(32) NOT NULL,
-- ========== ENTITY LINKAGE ==========
-- The type of record this is attached to
-- Currently supported values:
-- * 'model_weight'
-- * 'media_file'
-- * 'comment'
entity_type VARCHAR(32) NOT NULL,
-- The token for the record.
entity_token VARCHAR(32) NOT NULL,
-- ========== TIMESTAMPS ==========
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-- INDICES --
PRIMARY KEY (id),
UNIQUE KEY (token, entity_type, entity_token),
KEY index_token (token),
KEY index_entity_token (entity_token)
-- NB: Realistically, we probably don't need this index until we have a lot of entity types, and the entity_token
-- entropy is probably sufficient enough as-is.
-- KEY index_entity_type_and_token (entity_type, entity_token),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
@@ -0,0 +1,19 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- A form of optimistic locking
CREATE TABLE idempotency_tokens (
-- Not used for anything except replication.
id BIGINT(20) NOT NULL AUTO_INCREMENT,
-- This can be a UUID or any entropic value.
idempotency_value VARCHAR(36) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- INDICES --
PRIMARY KEY (id),
UNIQUE KEY (idempotency_value)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
+5
View File
@@ -58,6 +58,11 @@ CREATE TABLE media_files (
-- The original filename of the media (if uploaded by a user)
maybe_origin_filename VARCHAR(255) DEFAULT NULL,
-- Whether this media file was generated as part of a batch
-- If so, we can look up the batch in a separate query/call to the `batch_generations` table.
-- We won't hold the batch token in this table since it'll be very sparsely populated.
is_batch_generated BOOLEAN NOT NULL DEFAULT FALSE,
-- ========== METADATA ==========
-- We can store text transcripts, etc. in other tables and refer back via foreign key.
@@ -165,6 +165,7 @@ CREATE TABLE model_weights (
-- INDICES --
PRIMARY KEY (id),
UNIQUE KEY (token),
UNIQUE KEY unique_index_maybe_migration_old_model_token (maybe_migration_old_model_token),
KEY index_weights_type (weights_type),
KEY index_weights_category (weights_category),
@@ -43,6 +43,7 @@ CREATE TABLE tts_models (
has_self_contained_pitch_model BOOLEAN NOT NULL DEFAULT FALSE,
-- NB(2022-07-05): THIS IS NOW MEANINGLESS AND SUPERSEDED BY `TEXT_PIPELINE_TYPE`.
-- NB(2024-01-20): All 8720 records in the database are "basic".
-- NB: DO NOT CHANGE ORDER; APPEND ONLY!
-- How text should be handled.
text_preprocessing_algorithm ENUM(
@@ -26,12 +26,14 @@ impl ModelCategory {
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum ModelType {
VallEx,
StyleTTS2,
}
impl ModelType {
pub fn to_str(&self) -> &'static str {
match self {
ModelType::VallEx => "vallex",
ModelType::StyleTTS2 => "styletts2",
}
}
}
@@ -25,6 +25,11 @@ impl PublicPath for WeightFileBucketPath {}
impl WeightFileBucketPath {
// TODO(bt,2024-01-14): This is temporary standardization. Clean this up.
pub fn generate_for_tt2_model() -> Self {
Self::generate_new(Some("tt2_"), Some(".pt"))
}
// TODO(bt,2023-12-19): This is temporary standardization. Clean this up.
pub fn generate_for_svc_model() -> Self {
Self::generate_new(Some("svc_"), Some(".pt"))
@@ -35,6 +40,11 @@ impl WeightFileBucketPath {
Self::generate_new(Some("rvc_"), Some(".pt"))
}
// TODO(bt,2024-01-15): This is temporary standardization. Clean this up.
pub fn tt2_model_file_from_object_hash(hash: &str) -> Self {
Self::from_object_hash(hash, Some("tt2_"), Some(".pt"))
}
// TODO(bt,2023-12-19): This is temporary standardization. Clean this up.
pub fn svc_model_file_from_object_hash(hash: &str) -> Self {
Self::from_object_hash(hash, Some("svc_"), Some(".pt"))
@@ -0,0 +1,40 @@
[package]
name = "composite_identifiers"
edition = "2018"
version = "0.0.1"
authors = [
"Brandon Thomas <bt@brand.io>",
"Brandon Thomas <echelon@gmail.com>",
]
publish = false
[lib]
name = "composite_identifiers"
path = "src/lib.rs"
[dependencies]
# Internal
enums = { path = "../enums" }
tokens = { path = "../tokens" }
# Workspace hack (faster compile times)
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
# Serialization
serde = "1.0.125"
serde_derive = "1.0.125"
sqlx = { version = "0.7.2", features = [ "mysql", "sqlite", "runtime-tokio-native-tls", "chrono" ] }
sqlx-core = { version = "0.7.2" }
sqlx-mysql= { version = "0.7.2" }
utoipa = { version = "4", features = ["chrono","actix_extras"] }
[dev-dependencies]
# Enum utilities
strum = { version = "0.25", features = ["derive"] }
# Test serialization
serde_json = "1.0.108"
toml = "0.5.8"
@@ -0,0 +1,28 @@
use enums::by_table::batch_generations::batch_generation_entity_type::BatchGenerationEntityType;
use tokens::tokens::media_files::MediaFileToken;
// TODO(bt, 2024-01-16): A ref type with <'a> lifetime of inner data instead of ownership?
pub enum BatchGenerationEntity {
MediaFile(MediaFileToken),
}
// TODO(bt, 2024-01-16): Codegen? Make traits for these? Maybe overkill.
impl BatchGenerationEntity {
pub fn get_entity_type(&self) -> BatchGenerationEntityType {
match self {
Self::MediaFile(_) => BatchGenerationEntityType::MediaFile,
}
}
pub fn get_entity_token_str(&self) -> &str {
match self {
Self::MediaFile(token) => token.as_str(),
}
}
pub fn get_composite_keys(&self) -> (BatchGenerationEntityType, &str) {
match self {
Self::MediaFile(token) => (BatchGenerationEntityType::MediaFile, token.as_str()),
}
}
}
@@ -0,0 +1 @@
pub mod batch_generation_entity;
@@ -0,0 +1 @@
pub mod batch_generations;
@@ -0,0 +1,22 @@
//! composite_identifiers
//!
//! The purpose of this library is to provide easy to construct, **typesafe**, composite identifiers.
//! This is mostly a combination of `tokens` and `enums`.
//!
// Never allow these
#![forbid(private_bounds)]
#![forbid(private_interfaces)]
#![forbid(unused_must_use)] // NB: It's unsafe to not close/check some things
// Okay to toggle
#![forbid(unreachable_patterns)]
#![forbid(unused_imports)]
#![forbid(unused_mut)]
#![forbid(unused_variables)]
// Always allow
#![allow(dead_code)]
#![allow(non_snake_case)]
pub mod by_table;
@@ -0,0 +1,109 @@
use std::collections::BTreeSet;
use serde::Deserialize;
use serde::Serialize;
#[cfg(test)]
use strum::EnumCount;
#[cfg(test)]
use strum::EnumIter;
use utoipa::ToSchema;
/// Used in the `batch_generations` table in a `VARCHAR(32)` field named `entity_type`.
#[cfg_attr(test, derive(EnumIter, EnumCount))]
#[derive(Clone, Copy, Eq, PartialEq, Hash, Deserialize, Serialize, Ord, PartialOrd, ToSchema)]
pub enum BatchGenerationEntityType {
/// Media files
/// This will probably be the only type supported, but we'll leave the possibility of future types.
#[serde(rename = "media_file")]
MediaFile,
}
// TODO(bt, 2023-01-17): This desperately needs MySQL integration tests!
impl_enum_display_and_debug_using_to_str!(BatchGenerationEntityType);
impl_mysql_enum_coders!(BatchGenerationEntityType);
impl_mysql_from_row!(BatchGenerationEntityType);
/// NB: Legacy API for older code.
impl BatchGenerationEntityType {
pub fn to_str(&self) -> &'static str {
match self {
Self::MediaFile => "media_file",
}
}
pub fn from_str(value: &str) -> Result<Self, String> {
match value {
"media_file" => Ok(Self::MediaFile),
_ => Err(format!("invalid value: {:?}", value)),
}
}
pub fn all_variants() -> BTreeSet<Self> {
// NB: BTreeSet is sorted
// NB: BTreeSet::from() isn't const, but not worth using LazyStatic, etc.
BTreeSet::from([
Self::MediaFile,
])
}
}
#[cfg(test)]
mod tests {
use crate::by_table::batch_generations::batch_generation_entity_type::BatchGenerationEntityType;
use crate::test_helpers::assert_serialization;
mod serde {
use super::*;
#[test]
fn test_serialization() {
assert_serialization(BatchGenerationEntityType::MediaFile, "media_file");
}
}
mod impl_methods {
use super::*;
#[test]
fn to_str() {
assert_eq!(BatchGenerationEntityType::MediaFile.to_str(), "media_file");
}
#[test]
fn from_str() {
assert_eq!(BatchGenerationEntityType::from_str("media_file").unwrap(), BatchGenerationEntityType::MediaFile);
assert!(BatchGenerationEntityType::from_str("foo").is_err());
}
}
mod manual_variant_checks {
use super::*;
#[test]
fn all_variants() {
let mut variants = BatchGenerationEntityType::all_variants();
assert_eq!(variants.len(), 1);
assert_eq!(variants.pop_first(), Some(BatchGenerationEntityType::MediaFile));
assert_eq!(variants.pop_first(), None);
}
}
mod mechanical_checks {
use super::*;
#[test]
fn variant_length() {
use strum::IntoEnumIterator;
assert_eq!(BatchGenerationEntityType::all_variants().len(), BatchGenerationEntityType::iter().len());
}
#[test]
fn round_trip() {
for variant in BatchGenerationEntityType::all_variants() {
assert_eq!(variant, BatchGenerationEntityType::from_str(variant.to_str()).unwrap());
assert_eq!(variant, BatchGenerationEntityType::from_str(&format!("{}", variant)).unwrap());
assert_eq!(variant, BatchGenerationEntityType::from_str(&format!("{:?}", variant)).unwrap());
}
}
}
}
@@ -0,0 +1 @@
pub mod batch_generation_entity_type;
@@ -29,8 +29,14 @@ pub enum InferenceCategory {
#[serde(rename = "video_filter")]
VideoFilter,
#[serde(rename = "image_generation")]
ImageGeneration,
#[serde(rename = "mocap")]
Mocap,
#[serde(rename = "workflow")]
Workflow,
}
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
@@ -45,7 +51,9 @@ impl InferenceCategory {
Self::TextToSpeech => "text_to_speech",
Self::VoiceConversion => "voice_conversion",
Self::VideoFilter => "video_filter",
Self::ImageGeneration => "image_generation",
Self::Mocap => "mocap",
Self::Workflow => "workflow",
}
}
@@ -55,7 +63,9 @@ impl InferenceCategory {
"text_to_speech" => Ok(Self::TextToSpeech),
"voice_conversion" => Ok(Self::VoiceConversion),
"video_filter" => Ok(Self::VideoFilter),
"image_generation" => Ok(Self::ImageGeneration),
"mocap" => Ok(Self::Mocap),
"workflow" => Ok(Self::Workflow),
_ => Err(format!("invalid value: {:?}", value)),
}
}
@@ -68,7 +78,9 @@ impl InferenceCategory {
Self::TextToSpeech,
Self::VoiceConversion,
Self::VideoFilter,
Self::ImageGeneration,
Self::Mocap,
Self::Workflow,
])
}
}
@@ -84,7 +96,9 @@ mod tests {
assert_serialization(InferenceCategory::TextToSpeech, "text_to_speech");
assert_serialization(InferenceCategory::VoiceConversion, "voice_conversion");
assert_serialization(InferenceCategory::VideoFilter, "video_filter");
assert_serialization(InferenceCategory::Mocap, "mocap")
assert_serialization(InferenceCategory::ImageGeneration, "image_generation");
assert_serialization(InferenceCategory::Mocap, "mocap");
assert_serialization(InferenceCategory::Workflow, "workflow")
}
#[test]
@@ -93,7 +107,9 @@ mod tests {
assert_eq!(InferenceCategory::TextToSpeech.to_str(), "text_to_speech");
assert_eq!(InferenceCategory::VoiceConversion.to_str(), "voice_conversion");
assert_eq!(InferenceCategory::VideoFilter.to_str(), "video_filter");
assert_eq!(InferenceCategory::ImageGeneration.to_str(), "image_generation");
assert_eq!(InferenceCategory::Mocap.to_str(), "mocap");
assert_eq!(InferenceCategory::Workflow.to_str(), "workflow");
}
#[test]
@@ -102,19 +118,23 @@ mod tests {
assert_eq!(InferenceCategory::from_str("text_to_speech").unwrap(), InferenceCategory::TextToSpeech);
assert_eq!(InferenceCategory::from_str("voice_conversion").unwrap(), InferenceCategory::VoiceConversion);
assert_eq!(InferenceCategory::from_str("video_filter").unwrap(), InferenceCategory::VideoFilter);
assert_eq!(InferenceCategory::from_str("image_generation").unwrap(), InferenceCategory::ImageGeneration);
assert_eq!(InferenceCategory::from_str("mocap").unwrap(), InferenceCategory::Mocap);
assert_eq!(InferenceCategory::from_str("workflow").unwrap(), InferenceCategory::Workflow);
}
#[test]
fn all_variants() {
// Static check
let mut variants = InferenceCategory::all_variants();
assert_eq!(variants.len(), 5);
assert_eq!(variants.len(), 7);
assert_eq!(variants.pop_first(), Some(InferenceCategory::LipsyncAnimation));
assert_eq!(variants.pop_first(), Some(InferenceCategory::TextToSpeech));
assert_eq!(variants.pop_first(), Some(InferenceCategory::VoiceConversion));
assert_eq!(variants.pop_first(), Some(InferenceCategory::VideoFilter));
assert_eq!(variants.pop_first(), Some(InferenceCategory::ImageGeneration));
assert_eq!(variants.pop_first(), Some(InferenceCategory::Mocap));
assert_eq!(variants.pop_first(), Some(InferenceCategory::Workflow));
assert_eq!(variants.pop_first(), None);
// Generated check
@@ -33,8 +33,14 @@ pub enum InferenceModelType {
VallEX,
#[serde(rename = "rerender_a_video")]
RerenderAVideo,
#[serde(rename = "stable_diffusion")]
StableDiffusion,
#[serde(rename = "mocap_net")]
MocapNet,
#[serde(rename = "comfy_ui")]
ComfyUi,
#[serde(rename = "styletts2")]
StyleTTS2,
}
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
@@ -52,7 +58,10 @@ impl InferenceModelType {
Self::Vits => "vits",
Self::VallEX => "vall_e_x",
Self::RerenderAVideo => "rerender_a_video",
Self::StableDiffusion => "stable_diffusion",
Self::MocapNet => "mocap_net",
Self::StyleTTS2 => "styletts2",
Self::ComfyUi => "comfy_ui",
}
}
@@ -65,7 +74,10 @@ impl InferenceModelType {
"vits" => Ok(Self::Vits),
"vall_e_x" => Ok(Self::VallEX),
"rerender_a_video" => Ok(Self::RerenderAVideo),
"stable_diffusion" => Ok(Self::StableDiffusion),
"mocap_net" => Ok(Self::MocapNet),
"styletts2" => Ok(Self::StyleTTS2),
"comfy_ui" => Ok(Self::ComfyUi),
_ => Err(format!("invalid value: {:?}", value)),
}
}
@@ -81,7 +93,10 @@ impl InferenceModelType {
InferenceModelType::Vits,
InferenceModelType::VallEX,
InferenceModelType::RerenderAVideo,
InferenceModelType::StableDiffusion,
InferenceModelType::MocapNet,
InferenceModelType::StyleTTS2,
InferenceModelType::ComfyUi,
])
}
}
@@ -100,7 +115,10 @@ mod tests {
assert_serialization(InferenceModelType::Vits, "vits");
assert_serialization(InferenceModelType::VallEX, "vall_e_x");
assert_serialization(InferenceModelType::RerenderAVideo, "rerender_a_video");
assert_serialization(InferenceModelType::StableDiffusion, "stable_diffusion");
assert_serialization(InferenceModelType::MocapNet, "mocap_net");
assert_serialization(InferenceModelType::ComfyUi, "comfy_ui");
assert_serialization(InferenceModelType::StyleTTS2, "styletts2");
}
#[test]
@@ -112,7 +130,10 @@ mod tests {
assert_eq!(InferenceModelType::Vits.to_str(), "vits");
assert_eq!(InferenceModelType::VallEX.to_str(), "vall_e_x");
assert_eq!(InferenceModelType::RerenderAVideo.to_str(), "rerender_a_video");
assert_eq!(InferenceModelType::StableDiffusion.to_str(), "stable_diffusion");
assert_eq!(InferenceModelType::MocapNet.to_str(), "mocap_net");
assert_eq!(InferenceModelType::StyleTTS2.to_str(), "styletts2");
assert_eq!(InferenceModelType::ComfyUi.to_str(), "comfy_ui");
}
#[test]
@@ -124,14 +145,17 @@ mod tests {
assert_eq!(InferenceModelType::from_str("vits").unwrap(), InferenceModelType::Vits);
assert_eq!(InferenceModelType::from_str("vall_e_x").unwrap(), InferenceModelType::VallEX);
assert_eq!(InferenceModelType::from_str("rerender_a_video").unwrap(), InferenceModelType::RerenderAVideo);
assert_eq!(InferenceModelType::from_str("stable_diffusion").unwrap(), InferenceModelType::StableDiffusion);
assert_eq!(InferenceModelType::from_str("mocap_net").unwrap(), InferenceModelType::MocapNet);
assert_eq!(InferenceModelType::from_str("styletts2").unwrap(), InferenceModelType::StyleTTS2);
assert_eq!(InferenceModelType::from_str("comfy_ui").unwrap(), InferenceModelType::ComfyUi);
}
#[test]
fn all_variants() {
// Static check
let mut variants = InferenceModelType::all_variants();
assert_eq!(variants.len(), 8);
assert_eq!(variants.len(), 11);
assert_eq!(variants.pop_first(), Some(InferenceModelType::RvcV2));
assert_eq!(variants.pop_first(), Some(InferenceModelType::SadTalker));
assert_eq!(variants.pop_first(), Some(InferenceModelType::SoVitsSvc));
@@ -139,7 +163,10 @@ mod tests {
assert_eq!(variants.pop_first(), Some(InferenceModelType::Vits));
assert_eq!(variants.pop_first(), Some(InferenceModelType::VallEX));
assert_eq!(variants.pop_first(), Some(InferenceModelType::RerenderAVideo));
assert_eq!(variants.pop_first(), Some(InferenceModelType::StableDiffusion));
assert_eq!(variants.pop_first(), Some(InferenceModelType::MocapNet));
assert_eq!(variants.pop_first(), Some(InferenceModelType::ComfyUi));
assert_eq!(variants.pop_first(), Some(InferenceModelType::StyleTTS2));
assert_eq!(variants.pop_first(), None);
// Generated check
@@ -29,6 +29,9 @@ pub enum InferenceResultType {
#[serde(rename = "zs_voice_embedding")]
ZeroShotVoiceEmbedding,
#[serde(rename = "upload_model")]
UploadModel
}
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
@@ -43,6 +46,7 @@ impl InferenceResultType {
Self::TextToSpeech => "text_to_speech",
Self::VoiceConversion => "voice_conversion",
Self::ZeroShotVoiceEmbedding => "zs_voice_embedding",
Self::UploadModel => "upload_model",
}
}
@@ -52,6 +56,7 @@ impl InferenceResultType {
"text_to_speech" => Ok(Self::TextToSpeech),
"voice_conversion" => Ok(Self::VoiceConversion),
"zs_voice_embedding" => Ok(Self::ZeroShotVoiceEmbedding),
"upload_model" => Ok(Self::UploadModel),
_ => Err(format!("invalid value: {:?}", value)),
}
}
@@ -64,6 +69,7 @@ impl InferenceResultType {
InferenceResultType::TextToSpeech,
InferenceResultType::VoiceConversion,
InferenceResultType::ZeroShotVoiceEmbedding,
InferenceResultType::UploadModel,
])
}
}
@@ -79,6 +85,7 @@ mod tests {
assert_serialization(InferenceResultType::TextToSpeech, "text_to_speech");
assert_serialization(InferenceResultType::VoiceConversion, "voice_conversion");
assert_serialization(InferenceResultType::ZeroShotVoiceEmbedding, "zs_voice_embedding");
assert_serialization(InferenceResultType::UploadModel, "upload_model");
}
#[test]
@@ -87,6 +94,7 @@ mod tests {
assert_eq!(InferenceResultType::TextToSpeech.to_str(), "text_to_speech");
assert_eq!(InferenceResultType::VoiceConversion.to_str(), "voice_conversion");
assert_eq!(InferenceResultType::ZeroShotVoiceEmbedding.to_str(), "zs_voice_embedding");
assert_eq!(InferenceResultType::UploadModel.to_str(), "upload_model");
}
#[test]
@@ -95,17 +103,19 @@ mod tests {
assert_eq!(InferenceResultType::from_str("text_to_speech").unwrap(), InferenceResultType::TextToSpeech);
assert_eq!(InferenceResultType::from_str("voice_conversion").unwrap(), InferenceResultType::VoiceConversion);
assert_eq!(InferenceResultType::from_str("zs_voice_embedding").unwrap(), InferenceResultType::ZeroShotVoiceEmbedding);
assert_eq!(InferenceResultType::from_str("upload_model").unwrap(), InferenceResultType::UploadModel);
}
#[test]
fn all_variants() {
// Static check
let mut variants = InferenceResultType::all_variants();
assert_eq!(variants.len(), 4);
assert_eq!(variants.len(), 5);
assert_eq!(variants.pop_first(), Some(InferenceResultType::MediaFile));
assert_eq!(variants.pop_first(), Some(InferenceResultType::TextToSpeech));
assert_eq!(variants.pop_first(), Some(InferenceResultType::VoiceConversion));
assert_eq!(variants.pop_first(), Some(InferenceResultType::ZeroShotVoiceEmbedding));
assert_eq!(variants.pop_first(), Some(InferenceResultType::UploadModel));
assert_eq!(variants.pop_first(), None);
// Generated check
@@ -29,6 +29,10 @@ pub enum IdCategory {
#[serde(rename = "mocap")]
MocapResult,
// Results from workflows
#[serde(rename = "workflow")]
WorkflowResult,
/// Results from tacotron2
/// Applies for RVC and SVC
#[serde(rename = "tts_result")]
@@ -78,6 +82,7 @@ impl IdCategory {
Self::ModelWeights => "model_weights",
Self::FileUpload => "file_upload",
Self::MocapResult => "mocap",
Self::WorkflowResult => "workflow",
}
}
@@ -94,6 +99,7 @@ impl IdCategory {
"model_weights" => Ok(Self::ModelWeights),
"file_upload" => Ok(Self::FileUpload),
"mocap" => Ok(Self::MocapResult),
"workflow" => Ok(Self::WorkflowResult),
_ => Err(format!("invalid value: {:?}", value)),
}
}
@@ -113,6 +119,7 @@ impl IdCategory {
Self::ModelWeights,
Self::FileUpload,
Self::MocapResult,
Self::WorkflowResult,
])
}
}
@@ -138,6 +145,7 @@ mod tests {
assert_serialization(IdCategory::ModelWeights, "model_weights");
assert_serialization(IdCategory::FileUpload, "file_upload");
assert_serialization(IdCategory::MocapResult, "mocap");
assert_serialization(IdCategory::WorkflowResult, "workflow");
}
#[test]
@@ -153,6 +161,7 @@ mod tests {
assert_eq!(IdCategory::ModelWeights.to_str(), "model_weights");
assert_eq!(IdCategory::FileUpload.to_str(), "file_upload");
assert_eq!(IdCategory::MocapResult.to_str(), "mocap");
assert_eq!(IdCategory::WorkflowResult.to_str(), "workflow");
}
#[test]
@@ -168,17 +177,19 @@ mod tests {
assert_eq!(IdCategory::from_str("model_weights").unwrap(), IdCategory::ModelWeights);
assert_eq!(IdCategory::from_str("file_upload").unwrap(), IdCategory::FileUpload);
assert_eq!(IdCategory::from_str("mocap").unwrap(), IdCategory::MocapResult);
assert_eq!(IdCategory::from_str("workflow").unwrap(), IdCategory::WorkflowResult);
}
#[test]
fn all_variants() {
// Static check
let mut variants = IdCategory::all_variants();
assert_eq!(variants.len(), 11);
assert_eq!(variants.len(), 12);
assert_eq!(variants.pop_first(), Some(IdCategory::MediaFile));
assert_eq!(variants.pop_first(), Some(IdCategory::LipsyncAnimationResult));
assert_eq!(variants.pop_first(), Some(IdCategory::VideoFilterResult));
assert_eq!(variants.pop_first(), Some(IdCategory::MocapResult));
assert_eq!(variants.pop_first(), Some(IdCategory::WorkflowResult));
assert_eq!(variants.pop_first(), Some(IdCategory::TtsResult));
assert_eq!(variants.pop_first(), Some(IdCategory::VoiceConversionResult));
assert_eq!(variants.pop_first(), Some(IdCategory::ZeroShotTtsResult));
@@ -38,6 +38,15 @@ pub enum MediaFileOriginModelType {
#[serde(rename = "mocap_net")]
MocapNet,
#[serde(rename = "comfy_ui")]
ComfyUi,
#[serde(rename = "styletts2")]
StyleTTS2,
#[serde(rename = "stable_diffusion_1_5")]
StableDiffusion15,
}
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
@@ -56,6 +65,9 @@ impl MediaFileOriginModelType {
Self::VallEX => "vall_e_x",
Self::Rerender => "rerender",
Self::MocapNet => "mocap_net",
Self::ComfyUi => "comfy_ui",
Self::StyleTTS2 => "styletts2",
Self::StableDiffusion15 => "stable_diffusion_1_5"
}
}
@@ -68,6 +80,9 @@ impl MediaFileOriginModelType {
"vall_e_x" => Ok(Self::VallEX),
"rerender" => Ok(Self::Rerender),
"mocap_net" => Ok(Self::MocapNet),
"comfy_ui" => Ok(Self::ComfyUi),
"styletts2" => Ok(Self::StyleTTS2),
"stable_diffusion_1_5" => Ok(Self::StableDiffusion15),
_ => Err(format!("invalid value: {:?}", value)),
}
}
@@ -83,6 +98,9 @@ impl MediaFileOriginModelType {
Self::VallEX,
Self::Rerender,
Self::MocapNet,
Self::ComfyUi,
Self::StyleTTS2,
Self::StableDiffusion15
])
}
}
@@ -109,6 +127,9 @@ mod tests {
assert_eq!(MediaFileOriginModelType::VallEX.to_str(), "vall_e_x");
assert_eq!(MediaFileOriginModelType::Rerender.to_str(), "rerender");
assert_eq!(MediaFileOriginModelType::MocapNet.to_str(), "mocap_net");
assert_eq!(MediaFileOriginModelType::ComfyUi.to_str(), "comfy_ui");
assert_eq!(MediaFileOriginModelType::StyleTTS2.to_str(), "styletts2");
assert_eq!(MediaFileOriginModelType::StableDiffusion15.to_str(), "stable_diffusion_1_5");
}
#[test]
@@ -120,13 +141,16 @@ mod tests {
assert_eq!(MediaFileOriginModelType::from_str("vall_e_x").unwrap(), MediaFileOriginModelType::VallEX);
assert_eq!(MediaFileOriginModelType::from_str("rerender").unwrap(), MediaFileOriginModelType::Rerender);
assert_eq!(MediaFileOriginModelType::from_str("mocap_net").unwrap(), MediaFileOriginModelType::MocapNet);
assert_eq!(MediaFileOriginModelType::from_str("comfy_ui").unwrap(), MediaFileOriginModelType::ComfyUi);
assert_eq!(MediaFileOriginModelType::from_str("styletts2").unwrap(), MediaFileOriginModelType::StyleTTS2);
assert_eq!(MediaFileOriginModelType::from_str("stable_diffusion_1_5").unwrap(), MediaFileOriginModelType::StyleTTS2);
assert!(MediaFileOriginModelType::from_str("foo").is_err());
}
#[test]
fn all_variants() {
let mut variants = MediaFileOriginModelType::all_variants();
assert_eq!(variants.len(), 7);
assert_eq!(variants.len(), 9);
assert_eq!(variants.pop_first(), Some(MediaFileOriginModelType::RvcV2));
assert_eq!(variants.pop_first(), Some(MediaFileOriginModelType::SadTalker));
assert_eq!(variants.pop_first(), Some(MediaFileOriginModelType::SoVitsSvc));
@@ -134,6 +158,9 @@ mod tests {
assert_eq!(variants.pop_first(), Some(MediaFileOriginModelType::VallEX));
assert_eq!(variants.pop_first(), Some(MediaFileOriginModelType::Rerender));
assert_eq!(variants.pop_first(), Some(MediaFileOriginModelType::MocapNet));
assert_eq!(variants.pop_first(), Some(MediaFileOriginModelType::ComfyUi));
assert_eq!(variants.pop_first(), Some(MediaFileOriginModelType::StyleTTS2));
assert_eq!(variants.pop_first(), Some(MediaFileOriginModelType::StableDiffusion15));
assert_eq!(variants.pop_first(), None);
}
}
@@ -46,6 +46,12 @@ pub enum MediaFileOriginProductCategory {
// Mocap
#[serde(rename = "mocap")]
Mocap,
#[serde(rename = "image_gen")]
ImageGeneration,
// Workflow
#[serde(rename = "workflow")]
Workflow,
}
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
@@ -64,6 +70,8 @@ impl MediaFileOriginProductCategory {
Self::ZeroShotVoice => "zs_voice",
Self::VideoFilter => "video_filter",
Self::Mocap => "mocap",
Self::ImageGeneration => "image_gen",
Self::Workflow => "workflow",
}
}
@@ -76,6 +84,8 @@ impl MediaFileOriginProductCategory {
"zs_voice" => Ok(Self::ZeroShotVoice),
"video_filter" => Ok(Self::VideoFilter),
"mocap" => Ok(Self::Mocap),
"image_gen" => Ok(Self::ImageGeneration),
"workflow" => Ok(Self::Workflow),
_ => Err(format!("invalid value: {:?}", value)),
}
}
@@ -91,6 +101,8 @@ impl MediaFileOriginProductCategory {
Self::VoiceConversion,
Self::ZeroShotVoice,
Self::Mocap,
Self::ImageGeneration,
Self::Workflow,
])
}
}
@@ -111,7 +123,9 @@ mod tests {
assert_serialization(MediaFileOriginProductCategory::VoiceConversion, "voice_conversion");
assert_serialization(MediaFileOriginProductCategory::ZeroShotVoice, "zs_voice");
assert_serialization(MediaFileOriginProductCategory::VideoFilter, "video_filter");
assert_serialization(MediaFileOriginProductCategory::Mocap, "mocap")
assert_serialization(MediaFileOriginProductCategory::Mocap, "mocap");
assert_serialization(MediaFileOriginProductCategory::Mocap, "image_gen");
assert_serialization(MediaFileOriginProductCategory::Workflow, "workflow");
}
#[test]
@@ -123,6 +137,8 @@ mod tests {
assert_eq!(MediaFileOriginProductCategory::ZeroShotVoice.to_str(), "zs_voice");
assert_eq!(MediaFileOriginProductCategory::VideoFilter.to_str(), "video_filter");
assert_eq!(MediaFileOriginProductCategory::Mocap.to_str(), "mocap");
assert_eq!(MediaFileOriginProductCategory::ImageGeneration.to_str(), "image_gen");
assert_eq!(MediaFileOriginProductCategory::Workflow.to_str(), "workflow");
}
#[test]
@@ -134,12 +150,14 @@ mod tests {
assert_eq!(MediaFileOriginProductCategory::from_str("zs_voice").unwrap(), MediaFileOriginProductCategory::ZeroShotVoice);
assert_eq!(MediaFileOriginProductCategory::from_str("video_filter").unwrap(), MediaFileOriginProductCategory::VideoFilter);
assert_eq!(MediaFileOriginProductCategory::from_str("mocap").unwrap(), MediaFileOriginProductCategory::Mocap);
assert_eq!(MediaFileOriginProductCategory::from_str("image_gen").unwrap(),MediaFileOriginProductCategory::ImageGeneration);
assert_eq!(MediaFileOriginProductCategory::from_str("workflow").unwrap(), MediaFileOriginProductCategory::Workflow);
}
#[test]
fn all_variants() {
let mut variants = MediaFileOriginProductCategory::all_variants();
assert_eq!(variants.len(), 7);
assert_eq!(variants.len(), 9);
assert_eq!(variants.pop_first(), Some(MediaFileOriginProductCategory::Unknown));
assert_eq!(variants.pop_first(), Some(MediaFileOriginProductCategory::FaceAnimator));
assert_eq!(variants.pop_first(), Some(MediaFileOriginProductCategory::TextToSpeech));
@@ -147,6 +165,8 @@ mod tests {
assert_eq!(variants.pop_first(), Some(MediaFileOriginProductCategory::ZeroShotVoice));
assert_eq!(variants.pop_first(), Some(MediaFileOriginProductCategory::VideoFilter));
assert_eq!(variants.pop_first(), Some(MediaFileOriginProductCategory::Mocap));
assert_eq!(variants.pop_first(), Some(MediaFileOriginProductCategory::ImageGeneration));
assert_eq!(variants.pop_first(), Some(MediaFileOriginProductCategory::Workflow));
assert_eq!(variants.pop_first(), None);
}
}
+2
View File
@@ -1,5 +1,6 @@
// ===== MySql =====
pub mod audit_logs;
pub mod batch_generations;
pub mod comments;
pub mod email_sender_jobs;
pub mod entity_stats;
@@ -17,6 +18,7 @@ pub mod user_ratings;
pub mod voice_conversion_models;
pub mod voice_conversion_results;
pub mod zs_voices;
// ===== Sqlite =====
pub mod tts_render_tasks;
pub mod web_rendition_targets;
@@ -17,6 +17,8 @@ pub enum WeightsCategory {
Vocoder,
#[serde(rename = "voice_conversion")]
VoiceConversion,
#[serde(rename = "workflow_config")]
WorkflowConfig,
}
impl WeightsCategory {
@@ -26,6 +28,7 @@ impl WeightsCategory {
Self::TextToSpeech => "text_to_speech",
Self::Vocoder => "vocoder",
Self::VoiceConversion => "voice_conversion",
Self::WorkflowConfig => "workflow_config",
}
}
@@ -35,6 +38,7 @@ impl WeightsCategory {
"text_to_speech" => Ok(Self::TextToSpeech),
"vocoder" => Ok(Self::Vocoder),
"voice_conversion" => Ok(Self::VoiceConversion),
"workflow_config" => Ok(Self::WorkflowConfig),
_ => Err(format!("invalid value: {:?}", value)),
}
}
@@ -45,6 +49,7 @@ impl WeightsCategory {
Self::TextToSpeech,
Self::Vocoder,
Self::VoiceConversion,
Self::WorkflowConfig,
])
}
}
@@ -62,6 +67,7 @@ mod tests {
assert_eq!(WeightsCategory::TextToSpeech.to_str(), "text_to_speech");
assert_eq!(WeightsCategory::Vocoder.to_str(), "vocoder");
assert_eq!(WeightsCategory::VoiceConversion.to_str(), "voice_conversion");
assert_eq!(WeightsCategory::WorkflowConfig.to_str(), "workflow_config");
}
#[test]
@@ -70,16 +76,18 @@ mod tests {
assert_eq!(WeightsCategory::from_str("text_to_speech").unwrap(), WeightsCategory::TextToSpeech);
assert_eq!(WeightsCategory::from_str("vocoder").unwrap(), WeightsCategory::Vocoder);
assert_eq!(WeightsCategory::from_str("voice_conversion").unwrap(), WeightsCategory::VoiceConversion);
assert_eq!(WeightsCategory::from_str("workflow_config").unwrap(), WeightsCategory::WorkflowConfig);
assert!(WeightsCategory::from_str("invalid").is_err());
}
#[test]
fn test_all_variants() {
let variants = WeightsCategory::all_variants();
assert_eq!(variants.len(), 4);
assert_eq!(variants.len(), 5);
assert!(variants.contains(&WeightsCategory::ImageGeneration));
assert!(variants.contains(&WeightsCategory::TextToSpeech));
assert!(variants.contains(&WeightsCategory::Vocoder));
assert!(variants.contains(&WeightsCategory::VoiceConversion));
assert!(variants.contains(&WeightsCategory::WorkflowConfig));
}
}
@@ -25,6 +25,8 @@ pub enum WeightsType {
LoRA,
#[serde(rename = "vall_e")]
VallE,
#[serde(rename = "comfy_ui")]
ComfyUi,
}
@@ -39,6 +41,7 @@ impl WeightsType {
Self::Tacotron2 => "tt2",
Self::LoRA => "loRA",
Self::VallE => "vall_e",
Self::ComfyUi => "comfy_ui",
}
}
@@ -52,6 +55,7 @@ impl WeightsType {
"tt2" => Ok(Self::Tacotron2),
"loRA" => Ok(Self::LoRA),
"vall_e" => Ok(Self::VallE),
"comfy_ui" => Ok(Self::ComfyUi),
_ => Err(format!("invalid value: {:?}", value)),
}
}
@@ -65,7 +69,8 @@ impl WeightsType {
Self::SoVitsSvc,
Self::Tacotron2,
Self::LoRA,
Self::VallE
Self::VallE,
Self::ComfyUi,
])
}
}
@@ -88,6 +93,7 @@ mod tests {
assert_eq!(WeightsType::Tacotron2.to_str(), "tt2");
assert_eq!(WeightsType::LoRA.to_str(), "loRA");
assert_eq!(WeightsType::VallE.to_str(), "vall_e");
assert_eq!(WeightsType::ComfyUi.to_str(), "comfy_ui");
}
#[test]
@@ -100,13 +106,14 @@ mod tests {
assert_eq!(WeightsType::from_str("tt2").unwrap(), WeightsType::Tacotron2);
assert_eq!(WeightsType::from_str("loRA").unwrap(), WeightsType::LoRA);
assert_eq!(WeightsType::from_str("vall_e").unwrap(), WeightsType::VallE);
assert_eq!(WeightsType::from_str("comfy_ui").unwrap(), WeightsType::ComfyUi);
assert!(WeightsType::from_str("invalid").is_err());
}
#[test]
fn test_all_variants() {
let variants = WeightsType::all_variants();
assert_eq!(variants.len(), 8);
assert_eq!(variants.len(), 9);
assert!(variants.contains(&WeightsType::HifiganTacotron2));
assert!(variants.contains(&WeightsType::RvcV2));
assert!(variants.contains(&WeightsType::StableDiffusion15));
@@ -115,5 +122,6 @@ mod tests {
assert!(variants.contains(&WeightsType::Tacotron2));
assert!(variants.contains(&WeightsType::LoRA));
assert!(variants.contains(&WeightsType::VallE));
assert!(variants.contains(&WeightsType::ComfyUi));
}
}
@@ -16,6 +16,8 @@ pub enum ZsVoiceModelType {
/// TTS-type zero shot models
#[serde(rename = "vall-e-x")]
VallEX,
#[serde(rename = "styletts2")]
StyleTTS2,
}
// TODO(bt, 2023-01-17): This desperately needs MySQL integration tests!
@@ -27,12 +29,14 @@ impl ZsVoiceModelType {
pub fn to_str(&self) -> &'static str {
match self {
Self::VallEX=> "vall-e-x",
Self::StyleTTS2 => "styletts2",
}
}
pub fn from_str(value: &str) -> Result<Self, String> {
match value {
"vall-e-x" => Ok(Self::VallEX),
"styletts2" => Ok(Self::StyleTTS2),
_ => Err(format!("invalid value: {:?}", value)),
}
}
@@ -42,6 +46,7 @@ impl ZsVoiceModelType {
// NB: BTreeSet::from() isn't const, but not worth using LazyStatic, etc.
BTreeSet::from([
Self::VallEX,
Self::StyleTTS2,
])
}
}
@@ -66,11 +71,13 @@ mod tests {
#[test]
fn to_str() {
assert_eq!(ZsVoiceModelType::VallEX.to_str(), "vall-e-x");
assert_eq!(ZsVoiceModelType::StyleTTS2.to_str(), "styletts2");
}
#[test]
fn from_str() {
assert_eq!(ZsVoiceModelType::from_str("vall-e-x").unwrap(), ZsVoiceModelType::VallEX);
assert_eq!(ZsVoiceModelType::from_str("styletts2").unwrap(), ZsVoiceModelType::StyleTTS2);
assert!(ZsVoiceModelType::from_str("foo").is_err());
}
}
@@ -81,8 +88,9 @@ mod tests {
#[test]
fn all_variants() {
let mut variants = ZsVoiceModelType::all_variants();
assert_eq!(variants.len(), 1);
assert_eq!(variants.len(), 2);
assert_eq!(variants.pop_first(), Some(ZsVoiceModelType::VallEX));
assert_eq!(variants.pop_first(), Some(ZsVoiceModelType::StyleTTS2));
assert_eq!(variants.pop_first(), None);
}
}
+9 -1
View File
@@ -24,6 +24,7 @@ use strum::EnumIter;
pub(crate) enum TokenPrefix {
AnonymousVisitorTracking, // AVTs are not stored as primary keys in any table, but an index in many tables.
AuditLog,
BatchGeneration,
Comment,
DownloadJob,
EmailSenderJob,
@@ -90,6 +91,7 @@ impl PrefixGenerator for TokenPrefix {
match self {
Self::AnonymousVisitorTracking => "avt_",
Self::AuditLog => "audit_",
Self::BatchGeneration => "batch_g_",
Self::Comment => "comment_",
Self::DownloadJob => "jdown_", // NB: Previously "JGUP:"
Self::EmailSenderJob => "email_job_",
@@ -297,7 +299,13 @@ mod tests {
#[test]
fn test_all_prefixes_end_with_separator_length_one() {
for prefix in get_all_prefixes().iter().map(|s| *s) {
if prefix == "news_story_" || prefix == "tts_task_" || prefix == "INT_API:" || prefix == "pw_reset_" || prefix == "email_job_" {
if prefix == "news_story_"
|| prefix == "tts_task_"
|| prefix == "INT_API:"
|| prefix == "pw_reset_"
|| prefix == "email_job_"
|| prefix == "batch_g_"
{
// TODO/FIXME: I'm too tired at 5AM to replacen from the left. Make this test valid.
// These tokens are from the AIChatBot sidecar, so asserting their validity is less important.
continue;
@@ -0,0 +1,15 @@
use std::fmt::Debug;
use serde::Deserialize;
use serde::Serialize;
use utoipa::ToSchema;
use crate::prefixes::TokenPrefix;
/// The primary key for Audit Logs.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, sqlx::Type, Debug, Serialize, Deserialize, ToSchema)]
#[sqlx(transparent)]
pub struct BatchGenerationToken(pub String);
impl_string_token!(BatchGenerationToken);
impl_crockford_generator!(BatchGenerationToken, 32usize, TokenPrefix::BatchGeneration, CrockfordLower);
+2 -1
View File
@@ -2,6 +2,7 @@ pub mod anonymous_visitor_tracking;
pub mod api_tokens_external;
pub mod api_tokens_internal;
pub mod audit_logs;
pub mod batch_generations;
pub mod comments;
pub mod email_sender_job_token;
pub mod firehose_entries;
@@ -20,6 +21,7 @@ pub mod tts_results;
pub mod twitch_event_rule;
pub mod twitch_oauth_tokens_grouping;
pub mod twitch_oauth_tokens_internal;
pub mod user_bookmarks;
pub mod user_sessions;
pub mod user_subscriptions;
pub mod users;
@@ -34,4 +36,3 @@ pub mod w2l_templates;
pub mod zs_voice_dataset_samples;
pub mod zs_voice_datasets;
pub mod zs_voices;
pub mod user_bookmarks;
+7 -6
View File
@@ -7,13 +7,12 @@ use errors::AnyhowResult;
use crate::bucket_clients::get_bucket_clients;
use crate::cli_args::parse_cli_args;
use crate::seeding::model_weights::seed_weights; // V1
use crate::seeding::seed_model_weights::seed_weights_files; // V2 v3 will come later on when everything is more conslidated and clear.
use crate::seeding::model_weights::seed_weights;
use crate::seeding::media_files::seed_media_seedtool;
use crate::seeding::seed_media_files::seed_media_files;
use crate::seeding::tts_tacotron2::seed_tts_tacotron2;
use crate::seeding::users::seed_user_accounts;
use crate::seeding::voice_conversion::seed_voice_conversion;
use crate::seeding::zero_shot_tts::seed_zero_shot_tts;
pub mod bucket_clients;
@@ -58,12 +57,14 @@ pub async fn main() -> AnyhowResult<()> {
//seed_zero_shot_tts(&pool, maybe_bucket_clients.as_ref()).await?;
seed_voice_conversion(&pool).await?;
seed_weights(&pool).await?;
seed_media_seedtool(&pool).await?;
seed_tts_tacotron2(&pool, maybe_bucket_clients.as_ref()).await?;
// should seed the weights with a few files for hanashi
seed_weights_files(&pool, maybe_bucket_clients.as_ref()).await?;
info!("Done!");
//seed_weights_files(&pool, maybe_bucket_clients.as_ref()).await?;
//println!("TESTING DOWLOAD");
//test_seed_weights_files().await?;
//info!("Done!");
Ok(())
}
@@ -0,0 +1,56 @@
use log::info;
use sqlx::{MySql, Pool};
use cloud_storage::remote_file_manager::media_descriptor::MediaVideoMp4Descriptor;
use cloud_storage::remote_file_manager::remote_cloud_file_manager::RemoteCloudFileClient;
use enums::by_table::media_files::media_file_type::MediaFileType;
use enums::common::visibility::Visibility;
use mysql_queries::queries::media_files::create::insert_media_file_from_cli_tool::{insert_media_file_from_cli_tool, InsertArgs};
use errors::{anyhow, AnyhowResult};
use mysql_queries::queries::users::user::get_user_token_by_username::get_user_token_by_username;
use storyteller_root::get_seed_tool_data_root;
use tokens::tokens::media_files::MediaFileToken;
use tokens::tokens::users::UserToken;
use crate::seeding::users::HANASHI_USERNAME;
pub async fn seed_test_videos(mysql_pool: &Pool<MySql>, user_token: UserToken) -> AnyhowResult<()> {
let model_weight_token1 = MediaFileToken::generate_for_testing_and_dev_seeding_never_use_in_production_seriously();
let seed_tool_data_root = get_seed_tool_data_root();
let mut media_file_path = seed_tool_data_root.clone();
media_file_path.push("media/video/video-style-transfer/miku.mp4");
let remote_cloud_file_client = RemoteCloudFileClient::get_remote_cloud_file_client().await?;
let video_media_descriptor = Box::new(MediaVideoMp4Descriptor {});
let metadata1 = remote_cloud_file_client.upload_file(video_media_descriptor, media_file_path.as_path().to_str().unwrap()).await?;
let bucket_details = metadata1.bucket_details.as_ref().unwrap().clone();
let media1 = InsertArgs {
pool: &mysql_pool,
maybe_use_apriori_media_token: Some(&model_weight_token1),
media_file_type: MediaFileType::Video,
maybe_mime_type: Some(&*metadata1.mimetype),
file_size_bytes: metadata1.file_size_bytes,
sha256_checksum: &metadata1.sha256_checksum,
maybe_origin_filename: Some("miku.mp4"),
maybe_creator_user_token: Some(&user_token),
creator_set_visibility: Visibility::Public,
public_bucket_directory_hash: &bucket_details.object_hash,
maybe_public_bucket_prefix: Some(&bucket_details.prefix),
maybe_public_bucket_extension: Some(&bucket_details.suffix),
};
let (_media_file_token1, _) = insert_media_file_from_cli_tool(media1).await.unwrap();
Ok(())
}
pub async fn seed_media_seedtool(mysql_pool: &Pool<MySql>) -> AnyhowResult<()> {
info!("Seeding weights...");
let user_token = match get_user_token_by_username(HANASHI_USERNAME, mysql_pool).await? {
None => {
return Err(anyhow!("could not find user hanashi"));
}
Some(token) => token,
};
seed_test_videos(mysql_pool, user_token.clone()).await?;
Ok(())
}
@@ -4,4 +4,5 @@ pub mod tts_tacotron2;
pub mod users;
pub mod voice_conversion;
pub mod zero_shot_tts;
pub mod seed_model_weights;
pub mod seed_model_weights;
pub(crate) mod media_files;
@@ -1,8 +1,12 @@
use std::path::PathBuf;
use std::vec;
use log::info;
use sqlx::{MySql, Pool};
use cloud_storage::remote_file_manager::remote_cloud_bucket_details::RemoteCloudBucketDetails;
use cloud_storage::remote_file_manager::remote_cloud_file_manager::RemoteCloudFileClient;
use cloud_storage::remote_file_manager::weights_descriptor::{WeightsLoRADescriptor, WeightsSD15Descriptor, WeightsWorkflowDescriptor};
use enums::by_table::model_weights::{
weights_category::WeightsCategory,
weights_types::WeightsType,
@@ -11,11 +15,48 @@ use enums::common::visibility::Visibility;
use errors::{anyhow, AnyhowResult};
use mysql_queries::queries::model_weights::create::create_weight::{create_weight, CreateModelWeightsArgs};
use mysql_queries::queries::users::user::get_user_token_by_username::get_user_token_by_username;
use storyteller_root::get_seed_tool_data_root;
use tokens::tokens::model_weights::ModelWeightToken;
use tokens::tokens::users::UserToken;
use crate::seeding::users::HANASHI_USERNAME;
pub async fn test_seed_weights_files() -> AnyhowResult<()> {
let seed_path = PathBuf::from("/storyteller/root/custom-seed-tool-data");
let remote_cloud_file_client = RemoteCloudFileClient::get_remote_cloud_file_client().await;
let remote_cloud_file_client = match remote_cloud_file_client {
Ok(res) => {
res
}
Err(_) => {
return Err(anyhow!("failed to get remote cloud file client"));
}
};
let mut path_dl1 = seed_path.clone();
path_dl1.push("downloads/loRA");
let mut path_dl2 = seed_path.clone();
path_dl2.push("downloads/checkpoint");
let bucket_details1 = RemoteCloudBucketDetails {
object_hash: String::from("apa0ej6es8d3ss2gwtf1cghge35qn9tn"),
prefix: String::from("sd15"),
suffix: String::from("safetensors"),
};
let bucket_details2 = RemoteCloudBucketDetails {
object_hash: String::from("27kz11et18fargyyxbj66ntfn621k9d3"),
prefix: String::from("loRA"),
suffix: String::from("safetensors"),
};
remote_cloud_file_client.download_file(bucket_details1, String::from("./checkpoint")).await?;
remote_cloud_file_client.download_file(bucket_details2, String::from("./loRA")).await?;
Ok(())
}
pub async fn seed_weights_for_paging(mysql_pool: &Pool<MySql>, user_token: UserToken) -> AnyhowResult<()> {
let sd1_5_markdown_description = r#"
# Dragonfruit AI Models Update and Workflow
@@ -105,22 +146,22 @@ pub async fn seed_weights_for_paging(mysql_pool: &Pool<MySql>, user_token: UserT
_ => WeightsType::LoRA
};
let mut model_weight_token;
let mut title;
let mut description;
let mut description_rendered_html;
let mut original_filename;
let mut original_download_url;
let model_weight_token;
let title;
let description;
let description_rendered_html;
let original_filename;
let original_download_url;
let mut _private_bucket_hash:String = "".to_string();
let mut private_bucket_prefix;
let mut private_bucket_extension;
let _private_bucket_hash = "".to_string();
let private_bucket_prefix;
let private_bucket_extension;
//let mut cached_user_ratings_total_count;
//let mut cached_user_ratings_positive_count;
//let mut cached_user_ratings_negative_count;
//let mut cached_user_ratings_ratio;
let mut version;
let version;
match i {
1..=20 => {
@@ -330,6 +371,382 @@ pub async fn seed_weights_for_paging(mysql_pool: &Pool<MySql>, user_token: UserT
}
Ok(())
}
pub async fn seed_weights_for_testing_inference(mysql_pool: &Pool<MySql>, user_token: UserToken) -> AnyhowResult<()>{
let miyhoyo_description = r#"一个面向米哈游角色的模型合集~A collection for MIHOYO Characters~
对应人物tag记录在版本信息里,可在右侧“About this version”选项中查看。The corresponding character prompts are recorded in the version information and can be viewed in the About this version option on the right.
打开目录寻找最爱~(附带链接,点击直达)~Open the catalog, find your favorites~ (with links, click to go directly):
崩坏三 Honkai Impact 3rd:
梅比乌斯- Mobius
琪亚娜-Kiana:琪亚娜 合集-Collections for Kiana (Honkai Impact 3rd)
布洛妮娅-bronya:布洛妮娅 合集-Collections for Bronya (Honkai Impact 3rd | Honkai Star Rail)
芽衣:雷电芽衣 合集-Collections for Raiden Mei (Honkai Impact 3rd)
西琳-Sirin
魔法少女-Miracle ☆ Magical Girl
赤鸢-Jingwei
丹朱苍玄-Nuwa/Fuxi
李素裳-Li Sushang
玉骑士·月痕/锦岁玉团-Jade Knight/Auspicious Dazzle
卡莲-kallen
第六夜想曲-Sixth Serenade
符华-Fu hua
崩落
云墨丹心-Azure Empyrea
八重樱-Yae Sakura
逆神巫女-Gyakushinn Miko
御神装·勿忘-Goushinnso Memento
信花舞伎-Blooming Maiko
希尔-Seele
生死律者-Herrscher of Rebirth
栖于永夜-Eternal Night's Embrace
德莉莎-Theresa:德莉莎 合集-Collections for Theresa (Honkai Impact 3rd)
月下誓约-Lunar Vow: Crimson Love
月下初拥-Luna Kindred
花裳月纱-Rosy Bridesmaid
格蕾修-Griseo
繁星·绘世之卷-Starry Impression
天行·绘星之卷-Cosmic Expression
画中的童话-Maroon Riding Hood
原神 Genshin:
凝光-Ningguang
申鹤-Shenhe
妮露
诺艾尔
神里绫华(包含礼装)
甘雨(包含喜茶联动礼装)-Ganyu
胡桃(包含森罗联动礼装)-Hutao
琳妮特-Lynette
绮良良-Kirara
坎蒂丝-Candace
芙宁娜-Furina
芙宁娜/芙卡洛斯-Furina/Focalors
克洛琳德-Clorinde
娜维娅-Navia
丝柯克-Skirk
夏洛蒂-Charlotte
归终-Guizhong
闲云-Xianyun
千织-Chiori
夏沃蕾-Chevreuse
崩坏:星穹铁道 Honkai Star Rand:
驭空-Yukong
银狼-Silver Wolf
符玄-Fu Xuan
李素裳-Sushang
三月七(礼装)-March 7th (New Outfit)
停云-Tingyun
青雀-Qingque
布洛妮娅·兰德-Bronya Rand
镜流-Jingliu
卡芙卡-Kafka
托帕-Topaz
桂乃芬-Guinaifen
玲可-Lynx
佩拉-Peia
寒鸦-Hanya
藿藿-Huohuo
阮·梅-Ruan Mei
雪衣-Xueyi
希露瓦-Serval
绝区零 Zenless-zone-zero:
星见雅-Miyabi
猫宫又奈-Nekomata
艾莲·乔-Ellen
妮可-Nicole
苍角-Soukaku
格莉丝-Grace
珂蕾妲-koleda
可琳-Corin
其他 Others:
鹿鸣-Luming
"""#;
let sd1_5_markdown_description = r#"
00025-2161235528-1girl,(orange_hair_1.1),(zentangle, mandala, tangle, entangle_0.6),(fractal art),the most beautiful form of chaos,brutalist desi.png
00010-1626070972-elf portrait,enchanting beauty,fantasy,ethereal glow,pointed ears,delicate facial features,long elegant hair,nature-themed attir.png
00001-301370162-girl in a snowy landscape,winter coat,fluffy hood,white fur trim,breath visible in cold air,soft falling snowflakes,glistening s.png
00002-3996269517-venomous sorcerer,ominous dark robes,glowing green eyes,holding a staff with a serpent design,mystical green flames,poisonous mi.png
00003-3817469732-Thunder Deity,immense power,hovering above the sea,stormy ocean waves below,crackling lightning in fingertips,dramatic stormy cl.png
if you want to remake my front image, check this out: Lightflow | SD webUI Extension - workflow restore & save in one click - majicMIXfantasy example | Stable Diffusion Other | Civitai
v3 is here. Shouldn't be difficult to use. Simple and complex prompts can be used, unleash your imagination.
v3来了,简单复杂的提示词都可以用。
I developed the v3 version towards 2D in order to make more room for 2.5D models like majicmix lux.
v3版本我往2D发展是为了给majicmix lux等2.5D模型让出更多空间。
merged from融了:
Jack Of All by GeneratedJudge
AWPainting by DynamicWang
majicMIX fantasy v2 =
Noosphere by skumerz + dalcefoPainting + 饭特稀V08 by zhazhahui345 + GhostMix
"#;
let sd_vae_description = r"This is an earlier version of a stable VAE. Compared to other VAEs, it has a higher level of stability. I am not the creator, but I could not find this VAE on the website, so I am sharing it here.
这是较早时候的稳定VAE,与其他VAE相比具有较高的稳定性,不容易坏图。我不是作者,但是站里没找着所以搬运。#";
info!("Seeding weights for inference...");
ModelWeightToken::reset_rng_for_testing_and_dev_seeding_never_use_in_production_seriously(54321);
let model_weight_token1 = ModelWeightToken::generate_for_testing_and_dev_seeding_never_use_in_production_seriously();
let model_weight_token2 = ModelWeightToken::generate_for_testing_and_dev_seeding_never_use_in_production_seriously();
let model_weight_token3 = ModelWeightToken::generate_for_testing_and_dev_seeding_never_use_in_production_seriously();
let remote_cloud_file_client = RemoteCloudFileClient::get_remote_cloud_file_client().await?;
let sd_15_weights_descriptor = Box::new(WeightsSD15Descriptor {});
let lora_descriptor = Box::new(WeightsLoRADescriptor{});
let sd_vae_15_weights_descriptor = Box::new(WeightsSD15Descriptor {});
let mut path_object_SD = get_seed_tool_data_root();
path_object_SD.push("models/imagegen/sd15/majicmixFantasy_v30Vae.safetensors");
let mut path_object_loRA = get_seed_tool_data_root();
path_object_loRA.push("models/imagegen/loRA/xiawolei-v100-000019.safetensors");
let mut path_to_VAE = get_seed_tool_data_root();
path_to_VAE.push("models/imagegen/vae/zVae_v20.safetensors");
let metadata1 = remote_cloud_file_client.upload_file(sd_15_weights_descriptor,path_object_SD.as_path().to_str().unwrap()).await?;
let metadata2 = remote_cloud_file_client.upload_file(lora_descriptor,path_object_loRA.as_path().to_str().unwrap()).await?;
let metadata3 = remote_cloud_file_client.upload_file(sd_vae_15_weights_descriptor,path_to_VAE.as_path().to_str().unwrap()).await?;
let weights1 = CreateModelWeightsArgs {
token: &model_weight_token1, // replace with actual ModelWeightToken
weights_type: WeightsType::StableDiffusion15, // replace with actual WeightsType
weights_category: WeightsCategory::ImageGeneration, // replace with actual WeightsCategory
title: "Dragonfruit".to_string(),
maybe_description_markdown: Some(sd1_5_markdown_description.to_string()),
maybe_description_rendered_html: Some("<p>Description</p>".to_string()),
creator_user_token: Some(&user_token), // replace with actual UserToken
creator_ip_address: "192.168.1.1",
creator_set_visibility: Visibility::Public,
maybe_last_update_user_token: Some("Last Update User Token".to_string()),
original_download_url: Some("https://civitai.com/models/41865/majicmix-fantasy".to_string()),
original_filename: Some("majicmixFantasy_v30Vae.safetensors".to_string()),
file_size_bytes: metadata1.file_size_bytes as i32,
file_checksum_sha2: metadata1.sha256_checksum.to_string(),
public_bucket_hash: metadata1.bucket_details.clone().unwrap().object_hash,
maybe_public_bucket_prefix: Some(metadata1.bucket_details.clone().unwrap().prefix),
maybe_public_bucket_extension: Some(metadata1.bucket_details.clone().unwrap().suffix),
version: 1,
mysql_pool: &mysql_pool, // replace with actual MySqlPool
};
let weights2 = CreateModelWeightsArgs {
token: &model_weight_token2, // replace with actual ModelWeightToken
weights_type: WeightsType::LoRA, // replace with actual WeightsType
weights_category: WeightsCategory::ImageGeneration, // replace with actual WeightsCategory
title: "MIHOYO Collection 米家全家桶 (Honkai Impact 3rd | Honkai Star Rail | Genshin Impact | Zenless Zone Zero)".to_string(),
maybe_description_markdown: Some(miyhoyo_description.to_string()),
maybe_description_rendered_html: Some(miyhoyo_description.to_string()),
creator_user_token: Some(&user_token), // replace with actual UserToken
creator_ip_address: "292.268.2.2",
creator_set_visibility: Visibility::Public,
maybe_last_update_user_token: Some("<p> Honkai <p>".to_string()),
original_download_url: Some("https://civitai.com/models/95243/mihoyo-collection-honkai-impact-3rd-or-honkai-star-rail-or-genshin-impact-or-zenless-zone-zero".to_string()),
original_filename: Some("xiawolei-v100-000019.safetensors".to_string()),
file_size_bytes: metadata2.file_size_bytes as i32,
file_checksum_sha2: metadata2.sha256_checksum.to_string(),
public_bucket_hash: metadata2.bucket_details.clone().unwrap().object_hash.clone(),
maybe_public_bucket_prefix: Some(metadata2.bucket_details.clone().unwrap().prefix),
maybe_public_bucket_extension: Some(metadata2.bucket_details.clone().unwrap().suffix),
version: 2,
mysql_pool: &mysql_pool, // replace with actual MySqlPool
};
let weights3 = CreateModelWeightsArgs {
token: &model_weight_token3, // replace with actual ModelWeightToken
weights_type: WeightsType::StableDiffusion15, // replace with actual WeightsType
weights_category: WeightsCategory::ImageGeneration, // replace with actual WeightsCategory
title: "z-vae".to_string(),
maybe_description_markdown: Some(sd_vae_description.to_string()),
maybe_description_rendered_html: Some("<p>Description</p>".to_string()),
creator_user_token: Some(&user_token), // replace with actual UserToken
creator_ip_address: "192.168.1.1",
creator_set_visibility: Visibility::Public,
maybe_last_update_user_token: Some("Last Update User Token".to_string()),
original_download_url: Some("https://civitai.com/models/97653/z-vae".to_string()),
original_filename: Some("zVae_v20.safetensors".to_string()),
file_size_bytes: metadata3.file_size_bytes as i32,
file_checksum_sha2: metadata3.sha256_checksum.to_string(),
public_bucket_hash: metadata3.bucket_details.clone().unwrap().object_hash,
maybe_public_bucket_prefix: Some(metadata3.bucket_details.clone().unwrap().prefix),
maybe_public_bucket_extension: Some(metadata3.bucket_details.clone().unwrap().suffix),
version: 1,
mysql_pool: &mysql_pool, // replace with actual MySqlPool
};
create_weight(weights1).await?;
create_weight(weights2).await?;
create_weight(weights3).await?;
Ok(())
}
pub async fn seed_workflows_for_testing_inference(mysql_pool: &Pool<MySql>, user_token: UserToken) -> AnyhowResult<()>{
let model_weight_token1 = ModelWeightToken::generate_for_testing_and_dev_seeding_never_use_in_production_seriously();
let model_weight_token2 = ModelWeightToken::generate_for_testing_and_dev_seeding_never_use_in_production_seriously();
let mut path_to_comfy = get_seed_tool_data_root();
path_to_comfy.push("models/workflows/comfyui/workflow_api.json");
let remote_cloud_file_client = RemoteCloudFileClient::get_remote_cloud_file_client().await?;
let comfy_weights_descriptor = Box::new(WeightsWorkflowDescriptor {});
let metadata1 = remote_cloud_file_client.upload_file(comfy_weights_descriptor, path_to_comfy.as_path().to_str().unwrap()).await?;
let mut path_to_comfy2 = get_seed_tool_data_root();
path_to_comfy2.push("models/workflows/comfyui/majicmixRealistic_v7.safetensors");
let comfy_weights_descriptor2 = Box::new(WeightsSD15Descriptor {});
let metadata2 = remote_cloud_file_client.upload_file(comfy_weights_descriptor2, path_to_comfy2.as_path().to_str().unwrap()).await?;
let weights1 = CreateModelWeightsArgs {
token: &model_weight_token1, // replace with actual ModelWeightToken
weights_type: WeightsType::ComfyUi, // replace with actual WeightsType
weights_category: WeightsCategory::WorkflowConfig, // replace with actual WeightsCategory
title: "comfy-test-workflow".to_string(),
maybe_description_markdown: Some("Test workflow for ComfyUI".to_string()),
maybe_description_rendered_html: Some("<p>Description</p>".to_string()),
creator_user_token: Some(&user_token), // replace with actual UserToken
creator_ip_address: "192.168.1.1",
creator_set_visibility: Visibility::Public,
maybe_last_update_user_token: Some("Last Update User Token".to_string()),
original_download_url: Some("https://github.com/comfyanonymous/ComfyUI".to_string()),
original_filename: Some("test-workflow.json".to_string()),
file_size_bytes: metadata1.file_size_bytes as i32,
file_checksum_sha2: metadata1.sha256_checksum.to_string(),
public_bucket_hash: metadata1.bucket_details.clone().unwrap().object_hash,
maybe_public_bucket_prefix: Some(metadata1.bucket_details.clone().unwrap().prefix),
maybe_public_bucket_extension: Some(metadata1.bucket_details.clone().unwrap().suffix),
version: 1,
mysql_pool: &mysql_pool, // replace with actual MySqlPool
};
let weights2 = CreateModelWeightsArgs {
token: &model_weight_token2, // replace with actual ModelWeightToken
weights_type: WeightsType::ComfyUi, // replace with actual WeightsType
weights_category: WeightsCategory::WorkflowConfig, // replace with actual WeightsCategory
title: "v1-5-pruned-emaonly".to_string(),
maybe_description_markdown: Some("Test model for ComfyUI".to_string()),
maybe_description_rendered_html: Some("<p>Description</p>".to_string()),
creator_user_token: Some(&user_token), // replace with actual UserToken
creator_ip_address: "192.168.1.1",
creator_set_visibility: Visibility::Public,
maybe_last_update_user_token: Some("Last Update User Token".to_string()),
original_download_url: Some("https://huggingface.co/runwayml/stable-diffusion-v1-5".to_string()),
original_filename: Some("v1-5-pruned-emaonly.ckpt".to_string()),
file_size_bytes: metadata2.file_size_bytes as i32,
file_checksum_sha2: metadata2.sha256_checksum.to_string(),
public_bucket_hash: metadata2.bucket_details.clone().unwrap().object_hash,
maybe_public_bucket_prefix: Some(metadata2.bucket_details.clone().unwrap().prefix),
maybe_public_bucket_extension: Some(metadata2.bucket_details.clone().unwrap().suffix),
version: 1,
mysql_pool: &mysql_pool, // replace with actual MySqlPool
};
create_weight(weights1).await?;
create_weight(weights2).await?;
Ok(())
}
pub async fn seed_weights_for_user_token(
mysql_pool: &Pool<MySql>,
user_token: UserToken
@@ -630,6 +1047,7 @@ pub async fn original_seed_weights(mysql_pool: &Pool<MySql>, _user_token: UserTo
Ok(())
}
pub async fn seed_weights(mysql_pool: &Pool<MySql>) -> AnyhowResult<()> {
info!("Seeding weights...");
@@ -640,9 +1058,12 @@ pub async fn seed_weights(mysql_pool: &Pool<MySql>) -> AnyhowResult<()> {
Some(token) => token,
};
//original_seed_weights(mysql_pool,user_token).await?;
//seed_weights_for_user_token(mysql_pool, user_token).await?;
seed_weights_for_paging(mysql_pool,user_token).await?;
// original_seed_weights(mysql_pool,user_token).await?;
// seed_weights_for_user_token(mysql_pool, user_token).await?;
// seed_weights_for_paging(mysql_pool,user_token).await?;
seed_weights_for_testing_inference(mysql_pool,user_token.clone()).await?;
println!("TESTING DOWLOAD");
test_seed_weights_files().await?;
seed_workflows_for_testing_inference(mysql_pool,user_token.clone()).await?;
Ok(())
}
@@ -226,3 +226,5 @@ async fn seed_file_to_bucket(
maybe_bucket_extension: maybe_bucket_extension.map(|s| s.to_string()),
})
}
+4 -4
View File
@@ -64,10 +64,10 @@ pub async fn main() -> AnyhowResult<()> {
let bytes = file_read_bytes(args.file_path)?;
let mimetype = get_mimetype_for_bytes(&bytes);
let mut media_file_type;
let mut maybe_mime_type;
let mut maybe_public_bucket_prefix;
let mut maybe_public_bucket_extension;
let media_file_type;
let maybe_mime_type;
let maybe_public_bucket_prefix;
let maybe_public_bucket_extension;
match mimetype {
Some("audio/wav") |
+4 -2
View File
@@ -14,6 +14,7 @@ use sqlx::mysql::MySqlPoolOptions;
use config::shared_constants::DEFAULT_RUST_LOG;
use elasticsearch_schema::searches::search_model_weights::search_model_weights;
use elasticsearch_schema::searches::search_tts_models::search_tts_models;
use enums::by_table::model_weights::weights_types::WeightsType;
use errors::AnyhowResult;
use crate::cli_args::{Action, Environment, parse_cli_args};
@@ -55,9 +56,10 @@ pub async fn main() -> AnyhowResult<()> {
}
Action::SearchModelWeights => {
info!("Searching model weights...");
let results = search_model_weights(&elasticsearch, "zel", Some("en")).await?;
//let results = search_model_weights(&elasticsearch, "zel", Some("en"), Some(WeightsType::SoVitsSvc)).await?;
let results = search_model_weights(&elasticsearch, "zel", None, Some(WeightsType::RvcV2), None).await?;
for result in results {
println!("Result: {:?}", result);
println!("Result: {:#?}", result);
}
}
}
+47
View File
@@ -0,0 +1,47 @@
use std::str::FromStr;
use clap::Parser;
use strum::{EnumCount, EnumString, IntoEnumIterator};
use strum::EnumIter;
use errors::{anyhow, AnyhowResult};
pub struct ParsedArgs {
pub action: Action,
}
#[derive(Clone, Copy, Debug, EnumIter, EnumCount, EnumString, strum::Display)]
#[strum(serialize_all = "snake_case")]
pub enum Action {
/// Migrate VC
MigrateVoiceConversion,
/// Migrate TTS
MigrateTts,
}
#[derive(Parser, Debug)]
#[command(name="migration-tool")]
pub struct Args {
#[arg(name="action", long="action", help="action to take", required=true)]
action: String,
}
pub fn parse_cli_args() -> AnyhowResult<ParsedArgs> {
let args = Args::parse();
Ok(ParsedArgs {
action: action_from_str(&args.action)?,
})
}
fn action_from_str(value: &str) -> AnyhowResult<Action> {
let action = Action::from_str(value)
.map_err(|err| {
let choices = Action::iter()
.map(|e| e.to_string())
.collect::<Vec<_>>();
anyhow!("parse error: {:?}, provided: \"{}\" choices: {:?}", err, value, choices)
})?;
Ok(action)
}
+16 -2
View File
@@ -5,17 +5,21 @@
use std::time::Duration;
use log::info;
use sqlx::{MySql, Pool};
use sqlx::mysql::MySqlPoolOptions;
use cloud_storage::bucket_client::BucketClient;
use cloud_storage::bucket_client::BucketClient;
use config::shared_constants::DEFAULT_RUST_LOG;
use errors::AnyhowResult;
use crate::cli_args::{Action, parse_cli_args};
use crate::deps::Deps;
use crate::migrations::tts_models_to_weights::migrate::migrate_tts_to_weights;
use crate::migrations::voice_conversion_to_weights::migrate::migrate_voice_conversion_to_weights;
pub mod cli_args;
pub mod deps;
pub mod migrations;
@@ -40,10 +44,20 @@ pub async fn main() -> AnyhowResult<()> {
bucket_production_private: get_bucket_client("PRODUCTION_PRIVATE")?,
};
migrate_voice_conversion_to_weights(&deps).await?;
let args = parse_cli_args()?;
match args.action {
Action::MigrateVoiceConversion => {
migrate_voice_conversion_to_weights(&deps).await?;
}
Action::MigrateTts => {
migrate_tts_to_weights(&deps).await?;
}
}
Ok(())
}
async fn get_mysql(env_var_name: &str) -> AnyhowResult<Pool<MySql>> {
info!("Connecting to MySQL {env_var_name}...");
@@ -1 +1,2 @@
pub mod tts_models_to_weights;
pub mod voice_conversion_to_weights;
@@ -0,0 +1,47 @@
use tempdir::TempDir;
use buckets::public::weight_files::bucket_file_path::WeightFileBucketPath;
use cloud_storage::bucket_path_unifier::BucketPathUnifier;
use errors::AnyhowResult;
use filesys::safe_delete_temp_directory::safe_delete_temp_directory;
use filesys::safe_delete_temp_file::safe_delete_temp_file;
use hashing::sha256::sha256_hash_file::sha256_hash_file;
use mysql_queries::queries::model_weights::migration::upsert_model_weight_from_tts_model::CopiedTtsFileData;
use mysql_queries::queries::tts::tts_models::migration::list_whole_tts_models_using_cursor::WholeTtsModelRecord;
use crate::deps::Deps;
pub async fn copy_cloud_files(model: &WholeTtsModelRecord, deps: &Deps) -> AnyhowResult<CopiedTtsFileData> {
let copied_file_data = copy_model(model, deps).await?;
Ok(copied_file_data)
}
async fn copy_model(model: &WholeTtsModelRecord, deps: &Deps) -> AnyhowResult<CopiedTtsFileData> {
let bucket_path_unifier = BucketPathUnifier::default_paths();
let old_model_bucket_path = bucket_path_unifier.tts_synthesizer_path(&model.private_bucket_hash);
// TODO(bt,2023-12-19): Probably faster to stream between buckets, but whatever.
let temp_dir = TempDir::new("model_transfer")?;
let model_temp_fs_path = temp_dir.path().join("model.bin");
deps.bucket_production_private.download_file_to_disk(&old_model_bucket_path, &model_temp_fs_path).await?;
let file_checksum = sha256_hash_file(&model_temp_fs_path)?;
let new_model_bucket_path = WeightFileBucketPath::generate_for_tt2_model();
deps.bucket_production_public.upload_filename_with_content_type(
&new_model_bucket_path.get_full_object_path_str(),
&model_temp_fs_path,
"application/octet-stream").await?;
safe_delete_temp_file(&model_temp_fs_path);
safe_delete_temp_directory(&temp_dir);
Ok(CopiedTtsFileData {
bucket_path: new_model_bucket_path,
file_sha_hash: file_checksum,
})
}
@@ -0,0 +1,95 @@
use std::thread;
use std::time::Duration;
use log::{info, warn};
use buckets::public::weight_files::bucket_file_path::WeightFileBucketPath;
use enums::by_table::model_weights::weights_types::WeightsType;
use errors::AnyhowResult;
use mysql_queries::queries::model_weights::get::get_weight::get_weight_by_token;
use mysql_queries::queries::model_weights::migration::upsert_model_weight_from_tts_model::{CopiedTtsFileData, upsert_model_weight_from_tts_model};
use mysql_queries::queries::tts::tts_models::migration::list_whole_tts_models_using_cursor::{list_whole_tts_models_using_cursor, WholeTtsModelRecord};
use tokens::tokens::model_weights::ModelWeightToken;
use crate::deps::Deps;
use crate::migrations::tts_models_to_weights::copy_cloud_files::copy_cloud_files;
const PAGE_SIZE: u64 = 10;
// TODO(bt,2024-01-15): This hasn't been fully vetted / tested. Do not run until it's combed over.
pub async fn migrate_tts_to_weights(deps: &Deps) -> AnyhowResult<()> {
let mut cursor = 0;
let mut counter = 0;
loop {
info!("Querying {PAGE_SIZE} models at cursor = {cursor}");
let results
= list_whole_tts_models_using_cursor(&deps.mysql_production, PAGE_SIZE, cursor).await?;
if results.is_empty() {
warn!("No more results found; exiting.");
break;
}
for result in results.iter() {
println!("\n\nmigrating over (counter: {counter}, id: {}, token: {:?}) : {:?} ...", result.id, result.token, result);
copy_model_record_and_bucket_files(result, &deps).await?;
counter += 1;
}
if let Some(last_id) = results.last().map(|result| result.id) {
cursor = last_id as u64;
}
thread::sleep(Duration::from_millis(500));
}
Ok(())
}
async fn copy_model_record_and_bucket_files(record: &WholeTtsModelRecord, deps: &Deps) -> AnyhowResult<()> {
let mut maybe_copied_data = None;
match &record.maybe_migration_new_model_weights_token {
None => {
info!("Copying bucket files for record {:?} ...", record.token);
let result = copy_cloud_files(record, &deps).await?;
maybe_copied_data = Some(result);
}
Some(token) => {
info!("Existing migrated record; skipping cloud bucket copy...");
maybe_copied_data = lookup_bucket_details_from_record(token, &deps).await?;
}
}
if let Some(copied_data) = &maybe_copied_data {
info!("Upserting records...");
upsert_model_weight_from_tts_model(record, &deps.mysql_production, copied_data).await?;
}
Ok(())
}
/// Look up the bucket storage details from a previously-migrated record
async fn lookup_bucket_details_from_record(model_weight_token: &ModelWeightToken, deps: &Deps) -> AnyhowResult<Option<CopiedTtsFileData>> {
let maybe_model_weight_record =
get_weight_by_token(model_weight_token, true, &deps.mysql_production).await?;
let model_weight_record = match maybe_model_weight_record {
None => return Ok(None),
Some(record) => record,
};
let bucket_path = match model_weight_record.weights_type {
WeightsType::Tacotron2 => WeightFileBucketPath::tt2_model_file_from_object_hash(&model_weight_record.public_bucket_hash),
_ => return Ok(None), // NB: SVC, RVC, Stable Diffusion, etc. aren't valid for TTS migration
};
Ok(Some(CopiedTtsFileData {
bucket_path,
file_sha_hash: model_weight_record.file_checksum_sha2,
}))
}
@@ -0,0 +1,2 @@
pub mod copy_cloud_files;
pub mod migrate;
@@ -6,7 +6,7 @@ use log::{info, warn};
use buckets::public::weight_files::bucket_file_path::WeightFileBucketPath;
use enums::by_table::model_weights::weights_types::WeightsType;
use errors::AnyhowResult;
use mysql_queries::queries::model_weights::get_weight::get_weight_by_token;
use mysql_queries::queries::model_weights::get::get_weight::get_weight_by_token;
use mysql_queries::queries::model_weights::migration::upsert_model_weight_from_voice_conversion_model::{CopiedFileData, upsert_model_weight_from_voice_conversion_model};
use mysql_queries::queries::voice_conversion::migration::list_whole_voice_conversion_models_using_cursor::{list_whole_voice_conversion_models_using_cursor, WholeVoiceConversionModelRecord};
use tokens::tokens::model_weights::ModelWeightToken;
@@ -19,7 +19,6 @@ pub trait BucketOrchestrationCore {
bytes: &[u8],
content_type: &str,
is_public: bool) -> AnyhowResult<()>;
}
@@ -1,6 +1,9 @@
use crate::remote_file_manager::remote_cloud_bucket_details::RemoteCloudBucketDetails;
#[derive(Debug, Clone)]
pub struct FileMetaData {
pub file_size_bytes: u64,
pub sha256_checksum: String,
pub mimetype: String
pub mimetype: String,
pub bucket_details: Option<RemoteCloudBucketDetails>
}
@@ -0,0 +1,40 @@
use crate::remote_file_manager::file_descriptor::FileDescriptor;
// TODO ASK BRANDON WHAT path should this be?
const MEDIA_FILE_DIRECTORY: &str = "/media";
pub struct MediaImagePngDescriptor;
impl FileDescriptor for MediaImagePngDescriptor {
fn remote_directory_path(&self) -> &str {
MEDIA_FILE_DIRECTORY
}
fn get_suffix(&self)->String {
"png".to_string()
}
fn get_prefix(&self)->String {
"image".to_string()
}
fn is_public(&self) -> bool {
true
}
}
pub struct MediaVideoMp4Descriptor;
impl FileDescriptor for MediaVideoMp4Descriptor {
fn remote_directory_path(&self) -> &str {
MEDIA_FILE_DIRECTORY
}
fn get_suffix(&self)->String {
"mp4".to_string()
}
fn get_prefix(&self)->String {
"video".to_string()
}
fn is_public(&self) -> bool {
true
}
}
@@ -1,7 +1,8 @@
use crate::remote_file_manager::media_descriptor;
use crate::remote_file_manager::weights_descriptor::{self};
use super::file_descriptor::FileDescriptor;
#[derive(Debug, Clone)]
pub struct RemoteCloudBucketDetails {
pub object_hash: String,
pub prefix: String,
@@ -28,6 +29,7 @@ impl RemoteCloudBucketDetails {
pub fn file_descriptor_from_bucket_details(&self) -> Box<dyn FileDescriptor> {
match self.prefix.as_str() {
// Weights
"loRA" => Box::new(weights_descriptor::WeightsLoRADescriptor {}),
"sd15" => Box::new(weights_descriptor::WeightsSD15Descriptor {}),
"sdxl" => Box::new(weights_descriptor::WeightsSDXLDescriptor {}),
@@ -40,6 +42,20 @@ impl RemoteCloudBucketDetails {
}
},
"svc" => Box::new(weights_descriptor::WeightsSVCDescriptor {}),
"workflow" => Box::new(weights_descriptor::WeightsWorkflowDescriptor {}),
// Media
"image" => {
match self.suffix.as_str() {
"png" => Box::new(media_descriptor::MediaImagePngDescriptor {}),
_ => panic!("Unknown suffix: {}",self.suffix)
}
},
"video" => {
match self.suffix.as_str() {
"mp4" => Box::new(media_descriptor::MediaVideoMp4Descriptor {}),
_ => panic!("Unknown suffix: {}",self.suffix)
}
},
_ => panic!("Unknown prefix: {}", self.prefix)
}
}
@@ -1,4 +1,5 @@
use anyhow::anyhow;
use errors::AnyhowResult;
use filesys::file_read_bytes::file_read_bytes;
use filesys::file_size::file_size;
@@ -17,12 +18,7 @@ pub struct RemoteCloudFileClient {
}
impl RemoteCloudFileClient {
pub fn new(bucket_orchestration_client: Box<dyn BucketOrchestrationCore>) -> Self {
Self {
bucket_orchestration_client
}
}
pub async fn get_remote_cloud_file_client() -> AnyhowResult<Self> {
let bucket_orchestration = match BucketOrchestration::new_bucket_client_from_existing_env() {
Ok(client) => client,
@@ -36,11 +32,18 @@ impl RemoteCloudFileClient {
})
}
pub fn new(bucket_orchestration_client: Box<dyn BucketOrchestrationCore>) -> Self {
Self {
bucket_orchestration_client
}
}
// Where the to_system_file_path is let sd_checkpoint_path = work_temp_dir.path().join("sd_checkpoint.safetensors"); path and file name and extension
pub async fn download_file(&self, remote_cloud_bucket_details:RemoteCloudBucketDetails, to_system_file_path:String) -> AnyhowResult<()> {
let file_descriptor = remote_cloud_bucket_details.file_descriptor_from_bucket_details();
let file_bucket_directory = FileBucketDirectory::from_existing_bucket_details(remote_cloud_bucket_details);
let full_remote_cloud_file_path = file_bucket_directory.get_full_remote_cloud_file_path().to_string();
let is_public = file_descriptor.is_public().clone();
let is_public = file_descriptor.is_public();
self.bucket_orchestration_client.download_file_to_disk(full_remote_cloud_file_path, to_system_file_path, is_public).await?;
Ok(())
@@ -53,17 +56,26 @@ impl RemoteCloudFileClient {
println!("Reading media file: {:?}", from_system_file_path);
// get meta data
let bytes = file_read_bytes(from_system_file_path)?;
let result = Self::get_file_meta_data(from_system_file_path)?;
let mut result = Self::get_file_meta_data(from_system_file_path)?;
let is_public = file_descriptor.is_public();
let suffix = file_descriptor.get_suffix().clone();
let prefix = file_descriptor.get_prefix().clone();
let directory = FileBucketDirectory::generate_new(
file_descriptor
);
result.bucket_details = Some(RemoteCloudBucketDetails {
object_hash: directory.get_file_object_hash().to_string(),
suffix,
prefix,
});
println!("Uploading media file to bucket path: {:?}",directory.get_full_remote_cloud_file_path());
self.bucket_orchestration_client.upload_file_with_content_type_process(
&directory.get_remote_cloud_base_directory(),
&directory.get_full_remote_cloud_file_path(),
bytes.as_ref(),
result.mimetype.as_ref(),
is_public
@@ -73,7 +85,7 @@ impl RemoteCloudFileClient {
}
// Retrieve the metadata from the file
fn get_file_meta_data(system_file_path:&str) -> AnyhowResult<FileMetaData> {
pub fn get_file_meta_data(system_file_path:&str) -> AnyhowResult<FileMetaData> {
let file_size_bytes = file_size(system_file_path.clone())?;
let sha256_checksum = sha256_hash_file(system_file_path.clone())?;
@@ -83,7 +95,8 @@ impl RemoteCloudFileClient {
Ok(FileMetaData {
file_size_bytes,
sha256_checksum,
mimetype: mimetype.to_string()
mimetype: mimetype.to_string(),
bucket_details: None
})
}
}
@@ -92,6 +105,7 @@ impl RemoteCloudFileClient {
mod tests {
use async_trait::async_trait;
use env_logger;
use errors::AnyhowResult;
use crate::remote_file_manager::bucket_orchestration::BucketOrchestrationCore;
@@ -125,7 +139,8 @@ mod tests {
is_public: bool) -> AnyhowResult<()> {
println!("Upload File to Disk");
println!("{}",object_name);
assert_eq!(object_name,String::from("/weights/2/y/q/m/2/2yqm2f1bamh88seyd690h9v24apgezhr/loRA_2yqm2f1bamh88seyd690h9v24apgezhr.safetensors"));
// this is random you have to just check the outputs
//assert_eq!(object_name,String::from("/weights/2/y/q/m/2/2yqm2f1bamh88seyd690h9v24apgezhr/loRA_2yqm2f1bamh88seyd690h9v24apgezhr.safetensors"));
println!("ContentType:{}",content_type);
println!("{}",is_public);
assert_eq!(is_public,true);
@@ -3,7 +3,6 @@ use super::file_descriptor::FileDescriptor;
pub struct WeightsLoRADescriptor;
const REMOTE_FILE_DIRECTORY: &str = "/weights";
impl FileDescriptor for WeightsLoRADescriptor {
fn remote_directory_path(&self) -> &str {
REMOTE_FILE_DIRECTORY
@@ -26,6 +25,7 @@ impl FileDescriptor for WeightsLoRADescriptor {
}
}
pub struct WeightsSD15Descriptor;
impl FileDescriptor for WeightsSD15Descriptor {
@@ -166,6 +166,26 @@ impl FileDescriptor for crate::remote_file_manager::weights_descriptor::WeightsV
}
// This will be ensure that the right bucket is picked
fn is_public(&self) -> bool {
true
}
}
pub struct WeightsWorkflowDescriptor;
impl FileDescriptor for WeightsWorkflowDescriptor {
fn remote_directory_path(&self) -> &str {
REMOTE_FILE_DIRECTORY
}
fn get_suffix(&self) -> String {
"json".to_string()
}
fn get_prefix(&self) -> String {
"workflow".to_string()
}
fn is_public(&self) -> bool {
true
}
@@ -57,6 +57,59 @@ impl GoogleDriveDownloadCommand {
}
}
pub async fn download_file_with_file_name(&self,
download_url: &str,
temp_dir: &TempDir,
file_name:&str) -> AnyhowResult<String>
{
let temp_dir_path = temp_dir.path()
.to_str()
.unwrap_or("/tmp")
.to_string();
let temp_filename = format!("{}/{}", temp_dir_path, file_name);
info!("Downloading {} to: {}", download_url, temp_filename);
let mut command = format!("{} --url \"{}\" --output_filename {}",
&self.download_script,
download_url,
&temp_filename);
if let Some(venv_activation_script) = self.maybe_venv_activation_script.as_deref() {
// NB: "." is source for non-bash shells
command = format!(". {} && {}",
venv_activation_script,
&command);
}
if let Some(change_to_directory) = self.maybe_change_to_directory.as_deref() {
command = format!("cd {} && {}",
change_to_directory,
&command);
}
if let Some(docker_options) = self.maybe_docker_options.as_ref() {
command = docker_options.to_command_string(&command);
}
info!("Running command: {}", command);
let result = Command::new("sh")
.arg("-c")
.arg(command)
.output()?;
info!("Downloader Result: {:?}", result);
if !result.status.success() {
let reason = String::from_utf8(result.stderr).unwrap_or("UNKNOWN".to_string());
return Err(anyhow!("Failure to execute command: {:?}", reason))
}
Ok(temp_filename)
}
/// Download file from Google Drive into the `TempDir`.
/// Return the local filesystem filename.
pub async fn download_file(&self,
@@ -30,7 +30,7 @@ impl TtlKeyCounter {
Ok(0)
}
Some(count) => {
let return_count = count.clone();
let return_count = *count;
*count = count.saturating_add(1);
Ok(return_count)
}
+2 -1
View File
@@ -27,6 +27,7 @@ chrono = { version = "0.4.22", features = ["serde"] }
serde = { version = "1.0.152", features = ["derive"] }
serde_json = "1.0.108"
my-workspace-hack = { version = "0.1", path = "../../my-workspace-hack" }
regex = "1.10.2"
[dev-dependencies]
# None yet
# None yet
@@ -1,22 +1,125 @@
use elasticsearch::{Elasticsearch, SearchParts};
use log::error;
use serde_json::{json, Value};
use errors::AnyhowResult;
use enums::by_table::model_weights::weights_category::WeightsCategory;
use enums::by_table::model_weights::weights_types::WeightsType;
use errors::{anyhow, AnyhowResult};
use crate::documents::model_weight_document::{MODEL_WEIGHT_INDEX, ModelWeightDocument};
pub struct SearchModelWeightsQuery<'a> {
pub search_term: &'a str,
pub maybe_language_subtag: Option<&'a str>,
pub maybe_weights_type: Option<WeightsType>,
pub maybe_weights_category: Option<WeightsCategory>,
}
impl <'a>SearchModelWeightsQuery<'a> {
fn base_query(&self) -> Value {
json!({
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"fuzzy": {
"title": {
"value": self.search_term,
"fuzziness": 2
}
}
},
{
"match": {
"title": {
"query": self.search_term,
"boost": 1
}
}
},
{
"multi_match": {
"query": self.search_term,
"type": "bool_prefix",
"fields": [
"title",
"title._2gram",
"title._3gram"
],
"boost": 50
}
}
]
}
}
]
}
}
})
}
pub fn query(&self) -> AnyhowResult<Value> {
let mut search_json = self.base_query();
let must_clause = search_json.pointer_mut("/query/bool/must")
.map(|pointer| pointer.as_array_mut())
.flatten()
.ok_or_else(|| anyhow!("could not get pointer to must clause"))?;
if let Some(maybe_language_subtag) = &self.maybe_language_subtag {
must_clause.push(json!(
{
"match": {
"maybe_ietf_primary_language_subtag": maybe_language_subtag
}
}
));
}
if let Some(weights_type) = &self.maybe_weights_type {
must_clause.push(json!(
{
"match": {
"weights_type": weights_type.to_string(),
}
}
));
}
if let Some(weights_category) = &self.maybe_weights_category {
must_clause.push(json!(
{
"match": {
"weights_category": weights_category.to_string(),
}
}
));
}
Ok(search_json)
}
}
pub async fn search_model_weights(
client: &Elasticsearch,
search_term: &str,
maybe_language_subtag: Option<&str>,
maybe_weights_type: Option<WeightsType>,
maybe_weights_category: Option<WeightsCategory>,
) -> AnyhowResult<Vec<ModelWeightDocument>> {
let search_json = match maybe_language_subtag {
None => query_model_weights(search_term),
Some(language) => query_model_weights_with_required_language(search_term, language)
let query = SearchModelWeightsQuery {
search_term,
maybe_language_subtag,
maybe_weights_type,
maybe_weights_category,
};
let search_json = query.query()?;
let search_response = client
.search(SearchParts::Index(&[MODEL_WEIGHT_INDEX]))
.body(search_json)
@@ -44,11 +147,7 @@ pub async fn search_model_weights(
let maybe_object = hit.get_mut("_source")
.map(|source| source.take());
if let Some(value) = maybe_object {
let document = serde_json::from_value::<ModelWeightDocument>(value)
.map_err(|err| {
error!("Error: {:?}", &err);
err
})?;
let document = serde_json::from_value::<ModelWeightDocument>(value)?;
documents.push(document);
}
}
@@ -59,97 +158,164 @@ pub async fn search_model_weights(
Ok(documents)
}
fn query_model_weights(search_term: &str) -> Value {
json!({
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"fuzzy": {
"title": {
"value": search_term,
"fuzziness": 2
}
}
},
{
"match": {
"title": {
"query": search_term,
"boost": 1
}
}
},
{
"multi_match": {
"query": search_term,
"type": "bool_prefix",
"fields": [
"title",
"title._2gram",
"title._3gram"
],
"boost": 50
}
}
]
}
}
]
}
}
})
}
#[cfg(test)]
mod tests {
use regex::Regex;
fn query_model_weights_with_required_language(search_term: &str, language_tag: &str) -> Value {
json!({
"query": {
"bool": {
"must": [
{
"match": {
"maybe_ietf_primary_language_subtag": language_tag
}
},
{
"bool": {
"should": [
{
"fuzzy": {
"title": {
"value": search_term,
"fuzziness": 2
use enums::by_table::model_weights::weights_category::WeightsCategory;
use enums::by_table::model_weights::weights_types::WeightsType;
use errors::AnyhowResult;
use crate::searches::search_model_weights::SearchModelWeightsQuery;
fn query_to_json_string(query: SearchModelWeightsQuery<'_>) -> AnyhowResult<String> {
let json = query.query()?;
let json = serde_json::to_string(&json)?;
Ok(json)
}
fn compact_json(json: &str) -> String {
let regex = Regex::new("\\s+").expect("regex should parse");
let json = regex.replace_all(&json, "");
json.to_string()
}
#[test]
fn default_search_only_keyword() {
let query = SearchModelWeightsQuery {
search_term: "FOO_BAR_BAZ",
maybe_language_subtag: None,
maybe_weights_type: None,
maybe_weights_category: None,
};
let json = query_to_json_string(query).unwrap();
// NB: Keys in emitted JSON are sorted.
let expected_json = r#"
{
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"fuzzy": {
"title": {
"fuzziness": 2,
"value": "FOO_BAR_BAZ"
}
}
},
{
"match": {
"title": {
"boost": 1,
"query": "FOO_BAR_BAZ"
}
}
},
{
"multi_match": {
"boost": 50,
"fields": [
"title",
"title._2gram",
"title._3gram"
],
"query": "FOO_BAR_BAZ",
"type": "bool_prefix"
}
}
}
},
{
"match": {
"title": {
"query": search_term,
"boost": 1
}
}
},
{
"multi_match": {
"query": search_term,
"type": "bool_prefix",
"fields": [
"title",
"title._2gram",
"title._3gram"
],
"boost": 50
}
]
}
]
}
}
]
}
]
}
}
}
})
"#;
let expected_json = compact_json(&expected_json);
assert_eq!(&json, &expected_json);
}
#[test]
fn search_with_language_and_weights() {
let query = SearchModelWeightsQuery {
search_term: "FOO_BAR_BAZ",
maybe_language_subtag: Some("en"),
maybe_weights_type: Some(WeightsType::SoVitsSvc),
maybe_weights_category: Some(WeightsCategory::Vocoder),
};
let json = query_to_json_string(query).unwrap();
// NB: Keys in emitted JSON are sorted.
let expected_json = r#"
{
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"fuzzy": {
"title": {
"fuzziness": 2,
"value": "FOO_BAR_BAZ"
}
}
},
{
"match": {
"title": {
"boost": 1,
"query": "FOO_BAR_BAZ"
}
}
},
{
"multi_match": {
"boost": 50,
"fields": [
"title",
"title._2gram",
"title._3gram"
],
"query": "FOO_BAR_BAZ",
"type": "bool_prefix"
}
}
]
}
},
{
"match": {
"maybe_ietf_primary_language_subtag": "en"
}
},
{
"match": {
"weights_type": "so_vits_svc"
}
},
{
"match": {
"weights_category": "vocoder"
}
}
]
}
}
}
"#;
let expected_json = compact_json(&expected_json);
assert_eq!(&json, &expected_json);
}
}
+1 -1
View File
@@ -37,7 +37,7 @@ impl JobStats {
pub fn get_status(&self) -> AnyhowResult<SuccessAndFailureStats> {
// NB: lock errors can't be moved between threads, so we change their type
let mut lock = self.inner.read()
let lock = self.inner.read()
.map_err(|e| anyhow!("lock read error: {:?}", e))?;
Ok(SuccessAndFailureStats {
@@ -0,0 +1,75 @@
use serde_derive::{Deserialize, Serialize};
use sqlx::MySql;
use sqlx::pool::PoolConnection;
use enums::common::visibility::Visibility;
use errors::AnyhowResult;
use mysql_queries::queries::model_weights::get::get_weight_for_legacy_tts_enqueue::{get_weight_for_legacy_tts_enqueue_with_connection, ModelWeightForLegacyTtsEnqueue};
use mysql_queries::queries::tts::tts_models::get_tts_model::{get_tts_model_by_token_using_connection, TtsModelRecord};
use tokens::tokens::model_weights::ModelWeightToken;
/// Get TTS model
/// This is for the tts inference page.
pub async fn get_tts_model_for_enqueue_inference_migration(
token: &str,
mysql_connection: &mut PoolConnection<MySql>,
can_see_deleted: bool,
) -> AnyhowResult<Option<TtsModelForEnqueueInferenceMigrationWrapper>> {
// NB: This is temporary migration code as we switch from the `tts_models` table to the `model_weights` table.
let use_weights_table = token.starts_with(ModelWeightToken::token_prefix());
if use_weights_table {
let token = ModelWeightToken::new_from_str(token);
let maybe_model = get_weight_for_legacy_tts_enqueue_with_connection(
&token,
can_see_deleted,
mysql_connection
).await?;
Ok(maybe_model.map(|model| TtsModelForEnqueueInferenceMigrationWrapper::ModelWeight(model)))
} else {
let maybe_model = get_tts_model_by_token_using_connection(
&token,
true,
mysql_connection
).await?;
Ok(maybe_model.map(|model| TtsModelForEnqueueInferenceMigrationWrapper::LegacyTts(model)))
}
}
/// Union over the legacy table and the new table to support an easier migration.
/// This enum can hold a record of either type and present a unified accessor interface.
#[derive(Clone, Serialize, Deserialize)]
pub enum TtsModelForEnqueueInferenceMigrationWrapper {
/// Old type from the `tts_models` table, on the way out
LegacyTts(TtsModelRecord),
/// New type, replacing the `tts_models` table.
ModelWeight(ModelWeightForLegacyTtsEnqueue),
}
impl TtsModelForEnqueueInferenceMigrationWrapper {
pub fn token(&self) -> &str {
match self {
Self::LegacyTts(ref model) => model.model_token.as_str(),
Self::ModelWeight(ref model) => model.token.as_str(),
}
}
pub fn creator_user_token(&self) -> &str {
match self {
Self::LegacyTts(ref model) => &model.creator_user_token,
Self::ModelWeight(ref model) => model.creator_user_token.as_str(),
}
}
pub fn creator_set_visibility(&self) -> Visibility{
match self {
Self::LegacyTts(ref model) => model.creator_set_visibility,
Self::ModelWeight(ref model) => model.creator_set_visibility,
}
}
}
@@ -0,0 +1,200 @@
use std::path::PathBuf;
use chrono::{DateTime, Utc};
use sqlx::MySqlPool;
use buckets::public::weight_files::bucket_file_path::WeightFileBucketPath;
use cloud_storage::bucket_path_unifier::BucketPathUnifier;
use enums::by_table::tts_models::tts_model_type::TtsModelType;
use mysql_queries::queries::model_weights::get::get_weight_for_legacy_tts_inference::{get_weight_for_legacy_tts_inference, ModelWeightForLegacyTtsInference};
use mysql_queries::queries::tts::tts_models::get_tts_model_for_inference_improved::{CustomVocoderFields, get_tts_model_for_inference_improved, TtsModelForInferenceError, TtsModelForInferenceRecord};
use tokens::tokens::model_weights::ModelWeightToken;
use tokens::tokens::users::UserToken;
/// Get TTS model
/// This is for the inference inference job.
pub async fn get_tts_model_for_run_inference_migration(
tts_model_token: &str,
mysql_pool: &MySqlPool,
) -> Result<Option<TtsModelForRunInferenceMigrationWrapper>, TtsModelForInferenceError> {
// NB: This is temporary migration code as we switch from the `tts_models` table to the `model_weights` table.
if tts_model_token.starts_with(ModelWeightToken::token_prefix()) {
let token = ModelWeightToken::new_from_str(tts_model_token);
let maybe_model = get_weight_for_legacy_tts_inference(
&token,
mysql_pool
).await?;
Ok(maybe_model.map(|model| TtsModelForRunInferenceMigrationWrapper::ModelWeight(model)))
} else {
let maybe_model = get_tts_model_for_inference_improved(
mysql_pool,
&tts_model_token,
).await?;
Ok(maybe_model.map(|model| TtsModelForRunInferenceMigrationWrapper::LegacyTts(model)))
}
}
/// Migration wrapper type.
/// Union over the legacy table and the new table to support an easier migration.
/// This enum can hold a record of either type and present a unified accessor interface.
#[derive(Clone)]
pub enum TtsModelForRunInferenceMigrationWrapper {
/// Old type from the `tts_models` table, on the way out
LegacyTts(TtsModelForInferenceRecord),
/// New type, replacing the `tts_models` table.
ModelWeight(ModelWeightForLegacyTtsInference),
}
impl TtsModelForRunInferenceMigrationWrapper {
pub fn token(&self) -> &str {
match self {
Self::LegacyTts(ref model) => model.model_token.as_str(),
Self::ModelWeight(ref model) => model.token.as_str(),
}
}
pub fn title(&self) -> &str {
match self {
Self::LegacyTts(ref model) => &model.title,
Self::ModelWeight(ref model) => &model.title,
}
}
pub fn creator_user_token(&self) -> &UserToken {
match self {
Self::LegacyTts(ref model) => &model.creator_user_token,
Self::ModelWeight(ref model) => &model.creator_user_token,
}
}
pub fn creator_username(&self) -> &str {
match self {
Self::LegacyTts(ref model) => &model.creator_username,
Self::ModelWeight(ref model) => &model.creator_username,
}
}
pub fn creator_display_name(&self) -> &str {
match self {
Self::LegacyTts(ref model) => &model.creator_display_name,
Self::ModelWeight(ref model) => &model.creator_display_name,
}
}
pub fn created_at(&self) -> &DateTime<Utc> {
match self {
Self::LegacyTts(ref model) => &model.created_at,
Self::ModelWeight(ref model) => &model.created_at,
}
}
pub fn updated_at(&self) -> &DateTime<Utc> {
match self {
Self::LegacyTts(ref model) => &model.updated_at,
Self::ModelWeight(ref model) => &model.updated_at,
}
}
pub fn mod_deleted_at(&self) -> Option<&DateTime<Utc>> {
match self {
Self::LegacyTts(ref model) => model.mod_deleted_at.as_ref(),
Self::ModelWeight(ref model) => model.mod_deleted_at.as_ref(),
}
}
pub fn user_deleted_at(&self) -> Option<&DateTime<Utc>> {
match self {
Self::LegacyTts(ref model) => model.user_deleted_at.as_ref(),
Self::ModelWeight(ref model) => model.user_deleted_at.as_ref(),
}
}
pub fn tts_model_type(&self) -> TtsModelType {
match self {
Self::LegacyTts(ref model) => model.tts_model_type,
Self::ModelWeight(ref _model) => TtsModelType::Tacotron2, // NB: Always TT2
}
}
pub fn maybe_default_pretrained_vocoder(&self) -> Option<&str> {
match self {
Self::LegacyTts(ref model) => model.maybe_default_pretrained_vocoder.as_deref(),
Self::ModelWeight(ref model) => model.maybe_default_pretrained_vocoder.as_deref(),
}
}
/* NB(bt, 2024-01-20): Breakdown of the text_pipeline_type values in the DB:
mysql> select text_pipeline_type , count(*) from tts_models group by text_pipeline_type ;
+--------------------+----------+
| text_pipeline_type | count(*) |
+--------------------+----------+
| NULL | 4406 |
| legacy_fakeyou | 2572 |
| english_v1 | 1548 |
| spanish_v2 | 194 |
+--------------------+----------+
*/
pub fn text_pipeline_type(&self) -> Option<&str> {
match self {
Self::LegacyTts(ref model) => model.text_pipeline_type.as_deref(),
Self::ModelWeight(ref model) => model.maybe_text_pipeline_type.as_deref(),
}
}
pub fn use_default_mel_multiply_factor(&self) -> bool {
match self {
Self::LegacyTts(ref model) => model.use_default_mel_multiply_factor,
Self::ModelWeight(ref model) => model.use_default_mel_multiply_factor,
}
}
pub fn maybe_custom_mel_multiply_factor(&self) -> Option<f64> {
match self {
Self::LegacyTts(ref model) => model.maybe_custom_mel_multiply_factor,
Self::ModelWeight(ref model) => model.maybe_custom_mel_multiply_factor,
}
}
pub fn maybe_custom_vocoder(&self) -> Option<&CustomVocoderFields> {
match self {
Self::LegacyTts(ref model) => model.maybe_custom_vocoder.as_ref(),
Self::ModelWeight(ref model) => model.maybe_custom_vocoder.as_ref(),
}
}
/// Which bucket to download the weights from
pub fn is_private_bucket(&self) -> bool {
match self {
Self::LegacyTts(ref _model) => true,
Self::ModelWeight(ref _model) => false,
}
}
/// Path to the weights in the bucket
/// The old and new schemes are quite different.
pub fn bucket_object_path(&self, bucket_path_unifier: &BucketPathUnifier) -> PathBuf {
match self {
Self::LegacyTts(ref model) => bucket_path_unifier.tts_synthesizer_path(&model.private_bucket_hash),
Self::ModelWeight(ref model) => {
let path = WeightFileBucketPath::from_object_hash(
&model.public_bucket_hash,
model.maybe_public_bucket_prefix.as_deref(),
model.maybe_public_bucket_extension.as_deref());
PathBuf::from(path.get_full_object_path_str())
},
}
}
// NB: Just for vits, which we never supported anyway
pub fn vits_traced_synthesizer_object_path(&self, bucket_path_unifier: &BucketPathUnifier) -> PathBuf {
match self {
Self::LegacyTts(ref model) => bucket_path_unifier.tts_traced_synthesizer_path(&model.private_bucket_hash),
Self::ModelWeight(ref _model) => PathBuf::from("VITS_UNSUPPORTED_FOR_MODEL_WEIGHTS"),
}
}
}
@@ -0,0 +1,249 @@
use chrono::{DateTime, Utc};
use serde_derive::{Deserialize, Serialize};
use sqlx::MySql;
use sqlx::pool::PoolConnection;
use enums::by_table::tts_models::tts_model_type::TtsModelType;
use enums::common::visibility::Visibility;
use errors::AnyhowResult;
use mysql_queries::column_types::vocoder_type::VocoderType;
use mysql_queries::queries::model_weights::get::get_weight_for_legacy_tts_info::{get_weight_for_legacy_tts_info_with_connection, ModelWeightForLegacyTtsInfo};
use mysql_queries::queries::tts::tts_models::get_tts_model::{get_tts_model_by_token_using_connection, TtsModelRecord};
use tokens::tokens::model_weights::ModelWeightToken;
/// Get TTS model
/// This is for the tts model info page
pub async fn get_tts_model_info_migration(
token: &str,
mysql_connection: &mut PoolConnection<MySql>,
can_see_deleted: bool,
use_weights_table: bool,
) -> AnyhowResult<Option<TtsModelInfoMigrationWrapper>> {
// NB: This is temporary migration code as we switch from the `tts_models` table to the `model_weights` table.
if use_weights_table {
let token = ModelWeightToken::new_from_str(token);
let maybe_model = get_weight_for_legacy_tts_info_with_connection(
&token,
can_see_deleted,
mysql_connection
).await?;
Ok(maybe_model.map(|model| TtsModelInfoMigrationWrapper::ModelWeight(model)))
} else {
let maybe_model = get_tts_model_by_token_using_connection(
&token,
true,
mysql_connection
).await?;
Ok(maybe_model.map(|model| TtsModelInfoMigrationWrapper::LegacyTts(model)))
}
}
/// Union over the legacy table and the new table to support an easier migration.
/// This enum can hold a record of either type and present a unified accessor interface.
#[derive(Clone, Serialize, Deserialize)]
pub enum TtsModelInfoMigrationWrapper {
/// Old type from the `tts_models` table, on the way out
LegacyTts(TtsModelRecord),
/// New type, replacing the `tts_models` table.
ModelWeight(ModelWeightForLegacyTtsInfo),
}
impl TtsModelInfoMigrationWrapper {
pub fn token(&self) -> &str {
match self {
Self::LegacyTts(ref model) => model.model_token.as_str(),
Self::ModelWeight(ref model) => model.token.as_str(),
}
}
pub fn title(&self) -> &str {
match self {
Self::LegacyTts(ref model) => &model.title,
Self::ModelWeight(ref model) => &model.title,
}
}
pub fn ietf_language_tag(&self) -> &str {
match self {
Self::LegacyTts(ref model) => &model.ietf_language_tag,
Self::ModelWeight(ref model) => model.maybe_ietf_language_tag.as_deref().unwrap_or("en"),
}
}
pub fn ietf_primary_language_subtag(&self) -> &str {
match self {
Self::LegacyTts(ref model) => &model.ietf_primary_language_subtag,
Self::ModelWeight(ref model) => model.maybe_ietf_primary_language_subtag.as_deref().unwrap_or("en"),
}
}
pub fn creator_user_token(&self) -> &str {
match self {
Self::LegacyTts(ref model) => &model.creator_user_token,
Self::ModelWeight(ref model) => model.creator_user_token.as_str(),
}
}
pub fn creator_username(&self) -> &str {
match self {
Self::LegacyTts(ref model) => &model.creator_username,
Self::ModelWeight(ref model) => &model.creator_username,
}
}
pub fn creator_display_name(&self) -> &str {
match self {
Self::LegacyTts(ref model) => &model.creator_display_name,
Self::ModelWeight(ref model) => &model.creator_display_name,
}
}
pub fn creator_gravatar_hash(&self) -> &str {
match self {
Self::LegacyTts(ref model) => &model.creator_gravatar_hash,
Self::ModelWeight(ref model) => &model.creator_gravatar_hash,
}
}
pub fn creator_set_visibility(&self) -> Visibility{
match self {
Self::LegacyTts(ref model) => model.creator_set_visibility,
Self::ModelWeight(ref model) => model.creator_set_visibility,
}
}
pub fn created_at(&self) -> &DateTime<Utc> {
match self {
Self::LegacyTts(ref model) => &model.created_at,
Self::ModelWeight(ref model) => &model.created_at,
}
}
pub fn updated_at(&self) -> &DateTime<Utc> {
match self {
Self::LegacyTts(ref model) => &model.updated_at,
Self::ModelWeight(ref model) => &model.updated_at,
}
}
// Not supported in the new table
pub fn is_front_page_featured(&self) -> bool {
match self {
Self::LegacyTts(ref model) => model.is_front_page_featured,
Self::ModelWeight(ref _model) => false,
}
}
// Not supported in the new table
pub fn is_twitch_featured(&self) -> bool {
match self {
Self::LegacyTts(ref model) => model.is_twitch_featured,
Self::ModelWeight(ref _model) => false,
}
}
// Not supported in the new table
pub fn is_locked_from_use(&self) -> bool {
match self {
Self::LegacyTts(ref model) => model.is_locked_from_use,
Self::ModelWeight(ref _model) => false,
}
}
// Not supported in the new table
pub fn is_locked_from_user_modification(&self) -> bool {
match self {
Self::LegacyTts(ref model) => model.is_locked_from_user_modification,
Self::ModelWeight(ref _model) => false,
}
}
// Not supported in the new table
pub fn user_ratings_positive_count(&self) -> u32 {
match self {
Self::LegacyTts(ref model) => model.user_ratings_positive_count,
Self::ModelWeight(ref _model) => 0,
}
}
// Not supported in the new table
pub fn user_ratings_negative_count(&self) -> u32 {
match self {
Self::LegacyTts(ref model) => model.user_ratings_negative_count,
Self::ModelWeight(ref _model) => 0,
}
}
// Not supported in the new table
pub fn user_ratings_total_count(&self) -> u32 {
match self {
Self::LegacyTts(ref model) => model.user_ratings_total_count,
Self::ModelWeight(ref _model) => 0,
}
}
// Not supported in the new table
pub fn maybe_suggested_unique_bot_command(&self) -> Option<&str> {
match self {
Self::LegacyTts(ref model) => model.maybe_suggested_unique_bot_command.as_deref(),
Self::ModelWeight(ref _model) => None,
}
}
pub fn tts_model_type(&self) -> TtsModelType {
match self {
Self::LegacyTts(ref model) => model.tts_model_type,
Self::ModelWeight(ref _model) => TtsModelType::Tacotron2, // NB: Always TT2
}
}
pub fn description_markdown(&self) -> &str {
match self {
Self::LegacyTts(ref model) => &model.description_markdown,
Self::ModelWeight(ref model) => &model.maybe_description_markdown.as_deref().unwrap_or(""),
}
}
pub fn description_rendered_html(&self) -> &str {
match self {
Self::LegacyTts(ref model) => &model.description_rendered_html,
Self::ModelWeight(ref model) => &model.maybe_description_rendered_html.as_deref().unwrap_or(""),
}
}
pub fn maybe_default_pretrained_vocoder(&self) -> Option<VocoderType> {
match self {
Self::LegacyTts(ref model) => model.maybe_default_pretrained_vocoder,
Self::ModelWeight(ref model) => model.maybe_default_pretrained_vocoder,
}
}
pub fn text_preprocessing_algorithm(&self) -> &str {
match self {
Self::LegacyTts(ref model) => &model.text_preprocessing_algorithm,
Self::ModelWeight(ref _model) => "basic", // NB: All records in the DB are "basic"
}
}
/* NB(bt, 2024-01-20): Breakdown of the text_pipeline_type values in the DB:
mysql> select text_pipeline_type , count(*) from tts_models group by text_pipeline_type ;
+--------------------+----------+
| text_pipeline_type | count(*) |
+--------------------+----------+
| NULL | 4406 |
| legacy_fakeyou | 2572 |
| english_v1 | 1548 |
| spanish_v2 | 194 |
+--------------------+----------+
*/
pub fn text_pipeline_type(&self) -> Option<&str> {
match self {
Self::LegacyTts(ref model) => model.text_pipeline_type.as_deref(),
Self::ModelWeight(ref model) => model.maybe_text_pipeline_type.as_deref(),
}
}
}
@@ -13,14 +13,14 @@ use mysql_queries::queries::tts::tts_models::list_tts_models::{list_tts_models_w
pub async fn list_tts_models_for_migration(
mysql_connection: &mut PoolConnection<MySql>,
use_weights_table: bool,
) -> AnyhowResult<Vec<TtsModelForList>> {
) -> AnyhowResult<Vec<TtsModelForListMigrationWrapper>> {
// NB: This is temporary migration code as we switch from the `tts_models` table to the `model_weights` table.
if use_weights_table {
let models = list_model_weights_for_text_to_speech(
mysql_connection).await?;
Ok(models.into_iter()
.map(|model| TtsModelForList::ModelWeight(model))
.map(|model| TtsModelForListMigrationWrapper::ModelWeight(model))
.collect())
} else {
@@ -28,7 +28,7 @@ pub async fn list_tts_models_for_migration(
mysql_connection, None, false).await?;
Ok(models.into_iter()
.map(|model| TtsModelForList::LegacyTts(model))
.map(|model| TtsModelForListMigrationWrapper::LegacyTts(model))
.collect())
}
}
@@ -36,120 +36,120 @@ pub async fn list_tts_models_for_migration(
/// Union over the legacy table and the new table to support an easier migration.
/// This enum can hold a record of either type and present a unified accessor interface.
#[derive(Clone)]
pub enum TtsModelForList {
pub enum TtsModelForListMigrationWrapper {
/// Old type from the `tts_models` table, on the way out
LegacyTts(TtsModelRecordForList),
/// New type, replacing the `tts_models` table.
ModelWeight(ModelWeightForTts),
}
impl TtsModelForList {
impl TtsModelForListMigrationWrapper {
pub fn token(&self) -> &str {
match self {
TtsModelForList::LegacyTts(ref model) => model.model_token.as_str(),
TtsModelForList::ModelWeight(ref model) => model.token.as_str(),
TtsModelForListMigrationWrapper::LegacyTts(ref model) => model.model_token.as_str(),
TtsModelForListMigrationWrapper::ModelWeight(ref model) => model.token.as_str(),
}
}
pub fn title(&self) -> &str {
match self {
TtsModelForList::LegacyTts(ref model) => &model.title,
TtsModelForList::ModelWeight(ref model) => &model.title,
TtsModelForListMigrationWrapper::LegacyTts(ref model) => &model.title,
TtsModelForListMigrationWrapper::ModelWeight(ref model) => &model.title,
}
}
pub fn ietf_language_tag(&self) -> &str {
match self {
TtsModelForList::LegacyTts(ref model) => &model.ietf_language_tag,
TtsModelForList::ModelWeight(ref model) => &model.ietf_language_tag,
TtsModelForListMigrationWrapper::LegacyTts(ref model) => &model.ietf_language_tag,
TtsModelForListMigrationWrapper::ModelWeight(ref model) => &model.ietf_language_tag,
}
}
pub fn ietf_primary_language_subtag(&self) -> &str {
match self {
TtsModelForList::LegacyTts(ref model) => &model.ietf_primary_language_subtag,
TtsModelForList::ModelWeight(ref model) => &model.ietf_primary_language_subtag,
TtsModelForListMigrationWrapper::LegacyTts(ref model) => &model.ietf_primary_language_subtag,
TtsModelForListMigrationWrapper::ModelWeight(ref model) => &model.ietf_primary_language_subtag,
}
}
pub fn creator_user_token(&self) -> &str {
match self {
TtsModelForList::LegacyTts(ref model) => &model.creator_user_token,
TtsModelForList::ModelWeight(ref model) => model.creator_user_token.as_str(),
TtsModelForListMigrationWrapper::LegacyTts(ref model) => &model.creator_user_token,
TtsModelForListMigrationWrapper::ModelWeight(ref model) => model.creator_user_token.as_str(),
}
}
pub fn creator_username(&self) -> &str {
match self {
TtsModelForList::LegacyTts(ref model) => &model.creator_username,
TtsModelForList::ModelWeight(ref model) => &model.creator_username,
TtsModelForListMigrationWrapper::LegacyTts(ref model) => &model.creator_username,
TtsModelForListMigrationWrapper::ModelWeight(ref model) => &model.creator_username,
}
}
pub fn creator_display_name(&self) -> &str {
match self {
TtsModelForList::LegacyTts(ref model) => &model.creator_display_name,
TtsModelForList::ModelWeight(ref model) => &model.creator_display_name,
TtsModelForListMigrationWrapper::LegacyTts(ref model) => &model.creator_display_name,
TtsModelForListMigrationWrapper::ModelWeight(ref model) => &model.creator_display_name,
}
}
pub fn creator_gravatar_hash(&self) -> &str {
match self {
TtsModelForList::LegacyTts(ref model) => &model.creator_gravatar_hash,
TtsModelForList::ModelWeight(ref model) => &model.creator_gravatar_hash,
TtsModelForListMigrationWrapper::LegacyTts(ref model) => &model.creator_gravatar_hash,
TtsModelForListMigrationWrapper::ModelWeight(ref model) => &model.creator_gravatar_hash,
}
}
pub fn creator_set_visibility(&self) -> Visibility{
match self {
TtsModelForList::LegacyTts(ref model) => model.creator_set_visibility,
TtsModelForList::ModelWeight(ref model) => model.creator_set_visibility,
TtsModelForListMigrationWrapper::LegacyTts(ref model) => model.creator_set_visibility,
TtsModelForListMigrationWrapper::ModelWeight(ref model) => model.creator_set_visibility,
}
}
pub fn created_at(&self) -> &DateTime<Utc> {
match self {
TtsModelForList::LegacyTts(ref model) => &model.created_at,
TtsModelForList::ModelWeight(ref model) => &model.created_at,
TtsModelForListMigrationWrapper::LegacyTts(ref model) => &model.created_at,
TtsModelForListMigrationWrapper::ModelWeight(ref model) => &model.created_at,
}
}
pub fn updated_at(&self) -> &DateTime<Utc> {
match self {
TtsModelForList::LegacyTts(ref model) => &model.updated_at,
TtsModelForList::ModelWeight(ref model) => &model.updated_at,
TtsModelForListMigrationWrapper::LegacyTts(ref model) => &model.updated_at,
TtsModelForListMigrationWrapper::ModelWeight(ref model) => &model.updated_at,
}
}
// Not supported in the new table
pub fn is_front_page_featured(&self) -> bool {
match self {
TtsModelForList::LegacyTts(ref model) => model.is_front_page_featured,
TtsModelForList::ModelWeight(ref _model) => false,
TtsModelForListMigrationWrapper::LegacyTts(ref model) => model.is_front_page_featured,
TtsModelForListMigrationWrapper::ModelWeight(ref _model) => false,
}
}
// Not supported in the new table
pub fn user_ratings_positive_count(&self) -> u32 {
match self {
TtsModelForList::LegacyTts(ref model) => model.user_ratings_positive_count,
TtsModelForList::ModelWeight(ref _model) => 0,
TtsModelForListMigrationWrapper::LegacyTts(ref model) => model.user_ratings_positive_count,
TtsModelForListMigrationWrapper::ModelWeight(ref _model) => 0,
}
}
// Not supported in the new table
pub fn user_ratings_negative_count(&self) -> u32 {
match self {
TtsModelForList::LegacyTts(ref model) => model.user_ratings_negative_count,
TtsModelForList::ModelWeight(ref _model) => 0,
TtsModelForListMigrationWrapper::LegacyTts(ref model) => model.user_ratings_negative_count,
TtsModelForListMigrationWrapper::ModelWeight(ref _model) => 0,
}
}
// Not supported in the new table
pub fn user_ratings_total_count(&self) -> u32 {
match self {
TtsModelForList::LegacyTts(ref model) => model.user_ratings_total_count,
TtsModelForList::ModelWeight(ref _model) => 0,
TtsModelForListMigrationWrapper::LegacyTts(ref model) => model.user_ratings_total_count,
TtsModelForListMigrationWrapper::ModelWeight(ref _model) => 0,
}
}
}
@@ -1 +1,4 @@
pub mod get_tts_model_for_enqueue_inference_migration;
pub mod get_tts_model_for_run_inference_migration;
pub mod get_tts_model_info_migration;
pub mod list_tts_models_for_migration;
@@ -67,6 +67,7 @@ impl VcModelForList {
WeightsType::Tacotron2 => None,
WeightsType::LoRA => None,
WeightsType::VallE => None,
WeightsType::ComfyUi => None,
},
}
}
@@ -106,6 +106,7 @@ impl VcModel {
WeightsType::Tacotron2 => VcModelType::Invalid,
WeightsType::LoRA => VcModelType::Invalid,
WeightsType::VallE => VcModelType::Invalid,
WeightsType::ComfyUi => VcModelType::Invalid,
}
}
}
@@ -77,6 +77,7 @@ impl VcModelLite {
WeightsType::HifiganTacotron2 => None, // NB: Not used directly in inference. Included by other models.
WeightsType::LoRA => None, // NB: not used directly in inference. Included in other models.
WeightsType::VallE => None, // TODO(bt,2023-12-18): Does this mean speaker weights?
WeightsType::ComfyUi => None, // NB: not used directly in inference. Included in other models.
}
}
}
@@ -97,6 +98,7 @@ impl VcModelLite {
WeightsType::HifiganTacotron2 => None, // NB: Not used directly in inference. Included by other models.
WeightsType::LoRA => None, // NB: not used directly in inference. Included in other models.
WeightsType::VallE => None, // TODO(bt,2023-12-18): Does this mean speaker weights?
WeightsType::ComfyUi => None, // NB: not used directly in inference. Included in other models.
}
}
}
+1
View File
@@ -16,6 +16,7 @@ path = "src/lib.rs"
# Internal
buckets = { path = "../../_types/buckets" }
composite_identifiers = { path = "../../_types/composite_identifiers" }
config = { path = "../deprecated/config" }
container_common = { path = "../deprecated/container_common" }
enums = { path = "../../_types/enums" }
@@ -1,11 +1,12 @@
use enums::by_table::generic_inference_jobs::inference_category::InferenceCategory;
use errors::AnyhowResult;
use crate::payloads::generic_inference_args::image_generation_payload::StableDiffusionArgs;
use crate::payloads::generic_inference_args::lipsync_payload::LipsyncArgs;
use crate::payloads::generic_inference_args::mocap_payload::MocapArgs;
use crate::payloads::generic_inference_args::tts_payload::TTSArgs;
use crate::payloads::generic_inference_args::videofilter_payload::{RerenderArgs};
use crate::payloads::generic_inference_args::videofilter_payload::RerenderArgs;
use crate::payloads::generic_inference_args::workflow_payload::WorkflowArgs;
/// Used to encode extra state for the `generic_inference_jobs` table.
/// This should act somewhat like a serialized protobuf stored inside a record.
@@ -42,9 +43,17 @@ pub enum InferenceCategoryAbbreviated {
#[serde(alias = "video_filter")]
VideoFilter,
#[serde(rename = "ig")] // NB: DO NOT CHANGE. It could break live jobs. Renamed to be fewer bytes.
#[serde(alias = "image_generation")]
ImageGeneration,
#[serde(rename = "mc")] // NB: DO NOT CHANGE. It could break live jobs. Renamed to be fewer bytes.
#[serde(alias = "mocap")]
Mocap,
#[serde(rename = "wf")] // NB: DO NOT CHANGE. It could break live jobs. Renamed to be fewer bytes.
#[serde(alias = "workflow")]
Workflow,
}
#[derive(Serialize, Deserialize, Clone, Copy, Debug)]
@@ -98,10 +107,15 @@ pub enum PolymorphicInferenceArgs {
/// Rerender a video. (Short name to save space when serializing.)
Rr(RerenderArgs),
// Mocap (Short name to save space when serializing.)
Mc(MocapArgs)
}
/// Image generation. (Short name to save space when serializing.)
Ig(StableDiffusionArgs),
// Mocap (Short name to save space when serializing.)
Mc(MocapArgs),
// ComfyUI (Short name to save space when serializing.)
Cu(WorkflowArgs)
}
impl GenericInferenceArgs {
@@ -121,7 +135,9 @@ impl InferenceCategoryAbbreviated {
InferenceCategory::TextToSpeech => Self::TextToSpeech,
InferenceCategory::VoiceConversion => Self::VoiceConversion,
InferenceCategory::VideoFilter => Self::VideoFilter,
InferenceCategory::ImageGeneration => Self::ImageGeneration,
InferenceCategory::Mocap => Self::Mocap,
InferenceCategory::Workflow => Self::Workflow,
}
}
@@ -131,14 +147,19 @@ impl InferenceCategoryAbbreviated {
Self::TextToSpeech => InferenceCategory::TextToSpeech,
Self::VoiceConversion => InferenceCategory::VoiceConversion,
Self::VideoFilter => InferenceCategory::VideoFilter,
Self::ImageGeneration =>InferenceCategory::ImageGeneration,
Self::Mocap => InferenceCategory::Mocap,
Self::Workflow => InferenceCategory::Workflow,
}
}
}
#[cfg(test)]
mod tests {
use tokens::tokens::{media_files::MediaFileToken, model_weights::ModelWeightToken};
use crate::payloads::generic_inference_args::generic_inference_args::{FundamentalFrequencyMethodForJob, GenericInferenceArgs, InferenceCategoryAbbreviated, PolymorphicInferenceArgs};
use crate::payloads::generic_inference_args::image_generation_payload::StableDiffusionArgs;
use crate::payloads::generic_inference_args::lipsync_payload::{LipsyncAnimationAudioSource, LipsyncAnimationImageSource, LipsyncArgs};
use crate::payloads::generic_inference_args::tts_payload::TTSArgs;
@@ -187,6 +208,51 @@ mod tests {
assert!(json.len() < 1000);
}
#[test]
fn typical_image_gen_args_serialize() {
let video_media_token = MediaFileToken("video_media_token".to_string());
let image_media_token = MediaFileToken("image_media_token".to_string());
let sd_model_token = ModelWeightToken("sd_model_token".to_string());
let lora_model_token = ModelWeightToken("lora_model_token".to_string());
let prompt = "prompt".to_string();
let a_prompt = "a_prompt".to_string();
let n_prompt = "n_prompt".to_string();
let seed = 1;
let upload_path = "upload_path".to_string();
let lora_upload_path = "lora_upload_path".to_string();
let checkpoint = "checkpoint".to_string();
let type_of_inference = "type_of_inference".to_string();
let version: u32 = 0;
let args = GenericInferenceArgs {
inference_category: Some(InferenceCategoryAbbreviated::ImageGeneration),
args: Some(PolymorphicInferenceArgs::Ig(StableDiffusionArgs {
maybe_sd_model_token: Some(sd_model_token),
maybe_lora_model_token: Some(lora_model_token),
maybe_sampler: Some("sampler".to_string()),
maybe_height: Some(512),
maybe_width: Some(512),
maybe_cfg_scale: Some(7),
maybe_prompt: Some(prompt),
maybe_n_prompt: Some(n_prompt),
maybe_batch_count: Some(1),
maybe_number_of_samples: Some(25),
maybe_seed: Some(seed),
maybe_upload_path: Some(upload_path),
maybe_lora_upload_path: Some(lora_upload_path),
type_of_inference,
maybe_description: Some("Option".to_string()),
maybe_name: Some("Model Name".to_string()),
maybe_version: Some(version),
})),
};
let json = serde_json::ser::to_string(&args).unwrap();
assert_eq!(json, r#"{"cat":"ig","args":{"Ig":{"sd":"sd_model_token","lm":"lora_model_token","w":512,"h":512,"s":"sampler","p":"prompt","np":"n_prompt","se":1,"mu":"upload_path","cf":7,"lu":"lora_upload_path","sa":25,"bc":1,"t":"type_of_inference","de":"Option","na":"Model Name"}}}"#.to_string());
}
#[test]
fn typical_voice_conversion_args_serialize() {
let args = GenericInferenceArgs {
@@ -0,0 +1,92 @@
use tokens::tokens::model_weights::ModelWeightToken;
/// Video sources can be one of several:
/// - F: media_files (todo)
/// - U: media_uploads (legacy)
/// For image to image we probably want images
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub enum StableDiffusionSource {
// NB: DO NOT CHANGE. It could break live jobs. Renamed to be fewer bytes.
/// Media File Token (media_files table)
/// Serde cannot yet rename enum variants.
F(String),
// NB: DO NOT CHANGE. It could break live jobs. Renamed to be fewer bytes.
/// Media Upload Token (media_uploads table)
/// Serde cannot yet rename enum variants.
U(String),
}
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq)]
pub struct StableDiffusionArgs {
#[serde(rename = "sd")]
#[serde(skip_serializing_if = "Option::is_none")]
pub maybe_sd_model_token: Option<ModelWeightToken>,
#[serde(rename = "lm")]
#[serde(skip_serializing_if = "Option::is_none")]
pub maybe_lora_model_token: Option<ModelWeightToken>,
#[serde(rename = "w")]
#[serde(skip_serializing_if = "Option::is_none")]
pub maybe_width: Option<u32>,
#[serde(rename = "h")]
#[serde(skip_serializing_if = "Option::is_none")]
pub maybe_height: Option<u32>,
#[serde(rename = "s")]
#[serde(skip_serializing_if = "Option::is_none")]
pub maybe_sampler: Option<String>,
#[serde(rename = "p")]
#[serde(skip_serializing_if = "Option::is_none")]
pub maybe_prompt: Option<String>,
#[serde(rename = "np")]
#[serde(skip_serializing_if = "Option::is_none")]
pub maybe_n_prompt: Option<String>,
#[serde(rename = "se")]
#[serde(skip_serializing_if = "Option::is_none")]
pub maybe_seed: Option<i64>,
#[serde(rename = "mu")]
#[serde(skip_serializing_if = "Option::is_none")]
pub maybe_upload_path: Option<String>,
#[serde(rename = "cf")]
#[serde(skip_serializing_if = "Option::is_none")]
pub maybe_cfg_scale: Option<u32>,
#[serde(rename = "lu")]
#[serde(skip_serializing_if = "Option::is_none")]
pub maybe_lora_upload_path: Option<String>,
#[serde(rename = "sa")]
#[serde(skip_serializing_if = "Option::is_none")]
pub maybe_number_of_samples: Option<u32>,
#[serde(rename = "bc")]
pub maybe_batch_count: Option<u32>,
#[serde(rename = "t")]
pub type_of_inference: String,
// loRA / checkpoint description
#[serde(rename = "de")]
#[serde(skip_serializing_if = "Option::is_none")]
pub maybe_description: Option<String>,
// loRA / checkpoint name and description
#[serde(rename = "na")]
#[serde(skip_serializing_if = "Option::is_none")]
pub maybe_name: Option<String>,
#[serde(rename = "ve")]
#[serde(skip_serializing_if = "Option::is_none")]
pub maybe_version: Option<u32>
}
@@ -2,4 +2,6 @@ pub mod generic_inference_args;
pub mod lipsync_payload;
pub mod tts_payload;
pub mod videofilter_payload;
pub mod mocap_payload;
pub mod image_generation_payload;
pub mod mocap_payload;
pub mod workflow_payload;
@@ -0,0 +1,30 @@
use std::collections::HashMap;
use tokens::tokens::model_weights::ModelWeightToken;
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(untagged)]
pub enum NewValue {
String(String),
Float(f32),
Int(i32),
Bool(bool),
}
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
pub struct WorkflowArgs {
#[serde(rename = "sd")]
#[serde(skip_serializing_if = "Option::is_none")]
pub maybe_sd_model: Option<ModelWeightToken>,
#[serde(rename = "lora")]
#[serde(skip_serializing_if = "Option::is_none")]
pub maybe_lora_model: Option<ModelWeightToken>,
#[serde(rename = "workflow_config")]
#[serde(skip_serializing_if = "Option::is_none")]
pub maybe_workflow_config: Option<ModelWeightToken>,
#[serde(rename = "json_modifications")]
#[serde(skip_serializing_if = "Option::is_none")]
pub maybe_json_modifications: Option<HashMap<String, NewValue>>,
}
@@ -0,0 +1,99 @@
use anyhow::anyhow;
use log::error;
use sqlx::{MySql, QueryBuilder, Transaction};
use composite_identifiers::by_table::batch_generations::batch_generation_entity::BatchGenerationEntity;
use errors::AnyhowResult;
use tokens::tokens::batch_generations::BatchGenerationToken;
pub struct BatchEntry {
pub batch_token: BatchGenerationToken,
pub entity: BatchGenerationEntity,
}
pub struct InsertBatchArgs<'a, 'b> {
pub entries: Vec<BatchGenerationEntity>,
pub transaction: &'a mut Transaction<'b, MySql>,
}
/// Insert a list of entities into a "batch" together for grouping; returns the new batch token identifier to return
/// to the HTTP caller.
///
/// NB: Calling code is responsible for rolling back the transaction if this fails.
pub async fn insert_batch_generation_records<'a, 'b>(args: InsertBatchArgs<'a, 'b>) -> AnyhowResult<BatchGenerationToken> {
let batch_token = BatchGenerationToken::generate();
let mut query_builder = QueryBuilder::new(r#"
INSERT INTO batch_generations (token, entity_type, entity_token) VALUES
"#);
for (i, entry) in args.entries.iter().enumerate() {
let (entity_type, entity_token) = entry.get_composite_keys();
query_builder.push("(");
query_builder.push_bind(&batch_token);
query_builder.push(",");
query_builder.push_bind(entity_type);
query_builder.push(",");
query_builder.push_bind(entity_token);
query_builder.push(")");
if i < args.entries.len() - 1 {
query_builder.push(",");
}
}
let query = query_builder.build();
let query_result = query.execute(&mut **args.transaction).await;
match query_result {
Ok(_) => Ok(batch_token),
Err(err) => {
error!("Error with batch generation query: {:?}", &err);
Err(anyhow!("model category creation error: {:?}", &err))
},
}
}
#[ignore]
#[cfg(test)]
mod tests {
use sqlx::mysql::MySqlPoolOptions;
use composite_identifiers::by_table::batch_generations::batch_generation_entity::BatchGenerationEntity;
use config::shared_constants::DEFAULT_MYSQL_CONNECTION_STRING;
use tokens::tokens::media_files::MediaFileToken;
use crate::queries::batch_generations::insert_batch_generation_records::{insert_batch_generation_records, InsertBatchArgs};
async fn setup() -> sqlx::Pool<sqlx::MySql> {
MySqlPoolOptions::new()
.max_connections(3)
.connect(&DEFAULT_MYSQL_CONNECTION_STRING).await
.unwrap()
}
#[ignore]
#[tokio::test]
async fn test() {
let pool = setup().await;
let mut transaction = pool.begin().await.unwrap();
let entries = vec![
BatchGenerationEntity::MediaFile(MediaFileToken::new_from_str("media_foo")),
BatchGenerationEntity::MediaFile(MediaFileToken::new_from_str("media_bar")),
BatchGenerationEntity::MediaFile(MediaFileToken::new_from_str("media_baz")),
];
let r = insert_batch_generation_records(InsertBatchArgs {
entries,
transaction: &mut transaction,
}).await;
transaction.commit().await.unwrap();
}
}
@@ -0,0 +1 @@
pub mod insert_batch_generation_records;
@@ -179,7 +179,9 @@ fn raw_record_to_public_result(record: RawGenericInferenceJobStatus) -> GenericI
InferenceCategory::TextToSpeech => record.maybe_tts_model_title.as_deref(),
InferenceCategory::VoiceConversion => record.maybe_voice_conversion_model_title.as_deref(),
InferenceCategory::VideoFilter => Some("Video Filter"),
InferenceCategory::ImageGeneration => Some("Image Generation"),
InferenceCategory::Mocap => Some("Mocap"),
InferenceCategory::Workflow => Some("Workflow"),
};
// NB: A bit of a hack. We store TTS results with a full path.
@@ -189,7 +191,9 @@ fn raw_record_to_public_result(record: RawGenericInferenceJobStatus) -> GenericI
InferenceCategory::TextToSpeech => (false, record.maybe_tts_public_bucket_path.as_deref()),
InferenceCategory::VoiceConversion => (true, record.maybe_voice_conversion_public_bucket_hash.as_deref()),
InferenceCategory::VideoFilter => (true, record.maybe_media_file_public_bucket_directory_hash.as_deref()),
InferenceCategory::ImageGeneration => (true, record.maybe_media_file_public_bucket_directory_hash.as_deref()),
InferenceCategory::Mocap => (true, record.maybe_media_file_public_bucket_directory_hash.as_deref()),
InferenceCategory::Workflow => (true, record.maybe_media_file_public_bucket_directory_hash.as_deref()),
};
// NB: We've moved voice conversion out of their own table and into media_files
@@ -217,7 +221,7 @@ fn raw_record_to_public_result(record: RawGenericInferenceJobStatus) -> GenericI
maybe_media_file_public_bucket_prefix: record.maybe_media_file_public_bucket_prefix.clone(),
maybe_media_file_public_bucket_extension: record.maybe_media_file_public_bucket_extension.clone(),
public_bucket_location_is_hash: bucket_path_is_hash,
maybe_successfully_completed_at: record.maybe_successfully_completed_at.clone(),
maybe_successfully_completed_at: record.maybe_successfully_completed_at,
}
})
})
@@ -0,0 +1,153 @@
use anyhow::anyhow;
use sqlx;
use sqlx::MySqlPool;
use enums::by_table::generic_synthetic_ids::id_category::IdCategory;
use enums::by_table::media_files::media_file_origin_category::MediaFileOriginCategory;
use enums::by_table::media_files::media_file_origin_model_type::MediaFileOriginModelType;
use enums::by_table::media_files::media_file_origin_product_category::MediaFileOriginProductCategory;
use enums::by_table::media_files::media_file_type::MediaFileType;
use errors::AnyhowResult;
use tokens::tokens::media_files::MediaFileToken;
use tokens::tokens::users::UserToken;
use crate::queries::generic_inference::job::list_available_generic_inference_jobs::AvailableInferenceJob;
use crate::queries::generic_synthetic_ids::transactional_increment_generic_synthetic_id::transactional_increment_generic_synthetic_id;
pub struct InsertArgs<'a> {
pub pool: &'a MySqlPool,
pub job: &'a AvailableInferenceJob,
pub maybe_mime_type: Option<&'a str>,
pub file_size_bytes: u64,
pub sha256_checksum: &'a str,
// TODO: Media duration.
//pub duration_millis: u64,
pub public_bucket_directory_hash: &'a str,
pub maybe_public_bucket_prefix: Option<&'a str>,
pub maybe_public_bucket_extension: Option<&'a str>,
pub is_on_prem: bool,
pub worker_hostname: &'a str,
pub worker_cluster: &'a str,
pub media_file_type: MediaFileType,
}
pub async fn insert_media_file_from_comfy_ui(args: InsertArgs<'_>) -> AnyhowResult<(MediaFileToken, u64)>
{
let result_token = MediaFileToken::generate();
let mut maybe_creator_file_synthetic_id : Option<u64> = None;
let mut maybe_creator_category_synthetic_id : Option<u64> = None;
let mut transaction = args.pool.begin().await?;
if let Some(creator_user_token) = args.job.maybe_creator_user_token.as_deref() {
let user_token = UserToken::new_from_str(creator_user_token);
let next_media_file_id = transactional_increment_generic_synthetic_id(
&user_token,
IdCategory::MediaFile,
&mut transaction
).await?;
let next_comfy_ui_id = transactional_increment_generic_synthetic_id(
&user_token,
IdCategory::WorkflowResult,
&mut transaction
).await?;
maybe_creator_file_synthetic_id = Some(next_media_file_id);
maybe_creator_category_synthetic_id = Some(next_comfy_ui_id);
}
const ORIGIN_CATEGORY : MediaFileOriginCategory = MediaFileOriginCategory::Inference;
const ORIGIN_PRODUCT_CATEGORY : MediaFileOriginProductCategory = MediaFileOriginProductCategory::Workflow;
const ORIGIN_MODEL_TYPE : MediaFileOriginModelType = MediaFileOriginModelType::ComfyUi;
let record_id = {
let query_result = sqlx::query!(
r#"
INSERT INTO media_files
SET
token = ?,
origin_category = ?,
origin_product_category = ?,
maybe_origin_model_type = ?,
media_type = ?,
maybe_mime_type = ?,
file_size_bytes = ?,
checksum_sha2 = ?,
public_bucket_directory_hash = ?,
maybe_public_bucket_prefix = ?,
maybe_public_bucket_extension = ?,
maybe_creator_user_token = ?,
maybe_creator_anonymous_visitor_token = ?,
creator_ip_address = ?,
creator_set_visibility = ?,
maybe_creator_file_synthetic_id = ?,
maybe_creator_category_synthetic_id = ?,
is_generated_on_prem = ?,
generated_by_worker = ?,
generated_by_cluster = ?
"#,
result_token.as_str(),
ORIGIN_CATEGORY.to_str(),
ORIGIN_PRODUCT_CATEGORY.to_str(),
ORIGIN_MODEL_TYPE.to_str(),
args.media_file_type.to_str(),
args.maybe_mime_type,
args.file_size_bytes,
args.sha256_checksum,
args.public_bucket_directory_hash,
args.maybe_public_bucket_prefix,
args.maybe_public_bucket_extension,
args.job.maybe_creator_user_token,
args.job.maybe_creator_anonymous_visitor_token,
args.job.creator_ip_address,
args.job.creator_set_visibility.to_str(),
maybe_creator_file_synthetic_id,
maybe_creator_category_synthetic_id,
args.is_on_prem,
args.worker_hostname,
args.worker_cluster
)
.execute(&mut *transaction)
.await;
let record_id = match query_result {
Ok(res) => {
res.last_insert_id()
},
Err(err) => {
// TODO: handle better
//transaction.rollback().await?;
return Err(anyhow!("Mysql error: {:?}", err));
}
};
record_id
};
transaction.commit().await?;
Ok((result_token, record_id))
}
@@ -18,6 +18,7 @@ pub struct InsertArgs<'a> {
pub pool: &'a MySqlPool,
pub job: &'a AvailableInferenceJob,
pub origin_model_type: MediaFileOriginModelType,
pub maybe_mime_type: Option<&'a str>,
pub file_size_bytes: u64,
pub sha256_checksum: &'a str,
@@ -65,11 +66,10 @@ pub async fn insert_media_file_from_zero_shot(
maybe_creator_category_synthetic_id = Some(next_lipsync_id);
}
// TODO: Ask if it make sense to use ONE function to do the insert
// TODO: Ask if it make sense to use ONE function to do the insert * I agree it does .... use insert media file generic and eventually remove all this.
// Since fill this out apart of the funtion this seems like the only thing to change.
const ORIGIN_CATEGORY : MediaFileOriginCategory = MediaFileOriginCategory::Inference;
const ORIGIN_PRODUCT_CATEGORY : MediaFileOriginProductCategory = MediaFileOriginProductCategory::ZeroShotVoice;
const ORIGIN_MODEL_TYPE : MediaFileOriginModelType = MediaFileOriginModelType::VallEX;
const MEDIA_TYPE : MediaFileType = MediaFileType::Audio;
let record_id = {
@@ -111,8 +111,8 @@ pub async fn insert_media_file_from_zero_shot(
ORIGIN_CATEGORY.to_str(),
ORIGIN_PRODUCT_CATEGORY.to_str(),
ORIGIN_MODEL_TYPE.to_str(),
args.origin_model_type.to_str(),
MEDIA_TYPE.to_str(),
args.maybe_mime_type,
args.file_size_bytes,
@@ -0,0 +1,198 @@
use anyhow::anyhow;
use enums::common::visibility::Visibility;
use sqlx;
use sqlx::MySqlPool;
use enums::by_table::generic_synthetic_ids::id_category::IdCategory;
use enums::by_table::media_files::media_file_origin_category::{MediaFileOriginCategory, self};
use enums::by_table::media_files::media_file_origin_model_type::MediaFileOriginModelType;
use enums::by_table::media_files::media_file_origin_product_category::MediaFileOriginProductCategory;
use enums::by_table::media_files::media_file_type::MediaFileType;
use errors::AnyhowResult;
use tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken;
use tokens::tokens::media_files::MediaFileToken;
use tokens::tokens::model_weights::ModelWeightToken;
use tokens::tokens::users::UserToken;
use crate::queries::generic_inference::job::list_available_generic_inference_jobs::AvailableInferenceJob;
use crate::queries::generic_synthetic_ids::transactional_increment_generic_synthetic_id::transactional_increment_generic_synthetic_id;
use crate::queries::media_files::create::insert_media_file_from_file_upload::UploadType;
// thought about this it seems like this can be a bit more geneneric instead of having this we can ...
pub struct InsertArgs<'a> {
pub pool: &'a MySqlPool,
pub job: &'a AvailableInferenceJob,
pub media_type: MediaFileType,
// Origin and categorization
pub origin_category: MediaFileOriginCategory,
pub origin_product_category: MediaFileOriginProductCategory,
pub maybe_origin_model_type: Option<MediaFileOriginModelType>,
pub maybe_origin_model_token: Option<ModelWeightToken>,
pub maybe_origin_filename: Option<String>,
// Generation flags and media details
pub is_batch_generated: bool, // Assuming you set this in your application logic
pub maybe_mime_type: Option<&'a str>,
pub file_size_bytes: u64,
pub maybe_duration_millis: Option<u64>,
pub maybe_audio_encoding: Option<&'a str>,
pub maybe_video_encoding: Option<&'a str>,
pub maybe_frame_width: Option<u32>,
pub maybe_frame_height: Option<u32>,
pub checksum_sha2: &'a str,
// Storage details
pub public_bucket_directory_hash: &'a str,
pub maybe_public_bucket_prefix: Option<&'a str>,
pub maybe_public_bucket_extension: Option<&'a str>,
pub extra_file_modification_info: Option<&'a str>, // Assuming TEXT type can be represented by &str
// Creator information
pub maybe_creator_user_token: Option<&'a UserToken>,
pub maybe_creator_anonymous_visitor_token: Option<&'a AnonymousVisitorTrackingToken>,
pub creator_ip_address: &'a str,
pub creator_set_visibility: Visibility,
pub maybe_creator_file_synthetic_id_category: IdCategory,
pub maybe_creator_category_synthetic_id_category: IdCategory,
// Modification and generation info
pub maybe_mod_user_token: Option<&'a UserToken>,
pub is_generated_on_prem: bool,
pub generated_by_worker: Option<&'a str>,
pub generated_by_cluster: Option<&'a str>,
}
pub async fn insert_media_file_generic(
args: InsertArgs<'_>
) -> AnyhowResult<(MediaFileToken, u64)>
{
let result_token = MediaFileToken::generate();
let mut maybe_creator_file_synthetic_id : Option<u64> = None;
let mut maybe_creator_category_synthetic_id : Option<u64> = None;
let mut transaction = args.pool.begin().await?;
// create a user token
if let Some(creator_user_token) = args.job.maybe_creator_user_token.as_deref() {
let user_token = UserToken::new_from_str(creator_user_token);
let next_media_file_id = transactional_increment_generic_synthetic_id(
&user_token,
args.maybe_creator_file_synthetic_id_category,
&mut transaction
).await?;
let category_id = transactional_increment_generic_synthetic_id(
&user_token,
args.maybe_creator_category_synthetic_id_category,
&mut transaction
).await?;
maybe_creator_file_synthetic_id = Some(next_media_file_id);
maybe_creator_category_synthetic_id = Some(category_id);
}
let query_result = sqlx::query!(
r#"
INSERT INTO media_files
SET
token = ?,
media_type = ?,
origin_category = ?,
origin_product_category = ?,
maybe_origin_model_type = ?,
maybe_origin_model_token = ?,
maybe_origin_filename = ?,
is_batch_generated = ?,
maybe_mime_type = ?,
file_size_bytes = ?,
maybe_duration_millis = ?,
maybe_audio_encoding = ?,
maybe_video_encoding = ?,
maybe_frame_width = ?,
maybe_frame_height = ?,
checksum_sha2 = ?,
public_bucket_directory_hash = ?,
maybe_public_bucket_prefix = ?,
maybe_public_bucket_extension = ?,
extra_file_modification_info = ?,
maybe_creator_user_token = ?,
maybe_creator_anonymous_visitor_token = ?,
creator_ip_address = ?,
creator_set_visibility = ?,
maybe_creator_file_synthetic_id = ?,
maybe_creator_category_synthetic_id = ?,
maybe_mod_user_token = ?,
is_generated_on_prem = ?,
generated_by_worker = ?,
generated_by_cluster = ?
"#,
result_token,
args.media_type.to_str(),
args.origin_category.to_str(),
args.origin_product_category.to_str(),
args.maybe_origin_model_type.map(|e| e.to_str()),
args.maybe_origin_model_token.map(|e| e.to_string()),
args.maybe_origin_filename,
args.is_batch_generated,
args.maybe_mime_type,
args.file_size_bytes,
args.maybe_duration_millis,
args.maybe_audio_encoding,
args.maybe_video_encoding,
args.maybe_frame_width,
args.maybe_frame_height,
args.checksum_sha2,
args.public_bucket_directory_hash,
args.maybe_public_bucket_prefix,
args.maybe_public_bucket_extension,
args.extra_file_modification_info,
args.maybe_creator_user_token.map(|e| e.to_string()),
args.maybe_creator_anonymous_visitor_token.map(|e| e.to_string()),
args.creator_ip_address,
args.creator_set_visibility.to_str(),
maybe_creator_file_synthetic_id,
maybe_creator_category_synthetic_id,
args.maybe_mod_user_token,
args.is_generated_on_prem,
args.generated_by_worker,
args.generated_by_cluster
).execute(&mut *transaction).await;
let record_id = match query_result {
Ok(res) => {
res.last_insert_id()
},
Err(err) => {
// TODO: handle better
//transaction.rollback().await?;
return Err(anyhow!("Mysql error: {:?}", err));
}
};
transaction.commit().await?;
Ok((result_token, record_id))
}
@@ -6,3 +6,5 @@ pub mod insert_media_file_from_tacotron2;
pub mod insert_media_file_from_voice_conversion;
pub mod insert_media_file_from_zero_shot_tts;
pub mod insert_media_file_from_mocapnet;
pub mod insert_media_file_generic;
pub mod insert_media_file_from_comfy_ui;
@@ -212,8 +212,17 @@ LEFT OUTER JOIN entity_stats
}
match view_as {
ViewAs::Moderator => {}
ViewAs::Author | ViewAs::AnotherUser => {
ViewAs::Moderator | ViewAs::Author => {
if !first_predicate_added {
query_builder.push(" WHERE ");
first_predicate_added = true;
} else {
query_builder.push(" AND ");
}
// NB(bt): Actually, mods don't want to see deleted files. We'll improve the moderator UI later.
query_builder.push(" m.user_deleted_at IS NULL AND m.mod_deleted_at IS NULL ");
}
ViewAs::AnotherUser => {
if !first_predicate_added {
query_builder.push(" WHERE ");
first_predicate_added = true;
@@ -202,10 +202,10 @@ LEFT OUTER JOIN entity_stats
}
match view_as {
ViewAs::Author => {
ViewAs::Author | ViewAs::Moderator => {
// NB(bt): Actually, mods don't want to see deleted files. We'll improve the moderator UI later.
query_builder.push(" AND m.user_deleted_at IS NULL AND m.mod_deleted_at IS NULL ");
}
ViewAs::Moderator => {}
ViewAs::AnotherUser => {
query_builder.push(" AND m.user_deleted_at IS NULL AND m.mod_deleted_at IS NULL ");
// FIXME: Binding shouldn't require to_str().
+1 -3
View File
@@ -1,5 +1,6 @@
pub mod api_tokens;
pub mod audit_logs;
pub mod batch_generations;
pub mod billing;
pub mod comments;
pub mod email_sender_jobs;
@@ -18,12 +19,9 @@ pub mod stats;
pub mod trending_model_analytics;
pub mod tts;
pub mod twitch;
pub mod user_bookmarks;
pub mod users;
pub mod vocoder;
pub mod voice_clone_requests;
pub mod voice_conversion;
pub mod voice_designer;
pub mod w2l;
@@ -21,21 +21,17 @@ pub struct CreateModelWeightsArgs<'a> {
pub maybe_last_update_user_token: Option<String>,
pub original_download_url: Option<String>,
pub original_filename: Option<String>,
pub file_size_bytes: i32,
pub file_size_bytes: u64,
pub file_checksum_sha2: String,
pub public_bucket_hash: String,
pub maybe_public_bucket_prefix: Option<String>,
pub maybe_public_bucket_extension: Option<String>,
//pub cached_user_ratings_total_count: u32,
//pub cached_user_ratings_positive_count: u32,
//pub cached_user_ratings_negative_count: u32,
//pub maybe_cached_user_ratings_ratio: Option<f32>,
pub version: i32,
pub version: u32,
pub mysql_pool: &'a MySqlPool,
}
pub async fn create_weight(args: CreateModelWeightsArgs<'_>) -> AnyhowResult<ModelWeightToken> {
let model_weights_token = ModelWeightToken::generate();
let transaction = args.mysql_pool.begin().await?;
let query_result = sqlx
::query!(
@@ -78,16 +74,12 @@ pub async fn create_weight(args: CreateModelWeightsArgs<'_>) -> AnyhowResult<Mod
args.public_bucket_hash,
args.maybe_public_bucket_prefix,
args.maybe_public_bucket_extension,
//args.cached_user_ratings_total_count,
//args.cached_user_ratings_positive_count,
//args.cached_user_ratings_negative_count,
//args.maybe_cached_user_ratings_ratio,
args.version
)
.execute(args.mysql_pool).await;
match query_result {
Ok(_) => { Ok(model_weights_token) }
Ok(_) => { Ok(args.token.clone()) }
Err(err) => {
transaction.rollback().await?;
warn!("Transaction failure: {:?}", err);
@@ -0,0 +1,138 @@
use anyhow::anyhow;
use chrono::{DateTime, Utc};
use log::error;
use sqlx::{MySql, MySqlPool};
use sqlx::pool::PoolConnection;
use container_common::anyhow_result::AnyhowResult;
use enums::by_table::model_weights::weights_category::WeightsCategory;
use enums::by_table::model_weights::weights_types::WeightsType;
use enums::common::visibility::Visibility;
use tokens::tokens::{model_weights::ModelWeightToken, users::UserToken};
#[derive(Clone, Serialize, Deserialize)]
pub struct ModelWeightForLegacyTtsEnqueue {
pub token: ModelWeightToken,
pub weights_type: WeightsType,
pub weights_category: WeightsCategory,
pub creator_user_token: UserToken,
pub creator_set_visibility: Visibility,
pub user_deleted_at: Option<DateTime<Utc>>,
pub mod_deleted_at: Option<DateTime<Utc>>,
}
pub async fn get_weight_for_legacy_tts_enqueue(
weight_token: &ModelWeightToken,
can_see_deleted: bool,
mysql_pool: &MySqlPool
) -> AnyhowResult<Option<ModelWeightForLegacyTtsEnqueue>> {
let mut connection = mysql_pool.acquire().await?;
get_weight_for_legacy_tts_enqueue_with_connection(weight_token, can_see_deleted, &mut connection).await
}
pub async fn get_weight_for_legacy_tts_enqueue_with_connection(
weight_token: &ModelWeightToken,
can_see_deleted: bool,
mysql_connection: &mut PoolConnection<MySql>
) -> AnyhowResult<Option<ModelWeightForLegacyTtsEnqueue>> {
let maybe_result = if can_see_deleted {
select_include_deleted(weight_token, mysql_connection).await
} else {
select_without_deleted(weight_token, mysql_connection).await
};
let record: RawWeight = match maybe_result {
Ok(record) => record,
Err(sqlx::Error::RowNotFound) => {
return Ok(None);
}
Err(err) => {
error!("Error fetching weights by token: {:?}", err);
return Err(anyhow!("Error fetching weights by token: {:?}", err));
}
};
Ok(Some(ModelWeightForLegacyTtsEnqueue {
token: record.token,
weights_type: record.weights_type,
weights_category: record.weights_category,
creator_user_token: record.creator_user_token,
creator_set_visibility: record.creator_set_visibility,
user_deleted_at: record.user_deleted_at,
mod_deleted_at: record.mod_deleted_at,
}))
}
async fn select_include_deleted(
weight_token: &ModelWeightToken,
mysql_connection: &mut PoolConnection<MySql>
) -> Result<RawWeight, sqlx::Error> {
sqlx
::query_as!(
RawWeight,
r#"
SELECT
wt.token as `token: tokens::tokens::model_weights::ModelWeightToken`,
wt.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,
wt.weights_category as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,
wt.creator_user_token as `creator_user_token: tokens::tokens::users::UserToken`,
wt.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,
wt.user_deleted_at,
wt.mod_deleted_at
FROM model_weights as wt
WHERE
wt.token = ?
"#,
weight_token.as_str()
)
.fetch_one(&mut **mysql_connection).await
}
async fn select_without_deleted(
weight_token: &ModelWeightToken,
mysql_connection: &mut PoolConnection<MySql>
) -> Result<RawWeight, sqlx::Error> {
sqlx
::query_as!(
RawWeight,
r#"
SELECT
wt.token as `token: tokens::tokens::model_weights::ModelWeightToken`,
wt.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,
wt.weights_category as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,
wt.creator_user_token as `creator_user_token: tokens::tokens::users::UserToken`,
wt.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,
wt.user_deleted_at,
wt.mod_deleted_at
FROM model_weights as wt
WHERE
wt.token = ?
AND wt.user_deleted_at IS NULL
AND wt.mod_deleted_at IS NULL
"#,
weight_token.as_str()
)
.fetch_one(&mut **mysql_connection).await
}
// RawWeight is the struct that is returned from the database in raw form.
#[derive(Serialize)]
struct RawWeight {
pub token: ModelWeightToken,
pub weights_type: WeightsType,
pub weights_category: WeightsCategory,
pub creator_user_token: UserToken,
pub creator_set_visibility: Visibility,
pub user_deleted_at: Option<DateTime<Utc>>,
pub mod_deleted_at: Option<DateTime<Utc>>,
}
@@ -0,0 +1,296 @@
use chrono::{DateTime, Utc};
use log::error;
use sqlx::{MySql, MySqlPool};
use sqlx::pool::PoolConnection;
use enums::by_table::model_weights::weights_category::WeightsCategory;
use enums::by_table::model_weights::weights_types::WeightsType;
use enums::common::visibility::Visibility;
use enums::common::vocoder_type::VocoderType;
use tokens::tokens::{model_weights::ModelWeightToken, users::UserToken};
use crate::helpers::boolean_converters::nullable_i8_to_bool_default_false;
use crate::queries::tts::tts_models::get_tts_model_for_inference_improved::{CustomVocoderFields, TtsModelForInferenceError};
#[derive(Clone)]
pub struct ModelWeightForLegacyTtsInference {
pub token: ModelWeightToken,
pub title: String,
pub weights_type: WeightsType,
pub weights_category: WeightsCategory,
pub maybe_description_markdown: Option<String>,
pub maybe_description_rendered_html: Option<String>,
pub creator_user_token: UserToken,
pub creator_username: String,
pub creator_display_name: String,
pub creator_gravatar_hash: String,
pub creator_ip_address: String,
pub creator_set_visibility: Visibility,
pub maybe_last_update_user_token: Option<UserToken>,
pub original_download_url: Option<String>,
pub original_filename: Option<String>,
pub file_size_bytes: i32,
pub file_checksum_sha2: String,
pub public_bucket_hash: String,
pub maybe_public_bucket_prefix: Option<String>,
pub maybe_public_bucket_extension: Option<String>,
pub maybe_cover_image_public_bucket_hash: Option<String>,
pub maybe_cover_image_public_bucket_prefix: Option<String>,
pub maybe_cover_image_public_bucket_extension: Option<String>,
pub maybe_ratings_positive_count: Option<u32>,
pub maybe_ratings_negative_count: Option<u32>,
pub maybe_bookmark_count: Option<u32>,
pub maybe_ietf_language_tag: Option<String>,
pub maybe_ietf_primary_language_subtag: Option<String>,
pub maybe_default_pretrained_vocoder: Option<String>,
pub maybe_text_pipeline_type: Option<String>,
// Joined custom vocoder fields
pub maybe_custom_vocoder: Option<CustomVocoderFields>,
pub use_default_mel_multiply_factor: bool,
pub maybe_custom_mel_multiply_factor: Option<f64>,
pub version: i32,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub user_deleted_at: Option<DateTime<Utc>>,
pub mod_deleted_at: Option<DateTime<Utc>>,
}
pub async fn get_weight_for_legacy_tts_inference(
weight_token: &ModelWeightToken,
mysql_pool: &MySqlPool
) -> Result<Option<ModelWeightForLegacyTtsInference>, TtsModelForInferenceError> {
let mut connection = mysql_pool.acquire()
.await
.map_err(|err| {
error!("Error acquiring db connection from pool: {:?}", err);
TtsModelForInferenceError::DatabaseError {
reason: format!("Mysql connection error: {:?}", err)
}
})?;
get_weight_for_legacy_tts_inference_with_connection(weight_token, &mut connection).await
}
pub async fn get_weight_for_legacy_tts_inference_with_connection(
weight_token: &ModelWeightToken,
mysql_connection: &mut PoolConnection<MySql>
) -> Result<Option<ModelWeightForLegacyTtsInference>, TtsModelForInferenceError> {
let maybe_result = select_include_deleted(weight_token, mysql_connection).await;
let record: RawWeight = match maybe_result {
Ok(record) => record,
Err(sqlx::Error::RowNotFound) => {
return Ok(None);
}
Err(err) => {
error!("Error fetching weights by token: {:?}", err);
return Err(TtsModelForInferenceError::DatabaseError {
reason: format!("Mysql error: {:?}", err)
});
}
};
if record.mod_deleted_at.is_some() || record.user_deleted_at.is_some() {
return Err(TtsModelForInferenceError::ModelDeleted);
}
Ok(Some(ModelWeightForLegacyTtsInference {
token: record.token,
title: record.title,
weights_type: record.weights_type,
weights_category: record.weights_category,
maybe_description_markdown: record.maybe_description_markdown,
maybe_description_rendered_html: record.maybe_description_rendered_html,
creator_user_token: record.creator_user_token,
creator_username: record.creator_username,
creator_display_name: record.creator_display_name,
creator_gravatar_hash: record.creator_gravatar_hash,
creator_ip_address: record.creator_ip_address,
creator_set_visibility: record.creator_set_visibility,
maybe_last_update_user_token: record.maybe_last_update_user_token,
original_download_url: record.original_download_url,
original_filename: record.original_filename,
file_size_bytes: record.file_size_bytes,
file_checksum_sha2: record.file_checksum_sha2,
public_bucket_hash: record.public_bucket_hash,
maybe_public_bucket_prefix: record.maybe_public_bucket_prefix,
maybe_public_bucket_extension: record.maybe_public_bucket_extension,
maybe_cover_image_public_bucket_hash: record.maybe_cover_image_public_bucket_hash,
maybe_cover_image_public_bucket_prefix: record.maybe_cover_image_public_bucket_prefix,
maybe_cover_image_public_bucket_extension: record.maybe_cover_image_public_bucket_extension,
maybe_ratings_positive_count: record.maybe_ratings_positive_count,
maybe_ratings_negative_count: record.maybe_ratings_negative_count,
maybe_bookmark_count: record.maybe_bookmark_count,
maybe_ietf_language_tag: record.maybe_ietf_language_tag,
maybe_ietf_primary_language_subtag: record.maybe_ietf_primary_language_subtag,
maybe_default_pretrained_vocoder: record.maybe_default_pretrained_vocoder,
maybe_text_pipeline_type: record.maybe_text_pipeline_type,
maybe_custom_vocoder: match record.maybe_custom_vocoder_token {
// NB: We're relying on a single field's presence to infer that the others vocoder fields
// are also there. If for some reason they aren't, fail open.
None => None,
Some(vocoder_token) => Some(CustomVocoderFields {
vocoder_token,
vocoder_type: record.maybe_custom_vocoder_type.ok_or(
TtsModelForInferenceError::DatabaseError { reason: "custom_vocoder_type field error".to_string() })?,
vocoder_title: record.maybe_custom_vocoder_title.ok_or(
TtsModelForInferenceError::DatabaseError { reason: "custom_vocoder_title field error".to_string() })?,
vocoder_private_bucket_hash: record.maybe_custom_vocoder_private_bucket_hash.ok_or(
TtsModelForInferenceError::DatabaseError { reason: "vocoder_private_bucket_hash field error".to_string() })?,
})
},
use_default_mel_multiply_factor: nullable_i8_to_bool_default_false(record.use_default_mel_multiply_factor),
maybe_custom_mel_multiply_factor: record.maybe_custom_mel_multiply_factor,
version: record.version,
created_at: record.created_at,
updated_at: record.updated_at,
user_deleted_at: record.user_deleted_at,
mod_deleted_at: record.mod_deleted_at,
}))
}
async fn select_include_deleted(
weight_token: &ModelWeightToken,
mysql_connection: &mut PoolConnection<MySql>
) -> Result<RawWeight, sqlx::Error> {
sqlx
::query_as!(
RawWeight,
r#"
SELECT
wt.token as `token: tokens::tokens::model_weights::ModelWeightToken`,
wt.title,
wt.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,
wt.weights_category as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,
wt.maybe_description_markdown,
wt.maybe_description_rendered_html,
wt.creator_user_token as `creator_user_token: tokens::tokens::users::UserToken`,
users.username as creator_username,
users.display_name as creator_display_name,
users.email_gravatar_hash AS creator_gravatar_hash,
wt.creator_ip_address,
wt.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,
wt.maybe_last_update_user_token as `maybe_last_update_user_token: tokens::tokens::users::UserToken`,
wt.original_download_url,
wt.original_filename,
wt.file_size_bytes,
wt.file_checksum_sha2,
wt.public_bucket_hash,
wt.maybe_public_bucket_prefix,
wt.maybe_public_bucket_extension,
cover_image.public_bucket_directory_hash as maybe_cover_image_public_bucket_hash,
cover_image.maybe_public_bucket_prefix as maybe_cover_image_public_bucket_prefix,
cover_image.maybe_public_bucket_extension as maybe_cover_image_public_bucket_extension,
entity_stats.ratings_positive_count as maybe_ratings_positive_count,
entity_stats.ratings_negative_count as maybe_ratings_negative_count,
entity_stats.bookmark_count as maybe_bookmark_count,
w_extension.ietf_language_tag as maybe_ietf_language_tag,
w_extension.ietf_primary_language_subtag as maybe_ietf_primary_language_subtag,
w_extension.maybe_default_pretrained_vocoder,
w_extension.text_pipeline_type as maybe_text_pipeline_type,
w_extension.use_default_mel_multiply_factor,
w_extension.maybe_custom_mel_multiply_factor,
w_extension.maybe_custom_vocoder_token,
vocoder.vocoder_type as `maybe_custom_vocoder_type: enums::common::vocoder_type::VocoderType`,
vocoder.title as maybe_custom_vocoder_title,
vocoder.private_bucket_hash as maybe_custom_vocoder_private_bucket_hash,
wt.version,
wt.created_at,
wt.updated_at,
wt.user_deleted_at,
wt.mod_deleted_at
FROM model_weights as wt
JOIN users
ON users.token = wt.creator_user_token
LEFT OUTER JOIN media_files as cover_image
ON cover_image.token = wt.maybe_cover_image_media_file_token
LEFT OUTER JOIN entity_stats
ON entity_stats.entity_type = "model_weight"
AND entity_stats.entity_token = wt.token
LEFT OUTER JOIN model_weights_extension_tts_details as w_extension
ON w_extension.model_weights_token = wt.token
LEFT OUTER JOIN vocoder_models AS vocoder
ON vocoder.token = w_extension.maybe_custom_vocoder_token
WHERE
wt.token = ?
"#,
weight_token.as_str()
)
.fetch_one(&mut **mysql_connection).await
}
#[derive(Serialize)]
pub struct RawWeight {
token: ModelWeightToken,
title: String,
weights_type: WeightsType,
weights_category: WeightsCategory,
maybe_description_markdown: Option<String>,
maybe_description_rendered_html: Option<String>,
creator_user_token: UserToken,
creator_username: String,
creator_display_name: String,
creator_gravatar_hash: String,
creator_ip_address: String,
creator_set_visibility: Visibility,
maybe_last_update_user_token: Option<UserToken>,
original_download_url: Option<String>,
original_filename: Option<String>,
file_size_bytes: i32,
file_checksum_sha2: String,
public_bucket_hash: String,
maybe_public_bucket_prefix: Option<String>,
maybe_public_bucket_extension: Option<String>,
maybe_cover_image_public_bucket_hash: Option<String>,
maybe_cover_image_public_bucket_prefix: Option<String>,
maybe_cover_image_public_bucket_extension: Option<String>,
maybe_ratings_positive_count: Option<u32>,
maybe_ratings_negative_count: Option<u32>,
maybe_bookmark_count: Option<u32>,
maybe_ietf_language_tag: Option<String>,
maybe_ietf_primary_language_subtag: Option<String>,
maybe_default_pretrained_vocoder: Option<String>,
maybe_text_pipeline_type: Option<String>,
// Joined custom vocoder fields
maybe_custom_vocoder_token: Option<String>,
maybe_custom_vocoder_type: Option<VocoderType>,
maybe_custom_vocoder_title: Option<String>,
maybe_custom_vocoder_private_bucket_hash: Option<String>,
use_default_mel_multiply_factor: Option<i8>, // bool; note this was *not* optional before, but is because of our join
maybe_custom_mel_multiply_factor: Option<f64>,
version: i32,
created_at: DateTime<Utc>,
updated_at: DateTime<Utc>,
user_deleted_at: Option<DateTime<Utc>>,
mod_deleted_at: Option<DateTime<Utc>>,
}
@@ -0,0 +1,325 @@
use anyhow::anyhow;
use chrono::{DateTime, Utc};
use log::error;
use sqlx::{MySql, MySqlPool};
use sqlx::pool::PoolConnection;
use container_common::anyhow_result::AnyhowResult;
use enums::by_table::model_weights::weights_category::WeightsCategory;
use enums::by_table::model_weights::weights_types::WeightsType;
use enums::common::visibility::Visibility;
use tokens::tokens::{model_weights::ModelWeightToken, users::UserToken};
use crate::column_types::vocoder_type::VocoderType;
#[derive(Serialize, Deserialize, Clone)]
pub struct ModelWeightForLegacyTtsInfo {
pub token: ModelWeightToken,
pub title: String,
pub weights_type: WeightsType,
pub weights_category: WeightsCategory,
pub maybe_description_markdown: Option<String>,
pub maybe_description_rendered_html: Option<String>,
pub creator_user_token: UserToken,
pub creator_username: String,
pub creator_display_name: String,
pub creator_gravatar_hash: String,
pub creator_ip_address: String,
pub creator_set_visibility: Visibility,
pub maybe_last_update_user_token: Option<UserToken>,
pub original_download_url: Option<String>,
pub original_filename: Option<String>,
pub file_size_bytes: i32,
pub file_checksum_sha2: String,
pub public_bucket_hash: String,
pub maybe_public_bucket_prefix: Option<String>,
pub maybe_public_bucket_extension: Option<String>,
pub maybe_cover_image_public_bucket_hash: Option<String>,
pub maybe_cover_image_public_bucket_prefix: Option<String>,
pub maybe_cover_image_public_bucket_extension: Option<String>,
pub maybe_ratings_positive_count: Option<u32>,
pub maybe_ratings_negative_count: Option<u32>,
pub maybe_bookmark_count: Option<u32>,
pub maybe_ietf_language_tag: Option<String>,
pub maybe_ietf_primary_language_subtag: Option<String>,
pub maybe_default_pretrained_vocoder: Option<VocoderType>,
pub maybe_text_pipeline_type: Option<String>,
pub version: i32,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub user_deleted_at: Option<DateTime<Utc>>,
pub mod_deleted_at: Option<DateTime<Utc>>,
}
pub async fn get_weight_for_legacy_tts_info(
weight_token: &ModelWeightToken,
can_see_deleted: bool,
mysql_pool: &MySqlPool
) -> AnyhowResult<Option<ModelWeightForLegacyTtsInfo>> {
let mut connection = mysql_pool.acquire().await?;
get_weight_for_legacy_tts_info_with_connection(weight_token, can_see_deleted, &mut connection).await
}
pub async fn get_weight_for_legacy_tts_info_with_connection(
weight_token: &ModelWeightToken,
can_see_deleted: bool,
mysql_connection: &mut PoolConnection<MySql>
) -> AnyhowResult<Option<ModelWeightForLegacyTtsInfo>> {
let maybe_result = if can_see_deleted {
select_include_deleted(weight_token, mysql_connection).await
} else {
select_without_deleted(weight_token, mysql_connection).await
};
let record: RawWeight = match maybe_result {
Ok(record) => record,
Err(sqlx::Error::RowNotFound) => {
return Ok(None);
}
Err(err) => {
error!("Error fetching weights by token: {:?}", err);
return Err(anyhow!("Error fetching weights by token: {:?}", err));
}
};
// unwrap the result
Ok(
Some(ModelWeightForLegacyTtsInfo {
token: record.token,
title: record.title,
weights_type: record.weights_type,
weights_category: record.weights_category,
maybe_description_markdown: record.maybe_description_markdown,
maybe_description_rendered_html: record.maybe_description_rendered_html,
creator_user_token: record.creator_user_token,
creator_username: record.creator_username,
creator_display_name: record.creator_display_name,
creator_gravatar_hash: record.creator_gravatar_hash,
creator_ip_address: record.creator_ip_address,
creator_set_visibility: record.creator_set_visibility,
maybe_last_update_user_token: record.maybe_last_update_user_token,
original_download_url: record.original_download_url,
original_filename: record.original_filename,
file_size_bytes: record.file_size_bytes,
file_checksum_sha2: record.file_checksum_sha2,
public_bucket_hash: record.public_bucket_hash,
maybe_public_bucket_prefix: record.maybe_public_bucket_prefix,
maybe_public_bucket_extension: record.maybe_public_bucket_extension,
maybe_cover_image_public_bucket_hash: record.maybe_cover_image_public_bucket_hash,
maybe_cover_image_public_bucket_prefix: record.maybe_cover_image_public_bucket_prefix,
maybe_cover_image_public_bucket_extension: record.maybe_cover_image_public_bucket_extension,
maybe_ratings_positive_count: record.maybe_ratings_positive_count,
maybe_ratings_negative_count: record.maybe_ratings_negative_count,
maybe_bookmark_count: record.maybe_bookmark_count,
maybe_ietf_language_tag: record.maybe_ietf_language_tag,
maybe_ietf_primary_language_subtag: record.maybe_ietf_primary_language_subtag,
maybe_default_pretrained_vocoder: record.maybe_default_pretrained_vocoder,
maybe_text_pipeline_type: record.maybe_text_pipeline_type,
version: record.version,
created_at: record.created_at,
updated_at: record.updated_at,
user_deleted_at: record.user_deleted_at,
mod_deleted_at: record.mod_deleted_at,
})
)
}
async fn select_include_deleted(
weight_token: &ModelWeightToken,
mysql_connection: &mut PoolConnection<MySql>
) -> Result<RawWeight, sqlx::Error> {
sqlx
::query_as!(
RawWeight,
r#"
SELECT
wt.token as `token: tokens::tokens::model_weights::ModelWeightToken`,
wt.title,
wt.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,
wt.weights_category as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,
wt.maybe_description_markdown,
wt.maybe_description_rendered_html,
wt.creator_user_token as `creator_user_token: tokens::tokens::users::UserToken`,
users.username as creator_username,
users.display_name as creator_display_name,
users.email_gravatar_hash AS creator_gravatar_hash,
wt.creator_ip_address,
wt.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,
wt.maybe_last_update_user_token as `maybe_last_update_user_token: tokens::tokens::users::UserToken`,
wt.original_download_url,
wt.original_filename,
wt.file_size_bytes,
wt.file_checksum_sha2,
wt.public_bucket_hash,
wt.maybe_public_bucket_prefix,
wt.maybe_public_bucket_extension,
cover_image.public_bucket_directory_hash as maybe_cover_image_public_bucket_hash,
cover_image.maybe_public_bucket_prefix as maybe_cover_image_public_bucket_prefix,
cover_image.maybe_public_bucket_extension as maybe_cover_image_public_bucket_extension,
entity_stats.ratings_positive_count as maybe_ratings_positive_count,
entity_stats.ratings_negative_count as maybe_ratings_negative_count,
entity_stats.bookmark_count as maybe_bookmark_count,
w_extension.ietf_language_tag as maybe_ietf_language_tag,
w_extension.ietf_primary_language_subtag as maybe_ietf_primary_language_subtag,
w_extension.maybe_default_pretrained_vocoder as `maybe_default_pretrained_vocoder: crate::column_types::vocoder_type::VocoderType`,
w_extension.text_pipeline_type as maybe_text_pipeline_type,
wt.version,
wt.created_at,
wt.updated_at,
wt.user_deleted_at,
wt.mod_deleted_at
FROM model_weights as wt
JOIN users
ON users.token = wt.creator_user_token
LEFT OUTER JOIN media_files as cover_image
ON cover_image.token = wt.maybe_cover_image_media_file_token
LEFT OUTER JOIN entity_stats
ON entity_stats.entity_type = "model_weight"
AND entity_stats.entity_token = wt.token
LEFT OUTER JOIN model_weights_extension_tts_details as w_extension
ON w_extension.model_weights_token = wt.token
WHERE
wt.token = ?
"#,
weight_token.as_str()
)
.fetch_one(&mut **mysql_connection).await
}
async fn select_without_deleted(
weight_token: &ModelWeightToken,
mysql_connection: &mut PoolConnection<MySql>
) -> Result<RawWeight, sqlx::Error> {
//as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,
//as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`
sqlx
::query_as!(
RawWeight,
r#"
SELECT
wt.token as `token: tokens::tokens::model_weights::ModelWeightToken`,
wt.title,
wt.weights_type as `weights_type: enums::by_table::model_weights::weights_types::WeightsType`,
wt.weights_category as `weights_category: enums::by_table::model_weights::weights_category::WeightsCategory`,
wt.maybe_description_markdown,
wt.maybe_description_rendered_html,
wt.creator_ip_address,
wt.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,
wt.creator_user_token as `creator_user_token: tokens::tokens::users::UserToken`,
users.username as creator_username,
users.display_name as creator_display_name,
users.email_gravatar_hash AS creator_gravatar_hash,
wt.maybe_last_update_user_token as `maybe_last_update_user_token: tokens::tokens::users::UserToken`,
wt.original_download_url,
wt.original_filename,
wt.file_size_bytes,
wt.file_checksum_sha2,
wt.public_bucket_hash,
wt.maybe_public_bucket_prefix,
wt.maybe_public_bucket_extension,
cover_image.public_bucket_directory_hash as maybe_cover_image_public_bucket_hash,
cover_image.maybe_public_bucket_prefix as maybe_cover_image_public_bucket_prefix,
cover_image.maybe_public_bucket_extension as maybe_cover_image_public_bucket_extension,
entity_stats.ratings_positive_count as maybe_ratings_positive_count,
entity_stats.ratings_negative_count as maybe_ratings_negative_count,
entity_stats.bookmark_count as maybe_bookmark_count,
w_extension.ietf_language_tag as maybe_ietf_language_tag,
w_extension.ietf_primary_language_subtag as maybe_ietf_primary_language_subtag,
w_extension.maybe_default_pretrained_vocoder as `maybe_default_pretrained_vocoder: crate::column_types::vocoder_type::VocoderType`,
w_extension.text_pipeline_type as maybe_text_pipeline_type,
wt.version,
wt.created_at,
wt.updated_at,
wt.user_deleted_at,
wt.mod_deleted_at
FROM model_weights as wt
JOIN users
ON users.token = wt.creator_user_token
LEFT OUTER JOIN media_files as cover_image
ON cover_image.token = wt.maybe_cover_image_media_file_token
LEFT OUTER JOIN entity_stats
ON entity_stats.entity_type = "model_weight"
AND entity_stats.entity_token = wt.token
LEFT OUTER JOIN model_weights_extension_tts_details as w_extension
ON w_extension.model_weights_token = wt.token
WHERE
wt.token = ?
AND wt.user_deleted_at IS NULL
AND wt.mod_deleted_at IS NULL
"#,
weight_token.as_str()
)
.fetch_one(&mut **mysql_connection).await
}
// RawWeight is the struct that is returned from the database in raw form.
#[derive(Serialize)]
pub struct RawWeight {
pub token: ModelWeightToken,
pub title: String,
pub weights_type: WeightsType,
pub weights_category: WeightsCategory,
pub maybe_description_markdown: Option<String>,
pub maybe_description_rendered_html: Option<String>,
pub creator_user_token: UserToken,
pub creator_username: String,
pub creator_display_name: String,
pub creator_gravatar_hash: String,
pub creator_ip_address: String,
pub creator_set_visibility: Visibility,
pub maybe_last_update_user_token: Option<UserToken>,
pub original_download_url: Option<String>,
pub original_filename: Option<String>,
pub file_size_bytes: i32,
pub file_checksum_sha2: String,
pub public_bucket_hash: String,
pub maybe_public_bucket_prefix: Option<String>,
pub maybe_public_bucket_extension: Option<String>,
pub maybe_cover_image_public_bucket_hash: Option<String>,
pub maybe_cover_image_public_bucket_prefix: Option<String>,
pub maybe_cover_image_public_bucket_extension: Option<String>,
pub maybe_ratings_positive_count: Option<u32>,
pub maybe_ratings_negative_count: Option<u32>,
pub maybe_bookmark_count: Option<u32>,
pub maybe_ietf_language_tag: Option<String>,
pub maybe_ietf_primary_language_subtag: Option<String>,
pub maybe_default_pretrained_vocoder: Option<VocoderType>,
pub maybe_text_pipeline_type: Option<String>,
pub version: i32,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub user_deleted_at: Option<DateTime<Utc>>,
pub mod_deleted_at: Option<DateTime<Utc>>,
}
@@ -0,0 +1,4 @@
pub mod get_weight;
pub mod get_weight_for_legacy_tts_enqueue;
pub mod get_weight_for_legacy_tts_inference;
pub mod get_weight_for_legacy_tts_info;

Some files were not shown because too many files have changed in this diff Show More