Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
27f77c5
fix(gemm): derive MoE tuning shapes from the observed dispatch tuple
Aug 19, 2026
2509f28
fix(gemm): preserve integrate faults and add fused-MoE coverage
Aug 19, 2026
372e076
fix(gemm): retry forge E2E integrate within fault budget
Aug 20, 2026
b438a85
fix(warm-replay): apply recipe patches via nogit when git HEAD is absent
Aug 20, 2026
4264201
fix(breakdown): show forge GEMM e2e gain instead of micro speedup
Aug 20, 2026
9d04cb9
fix(forge-gemm): persist all aiter tuned CSV env keys durably
Aug 20, 2026
353ec09
fix(model-path): resolve serving model path at bootstrap and E2E inte…
Aug 20, 2026
9578316
fix(model-path): wire unified resolver through session executors
Aug 20, 2026
8d88075
fix(nogit-patch): tolerate placeholder git index headers
Aug 20, 2026
0c4866f
Merge origin/main into feature/leixin/forge-fmoe-key-from-log
Aug 20, 2026
a978aee
Merge origin/main into feature/leixin/forge-fmoe-key-from-log
Aug 20, 2026
14bf84a
fix(forge-gemm): stop diagnostics from blocking the run they describe
Aug 20, 2026
2cca948
fix(gemm): name the adopted artifact, and resolve the framework bench…
Aug 20, 2026
c358858
fix(forge-gemm): keep the durable CSV out of aiter's auto-merge scan
Aug 20, 2026
31f6cd3
feat(forge-gemm): tell forge the workload's input sequence length
Aug 20, 2026
660973d
feat(forge-gemm): hand forge the trace shape manifest when one exists
Aug 20, 2026
ab85fc8
Revert "feat(forge-gemm): hand forge the trace shape manifest when on…
Aug 20, 2026
3591e62
Revert "feat(forge-gemm): tell forge the workload's input sequence le…
Aug 20, 2026
2f3e05c
fix(gemm): name the adopted artifact from the candidate, not the stack
Aug 20, 2026
2700241
test(gemm): cover the MoE runtime key handoff
Aug 21, 2026
6be8871
fix(forge-gemm): give every forge wording a verdict, and lift the reason
Aug 21, 2026
1cfc763
fix(forge-gemm): keep the reason lift from breaking the run it describes
Aug 21, 2026
4851c8a
fix(forge-gemm): take tokens as sent, and stop token counts vetoing a…
Aug 21, 2026
7112a92
fix(gemm): neutralise the envelope when E2E validation raises, drop d…
Aug 21, 2026
019b262
style: cut the comments on today's fixes down to the constraint
Aug 21, 2026
0b356ad
fix(warm-replay): refuse a required timeline without a git HEAD, as b…
Aug 21, 2026
e806fca
test(warm-replay): cover the nogit revert the teardown depends on
Aug 21, 2026
95e2e34
Merge origin/main into feature/leixin/forge-fmoe-key-from-log
Aug 21, 2026
9a0292f
fix(test): read _apply_warm_patches' legacy return as the list it is
Aug 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions src/hyperloom/agents/kernel/tests/test_forge_gemm_tuning.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def _payload() -> dict:
"global_timeout": 456,
"tuner": "fmoe_ck",
"untuned_csv": "/tmp/in.csv",
"moe_untuned_csv": "/tmp/untuned_fmoe_from_runtime.csv",
"shapes_json": "/tmp/shapes.json",
"tunableop_input": "/tmp/tunable.txt",
"kernel_signature_log": "/tmp/server.log",
Expand All @@ -57,12 +58,59 @@ def test_build_cmd_maps_all_options():
assert cmd[cmd.index("--quant-type") + 1] == "auto"
assert cmd[cmd.index("--mp") + 1] == "8"
assert cmd[cmd.index("--tuner") + 1] == "fmoe_ck"
assert cmd[cmd.index("--untuned-csv") + 1] == "/tmp/in.csv"
assert cmd[cmd.index("--kernel-signature-log") + 1] == "/tmp/server.log"
assert cmd[cmd.index("--tp") + 1] == "1"
assert cmd[cmd.index("--conc") + 1] == "256"
assert cmd[cmd.index("--timeout") + 1] == "123"
assert cmd[cmd.index("--global-timeout") + 1] == "456"
assert cmd[cmd.index("--tokens") + 1] == "64,128"
assert "--skip-gpu-check" in cmd
assert "--verbose" in cmd
assert "--thorough" in cmd


def test_build_cmd_forwards_the_moe_untuned_csv():
"""The runtime-derived MoE key reaches forge only through this option.

The orchestrator derives the CSV from the dispatch tuple in the server log;
without the option forge infers the key from the model config instead --
the exact failure this lane exists to remove, and one that leaves no trace
because the tuning still reports success.
"""
cmd = forge_gemm_tuning._build_cmd(_payload())

assert cmd[cmd.index("--moe-untuned-csv") + 1] == "/tmp/untuned_fmoe_from_runtime.csv"


def test_build_cmd_omits_the_moe_untuned_csv_when_absent():
"""No runtime key observed: forge must not receive an empty option."""
payload = _payload()
payload.pop("moe_untuned_csv")

assert "--moe-untuned-csv" not in forge_gemm_tuning._build_cmd(payload)


