Skip to content

Commit a85b084

Browse files
committed
Update notebook to approve winning verison, and added model package group image to operation manual
1 parent a00bb70 commit a85b084

File tree

3 files changed

+48
-14
lines changed

3 files changed

+48
-14
lines changed

OPERATIONS.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ Having created the A/B Testing Deployment Pipeline, this operations manual provi
44

55
## A/B Testing for Machine Learning models
66

7-
Successful A/B Testing for machine learning models requires measuring how effective predictions are against end users.
8-
It is important to be able to identify users consistently and be able to attribute success actions against the model predictions back to users.
7+
Successful A/B Testing for machine learning models requires measuring how effective predictions are against end users. It is important to be able to identify users consistently and be able to attribute success actions against the model predictions back to users.
98

109
### Conversion Metrics
1110

@@ -46,7 +45,11 @@ The configuration is stored in the CodeCommit source repository by stage name eg
4645
* `epsilon` - The epsilon parameter used by the `EpsilonGreedy` strategy.
4746
* `warmup` - The number of invocations to warm up before applying the strategy.
4847

49-
In addition to the above, you must specify the `champion` and `challenger` model variants for the deployment.
48+
In addition to the above, you must specify the `champion` and `challenger` model variants for the deployment.
49+
50+
These will be loaded from the two Model Package Groups in the registry that include the project name and suffixed with `champion` or `challenger` for example project name `ab-testing-pipeline` these model package groups in the sample notebook:
51+
52+
![\[Model Registry\]](docs/ab-testing-pipeline-model-registry.png)
5053

5154
**Latest Approved Versions**
5255

50.6 KB
Loading

notebook/mab-reviews-helpfulness.ipynb

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@
286286
"cell_type": "markdown",
287287
"metadata": {},
288288
"source": [
289-
"Create new pandas series that concat the label and tokenize values (this should less than 2 minutes)"
289+
"Create new pandas series that concatenates the label and tokenize values (this should less than 2 minutes)"
290290
]
291291
},
292292
{
@@ -587,7 +587,7 @@
587587
"cell_type": "markdown",
588588
"metadata": {},
589589
"source": [
590-
"Now, we can create the pipeline\n"
590+
"Now, we can create the pipeline."
591591
]
592592
},
593593
{
@@ -792,13 +792,13 @@
792792
" latest_model_package_arn = package['ModelPackageArn']\n",
793793
" model_package_version = latest_model_package_arn.split('/')[-1]\n",
794794
" if package['ModelApprovalStatus'] == 'PendingManualApproval':\n",
795-
" print(f\"Approving Version: {model_package_version}\")\n",
795+
" print(f\"Approving Champion Version: {model_package_version}\")\n",
796796
" model_package_update_response = sm_client.update_model_package(\n",
797797
" ModelPackageArn=latest_model_package_arn,\n",
798798
" ModelApprovalStatus=\"Approved\",\n",
799799
" )\n",
800800
" else:\n",
801-
" print(f\"Model Version: {model_package_version} approved\")"
801+
" print(f\"Champion Version: {model_package_version} approved\")"
802802
]
803803
},
804804
{
@@ -900,7 +900,7 @@
900900
"metadata": {},
901901
"outputs": [],
902902
"source": [
903-
"max_jobs = 15\n",
903+
"max_jobs = 9\n",
904904
"objective_name = 'validation:accuracy'\n",
905905
"tuner = HyperparameterTuner(estimator, \n",
906906
" objective_name,\n",
@@ -1091,7 +1091,7 @@
10911091
")\n",
10921092
"\n",
10931093
"model_package_version = model_package.model_package_arn.split('/')[-1]\n",
1094-
"print(f\"Registered and Approved Version: {model_package_version}\")"
1094+
"print(f\"Registered and Approved Challenger Version: {model_package_version}\")"
10951095
]
10961096
},
10971097
{
@@ -1391,8 +1391,9 @@
13911391
" r = requests.put(rest_api, data=json.dumps(payload))\n",
13921392
" return r.status_code, r.json() # Returns 201 if new, or 200 if update\n",
13931393
"\n",
1394-
"def api_invocation(text_array):\n",
1394+
"def api_invocation(user_id, text_array):\n",
13951395
" payload = {\n",
1396+
" \"user_id\": user_id,\n",
13961397
" \"endpoint_name\": endpoint_name, \n",
13971398
" \"content_type\": \"application/json\",\n",
13981399
" \"data\": json.dumps({\"instances\" : text_array, \"configuration\": { \"k\": 1 }}), \n",
@@ -1484,7 +1485,7 @@
14841485
"outputs": [],
14851486
"source": [
14861487
"def api_predict(i):\n",
1487-
" result = api_invocation(input_batch[i])\n",
1488+
" result = api_invocation(i, input_batch[i])\n",
14881489
" if 'predictions' in result:\n",
14891490
" predictions = parse_predictions(result['predictions']) \n",
14901491
" # Join predictions with test results\n",
@@ -1686,9 +1687,11 @@
16861687
"cell_type": "markdown",
16871688
"metadata": {},
16881689
"source": [
1689-
"### Calling the winner\n",
1690+
"## Calling the winner\n",
16901691
"\n",
1691-
"Assuming a normal distribution, lets evaluate a confidence score for the best performing variant."
1692+
"### Evaluate if statistically significant\n",
1693+
"\n",
1694+
"Assuming a normal distribution, let's evaluate a confidence score for the best performing variant."
16921695
]
16931696
},
16941697
{
@@ -1733,6 +1736,34 @@
17331736
"conf"
17341737
]
17351738
},
1739+
{
1740+
"cell_type": "markdown",
1741+
"metadata": {},
1742+
"source": [
1743+
"### Promote Model\n",
1744+
"\n",
1745+
"If our new estimator is a winning model, we can register that model in the `Champion` model package group in the registry to trigger a new deployment with this single variant."
1746+
]
1747+
},
1748+
{
1749+
"cell_type": "code",
1750+
"execution_count": null,
1751+
"metadata": {},
1752+
"outputs": [],
1753+
"source": [
1754+
"model_package = best_estimator.register(\n",
1755+
" content_types=[\"text/plain\"],\n",
1756+
" response_types=[\"text/csv\"],\n",
1757+
" inference_instances=[\"ml.t2.medium\", \"ml.m5.xlarge\"],\n",
1758+
" transform_instances=[\"ml.m5.xlarge\"],\n",
1759+
" model_package_group_name=champion_model_group,\n",
1760+
" approval_status=\"Approved\"\n",
1761+
")\n",
1762+
"\n",
1763+
"model_package_version = model_package.model_package_arn.split('/')[-1]\n",
1764+
"print(f\"Registered and Approved Champion Version: {model_package_version}\")"
1765+
]
1766+
},
17361767
{
17371768
"cell_type": "markdown",
17381769
"metadata": {},
@@ -1825,4 +1856,4 @@
18251856
},
18261857
"nbformat": 4,
18271858
"nbformat_minor": 4
1828-
}
1859+
}

0 commit comments

Comments
 (0)