ChatGPTやClaudeのWebサイトはReactで作られているが、そこまでしたくなくサクッと作って、サクッと公開したいとき、streamlitは非常に楽。
ただ、streamlitは静的ビルドができず、S3+CloudFrontでは公開できない。今回は、プライベートVPC内のEC2+ALBで公開する方法を紹介する。
※パブリックVPC内であれば、EC2+Elastic IPだけでも公開できます。
Streamlitの簡易LLMアプリケーション作成
streamlitのインストール
pip3 install streamlit
下記にAmazon BedrockのClaude3のWebアプリを立ち上げるstreamlitのプログラムを載せる。
BedrockのClaudeを使用するには、Bedrockのコンソール画面->モデルアクセスからモデルアクセスをリクエストする必要がある。
下記コマンドでBedrockを使用権限のあるAWSユーザーで認証しておく必要がある。
aws configure
import boto3
import json
import streamlit as st
# Bedrockのレスポンスを待つ関数
@st.cache_data
def get_bedrock_response(input_text):
bedrock = boto3.client(service_name='bedrock-runtime')
body = json.dumps({
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 2000,
"temperature": 0.1,
"top_p": 0.9,
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": input_text,
}
]
}
]
})
modelId = 'anthropic.claude-3-sonnet-20240229-v1:0' # claude-3-sonnetモデルのモデルIDを指定
accept = 'application/json'
contentType = 'application/json'
response = bedrock.invoke_model(body=body, modelId=modelId, accept=accept, contentType=contentType)
response_body = json.loads(response.get('body').read())
response_text = response_body.get('content')[0]['text']
return response_text
def main():
st.title("Anthropic claude-3-sonnet")
input_text = st.text_input("このテキストをBedrockに送信します")
send_button = st.button("送信")
if send_button:
# レスポンスを待つ処理を別の関数に分ける
result = st.info("処理中...")
try:
response_text = get_bedrock_response(input_text)
result.empty()
st.write(response_text)
except Exception as e:
result.error(f"エラーが発生しました: {e}")
if __name__ == "__main__":
main()
EC2の設定
Nginxをインストールして起動する。
sudo apt-get install nginx
sudo systemctl status nginx.service
設定を変更する。
sudo emacs /etc/nginx/nginx.conf
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
location /app {
proxy_pass http://localhost:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Nginxを再起動する。
sudo systemctl restart nginx.service
streamlit run app.py --server.baseUrlPath=/app --server.port 8000 --server.enableCORS=false --server.enableXsrfProtection=false
バックグラウンド実行の場合は下記コマンド
nohup streamlit run app.py --server.baseUrlPath=/app --server.port 8000 --server.enableCORS=false --server.enableXsrfProtection=false &
ALBの設定
- ロードバランサーのコンソール画面でALBを作成する。
- ターゲットグループとして、ポート80でEC2インスタンスを登録する。
- リスナーとルールで、HTTPS:443をSSL/TLS 証明書を付けてターゲットグループに転送するよう設定する。
Route53の設定
Route53で、ドメインを作成し、AレコードでALBへエイリアスをする。
これで作成してドメインでHTTPSによるアクセスが可能になる。