changh95 commited on
Commit
0f52070
·
verified ·
1 Parent(s): 6f1ab29

Add files using upload-large-folder tool

Browse files
Files changed (47) hide show
  1. README.md +154 -318
  2. code/models/common/auto_compose.py +161 -0
  3. code/models/common/rmsnorm.py +226 -0
  4. code/models/common/tensor_utils.py +229 -0
  5. code/models/common/validation_tools.py +719 -0
  6. code/models/tt_transformers/Host_Mem_Profile.md +88 -0
  7. code/models/tt_transformers/PERF.md +247 -0
  8. code/models/tt_transformers/README.md +388 -0
  9. code/models/tt_transformers/conftest.py +31 -0
  10. code/models/tt_transformers/host_mem_profiler.py +188 -0
  11. image/blobs/sha256/0690f7dcdac59b821f2eff8a565951a2120a112c6b9613f43be03bb143f8875b +1 -0
  12. image/blobs/sha256/0b3b7bf707349d15afaf4582949a95082c50449ac8e4f7346d1bbee5bc7ba1c5 +1 -0
  13. image/blobs/sha256/18b68d787d3c7446ef9eb0eba334950a837818ace17924cb42e6e6a2fac47a17 +1 -0
  14. image/blobs/sha256/18f46874ca6617cba588e37f39ecd58f44b02065d3c3ea3909c403d2260b686d +1 -0
  15. image/blobs/sha256/1d805657f0ef573b66e654d64007281d8aadf4dfa8aa1eb88672c886293dfe13 +1 -0
  16. image/blobs/sha256/1f179d27e2f48842a37b1dbe6300e0e9d83c174ae4c6d879f38b473d31ff159f +1 -0
  17. image/blobs/sha256/28b873d0d487580ae6a42f1c52c28160516c4f2e4d82abf93e6f6b7c95e49bc7 +1 -0
  18. image/blobs/sha256/3dcb0a4c97491bdc43addf1e7fe76c9dd7a714314fc4729a32cf94c89455a2a5 +1 -0
  19. image/blobs/sha256/4b7d28cf86399d4e9f4f1eeba9a85df52bfc3e360e1c831def2915ad8cff54db +1 -0
  20. image/blobs/sha256/5116d36f79d2da6aa08f8ffcff866e39d7c0f5be5bbf3d74c6e8c8caebf2c5fd +0 -0
  21. image/blobs/sha256/5628e13ce208b83d793af15fa41c28d1702e7a43e27c8c72944442d01e959a71 +1 -0
  22. image/blobs/sha256/5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef +0 -0
  23. image/blobs/sha256/639c9dd1747f941795c619f445de593cc6d7957060442b3dbe0148bd1be1eeb3 +0 -0
  24. image/blobs/sha256/718b6feb51a3973517c6ac89780d58b88478d3ddbdc41353af609f6c944dc085 +1 -0
  25. image/blobs/sha256/77b04a4822168bcd77a83c78c22a390734a35e4232b7c9f2485b2663b5fefb7c +1 -0
  26. image/blobs/sha256/7f2d9782a5ff3e0bf36c4b028cdf5b4e59db0cdf2122cea0669de2841c5d05f7 +1 -0
  27. image/blobs/sha256/8529443804912d6639846836d1b7ab793de42b54e3b4058e14a059f0d5fe4ade +0 -0
  28. image/blobs/sha256/89fcc824b4db414c4ba9f1a86324bd6bfa92505480f7c02fd87f4e3c79ebf1de +1 -0
  29. image/blobs/sha256/8a28dfa1a683cbd7674d79f7ac878f4ba04d0a72bccfe56cec0f0f008b325bdd +1 -0
  30. image/blobs/sha256/96f3b28657c091e4818e2407f66db33853828fdb8abef3177cdf5c8d525f7dbf +0 -0
  31. image/blobs/sha256/bc34115d8ab3da3bb2818457b8bc493ed594968b9ae39c48e30c22b37294974b +1 -0
  32. image/blobs/sha256/c0d475ded7d3e60cdc094385f92036f940b605a0438578608e031030a8819ae9 +0 -0
  33. image/blobs/sha256/cf8ccef7cd12a5a0492c4e3cde07fef8807fe0cd228de6257516ba32f752276c +1 -0
  34. image/blobs/sha256/dfbe9006d67d8efd33cd4834af36a9acd4030ef4f5a9aca44181d9555d590526 +1 -0
  35. image/blobs/sha256/e1272a58679febd696c70d77b53ffeb43cba62b4ddb3d97dd4e632c6848d2856 +0 -0
  36. image/blobs/sha256/e71053098ec0882ae447db33f4d23f6455424ec7cf649519ac98455342a3ffbe +1 -0
  37. image/blobs/sha256/e78a28551be8e30ee61eba8b7627859a67e05827f5119754228edfe4ca005e48 +1 -0
  38. image/blobs/sha256/e94cd641692a2de981d616a078e01282ac9e8cef9fb44bfa26cbab8bc16d9812 +1 -0
  39. image/blobs/sha256/ec0a7658dda53cfa39e9a61f8506fce49e56b206fee8ab604f17daa0a8f42f43 +1 -0
  40. image/blobs/sha256/fd7308f35b11a131ac41df34684d400e1400055c0e48edb78f7f3292ce84db55 +1 -0
  41. image/blobs/sha256/fff7562e27cd6bcd475d31d119da76f39d239cfc59ab03ff6579a8f10ca6e05c +1 -0
  42. image/index.json +1 -0
  43. image/manifest.json +1 -0
  44. image/oci-layout +1 -0
  45. image/repositories +1 -0
  46. requirements.lock +86 -0
  47. 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
