9
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Dify・AWS】DifyをAWS上にデプロイし、簡単にチャットボットが作成できて感動した話

Last updated at Posted at 2024-12-15

1.はじめに

どうも、ARIの名古屋支社に勤務している愛知県民こと、
新藏(にいくら)と申します♪
(/・ω・)/

生成AI、盛り上がっていますね。

最近、各生成AIサービスとの連携が簡単にできて、
アプリケーションを作成することができるツールとしてDifyを知りました。

少し調べると、AWS上にDifyをデプロイして動かすワークショップが見つかったので、
今回はDifyのデプロイについて記事にしたいと思います!

最後にも記載するのですが、
自分自身の予想以上に簡単にDifyがデプロイできたので、感動しました♪

チャットボットやDifyについて勉強中の方の参考になれば幸いです。
(*^^)v

2.Difyとは

まず初めに、Dify(ディファイ)とは何かについて、一言で言うと、
AI機能を持つアプリケーション(チャットボット等)を簡単に作成することができるツール
となります。

Difyにはクラウド版とGitHub上に公開されているコミュニティ版があり、
今回はOSSとして公開されているコミュニティ版を使用して、
AWS環境にチャットボットを作成しました。

参考

3.構成図

今回の構成図を紹介します。

000_architecture.png
出典:https://catalog.us-east-1.prod.workshops.aws/workshops/95a3c231-2064-4a33-9a3d-624b7c11aaa6/ja-JP

構成としてはとてもシンプルで、EC2上にDifyのコンテナをデプロイし、
Bedrockと連携してチャットボットの回答を作成する
という構成となります。

また、後述のCloudFormationテンプレートを確認すると分かるのですが、
EBSを使用してEC2インスタンスを停止してもデータが飛ばないようにしています。

4.いざ、デプロイ

4.1.Bedrockの設定

まず初めに、Difyから呼び出すBedrockのモデルを指定します。

4.1.1.マネジメントコンソールにログインし、オレゴンリージョンを選択します。

210_Bedrock設定_1.png

今回はオレゴンリージョンですが、東京リージョンでも同じように設定ができます。
ただ、Amazonがアメリカの会社なので、
使えるモデルの種類はアメリカのリージョンの方が多いです

4.1.2.Bedrockの管理画面にて「モデルアクセス」を選択し、「特定のモデルを有効にする」を選択します。

220_Bedrock設定_2.png

4.1.3.有効にするモデルを選択します。

今回は以下のモデルを選択しました。

  • Titan Text Embeddings V2
  • Claude 3.5 Haiku
  • Claude 3.5 Sonnet V2
230_Bedrock設定_3.png

Copilot曰く、それぞれのモデルの特徴は以下とのことでした。
違う点があるかもしれませんが、ご参考までに・・・

  • Titan Text Embeddings V2
    • 高精度なテキスト埋め込み: テキストデータの意味を高精度に捉えることができます。
    • 多用途: 検索、分類、クラスタリングなど、さまざまな自然言語処理タスクに適用可能です。
    • スケーラビリティ: 大規模なデータセットにも対応できるように設計されています。
       
  • Claude 3.5 Haiku
    * 高速かつ高性能: 低コストながらも高速で高性能な処理が可能です。
    * コーディング・数学的タスクに強い: プログラミングや数学関連のタスクで優れたパフォーマンスを発揮します。
    * 多言語対応力の強化: 日本語を含む多言語での自然な応答が可能です。
     
  • Claude 3.5 Sonnet V2
    • 知性の向上: 前バージョンに比べて、より高度な知的タスクに対応できます。
    • 速度とコストのバランス: 高速な処理とコスト効率の良さを兼ね備えています。
    • 多様な応用: アイデア提案や課題発見など、クリエイティブなタスクにも適しています。

4.1.4.Bedrockを使用する目的等を入力します。

240_Bedrock設定_4.png

以上でBedrockの設定は完了です!

4.2.CloudFormationの実行

続きまして、CloudFormationを使用してEC2インスタンスとDifyのコンテナを作成します。

4.2.1.テンプレートをダウンロード
以下のコードブロック、もしくはURLからテンプレートをコピーし、PCに保存します

dify-self-deployment.yml
dify-self-deployment.yml
AWSTemplateFormatVersion: '2010-09-09'
Description: Dify CloudFormation Template

Parameters:
  VpcCIDR:
    Type: String
    Default: 192.168.0.0/16
    Description: CIDR block for the VPC

  Subnet1CIDR:
    Type: String
    Default: 192.168.0.0/20
    Description: CIDR block for Subnet 1

  Subnet2CIDR:
    Type: String
    Default: 192.168.16.0/20
    Description: CIDR block for Subnet 2

  AllowedCIDR:
    Type: String
    Default: 0.0.0.0/0
    Description: CIDR block to allow HTTP traffic from

  AmazonLinuxAMI:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64


