diff --git a/.travis.yml b/.travis.yml index 7d2e604..6e2ae84 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,48 @@ language: python + python: - - 3.6 + - 3.7 + services: - docker + +before_install: + # Replace all slashes (which are common in branch names) in VERSION with dashes for Docker compatibility + - if [[ "$TRAVIS_BRANCH" == "master" ]]; then + VERSION=latest; + else + VERSION=${TRAVIS_BRANCH//\//-}; + fi + + # Default variables (used by Jenkins) + - '[[ -z "$DOCKERFILE" ]] && export DOCKERFILE=Dockerfile || /bin/true' + - '[[ -z "$IMAGE" ]] && export IMAGE=test || /bin/true' + - '[[ -z "$ARCH" ]] && export ARCH=x86_64 || /bin/true' + - '[[ -z "$VERSION" ]] && export VERSION=jenkins || /bin/true' + install: - - docker build -t max-audio-classifier . - - docker run -it -d -p 5000:5000 max-audio-classifier + - docker build -f "$DOCKERFILE" -t codait/max-audio-classifier:"$IMAGE"-"$ARCH"-"$VERSION" . + - docker run --rm -p 5000:5000 codait/max-audio-classifier:"$IMAGE"-"$ARCH"-"$VERSION" - pip install -r requirements-test.txt + before_script: - flake8 . --max-line-length=127 - bandit -r . - sleep 30 + script: - pytest tests/test.py + +after_success: + - if [[ "$IMAGE" != "test" && "$TRAVIS_PULL_REQUEST" == "false" ]] && [[ "$TRAVIS_BRANCH" == "master" || "$TRAVIS_BRANCH" == "$TRAVIS_TAG" ]]; then + echo "$DOCKER_PASS" | docker login -u "$DOCKER_USER" --password-stdin; + docker push codait/max-audio-classifier:"$IMAGE"-"$ARCH"-"$VERSION"; + fi + +matrix: + include: + - os: linux + env: DOCKERFILE=Dockerfile IMAGE=test ARCH=x86_64 + - os: linux + arch: arm64 + env: DOCKERFILE=Dockerfile.arm32v7 IMAGE=arm ARCH=arm32v7 diff --git a/Dockerfile.arm32v7 b/Dockerfile.arm32v7 index 564a65f..744c96d 100644 --- a/Dockerfile.arm32v7 +++ b/Dockerfile.arm32v7 @@ -1,5 +1,5 @@ # -# Copyright 2018-2019 IBM Corp. All Rights Reserved. +# Copyright 2018-2020 IBM Corp. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # + FROM quay.io/codait/max-base:arm-arm32v7-v1.3.3 ARG model_bucket=https://max-cdn.cdn.appdomain.cloud/max-audio-classifier/1.0.0 @@ -26,14 +27,16 @@ RUN apt-get update && apt-get -y install llvm-dev libatlas3-base libhdf5-dev && RUN wget -nv --show-progress --progress=bar:force:noscroll ${model_bucket}/${model_file} --output-document=assets/${model_file} && \ tar -x -C assets/ -f assets/${model_file} -v && rm assets/${model_file} +RUN python -m pip install https://www.piwheels.org/simple/tensorflow/tensorflow-1.13.1-cp37-none-linux_armv7l.whl + COPY requirements.txt /workspace -RUN pip install -r requirements.txt +# Skip tensorflow in requirements.txt +RUN grep -v 'tensorflow' requirements.txt | python -m pip install -r /dev/stdin COPY . /workspace # check file integrity RUN sha512sum -c sha512sums.txt - EXPOSE 5000 CMD python app.py diff --git a/README.md b/README.md index bc33d92..a8e5ee2 100644 --- a/README.md +++ b/README.md @@ -63,10 +63,16 @@ arXiv:1609.09430, 2016. To run the docker image, which automatically starts the model serving API, run: +Intel CPUs: ```bash $ docker run -it -p 5000:5000 quay.io/codait/max-audio-classifier ``` +ARM CPUs (eg Raspberry Pi): +```bash +$ docker run -it -p 5000:5000 codait/max-audio-classifier:arm-arm32v7-latest +``` + This will pull a pre-built image from the Quay.io container registry (or use an existing image if already cached locally) and run it. If you'd rather checkout and build the model locally you can follow the [run locally](#run-locally) steps below. @@ -116,6 +122,12 @@ To build the Docker image locally, run: $ docker build -t max-audio-classifier . ``` +For ARM CPUs (eg Raspberry Pi), run: + +```bash +$ docker build -f Dockerfile.arm32v7 -t max-audio-classifier . +``` + All required model assets will be downloaded during the build process. _Note_ that currently this Docker image is CPU only (we will add support for GPU images later). diff --git a/requirements.txt b/requirements.txt index ba99388..1e6a81d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,3 +5,5 @@ resampy==0.2.1 pandas==0.24.2 keras==2.2.4 h5py==2.9.0 +# pin numba (dependency of resampy) version to be 0.49.1, because numba 0.50.1 depends on a higher version of llvmlite that travis doesn't have: https://github.com/numba/numba/commit/c2ae57a4a3ed1687f843b724a1a160188c1db2ef +numba==0.49.1