Skip to content

Commit

Permalink
Deploy demo (deepset-ai#1837)
Browse files Browse the repository at this point in the history
* Add GH Actions workflow for demo deployment

* update demo ec2 instance type

* remove redundant docker-compose build

* add custom demo command and env vars

* deploy demo on updates to workflow resources
  • Loading branch information
askainet authored Dec 3, 2021
1 parent bec14b6 commit 4f6dc36
Show file tree
Hide file tree
Showing 6 changed files with 233 additions and 19 deletions.
40 changes: 40 additions & 0 deletions .github/workflows/demo.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Demo

on:
workflow_dispatch:
push:
branches:
- master
paths:
- ".github/workflows/demo**"

env:
AWS_REGION: eu-west-1

permissions:
id-token: write
contents: read

jobs:
deploy:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2

- name: AWS Authentication
uses: aws-actions/configure-aws-credentials@master
with:
aws-region: ${{ env.AWS_REGION }}
role-to-assume: ${{ secrets.DEMO_AWS_DEPLOY_ROLE }}

- name: Deploy demo
env:
CF_KEY_NAME: ${{ secrets.DEMO_CF_KEY_NAME }}
CF_IMAGE_ID: ${{ secrets.DEMO_CF_IMAGE_ID }}
CF_IAM_INSTANCE_PROFILE: ${{ secrets.DEMO_CF_IAM_INSTANCE_PROFILE }}
run: |
aws cloudformation deploy \
--template-file .github/workflows/demo/ec2-autoscaling-group.yaml \
--stack-name haystack-demo-production-instance \
--parameter-overrides CommitShortSHA=${{ github.sha }} KeyName=${CF_KEY_NAME} ImageId=${CF_IMAGE_ID} IamInstanceProfile=${CF_IAM_INSTANCE_PROFILE} \
--capabilities CAPABILITY_IAM
16 changes: 16 additions & 0 deletions .github/workflows/demo/docker-compose.demo.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
version: "3"
services:
haystack-api:
restart: always
environment:
CONCURRENT_REQUEST_PER_WORKER: 16
command: "/bin/bash -c 'sleep 10 && gunicorn rest_api.application:app -b 0.0.0.0 -k uvicorn.workers.UvicornWorker --workers 3 --timeout 180'"

elasticsearch:
restart: always
ui:
restart: always
environment:
DEFAULT_DOCS_FROM_RETRIEVER: 7
DEFAULT_NUMBER_OF_ANSWERS: 5
DISABLE_FILE_UPLOAD: 1
158 changes: 158 additions & 0 deletions .github/workflows/demo/ec2-autoscaling-group.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/awslabs/goformation/v5.2.11/schema/cloudformation.schema.json


Parameters:
Project:
Description: A project name that is used for resource names
Type: String
Default: haystack-demo

Environment:
Description: An environment name that is suffixed to resource names
Type: String
Default: production

VPCStack:
Description: VPC stack name
Type: String
Default: haystack-demo-production-vpc

CommitShortSHA:
Description: Commit short reference that triggered this deployment
Type: String

InstanceType:
Description: EC2 instance type
Type: String
Default: p3.2xlarge

ImageId:
Description: AMI to use for the EC2 instance
Type: String

IamInstanceProfile:
Description: IAM instance profile to attach to the EC2 instance
Type: String

KeyName:
Description: EC2 key pair to add to the EC2 instance
Type: String

Resources:
AutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
CreationPolicy:
ResourceSignal:
Count: "1"
Timeout: PT45M
UpdatePolicy:
AutoScalingRollingUpdate:
MinInstancesInService: "1"
MaxBatchSize: "1"
PauseTime: PT45M
WaitOnResourceSignals: true
SuspendProcesses:
- HealthCheck
- ReplaceUnhealthy
- AZRebalance
- AlarmNotification
- ScheduledActions
Properties:
LaunchConfigurationName: !Ref InstanceConfiguration
VPCZoneIdentifier:
- !ImportValue
"Fn::Sub": "${VPCStack}-PublicSubnet1"
- !ImportValue
"Fn::Sub": "${VPCStack}-PublicSubnet2"
MaxSize: "2"
DesiredCapacity: "1"
MinSize: "1"
TargetGroupARNs:
- !ImportValue
"Fn::Sub": "${VPCStack}-DefaultTargetGroup"
Tags:
- Key: Name
Value: !Sub ${Project}-${Environment}
PropagateAtLaunch: true
- Key: Environment
Value: !Ref Project
PropagateAtLaunch: true
- Key: Project
Value: !Ref Environment
PropagateAtLaunch: true
- Key: CommitShortSHA
Value: !Ref CommitShortSHA
PropagateAtLaunch: true

InstanceConfiguration:
Type: AWS::AutoScaling::LaunchConfiguration
Properties:
LaunchConfigurationName: !Sub ${Project}-${Environment}-${CommitShortSHA}
InstanceType: !Ref InstanceType
ImageId: !Ref ImageId
IamInstanceProfile: !Ref IamInstanceProfile
KeyName: !Ref KeyName
AssociatePublicIpAddress: true
SecurityGroups:
- !ImportValue
"Fn::Sub": "${VPCStack}-InstanceSecurityGroup"
EbsOptimized: true
BlockDeviceMappings:
- DeviceName: /dev/sda1
Ebs:
VolumeSize: 200

UserData:
Fn::Base64: !Sub |
#!/bin/bash -ex
mkdir -p /opt/aws/bin
wget https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-py3-latest.tar.gz
python3 -m easy_install --script-dir /opt/aws/bin aws-cfn-bootstrap-py3-latest.tar.gz

trap '/opt/aws/bin/cfn-signal --exit-code 1 --stack ${AWS::StackId} --resource AutoScalingGroup --region ${AWS::Region}' ERR

echo "Deploying Haystack demo, commit ${CommitShortSHA}"

echo 'APT::Periodic::Update-Package-Lists "0";
APT::Periodic::Unattended-Upgrade "0";' > /etc/apt/apt.conf.d/20auto-upgrades

apt update
apt install -y curl git ca-certificates curl gnupg lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update
apt install -y docker-ce docker-ce-cli containerd.io

# Install Docker compose
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/bin/docker-compose
chmod +x /usr/bin/docker-compose

# Install Nvidia container runtime
curl -s -L https://nvidia.github.io/nvidia-container-runtime/gpgkey | \
apt-key add -
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-container-runtime/$distribution/nvidia-container-runtime.list | \
tee /etc/apt/sources.list.d/nvidia-container-runtime.list
apt-get update
apt-get install -y nvidia-container-runtime

# Setup and start Docker
groupadd docker || true
usermod -aG docker $USER || true
newgrp docker || true
systemctl unmask docker
systemctl restart docker

# Exposes the GPUs to Docker
docker run --rm --gpus all ubuntu nvidia-smi

# Clone and start Haystack
git clone --branch deploy-demo https://github.com/askainet/haystack.git /opt/haystack
cd /opt/haystack
export COMPOSE_FILE=docker-compose-gpu.yml:.github/workflows/demo/docker-compose.demo.yml
docker-compose pull
docker-compose up -d

/opt/aws/bin/cfn-signal --exit-code $? --stack ${AWS::StackId} --resource AutoScalingGroup --region ${AWS::Region}
2 changes: 1 addition & 1 deletion docker-compose-gpu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ services:
elasticsearch:
# This will start an empty elasticsearch instance (so you have to add your documents yourself)
#image: "elasticsearch:7.9.2"
# If you want a demo image instead that is "ready-to-query" with some indexed articles
# If you want a demo image instead that is "ready-to-query" with some indexed articles
# about countries and capital cities from Wikipedia:
image: "deepset/elasticsearch-countries-and-capitals"
ports:
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ services:
elasticsearch:
# This will start an empty elasticsearch instance (so you have to add your documents yourself)
#image: "elasticsearch:7.9.2"
# If you want a demo image instead that is "ready-to-query" with some indexed articles
# If you want a demo image instead that is "ready-to-query" with some indexed articles
# about countries and capital cities from Wikipedia:
image: "deepset/elasticsearch-countries-and-capitals"
ports:
Expand Down
34 changes: 17 additions & 17 deletions ui/webapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def main():

# Persistent state
state = SessionState.get(
random_question=DEFAULT_QUESTION_AT_STARTUP,
random_question=DEFAULT_QUESTION_AT_STARTUP,
random_answer="",
last_question=DEFAULT_QUESTION_AT_STARTUP,
results=None,
Expand All @@ -51,7 +51,7 @@ def reset_results(*args):
# Title
st.write("# Haystack Demo - Explore the world")
st.markdown("""
This demo takes its data from a selection of Wikipedia pages crawled in November 2021 on the topic of
This demo takes its data from a selection of Wikipedia pages crawled in November 2021 on the topic of
<h3 style='text-align:center;padding: 0 0 1rem;'>Countries and capital cities</h3>
Expand All @@ -63,18 +63,18 @@ def reset_results(*args):
# Sidebar
st.sidebar.header("Options")
top_k_reader = st.sidebar.slider(
"Max. number of answers",
min_value=1,
max_value=10,
value=DEFAULT_NUMBER_OF_ANSWERS,
step=1,
"Max. number of answers",
min_value=1,
max_value=10,
value=DEFAULT_NUMBER_OF_ANSWERS,
step=1,
on_change=reset_results)
top_k_retriever = st.sidebar.slider(
"Max. number of documents from retriever",
min_value=1,
max_value=10,
value=DEFAULT_DOCS_FROM_RETRIEVER,
step=1,
"Max. number of documents from retriever",
min_value=1,
max_value=10,
value=DEFAULT_DOCS_FROM_RETRIEVER,
step=1,
on_change=reset_results)
eval_mode = st.sidebar.checkbox("Evaluation mode")
debug = st.sidebar.checkbox("Show debug info")
Expand Down Expand Up @@ -107,7 +107,7 @@ def reset_results(*args):
text-align: center;
}}
.haystack-footer h4 {{
margin: 0.1rem;
margin: 0.1rem;
padding:0;
}}
footer {{
Expand All @@ -132,7 +132,7 @@ def reset_results(*args):
# Search bar
question = st.text_input("",
value=state.random_question,
max_chars=100,
max_chars=100,
on_change=reset_results
)
col1, col2 = st.columns(2)
Expand All @@ -147,7 +147,7 @@ def reset_results(*args):
#state.get_next_question = col2.button("Random question")
if col2.button("Random question"):
reset_results()
new_row = df.sample(1)
new_row = df.sample(1)
while new_row["Question Text"].values[0] == state.random_question: # Avoid picking the same question twice (the change is not visible on the UI)
new_row = df.sample(1)
state.random_question = new_row["Question Text"].values[0]
Expand Down Expand Up @@ -200,7 +200,7 @@ def reset_results(*args):
answer, context = result["answer"], result["context"]
start_idx = context.find(answer)
end_idx = start_idx + len(answer)
# Hack due to this bug: https://github.com/streamlit/streamlit/issues/3190
# Hack due to this bug: https://github.com/streamlit/streamlit/issues/3190
st.write(markdown(context[:start_idx] + str(annotation(answer, "ANSWER", "#8ef")) + context[end_idx:]), unsafe_allow_html=True)
source = ""
url, title = get_backlink(result)
Expand All @@ -213,7 +213,7 @@ def reset_results(*args):
else:
st.info("🤔 &nbsp;&nbsp; Haystack is unsure whether any of the documents contain an answer to your question. Try to reformulate it!")
st.write("**Relevance:** ", result["relevance"])

if eval_mode and result["answer"]:
# Define columns for buttons
is_correct_answer = None
Expand Down

0 comments on commit 4f6dc36

Please sign in to comment.