Skip to content

Commit 32a2194

Browse files
adam-xiaoyaoclaude
andcommitted
[Perf] Improve FP8 dispatch storage release
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent bd44505 commit 32a2194

2 files changed

Lines changed: 85 additions & 55 deletions

File tree

sonicmoe/ernie_compat/mlp_node_v2.py

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -504,22 +504,10 @@ def _attach_fp8_weight_attrs(
504504
w2: torch.Tensor,
505505
payload: dict[str, tuple[torch.Tensor, torch.Tensor]],
506506
) -> None:
507-
w1.fp8_weight = {
508-
"w1_fused": payload["w1_fused"][0],
509-
"w1T_varlen": payload["w1T_varlen"][0],
510-
}
511-
w1.fp8_scale = {
512-
"w1_fused": payload["w1_fused"][1],
513-
"w1T_varlen": payload["w1T_varlen"][1],
514-
}
515-
w2.fp8_weight = {
516-
"w2_varlen": payload["w2_varlen"][0],
517-
"w2_dgated": payload["w2_dgated"][0],
518-
}
519-
w2.fp8_scale = {
520-
"w2_varlen": payload["w2_varlen"][1],
521-
"w2_dgated": payload["w2_dgated"][1],
522-
}
507+
w1.fp8 = payload["w1_fused"]
508+
w1.transposed_fp8 = payload["w1T_varlen"]
509+
w2.fp8 = payload["w2_varlen"]
510+
w2.transposed_fp8 = payload["w2_dgated"]
523511

524512
# ── Weight layout helpers (instance-scoped) ─────────────────────────────
525513

@@ -907,7 +895,6 @@ def forward(
907895
False, # is_inference_mode_enabled
908896
False, # use_low_precision_postact_buffer
909897
fp8_activation_payload,
910-
fp8_weight_payload,
911898
)
912899

