Add files using upload-large-folder tool
Browse files- README.md +154 -318
- code/models/common/auto_compose.py +161 -0
- code/models/common/rmsnorm.py +226 -0
- code/models/common/tensor_utils.py +229 -0
- code/models/common/validation_tools.py +719 -0
- code/models/tt_transformers/Host_Mem_Profile.md +88 -0
- code/models/tt_transformers/PERF.md +247 -0
- code/models/tt_transformers/README.md +388 -0
- code/models/tt_transformers/conftest.py +31 -0
- code/models/tt_transformers/host_mem_profiler.py +188 -0
- image/blobs/sha256/0690f7dcdac59b821f2eff8a565951a2120a112c6b9613f43be03bb143f8875b +1 -0
- image/blobs/sha256/0b3b7bf707349d15afaf4582949a95082c50449ac8e4f7346d1bbee5bc7ba1c5 +1 -0
- image/blobs/sha256/18b68d787d3c7446ef9eb0eba334950a837818ace17924cb42e6e6a2fac47a17 +1 -0
- image/blobs/sha256/18f46874ca6617cba588e37f39ecd58f44b02065d3c3ea3909c403d2260b686d +1 -0
- image/blobs/sha256/1d805657f0ef573b66e654d64007281d8aadf4dfa8aa1eb88672c886293dfe13 +1 -0
- image/blobs/sha256/1f179d27e2f48842a37b1dbe6300e0e9d83c174ae4c6d879f38b473d31ff159f +1 -0
- image/blobs/sha256/28b873d0d487580ae6a42f1c52c28160516c4f2e4d82abf93e6f6b7c95e49bc7 +1 -0
- image/blobs/sha256/3dcb0a4c97491bdc43addf1e7fe76c9dd7a714314fc4729a32cf94c89455a2a5 +1 -0
- image/blobs/sha256/4b7d28cf86399d4e9f4f1eeba9a85df52bfc3e360e1c831def2915ad8cff54db +1 -0
- image/blobs/sha256/5116d36f79d2da6aa08f8ffcff866e39d7c0f5be5bbf3d74c6e8c8caebf2c5fd +0 -0
- image/blobs/sha256/5628e13ce208b83d793af15fa41c28d1702e7a43e27c8c72944442d01e959a71 +1 -0
- image/blobs/sha256/5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef +0 -0
- image/blobs/sha256/639c9dd1747f941795c619f445de593cc6d7957060442b3dbe0148bd1be1eeb3 +0 -0
- image/blobs/sha256/718b6feb51a3973517c6ac89780d58b88478d3ddbdc41353af609f6c944dc085 +1 -0
- image/blobs/sha256/77b04a4822168bcd77a83c78c22a390734a35e4232b7c9f2485b2663b5fefb7c +1 -0
- image/blobs/sha256/7f2d9782a5ff3e0bf36c4b028cdf5b4e59db0cdf2122cea0669de2841c5d05f7 +1 -0
- image/blobs/sha256/8529443804912d6639846836d1b7ab793de42b54e3b4058e14a059f0d5fe4ade +0 -0
- image/blobs/sha256/89fcc824b4db414c4ba9f1a86324bd6bfa92505480f7c02fd87f4e3c79ebf1de +1 -0
- image/blobs/sha256/8a28dfa1a683cbd7674d79f7ac878f4ba04d0a72bccfe56cec0f0f008b325bdd +1 -0
- image/blobs/sha256/96f3b28657c091e4818e2407f66db33853828fdb8abef3177cdf5c8d525f7dbf +0 -0
- image/blobs/sha256/bc34115d8ab3da3bb2818457b8bc493ed594968b9ae39c48e30c22b37294974b +1 -0
- image/blobs/sha256/c0d475ded7d3e60cdc094385f92036f940b605a0438578608e031030a8819ae9 +0 -0
- image/blobs/sha256/cf8ccef7cd12a5a0492c4e3cde07fef8807fe0cd228de6257516ba32f752276c +1 -0
- image/blobs/sha256/dfbe9006d67d8efd33cd4834af36a9acd4030ef4f5a9aca44181d9555d590526 +1 -0
- image/blobs/sha256/e1272a58679febd696c70d77b53ffeb43cba62b4ddb3d97dd4e632c6848d2856 +0 -0
- image/blobs/sha256/e71053098ec0882ae447db33f4d23f6455424ec7cf649519ac98455342a3ffbe +1 -0
- image/blobs/sha256/e78a28551be8e30ee61eba8b7627859a67e05827f5119754228edfe4ca005e48 +1 -0
- image/blobs/sha256/e94cd641692a2de981d616a078e01282ac9e8cef9fb44bfa26cbab8bc16d9812 +1 -0
- image/blobs/sha256/ec0a7658dda53cfa39e9a61f8506fce49e56b206fee8ab604f17daa0a8f42f43 +1 -0
- image/blobs/sha256/fd7308f35b11a131ac41df34684d400e1400055c0e48edb78f7f3292ce84db55 +1 -0
- image/blobs/sha256/fff7562e27cd6bcd475d31d119da76f39d239cfc59ab03ff6579a8f10ca6e05c +1 -0
- image/index.json +1 -0
- image/manifest.json +1 -0
- image/oci-layout +1 -0
- image/repositories +1 -0
- requirements.lock +86 -0
- tt_kernel_manifest.json +120 -0
README.md
CHANGED
|
@@ -1,348 +1,184 @@
|
|
| 1 |
---
|
| 2 |
-
pipeline_tag: object-detection
|
| 3 |
tags:
|
| 4 |
-
- tenstorrent
|
| 5 |
- blackhole
|
| 6 |
- p150
|
| 7 |
-
-
|
| 8 |
-
- tt-
|
| 9 |
-
- tt-
|
| 10 |
-
- visual-grounding
|
| 11 |
-
- open-vocabulary
|
| 12 |
-
- vlm
|
| 13 |
-
- qwen2.5
|
| 14 |
-
base_model:
|
| 15 |
-
- nvidia/LocateAnything-3B
|
| 16 |
-
license: other
|
| 17 |
-
license_name: nvidia-license
|
| 18 |
-
license_link: https://huggingface.co/nvidia/LocateAnything-3B/blob/main/LICENSE
|
| 19 |
---
|
| 20 |
|
| 21 |
-
#
|
| 22 |
|
| 23 |
-
NVIDIA LocateAnything-3B
|
| 24 |
|
| 25 |
-
|
| 26 |
|
| 27 |
-
|
| 28 |
-
|---|---|
|
| 29 |
-
| Hardware | Tenstorrent Blackhole **p150a** (single chip) |
|
| 30 |
-
| Runtime | [tt-metal](https://github.com/tenstorrent/tt-metal) / tt-nn |
|
| 31 |
-
| Upstream model | [huggingface.co/nvidia/LocateAnything-3B](https://huggingface.co/nvidia/LocateAnything-3B) |
|
| 32 |
-
| Port source | [github.com/changh95/tt-locate-anything](https://github.com/changh95/tt-locate-anything) |
|
| 33 |
-
|
| 34 |
-
> [!IMPORTANT]
|
| 35 |
-
> This repo holds **model code, not weights.** It is a tt-nn port that runs against a
|
| 36 |
-
> built `tt-metal` checkout on a machine with a Blackhole card; weights are fetched
|
| 37 |
-
> from the upstream repo above. See *Licensing* at the end for terms.
|
| 38 |
-
|
| 39 |
-
---
|
| 40 |
-
|
| 41 |
-
## Project README
|
| 42 |
-
|
| 43 |
-
End-to-end port of NVIDIA
|
| 44 |
-
[LocateAnything-3B](https://huggingface.co/nvidia/LocateAnything-3B) — an Eagle-family
|
| 45 |
-
visual-grounding / open-vocabulary detection VLM — to Tenstorrent **tt-metal**
|
| 46 |
-
(tt-nn + tt-metallium), running on a single Blackhole **p150a** chip.
|
| 47 |
-
|
| 48 |
-
The model is a **MoonViT-SO-400M** vision tower + a 2×2 patch merger + an `mlp1`
|
| 49 |
-
projector feeding a **Qwen2.5-3B-Instruct** language model with an extended
|
| 50 |
-
detection vocabulary. Given an image and a free-text query ("locate all the
|
| 51 |
-
instances that match …"), it emits `<ref>label</ref><box><x1><y1><x2><y2></box>`
|
| 52 |
-
token sequences that decode to pixel boxes.
|
| 53 |
-
|
| 54 |
-
This repository contains:
|
| 55 |
-
|
| 56 |
-
- a TT-NN MoonViT vision tower + projector (`locate_anything/tt/vision.py`),
|
| 57 |
-
- a thin `Transformer` subclass that drives the Qwen2.5-3B backbone from
|
| 58 |
-
pre-merged image+text embeddings (`locate_anything/tt/model_la.py`),
|
| 59 |
-
- an experimental on-device **Parallel Box Decoding** (MTP) decoder
|
| 60 |
-
(`locate_anything/tt/mtp.py`),
|
| 61 |
-
- a self-contained torch-CPU reference + golden/oracle builders
|
| 62 |
-
(`locate_anything/reference/`),
|
| 63 |
-
- pytest suites for per-stage vision PCC, an end-to-end baseline benchmark with a
|
| 64 |
-
PCC accuracy gate, an MTP fidelity test, and two image-in / boxes-out demos.
|
| 65 |
-
|
| 66 |
-
Unlike a from-scratch ttnn model, **LocateAnything's LLM backbone reuses
|
| 67 |
-
tt-metal's own model libraries** — `models.tt_transformers` (the stock Qwen2.5
|
| 68 |
-
`Transformer` / `Generator` / paged-KV `Attention` / `MLP`) and
|
| 69 |
-
`models.demos.qwen25_vl` (vision-token merge + prefill prep). So this repo is an
|
| 70 |
-
*overlay* on a tt-metal checkout, not a standalone reimplementation: point Python
|
| 71 |
-
at a built tt-metal and run from here. See **Environment setup**.
|
| 72 |
-
|
| 73 |
-
---
|
| 74 |
-
|
| 75 |
-
## Demo
|
| 76 |
|
| 77 |
-
|
| 78 |
-
the full pipeline (MoonViT vision + Qwen2.5-3B LLM) on one Blackhole p150a.
|
| 79 |
-
Reproduce with `pytest locate_anything/tests/test_demo_visualize.py` (AR) or
|
| 80 |
-
`test_demo_mtp_visualize.py` (MTP); query and image are set via `LA_QUERY` /
|
| 81 |
-
`LA_IMAGE`.
|
| 82 |
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
---
|
| 88 |
-
|
| 89 |
-
## Contents
|
| 90 |
-
|
| 91 |
-
```
|
| 92 |
-
locate_anything/
|
| 93 |
-
├── reference/
|
| 94 |
-
│ ├── la_inputs.py # image preprocess + chat-template build (no cv2/lmdb/decord)
|
| 95 |
-
│ ├── extract_llm_checkpoint.py# LocateAnything-3B → vanilla Qwen2.5-3B HF dir for tt_transformers
|
| 96 |
-
│ ├── run_reference.py # HF torch-CPU golden dump (vision + prefill logits) → golden.pt
|
| 97 |
-
│ ├── mtp_cpu_loop.py # correct bsz=1 hybrid/fast MTP loop (torch CPU); the device blueprint
|
| 98 |
-
│ └── mtp_oracle.py # picks a box-yielding (image,query); dumps MTP oracle → mtp_oracle.pt
|
| 99 |
-
├── tt/
|
| 100 |
-
│ ├── vision.py # TT-NN MoonViT-SO-400M + mlp1 projector (bf16 / HiFi4)
|
| 101 |
-
│ ├── model_la.py # LATransformer: Qwen2.5-3B with embeds-driven prefill
|
| 102 |
-
│ └── mtp.py # MTPDecoder: on-device Parallel Box Decoding (experimental)
|
| 103 |
-
└── tests/
|
| 104 |
-
├── test_vision.py # incremental vision PCC vs golden (gate ≥ 0.99)
|
| 105 |
-
├── bench_locate_anything.py # baseline benchmark: prefill PCC + greedy AR decode + metrics
|
| 106 |
-
├── test_mtp.py # device-MTP vs torch-CPU-MTP logit PCC (fidelity)
|
| 107 |
-
├── test_demo_visualize.py # image → boxes (greedy AR) visualization
|
| 108 |
-
└── test_demo_mtp_visualize.py # image → boxes (hybrid MTP) visualization
|
| 109 |
-
scripts/
|
| 110 |
-
└── download_weights.sh # pull LocateAnything-3B + extract the Qwen2.5-3B LLM dir
|
| 111 |
-
conftest.py # loads tt-metal's device fixtures (mesh_device, device_params, …)
|
| 112 |
```
|
| 113 |
|
| 114 |
-
|
| 115 |
-
torch goldens. The first come from your tt-metal build; the second from the Hugging
|
| 116 |
-
Face Hub; the third are generated locally.
|
| 117 |
|
| 118 |
-
-
|
| 119 |
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
`ttnn`, `models.tt_transformers`, and `models.demos.qwen25_vl`, all of which
|
| 125 |
-
this repo imports directly.
|
| 126 |
-
|
| 127 |
-
2. **Install the Python deps** (the tt-metal `python_env` already has most of
|
| 128 |
-
them). A working set on top of `ttnn`:
|
| 129 |
-
|
| 130 |
-
```bash
|
| 131 |
-
pip install torch torchvision transformers safetensors pillow numpy loguru \
|
| 132 |
-
huggingface_hub matplotlib
|
| 133 |
-
```
|
| 134 |
-
|
| 135 |
-
`torch` can be CPU-only — it is used for the reference, host embedding lookup,
|
| 136 |
-
the vision-token merge, and host argmax sampling.
|
| 137 |
-
|
| 138 |
-
3. **Point Python at tt-metal** and set the runtime env. The single most important
|
| 139 |
-
variable is `TT_VISIBLE_DEVICES`, which constrains UMD to a single chip:
|
| 140 |
-
|
| 141 |
-
```bash
|
| 142 |
-
export TT_METAL_HOME=/path/to/tt-metal
|
| 143 |
-
export ARCH_NAME=blackhole
|
| 144 |
-
export MESH_DEVICE=N150 # single-chip 1x1 mesh
|
| 145 |
-
export PYTHONPATH=$PWD:$TT_METAL_HOME:$TT_METAL_HOME/ttnn:$TT_METAL_HOME/tools
|
| 146 |
-
# Run on exactly ONE Blackhole chip. Set BOTH so UMD opens only this chip:
|
| 147 |
-
export TT_VISIBLE_DEVICES=0
|
| 148 |
-
export TT_METAL_VISIBLE_DEVICES=0
|
| 149 |
-
```
|
| 150 |
-
|
| 151 |
-
`conftest.py` re-uses tt-metal's own pytest fixtures and hooks (so
|
| 152 |
-
`mesh_device` / `device_params` / `reset_seeds` behave identically to running
|
| 153 |
-
inside the tt-metal tree); it requires `TT_METAL_HOME` to be set.
|
| 154 |
-
|
| 155 |
-
4. **Download the weights** and extract the LLM directory:
|
| 156 |
|
| 157 |
-
|
| 158 |
-
bash scripts/download_weights.sh
|
| 159 |
-
# → LocateAnything-3B snapshot (LA_MODEL_PATH) + extracted Qwen2.5-3B (HF_MODEL)
|
| 160 |
-
export HF_MODEL=~/.cache/locate_anything/LA-Qwen2.5-3B
|
| 161 |
-
```
|
| 162 |
|
| 163 |
-
|
| 164 |
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
```
|
| 169 |
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
|
|
|
|
|
|
|
| 173 |
|
| 174 |
```bash
|
| 175 |
-
#
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
#
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
#
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
python -m tracy --no-runtime-analysis --collect-noc-traces \
|
| 191 |
-
--profiler-capture-perf-counters=all -v -r -o ./tracy_out \
|
| 192 |
-
-m pytest locate_anything/tests/bench_locate_anything.py
|
| 193 |
```
|
| 194 |
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 210 |
|
| 211 |
| Stage | PCC |
|
| 212 |
|---|---:|
|
| 213 |
-
| Vision `patch_embed`
|
| 214 |
-
| Vision `encoder_out` (27 blocks)
|
| 215 |
-
| Vision `vit_proj` (after `mlp1`)
|
| 216 |
-
| LLM prefill last-token logits
|
| 217 |
-
| **Full on-device logits (vision
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
golden is taken in fp32 so the bf16 port has a fair high-precision target (a 27-layer
|
| 221 |
-
bf16 tower drifts on its own). The `mlp1` LayerNorm/GELU lifts the projector PCC
|
| 222 |
-
above the encoder's. The LLM uses **BF16 attention + BFP8 MLP weights**; BFP8 MLP is
|
| 223 |
-
required for the ≥0.99 gate (BFP4 MLP only reaches ~0.935), and the decode `w1`/`w3`
|
| 224 |
-
outputs are spilled to DRAM so the BFP8 weight-stream circular buffers fit L1 on one
|
| 225 |
-
chip.
|
| 226 |
-
|
| 227 |
-
### Performance (warm, trace-replay decode, everything on device)
|
| 228 |
|
| 229 |
| Metric | Value |
|
| 230 |
|---|---:|
|
| 231 |
-
| Decode throughput
|
| 232 |
-
| Vision (MoonViT +
|
| 233 |
-
| Prefill
|
| 234 |
-
| End-to-end
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
|
| 238 |
-
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
|
| 242 |
-
|
| 243 |
-
|
| 244 |
-
|
| 245 |
-
|
| 246 |
-
|
| 247 |
-
|
| 248 |
-
|
| 249 |
-
|
| 250 |
-
|
| 251 |
-
|
| 252 |
-
|
| 253 |
-
|
| 254 |
-
|
| 255 |
-
|
| 256 |
-
|
| 257 |
-
|
| 258 |
-
|
| 259 |
-
|
| 260 |
-
|
| 261 |
-
|
| 262 |
-
|
| 263 |
-
|
| 264 |
-
|
| 265 |
-
|
| 266 |
-
|
| 267 |
-
|
| 268 |
-
|
| 269 |
-
|
| 270 |
-
|
| 271 |
-
|
| 272 |
-
|
| 273 |
-
|
| 274 |
-
|
| 275 |
-
|
| 276 |
-
|
| 277 |
-
|
| 278 |
-
|
| 279 |
-
|
| 280 |
-
|
| 281 |
-
(a pure reshape) → `mlp1` projector `LayerNorm(4608) → Linear → GELU → Linear` to
|
| 282 |
-
2048-d. PCC validated at 0.99999 (patch embed) / 0.9911 (projector).
|
| 283 |
-
- **Qwen2.5-3B LLM** (`tt/model_la.py`): the stock `tt_transformers` `Transformer`,
|
| 284 |
-
with one added method that feeds **pre-merged image+text embeddings** into prefill
|
| 285 |
-
instead of token ids (standard 1D RoPE, `rope_theta=1e6`; *no* mrope). hidden 2048,
|
| 286 |
-
36 layers, 16 heads / 2 KV heads (GQA), head_dim 128, intermediate 11008, tied
|
| 287 |
-
embeddings, extended vocab 152681. Image embeds are scattered into the text
|
| 288 |
-
embeds at `image_token_index` (151665) on host, then prefill runs on device with
|
| 289 |
-
a paged KV cache; greedy decode runs through the stock `Generator` with trace.
|
| 290 |
-
- **Parallel Box Decoding / MTP** (`tt/mtp.py`, experimental): predicts a whole
|
| 291 |
-
6-token box per forward using the block-bidirectional "generation window"
|
| 292 |
-
attention from NVIDIA's reference, with lazy KV commit. Closely reproduces the
|
| 293 |
-
torch-CPU MTP loop in `reference/mtp_cpu_loop.py`.
|
| 294 |
-
|
| 295 |
-
**Host vs device.** The forward keeps the heavy compute on chip; host work is the
|
| 296 |
-
image layout reshape and 2×2 patch merge, the text-token embedding lookup and the
|
| 297 |
-
vision↔text embedding merge, and argmax sampling (the 152681-wide vocab exceeds the
|
| 298 |
-
on-device-sampling 64K/split limit, but host argmax is negligible since decode is
|
| 299 |
-
device-bound).
|
| 300 |
-
|
| 301 |
-
---
|
| 302 |
-
|
| 303 |
-
## Known caveats
|
| 304 |
-
|
| 305 |
-
- **Overlay on tt-metal, not standalone.** The LLM path imports `tt_transformers`
|
| 306 |
-
and `qwen25_vl` directly; `conftest.py` reuses tt-metal's device fixtures. You
|
| 307 |
-
need a built tt-metal checkout on `PYTHONPATH` (`TT_METAL_HOME` set). This is by
|
| 308 |
-
design — the port deliberately reuses the tuned stock Qwen2.5 implementation
|
| 309 |
-
rather than re-deriving it.
|
| 310 |
-
- **One image per forward, single chip.** Batch is 1 and the model runs on exactly
|
| 311 |
-
one p150a; nothing is sharded across chips. Set `TT_VISIBLE_DEVICES` to isolate
|
| 312 |
-
the chip you want.
|
| 313 |
-
- **MTP is approximate and not accuracy-gated.** It is a faithful device port of the
|
| 314 |
-
torch-CPU MTP (logit PCC ~0.986) and runs the model's intended fast path, but
|
| 315 |
-
greedy MTP ≠ greedy AR by construction; for deterministic, gate-passing detection
|
| 316 |
-
use the default AR path. The MTP demo accepts `LA_TEMP` / `LA_TOP_P` /
|
| 317 |
-
`LA_REP_PEN` for the model's intended sampling.
|
| 318 |
-
- **Goldens are generated, not shipped.** `golden.pt` / `mtp_oracle.pt` depend on
|
| 319 |
-
your torch/transformers build; regenerate them with the `reference/` scripts if
|
| 320 |
-
you change the image, query, or token-limit.
|
| 321 |
-
- **BFP8 MLP is mandatory** for the ≥0.99 gate; the decode `w1`/`w3` DRAM spill is
|
| 322 |
-
what makes it fit L1 on a single chip (the alternative BFP4 MLP drops PCC to
|
| 323 |
-
~0.935).
|
| 324 |
-
|
| 325 |
-
---
|
| 326 |
-
|
| 327 |
-
## License
|
| 328 |
-
|
| 329 |
-
Apache 2.0 (matches upstream LocateAnything, Qwen2.5, MoonViT/Kimi-VL, and tt-metal).
|
| 330 |
-
|
| 331 |
-
---
|
| 332 |
-
|
| 333 |
-
## Acknowledgements
|
| 334 |
-
|
| 335 |
-
- Original model: NVIDIA **LocateAnything-3B** — https://huggingface.co/nvidia/LocateAnything-3B
|
| 336 |
-
- Language backbone: **Qwen2.5-3B-Instruct** — https://huggingface.co/Qwen/Qwen2.5-3B-Instruct
|
| 337 |
-
- Vision tower: **MoonViT** (Kimi-VL / Moonshot AI), SigLIP-SO400M shape
|
| 338 |
-
- Runtime: Tenstorrent **tt-metal / tt-nn** — https://github.com/tenstorrent/tt-metal
|
| 339 |
-
|
| 340 |
-
---
|
| 341 |
-
|
| 342 |
-
## Licensing
|
| 343 |
-
|
| 344 |
-
The **upstream model** is licensed **`other`** (nvidia-license) - see [the licence](https://huggingface.co/nvidia/LocateAnything-3B/blob/main/LICENSE).
|
| 345 |
-
|
| 346 |
-
Governed by NVIDIA's own licence, not an OSI licence - read it before any use.
|
| 347 |
|
| 348 |
-
The **port code** here was written by [Hyunggi Chang](https://github.com/changh95) and is published under the same terms, since a port cannot grant more than its upstream does. The **weights are not redistributed** in this repository - they are fetched from the upstream repo, under whatever terms that repo sets.
|
|
|
|
| 1 |
---
|
|
|
|
| 2 |
tags:
|
|
|
|
| 3 |
- blackhole
|
| 4 |
- p150
|
| 5 |
+
- tt-dit-server
|
| 6 |
+
- tt-model-cache
|
| 7 |
+
- tt-model-container
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
---
|
| 9 |
|
| 10 |
+
# locate-anything-3b-blackhole
|
| 11 |
|
| 12 |
+
NVIDIA LocateAnything-3B (MoonViT-SO-400M vision tower + Qwen2.5-3B LLM with a detection vocabulary) doing visual grounding / open-vocabulary detection on a single Tenstorrent Blackhole p150a via tt-nn: image + free-text query -> labelled boxes. Vision tower and LLM both run on the chip; greedy AR decode with trace replay reaches ~38 tok/s, ~53 ms vision, ~64 ms prefill, ~2.3 frames/s end-to-end at PCC 0.9928 vs the torch reference. Weights are fetched from nvidia/LocateAnything-3B (NVIDIA license, 'other' - not OSI; read it before use); the port code (Apache-2.0 SPDX headers) is redistributed under the same upstream terms. Port source: github.com/changh95/tt-locate-anything @ 7a3b7407c4f1268cfb14ce1dd0ed4cdcd877b9a1.
|
| 13 |
|
| 14 |
+
Runs on **p150** (mesh `P150`).
|
| 15 |
|
| 16 |
+
Packaged and published with [tt-model-manager](https://github.com/tenstorrent/tt-model-manager) 0.1.0 (manifest schema 5.1).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
|
| 18 |
+
## Quickstart
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
|
| 20 |
+
```bash
|
| 21 |
+
tt-model pull changh95/locate-anything-3b-blackhole --with-weights
|
| 22 |
+
tt-model serve changh95/locate-anything-3b-blackhole
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
```
|
| 24 |
|
| 25 |
+
`pull --with-weights` downloads the Docker image and the [`nvidia/LocateAnything-3B`](https://huggingface.co/nvidia/LocateAnything-3B) weights at `c32291ca5e996f5a7a485845b4f57a233936bba0` (into your HF cache; they are not in the image). `serve` starts the model's own HTTP server on port 20000 (or the next free port, if that one is busy); the first start compiles kernels for your device, which takes several minutes, and the server is ready when it logs `Application startup complete`.
|
|
|
|
|
|
|
| 26 |
|
| 27 |
+
### tt-cli users
|
| 28 |
|
| 29 |
+
```bash
|
| 30 |
+
tt serve changh95/locate-anything-3b-blackhole # pulls image + weights, boots, prints the port
|
| 31 |
+
tt model stop changh95/locate-anything-3b-blackhole
|
| 32 |
+
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
|
| 34 |
+
`tt-model stop changh95/locate-anything-3b-blackhole` does the same without tt-cli.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
|
| 36 |
+
### What this server is (and is not)
|
| 37 |
|
| 38 |
+
The port is the one `serve` printed (20000, or the next free one). This is the model's
|
| 39 |
+
own HTTP API, **not** an OpenAI-compatible one: `curl <endpoint>/v1/models` only returns a
|
| 40 |
+
stub so the ready card does not 404, and `tt-model curl` does not apply. The routes are:
|
|
|
|
| 41 |
|
| 42 |
+
| route | what |
|
| 43 |
+
|---|---|
|
| 44 |
+
| `GET /health` | `{"status": "ok" \| "starting", "model", "device"}` - `ok` only after warm-up |
|
| 45 |
+
| `GET /info` | model, weights repo + revision loaded, source commit, input limits, license |
|
| 46 |
+
| `POST /predict` | one image + one query -> labelled boxes (JSON) |
|
| 47 |
|
| 48 |
```bash
|
| 49 |
+
PORT=20000 # the port serve printed
|
| 50 |
+
curl -s localhost:$PORT/health
|
| 51 |
+
curl -s localhost:$PORT/info | python -m json.tool
|
| 52 |
+
|
| 53 |
+
# media/demo_input.png (1920x1080) with the README's query "car"; several categories are
|
| 54 |
+
# joined with </c>, e.g. "person</c>car". The PNG is 3.6 MB (4.8 MB as base64), far above
|
| 55 |
+
# the shell's 128 KiB per-argument limit, so an inline "$(base64 -w0 ...)" fails with
|
| 56 |
+
# "Argument list too long": write the body to a file and post it with -d @file.
|
| 57 |
+
python3 - <<'EOF'
|
| 58 |
+
import base64, json
|
| 59 |
+
img = base64.b64encode(open("media/demo_input.png", "rb").read()).decode()
|
| 60 |
+
json.dump({"image": img, "query": "car", "max_new_tokens": 128}, open("/tmp/la_req.json", "w"))
|
| 61 |
+
EOF
|
| 62 |
+
curl -s localhost:$PORT/predict -H 'Content-Type: application/json' -d @/tmp/la_req.json \
|
| 63 |
+
| python3 -m json.tool
|
|
|
|
|
|
|
|
|
|
| 64 |
```
|
| 65 |
|
| 66 |
+
Request fields: `image` (base64 PNG/JPEG, exactly one image), `query` (required free text,
|
| 67 |
+
1-1000 chars; join categories with `</c>`), `max_new_tokens` (optional, default 128, cap 1024;
|
| 68 |
+
each box costs ~6-8 tokens plus its label), `return_overlay` (optional bool; adds
|
| 69 |
+
`overlay_png_b64`, the boxes drawn on your image).
|
| 70 |
+
|
| 71 |
+
Response: `detections: [{label, box: [x1, y1, x2, y2], box_norm: [..0..1000..]}]` with `box`
|
| 72 |
+
in ORIGINAL image pixels, `points` (the model's 2-coordinate outputs, same shape), `raw_text`
|
| 73 |
+
(the generated `<ref>car</ref><box><282><414><606><794></box><|im_end|>` string for the demo image),
|
| 74 |
+
`width`/`height`, `canonical_size` and `grid_hw` (what the model actually saw, see below),
|
| 75 |
+
`prompt_tokens`, `num_generated_tokens`, `stopped_on_eos`, `decode_mode`
|
| 76 |
+
(`ar_greedy_trace`), and `timing_ms` (`vision`, `prefill`, `decode`, `total`, `decode_tok_s`).
|
| 77 |
+
Errors: 400 for a bad image / empty query / prompt too long, 503 while starting, 500 with
|
| 78 |
+
the exception text otherwise. One request at a time is served (batch 1, stateful KV cache);
|
| 79 |
+
concurrent calls queue.
|
| 80 |
+
|
| 81 |
+
A one-line check that the hardware phase also runs:
|
| 82 |
+
`python code/locate_anything/server/smoke_test.py --url http://127.0.0.1:$PORT` prints
|
| 83 |
+
`PASS ...` with the box count and timings.
|
| 84 |
+
|
| 85 |
+
### Input handling
|
| 86 |
+
|
| 87 |
+
Every image is preprocessed like the HF processor at `LA_IN_TOKEN_LIMIT=1024` (all README
|
| 88 |
+
numbers use this cap; upstream's default is 25600) and then squash-resized onto ONE canonical
|
| 89 |
+
vision grid so MoonViT is built once: by default the grid the demo image (16:9) gets at that
|
| 90 |
+
cap, 24x44 patches = 336x616 px = 264 image tokens. Boxes are normalized over that view, so
|
| 91 |
+
they map back to your original pixels exactly; non-16:9 images are distorted before the
|
| 92 |
+
model sees them. The grid is fixed for the life of the server and comes from the
|
| 93 |
+
`LA_CANON_GRID=HxW` environment variable (even numbers of 14-px patches, e.g. `32x32` for
|
| 94 |
+
square inputs). `tt-model serve` passes the container only the manifest's `serve.env`
|
| 95 |
+
(there is no `--env` flag), so this package always serves the 24x44 grid; to serve another
|
| 96 |
+
one, run the app on a host with tt-metal (see `SERVING.md`) or repackage with the variable
|
| 97 |
+
added to `serve.env` in `tt-model.yaml`.
|
| 98 |
+
|
| 99 |
+
### First boot
|
| 100 |
+
|
| 101 |
+
- `tt-model serve` downloads ~7.6 GB of weights (2 safetensors shards + tokenizer/config)
|
| 102 |
+
into your HF cache before the container starts.
|
| 103 |
+
- Inside the container the app writes a vanilla Qwen2.5-3B checkpoint (6.8 GB) to
|
| 104 |
+
`~/.cache/tt-model/locate-anything-3b-blackhole/weights/la-qwen2_5-3b` (once), converts the
|
| 105 |
+
LLM weights to BFP8 into `.../tensors/P150/tensor_cache_bfp8` (once), JIT-compiles kernels
|
| 106 |
+
into `.../cache` (once), uploads MoonViT and runs two warm-up passes (prefill + 4 decode
|
| 107 |
+
steps; the decode trace is captured on the first). Measured on the validation host: a
|
| 108 |
+
cold first boot is a few minutes (extraction ~5 s, BFP8 conversion ~25 s, JIT + warm-up
|
| 109 |
+
~1-2 min), later boots ~15 s; `tt-model logs -f changh95/locate-anything-3b-blackhole`
|
| 110 |
+
shows `Loading weights`, `Warming up`, `Warmup complete`. Host RAM peak ~10 GB.
|
| 111 |
+
- Disk: 7.2 GB (HF cache) + 6.8 GB (extracted LLM) + 4 GB (BFP8 tensor cache) + ~0.4 GB JIT cache.
|
| 112 |
+
- The weights repo is public and ungated; no `hf auth login` is needed for it.
|
| 113 |
+
|
| 114 |
+
### Results (from the port README; single p150a, everything on device, warm, trace decode)
|
| 115 |
+
|
| 116 |
+
| Input (`media/demo_input.png`) | Greedy AR decode (`media/demo_ar.png`) |
|
| 117 |
+
|:---:|:---:|
|
| 118 |
+
|  |  |
|
| 119 |
+
|
| 120 |
+
Accuracy (PCC vs the torch-CPU golden, gate >= 0.99):
|
| 121 |
|
| 122 |
| Stage | PCC |
|
| 123 |
|---|---:|
|
| 124 |
+
| Vision `patch_embed` | 0.99999 |
|
| 125 |
+
| Vision `encoder_out` (27 blocks) | 0.9809 |
|
| 126 |
+
| Vision `vit_proj` (after `mlp1`) | 0.9911 |
|
| 127 |
+
| LLM prefill last-token logits | 0.9922 |
|
| 128 |
+
| **Full on-device logits (vision -> LLM)** | **0.9928** |
|
| 129 |
+
|
| 130 |
+
Performance:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 131 |
|
| 132 |
| Metric | Value |
|
| 133 |
|---|---:|
|
| 134 |
+
| Decode throughput | ~38 tok/s |
|
| 135 |
+
| Vision (MoonViT + projector) | ~53 ms |
|
| 136 |
+
| Prefill | ~64 ms |
|
| 137 |
+
| End-to-end | ~2.32 frames/s |
|
| 138 |
+
|
| 139 |
+
The LLM runs BF16 attention + BFP8 MLP weights (the `accuracy` preset; BFP8 MLP is what the
|
| 140 |
+
>= 0.99 gate needs, BFP4 reaches ~0.935). Decode is weight-bandwidth bound (~3 GB/token), so
|
| 141 |
+
trace replay is the big win (7.5 -> 38 tok/s) and a second command queue is not. The
|
| 142 |
+
experimental on-device Parallel Box Decoding (MTP, `media/demo_mtp.png`) is approximate,
|
| 143 |
+
not accuracy-gated, and not served. The validated run needed one change to tt-metal's
|
| 144 |
+
`models/tt_transformers/tt/mlp.py`, and this package ships it as an overlay
|
| 145 |
+
(`code/models/tt_transformers/tt/mlp.py`, otherwise byte-identical to the stock file): in
|
| 146 |
+
single-chip decode the `w1`/`w3` outputs are moved to DRAM before the next matmul, because
|
| 147 |
+
with stock bf16 L1-sharded intermediates the `w3` weight-stream circular buffers do not fit
|
| 148 |
+
L1 on one p150a (`Statically allocated circular buffers ... clash with L1 buffers` at the
|
| 149 |
+
first decode step). Measured with the overlay on the validation host: `media/demo_input.png`
|
| 150 |
+
+ `car` -> the same box as `media/demo_ar.png`, vision 49 ms, prefill 58 ms, decode 41 tok/s,
|
| 151 |
+
346 ms end-to-end. `LA_PREC=bfp8attn` (all-BFP8 attention, PCC 0.9912) remains available.
|
| 152 |
+
|
| 153 |
+
### Layout notes
|
| 154 |
+
|
| 155 |
+
`code/locate_anything/` is the port (`tt/vision.py` MoonViT, `tt/model_la.py` the embeds-fed
|
| 156 |
+
Qwen2.5-3B `Transformer` subclass, `tt/pipeline.py` the serving recipe, `tt/mtp.py` the
|
| 157 |
+
experimental MTP decoder, `reference/` the torch-CPU reference and the LLM-checkpoint
|
| 158 |
+
extractor, `tests/` the PCC/benchmark/demo pytest suites, `server/` this app + smoke test).
|
| 159 |
+
`code/models/{common,tt_transformers,demos/qwen25_vl}` are the tt-metal packages the LLM
|
| 160 |
+
path reuses (stock Qwen2.5 `Transformer`/`Generator`/paged `Attention`), with the one
|
| 161 |
+
overlay file `models/tt_transformers/tt/mlp.py` described above. The tests need a device
|
| 162 |
+
and the torch-CPU goldens (`reference/run_reference.py`), which are not shipped.
|
| 163 |
+
|
| 164 |
+
### Licensing
|
| 165 |
+
|
| 166 |
+
The **upstream model and weights** are licensed **`other`** (nvidia-license):
|
| 167 |
+
https://huggingface.co/nvidia/LocateAnything-3B/blob/main/LICENSE - NVIDIA's own licence,
|
| 168 |
+
not an OSI licence; read it before any use. The weights are **not redistributed** here; they
|
| 169 |
+
are fetched from the upstream repo under whatever terms that repo sets. The **port code**
|
| 170 |
+
(Apache-2.0 SPDX headers; written by Hyunggi Chang, github.com/changh95/tt-locate-anything)
|
| 171 |
+
is published under the same upstream terms, since a port cannot grant more than its upstream
|
| 172 |
+
does. Backbone: Qwen2.5-3B-Instruct (Apache-2.0); vision tower: MoonViT (Kimi-VL, Moonshot AI);
|
| 173 |
+
runtime: Tenstorrent tt-metal / tt-nn (Apache-2.0).
|
| 174 |
+
|
| 175 |
+
## Provenance
|
| 176 |
+
|
| 177 |
+
The exact sources the image was built from — `code/` in this repo is byte-identical to the model code inside the image:
|
| 178 |
+
|
| 179 |
+
| component | built from |
|
| 180 |
+
| --- | --- |
|
| 181 |
+
| tt-metal | [`8b98410e730bb504fea43a88609756e34821d91d`](https://github.com/tenstorrent/tt-metal/commit/8b98410e730bb504fea43a88609756e34821d91d) |
|
| 182 |
+
| `code/` digest | `eb3aa8433050cc46` (sha256, first 16 hex digits) |
|
| 183 |
+
| built | 2026-09-12T06:57:00+00:00 by tt-model 0.1.0 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 184 |
|
|
|
code/models/common/auto_compose.py
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# SPDX-FileCopyrightText: © 2025 Tenstorrent USA, Inc.
|
| 2 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 3 |
+
|
| 4 |
+
"""
|
| 5 |
+
Automatic composition of multi-device sharded tensors using TensorTopology.
|
| 6 |
+
|
| 7 |
+
This module provides utilities to infer the correct MeshToTensor composer from a
|
| 8 |
+
sharded ttnn.Tensor's topology metadata and use it to compose shards on host.
|
| 9 |
+
"""
|
| 10 |
+
|
| 11 |
+
from typing import Optional
|
| 12 |
+
|
| 13 |
+
import torch
|
| 14 |
+
from loguru import logger
|
| 15 |
+
|
| 16 |
+
import ttnn
|
| 17 |
+
|
| 18 |
+
# ======================================================================================
|
| 19 |
+
# Public API
|
| 20 |
+
# ======================================================================================
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
def to_torch_auto_compose(tensor: ttnn.Tensor, device: Optional[ttnn.MeshDevice] = None) -> torch.Tensor:
|
| 24 |
+
"""
|
| 25 |
+
Convert a (possibly multi-device) TTNN tensor to torch, automatically
|
| 26 |
+
composing shards based on the tensor's topology.
|
| 27 |
+
|
| 28 |
+
Args:
|
| 29 |
+
tensor: The distributed tensor to convert
|
| 30 |
+
device: Optional MeshDevice to use when the tensor lives on host
|
| 31 |
+
|
| 32 |
+
Returns:
|
| 33 |
+
PyTorch tensor with shards composed
|
| 34 |
+
"""
|
| 35 |
+
composer = _infer_mesh_composer_from_topology(tensor, device=device)
|
| 36 |
+
try:
|
| 37 |
+
return ttnn.to_torch(tensor, mesh_composer=composer)
|
| 38 |
+
except Exception as e:
|
| 39 |
+
logger.error(f"Failed to convert tensor to torch with mesh_composer: {e}")
|
| 40 |
+
raise
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
def extract_tensor_topology_info(
|
| 44 |
+
tensor: ttnn.Tensor,
|
| 45 |
+
) -> tuple[list[object], list[int]]:
|
| 46 |
+
"""
|
| 47 |
+
Extract placements and distribution shape from a tensor's topology.
|
| 48 |
+
|
| 49 |
+
Returns:
|
| 50 |
+
(placements, dist_shape)
|
| 51 |
+
"""
|
| 52 |
+
topology = tensor.tensor_topology()
|
| 53 |
+
placements = topology.placements()
|
| 54 |
+
dist_shape = list(topology.distribution_shape())
|
| 55 |
+
return placements, dist_shape
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
def get_device_from_tensor(tensor: ttnn.Tensor) -> Optional[ttnn.MeshDevice]:
|
| 59 |
+
"""Get device from tensor or fallback to provided mesh_device."""
|
| 60 |
+
device = tensor.device()
|
| 61 |
+
# tensor.device() returns None if the tensor is on the host (ttnn/core/tensor/tensor.cpp --> Tensor::device())
|
| 62 |
+
if device is None:
|
| 63 |
+
logger.debug("tensor.device() returns None, tensor is on the host")
|
| 64 |
+
else:
|
| 65 |
+
logger.debug(f"tensor.device() returns {device}")
|
| 66 |
+
|
| 67 |
+
return device
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
# ======================================================================================
|
| 71 |
+
# Private Implementation
|
| 72 |
+
# ======================================================================================
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
def _infer_mesh_composer_from_topology(
|
| 76 |
+
tensor: ttnn.Tensor, *, device: Optional[ttnn.MeshDevice] = None
|
| 77 |
+
) -> Optional[ttnn.CppMeshToTensor]:
|
| 78 |
+
"""
|
| 79 |
+
Return a MeshToTensor composer inferred from the tensor's TensorTopology,
|
| 80 |
+
or None if no composition is needed (fully replicated, single-device).
|
| 81 |
+
|
| 82 |
+
Note: For ND meshes with replicated dimensions, the composer will concatenate
|
| 83 |
+
all replicas, resulting in duplicated data. Callers may want to slice the
|
| 84 |
+
result if only one copy is desired.
|
| 85 |
+
|
| 86 |
+
Args:
|
| 87 |
+
tensor: The distributed tensor to infer composer for
|
| 88 |
+
|
| 89 |
+
Returns:
|
| 90 |
+
MeshToTensor composer or None if no composition needed
|
| 91 |
+
"""
|
| 92 |
+
placements, dist_shape = extract_tensor_topology_info(tensor)
|
| 93 |
+
|
| 94 |
+
# No distribution or trivial 1-device case
|
| 95 |
+
if len(dist_shape) == 0 or (len(dist_shape) == 1 and dist_shape[0] == 1):
|
| 96 |
+
return None
|
| 97 |
+
|
| 98 |
+
tensor_device = get_device_from_tensor(tensor)
|
| 99 |
+
mesh_device = tensor_device or device
|
| 100 |
+
if mesh_device is None:
|
| 101 |
+
# As a last resort, try default device for backward-compatibility
|
| 102 |
+
mesh_device = ttnn.GetDefaultDevice()
|
| 103 |
+
if mesh_device is None:
|
| 104 |
+
raise RuntimeError(
|
| 105 |
+
"Tensor is on host and no mesh_device provided. "
|
| 106 |
+
"Pass device=... to to_torch_auto_compose or set a default via ttnn.SetDefaultDevice(...)."
|
| 107 |
+
)
|
| 108 |
+
|
| 109 |
+
# Must match length (should be guaranteed by C++ TT_FATAL in ttnn/core/distributed/distributed_tensor.cpp)
|
| 110 |
+
assert len(dist_shape) == len(placements)
|
| 111 |
+
|
| 112 |
+
if len(dist_shape) == 1 and mesh_device.shape.dims() == 1:
|
| 113 |
+
return _compose_1d_sharded(mesh_device, placements, dist_shape)
|
| 114 |
+
else:
|
| 115 |
+
# N >= 2 dimensions
|
| 116 |
+
return _compose_nd_sharded(mesh_device, placements, dist_shape)
|
| 117 |
+
|
| 118 |
+
|
| 119 |
+
def _compose_1d_sharded(
|
| 120 |
+
device: ttnn.MeshDevice,
|
| 121 |
+
placements: list[object],
|
| 122 |
+
dist_shape: list[int],
|
| 123 |
+
) -> Optional[ttnn.CppMeshToTensor]:
|
| 124 |
+
"""Handle 1D case - returns None if fully replicated."""
|
| 125 |
+
p = placements[0]
|
| 126 |
+
if isinstance(p, ttnn.PlacementShard):
|
| 127 |
+
# Use ND composer with shape override to match the tensor's distribution
|
| 128 |
+
composer_cfg = ttnn.MeshComposerConfig(dims=[p.dim], mesh_shape_override=ttnn.MeshShape(dist_shape))
|
| 129 |
+
return ttnn.create_mesh_composer(device, composer_cfg)
|
| 130 |
+
# Fully replicated - no composition needed
|
| 131 |
+
return None
|
| 132 |
+
|
| 133 |
+
|
| 134 |
+
def _compose_nd_sharded(
|
| 135 |
+
device: ttnn.MeshDevice,
|
| 136 |
+
placements: list[object],
|
| 137 |
+
dist_shape: list[int],
|
| 138 |
+
) -> ttnn.CppMeshToTensor:
|
| 139 |
+
"""
|
| 140 |
+
Handle ND (N>=2) case.
|
| 141 |
+
|
| 142 |
+
For replicated mesh dims, we use dim 0 as convention (the composed result
|
| 143 |
+
will include all replicas concatenated, which is typically not desired but
|
| 144 |
+
is how the C++ API works).
|
| 145 |
+
"""
|
| 146 |
+
dims = []
|
| 147 |
+
shape_override = []
|
| 148 |
+
for i, p in enumerate(placements):
|
| 149 |
+
if isinstance(p, ttnn.PlacementShard):
|
| 150 |
+
dims.append(p.dim)
|
| 151 |
+
shape_override.append(dist_shape[i])
|
| 152 |
+
else:
|
| 153 |
+
assert isinstance(p, ttnn.PlacementReplicate)
|
| 154 |
+
# [INFO] steal from TensorDistribution2x4Test test case in test_distributed_tensor.cpp
|
| 155 |
+
# Replicated: use dim 0 as convention
|
| 156 |
+
dims.append(0)
|
| 157 |
+
# Replicated: use shape 1 to skip concatenation
|
| 158 |
+
shape_override.append(1)
|
| 159 |
+
|
| 160 |
+
composer_cfg = ttnn.MeshComposerConfig(dims=dims, mesh_shape_override=ttnn.MeshShape(shape_override))
|
| 161 |
+
return ttnn.create_mesh_composer(device, composer_cfg)
|
code/models/common/rmsnorm.py
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# SPDX-FileCopyrightText: © 2023 Tenstorrent USA, Inc.
|
| 2 |
+
|
| 3 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 4 |
+
import ttnn
|
| 5 |
+
from models.common.lightweightmodule import LightweightModule
|
| 6 |
+
from models.tt_transformers.tt.common import Mode
|
| 7 |
+
|
| 8 |
+
TILE = 32
|
| 9 |
+
SHARD_HEIGHT = TILE # Current ttnn.rms_norm implementation requires shard height to be a single tile
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
class RMSNorm(LightweightModule):
|
| 13 |
+
"""
|
| 14 |
+
RMSNorm supporting replication over a MeshDevice and sharding within devices.
|
| 15 |
+
|
| 16 |
+
This class implements a Root Mean Square Normalization (RMSNorm) that can be
|
| 17 |
+
distributed across multiple devices and cores. If the `device` parameter is a
|
| 18 |
+
MeshDevice, the weights and computations are replicated across all devices in
|
| 19 |
+
the mesh. Expects an interleaved input tensor, can optionally output a sharded tensor.
|
| 20 |
+
|
| 21 |
+
Args:
|
| 22 |
+
device: The device or MeshDevice on which to perform the computations.
|
| 23 |
+
state_dict: The state dictionary containing the model parameters.
|
| 24 |
+
dim: Input dimension (e.g. model hidden dimension size).
|
| 25 |
+
layer_num: The layer number to determine the weight key in the state dictionary.
|
| 26 |
+
weight_key: The key for retrieving the weight from the state dictionary.
|
| 27 |
+
weight_cache_path: Optional path for caching the tilized weights.
|
| 28 |
+
weight_memory_config: Configuration for the weight memory, default is DRAM_MEMORY_CONFIG.
|
| 29 |
+
weight_dtype: The data type for the tensors, bfp8_b hits >0.999 PCC in the models we tested.
|
| 30 |
+
model_config: Optional configuration dictionary for the model.
|
| 31 |
+
eps (float): Small value to avoid division by zero in normalization, default is 1e-05.
|
| 32 |
+
|
| 33 |
+
If model_config is provided, it must specify SHARDED_NORM_INPUT_MEMCFG, SHARDED_NORM_PRGM_CFG
|
| 34 |
+
and SHARDED_NORM_OUTPUT_MEMCFG. If not provided, default configurations will be generated.
|
| 35 |
+
"""
|
| 36 |
+
|
| 37 |
+
def __init__(
|
| 38 |
+
self,
|
| 39 |
+
device,
|
| 40 |
+
dim,
|
| 41 |
+
state_dict,
|
| 42 |
+
weight_key,
|
| 43 |
+
layer_num=None,
|
| 44 |
+
state_dict_prefix=None,
|
| 45 |
+
weight_cache_path=None,
|
| 46 |
+
weight_memory_config=ttnn.DRAM_MEMORY_CONFIG,
|
| 47 |
+
weight_dtype=ttnn.bfloat16,
|
| 48 |
+
is_distributed=None,
|
| 49 |
+
eps: float = 1e-05,
|
| 50 |
+
add_unit_offset=False,
|
| 51 |
+
sharded_program_config=None,
|
| 52 |
+
sharded_output_config=None,
|
| 53 |
+
output_mem_config=None,
|
| 54 |
+
ccl_topology=ttnn.Topology.Ring,
|
| 55 |
+
tt_ccl=None,
|
| 56 |
+
fp32_dest_acc_en=True,
|
| 57 |
+
):
|
| 58 |
+
super().__init__()
|
| 59 |
+
self.device = device
|
| 60 |
+
self.eps = eps
|
| 61 |
+
self.is_distributed = is_distributed
|
| 62 |
+
self.ccl_topology = ccl_topology
|
| 63 |
+
self.tt_ccl = tt_ccl
|
| 64 |
+
|
| 65 |
+
if state_dict_prefix:
|
| 66 |
+
weight_name = f"{state_dict_prefix}{weight_key}.weight"
|
| 67 |
+
else:
|
| 68 |
+
if layer_num is None:
|
| 69 |
+
weight_name = f"{weight_key}.weight"
|
| 70 |
+
else:
|
| 71 |
+
weight_name = f"layers.{layer_num}.{weight_key}.weight"
|
| 72 |
+
|
| 73 |
+
torch_weight = (
|
| 74 |
+
state_dict[weight_name].unsqueeze(0).view(1, 1, dim).reshape([1, 1, dim // SHARD_HEIGHT, SHARD_HEIGHT])
|
| 75 |
+
)
|
| 76 |
+
|
| 77 |
+
# Add offset before caching
|
| 78 |
+
if add_unit_offset:
|
| 79 |
+
torch_weight = torch_weight + 1.0
|
| 80 |
+
|
| 81 |
+
# Compatibility with models that don't use mesh devices (e.g. single-chip Mistral-7b)
|
| 82 |
+
is_mesh_device = device.__class__.__name__ == "MeshDevice"
|
| 83 |
+
|
| 84 |
+
self.weight = ttnn.as_tensor(
|
| 85 |
+
torch_weight,
|
| 86 |
+
device=device,
|
| 87 |
+
dtype=weight_dtype,
|
| 88 |
+
layout=ttnn.ROW_MAJOR_LAYOUT,
|
| 89 |
+
memory_config=weight_memory_config,
|
| 90 |
+
cache_file_name=None if weight_cache_path is None else weight_cache_path / weight_name,
|
| 91 |
+
mesh_mapper=ttnn.ReplicateTensorToMesh(device) if is_mesh_device else None,
|
| 92 |
+
)
|
| 93 |
+
|
| 94 |
+
if self.is_distributed:
|
| 95 |
+
self.weight_distributed = ttnn.as_tensor(
|
| 96 |
+
torch_weight,
|
| 97 |
+
device=device,
|
| 98 |
+
dtype=weight_dtype,
|
| 99 |
+
layout=ttnn.ROW_MAJOR_LAYOUT,
|
| 100 |
+
memory_config=weight_memory_config,
|
| 101 |
+
cache_file_name=(
|
| 102 |
+
None if weight_cache_path is None else weight_cache_path / (weight_name + "_distributed")
|
| 103 |
+
),
|
| 104 |
+
mesh_mapper=(
|
| 105 |
+
ttnn.ShardTensor2dMesh(device, dims=(None, 2), mesh_shape=list(device.shape))
|
| 106 |
+
if is_mesh_device
|
| 107 |
+
else None
|
| 108 |
+
),
|
| 109 |
+
)
|
| 110 |
+
|
| 111 |
+
self.sharded_output_config = sharded_output_config
|
| 112 |
+
self.sharded_program_config = sharded_program_config
|
| 113 |
+
self.output_mem_config = output_mem_config
|
| 114 |
+
|
| 115 |
+
self.compute_kernel_config_hifi2 = ttnn.WormholeComputeKernelConfig(
|
| 116 |
+
math_fidelity=ttnn.MathFidelity.HiFi2,
|
| 117 |
+
math_approx_mode=False,
|
| 118 |
+
fp32_dest_acc_en=fp32_dest_acc_en,
|
| 119 |
+
packer_l1_acc=True,
|
| 120 |
+
)
|
| 121 |
+
|
| 122 |
+
def forward(
|
| 123 |
+
self,
|
| 124 |
+
x: ttnn.Tensor,
|
| 125 |
+
mode: Mode | str,
|
| 126 |
+
in_sharded=False,
|
| 127 |
+
out_sharded=False,
|
| 128 |
+
norm_config=None,
|
| 129 |
+
) -> ttnn.Tensor:
|
| 130 |
+
if isinstance(mode, str):
|
| 131 |
+
try:
|
| 132 |
+
mode = Mode(mode)
|
| 133 |
+
except ValueError:
|
| 134 |
+
raise ValueError(f"Invalid mode: {mode}")
|
| 135 |
+
elif not isinstance(mode, Mode):
|
| 136 |
+
raise ValueError(f"Invalid mode: {mode}")
|
| 137 |
+
|
| 138 |
+
sharded_program_config = norm_config.get("sharded_program_config") if norm_config else None
|
| 139 |
+
sharded_output_config = norm_config.get("sharded_output_config") if norm_config else None
|
| 140 |
+
output_mem_config = norm_config.get("output_mem_config") if norm_config else None
|
| 141 |
+
# Optional L1 placement for the distributed 3-op outputs (pre/gather/post); None -> DRAM default.
|
| 142 |
+
distributed_out_mc = norm_config.get("distributed_output_mem_config") if norm_config else None
|
| 143 |
+
|
| 144 |
+
# If input is sharded do sharded RMSNorm and optionally return sharded output
|
| 145 |
+
program_config = sharded_program_config if in_sharded else None
|
| 146 |
+
memory_config = sharded_output_config if out_sharded else None
|
| 147 |
+
distributed = self.is_distributed and self.is_distributed(mode)
|
| 148 |
+
weight = self.weight_distributed if distributed else self.weight
|
| 149 |
+
|
| 150 |
+
if in_sharded:
|
| 151 |
+
assert not distributed, "Distributed RMSNorm does not support sharded inputs"
|
| 152 |
+
else:
|
| 153 |
+
assert not out_sharded, "Non-sharded version of RMSNorm cannot output a sharded tensor"
|
| 154 |
+
|
| 155 |
+
if distributed:
|
| 156 |
+
x = self._distributed_rmsnorm(
|
| 157 |
+
x,
|
| 158 |
+
epsilon=self.eps,
|
| 159 |
+
weight=weight,
|
| 160 |
+
compute_kernel_config=self.compute_kernel_config_hifi2,
|
| 161 |
+
output_memory_config=distributed_out_mc,
|
| 162 |
+
)
|
| 163 |
+
else:
|
| 164 |
+
x = ttnn.rms_norm(
|
| 165 |
+
x,
|
| 166 |
+
epsilon=self.eps,
|
| 167 |
+
weight=weight,
|
| 168 |
+
program_config=program_config,
|
| 169 |
+
memory_config=memory_config,
|
| 170 |
+
compute_kernel_config=self.compute_kernel_config_hifi2,
|
| 171 |
+
)
|
| 172 |
+
|
| 173 |
+
if in_sharded and not out_sharded:
|
| 174 |
+
return ttnn.sharded_to_interleaved(x)
|
| 175 |
+
else:
|
| 176 |
+
if output_mem_config is not None:
|
| 177 |
+
x = ttnn.to_memory_config(x, output_mem_config)
|
| 178 |
+
return x
|
| 179 |
+
|
| 180 |
+
def _distributed_rmsnorm(
|
| 181 |
+
self,
|
| 182 |
+
inp,
|
| 183 |
+
epsilon=None,
|
| 184 |
+
weight=None,
|
| 185 |
+
program_config=None,
|
| 186 |
+
memory_config=None,
|
| 187 |
+
compute_kernel_config=None,
|
| 188 |
+
output_memory_config=None,
|
| 189 |
+
):
|
| 190 |
+
assert program_config is None, "Distributed RMSNorm does not support sharded inputs"
|
| 191 |
+
assert memory_config is None, "Distributed RMSNorm does not support sharded outputs"
|
| 192 |
+
assert self.tt_ccl is not None, "Distributed RMSNorm requires tt_ccl"
|
| 193 |
+
|
| 194 |
+
# Interleaved output placement for the 3 ops; default DRAM (matches the prior hardcoded behavior).
|
| 195 |
+
mc = output_memory_config if output_memory_config is not None else ttnn.DRAM_MEMORY_CONFIG
|
| 196 |
+
|
| 197 |
+
# Run distributed rmsnorm part 1
|
| 198 |
+
tt_stats = ttnn.rms_norm_pre_all_gather(
|
| 199 |
+
inp, compute_kernel_config=compute_kernel_config, dtype=ttnn.bfloat16, memory_config=mc
|
| 200 |
+
)
|
| 201 |
+
# AllGather stats
|
| 202 |
+
tt_stats = ttnn.experimental.all_gather_async(
|
| 203 |
+
tt_stats,
|
| 204 |
+
persistent_output_buffer=None,
|
| 205 |
+
dim=3,
|
| 206 |
+
multi_device_global_semaphore=self.tt_ccl.get_and_cycle_ag_semaphore_handles(),
|
| 207 |
+
num_links=1,
|
| 208 |
+
topology=self.ccl_topology,
|
| 209 |
+
memory_config=mc,
|
| 210 |
+
barrier_semaphore=self.tt_ccl.get_and_cycle_barrier_semaphore_handle(),
|
| 211 |
+
chunks_per_sync=10,
|
| 212 |
+
num_workers_per_link=2,
|
| 213 |
+
num_buffers_per_channel=2,
|
| 214 |
+
)
|
| 215 |
+
# Run distributed rmsnorm part 2
|
| 216 |
+
tt_out = ttnn.rms_norm_post_all_gather(
|
| 217 |
+
inp,
|
| 218 |
+
tt_stats,
|
| 219 |
+
epsilon=epsilon,
|
| 220 |
+
weight=weight,
|
| 221 |
+
compute_kernel_config=compute_kernel_config,
|
| 222 |
+
memory_config=mc,
|
| 223 |
+
)
|
| 224 |
+
tt_stats.deallocate(True)
|
| 225 |
+
|
| 226 |
+
return tt_out
|
code/models/common/tensor_utils.py
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# SPDX-FileCopyrightText: © 2025 Tenstorrent USA, Inc.
|
| 2 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 3 |
+
|
| 4 |
+
"""
|
| 5 |
+
Tensor utility functions for TTTv2 modules.
|
| 6 |
+
"""
|
| 7 |
+
|
| 8 |
+
import json
|
| 9 |
+
import math
|
| 10 |
+
import re
|
| 11 |
+
|
| 12 |
+
import torch
|
| 13 |
+
|
| 14 |
+
import ttnn
|
| 15 |
+
|
| 16 |
+
# Standard tile size - hardware constant
|
| 17 |
+
TILE_SIZE = ttnn.TILE_SIZE # 32
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
def nearest_multiple(value: int, multiple: int) -> int:
|
| 21 |
+
return math.ceil(value / multiple) * multiple
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
def nearest_32(value: int) -> int:
|
| 25 |
+
return nearest_multiple(value, TILE_SIZE)
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
def num_to_core_range_set(num_cores: int):
|
| 29 |
+
assert num_cores < 8 or num_cores % 8 == 0
|
| 30 |
+
num_x = min(num_cores, 8)
|
| 31 |
+
num_y = num_cores // num_x
|
| 32 |
+
assert num_x * num_y == num_cores
|
| 33 |
+
return ttnn.CoreRangeSet(
|
| 34 |
+
{
|
| 35 |
+
ttnn.CoreRange(
|
| 36 |
+
ttnn.CoreCoord(0, 0),
|
| 37 |
+
ttnn.CoreCoord(num_x - 1, num_y - 1),
|
| 38 |
+
)
|
| 39 |
+
}
|
| 40 |
+
)
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
def get_out_subblock_w(per_core_n: int, out_subblock_h: int = 1) -> int:
|
| 44 |
+
out_subblock_w = 4
|
| 45 |
+
while out_subblock_w > 1:
|
| 46 |
+
if out_subblock_w * out_subblock_h <= 4 and per_core_n % out_subblock_w == 0:
|
| 47 |
+
break
|
| 48 |
+
out_subblock_w -= 1
|
| 49 |
+
return out_subblock_w
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
def align_shape_to_tile(shape, tile_size: int = TILE_SIZE):
|
| 53 |
+
"""Round up the last two dimensions of *shape* to multiples of *tile_size*.
|
| 54 |
+
|
| 55 |
+
This is the recommended replacement for the deprecated ``ttnn.pad_to_tile_shape``.
|
| 56 |
+
|
| 57 |
+
Args:
|
| 58 |
+
shape: An iterable of dimension sizes (list, tuple, or ttnn.Shape).
|
| 59 |
+
tile_size: Tile dimension to align to (default 32).
|
| 60 |
+
|
| 61 |
+
Returns:
|
| 62 |
+
List[int]: A new shape with the last two dims tile-aligned.
|
| 63 |
+
"""
|
| 64 |
+
import math
|
| 65 |
+
|
| 66 |
+
result = list(shape)
|
| 67 |
+
if len(result) >= 1:
|
| 68 |
+
result[-1] = math.ceil(result[-1] / tile_size) * tile_size
|
| 69 |
+
if len(result) >= 2:
|
| 70 |
+
result[-2] = math.ceil(result[-2] / tile_size) * tile_size
|
| 71 |
+
return result
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
def get_rot_transformation_mat(dhead: int = TILE_SIZE) -> torch.Tensor:
|
| 75 |
+
"""
|
| 76 |
+
Create rotation transformation matrix for RoPE.
|
| 77 |
+
|
| 78 |
+
Constructs a permutation matrix that pairs adjacent dimensions with
|
| 79 |
+
signs (+1, -1) for the RoPE rotation:
|
| 80 |
+
[0, 1] → +1 at (0,1), -1 at (1,0)
|
| 81 |
+
[2, 3] → +1 at (2,3), -1 at (3,2)
|
| 82 |
+
...
|
| 83 |
+
|
| 84 |
+
Used by ttnn.experimental.rotary_embedding_llama.
|
| 85 |
+
|
| 86 |
+
Args:
|
| 87 |
+
dhead: Matrix dimension. Must equal TILE_SIZE. Use TILE_SIZE for decode.
|
| 88 |
+
|
| 89 |
+
Returns:
|
| 90 |
+
torch.Tensor of shape [1, 1, dhead, dhead].
|
| 91 |
+
"""
|
| 92 |
+
rot_emb_matrix = torch.zeros(1, 1, dhead, dhead)
|
| 93 |
+
rot_emb_matrix[..., torch.arange(0, dhead, 2), torch.arange(1, dhead, 2)] = 1
|
| 94 |
+
rot_emb_matrix[..., torch.arange(1, dhead, 2), torch.arange(0, dhead, 2)] = -1
|
| 95 |
+
return rot_emb_matrix
|
| 96 |
+
|
| 97 |
+
|
| 98 |
+
def zeros_like_kv_cache(batch_size: int, n_kv_heads: int, max_seq_len: int, head_dim: int) -> torch.Tensor:
|
| 99 |
+
"""Create zeros tensor for standard KV cache."""
|
| 100 |
+
return torch.zeros((batch_size, n_kv_heads, max_seq_len, head_dim))
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
def zeros_like_paged_cache(paged_config, n_kv_heads: int, head_dim: int) -> torch.Tensor:
|
| 104 |
+
"""Create zeros tensor for paged KV cache."""
|
| 105 |
+
return torch.zeros((paged_config.max_num_blocks, n_kv_heads, paged_config.block_size, head_dim))
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
# todo)) add a on-device pad_dim_to_size function?
|
| 109 |
+
def pad_dim_to_size(x: "torch.Tensor", dim: int, size: int) -> "torch.Tensor":
|
| 110 |
+
"""Pads the specified dimension of the input tensor with zeros."""
|
| 111 |
+
if dim < 0:
|
| 112 |
+
dim = x.dim() + dim
|
| 113 |
+
current_size = x.size(dim)
|
| 114 |
+
pad_size = size - current_size
|
| 115 |
+
|
| 116 |
+
if pad_size < 0:
|
| 117 |
+
raise ValueError(f"Target size {size} is smaller than current size {current_size} on dim {dim}")
|
| 118 |
+
|
| 119 |
+
if pad_size == 0:
|
| 120 |
+
return x
|
| 121 |
+
|
| 122 |
+
pad = [0] * (2 * x.dim())
|
| 123 |
+
pad_index = 2 * (x.dim() - dim - 1)
|
| 124 |
+
pad[pad_index + 1] = pad_size
|
| 125 |
+
|
| 126 |
+
return torch.nn.functional.pad(x, pad, mode="constant", value=0)
|
| 127 |
+
|
| 128 |
+
|
| 129 |
+
def pad_to_shape(x: "torch.Tensor", target_shape: tuple[int, ...], pad_value: float = 0.0) -> "torch.Tensor":
|
| 130 |
+
"""Pad tensor to target_shape in a single F.pad call (more efficient than per-dim padding)."""
|
| 131 |
+
if x.shape == target_shape:
|
| 132 |
+
return x
|
| 133 |
+
|
| 134 |
+
# F.pad expects: (left_last, right_last, left_second_last, right_second_last, ...)
|
| 135 |
+
pad = []
|
| 136 |
+
for orig, target in zip(reversed(x.shape), reversed(target_shape)):
|
| 137 |
+
if target < orig:
|
| 138 |
+
raise ValueError(f"Target size {target} is smaller than current size {orig}")
|
| 139 |
+
pad.extend([0, target - orig])
|
| 140 |
+
|
| 141 |
+
return torch.nn.functional.pad(x, pad, mode="constant", value=pad_value)
|
| 142 |
+
|
| 143 |
+
|
| 144 |
+
def get_padded_hidden_dim(hidden_dim: int, num_devices: int, tile_size: int = 32) -> int:
|
| 145 |
+
"""
|
| 146 |
+
Compute padded hidden_dim to satisfy ttnn.from_torch's tile alignment constraint.
|
| 147 |
+
|
| 148 |
+
ttnn.from_torch requires physical shard shapes to be tile-aligned. When sharding
|
| 149 |
+
a tensor across devices, each shard_dim = hidden_dim / num_devices must be
|
| 150 |
+
divisible by tile_size.
|
| 151 |
+
|
| 152 |
+
We pad the global tensor first, then shard evenly so only the last shard has padding.
|
| 153 |
+
"""
|
| 154 |
+
shard_dim = hidden_dim // num_devices
|
| 155 |
+
padded_shard = ((shard_dim + tile_size - 1) // tile_size) * tile_size
|
| 156 |
+
return padded_shard * num_devices
|
| 157 |
+
|
| 158 |
+
|
| 159 |
+
def parse_shard_dims_from_mesh_mapper_config(mesh_mapper_config: ttnn.MeshMapperConfig) -> list[int]:
|
| 160 |
+
"""
|
| 161 |
+
Parse shard dimensions from MeshMapperConfig's repr.
|
| 162 |
+
|
| 163 |
+
MeshMapperConfig doesn't expose .placements directly, but repr shows them:
|
| 164 |
+
'MeshMapperConfig(placements: [PlacementShard(-1)], mesh_shape_override=MeshShape([8]))'
|
| 165 |
+
|
| 166 |
+
This parses out the shard dimensions (e.g., [-1]) from PlacementShard entries.
|
| 167 |
+
Returns empty list if no PlacementShard found (e.g., replicated).
|
| 168 |
+
|
| 169 |
+
Note: This is a workaround until TTNN exposes .placements directly.
|
| 170 |
+
"""
|
| 171 |
+
config_repr = repr(mesh_mapper_config)
|
| 172 |
+
matches = re.findall(r"PlacementShard\((-?\d+)\)", config_repr)
|
| 173 |
+
return [int(d) for d in matches]
|
| 174 |
+
|
| 175 |
+
|
| 176 |
+
def memory_config_to_dict(memory_config: ttnn.MemoryConfig):
|
| 177 |
+
# Convert to plain types for deterministic serialization.
|
| 178 |
+
return {
|
| 179 |
+
"memory_layout": str(memory_config.memory_layout),
|
| 180 |
+
"buffer_type": str(memory_config.buffer_type),
|
| 181 |
+
"shard_spec": str(memory_config.shard_spec),
|
| 182 |
+
"is_sharded": bool(memory_config.is_sharded()),
|
| 183 |
+
"interleaved": bool(memory_config.interleaved),
|
| 184 |
+
"hash": int(memory_config.__hash__()),
|
| 185 |
+
}
|
| 186 |
+
|
| 187 |
+
|
| 188 |
+
def compute_kernel_config_to_str(compute_kernel_config: ttnn.WormholeComputeKernelConfig):
|
| 189 |
+
# Backward compat shim; prefer compute_kernel_config_to_dict + serialize_config.
|
| 190 |
+
cfg = compute_kernel_config_to_dict(compute_kernel_config)
|
| 191 |
+
return serialize_config(cfg)
|
| 192 |
+
|
| 193 |
+
|
| 194 |
+
def compute_kernel_config_to_dict(compute_kernel_config: ttnn.WormholeComputeKernelConfig):
|
| 195 |
+
return {
|
| 196 |
+
"math_fidelity": str(compute_kernel_config.math_fidelity),
|
| 197 |
+
"math_approx_mode": str(compute_kernel_config.math_approx_mode),
|
| 198 |
+
"fp32_dest_acc_en": bool(compute_kernel_config.fp32_dest_acc_en),
|
| 199 |
+
"packer_l1_acc": bool(compute_kernel_config.packer_l1_acc),
|
| 200 |
+
"dst_full_sync_en": bool(compute_kernel_config.dst_full_sync_en),
|
| 201 |
+
"throttle_level": str(compute_kernel_config.throttle_level),
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
|
| 205 |
+
def program_config_to_str(program_config: ttnn.MatmulMultiCoreReuseMultiCastDRAMShardedProgramConfig):
|
| 206 |
+
# Backward compat shim; prefer program_config_to_dict + serialize_config.
|
| 207 |
+
cfg = program_config_to_dict(program_config)
|
| 208 |
+
return serialize_config(cfg)
|
| 209 |
+
|
| 210 |
+
|
| 211 |
+
def program_config_to_dict(program_config):
|
| 212 |
+
if hasattr(program_config, "to_json"):
|
| 213 |
+
d = json.loads(program_config.to_json())
|
| 214 |
+
d["type"] = type(program_config).__name__
|
| 215 |
+
return d
|
| 216 |
+
else:
|
| 217 |
+
return {"type": type(program_config).__name__, "repr": repr(program_config)}
|
| 218 |
+
|
| 219 |
+
|
| 220 |
+
def serialize_config(cfg_dict: dict, fmt: str = "json") -> str:
|
| 221 |
+
if fmt == "json":
|
| 222 |
+
return json.dumps(cfg_dict, sort_keys=True)
|
| 223 |
+
if fmt == "yaml":
|
| 224 |
+
try:
|
| 225 |
+
import yaml
|
| 226 |
+
except ImportError as exc: # pragma: no cover - optional dependency
|
| 227 |
+
raise RuntimeError("PyYAML is required for yaml serialization") from exc
|
| 228 |
+
return yaml.safe_dump(cfg_dict, sort_keys=True)
|
| 229 |
+
raise ValueError(f"Unsupported format: {fmt}")
|
code/models/common/validation_tools.py
ADDED
|
@@ -0,0 +1,719 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# SPDX-FileCopyrightText: © 2025 Tenstorrent USA, Inc.
|
| 2 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 3 |
+
|
| 4 |
+
"""
|
| 5 |
+
TTNN Validation Framework
|
| 6 |
+
|
| 7 |
+
A decorator-based validation system for comparing TTNN implementations against
|
| 8 |
+
reference implementations (in PyTorch). Supports automatic input/output
|
| 9 |
+
mapping, metric computation, and result collection.
|
| 10 |
+
|
| 11 |
+
Key Features:
|
| 12 |
+
- Automatic comparison of TTNN vs reference implementations
|
| 13 |
+
- TTNN-native metric computation (stays on device until final scalar)
|
| 14 |
+
- Flexible input/output mapping
|
| 15 |
+
- Built-in metrics: max_abs_error, mean_abs_error, cosine_similarity
|
| 16 |
+
- Performance tracking
|
| 17 |
+
- Result registry for batch reporting
|
| 18 |
+
"""
|
| 19 |
+
|
| 20 |
+
import time
|
| 21 |
+
from dataclasses import dataclass, field
|
| 22 |
+
from enum import Enum
|
| 23 |
+
from functools import wraps
|
| 24 |
+
from typing import Any, Callable, Dict, List, Optional
|
| 25 |
+
|
| 26 |
+
import torch
|
| 27 |
+
|
| 28 |
+
import ttnn
|
| 29 |
+
|
| 30 |
+
from .auto_compose import to_torch_auto_compose
|
| 31 |
+
from .distribute_as import from_torch_dist_as
|
| 32 |
+
from .metrics import DEFAULT_METRICS
|
| 33 |
+
|
| 34 |
+
# ============================================================================
|
| 35 |
+
# Public API
|
| 36 |
+
# ============================================================================
|
| 37 |
+
|
| 38 |
+
# Module exports are defined at the package level in __init__.py
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
def get_validation_registry() -> "ValidationRegistry":
|
| 42 |
+
"""Get the global validation registry"""
|
| 43 |
+
return _validation_registry
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
def enable_validation(enabled: bool = True):
|
| 47 |
+
"""Enable or disable validation globally"""
|
| 48 |
+
_validation_registry.enabled = enabled
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
def clear_validation_results():
|
| 52 |
+
"""Clear all validation results"""
|
| 53 |
+
_validation_registry.results.clear()
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
def compare_to_ttnn(
|
| 57 |
+
reference_fn: Callable,
|
| 58 |
+
*,
|
| 59 |
+
input_to_ttnn: Optional[Callable] = None,
|
| 60 |
+
output_to_ttnn: Optional[Callable] = None,
|
| 61 |
+
metric_tolerances: Optional[Dict[Any, Any]] = None,
|
| 62 |
+
enabled: bool = True,
|
| 63 |
+
raise_exceptions: bool = False,
|
| 64 |
+
return_reference_output: bool = False,
|
| 65 |
+
):
|
| 66 |
+
"""
|
| 67 |
+
Convenience wrapper for TTNN-on-device comparison. Provides useful visual cue to users that the reference function is a TTNN-native function.
|
| 68 |
+
|
| 69 |
+
Args:
|
| 70 |
+
reference_fn: Reference function to compare against
|
| 71 |
+
input_to_ttnn: Maps decorated function inputs to reference function inputs
|
| 72 |
+
output_to_ttnn: Maps decorated function outputs to reference function outputs
|
| 73 |
+
metric_tolerances: Dictionary specifying tolerances and optionally custom metrics.
|
| 74 |
+
enabled: Whether validation is enabled (can disable globally via registry)
|
| 75 |
+
raise_exceptions: When True, re-raise any exceptions encountered during
|
| 76 |
+
reference execution, output mapping, or metric computation instead
|
| 77 |
+
of logging them into validation results.
|
| 78 |
+
|
| 79 |
+
Examples:
|
| 80 |
+
@compare_to_ttnn(
|
| 81 |
+
reference_fn=lambda self, x: ttnn.matmul(x, self.weight),
|
| 82 |
+
input_to_ttnn=lambda self, x: (self, x),
|
| 83 |
+
)
|
| 84 |
+
def __call__(self, x):
|
| 85 |
+
return torch.matmul(x, self.torch_weight)
|
| 86 |
+
# alternatively, the decorated function can return a TTNN tensor: return ttnn.from_torch(x) @ self.weight
|
| 87 |
+
|
| 88 |
+
NOTES:
|
| 89 |
+
- The reference function is expected to accepts TTNN tensors and returns a TTNN tensor
|
| 90 |
+
- The decorated function inputs/outputs TTNN tensors, Torch tensors, or mixed TTNN and Torch tensors
|
| 91 |
+
- When decorated function returns torch tensors:
|
| 92 |
+
- the reference function's inputs will be constructed through either input_to_ttnn or from_torch(decorated function inputs, device=ttnn.GetDefaultDevice())
|
| 93 |
+
- the metric on output tensor will be computed on the host
|
| 94 |
+
- Experimental support for on-device metric computation is provided and used when both the decorated function and the reference function return TTNN tensors
|
| 95 |
+
"""
|
| 96 |
+
|
| 97 |
+
# Default converters: recursively convert any TTNN tensors to torch, auto-compose shards.
|
| 98 |
+
# Non-tensor objects are passed through unchanged.
|
| 99 |
+
|
| 100 |
+
def _to_ttnn_auto(x: Any) -> Any:
|
| 101 |
+
if torch.is_tensor(x):
|
| 102 |
+
# Use auto-compose; relies on tensor.device() or a globally-set default device
|
| 103 |
+
assert (
|
| 104 |
+
ttnn.GetDefaultDevice() is not None
|
| 105 |
+
), "Default device is not set. It is required by compare_to_ttnn. Please set it via ttnn.SetDefaultDevice(...)."
|
| 106 |
+
return ttnn.from_torch(x, device=ttnn.GetDefaultDevice())
|
| 107 |
+
return x
|
| 108 |
+
|
| 109 |
+
def _default_input_map(*args, **kwargs):
|
| 110 |
+
ref_args = _map_structure(args, _to_ttnn_auto)
|
| 111 |
+
ref_kwargs = _map_structure(kwargs, _to_ttnn_auto)
|
| 112 |
+
return ref_args, ref_kwargs
|
| 113 |
+
|
| 114 |
+
map_fn_to_match_sig = lambda tt_tensor, filler: to_torch_auto_compose(tt_tensor)
|
| 115 |
+
|
| 116 |
+
return __validate_against(
|
| 117 |
+
reference_fn=reference_fn,
|
| 118 |
+
input_map=input_to_ttnn or _default_input_map,
|
| 119 |
+
output_map=output_to_ttnn,
|
| 120 |
+
metric_tolerances=metric_tolerances,
|
| 121 |
+
enabled=enabled,
|
| 122 |
+
raise_exceptions=raise_exceptions,
|
| 123 |
+
reference_output_map_fn=map_fn_to_match_sig if return_reference_output else None,
|
| 124 |
+
)
|
| 125 |
+
|
| 126 |
+
|
| 127 |
+
def compare_to_torch(
|
| 128 |
+
reference_fn: Callable,
|
| 129 |
+
*,
|
| 130 |
+
input_to_torch: Optional[Callable] = None,
|
| 131 |
+
output_to_torch: Optional[Callable] = None,
|
| 132 |
+
metric_tolerances: Optional[Dict[Any, Any]] = None,
|
| 133 |
+
enabled: bool = True,
|
| 134 |
+
raise_exceptions: bool = False,
|
| 135 |
+
return_reference_output: Optional[Callable[..., bool] | bool] = False,
|
| 136 |
+
):
|
| 137 |
+
"""
|
| 138 |
+
Convenience wrapper for host/CPU comparison using torch.
|
| 139 |
+
|
| 140 |
+
# Args:
|
| 141 |
+
# reference_fn: Reference function to compare against
|
| 142 |
+
# input_to_torch: Maps decorated function inputs to reference function inputs
|
| 143 |
+
# output_to_torch: Maps decorated function outputs to reference function outputs
|
| 144 |
+
# metric_tolerances: Dictionary specifying tolerances and optionally custom metrics.
|
| 145 |
+
# enabled: Whether validation is enabled (can disable globally via registry)
|
| 146 |
+
# raise_exceptions: When True, re-raise any exceptions encountered during
|
| 147 |
+
# reference execution, output mapping, or metric computation instead
|
| 148 |
+
# of logging them into validation results.
|
| 149 |
+
#
|
| 150 |
+
# Notes:
|
| 151 |
+
# - compare_to_torch is used when the reference function is a PyTorch function
|
| 152 |
+
# - the reference function takes as inputs to_torch_auto_compose(decorated function inputs) and compares the outputs with to_torch_auto_compose(decorated function outputs)
|
| 153 |
+
# - the decorated function inputs/outputs TTNN tensors, Torch tensors, or mixed TTNN and Torch tensors
|
| 154 |
+
"""
|
| 155 |
+
|
| 156 |
+
# Default converters: recursively convert any TTNN tensors to torch, auto-compose shards.
|
| 157 |
+
# Non-tensor objects are passed through unchanged.
|
| 158 |
+
|
| 159 |
+
def _to_torch_auto(x: Any) -> Any:
|
| 160 |
+
if isinstance(x, ttnn.Tensor):
|
| 161 |
+
# Use auto-compose; relies on tensor.device() or a globally-set default device
|
| 162 |
+
return to_torch_auto_compose(x)
|
| 163 |
+
return x
|
| 164 |
+
|
| 165 |
+
def _default_input_map(*args, **kwargs):
|
| 166 |
+
ref_args = _map_structure(args, _to_torch_auto)
|
| 167 |
+
ref_kwargs = _map_structure(kwargs, _to_torch_auto)
|
| 168 |
+
return ref_args, ref_kwargs
|
| 169 |
+
|
| 170 |
+
def _default_output_map(output):
|
| 171 |
+
return _map_structure(output, _to_torch_auto)
|
| 172 |
+
|
| 173 |
+
return __validate_against(
|
| 174 |
+
reference_fn=reference_fn,
|
| 175 |
+
input_map=input_to_torch or _default_input_map,
|
| 176 |
+
output_map=output_to_torch or _default_output_map,
|
| 177 |
+
metric_tolerances=metric_tolerances,
|
| 178 |
+
enabled=enabled,
|
| 179 |
+
raise_exceptions=raise_exceptions,
|
| 180 |
+
reference_output_map_fn=from_torch_dist_as if return_reference_output else None,
|
| 181 |
+
)
|
| 182 |
+
|
| 183 |
+
|
| 184 |
+
# ============================================================================
|
| 185 |
+
# Data Structures
|
| 186 |
+
# ============================================================================
|
| 187 |
+
|
| 188 |
+
|
| 189 |
+
@dataclass
|
| 190 |
+
class MetricResult:
|
| 191 |
+
"""Per-metric validation outcome"""
|
| 192 |
+
|
| 193 |
+
value: float = float("inf")
|
| 194 |
+
passed: bool = False
|
| 195 |
+
error: str = ""
|
| 196 |
+
|
| 197 |
+
|
| 198 |
+
@dataclass
|
| 199 |
+
class ValidationResult:
|
| 200 |
+
"""Results from a single validation run"""
|
| 201 |
+
|
| 202 |
+
function_name: str
|
| 203 |
+
passed: bool
|
| 204 |
+
# Map of metric name to its result (value/pass/fail/error)
|
| 205 |
+
metrics: Dict[Any, MetricResult] = field(default_factory=dict)
|
| 206 |
+
execution_time_impl: float = 0.0
|
| 207 |
+
execution_time_ref: float = 0.0
|
| 208 |
+
timestamp: float = field(default_factory=time.time)
|
| 209 |
+
logs: List[str] = field(default_factory=list)
|
| 210 |
+
|
| 211 |
+
|
| 212 |
+
class ValidationRegistry:
|
| 213 |
+
"""Global registry for validation results"""
|
| 214 |
+
|
| 215 |
+
def __init__(self):
|
| 216 |
+
self.results: List[ValidationResult] = []
|
| 217 |
+
self.enabled = True
|
| 218 |
+
|
| 219 |
+
def add_result(self, result: ValidationResult):
|
| 220 |
+
self.results.append(result)
|
| 221 |
+
|
| 222 |
+
def get_summary(self) -> Dict[str, Any]:
|
| 223 |
+
"""Get summary statistics of all validations"""
|
| 224 |
+
if not self.results:
|
| 225 |
+
return {"total": 0, "passed": 0, "failed": 0}
|
| 226 |
+
|
| 227 |
+
passed = sum(1 for r in self.results if r.passed)
|
| 228 |
+
failed = len(self.results) - passed
|
| 229 |
+
|
| 230 |
+
return {
|
| 231 |
+
"total": len(self.results),
|
| 232 |
+
"passed": passed,
|
| 233 |
+
"failed": failed,
|
| 234 |
+
"pass_rate": passed / len(self.results) if self.results else 0.0,
|
| 235 |
+
"avg_speedup": (
|
| 236 |
+
sum(r.execution_time_ref / r.execution_time_impl for r in self.results if r.execution_time_impl > 0)
|
| 237 |
+
/ len(self.results)
|
| 238 |
+
if self.results
|
| 239 |
+
else 0.0
|
| 240 |
+
),
|
| 241 |
+
}
|
| 242 |
+
|
| 243 |
+
def print_report(self, verbose: bool = False):
|
| 244 |
+
"""Print detailed validation report"""
|
| 245 |
+
summary = self.get_summary()
|
| 246 |
+
print("\n" + "=" * 80)
|
| 247 |
+
print("VALIDATION REPORT")
|
| 248 |
+
print("=" * 80)
|
| 249 |
+
print()
|
| 250 |
+
|
| 251 |
+
for result in self.results:
|
| 252 |
+
status = "✓ PASS" if result.passed else "✗ FAIL"
|
| 253 |
+
print(f"{status} - {result.function_name}")
|
| 254 |
+
print(
|
| 255 |
+
f" Execution time: impl={result.execution_time_impl*1000:.2f}ms, ref={result.execution_time_ref*1000:.2f}ms"
|
| 256 |
+
)
|
| 257 |
+
|
| 258 |
+
if result.metrics:
|
| 259 |
+
print(f" Metrics:")
|
| 260 |
+
for metric_name, mres in result.metrics.items():
|
| 261 |
+
# Use enum value for readability if metric is an Enum
|
| 262 |
+
name_str = metric_name.value if hasattr(metric_name, "value") else str(metric_name)
|
| 263 |
+
if mres.value is not None:
|
| 264 |
+
try:
|
| 265 |
+
val_str = f"{mres.value:.6f}"
|
| 266 |
+
except Exception:
|
| 267 |
+
val_str = str(mres.value)
|
| 268 |
+
else:
|
| 269 |
+
val_str = "-"
|
| 270 |
+
status = "PASS" if mres.passed else "FAIL"
|
| 271 |
+
print(f" {name_str}: {val_str} — {status}")
|
| 272 |
+
if mres.error:
|
| 273 |
+
print(f" error: {mres.error}")
|
| 274 |
+
|
| 275 |
+
# Print any collected logs for this validation
|
| 276 |
+
if result.logs and verbose:
|
| 277 |
+
print(" Logs:")
|
| 278 |
+
for entry in result.logs:
|
| 279 |
+
try:
|
| 280 |
+
msg = str(entry)
|
| 281 |
+
except Exception:
|
| 282 |
+
msg = "<unprintable log entry>"
|
| 283 |
+
print(f" {msg}")
|
| 284 |
+
|
| 285 |
+
# All errors are reported via per-metric entries
|
| 286 |
+
print()
|
| 287 |
+
|
| 288 |
+
print("-" * 36 + "Summary:" + "-" * 36)
|
| 289 |
+
print(f"Total validations: {summary['total']}")
|
| 290 |
+
print(f"Passed: {summary['passed']} ({summary['pass_rate']*100:.1f}%)")
|
| 291 |
+
print(f"Failed: {summary['failed']}")
|
| 292 |
+
print(f"Average speedup: {summary['avg_speedup']:.2f}x")
|
| 293 |
+
print()
|
| 294 |
+
print("=" * 80 + "\n")
|
| 295 |
+
|
| 296 |
+
|
| 297 |
+
# Global validation registry
|
| 298 |
+
_validation_registry = ValidationRegistry()
|
| 299 |
+
|
| 300 |
+
|
| 301 |
+
# ============================================================================
|
| 302 |
+
# Validation Decorator
|
| 303 |
+
# ============================================================================
|
| 304 |
+
|
| 305 |
+
|
| 306 |
+
class Metric(str, Enum):
|
| 307 |
+
"""Enumeration of supported metric names, values match current string keys."""
|
| 308 |
+
|
| 309 |
+
MAX_ABS_ERROR = "max_abs_error"
|
| 310 |
+
MEAN_ABS_ERROR = "mean_abs_error"
|
| 311 |
+
PCC = "pcc"
|
| 312 |
+
|
| 313 |
+
|
| 314 |
+
@dataclass
|
| 315 |
+
class MetricSpec:
|
| 316 |
+
"""Metric specification: name, tolerance, direction, and compute function."""
|
| 317 |
+
|
| 318 |
+
tolerance: float
|
| 319 |
+
higher_is_better: bool
|
| 320 |
+
compute_fn: Callable[[Any, Any], float]
|
| 321 |
+
name: str = field(default="")
|
| 322 |
+
|
| 323 |
+
|
| 324 |
+
# Registry of built-in metrics with defaults. Tolerances here are sensible
|
| 325 |
+
# defaults; callers can override per-validation via `tolerances`.
|
| 326 |
+
METRIC_SPECS: Dict[Metric, MetricSpec] = {
|
| 327 |
+
Metric.MAX_ABS_ERROR: MetricSpec(
|
| 328 |
+
name=Metric.MAX_ABS_ERROR.value,
|
| 329 |
+
tolerance=0.0,
|
| 330 |
+
higher_is_better=False,
|
| 331 |
+
compute_fn=DEFAULT_METRICS[Metric.MAX_ABS_ERROR.value],
|
| 332 |
+
),
|
| 333 |
+
Metric.MEAN_ABS_ERROR: MetricSpec(
|
| 334 |
+
name=Metric.MEAN_ABS_ERROR.value,
|
| 335 |
+
tolerance=0.0,
|
| 336 |
+
higher_is_better=False,
|
| 337 |
+
compute_fn=DEFAULT_METRICS[Metric.MEAN_ABS_ERROR.value],
|
| 338 |
+
),
|
| 339 |
+
Metric.PCC: MetricSpec(
|
| 340 |
+
name=Metric.PCC.value,
|
| 341 |
+
tolerance=0.0,
|
| 342 |
+
higher_is_better=True,
|
| 343 |
+
compute_fn=DEFAULT_METRICS[Metric.PCC.value],
|
| 344 |
+
),
|
| 345 |
+
}
|
| 346 |
+
|
| 347 |
+
# Convenience groupings for quick checks
|
| 348 |
+
HIGHER_IS_BETTER_METRICS = {m.value for m, spec in METRIC_SPECS.items() if spec.higher_is_better}
|
| 349 |
+
LOWER_IS_BETTER_METRICS = {m.value for m, spec in METRIC_SPECS.items() if not spec.higher_is_better}
|
| 350 |
+
|
| 351 |
+
|
| 352 |
+
# Helper: prefer Metric enum as dict key when possible
|
| 353 |
+
def _metric_key(key: Any) -> Any:
|
| 354 |
+
try:
|
| 355 |
+
return Metric(key)
|
| 356 |
+
except Exception:
|
| 357 |
+
return key
|
| 358 |
+
|
| 359 |
+
|
| 360 |
+
# Helper: Build active metrics map (name -> compute fn). Accept Metric enum keys for tolerances.
|
| 361 |
+
def _normalize_key(k: Any) -> str:
|
| 362 |
+
try:
|
| 363 |
+
# Enum or similar objects with .value as canonical string
|
| 364 |
+
return k.value if hasattr(k, "value") else str(k)
|
| 365 |
+
except Exception:
|
| 366 |
+
return str(k)
|
| 367 |
+
|
| 368 |
+
|
| 369 |
+
# Helper: Prepare metrics, tolerances, and directionality
|
| 370 |
+
def _prepare_metric_config(metric_tolerances_input):
|
| 371 |
+
metrics_map = {name: fn for name, fn in DEFAULT_METRICS.items()}
|
| 372 |
+
hib = set(HIGHER_IS_BETTER_METRICS)
|
| 373 |
+
logs_local: List[str] = []
|
| 374 |
+
tol_map: Dict[str, float] = {}
|
| 375 |
+
|
| 376 |
+
if not isinstance(metric_tolerances_input, dict):
|
| 377 |
+
logs_local.append(f"metric_tolerances_input must be a dict, got {type(metric_tolerances_input)}")
|
| 378 |
+
metric_tolerances_input = dict()
|
| 379 |
+
|
| 380 |
+
if not metric_tolerances_input:
|
| 381 |
+
logs_local.append("no metric tolerances provided")
|
| 382 |
+
metric_tolerances_input = dict()
|
| 383 |
+
|
| 384 |
+
for raw_key, spec in metric_tolerances_input.items():
|
| 385 |
+
name = _normalize_key(raw_key)
|
| 386 |
+
if isinstance(spec, MetricSpec):
|
| 387 |
+
tol_map[name] = float(spec.tolerance)
|
| 388 |
+
metrics_map[name] = spec.compute_fn
|
| 389 |
+
spec.name = name if spec.name == "" else spec.name
|
| 390 |
+
if spec.higher_is_better:
|
| 391 |
+
hib.add(name)
|
| 392 |
+
else:
|
| 393 |
+
hib.discard(name)
|
| 394 |
+
continue
|
| 395 |
+
try:
|
| 396 |
+
tol_map[name] = float(spec)
|
| 397 |
+
except Exception:
|
| 398 |
+
logs_local.append(f"unrecognized tolerance: {raw_key}: {spec}")
|
| 399 |
+
|
| 400 |
+
return metrics_map, hib, tol_map, logs_local
|
| 401 |
+
|
| 402 |
+
|
| 403 |
+
# todo)) also allow raise an exception from the a failed metric!
|
| 404 |
+
|
| 405 |
+
# todo)) add support for multiple outputs from the reference function and the decorated function!
|
| 406 |
+
# e.g., return logits, past_key_values, etc.
|
| 407 |
+
|
| 408 |
+
# todo)) make sure the dtypes are taken care of in the validate_against decorator!
|
| 409 |
+
# e.g., if the decorated function is of dtype bfp4, what is the dtype of the to_torch_auto_compose output?
|
| 410 |
+
|
| 411 |
+
# todo)) add file line number to the validation results!
|
| 412 |
+
|
| 413 |
+
# todo)) add function to export the validation results to a csv file!
|
| 414 |
+
|
| 415 |
+
# todo)) enhance report to use file line number as index to summarize the validation results
|
| 416 |
+
# e.g., ✗ FAIL - __main__.Attention.__call__ (line 100) -> 100 failed validations
|
| 417 |
+
|
| 418 |
+
# todo)) remove compile time from speed up calculation -- e.g., 9118.15ms should be removed in the example below:
|
| 419 |
+
# ================================================================================
|
| 420 |
+
# VALIDATION REPORT
|
| 421 |
+
# ================================================================================
|
| 422 |
+
# Total validations: 1400
|
| 423 |
+
# Passed: 1400 (100.0%)
|
| 424 |
+
# Failed: 0
|
| 425 |
+
# Average speedup: 0.97x
|
| 426 |
+
|
| 427 |
+
# ✓ PASS - __main__.TransformerBlock.__call__
|
| 428 |
+
# Execution time: impl=9118.15ms, ref=14.84ms
|
| 429 |
+
# Metrics:
|
| 430 |
+
# pcc: 0.999743 — PASS
|
| 431 |
+
|
| 432 |
+
# ✓ PASS - __main__.TransformerBlock.__call__
|
| 433 |
+
# Execution time: impl=3.05ms, ref=12.73ms
|
| 434 |
+
# Metrics:
|
| 435 |
+
# pcc: 0.999913 — PASS
|
| 436 |
+
|
| 437 |
+
# ✓ PASS - __main__.TransformerBlock.__call__
|
| 438 |
+
# Execution time: impl=3.31ms, ref=12.48ms
|
| 439 |
+
# Metrics:
|
| 440 |
+
# pcc: 0.999962 — PASS
|
| 441 |
+
|
| 442 |
+
# ✓ PASS - __main__.TransformerBlock.__call__
|
| 443 |
+
# Execution time: impl=3.11ms, ref=12.89ms
|
| 444 |
+
# Metrics:
|
| 445 |
+
# pcc: 1.000000 — PASS
|
| 446 |
+
|
| 447 |
+
# ✓ PASS - __main__.TransformerBlock.__call__
|
| 448 |
+
# Execution time: impl=3.16ms, ref=12.97ms
|
| 449 |
+
# Metrics:
|
| 450 |
+
# pcc: 0.999998 — PASS
|
| 451 |
+
|
| 452 |
+
|
| 453 |
+
# todo)) stretch goals:
|
| 454 |
+
# - generate unit test automatically from the failed validations
|
| 455 |
+
def __validate_against(
|
| 456 |
+
reference_fn: Callable,
|
| 457 |
+
*,
|
| 458 |
+
input_map: Optional[Callable] = None,
|
| 459 |
+
output_map: Optional[Callable] = None,
|
| 460 |
+
metric_tolerances: Optional[Dict[Any, Any]] = None,
|
| 461 |
+
enabled: bool = True,
|
| 462 |
+
raise_exceptions: bool = False,
|
| 463 |
+
reference_output_map_fn: Optional[Callable] = None,
|
| 464 |
+
):
|
| 465 |
+
"""
|
| 466 |
+
Decorator to validate a function against a reference implementation.
|
| 467 |
+
|
| 468 |
+
Args:
|
| 469 |
+
reference_fn: Reference function to compare against
|
| 470 |
+
input_map: Maps decorated function inputs to reference function inputs
|
| 471 |
+
Signature: (args, kwargs) -> (ref_args, ref_kwargs)
|
| 472 |
+
If None, inputs are passed as-is
|
| 473 |
+
output_map: Converts impl output to match ref output's type
|
| 474 |
+
Signature: (output) -> comparable_output
|
| 475 |
+
Applied ONLY to impl_output to convert it to ref_output's type
|
| 476 |
+
Common use: lambda x: ttnn.to_torch(x).squeeze() to convert ttnn → torch
|
| 477 |
+
If None, outputs are used as-is (both must already be same type)
|
| 478 |
+
metric_tolerances: Dictionary specifying tolerances and optionally custom metrics.
|
| 479 |
+
Accepts the following per metric key (str or Metric):
|
| 480 |
+
- float: tolerance only (uses built-in compute + direction)
|
| 481 |
+
- MetricSpec instance
|
| 482 |
+
Validation fails if any metric exceeds its tolerance
|
| 483 |
+
enabled: Whether validation is enabled (can disable globally via registry)
|
| 484 |
+
raise_exceptions: When True, re-raise any exceptions encountered during
|
| 485 |
+
reference execution, output mapping, or metric computation instead
|
| 486 |
+
of logging them into validation results.
|
| 487 |
+
|
| 488 |
+
Examples:
|
| 489 |
+
# Pattern 1: TTNN-native metrics (recommended, 100-1000× faster!)
|
| 490 |
+
# Both impl and ref return ttnn.Tensor, no output_map needed
|
| 491 |
+
def _reference_impl(self, x):
|
| 492 |
+
x_torch = ttnn.to_torch(x).squeeze(0)
|
| 493 |
+
result_torch = torch.matmul(x_torch, self.weight_torch)
|
| 494 |
+
# Convert back to TTNN for on-device metrics!
|
| 495 |
+
return ttnn.from_torch(result_torch.unsqueeze(0), device=self.device, ...)
|
| 496 |
+
|
| 497 |
+
@validate_against(
|
| 498 |
+
reference_fn=lambda self, x: self._reference_impl(x),
|
| 499 |
+
tolerances={'max_abs_error': 1e-3}
|
| 500 |
+
)
|
| 501 |
+
def __call__(self, x):
|
| 502 |
+
return ttnn.matmul(x, self.weight)
|
| 503 |
+
|
| 504 |
+
# Pattern 2: PyTorch metrics (when reference returns torch.Tensor)
|
| 505 |
+
# Use output_map to convert impl output (ttnn.Tensor) to match ref (torch.Tensor)
|
| 506 |
+
@validate_against(
|
| 507 |
+
reference_fn=torch.nn.functional.rms_norm,
|
| 508 |
+
input_map=lambda args, kwargs: (
|
| 509 |
+
(ttnn.to_torch(args[1]).squeeze(),),
|
| 510 |
+
{'eps': args[0].eps}
|
| 511 |
+
),
|
| 512 |
+
output_map=lambda x: ttnn.to_torch(x).squeeze(), # Convert impl: ttnn → torch
|
| 513 |
+
tolerances={'max_abs_error': 1e-3}
|
| 514 |
+
)
|
| 515 |
+
def __call__(self, x):
|
| 516 |
+
return ttnn.rms_norm(x, self.weight, self.eps) # Returns ttnn.Tensor
|
| 517 |
+
"""
|
| 518 |
+
|
| 519 |
+
if metric_tolerances is None:
|
| 520 |
+
metric_tolerances = {
|
| 521 |
+
Metric.MAX_ABS_ERROR: 1e-2,
|
| 522 |
+
Metric.PCC: 0.99,
|
| 523 |
+
}
|
| 524 |
+
|
| 525 |
+
metrics_to_use, higher_is_better_effective, tolerances_map, pre_logs = _prepare_metric_config(metric_tolerances)
|
| 526 |
+
|
| 527 |
+
def decorator(func):
|
| 528 |
+
@wraps(func)
|
| 529 |
+
def wrapper(*args, **kwargs):
|
| 530 |
+
# Check if validation is enabled
|
| 531 |
+
if not enabled or not _validation_registry.enabled:
|
| 532 |
+
return func(*args, **kwargs)
|
| 533 |
+
|
| 534 |
+
# Execute implementation
|
| 535 |
+
start_time = time.perf_counter()
|
| 536 |
+
impl_output = func(*args, **kwargs)
|
| 537 |
+
impl_time = time.perf_counter() - start_time
|
| 538 |
+
logs: List[str] = pre_logs.copy()
|
| 539 |
+
|
| 540 |
+
# Map inputs for reference function: prefer input_map, else pass-through
|
| 541 |
+
if input_map:
|
| 542 |
+
_nm = getattr(input_map, "__name__", None) or type(input_map).__name__
|
| 543 |
+
logs.append(f"input_map={_nm}")
|
| 544 |
+
try:
|
| 545 |
+
mapped = input_map(*args, **kwargs)
|
| 546 |
+
except Exception as e:
|
| 547 |
+
# If input mapping fails, log error, record result, and return impl output
|
| 548 |
+
logs.append(f"input_mapping_error={str(e)}")
|
| 549 |
+
result = ValidationResult(
|
| 550 |
+
function_name=f"{func.__module__}.{func.__qualname__}",
|
| 551 |
+
passed=False,
|
| 552 |
+
metrics={
|
| 553 |
+
"input_mapping": MetricResult(
|
| 554 |
+
value=None, passed=False, error=f"Input mapping failed: {str(e)}"
|
| 555 |
+
)
|
| 556 |
+
},
|
| 557 |
+
execution_time_impl=impl_time,
|
| 558 |
+
execution_time_ref=0.0,
|
| 559 |
+
logs=logs,
|
| 560 |
+
)
|
| 561 |
+
_validation_registry.add_result(result)
|
| 562 |
+
# Re-raise exception if raise_exceptions is True
|
| 563 |
+
if raise_exceptions:
|
| 564 |
+
raise
|
| 565 |
+
return impl_output
|
| 566 |
+
# Normalize mapper output:
|
| 567 |
+
# - If (ref_args, ref_kwargs) with kwargs as dict, use directly
|
| 568 |
+
# - Otherwise, treat return as positional args and use empty kwargs
|
| 569 |
+
if isinstance(mapped, tuple) and len(mapped) == 2 and isinstance(mapped[1], dict):
|
| 570 |
+
ref_args, ref_kwargs = mapped
|
| 571 |
+
else:
|
| 572 |
+
ref_args = mapped if isinstance(mapped, (list, tuple)) else (mapped,)
|
| 573 |
+
ref_kwargs = {}
|
| 574 |
+
else:
|
| 575 |
+
logs.append("input_map=pass-through")
|
| 576 |
+
ref_args, ref_kwargs = args, kwargs
|
| 577 |
+
|
| 578 |
+
# Execute reference
|
| 579 |
+
try:
|
| 580 |
+
start_time = time.perf_counter()
|
| 581 |
+
ref_output = reference_fn(*ref_args, **ref_kwargs)
|
| 582 |
+
ref_time = time.perf_counter() - start_time
|
| 583 |
+
except Exception as e:
|
| 584 |
+
# If reference fails, just return impl output and log error via metrics
|
| 585 |
+
logs.append(f"reference_execution_error={str(e)}")
|
| 586 |
+
# Record elapsed time until failure
|
| 587 |
+
ref_time = time.perf_counter() - start_time
|
| 588 |
+
result = ValidationResult(
|
| 589 |
+
function_name=f"{func.__module__}.{func.__qualname__}",
|
| 590 |
+
passed=False,
|
| 591 |
+
metrics={
|
| 592 |
+
"reference_execution": MetricResult(
|
| 593 |
+
value=None, passed=False, error=f"Reference execution failed: {str(e)}"
|
| 594 |
+
)
|
| 595 |
+
},
|
| 596 |
+
execution_time_impl=impl_time,
|
| 597 |
+
execution_time_ref=ref_time,
|
| 598 |
+
logs=logs,
|
| 599 |
+
)
|
| 600 |
+
_validation_registry.add_result(result)
|
| 601 |
+
# Re-raise exception if raise_exceptions is True
|
| 602 |
+
if raise_exceptions:
|
| 603 |
+
raise
|
| 604 |
+
return impl_output
|
| 605 |
+
|
| 606 |
+
# Map outputs for comparison
|
| 607 |
+
# Note: output_map only applies to impl_output to convert it to match ref_output's type
|
| 608 |
+
try:
|
| 609 |
+
_nm = getattr(output_map, "__name__", None) or type(output_map).__name__
|
| 610 |
+
logs.append(f"output_map={_nm}")
|
| 611 |
+
impl_comparable = output_map(impl_output) if output_map else impl_output
|
| 612 |
+
ref_comparable = ref_output # Reference output is always used as-is
|
| 613 |
+
except Exception as e:
|
| 614 |
+
logs.append(f"output_mapping_error={str(e)}")
|
| 615 |
+
result = ValidationResult(
|
| 616 |
+
function_name=f"{func.__module__}.{func.__qualname__}",
|
| 617 |
+
passed=False,
|
| 618 |
+
metrics={
|
| 619 |
+
"output_mapping": MetricResult(
|
| 620 |
+
value=None, passed=False, error=f"Output mapping failed: {str(e)}"
|
| 621 |
+
)
|
| 622 |
+
},
|
| 623 |
+
execution_time_impl=impl_time,
|
| 624 |
+
execution_time_ref=ref_time,
|
| 625 |
+
logs=logs,
|
| 626 |
+
)
|
| 627 |
+
_validation_registry.add_result(result)
|
| 628 |
+
# Re-raise exception if raise_exceptions is True
|
| 629 |
+
if raise_exceptions:
|
| 630 |
+
raise
|
| 631 |
+
return impl_output
|
| 632 |
+
|
| 633 |
+
# Compute metrics
|
| 634 |
+
computed_metrics: Dict[Any, MetricResult] = {}
|
| 635 |
+
passed = True
|
| 636 |
+
|
| 637 |
+
for metric_name, threshold in tolerances_map.items():
|
| 638 |
+
try:
|
| 639 |
+
metric_fn = metrics_to_use.get(metric_name)
|
| 640 |
+
|
| 641 |
+
# Store results keyed by enum when available
|
| 642 |
+
metric_key = _metric_key(metric_name)
|
| 643 |
+
# If metric function isn't known, record an error
|
| 644 |
+
if metric_fn is None:
|
| 645 |
+
computed_metrics[metric_key] = MetricResult(
|
| 646 |
+
value=None, passed=False, error=f"Unknown metric: {metric_name}"
|
| 647 |
+
)
|
| 648 |
+
passed = False
|
| 649 |
+
continue
|
| 650 |
+
|
| 651 |
+
value = metric_fn(impl_comparable, ref_comparable)
|
| 652 |
+
|
| 653 |
+
# Determine direction using registry when available
|
| 654 |
+
if metric_name in higher_is_better_effective:
|
| 655 |
+
ok = value >= threshold
|
| 656 |
+
err = None
|
| 657 |
+
if not ok:
|
| 658 |
+
passed = False
|
| 659 |
+
err = f"{metric_name}={value:.6e} below threshold {threshold:.6e}"
|
| 660 |
+
computed_metrics[metric_key] = MetricResult(value=value, passed=ok, error=err)
|
| 661 |
+
else:
|
| 662 |
+
ok = value <= threshold
|
| 663 |
+
err = None
|
| 664 |
+
if not ok:
|
| 665 |
+
passed = False
|
| 666 |
+
err = f"{metric_name}={value:.6e} exceeds tolerance {threshold:.6e}"
|
| 667 |
+
computed_metrics[metric_key] = MetricResult(value=value, passed=ok, error=err)
|
| 668 |
+
except Exception as e:
|
| 669 |
+
msg = f"Metric {metric_name} failed: {str(e)}"
|
| 670 |
+
computed_metrics[metric_key] = MetricResult(value=None, passed=False, error=msg)
|
| 671 |
+
passed = False
|
| 672 |
+
if raise_exceptions:
|
| 673 |
+
raise
|
| 674 |
+
|
| 675 |
+
# Optionally return the (aligned) reference output instead of impl output
|
| 676 |
+
backup_impl_output = impl_output
|
| 677 |
+
try:
|
| 678 |
+
if reference_output_map_fn:
|
| 679 |
+
impl_output = reference_output_map_fn(ref_output, impl_output)
|
| 680 |
+
logs.append(f"reference_output_mapping_fn={reference_output_map_fn.__name__}")
|
| 681 |
+
except Exception as e:
|
| 682 |
+
# If alignment fails, fall back to impl output
|
| 683 |
+
impl_output = backup_impl_output
|
| 684 |
+
# Re-raise exception if raise_exceptions is True after logging the error
|
| 685 |
+
logs.append(f"reference_output_mapping_error={str(e)}")
|
| 686 |
+
if raise_exceptions:
|
| 687 |
+
raise
|
| 688 |
+
|
| 689 |
+
# Record results
|
| 690 |
+
pass_count = sum(1 for v in computed_metrics.values() if v.passed)
|
| 691 |
+
fail_count = sum(1 for v in computed_metrics.values() if not v.passed)
|
| 692 |
+
logs.append(f"metrics={pass_count}_pass,{fail_count}_fail")
|
| 693 |
+
result = ValidationResult(
|
| 694 |
+
function_name=f"{func.__module__}.{func.__qualname__}",
|
| 695 |
+
passed=passed,
|
| 696 |
+
metrics=computed_metrics,
|
| 697 |
+
execution_time_impl=impl_time,
|
| 698 |
+
execution_time_ref=ref_time,
|
| 699 |
+
logs=logs,
|
| 700 |
+
)
|
| 701 |
+
_validation_registry.add_result(result)
|
| 702 |
+
|
| 703 |
+
return impl_output
|
| 704 |
+
|
| 705 |
+
return wrapper
|
| 706 |
+
|
| 707 |
+
return decorator
|
| 708 |
+
|
| 709 |
+
|
| 710 |
+
def _map_structure(obj: Any, fn: Callable[[Any], Any]) -> Any:
|
| 711 |
+
"""
|
| 712 |
+
Map a structure of objects to a new structure using a function.
|
| 713 |
+
"""
|
| 714 |
+
if isinstance(obj, (list, tuple)):
|
| 715 |
+
mapped = [_map_structure(x, fn) for x in obj]
|
| 716 |
+
return type(obj)(mapped)
|
| 717 |
+
if isinstance(obj, dict):
|
| 718 |
+
return {k: _map_structure(v, fn) for k, v in obj.items()}
|
| 719 |
+
return fn(obj)
|
code/models/tt_transformers/Host_Mem_Profile.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Model memory on host for performance and accuracy
|
| 2 |
+
|
| 3 |
+
[Host memory usage results](../sample_data/host_mem_profiling/) at peak memory (in MB) are collected from host_mem_profiler.py by running the target demo under memory_profiler at
|
| 4 |
+
100 ms sampling intervals. You can generate these results by running the script with --mesh-device, --hf-model, and
|
| 5 |
+
--test arguments in [demo/simple_text_demo.py](demo/simple_text_demo.py); it produces a timestamped PNG plot under profiling_results/ and prints peak and baseline RSS to the
|
| 6 |
+
console.
|
| 7 |
+
|
| 8 |
+
Note that all measurements include child processes spawned by the TT device runtime, giving a realistic view of total
|
| 9 |
+
host-side footprint. Peak memory is defined as the maximum RSS observed across the full test lifetime — including
|
| 10 |
+
model weight loading, KV-cache allocation, and decode iterations. Baseline is the RSS at process start before any
|
| 11 |
+
model work begins.
|
| 12 |
+
|
| 13 |
+
Host memory (RSS) was profiled across three configurations — [Performance](#performance), [Accuracy](#accuracy), and [Multimodal](#multimodal-models) — using up to 200
|
| 14 |
+
decode iterations on T3K (8-chip) and N300 (2-chip) devices.
|
| 15 |
+
|
| 16 |
+
All [numbers](../sample_data/host_mem_profiling/) below were captured with a maximum generation of 200 tokens (200 decode iterations) to match the
|
| 17 |
+
conditions used for centralized targets in [models/model_targets.yaml](../model_targets.yaml).
|
| 18 |
+
|
| 19 |
+
## Performance
|
| 20 |
+
|
| 21 |
+
This configuration uses bfp4 MLP and bfp8 attention weights for all models except:
|
| 22 |
+
* Qwen-2.5-7B, which uses bfp8 MLP and bfp16 attention weights in all decoder layers
|
| 23 |
+
* Llama-3.1-8B which uses bfp8 MLP in only the 32nd decoder layer and bfp4 MLP elsewhere
|
| 24 |
+
|
| 25 |
+
| Model | Device | batch-1 max mem (MB) | batch-32 max mem (MB) | Speed (t/s/u) | TTFT (ms) |
|
| 26 |
+
|-------------------|-------------|-----------------------|-----------------------|---------------|-----------|
|
| 27 |
+
| Llama-3.2-1B | T3K | 3532 | 2712 | 119.8 | 32 |
|
| 28 |
+
| Llama-3.2-3B | T3K | 7846 | 5388 | 68.5 | 52 |
|
| 29 |
+
| Llama-3.1-8B | T3K | 13683 | 6922 | 64.3 | 53 |
|
| 30 |
+
| Llama-3.2-11B | T3K | 13885 | 7254 | 62.7 | 47 |
|
| 31 |
+
| Llama-3.1-70B | T3K | 35820 | 35187 | 16.6 | 164 |
|
| 32 |
+
| Llama-3.3-70B | T3K | 101640 | 36176 | 16.6 | 164 |
|
| 33 |
+
| Llama-3.2-90B | T3K | 34427 | 34842 | 6 | 5535 |
|
| 34 |
+
| Qwen2.5-7B | N300 | 16597 | 17754 | 24.6 | 92 |
|
| 35 |
+
| Qwen2.5-72B | T3K | 147106 | 145432 | 15.2 | 225 |
|
| 36 |
+
| Qwen2.5-32B | T3K | 53434 | 15594 | 22.4 | 190 |
|
| 37 |
+
| Qwen3-32B | T3K | 56033 | 20422 | 22.9 | 123 |
|
| 38 |
+
| QwQ-32B | T3K | 69900 | 67186 | 20.7 | 105 |
|
| 39 |
+
|
| 40 |
+
## Accuracy
|
| 41 |
+
|
| 42 |
+
This configuration uses bfp8 MLP and BF16 attention weights (70B+ models use bfp8 attention and bfp4 MLP).
|
| 43 |
+
Llama 3 models test as insensitive to attention precision and so we use bfp8 attention and kv-cache for them even in accuracy mode.
|
| 44 |
+
|
| 45 |
+
| Model | Device | batch-1 max mem (MB) | batch-32 max mem (MB) | Speed (t/s/u) | TTFT (ms) |
|
| 46 |
+
|-------------------|-------------|----------------------|------------------------|---------------|-----------|
|
| 47 |
+
| Llama-3.2-1B | T3K | 4654 | 2707 | 120.5 | 28 |
|
| 48 |
+
| Llama-3.2-3B | T3K | 10374 | 5270 | 67.9 | 69 |
|
| 49 |
+
| Llama-3.1-8B | T3K | 20406 | 7704 | 60.8 | 81 |
|
| 50 |
+
| Llama-3.2-11B | T3K | 20265 | 7051 | 61.4 | 53 |
|
| 51 |
+
| Llama-3.1-70B | T3K | 154122 | 37370 | 16.5 | 168 |
|
| 52 |
+
| Llama-3.3-70B | T3K | 100112 | 35026 | 16.5 | 168 |
|
| 53 |
+
| Llama-3.2-90B | T3K | 155139 | 34997 | 6 | 5600 |
|
| 54 |
+
| Qwen2.5-7B | N300 | 20189 | 17956 | 24.6 | 92 |
|
| 55 |
+
| Qwen2.5-72B | T3K | 146204 | 147032 | 15.1 | 216 |
|
| 56 |
+
| Qwen2.5-32B | T3K | 74162 | 14811 | 19.7 | 183 |
|
| 57 |
+
| Qwen3-32B | T3K | 76288 | 20785 | 19.6 | 119 |
|
| 58 |
+
| QwQ-32B | T3K | 72627 | 67278 | 18.3 | 120 |
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
## Multimodal Models
|
| 62 |
+
The results are collected using this script [demo/simple_vision_demo.py](demo/simple_vision_demo.py)); with host memory profiler and evaluated on both language and vision branches.
|
| 63 |
+
The memory is reported in MB.
|
| 64 |
+
|
| 65 |
+
| Model | Device | batch-1 max mem (MB) | batch-32 max mem (MB) | Speed (t/s/u) | TTFT (ms) |
|
| 66 |
+
|-------------------|-------------|-----------------------|-----------------------|---------------|-----------|
|
| 67 |
+
| Llama-3.2-11B | T3K | 14309 | 8610 | 61.4 | 53 |
|
| 68 |
+
| Llama-3.2-90B | T3K | 75451 | - | 6 | 5600 |
|
| 69 |
+
| Qwen2.5-VL-3B | N300 | 9319 | 9068 | 24.6 | 92 |
|
| 70 |
+
| Qwen2.5-VL-7B | N300 | 18745 | 10946 | 24.6 | 92 |
|
| 71 |
+
| Qwen2.5-VL-72B | T3K | 160437 | 147925 | 15.1 | 216 |
|
| 72 |
+
| Qwen2.5-VL-32B | T3K | 71960 | 68464 | 19.7 | 183 |
|
| 73 |
+
| Qwen3-VL-32B | T3K | 76297 | 21514 | 19.6 | 119 |
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
[Performance](#performance) vs. [Accuracy](#accuracy) modes trade memory for precision: accuracy mode uses BF16 attention weights versus bfp8/bfp4
|
| 77 |
+
in performance mode, and typically raises peak memory. The increase is clearest at batch-1, where most models grow noticeably Llama-3.1-8B rises from 13.7 GB to 20.4 GB and Qwen2.5-32B from 53 GB to 74 GB — while 70B+ models show a smaller relative increase since attention weight precision is already reduced in both modes. At batch-32 the picture is mixed: KV-cache and activations dominate, and several models (Llama-3.2-1B/3B/11B, Llama-3.3-70B, Qwen2.5-32B) report slightly lower peaks in accuracy mode rather than higher.
|
| 78 |
+
|
| 79 |
+
Memory scales roughly with model size, ranging from ~3–4 GB for 1B models up to ~147–155 GB for 72–90B models. The
|
| 80 |
+
largest models (Qwen2.5-72B, Llama-3.2-90B) show little difference between batch-1 and batch-32, suggesting KV-cache
|
| 81 |
+
and weight loading dominate over activation memory. Mid-size models (32B class) exhibit a larger batch-1 to batch-32
|
| 82 |
+
gap, likely due to KV-cache growth with sequence length at batch-1.
|
| 83 |
+
|
| 84 |
+
Throughput and TTFT follow expected trends: smaller models deliver higher tokens/s/user (up to 120 t/s/u for 1B) and
|
| 85 |
+
low TTFT (~30 ms), while 90B models drop to 6 t/s/u with TTFT exceeding 5.5 seconds.
|
| 86 |
+
|
| 87 |
+
[Multimodal](#multimodal-models) models carry a modest overhead versus their text-only counterparts — Llama-3.2-11B adds ~400 MB at batch-1
|
| 88 |
+
though Qwen2.5-VL-72B reaches the highest overall footprint at ~160 GB.
|
code/models/tt_transformers/PERF.md
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Note: DEPRECATED. PLEASE CHECK THE YAML FILE [models/model_targets.yaml](models/model_targets.yaml)
|
| 2 |
+
|
| 3 |
+
# Model performance and accuracy
|
| 4 |
+
|
| 5 |
+
Performance and token accuracy using teacher forcing is collected from [demo/simple_text_demo.py](demo/simple_text_demo.py) with the `ci-token-matching` test case. You can generate this table by running these tests with the `lt` tool (tell it to run `table` or `pareto`) and pressing `m` whilst in the results section to export to markdown.
|
| 6 |
+
|
| 7 |
+
Note that token accuracy parses the below to determine expected values +- 0.5. In May 2025 we switched the default to measuring the accuracy by prefilling 512 tokens and generating another 511, rather than generating 128 tokens in earlier versions. This caused overall accuracy values to drop slightly.
|
| 8 |
+
|
| 9 |
+
Also note that all the performance metrics below were taken for a maximum generation of 200 tokens, i.e., 200 decode iterations.
|
| 10 |
+
|
| 11 |
+
## Performance
|
| 12 |
+
|
| 13 |
+
This configuration uses bfp4 MLP and bfp8 attention weights for all models except:
|
| 14 |
+
* Qwen-2.5-7B, which uses bfp8 MLP and bfp16 attention weights in all decoder layers
|
| 15 |
+
* Llama-3.1-8B which uses bfp8 MLP in only the 32nd decoder layer and bfp4 MLP elsewhere
|
| 16 |
+
|
| 17 |
+
| Model | Device | Top-1 (%) | Top-5 (%) | Speed (t/s/u) | TTFT (ms) |
|
| 18 |
+
|-------------------|-------------|-----------|-----------|---------------|-----------|
|
| 19 |
+
| Llama-3.2-1B | N150 | 79 | 97 | 87.8 | 26 |
|
| 20 |
+
| Llama-3.2-1B | N300 | 79 | 97 | 105.9 | 22 |
|
| 21 |
+
| Llama-3.2-1B | T3K | 80 | 97 | 119.8 | 32 |
|
| 22 |
+
| Llama-3.2-1B | TG | 77 | 96 | 51.0 | |
|
| 23 |
+
| Llama-3.2-3B | N150 | 89 | 98 | 54.0 | 55 |
|
| 24 |
+
| Llama-3.2-3B | N300 | 89 | 98 | 68.0 | 39 |
|
| 25 |
+
| Llama-3.2-3B | T3K | 91 | 99 | 68.5 | 52 |
|
| 26 |
+
| Llama-3.2-3B | TG | 87 | 97 | 33.5 | |
|
| 27 |
+
| Llama-3.1-8B | N150 | 90 | 97 | 28.3 | 104 |
|
| 28 |
+
| Llama-3.1-8B | N300 | 90 | 97 | 44.2 | 67 |
|
| 29 |
+
| Llama-3.1-8B | P100 | 90 | 98 | 29.5 | 84 |
|
| 30 |
+
| Llama-3.1-8B | P150 | 90 | 98 | 33.6 | 76 |
|
| 31 |
+
| Llama-3.1-8B | T3K | 90 | 98 | 64.3 | 53 |
|
| 32 |
+
| Llama-3.1-8B | T3K (DP=4) | | | 39.6 | 58 |
|
| 33 |
+
| Llama-3.1-8B | T3K (DP=8) | | | 24.9 | 86 |
|
| 34 |
+
| Llama-3.1-8B | TG | 88 | 97 | 29.5 | |
|
| 35 |
+
| Llama-3.2-11B | N150 | 90 | 98 | 55.5 | 58 |
|
| 36 |
+
| Llama-3.2-11B | N300 | 90 | 98 | 44.1 | 67 |
|
| 37 |
+
| Llama-3.2-11B | T3K | 90 | 98 | 62.7 | 47 |
|
| 38 |
+
| Llama-3.2-11B | TG | 87 | 97 | 29.5 | |
|
| 39 |
+
| Llama-3.1-70B | T3K | 96 | 100 | 16.6 | 164 |
|
| 40 |
+
| Llama-3.3-70B | T3K | 96 | 100 | 16.6 | 164 |
|
| 41 |
+
| Llama-3.1-70B | TG | 95 | 100 | 12.7 | |
|
| 42 |
+
| Llama-3.3-70B | TG | 95 | 100 | 12.7 | |
|
| 43 |
+
| Llama-3.1-70B | TG (DP=4) | | | 14.8 | 189 |
|
| 44 |
+
| Llama-3.2-90B | T3K | 96 | 100 | 6 | 5535 |
|
| 45 |
+
| Qwen2.5-7B | N300 | 84 | 96 | 24.6 | 92 |
|
| 46 |
+
| Qwen2.5-72B | T3K | 99 | 100 | 15.2 | 225 |
|
| 47 |
+
| Qwen2.5-32B | T3K | 98 | 99 | 22.4 | 190 |
|
| 48 |
+
| Qwen2.5-72B | P150x8 | 99 | 100 | | |
|
| 49 |
+
| Qwen2.5-32B | P150x8 | 97 | 99 | | |
|
| 50 |
+
| Qwen2.5-Coder-32B | T3K | 96 | 99 | 22.4 | 190 |
|
| 51 |
+
| Qwen3-32B | T3K | 89 | 97 | 22.9 | 123 |
|
| 52 |
+
| QwQ-32B | T3K | 96 | 100 | 20.7 | 105 |
|
| 53 |
+
| Phi3.5-mini | N150 | | | 43.2 | 98 |
|
| 54 |
+
| Phi3.5-mini | N300 | | | 57.8 | 62 |
|
| 55 |
+
| Phi3.5-mini | T3K | | | 48.8 | 51 |
|
| 56 |
+
| Mistral-7B | N150 | 95 | 99 | 29.75 | 100.24 |
|
| 57 |
+
| Mistral-7B | N300 | 95 | 100 | 47.01 | 65.95 |
|
| 58 |
+
| Mistral-7B | T3K | 95 | 100 | 67.82 | 53.93 |
|
| 59 |
+
| Mistral-Small-3.1-24B | T3K | 95 | 99 | | |
|
| 60 |
+
| Phi-3-mini-128k-instruct | N150 | 89 | 99 | 45.0 | 73.32 |
|
| 61 |
+
| Phi-3-mini-128k-instruct | N300 | 89 | 99 | 60.87 | 114.94 |
|
| 62 |
+
| Phi-4 | N300 | 97 | 100 | 37.34 | 123.33 |
|
| 63 |
+
| Mixtral-8x7B-v0.1 | T3K | 98 | 100 | 67.82 | 53.93 |
|
| 64 |
+
| Ministral-8B | N300 | 93 | 98 | 22.15 | 79.3 |
|
| 65 |
+
|
| 66 |
+
## Accuracy
|
| 67 |
+
|
| 68 |
+
This configuration uses bfp8 MLP and BF16 attention weights (70B+ models use bfp8 attention and bfp4 MLP).
|
| 69 |
+
Llama 3 models test as insensitive to attention precision and so we use bfp8 attention and kv-cache for them even in accuracy mode.
|
| 70 |
+
|
| 71 |
+
| Model | Device | Top-1 (%) | Top-5 (%) | Speed (t/s/u) | TTFT (ms) |
|
| 72 |
+
|-------------------|-------------|-----------|-----------|---------------|-----------|
|
| 73 |
+
| Llama-3.2-1B | N150 | 87 | 99 | 84.7 | 29 |
|
| 74 |
+
| Llama-3.2-1B | N300 | 87 | 98 | 102.8 | 21 |
|
| 75 |
+
| Llama-3.2-1B | T3K | 88 | 99 | 120.5 | 28 |
|
| 76 |
+
| Llama-3.2-1B | TG | 85 | 98 | 48.4 | |
|
| 77 |
+
| Llama-3.2-3B | N150 | 96 | 100 | 47.6 | 63 |
|
| 78 |
+
| Llama-3.2-3B | N300 | 96 | 100 | 63.5 | 41 |
|
| 79 |
+
| Llama-3.2-3B | T3K | 96 | 100 | 67.9 | 69 |
|
| 80 |
+
| Llama-3.2-3B | TG | 92 | 99 | 33.6 | |
|
| 81 |
+
| Llama-3.1-8B | N150 | 96 | 100 | 25.2 | 138 |
|
| 82 |
+
| Llama-3.1-8B | N300 | 96 | 100 | 38.8 | 79 |
|
| 83 |
+
| Llama-3.1-8B | T3K | 97 | 100 | 60.8 | 81 |
|
| 84 |
+
| Llama-3.1-8B | TG | 95 | 100 | 29.5 | |
|
| 85 |
+
| Llama-3.2-11B | N150 | 95 | 100 | 56.7 | 62 |
|
| 86 |
+
| Llama-3.2-11B | N300 | 95 | 100 | 38.3 | 78 |
|
| 87 |
+
| Llama-3.2-11B | T3K | 96 | 100 | 61.4 | 53 |
|
| 88 |
+
| Llama-3.2-11B | TG | 94 | 100 | 29.5 | |
|
| 89 |
+
| Llama-3.1-70B | T3K | 96 | 100 | 16.5 | 168 |
|
| 90 |
+
| Llama-3.1-70B | TG | 95 | 100 | 12.7 | |
|
| 91 |
+
| Llama-3.2-90B | T3K | 96 | 100 | 6 | 5600 |
|
| 92 |
+
| Qwen2.5-7B | N300 | 84 | 96 | 24.6 | 92 |
|
| 93 |
+
| Qwen2.5-72B | T3K | 99 | 100 | 15.1 | 216 |
|
| 94 |
+
| Qwen2.5-32B | T3K | 95 | 99 | 19.7 | 183 |
|
| 95 |
+
| Qwen2.5-72B | P150x8 | 99 | 100 | | |
|
| 96 |
+
| Qwen2.5-32B | P150x8 | 97 | 99 | | |
|
| 97 |
+
| Qwen2.5-Coder-32B | T3K | 95 | 99 | 19.7 | 183 |
|
| 98 |
+
| Qwen3-32B | T3K | 95 | 100 | 19.6 | 119 |
|
| 99 |
+
| QwQ-32B | T3K | 99 | 100 | 18.3 | 120 |
|
| 100 |
+
| Phi3.5-mini | N150 | | | 38.8 | 92 |
|
| 101 |
+
| Phi3.5-mini | N300 | | | 53.9 | 63 |
|
| 102 |
+
| Phi3.5-mini | T3K | | | 48.6 | 53 |
|
| 103 |
+
| Mistral-7B | N150 | 96 | 100 | 29.75 | 100.24 |
|
| 104 |
+
| Mistral-7B | N300 | 97 | 100 | 47.01 | 65.95 |
|
| 105 |
+
| Mistral-7B | T3K | 98 | 100 | 67.82 | 53.93 |
|
| 106 |
+
| Mistral-Small-3.1-24B | T3K | 95 | 99 | | |
|
| 107 |
+
| Phi-3-mini-128k-instruct | N150 | 94 | 99 | 40.41 | 82.58 |
|
| 108 |
+
| Phi-3-mini-128k-instruct | N300 | 94 | 99 | 57.0 | 115.36 |
|
| 109 |
+
| Phi-4 | N300 | 99 | 100 | 20.48 | 146.32 |
|
| 110 |
+
| Mixtral-8x7B-v0.1 | T3K | 95 | 100 | 67.82 | 53.93 |
|
| 111 |
+
| Ministral-8B | N300 | 97 | 100 | 19.95 | 93.22 |
|
| 112 |
+
|
| 113 |
+
## Long-context (64K Tokens)
|
| 114 |
+
|
| 115 |
+
This configuration uses bfp4 MLP FF1+FF3 for all models. **Batch_size=1 and prefill_length is 64k tokens.**
|
| 116 |
+
|
| 117 |
+
| Model | Device | Speed (t/s/u) | TTFT (ms) |
|
| 118 |
+
|----------------|--------|---------------|-----------|
|
| 119 |
+
| Llama-3.2-1B | N150 | 53.0 | 20066 |
|
| 120 |
+
| Llama-3.2-1B | N300 | 65.2 | 10949 |
|
| 121 |
+
| Llama-3.2-1B | T3K | 73.7 | 5271 |
|
| 122 |
+
| Llama-3.2-1B | TG | | |
|
| 123 |
+
| Llama-3.2-3B | N150 | 25.3 | 46743 |
|
| 124 |
+
| Llama-3.2-3B | N300 | 34.8 | 22921 |
|
| 125 |
+
| Llama-3.2-3B | T3K | 41.0 | 10677 |
|
| 126 |
+
| Llama-3.2-3B | TG | | |
|
| 127 |
+
| Llama-3.1-8B | N150 | 16.9 | 64385 |
|
| 128 |
+
| Llama-3.1-8B | N300 | 26.1 | 36229 |
|
| 129 |
+
| Llama-3.1-8B | T3K | 38.1 | 16165 |
|
| 130 |
+
| Llama-3.1-8B | TG | | |
|
| 131 |
+
| Llama-3.2-11B | N300 | 26.1 | 36247 |
|
| 132 |
+
| Llama-3.2-11B | T3K | 38.4 | 16167 |
|
| 133 |
+
| Llama-3.2-11B | TG | | |
|
| 134 |
+
| Llama-3.1-70B | T3K | 11.9 | 74363 |
|
| 135 |
+
| Llama-3.1-70B | TG | | |
|
| 136 |
+
| Qwen2.5-7B | N300 | | |
|
| 137 |
+
| Qwen2.5-72B | T3K | | |
|
| 138 |
+
|
| 139 |
+
## Long-context (32K Tokens)
|
| 140 |
+
|
| 141 |
+
This configuration uses bfp4 MLP FF1+FF3 for all models. **Batch_size=1 and prefill_length is 32k tokens.**
|
| 142 |
+
|
| 143 |
+
| Model | Device | Speed (t/s/u) | TTFT (ms) |
|
| 144 |
+
|---------------------------|--------|---------------|-----------|
|
| 145 |
+
| Phi-3-mini-128k-instruct | N300 | 26.1 | 10072 |
|
| 146 |
+
|
| 147 |
+
## Short-Context, Batch-32
|
| 148 |
+
|
| 149 |
+
This configuration uses bfp4 MLP FF1+FF3 for all models. **Batch_size=32 and prefill_length is 128 tokens.**
|
| 150 |
+
|
| 151 |
+
| Model | Device | Speed (t/s/u) | avg TTFT (ms) |
|
| 152 |
+
|----------------|--------|---------------|---------------|
|
| 153 |
+
| Llama-3.2-1B | N150 | 54.7 | 38 |
|
| 154 |
+
| Llama-3.2-1B | N300 | 64.2 | 34 |
|
| 155 |
+
| Llama-3.2-1B | T3K | 69.9 | 42 |
|
| 156 |
+
| Llama-3.2-1B | TG | | |
|
| 157 |
+
| Llama-3.2-3B | N150 | 36.5 | 69 |
|
| 158 |
+
| Llama-3.2-3B | N300 | 45.8 | 51 |
|
| 159 |
+
| Llama-3.2-3B | T3K | 47.8 | 63 |
|
| 160 |
+
| Llama-3.2-3B | TG | | |
|
| 161 |
+
| Llama-3.1-8B | N150 | 22.3 | 119 |
|
| 162 |
+
| Llama-3.1-8B | N300 | 33.5 | 80 |
|
| 163 |
+
| Llama-3.1-8B | T3K | 45.6 | 64 |
|
| 164 |
+
| Llama-3.1-8B | TG | | |
|
| 165 |
+
| Llama-3.2-11B | N300 | 33.4 | 79 |
|
| 166 |
+
| Llama-3.2-11B | T3K | 45.1 | 64 |
|
| 167 |
+
| Llama-3.2-11B | TG | | |
|
| 168 |
+
| Llama-3.1-70B | T3K | 14.8 | 192 |
|
| 169 |
+
| Llama-3.1-70B | TG | | |
|
| 170 |
+
| Qwen2.5-7B | N300 | | |
|
| 171 |
+
| Qwen2.5-72B | T3K | | |
|
| 172 |
+
| Phi-3-mini-128k-instruct | 150 | 25.66 | 68.58 |
|
| 173 |
+
| Phi-3-mini-128k-instruct | N300 | 39.4 | 85.99 |
|
| 174 |
+
|
| 175 |
+
# Llama 3 model precision and math fidelity
|
| 176 |
+
|
| 177 |
+
## precision_cfg = {ff1_3: bfp4, ff2: bfp4, wqkv: bfp8, wo: bfp8, kv_cache: bfp8, activation: mixed}, fidelity_cfg = {li_ff1_3: lofi, li_ff2: lofi, li_qkv_decode: hifi2, li_o_decode: hifi2, sdpa_decode: hifi2na, li_qkv_prefill: hifi2, li_o_prefill: hifi2fp16, sdpa_prefill: hifi4}
|
| 178 |
+
|
| 179 |
+
| Model | Device | Top-1 (%) | Top-5 (%) | Speed (t/s/u) | TTFT (ms) |
|
| 180 |
+
|----------------|--------|-----------|-----------|---------------|-----------|
|
| 181 |
+
| Llama-3.2-1B | N300 | 85 | 98 | 100.3 | 69 |
|
| 182 |
+
|
| 183 |
+
## precision_cfg = {ff1_3: bfp4, ff2: bfp8, wqkv: bfp8, wo: bfp8, kv_cache: bfp8, activation: mixed}, fidelity_cfg = {li_ff1_3: lofi, li_ff2: hifi2, li_qkv_decode: hifi2, li_o_decode: hifi2, sdpa_decode: hifi2na, li_qkv_prefill: hifi2, li_o_prefill: hifi2fp16, sdpa_prefill: hifi4}
|
| 184 |
+
|
| 185 |
+
| Model | Device | Top-1 (%) | Top-5 (%) | Speed (t/s/u) | TTFT (ms) |
|
| 186 |
+
|----------------|--------|-----------|-----------|---------------|-----------|
|
| 187 |
+
| Llama-3.2-1B | N300 | 88 | 98 | 100.3 | 55 |
|
| 188 |
+
|
| 189 |
+
## precision_cfg = {ff1_3: bfp4, ff2: bf16, wqkv: bfp8, wo: bfp8, kv_cache: bfp8, activation: mixed}, fidelity_cfg = {li_ff1_3: lofi, li_ff2: hifi4, li_qkv_decode: hifi2, li_o_decode: hifi2, sdpa_decode: hifi2na, li_qkv_prefill: hifi2, li_o_prefill: hifi2fp16, sdpa_prefill: hifi4}
|
| 190 |
+
|
| 191 |
+
| Model | Device | Top-1 (%) | Top-5 (%) | Speed (t/s/u) | TTFT (ms) |
|
| 192 |
+
|----------------|--------|-----------|-----------|---------------|-----------|
|
| 193 |
+
| Llama-3.2-1B | N300 | 87 | 98 | 96.8 | 51 |
|
| 194 |
+
|
| 195 |
+
## precision_cfg = {ff1_3: bfp8, ff2: bfp4, wqkv: bfp8, wo: bfp8, kv_cache: bfp8, activation: mixed}, fidelity_cfg = {li_ff1_3: hifi2, li_ff2: lofi, li_qkv_decode: hifi2, li_o_decode: hifi2, sdpa_decode: hifi2na, li_qkv_prefill: hifi2, li_o_prefill: hifi2fp16, sdpa_prefill: hifi4}
|
| 196 |
+
|
| 197 |
+
| Model | Device | Top-1 (%) | Top-5 (%) | Speed (t/s/u) | TTFT (ms) |
|
| 198 |
+
|----------------|--------|-----------|-----------|---------------|-----------|
|
| 199 |
+
| Llama-3.2-1B | N300 | 87 | 98 | 98.5 | 50 |
|
| 200 |
+
|
| 201 |
+
## precision_cfg = {ff1_3: bfp8, ff2: bfp8, wqkv: bfp8, wo: bfp8, kv_cache: bfp8, activation: mixed}, fidelity_cfg = {li_ff1_3: hifi2, li_ff2: hifi2, li_qkv_decode: hifi2, li_o_decode: hifi2, sdpa_decode: hifi2na, li_qkv_prefill: hifi2, li_o_prefill: hifi2fp16, sdpa_prefill: hifi4}
|
| 202 |
+
|
| 203 |
+
| Model | Device | Top-1 (%) | Top-5 (%) | Speed (t/s/u) | TTFT (ms) |
|
| 204 |
+
|----------------|--------|-----------|-----------|---------------|-----------|
|
| 205 |
+
| Llama-3.2-1B | N300 | 91 | 98 | 99.0 | 60 |
|
| 206 |
+
|
| 207 |
+
## precision_cfg = {ff1_3: bfp8, ff2: bf16, wqkv: bfp8, wo: bfp8, kv_cache: bfp8, activation: mixed}, fidelity_cfg = {li_ff1_3: hifi2, li_ff2: hifi4, li_qkv_decode: hifi2, li_o_decode: hifi2, sdpa_decode: hifi2na, li_qkv_prefill: hifi2, li_o_prefill: hifi2fp16, sdpa_prefill: hifi4}
|
| 208 |
+
|
| 209 |
+
| Model | Device | Top-1 (%) | Top-5 (%) | Speed (t/s/u) | TTFT (ms) |
|
| 210 |
+
|----------------|--------|-----------|-----------|---------------|-----------|
|
| 211 |
+
| Llama-3.2-1B | N300 | 89 | 99 | 95.2 | 49 |
|
| 212 |
+
|
| 213 |
+
## precision_cfg = {ff1_3: bf16, ff2: bfp4, wqkv: bfp8, wo: bfp8, kv_cache: bfp8, activation: mixed}, fidelity_cfg = {li_ff1_3: hifi4, li_ff2: lofi, li_qkv_decode: hifi2, li_o_decode: hifi2, sdpa_decode: hifi2na, li_qkv_prefill: hifi2, li_o_prefill: hifi2fp16, sdpa_prefill: hifi4}
|
| 214 |
+
|
| 215 |
+
| Model | Device | Top-1 (%) | Top-5 (%) | Speed (t/s/u) | TTFT (ms) |
|
| 216 |
+
|----------------|--------|-----------|-----------|---------------|-----------|
|
| 217 |
+
| Llama-3.2-1B | N300 | 89 | 98 | 95.2 | 53 |
|
| 218 |
+
|
| 219 |
+
## precision_cfg = {ff1_3: bf16, ff2: bfp8, wqkv: bfp8, wo: bfp8, kv_cache: bfp8, activation: mixed}, fidelity_cfg = {li_ff1_3: hifi4, li_ff2: hifi2, li_qkv_decode: hifi2, li_o_decode: hifi2, sdpa_decode: hifi2na, li_qkv_prefill: hifi2, li_o_prefill: hifi2fp16, sdpa_prefill: hifi4}
|
| 220 |
+
|
| 221 |
+
| Model | Device | Top-1 (%) | Top-5 (%) | Speed (t/s/u) | TTFT (ms) |
|
| 222 |
+
|----------------|--------|-----------|-----------|---------------|-----------|
|
| 223 |
+
| Llama-3.2-1B | N300 | 91 | 98 | 94.4 | 57 |
|
| 224 |
+
|
| 225 |
+
## precision_cfg = {ff1_3: bf16, ff2: bf16, wqkv: bfp8, wo: bfp8, kv_cache: bfp8, activation: mixed}, fidelity_cfg = {li_ff1_3: hifi4, li_ff2: hifi4, li_qkv_decode: hifi2, li_o_decode: hifi2, sdpa_decode: hifi2na, li_qkv_prefill: hifi2, li_o_prefill: hifi2fp16, sdpa_prefill: hifi4}
|
| 226 |
+
|
| 227 |
+
| Model | Device | Top-1 (%) | Top-5 (%) | Speed (t/s/u) | TTFT (ms) |
|
| 228 |
+
|----------------|--------|-----------|-----------|---------------|-----------|
|
| 229 |
+
| Llama-3.2-1B | N300 | 90 | 98 | 91.2 | 60 |
|
| 230 |
+
|
| 231 |
+
## precision_cfg = {ff1_3: bfp8, ff2: bfp8, wqkv: bfp8, wo: bfp4, kv_cache: bfp8, activation: bf16}, fidelity_cfg = {li_ff1_3: hifi2, li_ff2: hifi2, li_qkv_decode: hifi2, li_o_decode: lofi, sdpa_decode: hifi2na, li_qkv_prefill: hifi2, li_o_prefill: lofi, sdpa_prefill: hifi4}
|
| 232 |
+
|
| 233 |
+
| Model | Device | Top-1 (%) | Top-5 (%) | Speed (t/s/u) | TTFT (ms) |
|
| 234 |
+
|----------------|--------|-----------|-----------|---------------|-----------|
|
| 235 |
+
| Llama-3.2-1B | N300 | 88 | 98 | 98.2 | 45 |
|
| 236 |
+
|
| 237 |
+
## precision_cfg = {ff1_3: bfp8, ff2: bfp8, wqkv: bfp8, wo: bfp4, kv_cache: bfp8, activation: bfp8}, fidelity_cfg = {li_ff1_3: hifi2, li_ff2: hifi2, li_qkv_decode: hifi2, li_o_decode: lofi, sdpa_decode: hifi2na, li_qkv_prefill: hifi2, li_o_prefill: lofi, sdpa_prefill: hifi4}
|
| 238 |
+
|
| 239 |
+
| Model | Device | Top-1 (%) | Top-5 (%) | Speed (t/s/u) | TTFT (ms) |
|
| 240 |
+
|----------------|--------|-----------|-----------|---------------|-----------|
|
| 241 |
+
| Llama-3.2-1B | N300 | 90 | 98 | 101.0 | 57 |
|
| 242 |
+
|
| 243 |
+
## precision_cfg = {ff1_3: bfp8, ff2: bfp8, wqkv: bfp8, wo: bfp4, kv_cache: bfp8, activation: mixed}, fidelity_cfg = {li_ff1_3: hifi2, li_ff2: hifi2, li_qkv_decode: hifi2, li_o_decode: lofi, sdpa_decode: hifi2na, li_qkv_prefill: hifi2, li_o_prefill: lofi, sdpa_prefill: hifi4}
|
| 244 |
+
|
| 245 |
+
| Model | Device | Top-1 (%) | Top-5 (%) | Speed (t/s/u) | TTFT (ms) |
|
| 246 |
+
|----------------|--------|-----------|-----------|---------------|-----------|
|
| 247 |
+
| Llama-3.2-1B | N300 | 90 | 98 | 99.4 | 73 |
|
code/models/tt_transformers/README.md
ADDED
|
@@ -0,0 +1,388 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# TT-Transformers
|
| 2 |
+
|
| 3 |
+
This code can run large language models such as the Llama3 family, Qwen2.5, Mistral, DeepSeek-R1-Distill variants and similar. Tensor-parallelism automatically distributes workloads across all available chips.
|
| 4 |
+
|
| 5 |
+
The current version is verified to work with the following models:
|
| 6 |
+
| Model | Hardware | <org/model> |
|
| 7 |
+
|--------------------------------------------------------------------------------------------------|-----------------------------|-------------------------------------------------|
|
| 8 |
+
| [DeepSeek R1 Distill Llama 70B](https://huggingface.co/deepseek-ai/DeepSeek-R1-Distill-Llama-70B)| LoudBox / QuietBox / Galaxy | ```deepseek-ai/DeepSeek-R1-Distill-Llama-70B``` |
|
| 9 |
+
| [Llama 3.1 8B](https://huggingface.co/meta-llama/Llama-3.1-8B) | n150 / p100 / p150 | ```meta-llama/Llama-3.1-8B``` |
|
| 10 |
+
| [Llama 3.1 70B](https://huggingface.co/meta-llama/Llama-3.1-70B) | LoudBox / QuietBox / Galaxy | ```meta-llama/Llama-3.1-70B``` |
|
| 11 |
+
| [Llama 3.2 1B](https://huggingface.co/meta-llama/Llama-3.2-1B) | n150 | ```meta-llama/Llama-3.2-1B``` |
|
| 12 |
+
| [Llama 3.2 3B](https://huggingface.co/meta-llama/Llama-3.2-3B) | n150 | ```meta-llama/Llama-3.2-3B``` |
|
| 13 |
+
| [Llama 3.2 11B Vision](https://huggingface.co/meta-llama/Llama-3.2-11B-Vision) | n300 | ```meta-llama/Llama-3.2-11B-Vision``` |
|
| 14 |
+
| [Llama 3.2 90B Vision](https://huggingface.co/meta-llama/Llama-3.2-90B-Vision) | LoudBox / QuietBox | ```meta-llama/Llama-3.2-90B-Vision``` |
|
| 15 |
+
| [Mistral 7B Instruct v0.3](https://huggingface.co/mistralai/Mistral-7B-Instruct-v0.3) | n150 | ```mistralai/Mistral-7B-Instruct-v0.3``` |
|
| 16 |
+
| [Mistral Small 3.1 24B Instruct](https://huggingface.co/mistralai/Mistral-Small-3.1-24B-Instruct-2503) | T3K | ```mistralai/Mistral-Small-3.1-24B-Instruct-2503``` |
|
| 17 |
+
| [Mixtral 8x7B Instruct v0.1](https://huggingface.co/mistralai/Mixtral-8x7B-Instruct-v0.1) | LoudBox / QuietBox | ```mistralai/Mixtral-8x7B-Instruct-v0.1``` |
|
| 18 |
+
| [Qwen 2.5 7B](https://huggingface.co/Qwen/Qwen2.5-7B) | n300 | ```Qwen/Qwen2.5-7B``` |
|
| 19 |
+
| [Qwen 2.5 Coder 32B](https://huggingface.co/Qwen/Qwen2.5-Coder-32B) | LoudBox / QuietBox | ```Qwen/Qwen2.5-Coder-32B``` |
|
| 20 |
+
| [Qwen 2.5 72B](https://huggingface.co/Qwen/Qwen2.5-72B) | LoudBox / QuietBox | ```Qwen/Qwen2.5-72B``` |
|
| 21 |
+
| [Qwen 3 32B](https://huggingface.co/Qwen/Qwen3-32B) | LoudBox / QuietBox | ```Qwen/Qwen3-32B``` |
|
| 22 |
+
| [Phi-3-mini-128k-instruct](https://huggingface.co/microsoft/Phi-3-mini-128k-instruct) | n150 / n300 | ```microsoft/Phi-3-mini-128k-instruct``` |
|
| 23 |
+
|
| 24 |
+
<details>
|
| 25 |
+
<summary> Explore an extended list of compatible models (experimental) </summary>
|
| 26 |
+
|
| 27 |
+
| Model | Hardware | <org/model>. |
|
| 28 |
+
|---------------------------------------------------------------------------------------------------------------------------|----------|-------------------------------------------------------------|
|
| 29 |
+
| [Bellatrix-Tiny-0.5B](https://huggingface.co/prithivMLmods/Bellatrix-Tiny-0.5B) | N150 | `prithivMLmods/Bellatrix-Tiny-0.5B` |
|
| 30 |
+
| [Bellatrix-Tiny-1B](https://huggingface.co/prithivMLmods/Bellatrix-Tiny-1B) | N150 | `prithivMLmods/Bellatrix-Tiny-1B` |
|
| 31 |
+
| [Bellatrix-Tiny-1B-R1](https://huggingface.co/prithivMLmods/Bellatrix-Tiny-1B-R1) | N150 | `prithivMLmods/Bellatrix-Tiny-1B-R1` |
|
| 32 |
+
| [deepseek-coder-6.7b-instruct](https://huggingface.co/deepseek-ai/deepseek-coder-6.7b-instruct) | N300 | `deepseek-ai/deepseek-coder-6.7b-instruct` |
|
| 33 |
+
| [deepseek-llm-7b-base](https://huggingface.co/deepseek-ai/deepseek-llm-7b-base) | N300 | `deepseek-ai/deepseek-llm-7b-base` |
|
| 34 |
+
| [deepseek-llm-7b-chat](https://huggingface.co/deepseek-ai/deepseek-llm-7b-chat) | N300 | `deepseek-ai/deepseek-llm-7b-chat` |
|
| 35 |
+
| [DeepSeek-R1-Distill-Llama-8B](https://huggingface.co/deepseek-ai/DeepSeek-R1-Distill-Llama-8B) | N300 | `deepseek-ai/DeepSeek-R1-Distill-Llama-8B` |
|
| 36 |
+
| [DeepSeek-R1-Distill-Llama-8B](https://huggingface.co/unsloth/DeepSeek-R1-Distill-Llama-8B) | N300 | `unsloth/DeepSeek-R1-Distill-Llama-8B` |
|
| 37 |
+
| [DeepSeek-R1-Distill-Llama-8B-abliterated](https://huggingface.co/huihui-ai/DeepSeek-R1-Distill-Llama-8B-abliterated) | N300 | `huihui-ai/DeepSeek-R1-Distill-Llama-8B-abliterated` |
|
| 38 |
+
| [DeepSeek-R1-Distill-Qwen-1.5B](https://huggingface.co/deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B) | N150 | `deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B` |
|
| 39 |
+
| [DeepSeek-R1-Distill-Qwen-32B](https://huggingface.co/deepseek-ai/DeepSeek-R1-Distill-Qwen-32B) | T3K | `deepseek-ai/DeepSeek-R1-Distill-Qwen-32B` |
|
| 40 |
+
| [DeepSeek-R1-Distill-Qwen-32B-Japanese](https://huggingface.co/cyberagent/DeepSeek-R1-Distill-Qwen-32B-Japanese) | T3K | `cyberagent/DeepSeek-R1-Distill-Qwen-32B-Japanese` |
|
| 41 |
+
| [DeepSeek-R1-Distill-Qwen-32B-abliterated](https://huggingface.co/huihui-ai/DeepSeek-R1-Distill-Qwen-32B-abliterated) | T3K | `huihui-ai/DeepSeek-R1-Distill-Qwen-32B-abliterated` |
|
| 42 |
+
| [DeepSeek-R1-Distill-Qwen-7B](https://huggingface.co/deepseek-ai/DeepSeek-R1-Distill-Qwen-7B) | N300 | `deepseek-ai/DeepSeek-R1-Distill-Qwen-7B` |
|
| 43 |
+
| [DeepSeek-R1-Distill-Qwen-7B-abliterated-v2](https://huggingface.co/huihui-ai/DeepSeek-R1-Distill-Qwen-7B-abliterated-v2) | N300 | `huihui-ai/DeepSeek-R1-Distill-Qwen-7B-abliterated-v2` |
|
| 44 |
+
| [DeepSeek-R1-Distill-Qwen-7B-Japanese](https://huggingface.co/lightblue/DeepSeek-R1-Distill-Qwen-7B-Japanese) | N300 | `lightblue/DeepSeek-R1-Distill-Qwen-7B-Japanese` |
|
| 45 |
+
| [Dobby-Mini-Leashed-Llama-3.1-8B](https://huggingface.co/SentientAGI/Dobby-Mini-Leashed-Llama-3.1-8B) | N300 | `SentientAGI/Dobby-Mini-Leashed-Llama-3.1-8B` |
|
| 46 |
+
| [Dobby-Mini-Unhinged-Llama-3.1-8B](https://huggingface.co/SentientAGI/Dobby-Mini-Unhinged-Llama-3.1-8B) | N300 | `SentientAGI/Dobby-Mini-Unhinged-Llama-3.1-8B` |
|
| 47 |
+
| [Dolphin3.0-Mistral-24B](https://huggingface.co/cognitivecomputations/Dolphin3.0-Mistral-24B) | T3K | `cognitivecomputations/Dolphin3.0-Mistral-24B` |
|
| 48 |
+
| [Dolphin3.0-R1-Mistral-24B](https://huggingface.co/cognitivecomputations/Dolphin3.0-R1-Mistral-24B) | T3K | `cognitivecomputations/Dolphin3.0-R1-Mistral-24B` |
|
| 49 |
+
| [EuroLLM-9B-Instruct](https://huggingface.co/utter-project/EuroLLM-9B-Instruct) | N300 | `utter-project/EuroLLM-9B-Instruct` |
|
| 50 |
+
| [GPT4chan-24B](https://huggingface.co/v2ray/GPT4chan-24B) | T3K | `v2ray/GPT4chan-24B` |
|
| 51 |
+
| [Llama-2-7b-chat-hf](https://huggingface.co/meta-llama/Llama-2-7b-hf) | N300 | `meta-llama/Llama-2-7b-hf` |
|
| 52 |
+
| [Llama-2-7b-hf](https://huggingface.co/meta-llama/Llama-2-7b-hf) | N300 | `meta-llama/Llama-2-7b-hf` |
|
| 53 |
+
| [Llama-3.1-8B-Instruct](https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct) | N300 | `meta-llama/Llama-3.1-8B-Instruct` |
|
| 54 |
+
| [Llama-3.2-1B-Instruct](https://huggingface.co/meta-llama/Llama-3.2-1B-Instruct) | N150 | `meta-llama/Llama-3.2-1B-Instruct` |
|
| 55 |
+
| [Llama-3.2-3B-Instruct](https://huggingface.co/meta-llama/Llama-3.2-3B-Instruct) | N150 | `meta-llama/Llama-3.2-3B-Instruct` |
|
| 56 |
+
| [Llama-3.2-6B-AlgoCode](https://huggingface.co/prithivMLmods/Llama-3.2-6B-AlgoCode) | N150 | `prithivMLmods/Llama-3.2-6B-AlgoCode` |
|
| 57 |
+
| [Llama-Krikri-8B-Base](https://huggingface.co/ilsp/Llama-Krikri-8B-Base) | N150 | `ilsp/Llama-Krikri-8B-Base` |
|
| 58 |
+
| [Llama-Krikri-8B-Instruct](https://huggingface.co/ilsp/Llama-Krikri-8B-Instruct) | N300 | `ilsp/Llama-Krikri-8B-Instruct` |
|
| 59 |
+
| [LwQ-10B-Instruct](https://huggingface.co/prithivMLmods/LwQ-10B-Instruct) | N300 | `prithivMLmods/LwQ-10B-Instruct` |
|
| 60 |
+
| [Magnum-v4-Cydonia-vXXX-22B](https://huggingface.co/Kaoeiri/Magnum-v4-Cydonia-vXXX-22B) | T3K | `Kaoeiri/Magnum-v4-Cydonia-vXXX-22B` |
|
| 61 |
+
| [Megatron-Opus-7B-Exp](https://huggingface.co/prithivMLmods/Megatron-Opus-7B-Exp) | N300 | `prithivMLmods/Megatron-Opus-7B-Exp` |
|
| 62 |
+
| [Meta-Llama-3-8B](https://huggingface.co/meta-llama/Meta-Llama-3-8B) | N300 | `meta-llama/Meta-Llama-3-8B` |
|
| 63 |
+
| [Meta-Llama-3-8B-Instruct](https://huggingface.co/meta-llama/Meta-Llama-3-8B-Instruct) | N300 | `meta-llama/Meta-Llama-3-8B-Instruct` |
|
| 64 |
+
| [Mistral-7B-Instruct-v0.1](https://huggingface.co/mistralai/Mistral-7B-Instruct-v0.1) | N150 | `mistralai/Mistral-7B-Instruct-v0.1` |
|
| 65 |
+
| [Mistral-7B-Instruct-v0.2](https://huggingface.co/mistralai/Mistral-7B-Instruct-v0.2) | N150 | `mistralai/Mistral-7B-Instruct-v0.2` |
|
| 66 |
+
| [Mistral-7B-v0.1](https://huggingface.co/mistralai/Mistral-7B-v0.1) | N150 | `mistralai/Mistral-7B-v0.1` |
|
| 67 |
+
| [Mistral-Small-24B-Base-2501](https://huggingface.co/mistralai/Mistral-Small-24B-Base-2501) | T3K | `mistralai/Mistral-Small-24B-Base-2501` |
|
| 68 |
+
| [Mistral-Small-24B-Instruct-2501](https://huggingface.co/mistralai/Mistral-Small-24B-Instruct-2501) | T3K | `mistralai/Mistral-Small-24B-Instruct-2501` |
|
| 69 |
+
| [Mistral-Small-3.1-24B-Instruct-2503](https://huggingface.co/mistralai/Mistral-Small-3.1-24B-Instruct-2503) | T3K | `mistralai/Mistral-Small-3.1-24B-Instruct-2503` |
|
| 70 |
+
| [NuminaMath-7B-TIR](https://huggingface.co/AI-MO/NuminaMath-7B-TIR) | N300 | `AI-MO/NuminaMath-7B-TIR` |
|
| 71 |
+
| [OpenThinker-7B](https://huggingface.co/open-thoughts/OpenThinker-7B) | N300 | `open-thoughts/OpenThinker-7B` |
|
| 72 |
+
| [Primal-Mini-3B-Exp](https://huggingface.co/prithivMLmods/Primal-Mini-3B-Exp) | N150 | `prithivMLmods/Primal-Mini-3B-Exp` |
|
| 73 |
+
| [Qwen2.5-0.5B](https://huggingface.co/Qwen/Qwen2.5-0.5B) | N150 | `Qwen/Qwen2.5-0.5B` |
|
| 74 |
+
| [Qwen2.5-0.5B-Instruct](https://huggingface.co/Qwen/Qwen2.5-0.5B-Instruct) | N150 | `Qwen/Qwen2.5-0.5B-Instruct` |
|
| 75 |
+
| [Qwen2.5-1.5B](https://huggingface.co/Qwen/Qwen2.5-1.5B) | N150 | `Qwen/Qwen2.5-1.5B` |
|
| 76 |
+
| [Qwen2.5-1.5B-Instruct](https://huggingface.co/Qwen/Qwen2.5-1.5B-Instruct) | N150 | `Qwen/Qwen2.5-1.5B-Instruct` |
|
| 77 |
+
| [Qwen2.5-3B-Instruct](https://huggingface.co/Qwen/Qwen2.5-3B-Instruct) | N150 | `Qwen/Qwen2.5-3B-Instruct` |
|
| 78 |
+
| [Qwen2.5-32B](https://huggingface.co/Qwen/Qwen2.5-32B) | T3K | `Qwen/Qwen2.5-32B` |
|
| 79 |
+
| [Qwen2.5-Coder-7B-Instruct](https://huggingface.co/Qwen/Qwen2.5-Coder-7B-Instruct) | N300 | `Qwen/Qwen2.5-Coder-7B-Instruct` |
|
| 80 |
+
| [Qwen2.5-Math-1.5B](https://huggingface.co/Qwen/Qwen2.5-Math-1.5B) | N150 | `Qwen/Qwen2.5-Math-1.5B` |
|
| 81 |
+
| [Qwen2.5-Math-7B](https://huggingface.co/Qwen/Qwen2.5-Math-7B) | N300 | `Qwen/Qwen2.5-Math-7B` |
|
| 82 |
+
| [Reasoning-Distilled-ta-7B](https://huggingface.co/prithivMLmods/Reasoning-Distilled-ta-7B) | N300 | `prithivMLmods/Reasoning-Distilled-ta-7B` |
|
| 83 |
+
| [s1-32B](https://huggingface.co/simplescaling/s1-32B) | T3K | `simplescaling/s1-32B` |
|
| 84 |
+
| [Selene-1-Mini-Llama-3.1-8B](https://huggingface.co/AtlaAI/Selene-1-Mini-Llama-3.1-8B) | N300 | `AtlaAI/Selene-1-Mini-Llama-3.1-8B` |
|
| 85 |
+
| [Sky-T1-32B-Preview](https://huggingface.co/NovaSky-AI/Sky-T1-32B-Preview) | T3K | `NovaSky-AI/Sky-T1-32B-Preview` |
|
| 86 |
+
| [SmallThinker-3B-Preview](https://huggingface.co/PowerInfer/SmallThinker-3B-Preview) | N150 | `PowerInfer/SmallThinker-3B-Preview` |
|
| 87 |
+
| [SmolLM2-1.7B-Instruct](https://huggingface.co/HuggingFaceTB/SmolLM2-1.7B-Instruct) | N150 | `HuggingFaceTB/SmolLM2-1.7B-Instruct` |
|
| 88 |
+
| [Sqweeks-7B-Instruct](https://huggingface.co/prithivMLmods/Sqweeks-7B-Instruct) | N300 | `prithivMLmods/Sqweeks-7B-Instruct` |
|
| 89 |
+
| [TinyLlama-1.1B-Chat-v1.0](https://huggingface.co/TinyLlama/TinyLlama-1.1B-Chat-v1.0) | N150 | `TinyLlama/TinyLlama-1.1B-Chat-v1.0` |
|
| 90 |
+
| [TinySwallow-1.5B](https://huggingface.co/SakanaAI/TinySwallow-1.5B) | N150 | `SakanaAI/TinySwallow-1.5B` |
|
| 91 |
+
| [TinySwallow-1.5B-Instruct](https://huggingface.co/SakanaAI/TinySwallow-1.5B-Instruct) | N150 | `SakanaAI/TinySwallow-1.5B-Instruct` |
|
| 92 |
+
| [Triangulum-v2-10B](https://huggingface.co/prithivMLmods/Triangulum-v2-10B) | N300 | `prithivMLmods/Triangulum-v2-10B` |
|
| 93 |
+
| [WebMind-7B-v0.1](https://huggingface.co/prithivMLmods/WebMind-7B-v0.1) | N300 | `prithivMLmods/WebMind-7B-v0.1` |
|
| 94 |
+
| [WizardLM-7B-Uncensored](https://huggingface.co/cognitivecomputations/WizardLM-7B-Uncensored) | N300 | `cognitivecomputations/WizardLM-7B-Uncensored` |
|
| 95 |
+
| [Xwen-7B-Chat](https://huggingface.co/xwen-team/Xwen-7B-Chat) | N300 | `xwen-team/Xwen-7B-Chat` |
|
| 96 |
+
| [YuE-s1-7B-anneal-en-cot](https://huggingface.co/m-a-p/YuE-s1-7B-anneal-en-cot) | N300 | `m-a-p/YuE-s1-7B-anneal-en-cot` |
|
| 97 |
+
| [YuE-s2-1B-general](https://huggingface.co/m-a-p/YuE-s2-1B-general) | N150 | `m-a-p/YuE-s2-1B-general` |
|
| 98 |
+
|
| 99 |
+
</details>
|
| 100 |
+
|
| 101 |
+
## Prerequisites
|
| 102 |
+
|
| 103 |
+
Install [TT-Metalium and TTNN](../../INSTALLING.md).
|
| 104 |
+
|
| 105 |
+
|
| 106 |
+
## How to Run
|
| 107 |
+
|
| 108 |
+
To configure the weights and run a demo, choose [Automatic Download](#automatic-download) for a quick setup or [Manual Download](#manual-download) for more control over the files.
|
| 109 |
+
|
| 110 |
+
---
|
| 111 |
+
|
| 112 |
+
### Automatic Setup
|
| 113 |
+
|
| 114 |
+
#### Login to HuggingFace using your token
|
| 115 |
+
|
| 116 |
+
Use `huggingface-cli login` or set the token with the command `export HF_TOKEN=<token>`
|
| 117 |
+
- To obtain a HuggingFace token visit: https://huggingface.co/docs/hub/security-tokens
|
| 118 |
+
|
| 119 |
+
#### Choose your Model
|
| 120 |
+
|
| 121 |
+
Set the `HF_MODEL` environment variable to the HuggingFace org/name of the model to be run.
|
| 122 |
+
|
| 123 |
+
This will automatically download the weights into your HuggingFace cache directory and run the model directly.
|
| 124 |
+
|
| 125 |
+
- Check the models chart on the top of the page and substitute the `<org/model>` on the following command:
|
| 126 |
+
```
|
| 127 |
+
export HF_MODEL=<org/name>
|
| 128 |
+
```
|
| 129 |
+
|
| 130 |
+
#### You are all set!
|
| 131 |
+
|
| 132 |
+
- Skip to section: [Run the Demo](#run-the-demo)
|
| 133 |
+
|
| 134 |
+
---
|
| 135 |
+
|
| 136 |
+
### Manual Setup
|
| 137 |
+
|
| 138 |
+
If you wish, you can manually download the weights [from HuggingFace](#download-weights-from-huggingface) as described by the following section:
|
| 139 |
+
|
| 140 |
+
#### Download Weights from HuggingFace
|
| 141 |
+
|
| 142 |
+
Navigate to [HuggingFace](https://huggingface.co) and download the weights of the model you wish to run (check [models chart](#tt-transformers) for compatibility and direct links to HuggingFace models).
|
| 143 |
+
|
| 144 |
+
- Ensure your model directory has the following structure:
|
| 145 |
+
```
|
| 146 |
+
/path_to/org/model/
|
| 147 |
+
config.json
|
| 148 |
+
generation_config.json
|
| 149 |
+
model-00001-of-00062.safetensors
|
| 150 |
+
...
|
| 151 |
+
```
|
| 152 |
+
|
| 153 |
+
- Set `HF_MODEL` to the directory of the downloaded weights:
|
| 154 |
+
```
|
| 155 |
+
export HF_MODEL=<path_to_downloaded_directory>
|
| 156 |
+
```
|
| 157 |
+
|
| 158 |
+
#### You are all set!
|
| 159 |
+
|
| 160 |
+
- Skip to section: [Run the Demo](#run-the-demo)
|
| 161 |
+
|
| 162 |
+
---
|
| 163 |
+
|
| 164 |
+
### Run the Demo
|
| 165 |
+
|
| 166 |
+
- Make sure `HF_MODEL` has been set:
|
| 167 |
+
|
| 168 |
+
`export HF_MODEL=<hf_model_name or hf_downloaded_directory>`
|
| 169 |
+
|
| 170 |
+
- Run the Demo
|
| 171 |
+
|
| 172 |
+
These are some example commands on how to run the demo. For more information about the parameters, check [parameters description.](#parameters-description)
|
| 173 |
+
|
| 174 |
+
```
|
| 175 |
+
# Batch-1
|
| 176 |
+
pytest models/tt_transformers/demo/simple_text_demo.py -k "performance and batch-1"
|
| 177 |
+
|
| 178 |
+
# Batch-32
|
| 179 |
+
pytest models/tt_transformers/demo/simple_text_demo.py -k "performance and batch-32"
|
| 180 |
+
|
| 181 |
+
# Long context with custom parameters
|
| 182 |
+
pytest models/tt_transformers/demo/simple_text_demo.py -k "long-context" --max_seq_len=16384
|
| 183 |
+
|
| 184 |
+
# Long-context
|
| 185 |
+
pytest models/tt_transformers/demo/simple_text_demo.py -k "performance and long"
|
| 186 |
+
```
|
| 187 |
+
|
| 188 |
+
The above examples are run in `ModelOptimizations.performance` mode. You can override this by setting the `optimizations` or the `decoder_config_file` argument in the demo. To use instead the accuracy mode you can call the above tests with `-k "accuracy and ..."` instead of performance.
|
| 189 |
+
|
| 190 |
+
NOTE: trace region sizes are declared in [`models/model_trace_region_sizes.yaml`](../model_trace_region_sizes.yaml) and resolved at device-open time via [`get_supported_trace_region_size`](demo/trace_region_config.py) (which delegates to [`resolve_trace_region_size`](../demos/utils/trace_region_sizes.py)). A `(model, SKU)` pair without a YAML entry is not an error: resolution logs an info message and falls back to `TRACE_REGION_SIZE_DYNAMIC` (`0`, dynamic allocation). Add an explicit entry when a model needs a fixed reserved trace region.
|
| 191 |
+
|
| 192 |
+
## Details
|
| 193 |
+
|
| 194 |
+
### Extra compatibility settings for non-Llama models
|
| 195 |
+
|
| 196 |
+
If you are bringing up a new model that is similar to these but is not listed above, you may also need to set additional environment variables:
|
| 197 |
+
- `MAX_PREFILL_CHUNK_SIZE` - this determines how many thousands of tokens are prefilled in one go. For optimal performance pick 128. Depending on the model dimensions and hardware you're running on, there may not be enough L1 to prefill 128K tokens at once, in which case you can reduce this in powers of 2 down to 4.
|
| 198 |
+
- `PAD_MLP_CORES` - models with a hidden_dim that is not a nice power of 2 may not have a valid layout or may run with lower performance. You can set this to a multiple of 8 between 8 and 64; `16` and `32` commonly work well if this is required.
|
| 199 |
+
|
| 200 |
+
You should also watch out for:
|
| 201 |
+
- RoPE encoding style. `llama3`, `yarn` and of course `none` are supported. HuggingFace models encode the complex numbers in RoPE as r1, r2, ..., i1, i2, ... whereas Meta models encode the complex numbers as r1, i1, r2, i2, ... - TTT uses a Meta-style implementation of the RoPE op and when loading a HuggingFace it will reshuffle the weights of the pre-rope attention weights to interleave their outputs in this style (see `reverse_permute` in [load_checkpoints.py](tt/load_checkpoints.py)). When _using_ TTT this happens invisibly and should not affect you, but when bringing up a new model or modifying TTT being aware of this will make some otherwise confusing things clearer.
|
| 202 |
+
- Our [accuracy test](demo/simple_text_demo.py -k ci-token-matching) will require you to [generate some reference logits](tests/generate_reference_hf.py) and perhaps update the test to use them.
|
| 203 |
+
- We parallelise attention over the number of heads. If this number is e.g. 14 then you will not be able to run it on more than 2 chips (because 14/2=7, a prime number). We do not support head-padding or similar mitigations at this time but a PR would be cool.
|
| 204 |
+
|
| 205 |
+
Huggingface models specify their architecture in the `config.json` file. The following architectures are known to work:
|
| 206 |
+
|
| 207 |
+
- LlamaForCausalLM
|
| 208 |
+
- Qwen2ForCausalLM
|
| 209 |
+
- Qwen3ForCausalLM
|
| 210 |
+
- MistralForCausalLM
|
| 211 |
+
- Mistral3ForConditionalGeneration
|
| 212 |
+
- Phi3ForCausalLM
|
| 213 |
+
|
| 214 |
+
At the time of writing this covers the majority of popular HuggingFace text-generation models. If you find another architecture that works or extend TT-Transformers to support one we would love to accept a PR!
|
| 215 |
+
|
| 216 |
+
---
|
| 217 |
+
|
| 218 |
+
### Environment Variables Description
|
| 219 |
+
|
| 220 |
+
- `HF_MODEL` is the HuggingFace org/name of the model you want to run or the path to the downloaded Huggingface weights.
|
| 221 |
+
- `TT_CACHE_PATH` is optional. It sets the path for ttnn's weight cache files. See below for more details.
|
| 222 |
+
- `MESH_DEVICE` is optional. It allows you to use fewer devices than are available. See below for more details.
|
| 223 |
+
|
| 224 |
+
On the first execution of each model, TTNN will create weight cache files for that model, to speed up future runs. These cache files only need to be created once for each model and device. These files are stored in one of three places:
|
| 225 |
+
|
| 226 |
+
1. `TT_CACHE_PATH` if you have set it.
|
| 227 |
+
2. `HF_MODEL/device_name` if a path to downloaded weights was specified using `HF_MODEL`.
|
| 228 |
+
3. `model_cache/HF_MODEL/device_name` if a HuggingFace model name was specified using `HF_MODEL`.
|
| 229 |
+
|
| 230 |
+
The device name used is:
|
| 231 |
+
|
| 232 |
+
- `N150` for N150
|
| 233 |
+
- `N300` for N300
|
| 234 |
+
- `T3K` for LoudBox / QuietBox
|
| 235 |
+
- `TG` for Galaxy
|
| 236 |
+
|
| 237 |
+
By default tensor parallelism is used to run the model over all available chips. You can instead run on a smaller mesh either for testing or for performance reasons (for very small models the communication overhead of tensor parallelism may be larger than the performance gained). To use a smaller mesh, set `MESH_DEVICE` to one of the supported devices: `N150`, `N300`, `T3K` or `TG`.
|
| 238 |
+
|
| 239 |
+
Example: `export MESH_DEVICE=N150`, will enable running one a single chip of a multi-chip system.
|
| 240 |
+
|
| 241 |
+
---
|
| 242 |
+
|
| 243 |
+
### Parameters Description
|
| 244 |
+
|
| 245 |
+
The `simple_text_demo.py` script includes the following main modes of operation and is parametrized to support other configurations.
|
| 246 |
+
|
| 247 |
+
- `batch-1`: Runs a small prompt (128 tokens) for a single user
|
| 248 |
+
- `batch-32`: Runs a small prompt (128 tokens) for a a batch of 32 users
|
| 249 |
+
- `long-context`: Runs a large prompt (64k tokens) for a single user
|
| 250 |
+
- `reasoning-1`: Runs a reasoning prompt for a single user (generates up to 15k tokens)
|
| 251 |
+
|
| 252 |
+
If you want to provide your own demo configuration, please take a look at the pytest parametrize calls in `models/tt_transformers/demo/simple_text_demo.py`. For convenience we list all the supported params below:
|
| 253 |
+
|
| 254 |
+
- `input_prompts (string)`: input json file with prompts to process. See `models/tt_transformers/demo/*.json` for a list of input files
|
| 255 |
+
- `instruct (bool)`: Whether to use Llama instruct weights or general weights
|
| 256 |
+
- `repeat_batches (int)`: Number of consecutive batches of users to run (default: 1)
|
| 257 |
+
- `max_seq_len (int)`: Maximum context length supported by the model (refer to the table above)
|
| 258 |
+
- `batch_size (int)`: Number of users in a batch (Supports 1/2/4/8/16/32 batches)
|
| 259 |
+
- `max_generated_tokens (int)`: Maximum number of tokens to generate for each user (Note that the users will stop generation before this limit if they reach a eos token)
|
| 260 |
+
- `paged_attention (bool)`: Whether to use paged attention or default attention (vLLM support (WIP) requires paged attention)
|
| 261 |
+
- `page_params (dict)`: Page parameters for paged attention - [`block_size`, `max_num_blocks`]. For smaller context lengths use `block_size=32` and `max_num_blocks=1024`, for larger context use block_size=64 and max_num_blocks=2048
|
| 262 |
+
- `sampling_params (dict)`: Sampling parameters for decoding -[`temperature`, `top_p`]. If temperature is set to 0, argmax (greedy decode) is used.
|
| 263 |
+
- `stop_at_eos (bool)`: Flag to stop decoding when the model generates an EoS token
|
| 264 |
+
- `optimizations (ModelOptimizations)`: Optimization level to use for the model [`accuracy`, `performance`]. Applied uniformly across all decoders unless an override config exists in `models/tt_transformers/model_params/<model-name>`
|
| 265 |
+
- `decoder_config_file (DecodersPrecision)`: Fine-grained optimization control that allows specifying a configuration file to set different settings for each decoder.
|
| 266 |
+
|
| 267 |
+
Please note that using `argmax` with `batch_size > 1` or using `top-p` sampling with any batch size, these ops will be run on host. This is because those ops are not yet fully supported on device. A decrease in performance is expected when these configurations are enabled.
|
| 268 |
+
|
| 269 |
+
---
|
| 270 |
+
|
| 271 |
+
### Optimization overrides
|
| 272 |
+
Some models require a unique set of optimizations defined in `models/tt_transformers/model_params/<model-name>`. To override the default optimizations, you can define files named `models/tt_transformers/tt/model_config/PERFORMANCE_DECODER_CONFIG_FILENAME` and `models/tt_transformers/tt/model_config/ACCURACY_DECODER_CONFIG_FILENAME` in the appropriate `models/tt_transformers/model_params/<model-name>` directory to override the `ModelOptimizations.performance` and `ModelOptimizations.accuracy` optimizations respectively. For example, to override the default "performance" optimizations for Llama3.1-8B-Instruct, a file named `performance_decoder_config.json` has been created in the `models/tt_transformers/model_params/Llama3.1-8B-Instruct` directory. The content to write in override files is described in [the custom optimizations section](#custom-optimizations). Optimizations are applied with the following prioritization:
|
| 273 |
+
1. from override config (if it exists)
|
| 274 |
+
2. from the `optimizations` argument
|
| 275 |
+
|
| 276 |
+
---
|
| 277 |
+
|
| 278 |
+
### Custom input arguments
|
| 279 |
+
To facilitate testing different configurations, `simple_text_demo.py` supports argument overrides. The full list of overrides is included in `models/tt_transformers/demo/conftest.py`.
|
| 280 |
+
|
| 281 |
+
An example usage where the `batch-1` test is modified to run with 16 users and keep generating tokens until 1024 are generated:
|
| 282 |
+
|
| 283 |
+
```
|
| 284 |
+
pytest models/tt_transformers/demo/simple_text_demo.py -k "performance and batch-1" --batch_size 16 --max_generated_tokens 1024 --stop_at_eos 0
|
| 285 |
+
```
|
| 286 |
+
|
| 287 |
+
---
|
| 288 |
+
|
| 289 |
+
### Custom optimizations
|
| 290 |
+
To apply the same settings across all decoders, the `optimizations` argument can be used. `optimizations` offers a wide range of configurations for precision and math fidelity. The user can override the configurations of the data types of the weight tensors and activation tensors and the math fidelity of the kernels that works on those tensors, using the `--optimizations` argument on the command line. For example:
|
| 291 |
+
|
| 292 |
+
```
|
| 293 |
+
pytest models/tt_transformers/demo/simple_text_demo.py -k "accuracy and batch-1" --optimizations 'precision_cfg = {ff1_3: bfp4, ff2: bfp4, wqkv: bfp8, wo: bfp8, kv_cache: bfp8, activation: mixed}, fidelity_cfg = {li_ff1_3: hifi2, li_ff2: lofi, li_qkv_decode: hifi2, li_o_decode: hifi2, sdpa_decode: hifi2na, li_qkv_prefill: hifi2, li_o_prefill: hifi2fp16, sdpa_prefill: hifi4}'
|
| 294 |
+
```
|
| 295 |
+
|
| 296 |
+
Please refer to [model_config.py](models/tt_transformers/tt/model_config.py) for the full list of supported key-value pairs in the `--optimizations` argument. Centralized performance and accuracy targets are defined in [models/model_targets.yaml](../model_targets.yaml). The `lt` utility can still export markdown snapshots for local Pareto analysis.
|
| 297 |
+
|
| 298 |
+
To apply non-uniform settings across the decoders, the user can provide a JSON file using the `decoder_config_file` argument to specify the configuration for each decoder. For example
|
| 299 |
+
|
| 300 |
+
```
|
| 301 |
+
pytest models/tt_transformers/demo/simple_text_demo.py -k "performance and batch-1" --decoder_config_file 'models/tt_transformers/demo/config_16_decoders.json'
|
| 302 |
+
```
|
| 303 |
+
|
| 304 |
+
When a component is not specified (e.g., FF2 is missing for decoder 2 in `models/tt_transformers/demo/config_16_decoders.json`), the baseline configuration is used for that component.
|
| 305 |
+
|
| 306 |
+
---
|
| 307 |
+
|
| 308 |
+
### Expected performance and accuracy
|
| 309 |
+
|
| 310 |
+
See [models/model_targets.yaml](../model_targets.yaml) for expected performance and accuracy targets across supported configurations.
|
| 311 |
+
Accuracy of the network architectures is measured by exact token matching using teacher forcing method. During inference the previous token is replaced by the ground truth token while the network generates the next token. This allows to avoid accumulating errors when comparisons on a finer level (tokens) assessed in comparison to other known metrics that compare quality and context of the answer. Token accuracy can be reported by passing the argument shown below:
|
| 312 |
+
|
| 313 |
+
```
|
| 314 |
+
pytest models/tt_transformers/demo/simple_text_demo.py -k "performance and batch-1" --token_accuracy True
|
| 315 |
+
```
|
| 316 |
+
|
| 317 |
+
---
|
| 318 |
+
|
| 319 |
+
### Implementation notes
|
| 320 |
+
|
| 321 |
+
**Chunked prefill (text-only)**: All of the compatible model/device combinations support a max prefill context-length of 128k, with the exception of Llama3.1-8B and Llama3.2-11B on N150 which have a max of 32k (due to a lack of memory). To support these large max context-lengths, chunked prefill is performed with different max chunk sizes as shown in the table below.
|
| 322 |
+
|
| 323 |
+
Max Prefill Chunk Sizes (text-only):
|
| 324 |
+
| | N150 | N300 | T3K | TG |
|
| 325 |
+
|--------------|---------------|---------------|----------------|-------------|
|
| 326 |
+
| Llama3.2-1B | 128k tokens | 128k tokens | 128k tokens | 128k tokens |
|
| 327 |
+
| Llama3.2-3B | 8k tokens | 128k tokens | 128k tokens | 128k tokens |
|
| 328 |
+
| Qwen2.5-7B | 4k tokens | 32k tokens | 128k tokens | 128k tokens |
|
| 329 |
+
| Llama3.1-8B | 4k tokens | 64k tokens | 128k tokens | 128k tokens |
|
| 330 |
+
| Llama3.2-11B | 4k tokens | 64k tokens | 128k tokens | 128k tokens |
|
| 331 |
+
| Mistral-Small-3.1-24B | 8k tokens | 128k tokens | 128k tokens | 128k tokens |
|
| 332 |
+
| Llama3.1-70B | Not supported | Not supported | 32k tokens | 128k tokens |
|
| 333 |
+
| Llama3.2-90B | Not supported | Not supported | 32k tokens | Not supported |
|
| 334 |
+
| DeepSeek-R1-Distill-Llama3.3-70B | Not supported | Not supported | 32k tokens | 128k tokens |
|
| 335 |
+
|
| 336 |
+
|
| 337 |
+
- These max chunk sizes are specific to max context length 128k and are configured via `MAX_PREFILL_CHUNK_SIZES_DIV1024` in [model_config.py](https://github.com/tenstorrent/tt-metal/blob/main/models/demos/llama3/tt/model_config.py). If the max context length is set to a smaller value using the `max_seq_len` flag (see [Run the demo](#run-the-demo)), these chunk sizes can possibly be increased due to using a smaller KV cache.
|
| 338 |
+
|
| 339 |
+
**Chunked prefill (Llama3.2-11B multimodal)**: Llama3.2-11B multimodal is currently only supported on N300 and T3000. On N300, a max prefill context length of 8k is supported, while T3000 supports a max context length of 128k.
|
| 340 |
+
|
| 341 |
+
**Chunked prefill (Mistral-Small-3.1-24B multimodal)**: Mistral-Small-3.1-24B-Instruct-2503 (Pixtral vision) is currently supported on T3000. On T3000, a max prefill context length of 128k is supported.
|
| 342 |
+
|
| 343 |
+
---
|
| 344 |
+
|
| 345 |
+
### Memory Optimization
|
| 346 |
+
|
| 347 |
+
#### HuggingFace Model Caching Control
|
| 348 |
+
|
| 349 |
+
To help manage memory usage, you can control whether the HuggingFace model is cached in memory using the `cache_hf` parameter via command line or code:
|
| 350 |
+
|
| 351 |
+
```python
|
| 352 |
+
# Default: disables caching to conserve memory usage
|
| 353 |
+
model_args = ModelArgs(
|
| 354 |
+
mesh_device,
|
| 355 |
+
cache_hf=False, # Default: Reduces memory usage by not keeping HF model in memory
|
| 356 |
+
max_batch_size=1,
|
| 357 |
+
max_seq_len=2048
|
| 358 |
+
)
|
| 359 |
+
|
| 360 |
+
# Optional: enables caching for faster repeated access
|
| 361 |
+
model_args = ModelArgs(
|
| 362 |
+
mesh_device,
|
| 363 |
+
cache_hf=True, # Cache HF model for better performance running reference tests
|
| 364 |
+
max_batch_size=4,
|
| 365 |
+
max_seq_len=4096
|
| 366 |
+
)
|
| 367 |
+
```
|
| 368 |
+
|
| 369 |
+
**When to disable caching (`cache_hf=False`):**
|
| 370 |
+
- Running on systems with limited memory (< 256GB)
|
| 371 |
+
- Loading large models (70B+ parameters)
|
| 372 |
+
- Using the model for single inference runs
|
| 373 |
+
- When you don't need reference model comparisons
|
| 374 |
+
|
| 375 |
+
**When to keep caching enabled (`cache_hf=True`, default):**
|
| 376 |
+
- Sufficient memory available
|
| 377 |
+
- Comparisons with torch model is needed
|
| 378 |
+
- Minimizing test duration is prioritized over memory usage
|
| 379 |
+
- Running reference model tests
|
| 380 |
+
|
| 381 |
+
The `cache_hf` parameter affects:
|
| 382 |
+
- `load_state_dict()` method: Controls whether HF model is cached after loading
|
| 383 |
+
- `reference_transformer()` method: Controls whether to reuse cached model or load fresh
|
| 384 |
+
|
| 385 |
+
**Memory Impact:**
|
| 386 |
+
- Disabling caching saves approximately the full model size in memory
|
| 387 |
+
- For a 70B model, this can save ~140GB+ of memory usage
|
| 388 |
+
- Increased test duration as model needs to be reloaded for reference operations
|
code/models/tt_transformers/conftest.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# SPDX-FileCopyrightText: © 2025 Tenstorrent USA, Inc.
|
| 2 |
+
|
| 3 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 4 |
+
import os
|
| 5 |
+
|
| 6 |
+
import pytest
|
| 7 |
+
|
| 8 |
+
import ttnn
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
@pytest.fixture
|
| 12 |
+
def device_params(request, galaxy_type):
|
| 13 |
+
# Get param dict passed in from test parametrize (or default to empty dict).
|
| 14 |
+
# Any TRACE_MODEL_KEY_PARAM is left in place; the mesh_device fixture resolves it
|
| 15 |
+
# to trace_region_size using the logical submesh SKU.
|
| 16 |
+
params = getattr(request, "param", {}).copy()
|
| 17 |
+
|
| 18 |
+
mesh_device = {"N150": (1, 1), "N300": (1, 2), "N150x4": (1, 4), "T3K": (1, 8), "TG": (8, 4), "P150x8": (1, 8)}.get(
|
| 19 |
+
os.environ.get("MESH_DEVICE"), len(ttnn.get_device_ids())
|
| 20 |
+
)
|
| 21 |
+
is_single_device = (mesh_device == (1, 1)) if isinstance(mesh_device, tuple) else (mesh_device == 1)
|
| 22 |
+
|
| 23 |
+
if "fabric_config" in params:
|
| 24 |
+
if is_single_device:
|
| 25 |
+
params["fabric_config"] = None
|
| 26 |
+
elif params["fabric_config"] == True:
|
| 27 |
+
params["fabric_config"] = (
|
| 28 |
+
ttnn.FabricConfig.FABRIC_1D_RING if galaxy_type == "6U" else ttnn.FabricConfig.FABRIC_1D
|
| 29 |
+
)
|
| 30 |
+
|
| 31 |
+
return params
|
code/models/tt_transformers/host_mem_profiler.py
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# SPDX-FileCopyrightText: © 2025 Tenstorrent AI ULC
|
| 2 |
+
|
| 3 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 4 |
+
|
| 5 |
+
"""
|
| 6 |
+
host_mem_profiler.py — Host-side memory profiler for model tests
|
| 7 |
+
===============================================================
|
| 8 |
+
|
| 9 |
+
What this script does
|
| 10 |
+
---------------------
|
| 11 |
+
Wraps a pytest run with `memory_profiler` to record the host process
|
| 12 |
+
memory (RSS) at 100 ms intervals while the model test executes.
|
| 13 |
+
After the run it produces a PNG plot showing memory over time with a
|
| 14 |
+
peak-memory reference line. The script exits with pytest's own return
|
| 15 |
+
code, so CI pipelines see failures correctly and no plot is saved for a
|
| 16 |
+
failed run.
|
| 17 |
+
|
| 18 |
+
Measured memory includes all child processes spawned by the test
|
| 19 |
+
(e.g. the TT device runtime), giving a realistic view of total host
|
| 20 |
+
footprint during inference.
|
| 21 |
+
|
| 22 |
+
Dependencies
|
| 23 |
+
------------
|
| 24 |
+
`memory-profiler` and `matplotlib` are auto-installed at startup if
|
| 25 |
+
absent. Everything else must already be present in the active
|
| 26 |
+
environment (loguru, pytest, and the tt-metal Python stack).
|
| 27 |
+
|
| 28 |
+
pip install memory-profiler matplotlib # manual one-time install
|
| 29 |
+
|
| 30 |
+
Arguments
|
| 31 |
+
---------
|
| 32 |
+
--mesh-device Value forwarded as the MESH_DEVICE environment variable
|
| 33 |
+
to the test process (e.g. N150, N300, T3K, TG).
|
| 34 |
+
Default: N150
|
| 35 |
+
--hf-model Hugging Face model ID forwarded as HF_MODEL.
|
| 36 |
+
Default: meta-llama/Llama-3.2-1B-Instruct
|
| 37 |
+
--test Pytest target — a file path, directory, or node id.
|
| 38 |
+
Default: models/tt_transformers/demo/simple_text_demo.py
|
| 39 |
+
-k Optional pytest -k filter expression to select a subset
|
| 40 |
+
of tests within the target.
|
| 41 |
+
|
| 42 |
+
Output
|
| 43 |
+
------
|
| 44 |
+
A timestamped directory is created under profiling_results/:
|
| 45 |
+
|
| 46 |
+
profiling_results/<name>_<YYYYMMDD_HHMMSS>/
|
| 47 |
+
memory_profile.png ← time-series plot (peak annotated in red)
|
| 48 |
+
|
| 49 |
+
The script exits with pytest's return code; no plot is saved on failure.
|
| 50 |
+
|
| 51 |
+
Usage examples
|
| 52 |
+
--------------
|
| 53 |
+
# Minimal — profile the default Llama-3.2-1B demo on a single N150 card:
|
| 54 |
+
python host_mem_profiler.py
|
| 55 |
+
|
| 56 |
+
# Llama-3.1-8B on a T3K (8-chip) host, full test file:
|
| 57 |
+
python host_mem_profiler.py \\
|
| 58 |
+
--mesh-device T3K \\
|
| 59 |
+
--hf-model meta-llama/Llama-3.1-8B-Instruct \\
|
| 60 |
+
--test models/tt_transformers/demo/simple_text_demo.py
|
| 61 |
+
|
| 62 |
+
# Same model but only the decode token accuracy test case:
|
| 63 |
+
python host_mem_profiler.py \\
|
| 64 |
+
--mesh-device T3K \\
|
| 65 |
+
--hf-model meta-llama/Llama-3.1-8B-Instruct \\
|
| 66 |
+
--test models/tt_transformers/demo/simple_text_demo.py \\
|
| 67 |
+
-k performance-ci-token-mathcing
|
| 68 |
+
"""
|
| 69 |
+
|
| 70 |
+
import argparse
|
| 71 |
+
import importlib
|
| 72 |
+
import os
|
| 73 |
+
import subprocess
|
| 74 |
+
import sys
|
| 75 |
+
from datetime import datetime
|
| 76 |
+
from pathlib import Path
|
| 77 |
+
|
| 78 |
+
from loguru import logger
|
| 79 |
+
|
| 80 |
+
_ALLOWED_PACKAGES = {"memory-profiler", "matplotlib"}
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
def _require(package, import_name=None):
|
| 84 |
+
if package not in _ALLOWED_PACKAGES:
|
| 85 |
+
raise ValueError(f"Package '{package}' is not in the allowed list: {_ALLOWED_PACKAGES}")
|
| 86 |
+
import_name = import_name or package
|
| 87 |
+
try:
|
| 88 |
+
importlib.import_module(import_name)
|
| 89 |
+
except ImportError:
|
| 90 |
+
print(f"Installing missing dependency: {package}")
|
| 91 |
+
subprocess.check_call([sys.executable, "-m", "pip", "install", package])
|
| 92 |
+
importlib.invalidate_caches() # flush finder cache so the new package is visible
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
_require("memory-profiler", "memory_profiler")
|
| 96 |
+
_require("matplotlib")
|
| 97 |
+
|
| 98 |
+
import matplotlib.pyplot as plt
|
| 99 |
+
from memory_profiler import memory_usage
|
| 100 |
+
|
| 101 |
+
PYTEST_EXTRA_ARGS = ["-v", "-s"]
|
| 102 |
+
OUTPUT_ROOT = Path("profiling_results")
|
| 103 |
+
|
| 104 |
+
|
| 105 |
+
# ── Runner ────────────────────────────────────────────────────────────────────
|
| 106 |
+
def make_runner(model_cfg, k_filter=None):
|
| 107 |
+
"""Return a zero-arg callable that runs a model's test suite."""
|
| 108 |
+
|
| 109 |
+
def run():
|
| 110 |
+
env = os.environ.copy()
|
| 111 |
+
env.update(model_cfg["env"])
|
| 112 |
+
cmd = [sys.executable, "-m", "pytest", model_cfg["test"], *PYTEST_EXTRA_ARGS]
|
| 113 |
+
if k_filter:
|
| 114 |
+
cmd += ["-k", k_filter]
|
| 115 |
+
result = subprocess.run(cmd, capture_output=False, env=env)
|
| 116 |
+
return result.returncode
|
| 117 |
+
|
| 118 |
+
return run
|
| 119 |
+
|
| 120 |
+
|
| 121 |
+
# ── Plot ──────────────────────────────────────────────────────────────────────
|
| 122 |
+
def plot_results(name, elapsed, mib, out_dir):
|
| 123 |
+
fig, ax = plt.subplots(figsize=(14, 6))
|
| 124 |
+
ax.plot(elapsed, mib, "+-k", linewidth=1.0, markersize=4, label=name)
|
| 125 |
+
ax.axhline(max(mib), color="red", linestyle="--", linewidth=0.8, label=f"Peak: {max(mib):.1f} MiB")
|
| 126 |
+
|
| 127 |
+
ax.set_xlabel("Time (s)")
|
| 128 |
+
ax.set_ylabel("Memory (MiB)")
|
| 129 |
+
ax.set_title("Memory Usage Over Time")
|
| 130 |
+
ax.legend()
|
| 131 |
+
fig.tight_layout()
|
| 132 |
+
fig.savefig(os.path.join(out_dir, "memory_profile.png"), dpi=150)
|
| 133 |
+
plt.close(fig)
|
| 134 |
+
logger.info(f"Saved at {os.path.join(out_dir, 'memory_profile.png')}")
|
| 135 |
+
|
| 136 |
+
|
| 137 |
+
# ── Main ──────────────────────────────────────────────────────────────────────
|
| 138 |
+
if __name__ == "__main__":
|
| 139 |
+
parser = argparse.ArgumentParser(description="Profile host-side memory usage of a model test")
|
| 140 |
+
parser.add_argument("--mesh-device", default="N150", help="MESH_DEVICE value (e.g. N150, T3K)")
|
| 141 |
+
parser.add_argument("--hf-model", default="meta-llama/Llama-3.2-1B-Instruct", help="Hugging Face model ID")
|
| 142 |
+
parser.add_argument("--test", default="models/tt_transformers/demo/simple_text_demo.py", help="Pytest target path")
|
| 143 |
+
parser.add_argument("-k", default=None, help="pytest -k filter expression")
|
| 144 |
+
args = parser.parse_args()
|
| 145 |
+
|
| 146 |
+
name = args.hf_model.split("/")[-1] if "/" in args.hf_model else args.hf_model
|
| 147 |
+
if args.k:
|
| 148 |
+
name = f"{name}_{args.k}"
|
| 149 |
+
|
| 150 |
+
model = {
|
| 151 |
+
"name": name,
|
| 152 |
+
"env": {
|
| 153 |
+
"MESH_DEVICE": args.mesh_device,
|
| 154 |
+
"HF_MODEL": args.hf_model,
|
| 155 |
+
},
|
| 156 |
+
"test": args.test,
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
logger.info(f"\n{'='*60}\nProfiling: {model['name']}\n{'='*60}")
|
| 160 |
+
|
| 161 |
+
mem_ts, returncode = memory_usage(
|
| 162 |
+
(make_runner(model, args.k), [], {}),
|
| 163 |
+
interval=0.1,
|
| 164 |
+
retval=True,
|
| 165 |
+
timestamps=True,
|
| 166 |
+
include_children=True,
|
| 167 |
+
)
|
| 168 |
+
if returncode:
|
| 169 |
+
logger.error(f"pytest exited with code {returncode} — skipping plot")
|
| 170 |
+
sys.exit(returncode)
|
| 171 |
+
|
| 172 |
+
mib = [m for m, _ in mem_ts]
|
| 173 |
+
ts = [t for _, t in mem_ts]
|
| 174 |
+
t0 = ts[0]
|
| 175 |
+
elapsed = [t - t0 for t in ts]
|
| 176 |
+
|
| 177 |
+
logger.info(f" Peak: {max(mib):.1f} MiB")
|
| 178 |
+
logger.info(f" Baseline: {min(mib):.1f} MiB")
|
| 179 |
+
|
| 180 |
+
safe_name = name.replace("/", "_").replace(" ", "_")
|
| 181 |
+
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
| 182 |
+
output_root = OUTPUT_ROOT.resolve()
|
| 183 |
+
out_dir = (output_root / f"{safe_name}_{timestamp}").resolve()
|
| 184 |
+
if not out_dir.is_relative_to(output_root):
|
| 185 |
+
raise ValueError(f"Refusing to write outside output root: {out_dir}")
|
| 186 |
+
out_dir.mkdir(parents=True, exist_ok=True)
|
| 187 |
+
|
| 188 |
+
plot_results(model["name"], elapsed, mib, out_dir)
|
image/blobs/sha256/0690f7dcdac59b821f2eff8a565951a2120a112c6b9613f43be03bb143f8875b
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"id":"d0bbcfefb7467acdbf3aef2851c41c9c57d0eb61a01bdc4ce5e7e58bfa34e90c","parent":"155ab0b6484fdeee7919c43f2a38a56151bd05a8b48891fa53929c0e45577105","created":"1970-01-01T09:00:00+09:00","container_config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"os":"linux"}
|
image/blobs/sha256/0b3b7bf707349d15afaf4582949a95082c50449ac8e4f7346d1bbee5bc7ba1c5
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"id":"443ab363fe01ac0190ecbaf3fa1afbc9676ce328e3a82321261b28d57844fa11","parent":"94055894755a230626deff4f0207669ea80cf6f5e7990ddf2950bfb2560a8c68","created":"2026-09-12T15:59:37.210009429+09:00","container_config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"config":{"Hostname":"","Domainname":"","User":"tt","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/opt/tt-venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","VENV=/opt/tt-venv","VIRTUAL_ENV=/opt/tt-venv","TT_METAL_RUNTIME_ROOT=/opt/tt-metal","TT_METAL_HOME=/opt/tt-metal","PYTHONPATH=/opt/tt-metal","LD_LIBRARY_PATH=/opt/tt-metal/build/lib:/opt/openmpi-v5.0.7-ulfm/lib","EXTRA_MODELS_DIR=","TT_VLLM_BUILTIN_MODELS=","TT_MODEL_KIND=tt-dit-server","HF_HOME=/hf","TT_METAL_CACHE=/cache","HOME=/home/tt","USER=tt","LOGNAME=tt"],"Cmd":["/usr/local/bin/serve-default.sh"],"ArgsEscaped":true,"Image":"","Volumes":null,"WorkingDir":"/home/tt/work","Entrypoint":["/usr/local/bin/entrypoint.sh"],"OnBuild":null,"Labels":{"org.opencontainers.image.revision":"8b98410e730bb504fea43a88609756e34821d91d","org.opencontainers.image.version":"22.04","org.tenstorrent.tt-model":"locate-anything-3b-blackhole","org.tenstorrent.tt-model.arch":"blackhole","org.tenstorrent.tt-model.kind":"tt-dit-server","org.tenstorrent.tt-model.plugin":"","org.tenstorrent.tt-model.profiles":"default","org.tenstorrent.tt-model.repo":"changh95/locate-anything-3b-blackhole","org.tenstorrent.tt-model.tt-metal":"v0.78.0-dev20260820-25-g8b98410e73","org.tenstorrent.tt-model.weights":"nvidia/LocateAnything-3B"}},"architecture":"amd64","os":"linux"}
|
image/blobs/sha256/18b68d787d3c7446ef9eb0eba334950a837818ace17924cb42e6e6a2fac47a17
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"id":"87cb9513aafc6caae0d486fd87639985a32e69f3f8c9b8c6ede95f9cccfaa667","parent":"525c1f4cf166cfba577e017bb1da9678a6667fa9bbd56a2608bf2e3585e0cf8a","created":"1970-01-01T09:00:00+09:00","container_config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"os":"linux"}
|
image/blobs/sha256/18f46874ca6617cba588e37f39ecd58f44b02065d3c3ea3909c403d2260b686d
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"id":"d1597874ea56b73b5fdf623f9323c8d1620b2625e4b8924ee358c61652b82be5","parent":"b58135a7607f916cd7221128976d64d0f39fc917e1ba780df8efe3e2c4c7d23a","created":"1970-01-01T09:00:00+09:00","container_config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"os":"linux"}
|
image/blobs/sha256/1d805657f0ef573b66e654d64007281d8aadf4dfa8aa1eb88672c886293dfe13
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"id":"0e81830e949af791d050288892e16a4dd59392bbcc7479a00ab3629ae8e529e6","parent":"d0bbcfefb7467acdbf3aef2851c41c9c57d0eb61a01bdc4ce5e7e58bfa34e90c","created":"1970-01-01T09:00:00+09:00","container_config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"os":"linux"}
|
image/blobs/sha256/1f179d27e2f48842a37b1dbe6300e0e9d83c174ae4c6d879f38b473d31ff159f
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"id":"d08f3a800926365edee4ef1f3c9d6d42ca6762b65af44fe80261a5543cd58905","parent":"b2319e94f380633a4827308b9cb5ac756723a5f05cefd50d47dafdcba43981b2","created":"1970-01-01T09:00:00+09:00","container_config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"os":"linux"}
|
image/blobs/sha256/28b873d0d487580ae6a42f1c52c28160516c4f2e4d82abf93e6f6b7c95e49bc7
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"id":"f3d345315bfbedaf1b9e3924e84e2a596382cae91d99fac771a0d023a3f0d356","parent":"5a70f6b5efbd972a1364d6f6d00f598c5fe6c68f620defce025d5d7c0e89e158","created":"1970-01-01T09:00:00+09:00","container_config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"os":"linux"}
|
image/blobs/sha256/3dcb0a4c97491bdc43addf1e7fe76c9dd7a714314fc4729a32cf94c89455a2a5
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"id":"2dcd7c4c5dcd97f8c692bc32701ed37ed86c9683cc3afff3156da3af639b7f52","parent":"0c37cc42f3bf2829965c4c3a62507e4e540086b724c37f43bf5e53243e230a2b","created":"1970-01-01T09:00:00+09:00","container_config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"os":"linux"}
|
image/blobs/sha256/4b7d28cf86399d4e9f4f1eeba9a85df52bfc3e360e1c831def2915ad8cff54db
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"id":"b2319e94f380633a4827308b9cb5ac756723a5f05cefd50d47dafdcba43981b2","parent":"e618d643825753f4550a54eacfd500e6e7652078cf4168c9ef3f869701db7fc5","created":"1970-01-01T09:00:00+09:00","container_config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"os":"linux"}
|
image/blobs/sha256/5116d36f79d2da6aa08f8ffcff866e39d7c0f5be5bbf3d74c6e8c8caebf2c5fd
ADDED
|
Binary file (39.9 kB). View file
|
|
|
image/blobs/sha256/5628e13ce208b83d793af15fa41c28d1702e7a43e27c8c72944442d01e959a71
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"id":"e618d643825753f4550a54eacfd500e6e7652078cf4168c9ef3f869701db7fc5","created":"1970-01-01T09:00:00+09:00","container_config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"os":"linux"}
|
image/blobs/sha256/5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef
ADDED
|
Binary file (1.02 kB). View file
|
|
|
image/blobs/sha256/639c9dd1747f941795c619f445de593cc6d7957060442b3dbe0148bd1be1eeb3
ADDED
|
Binary file (23 kB). View file
|
|
|
image/blobs/sha256/718b6feb51a3973517c6ac89780d58b88478d3ddbdc41353af609f6c944dc085
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"id":"94055894755a230626deff4f0207669ea80cf6f5e7990ddf2950bfb2560a8c68","parent":"56c06abc3c98b8e8b28ca977494b08c3467fc2ef2ba5ef89bc016a6c5aaed462","created":"1970-01-01T09:00:00+09:00","container_config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"os":"linux"}
|
image/blobs/sha256/77b04a4822168bcd77a83c78c22a390734a35e4232b7c9f2485b2663b5fefb7c
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"id":"0c37cc42f3bf2829965c4c3a62507e4e540086b724c37f43bf5e53243e230a2b","parent":"0e81830e949af791d050288892e16a4dd59392bbcc7479a00ab3629ae8e529e6","created":"1970-01-01T09:00:00+09:00","container_config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"os":"linux"}
|
image/blobs/sha256/7f2d9782a5ff3e0bf36c4b028cdf5b4e59db0cdf2122cea0669de2841c5d05f7
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"id":"69f6359ca11460b168172b1ad4ba59ef64db4fe7ef455e604d5987c89ec68fea","parent":"87cb9513aafc6caae0d486fd87639985a32e69f3f8c9b8c6ede95f9cccfaa667","created":"1970-01-01T09:00:00+09:00","container_config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"os":"linux"}
|
image/blobs/sha256/8529443804912d6639846836d1b7ab793de42b54e3b4058e14a059f0d5fe4ade
ADDED
|
Binary file (4.61 kB). View file
|
|
|
image/blobs/sha256/89fcc824b4db414c4ba9f1a86324bd6bfa92505480f7c02fd87f4e3c79ebf1de
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"id":"5a70f6b5efbd972a1364d6f6d00f598c5fe6c68f620defce025d5d7c0e89e158","parent":"2dcd7c4c5dcd97f8c692bc32701ed37ed86c9683cc3afff3156da3af639b7f52","created":"1970-01-01T09:00:00+09:00","container_config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"os":"linux"}
|
image/blobs/sha256/8a28dfa1a683cbd7674d79f7ac878f4ba04d0a72bccfe56cec0f0f008b325bdd
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"id":"56c06abc3c98b8e8b28ca977494b08c3467fc2ef2ba5ef89bc016a6c5aaed462","parent":"c142e2f41d7cc33a0e167943cc3f43767c01aa6576edb983bd44e3590d9deaec","created":"1970-01-01T09:00:00+09:00","container_config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"os":"linux"}
|
image/blobs/sha256/96f3b28657c091e4818e2407f66db33853828fdb8abef3177cdf5c8d525f7dbf
ADDED
|
Binary file (4.61 kB). View file
|
|
|
image/blobs/sha256/bc34115d8ab3da3bb2818457b8bc493ed594968b9ae39c48e30c22b37294974b
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"architecture":"amd64","config":{"User":"tt","Env":["PATH=/opt/tt-venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","VENV=/opt/tt-venv","VIRTUAL_ENV=/opt/tt-venv","TT_METAL_RUNTIME_ROOT=/opt/tt-metal","TT_METAL_HOME=/opt/tt-metal","PYTHONPATH=/opt/tt-metal","LD_LIBRARY_PATH=/opt/tt-metal/build/lib:/opt/openmpi-v5.0.7-ulfm/lib","EXTRA_MODELS_DIR=","TT_VLLM_BUILTIN_MODELS=","TT_MODEL_KIND=tt-dit-server","HF_HOME=/hf","TT_METAL_CACHE=/cache","HOME=/home/tt","USER=tt","LOGNAME=tt"],"Entrypoint":["/usr/local/bin/entrypoint.sh"],"Cmd":["/usr/local/bin/serve-default.sh"],"WorkingDir":"/home/tt/work","Labels":{"org.opencontainers.image.revision":"8b98410e730bb504fea43a88609756e34821d91d","org.opencontainers.image.version":"22.04","org.tenstorrent.tt-model":"locate-anything-3b-blackhole","org.tenstorrent.tt-model.arch":"blackhole","org.tenstorrent.tt-model.kind":"tt-dit-server","org.tenstorrent.tt-model.plugin":"","org.tenstorrent.tt-model.profiles":"default","org.tenstorrent.tt-model.repo":"changh95/locate-anything-3b-blackhole","org.tenstorrent.tt-model.tt-metal":"v0.78.0-dev20260820-25-g8b98410e73","org.tenstorrent.tt-model.weights":"nvidia/LocateAnything-3B"},"ArgsEscaped":true},"created":"2026-09-12T15:59:37.210009429+09:00","history":[{"created":"2026-09-03T12:14:51.139348462Z","created_by":"/bin/sh -c #(nop) ARG RELEASE","empty_layer":true},{"created":"2026-09-03T12:14:51.170427469Z","created_by":"/bin/sh -c #(nop) ARG LAUNCHPAD_BUILD_ARCH","empty_layer":true},{"created":"2026-09-03T12:14:51.200307479Z","created_by":"/bin/sh -c #(nop) LABEL org.opencontainers.image.version=22.04","empty_layer":true},{"created":"2026-09-03T12:14:53.528689977Z","created_by":"/bin/sh -c #(nop) ADD file:81c01921c5f642ac2fcbfae682e489e8e64b347467d9fa1587707e310e64d790 in / "},{"created":"2026-09-03T12:14:54.045714841Z","created_by":"/bin/sh -c #(nop) CMD [\"/bin/bash\"]","empty_layer":true},{"created":"2026-09-12T15:18:22.627027282+09:00","created_by":"ARG OMPI_DIR=/opt/openmpi-v5.0.7-ulfm","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:18:22.627027282+09:00","created_by":"ARG EXTRA_MODELS_DIR=","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:18:22.627027282+09:00","created_by":"ARG TT_MODEL_KIND","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:18:22.627027282+09:00","created_by":"ARG MODEL_NAME","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:18:22.627027282+09:00","created_by":"ARG MODEL_REPO","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:18:22.627027282+09:00","created_by":"ARG MODEL_WEIGHTS","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:18:22.627027282+09:00","created_by":"ARG MODEL_ARCH","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:18:22.627027282+09:00","created_by":"ARG MODEL_PROFILES","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:18:22.627027282+09:00","created_by":"ARG MODEL_TT_METAL_SHA","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:18:22.627027282+09:00","created_by":"ARG MODEL_TT_METAL_DESCRIBE","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:18:22.627027282+09:00","created_by":"ARG MODEL_PLUGIN_SHA","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:18:22.627027282+09:00","created_by":"RUN |11 OMPI_DIR=/opt/openmpi-v5.0.7-ulfm EXTRA_MODELS_DIR= TT_MODEL_KIND=tt-dit-server MODEL_NAME=locate-anything-3b-blackhole MODEL_REPO=changh95/locate-anything-3b-blackhole MODEL_WEIGHTS=nvidia/LocateAnything-3B MODEL_ARCH=blackhole MODEL_PROFILES=default MODEL_TT_METAL_SHA=8b98410e730bb504fea43a88609756e34821d91d MODEL_TT_METAL_DESCRIBE=v0.78.0-dev20260820-25-g8b98410e73 MODEL_PLUGIN_SHA= /bin/sh -c apt-get update \u0026\u0026 apt-get install -y --no-install-recommends libhwloc15 libnuma1 libatomic1 libudev1 libcap2 zlib1g libmpc3 libmpfr6 libgmp10 libzstd1 libevent-core-2.1-7 libevent-pthreads-2.1-7 libgl1 libsndfile1 ca-certificates \u0026\u0026 apt-get clean \u0026\u0026 rm -rf /var/lib/apt/lists/* # buildkit","comment":"buildkit.dockerfile.v0"},{"created":"2026-09-12T15:18:22.929268734+09:00","created_by":"RUN |11 OMPI_DIR=/opt/openmpi-v5.0.7-ulfm EXTRA_MODELS_DIR= TT_MODEL_KIND=tt-dit-server MODEL_NAME=locate-anything-3b-blackhole MODEL_REPO=changh95/locate-anything-3b-blackhole MODEL_WEIGHTS=nvidia/LocateAnything-3B MODEL_ARCH=blackhole MODEL_PROFILES=default MODEL_TT_METAL_SHA=8b98410e730bb504fea43a88609756e34821d91d MODEL_TT_METAL_DESCRIBE=v0.78.0-dev20260820-25-g8b98410e73 MODEL_PLUGIN_SHA= /bin/sh -c existing=\"$(getent passwd 1000 | cut -d: -f1)\" \u0026\u0026 if [ -n \"$existing\" ]; then userdel -r \"$existing\" 2\u003e/dev/null || userdel \"$existing\"; fi \u0026\u0026 useradd --uid 1000 --create-home --home-dir /home/tt --shell /bin/bash tt \u0026\u0026 mkdir -p /home/tt/work/logs /cache /opt/tt-metal \u0026\u0026 chown -R tt:tt /home/tt /cache /opt/tt-metal \u0026\u0026 chmod 1777 /home/tt /home/tt/work /home/tt/work/logs /cache # buildkit","comment":"buildkit.dockerfile.v0"},{"created":"2026-09-12T15:20:34.958721745+09:00","created_by":"COPY /opt/openmpi-v5.0.7-ulfm /opt/openmpi-v5.0.7-ulfm # buildkit","comment":"buildkit.dockerfile.v0"},{"created":"2026-09-12T15:20:40.413645687+09:00","created_by":"COPY /opt/tenstorrent /opt/tenstorrent # buildkit","comment":"buildkit.dockerfile.v0"},{"created":"2026-09-12T15:59:09.695650358+09:00","created_by":"COPY /usr/local/share/uv /usr/local/share/uv # buildkit","comment":"buildkit.dockerfile.v0"},{"created":"2026-09-12T15:59:13.968046982+09:00","created_by":"COPY /opt/tt-venv /opt/tt-venv # buildkit","comment":"buildkit.dockerfile.v0"},{"created":"2026-09-12T15:59:14.05489038+09:00","created_by":"COPY /opt/vllm /opt/vllm # buildkit","comment":"buildkit.dockerfile.v0"},{"created":"2026-09-12T15:59:14.837070708+09:00","created_by":"COPY --chown=tt:tt /opt/tt-metal/runtime /opt/tt-metal/runtime # buildkit","comment":"buildkit.dockerfile.v0"},{"created":"2026-09-12T15:59:16.252685022+09:00","created_by":"COPY --chown=tt:tt /opt/tt-metal/build_Release /opt/tt-metal/build_Release # buildkit","comment":"buildkit.dockerfile.v0"},{"created":"2026-09-12T15:59:17.681704755+09:00","created_by":"COPY --chown=tt:tt /opt/tt-metal/build /opt/tt-metal/build # buildkit","comment":"buildkit.dockerfile.v0"},{"created":"2026-09-12T15:59:20.295619738+09:00","created_by":"COPY --chown=tt:tt /opt/tt-metal/tt_metal /opt/tt-metal/tt_metal # buildkit","comment":"buildkit.dockerfile.v0"},{"created":"2026-09-12T15:59:21.696437386+09:00","created_by":"COPY --chown=tt:tt /opt/tt-metal/ttnn /opt/tt-metal/ttnn # buildkit","comment":"buildkit.dockerfile.v0"},{"created":"2026-09-12T15:59:21.905622694+09:00","created_by":"COPY --chown=tt:tt /opt/tt-metal/tools /opt/tt-metal/tools # buildkit","comment":"buildkit.dockerfile.v0"},{"created":"2026-09-12T15:59:22.036864821+09:00","created_by":"COPY --chown=tt:tt /opt/tt-metal/setup.py /opt/tt-metal/pyproject.toml /opt/tt-metal/ # buildkit","comment":"buildkit.dockerfile.v0"},{"created":"2026-09-12T15:59:22.212260176+09:00","created_by":"COPY --chown=tt:tt code/ /opt/tt-metal/ # buildkit","comment":"buildkit.dockerfile.v0"},{"created":"2026-09-12T15:59:22.296404672+09:00","created_by":"COPY entrypoint.sh /usr/local/bin/entrypoint.sh # buildkit","comment":"buildkit.dockerfile.v0"},{"created":"2026-09-12T15:59:22.381901539+09:00","created_by":"COPY --chmod=0755 serve-default.sh /usr/local/bin/serve-default.sh # buildkit","comment":"buildkit.dockerfile.v0"},{"created":"2026-09-12T15:59:22.381901539+09:00","created_by":"ENV VENV=/opt/tt-venv","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:59:22.381901539+09:00","created_by":"ENV VIRTUAL_ENV=/opt/tt-venv","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:59:22.381901539+09:00","created_by":"ENV PATH=/opt/tt-venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:59:22.381901539+09:00","created_by":"ENV TT_METAL_RUNTIME_ROOT=/opt/tt-metal","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:59:22.381901539+09:00","created_by":"ENV TT_METAL_HOME=/opt/tt-metal","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:59:22.381901539+09:00","created_by":"ENV PYTHONPATH=/opt/tt-metal","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:59:22.381901539+09:00","created_by":"ENV LD_LIBRARY_PATH=/opt/tt-metal/build/lib:/opt/openmpi-v5.0.7-ulfm/lib","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:59:22.381901539+09:00","created_by":"ENV EXTRA_MODELS_DIR=","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:59:22.381901539+09:00","created_by":"ARG TT_VLLM_BUILTIN_MODELS=","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:59:22.381901539+09:00","created_by":"ENV TT_VLLM_BUILTIN_MODELS=","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:59:22.381901539+09:00","created_by":"ENV TT_MODEL_KIND=tt-dit-server","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:59:22.381901539+09:00","created_by":"ENV HF_HOME=/hf","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:59:22.381901539+09:00","created_by":"ENV TT_METAL_CACHE=/cache","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:59:22.381901539+09:00","created_by":"ENV HOME=/home/tt","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:59:22.381901539+09:00","created_by":"ENV USER=tt","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:59:22.381901539+09:00","created_by":"ENV LOGNAME=tt","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:59:22.381901539+09:00","created_by":"USER tt","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:59:22.47282321+09:00","created_by":"WORKDIR /home/tt/work","comment":"buildkit.dockerfile.v0"},{"created":"2026-09-12T15:59:22.557362177+09:00","created_by":"COPY verify.sh /ctx/verify.sh # buildkit","comment":"buildkit.dockerfile.v0"},{"created":"2026-09-12T15:59:36.937396823+09:00","created_by":"RUN |12 OMPI_DIR=/opt/openmpi-v5.0.7-ulfm EXTRA_MODELS_DIR= TT_MODEL_KIND=tt-dit-server MODEL_NAME=locate-anything-3b-blackhole MODEL_REPO=changh95/locate-anything-3b-blackhole MODEL_WEIGHTS=nvidia/LocateAnything-3B MODEL_ARCH=blackhole MODEL_PROFILES=default MODEL_TT_METAL_SHA=8b98410e730bb504fea43a88609756e34821d91d MODEL_TT_METAL_DESCRIBE=v0.78.0-dev20260820-25-g8b98410e73 MODEL_PLUGIN_SHA= TT_VLLM_BUILTIN_MODELS= /bin/sh -c bash /ctx/verify.sh # buildkit","comment":"buildkit.dockerfile.v0"},{"created":"2026-09-12T15:59:36.937396823+09:00","created_by":"USER root","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:59:37.210009429+09:00","created_by":"RUN |12 OMPI_DIR=/opt/openmpi-v5.0.7-ulfm EXTRA_MODELS_DIR= TT_MODEL_KIND=tt-dit-server MODEL_NAME=locate-anything-3b-blackhole MODEL_REPO=changh95/locate-anything-3b-blackhole MODEL_WEIGHTS=nvidia/LocateAnything-3B MODEL_ARCH=blackhole MODEL_PROFILES=default MODEL_TT_METAL_SHA=8b98410e730bb504fea43a88609756e34821d91d MODEL_TT_METAL_DESCRIBE=v0.78.0-dev20260820-25-g8b98410e73 MODEL_PLUGIN_SHA= TT_VLLM_BUILTIN_MODELS= /bin/sh -c chmod -R a+rwX /home/tt # buildkit","comment":"buildkit.dockerfile.v0"},{"created":"2026-09-12T15:59:37.210009429+09:00","created_by":"USER tt","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:59:37.210009429+09:00","created_by":"LABEL org.tenstorrent.tt-model=locate-anything-3b-blackhole org.tenstorrent.tt-model.repo=changh95/locate-anything-3b-blackhole org.tenstorrent.tt-model.weights=nvidia/LocateAnything-3B org.tenstorrent.tt-model.arch=blackhole org.tenstorrent.tt-model.kind=tt-dit-server org.tenstorrent.tt-model.profiles=default org.opencontainers.image.revision=8b98410e730bb504fea43a88609756e34821d91d org.tenstorrent.tt-model.tt-metal=v0.78.0-dev20260820-25-g8b98410e73 org.tenstorrent.tt-model.plugin=","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:59:37.210009429+09:00","created_by":"ENTRYPOINT [\"/usr/local/bin/entrypoint.sh\"]","comment":"buildkit.dockerfile.v0","empty_layer":true},{"created":"2026-09-12T15:59:37.210009429+09:00","created_by":"CMD [\"/usr/local/bin/serve-default.sh\"]","comment":"buildkit.dockerfile.v0","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:ea16cace89338c84eb6bcb91a7efdfcae6838fff359efe951858227436486c34","sha256:e64f34e6f7fc770276a58ce68b18755913e8f6a38b80274ed30b138ba6db8cef","sha256:3f6ad10d5ba93a17af361223d9d9cd8c53c34d4156cd69af1e9b9af1bebcd4bb","sha256:5b60873863c0500f341a4c237ab1c18b929b3ac1571a2808b87fcacfdd1f2168","sha256:0311ceefbd13017ef17eb9844fbfd15250b1bb099d408687eef4372ad2c65ee5","sha256:661b4446add5adf8c9d4eaab02ab1fe419f17114b8c7a7a381707be7973467e5","sha256:2f1823fe031c57258362a517aa11e3c4a55eccca738913d0cc87587ccfb6fd1a","sha256:e1272a58679febd696c70d77b53ffeb43cba62b4ddb3d97dd4e632c6848d2856","sha256:d1a9879f27dd477b46fe73ced95ea58803d70fc7c2bb42b875c605b8fc744e14","sha256:184743fecd7fc3deb4e6f457a2a602932fe813f75148eec4b6e75ff88a9f2be2","sha256:59b37b1999541425b0a7cda1ce01f95f1be228fa97cd09f6631acfb2fab990fd","sha256:ca297dc8905fb0b70eebf7e9c58d50df4d8d38c5ece2cc866c22798cfc2dfd01","sha256:4f4c468252314917a1847056077663ed71f3abc1dc386c03bca471690a23c83b","sha256:c94435d8cb1f57c0296304800fe6e7376c511a75484d5da38e0eceb4a8cba02d","sha256:639c9dd1747f941795c619f445de593cc6d7957060442b3dbe0148bd1be1eeb3","sha256:082a9ded324a46a5cc7fe15bde1b9d83c03804f0f84eac7ce6bb51229b894f1f","sha256:8529443804912d6639846836d1b7ab793de42b54e3b4058e14a059f0d5fe4ade","sha256:96f3b28657c091e4818e2407f66db33853828fdb8abef3177cdf5c8d525f7dbf","sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef","sha256:c0d475ded7d3e60cdc094385f92036f940b605a0438578608e031030a8819ae9","sha256:53deb2ae079afabdafec52b959453dccca54d8c7eb6315862fcab21d186bcbdd","sha256:5116d36f79d2da6aa08f8ffcff866e39d7c0f5be5bbf3d74c6e8c8caebf2c5fd"]}}
|
image/blobs/sha256/c0d475ded7d3e60cdc094385f92036f940b605a0438578608e031030a8819ae9
ADDED
|
Binary file (4.1 kB). View file
|
|
|
image/blobs/sha256/cf8ccef7cd12a5a0492c4e3cde07fef8807fe0cd228de6257516ba32f752276c
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"id":"ad0118a7016e58d45485fd05788ec2150a90083b48a6e651e81346550adf57bb","parent":"d08f3a800926365edee4ef1f3c9d6d42ca6762b65af44fe80261a5543cd58905","created":"1970-01-01T09:00:00+09:00","container_config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"os":"linux"}
|
image/blobs/sha256/dfbe9006d67d8efd33cd4834af36a9acd4030ef4f5a9aca44181d9555d590526
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"id":"525c1f4cf166cfba577e017bb1da9678a6667fa9bbd56a2608bf2e3585e0cf8a","parent":"d1597874ea56b73b5fdf623f9323c8d1620b2625e4b8924ee358c61652b82be5","created":"1970-01-01T09:00:00+09:00","container_config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"os":"linux"}
|
image/blobs/sha256/e1272a58679febd696c70d77b53ffeb43cba62b4ddb3d97dd4e632c6848d2856
ADDED
|
Binary file (2.05 kB). View file
|
|
|
image/blobs/sha256/e71053098ec0882ae447db33f4d23f6455424ec7cf649519ac98455342a3ffbe
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"id":"c142e2f41d7cc33a0e167943cc3f43767c01aa6576edb983bd44e3590d9deaec","parent":"69f6359ca11460b168172b1ad4ba59ef64db4fe7ef455e604d5987c89ec68fea","created":"1970-01-01T09:00:00+09:00","container_config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"os":"linux"}
|
image/blobs/sha256/e78a28551be8e30ee61eba8b7627859a67e05827f5119754228edfe4ca005e48
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"id":"12e1b52d50de6740b0ae582760feedf780e2affcaa1c5d15bef6df3f7da931d4","parent":"0308415c0d87b5deb13640aea7b13b37d66d085488d40063d6304dcc2de92520","created":"1970-01-01T09:00:00+09:00","container_config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"os":"linux"}
|
image/blobs/sha256/e94cd641692a2de981d616a078e01282ac9e8cef9fb44bfa26cbab8bc16d9812
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"id":"0308415c0d87b5deb13640aea7b13b37d66d085488d40063d6304dcc2de92520","parent":"ad0118a7016e58d45485fd05788ec2150a90083b48a6e651e81346550adf57bb","created":"1970-01-01T09:00:00+09:00","container_config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"os":"linux"}
|
image/blobs/sha256/ec0a7658dda53cfa39e9a61f8506fce49e56b206fee8ab604f17daa0a8f42f43
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","config":{"mediaType":"application/vnd.oci.image.config.v1+json","digest":"sha256:bc34115d8ab3da3bb2818457b8bc493ed594968b9ae39c48e30c22b37294974b","size":14594},"layers":[{"mediaType":"application/vnd.oci.image.layer.v1.tar","digest":"sha256:ea16cace89338c84eb6bcb91a7efdfcae6838fff359efe951858227436486c34","size":80641024},{"mediaType":"application/vnd.oci.image.layer.v1.tar","digest":"sha256:e64f34e6f7fc770276a58ce68b18755913e8f6a38b80274ed30b138ba6db8cef","size":204086784},{"mediaType":"application/vnd.oci.image.layer.v1.tar","digest":"sha256:3f6ad10d5ba93a17af361223d9d9cd8c53c34d4156cd69af1e9b9af1bebcd4bb","size":352256},{"mediaType":"application/vnd.oci.image.layer.v1.tar","digest":"sha256:5b60873863c0500f341a4c237ab1c18b929b3ac1571a2808b87fcacfdd1f2168","size":33464832},{"mediaType":"application/vnd.oci.image.layer.v1.tar","digest":"sha256:0311ceefbd13017ef17eb9844fbfd15250b1bb099d408687eef4372ad2c65ee5","size":454126592},{"mediaType":"application/vnd.oci.image.layer.v1.tar","digest":"sha256:661b4446add5adf8c9d4eaab02ab1fe419f17114b8c7a7a381707be7973467e5","size":187652608},{"mediaType":"application/vnd.oci.image.layer.v1.tar","digest":"sha256:2f1823fe031c57258362a517aa11e3c4a55eccca738913d0cc87587ccfb6fd1a","size":1099616768},{"mediaType":"application/vnd.oci.image.layer.v1.tar","digest":"sha256:e1272a58679febd696c70d77b53ffeb43cba62b4ddb3d97dd4e632c6848d2856","size":2048},{"mediaType":"application/vnd.oci.image.layer.v1.tar","digest":"sha256:d1a9879f27dd477b46fe73ced95ea58803d70fc7c2bb42b875c605b8fc744e14","size":454599168},{"mediaType":"application/vnd.oci.image.layer.v1.tar","digest":"sha256:184743fecd7fc3deb4e6f457a2a602932fe813f75148eec4b6e75ff88a9f2be2","size":130853888},{"mediaType":"application/vnd.oci.image.layer.v1.tar","digest":"sha256:59b37b1999541425b0a7cda1ce01f95f1be228fa97cd09f6631acfb2fab990fd","size":130853888},{"mediaType":"application/vnd.oci.image.layer.v1.tar","digest":"sha256:ca297dc8905fb0b70eebf7e9c58d50df4d8d38c5ece2cc866c22798cfc2dfd01","size":191707136},{"mediaType":"application/vnd.oci.image.layer.v1.tar","digest":"sha256:4f4c468252314917a1847056077663ed71f3abc1dc386c03bca471690a23c83b","size":65318400},{"mediaType":"application/vnd.oci.image.layer.v1.tar","digest":"sha256:c94435d8cb1f57c0296304800fe6e7376c511a75484d5da38e0eceb4a8cba02d","size":4678144},{"mediaType":"application/vnd.oci.image.layer.v1.tar","digest":"sha256:639c9dd1747f941795c619f445de593cc6d7957060442b3dbe0148bd1be1eeb3","size":23040},{"mediaType":"application/vnd.oci.image.layer.v1.tar","digest":"sha256:082a9ded324a46a5cc7fe15bde1b9d83c03804f0f84eac7ce6bb51229b894f1f","size":8888832},{"mediaType":"application/vnd.oci.image.layer.v1.tar","digest":"sha256:8529443804912d6639846836d1b7ab793de42b54e3b4058e14a059f0d5fe4ade","size":4608},{"mediaType":"application/vnd.oci.image.layer.v1.tar","digest":"sha256:96f3b28657c091e4818e2407f66db33853828fdb8abef3177cdf5c8d525f7dbf","size":4608},{"mediaType":"application/vnd.oci.image.layer.v1.tar","digest":"sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef","size":1024},{"mediaType":"application/vnd.oci.image.layer.v1.tar","digest":"sha256:c0d475ded7d3e60cdc094385f92036f940b605a0438578608e031030a8819ae9","size":4096},{"mediaType":"application/vnd.oci.image.layer.v1.tar","digest":"sha256:53deb2ae079afabdafec52b959453dccca54d8c7eb6315862fcab21d186bcbdd","size":1162240},{"mediaType":"application/vnd.oci.image.layer.v1.tar","digest":"sha256:5116d36f79d2da6aa08f8ffcff866e39d7c0f5be5bbf3d74c6e8c8caebf2c5fd","size":39936}]}
|
image/blobs/sha256/fd7308f35b11a131ac41df34684d400e1400055c0e48edb78f7f3292ce84db55
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"id":"b58135a7607f916cd7221128976d64d0f39fc917e1ba780df8efe3e2c4c7d23a","parent":"f3d345315bfbedaf1b9e3924e84e2a596382cae91d99fac771a0d023a3f0d356","created":"1970-01-01T09:00:00+09:00","container_config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"os":"linux"}
|
image/blobs/sha256/fff7562e27cd6bcd475d31d119da76f39d239cfc59ab03ff6579a8f10ca6e05c
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"id":"155ab0b6484fdeee7919c43f2a38a56151bd05a8b48891fa53929c0e45577105","parent":"12e1b52d50de6740b0ae582760feedf780e2affcaa1c5d15bef6df3f7da931d4","created":"1970-01-01T09:00:00+09:00","container_config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"os":"linux"}
|
image/index.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"schemaVersion":2,"mediaType":"application/vnd.oci.image.index.v1+json","manifests":[{"mediaType":"application/vnd.oci.image.manifest.v1+json","digest":"sha256:ec0a7658dda53cfa39e9a61f8506fce49e56b206fee8ab604f17daa0a8f42f43","size":3615,"annotations":{"io.containerd.image.name":"docker.io/tt-model/locate-anything-3b-blackhole:bc34115d8ab3","org.opencontainers.image.ref.name":"bc34115d8ab3"}}]}
|
image/manifest.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
[{"Config":"blobs/sha256/bc34115d8ab3da3bb2818457b8bc493ed594968b9ae39c48e30c22b37294974b","RepoTags":["tt-model/locate-anything-3b-blackhole:bc34115d8ab3"],"Layers":["blobs/sha256/ea16cace89338c84eb6bcb91a7efdfcae6838fff359efe951858227436486c34","blobs/sha256/e64f34e6f7fc770276a58ce68b18755913e8f6a38b80274ed30b138ba6db8cef","blobs/sha256/3f6ad10d5ba93a17af361223d9d9cd8c53c34d4156cd69af1e9b9af1bebcd4bb","blobs/sha256/5b60873863c0500f341a4c237ab1c18b929b3ac1571a2808b87fcacfdd1f2168","blobs/sha256/0311ceefbd13017ef17eb9844fbfd15250b1bb099d408687eef4372ad2c65ee5","blobs/sha256/661b4446add5adf8c9d4eaab02ab1fe419f17114b8c7a7a381707be7973467e5","blobs/sha256/2f1823fe031c57258362a517aa11e3c4a55eccca738913d0cc87587ccfb6fd1a","blobs/sha256/e1272a58679febd696c70d77b53ffeb43cba62b4ddb3d97dd4e632c6848d2856","blobs/sha256/d1a9879f27dd477b46fe73ced95ea58803d70fc7c2bb42b875c605b8fc744e14","blobs/sha256/184743fecd7fc3deb4e6f457a2a602932fe813f75148eec4b6e75ff88a9f2be2","blobs/sha256/59b37b1999541425b0a7cda1ce01f95f1be228fa97cd09f6631acfb2fab990fd","blobs/sha256/ca297dc8905fb0b70eebf7e9c58d50df4d8d38c5ece2cc866c22798cfc2dfd01","blobs/sha256/4f4c468252314917a1847056077663ed71f3abc1dc386c03bca471690a23c83b","blobs/sha256/c94435d8cb1f57c0296304800fe6e7376c511a75484d5da38e0eceb4a8cba02d","blobs/sha256/639c9dd1747f941795c619f445de593cc6d7957060442b3dbe0148bd1be1eeb3","blobs/sha256/082a9ded324a46a5cc7fe15bde1b9d83c03804f0f84eac7ce6bb51229b894f1f","blobs/sha256/8529443804912d6639846836d1b7ab793de42b54e3b4058e14a059f0d5fe4ade","blobs/sha256/96f3b28657c091e4818e2407f66db33853828fdb8abef3177cdf5c8d525f7dbf","blobs/sha256/5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef","blobs/sha256/c0d475ded7d3e60cdc094385f92036f940b605a0438578608e031030a8819ae9","blobs/sha256/53deb2ae079afabdafec52b959453dccca54d8c7eb6315862fcab21d186bcbdd","blobs/sha256/5116d36f79d2da6aa08f8ffcff866e39d7c0f5be5bbf3d74c6e8c8caebf2c5fd"],"LayerSources":{"sha256:0311ceefbd13017ef17eb9844fbfd15250b1bb099d408687eef4372ad2c65ee5":{"mediaType":"application/vnd.oci.image.layer.v1.tar","size":454126592,"digest":"sha256:0311ceefbd13017ef17eb9844fbfd15250b1bb099d408687eef4372ad2c65ee5"},"sha256:082a9ded324a46a5cc7fe15bde1b9d83c03804f0f84eac7ce6bb51229b894f1f":{"mediaType":"application/vnd.oci.image.layer.v1.tar","size":8888832,"digest":"sha256:082a9ded324a46a5cc7fe15bde1b9d83c03804f0f84eac7ce6bb51229b894f1f"},"sha256:184743fecd7fc3deb4e6f457a2a602932fe813f75148eec4b6e75ff88a9f2be2":{"mediaType":"application/vnd.oci.image.layer.v1.tar","size":130853888,"digest":"sha256:184743fecd7fc3deb4e6f457a2a602932fe813f75148eec4b6e75ff88a9f2be2"},"sha256:2f1823fe031c57258362a517aa11e3c4a55eccca738913d0cc87587ccfb6fd1a":{"mediaType":"application/vnd.oci.image.layer.v1.tar","size":1099616768,"digest":"sha256:2f1823fe031c57258362a517aa11e3c4a55eccca738913d0cc87587ccfb6fd1a"},"sha256:3f6ad10d5ba93a17af361223d9d9cd8c53c34d4156cd69af1e9b9af1bebcd4bb":{"mediaType":"application/vnd.oci.image.layer.v1.tar","size":352256,"digest":"sha256:3f6ad10d5ba93a17af361223d9d9cd8c53c34d4156cd69af1e9b9af1bebcd4bb"},"sha256:4f4c468252314917a1847056077663ed71f3abc1dc386c03bca471690a23c83b":{"mediaType":"application/vnd.oci.image.layer.v1.tar","size":65318400,"digest":"sha256:4f4c468252314917a1847056077663ed71f3abc1dc386c03bca471690a23c83b"},"sha256:5116d36f79d2da6aa08f8ffcff866e39d7c0f5be5bbf3d74c6e8c8caebf2c5fd":{"mediaType":"application/vnd.oci.image.layer.v1.tar","size":39936,"digest":"sha256:5116d36f79d2da6aa08f8ffcff866e39d7c0f5be5bbf3d74c6e8c8caebf2c5fd"},"sha256:53deb2ae079afabdafec52b959453dccca54d8c7eb6315862fcab21d186bcbdd":{"mediaType":"application/vnd.oci.image.layer.v1.tar","size":1162240,"digest":"sha256:53deb2ae079afabdafec52b959453dccca54d8c7eb6315862fcab21d186bcbdd"},"sha256:59b37b1999541425b0a7cda1ce01f95f1be228fa97cd09f6631acfb2fab990fd":{"mediaType":"application/vnd.oci.image.layer.v1.tar","size":130853888,"digest":"sha256:59b37b1999541425b0a7cda1ce01f95f1be228fa97cd09f6631acfb2fab990fd"},"sha256:5b60873863c0500f341a4c237ab1c18b929b3ac1571a2808b87fcacfdd1f2168":{"mediaType":"application/vnd.oci.image.layer.v1.tar","size":33464832,"digest":"sha256:5b60873863c0500f341a4c237ab1c18b929b3ac1571a2808b87fcacfdd1f2168"},"sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef":{"mediaType":"application/vnd.oci.image.layer.v1.tar","size":1024,"digest":"sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef"},"sha256:639c9dd1747f941795c619f445de593cc6d7957060442b3dbe0148bd1be1eeb3":{"mediaType":"application/vnd.oci.image.layer.v1.tar","size":23040,"digest":"sha256:639c9dd1747f941795c619f445de593cc6d7957060442b3dbe0148bd1be1eeb3"},"sha256:661b4446add5adf8c9d4eaab02ab1fe419f17114b8c7a7a381707be7973467e5":{"mediaType":"application/vnd.oci.image.layer.v1.tar","size":187652608,"digest":"sha256:661b4446add5adf8c9d4eaab02ab1fe419f17114b8c7a7a381707be7973467e5"},"sha256:8529443804912d6639846836d1b7ab793de42b54e3b4058e14a059f0d5fe4ade":{"mediaType":"application/vnd.oci.image.layer.v1.tar","size":4608,"digest":"sha256:8529443804912d6639846836d1b7ab793de42b54e3b4058e14a059f0d5fe4ade"},"sha256:96f3b28657c091e4818e2407f66db33853828fdb8abef3177cdf5c8d525f7dbf":{"mediaType":"application/vnd.oci.image.layer.v1.tar","size":4608,"digest":"sha256:96f3b28657c091e4818e2407f66db33853828fdb8abef3177cdf5c8d525f7dbf"},"sha256:c0d475ded7d3e60cdc094385f92036f940b605a0438578608e031030a8819ae9":{"mediaType":"application/vnd.oci.image.layer.v1.tar","size":4096,"digest":"sha256:c0d475ded7d3e60cdc094385f92036f940b605a0438578608e031030a8819ae9"},"sha256:c94435d8cb1f57c0296304800fe6e7376c511a75484d5da38e0eceb4a8cba02d":{"mediaType":"application/vnd.oci.image.layer.v1.tar","size":4678144,"digest":"sha256:c94435d8cb1f57c0296304800fe6e7376c511a75484d5da38e0eceb4a8cba02d"},"sha256:ca297dc8905fb0b70eebf7e9c58d50df4d8d38c5ece2cc866c22798cfc2dfd01":{"mediaType":"application/vnd.oci.image.layer.v1.tar","size":191707136,"digest":"sha256:ca297dc8905fb0b70eebf7e9c58d50df4d8d38c5ece2cc866c22798cfc2dfd01"},"sha256:d1a9879f27dd477b46fe73ced95ea58803d70fc7c2bb42b875c605b8fc744e14":{"mediaType":"application/vnd.oci.image.layer.v1.tar","size":454599168,"digest":"sha256:d1a9879f27dd477b46fe73ced95ea58803d70fc7c2bb42b875c605b8fc744e14"},"sha256:e1272a58679febd696c70d77b53ffeb43cba62b4ddb3d97dd4e632c6848d2856":{"mediaType":"application/vnd.oci.image.layer.v1.tar","size":2048,"digest":"sha256:e1272a58679febd696c70d77b53ffeb43cba62b4ddb3d97dd4e632c6848d2856"},"sha256:e64f34e6f7fc770276a58ce68b18755913e8f6a38b80274ed30b138ba6db8cef":{"mediaType":"application/vnd.oci.image.layer.v1.tar","size":204086784,"digest":"sha256:e64f34e6f7fc770276a58ce68b18755913e8f6a38b80274ed30b138ba6db8cef"},"sha256:ea16cace89338c84eb6bcb91a7efdfcae6838fff359efe951858227436486c34":{"mediaType":"application/vnd.oci.image.layer.v1.tar","size":80641024,"digest":"sha256:ea16cace89338c84eb6bcb91a7efdfcae6838fff359efe951858227436486c34"}}}]
|
image/oci-layout
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"imageLayoutVersion": "1.0.0"}
|
image/repositories
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"tt-model/locate-anything-3b-blackhole":{"bc34115d8ab3":"5116d36f79d2da6aa08f8ffcff866e39d7c0f5be5bbf3d74c6e8c8caebf2c5fd"}}
|
requirements.lock
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
annotated-doc==0.0.5
|
| 2 |
+
annotated-types==0.8.0
|
| 3 |
+
anyio==4.15.1
|
| 4 |
+
certifi==2026.7.22
|
| 5 |
+
cfgv==3.5.0
|
| 6 |
+
charset-normalizer==3.5.1
|
| 7 |
+
click==8.5.0
|
| 8 |
+
contourpy==1.3.3
|
| 9 |
+
cycler==0.12.1
|
| 10 |
+
distlib==0.4.3
|
| 11 |
+
distro==1.9.0
|
| 12 |
+
elastic-transport==9.4.2
|
| 13 |
+
elasticsearch==9.5.1
|
| 14 |
+
fastapi==0.141.1
|
| 15 |
+
filelock==3.32.6
|
| 16 |
+
fonttools==4.65.0
|
| 17 |
+
fsspec==2026.7.0
|
| 18 |
+
graphviz==0.21
|
| 19 |
+
h11==0.16.0
|
| 20 |
+
hf-xet==1.6.0
|
| 21 |
+
httpcore==1.0.9
|
| 22 |
+
httpx==0.28.1
|
| 23 |
+
huggingface_hub==1.31.0
|
| 24 |
+
identify==2.6.19
|
| 25 |
+
idna==3.19
|
| 26 |
+
iniconfig==2.3.0
|
| 27 |
+
Jinja2==3.1.6
|
| 28 |
+
kiwisolver==1.5.1
|
| 29 |
+
linkify-it-py==2.2.0
|
| 30 |
+
loguru==0.7.3
|
| 31 |
+
markdown-it-py==4.2.0
|
| 32 |
+
MarkupSafe==3.0.3
|
| 33 |
+
matplotlib==3.11.2
|
| 34 |
+
mdit-py-plugins==0.6.1
|
| 35 |
+
mdurl==0.1.2
|
| 36 |
+
ml_dtypes==0.5.4
|
| 37 |
+
mpmath==1.3.0
|
| 38 |
+
networkx==3.6.1
|
| 39 |
+
nodeenv==1.10.0
|
| 40 |
+
numpy==1.26.4
|
| 41 |
+
packaging==26.3
|
| 42 |
+
pandas==3.0.5
|
| 43 |
+
pillow==12.3.0
|
| 44 |
+
platformdirs==4.11.8
|
| 45 |
+
pluggy==1.6.0
|
| 46 |
+
pre_commit==4.6.2
|
| 47 |
+
psutil==7.2.2
|
| 48 |
+
pydantic==2.13.5
|
| 49 |
+
pydantic_core==2.46.5
|
| 50 |
+
Pygments==2.21.0
|
| 51 |
+
pyluwen==0.9.0
|
| 52 |
+
pyparsing==3.3.2
|
| 53 |
+
pytest==9.1.1
|
| 54 |
+
python-dateutil==2.9.0.post0
|
| 55 |
+
python-discovery==1.6.0
|
| 56 |
+
PyYAML==6.0.3
|
| 57 |
+
regex==2026.9.10
|
| 58 |
+
requests==2.34.2
|
| 59 |
+
rich==15.0.0
|
| 60 |
+
safetensors==0.8.0
|
| 61 |
+
seaborn==0.13.2
|
| 62 |
+
setuptools==80.10.2
|
| 63 |
+
setuptools-scm==8.1.0
|
| 64 |
+
shellingham==1.5.4
|
| 65 |
+
six==1.17.0
|
| 66 |
+
sniffio==1.3.1
|
| 67 |
+
starlette==1.6.0
|
| 68 |
+
sympy==1.14.0
|
| 69 |
+
textual==8.2.8
|
| 70 |
+
tokenizers==0.22.2
|
| 71 |
+
tomli==2.4.1
|
| 72 |
+
torch==2.11.0+cpu
|
| 73 |
+
tqdm==4.70.1
|
| 74 |
+
transformers==5.12.1
|
| 75 |
+
tt-smi==6.5.0
|
| 76 |
+
tt-tools-common==1.6.0
|
| 77 |
+
tt-umd==0.9.10
|
| 78 |
+
ttnn==0.65.2.dev9100
|
| 79 |
+
ttnn==0.75.0rc10.dev657+g8b98410e730
|
| 80 |
+
typer==0.27.2
|
| 81 |
+
typing-inspection==0.4.4
|
| 82 |
+
typing_extensions==4.16.0
|
| 83 |
+
urllib3==2.7.0
|
| 84 |
+
uvicorn==0.52.4
|
| 85 |
+
virtualenv==21.7.9
|
| 86 |
+
wheel==0.48.0
|
tt_kernel_manifest.json
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"schema_version": "5.1",
|
| 3 |
+
"name": "locate-anything-3b-blackhole",
|
| 4 |
+
"tt_metal_version": "0.65.2.dev9100",
|
| 5 |
+
"arch": "blackhole",
|
| 6 |
+
"device_count": 1,
|
| 7 |
+
"producer": {
|
| 8 |
+
"tt_kernel_version": "0.1.0",
|
| 9 |
+
"created_at": "2026-09-12T06:59:49.276222+00:00",
|
| 10 |
+
"hostname": "deepgadget"
|
| 11 |
+
},
|
| 12 |
+
"weights": {
|
| 13 |
+
"repo_id": "nvidia/LocateAnything-3B",
|
| 14 |
+
"revision": "c32291ca5e996f5a7a485845b4f57a233936bba0",
|
| 15 |
+
"allow_patterns": null,
|
| 16 |
+
"ignore_patterns": [
|
| 17 |
+
"assets/*",
|
| 18 |
+
"training_args.bin"
|
| 19 |
+
],
|
| 20 |
+
"repo_type": "model"
|
| 21 |
+
},
|
| 22 |
+
"mesh": null,
|
| 23 |
+
"entrypoint": null,
|
| 24 |
+
"resources": null,
|
| 25 |
+
"capabilities": null,
|
| 26 |
+
"env": {},
|
| 27 |
+
"bundled": null,
|
| 28 |
+
"deps": null,
|
| 29 |
+
"container": {
|
| 30 |
+
"image": {
|
| 31 |
+
"registry": "hf",
|
| 32 |
+
"repository": "locate-anything-3b-blackhole",
|
| 33 |
+
"tag": "tt-model/locate-anything-3b-blackhole:bc34115d8ab3",
|
| 34 |
+
"digest": "sha256:bc34115d8ab3da3bb2818457b8bc493ed594968b9ae39c48e30c22b37294974b"
|
| 35 |
+
},
|
| 36 |
+
"kind": "tt-dit-server",
|
| 37 |
+
"runtime": {
|
| 38 |
+
"app": "locate_anything.server.app:app",
|
| 39 |
+
"mesh_shape_env": "TT_MESH_SHAPE",
|
| 40 |
+
"packages": [
|
| 41 |
+
"numpy>=1.24.4,<2",
|
| 42 |
+
"transformers==5.12.1",
|
| 43 |
+
"safetensors",
|
| 44 |
+
"huggingface_hub",
|
| 45 |
+
"loguru",
|
| 46 |
+
"tqdm",
|
| 47 |
+
"pytest",
|
| 48 |
+
"pyyaml"
|
| 49 |
+
],
|
| 50 |
+
"lock": "requirements.lock"
|
| 51 |
+
},
|
| 52 |
+
"serve": {
|
| 53 |
+
"hardware": "p150",
|
| 54 |
+
"mesh_device": "P150",
|
| 55 |
+
"port": 20000,
|
| 56 |
+
"max_model_len": null,
|
| 57 |
+
"max_num_seqs": null,
|
| 58 |
+
"block_size": null,
|
| 59 |
+
"server_timeout": null,
|
| 60 |
+
"capabilities": null,
|
| 61 |
+
"additional_config": {},
|
| 62 |
+
"args": [],
|
| 63 |
+
"env": {
|
| 64 |
+
"TT_WEIGHTS_REVISION": "c32291ca5e996f5a7a485845b4f57a233936bba0",
|
| 65 |
+
"TT_METAL_VISIBLE_DEVICES": "0",
|
| 66 |
+
"LA_IN_TOKEN_LIMIT": "1024",
|
| 67 |
+
"LA_PREC": "accuracy",
|
| 68 |
+
"LA_TRACE": "1",
|
| 69 |
+
"LA_WARMUP_RUNS": "2"
|
| 70 |
+
}
|
| 71 |
+
},
|
| 72 |
+
"serve_profiles": [
|
| 73 |
+
{
|
| 74 |
+
"hardware": null,
|
| 75 |
+
"mesh_device": null,
|
| 76 |
+
"port": null,
|
| 77 |
+
"max_model_len": null,
|
| 78 |
+
"max_num_seqs": null,
|
| 79 |
+
"block_size": null,
|
| 80 |
+
"server_timeout": null,
|
| 81 |
+
"capabilities": null,
|
| 82 |
+
"additional_config": {},
|
| 83 |
+
"args": [],
|
| 84 |
+
"env": {},
|
| 85 |
+
"name": "default",
|
| 86 |
+
"description": null
|
| 87 |
+
}
|
| 88 |
+
],
|
| 89 |
+
"default_profile": null,
|
| 90 |
+
"code_dir": "code",
|
| 91 |
+
"verify": [
|
| 92 |
+
"import locate_anything.server.app as a; assert a.app",
|
| 93 |
+
"import locate_anything.tt.pipeline, locate_anything.tt.vision, locate_anything.tt.model_la, locate_anything.reference.la_inputs, locate_anything.reference.extract_llm_checkpoint",
|
| 94 |
+
"import models.tt_transformers.tt.model_config, models.tt_transformers.tt.generator, models.demos.qwen25_vl.tt.common, models.common.utility_functions",
|
| 95 |
+
"import transformers; assert transformers.__version__ == '5.12.1', transformers.__version__",
|
| 96 |
+
"import safetensors, huggingface_hub, loguru, tqdm, pytest, yaml, numpy; assert numpy.__version__.startswith('1.'), numpy.__version__",
|
| 97 |
+
"from pathlib import Path; assert Path('/opt/tt-metal/models/tt_transformers/tt/prefetcher/prefetcher_config.yaml').is_file()",
|
| 98 |
+
"from pathlib import Path; assert Path('/opt/tt-metal/locate_anything/server/smoke_test.py').is_file()",
|
| 99 |
+
"from pathlib import Path; assert 'spill_ff1_3' in Path('/opt/tt-metal/models/tt_transformers/tt/mlp.py').read_text(), 'mlp.py overlay (decode w1/w3 DRAM spill) missing'"
|
| 100 |
+
],
|
| 101 |
+
"built": {
|
| 102 |
+
"image": "tt-model/locate-anything-3b-blackhole:bc34115d8ab3",
|
| 103 |
+
"repo": "changh95/locate-anything-3b-blackhole",
|
| 104 |
+
"tt_model_version": "0.1.0",
|
| 105 |
+
"created_at": "2026-09-12T06:57:00+00:00",
|
| 106 |
+
"tt_metal": {
|
| 107 |
+
"sha": "8b98410e730bb504fea43a88609756e34821d91d",
|
| 108 |
+
"describe": "v0.78.0-dev20260820-25-g8b98410e73",
|
| 109 |
+
"dirty": false,
|
| 110 |
+
"scm_version": "0.65.2.dev9100",
|
| 111 |
+
"mode": "local",
|
| 112 |
+
"remote": "https://github.com/tenstorrent/tt-metal.git",
|
| 113 |
+
"branch": "main",
|
| 114 |
+
"pushed": true
|
| 115 |
+
},
|
| 116 |
+
"code_sha256": "eb3aa8433050cc460c7a398efeb03b287d79aec9d177cda4a18583f71484065a",
|
| 117 |
+
"image_digest": "sha256:bc34115d8ab3da3bb2818457b8bc493ed594968b9ae39c48e30c22b37294974b"
|
| 118 |
+
}
|
| 119 |
+
}
|
| 120 |
+
}
|