File size: 13,592 Bytes
aec3f16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e0adbab
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
aec3f16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# 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")),
])