Repository navigation
[Quant] Reject non-finite and non-per-tensor fp8 K/V scales at checkpoint load - #40243
Closed
rchalamala wants to merge 2 commits into
Closed
rchalamala wants to merge 2 commits into
rchalamala wants to merge 2 commits into
Conversation
rchalamala
marked this pull request as ready for review
September 18, 2026 22:38
rchalamala
requested review from
Alisehen,
AniZpZ,
BBuf,
Edwardf0t1,
FlamingoPg,
HaiShaw,
OrangeRedeng,
b8zhong,
ch-wan and
mmangkad
as code owners
September 18, 2026 22:38
Contributor
|
/tag-and-rerun-ci |
rchalamala
force-pushed
the
fp8-kv-scale-validation
branch
from
September 18, 2026 23:01
ba3e1f1 to
f75666c
Compare
rchalamala
marked this pull request as draft
September 18, 2026 23:05
rchalamala
force-pushed
the
fp8-kv-scale-validation
branch
from
September 19, 2026 04:13
f75666c to
6a1aabe
Compare
…scale check) * quant: reject non-finite fp8 K/V scales at load (sibling of the zero-scale check) * kv_cache: raise ValueError for non-finite scales instead of assert * kv_cache: validate the final converted scales as well; FNUZ doubling can push a finite float32 scale past the dtype max, so reject non-finite or overflowing values before mutating the layer --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Check numel before the finite check so multi-element scales raise a clear ValueError instead of an ambiguous RuntimeError, and evaluate isfinite on CPU copies. Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
rchalamala
force-pushed
the
fp8-kv-scale-validation
branch
from
September 19, 2026 04:25
6a1aabe to
df9ed1c
Compare
4 tasks done
3 of 5 tasks
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.
Motivation
BaseKVCacheMethod.process_weights_after_loadinginpython/sglang/srt/layers/quantization/kv_cache.pyvalidates checkpoint-loaded fp8 K/V scales only incidentally, so corrupt scales either crash with confusing errors or are silently accepted:isinstance(k_scale, float)per-tensor check at the bottom of the method:if layer.k_scale > 0.0raisesRuntimeError: Boolean value of Tensor with more than one value is ambiguousfirst.> 0.0nor<= 0.0, so it falls into the single-kv_scale remap branch and dies onassert layer.k_scale > 0.0— a bare AssertionError with no message.> 0.0and is copied straight intolayer.k_scale_float, so an infinite scale reaches the attention forward.max(k, v)picks the valid one) and the corrupt value is silently replaced.Probe of
process_weights_after_loadingon unmodified base 929230a (CPU, scalar/tensor parameters injected into a stub layer):Same probe with this PR:
Modifications
Two stacked guards at the top of
process_weights_after_loading, plus a post-conversion guard before the layer is mutated:numel() != 1, raise a ValueError naming both shapes. This replaces the ambiguous-bool RuntimeError with an explicit message.torch.isfinite(...).all(), otherwise raise a ValueError naming both values. This catches NaN and ±inf in one place, including the -inf case that was previously remapped away.math.isfiniteon both Python floats and require each to fit intorch.finfo(layer.k_scale.dtype).max, otherwise raise a ValueError naming both converted values. This closes the FNUZ overflow hole where a finite checkpoint scale doubles past the float32 maximum.The existing branches are unchanged: separate positive scales still win, two non-positive scales still default to 1.0, and the single-kv_scale → k_scale → v_scale remap keeps its current behavior. The pre-existing
isinstance(float)check stays as a backstop.Accuracy Tests
New regression file
test/registered/unit/layers/quantization/test_kv_cache_scale_validation.py(CPU, registeredbase-a-test-cpu): inf/-inf/NaN rejection, multi-element rejection with a per-tensor ValueError (including a multi-element scale containing NaN, which previously raised the ambiguous RuntimeError), zero-scale AssertionError preserved, finite scales accepted, unset scales defaulting to 1.0, FNUZ doubling of 3e38 rejected as post-conversion overflow, and FNUZ doubling of 1e38 accepted within float32.Commands (CPU):
The 2 fp4 failures (
TestFP4MXBlock16KVCacheMethod::test_quantize_dequantize_roundtrip_cpu,TestFP4MXBlock16KVQuantizeUtil::test_roundtrip_cpu) are pre-existing and environmental: torch inductor emitsImportError: /lib64/libc.so.6: version 'GLIBC_2.38' not foundon this CPU box. Re-running the same file on unmodified base 929230a reproduces the identical 2 failed / 22 passed / 1 skipped result.Lint:
ruff check --select=F401,F821,UP037(the pre-commit hook's selection) passes on both changed files;ruff format --checkreports both files already formatted.Speed Tests and Profiling
No speed impact claimed; not measured (CPU-only validation host).
Validation limits
is_fp8_fnuz()in the new tests (post-conversion overflow rejected, within-float32 doubling accepted); no real FNUZ/ROCm hardware run.Checklist
CI States
Latest PR Test (Base): ❌ Run #35421236779
Latest PR Test (Extra): ❌ Run #35421236633
Latest PR Test (AMD ROCm 10): ❌ Run #35421236734