changh95's picture
tt-model push sceneseg-p150 (container)
e0adbab verified
Raw History Blame Contribute Delete
13.6 kB
# SPDX-License-Identifier: Apache-2.0
"""Build-time knobs of the sceneseg-p150 graph (``ttaw.knobs``): each is read once when the graph is built and has a
``SCENESEG_<NAME>`` environment switch for A/B runs; the defaults are the published configuration and are pinned in
``tt-model.yaml serve.env``."""
from __future__ import annotations
from ..ttaw.knobs import Knob, Knobs
__all__ = ["KNOBS"]
KNOBS = Knobs("SCENESEG", [
Knob("WEIGHT_TERMS", 2,
"every conv, transposed conv and linear runs its weights as two bf16 terms (hi + lo, ~16 significant bits), "
"one bias-free conv per product, summed in fp32; the bias is added afterwards as an fp32 row, never fused "
"(C17 weight_terms; PLAN.md 9.3 precision policy: plain bf16 weights failed the CenterPoint / BEVDet / YOLOX "
"gates; fix round 1: a fused bias truncates toward zero). 1 = plain bf16 weights (biases still fp32): "
"21.6 ms less per replay, A/B only (OPT_BASELINE.md)", choices=(1, 2)),
Knob("ACT_TERMS", 2,
"the backbone (stem, 16 MBConv blocks incl. SE) keeps its activations in float32 and feeds each conv / linear "
"two bf16 terms of them (hi + lo, ~16 significant bits; fix round 1: bf16 activation rounding in the backbone "
"decided the held-out frames that missed argmax agreement 0.995); the decoder and SceneContext stay bf16. "
"1 = bf16 backbone activations (as the first port), A/B only", choices=(1, 2)),
Knob("EPI", True,
"conv / linear epilogue (OPT_PLAN EPI): the fp32 term sum, the fp32 bias row, the fp32 activation and the "
"cast of every layer as ONE generic_op (tt/epi.py, the stock LLKs in the stock order: bit-identical) instead "
"of up to four stock programs (OPT_REPORT R1.3: b2b 60.93 -> 49.55 ms); 0 = the stock ttnn.add / activation / "
"typecast sequence"),
Knob("TERM_STACK", "exact",
"ST2 (needs EPI): a two-term conv / transposed conv (groups 1, Cout % 32 == 0) runs as ONE conv over "
"[W_hi ; W_lo] stacked on the output channels, its fp32 halves read by the EPI kernel as the two products "
"(one input read / halo / slice sequence instead of two). exact = every such layer except the 7 whose "
"stacked form is not bit-identical (tt/model.py ST2_INEXACT, st2_probe.py); all = every such layer (not "
"bit-identical; OPT_REPORT R1.4: exact 44.82 ms, all 46.66, off 49.55 b2b); off = one conv per weight term",
choices=("off", "exact", "all")),
Knob("DW_KERNEL", True,
"K11 (OPT_PLAN K11): the 16 backbone depthwise convs (groups=C) + bias + SiLU as ONE generic_op each "
"(tt/dw.py: float32 input and weights, one SFPMAD per tap, the stock fp32 bias add and silu_tile) on the "
"float32 backbone map, instead of the dense groups=C conv per term product after the hi / lo activation split "
"plus EPI. More precise than the stock form (probe dw_probe.py: max rel. error 1e-7 vs 1e-3), not "
"bit-identical: gated (OPT_REPORT round 2). Needs ACT_TERMS=2 (a float32 backbone); 0 = the stock path"),
Knob("DW_STAGE", True,
"K11 stride-2 band load (OPT_REPORT R2.2): each input row is read as whole 16-pixel face runs into a staging "
"row and scattered to the column-parity planes by local copies; 0 = one 64 B DRAM read per pixel and channel "
"half (R2.1 form: latency-bound, 1.06 ms for the 160x320x96 layer). Bit-identical"),
Knob("DW_WPACK", True,
"R7.1 K11 packed weights: each depthwise weight tile carries 8 taps (rows 4l..4l+3 = tap l, all 32 channels) "
"instead of one tap broadcast to 32 rows, so a channel tile's weights are ceil(k*k/8) tiles (2 / 4 instead "
"of 9 / 25: 4.5-6x less DRAM weight traffic per core and channel tile) and they are unpacked to DEST once "
"per output tile (twice for 5x5) instead of once per tap; the SFPU reads each tap's weight vector at its "
"DEST row group. Same SFPMAD operands and order: bit-identical; 0 = one weight tile per tap"),
Knob("EPI_SPLIT", True,
"EPI-split (OPT_REPORT R2.3, needs EPI and ACT_TERMS=2): the MBConv project conv's epilogue also adds the "
"residual and writes the next conv's bf16 (hi, lo) activation terms, and the SE gate multiply is fused with "
"the split of the project conv's input (one generic_op instead of multiply + typecast / typecast / subtract "
"/ typecast); the stage outputs' hi term is the decoder's bf16 cast. Bit-identical; 0 = the stock ops"),
Knob("CLASS_KERNEL", True,
"K8 (OPT_REPORT R2.4, needs EPI): the served class map decided in the class-margin conv's epilogue (the EPI "
"writer runs ttnn.argmax's SFPU compare semantics on the three margins) and written as uint8 [1, 320, 640] "
"(200 KB) instead of fp32 margins + transpose + reshape + argmax + untilize (uint32, 800 KB). Bit-identical "
"class map; the debug variant (margins / logits) keeps the stock path; 0 = the stock path"),
Knob("CONV_L1", 3200,
"L1P (OPT_REPORT R2.5): decoder / SceneContext kxk convs whose input map has at most this many pixels "
"(3200 = the 10x20, 20x40 and 40x80 maps) run ttnn's L1 path (Conv2dL1FullSliceConfig: the whole input moved "
"to L1) instead of the automatic DRAM slicing (its PaddedSlice / SliceWrite / ReshapeView programs); 12800 "
"(80x160) overflows L1 (2.6 MB of CBs per core); 0 = never"),
Knob("SUBPIXEL", "01234",
"S1 (OPT_PLAN rank 1): the decoder up-blocks listed (digits 0-4: neck 0-2, head 3-4; 'all' / 'off') run "
"the sub-pixel form (tt/subpixel.py): ConvT k2 s2 + 1x1 skip + the first 3x3 + GELU as a 2x2 phase conv on "
"the low-res map, the composed skip 3x3 and ONE generic_op epilogue (depth-to-space gather, skip terms, "
"border-aware bias, GELU). Exact in real arithmetic, rounds differently (no bf16 rounding of the up-block "
"sum): gated. Needs EPI and WEIGHT_TERMS=2"),
Knob("SUBPIXEL_Z", "ssspr",
"S1 Z-conv form per decoder block (5 letters): s = one 2x2 conv over all 8 Cout stacked phase outputs, "
"e = one 2x2 conv per weight term (4 Cout each), p = one 2x2 conv per phase (2 Cout each); t / r / q = the "
"same as 3x3 convs on the H x W grid (each phase's taps placed in a 3x3 kernel: 2.25x MACs, but ttnn's "
"3x3 path is faster on the 160x320 map); the fastest per block in s1_zsweep*.log"),
Knob("DEC_W1", "1,3,5,7,9,10",
"P2 decoder precision map (OPT_REPORT round 4, gated): the decoder 3x3 convs decode_layer_<n> listed (comma "
"separated n; the second 3x3 of each block is 1, 3, 5, 7, 9; 10 = the class-margin conv and the debug logit "
"conv) run ONE bf16 weight "
"term instead of two (hi + lo): half the conv MACs and half the fp32 conv output the epilogue reads. The "
"decoder activations are bf16 already; the products still accumulate in fp32 and the bias stays an unfused "
"fp32 row. Chosen on a tuning set disjoint from the gated frames (OPT_REPORT R4.1); '' = every layer two "
"terms"),
Knob("S1_W1", "bbbbb",
"P2 for the S1 blocks (round 4, gated): one letter per decoder block 0-4, '-' = two weight terms, 'z' = the "
"Z conv with ONE bf16 weight term (the composed G rounded once; the S1 epilogue adds no lo product), 's' = "
"the composed skip conv with one term, 'b' = both (OPT_REPORT R4.2). Needs SUBPIXEL for that block"),
Knob("W1_EXTRA", "ctx",
"P2 beyond the decoder (OPT_REPORT R4.3 / R4.5, gated): comma separated groups that run ONE bf16 weight "
"term: expand (the MBConv expand 1x1 convs), project (the MBConv project 1x1 convs), head (features.8 1x1), "
"ctx (SceneContext linears and convs); the backbone keeps its two activation terms. Tuning set (tune2): ctx "
"neutral, head no gain, project -4e-3 on the worst frame; expand -2e-4 there but -2.5e-3 on the held-out "
"gate (0.998574 -> 0.996045 bgr, job3_w1x): rejected. off = none"),
Knob("S1_SHARDED", "all",
"R5.1 (OPT_PLAN round-4 item 2): S1 convs whose output the S1 epilogue reads straight from the conv's L1 "
"shards (the reader's TensorAccessor resolves sharded pages; no ShardedToInterleaved DRAM round trip): "
"skip = the composed skip convs (forced onto ttnn's L1 path), all = the skip and the L1-path Z convs; "
"off = every S1 conv output moved to DRAM interleaved. Bit-identical (same values, other memory)",
choices=("off", "skip", "all")),
Knob("DEC_FID", "HiFi3",
"R5.3 (gated): math fidelity of the decoder / SceneContext convs: '<fidelity>[:<groups>]', fidelity one of "
"HiFi4 / HiFi3 / HiFi2 / LoFi, groups a comma list of s1 (the S1 Z / skip convs), dec (the decoder 3x3 "
"convs decode_layer_*), ctx (SceneContext convs), margin (class-margin + debug logit conv); default all "
"four. The decoder runs bf16 activations and (P2) one bf16 weight term; fp32 accumulation unchanged. '' = "
"the model precision (HiFi4) everywhere"),
Knob("EPI_BIAS_LOCAL", True,
"EPI-B (OPT_REPORT R4.4): the EPI and S1 epilogue readers load only the resident bias / gate-row tiles of the "
"output columns each core writes, instead of every column tile on every core (CT x 4 KB per core: up to "
"17.7 MB of reads per program on the 1152-channel maps). Bit-identical; 0 = every tile on every core"),
Knob("STEM_KERNEL", True,
"K-IN kernel form (OPT_PLAN rank 5 / MK0, needs INPUT_LAYOUT=rows, EPI, two weight and activation terms): the "
"stem conv + bias map + SiLU as ONE generic_op on the uploaded uint8 rows (tt/stem.py: bf16 im2col tiles "
"built by the reader, the two weight-term products on the FPU, the EPI epilogue LLKs) instead of the bf16 "
"cast, the 6-byte-stick reshape and one re-sharded conv per weight term + EPI; 0 = the stock stem"),
Knob("SE_KERNEL", True,
"SE-K (OPT_PLAN rank 10, needs EPI_SPLIT): each MBConv squeeze-excitation MLP (fc1 + SiLU + fc2 + sigmoid on "
"the fp32 row sum) as ONE generic_op (tt/sek.py: every core computes fc1, its share of fc2; the stock "
"products and epilogue LLKs, all products of a layer accumulated in one fp32 DEST tile) instead of two "
"Linear layers (activation split, three GEMVs and an epilogue each); 0 = the stock path"),
Knob("CONV_CFG", "dl1=db,dl3=db,dl5=h3db,z0=db,z1=db,z2=db,s0=db,s1=db,s2=db,s3=db,ctx=db",
"R6: per-layer ttnn conv configuration, comma list tag=preset (tags dl<n> = decode_layer_<n>, z<b> / s<b> = "
"S1 block b's Z / skip convs, mrg = class-margin conv, ctx = SceneContext convs; presets db / adb / wdb = activation and weight double "
"buffers, h<n> / w<n> [db] = explicit DRAM slices; tt/model.py conv_presets). Default: double buffers on the L1-path decoder / SceneContext convs and decode_layer_5 as 3 "
"height slices with double buffers (bit-identical, OPT_REPORT R6.2; slice_probe.py); off = ttnn's defaults"),
Knob("TAIL_MK", False,
"MK-T (OPT_PLAN 3.4, the D19 module megakernel; needs CLASS_KERNEL and DEC_W1 9 and 10): decode_layer_9 (3x3 "
"128 -> 64 + bias + GELU) + the class-margin conv + the class decision as ONE generic_op (tt/mkt.py: per "
"core 2-3 image rows, implicit-GEMM 3x3 convs from L1 column bands, the 64-channel map kept in an L1 store "
"with its halo rows exchanged between neighbour cores by unicast semaphores); uint8 class map. Not "
"bit-identical (in-DEST accumulation order, the bias as hi + lo bf16 terms): gated; 0 = the stock convs "
"+ EPI + K8"),
Knob("INPUT_LAYOUT", "rows",
"uploaded squash layout (OPT_PLAN K-IN, stock form): rows = [1, 1, 320, 1920] uint8 (320 pages of 1,920 B), "
"cast to bf16 then reshaped to pixel rows on the device; pixels = [1, 1, 204800, 3] (204,800 pages of 3 B: "
"5.3 ms of H2D). Bit-identical", choices=("rows", "pixels")),
Knob("HOST_SQUASH", "numba",
"host squash (OPT_PLAN H1): numba = the compiled twin of host/fast.py (RGB in, the BGR swap folded into its "
"reads, one thread), bit-identical to numpy = the vendored ttaw.image_linear oracle on a BGR copy",
choices=("numba", "numpy")),
Knob("HOST_SQUASH_THREADS", 4,
"R6 (HOST_SQUASH=numba): the squash twin as one fused pass per output row (the two horizontal source rows "
"in registers, no int32 scratch map) on this many numba threads (<= 4 of the 8 shared vCPUs); 0 = the "
"round-1 two-pass kernel on one thread. Bit-identical (integer arithmetic)", choices=(0, 1, 2, 4)),
Knob("LOAD_BIAS_HASH", 1,
"R8 (load time only): S1 bias_patterns finds the interior bias row with a 64-bit row hash + exact check "
"instead of np.unique(axis=0) (about 20 s of the graph build); a hash collision or a count tie falls back "
"to np.unique, so the result is bit-identical. 0 = np.unique always", choices=(0, 1)),
Knob("HOST_POST", "numba",
"host post-processing (OPT_PLAN H2): numba = the compiled twin of host/fast.py (mask + class map gathered to "
"the source size in one pass, 4 threads), bit-identical to numpy = host/postprocess.py's where + "
"INTER_NEAREST oracle", choices=("numba", "numpy")),
])