|
Download code/models/common/README.md from tt-hous/clef: direct link, hf CLI and curl.
- Browser
- Download file 11.7 kB
-
https://huggingface.co/tt-hous/clef/resolve/main/code/models/common/README.md
- Command line
-
hf download hf://tt-hous/clef/code/models/common/README.md
-
curl -L -o README.md https://huggingface.co/tt-hous/clef/resolve/main/code/models/common/README.md
11.7 kB
| # TTNN Validation & Testing Utilities | |
| Helpers for validating TTNN computations against reference implementations and | |
| for moving tensors between TTNN and PyTorch. The public API is implemented | |
| across `models.common.validation_tools`, `models.common.metrics`, | |
| `models.common.auto_compose`, and `models.common.distribute_as`, and is | |
| exercised in: | |
| - `models/common/tests/test_validation_tools.py` | |
| - `models/common/tests/test_metrics.py` | |
| - `models/common/tests/test_auto_compose.py` | |
| - `models/common/tests/test_distribute_as.py` | |
| - `models/common/tests/host/test_metrics_pytorch_only.py` | |
| The examples in these tests are the most up‑to‑date reference for usage. | |
| ## Quick Start – host reference (`compare_to_torch`) | |
| Use `compare_to_torch` when your reference implementation is a PyTorch function. | |
| Inputs and outputs are automatically converted between TTNN and PyTorch. | |
| ```python | |
| import torch | |
| import ttnn | |
| from models.common.validation_tools import compare_to_torch, Metric, get_validation_registry | |
| @compare_to_torch( | |
| reference_fn=torch.matmul, | |
| metric_tolerances={ | |
| Metric.MAX_ABS_ERROR: 1e-1, | |
| Metric.PCC: 0.99, | |
| }, | |
| ) | |
| def ttnn_matmul(a, b): | |
| # a, b are TTNN tensors (possibly sharded) | |
| return ttnn.matmul(a, b) | |
| def run_example(device: ttnn.MeshDevice): | |
| m, n, k = 16, 24, 12 | |
| a = torch.randn(1, m, k, dtype=torch.bfloat16) | |
| b = torch.randn(1, k, n, dtype=torch.bfloat16) | |
| a_tt = ttnn.from_torch(a.unsqueeze(0), device=device, dtype=ttnn.bfloat16, layout=ttnn.TILE_LAYOUT) | |
| b_tt = ttnn.from_torch(b.unsqueeze(0), device=device, dtype=ttnn.bfloat16, layout=ttnn.TILE_LAYOUT) | |
| _ = ttnn_matmul(a_tt, b_tt) | |
| registry = get_validation_registry() | |
| registry.print_report() | |
| ``` | |
| Note: | |
| - When the signature of the decorated function is different from the reference function, `input_to_torch` and `output_to_torch` can be used to map the inputs and outputs between the decorated function and the reference function. | |
| - See `models/common/tests/test_validation_tools.py::test_validation_matmul` for a real test using | |
| this pattern. | |
| ## Quick Start – TTNN reference (`compare_to_ttnn`) | |
| Use `compare_to_ttnn` when both your implementation and reference are TTNN‑based | |
| and you want metrics computed directly on device. | |
| ```python | |
| import torch | |
| import ttnn | |
| from models.common.validation_tools import compare_to_ttnn | |
| def torch_rms_norm(x, weight, eps=1e-6): | |
| var = x.pow(2).mean(-1, keepdim=True) | |
| return weight * x * torch.rsqrt(var + eps) | |
| class DeviceValidatedRMSNorm: | |
| def __init__(self, weight: torch.Tensor, eps: float, device: ttnn.MeshDevice): | |
| self.eps = eps | |
| self.device = device | |
| self.weight_torch = weight | |
| self.weight = ttnn.from_torch( | |
| weight.unsqueeze(0).unsqueeze(0), device=device, dtype=ttnn.bfloat16, layout=ttnn.TILE_LAYOUT | |
| ) | |
| def _reference_impl(self, x): | |
| x_torch = ttnn.to_torch(x).squeeze(0) | |
| y_torch = torch_rms_norm(x_torch, self.weight_torch, self.eps) | |
| return ttnn.from_torch( | |
| y_torch.unsqueeze(0), device=self.device, dtype=ttnn.bfloat16, layout=ttnn.TILE_LAYOUT | |
| ) | |
| @compare_to_ttnn(reference_fn=lambda self, x: self._reference_impl(x)) | |
| def __call__(self, x): | |
| x_sq = ttnn.mul(x, x) | |
| mean_x_sq = ttnn.mean(x_sq, dim=-1, keepdim=True) | |
| rms = ttnn.sqrt(ttnn.add(mean_x_sq, self.eps)) | |
| x_norm = ttnn.mul(x, ttnn.reciprocal(rms)) | |
| return ttnn.mul(x_norm, self.weight) | |
| ``` | |
| Note: | |
| - When the signature of the decorated function is different from the reference function, `input_to_ttnn` and `output_to_ttnn` can be used to map the inputs and outputs between the decorated function and the reference function. | |
| - This mirrors the pattern used by `DeviceValidatedRMSNorm` in | |
| `models/common/tests/test_validation_tools.py`. | |
| ## Features | |
| - **Decorator‑based validation** – Wrap TTNN functions or methods and compare | |
| them against PyTorch or TTNN references. | |
| - **Host and device modes** – `compare_to_torch` (PyTorch reference) and | |
| `compare_to_ttnn` (TTNN reference). | |
| - **TTNN‑native metrics** – When both outputs are TTNN tensors, metrics are | |
| computed on device with minimal host transfer. | |
| - **Configurable tolerances** – Per‑metric tolerances via the `Metric` enum, | |
| string keys, or `MetricSpec`. | |
| - **Custom metrics** – Inject your own metric functions. | |
| - **Global registry** – Collects all validation runs for reporting. | |
| - **Easy disabling** – Turn validation on/off globally without changing call | |
| sites. | |
| ## Core Components | |
| ### Validation decorators | |
| All decorators live in `models.common.validation_tools`: | |
| - `compare_to_torch(reference_fn, *, input_to_torch=None, output_to_torch=None, metric_tolerances=None, enabled=True, raise_exceptions=False, return_reference_output=False)` | |
| - Use when `reference_fn` is a PyTorch implementation. | |
| - By default, all TTNN tensors in the arguments/outputs are converted to | |
| PyTorch via `to_torch_auto_compose`. | |
| - Optional `input_to_torch(*args, **kwargs)` lets you override how inputs | |
| are mapped to the reference. | |
| - Optional `output_to_torch(output)` converts the implementation output | |
| before metrics are computed. | |
| - `compare_to_ttnn(reference_fn, *, input_to_ttnn=None, output_to_ttnn=None, metric_tolerances=None, enabled=True, raise_exceptions=False, return_reference_output=False)` | |
| - Use when `reference_fn` consumes and returns TTNN tensors. | |
| - Optional `input_to_ttnn(*args, **kwargs)` lets you override how inputs | |
| are mapped to the reference. | |
| - Optional `output_to_ttnn(output)` converts the implementation output | |
| before metrics are computed. | |
| - If both implementation and reference return TTNN tensors, metrics run | |
| entirely on device. | |
| In both cases, decorating a function records a `ValidationResult` in the global | |
| `ValidationRegistry` every time the function is called (unless disabled). | |
| ### Metrics | |
| Metric utilities are implemented in `models.common.metrics`: | |
| - `compute_max_abs_error(impl, ref)` – max absolute error. | |
| - `compute_mean_abs_error(impl, ref)` – mean absolute error. | |
| - `compute_pcc(impl, ref)` – Pearson correlation coefficient; uses TTNN | |
| operations when possible and falls back to host. | |
| - `comp_allclose(impl, ref, rtol=..., atol=...)` – allclose check plus a | |
| detailed delta string. | |
| - `DEFAULT_METRICS` – dict with built‑in metrics (`"max_abs_error"`, | |
| `"mean_abs_error"`, `"pcc"`). | |
| Metrics support both TTNN and PyTorch tensors. | |
| ### Registry and control functions | |
| From `models.common.validation_tools`: | |
| - `get_validation_registry() -> ValidationRegistry` | |
| - Holds all `ValidationResult` objects. | |
| - Provides `get_summary()` and `print_report(verbose: bool = False)`. | |
| - `enable_validation(enabled: bool = True)` | |
| - Globally enable/disable validation; when disabled, decorators become | |
| transparent wrappers. | |
| - `clear_validation_results()` | |
| - Clear all accumulated validation results. | |
| `ValidationResult` includes: | |
| - `function_name` | |
| - `passed` (bool) | |
| - `metrics` – map of metric name → per‑metric result (value, passed, error) | |
| - `execution_time_impl`, `execution_time_ref` | |
| - `timestamp` | |
| - `logs` – optional debug strings | |
| ### Auto‑compose helper | |
| `to_torch_auto_compose` lives in `models.common.auto_compose`. | |
| It converts an arbitrary TTNN tensor (including sharded/replicated multi‑device | |
| tensors) to a single PyTorch tensor by automatically choosing the appropriate | |
| mesh composer. | |
| It is heavily used in: | |
| - `test_auto_compose.py` | |
| - `test_distribute_as.py` | |
| - all `compare_to_torch`‑based examples. | |
| ## Usage Patterns | |
| High‑level patterns illustrated in the tests: | |
| 1. **Host reference with explicit input mapping** | |
| - See `HostValidatedRMSNorm` in `models/common/tests/test_validation_tools.py`. | |
| - Uses `compare_to_torch` with `input_to_torch` to map TTNN inputs and | |
| TTNN weights to a pure‑PyTorch reference function. | |
| 2. **TTNN reference (on‑device metrics)** | |
| - See `DeviceValidatedRMSNorm` in `models/common/tests/test_validation_tools.py`. | |
| - Uses `compare_to_ttnn` where both implementation and reference return | |
| TTNN tensors; metrics run on device. | |
| 3. **Simple library calls** | |
| - See `ttnn_matmul` and `ttnn_matmul_reverse` in `models/common/tests/test_validation_tools.py`. | |
| - `compare_to_torch(reference_fn=torch.matmul, ...)` with optional | |
| `input_to_torch` remapping. | |
| 4. **Checkpoint / `from_torch` validation** | |
| - See `from_torch_checkpoint` in `models/common/tests/test_validation_tools.py`. | |
| - Validates a direct `ttnn.from_torch(...)` call using `compare_to_torch` | |
| and `output_to_torch`. | |
| 5. **Custom metric via `MetricSpec`** | |
| - See `ttnn_matmul_metric_spec` in `models/common/tests/test_validation_tools.py` | |
| and `MetricSpec` usage in `models/common/tests/host/test_metrics_pytorch_only.py`. | |
| - Use `MetricSpec(tolerance=..., higher_is_better=..., compute_fn=...)` | |
| in `metric_tolerances`. | |
| 6. **Non‑decorator usage** | |
| - `test_validation_non_decorator_class_vs_class_torch` demonstrates calling | |
| `compare_to_torch` in a more manual, non‑decorator style between two | |
| callable classes. | |
| ## Default Metrics and Tolerances | |
| When `metric_tolerances` is omitted, the framework uses sensible defaults: | |
| - `Metric.MAX_ABS_ERROR` with tolerance `1e-2` | |
| - `Metric.PCC` with tolerance `0.99` | |
| If you pass a `metric_tolerances` dict, keys can be: | |
| - `Metric` enum members (recommended), e.g. `Metric.MAX_ABS_ERROR` | |
| - strings (`"max_abs_error"`, `"mean_abs_error"`, `"pcc"`) | |
| - arbitrary names when used with `MetricSpec` | |
| Values can be: | |
| - a float tolerance (uses the built‑in metric) | |
| - a `MetricSpec` instance to define a custom metric and tolerance | |
| Example: | |
| ```python | |
| from models.common.validation_tools import Metric, MetricSpec | |
| from models.common.metrics import compute_pcc | |
| @compare_to_torch( | |
| reference_fn=torch.matmul, | |
| metric_tolerances={ | |
| Metric.PCC: MetricSpec(tolerance=0.99, higher_is_better=True, compute_fn=compute_pcc), | |
| Metric.MAX_ABS_ERROR: 1.5e-1, | |
| }, | |
| ) | |
| def ttnn_matmul_metric_spec(a, b): | |
| return ttnn.matmul(a, b) | |
| ``` | |
| ## Testing | |
| The local test suite in `models/common/tests` shows end‑to‑end usage: | |
| - `test_validation_tools.py` | |
| - Core decorator usage, registry behaviour, error handling, custom metrics. | |
| - `test_metrics.py` | |
| - Numerical correctness of device and host metric functions. | |
| - `host/test_metrics_pytorch_only.py` | |
| - Pure‑PyTorch metric tests. | |
| - `test_auto_compose.py` | |
| - Auto‑composition of sharded/replicated TTNN tensors into PyTorch. | |
| - `test_distribute_as.py` | |
| - Distribution helpers (`from_torch_dist_as`) that mirror an existing TTNN | |
| tensor’s topology. | |
| Example commands (run from the repo root, with TTNN available): | |
| ```bash | |
| python -m pytest models/common/tests/test_validation_tools.py -v | |
| python -m pytest models/common/tests/test_metrics.py -v | |
| python -m pytest models/common/tests/host/test_metrics_pytorch_only.py -v | |
| ``` | |
| ## API Reference (public surface) | |
| All symbols below are imported from `models.common.validation_tools` and `models.common.metrics`: | |
| - Decorators: | |
| - `compare_to_torch` | |
| - `compare_to_ttnn` | |
| - Registry and control: | |
| - `ValidationResult` | |
| - `ValidationRegistry` | |
| - `get_validation_registry` | |
| - `enable_validation` | |
| - `clear_validation_results` | |
| - Metrics: | |
| - `Metric` (enum: `MAX_ABS_ERROR`, `MEAN_ABS_ERROR`, `PCC`) | |
| - `MetricSpec` | |
| - `compute_max_abs_error` | |
| - `compute_mean_abs_error` | |
| - `compute_pcc` | |
| - `comp_allclose` | |
| - `DEFAULT_METRICS` | |
| - Auto‑compose: | |
| - `to_torch_auto_compose` | |
| For concrete, runnable examples of each API, see the tests listed at the top | |
| of this document. | |