{"id":1445,"date":"2022-01-05T20:23:32","date_gmt":"2022-01-05T20:23:32","guid":{"rendered":"https:\/\/salarydistribution.com\/machine-learning\/2022\/01\/05\/deploying-ml-models-using-sagemaker-serverless-inference-preview\/"},"modified":"2022-01-05T20:23:32","modified_gmt":"2022-01-05T20:23:32","slug":"deploying-ml-models-using-sagemaker-serverless-inference-preview","status":"publish","type":"post","link":"https:\/\/salarydistribution.com\/machine-learning\/2022\/01\/05\/deploying-ml-models-using-sagemaker-serverless-inference-preview\/","title":{"rendered":"Deploying ML models using SageMaker Serverless Inference (Preview)"},"content":{"rendered":"<div id=\"\">\n<p>Amazon SageMaker Serverless Inference (Preview) was recently announced at re:Invent 2021 as a new model hosting feature that lets customers serve model predictions without having to explicitly provision compute instances or configure scaling policies to handle traffic variations. Serverless Inference is a new deployment capability that complements SageMaker\u2019s existing options for deployment that include: SageMaker Real-Time Inference for workloads with low latency requirements in the order of milliseconds, SageMaker Batch Transform to run predictions on batches of data, and SageMaker Asynchronous Inference for inferences with large payload sizes or requiring long processing times.<\/p>\n<p>Serverless Inference means that you don\u2019t need to configure and manage the underlying infrastructure hosting your models. When you host your model on a Serverless Inference endpoint, simply select the memory and max concurrent invocations. Then, SageMaker will automatically provision, scale, and terminate compute capacity based on the inference request volume. SageMaker Serverless Inference also means that you only pay for the duration of running the inference code and the amount of data processed, not for idle time. Moreover, you can scale to zero to optimize your inference costs.<\/p>\n<p>Serverless Inference is a great choice for customers that have intermittent or unpredictable prediction traffic. For example, a document processing service used to extract and analyze data on a periodic basis. Customers that choose Serverless Inference should make sure that their workloads can tolerate cold starts. A cold start can occur when your endpoint doesn\u2019t receive traffic for a period of time. It can also occur when your concurrent requests exceed the current request usage. The cold start time will depend on your model size, how long it takes to download, and your container startup time.<\/p>\n<p>Let\u2019s look at how it works from a high level view.<\/p>\n<h2>How it works<\/h2>\n<p>A Serverless Inference endpoint can be setup using the AWS Management Console, any standard AWS SDKs, or the AWS CLI. Because Serverless Inference uses the same APIs as SageMaker Hosting persistent endpoints to configure and deploy endpoints, the steps to create a Serverless Inference endpoint are identical. The only modification required is changes to configuration parameters that are setup on your endpoint configuration.<\/p>\n<p><a href=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2022\/01\/03\/ML-6976-image001.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-32057\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2022\/01\/03\/ML-6976-image001.png\" alt=\"\" width=\"702\" height=\"204\"><\/a><\/p>\n<p>To create a Serverless Inference endpoint, you perform three basic steps:<\/p>\n<p><strong>Step 1:<\/strong> Create a SageMaker Model that packages your model artifacts for deployment on SageMaker using the <a href=\"https:\/\/docs.aws.amazon.com\/sagemaker\/latest\/APIReference\/API_CreateModel.html\" target=\"_blank\" rel=\"noopener noreferrer\"><em>CreateModel<\/em><\/a> API. This step can also be done via <a href=\"https:\/\/aws.amazon.com\/cloudformation\/\" target=\"_blank\" rel=\"noopener noreferrer\">AWS CloudFormation<\/a> using the <a href=\"https:\/\/docs.aws.amazon.com\/AWSCloudFormation\/latest\/UserGuide\/aws-resource-sagemaker-model.html\" target=\"_blank\" rel=\"noopener noreferrer\">AWS::SageMaker::Model <\/a>resource.<\/p>\n<p><strong>Step 2:<\/strong> Create an endpoint configuration using the <a href=\"https:\/\/docs.aws.amazon.com\/sagemaker\/latest\/APIReference\/API_CreateEndpointConfig.html\" target=\"_blank\" rel=\"noopener noreferrer\"><em>CreateEndpointConfig <\/em><\/a>API and the new configuration <em>ServerlessConfig<\/em> options, or selecting the serverless option in the AWS Management Console as shown in the following image. Note that this step can also be done via AWS CloudFormation using the <a href=\"https:\/\/docs.aws.amazon.com\/AWSCloudFormation\/latest\/UserGuide\/aws-resource-sagemaker-endpointconfig.html\" target=\"_blank\" rel=\"noopener noreferrer\">AWS::SageMaker::EndpointConfig<\/a> resource. You must specify the <em>Memory Size<\/em> which, at a minimum, should be as big as your runtime model object, and the <em>Max Concurrency<\/em>, which represents the max concurrent invocations for a single endpoint.<\/p>\n<p><a href=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2022\/01\/03\/ML-6976-image003.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-32058\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2022\/01\/03\/ML-6976-image003.png\" alt=\"\" width=\"552\" height=\"239\"><\/a><\/p>\n<p><strong>Step 3:<\/strong> Finally, using the endpoint configuration that you created in Step 2, create your endpoint using either the AWS Management Console, or programmatically using the <a href=\"https:\/\/docs.aws.amazon.com\/sagemaker\/latest\/APIReference\/API_CreateEndpoint.html\" target=\"_blank\" rel=\"noopener noreferrer\"><em>CreateEndpoint<\/em><\/a> API. This step can also be done via <a href=\"https:\/\/aws.amazon.com\/cloudformation\/\" target=\"_blank\" rel=\"noopener noreferrer\">AWS CloudFormation<\/a> using the <a href=\"https:\/\/docs.aws.amazon.com\/AWSCloudFormation\/latest\/UserGuide\/aws-resource-sagemaker-endpoint.html\" target=\"_blank\" rel=\"noopener noreferrer\">AWS::SageMaker::Endpoint<\/a> resource.<\/p>\n<p>That\u2019s it! Then, SageMaker creates an HTTPS URL that you can use to invoke your endpoint through your client applications using the existing runtime client and the <em>invoke_endpoint<\/em> request.<\/p>\n<p><a href=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2022\/01\/03\/ML-6976-image005.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-32059\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2022\/01\/03\/ML-6976-image005.png\" alt=\"\" width=\"892\" height=\"331\"><\/a><\/p>\n<h2>Deep Dive<\/h2>\n<p>Next, we\u2019ll dive deeper into the high-level steps above by showcasing a detailed how-to for creating a new SageMaker Serverless Inference endpoint.<\/p>\n<h3>Setup and training<\/h3>\n<p>For <strong>preview<\/strong> the following <strong>regions<\/strong> are <strong>supported<\/strong> so make sure to create a SageMaker Notebook Instance or SageMaker Studio Notebook in one of these regions: <strong>us-east-1<\/strong>, <strong>us-east-2<\/strong>, <strong>us-west-2<\/strong>, <strong>eu-west-1<\/strong>, <strong>ap-northeast-1<\/strong>, and <strong>ap-southeast-2<\/strong>. For this example, we\u2019ll be using the Amazon provided <a href=\"https:\/\/docs.aws.amazon.com\/sagemaker\/latest\/dg\/xgboost.html\" target=\"_blank\" rel=\"noopener noreferrer\">XGBoost Algorithm<\/a> to solve a regression problem with the <a href=\"https:\/\/archive.ics.uci.edu\/ml\/datasets\/abalone\" target=\"_blank\" rel=\"noopener noreferrer\">Abalone dataset<\/a>. The <a href=\"https:\/\/github.com\/aws\/amazon-sagemaker-examples\/blob\/master\/serverless-inference\/Serverless-Inference-Walkthrough.ipynb\" target=\"_blank\" rel=\"noopener noreferrer\">notebook<\/a> code can be found in the sagemaker-examples repository.<\/p>\n<p>First, we must setup the appropriate SDK clients and retrieve the public dataset for model training. Note that an upgrade to the SDK may be required if you are running on an older version.<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-python\"># Setup clients\nimport boto3\nimport sagemaker\nfrom sagemaker.estimator import Estimator\n\n#client setup\nclient = boto3.client(service_name=\"sagemaker\")\nruntime = boto3.client(service_name=\"sagemaker-runtime\")\n\nboto_session = boto3.session.Session()\nregion = boto_session.region_name\nprint(region)\nsagemaker_session = sagemaker.Session()\nbase_job_prefix = \"xgboost-example\"\nrole = sagemaker.get_execution_role()\nprint(role)\ndefault_bucket = sagemaker_session.default_bucket()\ns3_prefix = base_job_prefix\ntraining_instance_type = \"ml.m5.xlarge\"\n\n# retrieve data\n!aws s3 cp s3:\/\/sagemaker-sample-files\/datasets\/tabular\/uci_abalone\/train_csv\/abalone_dataset1_train.csv .\n# upload data to S3\n!aws s3 cp abalone_dataset1_train.csv s3:\/\/{default_bucket}\/xgboost-regression\/train.csv<\/code><\/pre>\n<\/p><\/div>\n<p>After setting up the clients and downloading the data that will be used to train the model, we can now prepare for model training using SageMaker Training Jobs. In the following, we are performing the steps to configure and fit our model that will be deployed to a serverless endpoint.<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-python\">from sagemaker.inputs import TrainingInput\ntraining_path = f\"s3:\/\/{default_bucket}\/xgboost-regression\/train.csv\"\ntrain_input = TrainingInput(training_path, content_type=\"text\/csv\")\n\nmodel_path = f\"s3:\/\/{default_bucket}\/{s3_prefix}\/xgb_model\"\n\n# retrieve xgboost image\nimage_uri = sagemaker.image_uris.retrieve(\n    framework=\"xgboost\",\n    region=region,\n    version=\"1.0-1\",\n    py_version=\"py3\",\n    instance_type=training_instance_type,\n)\n\n# Configure Training Estimator\nxgb_train = Estimator(\n    image_uri=image_uri,\n    instance_type=training_instance_type,\n    instance_count=1,\n    output_path=model_path,\n    sagemaker_session=sagemaker_session,\n    role=role,\n)\n\n# Set Hyperparameters\nxgb_train.set_hyperparameters(\n    objective=\"reg:linear\",\n    num_round=50,\n    max_depth=5,\n    eta=0.2,\n    gamma=4,\n    min_child_weight=6,\n    subsample=0.7,\n    silent=0,\n)\n\n# Fit model\nxgb_train.fit({\"train\": train_input})<\/code><\/pre>\n<\/p><\/div>\n<h3>Model creation<\/h3>\n<p>Next, we must package our model for deployment on SageMaker. For the Model Creation step, we need two parameters:<em> Image<\/em> and <em>ModelDataUrl<\/em>.<\/p>\n<p><em>Image <\/em>points to the container image for inference. Because we are using a SageMaker managed container, we retrieved this for training under the variable <strong>image_uri<\/strong>, and we can use the same image for inference. If you are bringing your own custom container, then you must supply your own container image that is compatible for hosting on SageMaker as you would today for hosting a SageMaker Hosting persistent endpoint.<\/p>\n<p><em>ModelDataUrl<\/em> points to the <a href=\"https:\/\/aws.amazon.com\/s3\/\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon Simple Storage Service (S3)<\/a> URL for the trained model artifact that we will pull from the training estimator.<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-python\"># Retrieve model data from training job\nmodel_artifacts = xgb_train.model_data\nmodel_artifacts\nfrom time import gmtime, strftime\nmodel_name = \"xgboost-serverless\" + strftime(\"%Y-%m-%d-%H-%M-%S\", gmtime())\nprint(\"Model name: \" + model_name)\n\n# dummy environment variables\nbyo_container_env_vars = {\"SAGEMAKER_CONTAINER_LOG_LEVEL\": \"20\", \"SOME_ENV_VAR\": \"myEnvVar\"}\ncreate_model_response = client.create_model(\n ModelName=model_name,\n Containers=[\n {\n \"Image\": image_uri,\n \"Mode\": \"SingleModel\",\n \"ModelDataUrl\": model_artifacts,\n \"Environment\": byo_container_env_vars,\n }\n ],\n ExecutionRoleArn=role,\n)\n\nprint(\"Model Arn: \" + create_model_response[\"ModelArn\"])<\/code><\/pre>\n<\/p><\/div>\n<p>We can now use our created model to work with creating an Endpoint Configuration, which is where you will add a serverless configuration.<\/p>\n<h3>Endpoint configuration creation<\/h3>\n<p>Up until now, the steps look identical to if you were deploying a SageMaker Hosting endpoint. This next step is the same. However, you\u2019ll take advantage of a new serverless configuration option in your endpoint configuration. There are two inputs required, and they can be configured to meet your use case:<\/p>\n<ul>\n<li><em>MaxConcurrency:<\/em> This can be set from <strong>1 to 50<\/strong>.<\/li>\n<li><em>Memory Size: <\/em>This can be the following values: <strong>1024 MB, 2048 MB, 3072 MB, 4096 MB, 5120 MB, or 6144 MB.<\/strong><\/li>\n<\/ul>\n<div class=\"hide-language\">\n<pre><code class=\"lang-python\">xgboost_epc_name = \"xgboost-serverless-epc\" + strftime(\"%Y-%m-%d-%H-%M-%S\", gmtime())\n\nendpoint_config_response = client.create_endpoint_config(\n    EndpointConfigName=xgboost_epc_name,\n    ProductionVariants=[\n        {\n        \"VariantName\": \"byoVariant\",\n        \"ModelName\": model_name,\n        \"ServerlessConfig\": {\n        \"MemorySizeInMB\": 4096,\n        \"MaxConcurrency\": 1,\n        },\n        },\n    ],\n)\nprint(\"Endpoint Configuration Arn: \" + endpoint_config_response[\"EndpointConfigArn\"])<\/code><\/pre>\n<\/p><\/div>\n<p>The configuration above indicates that this endpoint should be deployed as a serverless endpoint because we specified configuration options in <em>ServerlessConfig.<\/em><\/p>\n<h3>Endpoint creation and invocation<\/h3>\n<p>Next, we use the Endpoint Configuration to create our endpoint using the create_endpoint function.<\/p>\n<p>The following step should take a few minutes to deploy successfully.<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-python\">endpoint_name = \"xgboost-serverless-ep\" + strftime(\"%Y-%m-%d-%H-%M-%S\", gmtime())\ncreate_endpoint_response = client.create_endpoint(\n    EndpointName=endpoint_name,\n    EndpointConfigName=xgboost_epc_name,\n)\n\nprint(\"Endpoint Arn: \" + create_endpoint_response[\"EndpointArn\"])\n\n# wait for endpoint to reach a terminal state (InService) using describe endpoint\nimport time\ndescribe_endpoint_response = client.describe_endpoint(EndpointName=endpoint_name)\nwhile describe_endpoint_response[\"EndpointStatus\"] == \"Creating\":\n describe_endpoint_response = client.describe_endpoint(EndpointName=endpoint_name)\n print(describe_endpoint_response[\"EndpointStatus\"])\n time.sleep(15)\n\ndescribe_endpoint_response<\/code><\/pre>\n<\/p><\/div>\n<p>The created endpoint should display the Serverless Configuration that you provided in the previous step.<\/p>\n<p><a href=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2022\/01\/03\/ML-6976-image007.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-32060\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2022\/01\/03\/ML-6976-image007.png\" alt=\"\" width=\"1432\" height=\"416\"><\/a><\/p>\n<p>Now we can invoke the endpoint with a sample data point from the Abalone dataset.<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-python\">response = runtime.invoke_endpoint(\n    EndpointName=endpoint_name,\n    Body=b\".345,0.224414,.131102,0.042329,.279923,-0.110329,-0.099358,0.0\",\n    ContentType=\"text\/csv\",\n)\n\nprint(response[\"Body\"].read())<\/code><\/pre>\n<\/p><\/div>\n<h3>Monitoring<\/h3>\n<p>Serverless Inference emits metrics to Amazon CloudWatch. These metrics include the metrics that are emitted for SageMaker Hosting persistent endpoints, such as <em>MemoryUtilization <\/em>and <em>Invocations,<\/em> as well as a new metric called <em>ModelSetupTime<\/em>. This new metric tracks the time that it takes to launch new compute resources for your serverless endpoint.<\/p>\n<h2>Conclusion<\/h2>\n<p>In this post, we covered the high level steps for using Serverless Inference, as well as a deep dive on a specific example to help you get started with the new feature using the example provided in <a href=\"https:\/\/github.com\/aws\/amazon-sagemaker-examples\/blob\/master\/serverless-inference\/Serverless-Inference-Walkthrough.ipynb\" target=\"_blank\" rel=\"noopener noreferrer\">SageMaker examples on GitHub<\/a>. Serverless Inference is currently launched in preview, so we don\u2019t yet recommend it for production workloads. There are some features that Serverless Inference doesn\u2019t support yet, such as SageMaker Model Monitor, Multi-Model Endpoints, and Serial Inference Pipelines.<\/p>\n<p>Please check out the Feature Exclusions portion of the <a href=\"https:\/\/docs.aws.amazon.com\/sagemaker\/latest\/dg\/serverless-endpoints.html\" target=\"_blank\" rel=\"noopener noreferrer\">documentation<\/a> for additional information. The <a href=\"https:\/\/docs.aws.amazon.com\/sagemaker\/latest\/dg\/serverless-endpoints.html\" target=\"_blank\" rel=\"noopener noreferrer\">SageMaker Serverless Inference Documentation<\/a> is also a great resource for diving deeper into Serverless Inference capabilities, and we\u2019re excited to start getting customer feedback!<\/p>\n<hr>\n<h3>About the Authors<\/h3>\n<p><strong><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-28445 alignleft\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/09\/23\/Ram-Vegiraju.jpg\" alt=\"\" width=\"99\" height=\"115\">Ram Vegiraju<\/strong>\u00a0is a ML Architect with the SageMaker Service team. He focuses on helping customers build and optimize their AI\/ML solutions on Amazon SageMaker. In his spare time, he loves traveling and writing.<\/p>\n<p><strong><a href=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2019\/11\/25\/shelbees-100.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-10409 alignleft\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2019\/11\/25\/shelbees-100.jpg\" alt=\"\" width=\"100\" height=\"148\"><\/a>Shelbee Eigenbrode\u00a0<\/strong>is a Principal AI and Machine Learning Specialist Solutions Architect at Amazon Web Services (AWS). She holds six AWS certifications and has been in technology for 23 years spanning multiple industries, technologies, and roles. She is currently focusing on combining her DevOps and ML background to deliver and manage ML workloads at scale. With over 35 patents granted across various technology domains, she has a passion for continuous innovation and using data to drive business outcomes. Shelbee co-founded the Denver chapter of Women in Big Data.<\/p>\n<p><strong><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-17338 alignleft\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2020\/10\/21\/michaelpham.jpg\" alt=\"\" width=\"100\" height=\"136\">Michael Pham<\/strong>\u00a0is a Software Development Engineer in the Amazon SageMaker team. His current work focuses on helping developers efficiently host machine learning models. In his spare time he enjoys Olympic weightlifting, reading, and playing chess.<\/p>\n<p><strong><a href=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2022\/01\/04\/Rishabh-Ray-Chaudhury.png\"><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-32098 alignleft\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2022\/01\/04\/Rishabh-Ray-Chaudhury.png\" alt=\"\" width=\"100\" height=\"133\"><\/a>Rishabh Ray Chaudhury<\/strong> is a Senior Product Manager with Amazon SageMaker, focusing on Machine Learning inference. He is passionate about innovating and building new experiences for Machine Learning customers on AWS to help scale their workloads. In his spare time, he enjoys traveling and cooking. You can find him on <a href=\"https:\/\/www.linkedin.com\/in\/rishabh-ray-chaudhury-58528030\/\" target=\"_blank\" rel=\"noopener noreferrer\">LinkedIn<\/a>.<\/p>\n<p>       <!-- '\"` -->\n      <\/div>\n","protected":false},"excerpt":{"rendered":"<p>https:\/\/aws.amazon.com\/blogs\/machine-learning\/deploying-ml-models-using-sagemaker-serverless-inference-preview\/<\/p>\n","protected":false},"author":0,"featured_media":1446,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[],"_links":{"self":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/posts\/1445"}],"collection":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/comments?post=1445"}],"version-history":[{"count":0,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/posts\/1445\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/media\/1446"}],"wp:attachment":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/media?parent=1445"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/categories?post=1445"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/tags?post=1445"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}