AWS環境でAI関連のシステムのPOC（２）

# はじめに
写真からストーリーテリングを作成できればと思い、写真をインプットにキャプションを付けてくれるサービスを作成していきます。キャプションを付けてくれるサービスはReplicateの「BLIP-2」というモデルを利用していきます。


# アプリケーションの概要
PythonのWebアプリを開発する際に使うWebフレームワークであるDjangoを使い、画面からイメージをアップロードした時に、Replicateの「BLIP-2」というモデルを呼び出してキャプションを取得します。また、AWSのS3へのファイルアップロードも合せて行うようにしています。

■Djangoのフロー概要
```mermaid
graph LR;
    subgraph "サーバ"        
        URL\nPatterns-->Views;
        Views-->Serializer;
        Views-->Template;
        Serializer-->Models;
        Views-->Models;
        Models-->Database(sqlite);
    end
    subgraph "Replicate"
        Views-->BLIP-2
    end
    subgraph "AWS"
        Views-->S3
    end 
    User--  HTTPS -->URL\nPatterns;
```

# アプリケーションの準備

### Replicateの準備
Replicateにサインインしていきます。GitHubのコードでサインインできます。制限に達するまでは特にBillingへの登録は不要です。

https://replicate.com/

API tokensでトークンをメモしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468278/4655b99f-5058-f7c8-ebbf-3c23e5655cda.png)

### AWS S3の準備
AWSのアカウントがある前提となりますが、S3のバケットを作成。バケット名は任意です。AWSユーザのアクセスキーとシークレットキーをメモしておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468278/aaeabad6-63d1-09aa-9fc6-e018e2587d96.png)

# アプリケーションの作成
Djangoで画像のアップロード機能を作る方法については[Djangoで画像のアップロード機能を作る方法](https://denno-sekai.com/django-img-upload/)を参考にさせて頂きました。

```:追加するライブラリ
pip install replicate 'replicate用
pip install boto3　　　'S3用
```

環境変数とenvに以下を指定
```:.env
REPLICATE_API_TOKEN=r8_xxxxxx
AWS_ACCESS_KEY_ID=AKxxxxxx
AWS_SECRET_ACCESS_KEY=Jbxxxxx
AWS_STORAGE_BUCKET_NAME=caption-image-sandbox
```

```Python:views.py
ReplicateおよびS3へのファイルアップロードを呼び出すviews.pyは以下の通り

import replicate
import boto3
from django.conf import settings
from django.shortcuts import render, get_object_or_404
from .forms import UploadForm
from .models import UploadImage

s3 = boto3.resource('s3')
bucket = s3.Bucket(settings.AWS_STORAGE_BUCKET_NAME)
print(settings.AWS_STORAGE_BUCKET_NAME)

def index(request):
  params = {
    'title': 'キャプションを付ける画像のアップロード',
    'upload_form': UploadForm(),
    'id': None,
    'caption': None,
  }

  if (request.method == 'POST'):
    form = UploadForm(request.POST, request.FILES)
    if form.is_valid():
      upload_image = form.save()
      params['id'] = upload_image.id
      # S3へアップロード
      bucket.upload_file(upload_image.image.path, str(upload_image.id)+'.png')
      img = open(upload_image.image.path, 'rb')
      output = replicate.run(
        "andreasjansson/blip-2:f677695e5e89f8b236e52ecd1d3f01beb44c34606419bcc19345e046d8f786f9",
        input=  {
            "image": img,
            "caption": True,
            "question": "",
            "temperature": 1,
            "use_nucleus_sampling": False
        }
      )
      params['caption'] = output

  return render(request, 'index.html', params)

def preview(request, image_id=0):

  upload_image = get_object_or_404(UploadImage, id=image_id)

  params = {
    'title': '画像とキャプションの表示',
    'id': upload_image.id,
    'url': upload_image.image.url
  }

  return render(request, 'preview.html', params)
```



# 参考資料
[Djangoで画像のアップロード機能を作る方法](https://denno-sekai.com/django-img-upload/)


# まとめ
今回はローカルでDjangoのアプリケーションを作成し、画像のキャプションを取得するアプリケーションを作りました。次回は複数の画層のキャプションからストーリーテリングをする機能を作っていきたいと思います。