- - ttnn
8
- - tt-metal
9
- - tt-nn
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
- # NVIDIA LocateAnything-3B on Tenstorrent Blackhole
22
 
23
- NVIDIA LocateAnything-3B, an Eagle-family visual-grounding / open-vocabulary detection VLM (MoonViT-SO-400M vision tower plus a Qwen2.5-3B-Instruct backbone with an extended detection vocabulary), on a single Blackhole p150a.
24
 
25
- **TT-NN MoonViT tower plus an experimental on-device Parallel Box Decoding (MTP) decoder; overlays a tt-metal checkout.**
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
- Greedy autoregressive decode and the experimental hybrid-MTP path, both running
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
- | Input (`media/demo_input.png`) | AR decode (`media/demo_ar.png`) | Hybrid-MTP (`media/demo_mtp.png`) |
84
- |:---:|:---:|:---:|
85
- | ![](media/demo_input.png) | ![](media/demo_ar.png) | ![](media/demo_mtp.png) |
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
- This repo does **not** vendor the tt-metal monorepo, the model weights, or the
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
- ## Environment setup
121
-
122
- 1. **Build tt-metal** with its Python bindings (and Tracy if you plan to profile).
123
- Instructions: https://github.com/tenstorrent/tt-metal. This is the source of
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
- ```bash
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
- 5. **Generate the torch-CPU goldens** the PCC tests compare against:
164
 
165
- ```bash
166
- python locate_anything/reference/run_reference.py --in-token-limit 1024 # golden.pt
167
- python locate_anything/reference/mtp_oracle.py --in-token-limit 1024 # mtp_oracle.pt (MTP test only)
168
- ```
169
 
170
- ---
171
-
172
- ## Running the tests
 
 
173
 
174
  ```bash
175
- # 1) Vision tower per-stage PCC vs the torch golden (gate ≥ 0.99 on vit_proj)
176
- pytest -svq locate_anything/tests/test_vision.py
177
-
178
- # 2) Baseline benchmark: prefill PCC vs golden + greedy AR decode + metrics
179
- # Prints greppable: inference_speed=, accuracy=, peak_dram=, decode_tok_s=, vision_ms=, prefill_ms=
180
- pytest -svq locate_anything/tests/bench_locate_anything.py
181
-
182
- # 3) Experimental MTP (Parallel Box Decoding): device-MTP vs torch-CPU-MTP logit PCC
183
- pytest -svq locate_anything/tests/test_mtp.py
184
-
185
- # 4) Image → boxes demos (set LA_QUERY / LA_IMAGE / LA_OUT)
186
- LA_QUERY="car" pytest -svq locate_anything/tests/test_demo_visualize.py # greedy AR
187
- LA_QUERY="car" pytest -svq locate_anything/tests/test_demo_mtp_visualize.py # hybrid MTP
188
-
189
- # 5) Tracy-profiled run (requires a Tracy-enabled tt-metal build)
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
- `bench_locate_anything.py` env knobs: `LA_PREC` (`accuracy` default BF16
196
- attention + BFP8 MLP or `bfp8attn`), `LA_TRACE` (`1` default, trace-replay
197
- decode), `LA_VISION` (`device` default, or `golden` to feed the CPU vision golden
198
- and isolate LLM PCC).
199
-
200
- ---
201
-
202
- ## Results
203
-
204
- All numbers are for the fixed golden workload (one image + one query) on a single
205
- p150a, **everything on device** (MoonViT vision + Qwen2.5-3B LLM), warm-measured
206
- with trace-replay decode. The accuracy gate is **PCC 0.99** against the torch-CPU
207
- reference; the decoded box string matches the HF reference.
208
-
209
- ### Accuracy (PCC vs torch-CPU golden)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
210
 
