minimal MPS-specific bf16 guard - #22
Open
robbiemu wants to merge 1 commit into
Open
Conversation
Author
|
There is also a usability branch I could add as a followup pr: https://github.com/robbiemu/MisoTTS/tree/mps-usability here's what that accomplishes: Changed:
|
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.
Implemented a minimal MPS BF16 guard.
edit: I just wrapped up a long-format generation and listen test, and sadly this is not bit-perfect. This PR should be treated as a targeted MPS BF16 compatibility improvement, not a complete replacement for full FP32 MPS fallback. In my tests this is close enough to keep it from switching voices, but not identical renderings.
Reason:
MPS BF16 generation can diverge from CPU/CUDA BF16 at a narrow early-backbone decision boundary. In a focused diagnostic, CPU BF16 and CUDA BF16 produced an exact codebook1 tie, while MPS BF16 gave one candidate a one-step advantage. CPU FP32 preferred the same candidate as MPS BF16, but with a smaller gap, so this appears to be a BF16 backend boundary mismatch rather than a broad model failure. The divergence was traced to the first backbone block, and the smallest tested precision island that restored CPU/CUDA BF16 behavior was FP32 compute for only
backbone.layers[0].mlp. summaryThis PR keeps the bulk model in BF16 on MPS, but runs that one MLP path in FP32 and casts the output back to BF16 before returning to the normal residual path. This is intended to preserve MPS BF16 memory behavior while avoiding the observed first-layer parity issue.
Scope:
This does not change CPU or CUDA behavior, and the guard can be disabled with
MISO_DISABLE_MPS_BF16_LAYER0_MLP_FP32=1for A/B testing. Its a narrow fix:Changed:
apply_mps_bf16_layer0_mlp_fp32_guard, patching onlymodel.backbone.layers[0].mlp.forward.device=mps+dtype=torch.bfloat16, with disable env varMISO_DISABLE_MPS_BF16_LAYER0_MLP_FP32=1, plus an explicit optional override.Local validation:
rtk .venv/bin/python -m pytest tests/test_mps_bf16_layer0_mlp_guard.py -qpassed:3 passedrtk uv run --project . python -m pytest tests/test_mps_bf16_layer0_mlp_guard.py -qpassed:3 passedargmax_token = 316logit[316] = 17.875logit[1056] = 17.875gap = 0.0ties = 2Results:
The overhead numbers are also important: the focused diagnostic I linked to above went from about 59.4s baseline to 60.5s with layer00_mlp_fp32_only, roughly +1.9%, and the extra storage cost for keeping FP32 copies of w1/w2/w3 is about 336 MiB.
The specific numerical boundary we isolated is resolved by the minimal MPS BF16 guard: it restores the observed tie behavior and keeps production outputs decode-valid. However, end-to-end production listening still exposes quality issues, including issues also present on CPU BF16, so this PR does not resolve the full generation/audio-quality problem. This PR should be treated as an experimental targeted MPS BF16 compatibility improvement, not a complete replacement for full FP32 MPS fallback.
Development note: ChatGPT was used to help plan diagnostics, interpret results, and draft this PR description.
probably: Fixes #1