Restructure: cutedsl/ -> dsv4/ with proper layering
- Split bridge.py -> ops/quantize.py, ops/layouts.py, ops/gemm_runner.py - Renamed classes: CuTeDSLNvfp4Linear -> Nvfp4Linear, etc. - Moved kernel code to dsv4/kernels/ (gemm, attention, compressor, decode, cuda) - Moved PyTorch bridges to dsv4/ops/ - Moved nn.Module layers to dsv4layers/ - Moved reference implementations to dsv4/reference/ - Moved vendored CUTLASS code to vendored/ - Archived ~190 debug tests to tests/archive/ - Kept ~15 canonical tests in tests/unit/ - Updated all import paths - Added stubs for future components (model/, cache/, loader/) - Updated pyproject.toml: dsv4-inference package name
This commit is contained in:
@@ -6,7 +6,7 @@ sys.path.insert(0, '/root/nvfp4-megamoe-kernel/cutedsl')
|
||||
sys.path.insert(0, '/root/nvfp4-megamoe-kernel/vllm')
|
||||
|
||||
from cutedsl.reference.moe_pipeline import moe_pipeline
|
||||
from vllm.nvfp4_cutedsl import CuTeDSLMoERunner
|
||||
from vllm.nvfp4_cutedsl import Nvfp4MoE
|
||||
|
||||
torch.cuda.set_device(0)
|
||||
|
||||
@@ -33,7 +33,7 @@ ref_out = moe_pipeline(
|
||||
print(f"Reference output: amax={ref_out.amax().item():.4f} mean={ref_out.mean().item():.4f}")
|
||||
|
||||
# Run runner with warmup gs
|
||||
runner = CuTeDSLMoERunner(
|
||||
runner = Nvfp4MoE(
|
||||
num_experts=3, hidden_size=256, intermediate_size=512,
|
||||
max_num_tokens=4, top_k=2, device='cuda'
|
||||
)
|
||||
@@ -51,14 +51,14 @@ def dequant_nvfp4(packed_uint8, scale_e4m3, global_scale):
|
||||
def test_projection(name, weight, weight_sf, weight_gs, hidden_states, in_features, out_features):
|
||||
"""Test a single NVFP4 projection."""
|
||||
sys.path.insert(0, "/root/nvfp4-megamoe-kernel")
|
||||
from cutedsl.nvfp4_linear import CuTeDSLNvfp4Linear
|
||||
from dsv4.layers.linear import Nvfp4Linear
|
||||
|
||||
# Convert weight to CuTeDSL format: (out, in_packed) uint8 → (in_packed, out) float4
|
||||
fp4 = [weight.view(torch.float4_e2m1fn_x2).permute(1, 0).contiguous()]
|
||||
sf = [weight_sf.permute(1, 0).contiguous()]
|
||||
gs = [weight_gs]
|
||||
|
||||
runner = CuTeDSLNvfp4Linear(
|
||||
runner = Nvfp4Linear(
|
||||
in_features=in_features,
|
||||
out_features=out_features,
|
||||
max_num_tokens=8192,
|
||||
@@ -55,7 +55,7 @@ def rms(x, w, eps=1e-6):
|
||||
return (w.float() * (x * torch.rsqrt(v+eps)).float()).to(x.dtype)
|
||||
|
||||
def make_runner(w, sf, gs_t, inf, outf, fused=False, lw=None):
|
||||
from cutedsl.nvfp4_linear import CuTeDSLNvfp4Linear
|
||||
from dsv4.layers.linear import Nvfp4Linear
|
||||
fp4 = w.view(torch.float4_e2m1fn_x2).permute(1,0).contiguous()
|
||||
s = sf.to(torch.float8_e4m3fn) if sf.dtype != torch.float8_e4m3fn else sf
|
||||
s = s.permute(1,0).contiguous()
|
||||
@@ -66,7 +66,7 @@ def make_runner(w, sf, gs_t, inf, outf, fused=False, lw=None):
|
||||
s32[:sp] *= g1/gs; s32[sp:] *= g2/gs; s = s32.to(torch.float8_e4m3fn)
|
||||
else:
|
||||
gs = gs_t.max().item() if gs_t.numel() > 1 else gs_t.item()
|
||||
r = CuTeDSLNvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r = Nvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r.fp4 = [fp4]; r.sf = [s]; r.gs = [gs]
|
||||
r.finalize_weights(); r._ensure_initialized()
|
||||
return r
|
||||
@@ -50,7 +50,7 @@ def rms(x, w, eps=1e-6):
|
||||
return (w.float() * (x * torch.rsqrt(v+eps)).float()).to(x.dtype)
|
||||
|
||||
def make_runner(w, sf, gs_t, inf, outf, fused=False, lw=None):
|
||||
from cutedsl.nvfp4_linear import CuTeDSLNvfp4Linear
|
||||
from dsv4.layers.linear import Nvfp4Linear
|
||||
fp4 = w.view(torch.float4_e2m1fn_x2).permute(1,0).contiguous()
|
||||
s = sf.to(torch.float8_e4m3fn) if sf.dtype != torch.float8_e4m3fn else sf
|
||||
s = s.permute(1,0).contiguous()
|
||||
@@ -61,7 +61,7 @@ def make_runner(w, sf, gs_t, inf, outf, fused=False, lw=None):
|
||||
s32[:sp] *= g1/gs; s32[sp:] *= g2/gs; s = s32.to(torch.float8_e4m3fn)
|
||||
else:
|
||||
gs = gs_t.max().item() if gs_t.numel() > 1 else gs_t.item()
|
||||
r = CuTeDSLNvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r = Nvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r.fp4 = [fp4]; r.sf = [s]; r.gs = [gs]
|
||||
r.finalize_weights(); r._ensure_initialized()
|
||||
return r
|
||||
@@ -82,7 +82,7 @@ def build_cos_sin(max_pos=4096, rope_dim=ROPE):
|
||||
|
||||
def test_blackwell_attention(layer_id, compress_ratio):
|
||||
"""Test the full blackwell attention pipeline for a specific layer."""
|
||||
from cutedsl.blackwell_attention import (
|
||||
from dsv4.reference.attention import (
|
||||
apply_gptj_rope, apply_inv_gptj_rope,
|
||||
blackwell_attention_forward,
|
||||
kv_quantize_fp8, kv_dequantize_fp8,
|
||||
@@ -52,7 +52,7 @@ def rms(x, w, eps=1e-6):
|
||||
return (w.float() * (x * torch.rsqrt(v+eps)).float()).to(x.dtype)
|
||||
|
||||
def make_runner(w, sf, gs_t, inf, outf, fused=False, lw=None):
|
||||
from cutedsl.nvfp4_linear import CuTeDSLNvfp4Linear
|
||||
from dsv4.layers.linear import Nvfp4Linear
|
||||
fp4 = w.view(torch.float4_e2m1fn_x2).permute(1,0).contiguous()
|
||||
s = sf.to(torch.float8_e4m3fn) if sf.dtype != torch.float8_e4m3fn else sf
|
||||
s = s.permute(1,0).contiguous()
|
||||
@@ -63,7 +63,7 @@ def make_runner(w, sf, gs_t, inf, outf, fused=False, lw=None):
|
||||
s32[:sp] *= g1/gs; s32[sp:] *= g2/gs; s = s32.to(torch.float8_e4m3fn)
|
||||
else:
|
||||
gs = gs_t.max().item() if gs_t.numel() > 1 else gs_t.item()
|
||||
r = CuTeDSLNvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r = Nvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r.fp4 = [fp4]; r.sf = [s]; r.gs = [gs]
|
||||
r.finalize_weights(); r._ensure_initialized()
|
||||
return r
|
||||
@@ -169,7 +169,7 @@ def main():
|
||||
# For this test, we use kv_n directly as the KV for attention
|
||||
|
||||
# ── Step 6: FULL ATTENTION (PyTorch SDPA, works on Blackwell) ──
|
||||
from cutedsl.csa_attention import full_attention_reference
|
||||
from dsv4.reference.csa_attention import full_attention_reference
|
||||
|
||||
o_attn = full_attention_reference(q_rope, kv_n, scale=SCALE)
|
||||
print(f" Attention output: amax={o_attn.amax():.4f} NaN={torch.isnan(o_attn).any()}")
|
||||
@@ -42,7 +42,7 @@ def rms(x, w, eps=1e-6):
|
||||
return (w.float() * (x * torch.rsqrt(v+eps)).float()).to(x.dtype)
|
||||
|
||||
def make_runner(w, sf, gs_t, inf, outf, fused=False, lw=None):
|
||||
from cutedsl.nvfp4_linear import CuTeDSLNvfp4Linear
|
||||
from dsv4.layers.linear import Nvfp4Linear
|
||||
fp4 = w.view(torch.float4_e2m1fn_x2).permute(1,0).contiguous()
|
||||
s = sf.to(torch.float8_e4m3fn) if sf.dtype != torch.float8_e4m3fn else sf
|
||||
s = s.permute(1,0).contiguous()
|
||||
@@ -53,7 +53,7 @@ def make_runner(w, sf, gs_t, inf, outf, fused=False, lw=None):
|
||||
s32[:sp] *= g1/gs; s32[sp:] *= g2/gs; s = s32.to(torch.float8_e4m3fn)
|
||||
else:
|
||||
gs = gs_t.max().item() if gs_t.numel() > 1 else gs_t.item()
|
||||
r = CuTeDSLNvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r = Nvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r.fp4 = [fp4]; r.sf = [s]; r.gs = [gs]
|
||||
r.finalize_weights(); r._ensure_initialized()
|
||||
return r
|
||||
@@ -61,7 +61,7 @@ def rms(x, w, eps=1e-6):
|
||||
return (w.float() * (x * torch.rsqrt(v+eps)).float()).to(x.dtype)
|
||||
|
||||
def make_runner(w, sf, gs_t, inf, outf, fused=False, lw=None):
|
||||
from cutedsl.nvfp4_linear import CuTeDSLNvfp4Linear
|
||||
from dsv4.layers.linear import Nvfp4Linear
|
||||
fp4 = w.view(torch.float4_e2m1fn_x2).permute(1,0).contiguous()
|
||||
s = sf.to(torch.float8_e4m3fn) if sf.dtype != torch.float8_e4m3fn else sf
|
||||
s = s.permute(1,0).contiguous()
|
||||
@@ -72,7 +72,7 @@ def make_runner(w, sf, gs_t, inf, outf, fused=False, lw=None):
|
||||
s32[:sp] *= g1/gs; s32[sp:] *= g2/gs; s = s32.to(torch.float8_e4m3fn)
|
||||
else:
|
||||
gs = gs_t.max().item() if gs_t.numel() > 1 else gs_t.item()
|
||||
r = CuTeDSLNvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r = Nvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r.fp4 = [fp4]; r.sf = [s]; r.gs = [gs]
|
||||
r.finalize_weights(); r._ensure_initialized()
|
||||
return r
|
||||
@@ -24,7 +24,7 @@ from vllm.model_executor.layers.csa_attention import (
|
||||
apply_gptj_rope,
|
||||
apply_inv_gptj_rope,
|
||||
)
|
||||
from cutedsl.native_swa_decode import native_swa_decode_attention
|
||||
from dsv4.ops.decode_swa import native_swa_decode_attention
|
||||
|
||||
torch.manual_seed(42)
|
||||
torch.cuda.set_device(0)
|
||||
@@ -43,7 +43,7 @@ def rms(x, w, eps=1e-6):
|
||||
return (w.float() * (x * torch.rsqrt(v+eps)).float()).to(x.dtype)
|
||||
|
||||
def make_runner(w, sf, gs_t, inf, outf, fused=False, lw=None):
|
||||
from cutedsl.nvfp4_linear import CuTeDSLNvfp4Linear
|
||||
from dsv4.layers.linear import Nvfp4Linear
|
||||
fp4 = w.view(torch.float4_e2m1fn_x2).permute(1,0).contiguous()
|
||||
s = sf.to(torch.float8_e4m3fn) if sf.dtype != torch.float8_e4m3fn else sf
|
||||
s = s.permute(1,0).contiguous()
|
||||
@@ -54,7 +54,7 @@ def make_runner(w, sf, gs_t, inf, outf, fused=False, lw=None):
|
||||
s32[:sp] *= g1/gs; s32[sp:] *= g2/gs; s = s32.to(torch.float8_e4m3fn)
|
||||
else:
|
||||
gs = gs_t.max().item() if gs_t.numel() > 1 else gs_t.item()
|
||||
r = CuTeDSLNvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r = Nvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r.fp4 = [fp4]; r.sf = [s]; r.gs = [gs]
|
||||
r.finalize_weights(); r._ensure_initialized()
|
||||
return r
|
||||
@@ -45,7 +45,7 @@ def rms(x, w, eps=1e-6):
|
||||
return (w.float() * (x * torch.rsqrt(v+eps)).float()).to(x.dtype)
|
||||
|
||||
def make_runner(w, sf, gs_t, inf, outf, fused=False, lw=None):
|
||||
from cutedsl.nvfp4_linear import CuTeDSLNvfp4Linear
|
||||
from dsv4.layers.linear import Nvfp4Linear
|
||||
fp4 = w.view(torch.float4_e2m1fn_x2).permute(1,0).contiguous()
|
||||
s = sf.to(torch.float8_e4m3fn) if sf.dtype != torch.float8_e4m3fn else sf
|
||||
s = s.permute(1,0).contiguous()
|
||||
@@ -56,7 +56,7 @@ def make_runner(w, sf, gs_t, inf, outf, fused=False, lw=None):
|
||||
s32[:sp] *= g1/gs; s32[sp:] *= g2/gs; s = s32.to(torch.float8_e4m3fn)
|
||||
else:
|
||||
gs = gs_t.max().item() if gs_t.numel() > 1 else gs_t.item()
|
||||
r = CuTeDSLNvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r = Nvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r.fp4 = [fp4]; r.sf = [s]; r.gs = [gs]
|
||||
r.finalize_weights(); r._ensure_initialized()
|
||||
return r
|
||||
@@ -57,7 +57,7 @@ def rms(x, w, eps=1e-6):
|
||||
return (w.float() * (x * torch.rsqrt(v+eps)).float()).to(x.dtype)
|
||||
|
||||
def make_runner(w, sf, gs_t, inf, outf, fused=False, lw=None):
|
||||
from cutedsl.nvfp4_linear import CuTeDSLNvfp4Linear
|
||||
from dsv4.layers.linear import Nvfp4Linear
|
||||
fp4 = w.view(torch.float4_e2m1fn_x2).permute(1,0).contiguous()
|
||||
s = sf.to(torch.float8_e4m3fn) if sf.dtype != torch.float8_e4m3fn else sf
|
||||
s = s.permute(1,0).contiguous()
|
||||
@@ -68,7 +68,7 @@ def make_runner(w, sf, gs_t, inf, outf, fused=False, lw=None):
|
||||
s32[:sp] *= g1/gs; s32[sp:] *= g2/gs; s = s32.to(torch.float8_e4m3fn)
|
||||
else:
|
||||
gs = gs_t.max().item() if gs_t.numel() > 1 else gs_t.item()
|
||||
r = CuTeDSLNvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r = Nvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r.fp4 = [fp4]; r.sf = [s]; r.gs = [gs]
|
||||
r.finalize_weights(); r._ensure_initialized()
|
||||
return r
|
||||
@@ -195,7 +195,7 @@ def main():
|
||||
|
||||
# ── Shared expert ─────────────────────────────────────────────────
|
||||
print("\n--- Shared Expert: CuTeDSL vs BF16 ---")
|
||||
from cutedsl.shared_expert_pipeline import CuTeDSLSharedExpertRunner
|
||||
from dsv4.layers.shared_expert import Nvfp4SharedExpert
|
||||
|
||||
sgw = G(f"{m}.shared_experts.gate_proj.weight"); sgsf = G(f"{m}.shared_experts.gate_proj.weight_scale")
|
||||
sggs = G(f"{m}.shared_experts.gate_proj.weight_scale_2").item()
|
||||
@@ -211,7 +211,7 @@ def main():
|
||||
s32 = sgu_sf.float(); s32[:si] *= sggs/smgs; s32[si:] *= sugs/smgs
|
||||
sgu_sf = s32.to(torch.float8_e4m3fn)
|
||||
|
||||
ser = CuTeDSLSharedExpertRunner(hidden_size=H, intermediate_size=si, max_num_tokens=8192,
|
||||
ser = Nvfp4SharedExpert(hidden_size=H, intermediate_size=si, max_num_tokens=8192,
|
||||
device=DEV, swiglu_limit=SL)
|
||||
ser.l1_fp4 = [sgu_w.view(torch.float4_e2m1fn_x2).permute(1,0).contiguous()]
|
||||
ser.l1_sf = [sgu_sf.permute(1,0).contiguous()]; ser.l1_gs = [smgs]
|
||||
@@ -39,12 +39,12 @@ def rms(x, w, eps=1e-6):
|
||||
return (w.float() * (x * torch.rsqrt(v+eps)).float()).to(x.dtype)
|
||||
|
||||
def make_runner(w, sf, gs_t, inf, outf):
|
||||
from cutedsl.nvfp4_linear import CuTeDSLNvfp4Linear
|
||||
from dsv4.layers.linear import Nvfp4Linear
|
||||
fp4 = w.view(torch.float4_e2m1fn_x2).permute(1,0).contiguous()
|
||||
s = sf.to(torch.float8_e4m3fn) if sf.dtype != torch.float8_e4m3fn else sf
|
||||
s = s.permute(1,0).contiguous()
|
||||
gs = gs_t.max().item() if gs_t.numel() > 1 else gs_t.item()
|
||||
r = CuTeDSLNvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r = Nvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r.fp4 = [fp4]; r.sf = [s]; r.gs = [gs]
|
||||
r.finalize_weights(); r._ensure_initialized()
|
||||
return r
|
||||
@@ -102,7 +102,7 @@ def causal_prefill_attention(q, kv, scale):
|
||||
|
||||
def test_full_layer(layer_id, num_tokens=8, num_moe_experts=16):
|
||||
"""Test a complete transformer layer with attention + MoE."""
|
||||
from cutedsl.runner import CuTeDSLMoERunner
|
||||
from dsv4.layers.moe import Nvfp4MoE
|
||||
|
||||
torch.cuda.set_device(0)
|
||||
torch.manual_seed(42)
|
||||
@@ -162,7 +162,7 @@ def test_full_layer(layer_id, num_tokens=8, num_moe_experts=16):
|
||||
# Free per-expert lists
|
||||
del gate_ws, gate_sfs, gate_gss, up_ws, up_sfs, up_gss, down_ws, down_sfs, down_gss
|
||||
|
||||
moe_runner = CuTeDSLMoERunner(
|
||||
moe_runner = Nvfp4MoE(
|
||||
num_experts=num_moe_experts,
|
||||
hidden_size=H,
|
||||
intermediate_size=INTERMEDIATE,
|
||||
@@ -56,7 +56,7 @@ def rms(x, w, eps=1e-6):
|
||||
return (w.float() * (x * torch.rsqrt(v+eps)).float()).to(x.dtype)
|
||||
|
||||
def make_runner(w, sf, gs_t, inf, outf, fused=False, lw=None):
|
||||
from cutedsl.nvfp4_linear import CuTeDSLNvfp4Linear
|
||||
from dsv4.layers.linear import Nvfp4Linear
|
||||
fp4 = w.view(torch.float4_e2m1fn_x2).permute(1,0).contiguous()
|
||||
s = sf.to(torch.float8_e4m3fn) if sf.dtype != torch.float8_e4m3fn else sf
|
||||
s = s.permute(1,0).contiguous()
|
||||
@@ -67,7 +67,7 @@ def make_runner(w, sf, gs_t, inf, outf, fused=False, lw=None):
|
||||
s32[:sp] *= g1/gs; s32[sp:] *= g2/gs; s = s32.to(torch.float8_e4m3fn)
|
||||
else:
|
||||
gs = gs_t.max().item() if gs_t.numel() > 1 else gs_t.item()
|
||||
r = CuTeDSLNvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r = Nvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r.fp4 = [fp4]; r.sf = [s]; r.gs = [gs]
|
||||
r.finalize_weights(); r._ensure_initialized()
|
||||
return r
|
||||
@@ -124,7 +124,7 @@ def bf16_causal_attention(q, kv, scale):
|
||||
|
||||
def make_moe_runner(layer_id, wm, model_path):
|
||||
"""Create CuTeDSL MoE runner for a layer."""
|
||||
from cutedsl.runner import CuTeDSLMoERunner
|
||||
from dsv4.layers.moe import Nvfp4MoE
|
||||
|
||||
p = f"model.layers.{layer_id}.mlp"
|
||||
G = lambda k: P(k, wm, model_path).to(DEV)
|
||||
@@ -147,7 +147,7 @@ def make_moe_runner(layer_id, wm, model_path):
|
||||
l2_sf = w2_sf.to(torch.float8_e4m3fn).permute(1,0).contiguous() if w2_sf.dtype != torch.float8_e4m3fn else w2_sf.permute(1,0).contiguous()
|
||||
|
||||
intermediate_size = 3072 # per expert
|
||||
runner = CuTeDSLMoERunner(
|
||||
runner = Nvfp4MoE(
|
||||
num_experts=NUM_EXPERTS,
|
||||
hidden_size=H,
|
||||
intermediate_size=intermediate_size,
|
||||
@@ -62,7 +62,7 @@ def rms(x, w, eps=1e-6):
|
||||
return (w.float() * (x * torch.rsqrt(v+eps)).float()).to(x.dtype)
|
||||
|
||||
def make_runner(w, sf, gs_t, inf, outf, fused=False, lw=None):
|
||||
from cutedsl.nvfp4_linear import CuTeDSLNvfp4Linear
|
||||
from dsv4.layers.linear import Nvfp4Linear
|
||||
fp4 = w.view(torch.float4_e2m1fn_x2).permute(1,0).contiguous()
|
||||
s = sf.to(torch.float8_e4m3fn) if sf.dtype != torch.float8_e4m3fn else sf
|
||||
s = s.permute(1,0).contiguous()
|
||||
@@ -73,7 +73,7 @@ def make_runner(w, sf, gs_t, inf, outf, fused=False, lw=None):
|
||||
s32[:sp] *= g1/gs; s32[sp:] *= g2/gs; s = s32.to(torch.float8_e4m3fn)
|
||||
else:
|
||||
gs = gs_t.max().item() if gs_t.numel() > 1 else gs_t.item()
|
||||
r = CuTeDSLNvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r = Nvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r.fp4 = [fp4]; r.sf = [s]; r.gs = [gs]
|
||||
r.finalize_weights(); r._ensure_initialized()
|
||||
return r
|
||||
@@ -135,7 +135,9 @@ def kv_quantize_nvfp4(kv_bf16):
|
||||
kv_bf16: (T, HD) BF16
|
||||
Returns: (T, HD//2) fp4, (T, HD//16) sf, scalar gs
|
||||
"""
|
||||
from cutedsl.bridge import quantize_to_nvfp4
|
||||
from dsv4.ops.quantize import (
|
||||
quantize_to_nvfp4,
|
||||
)
|
||||
return quantize_to_nvfp4(kv_bf16)
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ def rms(x, w, eps=1e-6):
|
||||
return (w.float() * (x * torch.rsqrt(v+eps)).float()).to(x.dtype)
|
||||
|
||||
def make_runner(w, sf, gs_t, inf, outf, fused=False, lw=None):
|
||||
from cutedsl.nvfp4_linear import CuTeDSLNvfp4Linear
|
||||
from dsv4.layers.linear import Nvfp4Linear
|
||||
fp4 = w.view(torch.float4_e2m1fn_x2).permute(1,0).contiguous()
|
||||
s = sf.to(torch.float8_e4m3fn) if sf.dtype != torch.float8_e4m3fn else sf
|
||||
s = s.permute(1,0).contiguous()
|
||||
@@ -61,7 +61,7 @@ def make_runner(w, sf, gs_t, inf, outf, fused=False, lw=None):
|
||||
s32[:sp] *= g1/gs; s32[sp:] *= g2/gs; s = s32.to(torch.float8_e4m3fn)
|
||||
else:
|
||||
gs = gs_t.max().item() if gs_t.numel() > 1 else gs_t.item()
|
||||
r = CuTeDSLNvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r = Nvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r.fp4 = [fp4]; r.sf = [s]; r.gs = [gs]
|
||||
r.finalize_weights(); r._ensure_initialized()
|
||||
return r
|
||||
@@ -80,15 +80,17 @@ def main():
|
||||
|
||||
# ── INSPECT: How does CuTeDSL runner.run() use gs? ────────────────
|
||||
print("\n--- INSPECTING CuTeDSL runner internals ---")
|
||||
from cutedsl.nvfp4_linear import CuTeDSLNvfp4Linear
|
||||
from cutedsl.bridge import quantize_activation_nvfp4
|
||||
from dsv4.layers.linear import Nvfp4Linear
|
||||
from dsv4.ops.quantize import (
|
||||
quantize_activation_nvfp4,
|
||||
)
|
||||
|
||||
print("\n quantize_activation_nvfp4 signature:")
|
||||
sig = inspect.signature(quantize_activation_nvfp4)
|
||||
print(f" {sig}")
|
||||
|
||||
print("\n CuTeDSLNvfp4Linear._run_impl source (key lines):")
|
||||
src = inspect.getsource(CuTeDSLNvfp4Linear._run_impl)
|
||||
print("\n Nvfp4Linear._run_impl source (key lines):")
|
||||
src = inspect.getsource(Nvfp4Linear._run_impl)
|
||||
for i, line in enumerate(src.split('\n')):
|
||||
stripped = line.strip()
|
||||
if any(kw in stripped for kw in ['global_scale', '_activation', 'quantize', 'return', 'def ']):
|
||||
@@ -47,12 +47,12 @@ def rms(x, w, eps=1e-6):
|
||||
return (w.float() * (x * torch.rsqrt(v+eps)).float()).to(x.dtype)
|
||||
|
||||
def make_runner(w, sf, gs_t, inf, outf):
|
||||
from cutedsl.nvfp4_linear import CuTeDSLNvfp4Linear
|
||||
from dsv4.layers.linear import Nvfp4Linear
|
||||
fp4 = w.view(torch.float4_e2m1fn_x2).permute(1,0).contiguous()
|
||||
s = sf.to(torch.float8_e4m3fn) if sf.dtype != torch.float8_e4m3fn else sf
|
||||
s = s.permute(1,0).contiguous()
|
||||
gs = gs_t.max().item() if gs_t.numel() > 1 else gs_t.item()
|
||||
r = CuTeDSLNvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r = Nvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r.fp4 = [fp4]; r.sf = [s]; r.gs = [gs]
|
||||
r.finalize_weights(); r._ensure_initialized()
|
||||
return r
|
||||
@@ -2,7 +2,7 @@
|
||||
"""
|
||||
DeepSeek-V4 MoE Runner NaN Test
|
||||
|
||||
Tests the CuTeDSLMoERunner (grouped GEMM path) with real weights.
|
||||
Tests the Nvfp4MoE (grouped GEMM path) with real weights.
|
||||
The single-expert tests pass — this test exercises the FULL MoE runner
|
||||
with routing, padding, grouped GEMM, and combine.
|
||||
|
||||
@@ -39,7 +39,7 @@ def rms(x, w, eps=1e-6):
|
||||
|
||||
|
||||
def pack_expert_weights(wm, G, layer_id=2, num_local_experts=16):
|
||||
"""Pack per-expert weights into stacked format for CuTeDSLMoERunner.
|
||||
"""Pack per-expert weights into stacked format for Nvfp4MoE.
|
||||
Only loads the first num_local_experts to fit in memory.
|
||||
"""
|
||||
m = f"model.layers.{layer_id}.mlp"
|
||||
@@ -77,7 +77,7 @@ def pack_expert_weights(wm, G, layer_id=2, num_local_experts=16):
|
||||
# Actually w13 = stacked gate+up, w2 = down
|
||||
# But our runner expects separate L1 (gate+up) and L2 (down)
|
||||
# The w13 format is (E, 2*intermediate, hidden//2) with gate and up interleaved
|
||||
# For CuTeDSLMoERunner, we stack gate and up side-by-side
|
||||
# For Nvfp4MoE, we stack gate and up side-by-side
|
||||
|
||||
# Stack gate and up into w13 format: (E, 2*intermediate, hidden//2)
|
||||
w13_w = torch.cat([torch.stack(gate_ws), torch.stack(up_ws)], dim=1) # (E, 6144, 3584)
|
||||
@@ -92,8 +92,8 @@ def pack_expert_weights(wm, G, layer_id=2, num_local_experts=16):
|
||||
|
||||
|
||||
def test_moe_runner(layer_id=2):
|
||||
"""Test the CuTeDSLMoERunner with real weights."""
|
||||
from cutedsl.runner import CuTeDSLMoERunner
|
||||
"""Test the Nvfp4MoE with real weights."""
|
||||
from dsv4.layers.moe import Nvfp4MoE
|
||||
|
||||
torch.cuda.set_device(0)
|
||||
torch.manual_seed(42)
|
||||
@@ -118,7 +118,7 @@ def test_moe_runner(layer_id=2):
|
||||
intermediate_size = INTERMEDIATE # 3072
|
||||
hidden_size = H # 7168
|
||||
|
||||
runner = CuTeDSLMoERunner(
|
||||
runner = Nvfp4MoE(
|
||||
num_experts=num_local_experts,
|
||||
hidden_size=hidden_size,
|
||||
intermediate_size=intermediate_size,
|
||||
@@ -178,7 +178,7 @@ def test_moe_runner(layer_id=2):
|
||||
def main():
|
||||
print("=" * 70)
|
||||
print(" DeepSeek-V4 MoE Runner NaN Test")
|
||||
print(" Tests CuTeDSLMoERunner (grouped GEMM) with real weights")
|
||||
print(" Tests Nvfp4MoE (grouped GEMM) with real weights")
|
||||
print("=" * 70)
|
||||
|
||||
test_moe_runner(layer_id=2)
|
||||
@@ -58,8 +58,11 @@ def main():
|
||||
topk_weights = torch.ones(NUM_TOKENS, TOP_K, dtype=torch.float32, device=DEVICE) / TOP_K
|
||||
|
||||
# Setup runner
|
||||
from vllm.nvfp4_cutedsl import CuTeDSLMoERunner
|
||||
from cutedsl.bridge import assemble_scales_3d_side, make_b_k_major
|
||||
from vllm.nvfp4_cutedsl import Nvfp4MoE
|
||||
from dsv4.ops.layouts import (
|
||||
assemble_scales_3d_side,
|
||||
make_b_k_major,
|
||||
)
|
||||
|
||||
l1_fp4, l1_sf, l1_gs_list = [], [], []
|
||||
l2_fp4, l2_sf, l2_gs_list = [], [], []
|
||||
@@ -91,7 +94,7 @@ def main():
|
||||
l2_sf.append(torch.ones(INTERMEDIATE_SIZE//16, HIDDEN_SIZE, dtype=torch.float8_e4m3fn, device=DEVICE))
|
||||
l2_gs_list.append(1.0)
|
||||
|
||||
runner = CuTeDSLMoERunner(
|
||||
runner = Nvfp4MoE(
|
||||
num_experts=NUM_EXPERTS, hidden_size=HIDDEN_SIZE,
|
||||
intermediate_size=INTERMEDIATE_SIZE, max_num_tokens=NUM_TOKENS,
|
||||
top_k=TOP_K, device=DEVICE,
|
||||
@@ -48,7 +48,7 @@ def rms(x, w, eps=1e-6):
|
||||
return (w.float() * (x * torch.rsqrt(v+eps)).float()).to(x.dtype)
|
||||
|
||||
def make_runner(w, sf, gs_t, inf, outf, fused=False, lw=None):
|
||||
from cutedsl.nvfp4_linear import CuTeDSLNvfp4Linear
|
||||
from dsv4.layers.linear import Nvfp4Linear
|
||||
fp4 = w.view(torch.float4_e2m1fn_x2).permute(1,0).contiguous()
|
||||
s = sf.to(torch.float8_e4m3fn) if sf.dtype != torch.float8_e4m3fn else sf
|
||||
s = s.permute(1,0).contiguous()
|
||||
@@ -59,7 +59,7 @@ def make_runner(w, sf, gs_t, inf, outf, fused=False, lw=None):
|
||||
s32[:sp] *= g1/gs; s32[sp:] *= g2/gs; s = s32.to(torch.float8_e4m3fn)
|
||||
else:
|
||||
gs = gs_t.max().item() if gs_t.numel() > 1 else gs_t.item()
|
||||
r = CuTeDSLNvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r = Nvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r.fp4 = [fp4]; r.sf = [s]; r.gs = [gs]
|
||||
r.finalize_weights(); r._ensure_initialized()
|
||||
return r
|
||||
@@ -108,8 +108,11 @@ def nvfp4_qk_attention(q, kv, scale):
|
||||
This is a standard GEMM that CuTeDSL can handle.
|
||||
We quantize Q as the "activation" and K^T as the "weight".
|
||||
"""
|
||||
from cutedsl.bridge import quantize_to_nvfp4, quantize_activation_nvfp4
|
||||
from cutedsl.nvfp4_linear import CuTeDSLNvfp4Linear
|
||||
from dsv4.ops.quantize import (
|
||||
quantize_to_nvfp4,
|
||||
quantize_activation_nvfp4,
|
||||
)
|
||||
from dsv4.layers.linear import Nvfp4Linear
|
||||
|
||||
T, NH, HD = q.shape
|
||||
device = q.device
|
||||
@@ -123,7 +126,7 @@ def nvfp4_qk_attention(q, kv, scale):
|
||||
kv_T = kv.T.contiguous() # (HD, T)
|
||||
w_fp4, w_sf, w_gs = quantize_to_nvfp4(kv_T) # (HD//2, T), (HD//16, T), scalar
|
||||
|
||||
# Use CuTeDSLNvfp4Linear runner for Q×K^T GEMM
|
||||
# Use Nvfp4Linear runner for Q×K^T GEMM
|
||||
# in_features=HD, out_features=T
|
||||
# Q is "activation" side, K^T is "weight" side
|
||||
M = T * NH
|
||||
@@ -131,7 +134,7 @@ def nvfp4_qk_attention(q, kv, scale):
|
||||
N = T
|
||||
|
||||
# Create runner for this specific (M, K, N) combination
|
||||
runner = CuTeDSLNvfp4Linear(
|
||||
runner = Nvfp4Linear(
|
||||
in_features=K, out_features=N, max_num_tokens=M, device=str(device)
|
||||
)
|
||||
|
||||
@@ -64,7 +64,7 @@ def rms(x, w, eps=1e-6):
|
||||
return (w.float() * (x * torch.rsqrt(v+eps)).float()).to(x.dtype)
|
||||
|
||||
def make_runner(w, sf, gs_t, inf, outf, fused=False, lw=None):
|
||||
from cutedsl.nvfp4_linear import CuTeDSLNvfp4Linear
|
||||
from dsv4.layers.linear import Nvfp4Linear
|
||||
fp4 = w.view(torch.float4_e2m1fn_x2).permute(1,0).contiguous()
|
||||
s = sf.to(torch.float8_e4m3fn) if sf.dtype != torch.float8_e4m3fn else sf
|
||||
s = s.permute(1,0).contiguous()
|
||||
@@ -75,7 +75,7 @@ def make_runner(w, sf, gs_t, inf, outf, fused=False, lw=None):
|
||||
s32[:sp] *= g1/gs; s32[sp:] *= g2/gs; s = s32.to(torch.float8_e4m3fn)
|
||||
else:
|
||||
gs = gs_t.max().item() if gs_t.numel() > 1 else gs_t.item()
|
||||
r = CuTeDSLNvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r = Nvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r.fp4 = [fp4]; r.sf = [s]; r.gs = [gs]
|
||||
r.finalize_weights(); r._ensure_initialized()
|
||||
return r
|
||||
@@ -163,7 +163,7 @@ class NVFP4Attention:
|
||||
Returns:
|
||||
(T, NH, HD) attention output
|
||||
"""
|
||||
from cutedsl.nvfp4_linear import CuTeDSLNvfp4Linear
|
||||
from dsv4.layers.linear import Nvfp4Linear
|
||||
|
||||
T, NH, HD = q_bf16.shape
|
||||
device = q_bf16.device
|
||||
@@ -175,13 +175,13 @@ class NVFP4Attention:
|
||||
# Q is "activation" (T*NH, HD), K^T is "weight" (T, HD)
|
||||
# GEMM: (T*NH, HD) × (HD, T) → (T*NH, T)
|
||||
#
|
||||
# We use CuTeDSLNvfp4Linear with in_features=HD, out_features=T
|
||||
# We use Nvfp4Linear with in_features=HD, out_features=T
|
||||
# Q is the "hidden_states", K (kv) is the "weight" matrix
|
||||
|
||||
# Create or get cached runner
|
||||
cache_key = (T, HD, NH)
|
||||
if self._runner is None or getattr(self, '_cache_key', None) != cache_key:
|
||||
runner = CuTeDSLNvfp4Linear(
|
||||
runner = Nvfp4Linear(
|
||||
in_features=HD,
|
||||
out_features=T,
|
||||
max_num_tokens=T * NH,
|
||||
@@ -191,15 +191,17 @@ class NVFP4Attention:
|
||||
# Set K as the weight: kv (T, HD) → treat as weight (N=T, K=HD)
|
||||
# quantize_to_nvfp4 quantizes along last dim (D=HD) as activation
|
||||
# For weight, we need (K, N) layout — but kv is (T, HD) = (N, K)
|
||||
# CuTeDSLNvfp4Linear expects weight in (N, K//2) after permute
|
||||
# Nvfp4Linear expects weight in (N, K//2) after permute
|
||||
|
||||
from cutedsl.bridge import quantize_to_nvfp4
|
||||
from dsv4.ops.quantize import (
|
||||
quantize_to_nvfp4,
|
||||
)
|
||||
# Quantize KV as a 2D tensor: (T, HD)
|
||||
# quantize_to_nvfp4 works on last dim (D=HD), returns:
|
||||
# (T, HD//2) fp4, (T, HD//16) sf, scalar gs
|
||||
kv_fp4, kv_sf, kv_gs = quantize_to_nvfp4(kv_bf16)
|
||||
|
||||
# For CuTeDSLNvfp4Linear, weight is (N, K_packed) = (T, HD//2)
|
||||
# For Nvfp4Linear, weight is (N, K_packed) = (T, HD//2)
|
||||
# Our kv_fp4 is already (T, HD//2) — perfect!
|
||||
# sf needs to be (N, K_sf) = (T, HD//16) — already correct
|
||||
|
||||
@@ -163,7 +163,7 @@ def dequant_nvfp4(packed_uint8, scale_e4m3, global_scale):
|
||||
def test_wo_b_nvfp4(z, wo_b_weight, wo_b_sf, wo_b_gs):
|
||||
"""Test wo_b NVFP4 GEMM against BF16 reference."""
|
||||
sys.path.insert(0, "/root/nvfp4-megamoe-kernel")
|
||||
from cutedsl.nvfp4_linear import CuTeDSLNvfp4Linear
|
||||
from dsv4.layers.linear import Nvfp4Linear
|
||||
|
||||
in_features = wo_b_weight.shape[1] * 2
|
||||
out_features = wo_b_weight.shape[0]
|
||||
@@ -173,7 +173,7 @@ def test_wo_b_nvfp4(z, wo_b_weight, wo_b_sf, wo_b_gs):
|
||||
sf = [wo_b_sf.permute(1, 0).contiguous()]
|
||||
gs = [wo_b_gs]
|
||||
|
||||
runner = CuTeDSLNvfp4Linear(
|
||||
runner = Nvfp4Linear(
|
||||
in_features=in_features,
|
||||
out_features=out_features,
|
||||
max_num_tokens=8192,
|
||||
@@ -91,8 +91,11 @@ def main():
|
||||
print(f"BF16 ref: amax={ref_out.amax().item():.4f}")
|
||||
|
||||
# CuTeDSL runner
|
||||
from vllm.nvfp4_cutedsl import CuTeDSLMoERunner
|
||||
from cutedsl.bridge import assemble_scales_3d_side, make_b_k_major
|
||||
from vllm.nvfp4_cutedsl import Nvfp4MoE
|
||||
from dsv4.ops.layouts import (
|
||||
assemble_scales_3d_side,
|
||||
make_b_k_major,
|
||||
)
|
||||
|
||||
l1_fp4, l1_sf, l1_gs = [], [], []
|
||||
l2_fp4, l2_sf, l2_gs = [], [], []
|
||||
@@ -125,7 +128,7 @@ def main():
|
||||
l2_sf.append(torch.ones(INTERMEDIATE_SIZE//16, HIDDEN_SIZE, dtype=torch.float8_e4m3fn, device=DEVICE))
|
||||
l2_gs.append(1.0)
|
||||
|
||||
runner = CuTeDSLMoERunner(
|
||||
runner = Nvfp4MoE(
|
||||
num_experts=NUM_EXPERTS, hidden_size=HIDDEN_SIZE,
|
||||
intermediate_size=INTERMEDIATE_SIZE, max_num_tokens=MAX_NUM_TOKENS,
|
||||
top_k=TOP_K, device=DEVICE,
|
||||
@@ -39,12 +39,12 @@ def rms(x, w, eps=1e-6):
|
||||
return (w.float() * (x * torch.rsqrt(v+eps)).float()).to(x.dtype)
|
||||
|
||||
def make_runner(w, sf, gs_t, inf, outf):
|
||||
from cutedsl.nvfp4_linear import CuTeDSLNvfp4Linear
|
||||
from dsv4.layers.linear import Nvfp4Linear
|
||||
fp4 = w.view(torch.float4_e2m1fn_x2).permute(1,0).contiguous()
|
||||
s = sf.to(torch.float8_e4m3fn) if sf.dtype != torch.float8_e4m3fn else sf
|
||||
s = s.permute(1,0).contiguous()
|
||||
gs = gs_t.max().item() if gs_t.numel() > 1 else gs_t.item()
|
||||
r = CuTeDSLNvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r = Nvfp4Linear(in_features=inf, out_features=outf, max_num_tokens=8192, device=str(w.device))
|
||||
r.fp4 = [fp4]; r.sf = [s]; r.gs = [gs]
|
||||
r.finalize_weights(); r._ensure_initialized()
|
||||
return r
|
||||
@@ -132,7 +132,7 @@ with torch.no_grad():
|
||||
print(f" Output: amax={o_with_rope.amax():.4f} NaN={torch.isnan(o_with_rope).any()}")
|
||||
|
||||
# Test 3: Full pipeline
|
||||
from cutedsl.csa_attention import apply_inv_gptj_rope
|
||||
from dsv4.reference.csa_attention import apply_inv_gptj_rope
|
||||
o_inv = apply_inv_gptj_rope(o_with_rope, positions, cos_sin, NOPE, ROPE)
|
||||
o_grouped = o_inv.view(NT, OG, HPG * HD).permute(1, 0, 2)
|
||||
woa_3d = woa.view(OG, OL, HPG * HD)
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test A: Compare moe_pipeline output vs CuTeDSLMoERunner output.
|
||||
Test A: Compare moe_pipeline output vs Nvfp4MoE output.
|
||||
|
||||
Uses the same weights and inputs. If they differ, the runner is broken.
|
||||
Runs on the B200 host (not inside Docker):
|
||||
@@ -13,9 +13,17 @@ from safetensors import safe_open
|
||||
REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
sys.path.insert(0, REPO_ROOT)
|
||||
|
||||
from cutedsl.moe_pipeline import run_nvfp4_moe
|
||||
from vllm.nvfp4_cutedsl import CuTeDSLMoERunner
|
||||
from cutedsl.bridge import quantize_to_nvfp4, quantize_weight_to_nvfp4, make_b_k_major, assemble_scales_3d_side, compute_expert_offsets
|
||||
from dsv4.reference.moe_pipeline import run_nvfp4_moe
|
||||
from vllm.nvfp4_cutedsl import Nvfp4MoE
|
||||
from dsv4.ops.quantize import (
|
||||
quantize_to_nvfp4,
|
||||
quantize_weight_to_nvfp4,
|
||||
)
|
||||
from dsv4.ops.layouts import (
|
||||
make_b_k_major,
|
||||
assemble_scales_3d_side,
|
||||
compute_expert_offsets,
|
||||
)
|
||||
|
||||
MODEL_DIR = "/root/nvidia-meeting/DeepSeek-V4-Pro-NVFP4"
|
||||
DEVICE = "cuda"
|
||||
@@ -126,9 +134,9 @@ def main():
|
||||
)
|
||||
print(f" Pipeline: amax={pipeline_out.abs().max():.4f}, mean={pipeline_out.float().mean():.6f}")
|
||||
|
||||
# ── Path 2: CuTeDSLMoERunner with checkpoint input_scale (what vLLM uses) ──
|
||||
print("\n Running CuTeDSLMoERunner (checkpoint gs)...")
|
||||
runner = CuTeDSLMoERunner(num_experts, hidden_size, intermediate_size, device=DEVICE)
|
||||
# ── Path 2: Nvfp4MoE with checkpoint input_scale (what vLLM uses) ──
|
||||
print("\n Running Nvfp4MoE (checkpoint gs)...")
|
||||
runner = Nvfp4MoE(num_experts, hidden_size, intermediate_size, device=DEVICE)
|
||||
runner.prepare_weights_direct(
|
||||
[w.clone() for w in weights['l1_fp4']],
|
||||
[w.clone() for w in weights['l1_sf']],
|
||||
@@ -157,12 +165,12 @@ def main():
|
||||
).item()
|
||||
print(f" Cosine vs pipeline: {cos_ckpt:.6f}")
|
||||
|
||||
# ── Path 3: CuTeDSLMoERunner with dynamic gs ──
|
||||
print("\n Running CuTeDSLMoERunner (dynamic gs)...")
|
||||
# ── Path 3: Nvfp4MoE with dynamic gs ──
|
||||
print("\n Running Nvfp4MoE (dynamic gs)...")
|
||||
# We can't use quantize_to_nvfp4 in the runner (cudagraph), but we can
|
||||
# compute the gs from the input and set it before calling run
|
||||
x_igs = (hidden_states.abs().max().item()) / (6.0 * 448.0)
|
||||
runner2 = CuTeDSLMoERunner(num_experts, hidden_size, intermediate_size, device=DEVICE)
|
||||
runner2 = Nvfp4MoE(num_experts, hidden_size, intermediate_size, device=DEVICE)
|
||||
runner2.prepare_weights_direct(
|
||||
[w.clone() for w in weights['l1_fp4']],
|
||||
[w.clone() for w in weights['l1_sf']],
|
||||
@@ -14,9 +14,14 @@ import os, sys, torch
|
||||
REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
sys.path.insert(0, REPO_ROOT)
|
||||
|
||||
from cutedsl.bridge import quantize_to_nvfp4, assemble_scales_2d_side
|
||||
from cutedsl.kernel.moe.torch_scaled_grouped_mm import pad_and_swizzle_single, ceil_div
|
||||
from vllm.nvfp4_cutedsl import CuTeDSLMoERunner
|
||||
from dsv4.ops.quantize import (
|
||||
quantize_to_nvfp4,
|
||||
)
|
||||
from dsv4.ops.layouts import (
|
||||
assemble_scales_2d_side,
|
||||
)
|
||||
from dsv4.kernels.gemm.grouped import pad_and_swizzle_single, ceil_div
|
||||
from vllm.nvfp4_cutedsl import Nvfp4MoE
|
||||
|
||||
|
||||
def test_scale_assembly():
|
||||
@@ -27,7 +32,7 @@ def test_scale_assembly():
|
||||
intermediate_size = 3072
|
||||
|
||||
# Create a runner just to use its _assemble_scales_cudagraph_safe
|
||||
runner = CuTeDSLMoERunner(num_experts, hidden_size, intermediate_size, device=DEVICE)
|
||||
runner = Nvfp4MoE(num_experts, hidden_size, intermediate_size, device=DEVICE)
|
||||
# Trigger _ensure_stacked and buffer allocation with dummy weights
|
||||
def rand_fp4(*shape):
|
||||
return torch.randint(0, 256, shape, dtype=torch.uint8, device=DEVICE).view(torch.float4_e2m1fn_x2)
|
||||
@@ -3,15 +3,20 @@
|
||||
import os, sys, torch
|
||||
REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
sys.path.insert(0, REPO_ROOT)
|
||||
from cutedsl.bridge import quantize_to_nvfp4, assemble_scales_2d_side
|
||||
from cutedsl.kernel.moe.torch_scaled_grouped_mm import pad_and_swizzle_single, ceil_div
|
||||
from vllm.nvfp4_cutedsl import CuTeDSLMoERunner
|
||||
from dsv4.ops.quantize import (
|
||||
quantize_to_nvfp4,
|
||||
)
|
||||
from dsv4.ops.layouts import (
|
||||
assemble_scales_2d_side,
|
||||
)
|
||||
from dsv4.kernels.gemm.grouped import pad_and_swizzle_single, ceil_div
|
||||
from vllm.nvfp4_cutedsl import Nvfp4MoE
|
||||
|
||||
DEVICE = "cuda"
|
||||
num_experts = 3
|
||||
hidden_size = 7168
|
||||
|
||||
runner = CuTeDSLMoERunner(num_experts, hidden_size, 3072, device=DEVICE)
|
||||
runner = Nvfp4MoE(num_experts, hidden_size, 3072, device=DEVICE)
|
||||
def rand_fp4(*shape):
|
||||
return torch.randint(0, 256, shape, dtype=torch.uint8, device=DEVICE).view(torch.float4_e2m1fn_x2)
|
||||
def rand_sf(*shape):
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Standalone test: Shared expert using CuTeDSL dedicated runner.
|
||||
|
||||
Tests the CuTeDSLSharedExpertRunner for the shared expert path.
|
||||
Tests the Nvfp4SharedExpert for the shared expert path.
|
||||
Compares against BF16 dequantized reference.
|
||||
|
||||
Usage: python3 test_shared_expert.py
|
||||
@@ -55,7 +55,7 @@ def main():
|
||||
torch.manual_seed(42)
|
||||
|
||||
sys.path.insert(0, "/root/nvfp4-megamoe-kernel")
|
||||
from cutedsl.shared_expert_pipeline import CuTeDSLSharedExpertRunner
|
||||
from dsv4.layers.shared_expert import Nvfp4SharedExpert
|
||||
|
||||
with open(os.path.join(MODEL_PATH, "model.safetensors.index.json")) as f:
|
||||
wm = json.load(f)["weight_map"]
|
||||
@@ -101,7 +101,7 @@ def main():
|
||||
l2_sf = [down_sf.permute(1, 0).contiguous()]
|
||||
|
||||
# Create runner
|
||||
runner = CuTeDSLSharedExpertRunner(
|
||||
runner = Nvfp4SharedExpert(
|
||||
hidden_size=HIDDEN_SIZE,
|
||||
intermediate_size=INTERMEDIATE_SIZE,
|
||||
max_num_tokens=8192,
|
||||
@@ -13,12 +13,16 @@ import torch
|
||||
import sys
|
||||
sys.path.insert(0, '/root/dsv4-nvfp4-workspace/kernel')
|
||||
|
||||
from cutedsl.bridge import (
|
||||
from dsv4.ops.quantize import (
|
||||
quantize_weight_to_nvfp4,
|
||||
quantize_activation_nvfp4,
|
||||
)
|
||||
from dsv4.ops.layouts import (
|
||||
make_b_k_major,
|
||||
assemble_scales_2d_side,
|
||||
assemble_scales_3d_side,
|
||||
)
|
||||
from dsv4.ops.gemm_runner import (
|
||||
run_nvfp4_grouped_gemm,
|
||||
warmup_compilation,
|
||||
)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user