{ "cells": [ { "attachments": {}, "cell_type": "markdown", "id": "33b776b2-616c-4582-b6d0-58688d46336a", "metadata": {}, "source": [ "# Stable Diffusion Inpainting with ClipSeg\n", "\n", "(English)\n", "\n", "Deploy Stable Diffusion Inpainting pipeline with [ClipSeg](https://huggingface.co/blog/clipseg-zero-shot).\n", "\n", "User can generate inpainted image without creating their own mask image. User can specify mask with text.\n", "\n", "(日本語)\n", "\n", "Stable Diffusion Inpainting pipeline と [ClipSeg](https://huggingface.co/blog/clipseg-zero-shot) をデプロイするサンプルノートブック。\n", "\n", "ユーザーはインペイントされた画像をマスク画像を作らずにテキストで指定して生成することが可能です。" ] }, { "cell_type": "code", "execution_count": null, "id": "e3590d84-82e9-4dfc-b907-e767b4c0e698", "metadata": { "tags": [] }, "outputs": [], "source": [ "import sagemaker, boto3, json\n", "from sagemaker import get_execution_role\n", "from sagemaker.pytorch.model import PyTorchModel\n", "from sagemaker.huggingface import HuggingFace\n", "from sagemaker.pytorch import PyTorch\n", "\n", "role = get_execution_role()\n", "region = boto3.Session().region_name\n", "sess = sagemaker.Session()\n", "bucket = sess.default_bucket()\n", "\n", "sagemaker.__version__" ] }, { "attachments": {}, "cell_type": "markdown", "id": "2a3eb0dc", "metadata": {}, "source": [ "## Generate Scripts for Inference\n", "\n", "(English)\n", "\n", "Generate `scripts/code/inference.py`, `scripts/code/requirements.txt` used for Inference.\n", "\n", "(日本語)\n", "\n", "推論で使うファイル `scripts/code/inference.py`, `scripts/code/requirements.txt` を作成します。" ] }, { "cell_type": "code", "execution_count": null, "id": "bb7be92e", "metadata": {}, "outputs": [], "source": [ "!mkdir -p sd_inpaint_clipseg_scripts/code" ] }, { "cell_type": "code", "execution_count": null, "id": "d676f97c-1dde-480b-96a4-0ab645870ac9", "metadata": { "tags": [] }, "outputs": [], "source": [ "%%writefile sd_inpaint_clipseg_scripts/code/requirements.txt\n", "transformers\n", "diffusers\n", "accelerate" ] }, { "cell_type": "code", "execution_count": null, "id": "0d2f98ff-2f2d-46d5-aa82-6c86a3479fe0", "metadata": { "tags": [] }, "outputs": [], "source": [ "%%writefile sd_inpaint_clipseg_scripts/code/inference.py\n", "import torch\n", "from transformers import CLIPSegProcessor, CLIPSegForImageSegmentation\n", "from diffusers import DiffusionPipeline\n", "from torch import autocast\n", "\n", "import json\n", "import base64\n", "from PIL import Image\n", "from io import BytesIO\n", "import numpy as np\n", "\n", "def model_fn(model_dir):\n", " processor = CLIPSegProcessor.from_pretrained(\"CIDAS/clipseg-rd64-refined\")\n", " model = CLIPSegForImageSegmentation.from_pretrained(\"CIDAS/clipseg-rd64-refined\")\n", "\n", " # Diffusion Pipeline: https://huggingface.co/docs/diffusers/api/diffusion_pipeline\n", " pipe = DiffusionPipeline.from_pretrained(\n", " \"runwayml/stable-diffusion-inpainting\",\n", " custom_pipeline=\"text_inpainting\",\n", " segmentation_model=model,\n", " segmentation_processor=processor\n", " )\n", " \n", " pipe = pipe.to(\"cuda\")\n", " return pipe\n", "\n", "def input_fn(data, content_type):\n", " if content_type == 'application/json':\n", " data = json.loads(data)\n", " else:\n", " raise TypeError('content_type is only allowed application/json')\n", " return data\n", "\n", "def predict_fn(data, model):\n", " pipe = model\n", " image_decoded = BytesIO(base64.b64decode(data['image'].encode()))\n", " image = Image.open(image_decoded).convert(\"RGB\")\n", " data[\"image\"] = image\n", " with autocast(\"cuda\"):\n", " image = pipe(**data).images[0]\n", " # Convert to JSON Encoded Image\n", " buffered = BytesIO()\n", " image.save(buffered, format=\"JPEG\")\n", " return base64.b64encode(buffered.getvalue()).decode()\n", "\n", "\n", "def output_fn(data, accept_type):\n", " if accept_type == 'application/json':\n", " data = json.dumps({'generated_image' : data})\n", " else:\n", " raise TypeError('content_type is only allowed application/json')\n", " return data" ] }, { "attachments": {}, "cell_type": "markdown", "id": "dc00c9bd", "metadata": {}, "source": [ "## Package and Deploy Model\n", "\n", "(English)\n", "\n", "We will package the files created, upload it on S3, and deploy inference endpoint.\n", "\n", "(日本語)\n", "\n", "作成したファイルをパッケージし S3 にアップロードし推論エンドポイントをデプロイします。" ] }, { "cell_type": "code", "execution_count": null, "id": "8bcc4590-cd44-40ca-a4dc-2ab364bc2828", "metadata": { "tags": [] }, "outputs": [], "source": [ "%cd sd_inpaint_clipseg_scripts\n", "!tar -czvf ../sd_inpaint_clipseg_package.tar.gz *\n", "%cd -" ] }, { "cell_type": "code", "execution_count": null, "id": "cded36d3-7891-4132-968d-e007069c9618", "metadata": { "tags": [] }, "outputs": [], "source": [ "model_path = sess.upload_data(\"sd_inpaint_clipseg_package.tar.gz\", bucket=bucket, key_prefix=f\"StableDiffusionInpainting-ClipSeg\")\n", "model_path" ] }, { "cell_type": "code", "execution_count": null, "id": "b71aa1e4-bf10-4486-9a1a-a6dd139b49fb", "metadata": { "tags": [] }, "outputs": [], "source": [ "endpoint_name = \"StableDiffusionInpainting-CLIPSeg\"\n", "\n", "huggingface_model = PyTorchModel(\n", " model_data=model_path,\n", " framework_version=\"2.0\",\n", " py_version='py310',\n", " role=role,\n", " name=endpoint_name\n", ")\n", "\n", "# deploy model to SageMaker Inference\n", "predictor = huggingface_model.deploy(\n", " initial_instance_count=1,\n", " instance_type='ml.g5.2xlarge',\n", " endpoint_name=endpoint_name\n", ")" ] }, { "attachments": {}, "cell_type": "markdown", "id": "bbe8aace", "metadata": {}, "source": [ "## Run Inference\n", "\n", "(English)\n", "\n", "Run inference on deployed endpoint.\n", "\n", "(日本語)\n", "\n", "デプロイしたエンドポイントで推論を実行します。" ] }, { "cell_type": "code", "execution_count": null, "id": "ca540936-5ab2-4949-b694-dd14a3f83d76", "metadata": { "tags": [] }, "outputs": [], "source": [ "from sagemaker.predictor import Predictor\n", "from sagemaker.predictor_async import AsyncPredictor\n", "from sagemaker.serializers import JSONSerializer\n", "from sagemaker.deserializers import JSONDeserializer\n", "\n", "import base64\n", "from PIL import Image\n", "from io import BytesIO\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "\n", "predictor_client = Predictor(\n", " endpoint_name=endpoint_name,\n", " sagemaker_session=sess,\n", " serializer=JSONSerializer(),\n", " deserializer=JSONDeserializer()\n", ")\n", "\n", "\n", "def inference(input_img_file_name, mask_text, prompt):\n", " with open(input_img_file_name, \"rb\") as f:\n", " input_img_image_bytes = f.read()\n", " encoded_input_image = base64.b64encode(bytearray(input_img_image_bytes)).decode()\n", " data = {\n", " \"prompt\": prompt,\n", " \"text\": mask_text,\n", " \"image\": encoded_input_image\n", " }\n", " response = predictor_client.predict(\n", " data=data\n", " )\n", " generated_image = response[\"generated_image\"] # Base64 Encoded JPEG\n", " generated_image_decoded = BytesIO(base64.b64decode(generated_image.encode()))\n", " generated_image_rgb = Image.open(generated_image_decoded).convert(\"RGB\")\n", " return generated_image_rgb\n", "\n", "def display_img_and_prompt(img, prmpt):\n", " \"\"\"Display the generated image.\"\"\"\n", " plt.figure(figsize=(12, 12))\n", " plt.imshow(np.array(img))\n", " plt.axis(\"off\")\n", " plt.title(prmpt)\n", " plt.show()" ] }, { "attachments": {}, "cell_type": "markdown", "id": "88769403", "metadata": {}, "source": [ "(English) Run inference on image in the directory. Feel free to change the file name and prompt.\n", "\n", "(日本語) ディレクトリにある画像ファイルで推論を実行します。好きなファイル名とプロンプトを指定してください。" ] }, { "cell_type": "code", "execution_count": null, "id": "c2d4e500-5f14-4c48-8ebe-af2084dd3dce", "metadata": { "tags": [] }, "outputs": [], "source": [ "input_img_file_name = \"dog_suit.jpg\"\n", "mask_text = \"a dog\"\n", "prompt = \"a cat\"\n", "generated_image = inference(input_img_file_name, mask_text, prompt)\n", "display_img_and_prompt(generated_image, prompt)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "19c0a88d", "metadata": {}, "source": [ "## Delete Endpoint\n", "\n", "(English)\n", "\n", "Delete deployed endpoint.\n", "\n", "(日本語)\n", "\n", "デプロイしたエンドポイントを削除します。" ] }, { "cell_type": "code", "execution_count": null, "id": "5e560f90-5294-4168-aa60-5d68d690774f", "metadata": { "tags": [] }, "outputs": [], "source": [ "predictor_client.delete_model()\n", "predictor_client.delete_endpoint()" ] } ], "metadata": { "availableInstances": [ { "_defaultOrder": 0, "_isFastLaunch": true, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 4, "name": "ml.t3.medium", "vcpuNum": 2 }, { "_defaultOrder": 1, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 8, "name": "ml.t3.large", "vcpuNum": 2 }, { "_defaultOrder": 2, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 16, "name": "ml.t3.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 3, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 32, "name": "ml.t3.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 4, "_isFastLaunch": true, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 8, "name": "ml.m5.large", "vcpuNum": 2 }, { "_defaultOrder": 5, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 16, "name": "ml.m5.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 6, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 32, "name": "ml.m5.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 7, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 64, "name": "ml.m5.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 8, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 128, "name": "ml.m5.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 9, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 192, "name": "ml.m5.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 10, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 256, "name": "ml.m5.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 11, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 384, "name": "ml.m5.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 12, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 8, "name": "ml.m5d.large", "vcpuNum": 2 }, { "_defaultOrder": 13, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 16, "name": "ml.m5d.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 14, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 32, "name": "ml.m5d.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 15, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 64, "name": "ml.m5d.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 16, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 128, "name": "ml.m5d.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 17, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 192, "name": "ml.m5d.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 18, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 256, "name": "ml.m5d.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 19, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 384, "name": "ml.m5d.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 20, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": true, "memoryGiB": 0, "name": "ml.geospatial.interactive", "supportedImageNames": [ "sagemaker-geospatial-v1-0" ], "vcpuNum": 0 }, { "_defaultOrder": 21, "_isFastLaunch": true, "category": "Compute optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 4, "name": "ml.c5.large", "vcpuNum": 2 }, { "_defaultOrder": 22, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 8, "name": "ml.c5.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 23, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 16, "name": "ml.c5.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 24, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 32, "name": "ml.c5.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 25, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 72, "name": "ml.c5.9xlarge", "vcpuNum": 36 }, { "_defaultOrder": 26, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 96, "name": "ml.c5.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 27, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 144, "name": "ml.c5.18xlarge", "vcpuNum": 72 }, { "_defaultOrder": 28, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 192, "name": "ml.c5.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 29, "_isFastLaunch": true, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 16, "name": "ml.g4dn.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 30, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 32, "name": "ml.g4dn.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 31, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 64, "name": "ml.g4dn.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 32, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 128, "name": "ml.g4dn.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 33, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 4, "hideHardwareSpecs": false, "memoryGiB": 192, "name": "ml.g4dn.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 34, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 256, "name": "ml.g4dn.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 35, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 61, "name": "ml.p3.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 36, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 4, "hideHardwareSpecs": false, "memoryGiB": 244, "name": "ml.p3.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 37, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 8, "hideHardwareSpecs": false, "memoryGiB": 488, "name": "ml.p3.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 38, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 8, "hideHardwareSpecs": false, "memoryGiB": 768, "name": "ml.p3dn.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 39, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 16, "name": "ml.r5.large", "vcpuNum": 2 }, { "_defaultOrder": 40, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 32, "name": "ml.r5.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 41, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 64, "name": "ml.r5.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 42, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 128, "name": "ml.r5.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 43, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 256, "name": "ml.r5.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 44, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 384, "name": "ml.r5.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 45, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 512, "name": "ml.r5.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 46, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 768, "name": "ml.r5.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 47, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 16, "name": "ml.g5.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 48, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 32, "name": "ml.g5.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 49, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 64, "name": "ml.g5.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 50, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 128, "name": "ml.g5.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 51, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 256, "name": "ml.g5.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 52, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 4, "hideHardwareSpecs": false, "memoryGiB": 192, "name": "ml.g5.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 53, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 4, "hideHardwareSpecs": false, "memoryGiB": 384, "name": "ml.g5.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 54, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 8, "hideHardwareSpecs": false, "memoryGiB": 768, "name": "ml.g5.48xlarge", "vcpuNum": 192 }, { "_defaultOrder": 55, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 8, "hideHardwareSpecs": false, "memoryGiB": 1152, "name": "ml.p4d.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 56, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 8, "hideHardwareSpecs": false, "memoryGiB": 1152, "name": "ml.p4de.24xlarge", "vcpuNum": 96 } ], "instance_type": "ml.t3.medium", "kernelspec": { "display_name": "Python 3 (Data Science)", "language": "python", "name": "python3__SAGEMAKER_INTERNAL__arn:aws:sagemaker:us-west-2:236514542706:image/datascience-1.0" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10" } }, "nbformat": 4, "nbformat_minor": 5 }