def test_build_cmd_asserts_every_option_it_can_emit():
"""Meta-guard: an option added to _build_cmd must be asserted in this file.

This file is the only guard on the agent-tool argv, and it had drifted to
covering 10 of the options it emits -- which is how the MoE CSV option went
unasserted while being the whole point of this lane. Comparing the emitted
flags against a declared set makes the next omission fail here.
"""
emitted = {tok for tok in forge_gemm_tuning._build_cmd(_payload()) if tok.startswith("--")}
declared = {
"--model-path", "--framework", "--precision", "--quant-type", "--gpu-type",
"--tp", "--conc", "--mp", "--output-dir", "--iters", "--warmup",
"--min-improvement-pct", "--timeout", "--global-timeout", "--tuner",
"--untuned-csv", "--moe-untuned-csv", "--shapes-json", "--tunableop-input",
"--kernel-signature-log", "--gpu-ids", "--skip-gpu-check", "--verbose",
"--thorough", "--tokens", "--kb-current-lib",
}
assert emitted <= declared, f"option(s) not declared here: {sorted(emitted - declared)}"


def test_build_cmd_forwards_provenance_but_no_knowledge_base_options(monkeypatch):
"""Tuning has no knowledge base; asking it to consult one aborts the run."""
payload = _payload()
Expand Down
1 change: 1 addition & 0 deletions src/hyperloom/agents/kernel/tools/forge_gemm_tuning.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ def _build_cmd(args: dict[str, Any]) -> list[str]:
_add_opt(cmd, args, "global_timeout", "--global-timeout")
_add_opt(cmd, args, "tuner", "--tuner")
_add_opt(cmd, args, "untuned_csv", "--untuned-csv")
_add_opt(cmd, args, "moe_untuned_csv", "--moe-untuned-csv")
_add_opt(cmd, args, "shapes_json", "--shapes-json")
_add_opt(cmd, args, "tunableop_input", "--tunableop-input")
_add_opt(cmd, args, "kernel_signature_log", "--kernel-signature-log")
Expand Down
59 changes: 59 additions & 0 deletions src/hyperloom/common/model_paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@

from __future__ import annotations

import os
from pathlib import Path
from typing import Any


def _identity_leaf(seg: str) -> str:
Expand Down Expand Up @@ -128,3 +130,60 @@
if isinstance(hit, str) and Path(hit).is_file():
return Path(hit).parent
return None


def resolve_serving_model_path(raw: str) -> str:
"""Resolve a session model identity to a path suitable for launching servers.

Precedence mirrors ``run_hyperloom.sbatch``: an existing directory wins,
then ``HL_MODEL_BASE/<repo-tail>``, then the HuggingFace hub cache via
:func:`resolve_local_model_dir`. When nothing resolves, the original
string is returned unchanged.
"""
text = str(raw or "").strip()
if not text:
return ""
try:
direct = Path(text).expanduser()
if direct.is_dir():
return str(direct)
except OSError:
pass
base = os.environ.get("HL_MODEL_BASE", "").strip()
if base:
leaf = text.rstrip("/").split("/")[-1]
if leaf:
candidate = Path(base) / leaf
try:
if candidate.is_dir():
return str(candidate)
except OSError:
pass
resolved = resolve_local_model_dir(text)
if resolved is not None:
return str(resolved)
return text


def resolve_session_model_path(
*,
params: dict[str, Any] | None = None,
state_model_path: str = "",
for_serving: bool = False,
) -> str:
"""Unified session model-path precedence for executors and handlers.

Order: ``params['model_path']`` → ``$MODEL_PATH`` → ``state.model_path``.
When ``for_serving`` is true, :func:`resolve_serving_model_path` is applied
to the chosen raw value.
"""
raw = (
str((params or {}).get("model_path") or "").strip()
or os.environ.get("MODEL_PATH", "").strip()
or str(state_model_path or "").strip()
)
if not raw:
return ""
if for_serving:
return resolve_serving_model_path(raw)
return raw
Original file line number Diff line number Diff line change
Expand Up @@ -1326,10 +1326,15 @@ def collect_gemm_tuning(state: dict[str, Any]) -> dict[str, Any]:
if not isinstance(raw, dict):
continue
engine = _resolve_gemm_engine(raw)
e2e_gain_pct = _to_float(raw.get("e2e_gain_pct"))
speedup = _to_float(raw.get("best_speedup"))
gain_pct: float | None = None
tuned_tput: float | None = None
if speedup is not None:
if e2e_gain_pct is not None:
gain_pct = e2e_gain_pct
if baseline_tput is not None:
tuned_tput = baseline_tput * (1.0 + e2e_gain_pct / 100.0)
elif speedup is not None:
gain_pct = (speedup - 1.0) * 100.0
if baseline_tput is not None:
tuned_tput = baseline_tput * speedup
Expand Down Expand Up @@ -1360,6 +1365,7 @@ def collect_gemm_tuning(state: dict[str, Any]) -> dict[str, Any]:
"gpu_type": str(raw.get("gpu_type") or gpu_type),
"baseline_tput": baseline_tput,
"best_speedup": speedup,
"e2e_gain_pct": e2e_gain_pct,
"gain_pct": gain_pct,
"tuned_tput": tuned_tput,
"tuned_file": tuned_file,
Expand Down
4 changes: 3 additions & 1 deletion src/hyperloom/inference_optimizer/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1985,7 +1985,9 @@ async def _run_optimize(args: argparse.Namespace) -> int:
)
sys.exit(2)
# Re-export so subprocess executors inject the resolved model into the Magpie YAML, not its hardcoded model.
os.environ["MODEL_PATH"] = str(args.model)
from hyperloom.common.model_paths import resolve_serving_model_path

os.environ["MODEL_PATH"] = resolve_serving_model_path(str(args.model)) or str(args.model)

# Quantization prelude (one-shot, before any session/baseline work):
# if --quantize was passed, quantize the source model now and rewrite
Expand Down
Loading
Loading