Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions .claude/skills/torch-tweak-assistant/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,16 @@ Do NOT activate this skill when:

### TorchAO Backend
- **Best for**: PyTorch-native quantization on Intel GPU / XPU
- **Simple**: `TorchAOBackend()` with no config needed

### Torch Inductor Backend
- **Best for**: PyTorch compiler-based optimization on Intel GPU / XPU
- **Simple**: `TorchInductorBackend()` with no config needed

### XPU Graph Backend
- **Best for**: replaying a module that was recorded once during tuning
- **Rejection**: failed, empty, or incorrect recordings are dropped for that module and input

### OpenVINO Backend
- **Best for**: an OpenVINO model on an Intel CPU or GPU
- **Simple**: `OpenVINOBackend()` with no config needed
- **Strengths**:
- Converts PyTorch models to OpenVINO IR for deployment
- Applies hardware-specific optimizations
Expand All @@ -82,7 +83,6 @@ Do NOT activate this skill when:

### Torch Eager Backend
- **Best for**: the uncompiled baseline inside a throughput search
- **Simple**: `TorchEagerBackend()` with no config needed

## Tuning Strategies

Expand All @@ -93,8 +93,8 @@ Do NOT activate this skill when:
## Best Practices

### Backend Selection
- **HighestThroughputStrategy**: TorchAO, Torch Inductor, OpenVINO, and eager. It measures each one and keeps the fastest. List order does not change the winner.
- **FirstWinsStrategy**: default order is Torch Inductor, OpenVINO, then eager. The first backend that builds is kept. TorchAO is not in that default, because the first backend that builds wins and a quantization that builds would be kept without a speed comparison.
- **HighestThroughputStrategy**: the default list is Torch Inductor, XPU graph, and eager. It measures each one and keeps the fastest. List order does not change the winner. TorchAO and OpenVINO are optional additions.
- **FirstWinsStrategy**: default order is XPU graph, Torch Inductor, OpenVINO, then eager. The first backend that builds is kept. TorchAO is not in that default, because the first backend that builds wins and a quantization that builds would be kept without a speed comparison.

