mtplx 2.4.2__tar.gz → 2.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (497) hide show
  1. {mtplx-2.4.2 → mtplx-2.5.0}/CHANGELOG.md +61 -0
  2. {mtplx-2.4.2 → mtplx-2.5.0}/CITATION.cff +1 -1
  3. {mtplx-2.4.2 → mtplx-2.5.0}/PKG-INFO +2 -2
  4. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/artifacts.py +34 -25
  5. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/attention_context.py +29 -0
  6. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/backends/descriptors.py +43 -0
  7. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/commands/public.py +30 -5
  8. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/constants.py +23 -0
  9. mtplx-2.5.0/mtplx/deepseek_v4_adaptive_width.py +340 -0
  10. mtplx-2.5.0/mtplx/deepseek_v4_attention_island.py +656 -0
  11. mtplx-2.5.0/mtplx/deepseek_v4_attn_proj_wide_m3.py +478 -0
  12. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/gdn_capture.py +30 -0
  13. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/generation.py +298 -13
  14. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/hy_v3_mtp_patch.py +82 -2
  15. mtplx-2.5.0/mtplx/kernels/gdn_tape_headquarter.py +229 -0
  16. mtplx-2.5.0/mtplx/kernels/laguna_dense_mlp.py +503 -0
  17. mtplx-2.5.0/mtplx/kernels/laguna_gated_oproj.py +410 -0
  18. mtplx-2.5.0/mtplx/kernels/laguna_moe_combine.py +301 -0
  19. mtplx-2.5.0/mtplx/kernels/laguna_moe_gather_gemm.py +273 -0
  20. mtplx-2.5.0/mtplx/kernels/laguna_moe_merged.py +482 -0
  21. mtplx-2.5.0/mtplx/kernels/laguna_moe_shared.py +365 -0
  22. mtplx-2.5.0/mtplx/kernels/laguna_moe_swiglu.py +359 -0
  23. mtplx-2.5.0/mtplx/kernels/laguna_prefill_moe_combine.py +180 -0
  24. mtplx-2.5.0/mtplx/kernels/laguna_prefill_qk_rope.py +447 -0
  25. mtplx-2.5.0/mtplx/kernels/laguna_prefill_router.py +252 -0
  26. mtplx-2.5.0/mtplx/kernels/laguna_qk_rope_sliding.py +358 -0
  27. mtplx-2.5.0/mtplx/kernels/laguna_qk_yarn_full.py +419 -0
  28. mtplx-2.5.0/mtplx/kernels/laguna_qkvg_fused.py +592 -0
  29. mtplx-2.5.0/mtplx/kernels/laguna_residual_router.py +292 -0
  30. mtplx-2.5.0/mtplx/kernels/laguna_route_csort.py +220 -0
  31. mtplx-2.5.0/mtplx/kernels/laguna_router_topk.py +335 -0
  32. mtplx-2.5.0/mtplx/kernels/laguna_sdpa_2pass.py +334 -0
  33. mtplx-2.5.0/mtplx/kernels/laguna_sdpa_pair.py +263 -0
  34. mtplx-2.5.0/mtplx/kernels/laguna_steel_attn.py +476 -0
  35. mtplx-2.5.0/mtplx/laguna_alt_step.py +685 -0
  36. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/models/deepseek_v4.py +924 -50
  37. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/mtp_patch.py +34 -13
  38. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/reasoning_codecs.py +17 -11
  39. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/runtime.py +154 -1
  40. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/server/omlx_bridge/tool_calling.py +215 -1
  41. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/server/openai.py +329 -9
  42. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/thermal.py +186 -5
  43. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/ui/onboarding.py +16 -5
  44. mtplx-2.5.0/mtplx/vendored_hy_v3.py +467 -0
  45. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/version.py +2 -2
  46. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx.egg-info/PKG-INFO +2 -2
  47. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx.egg-info/SOURCES.txt +45 -0
  48. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx.egg-info/requires.txt +1 -1
  49. {mtplx-2.4.2 → mtplx-2.5.0}/pyproject.toml +6 -3
  50. mtplx-2.5.0/scripts/deepseek_v4_adaptive_width_arms.sh +65 -0
  51. mtplx-2.5.0/scripts/deepseek_v4_adaptive_width_guarded.py +227 -0
  52. mtplx-2.5.0/scripts/deepseek_v4_attention_island_arms.sh +133 -0
  53. mtplx-2.5.0/scripts/deepseek_v4_attention_island_guarded.py +652 -0
  54. mtplx-2.5.0/scripts/deepseek_v4_attn_proj_wide_m3_arms.sh +47 -0
  55. mtplx-2.5.0/scripts/deepseek_v4_attn_proj_wide_m3_guarded.py +83 -0
  56. mtplx-2.5.0/scripts/deepseek_v4_mtpk_bench.py +2628 -0
  57. mtplx-2.5.0/tests/test_app_cli_env_parity.py +101 -0
  58. mtplx-2.5.0/tests/test_deepseek_v4_adaptive_width_bracket.py +528 -0
  59. mtplx-2.5.0/tests/test_deepseek_v4_adaptive_width_policy.py +462 -0
  60. mtplx-2.5.0/tests/test_deepseek_v4_attention_island.py +410 -0
  61. mtplx-2.5.0/tests/test_deepseek_v4_attention_island_bracket.py +528 -0
  62. mtplx-2.5.0/tests/test_deepseek_v4_attn_proj_wide_m3.py +337 -0
  63. mtplx-2.5.0/tests/test_deepseek_v4_attn_proj_wide_m3_bracket.py +213 -0
  64. mtplx-2.5.0/tests/test_deepseek_v4_o_lora.py +1100 -0
  65. mtplx-2.5.0/tests/test_gdn_tape_headquarter.py +75 -0
  66. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_hy_v3_mtp_backend.py +71 -7
  67. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_hy_v3_mtp_graft.py +7 -0
  68. mtplx-2.5.0/tests/test_laguna_alt_step.py +272 -0
  69. mtplx-2.5.0/tests/test_laguna_steel_attn.py +166 -0
  70. mtplx-2.5.0/tests/test_mtp_depth_n.py +217 -0
  71. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_omlx_bridge.py +33 -0
  72. mtplx-2.5.0/tests/test_runtime_deepseek_v4_o_lora.py +119 -0
  73. mtplx-2.5.0/tests/test_runtime_model_alias.py +85 -0
  74. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_thermal.py +166 -0
  75. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_tool_aware_stream_translator.py +54 -0
  76. mtplx-2.5.0/tests/test_tool_call_hidden_guard_and_key_repair.py +307 -0
  77. mtplx-2.4.2/scripts/deepseek_v4_mtpk_bench.py +0 -1104
  78. mtplx-2.4.2/tests/test_deepseek_v4_o_lora.py +0 -510
  79. {mtplx-2.4.2 → mtplx-2.5.0}/LICENSE +0 -0
  80. {mtplx-2.4.2 → mtplx-2.5.0}/MANIFEST.in +0 -0
  81. {mtplx-2.4.2 → mtplx-2.5.0}/NOTICE +0 -0
  82. {mtplx-2.4.2 → mtplx-2.5.0}/README.md +0 -0
  83. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/__init__.py +0 -0
  84. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/a3b_compiled_target_prefix.py +0 -0
  85. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/a3b_whole_moe.py +0 -0
  86. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/adaptive.py +0 -0
  87. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/app_settings.py +0 -0
  88. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/attention_split.py +0 -0
  89. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/backends/__init__.py +0 -0
  90. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/backends/deepseek_mtp.py +0 -0
  91. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/backends/gemma4_assistant.py +0 -0
  92. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/backends/glm_mtp.py +0 -0
  93. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/backends/hy_v3_mtp.py +0 -0
  94. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/backends/mimo_mtp.py +0 -0
  95. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/backends/nemotron_h_mtp.py +0 -0
  96. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/backends/qwen3_next.py +0 -0
  97. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/backends/registry.py +0 -0
  98. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/backends/step3p5_mtp.py +0 -0
  99. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/batched_decode.py +0 -0
  100. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/batching/__init__.py +0 -0
  101. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/batching/admission.py +0 -0
  102. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/batching/buckets.py +0 -0
  103. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/batching/scheduler.py +0 -0
  104. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/batching/state.py +0 -0
  105. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/__init__.py +0 -0
  106. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/code_eval.py +0 -0
  107. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/programming_prompts.py +0 -0
  108. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/prompts/aime_2026.jsonl +0 -0
  109. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/prompts/calibration_coding.jsonl +0 -0
  110. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/prompts/default.jsonl +0 -0
  111. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/prompts/flappy.jsonl +0 -0
  112. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/prompts/long_code.jsonl +0 -0
  113. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/prompts/long_code_uncapped.jsonl +0 -0
  114. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/prompts/python_modules_long.jsonl +0 -0
  115. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/runners/__init__.py +0 -0
  116. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/runners/aime.py +0 -0
  117. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/runners/batch_equivalence.py +0 -0
  118. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/runners/capture_commit_equivalence.py +0 -0
  119. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/runners/competitor_baselines.py +0 -0
  120. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/runners/contract_probe.py +0 -0
  121. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/runners/harness.py +0 -0
  122. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/runners/mtp1_gate.py +0 -0
  123. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/runners/mtp1_sampler_smoke.py +0 -0
  124. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/runners/mtp_adaptive.py +0 -0
  125. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/runners/mtp_chain_probe.py +0 -0
  126. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/runners/mtp_depth_grid.py +0 -0
  127. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/runners/mtp_depth_sweep.py +0 -0
  128. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/runners/mtp_tree_probe.py +0 -0
  129. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/runners/multi_qmv_probe.py +0 -0
  130. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/runners/preflight.py +0 -0
  131. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/runners/runtime_smoke.py +0 -0
  132. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/runners/session_bank.py +0 -0
  133. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/runners/truth.py +0 -0
  134. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/runners/verify_profile.py +0 -0
  135. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/runners/verify_qmm_probe.py +0 -0
  136. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/runners/verify_ratio.py +0 -0
  137. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/schema.py +0 -0
  138. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/validators/__init__.py +0 -0
  139. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/validators/aime.py +0 -0
  140. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/benchmarks/validators/basic.py +0 -0
  141. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/block_attention.py +0 -0
  142. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/cache_bank/__init__.py +0 -0
  143. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/cache_bank/codec.py +0 -0
  144. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/cache_bank/cold_tier.py +0 -0
  145. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/cache_state.py +0 -0
  146. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/chat_encoding.py +0 -0
  147. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/cli.py +0 -0
  148. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/commands/__init__.py +0 -0
  149. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/commands/forge.py +0 -0
  150. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/compile_state.py +0 -0
  151. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/compiled_forward.py +0 -0
  152. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/compressed_tensors.py +0 -0
  153. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/config.py +0 -0
  154. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/constrained.py +0 -0
  155. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/context_copy.py +0 -0
  156. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/correctors/__init__.py +0 -0
  157. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/correctors/diagonal_affine.py +0 -0
  158. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/correctors/low_rank.py +0 -0
  159. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/daemon_client.py +0 -0
  160. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/dashboard/__init__.py +0 -0
  161. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/dashboard/_static/assets/index-CRP90ECi.js +0 -0
  162. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/dashboard/_static/assets/index-DYvLRZ33.css +0 -0
  163. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/dashboard/_static/index.html +0 -0
  164. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/deepseek_mtp_patch.py +0 -0
  165. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/default_models.py +0 -0
  166. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/diagnostics.py +0 -0
  167. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/draft_lm_head.py +0 -0
  168. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/draft_sampling.py +0 -0
  169. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/engine_session.py +0 -0
  170. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/env.py +0 -0
  171. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/errors.py +0 -0
  172. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/expert_layout.py +0 -0
  173. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/fan_mode.py +0 -0
  174. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/fast_sampling.py +0 -0
  175. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/gemma4_pair.py +0 -0
  176. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/glm_mtp_patch.py +0 -0
  177. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/graphbank.py +0 -0
  178. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/hardware.py +0 -0
  179. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/hf_loader.py +0 -0
  180. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/kernel_selfcheck.py +0 -0
  181. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/kernels/__init__.py +0 -0
  182. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/kernels/a3b_whole_moe.py +0 -0
  183. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/kernels/copy_leaf.py +0 -0
  184. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/kernels/fused_norm.py +0 -0
  185. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/kernels/gdn_blocked_prefill.py +0 -0
  186. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/kernels/laguna_decode.py +0 -0
  187. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/kernels/lm_head_topk.py +0 -0
  188. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/kernels/logits_topk.py +0 -0
  189. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/kernels/native_gdn_tail.py +0 -0
  190. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/kernels/sdpa_2pass.py +0 -0
  191. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/kernels/sdpa_2pass_paged.py +0 -0
  192. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/kernels/sdpa_2pass_paged_q8.py +0 -0
  193. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/kernels/sdpa_gqa_packed.py +0 -0
  194. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/kernels/verify_mlp_fused.py +0 -0
  195. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/kpi/__init__.py +0 -0
  196. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/kpi/reference_vllm.py +0 -0
  197. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/kpi/runtime_kpis.py +0 -0
  198. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/kv_quant.py +0 -0
  199. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/laguna_compiled_step.py +0 -0
  200. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/loop_guard.py +0 -0
  201. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/metadata_scrub.py +0 -0
  202. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/mimo_mtp_patch.py +0 -0
  203. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/model_catalog.py +0 -0
  204. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/model_scheduler.py +0 -0
  205. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/models/__init__.py +0 -0
  206. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/models/laguna.py +0 -0
  207. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/models/laguna_config.py +0 -0
  208. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/models/laguna_fused.py +0 -0
  209. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/moe_packed_projections.py +0 -0
  210. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/mtp_activation_stats.py +0 -0
  211. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/mtp_adapters.py +0 -0
  212. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/native_mlp.py +0 -0
  213. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/nax_verify.py +0 -0
  214. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/nemotron_h_mtp_patch.py +0 -0
  215. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/opencode.py +0 -0
  216. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/optimization_profiles.py +0 -0
  217. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/pi.py +0 -0
  218. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/prefill_bench.py +0 -0
  219. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/profiles.py +0 -0
  220. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/progress_heartbeat.py +0 -0
  221. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/proj_quant.py +0 -0
  222. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/proposal_reranker.py +0 -0
  223. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/qwen3_5_mtp_patch.py +0 -0
  224. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/qwen_row_owned_router.py +0 -0
  225. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/ragged_attention.py +0 -0
  226. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/ragged_kv_cache.py +0 -0
  227. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/request_capture.py +0 -0
  228. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/roofline_profile.py +0 -0
  229. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/runtime_options.py +0 -0
  230. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/sampling.py +0 -0
  231. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/server/__init__.py +0 -0
  232. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/server/dashboard_state.py +0 -0
  233. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/server/omlx_bridge/__init__.py +0 -0
  234. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/server/omlx_bridge/adapter.py +0 -0
  235. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/server/omlx_bridge/thinking.py +0 -0
  236. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/server_urls.py +0 -0
  237. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/session_bank.py +0 -0
  238. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/speculative.py +0 -0
  239. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/step3p5_mtp_patch.py +0 -0
  240. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/swival.py +0 -0
  241. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/templates/qwen36_froggeric_v19/chat_template.jinja +0 -0
  242. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/templates/qwen36_froggeric_v21_3/chat_template.jinja +0 -0
  243. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/thermal_sidecar.py +0 -0
  244. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/thinking_guard.py +0 -0
  245. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/trace_parity.py +0 -0
  246. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/turboquant.py +0 -0
  247. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/ui/__init__.py +0 -0
  248. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/ui/banner.py +0 -0
  249. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/ui/chat_printer.py +0 -0
  250. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/ui/download_progress.py +0 -0
  251. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/ui/panels.py +0 -0
  252. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/ui/progress.py +0 -0
  253. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/verify_kernels.py +0 -0
  254. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/verify_qmv.py +0 -0
  255. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/vision/__init__.py +0 -0
  256. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/vision/processing.py +0 -0
  257. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/vision/qwen3_vl_tower.py +0 -0
  258. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx/vision/splice.py +0 -0
  259. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx.egg-info/dependency_links.txt +0 -0
  260. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx.egg-info/entry_points.txt +0 -0
  261. {mtplx-2.4.2 → mtplx-2.5.0}/mtplx.egg-info/top_level.txt +0 -0
  262. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/agent_user_path_qa.py +0 -0
  263. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/aime_serve_gate.py +0 -0
  264. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/aime_shape_memory_bench.py +0 -0
  265. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/code_eval_gate.py +0 -0
  266. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/collect_mtp_activation_stats.py +0 -0
  267. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/collect_mtp_hidden_calib.py +0 -0
  268. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/combine_mtp_adapters.py +0 -0
  269. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/compiled_verify_exactness.py +0 -0
  270. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/convert_step37_to_mtplx_step3p5.py +0 -0
  271. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/deepseek_v4_build_mtp_model.py +0 -0
  272. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/deepseek_v4_decode_verify.py +0 -0
  273. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/deepseek_v4_dispatch_census.py +0 -0
  274. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/deepseek_v4_guard_window.py +0 -0
  275. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/deepseek_v4_logits_gate.py +0 -0
  276. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/deepseek_v4_moe_tail_arms.sh +0 -0
  277. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/deepseek_v4_moe_tail_gate.py +0 -0
  278. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/deepseek_v4_moe_tail_guarded_bracket.py +0 -0
  279. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/deepseek_v4_mtp_bind_check.py +0 -0
  280. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/deepseek_v4_op_census.py +0 -0
  281. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/deepseek_v4_smoke_generate.py +0 -0
  282. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/deepseek_v4_sparse_gate_probe.py +0 -0
  283. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/deepseek_v4_validate_moe_tail_k3_bracket.py +0 -0
  284. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/eval_mtp_corrector.py +0 -0
  285. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/filter_mtp_adapter.py +0 -0
  286. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/fp16_turbo_exactness_20260707.py +0 -0
  287. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/fresh_venv_smoke.sh +0 -0
  288. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/gauntlet_scoreboard.py +0 -0
  289. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/hygiene_scan.sh +0 -0
  290. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/install_macos.sh +0 -0
  291. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/install_preview_global.sh +0 -0
  292. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/kvcache_exactness_audit_20260703.py +0 -0
  293. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/kvcache_soak_20260703.py +0 -0
  294. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/kvcache_warm_probe_20260703.py +0 -0
  295. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/make_fp16_precision_sibling.py +0 -0
  296. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/midform_gate.py +0 -0
  297. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/oc_tap.py +0 -0
  298. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/oc_tap_diff.py +0 -0
  299. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/ocspeed-20260703/abba_final.sh +0 -0
  300. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/ocspeed-20260703/accept_depth_probe.py +0 -0
  301. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/ocspeed-20260703/arm_runner.sh +0 -0
  302. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/ocspeed-20260703/forward_depth_bisect.py +0 -0
  303. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/ocspeed-20260703/longgen_probe.py +0 -0
  304. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/ocspeed-20260703/loop_degradation_probe.py +0 -0
  305. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/ocspeed-20260703/paired_longgen.sh +0 -0
  306. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/ocspeed-20260703/sdpa_microbench.py +0 -0
  307. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/ocspeed-20260703/snapshot_tail.py +0 -0
  308. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/opencode_concurrency_qa.py +0 -0
  309. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/phase0h_paged_verifier_exactness.py +0 -0
  310. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/pillar_gate_qa.py +0 -0
  311. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/probe_mlx_pr3026_qsdpa.py +0 -0
  312. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/probe_mx_compile_buckets.py +0 -0
  313. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/probe_paged_gqa_sdpa_routes.py +0 -0
  314. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/prodqa-20260703/candidate_truecold_20260703.py +0 -0
  315. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/prodqa-20260703/cold_pair_recheck.py +0 -0
  316. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/prodqa-20260703/competitors_20260703.sh +0 -0
  317. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/prodqa-20260703/decode_gap_matrix.py +0 -0
  318. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/prodqa-20260703/hermes_pty_driver.py +0 -0
  319. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/prodqa-20260703/omlx_probe.py +0 -0
  320. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/prodqa-20260703/pi_pty_driver.py +0 -0
  321. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/prodqa-20260703/pillar_ab_20260703.py +0 -0
  322. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/prodqa-20260703/tool_gauntlet_20260703.sh +0 -0
  323. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/quality_fp16_parent_logitdiff_20260707.py +0 -0
  324. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/r1_chisquare_verifier_correctness.py +0 -0
  325. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/release_macos_v1.sh +0 -0
  326. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/run_context_degradation_diagnostics.py +0 -0
  327. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/serve_openai_mtplx.py +0 -0
  328. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/session_cache_followup_qa.py +0 -0
  329. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/session_forensics.py +0 -0
  330. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/sparkle_rehearsal_kit.sh +0 -0
  331. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/step_acceptance.py +0 -0
  332. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/step_smoke.py +0 -0
  333. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/train_mtp_adapter_c4.py +0 -0
  334. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/validate_step_mtp_injector.py +0 -0
  335. {mtplx-2.4.2 → mtplx-2.5.0}/scripts/walltime-lab/run_project.py +0 -0
  336. {mtplx-2.4.2 → mtplx-2.5.0}/setup.cfg +0 -0
  337. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_a3b_compiled_target_prefix.py +0 -0
  338. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_a3b_whole_moe.py +0 -0
  339. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_adaptive.py +0 -0
  340. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_aime_serve_gate.py +0 -0
  341. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_ar_batch_penalties.py +0 -0
  342. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_artifacts.py +0 -0
  343. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_attention_split.py +0 -0
  344. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_background_warmup.py +0 -0
  345. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_batched_decode.py +0 -0
  346. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_batching_foundation.py +0 -0
  347. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_bracket_tool_rescue.py +0 -0
  348. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_cache_bank.py +0 -0
  349. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_cache_state.py +0 -0
  350. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_cli_parity_tools.py +0 -0
  351. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_code_eval.py +0 -0
  352. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_code_eval_gate.py +0 -0
  353. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_cold_tier_write_budget.py +0 -0
  354. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_compile_state.py +0 -0
  355. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_compiled_ar_wiring.py +0 -0
  356. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_compiled_forward.py +0 -0
  357. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_compressed_tensors.py +0 -0
  358. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_config.py +0 -0
  359. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_config_profile_precedence.py +0 -0
  360. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_constrained.py +0 -0
  361. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_context_copy_stats.py +0 -0
  362. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_context_degradation_profiles.py +0 -0
  363. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_correctors.py +0 -0
  364. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_cost_depth_policy.py +0 -0
  365. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_daemon_client.py +0 -0
  366. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_dashboard_endpoints.py +0 -0
  367. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_deepseek_v4_decode.py +0 -0
  368. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_deepseek_v4_dtypes.py +0 -0
  369. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_deepseek_v4_indexer.py +0 -0
  370. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_deepseek_v4_kernel_paths.py +0 -0
  371. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_deepseek_v4_loader.py +0 -0
  372. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_deepseek_v4_moe_tail.py +0 -0
  373. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_deepseek_v4_moe_tail_bracket.py +0 -0
  374. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_deepseek_v4_mtp.py +0 -0
  375. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_deepseek_v4_new_math.py +0 -0
  376. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_deepseek_v4_parity.py +0 -0
  377. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_deepseek_v4_sinkhorn_kernel.py +0 -0
  378. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_deepseek_v4_spec.py +0 -0
  379. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_deepseek_v4_swiglu_clamp.py +0 -0
  380. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_default_models.py +0 -0
  381. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_device_draft_core.py +0 -0
  382. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_diagnostics.py +0 -0
  383. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_download_progress.py +0 -0
  384. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_draft_lm_head.py +0 -0
  385. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_engine_session_concurrency.py +0 -0
  386. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_engine_session_env.py +0 -0
  387. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_env_flag_parsing.py +0 -0
  388. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_fast_sampling.py +0 -0
  389. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_forge_cli.py +0 -0
  390. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_gdn_blocked_prefill.py +0 -0
  391. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_gdn_boundary_retention.py +0 -0
  392. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_gdn_postconv_fusion.py +0 -0
  393. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_gdn_postconv_impl_gate.py +0 -0
  394. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_generation_store_on_prefill.py +0 -0
  395. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_generation_sustained.py +0 -0
  396. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_graphbank_compiled_verify.py +0 -0
  397. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_hf_loader.py +0 -0
  398. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_hygiene_scan.py +0 -0
  399. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_idle_postcommit_subagent.py +0 -0
  400. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_kernel_selfcheck.py +0 -0
  401. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_laguna_compiled_step.py +0 -0
  402. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_laguna_fused.py +0 -0
  403. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_laguna_model.py +0 -0
  404. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_lazy_snapshot_cow.py +0 -0
  405. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_loop_guard.py +0 -0
  406. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_max_idle_watchdog.py +0 -0
  407. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_max_lifecycle.py +0 -0
  408. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_memory_pressure_guard.py +0 -0
  409. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_metadata_scrub.py +0 -0
  410. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_metal_memory_caps.py +0 -0
  411. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_midform_gate.py +0 -0
  412. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_model_catalog.py +0 -0
  413. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_model_scheduler.py +0 -0
  414. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_moe_force_unsorted.py +0 -0
  415. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_moe_packed_projections.py +0 -0
  416. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_mtp_activation_stats.py +0 -0
  417. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_mtp_adapters.py +0 -0
  418. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_mtp_alias_load_path.py +0 -0
  419. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_mtp_depth_sweep.py +0 -0
  420. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_mtp_patch.py +0 -0
  421. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_mtp_payload_guards.py +0 -0
  422. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_mtp_weightless_degrade.py +0 -0
  423. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_nax_verify.py +0 -0
  424. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_no_mlx_imports.py +0 -0
  425. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_onboarding.py +0 -0
  426. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_openai_bridge.py +0 -0
  427. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_opencode.py +0 -0
  428. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_optimization_profiles.py +0 -0
  429. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_orphan_tool_markup.py +0 -0
  430. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_penalties.py +0 -0
  431. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_penalty_request_wiring.py +0 -0
  432. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_persistent_replay.py +0 -0
  433. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_phase0h_paged_verifier_exactness.py +0 -0
  434. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_policy_fingerprint_stability.py +0 -0
  435. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_postcommit_prefix_reuse.py +0 -0
  436. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_postcommit_resolve_for_request.py +0 -0
  437. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_postcommit_tools_plumbing.py +0 -0
  438. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_postcommit_wait.py +0 -0
  439. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_postcommit_wait_integration.py +0 -0
  440. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_prefill_bench.py +0 -0
  441. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_prefill_chunk_defaults.py +0 -0
  442. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_prefill_tps_regression.py +0 -0
  443. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_profiles.py +0 -0
  444. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_proj_quant.py +0 -0
  445. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_prompt_encoding.py +0 -0
  446. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_public_cli.py +0 -0
  447. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_qwen3_5_mtp_backend.py +0 -0
  448. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_qwen_row_owned_router.py +0 -0
  449. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_ragged_kv_cache.py +0 -0
  450. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_reasoning_stream_split.py +0 -0
  451. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_request_capture.py +0 -0
  452. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_runtime_kpis.py +0 -0
  453. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_sampling.py +0 -0
  454. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_scoped_reasoning_history.py +0 -0
  455. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_sdpa_gqa_packed.py +0 -0
  456. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_server_openai.py +0 -0
  457. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_session_bank.py +0 -0
  458. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_session_bank_env_caps.py +0 -0
  459. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_snapshot_free_rejection_repair.py +0 -0
  460. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_ssd_boundary_repersist.py +0 -0
  461. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_step3p5_mtp_patch.py +0 -0
  462. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_stream_guard_env.py +0 -0
  463. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_stream_stall_watchdog.py +0 -0
  464. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_sustained_long_context_qa.py +0 -0
  465. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_thermal_sidecar.py +0 -0
  466. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_thinking_guard.py +0 -0
  467. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_tool_nested_args_streaming.py +0 -0
  468. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_trace_parity.py +0 -0
  469. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_turboquant.py +0 -0
  470. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_turboquant_fallback.py +0 -0
  471. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_ui_progress.py +0 -0
  472. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_validators.py +0 -0
  473. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_vision_session_cache.py +0 -0
  474. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_vision_tower.py +0 -0
  475. {mtplx-2.4.2 → mtplx-2.5.0}/tests/test_vllm_reference.py +0 -0
  476. {mtplx-2.4.2 → mtplx-2.5.0}/vllm_metal/__init__.py +0 -0
  477. {mtplx-2.4.2 → mtplx-2.5.0}/vllm_metal/metal/README.md +0 -0
  478. {mtplx-2.4.2 → mtplx-2.5.0}/vllm_metal/metal/__init__.py +0 -0
  479. {mtplx-2.4.2 → mtplx-2.5.0}/vllm_metal/metal/build.py +0 -0
  480. {mtplx-2.4.2 → mtplx-2.5.0}/vllm_metal/metal/constants.py +0 -0
  481. {mtplx-2.4.2 → mtplx-2.5.0}/vllm_metal/metal/kernels_v1/copy_blocks.metal +0 -0
  482. {mtplx-2.4.2 → mtplx-2.5.0}/vllm_metal/metal/kernels_v1/float8.metal +0 -0
  483. {mtplx-2.4.2 → mtplx-2.5.0}/vllm_metal/metal/kernels_v1/gather_kv_cache.metal +0 -0
  484. {mtplx-2.4.2 → mtplx-2.5.0}/vllm_metal/metal/kernels_v1/kv_scale_update.metal +0 -0
  485. {mtplx-2.4.2 → mtplx-2.5.0}/vllm_metal/metal/kernels_v1/pagedattention.metal +0 -0
  486. {mtplx-2.4.2 → mtplx-2.5.0}/vllm_metal/metal/kernels_v1/reshape_and_cache.metal +0 -0
  487. {mtplx-2.4.2 → mtplx-2.5.0}/vllm_metal/metal/kernels_v1/utils.metal +0 -0
  488. {mtplx-2.4.2 → mtplx-2.5.0}/vllm_metal/metal/kernels_v2/copy_blocks.metal +0 -0
  489. {mtplx-2.4.2 → mtplx-2.5.0}/vllm_metal/metal/kernels_v2/float8.metal +0 -0
  490. {mtplx-2.4.2 → mtplx-2.5.0}/vllm_metal/metal/kernels_v2/gather_kv_cache.metal +0 -0
  491. {mtplx-2.4.2 → mtplx-2.5.0}/vllm_metal/metal/kernels_v2/gdn_linear_attention.metal +0 -0
  492. {mtplx-2.4.2 → mtplx-2.5.0}/vllm_metal/metal/kernels_v2/kv_scale_update.metal +0 -0
  493. {mtplx-2.4.2 → mtplx-2.5.0}/vllm_metal/metal/kernels_v2/pagedattention.metal +0 -0
  494. {mtplx-2.4.2 → mtplx-2.5.0}/vllm_metal/metal/kernels_v2/reshape_and_cache.metal +0 -0
  495. {mtplx-2.4.2 → mtplx-2.5.0}/vllm_metal/metal/kernels_v2/turboquant.metal +0 -0
  496. {mtplx-2.4.2 → mtplx-2.5.0}/vllm_metal/metal/kernels_v2/utils.metal +0 -0
  497. {mtplx-2.4.2 → mtplx-2.5.0}/vllm_metal/metal/paged_ops.cpp +0 -0
