sunandbean's picture
Add files using upload-large-folder tool
cfbcb75 verified
Raw History Blame Contribute Delete
4.34 kB
# SPDX-License-Identifier: Apache-2.0
"""Device and host helpers shared with the ACE-Step port.
Extracted verbatim from `tt-acestep` (Apache-2.0), where the same code opens the card, reports
DRAM, moves tensors, and prepares checkpoint tensors for ttnn: the matmul layout, the
adjacent-pair head permutation ttnn's rotary kernel expects, and the tiled rotation matrix.
The two ports also share `worker.py`, `remote.py`, `wire.py` and `oobleck_vae.py`; this module
exists so that this repository stands alone.
"""
from __future__ import annotations
from dataclasses import dataclass
import torch
import ttnn
MEM = ttnn.DRAM_MEMORY_CONFIG
def open_device(l1_small_size: int = 98304): # convs (VAE) keep their config tensors in L1_SMALL
return ttnn.open_mesh_device(mesh_shape=ttnn.MeshShape(1, 1),
dispatch_core_config=ttnn.DispatchCoreConfig(ttnn.DispatchCoreType.WORKER),
l1_small_size=l1_small_size)
def close_device(dev):
ttnn.close_mesh_device(dev)
def dram_stats(dev) -> dict:
try:
s = ttnn.get_memory_view(dev, ttnn.BufferType.DRAM)
return {"allocated_bytes": s.total_bytes_allocated_per_bank * s.num_banks,
"free_bytes": s.total_bytes_free_per_bank * s.num_banks}
except Exception: # pragma: no cover - diagnostics only
return {}
@dataclass
class Precision:
weight_dtype: ttnn.DataType = ttnn.bfloat16
mm_fidelity: ttnn.MathFidelity = ttnn.MathFidelity.HiFi2
sdpa_fidelity: ttnn.MathFidelity = ttnn.MathFidelity.HiFi4
sdpa_fp32_acc: bool = True
def _dev(dev, t: torch.Tensor, dtype=ttnn.bfloat16):
return ttnn.from_torch(t.contiguous(), dtype=dtype, layout=ttnn.TILE_LAYOUT, device=dev, memory_config=MEM)
def _row(dev, v: torch.Tensor):
"""[D] -> [1, 1, 1, D] bf16 row (norm gamma, shift, gate, bias)."""
return _dev(dev, v.to(torch.bfloat16).reshape(1, 1, 1, -1))
TILE = 32
SEQ_MULTIPLE = 128 # sequence lengths are padded to multiples of this at least (SDPA chunk sizes divide it)
NEG = -1e9 # additive mask value for excluded keys (finite, representable in bf16)
def linear_to_mm(w: torch.Tensor) -> torch.Tensor:
"""nn.Linear weight [out, in] -> matmul weight [in, out]."""
return w.t().contiguous()
def interleave_pairs_permutation(head_dim: int) -> torch.Tensor:
"""new[j] = old[p[j]]: rotate-half pairs (i, i + D/2) -> adjacent pairs (2i, 2i + 1).
Applying it to the rows of q_proj/k_proj (per head) and to q_norm/k_norm leaves every q.k product unchanged and
lets tt's rotary_embedding_llama (adjacent pairs) replace upstream's rotate_half RoPE."""
half = head_dim // 2
p = torch.empty(head_dim, dtype=torch.long)
p[0::2] = torch.arange(half)
p[1::2] = torch.arange(half) + half
return p
def permute_heads_rows(w_out_in: torch.Tensor, n_heads: int, head_dim: int, perm: torch.Tensor) -> torch.Tensor:
out, inp = w_out_in.shape
assert out == n_heads * head_dim
return w_out_in.view(n_heads, head_dim, inp)[:, perm, :].reshape(out, inp).contiguous()
def rot_transformation_mat(tile: int = TILE) -> torch.Tensor:
"""[1, 1, 32, 32] T with (x @ T)[2k] = -x[2k+1], (x @ T)[2k+1] = x[2k] (adjacent-pair rotation)."""
m = torch.zeros(1, 1, tile, tile)
m[..., torch.arange(0, tile, 2), torch.arange(1, tile, 2)] = 1.0
m[..., torch.arange(1, tile, 2), torch.arange(0, tile, 2)] = -1.0
return m
def rms(x: torch.Tensor, w: torch.Tensor, eps: float) -> torch.Tensor:
return x * torch.rsqrt(x.pow(2).mean(-1, keepdim=True) + eps) * w
def round_up(n: int, m: int = SEQ_MULTIPLE) -> int:
return (n + m - 1) // m * m
def swiglu_interleave(gate_out_in: torch.Tensor, up_out_in: torch.Tensor, tile: int = TILE) -> torch.Tensor:
"""[K, 2N] weight for minimal_matmul(fuse_swiglu=True): column tile 2p = gate tile p, 2p+1 = up tile p."""
g, u = linear_to_mm(gate_out_in), linear_to_mm(up_out_in)
K, N = g.shape
assert N % tile == 0, N
return torch.stack([g.view(K, N // tile, tile), u.view(K, N // tile, tile)], dim=2).reshape(K, 2 * N).contiguous()
def apply_rope_adjacent(x: torch.Tensor, cos: torch.Tensor, sin: torch.Tensor) -> torch.Tensor:
rot = torch.stack([-x[..., 1::2], x[..., 0::2]], dim=-1).flatten(-2)
return x * cos + rot * sin