Repository navigation
feat(infer): resolve serving plans for GPUs declared in SIEVAL_TARGET_GPU - #215
Merged
Merged
Conversation
This was referenced Oct 23, 2026
…_GPU Recipe resolution read the node's own GPUs from nvidia-smi, so a plan could not be resolved on a CPU node, and auto_resolve_plan raised "No GPU detected". A platform that decides on a CPU node whether a run needs a GPU could not get the plan or the inference identity it implies. SIEVAL_TARGET_GPU='<name>:<count>:<memory MiB>' now stands in for nvidia-smi in both resolvers. The fields are the ones nvidia-smi reports, verbatim: the name selects the hardware profile and is recorded in a path-only plan, and the memory decides tensor parallelism, so only those values reproduce the plan a node with the GPUs resolves. Unset, nothing changes. Declared, an engine launches only on a node with exactly those GPUs (sieval run and sieval infer start). infer_plans.yaml records as `gpu` the GPUs its plans were resolved for, outside every identity. A sieval run --resume declaring the same GPUs reuses the recorded plan of each served model whose path and infer are unchanged, rather than resolving it again. Tests fake detection and check that the declared plan equals the detected one for both resolvers, byte for byte as infer_plans.yaml writes it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
infer_plans.yaml is written through redact_secrets, so a plan with an engine api_key or authorization reads back holding "<redacted>". A resume that reused it launched the engine with the marker as its key, and every request then failed against it. The path/infer comparison could not tell: both sides are compared redacted. Such a plan is now resolved again. - holds_secret() says whether redact_secrets would redact anything. - _RecordedPlans resolves the recorded model types once, not per model. - The launch-GPU refusal names each field that differs, memory included, since two nodes of one GPU model can report different memory.total. - Docs, docstrings and the infer_plans.yaml header name the new exception. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ethan-scitix
force-pushed
the
feat/target-gpu
branch
from
October 23, 2026 09:06
8ca205d to
5eeeb1b
Compare
Merged
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.
Type
Summary
SIEVAL_TARGET_GPU='<name>:<count>:<memory MiB>'declares the GPUs a serving plan is resolved for. Both resolvers,_resolve_recipe_params(YAMLinfer:) andauto_resolve_plan(path:-only), read it instead ofnvidia-smi. A plan can therefore be resolved on any node, a CPU node included. When the variable is unset, nothing changes.nvidia-smi's own fields. The resolvers also run undersieval infer start, and a platform sets a job's environment more easily than its argv. The fields are whatdetect_local_gpureads, verbatim (NVIDIA H100 80GB HBM3:8:81559). The name selects the hardware profile and is recorded in apath:-only plan, and the memory decides TP. A shorthand likeH100-80G:8would resolve another plan, and with it another inference identity, so it is refused with the expected form.sieval runandsieval infer startrefuse to launch an engine on a node whose detected GPUs differ from the declaration. Without a declaration, nothing is checked.infer_plans.yamlgainsgpu, the GPUs its plans were resolved for (declared or detected). It sits outsidemodels, so it is in no identity. Asieval run --resume[DIR] declaring the same GPUs reuses the recorded plan of each served model whosepathandinferare unchanged, with the same capability layer and the samedeterministic. Otherwise the plan is resolved again.plan_from_mappingrebuilds aDeploymentPlanfrom its recorded form, and refuses a record with fields this version lacks.read_persisted_configandredact_secretslose their leading underscore, sincerun.pynow imports them.Identity impact. None for a run that declares nothing: the resolvers take the same path, and
infer_plans.yamlonly gains the top-levelgpukey.RESULT_SCHEMA_VERSIONstays 1.Related Issues
Closes #212. First of a stack: #216 (lazy engine launch, #213) and #217 (dry-run report, #214) build on it.
Test Plan
Automated
ruff check && ruff format --check)ty check)pdm run pytest)Environment:
pdm install --frozen-lockfile -G bfcl-v3 -G drop -G ifbench -G ifeval -G iheval -G math -G scicode -G spider -G code-eval -G test -G dev, macOS.tests/unit/cli tests/unit/infer tests/unit/core/runners tests/integration/resumegave 2149 passed.pytest tests/unit tests/integrationpassed up to the known macOS-onlytest_exec_quotebench_anchor.pyfailure.pytest -qgave 9407 passed, 94 skipped, 1 failed, the same macOS-onlytest_exec_quotebench_anchor.py.ruff,ty,pre-commit run -aandscripts/check_preflight.pyare clean.New tests (
tests/unit/infer/test_target_gpu.py;tests/unit/cli/test_run.py::TestDeclaredTargetGpu):nvidia-smireporting none (which is never asked). The two plans are equal, both as objects and as the YAMLinfer_plans.yamlwrites, forauto_resolve_planand forresolve_infer_config. A different declaration resolves a different plan, so the check has teeth.sieval run: theinfer_plansthe session receives with a declaration equal those it receives with detection on the same hardware. The recordedgpuis the same either way.inferblock each resolve again.tests/conftest.pyunsetsSIEVAL_TARGET_GPUfor every test, so a developer's shell cannot leak into a faked detection.🤖 Generated with Claude Code