# SPDX-FileCopyrightText: © 2026 Tenstorrent USA, Inc.
# SPDX-License-Identifier: Apache-2.0
"""``TTWeights``: the device-resident weight set of one (version, embodiment, policy) (IMPLEMENTATION_PLAN §2.2 row
``tt/weights.py``; WP-03).
Pipeline (plan §2.1 row ``build_device_plan``, f1 §6.1, WL §8.2)::
HostPlanCache(cache_root).load_or_build(version, e, plan_dtype_policy(policy), plan_options(policy, version))
-> {name: PlanTensor} (torch bf16, host transforms applied, .pt tier)
per tensor: ttnn.from_torch(t, dtype=dtype_of(t, policy), layout=TILE) (host tilize / bfp8 pack)
ttnn.dump_tensor(
/.tensorbin, host_tensor, mode=LOCAL) (.tensorbin tier, written once)
ttnn.to_device(host_tensor, device, memory_config=DRAM) (DRAM interleaved, persistent)
warm run: ttnn.load_tensor(/.tensorbin, device=device) (no torch, no safetensors)
The ``.tensorbin`` tier lives next to the host tier under the same directory key:
``HostPlanCache.directory(...).parent / "ttnn" / TTPolicy.weights_tag()`` (f1 §6.1 item 1), with a ``manifest.json``
(``common.weights.plan_manifest`` content + the per-tensor device dtype + file facts + the ttnn runtime version) and
a ``.complete`` marker written **last** (v3 semantics of ``models/common/weight_cache.py``): a missing marker, a
manifest identity mismatch, a per-tensor metadata mismatch or a wrong file size => cold path for that tensor.
Measured basis (mb1 §5 Table 5c, 16 x [4096, 8192] = 1.07 GB bf16): cold ``from_torch(device=)`` 0.51 s (host tilize
0.41 s + ``to_device`` 0.068 s at 15.8 GB/s PCIe); ``dump_tensor`` 0.48 s once; warm ``load_tensor(path, device=)``
0.138 s (7.8 GB/s). bfp8: host pack 0.94 s (2.3x slower than tilize), warm load 0.075 s for 0.57 GB.
Shapes follow the plan (f1 §2): 2-D ``[K, N]`` weights and ``[1, N]`` vectors, all TILE (mb1 §4: ROW_MAJOR gamma /
beta cost 2x and a ``[1,1,1,D]`` ROW_MAJOR gamma is rejected), DRAM interleaved. ``memory == "HOST"`` entries (N1.7
``vision.pos_embed_table``) are never uploaded; they are kept as torch tensors (``host(name)``) and cached as ``.pt``.
``ttnn`` is imported lazily inside :class:`TTNNBackend` so that CPU tests import this module without a device; the
backend seam also lets CPU tests exercise the cache / manifest / embodiment-switch logic with a fake backend.
"""
from __future__ import annotations
import json
import os
import time
from dataclasses import dataclass
from pathlib import Path
from typing import Any, Dict, Iterable, List, Mapping, Optional, Sequence, Tuple
import torch
from models.experimental.gr00t.common import checkpoint as checkpoint_mod
from models.experimental.gr00t.common import weights as W
from models.experimental.gr00t.common.configs import (
DIT_QUERY_ROWS_PAD,
HF_SNAPSHOT_SHAS,
TILE,
GR00TConfig,
LayoutConfig,
get_config,
)
from models.experimental.gr00t.tt.policy import (
DEVICE_DTYPES,
TTPolicy,
dtype_of,
plan_dtype_policy,
plan_options,
)
TENSORBIN_FORMAT = "gr00t-ttnn-plan-v1"
TENSORBIN_MARKER = ".complete"
TENSORBIN_MANIFEST = "manifest.json"
TENSORBIN_SUFFIX = ".tensorbin"
HOST_SUFFIX = ".pt"
FORCE_CONVERT_ENV = "GR00T_TT_FORCE_CONVERT"
#: Manifest identity keys (a mismatch in any of them => the whole directory is cold and is rewritten).
_IDENTITY_KEYS: Tuple[str, ...] = (
"format",
"version",
"hf_sha",
"embodiment_id",
"plan_dtype_policy",
"dtype_policy",
"transform_version",
"options",
"arch",
"runtime",
)
#: Per-tensor metadata that must match for a cached file to be reused.
_TENSOR_KEYS: Tuple[str, ...] = ("category", "logical_shape", "layout", "memory", "plan_dtype", "device_dtype")
# --------------------------------------------------------------------------------------------------------------------
# 1. Upload plan (headers only; CPU-testable)
# --------------------------------------------------------------------------------------------------------------------
@dataclass(frozen=True)
class UploadEntry:
"""One plan tensor with its device dtype decided (``PlanEntry`` + :func:`policy.dtype_of`)."""
name: str
category: str
logical_shape: Tuple[int, ...]
plan_dtype: str # dtype the host plan assigns (bf16 | bfp8_b | fp32)
device_dtype: str # dtype uploaded under the TTPolicy
layout: str # TILE | ROW_MAJOR
memory: str # DRAM | HOST
@property
def nbytes(self) -> float:
"""Tile-padded device bytes (WL §5 convention; 0 for host-only tensors)."""
if self.memory == "HOST":
return 0.0
return W.device_bytes(self.logical_shape, self.device_dtype, self.layout)
@property
def file_name(self) -> str:
return self.name + (HOST_SUFFIX if self.memory == "HOST" else TENSORBIN_SUFFIX)
def meta(self) -> Dict[str, Any]:
return {
"name": self.name,
"category": self.category,
"logical_shape": list(self.logical_shape),
"plan_dtype": self.plan_dtype,
"device_dtype": self.device_dtype,
"layout": self.layout,
"memory": self.memory,
"device_bytes": self.nbytes,
}
def upload_plan(
version: str,
embodiment_id: Optional[int],
policy: TTPolicy,
options: Optional[W.TransformOptions] = None,
categories: Optional[Iterable[str]] = None,
names: Optional[Iterable[str]] = None,
) -> Dict[str, UploadEntry]:
"""Every plan tensor of ``version`` with its device dtype under ``policy`` (no weight is read).
The enumeration uses the host plan policy :func:`plan_dtype_policy` (so the ``mixed`` candidates are flagged) and
can be restricted by ``categories`` / ``names`` exactly like ``common.weights.build_device_plan`` (unknown values
raise). Order: sorted by ``(category, name)`` -- the deterministic upload order.
"""
opts = options if options is not None else plan_options(policy, version)
meta = W.enumerate_plan(version, embodiment_id, plan_dtype_policy(policy), opts)
wanted = set(meta)
if categories is not None:
cats = set(categories)
unknown = cats - set(W.CATEGORIES)
if unknown:
raise KeyError(f"unknown categories {sorted(unknown)}")
wanted = {n for n in wanted if meta[n].category in cats}
if names is not None:
req = set(names)
missing = req - set(meta)
if missing:
raise KeyError(f"unknown plan tensor names {sorted(missing)[:5]}")
wanted &= req
out: Dict[str, UploadEntry] = {}
for name in sorted(wanted, key=lambda n: (meta[n].category, n)):
e = meta[name]
dd = dtype_of(e, policy)
if dd not in DEVICE_DTYPES:
raise ValueError(f"{name}: dtype decision {dd!r} not in {DEVICE_DTYPES}")
out[name] = UploadEntry(
name=name,
category=e.category,
logical_shape=tuple(int(d) for d in e.shape),
plan_dtype=e.dtype,
device_dtype=dd,
layout=e.layout,
memory=e.memory,
)
return out
def upload_byte_summary(entries: Mapping[str, UploadEntry]) -> Dict[str, Any]:
"""Per-category / per-dtype device bytes of an upload plan (token table and host tensors excluded, WL §6.1)."""
cats: Dict[str, Dict[str, float]] = {}
by_dtype: Dict[str, Dict[str, float]] = {}
total = 0.0
n = 0
for e in entries.values():
b = e.nbytes
c = cats.setdefault(e.category, {"count": 0, "bytes": 0.0, "mib": 0.0})
c["count"] += 1
c["bytes"] += b
c["mib"] = c["bytes"] / W.MIB
if e.memory == "HOST" or e.category == "llm_embed":
continue
d = by_dtype.setdefault(e.device_dtype, {"count": 0, "bytes": 0.0, "mib": 0.0})
d["count"] += 1
d["bytes"] += b
d["mib"] = d["bytes"] / W.MIB
total += b
n += 1
return {
"categories": cats,
"by_dtype": dict(sorted(by_dtype.items())),
"total_bytes": total,
"total_mib": total / W.MIB,
"n_tensors": n,
}
# --------------------------------------------------------------------------------------------------------------------
# 2. Backend seam (ttnn imported lazily)
# --------------------------------------------------------------------------------------------------------------------
class TTNNBackend:
"""The real backend: thin wrappers over the ``ttnn`` calls of the module docstring."""
def __init__(self) -> None:
import ttnn # lazy: never at module import (plan §2.1 rules)
self.ttnn = ttnn
self._dtypes = {"bf16": ttnn.bfloat16, "bfp8_b": ttnn.bfloat8_b, "fp32": ttnn.float32}
self._layouts = {"TILE": ttnn.TILE_LAYOUT, "ROW_MAJOR": ttnn.ROW_MAJOR_LAYOUT}
def runtime_tag(self) -> str:
"""``ttnn`` distribution version (carries the git hash, e.g. ``0.75.0rc10.dev1568+g668c2907575``)."""
try:
import importlib.metadata as md
return "ttnn-" + md.version("ttnn")
except Exception: # noqa: BLE001 - metadata absent in some source-tree layouts
v = getattr(self.ttnn, "__version__", None)
if not v:
raise RuntimeError("cannot determine the ttnn version for the tensorbin manifest")
return "ttnn-" + str(v)
def from_torch_host(self, t: torch.Tensor, dtype: str, layout: str):
if dtype not in self._dtypes:
raise ValueError(f"unknown device dtype {dtype!r}")
if layout not in self._layouts:
raise ValueError(f"unknown layout {layout!r}")
return self.ttnn.from_torch(t, dtype=self._dtypes[dtype], layout=self._layouts[layout])
def dump(self, path: Path, host_tensor) -> None:
self.ttnn.dump_tensor(str(path), host_tensor, mode=self.ttnn.DumpTensorMode.LOCAL)
def load(self, path: Path, device):
return self.ttnn.load_tensor(str(path), device=device)
def to_device(self, host_tensor, device):
return self.ttnn.to_device(host_tensor, device, memory_config=self.ttnn.DRAM_MEMORY_CONFIG)
def to_torch(self, tensor) -> torch.Tensor:
return self.ttnn.to_torch(tensor)
def copy_into(self, src, dst) -> None:
"""``ttnn.copy(input_a, input_b)``: copies ``src`` into ``dst`` in place (same shape / dtype / layout)."""
self.ttnn.copy(src, dst)
def deallocate(self, tensor) -> None:
self.ttnn.deallocate(tensor)
def synchronize(self, device) -> None:
if device is not None:
self.ttnn.synchronize_device(device)
def describe(self, tensor) -> Dict[str, Any]:
mc = tensor.memory_config()
return {
"shape": list(tensor.shape),
"padded_shape": list(tensor.padded_shape),
"dtype": str(tensor.dtype),
"layout": str(tensor.layout),
"buffer_type": str(mc.buffer_type),
"memory_layout": str(mc.memory_layout),
}
# --------------------------------------------------------------------------------------------------------------------
# 3. TTWeights
# --------------------------------------------------------------------------------------------------------------------
def tensorbin_directory(
host_cache: W.HostPlanCache, version: str, embodiment_id: int, policy: TTPolicy, options: W.TransformOptions
) -> Path:
"""``HostPlanCache.directory(...).parent / "ttnn" / policy.weights_tag()`` (f1 §6.1 item 1)."""
return (
host_cache.directory(version, embodiment_id, plan_dtype_policy(policy), options).parent
/ "ttnn"
/ policy.weights_tag()
)
def hoist_lengths(layout: LayoutConfig) -> Tuple[int, ...]:
"""Padded key lengths of the cross K/V hoist buffers of ``layout`` (plan §2.2 row ``tt/adapter.py``): the padded
half of ``cross_text_keys`` / ``cross_image_keys`` / ``cross_all_keys`` that are not None, ascending, unique."""
out = set()
for keys in (layout.cross_text_keys, layout.cross_image_keys, layout.cross_all_keys):
if keys is not None:
padded = int(keys[1])
if padded <= 0 or padded % TILE:
raise ValueError(f"{layout.name}: padded key length {padded} is not a positive multiple of {TILE}")
out.add(padded)
if not out:
raise ValueError(f"{layout.name}: no cross key set defined")
return tuple(sorted(out))
def rope_transformation_matrix(dhead: int = TILE) -> torch.Tensor:
"""``[1,1,32,32]`` transformation matrix of ``ttnn.experimental.rotary_embedding_llama`` (D8): ``+1`` at
``(2i, 2i+1)``, ``-1`` at ``(2i+1, 2i)`` (``models/common/tensor_utils.py::get_rot_transformation_mat``)."""
if dhead != TILE:
raise ValueError(f"the rotary_embedding_llama transformation matrix is one tile ({TILE}), got {dhead}")
m = torch.zeros(1, 1, dhead, dhead, dtype=torch.float32)
m[..., torch.arange(0, dhead, 2), torch.arange(1, dhead, 2)] = 1.0
m[..., torch.arange(1, dhead, 2), torch.arange(0, dhead, 2)] = -1.0
return m.to(torch.bfloat16)
def _as_layout(cfg: GR00TConfig, layout: Any) -> LayoutConfig:
"""Accept a ``LayoutConfig``, a layout name, or a ``tt/layout.py`` ``DeviceLayout`` (WP-02: carries
``layout_name`` and ``version``; an object exposing a ``.layout`` ``LayoutConfig`` is accepted too) -- an adapter
so this WP does not import WP-02's class."""
if isinstance(layout, LayoutConfig):
return layout
if isinstance(layout, str):
return cfg.layout(layout)
inner = getattr(layout, "layout", None)
if isinstance(inner, LayoutConfig):
return inner
name = getattr(layout, "layout_name", None)
if isinstance(name, str):
version = getattr(layout, "version", cfg.version)
if version != cfg.version:
raise ValueError(f"DeviceLayout is for {version}, weights are for {cfg.version}")
return cfg.layout(name)
raise TypeError(f"expected a LayoutConfig, a layout name or a DeviceLayout (layout_name), got {type(layout)}")
class TTWeights:
"""Device-resident plan tensors of one (version, embodiment, policy); build with :meth:`load`.
Public API (plan §2.2): ``get(name)``, ``host(name)``, ``names()``, ``host_names()``, ``by_category()``,
``embed_rows(input_ids_padded, image_slots)``, ``constants(layout)``, ``switch_embodiment(e)``, ``release()``;
facts: ``version``, ``embodiment_id``, ``policy``, ``options``, ``plan_dtype_policy``, ``entries`` (name ->
:class:`UploadEntry`), ``tensorbin_dir``, ``load_stats``, ``device_bytes``.
"""
def __init__(
self,
version: str,
embodiment_id: int,
policy: TTPolicy,
device: Any,
options: W.TransformOptions,
host_cache: W.HostPlanCache,
backend: Any,
) -> None:
self.version = version
self.cfg: GR00TConfig = get_config(version)
if not 0 <= int(embodiment_id) < self.cfg.encoders.max_num_embodiments:
raise IndexError(f"embodiment id {embodiment_id} out of range")
self.embodiment_id = int(embodiment_id)
self.policy = policy
self.device = device
self.options = options
self.plan_dtype_policy = plan_dtype_policy(policy)
self.host_cache = host_cache
self.backend = backend
self.tensorbin_dir: Path = tensorbin_directory(host_cache, version, self.embodiment_id, policy, options)
self.entries: Dict[str, UploadEntry] = {}
self._tensors: Dict[str, Any] = {}
self._host: Dict[str, torch.Tensor] = {}
self._constants: Dict[str, Dict[str, Any]] = {}
self._embed_table: Optional[torch.Tensor] = None
self.load_stats: Dict[str, Any] = {}
# ------------------------------------------------------------------ construction
@classmethod
def load(
cls,
version: str,
embodiment_id: Optional[int],
policy: TTPolicy,
device: Any,
cache_root: Optional[Path] = None,
categories: Optional[Iterable[str]] = None,
names: Optional[Iterable[str]] = None,
*,
layout_name: Optional[str] = None,
backend: Any = None,
force_convert: bool = False,
) -> "TTWeights":
"""Upload (or warm-load) the plan tensors of ``version`` / ``embodiment_id`` under ``policy`` to ``device``.
* ``embodiment_id=None`` -> the config's canonical embodiment.
* ``categories`` / ``names`` restrict the upload (tests, partial loads); the ``.tensorbin`` tier is per tensor
so a later full load reuses whatever a partial load wrote.
* ``layout_name`` selects the layout whose ``S_pad`` decides ``gate_up_layout="auto"`` (default canonical).
* ``force_convert`` (or ``GR00T_TT_FORCE_CONVERT=1``) ignores both cache tiers.
* ``backend`` defaults to :class:`TTNNBackend`; CPU tests inject a fake.
"""
cfg = get_config(version)
e = cfg.canonical_embodiment_id if embodiment_id is None else int(embodiment_id)
if not isinstance(policy, TTPolicy):
raise TypeError(f"policy must be a TTPolicy, got {type(policy).__name__}")
opts = plan_options(policy, version, layout_name)
host_cache = W.HostPlanCache(cache_root)
be = backend if backend is not None else TTNNBackend()
self = cls(version, e, policy, device, opts, host_cache, be)
force = bool(force_convert) or os.environ.get(FORCE_CONVERT_ENV, "0") == "1"
self._load(categories, names, force)
return self
def _load(self, categories: Optional[Iterable[str]], names: Optional[Iterable[str]], force: bool) -> None:
t_start = time.perf_counter()
full_request = categories is None and names is None
full_entries = upload_plan(self.version, self.embodiment_id, self.policy, self.options)
wanted = (
full_entries
if full_request
else upload_plan(self.version, self.embodiment_id, self.policy, self.options, categories, names)
)
if not wanted:
raise ValueError("the requested categories / names select no plan tensor")
self.entries = dict(wanted)
expected_identity = self._identity()
manifest = None if force else self._read_manifest(expected_identity)
warm: List[str] = []
cold: List[str] = []
for name, entry in wanted.items():
if manifest is not None and self._file_is_warm(manifest, entry):
warm.append(name)
else:
cold.append(name)
# --- warm tensors: .tensorbin straight to DRAM (no torch, no safetensors)
t0 = time.perf_counter()
for name in warm:
entry = wanted[name]
path = self.tensorbin_dir / entry.file_name
if entry.memory == "HOST":
self._host[name] = torch.load(path, map_location="cpu", weights_only=True)
else:
self._tensors[name] = self.backend.load(path, self.device)
self.backend.synchronize(self.device)
t_warm = time.perf_counter() - t0
# --- cold tensors: host plan -> tilize/pack -> dump -> upload
t_host = 0.0
t_cold = 0.0
file_facts: Dict[str, Dict[str, Any]] = {}
if cold:
t0 = time.perf_counter()
plan = self._host_plan(self.embodiment_id, cold, full_request, force)
t_host = time.perf_counter() - t0
t0 = time.perf_counter()
self.tensorbin_dir.mkdir(parents=True, exist_ok=True)
for name in cold:
entry = wanted[name]
pt = plan[name]
self._check_plan_tensor(entry, pt)
path = self.tensorbin_dir / entry.file_name
if entry.memory == "HOST":
torch.save(pt.tensor.contiguous(), path)
self._host[name] = pt.tensor
else:
host_t = self.backend.from_torch_host(pt.tensor, entry.device_dtype, entry.layout)
self.backend.dump(path, host_t)
self._tensors[name] = self.backend.to_device(host_t, self.device)
file_facts[name] = {"file": path.name, "file_bytes": int(path.stat().st_size)}
self.backend.synchronize(self.device)
t_cold = time.perf_counter() - t0
self._write_manifest(full_entries, expected_identity, manifest, file_facts)
n_dev = sum(1 for n in wanted if wanted[n].memory != "HOST")
self.load_stats = {
"path": "warm" if not cold else ("cold" if not warm else "partial"),
"seconds": time.perf_counter() - t_start,
"warm_load_s": t_warm,
"host_plan_s": t_host,
"convert_dump_upload_s": t_cold,
"n_warm": len(warm),
"n_cold": len(cold),
"n_device_tensors": n_dev,
"n_host_tensors": len(wanted) - n_dev,
"device_bytes": self.device_bytes,
"tensorbin_dir": str(self.tensorbin_dir),
"runtime": expected_identity["runtime"],
"forced": bool(force),
}
def _host_plan(self, embodiment_id: int, names: Sequence[str], full_request: bool, force: bool) -> W.DevicePlan:
"""Host plan tensors for ``names`` of embodiment ``embodiment_id``: the complete ``.pt`` tier when present,
else ``load_or_build`` for a full request (which populates the ``.pt`` tier), else a partial build."""
d = self.host_cache.directory(self.version, embodiment_id, self.plan_dtype_policy, self.options)
if not force and self.host_cache.is_complete(d):
return self.host_cache.load(d, names=names)
if full_request:
return self.host_cache.load_or_build(
self.version, embodiment_id, self.plan_dtype_policy, self.options, force_convert=force
)
return W.build_device_plan(
self.version, embodiment_id, self.plan_dtype_policy, options=self.options, names=names
)
@staticmethod
def _check_plan_tensor(entry: UploadEntry, pt: W.PlanTensor) -> None:
if tuple(pt.tensor.shape) != entry.logical_shape:
raise ValueError(f"{entry.name}: host tensor shape {tuple(pt.tensor.shape)} != plan {entry.logical_shape}")
if pt.dtype != entry.plan_dtype or pt.layout != entry.layout or pt.memory != entry.memory:
raise ValueError(
f"{entry.name}: host plan metadata ({pt.dtype}, {pt.layout}, {pt.memory}) != enumerated "
f"({entry.plan_dtype}, {entry.layout}, {entry.memory})"
)
want_torch = torch.float32 if entry.plan_dtype == "fp32" else torch.bfloat16
if pt.tensor.dtype != want_torch:
raise TypeError(f"{entry.name}: host tensor is {pt.tensor.dtype}, expected {want_torch}")
# ------------------------------------------------------------------ manifest / marker
def _identity(self) -> Dict[str, Any]:
from dataclasses import asdict
return {
"format": TENSORBIN_FORMAT,
"version": self.version,
"hf_sha": HF_SNAPSHOT_SHAS[self.version],
"embodiment_id": self.embodiment_id,
"plan_dtype_policy": self.plan_dtype_policy,
"dtype_policy": self.policy.dtype_policy,
"transform_version": W.TRANSFORM_VERSION,
"options": asdict(self.options),
"arch": self.host_cache.arch,
"runtime": self.backend.runtime_tag(),
}
def is_complete(self) -> bool:
marker = self.tensorbin_dir / TENSORBIN_MARKER
if not marker.is_file() or not (self.tensorbin_dir / TENSORBIN_MANIFEST).is_file():
return False
try:
return marker.read_text().strip() == TENSORBIN_FORMAT
except OSError:
return False
def _read_manifest(self, expected_identity: Mapping[str, Any]) -> Optional[Dict[str, Any]]:
"""The manifest when the marker is present and the identity matches; otherwise None (cold directory)."""
if not self.is_complete():
return None
try:
with open(self.tensorbin_dir / TENSORBIN_MANIFEST) as fh:
m = json.load(fh)
except (OSError, ValueError):
return None
if any(m.get(k) != expected_identity[k] for k in _IDENTITY_KEYS):
return None
if not isinstance(m.get("tensors"), dict):
return None
return m
def _file_is_warm(self, manifest: Mapping[str, Any], entry: UploadEntry) -> bool:
rec = manifest["tensors"].get(entry.name)
if rec is None or rec.get("file_bytes") is None:
return False
meta = entry.meta()
if any(rec.get(k) != meta[k] for k in _TENSOR_KEYS):
return False
path = self.tensorbin_dir / entry.file_name
if rec.get("file") != path.name:
return False
return path.is_file() and path.stat().st_size == int(rec["file_bytes"])
def _write_manifest(
self,
full_entries: Mapping[str, UploadEntry],
identity: Mapping[str, Any],
previous: Optional[Mapping[str, Any]],
file_facts: Mapping[str, Mapping[str, Any]],
) -> Dict[str, Any]:
"""Rewrite the manifest for the whole plan (file facts for the tensors on disk) then the marker, last.
With no valid previous manifest the directory is reset (stale ``.tensorbin`` / ``.pt`` files of a different
identity are removed) so a marker never outlives files it does not describe (WL §8.2 item 2)."""
directory = self.tensorbin_dir
directory.mkdir(parents=True, exist_ok=True)
marker = directory / TENSORBIN_MARKER
if marker.exists():
marker.unlink()
if previous is None:
keep = {full_entries[n].file_name for n in file_facts}
for p in directory.iterdir():
if p.is_file() and p.suffix in (TENSORBIN_SUFFIX, HOST_SUFFIX) and p.name not in keep:
p.unlink()
tensors: Dict[str, Any] = {}
total = 0
n_files = 0
for name, entry in full_entries.items():
rec = entry.meta()
rec["file"] = entry.file_name
rec["file_bytes"] = None
if name in file_facts:
rec["file_bytes"] = int(file_facts[name]["file_bytes"])
elif previous is not None and self._file_is_warm(previous, entry):
rec["file_bytes"] = int(previous["tensors"][name]["file_bytes"])
if rec["file_bytes"] is not None:
total += rec["file_bytes"]
n_files += 1
tensors[name] = rec
manifest: Dict[str, Any] = dict(identity)
manifest.update(
{
"policy": self.policy.to_dict(),
"n_tensors": len(tensors),
"n_files": n_files,
"file_bytes_total": total,
"device_bytes_total": upload_byte_summary(full_entries)["total_bytes"],
"complete": n_files == len(tensors),
"tensors": tensors,
}
)
with open(directory / TENSORBIN_MANIFEST, "w") as fh:
json.dump(manifest, fh, indent=1, sort_keys=True)
marker.write_text(TENSORBIN_FORMAT + "\n")
return manifest
def manifest(self) -> Dict[str, Any]:
"""The manifest on disk (raises when the directory is not complete)."""
if not self.is_complete():
raise FileNotFoundError(f"{self.tensorbin_dir}: no complete tensorbin tier")
with open(self.tensorbin_dir / TENSORBIN_MANIFEST) as fh:
return json.load(fh)
# ------------------------------------------------------------------ access
def get(self, name: str):
"""Device tensor ``name`` (``KeyError`` for unknown names; host-only entries point to :meth:`host`)."""
try:
return self._tensors[name]
except KeyError:
if name in self._host:
raise KeyError(f"{name!r} is a host-only plan tensor; use host({name!r})") from None
raise KeyError(f"unknown or not-loaded plan tensor {name!r}") from None
def host(self, name: str) -> torch.Tensor:
try:
return self._host[name]
except KeyError:
raise KeyError(f"unknown or not-loaded host plan tensor {name!r}") from None
def __contains__(self, name: object) -> bool:
return name in self._tensors
def __len__(self) -> int:
return len(self._tensors)
def names(self) -> List[str]:
return sorted(self._tensors)
def host_names(self) -> List[str]:
return sorted(self._host)
def by_category(self) -> Dict[str, List[str]]:
out: Dict[str, List[str]] = {}
for name in self.names():
out.setdefault(self.entries[name].category, []).append(name)
return out
@property
def device_bytes(self) -> float:
return float(sum(self.entries[n].nbytes for n in self._tensors))
def dtype_histogram(self) -> Dict[str, int]:
out: Dict[str, int] = {}
for n in self._tensors:
d = self.entries[n].device_dtype
out[d] = out.get(d, 0) + 1
return dict(sorted(out.items()))
# ------------------------------------------------------------------ host gather of token rows
def _embed_table_tensor(self) -> torch.Tensor:
"""The bf16 ``embed_tokens`` table ``[V, 2048]``, read lazily from the checkpoint on first use (WL §4.4 option
A: host gather; the resident-table + ``ttnn.embedding`` alternative is the WP-P lever)."""
if self._embed_table is None:
ck = checkpoint_mod.LazyCheckpoint(self.version)
key = self.cfg.checkpoint.llm_prefix + "embed_tokens.weight"
table = ck.get(key)
want = (self.cfg.llm.vocab, self.cfg.llm.hidden)
if tuple(table.shape) != want or table.dtype != torch.bfloat16:
raise ValueError(f"{key}: shape/dtype {tuple(table.shape)}/{table.dtype} != {want}/bf16")
self._embed_table = table
return self._embed_table
def embed_rows(self, input_ids_padded: torch.Tensor, image_slots: Any = None) -> torch.Tensor:
"""Token-embedding rows of a padded prompt: ``[1,1,S_pad,2048]`` bf16 (plan §3.1 host per call).
``input_ids_padded`` is ``SlotLayout.input_ids_padded`` ``(1, S_pad)``; ``image_slots`` is a ``SlotLayout`` /
``LayoutConfig`` (their ``.image_slots``) or a sequence of half-open ``(lo, hi)`` runs whose rows are zeroed
(they are replaced by vision rows on device, ``TokenSplicer``); ``None`` zeroes nothing. Exact gather
(f1 §0: embed-row gather exact 3/3).
"""
ids = torch.as_tensor(input_ids_padded)
if ids.ndim != 2 or ids.shape[0] != 1:
raise ValueError(f"input_ids_padded must be (1, S_pad), got {tuple(ids.shape)}")
s_pad = int(ids.shape[1])
if s_pad % TILE:
raise ValueError(f"S_pad={s_pad} is not a multiple of {TILE}")
table = self._embed_table_tensor()
rows = W.embed_rows(table, ids.long()).clone() # [1, S_pad, D], owns its bytes
slots: Tuple[Tuple[int, int], ...]
if image_slots is None:
slots = ()
elif hasattr(image_slots, "image_slots"):
slots = tuple(tuple(int(x) for x in run) for run in image_slots.image_slots)
else:
slots = tuple(tuple(int(x) for x in run) for run in image_slots)
for lo, hi in slots:
if not 0 <= lo < hi <= s_pad:
raise ValueError(f"image slot ({lo}, {hi}) outside [0, {s_pad})")
rows[:, lo:hi] = 0
return rows.reshape(1, 1, s_pad, table.shape[1]).to(torch.bfloat16)
# ------------------------------------------------------------------ constants
def _action_rows(self, layout: LayoutConfig) -> Tuple[int, int]:
"""``[M-H, M)``: the rows of the logical-64 DiT stream that hold the action tokens (plan §2.2 rows
``tt/encoders.py``: ``noise_to_xt`` / ``b3_pos_rows`` / Euler row mask)."""
m = self.cfg.dit.n_query_tokens
h = self.cfg.encoders.action_horizon
if (
layout.dit_m_logical != m
or layout.dit_m_pad != DIT_QUERY_ROWS_PAD
or self.cfg.dit.m_pad != DIT_QUERY_ROWS_PAD
):
raise ValueError(
f"{layout.name}: dit_m_logical/dit_m_pad {layout.dit_m_logical}/{layout.dit_m_pad} != {m}/{DIT_QUERY_ROWS_PAD}"
)
if not 0 < h <= m:
raise ValueError(f"action horizon {h} does not fit in {m} query tokens")
return m - h, m
def b3_pos_rows_host(self, layout: LayoutConfig, b3_pos: Optional[torch.Tensor] = None) -> torch.Tensor:
"""``[1,1,64,1536]``: ``enc.action.b3_pos`` (``b3 + position_embedding[0:H]``, f1 §2) at rows ``M-H..M``,
zeros elsewhere, in the precompute dtype."""
lo, hi = self._action_rows(layout)
src = b3_pos if b3_pos is not None else self.backend.to_torch(self.get("enc.action.b3_pos"))
emb = self.cfg.encoders.input_embedding_dim
if tuple(src.shape) != (hi - lo, emb):
raise ValueError(f"enc.action.b3_pos shape {tuple(src.shape)} != {(hi - lo, emb)}")
want = torch.float32 if self.policy.precompute_dtype == "fp32" else torch.bfloat16
out = torch.zeros(1, 1, DIT_QUERY_ROWS_PAD, emb, dtype=want)
out[0, 0, lo:hi] = src.to(want)
return out
def euler_row_mask_host(self, layout: LayoutConfig) -> torch.Tensor:
"""``[1,1,64,A_pad]`` bf16: 1 on the action rows ``M-H..M`` (``cfg.dit.velocity_rows`` of the decoder output),
0 on the state / future-token / pad rows, so ``x_t += dt * (v * mask)`` runs on all 64 rows (plan §2.2 row
``tt/encoders.py`` ``EulerUpdate``)."""
lo, hi = self._action_rows(layout)
vr = self.cfg.dit.velocity_rows
if vr.start != lo or vr.stop is not None:
raise ValueError(f"cfg.dit.velocity_rows {vr} disagrees with the action rows [{lo}, {hi})")
out = torch.zeros(1, 1, DIT_QUERY_ROWS_PAD, self.cfg.encoders.action_dim_pad, dtype=torch.bfloat16)
out[0, 0, lo:hi] = 1.0
return out
def constants(self, layout: Any) -> Dict[str, Any]:
"""Constant device tensors of one static layout (bf16 TILE DRAM), built once per layout name and cached:
* ``trans_mat`` ``[1,1,32,32]`` for ``rotary_embedding_llama`` (:func:`rope_transformation_matrix`, D8);
* ``q_dummy_`` ``[1,1,L_pad,2048]`` zeros per hoist length (D7: ``nlp_create_qkv_heads(q_dummy,
input_kv=kv)`` needs an equal-S Q; 2048 = 32 heads x 64 padded head dim);
* ``euler_row_mask`` ``[1,1,64,A_pad]`` (:meth:`euler_row_mask_host`);
* ``b3_pos_rows`` ``[1,1,64,1536]`` (:meth:`b3_pos_rows_host`; refreshed in place by :meth:`switch_embodiment`).
``layout`` is a ``LayoutConfig``, its name, or an object with a ``.layout`` ``LayoutConfig`` (``DeviceLayout``).
The attention masks belong to ``tt/layout.py`` (WP-02) and are not built here.
"""
lay = _as_layout(self.cfg, layout)
if lay.name in self._constants:
return self._constants[lay.name]
inner = self.cfg.dit.n_heads * self.cfg.dit.head_dim_pad
host: Dict[str, torch.Tensor] = {"trans_mat": rope_transformation_matrix()}
for l_pad in hoist_lengths(lay):
host[f"q_dummy_{l_pad}"] = torch.zeros(1, 1, l_pad, inner, dtype=torch.bfloat16)
host["euler_row_mask"] = self.euler_row_mask_host(lay)
host["b3_pos_rows"] = self.b3_pos_rows_host(lay)
out: Dict[str, Any] = {}
for key, t in host.items():
dtype = "fp32" if t.dtype == torch.float32 else "bf16"
out[key] = self.backend.to_device(self.backend.from_torch_host(t, dtype, "TILE"), self.device)
self.backend.synchronize(self.device)
self._constants[lay.name] = out
return out
# ------------------------------------------------------------------ embodiment switch
def encoder_names(self) -> List[str]:
return [n for n in self.names() if self.entries[n].category == "encoders"]
def switch_embodiment(self, embodiment_id: int) -> Dict[str, Any]:
"""Re-point the resident encoder buffers at embodiment ``embodiment_id`` **in place** (``ttnn.copy`` into the
existing DRAM buffers, so trace addresses stay valid; WL §8.2 item 5).
Only category ``encoders`` is rebuilt (the ``.pt`` tier of the new slot when complete, else a partial build
of that category); every shape / dtype must match the resident buffer (raise otherwise). ``b3_pos_rows`` of
every materialised :meth:`constants` set is refreshed the same way. Returns the switch statistics.
"""
e = int(embodiment_id)
if not 0 <= e < self.cfg.encoders.max_num_embodiments:
raise IndexError(f"embodiment id {e} out of range [0, {self.cfg.encoders.max_num_embodiments})")
enc = self.encoder_names()
full_enc = set(
upload_plan(self.version, self.embodiment_id, self.policy, self.options, categories=("encoders",))
)
if not enc or set(enc) != full_enc:
raise RuntimeError(
f"switch_embodiment needs the complete 'encoders' category resident ({len(enc)}/{len(full_enc)} "
"tensors loaded); load with categories including 'encoders'"
)
t0 = time.perf_counter()
plan = self._host_plan(e, enc, full_request=False, force=False)
missing = set(enc) - set(plan)
if missing:
raise KeyError(f"encoder plan of embodiment {e} lacks {sorted(missing)[:5]}")
t_host = time.perf_counter() - t0
t0 = time.perf_counter()
n_bytes = 0.0
for name in enc:
entry = self.entries[name]
pt = plan[name]
self._check_plan_tensor(entry, pt)
staged = self.backend.to_device(
self.backend.from_torch_host(pt.tensor, entry.device_dtype, entry.layout), self.device
)
self.backend.copy_into(staged, self._tensors[name])
self.backend.deallocate(staged)
n_bytes += entry.nbytes
b3 = plan["enc.action.b3_pos"].tensor if "enc.action.b3_pos" in plan else None
for lay_name, consts in self._constants.items():
if "b3_pos_rows" in consts:
if b3 is None:
raise RuntimeError("enc.action.b3_pos not resident; cannot refresh b3_pos_rows")
host_t = self.b3_pos_rows_host(self.cfg.layout(lay_name), b3)
dtype = "fp32" if host_t.dtype == torch.float32 else "bf16"
staged = self.backend.to_device(self.backend.from_torch_host(host_t, dtype, "TILE"), self.device)
self.backend.copy_into(staged, consts["b3_pos_rows"])
self.backend.deallocate(staged)
self.backend.synchronize(self.device)
previous = self.embodiment_id
self.embodiment_id = e
return {
"from": previous,
"to": e,
"n_tensors": len(enc),
"device_bytes": n_bytes,
"host_plan_s": t_host,
"copy_s": time.perf_counter() - t0,
}
# ------------------------------------------------------------------ teardown
def release(self) -> None:
"""Deallocate every device tensor (plan tensors and constants)."""
for consts in self._constants.values():
for t in consts.values():
self.backend.deallocate(t)
self._constants.clear()
for t in self._tensors.values():
self.backend.deallocate(t)
self._tensors.clear()
self._host.clear()
self._embed_table = None
__all__ = [
"TENSORBIN_FORMAT",
"TENSORBIN_MARKER",
"TENSORBIN_MANIFEST",
"TENSORBIN_SUFFIX",
"UploadEntry",
"upload_plan",
"upload_byte_summary",
"TTNNBackend",
"tensorbin_directory",
"hoist_lengths",
"rope_transformation_matrix",
"TTWeights",
]