rembgをAWS Lambdaで動かす

2025/02/21

プログラミング

rembgとは

rembgは画像の背景除去が簡単に行うためのPythonライブラリ。以下に示すように、必要なパッケージをインストールしたら、数行のコードで背景を除去できる。

  • 以下のコマンドを実行して、必要なライブラリをインストールする。
  • pip install rembg
    pip install onnxruntime
  • 以下のようにライブラリを利用して、背景除去を行う。
  • from rembg import remove
    from PIL import Image
    
    img = Image.open('sample.png')
    rembg_img = remove(img)
    rembg_img.save('rembg_sample.png')

    sample.png

    Notion Image

    rembg_sample.png

    Notion Image

    AWS Lambdaでrembgを使う

    課題

    AWS Lambdaで普通にrembgを使おうとすると、デプロイパッケージのサイズ上限や処理中の書き込み権限などでいくつかつまずく点がある。Dockerイメージを使用してLambda関数を作成すると、10GBまでデプロイが可能になるので、今回はこちらの方法を利用する。

    準備

    Dockerイメージを作成するために、以下のような構成でファイル群を作成する。

    rembg-on-lambda
      ├─ Dockerfile
      └─ src
          ├─ app.py
          └─ requirements.txt
    # Dockerfile
    
    FROM public.ecr.aws/lambda/python:3.10
    # JITの無効化によりマルチプロセッシングの利用しないように設定し、書き込み権限エラーを回避
    ENV NUMBA_DISABLE_JIT=1  
    WORKDIR ${LAMBDA_TASK_ROOT}
    COPY ./src ./
    RUN curl -L -o u2net.onnx https://github.com/danielgatis/rembg/releases/download/v0.0.0/u2net.onnx
    RUN python3.10 -m pip install -r requirements.txt -t .
    CMD ["app.lambda_handler"]
    # src/app.py
    
    import os
    import io
    import boto3
    import requests
    from datetime import datetime
    from rembg import remove
    from rembg.session_simple import SimpleSession
    import onnxruntime as ort
    from PIL import Image
    
    
    def lambda_handler(event, _):
    
        # パラメータ取得
        image_url = event.get("image_url")
        if not image_url:
            raise ValueError('Error: image_url is required.')
        
        # 画像取得
        response = requests.get(image_url, stream=True)
        response.raise_for_status()
        img = Image.open(io.BytesIO(response.content))
    
        # 背景除去
        u2net_home = os.path.join(os.path.dirname(__file__), "u2net.onnx")
        session = SimpleSession(
            "u2net",
            ort.InferenceSession(
                u2net_home,
                providers=ort.get_available_providers(),
                sess_options=ort.SessionOptions(),
            )
        )
        bg_removed_img = remove(img, session=session)
        
        # s3アップロード
        s3_client = boto3.client('s3')
        s3_bucket_name = '<your-s3-bucket-name>'
        img_data = io.BytesIO()
        bg_removed_img.save(img_data, format='PNG', compress_level=0)
        img_data.seek(0)
        current_time = datetime.now().strftime("%Y%m%d%H%M%S%f")
        object_key = f"rembg/{current_time}-{image_url.split('/')[-1]}"
        s3_client.upload_fileobj(img_data, s3_bucket_name, object_key)
    
        return {
            "message": f"Removed background and uploaded s3 {object_key}",
            "image_url": f"https://{s3_bucket_name}.s3.ap-northeast-1.amazonaws.com/{object_key}"
        }
    # src/requirements.txt
    
    boto3
    requests
    pillow
    rembg==2.0.30

    デプロイ手順

  • CloudShellに上で作成したrembg-on-lambdaディレクトリをアップロードする。
  • ※ CloudShellにはディレクトリを選択して直接アップロードすることできないので、今回は以下の手順でアップロードする。その他、CloudShell上でコードを作成しても良いし、githubからクローンしても良い。

  • ローカル環境でrembg-on-lambdaディレクトリをzipファイルに圧縮する。
  • CloudShell上でunzip rembg-on-lambda.zip を実行して、任意の場所にzipファイルを展開する。

  • CloudShell上で以下のコマンドを順に実行し、ECRにDockerイメージをプッシュする。
  • ① rembg-on-lambdaディレクトリに移動

    cd rembg-on-lambda

    ② Dockerイメージの構築

    docker build --tag rembg-container .

    ③ ECRリポジトリの作成

    ECR_REPO_NAME=rembg-container-repo
    aws ecr create-repository --repository-name ${ECR_REPO_NAME}

    ④ ECRサインイン認証情報の取得

    AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
    ECR_URL=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com
    aws ecr get-login-password | docker login --username AWS --password-stdin ${ECR_URL}

    ⑤ ECRにDockerイメージをプッシュ

    docker tag rembg-container ${ECR_URL}/${ECR_REPO_NAME}
    docker push ${ECR_URL}/${ECR_REPO_NAME}

  • ECRにプッシュしたDockerイメージを使用してLambda関数を作成する。
  • Notion Image

  • 作成した関数を開き、以下の2つの設定を修正する。
  • ① 「設定」>「一般設定」>「編集」から、「メモリ」を128MB→1024MBに、「タイムアウト」を3秒→10秒に緩和する。

    ② 「設定」>「アクセス権限」>「rembg-on-lambda-role-xxxxxx(ロール名)」から、「AmazonS3FullAccess」ポリシーを追加


  • 作成したLambda関数の動作確認を行う。
  • 「テスト」タブからイベントJSONのimage_urlに実際に存在する画像のURLを指定してテストを実行し、成功することを確認する。

    イベントJSON
    {
      "image_url": "https://example.com/path/to/image"
    }

  • CloudShellとECRの後片付けをする。
  • ① rembg-on-lambdaディレクトリとzipファイルを削除

    cd ..
    rm -rf rembg-on-lambda rembg-on-lambda.zip

    ② 未使用のコンテナ、イメージ、ネットワーク、ボリュームを一括削除

    docker system prune -a --volumes

    ③ ECRリポジトリの削除

    aws ecr delete-repository --force --repository-name ${ECR_REPO_NAME}

    参考資料



    著者画像

    ゆうき

    2018/04からITエンジニアとして活動、2021/11から独立。主な使用言語はPython, TypeScript, SAS, etc.