diffrhythm-1.2-p100a / code /models /common /modules /moe /tt_moe_gate_config.py
sunandbean's picture
Add files using upload-large-folder tool
629b123 verified
Raw History Blame Contribute Delete
5.21 kB
# SPDX-FileCopyrightText: Β© 2026 Tenstorrent USA, Inc.
#
# SPDX-License-Identifier: Apache-2.0
"""Config for ``TTMoEGate`` (the routing front-end).
Parsed from the same per-model YAML that ``TTMoEDecodeConfig`` reads β€” the gate-specific keys
(``n_group``/``score_func``/``routed_scaling_factor``/``score_correction_bias``/``gate_proj_bias``/
``gate_matmul_compute``) are exactly the extra keys ``TTMoEDecodeConfig`` ignores. Mirrors the
``TTMoEDecode(mesh_device, config, torch_weights...)`` entry-point convention: ``TTMoEGate`` takes this
config + the torch gate weight/bias(es), and builds everything on device internally.
"""
from __future__ import annotations
import yaml
from pydantic import BaseModel, ConfigDict
# Gate-relevant keys read from a model YAML; every other key (decode/compute/reduce/...) is ignored.
_GATE_YAML_KEYS = (
"num_routed_experts",
"select_experts_k",
"hidden_size",
"batch_per_device",
"n_group",
"score_func",
"softmax_position",
"routed_scaling_factor",
"score_correction_bias",
"gate_proj_bias",
"gate_matmul_high_fidelity",
"gate_matmul_compute",
"gate_matmul_auto_program_config",
"gate_matmul_program_config",
)
class TTMoEGateConfig(BaseModel):
"""Gate shape + routing semantics for ``TTMoEGate``.
``batch_per_device`` is OPTIONAL: when set, ``TTMoEGate`` sizes its per-token op buffers to it, so the
per-forward ``ttnn.slice`` of those buffers is a free full-tensor slice (zero perf cost β€” decode path).
When ``None``, the buffers are sized to the device core count and the slice trims ``cores β†’
batch_per_iter`` (the variable-/large-batch fallback). Either way the result is identical.
"""
model_config = ConfigDict(frozen=True)
# --- shape ---
num_routed_experts: int
select_experts_k: int
hidden_size: int
batch_per_device: int | None = None # set β†’ buffers sized to it (free slice); None β†’ sized to cores
# --- gate semantics (see TTMoEGate) ---
n_group: int = 1 # 1 β†’ generalized (ungrouped) op; 8 β†’ deepseek (grouped) op
score_func: str = "softmax" # "softmax" | "sigmoid" | "sqrtsoftplus"
# softmax ONLY (ignored otherwise) β€” where the softmax is applied relative to the top-k. With no score-
# correction bias both are mathematically equal (the global Z cancels under renorm), differing only in
# how the exp is computed (a selection bias would make them diverge, but softmax models are bias-free):
# "post" (default) β€” rank by the raw logit, then softmax OVER THE SELECTED top-k (the kernel op's
# exp-over-selected / ttnn.softmax(sel) in the fallback). The original behavior.
# "pre" β€” softmax over ALL experts UP FRONT (same slot as sqrtsoftplus), then LINEAR renorm
# over the selected top-k. The exp is the numerically-stable full softmax
# (max-subtracted over all experts) instead of the kernel's exp-over-raw-logit.
softmax_position: str = "post" # "post" | "pre"
routed_scaling_factor: float = 1.0
score_correction_bias: bool = False # deepseek/noaux_tc: e_score_correction_bias (selection-only)
gate_proj_bias: bool = (
False # gpt-oss: model has a router LINEAR/projection bias b (logits = Wx + b β†’ selection AND weights)
)
# router-matmul COMPUTE kernel fidelity. Default HIGH fidelity (HiFi2 + fp32 accumulate): the deep gate
# reduction drifts under the ttnn default (LoFi + bf16 accumulate) and flips near-tied experts at the
# top-k boundary, so every gate gets high fidelity (the matmul is tiny β†’ the cost is negligible). Set
# `gate_matmul_high_fidelity: false` to opt out (ttnn's default fidelity).
gate_matmul_high_fidelity: bool = True
# OPTIONAL full override of the compute kernel: a dict (keys math_fidelity / math_approx_mode /
# fp32_dest_acc_en / packer_l1_acc override the HiFi2 defaults). Wins over gate_matmul_high_fidelity
# when set; None β†’ use the flag above. See TTMoEGate._matmul_compute_config.
gate_matmul_compute: dict | None = None
# router-matmul PROGRAM config (kernel grid / 2D-mcast blocking). Default AUTO: derived from the gate
# matmul shape + device grid (TTMoEGate._derive_program_config) β€” a tuned config materially cuts the gate
# matmul latency vs ttnn's auto pick. Set `gate_matmul_auto_program_config: false` for ttnn's auto-select.
gate_matmul_auto_program_config: bool = True
# OPTIONAL full override of the program config: a dict whose `type` names the ttnn program-config class
# (default MatmulMultiCoreReuseMultiCastProgramConfig) and remaining keys are its kwargs
# (compute_with_storage_grid_size auto-filled). Wins over the auto flag when set; None β†’ auto / ttnn.
gate_matmul_program_config: dict | None = None
eps: float = 1e-20
@classmethod
def from_yaml(cls, yaml_text: str) -> "TTMoEGateConfig":
"""Build from a model YAML, picking only the gate-relevant keys (defaults fill the rest)."""
raw = yaml.safe_load(yaml_text)
return cls(**{k: raw[k] for k in _GATE_YAML_KEYS if k in raw})