Resources:
  DifyVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCIDR
      EnableDnsHostnames: true
      EnableDnsSupport: true
      InstanceTenancy: default
      Tags:
        - Key: Name
          Value: dify-vpc

  Subnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref DifyVPC
      AvailabilityZone: !Select [0, !GetAZs '']
      CidrBlock: !Ref Subnet1CIDR
      Tags:
        - Key: Name
          Value: dify-subnet-1

  Subnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref DifyVPC
      AvailabilityZone: !Select [1, !GetAZs '']
      CidrBlock: !Ref Subnet2CIDR
      Tags:
        - Key: Name
          Value: dify-subnet-2

  InternetGateway:
    Type: AWS::EC2::InternetGateway

  VPCGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref DifyVPC
      InternetGatewayId: !Ref InternetGateway

  RouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref DifyVPC

  Route:
    Type: AWS::EC2::Route
    DependsOn: VPCGatewayAttachment
    Properties:
      RouteTableId: !Ref RouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

  Subnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref Subnet1
      RouteTableId: !Ref RouteTable

  Subnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref Subnet2
      RouteTableId: !Ref RouteTable

  DifySecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Allow HTTP traffic
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: !Ref AllowedCIDR
          Description: Allow HTTP traffic from allowed CIDR
      SecurityGroupEgress:
        - IpProtocol: -1
          CidrIp: 0.0.0.0/0
          Description: Allow all outbound traffic
      VpcId: !Ref DifyVPC
      Tags:
        - Key: Name
          Value: dify-sg

  DifyWsInstanceRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/AmazonBedrockFullAccess'
        - 'arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore'

  InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Roles:
        - !Ref DifyWsInstanceRole

  DifyWsInstance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref AmazonLinuxAMI
      InstanceType: t3.medium
      NetworkInterfaces:
        - AssociatePublicIpAddress: 'true'
          DeviceIndex: '0'
          GroupSet:
            - !Ref DifySecurityGroup
          SubnetId: !Ref Subnet1
      BlockDeviceMappings:
        - DeviceName: /dev/xvda
          Ebs:
            VolumeSize: 20
            VolumeType: gp2
            Encrypted: 'true'
            
      Tags:
        - Key: Name
          Value: dify-ws
      IamInstanceProfile: !Ref InstanceProfile
      UserData:
        Fn::Base64: |
            #!/bin/bash
            max_attempts=5
            attempt_num=1
            success=false
            while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do
              sudo dnf install -y git docker
              if [ $? -eq 0 ]; then
                echo "dnf install succeeded"
                success=true
              else
                echo "dnf install $attempt_num failed. trying again..."
                sleep 3
                ((attempt_num++))
              fi
            done

            sudo systemctl start docker
            sudo gpasswd -a ec2-user docker
            sudo gpasswd -a ssm-user docker
            sudo chgrp docker /var/run/docker.sock
            sudo service docker restart
            sudo systemctl enable docker
            sudo curl -L "https://github.com/docker/compose/releases/download/v2.28.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
            sudo chmod +x /usr/local/bin/docker-compose
            sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
            cd /opt
            sudo git clone https://github.com/langgenius/dify.git
            cd /opt/dify
            sudo git checkout 0.9.1-fix1
            sudo git pull origin 0.9.1-fix1
            cd /opt/dify/docker
            sudo cp .env.example .env
            docker-compose up -d

Outputs:
  InstancePublicIP:
    Description: Public IP of the EC2 instance
    Value: !GetAtt DifyWsInstance.PublicIp
    Export:
      Name: DifyInstancePublicIP
  InstanceId:
    Description: InstanceId of the EC2 instance
    Value: !Ref DifyWsInstance
    Export:
      Name: DifyInstanceId

4.2.2.テンプレートを修正します。
前手順のyamlファイルをみると、Difyのバージョンが0.9.1で固定になっています。
最新版のDifyを使いたい場合は、コードを以下の様に修正してください。

- sudo git checkout 0.9.1-fix1
- sudo git pull origin 0.9.1-fix1

