eagle3-omni-inner.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #!/usr/bin/env python3
  2. """Patch vLLM's set_eagle3_aux_hidden_state_layers to resolve the eagle3
  3. interface on the inner language-model decoder when the outer model is a
  4. wrapper (e.g. MiMoV2OmniForCausalLM, whose text stack is
  5. MiMoV2ForCausalLM/MiMoV2Model and does implement SupportsEagle3).
  6. Root cause (2026-09-28, mimo26 vLLM lane): MiMo-V2.6-Flash-MOPD resolves to
  7. MiMoV2OmniForCausalLM (multimodal wrapper). For method=dflash the GPU model
  8. runner marks use_aux_hidden_state_outputs=True and calls
  9. set_eagle3_aux_hidden_state_layers(target, spec), which isinstance-checks
  10. SupportsEagle3 against the OUTER class and raises
  11. "Model does not support EAGLE3 interface" before ever consulting
  12. _inner_decoder(). Everything downstream (aux slots, _maybe_add_hidden_state)
  13. lives on the inner MiMoV2Model, and with PP=1 the relay helpers are no-ops,
  14. so an inner-resolved check is exactly the correct behaviour here.
  15. Idempotent, anchor-based: `--check` exits 0 only when the patch is present,
  16. 2 when the file is still patchable (and the build must apply it), 1 when the
  17. anchor is absent — it refuses silently-wrong sources. `--apply` writes once
  18. (no backup file; the container layer is disposable and the image rebuilds
  19. from this dir).
  20. """
  21. import sys
  22. MODULE = "vllm.v1.worker.gpu.spec_decode.eagle.eagle3_utils"
  23. ANCHOR = (
  24. " if not supports_eagle3(model):\n"
  25. ' raise RuntimeError("Model does not support EAGLE3 interface")\n'
  26. )
  27. PATCHED = (
  28. " if not supports_eagle3(model):\n"
  29. " # Multimodal wrappers (e.g. MiMoV2OmniForCausalLM) keep the\n"
  30. " # eagle3 carrier one level in — the language model whose method\n"
  31. " # set_aux_hidden_state_layers() already knows how to reach the\n"
  32. " # EagleModelMixin holder. Resolve it before failing (the\n"
  33. " # _inner_decoder() helper does NOT fit: it returns the bare\n"
  34. " # decoder, which lacks the protocol's method).\n"
  35. " _lang = None\n"
  36. " if hasattr(model, \"get_language_model\"):\n"
  37. " _lang = model.get_language_model()\n"
  38. " elif hasattr(model, \"language_model\"):\n"
  39. " _lang = model.language_model\n"
  40. " if _lang is None or not supports_eagle3(_lang):\n"
  41. ' raise RuntimeError("Model does not support EAGLE3 interface")\n'
  42. " logger.info(\n"
  43. ' "Eagle3 interface resolved on %s inside %s",\n'
  44. " type(_lang).__name__,\n"
  45. " type(model).__name__,\n"
  46. " )\n"
  47. " model = _lang\n"
  48. )
  49. def target_path() -> str:
  50. import importlib
  51. mod = importlib.import_module(MODULE)
  52. path = getattr(mod, "__file__", None)
  53. if not path:
  54. raise SystemExit(f"{MODULE} has no __file__ (frozen install?)")
  55. return path
  56. def main() -> int:
  57. check = "--check" in sys.argv
  58. path = target_path()
  59. with open(path, encoding="utf-8") as f:
  60. src = f.read()
  61. if PATCHED in src:
  62. print(f"ALREADY PATCHED: {path}")
  63. return 0
  64. if ANCHOR not in src:
  65. print(f"ANCHOR NOT FOUND (unexpected source): {path}", file=sys.stderr)
  66. return 1
  67. if check:
  68. print(f"NOT PATCHED YET: {path}", file=sys.stderr)
  69. return 2
  70. with open(path, "w", encoding="utf-8") as f:
  71. f.write(src.replace(ANCHOR, PATCHED, 1))
  72. print(f"APPLIED: {path}")
  73. return 0
  74. if __name__ == "__main__":
  75. sys.exit(main())