diff --git a/.github/workflows/android-perf.yml b/.github/workflows/android-perf.yml index 93ec4fe4e7..66e031bea7 100644 --- a/.github/workflows/android-perf.yml +++ b/.github/workflows/android-perf.yml @@ -3,6 +3,16 @@ name: android-perf on: schedule: - cron: 0 0 * * * + pull_request: + paths: + - .github/workflows/android-perf.yml + - extension/benchmark/android/benchmark/android-llm-device-farm-test-spec.yml.j2 + push: + branches: + - main + paths: + - .github/workflows/android-perf.yml + - extension/benchmark/android/benchmark/android-llm-device-farm-test-spec.yml.j2 # Note: GitHub has an upper limit of 10 inputs workflow_dispatch: inputs: @@ -30,10 +40,6 @@ on: description: The list of configs used the benchmark required: false type: string - test_spec: - description: The test spec to drive the test on AWS devices - required: false - type: string workflow_call: inputs: models: @@ -60,10 +66,6 @@ on: description: The list of configs used the benchmark required: false type: string - test_spec: - description: The test spec to drive the test on AWS devices - required: false - type: string concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref_name }}-${{ github.ref_type == 'branch' && github.sha }}-${{ github.event_name == 'workflow_dispatch' }}-${{ github.event_name == 'schedule' }} @@ -84,9 +86,9 @@ jobs: # Separate default values from the workflow dispatch. To ensure defaults are accessible # during scheduled runs and to provide flexibility for different defaults between # on-demand and periodic benchmarking. - CRON_DEFAULT_MODELS: "stories110M,dl3,mv3,mv2,ic4,ic3,vit" - CRON_DEFAULT_DEVICES: "samsung_galaxy_s22" - CRON_DEFAULT_DELEGATES: "xnnpack,qnn" + CRON_DEFAULT_MODELS: ${{ github.event_name == 'schedule' && 'stories110M,dl3,mv3,mv2,ic4,ic3,vit' || 'stories110M' }} + CRON_DEFAULT_DEVICES: samsung_galaxy_s22 + CRON_DEFAULT_DELEGATES: ${{ github.event_name == 'schedule' && 'xnnpack,qnn' || 'xnnpack' }} run: | set -ex MODELS="${{ inputs.models }}" @@ -125,6 +127,43 @@ jobs: echo "devices=$(echo "$MAPPED_ARNS_JSON" | jq -c .)" >> $GITHUB_OUTPUT echo "delegates=$(echo $DELEGATES | jq -Rc 'split(",")')" >> $GITHUB_OUTPUT + prepare-test-specs: + runs-on: linux.2xlarge + needs: set-parameters + strategy: + matrix: + model: ${{ fromJson(needs.set-parameters.outputs.models) }} + delegate: ${{ fromJson(needs.set-parameters.outputs.delegates) }} + fail-fast: false + steps: + - uses: actions/checkout@v3 + + - name: Prepare the spec + shell: bash + working-directory: extension/benchmark/android/benchmark + run: | + set -eux + + # The model will be exported in the next step to this S3 path + MODEL_PATH="https://gha-artifacts.s3.amazonaws.com/${{ github.repository }}/${{ github.run_id }}/artifacts/${{ matrix.model }}_${{ matrix.delegate }}/model.zip" + # We could write a script to properly use jinja here, but there is only one variable, + # so let's just sed it + sed -i -e 's,{{ model_path }},'"${MODEL_PATH}"',g' android-llm-device-farm-test-spec.yml.j2 + cp android-llm-device-farm-test-spec.yml.j2 android-llm-device-farm-test-spec.yml + + # Just print the test spec for debugging + cat android-llm-device-farm-test-spec.yml + + - name: Upload the spec + uses: seemethere/upload-artifact-s3@v5 + with: + s3-bucket: gha-artifacts + s3-prefix: | + ${{ github.repository }}/${{ github.run_id }}/artifacts/${{ matrix.model }}_${{ matrix.delegate }} + retention-days: 1 + if-no-files-found: error + path: extension/benchmark/android/benchmark/android-llm-device-farm-test-spec.yml + export-models: name: export-models uses: pytorch/test-infra/.github/workflows/linux_job.yml@main @@ -170,9 +209,18 @@ jobs: echo "Unsupported delegate ${{ matrix.delegate }}" exit 1 fi - PYTHON_EXECUTABLE=python bash .ci/scripts/test_llama.sh "${{ matrix.model }}" "${BUILD_MODE}" "${DTYPE}" "${DELEGATE_CONFIG}" "${ARTIFACTS_DIR_NAME}" + PYTHON_EXECUTABLE=python bash .ci/scripts/test_llama.sh \ + -model "${{ matrix.model }}" \ + -build_tool "${BUILD_MODE}" \ + -dtype "${DTYPE}" \ + -mode "${DELEGATE_CONFIG}" \ + -upload "${ARTIFACTS_DIR_NAME}" else - PYTHON_EXECUTABLE=python bash .ci/scripts/test_model.sh "${{ matrix.model }}" "${BUILD_MODE}" "${{ matrix.delegate }}" "${ARTIFACTS_DIR_NAME}" + PYTHON_EXECUTABLE=python bash .ci/scripts/test_model.sh \ + "${{ matrix.model }}" \ + "${BUILD_MODE}" \ + "${{ matrix.delegate }}" \ + "${ARTIFACTS_DIR_NAME}" fi echo "::endgroup::" @@ -212,6 +260,7 @@ jobs: uses: pytorch/test-infra/.github/workflows/mobile_job.yml@main needs: - set-parameters + - prepare-test-specs - build-benchmark-app - export-models strategy: @@ -231,10 +280,7 @@ jobs: device-pool-arn: ${{ matrix.device }} android-app-archive: https://gha-artifacts.s3.amazonaws.com/${{ github.repository }}/${{ github.run_id }}/artifacts/minibench/app-debug.apk android-test-archive: https://gha-artifacts.s3.amazonaws.com/${{ github.repository }}/${{ github.run_id }}/artifacts/minibench/app-debug-androidTest.apk - # NB: Need to set the default spec here so that it works for periodic too - test-spec: ${{ inputs.test_spec || 'https://ossci-android.s3.amazonaws.com/executorch/android-llm-device-farm-test-spec.yml' }} - # Uploaded to S3 from the previous job - extra-data: https://gha-artifacts.s3.amazonaws.com/${{ github.repository }}/${{ github.run_id }}/artifacts/${{ matrix.model }}_${{ matrix.delegate }}/model.zip + test-spec: https://gha-artifacts.s3.amazonaws.com/${{ github.repository }}/${{ github.run_id }}/artifacts/${{ matrix.model }}_${{ matrix.delegate }}/android-llm-device-farm-test-spec.yml upload-benchmark-results: needs: diff --git a/.github/workflows/upload-android-test-specs.yml b/.github/workflows/upload-android-test-specs.yml deleted file mode 100644 index 4c0b37ab11..0000000000 --- a/.github/workflows/upload-android-test-specs.yml +++ /dev/null @@ -1,94 +0,0 @@ -name: Upload AWS Device Farm Android test specs - -on: - pull_request: - paths: - - .github/workflows/upload-android-test-specs.yml - - extension/benchmark/android/benchmark/android-llm-device-farm-test-spec.yml - push: - branches: - - main - paths: - - .github/workflows/upload-android-test-specs.yml - - extension/benchmark/android/benchmark/android-llm-device-farm-test-spec.yml - -concurrency: - # NB: This concurency group needs to be different than the one used in android-perf, otherwise - # GH complains about concurrency deadlock - group: android-spec-${{ github.event.pull_request.number || github.ref_name }}-${{ github.ref_type == 'branch' && github.sha }}-${{ github.event_name == 'workflow_dispatch' }}-${{ github.event_name == 'schedule' }} - cancel-in-progress: true - -jobs: - upload-android-test-spec-for-validation: - runs-on: linux.2xlarge - steps: - - uses: actions/checkout@v3 - - - name: Upload the spec as a GitHub artifact for validation - uses: seemethere/upload-artifact-s3@v5 - with: - s3-bucket: gha-artifacts - s3-prefix: | - ${{ github.repository }}/${{ github.run_id }}/artifacts - retention-days: 1 - if-no-files-found: error - path: extension/benchmark/android/benchmark/android-llm-device-farm-test-spec.yml - - validate-android-test-spec: - needs: upload-android-test-spec-for-validation - uses: ./.github/workflows/android-perf.yml - permissions: - id-token: write - contents: read - with: - # Just use a small model here with a minimal amount of configuration to test the spec - models: stories110M - devices: samsung_galaxy_s22 - delegates: xnnpack - test_spec: https://gha-artifacts.s3.amazonaws.com/${{ github.repository }}/${{ github.run_id }}/artifacts/android-llm-device-farm-test-spec.yml - - upload-android-test-spec: - needs: validate-android-test-spec - runs-on: ubuntu-22.04 - timeout-minutes: 15 - permissions: - id-token: write - contents: read - steps: - - uses: actions/checkout@v3 - - - uses: actions/setup-python@v4 - with: - python-version: '3.11' - cache: pip - - - name: configure aws credentials - uses: aws-actions/configure-aws-credentials@v1.7.0 - with: - role-to-assume: arn:aws:iam::308535385114:role/gha_executorch_upload-frameworks-android - aws-region: us-east-1 - - - name: Only push to S3 when running the workflow manually from main branch - if: ${{ github.ref == 'refs/heads/main' }} - shell: bash - run: | - set -eux - echo "UPLOAD_ON_MAIN=1" >> "${GITHUB_ENV}" - - - name: Upload the spec to S3 ossci-android bucket - shell: bash - working-directory: extension/benchmark/android/benchmark/ - env: - SPEC_FILE: android-llm-device-farm-test-spec.yml - run: | - set -eux - - pip install awscli==1.32.18 - - AWS_CMD="aws s3 cp --dryrun" - if [[ "${UPLOAD_ON_MAIN:-0}" == "1" ]]; then - AWS_CMD="aws s3 cp" - fi - - shasum -a 256 "${SPEC_FILE}" - ${AWS_CMD} "${SPEC_FILE}" s3://ossci-android/executorch/ --acl public-read diff --git a/extension/benchmark/android/benchmark/android-llm-device-farm-test-spec.yml b/extension/benchmark/android/benchmark/android-llm-device-farm-test-spec.yml.j2 similarity index 92% rename from extension/benchmark/android/benchmark/android-llm-device-farm-test-spec.yml rename to extension/benchmark/android/benchmark/android-llm-device-farm-test-spec.yml.j2 index ffb528767a..d3d6ea04f1 100644 --- a/extension/benchmark/android/benchmark/android-llm-device-farm-test-spec.yml +++ b/extension/benchmark/android/benchmark/android-llm-device-farm-test-spec.yml.j2 @@ -8,6 +8,15 @@ phases: pre_test: commands: + # Download the model from S3 + - curl -s --fail '{{ model_path }}' -o model.zip + - unzip model.zip && ls -la + + # Copy the model to sdcard. This prints too much progress info when the files + # are large, so it's better to just silent them + - adb -s $DEVICEFARM_DEVICE_UDID push *.bin /sdcard > /dev/null && echo OK + - adb -s $DEVICEFARM_DEVICE_UDID push *.pte /sdcard > /dev/null && echo OK + # Prepare the model and the tokenizer - adb -s $DEVICEFARM_DEVICE_UDID shell "ls -la /sdcard/" - adb -s $DEVICEFARM_DEVICE_UDID shell "mkdir -p /data/local/tmp/minibench/"