+ LATEST_TAG=$(curl -s https://api.github.com/repos/langgenius/dify/releases/latest | jq -r .tag_name)
+ sudo git checkout $LATEST_TAG
+ sudo git pull origin $LATEST_TAG

次は実際にCloudFormationを動かしていきます!

4.2.3.マネジメントコンソールにログインし、東京リージョンを選択します。

005_CFnの実行_リージョン選択.png

4.2.4.CloudFormationの管理画面にて「スタックの作成」を選択し、「新しいリソースを使用」を選択します。

010_CFnの実行_1.png

4.2.5.「テンプレートファイルのアップロード」を選択し、前の手順でダウンロードしたyamlファイルを選択します。

020_CFnの実行_2.png

4.2.6.任意のスタック名を入力します。

030_CFnの実行_3.png

4.2.7.チェックボックスにチェックをします。

040_CFnの実行_4.png

4.2.8.全体的な設定を確認し、問題がなければ次に進みます。

050_CFnの実行_5.png

4.2.9.「リソース」タブを選択し、画面右の更新ボタンを選択するとリソースが作成される様子が確認できます。

060_CFnの実行_6.png

4.2.10.画面左の更新ボタンを押し、「CREATE_COMPLETE」と表示されていればリソースの作成が完了しています。

070_CFnの実行_7.png

4.2.11.「出力」タブを選択し、「InstancePublicIP」に記載のあるIPアドレスをコピーします。

080_CFnの実行_8.png

4.3.Difyへの接続

さて、CloudFormationを使用してDifyのデプロイができたので、
実際にDifyに接続していきます♪

4.3.1.WEBブラウザを立ち上げ、「http://(前手順でコピーしたIPアドレス)」に接続します。

4.3.2.初期設定の画面が表示されるのでメールアドレス、ユーザ名、パスワードを入力します。

入力する値は適当でOKですが、メールアドレスとパスワードはDifyにログインする際、必要になります。

110_Difyへのログイン_1.png

4.3.2.ログイン画面が表示されるので、前手順で設定したメールアドレスとパスワードを入力します。

120_Difyへのログイン_2.png

4.4.DifyとBedrockとの連携設定

次は、DifyとBedrockを連携させるための設定を実施します。

4.4.1.画面右上のユーザ名を選択し、「設定」を選択します。

310_DifyとBedrockの連携_1.png

4.4.2.「モデルプロバイダー」を選択し、Bedrockの「セットアップ」を選択します。

320_DifyとBedrockの連携_2.png

4.4.3.「AWS Region」には4.1節でBedrockの設定の際に使用したリージョンを、Avaiable Model Nameにはモデル名を入力します。

Claude 3.5 Sonnetを使用する場合は、
anthropic.claude-3-5-sonnet-20241022-v2:0
となります。

330_DifyとBedrockの連携_3.png

Model Nameで何を入れれば良いか分からない・・・
という場合は、以下の画像の様に生成AI聞くと答えてくれると思います♪

335_DifyとBedrockの連携_3.5.png

4.4.4.問題なく設定が出来たら、「モデルの表示」を選択します。

340_DifyとBedrockの連携_4.png

4.4.5.モデルプロバイダの画面にて、4.1節で設定したモデル以外を無効化します。

350_DifyとBedrockの連携_5.png
360_DifyとBedrockの連携_6.png

4.4.6.「システムモデル設定」を選択し、推論モデルと埋め込みモデルを選択します。

自分自身がデプロイした際は推論モデルとして、Claude 3.5 Haikuを、
埋め込みモデルとしてTitan Text Embeddings V2を使用しました。

370_DifyとBedrockの連携_7.png

システム推論モデルと埋め込みモデルについては、
Copilot曰く、以下とのことです。

システム推論モデル
システム推論モデルは、ユーザーからの入力に対して応答を生成するためのモデルです。これらのモデルは、自然言語処理(NLP)タスクに特化しており、以下のような用途に使用されます:

  • チャットボット:ユーザーとの対話を行うための応答を生成します。
  • テキスト生成:文章の生成や補完を行います。
  • 質問応答:ユーザーの質問に対して適切な回答を提供します。
     

埋め込みモデル
埋め込みモデルは、テキストデータを数値ベクトルに変換するためのモデルです。これにより、テキストデータの意味的な類似性を計算したり、検索エンジンの最適化を行ったりすることができます。主な用途は以下の通りです:

  • テキスト検索:文書やデータベース内の関連情報を検索します。
  • クラスタリング:類似したテキストをグループ化します。
  • 分類:テキストデータを特定のカテゴリに分類します。

以上で、Difyの設定は終了です!

4.5.チャットボットの作成

最後にチャットボットを作成していきましょう♪

4.5.1.Difyの管理画面から、「最初から作成」を選択し、「チャットフロー」を選択し、任意のアプリ名を入力します。

130_チャットボットの作成.png

4.5.2.「プレビュー」を選択し、質問をすると回答が返ってきます♪

410_チャットボットを動かす.png

5.デプロイにかかった時間と料金

最後に補足ですが、Difyのデプロイは約4時間で終わりました。
キャプチャを取得しながら進めていたため、作業自体は2~3時間あれば終わると思います!

2日間ほど遊び、AWSの使用料金は約1ドルでした!
内訳としてはEC2が7割、Bedrockが約2割、その他が1割くらいでした。

510_料金.png

6.おわりに

ここまで読んで下さり、ありがとうございます!!!
(^^)

いやはや、こんなにも簡単にチャットボットが作れる時代になるとは・・・驚きました

Difyはまだまだカスタマイズできるので、次回はその内容についての記事、
具体的にはDifyが内部的に持つベクトルDBを使って何かしたいと思います♪
(:3_ヽ)_

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?