diff --git a/.ci/scripts/test_backend.sh b/.ci/scripts/test_backend.sh index 6de519d3bec..e3f8c7d159c 100755 --- a/.ci/scripts/test_backend.sh +++ b/.ci/scripts/test_backend.sh @@ -113,7 +113,12 @@ GOLDEN_DIR="${ARTIFACT_DIR}/golden-artifacts" export GOLDEN_ARTIFACTS_DIR="${GOLDEN_DIR}" EXIT_CODE=0 -PYTEST_ARGS=(-c /dev/null -n auto) +PYTEST_WORKERS=auto +if [[ "$FLOW" == *qnn* && "$SUITE" == "models" ]]; then + # Concurrent QNN model exports can exhaust a linux.2xlarge runner. + PYTEST_WORKERS=2 +fi +PYTEST_ARGS=(-c /dev/null -n "$PYTEST_WORKERS") if [[ ${#PYTEST_RETRY_ARGS[@]} -gt 0 ]]; then PYTEST_ARGS+=("${PYTEST_RETRY_ARGS[@]}") fi diff --git a/.ci/scripts/test_model.sh b/.ci/scripts/test_model.sh index c056b5ac98a..a0ef093d91a 100755 --- a/.ci/scripts/test_model.sh +++ b/.ci/scripts/test_model.sh @@ -127,6 +127,14 @@ test_model() { return fi + if [[ "${MODEL_NAME}" == "yolo26" ]]; then + # Install yolo26 requirements (ultralytics). torch/torchvision are already + # installed and satisfy ultralytics, so only-if-needed leaves them as-is. + # No pytorch extra-index-url: it is unused here and would broaden pip's + # version resolution across all deps. + "${PYTHON_EXECUTABLE}" -m pip install --upgrade-strategy only-if-needed -r examples/models/yolo26/requirements.txt + fi + # Export a basic .pte and run the model. "${PYTHON_EXECUTABLE}" -m examples.portable.scripts.export --model_name="${MODEL_NAME}" "${STRICT}" run_portable_executor_runner diff --git a/.ci/scripts/test_model_e2e.sh b/.ci/scripts/test_model_e2e.sh index d8bca45e695..b64d4fef9b3 100755 --- a/.ci/scripts/test_model_e2e.sh +++ b/.ci/scripts/test_model_e2e.sh @@ -284,7 +284,7 @@ elif [[ "$MODEL_NAME" == *whisper* ]] || [ "$MODEL_NAME" = "voxtral_realtime" ]; fi fi pip install datasets soundfile - pip install torchcodec==0.11.0 --extra-index-url https://download.pytorch.org/whl/test/cpu + pip install torchcodec==0.15.0 --index-url https://download.pytorch.org/whl/cpu python -c "from datasets import load_dataset;import soundfile as sf;sample = load_dataset('distil-whisper/librispeech_long', 'clean', split='validation')[0]['audio'];sf.write('${MODEL_DIR}/$AUDIO_FILE', sample['array'][:sample['sampling_rate']*30], sample['sampling_rate'])" fi diff --git a/.ci/scripts/test_wheel_package_qnn.sh b/.ci/scripts/test_wheel_package_qnn.sh index 763bd8733c1..72e7123da07 100644 --- a/.ci/scripts/test_wheel_package_qnn.sh +++ b/.ci/scripts/test_wheel_package_qnn.sh @@ -167,8 +167,8 @@ PY # ) echo "=== [$LABEL] Install torch==${TORCH_VERSION} ===" - # Install torch based on the pinned PyTorch version, preferring the PyTorch test index - "$PIPBIN" install torch=="${TORCH_VERSION}" --extra-index-url "https://download.pytorch.org/whl/test" + # Install torch based on the pinned PyTorch version. + "$PIPBIN" install --no-cache-dir torch=="${TORCH_VERSION}" --index-url "https://download.pytorch.org/whl/cpu" "$PIPBIN" install wheel # Install torchao based on the pinned commit from third-party/ao submodule diff --git a/backends/arm/scripts/aot_arm_compiler.py b/backends/arm/scripts/aot_arm_compiler.py index 601d74bbf85..405b4a66efd 100644 --- a/backends/arm/scripts/aot_arm_compiler.py +++ b/backends/arm/scripts/aot_arm_compiler.py @@ -925,12 +925,16 @@ def _to_edge_cortex_m( def _to_channels_last(x): if isinstance(x, torch.Tensor): - if x.dim() == 4 and not x.is_contiguous(memory_format=torch.channels_last): - logging.warning( - "Converting input tensor with shape %s to channels_last", - list(x.shape), - ) - return x.to(memory_format=torch.channels_last) + if x.dim() == 4: + # Singleton channels can satisfy both contiguity checks while + # retaining NCHW strides, so always request the target format. + channels_last = x.to(memory_format=torch.channels_last) + if channels_last.stride() != x.stride(): + logging.warning( + "Converting input tensor with shape %s to channels_last", + list(x.shape), + ) + return channels_last return x elif isinstance(x, tuple): return tuple(_to_channels_last(t) for t in x) @@ -979,7 +983,7 @@ def _to_channels_last(x): ) edge._edge_programs["forward"] = pass_manager.transform() - return model_quant, edge + return model_quant, edge, example_inputs def _to_edge_no_delegate( @@ -1078,7 +1082,7 @@ def main() -> None: # noqa: C901 "(this target does not use delegated ops)." ) args.delegate = False - model_quant, edge = _to_edge_cortex_m( + model_quant, edge, example_inputs = _to_edge_cortex_m( exported_program, args, model, diff --git a/backends/arm/test/models/test_llama.py b/backends/arm/test/models/test_llama.py index 6f770e89652..5b2246c4020 100644 --- a/backends/arm/test/models/test_llama.py +++ b/backends/arm/test/models/test_llama.py @@ -208,6 +208,11 @@ def test_llama_tosa_FP(): pipeline.run() +@pytest.mark.xfail( + reason="index_put into a preserved fp32 mutable KV cache (torchao pytorch/ao#4466) is " + "not delegatable by the INT backend, so the cache round-trip forms a partition " + "dependency cycle. Same root cause as the xfailed static-cache tests: MLETORCH-1971." +) def test_llama_tosa_INT(): llama_model, llama_inputs, llama_meta = TestLlama().prepare_model() @@ -229,6 +234,11 @@ def test_llama_tosa_INT(): pipeline.run() +@pytest.mark.xfail( + reason="index_put into a preserved fp32 mutable buffer (torchao pytorch/ao#4466) is " + "not delegatable by the INT backend, so the KV-cache round-trip forms a partition " + "dependency cycle. Same root cause as the xfailed static-cache tests: MLETORCH-1971." +) def test_llama_tosa_INT_static(): llama_model, llama_inputs, _ = TestLlama().prepare_model_hf_static() if llama_model is None or llama_inputs is None: @@ -270,6 +280,11 @@ def test_llama_vgf_no_quant(): @common.SkipIfNoModelConverter +@pytest.mark.xfail( + reason="The KV cache stays fp32 (torchao pytorch/ao#4466), so attention reads it as " + "float while the query is quantized: MATMUL rejects the int8/float32 operand pair. " + "Same root cause as the xfailed static-cache tests: MLETORCH-1971." +) def test_llama_vgf_quant(): llama_model, llama_inputs, llama_meta = TestLlama().prepare_model() diff --git a/docs/source/getting-started.md b/docs/source/getting-started.md index 4d05ecb090f..ef161e8bbc3 100644 --- a/docs/source/getting-started.md +++ b/docs/source/getting-started.md @@ -160,7 +160,7 @@ For a full example of running a model on Android, see the [DeepLabV3AndroidDemo] #### Installation ExecuTorch supports both iOS and macOS via C++, as well as hardware backends for CoreML, MPS, and CPU. The iOS runtime library is provided as a collection of .xcframework targets and are made available as a Swift PM package. -To get started with Xcode, go to File > Add Package Dependencies. Paste the URL of the ExecuTorch repo into the search bar and select it. Make sure to change the branch name to the desired ExecuTorch version in format “swiftpm-”, (e.g. “swiftpm-0.6.0”). The ExecuTorch dependency can also be added to the package file manually. See [Using ExecuTorch on iOS](using-executorch-ios.md) for more information. +To get started with Xcode, go to File > Add Package Dependencies. Paste the URL of the ExecuTorch repo into the search bar and select it. Make sure to change the branch name to the desired ExecuTorch version in format “swiftpm-”, (e.g. “swiftpm-1.4.0”). The ExecuTorch dependency can also be added to the package file manually. See [Using ExecuTorch on iOS](using-executorch-ios.md) for more information. #### Runtime APIs Models can be loaded and run from Objective-C using the C++ APIs. diff --git a/docs/source/raspberry_pi_llama_tutorial.md b/docs/source/raspberry_pi_llama_tutorial.md index 6075e455c9b..754957670f9 100644 --- a/docs/source/raspberry_pi_llama_tutorial.md +++ b/docs/source/raspberry_pi_llama_tutorial.md @@ -57,7 +57,7 @@ First, clone the ExecuTorch repository with the Raspberry Pi support: ```bash # Create project directory -mkdir ~/executorch-rpi && cd ~/executorch-rpi && git clone -b release/1.0 https://github.com/pytorch/executorch.git && +mkdir ~/executorch-rpi && cd ~/executorch-rpi && git clone -b release/1.4 https://github.com/pytorch/executorch.git && cd executorch ``` diff --git a/docs/source/using-executorch-ios.md b/docs/source/using-executorch-ios.md index 0761f167482..6eecd7d46a3 100644 --- a/docs/source/using-executorch-ios.md +++ b/docs/source/using-executorch-ios.md @@ -28,7 +28,7 @@ The prebuilt ExecuTorch runtime, backend, and kernels are available as a [Swift #### Xcode -In Xcode, go to `File > Add Package Dependencies`. Paste the URL of the [ExecuTorch repo](https://github.com/pytorch/executorch) into the search bar and select it. Make sure to change the branch name to the desired ExecuTorch version in format "swiftpm-", (e.g. "swiftpm-1.0.0"), or a branch name in format "swiftpm-." (e.g. "swiftpm-1.1.0-20251101") for a [nightly build](https://ossci-ios.s3.amazonaws.com/list.html) on a specific date. +In Xcode, go to `File > Add Package Dependencies`. Paste the URL of the [ExecuTorch repo](https://github.com/pytorch/executorch) into the search bar and select it. Make sure to change the branch name to the desired ExecuTorch version in format "swiftpm-", (e.g. "swiftpm-1.4.0"), or a branch name in format "swiftpm-." (e.g. "swiftpm-1.5.0-20260801") for a [nightly build](https://ossci-ios.s3.amazonaws.com/list.html) on a specific date. ![](_static/img/swiftpm_xcode1.png) @@ -61,7 +61,7 @@ let package = Package( ], dependencies: [ // Use "swiftpm-." branch name for a nightly build. - .package(url: "https://github.com/pytorch/executorch.git", branch: "swiftpm-1.0.0") + .package(url: "https://github.com/pytorch/executorch.git", branch: "swiftpm-1.4.0") ], targets: [ .target( diff --git a/examples/models/mlperf_tiny/ds_cnn.py b/examples/models/mlperf_tiny/ds_cnn.py index 0e922192496..251f287c278 100644 --- a/examples/models/mlperf_tiny/ds_cnn.py +++ b/examples/models/mlperf_tiny/ds_cnn.py @@ -83,6 +83,4 @@ def get_eager_model(self) -> torch.nn.Module: return DSCNNKWS().eval() def get_example_inputs(self): - return ( - (torch.rand(1, 1, 49, 10) * 2 - 1).to(memory_format=torch.channels_last), - ) + return (torch.rand(1, 1, 49, 10) * 2 - 1,) diff --git a/examples/models/moshi/mimi/install_requirements.sh b/examples/models/moshi/mimi/install_requirements.sh index 9fc12f64bc9..6636d02ee20 100755 --- a/examples/models/moshi/mimi/install_requirements.sh +++ b/examples/models/moshi/mimi/install_requirements.sh @@ -8,7 +8,7 @@ set -x sudo apt install ffmpeg -y -pip install torchcodec==0.11.0 --extra-index-url https://download.pytorch.org/whl/test/cpu +pip install torchcodec==0.15.0 --index-url https://download.pytorch.org/whl/cpu pip install moshi==0.2.11 pip install bitsandbytes soundfile einops # Run llama2/install requirements for torchao deps diff --git a/extension/llm/tokenizers b/extension/llm/tokenizers index 1d7ca636008..636d7cd65b3 160000 --- a/extension/llm/tokenizers +++ b/extension/llm/tokenizers @@ -1 +1 @@ -Subproject commit 1d7ca636008fdf88b0c64498ce9cf426041c8443 +Subproject commit 636d7cd65b31af0150845d7d8ee62f47845f19e6 diff --git a/install_requirements.py b/install_requirements.py index 7986cfacff9..5165b61a2c8 100644 --- a/install_requirements.py +++ b/install_requirements.py @@ -16,7 +16,7 @@ # This will be dynamically set based on CUDA availability and CUDA backend enabled/disabled. TORCH_URL_BASE = "https://download.pytorch.org/whl/test" TORCHAO_URL_BASE = "https://download.pytorch.org/whl/nightly" -TORCHAO_NIGHTLY_VERSION = "0.18.0.dev20260715" +TORCHAO_NIGHTLY_VERSION = "0.18.0" # Since ExecuTorch often uses main-branch features of pytorch, only the nightly # pip versions will have the required features. diff --git a/setup.py b/setup.py index 8331deec8ad..b054f0fbe72 100644 --- a/setup.py +++ b/setup.py @@ -184,11 +184,12 @@ def _base_dependencies() -> List[str]: "packaging", "pandas>=2.2.2; python_version >= '3.10'", "parameterized", - "pytorch-tokenizers", + "pytorch-tokenizers>=1.4.0", "pyyaml", "ruamel.yaml", "sympy", "tabulate", + "torchao>=0.18.0", # See also third-party/TARGETS for buck's typing-extensions version. "typing-extensions>=4.10.0", # Keep this version in sync with: ./backends/apple/coreml/scripts/install_requirements.sh diff --git a/third-party/ao b/third-party/ao index 4aa81011346..5f2baf9d575 160000 --- a/third-party/ao +++ b/third-party/ao @@ -1 +1 @@ -Subproject commit 4aa810113463571cabb7342d1a00a1f3de9c54f2 +Subproject commit 5f2baf9d575cf732362594c998c399902942531f diff --git a/version.txt b/version.txt index 895d424d5d4..88c5fb891dc 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.4.0a0 +1.4.0