78c675eb8b
Two issues found by the diagnostic sweep in #292: 1. Profile double-count in pipe_layer_sparse: the outer t_emm span wrapped both the shared-expert GPU dispatch AND the moe() call, but moe() self-times its own t_emm internally (6 accumulation sites). Routed-expert matmul was counted twice -> accounted > elapsed -> 'other' went negative, and expert-matmul showed an inflated ~120s. Fix: split into two narrow spans around only the GPU work moe() does NOT cover (shared-expert dispatch, routed upload+add), letting moe() self-time as all other callers already do. Verified: 'other' now positive (14-17s), expert-matmul realistic (5-6s). 2. MTP blanket-disabled under CUDA (g_draft=0 when g_cuda_enabled). This was a conservative guard from #163 before the root cause (cold-expert fused-pair + IDOT kernel divergence) was fully diagnosed. GPU-resident experts have no divergence; the cold subset still does but achieves 30-50% acceptance anyway (matching non-CUDA builds). Add COLI_CUDA_MTP=1 opt-in so users can test speculation under CUDA. Default unchanged. Verified: COLI_CUDA_MTP=1 -> MTP ACTIVE (draft=3), 44% acceptance, 3 forwards for 8 tokens (vs 7 without MTP). Refs #292 #163