	{"id":60209,"date":"2021-03-30T09:27:37","date_gmt":"2021-03-30T08:27:37","guid":{"rendered":"https:\/\/www.artefact.com\/?post_type=news&#038;p=60209"},"modified":"2024-09-20T17:45:41","modified_gmt":"2024-09-20T16:45:41","slug":"serving-fastai-models-with-google-cloud-ai-platform","status":"publish","type":"blog","link":"https:\/\/www.artefact.com\/zh\/blog\/serving-fastai-models-with-google-cloud-ai-platform\/","title":{"rendered":"\u4f7f\u7528\u8c37\u6b4c\u4e91\u4eba\u5de5\u667a\u80fd\u5e73\u53f0\u4e3a FastAI \u6a21\u578b\u63d0\u4f9b\u670d\u52a1"},"content":{"rendered":"<p><div class=\"fusion-fullwidth fullwidth-box fusion-builder-row-1 fusion-flex-container nonhundred-percent-fullwidth non-hundred-percent-height-scrolling article-author\" style=\"--awb-border-radius-top-left:0px;--awb-border-radius-top-right:0px;--awb-border-radius-bottom-right:0px;--awb-border-radius-bottom-left:0px;--awb-background-color:#ffffff;--awb-flex-wrap:wrap;\" ><div class=\"fusion-builder-row fusion-row fusion-flex-align-items-flex-start fusion-flex-content-wrap\" style=\"max-width:calc( 1440px + 20px );margin-left: calc(-20px \/ 2 );margin-right: calc(-20px \/ 2 );\"><div class=\"fusion-layout-column fusion_builder_column fusion-builder-column-0 fusion_builder_column_1_2 1_2 fusion-flex-column\" style=\"--awb-bg-size:cover;--awb-width-large:50%;--awb-margin-top-large:0px;--awb-spacing-right-large:10px;--awb-margin-bottom-large:0px;--awb-spacing-left-large:10px;--awb-width-medium:50%;--awb-order-medium:0;--awb-spacing-right-medium:10px;--awb-spacing-left-medium:10px;--awb-width-small:100%;--awb-order-small:0;--awb-spacing-right-small:10px;--awb-spacing-left-small:10px;\"><div class=\"fusion-column-wrapper fusion-column-has-shadow fusion-flex-justify-content-flex-start fusion-content-layout-column\"><div class=\"fusion-title title fusion-title-1 fusion-sep-none fusion-title-text fusion-title-size-two\" style=\"--awb-margin-bottom-small:8px;\"><h2 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:50;line-height:1.2;\">Author<\/h2><\/div><img decoding=\"async\" src=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%27150%27%20height%3D%270%27%20viewBox%3D%270%200%20150%200%27%3E%3Crect%20width%3D%27150%27%20height%3D%270%27%20fill-opacity%3D%220%22%2F%3E%3C%2Fsvg%3E\" data-orig-src=\"https:\/\/www.artefact.com\/\/wp-content\/uploads\/2021\/04\/amale-elhamri.jpeg\" alt=\"Image\" class=\"lazyload artefact-elegant-image align-left article-author-image\" style=\"width: 150px; border-radius: 54% 46% 77% 23% \/ 74% 40% 60% 26%; overflow: hidden;\" width=\"150\" height=\"auto\" \/><div class=\"fusion-title title fusion-title-2 fusion-sep-none fusion-title-text fusion-title-size-three article-author-name-title\" style=\"--awb-margin-bottom-small:8px;\"><h3 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:20;line-height:1.2;\">Amale Elhamri<\/h3><\/div><div class=\"fusion-text fusion-text-1 article-author-description\"><p>Senior Data Scientist at Artefact France<\/p>\n<\/div><\/div><\/div><\/div><\/div><div class=\"fusion-fullwidth fullwidth-box fusion-builder-row-2 fusion-flex-container nonhundred-percent-fullwidth non-hundred-percent-height-scrolling\" style=\"--awb-border-radius-top-left:0px;--awb-border-radius-top-right:0px;--awb-border-radius-bottom-right:0px;--awb-border-radius-bottom-left:0px;--awb-flex-wrap:wrap;\" ><div class=\"fusion-builder-row fusion-row fusion-flex-align-items-flex-start fusion-flex-content-wrap\" style=\"max-width:calc( 1440px + 20px );margin-left: calc(-20px \/ 2 );margin-right: calc(-20px \/ 2 );\"><div class=\"fusion-layout-column fusion_builder_column fusion-builder-column-1 fusion_builder_column_1_1 1_1 fusion-flex-column\" style=\"--awb-bg-size:cover;--awb-width-large:100%;--awb-margin-top-large:0px;--awb-spacing-right-large:10px;--awb-margin-bottom-large:0px;--awb-spacing-left-large:10px;--awb-width-medium:100%;--awb-order-medium:0;--awb-spacing-right-medium:10px;--awb-spacing-left-medium:10px;--awb-width-small:100%;--awb-order-small:0;--awb-spacing-right-small:10px;--awb-spacing-left-small:10px;\"><div class=\"fusion-column-wrapper fusion-column-has-shadow fusion-flex-justify-content-flex-start fusion-content-layout-column\"><div class=\"fusion-image-element\" style=\"--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);\"><span class=\" fusion-imageframe imageframe-none imageframe-1 hover-type-none\"><img decoding=\"async\" width=\"300\" height=\"74\" title=\"Medium Blog\" src=\"https:\/\/www.artefact.com\/\/wp-content\/uploads\/2021\/04\/Medium-Blog.png\" data-orig-src=\"https:\/\/www.artefact.com\/\/wp-content\/uploads\/2021\/04\/Medium-Blog-300x74.png\" alt class=\"lazyload img-responsive wp-image-60582\" srcset=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%274000%27%20height%3D%27992%27%20viewBox%3D%270%200%204000%20992%27%3E%3Crect%20width%3D%274000%27%20height%3D%27992%27%20fill-opacity%3D%220%22%2F%3E%3C%2Fsvg%3E\" data-srcset=\"https:\/\/www.artefact.com\/\/wp-content\/uploads\/2021\/04\/Medium-Blog-200x50.png 200w, https:\/\/www.artefact.com\/\/wp-content\/uploads\/2021\/04\/Medium-Blog-400x99.png 400w, https:\/\/www.artefact.com\/\/wp-content\/uploads\/2021\/04\/Medium-Blog-600x149.png 600w, https:\/\/www.artefact.com\/\/wp-content\/uploads\/2021\/04\/Medium-Blog-800x198.png 800w, https:\/\/www.artefact.com\/\/wp-content\/uploads\/2021\/04\/Medium-Blog-1200x298.png 1200w\" data-sizes=\"auto\" data-orig-sizes=\"(max-width: 640px) 100vw, 300px\" \/><\/span><\/div><div class=\"fusion-text fusion-text-2 description\"><p>30 March 2021<br \/>\nIn this second article of the series of two, I will dive into the deployment and the serving of our models at scale. If you missed the first one about training a fastai model at scale on AI Platform Training, here is the <a href=\"https:\/\/medium.com\/artefact-engineering-and-data-science\/automating-the-training-of-ml-models-with-google-cloud-ai-platform-318712629974\" rel=\"noopener\" target=\"_blank\">link<\/a>.<\/p>\n<\/div><\/div><\/div><\/div><\/div><article class=\"fusion-fullwidth fullwidth-box fusion-builder-row-3 fusion-flex-container nonhundred-percent-fullwidth non-hundred-percent-height-scrolling\" style=\"--awb-border-radius-top-left:0px;--awb-border-radius-top-right:0px;--awb-border-radius-bottom-right:0px;--awb-border-radius-bottom-left:0px;--awb-flex-wrap:wrap;\" ><div class=\"fusion-builder-row fusion-row fusion-flex-align-items-flex-start fusion-flex-justify-content-center fusion-flex-content-wrap\" style=\"max-width:calc( 1440px + 20px );margin-left: calc(-20px \/ 2 );margin-right: calc(-20px \/ 2 );\"><div class=\"fusion-layout-column fusion_builder_column fusion-builder-column-2 fusion_builder_column_1_1 1_1 fusion-flex-column\" style=\"--awb-bg-size:cover;--awb-width-large:100%;--awb-margin-top-large:0px;--awb-spacing-right-large:10px;--awb-margin-bottom-large:0px;--awb-spacing-left-large:10px;--awb-width-medium:100%;--awb-order-medium:0;--awb-spacing-right-medium:10px;--awb-spacing-left-medium:10px;--awb-width-small:100%;--awb-order-small:0;--awb-spacing-right-small:10px;--awb-spacing-left-small:10px;\"><div class=\"fusion-column-wrapper fusion-column-has-shadow fusion-flex-justify-content-flex-start fusion-content-layout-column\"><div class=\"fusion-title title fusion-title-3 fusion-sep-none fusion-title-text fusion-title-size-two\" style=\"--awb-margin-bottom-small:8px;\"><h2 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:50;line-height:1.2;\">TL;DR<\/h2><\/div><div class=\"fusion-text fusion-text-3\"><p>In this second article of the series of two, I will dive into the deployment and the serving of our models at scale. If you missed the first one about training a fastai model at scale on AI Platform Training, here is the <a href=\"https:\/\/medium.com\/artefact-engineering-and-data-science\/automating-the-training-of-ml-models-with-google-cloud-ai-platform-318712629974\" target=\"_blank\" rel=\"noopener\">link<\/a>.<\/p>\n<\/div><div class=\"fusion-text fusion-text-4\"><p>Serving a deep learning model can reveal several challenges among which:<\/p>\n<\/div><ul style=\"--awb-line-height:27.2px;--awb-icon-width:27.2px;--awb-icon-height:27.2px;--awb-icon-margin:11.2px;--awb-content-margin:38.4px;\" class=\"fusion-checklist fusion-checklist-1 fusion-checklist-default type-icons\"><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon fa-angle-right fas\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p>scaling resources on instances with or without accelerators (NVIDIA GPUs)<\/p>\n<\/div><\/li><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon fa-angle-right fas\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p>cost efficiency<\/p>\n<\/div><\/li><\/ul><div class=\"fusion-text fusion-text-5\"><p>In this article, I will explain how I served a deep learning text classifier trained with the FastAI library following 2 main steps:<\/p>\n<\/div><ul style=\"--awb-line-height:27.2px;--awb-icon-width:27.2px;--awb-icon-height:27.2px;--awb-icon-margin:11.2px;--awb-content-margin:38.4px;\" class=\"fusion-checklist fusion-checklist-2 fusion-checklist-default type-icons\"><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p>Deploy fastai model using TorchServe<\/p>\n<\/div><\/li><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p>Host serving on GCP AI Platform Prediction<\/p>\n<\/div><\/li><\/ul><div class=\"fusion-text fusion-text-6\"><p>All materials can be found in the <a href=\"https:\/\/github.com\/artefactory\/deploy-fastai-torchserve-aiplatform\" target=\"_blank\" rel=\"noopener\">g<\/a><a href=\"https:\/\/github.com\/artefactory\/deploy-fastai-torchserve-aiplatform\" target=\"_blank\" rel=\"noopener\">ithub repository<\/a>. This repository was inspired by another project that aimed to deploy a fastai image classifier on AWS SageMaker Inference Endpoint <a href=\"https:\/\/github.com\/aws-samples\/amazon-sagemaker-endpoint-deployment-of-fastai-model-with-torchserve\" target=\"_blank\" rel=\"noopener\">here<\/a>.<\/p>\n<\/div><div class=\"fusion-title title fusion-title-4 fusion-sep-none fusion-title-text fusion-title-size-two\" style=\"--awb-margin-bottom-small:8px;\"><h2 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:50;line-height:1.2;\">1- Deploy fastai model using TorchServe<\/h2><\/div><div class=\"fusion-text fusion-text-7\"><p>TorchServe makes it easy to deploy PyTorch models at scale in production environments. It removes the heavy lifting of developing your own client server architecture. The FastAI library is based on the PyTorch framework. It makes it possible to use this technology to serve fastai models by loading your fastai model as a pure pytorch object (remove fastai abstraction).<\/p>\n<\/div><div class=\"fusion-title title fusion-title-5 fusion-sep-none fusion-title-text fusion-title-size-three\" style=\"--awb-margin-bottom-small:8px;\"><h3 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:20;line-height:1.2;\">1\u20131 Export Model Weights from FastAI<\/h3><\/div><div class=\"fusion-text fusion-text-8\"><p>To do that, you need to restore the FastAI learner from the export pickle from the last post, and save its model weights with PyTorch.<\/p>\n<\/div><div class=\"fusion-text fusion-text-9\"><div class=\"code\">import torch<br \/>\nfrom fastai.text import load_learner<br \/>\nfrom fastai.text.learner import get_c, get_text_vocab<br \/>\nlearn = load_learner(&#8220;fastai_cls.pkl&#8221;)<br \/>\nvocab_sz = len(_get_text_vocab(dls)) #dls is the dataloader you used for training<br \/>\nn_class = get_c(dls)<br \/>\nconfig = awd_lstm_clas_config.copy()<br \/>\ntorch.save(learn.model.state_dict(), &#8220;fastai_cls_weights.pth&#8221;)<\/div>\n<\/div><div class=\"fusion-title title fusion-title-6 fusion-sep-none fusion-title-text fusion-title-size-three\" style=\"--awb-margin-bottom-small:8px;\"><h3 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:20;line-height:1.2;\">1\u20132 PyTorch Model from FastAI<\/h3><\/div><div class=\"fusion-text fusion-text-10\"><p>Once you\u2019ve exported your pytorch weights, you need to rebuild the model structure to be able to load your weights into it. You might have to dig a little bit in fastai source code to find your implementation but luckily, In Jupyter notebook, one can investigate the source code by adding ?? in front of a function name.<\/p>\n<\/div><div class=\"fusion-text fusion-text-11\"><p>For text classifier, you can load a pure pytorch object by using the fastai get_text_classifier function<\/p>\n<\/div><div class=\"fusion-text fusion-text-12\"><div class=\"code\">from fastai.text.learner import get_text_classifier<br \/>\nfrom fastai.text.all import AWD_LSTM<br \/>\ntorch_pure_model = get_text_classifier(AWD_LSTM, vocab_sz, n_class, config=config)<\/div>\n<\/div><div class=\"fusion-title title fusion-title-7 fusion-sep-none fusion-title-text fusion-title-size-three\" style=\"--awb-margin-bottom-small:8px;\"><h3 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:20;line-height:1.2;\">1\u20133 Reproduce fastai preprocessing steps<\/h3><\/div><div class=\"fusion-text fusion-text-13\"><p>Once you have obtained your pytorch pure model, you need to apply the same preprocessing that was used for training. FastAI has a very handy method .predict that can be applied to a text (simple string object), that naturally reproduces training preprocessing and therefore removes risk of training serving skew.<\/p>\n<\/div><div class=\"fusion-text fusion-text-14\"><div class=\"code\">text = &#8220;This was a very good movie&#8221;<br \/>\npred_fastai = learn.predict(text)<br \/>\npred_fastai<br \/>\n&gt;&gt;(Category tensor(1), tensor(1), tensor([0.0036, 0.9964]))<\/div>\n<\/div><div class=\"fusion-text fusion-text-15\"><p>In our case, we have to take this responsibility ourselves, since we need to get rid of fastai abstraction and work directly with PyTorch objects.<\/p>\n<\/div><div class=\"fusion-text fusion-text-16\"><p>In my example, I used a spacy tokenizer so I reproduced fastai preprocessing as shown below:<br \/>\nimport torch<\/p>\n<\/div><div class=\"fusion-text fusion-text-17\"><div class=\"code\">import torch<br \/>\nfrom fastai.text.core import Tokenizer, SpacyTokenizerfrom fastai.text.data import Numericalize<br \/>\nexample = &#8220;Hello, this is a test.&#8221;<br \/>\ntokenizer = Tokenizer(<br \/>\ntok=SpacyTokenizer(&#8220;en&#8221;)<br \/>\n)<br \/>\nnumericalizer = Numericalize(vocab=vocab)<br \/>\nexample_processed = numericalizer(tokenizer(example))<br \/>\nexample_processed<br \/>\n&gt;&gt;&gt; tensor([ 4, 7, 26, 29, 16, 72, 69, 31])<br \/>\ninputs = example_processed.resize(1, len(example_processed))<br \/>\noutputs = model_torch.forward(inputs)[0]\npreds = torch.softmax(outputs, dim=-1) #You can use any activation function you need<br \/>\npreds<br \/>\n&gt;&gt;&gt; tensor([[0.0036, 0.9964]], grad_fn=)<\/div>\n<\/div><div class=\"fusion-text fusion-text-18\"><p>As you can notice, the results I get using torch functions and learn.predict are the same because I managed to preserve the same preprocessing steps.<\/p>\n<\/div><div class=\"fusion-title title fusion-title-8 fusion-sep-none fusion-title-text fusion-title-size-three\" style=\"--awb-margin-bottom-small:8px;\"><h3 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:20;line-height:1.2;\">1\u20134 Deploy your model via torchserve<\/h3><\/div><div class=\"fusion-text fusion-text-19\"><p>In this section we deploy the PyTorch model to TorchServe. For installation, please refer to TorchServe Github Repository.<br \/>\nOverall, there are mainly 3 steps to use TorchServe:<\/p>\n<ol>\n<li>Archive the model into *.mar.<\/li>\n<li>Start the torchserve.<\/li>\n<\/ol>\n<p>Call the API and get the response.<br \/>\nIn order to archive the model, at least 2 files are needed in our case:<\/p>\n<ol>\n<li>PyTorch model weights fastai_cls_weights.pth.<\/li>\n<li>TorchServe custom handler.<\/li>\n<\/ol>\n<\/div><div class=\"fusion-title title fusion-title-9 fusion-sep-none fusion-title-text fusion-title-size-three\" style=\"--awb-margin-bottom-small:8px;\"><h3 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:20;line-height:1.2;\">Custom Handler<\/h3><\/div><div class=\"fusion-text fusion-text-20\"><p>As shown in \/deployment\/handler.py, the TorchServe handler accepts data and context. In our example, we define another helper Python class with 4 instance methods to implement: initialize, preprocess, inference and postprocess.<\/p>\n<\/div><div class=\"fusion-text fusion-text-21\"><p>Now it\u2019s ready to setup and launch TorchServe.<\/p>\n<\/div><div class=\"fusion-title title fusion-title-10 fusion-sep-none fusion-title-text fusion-title-size-three\" style=\"--awb-margin-bottom-small:8px;\"><h3 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:20;line-height:1.2;\">TorchServe in Action<\/h3><\/div><div class=\"fusion-title title fusion-title-11 fusion-sep-none fusion-title-text fusion-title-size-six\" style=\"--awb-margin-bottom-small:8px;\"><h6 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:18;line-height:1.33;\">Step 1: Archive the model PyTorch<\/h6><\/div><div class=\"fusion-text fusion-text-22\"><div class=\"code\">torch-model-archiver<br \/>\n\u2014-model-name=fastai_model<br \/>\n&#8211;version=1.0<br \/>\n&#8211;serialized-file=\/home\/model-server\/fastai_cls_weights.pth<br \/>\n\u2014- extra-files=\/home\/model-server\/config.py,\/home\/model-server\/vocab.json<br \/>\n&#8211;handler=\/home\/model-server\/handler.py<br \/>\n\u2014-export-path=\/home\/model-server\/model-store\/<\/div>\n<\/div><div class=\"fusion-title title fusion-title-12 fusion-sep-none fusion-title-text fusion-title-size-six\" style=\"--awb-margin-bottom-small:8px;\"><h6 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:18;line-height:1.33;\">Step 2: Serve the Model<\/h6><\/div><div class=\"fusion-text fusion-text-23\"><div class=\"code\">torchserve &#8211;start &#8211;ncs &#8211;model-store model_store &#8211;models fastai_model.mar<\/div>\n<\/div><div class=\"fusion-title title fusion-title-13 fusion-sep-none fusion-title-text fusion-title-size-six\" style=\"--awb-margin-bottom-small:8px;\"><h6 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:18;line-height:1.33;\">Step 3: Call API and Get the Response (here we use curl).<\/h6><\/div><div class=\"fusion-text fusion-text-24\"><div class=\"code\">curl -X POST -H \"Content-Type: application\/json\" -d '[\"this was a bad movie\"]' http:\/\/127.0.0.1:8080\/predictions\/fastai_model\n<\/div>\n<\/div><div class=\"fusion-text fusion-text-25\"><p>The first call would have longer latency due to model weights loading defined in initialize, but this will be mitigated from the second call onward.<\/p>\n<\/div><div class=\"fusion-title title fusion-title-14 fusion-sep-none fusion-title-text fusion-title-size-two\" style=\"--awb-margin-bottom-small:8px;\"><h2 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:50;line-height:1.2;\">2- Deployment to AI Platform Prediction<\/h2><\/div><div class=\"fusion-text fusion-text-26\"><p>In this section we deploy the FastAI trained model with TorchServe in GCP AI Platform Prediction using a customized Docker image. For more details about GCP AI Platform Prediction routines using custom containers please refer to this article. Note that this option is only available if you use AI Platform Prediction with regional endpoints.<\/p>\n<\/div><div class=\"fusion-text fusion-text-27\"><p>Steps to deploy a fastai model on AI Platform Prediction:<\/p>\n<\/div><div class=\"fusion-text fusion-text-28\"><p>First, create an AI Platform Prediction model on a regional endpoint:<\/p>\n<\/div><div class=\"fusion-text fusion-text-29\"><div class=\"code\">gcloud beta ai-platform models create MODEL_NAME  #eg: fastai_text_clf<br \/>\n&#8211;region=REGION  #eg: europe-west1<br \/>\n&#8211;enable-logging<br \/>\n&#8211;enable-console-logging<\/div>\n<\/div><div class=\"fusion-title title fusion-title-15 fusion-sep-none fusion-title-text fusion-title-size-three\" style=\"--awb-margin-bottom-small:8px;\"><h3 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:20;line-height:1.2;\">2\u20131 Build your docker image that will be used by your version<\/h3><\/div><ul style=\"--awb-line-height:27.2px;--awb-icon-width:27.2px;--awb-icon-height:27.2px;--awb-icon-margin:11.2px;--awb-content-margin:38.4px;\" class=\"fusion-checklist fusion-checklist-3 fusion-checklist-default type-icons\"><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon fa-angle-right fas\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p>Create a folder model\/ in the root of the repository<\/p>\n<\/div><\/li><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon fa-angle-right fas\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p>Place your fastai model weights in model\/text\/ and name it fastai_cls_weights.pth<\/p>\n<\/div><\/li><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon fa-angle-right fas\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p>Create an artifact repository<\/p>\n<\/div><\/li><\/ul><div class=\"fusion-text fusion-text-30\"><div class=\"code\">gcloud beta artifacts repositories create ARTIFACT_REGISTRY_NAME  #eg: getting-started-fastai<br \/>\n&#8211;repository-format=docker<br \/>\n&#8211;location=REGION #eg: europe-west1<\/div>\n<\/div><ul style=\"--awb-line-height:27.2px;--awb-icon-width:27.2px;--awb-icon-height:27.2px;--awb-icon-margin:11.2px;--awb-content-margin:38.4px;\" class=\"fusion-checklist fusion-checklist-4 fusion-checklist-default type-icons\"><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon fa-angle-right fas\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p>Build your docker image<\/p>\n<\/div><\/li><\/ul><div class=\"fusion-text fusion-text-31\"><div class=\"code\">docker build -f TextDockerfile -t REGION-docker.pkg.dev\/PROJECT_ID\/ARTIFACT_REGISTRY_NAME\/fastai_text_cls:v0<\/div>\n<\/div><div class=\"fusion-title title fusion-title-16 fusion-sep-none fusion-title-text fusion-title-size-three\" style=\"--awb-margin-bottom-small:8px;\"><h3 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:20;line-height:1.2;\">2\u20132 (Optional) Check that your docker image runs fine<\/h3><\/div><ul style=\"--awb-line-height:27.2px;--awb-icon-width:27.2px;--awb-icon-height:27.2px;--awb-icon-margin:11.2px;--awb-content-margin:38.4px;\" class=\"fusion-checklist fusion-checklist-5 fusion-checklist-default type-icons\"><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon fa-angle-right fas\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p>Run your docker image locally and test it<\/p>\n<\/div><\/li><\/ul><div class=\"fusion-text fusion-text-32\"><div class=\"code\">docker run -it -p 8080:8080 REGION-docker.pkg.dev\/PROJECT_ID\/ARTIFACT_REGISTRY_NAME\/fastai_text_cls:v0<br \/>\ncurl -X POST -H \"Content-Type: application\/json\" -d '[\"this was a bad movie\"]' 127.0.0.1:8080\/predictions\/fastai_model\n<\/div>\n<\/div><div class=\"fusion-title title fusion-title-17 fusion-sep-none fusion-title-text fusion-title-size-three\" style=\"--awb-margin-bottom-small:8px;\"><h3 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:20;line-height:1.2;\">2\u20133 Push your docker image to a container registry in your GCP project<\/h3><\/div><div class=\"fusion-text fusion-text-33\"><p>You need to have the IAM credentials to do that. Once you\u2019ve ensured you have them, run the following<\/p>\n<\/div><div class=\"fusion-text fusion-text-34\"><div class=\"code\">gcloud auth configure-docker<br \/>\ndocker push REGION-docker.pkg.dev\/PROJECT_ID\/ARTIFACT_REGISTRY_NAME\/fastai_text_cls:v0<\/div>\n<\/div><div class=\"fusion-title title fusion-title-18 fusion-sep-none fusion-title-text fusion-title-size-three\" style=\"--awb-margin-bottom-small:8px;\"><h3 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:20;line-height:1.2;\">2\u20134 Create a model version using your docker image<\/h3><\/div><div class=\"fusion-text fusion-text-35\"><div class=\"code\">gcloud beta ai-platform versions create VERSION_NAME<br \/>\n&#8211;region=REGION<br \/>\n&#8211;model=MODEL_NAME<br \/>\n&#8211;image=REGION-docker.pkg.dev\/PROJECT_ID\/ARTIFACT_REGISTRY_NAME\/fastai_text_cls:v0<br \/>\n&#8211;ports=8080<br \/>\n&#8211;health-route=\/ping<br \/>\n&#8211;predict-route=\/predictions\/fastai_model<\/div>\n<\/div><div class=\"fusion-title title fusion-title-19 fusion-sep-none fusion-title-text fusion-title-size-three\" style=\"--awb-margin-bottom-small:8px;\"><h3 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:20;line-height:1.2;\">2\u20135 Test your model version<\/h3><\/div><div class=\"fusion-text fusion-text-36\"><div class=\"code\">curl -X POST<br \/>\n-H \"Authorization: Bearer $(gcloud auth print-access-token)\"<br \/>\n-H \"Content-Type: application\/json\"<br \/>\n-d '[\"this was a bad movie\"]'<br \/>\nhttps:\/\/REGION-ml.googleapis.com\/v1\/projects\/PROJECT_ID\/models\/MODEL_NAME\/versions\/VERSION_NAME:predict\n<\/div>\n<\/div><div class=\"fusion-text fusion-text-37\"><p>Your fastai model is now deployed in a serverless architecture on AI Platform Prediction. You can make online predictions by sending requests to your model as a REST API. All methods to request predictions can be found in<a href=\"https:\/\/cloud.google.com\/ai-platform\/prediction\/docs\/online-predict#requesting_predictions\" target=\"_blank\" rel=\"noopener\"> google documentation<\/a>.<\/p>\n<\/div><div class=\"fusion-title title fusion-title-20 fusion-sep-none fusion-title-text fusion-title-size-two\" style=\"--awb-margin-bottom-small:8px;\"><h2 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:50;line-height:1.2;\">Conclusion<\/h2><\/div><div class=\"fusion-text fusion-text-38\"><p>Using AI Platform Prediction to serve any type of model can be very useful. This article was aimed to show an example of a deep learning model using a heavy framework (pytorch) and serve it in a cost effective way.<\/p>\n<\/div><div class=\"fusion-text fusion-text-39\"><p>Some limitations are to keep in mind:<\/p>\n<\/div><ul style=\"--awb-line-height:27.2px;--awb-icon-width:27.2px;--awb-icon-height:27.2px;--awb-icon-margin:11.2px;--awb-content-margin:38.4px;\" class=\"fusion-checklist fusion-checklist-6 fusion-checklist-default type-icons\"><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon fa-angle-double-right fas\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p>Even with autoscaling, it is not possible to downscale to 0 instances when you use AI Platform models deployed on regional endpoints. Since that\u2019s the only option to use custom containers, you\u2019ll always have at least one instance up<\/p>\n<\/div><\/li><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon fa-angle-double-right fas\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p>Another explored option was to use custom routines rather than custom containers but you can only do so if your model and packaged code are below a limit size of 500 MB which in our case was not possible to achieve.<\/p>\n<\/div><\/li><\/ul><\/div><\/div><\/div><\/article><div class=\"fusion-fullwidth fullwidth-box fusion-builder-row-4 fusion-flex-container nonhundred-percent-fullwidth non-hundred-percent-height-scrolling\" style=\"--awb-border-radius-top-left:0px;--awb-border-radius-top-right:0px;--awb-border-radius-bottom-right:0px;--awb-border-radius-bottom-left:0px;--awb-flex-wrap:wrap;\" ><div class=\"fusion-builder-row fusion-row fusion-flex-align-items-flex-start fusion-flex-content-wrap\" style=\"max-width:calc( 1440px + 20px );margin-left: calc(-20px \/ 2 );margin-right: calc(-20px \/ 2 );\"><div class=\"fusion-layout-column fusion_builder_column fusion-builder-column-3 fusion_builder_column_1_1 1_1 fusion-flex-column\" style=\"--awb-bg-size:cover;--awb-width-large:100%;--awb-margin-top-large:0px;--awb-spacing-right-large:10px;--awb-margin-bottom-large:0px;--awb-spacing-left-large:10px;--awb-width-medium:100%;--awb-order-medium:0;--awb-spacing-right-medium:10px;--awb-spacing-left-medium:10px;--awb-width-small:100%;--awb-order-small:0;--awb-spacing-right-small:10px;--awb-spacing-left-small:10px;\"><div class=\"fusion-column-wrapper fusion-column-has-shadow fusion-flex-justify-content-flex-start fusion-content-layout-column\"><div class=\"fusion-text fusion-text-40\"><p>You can find more about us and our projects on our Medium blog<\/p>\n<\/div><div ><a class=\"fusion-button button-flat fusion-button-default-size button-default fusion-button-default button-1 fusion-button-default-span fusion-button-default-type button-primary-medium\" target=\"_self\" href=\"https:\/\/medium.com\/artefact-engineering-and-data-science\/serving-fastai-models-with-google-cloud-ai-platform-d2ef1b497231\" rel=\"noopener\"><span class=\"fusion-button-text awb-button__text awb-button__text--default\">View Articles<\/span><\/a><\/div><\/div><\/div><\/div><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>2021 \u5e74 3 \u6708 30 \u65e5<br \/>\n\u5728\u672c\u7cfb\u5217\u4e24\u7bc7\u6587\u7ae0\u4e2d\u7684\u7b2c\u4e8c\u7bc7\u4e2d\uff0c\u6211\u5c06\u6df1\u5165\u63a2\u8ba8\u6211\u4eec\u6a21\u578b\u7684\u5927\u89c4\u6a21\u90e8\u7f72\u4e0e\u670d\u52a1\u3002.<\/p>","protected":false},"featured_media":59251,"parent":0,"template":"","meta":{"_acf_changed":false,"ep_exclude_from_search":false},"blog-category":[2995,22035],"blog-language":[2991],"class_list":["post-60209","blog","type-blog","status-publish","has-post-thumbnail","hentry","blog-category-ai-technology","blog-category-data-ai-consulting","blog-language-en"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.artefact.com\/zh\/wp-json\/wp\/v2\/blog\/60209","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.artefact.com\/zh\/wp-json\/wp\/v2\/blog"}],"about":[{"href":"https:\/\/www.artefact.com\/zh\/wp-json\/wp\/v2\/types\/blog"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.artefact.com\/zh\/wp-json\/wp\/v2\/media\/59251"}],"wp:attachment":[{"href":"https:\/\/www.artefact.com\/zh\/wp-json\/wp\/v2\/media?parent=60209"}],"wp:term":[{"taxonomy":"blog-category","embeddable":true,"href":"https:\/\/www.artefact.com\/zh\/wp-json\/wp\/v2\/blog-category?post=60209"},{"taxonomy":"blog-language","embeddable":true,"href":"https:\/\/www.artefact.com\/zh\/wp-json\/wp\/v2\/blog-language?post=60209"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}