913900
# ── DownProjection forward (via FakeCtx) ─────────────────────────
@@ -924,7 +911,6 @@ def forward(
924911
activation_type,
925912
None, # fp8_protocol
926913
None,
927-
fp8_weight_payload,
928914
router_scores_expert_order,
929915
router_scores_token_order,
930916
score_src_idx,

sonicmoe/functional/__init__.py

Lines changed: 81 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,12 +1283,19 @@ def forward(
12831283
if prequant_activation_payload is not None:
12841284
x_fp8_pre, x_scales_pre = prequant_activation_payload
12851285
w1_fused_payload = _get_fp8_weight_attr(w1, "fp8")
1286-
z, y1 = _fused_blockscaled_gated_forward(
1287-
x, w1, expert_frequency_offset, x_gather_idx,
1288-
w1_fp8_pre=w1_fused_payload,
1289-
x_fp8_pre=x_fp8_pre, x_scales_pre=x_scales_pre,
1290-
store_z=not cfg.recompute_z,
1291-
fuse_y1_quant=fuse_y1,
1286+
fuse_y1 = _use_fuse_y1_quant()
1287+
z, y1, y1_fp8_fused, y1_scales_fused = (
1288+
_fused_blockscaled_gated_forward(
1289+
x,
1290+
w1,
1291+
expert_frequency_offset,
1292+
x_gather_idx,
1293+
w1_fp8_pre=w1_fused_payload,
1294+
x_fp8_pre=x_fp8_pre,
1295+
x_scales_pre=x_scales_pre,
1296+
store_z=not cfg.recompute_z,
1297+
fuse_y1_quant=fuse_y1,
1298+
)
12921299
)
12931300
if cfg.recompute_z:
12941301
# Forward skips preact storage; z is materialized just-in-time
@@ -2053,9 +2060,22 @@ def forward(
20532060

20542061
# w2 decoupling: in FP8+aligned+fused_gated mode, backward doesn't
20552062
# read bf16 w2 data (uses fp8 dgated cache + metadata). This enables
2056-
# stash_bf16_to_cpu() to resize_(0) the bf16 param storage.
2057-
_w2_decouple = z_is_fp8 and cfg.fused_gated
2063+
# clear_param_storage("moe_expert") to release bf16 expert weight storage
2064+
# without requiring recompute_z/save_z_fp8.
2065+
_w2_decouple = (
2066+
cfg.enabled
2067+
and use_quack_gemm
2068+
and cfg.alignment_assumed
2069+
and cfg.fused_gated
2070+
)
20582071
ctx._w2_decoupled = _w2_decouple
2072+
if _w2_decouple:
2073+
ctx._w2_dgated_fp8, ctx._w2_dgated_scales = _get_fp8_weight_attr(
2074+
w2, "transposed_fp8"
2075+
)
2076+
ctx._w2_shape = w2.shape # (H, I, E)
2077+
ctx._w2_dtype = w2.dtype
2078+
ctx._w2_device = w2.device
20592079

20602080
if z_is_fp8:
20612081
recompute_args = _PREQUANTIZED_SCALES.pop("z_fp8_recompute", None)
@@ -2099,10 +2119,6 @@ def forward(
20992119
else:
21002120
z_fp8, z_raw_scales = quantize_activation_blockscaled_fast(z)
21012121
if _w2_decouple:
2102-
ctx._w2_dgated_fp8, ctx._w2_dgated_scales = _get_fp8_weight_attr(w2, "transposed_fp8")
2103-
ctx._w2_shape = w2.shape # (H, I, E)
2104-
ctx._w2_dtype = w2.dtype
2105-
ctx._w2_device = w2.device
21062122
ctx.save_for_backward(
21072123
z_fp8,
21082124
z_raw_scales,
@@ -2129,17 +2145,30 @@ def forward(
21292145
s_reverse_scatter_idx,
21302146
)
21312147
else:
2132-
ctx.save_for_backward(
2133-
z,
2134-
w2,
2135-
b2,
2136-
topk_scores,
2137-
topk_scores_expert_order,
2138-
expert_frequency_offset,
2139-
x_gather_idx,
2140-
s_scatter_idx,
2141-
s_reverse_scatter_idx,
2142-
)
2148+
if _w2_decouple:
2149+
ctx.save_for_backward(
2150+
z,
2151+
# w2 omitted — backward uses ctx._w2_dgated_fp8 + metadata
2152+
b2,
2153+
topk_scores,
2154+
topk_scores_expert_order,
2155+
expert_frequency_offset,
2156+
x_gather_idx,
2157+
s_scatter_idx,
2158+
s_reverse_scatter_idx,
2159+
)
2160+
else:
2161+
ctx.save_for_backward(
2162+
z,
2163+
w2,
2164+
b2,
2165+
topk_scores,
2166+
topk_scores_expert_order,
2167+
expert_frequency_offset,
2168+
x_gather_idx,
2169+
s_scatter_idx,
2170+
s_reverse_scatter_idx,
2171+
)
21432172

21442173
# Keep w2 FP8 cache — backward hits cache (~38µs savings) at ~37MB memory cost.
21452174
# The cache auto-invalidates via w._version when optimizer updates weights.
@@ -2201,20 +2230,35 @@ def backward(ctx, dout: torch.Tensor):
22012230
# Defer dequantize: FP8 path uses fused kernel, others lazy-dequant
22022231
z = None
22032232
else:
2204-
(
2205-
z,
2206-
w2,
2207-
b2,
2208-
topk_scores,
2209-
topk_scores_expert_order,
2210-
expert_frequency_offset,
2211-
x_gather_idx,
2212-
s_scatter_idx,
2213-
s_reverse_scatter_idx,
2214-
) = ctx.saved_tensor()
2215-
w2_shape = w2.shape
2216-
w2_dtype = w2.dtype
2217-
w2_device = w2.device
2233+
if ctx._w2_decoupled:
2234+
(
2235+
z,
2236+
b2,
2237+
topk_scores,
2238+
topk_scores_expert_order,
2239+
expert_frequency_offset,
2240+
x_gather_idx,
2241+
s_scatter_idx,
2242+
s_reverse_scatter_idx,
2243+
) = ctx.saved_tensor()
2244+
w2_shape = ctx._w2_shape
2245+
w2_dtype = ctx._w2_dtype
2246+
w2_device = ctx._w2_device
2247+
else:
2248+
(
2249+
z,
2250+
w2,
2251+
b2,
2252+
topk_scores,
2253+
topk_scores_expert_order,
2254+
expert_frequency_offset,
2255+
x_gather_idx,
2256+
s_scatter_idx,
2257+
s_reverse_scatter_idx,
2258+
) = ctx.saved_tensor()
2259+
w2_shape = w2.shape
2260+
w2_dtype = w2.dtype
2261+
w2_device = w2.device
22182262
z_fp8 = z_raw_scales_u8 = None
22192263
if getattr(ctx, "_needs_z_recompute_bf16", False):
22202264
# Replace the zero-storage bf16 placeholder with a freshly recomputed

0 commit comments

Comments
 (0)