### Common Issues
- **Graph breaks**: conditional logic in a module blocks tuning of that module
Expand Down Expand Up @@ -124,6 +124,7 @@ tt.load(model, "tuned_model.tt")
from torch_tweak.torch.backend import (
TorchAOBackend,
TorchInductorBackend,
XPUGraphBackend,
OpenVINOBackend,
TorchEagerBackend,
)
Expand All @@ -133,6 +134,7 @@ strategy = HighestThroughputStrategy(
backends=[
TorchAOBackend(),
TorchInductorBackend(),
XPUGraphBackend(),
OpenVINOBackend(),
TorchEagerBackend(),
]
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ This page is the landing summary. The same file is the PyPI long description.
| Feature | Description |
|-----------------------------|---------------------------------------------------------------------------------------------------------------------------|
| Ease-of-use | Single line of code to run all possible tuning paths directly from your source code |
| Wide Backend Support | Compatible with TorchAO, Torch Inductor, OpenVINO, and eager PyTorch |
| Wide Backend Support | Compatible with TorchAO, Torch Inductor, XPU graph, OpenVINO, and eager PyTorch |
| Model Tuning | Enhance the performance of models such as ResNET and BERT for efficient inference deployment |
| Pipeline Tuning | Streamline Python code pipelines for models such as Stable Diffusion and Flux using seamless model wrapping and tuning |
| Correctness Testing | Ensures tuned models produce correct outputs by validating on provided data samples |
Expand All @@ -55,6 +55,7 @@ use frameworks like vLLM or SGLang for best performance. Use Torch Tweak for gen
from torch_tweak.torch.backend import (
TorchAOBackend,
TorchInductorBackend,
XPUGraphBackend,
OpenVINOBackend,
TorchEagerBackend,
)
Expand All @@ -65,13 +66,14 @@ strategy = HighestThroughputStrategy(
backends=[
TorchAOBackend(),
TorchInductorBackend(),
XPUGraphBackend(),
OpenVINOBackend(),
TorchEagerBackend(),
]
)
```

TorchAO, Torch Inductor, and OpenVINO configuration is in the [backends guide](docs/learn/backends.md).
TorchAO, Torch Inductor, XPU graph, and OpenVINO configuration is in the [backends guide](docs/learn/backends.md).
Torch Eager accepts an optional autocast dtype and otherwise runs the module unchanged.
Tune strategies are in [core functionalities](docs/learn/core_functionalities.md).

Expand Down
20 changes: 20 additions & 0 deletions docs/api/backends/xpu_graph_backend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!--
Copyright (c) 2026 Intel Corporation
SPDX-License-Identifier: Apache-2.0
-->

# XPU Graph Backend API

## XPUGraphBackend

::: torch_tweak.torch.backend.XPUGraphBackend
options:
show_root_heading: true
heading_level: 3

## XPUGraphBackendConfig

::: torch_tweak.torch.backend.XPUGraphBackendConfig
options:
show_root_heading: true
heading_level: 3
37 changes: 37 additions & 0 deletions docs/guides/backends/xpu_graph_backend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<!--
Copyright (c) 2026 Intel Corporation
SPDX-License-Identifier: Apache-2.0
-->

# XPU Graph Backend Guide

The XPU graph backend records the module on an Intel GPU once during tuning and replays that recording on later inference calls.
Recording is not repeated for each inference call.

## Overview

- **One recording**: warmup and capture run in `build`, while the module is being tuned
- **Replay**: inference copies new tensor values into the recorded inputs and calls `replay`
- **Rejection**: a failed recording, an empty recording, or outputs that disagree with eager drop this backend for that module and input
- **Static shapes**: a batch axis or another dynamic axis rejects the backend. Replay cannot change tensor shapes
- **Fallback**: an inference call whose inputs differ from the recorded call in shape, dtype, device, or a non-tensor value runs the original module

## Quick Start

```python
from torch_tweak.torch.backend import XPUGraphBackend
from torch_tweak.torch.tune_strategy import HighestThroughputStrategy

strategy = HighestThroughputStrategy(backends=[XPUGraphBackend()])
```

The backend is first in the default `FirstWinsStrategy` list, before Torch Inductor.
It is also in the default `HighestThroughputStrategy` list.

PyTorch records a native SYCL graph when it was built with a SYCL compiler of 2026.1 or newer, except on PVC.
An older build records the legacy SYCL command graph.
This backend uses the recording that build already performs.

## Next Steps

- API reference: [XPU Graph Backend](../../api/backends/xpu_graph_backend.md)
2 changes: 1 addition & 1 deletion docs/guides/tune_strategies/tune_strategies.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ tt.tune(model, input_data)

## FirstWinsStrategy

Tries backends in priority order and returns the first one that successfully builds and validates. If a backend fails, the strategy moves on to the next candidate instead of aborting. If all backends fail, the error is caught and the original model is used as-is. The default order is Torch Inductor, then OpenVINO, then eager. Put a backend earlier only when you want that one to win as soon as it builds.
Tries backends in priority order and returns the first one that successfully builds and validates. If a backend fails, the strategy moves on to the next candidate instead of aborting. If all backends fail, the error is caught and the original model is used as-is. The default order is XPU graph, Torch Inductor, OpenVINO, then eager. Put a backend earlier only when you want that one to win as soon as it builds.

### Usage

Expand Down
1 change: 1 addition & 0 deletions docs/guides/tuning.md
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ Example output from that command, with the cache directory set to `/tmp/torch-tw
2026-10-01 06:19:51,359 - INFO - name: First Wins Strategy
2026-10-01 06:19:51,359 - INFO - description: evaluate backends in order, return first working backend
2026-10-01 06:19:51,360 - INFO - backends:
2026-10-01 06:19:51,360 - INFO - XPUGraphBackend()
2026-10-01 06:19:51,360 - INFO - TorchInductorBackend()
2026-10-01 06:19:51,360 - INFO - OpenVINOBackend()
2026-10-01 06:19:51,360 - INFO - TorchEagerBackend()
Expand Down
14 changes: 14 additions & 0 deletions docs/learn/backends.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,20 @@ backend = TorchInductorBackend()

Guide: [Torch Inductor Backend](../guides/backends/torch_inductor_backend.md).

## XPU Graph Backend

The XPU graph backend records the module once while tuning and replays that recording for later inference.
PyTorch chooses native or legacy recording. This backend uses whichever one that build records.
A recording that fails, or that disagrees with eager, is rejected for that module and input.

```python
from torch_tweak.torch.backend import XPUGraphBackend

backend = XPUGraphBackend()
```

Guide: [XPU Graph Backend](../guides/backends/xpu_graph_backend.md).

## OpenVINO Backend

The OpenVINO backend converts the module to an OpenVINO model and runs it on an Intel CPU or GPU.
Expand Down
3 changes: 2 additions & 1 deletion docs/learn/core_functionalities.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ from torch_tweak.torch.tune_strategy import FirstWinsStrategy

strategy = FirstWinsStrategy(
backends=[
XPUGraphBackend(),
TorchInductorBackend(),
OpenVINOBackend(),
TorchEagerBackend(),
Expand All @@ -131,7 +132,7 @@ strategy = OneBackendStrategy(backend=OpenVINOBackend())

## HighestThroughputStrategy

Profiles all compatible backends and selects the fastest. Use this when maximum throughput matters and you can afford longer tuning time. `HighestThroughputStrategy()` with no backend list compares Torch Inductor and eager only.
Profiles all compatible backends and selects the fastest. Use this when maximum throughput matters and you can afford longer tuning time. `HighestThroughputStrategy()` with no backend list compares Torch Inductor, XPU graph, and eager.

```python
from torch_tweak.torch.tune_strategy import HighestThroughputStrategy
Expand Down
4 changes: 2 additions & 2 deletions docs/learn/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ NOTE: This file has been modified by Intel Corporation.

**Torch Tweak** is an inference toolkit designed for tuning and deploying Deep Learning models with a focus on Intel XPU (GPU) accelerators. It provides model tuning capabilities through compilation and conversion paths that can significantly improve inference speed and efficiency across various AI workloads including Computer Vision, Natural Language Processing, Speech Recognition, and Generative AI.

The toolkit enables seamless tuning of PyTorch models and pipelines using TorchAO, Torch Inductor, OpenVINO, and eager through a single Python API. The resulting tuned models are ready for deployment in production environments.
The toolkit enables seamless tuning of PyTorch models and pipelines using TorchAO, Torch Inductor, XPU graph, OpenVINO, and eager through a single Python API. The resulting tuned models are ready for deployment in production environments.

Torch Tweak works with your environment - relying first on your software versions - and selects the best-performing backend for your software and hardware setup, guiding you to supported technologies.

Expand All @@ -31,7 +31,7 @@ The distinct capabilities of Torch Tweak are summarized in the feature matrix:
| Feature | Description |
|-----------------------------|---------------------------------------------------------------------------------------------------------------------------|
| Ease-of-use | Single line of code to run all possible tuning paths directly from your source code |
| Wide Backend Support | Compatible with TorchAO, Torch Inductor, OpenVINO, and eager |
| Wide Backend Support | Compatible with TorchAO, Torch Inductor, XPU graph, OpenVINO, and eager |
| Model Tuning | Enhance the performance of models such as ResNET and BERT for efficient inference deployment |
| Pipeline Tuning | Streamline Python code pipelines for models such as Stable Diffusion and Flux using seamless model wrapping and tuning |
| Correctness Testing | Ensures tuned models produce correct outputs by validating on provided data samples |
Expand Down
7 changes: 6 additions & 1 deletion examples/E5Large/e5large/tune.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@

import torch
from torch_tweak.torch import HighestThroughputStrategy, inspect, save, tune, wrap
from torch_tweak.torch.backend import TorchEagerBackend, TorchInductorBackend
from torch_tweak.torch.backend import (
TorchEagerBackend,
TorchInductorBackend,
XPUGraphBackend,
)
from torch_tweak.torch.config import config as global_config

from .cmd_args import get_parser
Expand Down Expand Up @@ -97,6 +101,7 @@ def call_wrapper(*args, **kwargs):
backends=[
TorchEagerBackend(),
TorchInductorBackend(),
XPUGraphBackend(),
]
).enable_find_max_batch_size(True),
)
Expand Down
7 changes: 6 additions & 1 deletion examples/ESM2/esm2/tune.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@
from transformers import AutoTokenizer, EsmForMaskedLM

import torch_tweak.torch as tt
from torch_tweak.torch.backend import TorchEagerBackend, TorchInductorBackend
from torch_tweak.torch.backend import (
TorchEagerBackend,
TorchInductorBackend,
XPUGraphBackend,
)

DEVICE = torch.device("xpu")
MODEL_NAME = "facebook/esm2_t33_650M_UR50D"
Expand Down Expand Up @@ -61,6 +65,7 @@ def tune(
strategy = tt.FirstWinsStrategy(
backends=[
TorchInductorBackend(),
XPUGraphBackend(),
TorchEagerBackend(),
]
)
Expand Down
2 changes: 2 additions & 0 deletions examples/FLUX/flux/tune.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
OpenVINOBackendConfig,
TorchEagerBackend,
TorchInductorBackend,
XPUGraphBackend,
)

logger = getLogger(__name__)
Expand Down Expand Up @@ -58,6 +59,7 @@ def tune_model(
strategy = tt.FirstWinsStrategy(
backends=[
TorchInductorBackend(),
XPUGraphBackend(),
OpenVINOBackend(
OpenVINOBackendConfig(
use_dynamo=False,
Expand Down
16 changes: 12 additions & 4 deletions examples/Minimal/demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
import torch.nn as nn

import torch_tweak.torch as tt
from torch_tweak.torch.backend import TorchEagerBackend, TorchInductorBackend
from torch_tweak.torch.backend import (
TorchEagerBackend,
TorchInductorBackend,
XPUGraphBackend,
)


def main() -> None:
Expand All @@ -19,13 +23,17 @@ def main() -> None:
model = nn.Sequential(nn.Linear(32, 32), nn.ReLU(), nn.Linear(32, 8)).eval().to(device)
sample = torch.randn(32, device=device)

# Skip the max-batch search. The two batch sizes below are enough to pick a backend.
# One batch size keeps every tensor shape static, so the XPU graph can be recorded.
strategy = tt.HighestThroughputStrategy(
backends=[TorchInductorBackend(), TorchEagerBackend()],
backends=[
TorchInductorBackend(),
XPUGraphBackend(),
TorchEagerBackend(),
],
).enable_find_max_batch_size(False)

module = tt.Module(model, name="mlp", strategy=strategy)
tt.tune(module, sample, batch_sizes=[1, 4], device=device)
tt.tune(module, sample, batch_sizes=[4], device=device)

results = strategy.results[-1].highest_throughput_results if strategy.results else []
if not results:
Expand Down
7 changes: 6 additions & 1 deletion examples/ParakeetCTC/parakeet_ctc/tune.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@
from parakeet_ctc.cmd_args import parse_args
from parakeet_ctc.model import get_model
from torch_tweak.torch import FirstWinsStrategy, TuneStrategy, inspect, save, tune, wrap
from torch_tweak.torch.backend import TorchEagerBackend, TorchInductorBackend
from torch_tweak.torch.backend import (
TorchEagerBackend,
TorchInductorBackend,
XPUGraphBackend,
)

logger = getLogger(__name__)

Expand Down Expand Up @@ -81,6 +85,7 @@ def main():
strategy = FirstWinsStrategy(
backends=[
TorchInductorBackend(),
XPUGraphBackend(),
TorchEagerBackend(),
]
)
Expand Down
2 changes: 2 additions & 0 deletions examples/ParakeetRNNT/parakeet_rnnt/tune.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
TorchEagerBackend,
TorchInductorBackend,
TorchInductorBackendConfig,
XPUGraphBackend,
)

logger = getLogger(__name__)
Expand Down Expand Up @@ -48,6 +49,7 @@ def tune_model(
strategy = strategy or HighestThroughputStrategy(
backends=[
TorchInductorBackend(TorchInductorBackendConfig(autocast_enabled=True, autocast_dtype=torch.float16)),
XPUGraphBackend(),
TorchEagerBackend(),
]
).enable_find_max_batch_size(False)
Expand Down
2 changes: 2 additions & 0 deletions examples/ResNet/resnet/tune.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
TorchEagerBackend,
TorchInductorBackend,
TorchInductorBackendConfig,
XPUGraphBackend,
)

logger = getLogger(__name__)
Expand Down Expand Up @@ -60,6 +61,7 @@ def tune_model(
TorchInductorBackend(
config=TorchInductorBackendConfig(autocast_enabled=True, autocast_dtype=torch.float16)
),
XPUGraphBackend(),
TorchEagerBackend(),
]
).enable_find_max_batch_size(False),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
TorchEagerBackend,
TorchInductorBackend,
TorchInductorBackendConfig,
XPUGraphBackend,
)
from torch_tweak.torch.tune_strategy import HighestThroughputStrategy, OneBackendStrategy

Expand All @@ -35,6 +36,7 @@ def _inductor_backend() -> TorchInductorBackend:
def _backend_catalog() -> dict[str, Backend]:
return {
"inductor": _inductor_backend(),
"xpu_graph": XPUGraphBackend(),
"openvino": _openvino_backend(use_dynamo=False),
"openvino_dynamo": _openvino_backend(use_dynamo=True),
"eager": TorchEagerBackend(),
Expand Down
2 changes: 2 additions & 0 deletions properdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ nav:
- OpenVINO Backend: guides/backends/openvino_backend.md
- TorchAO Backend: guides/backends/torchao_backend.md
- Torch Inductor Backend: guides/backends/torch_inductor_backend.md
- XPU Graph Backend: guides/backends/xpu_graph_backend.md
- Torch Eager Backend: guides/backends/torch_eager_backend.md
- Tune Strategies: guides/tune_strategies/tune_strategies.md
- Deployment: guides/deployment/deployment.md
Expand Down Expand Up @@ -114,6 +115,7 @@ nav:
- OpenVINO Backend: api/backends/openvino_backend.md
- TorchAO Backend: api/backends/torchao_backend.md
- Torch Inductor Backend: api/backends/torch_inductor_backend.md
- XPU Graph Backend: api/backends/xpu_graph_backend.md
- Torch Eager Backend: api/backends/torch_eager_backend.md
- Tuning Strategies API:
- FirstWinsStrategy: api/tune_strategies/first_wins_strategy.md
Expand Down
Loading
Loading