@@ -4,6 +4,66 @@ All notable user-facing changes to MTPLX. The format is based on
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow
5
5
  [Semantic Versioning](https://semver.org/).
6
6
 
7
+ ## [2.5.0] - 2026-08-03
8
+
9
+ The next-model release: MTPLX can load new architecture aliases without a
10
+ hard-coded model-type wait, multi-layer MTP drafts are supported for the
11
+ upcoming Qwen generation, HY3 becomes a first-class serving target, and the
12
+ coding-agent bridge is materially more reliable. Experimental DeepSeek V4,
13
+ Laguna, and GDN speed lanes from David Tai land behind explicit opt-ins; the
14
+ shipping defaults remain unchanged.
15
+
16
+ ### Added
17
+
18
+ - Upcoming-Qwen architecture readiness: the native draft path now supports
19
+ `mtp_num_hidden_layers = N`, and unknown `model_type` values can resolve
20
+ through their declared architecture class. A synthetic `qwen3_8` alias
21
+ drill exercised load, generate, CLI, and app discovery before public weights
22
+ existed; this is compatibility preparation, not a claim that unreleased
23
+ weights were benchmarked.
24
+ - HY3 first-class serving: a vendored MTP-capable model class, official
25
+ defaults, suffixed think-tag handling, model discovery, and native OpenCode
26
+ tool calls. AR-only exports fail safely to the AR path rather than touching
27
+ an uninitialized draft head.
28
+ - Experimental DeepSeek-V4 shape-specialized verification lanes: prebound
29
+ output-LoRA routes, adaptive speculative width, exact M3 attention
30
+ projection, sinkhorn and attention-island kernels, and compiled
31
+ post-attention verifier islands. On the 128 GB M5 Max release machine, the
32
+ exact 2-bit DQ model plus official MTP shard measured about 31 AR tok/s and
33
+ 36 MTP tok/s versus about 4/6 tok/s on the conservative path. These routes
34
+ remain opt-in while broader model-quality validation continues. Contributed
35
+ by David Tai (@davidtai, #223).
36
+ - Experimental Laguna S-2.1 `mlx.fast` ports covering decode and prefill
37
+ kernels, including size-gated prefill MoE combine; fail-loud guards and
38
+ portable scratch space keep unsupported shapes on the safe route.
39
+ Contributed by David Tai (@davidtai, #222).
40
+ - Experimental GDN headquarter execution layout for verify tape capture,
41
+ env-gated with bit-exact coverage and loud fallback. Contributed by David
42
+ Tai (@davidtai, #209).
43
+
44
+ ### Fixed
45
+
46
+ - Coding-agent JSON tool calls can carry large write bodies without the hidden
47
+ tool guard aborting them, and common near-miss argument keys are repaired at
48
+ the protocol boundary. This was verified through real OpenCode CLI and
49
+ Desktop sessions, including a multi-file edit with all generated tests
50
+ passing.
51
+ - App and CLI launches now share the same coding-agent engine environment, so
52
+ a workflow does not silently change behavior depending on which Start button
53
+ launched it.
54
+ - `start` and `quickstart --dry-run` report the resolved profile instead of the
55
+ parser's placeholder default.
56
+ - Smart-fan mode holds through the post-generation heat-soak window before
57
+ restoring automatic control, avoiding the early restore that could distort
58
+ back-to-back performance runs (#227).
59
+
60
+ ### Compatibility
61
+
62
+ - `transformers` 5.14 is allowed after tokenizer and tool-template parity were
63
+ verified; the incompatible 5.13.0 release remains excluded (#175).
64
+ - No speculative-depth, cache, sampler, or model-speed default changed in this
65
+ release. The opt-in model kernels fail closed to established implementations.
66
+
7
67
  ## [2.4.2] - 2026-08-02
8
68
 
9
69
  The agentic-cache release: the session cache stops losing warm state
@@ -827,6 +887,7 @@ working as one product. Full notes:
827
887
  completions, and Anthropic `stop_sequences`) and `/v1/completions`
828
888
  streams tokens as they are generated with real finish reasons.
829
889
 
890
+ [2.5.0]: https://github.com/youssofal/MTPLX/releases/tag/v2.5.0
830
891
  [2.4.2]: https://github.com/youssofal/MTPLX/releases/tag/v2.4.2
831
892
  [2.4.1]: https://github.com/youssofal/MTPLX/releases/tag/v2.4.1
832
893
  [2.4.0]: https://github.com/youssofal/MTPLX/releases/tag/v2.4.0
@@ -8,7 +8,7 @@ authors:
8
8
  repository-code: "https://github.com/youssofal/mtplx"
9
9
  url: "https://github.com/youssofal/mtplx"
10
10
  license: Apache-2.0
11
- version: 2.4.2
11
+ version: 2.5.0
12
12
  abstract: "Native MTP speculative decoding for Qwen3-Next on Apple Silicon, using built-in MTP heads with math-correct rejection sampling and an OpenAI/Anthropic-compatible serving surface."
13
13
  keywords:
14
14
  - speculative decoding
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mtplx
3
- Version: 2.4.2
3
+ Version: 2.5.0
4
4
  Summary: Native MTP speculative decoding for Qwen3-Next on Apple Silicon.
5
5
  Author-email: Youssof Altoukhi <business@youssofal.com>
6
6
  License-Expression: Apache-2.0
@@ -28,7 +28,7 @@ Requires-Dist: huggingface-hub>=0.36
28
28
  Requires-Dist: pillow>=10
29
29
  Requires-Dist: mlx<0.33,>=0.31; sys_platform == "darwin" and platform_machine == "arm64"
30
30
  Requires-Dist: mlx-lm<0.32,>=0.31; sys_platform == "darwin" and platform_machine == "arm64"
31
- Requires-Dist: transformers!=5.13.0,<5.14; sys_platform == "darwin" and platform_machine == "arm64"
31
+ Requires-Dist: transformers!=5.13.0,<5.15; sys_platform == "darwin" and platform_machine == "arm64"
32
32
  Requires-Dist: nanobind>=2; sys_platform == "darwin" and platform_machine == "arm64"
33
33
  Requires-Dist: numpy>=2
34
34
  Requires-Dist: pydantic>=2
@@ -12,18 +12,14 @@ from typing import Any
12
12
 
13
13
  from .constants import (
14
14
  EXPECTED_ALL_PREQUANTIZED_MTP_KEYS,
15
- EXPECTED_ALL_PREQUANTIZED_MTP_TENSOR_COUNT,
16
15
  EXPECTED_MTP_KEYS,
17
- EXPECTED_PREQUANTIZED_MTP_KEYS,
18
- EXPECTED_PREQUANTIZED_MTP_TENSOR_COUNT,
19
16
  EXPECTED_MTP_TENSOR_COUNT,
17
+ EXPECTED_PREQUANTIZED_MTP_KEYS,
20
18
  EXPECTED_QWEN_MOE_MTP_KEYS,
21
- EXPECTED_QWEN_MOE_MTP_TENSOR_COUNT,
22
19
  EXPECTED_QWEN_MOE_PREQUANTIZED_MTP_KEYS,
23
- EXPECTED_QWEN_MOE_PREQUANTIZED_MTP_TENSOR_COUNT,
24
20
  EXPECTED_QWEN_MOE_SWITCH_MLP_MTP_KEYS,
25
- EXPECTED_QWEN_MOE_SWITCH_MLP_MTP_TENSOR_COUNT,
26
21
  MULTIMODAL_SIDECARS,
22
+ expand_mtp_layer_keys,
27
23
  )
28
24
  from .models.laguna_config import (
29
25
  LAGUNA_S_2_1_REPO_ID,
@@ -194,6 +190,13 @@ def _mtp_expected_key_set(
194
190
  prequantized = isinstance(mtp_quant, dict) and bool(mtp_quant.get("prequantized"))
195
191
  quant_policy = str(mtp_quant.get("policy") or "") if isinstance(mtp_quant, dict) else ""
196
192
  normalized = {normalize_mtp_key(key) for key in keys}
193
+ # Every named key set below is the canonical depth-1 template; checkpoints
194
+ # declaring mtp_num_hidden_layers > 1 replicate the layer keys per index.
195
+ n_layers = max(_num_mtp_layers(config), 1)
196
+
197
+ def _expanded(base: tuple[str, ...]) -> set[str]:
198
+ return expand_mtp_layer_keys(base, n_layers)
199
+
197
200
  if _is_qwen_moe_mtp_layout(config, normalized):
198
201
  if any(".mlp.switch_mlp." in key for key in normalized):
199
202
  has_prequantized_aux = any(
@@ -202,7 +205,7 @@ def _mtp_expected_key_set(
202
205
  )
203
206
  if prequantized or has_prequantized_aux:
204
207
  expected = _expected_prequantized_keys_for_present_aux(
205
- set(EXPECTED_QWEN_MOE_SWITCH_MLP_MTP_KEYS),
208
+ _expanded(EXPECTED_QWEN_MOE_SWITCH_MLP_MTP_KEYS),
206
209
  normalized,
207
210
  )
208
211
  return (
@@ -210,9 +213,10 @@ def _mtp_expected_key_set(
210
213
  len(expected),
211
214
  "prequantized-mlx-affine-qwen-moe-switch-mlx",
212
215
  )
216
+ expected = _expanded(EXPECTED_QWEN_MOE_SWITCH_MLP_MTP_KEYS)
213
217
  return (
214
- set(EXPECTED_QWEN_MOE_SWITCH_MLP_MTP_KEYS),
215
- EXPECTED_QWEN_MOE_SWITCH_MLP_MTP_TENSOR_COUNT,
218
+ expected,
219
+ len(expected),
216
220
  "bf16-qwen-moe-switch-mlx",
217
221
  )
218
222
  if _has_numbered_moe_experts(normalized):
@@ -224,42 +228,47 @@ def _mtp_expected_key_set(
224
228
  config,
225
229
  prequantized=prequantized or has_prequantized_aux,
226
230
  )
227
- if prequantized or normalized == set(EXPECTED_QWEN_MOE_PREQUANTIZED_MTP_KEYS):
231
+ if prequantized or normalized == _expanded(EXPECTED_QWEN_MOE_PREQUANTIZED_MTP_KEYS):
232
+ expected = _expanded(EXPECTED_QWEN_MOE_PREQUANTIZED_MTP_KEYS)
228
233
  return (
229
- set(EXPECTED_QWEN_MOE_PREQUANTIZED_MTP_KEYS),
230
- EXPECTED_QWEN_MOE_PREQUANTIZED_MTP_TENSOR_COUNT,
234
+ expected,
235
+ len(expected),
231
236
  "prequantized-mlx-affine-qwen-moe",
232
237
  )
238
+ expected = _expanded(EXPECTED_QWEN_MOE_MTP_KEYS)
233
239
  return (
234
- set(EXPECTED_QWEN_MOE_MTP_KEYS),
235
- EXPECTED_QWEN_MOE_MTP_TENSOR_COUNT,
240
+ expected,
241
+ len(expected),
236
242
  "bf16-qwen-moe",
237
243
  )
238
244
  if prequantized and quant_policy == "all":
245
+ expected = _expanded(EXPECTED_ALL_PREQUANTIZED_MTP_KEYS)
239
246
  return (
240
- set(EXPECTED_ALL_PREQUANTIZED_MTP_KEYS),
241
- EXPECTED_ALL_PREQUANTIZED_MTP_TENSOR_COUNT,
247
+ expected,
248
+ len(expected),
242
249
  "prequantized-mlx-affine",
243
250
  )
244
251
  if prequantized:
252
+ expected = _expanded(EXPECTED_PREQUANTIZED_MTP_KEYS)
245
253
  return (
246
- set(EXPECTED_PREQUANTIZED_MTP_KEYS),
247
- EXPECTED_PREQUANTIZED_MTP_TENSOR_COUNT,
254
+ expected,
255
+ len(expected),
248
256
  "prequantized-mlx-affine",
249
257
  )
250
- if normalized == set(EXPECTED_ALL_PREQUANTIZED_MTP_KEYS):
258
+ if normalized == _expanded(EXPECTED_ALL_PREQUANTIZED_MTP_KEYS):
251
259
  return (
252
- set(EXPECTED_ALL_PREQUANTIZED_MTP_KEYS),
253
- EXPECTED_ALL_PREQUANTIZED_MTP_TENSOR_COUNT,
260
+ set(normalized),
261
+ len(normalized),
254
262
  "prequantized-mlx-affine",
255
263
  )
256
- if normalized == set(EXPECTED_PREQUANTIZED_MTP_KEYS):
264
+ if normalized == _expanded(EXPECTED_PREQUANTIZED_MTP_KEYS):
257
265
  return (
258
- set(EXPECTED_PREQUANTIZED_MTP_KEYS),
259
- EXPECTED_PREQUANTIZED_MTP_TENSOR_COUNT,
266
+ set(normalized),
267
+ len(normalized),
260
268
  "prequantized-mlx-affine",
261
269
  )
262
- return set(EXPECTED_MTP_KEYS), EXPECTED_MTP_TENSOR_COUNT, "bf16"
270
+ expected = _expanded(EXPECTED_MTP_KEYS)
271
+ return expected, len(expected), "bf16"
263
272
 
264
273
 
265
274
  def _observed_sidecar_format(sidecar_format: str, tensors: tuple[TensorInfo, ...]) -> str:
@@ -13,11 +13,20 @@ VALID_ATTENTION_PHASES = {
13
13
  "postcommit",
14
14
  "unknown",
15
15
  }
16
+ VALID_MODEL_FORWARD_KINDS = {
17
+ "target_verify",
18
+ "repair",
19
+ "other",
20
+ }
16
21
 
17
22
  _ATTENTION_PHASE: ContextVar[str] = ContextVar(
18
23
  "mtplx_attention_phase",
19
24
  default="unknown",
20
25
  )
26
+ _MODEL_FORWARD_KIND: ContextVar[str] = ContextVar(
27
+ "mtplx_model_forward_kind",
28
+ default="other",
29
+ )
21
30
 
22
31
 
23
32
  def normalize_attention_phase(phase: str | None) -> str:
@@ -29,6 +38,15 @@ def current_attention_phase() -> str:
29
38
  return normalize_attention_phase(_ATTENTION_PHASE.get())
30
39
 
31
40
 
41
+ def normalize_model_forward_kind(kind: str | None) -> str:
42
+ value = (kind or "other").strip().lower()
43
+ return value if value in VALID_MODEL_FORWARD_KINDS else "other"
44
+
45
+
46
+ def current_model_forward_kind() -> str:
47
+ return normalize_model_forward_kind(_MODEL_FORWARD_KIND.get())
48
+
49
+
32
50
  @contextmanager
33
51
  def attention_phase(phase: str | None) -> Iterator[None]:
34
52
  token = _ATTENTION_PHASE.set(normalize_attention_phase(phase))
@@ -36,3 +54,14 @@ def attention_phase(phase: str | None) -> Iterator[None]:
36
54
  yield
37
55
  finally:
38
56
  _ATTENTION_PHASE.reset(token)
57
+
58
+
59
+ @contextmanager
60
+ def model_forward_kind(kind: str | None) -> Iterator[None]:
61
+ """Identify whether one decode-verify-phase target call verifies or repairs."""
62
+
63
+ token = _MODEL_FORWARD_KIND.set(normalize_model_forward_kind(kind))
64
+ try:
65
+ yield
66
+ finally:
67
+ _MODEL_FORWARD_KIND.reset(token)
@@ -570,6 +570,48 @@ GLM_MTP_DESCRIPTOR = BackendDescriptor(
570
570
  )
571
571
 
572
572
 
573
+ HY_V3_MTP_DESCRIPTOR = BackendDescriptor(
574
+ backend_id="hy_v3_mtp",
575
+ architecture_id="hy-v3-mtp",
576
+ model_family="hy",
577
+ display_name="Hy3 native MTP",
578
+ artifact_layout="single_mlx_folder_native_mtp",
579
+ runtime_capabilities=NATIVE_CONTRACT_DESCRIPTOR.runtime_capabilities,
580
+ # Official Tencent inference settings (tencent/Hy3 generation_config.json):
581
+ # temperature 0.9, top_p 1.0, top_k disabled. Do NOT inherit the Qwen
582
+ # 0.6/0.95/20 coding sampler; Hy3's CoT measurably degrades at greedy/cold
583
+ # settings (community reports on the release thread).
584
+ sampler_defaults=SamplerDefaults(temperature=0.9, top_p=1.0, top_k=0),
585
+ # Hy3 emits <think:opensource>...</think:opensource> (suffixed single
586
+ # tokens). The qwen3-style splitter handles suffixed spellings.
587
+ reasoning_codec=ReasoningCodec(
588
+ parser="qwen3",
589
+ display_name="Hy3 think tags",
590
+ default_mode="auto",
591
+ ),
592
+ draft_semantics=NATIVE_CONTRACT_DESCRIPTOR.draft_semantics,
593
+ uses_external_assistant=False,
594
+ uses_draft_lm_head=True,
595
+ hidden_variant="pre_norm",
596
+ tune_policy=TunePolicy(
597
+ supported=False,
598
+ unsupported_reason="Tune is supported for Qwen 3.5, Qwen 3.6, and Gemma 4 MTPLX models only.",
599
+ ),
600
+ kv_quant_policy=KVQuantPolicy(
601
+ supported=False,
602
+ disabled_reason="KV quantization is not supported for Hy3.",
603
+ ),
604
+ validation_status="experimental_contract_gated",
605
+ status="experimental_contract_gated",
606
+ notes=(
607
+ "Single appended NextN MoE layer (depth 1); 192-expert sigmoid top-8 "
608
+ "routing with expert bias; draft input eh_proj(concat[enorm(embedding), "
609
+ "hnorm(pre-final-norm hidden)]).",
610
+ "Official sampler: temperature 0.9, top_p 1.0, top_k off.",
611
+ ),
612
+ )
613
+
614
+
573
615
  GEMMA4_TARGET_DISTRIBUTION_POLICY = TargetDistributionPolicy(
574
616
  modes=("gemma4_target_prefix_exact",),
575
617
  default_mode="gemma4_target_prefix_exact",
@@ -695,6 +737,7 @@ DESCRIPTORS_BY_BACKEND_ID: dict[str, BackendDescriptor] = {
695
737
  STEP3P5_MTP_DESCRIPTOR.backend_id: STEP3P5_MTP_DESCRIPTOR,
696
738
  DEEPSEEK_MTP_DESCRIPTOR.backend_id: DEEPSEEK_MTP_DESCRIPTOR,
697
739
  GLM_MTP_DESCRIPTOR.backend_id: GLM_MTP_DESCRIPTOR,
740
+ HY_V3_MTP_DESCRIPTOR.backend_id: HY_V3_MTP_DESCRIPTOR,
698
741
  "mimo_mtp": NATIVE_CONTRACT_DESCRIPTOR,
699
742
  "nemotron_h_mtp": NATIVE_CONTRACT_DESCRIPTOR,
700
743
  }
@@ -307,6 +307,14 @@ def _opencode_memory_env_defaults() -> dict[str, str]:
307
307
  else _OPENCODE_DEFAULT_MAX_ENTRIES
308
308
  )
309
309
  return {
310
+ # Long-context decode route (>=32k): same keys the app's
311
+ # codingAgentRuntimeEnvironment and the CLI hermes lane already set —
312
+ # the OpenCode CLI lane missing them was surface drift (2026-08-03
313
+ # parity audit), not intent.
314
+ "MTPLX_VLLM_METAL_PAGED_GQA_SDPA_ROUTE": "async_per_head",
315
+ "MTPLX_VLLM_METAL_PAGED_GQA_SDPA_MIN_CONTEXT": "32768",
316
+ "MTPLX_VLLM_METAL_PAGED_GQA_SDPA_MIN_Q": "3",
317
+ "MTPLX_VLLM_METAL_PAGED_GQA_SDPA_MAX_Q": "5",
310
318
  "MTPLX_SESSION_BLOCK_PREFIX_RESTORE": "1",
311
319
  "MTPLX_SESSION_BANK_MAX_ENTRIES": max_entries,
312
320
  # "auto" = the engine budgets half the RAM surplus left after the
@@ -997,7 +1005,13 @@ def _resolved_default_profile_name(args: Any, model: str | None = None) -> str:
997
1005
 
998
1006
 
999
1007
  def _apply_qwen36_35b_optimized_speed_defaults(args: Any, model_id: str) -> None:
1000
- if model_id != QWEN36_35B_OPTIMIZED_SPEED_PUBLIC_MODEL_ID:
1008
+ # The -FP16 sibling shares the byte-identical INT packs and the measured
1009
+ # launch defaults; the app's substring detection already applied them to
1010
+ # it while this exact-id gate skipped it (2026-08-03 parity audit).
1011
+ if model_id not in {
1012
+ QWEN36_35B_OPTIMIZED_SPEED_PUBLIC_MODEL_ID,
1013
+ QWEN36_35B_OPTIMIZED_SPEED_FP16_PUBLIC_MODEL_ID,
1014
+ }:
1001
1015
  return
1002
1016
  cli_flags = getattr(args, "_cli_flags", set()) or set()
1003
1017
  injected = set(getattr(args, "_injected_default_flags", set()) or set())
@@ -1359,12 +1373,19 @@ def _pi_preserve_thinking_policy(args: Any) -> str:
1359
1373
 
1360
1374
 
1361
1375
  def _apply_pi_history_budget_env_defaults(env: dict[str, str]) -> None:
1376
+ """Pi lane = the shared coding-agent engine block + Pi history budgets.
1377
+
1378
+ Mirrors the app's composition exactly (codingAgentRuntimeEnvironment then
1379
+ the Pi-specific overrides in MTPLXCommandBuilder.swift). Before the
1380
+ 2026-08-03 parity audit the CLI Pi lane carried only the history keys —
1381
+ no session bank, SDPA route, postcommit wait, or frontier flags — and
1382
+ three of its values (96/16/150) diverged from the app-lane numbers
1383
+ (72/8/120) every app Pi user already runs; unified to the app values.
1384
+ """
1385
+ _apply_opencode_memory_env_defaults(env)
1362
1386
  env.setdefault("MTPLX_TOOL_RESULT_COMPACT_THRESHOLD_CHARS", "1200")
1363
1387
  env.setdefault("MTPLX_ACTIVE_READ_INSPECTION_COMPACT_MAX_LINES", "32")
1364
1388
  env.setdefault("MTPLX_ACTIVE_READ_INSPECTION_LINE_MAX_CHARS", "180")
1365
- env.setdefault("MTPLX_ACTIVE_READ_INSPECTION_TOTAL_MAX_LINES", "96")
1366
- env.setdefault("MTPLX_ACTIVE_READ_INSPECTION_MIN_LINES_PER_FILE", "16")
1367
- env.setdefault("MTPLX_ACTIVE_READ_INSPECTION_MULTI_FILE_LINE_MAX_CHARS", "150")
1368
1389
  env.setdefault("MTPLX_ACTIVE_TOOL_RESULT_COMPACT_MAX_LINES", "32")
1369
1390
  env.setdefault("MTPLX_ACTIVE_TOOL_RESULT_LINE_MAX_CHARS", "220")
1370
1391
 
@@ -12584,7 +12605,11 @@ def cmd_quickstart_public(args: Any) -> int:
12584
12605
  "target": target,
12585
12606
  "model": model,
12586
12607
  "cache_dir": cache_dir,
12587
- "profile": getattr(args, "profile", DEFAULT_PROFILE_NAME),
12608
+ # Display the profile the launch will actually resolve (per-model
12609
+ # turbo rewrite included) — the raw parser default here made the
12610
+ # dry-run advertise "sustained" for the turbo-default flagships
12611
+ # (the 2026-07-16 stale-display bug class, on one more surface).
12612
+ "profile": _resolved_default_profile_name(args, model),
12588
12613
  "generation_mode": _generation_mode_from_args(args),
12589
12614
  "max": bool(getattr(args, "max", False)),
12590
12615
  "download_if_missing": download,
@@ -184,6 +184,29 @@ EXPECTED_QWEN_MOE_PREQUANTIZED_MTP_TENSOR_COUNT = len(
184
184
  EXPECTED_QWEN_MOE_PREQUANTIZED_MTP_KEYS
185
185
  )
186
186
 
187
+ _MTP_LAYER_KEY_MARKER = "mtp.layers.0."
188
+
189
+
190
+ def expand_mtp_layer_keys(keys: tuple[str, ...] | set[str], n_layers: int) -> set[str]:
191
+ """Expand a depth-1 MTP key template across ``n_layers`` draft layers.
192
+
193
+ Every expected-key set in this module describes the canonical
194
+ single-layer (``mtp.layers.0.*``) head. Upstream checkpoints may declare
195
+ ``mtp_num_hidden_layers > 1`` (the config key is N-generic in the vLLM
196
+ reference contract); their weight layout replicates the per-layer
197
+ template at each index. Identity for ``n_layers <= 1``.
198
+ """
199
+ n = max(int(n_layers), 1)
200
+ expanded: set[str] = set()
201
+ for key in keys:
202
+ if _MTP_LAYER_KEY_MARKER in key:
203
+ for index in range(n):
204
+ expanded.add(key.replace(_MTP_LAYER_KEY_MARKER, f"mtp.layers.{index}.", 1))
205
+ else:
206
+ expanded.add(key)
207
+ return expanded
208
+
209
+
187
210
  MULTIMODAL_SIDECARS = (
188
211
  "preprocessor_config.json",
189
212
  "processor_config.json",