From 8d8ba0b192b1c48ed742f69602dc63e23cd8fcd5 Mon Sep 17 00:00:00 2001 From: Huy Do Date: Wed, 28 Aug 2024 14:14:33 -0700 Subject: [PATCH] Add LLaMA perf benchmark workflow for Apple iOS --- .github/workflows/apple-perf.yml | 178 +++++++++++++++++++++++++++++++ build/build_apple_llm_demo.sh | 24 +++++ 2 files changed, 202 insertions(+) create mode 100644 .github/workflows/apple-perf.yml create mode 100755 build/build_apple_llm_demo.sh diff --git a/.github/workflows/apple-perf.yml b/.github/workflows/apple-perf.yml new file mode 100644 index 0000000000..f875b76b0c --- /dev/null +++ b/.github/workflows/apple-perf.yml @@ -0,0 +1,178 @@ +name: apple-perf + +on: + pull_request: + schedule: + - cron: 0 1 * * * + # Note: GitHub has an upper limit of 10 inputs + workflow_dispatch: + inputs: + models: + description: Models to be benchmarked + required: false + type: string + default: stories110M + devices: + description: Target devices to run benchmark + required: false + type: string + default: apple_iphone_15 + delegates: + description: Backend delegates + required: false + type: string + default: xnnpack + benchmark_configs: + 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: + description: Models to be benchmarked + required: false + type: string + default: stories110M + devices: + description: Target devices to run benchmark + required: false + type: string + default: apple_iphone_15 + delegates: + description: Backend delegates + required: false + type: string + default: xnnpack + benchmark_configs: + 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' }} + cancel-in-progress: true + +jobs: + set-parameters: + runs-on: linux.2xlarge + outputs: + models: ${{ steps.set-parameters.outputs.models }} + devices: ${{ steps.set-parameters.outputs.devices }} + delegates: ${{ steps.set-parameters.outputs.delegates }} + steps: + - name: Set parameters + id: set-parameters + shell: bash + env: + # 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" + CRON_DEFAULT_DEVICES: "apple_iphone_15" + CRON_DEFAULT_DELEGATES: "xnnpack" + run: | + set -ex + MODELS="${{ inputs.models }}" + if [ -z "$MODELS" ]; then + MODELS="$CRON_DEFAULT_MODELS" + fi + DEVICES="${{ inputs.devices }}" + if [ -z "$DEVICES" ]; then + DEVICES="$CRON_DEFAULT_DEVICES" + fi + DELEGATES="${{ inputs.delegates }}" + if [ -z "$DELEGATES" ]; then + DELEGATES="$CRON_DEFAULT_DELEGATES" + fi + + # Mapping devices to their corresponding device-pool-arn + declare -A DEVICE_POOL_ARNS + DEVICE_POOL_ARNS[apple_iphone_15]="arn:aws:devicefarm:us-west-2:308535385114:devicepool:02a2cf0f-6d9b-45ee-ba1a-a086587469e6/3b5acd2e-92e2-4778-b651-7726bafe129d" + + # Resolve device names with their corresponding ARNs + if [[ ! $(echo "$DEVICES" | jq empty 2>/dev/null) ]]; then + DEVICES=$(echo "$DEVICES" | jq -Rc 'split(",")') + fi + declare -a MAPPED_ARNS=() + for DEVICE in $(echo "$DEVICES" | jq -r '.[]'); do + if [[ -z "${DEVICE_POOL_ARNS[$DEVICE]}" ]]; then + echo "Error: No ARN found for device '$DEVICE'. Abort." >&2 + exit 1 + fi + MAPPED_ARNS+=("${DEVICE_POOL_ARNS[$DEVICE]}") + done + + echo "models=$(echo $MODELS | jq -Rc 'split(",")')" >> $GITHUB_OUTPUT + MAPPED_ARNS_JSON=$(printf '%s\n' "${MAPPED_ARNS[@]}" | jq -R . | jq -s .) + echo "devices=$(echo "$MAPPED_ARNS_JSON" | jq -c .)" >> $GITHUB_OUTPUT + echo "delegates=$(echo $DELEGATES | jq -Rc 'split(",")')" >> $GITHUB_OUTPUT + + build-llm-demo: + name: build-llm-demo + uses: pytorch/test-infra/.github/workflows/macos_job.yml@main + needs: set-parameters + strategy: + matrix: + tokenizer: [bpe] + with: + runner: macos-latest-xlarge + python-version: '3.11' + submodules: 'true' + ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + upload-artifact: ios-apps + timeout: 90 + script: | + set -eux + + .ci/scripts/setup-conda.sh + + BUILD_TOOL=cmake + # Setup MacOS dependencies as there is no Docker support on MacOS atm + GITHUB_RUNNER=1 PYTHON_EXECUTABLE=python ${CONDA_RUN} --no-capture-output \ + .ci/scripts/setup-macos.sh "${BUILD_TOOL}" + + # Install CoreML Backend Requirements + PYTHON_EXECUTABLE=python ${CONDA_RUN} --no-capture-output \ + backends/apple/coreml/scripts/install_requirements.sh + + # Install MPS Backend Requirements + PYTHON_EXECUTABLE=python ${CONDA_RUN} --no-capture-output \ + backends/apple/mps/install_requirements.sh + + export ARTIFACTS_DIR_NAME=artifacts-to-be-uploaded + bash build/build_apple_llm_demo.sh ${{ matrix.tokenizer }} ${ARTIFACTS_DIR_NAME} + + upload-ios-apps: + needs: build-llm-demo + runs-on: linux.2xlarge + steps: + - name: Download the apps from GitHub + uses: actions/download-artifact@v3 + with: + # The name here needs to match the name of the upload-artifact parameter + name: ios-apps + path: ${{ runner.temp }}/artifacts/ + + - name: Verify the apps + shell: bash + working-directory: ${{ runner.temp }}/artifacts/ + run: | + ls -lah ./ + + - name: Upload the apps to S3 + uses: seemethere/upload-artifact-s3@v5 + with: + s3-bucket: gha-artifacts + s3-prefix: | + ${{ github.repository }}/${{ github.run_id }}/artifact + retention-days: 14 + if-no-files-found: ignore + path: ${{ runner.temp }}/artifacts/ diff --git a/build/build_apple_llm_demo.sh b/build/build_apple_llm_demo.sh new file mode 100755 index 0000000000..8e39309c44 --- /dev/null +++ b/build/build_apple_llm_demo.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. + +set -euo pipefail + +TOKENIZER="${1:-bpe}" +ARTIFACTS_DIR_NAME="$2" + +APP_PATH="examples/demo-apps/apple_ios/LLaMA/LLaMA" + +xcodebuild build -project "${APP_PATH}.xcodeproj" \ + -scheme LLaMA \ + -destination platform="iOS" \ + -allowProvisioningUpdates \ + DEVELOPMENT_TEAM=78E7V7QP35 \ + CODE_SIGN_STYLE=Manual \ + PROVISIONING_PROFILE_SPECIFIER=iLLaMA \ + CODE_SIGN_IDENTITY="iPhone Distribution" \ + CODE_SIGNING_REQUIRED=No \ + CODE_SIGNING_ALLOWED=No