Kaggleã®å¦ç¿ããæ稿ã¾ã§ãAWS, GitHub Actionsã使ã£ã¦èªååãã
éå±±ï¼@tkanayama_ï¼ã§ããå æ¥çµäºããKaggleã®"M5 Forecasting"ã¨ããã³ã³ãã«åå ããéãã¯ã©ã¦ããCI/CDã®åå¼·ãå ¼ãã¦ãAWS, GitHub Actionsã使ã£ã¦éãã§ã¿ã¾ããã
å 責
- Nçªç ãã ã£ãããã¿ã¾ãããä¸å¿ãåããã¨ããã£ã¦ãããããè¨äºã¯è¦ã¤ããã¾ããã§ããã
- ç§ã¯ã¯ã©ã¦ããªã©åå¼·ä¸ã®èº«åã§ãã®ã§ããã£ã¨ããããæ¹ããã or 説æãééã£ã¦ããããªã©ããã¾ãããæãã¦ãã ããã
- ç§ããã®ã·ã¹ãã ã使ã£ã¦åå ããã³ã³ãã®é ä½ã¯5,558ãã¼ã ä¸1,000,000,000ä½ã ã£ãã®ã§ãKaggleã§åã¦ããã©ããã¯å¥åé¡ã®ããã§ã :pien:
ãã®è¨äºã®ã´ã¼ã«
ä¸è¨ã®ãããªã·ã¹ãã ãæ§ç¯ãããã¨ãã´ã¼ã«ã¨ãã¾ãã
ã¦ã¼ã¶ã¼ããããã¨ã¯2ã¤ï¼å³ä¸ã§ã¦ã¼ã¶ã¼ãã伸ã³ã¦ããé»è²ç¢å°ï¼ã§ã
- å®è£ ããã³ã¼ããgit pushãã
- AWSã³ã³ã½ã¼ã«ããEC2ã®å®è¡ãã¿ã³ãæ¼ã
ã§ãããã®ä»ã¯ã·ã¹ãã ã«ãã£ã¦èªååããã¦ãããã¨ãç®æãã¾ããã¾ããå®è¡ä¸ã®ãã°ãã¡ã¢ãªä½¿ç¨çã»CPU使ç¨çãªã©ã¯CloudWatchãç¨ãã¦ãªã¢ã«ã¿ã¤ã *1ã§å¯è¦åãã¾ãã
ãã®è¨äºã§æ±ããã¨ã»æ±ããªããã¨
æ±ããã¨
- åè¿°ã®ã·ã¹ãã ãæ§ç¯ããããã«ãGitHubãAWSã®ã©ããªæ©è½ã使ã£ãã®ã説æãããã¨ãã¡ã¤ã³ã§æ±ãã¾ãã
æ±ããªããã¨
- ç´°ããå®ç¾æ¹æ³ï¼AWSã³ã³ã½ã¼ã«ã®æä½æ¹æ³ãªã©ï¼ã¯ãããã«å¤ãã£ã¦ãã¾ãå¯è½æ§ãé«ãã»ä»ã®å¤ãã®ããã°ã§ãã§ã«ç´¹ä»ããã¦ãããã¨ãããé©å®çç¥ãã¾ããç¹ã«ãAWS CLIå¨ãã®è¨å®ã¯æ¸ãã§ããåæã§è©±ãé²ãã¦ããã¾ãã
æ¬é¡
å¿ è¦ãªãã¨ã¯ã
- ã¯ã©ã¦ãä¸ã§å®è¡ãããã³ã¼ããç¨æãã
- Dockerfileãæ¸ã
- s3 bucketãç¨æãã
- ECRã®ã¬ãã¸ããªãç¨æãã
- GitHub Actionsãè¨å®ãã
- AMIãä½æãã
- EC2ã®èµ·åãã³ãã¬ã¼ããä½æãã
ã§ããé ã追ã£ã¦èª¬æãã¦ããã¾ãã
1. ã¯ã©ã¦ãä¸ã§å®è¡ãããã³ã¼ããç¨æãã
ã¾ãã¯ãsubmitãããåªåééããªãã®æå¼·ã®ã¢ã«ã´ãªãºã ãå®è£ ãã¾ãã
å®è£ ã§ãã¾ããã§ãããããä¾ã¨ãã¦ãTitanicã®sample submissionãåºåããã ãã®ã³ã¼ããç½®ãã¦ããã¾ãã(GitHub)
ãã®ã³ã¼ãã§ã¯MLãã¤ãã©ã¤ã³ã¨ãã¦gokartã使ã£ã¦ãã¾ããï¼æå±çµç¹ã®å½±é¿ãåãã¦ãã¾ããï¼
gokartã¯åºåå ã¨ãã¦AWS s3ãGoogle Cloud strageã®ãã±ããã®urlãä¸è¨ã®ããã«æå®ããã ãã§ãä¸éãã¡ã¤ã«ãæçµçµæãã¡ã¤ã«ã®åºåå ãå¤ãããã¨ãã§ããã®ã§ãä»åå®ç¾ããããã¤ãã©ã¤ã³ã«ã¯é½åãè¯ãã§ãã
TASK_WORKSPACE_DIRECTORY=s3://kaggle-titanic/
2. Dockerfileãæ¸ã
Dockerfileã¯ä¸è¨ã®ããã«è¨è¿°ãã¾ããã
FROM python:3.6.8-stretch COPY ./Pipfile /app/Pipfile COPY ./Pipfile.lock /app/Pipfile.lock WORKDIR /app RUN pip install --upgrade pip &&\ pip install pipenv &&\ pipenv install --system --deploy &&\ rm -rf ~/.cache WORKDIR / COPY ./conf /app/conf COPY ./titanic /app/titanic COPY ./main.py /app/main.py COPY ./script /app/script WORKDIR /app VOLUME "/app" ENV TASK_WORKSPACE_DIRECTORY s3://titanic-example/ CMD ["bash", "script/endpoint.sh"]
æå¾ã®2è¡ã§
- å¿ è¦ãªç°å¢å¤æ°ã®ã»ãã
- taskãå®è¡ããããã®shell scriptã®æå®
ãè¡ãªã£ã¦ãã¾ãããããã¯dokcer-composeã使ã£ã¦docker-compose.yamlå´ã«æ¸ãã»ãã綺éºãããããªããªã¨ä»æãã¾ããã
3. s3 bucketãç¨æãã
- ã®Dockerfileã«è¨è¿°ããåºåå bucketãä½æãã¾ããç¹çäºé ã¯ããã¾ããã
4. ECRã®ã¬ãã¸ããªãç¨æãã
AWSã®ECRã«ã¢ã¯ã»ã¹ããã¬ãã¸ããªãä½æãã¾ãããããã³ã³ã½ã¼ã«ä¸ã§10ç§ã§ã§ããã®ã§ç¹ã«è¨åãã¹ããã¤ã³ãã¯ããã¾ãããä»å㯠'titanic' ã¨ããååã§ä½ãã¾ãã
5. GitHub Actionsãè¨å®ãã
GitHub Actionsã¯ãå ¬å¼ãç¨æãã¦ããtemplateãã¨ã¦ãããããããã§ããä»åã¯ã"Deploy to Amazon ECS" ã¨ãããã³ãã¬ã¼ããå ã«ä¸è¨ã®ããã«ä½æãã¾ããã
on: push: branches: [ master ] name: Deploy to Amazon ECS jobs: deploy: name: Deploy runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v2 - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v1 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: us-east-2 - name: Login to Amazon ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v1 - name: Build, tag, and push image to Amazon ECR id: build-image env: ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} ECR_REPOSITORY: titanic IMAGE_TAG: latest run: | # Build a docker container and # push it to ECR so that it can # be deployed to ECS. docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG . docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"
ããã§ãsecrets.AWS_ACCESS_KEY_ID
ã¨secrets.AWS_SECRET_ACCESS_KEY
ã¯å¥éGitHubã®Secretsã«ç»é²ãã¦ããå¿
è¦ãããã¾ããï¼å¤é¨ã«å
¬éããªãããã«æ³¨æã§ãï¼ï¼
ã¾ããECR_REPOSITORY: titanic
ã®é¨åã¯ãã4. ECRã®ã¬ãã¸ããªãç¨æãããã§ä½æããã¬ãã¸ããªåã«èªã¿æ¿ãã¦ãã ããã
ããã¾ã§è¨å®ããä¸ã§git pushããã¨ãGitHub Actionsä¸ã§docker buildã¨docker pushãèµ°ãããã§ããECRã«docker imageãpushãããã¯ãã§ãã
5. AMIãä½æãã
次ã«ãAWSã³ã³ã½ã¼ã«ããec2ãèµ·åãã¾ããbaseã¨ãªãAMI㯠Amazon Linux AMI 2018.03.0 (HVM), SSD Volume Type
ãæå®ãã¾ãã
èµ·åããããsshæ¥ç¶ã§ãµã¼ãã¼å ã«å ¥ãã¾ãããã®å¾ãã·ã§ã«ä¸ã§ä¸è¨3ã¤ã®è¨å®ãè¡ãã¾ãã
dockeré¢é£
baseã®imageã«ã¯dockerãå ¥ã£ã¦ããªãã®ã§ãdockerãinstallãã¦ããã¾ãã
sudo yum update -y sudo yum install -y docker sudo usermod -a -G docker ec2-user
CloudWatché¢é£
CloudWatchã«å®è¡ãã°ãã¡ã¢ãªä½¿ç¨éãªã©ã®æ å ±ãéããå¯è¦åã§ããããã«ããããã®ä½æ¥ã§ããå ¬å¼ã®ãµã¤ãï¼ãµã¤ã1ã»ãµã¤ã2ï¼ãåèã«ããªãããä¸è¨ã®ã³ãã³ããå®è¡ãã¦ããã¾ãã
sudo yum install -y perl-Switch perl-DateTime perl-Sys-Syslog perl-LWP-Protocol-https perl-Digest-SHA.x86_64 curl https://aws-cloudwatch.s3.amazonaws.com/downloads/CloudWatchMonitoringScripts-1.2.2.zip -O unzip CloudWatchMonitoringScripts-1.2.2.zip && rm CloudWatchMonitoringScripts-1.2.2.zip && cd aws-scripts-mon
次ã«
crontab -e
ã§crontabãéããcrontabã«ä¸è¨ãè¨è¿°ãã¾ããï¼å®æçã«ã¡ã¢ãªä½¿ç¨éãCloudWatchã«éãå¦çã§ããï¼
*/5 * * * * ~/aws-scripts-mon/mon-put-instance-data.pl --mem-used-incl-cache-buff --mem-util --mem-used --mem-avail --disk-space-util --disk-path=/ --from-cron
Kaggle APIé¢é£
Kaggleã®èªåã®ã¢ã«ã¦ã³ããã¼ã¸ããAPI tokenããã¦ã³ãã¼ããã¦ãã¾ããããã¦ãä¸è¨ã®ããã«tokenã®æ å ±ãã³ãããã¦ã³ãã³ãã©ã¤ã³ä¸ã§å®è¡ãã¾ããï¼ãã®ãããããdocker-composeã¨AWS ãã©ã¡ã¼ã¿ã¹ãã¢ãçµã¿åããã¦ç°å¢å¤æ°ãå¤ããæ³¨å ¥ã§ããããã«ããæ¹ãå¾ããã®å¤æ´ã«å¼·ããã ã¨ãããã¨ã«ãããã°ãæ¸ããªããæ°ã¥ãã¾ãããï¼
echo 'KAGGLE_USERNAME=tepppeikanayama' >> ~/kaggle.txt echo 'KAGGLE_KEY=***********' >> ~/kaggle.txt
ã¤ã¡ã¼ã¸ã®ä½æ
ä¸è¨ãdockeré¢é£ããCloudWatché¢é£ããKaggle APIé¢é£ãã®å®è¡ãçµãã£ãããEC2ã®ã³ã³ã½ã¼ã«ä¸ã§ã¤ã¡ã¼ã¸ã®ä½æããã¾ãã
6. IAM roleãä½æãã
次ã«ã権é管çãè¡ãããã®IAM roleãè¨å®ãã¾ããä»åã¢ã¯ã»ã¹æ¨©éãå¿ è¦ãªãµã¼ãã¹ã¯ãS3, EC2, CloudWatchã®3ã¤ã§ããã³ã³ã½ã¼ã«ããIAMã®ãã¼ã¸ãéãããã®3ãµã¼ãã¹ã«å¯¾ãã¦FullAccessã®æ¨©éãæã£ãIAMãã¼ã«ãä½æãã¾ãã
7. EC2ã®èµ·åãã³ãã¬ã¼ããä½æãã
æå¾ã«ã EC2ã®èµ·åãã³ãã¬ã¼ããä½æãã¾ããèµ·åãã³ãã¬ã¼ãã¯ãEC2ã®ã³ã³ã½ã¼ã«ããç°¡åã«è¨å®ã§ãã¾ãã
è¨å®é ç®ã¯ä¸è¨ã§ãã
- AMI: ã5. AMIãä½æãããã§ä½æããAMIãæå®ãã¾ãã
- ã¤ã³ã¹ã¿ã³ã¹ã¿ã¤ã: å®è¡ãããã³ã¼ãã®å¤§ããã¨äºç®ã¨ã®å ¼ãåãã§ãé©å½ãªã¤ã³ã¹ã¿ã³ã¹ãé¸æãã¾ãã
- IAMãã¼ã«: ã6. IAM roleãä½æãããã§ä½æããIAMãã¼ã«ãé¸æãã¾ãã
- ã¦ã¼ã¶ã¼ãã¼ã¿ï¼ã¤ã³ã¹ã¿ã³ã¹èµ·åå¾ã«èªåã§å®è¡ãã¦ãããscriptã§ãï¼:
#!/bin/bash sudo service docker start $(aws --region us-east-2 ecr get-login | sed -e 's/-e none //g') docker pull 921126570142.dkr.ecr.us-east-2.amazonaws.com/titanic:latest docker container run --env-file=/home/ec2-user/kaggle.txt --log-driver=awslogs --log-opt awslogs-region=us-west-2 --log-opt awslogs-group=/home/ec2-user/logfile.log 921126570142.dkr.ecr.us-east-2.amazonaws.com/titanic echo "sudo halt" | at now + 5 minutes
ECRã®pathãªã©ã¯é©å®èªã¿æ¿ãã¦ãã ããããã£ã¦ãããã¨ã¨ãã¦ã¯ãECRã«pushãããææ°ã®docker imageãpullããâå®è¡ããâå®è¡ãçµãã£ããã·ã£ãããã¦ã³ãããã¨ããæµãã§ãã
ããã§ãæåã«æããå³ã®ãããªã·ã¹ãã ãå®æã§ãï¼
ä»å¾ãããããã¨
- docker-compose, ECS, ãã©ã¡ã¼ã¿ã¹ãã¢ãªã©ãçµã¿åããã¦ãç¹ã«ç°å¢å¤æ°å¨ããæ´çããã
- Terraformã§Infrastructure as Codeãå®ç¾ããã
*1:ã¡ã¢ãªä½¿ç¨çã»CPU使ç¨çã¯5åãããã®ã¿ã¤ã ã©ã°ãã