Repository navigation
fix(moe): pad fp8 calibration scale banks like the loader - #902
Merged
jason-fxz merged 1 commit intoNov 13, 2026
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ft bench bw --modelbuilds block-FP8 scale banks without the loader's padding. For Qwen3.8-Flash-Next-FP8 (H2560/I640), the 200 Bdown_scalerows disable fused multi-bank copy; the fallback then rejects the 400 Bgate_up_scalerows. The command exits 0 with null gather/overlap bandwidths. Hybrid with auto fetch (-1) consequently falls back to a fixed fetch cap of 1; remaining misses execute on CPU.Reuse
fp8_block_scale_padin both calibration bank builders, matching production strides and byte counts.down_scalebecomes 240 B and fused copy works; the aligned H2048/I512 layout is unchanged. Users must rerun calibration after updating; serving reads the saved profile without running the benchmark.Five-device validation against main
27740fec: the original command produces three null gather/overlap fields on every device; the fix restores them. Gather GB/s after: 4090 25.11, 5090 53.70, W7900D 27.15, R9700 36.85, H100 44.54. Both geometries pass byte-exact permuted expert copies; the existing padded-scale CPU numerical reference passes on all five devices.Model A/B switches the profiles generated by main/fix with identical serving code and settings: Qwen3.8-Flash-Next FP8, DFlash 2 k=7, Hybrid-auto, C1/TP1, 32,768 input/256 output, 2,048 expert slots, 12 CPU workers, graphs, PLE disk, naive KV40,960/chunk8,192. AB then BA, three fixed prompts per launch: six formal measurements/arm, excluding smoke and a separate 32K warmup; no outlier removal.
All speeds below are request-level medians in token/s; Decode includes [min,max]. Change is the ratio of Decode medians minus one. Decode excludes prefill and the first emitted batch; Generate includes prefill.
R9700 has large stalls: pooled Decode is 4.80→4.40 token/s despite its higher median. RTX4090 has a 137.76s TTFT outlier; pooled Generate is 5.19→4.65. All samples are retained. Profiles change CPU/GPU expert placement and greedy outputs differ; these results do not establish answer accuracy or an equal-output speedup.
Environment and reproduction
FreeToken0.2.2; Ubuntu24.04 containers, Triton3.8.0, Transformers5.18.0. CUDA13.0: Python3.12.3/PyTorch2.14.1+cu130. ROCm10.1.0: Python3.13.13/PyTorch2.14.0+rocm10.1.0 (HIP build7.16.26385).
H100 host: Ubuntu22.04; image-provided forward-compat libcuda580.95.05. Same per-device environment for both arms.
Run on each source version:
For a custom output file, set
FREETOKEN_BENCHBW_PATHto it when serving. benchbw-fp8-validation.zip contains the measured model driver, fixed token IDs, per-device commands, raw request records, and an independently verified statistics script.