Compare commits

...
Sign in to create a new pull request.

1 commit

Author SHA1 Message Date
Datta Nimmaturi
340584d5c0 Disable auto MTP on Windows and macOS 2026-06-05 09:22:20 +00:00
2 changed files with 63 additions and 3 deletions

View file

@ -492,6 +492,10 @@ def _extra_args_set_spec_type(extra_args: Optional[Iterable[str]]) -> bool:
return False
def _auto_mtp_supported_platform() -> bool:
return sys.platform not in ("win32", "darwin")
def _build_ngram_mod_flags(
caps: Optional[dict],
n_match: int = 24,
@ -2919,6 +2923,7 @@ class LlamaCppBackend:
_mtp_effective in ("mtp", "mtp+ngram")
or (
_mtp_effective == "auto"
and _auto_mtp_supported_platform()
and (
bool(self._nextn_predict_layers)
or _is_mtp_model_name(model_identifier, model_path)
@ -3635,7 +3640,8 @@ class LlamaCppBackend:
4B+ GPU/CPU: spec on is a net win (1.08x-1.46x).
Auto falls back to ngram-mod (zero-VRAM, near-zero idle cost on
diverse content); forced MTP variants engage anyway and just log
a warning per the user's choice.
a warning per the user's choice. Windows and macOS skip auto-MTP
until the llama.cpp MTP path no longer pegs CPU during generation.
"""
flags: List[str] = []
# Reset; emit branches re-set on the resolved emission.
@ -3779,9 +3785,18 @@ class LlamaCppBackend:
# effective_mode == "auto": today's promotion path. llama.cpp
# #22673: MTP is compatible with mmproj, so there's no vision gate.
if is_mtp_model and not _mtp_too_small:
# GPU: MTP-only. CPU/Mac: chain ngram-mod + MTP.
if (
is_mtp_model
and not _mtp_too_small
and _auto_mtp_supported_platform()
):
# Supported platforms: GPU = MTP-only; CPU = chain ngram-mod + MTP.
_emit_mtp(chain_ngram = not gpus)
elif is_mtp_model and not _mtp_too_small:
logger.info(
"MTP GGUF detected; auto-disabling MTP on Windows/macOS. "
"Use the Studio Speculative Decoding dropdown to force it."
)
elif is_mtp_model and _mtp_too_small:
# Sub-3B fallback: drop the MTP draft head, keep ngram-mod
# when the binary supports it.

View file

@ -1128,6 +1128,51 @@ def test_build_speculative_flags_matrix(
assert "--spec-ngram-mod-n-match" not in parsed
@pytest.mark.parametrize("platform_name", ["win32", "darwin"])
def test_build_speculative_flags_auto_skips_mtp_on_windows_and_macos(
monkeypatch, platform_name
):
monkeypatch.setattr(sys, "platform", platform_name)
backend = _resolver_backend(monkeypatch)
flags = backend._build_speculative_flags(
speculative_type = "auto",
spec_draft_n_max = None,
extra_args = None,
model_identifier = _MTP_MODEL,
model_path = None,
gpus = True,
binary = "/fake/llama-server",
)
parsed = _flags_dict(flags)
assert "--spec-type" not in parsed
assert "--spec-draft-n-max" not in parsed
assert backend.requested_spec_mode == "auto"
assert backend.speculative_type is None
def test_build_speculative_flags_forced_mtp_still_works_on_windows(monkeypatch):
monkeypatch.setattr(sys, "platform", "win32")
backend = _resolver_backend(monkeypatch)
flags = backend._build_speculative_flags(
speculative_type = "mtp",
spec_draft_n_max = None,
extra_args = None,
model_identifier = _MTP_MODEL,
model_path = None,
gpus = True,
binary = "/fake/llama-server",
)
parsed = _flags_dict(flags)
assert parsed.get("--spec-type") == "draft-mtp"
assert parsed.get("--spec-draft-n-max") == "2"
assert backend.requested_spec_mode == "mtp"
assert backend.speculative_type == "draft-mtp"
def test_build_speculative_flags_user_extra_args_owns_spec_type(monkeypatch):
# User --spec-type in extra_args bypasses the dropdown entirely.
backend = _resolver_backend(monkeypatch)