Upgrade the PyTorch version used by OpenVINO tests (torch / torchvision / torchaudio) and resolve fallout — missing operator translators, new functionalized `*_copy` aten ops, decomposition changes, FX-only tests failing in TorchScript mode, and accuracy regressions caused by stricter typing. Use when the user asks to "bump torch", "update pytorch to X.Y", "upgrade torch tests", or when pytorch_tests / model_hub pytorch tests fail after a torch version change. Do not use for: enabling a single new PyTorch operator unrelated to a version bump, GenAI / Optimum upgrades, or plugin-level numerical bugs unrelated to the frontend.
End-to-end procedure for bumping the PyTorch version used by OpenVINO layer tests and the PyTorch frontend, and fixing the regressions that typically follow.
Before editing anything, confirm with the user:
torch, torchvision:
torchvision minor = torch minor + 15 — e.g. torch 2.9.0 ↔ torchvision 0.24.0, torch 2.12.0 ↔ torchvision 0.27.0. Always confirm against the official release matrix.torchaudio is not pinned by tests/requirements_pytorch: it is unused by these tests and PyTorch removed it from the official installation instructions starting with the 2.8 release. Do not re-add it. If a future task genuinely needs torchaudio, note that it is in a maintenance phase and its latest release can lag torch by one or more minors (e.g. torch 2.12.0 ↔ torchaudio 2.11.0), so torchaudio==<torch version> may not exist — look up the latest available wheel at https://download.pytorch.org/whl/cpu/torchaudio/. Recent torchaudio wheels carry no Requires-Dist: torch pin, so a slightly older torchaudio installs cleanly alongside a newer torch.torch==2.3.1, torchaudio==2.3.1 for auto-gptq) should be touched. Default: leave it alone.PYTORCH_TRACING_MODE=EXPORT (FX) path must be validated. Skip the FX run only if the user explicitly opts out.Edit the following files. Keep ~= style in constraints.txt, exact == in requirements_*. A.B is the torchvision version (torch minor + 15):
torch~=X.Y.0, torchvision~=A.B.0 (constraints.txt does not pin torchaudio)torch==X.Y.0, torchvision==A.B.0 (no torchaudio — see Step 0)tests/model_hub_tests/pytorch/envs/*.txt — bump in lockstep except compile_gptq.txt unless the user confirms.Install into the active environment:
pip3 install --index-url https://download.pytorch.org/whl/cpu --upgrade \
torch==X.Y.0 torchvision==A.B.0Always test against a freshly built openvino_pytorch_frontend. A site-wide install (e.g. under ~/.local) can shadow the dev build — explicitly point at the build output. Set OV_REPO to the OpenVINO checkout root and OV_BUILD_BIN to its build artifact dir (typically $OV_REPO/bin/intel64/Release):
cd "$OV_REPO/tests/layer_tests"
export PYTHONPATH="$OV_BUILD_BIN/python"
export LD_LIBRARY_PATH="$OV_BUILD_BIN"
export TEST_DEVICE=CPU TEST_PRECISION=FP32The pytorch layer tests use two pytest markers to gate which path a test runs on:
-m precommit — TorchScript path (default tracing mode). Use this to validate the TS frontend.-m precommit_torch_export — torch.export / FX path. Requires PYTORCH_TRACING_MODE=EXPORT; the test runner reads that env var to switch the test class behaviour.Both runs are required after a version bump:
# TorchScript path
python3 -m pytest pytorch_tests/ -m precommit -n auto --tb=line -q \
2>&1 | tee /tmp/pt_run_ts.log | tail -5
# torch.export (FX) path
PYTORCH_TRACING_MODE=EXPORT \
python3 -m pytest pytorch_tests/ -m precommit_torch_export -n auto --tb=line -q \
2>&1 | tee /tmp/pt_run_fx.log | tail -5Collect unique failing test files from either log:
grep -E "^FAILED" /tmp/pt_run_ts.log /tmp/pt_run_fx.log | sed 's/\[.*//' | sort -uRun one failing test verbosely to see the real traceback before grouping fixes (add PYTORCH_TRACING_MODE=EXPORT for FX-side reproduction):
python3 -m pytest pytorch_tests/test_<name>.py -k <case> -x --tb=longSort failures into these buckets. The first three are the common ones for any minor torch bump.
Rebuild after any C++ change. Buckets A and B both modify the PyTorch frontend; re-run before re-testing:
cmake --build "$OV_REPO/build" --target openvino_pytorch_frontend -j$(nproc)
Each torch release tends to lower more ops to new aten variants. The *_copy family from functionalization (e.g. aten::select_copy, aten::view_copy, aten::squeeze_copy, aten::expand_copy, aten::permute_copy, aten::as_strided_copy, aten::split_with_sizes_copy, aten::unsqueeze_copy) is one common pattern, but the bucket also covers any other freshly-introduced op (renames, new overloads, ops promoted out of decomposition, etc.). Symptom: log line like No translator found for aten::<name>.
Decision tree:
Semantically equivalent to an existing op (typical for _copy variants — OV graphs are functional, so the copy is a no-op) → alias to the existing translator in the TorchScript table (aten::* keys) of src/frontends/pytorch/src/op_table.cpp:
{"aten::select_copy", op::quantizable_op<op::translate_select>},
{"aten::view_copy", op::quantizable_op<op::translate_reshape>},
{"aten::split_with_sizes_copy", op::translate_split_with_sizes},Different signature but same underlying op → write a thin wrapper that adapts inputs/attrs and dispatches to the existing translator.
Genuinely new behavior → implement a new translator under src/frontends/pytorch/src/op/ and register it in both tables if the FX path also emits it.
Add an FX-table entry (aten.<name>.default / specific overload) only if the FX path also reports the op missing.
Ensure the alias is actually covered by a TorchScript test. Many existing *_copy layer tests are marked only @pytest.mark.precommit_fx_backend (and sometimes precommit_torch_export), so the TS table entry you just added is never exercised by the TorchScript precommit job. After adding a TS alias, find the matching test class (e.g. TestSelectCopy, TestViewCopy) and add @pytest.mark.nightly + @pytest.mark.precommit so the new registration is validated. If no test exists for the op, add one. Reviewers (including Copilot) flag missing TS coverage for new TS registrations.
Symptom: TS test fails with "No translator found for aten::<op>" while an *_fx translator already exists.
Fix: register the existing translate_<op>_fx (or write a thin TS wrapper) in the TS section of op_table.cpp, and extend the translator body to accept the TS calling convention. Use num_inputs_check(context, min, max) and branch on input count for the TS dtype/layout/device tail. Example: see translate_scalar_tensor_fx in src/frontends/pytorch/src/op/scalar_tensor.cpp.
As in Bucket A, add @pytest.mark.nightly + @pytest.mark.precommit to the corresponding test so the TS path is exercised. If you added a new TS-only code branch (e.g. a TS dtype tail), add a parametrized case that hits it — extending the existing test, not duplicating it.
This bucket only applies when a test ends up executed in the TS path while its body relies on FX-only constructs (torch.cond, torch.while_loop, torch.ops.aten.*, torch.ops.quantized_decomposed.*, etc.). It happens when:
@pytest.mark.precommit and @pytest.mark.precommit_torch_export but the body works only on one path, or-m (e.g. ad-hoc full-suite reproduction).If the test is genuinely FX-only, drop the precommit marker so -m precommit skips it cleanly. If both backends are intended, add a body-level guard:
if not (self.use_torch_export() or self.use_torch_compile_backend()):
pytest.skip("FX-only test")For parametrize-time skipping, the helpers in tests/layer_tests/pytorch_tests/pytorch_layer_test_class.py are skip_if_export(*params, reason=...) (skips on the torch.export path), skip_if_fx(*params, reason=...) (skips on the torch.compile/FX path), and skip_check(*params, reason=...) (skips on whichever non-TS path is active). There is no skip_if_ts helper — to skip the TorchScript path, gate inside the test body with if not (self.use_torch_export() or self.use_torch_compile_backend()): pytest.skip(...).
Examples observed in past bumps:
aten::hardtanh_ is now emitted instead of aten::hardtanh when inplace=True — make the expected op-kind dynamic in the test.[0, 1.0] rejected as mixed int/float — change to [0.0, 1.0].scaled_dot_product_attention(enable_gqa=...)) — pass the value explicitly so traced graphs match across versions.Before assuming a translator bug, check whether the same input pattern triggers a known plugin issue (e.g. CPU Multiply(x, Constant(inf)) followed by IsInf with dynamic shape returns all-False due to a Mul+IsInf fusion). If reproducible without the PT FE, work around in the test input and note the underlying ticket in the commit message — do not paper over real frontend regressions.
Re-run both marker scopes from Step 2 until each ends with 0 failed:
python3 -m pytest pytorch_tests/ -m precommit -n auto --tb=line -q 2>&1 | tail -5
PYTORCH_TRACING_MODE=EXPORT \
python3 -m pytest pytorch_tests/ -m precommit_torch_export -n auto --tb=line -q 2>&1 | tail -5Expect a handful of new skipped/xfailed tests after Bucket C fixes — that is normal. FX-path failures usually point to missing FX-table entries or decomposition changes, not TS aliasing.
Model hub tests load real (downloaded) models and prepare inputs using torchvision/torch helpers directly in the test file. These helpers can break when the new torchvision version removes or renames an API.
Where to look: tests/model_hub_tests/pytorch/test_torchvision_models.py and similar files in that directory. Focus on load_model() — it typically contains model-specific input preparation branches.
How to run (from the repository root; install tests/model_hub_tests/pytorch/envs/<suite>.txt first):
export PYTHONPATH=$PWD/tests/model_hub_tests:$PYTHONPATH
export TEST_DEVICE=CPU # default is "CPU;GPU"
export HF_HUB_CACHE=$HOME/.cache/ov_model_hub/hf HF_HOME=$HOME/.cache/ov_model_hub/hf_home
export TORCH_HOME=$HOME/.cache/ov_model_hub/torch
export USE_SYSTEM_CACHE=False # "True" makes some suites wipe HF_HUB_CACHE after each test
python3 -m pytest tests/model_hub_tests/pytorch/test_timm.py -m precommit -n 4
python3 -m pytest tests/model_hub_tests/pytorch/test_timm.py -m nightly -k "<model names>"HF_HUB_CACHE, models are downloaded to a temp directory. Set a persistent cache when re-running the same models.timm_models, torchvision_models, hf_transformers_models, ...) use name,link[,mark,reason] with marks skip, xfail, xfail_trace, xfail_export. The test IDs include mark and reason, so select cases with -k <name>, not by full node ID.filter_timm() in test_timm.py, and test_models_list_complete checks it against the installed timm version. After a timm bump, regenerate it with filter_timm(timm.list_pretrained()) (see src/frontends/pytorch/README.md), keep the existing marks, and validate only the new models.-n 4 on a 64 GB runner. Do not add multi-GB models: several workers loading big models at the same time can run the runner out of memory.Common failure pattern:
ImportError: cannot import name '<name>' from 'torchvision.<module>'A helper function inside the test file imports an API (e.g. torchvision.io.read_video, torchvision.transforms.*) that was removed in the new version. The function is called from inside a load_model() branch for a specific model (e.g. optical-flow models like RAFT).
Fix:
torch.randn(...) tensor of the same shape.Example (optical-flow model input after a 520×960 resize+transform pipeline):
# before
frames = get_video()
self.example = prepare_frames_for_raft(model_name, [frames[100], frames[150]], ...)
# after
self.example = (torch.randn(2, 3, 520, 960), torch.randn(2, 3, 520, 960))
self.inputs = (torch.randn(2, 3, 520, 960), torch.randn(2, 3, 520, 960))Also check that any imports only needed by the removed helper are cleaned up (e.g. import tempfile, import torchvision.transforms.functional as F, get_model_weights).
Verify by checking the torchvision changelog for removed APIs whenever tests in this directory fail after a version bump.
One commit on a feature branch (project convention: <user>/pt_fe/<short-topic>, e.g. mvafin/pt_fe/torch_2_12_upgrade) covering: requirements, op_table.cpp additions, any translator extensions, and test fixes. List the new translators and the broken-test categories in the commit body — reviewers use it to map CI changes to user-visible behavior.
The pre-commit hook runs clang-format and may amend src/frontends/pytorch/src/op/*.cpp; re-stage and recommit if it does.
tests/model_hub_tests/pytorch/) sometimes import torchvision/torch APIs that are removed in a new release. The failure surfaces as an ImportError inside a subprocess (via multiprocessing_run), so the traceback points into the helper, not the test parametrize line. Always check the torchvision changelog for removed APIs when these tests fail after a bump. Replace removed API calls with equivalent torch.randn(...) inputs of the same shape.id(node) when walking ov.Node graphs in Python; wrappers are recreated. Use get_friendly_name().precommit_torch_export still runs under TS if pytest is invoked without -m. Use marker-filtered invocations from Step 2; reserve inline pytest.skip for genuinely dual-marked tests.precommit_fx_backend only. Always add precommit + nightly so the TorchScript job covers them (see Buckets A/B).pytest -n auto requires pytest-xdist (in tests/requirements_pytorch); confirm it is installed in the active env.torchvision minor = torch minor + 15 (torch 2.9 ↔ torchvision 0.24, torch 2.12 ↔ torchvision 0.27). Double-check the official release matrix before pinning.tests/requirements_pytorch, place --extra-index-url https://download.pytorch.org/whl/cpu before the torch== and torchvision== lines so the PyTorch CPU index is available when pip resolves those packages. The line order matters for some pip-based tooling even though pip applies the option globally once parsed.torchaudio is intentionally not in requirements_pytorch (unused; dropped from PyTorch's official install since 2.8). Do not re-add it. If you ever must, note it is in a maintenance phase and lags torch (torch 2.12.0 ↔ torchaudio 2.11.0), so pinning torchaudio==<torch version> blindly causes a CI install failure (No matching distribution found for torchaudio==X.Y.0) — look up the latest available wheel.f766feb
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.