211
  | Stage | PCC |
212
  |---|---:|
213
- | Vision `patch_embed` | 0.99999 |
214
- | Vision `encoder_out` (27 blocks) | 0.9809 |
215
- | Vision `vit_proj` (after `mlp1`) | 0.9911 |
216
- | LLM prefill last-token logits | 0.9922 |
217
- | **Full on-device logits (visionLLM)**| **0.9928** |
218
-
219
- The vision encoder is computed in bf16 with HiFi4 (fp32 dest accumulate); the
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 | **~38 tok/s** |
232
- | Vision (MoonViT + proj) | ~53 ms |
233
- | Prefill | ~64 ms |
234
- | End-to-end | **~2.32 frames/s** |
235
-
236
- Decode is **weight-bandwidth bound** (~3 GB/token streamed), not host-bound which
237
- is why the trace win is large and the second command queue is not.
238
-
239
- ### Optimization trajectory
240
-
241
- Each row was verified to improve throughput while holding PCC ≥ 0.99 (the baseline
242
- row is below the gate and is the starting point, not a kept result). Discarded
243
- experiments are listed below the table.
244
-
245
- | # | Commit | Change | FPS | decode tok/s | PCC |
246
- |---:|---|---|---:|---:|---:|
247
- | 0 | `e99e3bb` | Initial e2e port: Qwen2.5-3B LLM on 1×p150a (perf / BFP4 MLP), CPU vision golden, greedy AR decode | 0.19 | — | 0.935¹ |
248
- | 1 | `e9d4899` | BFP8 MLP (accuracy preset); DRAM-spill decode `w1`/`w3` to fit L1 → meets the gate | 0.57 | 7.5 | 0.992 |
249
- | 2 | `eb03f7b` | Move MoonViT vision + `mlp1` projector on device — full pipeline on one chip | 1.29 | 7.5 | 0.993 |
250
- | 3 | `08af3aa` | Trace-replay decode (5× faster decode) | **2.32** | **38** | 0.993 |
251
-
252
- ¹ Below the 0.99 gate kept only as the bring-up baseline; MLP weight precision
253
- (BFP4→BFP8) dominates LLM accuracy, not attention precision.
254
-
255
- Rejected after measurement:
256
-
257
- - **Second command queue (2CQ).** No gain the stock `tt_transformers` generator
258
- only issues on `cq_id=0`, and decode is device-compute / weight-bandwidth bound.
259
- - **All-BFP8 attention + KV.** Slower *and* lower PCC (0.9928 → 0.9912); BF16
260
- attention is already efficient on Blackhole.
261
- - **MTP / Parallel Box Decoding as the default.** ~60 tok/s over 16 forwards
262
- (~1.7× decode), but greedy MTP is intrinsically approximate — it degenerates
263
- under temperature 0 and does **not** reproduce greedy-AR boxes (NVIDIA's hybrid
264
- mode itself uses sampling). It fails the strict ≥0.99 / match-AR gate, so AR +
265
- trace stays the default. MTP is kept as an optional fast mode whose **device port
266
- is faithful to the torch-CPU MTP** (end-to-end device-vs-torch logit PCC ~0.986).
267
-
268
- **Within the strict ≥0.99-PCC / deterministic-match gate, trace-AR decode
269
- (38 tok/s, 0.9928 PCC, everything on device) is the speed ceiling.**
270
-
271
- ---
272
-
273
- ## Architecture notes
274
-
275
- - **MoonViT-SO-400M** (`tt/vision.py`): hidden 1152, 27 encoder layers, 16 heads
276
- (head_dim 72, padded to 96 for tile alignment), intermediate 4304, patch 14,
277
- GELU-tanh. `Conv2d` patch embed expressed as a single `(588, 1152)` matmul +
278
- host-precomputed bicubic-interpolated 2D position embedding; **interleaved-complex
279
- 2D RoPE** mapped onto `ttnn.experimental.rotary_embedding_llama`; full bidirectional
280
- packed attention via masked SDPA; final LayerNorm; **2×2 patch merge** on host
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
+ | ![](media/demo_input.png) | ![](media/demo_ar.png) |
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
+ }