1.はじめに
どうも、ARIの名古屋支社に勤務している愛知県民こと、
新藏(にいくら)と申します♪
(/・ω・)/
生成AI、盛り上がっていますね。
最近、各生成AIサービスとの連携が簡単にできて、
アプリケーションを作成することができるツールとしてDifyを知りました。
少し調べると、AWS上にDifyをデプロイして動かすワークショップが見つかったので、
今回はDifyのデプロイについて記事にしたいと思います!
最後にも記載するのですが、
自分自身の予想以上に簡単にDifyがデプロイできたので、感動しました♪
チャットボットやDifyについて勉強中の方の参考になれば幸いです。
(*^^)v
2.Difyとは
まず初めに、Dify(ディファイ)とは何かについて、一言で言うと、
AI機能を持つアプリケーション(チャットボット等)を簡単に作成することができるツール
となります。
Difyにはクラウド版とGitHub上に公開されているコミュニティ版があり、
今回はOSSとして公開されているコミュニティ版を使用して、
AWS環境にチャットボットを作成しました。
参考
3.構成図
今回の構成図を紹介します。
出典: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.マネジメントコンソールにログインし、オレゴンリージョンを選択します。
今回はオレゴンリージョンですが、東京リージョンでも同じように設定ができます。
ただ、Amazonがアメリカの会社なので、
使えるモデルの種類はアメリカのリージョンの方が多いです
4.1.2.Bedrockの管理画面にて「モデルアクセス」を選択し、「特定のモデルを有効にする」を選択します。
4.1.3.有効にするモデルを選択します。
今回は以下のモデルを選択しました。
- Titan Text Embeddings V2
- Claude 3.5 Haiku
- Claude 3.5 Sonnet V2
Copilot曰く、それぞれのモデルの特徴は以下とのことでした。
違う点があるかもしれませんが、ご参考までに・・・
- Titan Text Embeddings V2
- 高精度なテキスト埋め込み: テキストデータの意味を高精度に捉えることができます。
- 多用途: 検索、分類、クラスタリングなど、さまざまな自然言語処理タスクに適用可能です。
- スケーラビリティ: 大規模なデータセットにも対応できるように設計されています。
- Claude 3.5 Haiku
* 高速かつ高性能: 低コストながらも高速で高性能な処理が可能です。
* コーディング・数学的タスクに強い: プログラミングや数学関連のタスクで優れたパフォーマンスを発揮します。
* 多言語対応力の強化: 日本語を含む多言語での自然な応答が可能です。
- Claude 3.5 Sonnet V2
- 知性の向上: 前バージョンに比べて、より高度な知的タスクに対応できます。
- 速度とコストのバランス: 高速な処理とコスト効率の良さを兼ね備えています。
- 多様な応用: アイデア提案や課題発見など、クリエイティブなタスクにも適しています。
4.1.4.Bedrockを使用する目的等を入力します。
以上でBedrockの設定は完了です!
4.2.CloudFormationの実行
続きまして、CloudFormationを使用してEC2インスタンスとDifyのコンテナを作成します。
4.2.1.テンプレートをダウンロード
以下のコードブロック、もしくはURLからテンプレートをコピーし、PCに保存します
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.マネジメントコンソールにログインし、東京リージョンを選択します。
4.2.4.CloudFormationの管理画面にて「スタックの作成」を選択し、「新しいリソースを使用」を選択します。
4.2.5.「テンプレートファイルのアップロード」を選択し、前の手順でダウンロードしたyamlファイルを選択します。
4.2.6.任意のスタック名を入力します。
4.2.7.チェックボックスにチェックをします。
4.2.8.全体的な設定を確認し、問題がなければ次に進みます。
4.2.9.「リソース」タブを選択し、画面右の更新ボタンを選択するとリソースが作成される様子が確認できます。
4.2.10.画面左の更新ボタンを押し、「CREATE_COMPLETE」と表示されていればリソースの作成が完了しています。
4.2.11.「出力」タブを選択し、「InstancePublicIP」に記載のあるIPアドレスをコピーします。
4.3.Difyへの接続
さて、CloudFormationを使用してDifyのデプロイができたので、
実際にDifyに接続していきます♪
4.3.1.WEBブラウザを立ち上げ、「http://(前手順でコピーしたIPアドレス)」に接続します。
4.3.2.初期設定の画面が表示されるのでメールアドレス、ユーザ名、パスワードを入力します。
入力する値は適当でOKですが、メールアドレスとパスワードはDifyにログインする際、必要になります。
4.3.2.ログイン画面が表示されるので、前手順で設定したメールアドレスとパスワードを入力します。
4.4.DifyとBedrockとの連携設定
次は、DifyとBedrockを連携させるための設定を実施します。
4.4.1.画面右上のユーザ名を選択し、「設定」を選択します。
4.4.2.「モデルプロバイダー」を選択し、Bedrockの「セットアップ」を選択します。
4.4.3.「AWS Region」には4.1節でBedrockの設定の際に使用したリージョンを、Avaiable Model Nameにはモデル名を入力します。
Claude 3.5 Sonnetを使用する場合は、
anthropic.claude-3-5-sonnet-20241022-v2:0
となります。
4.4.4.問題なく設定が出来たら、「モデルの表示」を選択します。
4.4.5.モデルプロバイダの画面にて、4.1節で設定したモデル以外を無効化します。
4.4.6.「システムモデル設定」を選択し、推論モデルと埋め込みモデルを選択します。
自分自身がデプロイした際は推論モデルとして、Claude 3.5 Haikuを、
埋め込みモデルとしてTitan Text Embeddings V2を使用しました。
システム推論モデルと埋め込みモデルについては、
Copilot曰く、以下とのことです。
システム推論モデル
システム推論モデルは、ユーザーからの入力に対して応答を生成するためのモデルです。これらのモデルは、自然言語処理(NLP)タスクに特化しており、以下のような用途に使用されます:
- チャットボット:ユーザーとの対話を行うための応答を生成します。
- テキスト生成:文章の生成や補完を行います。
- 質問応答:ユーザーの質問に対して適切な回答を提供します。
埋め込みモデル
埋め込みモデルは、テキストデータを数値ベクトルに変換するためのモデルです。これにより、テキストデータの意味的な類似性を計算したり、検索エンジンの最適化を行ったりすることができます。主な用途は以下の通りです:
- テキスト検索:文書やデータベース内の関連情報を検索します。
- クラスタリング:類似したテキストをグループ化します。
- 分類:テキストデータを特定のカテゴリに分類します。
以上で、Difyの設定は終了です!
4.5.チャットボットの作成
最後にチャットボットを作成していきましょう♪
4.5.1.Difyの管理画面から、「最初から作成」を選択し、「チャットフロー」を選択し、任意のアプリ名を入力します。
4.5.2.「プレビュー」を選択し、質問をすると回答が返ってきます♪
5.デプロイにかかった時間と料金
最後に補足ですが、Difyのデプロイは約4時間で終わりました。
キャプチャを取得しながら進めていたため、作業自体は2~3時間あれば終わると思います!
2日間ほど遊び、AWSの使用料金は約1ドルでした!
内訳としてはEC2が7割、Bedrockが約2割、その他が1割くらいでした。
6.おわりに
ここまで読んで下さり、ありがとうございます!!!
(^^)
いやはや、こんなにも簡単にチャットボットが作れる時代になるとは・・・驚きました
Difyはまだまだカスタマイズできるので、次回はその内容についての記事、
具体的にはDifyが内部的に持つベクトルDBを使って何かしたいと思います♪
(:3_ヽ)_