From fa70526a3d158a96ef2a326da6b7985fe8ce1fc0 Mon Sep 17 00:00:00 2001 From: Montana Low Date: Tue, 2 Jan 2024 21:21:10 -0800 Subject: [PATCH 1/2] deploy specific models --- .../ubuntu-packages-and-docker-image.yml | 2 +- .../ubuntu-postgresml-python-package.yaml | 2 +- pgml-extension/Cargo.lock | 2 +- pgml-extension/Cargo.toml | 2 +- pgml-extension/sql/pgml--2.8.1--2.8.2.sql | 27 ++++++++++++ pgml-extension/src/api.rs | 42 ++++++++++++++++--- pgml-extension/src/orm/project.rs | 4 +- pgml-extension/src/orm/strategy.rs | 3 ++ 8 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 pgml-extension/sql/pgml--2.8.1--2.8.2.sql diff --git a/.github/workflows/ubuntu-packages-and-docker-image.yml b/.github/workflows/ubuntu-packages-and-docker-image.yml index 953c5d969..687b8dc4c 100644 --- a/.github/workflows/ubuntu-packages-and-docker-image.yml +++ b/.github/workflows/ubuntu-packages-and-docker-image.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: inputs: packageVersion: - default: "2.8.1" + default: "2.8.2" jobs: # # PostgresML extension. diff --git a/.github/workflows/ubuntu-postgresml-python-package.yaml b/.github/workflows/ubuntu-postgresml-python-package.yaml index 0e4be9b21..12ef98345 100644 --- a/.github/workflows/ubuntu-postgresml-python-package.yaml +++ b/.github/workflows/ubuntu-postgresml-python-package.yaml @@ -4,7 +4,7 @@ on: workflow_dispatch: inputs: packageVersion: - default: "2.8.1" + default: "2.8.2" jobs: postgresml-python: diff --git a/pgml-extension/Cargo.lock b/pgml-extension/Cargo.lock index 53cca9a37..acf5e52f2 100644 --- a/pgml-extension/Cargo.lock +++ b/pgml-extension/Cargo.lock @@ -1723,7 +1723,7 @@ dependencies = [ [[package]] name = "pgml" -version = "2.8.1" +version = "2.8.2" dependencies = [ "anyhow", "blas", diff --git a/pgml-extension/Cargo.toml b/pgml-extension/Cargo.toml index 01eec880f..ab5fb00dc 100644 --- a/pgml-extension/Cargo.toml +++ b/pgml-extension/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pgml" -version = "2.8.1" +version = "2.8.2" edition = "2021" [lib] diff --git a/pgml-extension/sql/pgml--2.8.1--2.8.2.sql b/pgml-extension/sql/pgml--2.8.1--2.8.2.sql new file mode 100644 index 000000000..2c6264fb9 --- /dev/null +++ b/pgml-extension/sql/pgml--2.8.1--2.8.2.sql @@ -0,0 +1,27 @@ +-- src/api.rs:317 +-- pgml::api::deploy +DROP FUNCTION IF EXISTS pgml."deploy"(BIGINT); +CREATE FUNCTION pgml."deploy"( + "model_id" BIGINT /* i64 */ +) RETURNS TABLE ( + "project" TEXT, /* alloc::string::String */ + "strategy" TEXT, /* alloc::string::String */ + "algorithm" TEXT /* alloc::string::String */ + ) + LANGUAGE c /* Rust */ +AS 'MODULE_PATHNAME', 'deploy_model_wrapper'; + +DROP FUNCTION IF EXISTS pgml."deploy"(text, pgml.Strategy, pgml.Algorithm); +CREATE FUNCTION pgml."deploy"( + "project_name" TEXT, /* &str */ + "strategy" pgml.Strategy, /* pgml::orm::strategy::Strategy */ + "algorithm" pgml.Algorithm DEFAULT NULL /* core::option::Option */ +) RETURNS TABLE ( + "project" TEXT, /* alloc::string::String */ + "strategy" TEXT, /* alloc::string::String */ + "algorithm" TEXT /* alloc::string::String */ + ) + LANGUAGE c /* Rust */ +AS 'MODULE_PATHNAME', 'deploy_strategy_wrapper'; + +ALTER TYPE pgml.strategy ADD VALUE 'specific'; diff --git a/pgml-extension/src/api.rs b/pgml-extension/src/api.rs index 3bf663026..5a4d8a29a 100644 --- a/pgml-extension/src/api.rs +++ b/pgml-extension/src/api.rs @@ -287,7 +287,7 @@ fn train_joint( }; if deploy { - project.deploy(model.id); + project.deploy(model.id, Strategy::new_score); } else { warning!("Not deploying newly trained model."); } @@ -300,8 +300,40 @@ fn train_joint( )]) } -#[pg_extern] -fn deploy( +#[pg_extern(name = "deploy")] +fn deploy_model( + model_id: i64 +) -> TableIterator< + 'static, + ( + name!(project, String), + name!(strategy, String), + name!(algorithm, String), + ), +> { + let model = unwrap_or_error!(Model::find_cached(model_id)); + + let project_id = Spi::get_one_with_args::( + "SELECT projects.id from pgml.projects JOIN pgml.models ON models.project_id = projects.id WHERE models.id = $1", + vec![(PgBuiltInOids::INT8OID.oid(), model_id.into_datum())], + ) + .unwrap(); + + let project_id = + project_id.unwrap_or_else(|| error!("Project does not exist.")); + + let project = Project::find(project_id).unwrap(); + project.deploy(model_id, Strategy::specific); + + TableIterator::new(vec![( + project.name, + Strategy::specific.to_string(), + model.algorithm.to_string(), + )]) +} + +#[pg_extern(name = "deploy")] +fn deploy_strategy( project_name: &str, strategy: Strategy, algorithm: default!(Option, "NULL"), @@ -378,7 +410,7 @@ fn deploy( let algorithm = algorithm.expect("No qualified models exist for this deployment."); let project = Project::find(project_id).unwrap(); - project.deploy(model_id); + project.deploy(model_id, strategy); TableIterator::new(vec![( project_name.to_string(), @@ -922,7 +954,7 @@ fn tune( }; if deploy { - project.deploy(model.id); + project.deploy(model.id, Strategy::new_score); } TableIterator::new(vec![( diff --git a/pgml-extension/src/orm/project.rs b/pgml-extension/src/orm/project.rs index b96bc7a67..a30db3169 100644 --- a/pgml-extension/src/orm/project.rs +++ b/pgml-extension/src/orm/project.rs @@ -89,14 +89,14 @@ impl Project { .unwrap() } - pub fn deploy(&self, model_id: i64) { + pub fn deploy(&self, model_id: i64, strategy: Strategy) { info!("Deploying model id: {:?}", model_id); Spi::get_one_with_args::( "INSERT INTO pgml.deployments (project_id, model_id, strategy) VALUES ($1, $2, $3::pgml.strategy) RETURNING id", vec![ (PgBuiltInOids::INT8OID.oid(), self.id.into_datum()), (PgBuiltInOids::INT8OID.oid(), model_id.into_datum()), - (PgBuiltInOids::TEXTOID.oid(), Strategy::most_recent.to_string().into_datum()), + (PgBuiltInOids::TEXTOID.oid(), strategy.to_string().into_datum()), ], ).unwrap(); let mut projects = PROJECT_ID_TO_DEPLOYED_MODEL_ID.exclusive(); diff --git a/pgml-extension/src/orm/strategy.rs b/pgml-extension/src/orm/strategy.rs index 2e8e54edf..dacc338e8 100644 --- a/pgml-extension/src/orm/strategy.rs +++ b/pgml-extension/src/orm/strategy.rs @@ -8,6 +8,7 @@ pub enum Strategy { best_score, most_recent, rollback, + specific, } impl std::str::FromStr for Strategy { @@ -19,6 +20,7 @@ impl std::str::FromStr for Strategy { "best_score" => Ok(Strategy::best_score), "most_recent" => Ok(Strategy::most_recent), "rollback" => Ok(Strategy::rollback), + "specific" => Ok(Strategy::rollback), _ => Err(()), } } @@ -31,6 +33,7 @@ impl std::string::ToString for Strategy { Strategy::best_score => "best_score".to_string(), Strategy::most_recent => "most_recent".to_string(), Strategy::rollback => "rollback".to_string(), + Strategy::specific => "specific".to_string(), } } } From fa2c864929a0c027c2b4af6cf523283f858cecc8 Mon Sep 17 00:00:00 2001 From: Montana Low Date: Wed, 3 Jan 2024 10:34:32 -0800 Subject: [PATCH 2/2] docs --- pgml-cms/docs/SUMMARY.md | 2 +- .../apis/client-sdks}/collections.md | 0 .../apis/sql-extensions/pgml.deploy.md | 36 ++++++++++++++----- 3 files changed, 29 insertions(+), 9 deletions(-) rename {pgml-docs/docs/guides/sdks => pgml-cms/docs/introduction/apis/client-sdks}/collections.md (100%) diff --git a/pgml-cms/docs/SUMMARY.md b/pgml-cms/docs/SUMMARY.md index 84e656fcb..bfc9ef6a1 100644 --- a/pgml-cms/docs/SUMMARY.md +++ b/pgml-cms/docs/SUMMARY.md @@ -36,7 +36,7 @@ * [pgml.tune()](introduction/apis/sql-extensions/pgml.tune.md) * [Client SDKs](introduction/apis/client-sdks/README.md) * [Overview](introduction/apis/client-sdks/getting-started.md) - * [Collections](../../pgml-docs/docs/guides/sdks/collections.md) + * [Collections](introduction/apis/client-sdks/collections.md) * [Pipelines](introduction/apis/client-sdks/pipelines.md) * [Search](introduction/apis/client-sdks/search.md) * [Tutorials](introduction/apis/client-sdks/tutorials/README.md) diff --git a/pgml-docs/docs/guides/sdks/collections.md b/pgml-cms/docs/introduction/apis/client-sdks/collections.md similarity index 100% rename from pgml-docs/docs/guides/sdks/collections.md rename to pgml-cms/docs/introduction/apis/client-sdks/collections.md diff --git a/pgml-cms/docs/introduction/apis/sql-extensions/pgml.deploy.md b/pgml-cms/docs/introduction/apis/sql-extensions/pgml.deploy.md index e24dabf05..e5c52f793 100644 --- a/pgml-cms/docs/introduction/apis/sql-extensions/pgml.deploy.md +++ b/pgml-cms/docs/introduction/apis/sql-extensions/pgml.deploy.md @@ -26,11 +26,11 @@ pgml.deploy( There are 3 different deployment strategies available: -| Strategy | Description | -| ------------- | --------------------------------------------------------------------------------------------------------------------- | -| `most_recent` | The most recently trained model for this project is immediately deployed, regardless of metrics. | -| `best_score` | The model that achieved the best key metric score is immediately deployed. | -| `rollback` | The model that was last deployed for this project is immediately redeployed, overriding the currently deployed model. | +| Strategy | Description | +| ------------- |--------------------------------------------------------------------------------------------------| +| `most_recent` | The most recently trained model for this project is immediately deployed, regardless of metrics. | +| `best_score` | The model that achieved the best key metric score is immediately deployed. | +| `rollback` | The model that was deployed before to the current one is deployed. | The default deployment behavior allows any algorithm to qualify. It's automatically used during training, but can be manually executed as well: @@ -40,11 +40,12 @@ The default deployment behavior allows any algorithm to qualify. It's automatica #### SQL -
SELECT * FROM pgml.deploy(
-    'Handwritten Digit Image Classifier',
+```sql
+SELECT * FROM pgml.deploy(
+   'Handwritten Digit Image Classifier',
     strategy => 'best_score'
 );
-
+``` #### Output @@ -121,3 +122,22 @@ SELECT * FROM pgml.deploy( Handwritten Digit Image Classifier | rollback | xgboost (1 row) ``` + +### Specific Model IDs + +In the case you need to deploy an exact model that is not the `most_recent` or `best_score`, you may deploy a model by id. Model id's can be found in the `pgml.models` table. + +#### SQL + +```sql +SELECT * FROM pgml.deploy(12); +``` + +#### Output + +```sql + project | strategy | algorithm +------------------------------------+----------+----------- + Handwritten Digit Image Classifier | specific | xgboost +(1 row) +``` pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy