|  | 
|  | 1 | +name: Test Metal Backend | 
|  | 2 | + | 
|  | 3 | +on: | 
|  | 4 | +  pull_request: | 
|  | 5 | +  push: | 
|  | 6 | +    branches: | 
|  | 7 | +      - main | 
|  | 8 | +      - release/* | 
|  | 9 | + | 
|  | 10 | +concurrency: | 
|  | 11 | +  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}-${{ github.event_name == 'workflow_dispatch' }}-${{ github.event_name == 'schedule' }} | 
|  | 12 | +  cancel-in-progress: false | 
|  | 13 | + | 
|  | 14 | +jobs: | 
|  | 15 | +  test-metal-builds: | 
|  | 16 | +    name: test-executorch-metal-build | 
|  | 17 | +    runs-on: macos-latest | 
|  | 18 | +    steps: | 
|  | 19 | +      - name: Checkout repository | 
|  | 20 | +        uses: actions/checkout@v3 | 
|  | 21 | +        with: | 
|  | 22 | +          submodules: recursive | 
|  | 23 | +          ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} | 
|  | 24 | + | 
|  | 25 | +      - name: Setup Python | 
|  | 26 | +        uses: actions/setup-python@v4 | 
|  | 27 | +        with: | 
|  | 28 | +          python-version: '3.10' | 
|  | 29 | + | 
|  | 30 | +      - name: Test ExecuTorch Metal build | 
|  | 31 | +        run: | | 
|  | 32 | +          set -eux | 
|  | 33 | +
 | 
|  | 34 | +          # Test ExecuTorch Metal build | 
|  | 35 | +          PYTHON_EXECUTABLE=python3 CMAKE_ARGS="-DEXECUTORCH_BUILD_METAL=ON" ./install_executorch.sh | 
|  | 36 | +
 | 
|  | 37 | +  export-voxtral-metal-artifact: | 
|  | 38 | +    name: export-voxtral-metal-artifact | 
|  | 39 | +    runs-on: macos-latest | 
|  | 40 | +    steps: | 
|  | 41 | +      - name: Checkout repository | 
|  | 42 | +        uses: actions/checkout@v3 | 
|  | 43 | +        with: | 
|  | 44 | +          submodules: recursive | 
|  | 45 | +          ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} | 
|  | 46 | + | 
|  | 47 | +      - name: Setup Python | 
|  | 48 | +        uses: actions/setup-python@v4 | 
|  | 49 | +        with: | 
|  | 50 | +          python-version: '3.10' | 
|  | 51 | + | 
|  | 52 | +      - name: Export Voxtral with Metal Backend | 
|  | 53 | +        env: | 
|  | 54 | +          EXECUTORCH_HF_TOKEN: ${{ secrets.EXECUTORCH_HF_TOKEN }} | 
|  | 55 | +        run: | | 
|  | 56 | +          set -eux | 
|  | 57 | +
 | 
|  | 58 | +          echo "::group::Setup ExecuTorch" | 
|  | 59 | +          PYTHON_EXECUTABLE=python3 ./install_executorch.sh | 
|  | 60 | +          echo "::endgroup::" | 
|  | 61 | +
 | 
|  | 62 | +          echo "::group::Setup Huggingface" | 
|  | 63 | +          pip3 install -U "huggingface_hub[cli]" accelerate | 
|  | 64 | +          huggingface-cli login --token $EXECUTORCH_HF_TOKEN | 
|  | 65 | +          OPTIMUM_ET_VERSION=$(cat .ci/docker/ci_commit_pins/optimum-executorch.txt) | 
|  | 66 | +          pip3 install git+https://github.com/huggingface/optimum-executorch.git@${OPTIMUM_ET_VERSION} | 
|  | 67 | +          pip3 install mistral-common librosa | 
|  | 68 | +          pip3 list | 
|  | 69 | +          echo "::endgroup::" | 
|  | 70 | +
 | 
|  | 71 | +          echo "::group::Export Voxtral" | 
|  | 72 | +          optimum-cli export executorch \ | 
|  | 73 | +              --model "mistralai/Voxtral-Mini-3B-2507" \ | 
|  | 74 | +              --task "multimodal-text-to-text" \ | 
|  | 75 | +              --recipe "metal" \ | 
|  | 76 | +              --dtype bfloat16 \ | 
|  | 77 | +              --max_seq_len 1024 \ | 
|  | 78 | +              --output_dir ./ | 
|  | 79 | +          python3 -m executorch.extension.audio.mel_spectrogram \ | 
|  | 80 | +              --feature_size 128 \ | 
|  | 81 | +              --stack_output \ | 
|  | 82 | +              --max_audio_len 300 \ | 
|  | 83 | +              --output_file voxtral_preprocessor.pte | 
|  | 84 | +
 | 
|  | 85 | +          test -f model.pte | 
|  | 86 | +          test -f aoti_metal_blob.ptd | 
|  | 87 | +          test -f voxtral_preprocessor.pte | 
|  | 88 | +          echo "::endgroup::" | 
|  | 89 | +
 | 
|  | 90 | +          echo "::group::Store Voxtral Artifacts" | 
|  | 91 | +          mkdir -p artifacts | 
|  | 92 | +          cp model.pte artifacts/ | 
|  | 93 | +          cp aoti_metal_blob.ptd artifacts/ | 
|  | 94 | +          cp voxtral_preprocessor.pte artifacts/ | 
|  | 95 | +          ls -al artifacts | 
|  | 96 | +          echo "::endgroup::" | 
|  | 97 | +
 | 
|  | 98 | +      - name: Upload artifacts | 
|  | 99 | +        uses: actions/upload-artifact@v4 | 
|  | 100 | +        with: | 
|  | 101 | +          name: voxtral-metal-export | 
|  | 102 | +          path: artifacts/ | 
|  | 103 | + | 
|  | 104 | +  test-voxtral-metal-e2e: | 
|  | 105 | +    name: test-voxtral-metal-e2e | 
|  | 106 | +    needs: export-voxtral-metal-artifact | 
|  | 107 | +    runs-on: macos-latest | 
|  | 108 | +    steps: | 
|  | 109 | +      - name: Checkout repository | 
|  | 110 | +        uses: actions/checkout@v3 | 
|  | 111 | +        with: | 
|  | 112 | +          submodules: recursive | 
|  | 113 | +          ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} | 
|  | 114 | + | 
|  | 115 | +      - name: Setup Python | 
|  | 116 | +        uses: actions/setup-python@v4 | 
|  | 117 | +        with: | 
|  | 118 | +          python-version: '3.10' | 
|  | 119 | + | 
|  | 120 | +      - name: Download artifacts | 
|  | 121 | +        uses: actions/download-artifact@v4 | 
|  | 122 | +        with: | 
|  | 123 | +          name: voxtral-metal-export | 
|  | 124 | +          path: artifacts/ | 
|  | 125 | + | 
|  | 126 | +      - name: Test Voxtral Metal E2E | 
|  | 127 | +        run: | | 
|  | 128 | +          set -eux | 
|  | 129 | +
 | 
|  | 130 | +          echo "::group::Setup ExecuTorch Requirements" | 
|  | 131 | +          CMAKE_ARGS="-DEXECUTORCH_BUILD_METAL=ON" ./install_requirements.sh | 
|  | 132 | +          pip3 list | 
|  | 133 | +          echo "::endgroup::" | 
|  | 134 | +
 | 
|  | 135 | +          echo "::group::Prepare Voxtral Artifacts" | 
|  | 136 | +          cp artifacts/model.pte . | 
|  | 137 | +          cp artifacts/aoti_metal_blob.ptd . | 
|  | 138 | +          cp artifacts/voxtral_preprocessor.pte . | 
|  | 139 | +          TOKENIZER_URL="https://huggingface.co/mistralai/Voxtral-Mini-3B-2507/resolve/main/tekken.json" | 
|  | 140 | +          curl -L $TOKENIZER_URL -o tekken.json | 
|  | 141 | +          ls -al model.pte aoti_metal_blob.ptd voxtral_preprocessor.pte tekken.json | 
|  | 142 | +          echo "::endgroup::" | 
|  | 143 | +
 | 
|  | 144 | +          echo "::group::Create Test Audio File" | 
|  | 145 | +          say -o call_samantha_hall.aiff "Call Samantha Hall" | 
|  | 146 | +          afconvert -f WAVE -d LEI16 call_samantha_hall.aiff call_samantha_hall.wav | 
|  | 147 | +          echo "::endgroup::" | 
|  | 148 | +
 | 
|  | 149 | +          echo "::group::Build Voxtral Runner" | 
|  | 150 | +          cmake --preset llm \ | 
|  | 151 | +                -DEXECUTORCH_BUILD_METAL=ON \ | 
|  | 152 | +                -DCMAKE_INSTALL_PREFIX=cmake-out \ | 
|  | 153 | +                -DCMAKE_BUILD_TYPE=Release \ | 
|  | 154 | +                -Bcmake-out -S. | 
|  | 155 | +          cmake --build cmake-out -j$(( $(sysctl -n hw.ncpu) - 1 )) --target install --config Release | 
|  | 156 | +
 | 
|  | 157 | +          cmake -DEXECUTORCH_BUILD_METAL=ON \ | 
|  | 158 | +                -DCMAKE_BUILD_TYPE=Release \ | 
|  | 159 | +                -Sexamples/models/voxtral \ | 
|  | 160 | +                -Bcmake-out/examples/models/voxtral/ | 
|  | 161 | +          cmake --build cmake-out/examples/models/voxtral --target voxtral_runner --config Release | 
|  | 162 | +          echo "::endgroup::" | 
|  | 163 | +
 | 
|  | 164 | +          echo "::group::Run Voxtral Runner" | 
|  | 165 | +          set +e | 
|  | 166 | +          OUTPUT=$(cmake-out/examples/models/voxtral/voxtral_runner \ | 
|  | 167 | +                --model_path model.pte \ | 
|  | 168 | +                --data_path aoti_metal_blob.ptd \ | 
|  | 169 | +                --tokenizer_path tekken.json \ | 
|  | 170 | +                --audio_path call_samantha_hall.wav \ | 
|  | 171 | +                --processor_path voxtral_preprocessor.pte \ | 
|  | 172 | +                --temperature 0 2>&1) | 
|  | 173 | +          EXIT_CODE=$? | 
|  | 174 | +          set -e | 
|  | 175 | +
 | 
|  | 176 | +          echo "$OUTPUT" | 
|  | 177 | +
 | 
|  | 178 | +          if ! echo "$OUTPUT" | grep -iq "Samantha"; then | 
|  | 179 | +            echo "Expected output 'Samantha' not found in output" | 
|  | 180 | +            exit 1 | 
|  | 181 | +          fi | 
|  | 182 | +
 | 
|  | 183 | +          if [ $EXIT_CODE -ne 0 ]; then | 
|  | 184 | +            echo "Unexpected exit code: $EXIT_CODE" | 
|  | 185 | +            exit $EXIT_CODE | 
|  | 186 | +          fi | 
|  | 187 | +          echo "::endgroup::" | 
0 commit comments