diff --git a/configs/ci-priority.yaml b/configs/ci-priority.yaml index 83a21a8117..77dacc59ac 100644 --- a/configs/ci-priority.yaml +++ b/configs/ci-priority.yaml @@ -6,9 +6,6 @@ version: 1 base-score: 1.0 adjustments: - # Preserve business priority as the primary key, then prefer smaller Slurm - # allocations within an otherwise identical class. - additional-node: -0.001 event: push: 2.0 multi-node: 1.25 @@ -26,7 +23,7 @@ adjustments: dynamo-sglang: 0.5 dynamo-vllm: 0.5 model-prefix: - kimik3: 1.5 + kimik3: 0.75 glm5: 0.75 glm5.1: 0.75 kimik2.5: 0.75 diff --git a/utils/ci_priority.py b/utils/ci_priority.py index 540d36e759..2d71a6bc47 100755 --- a/utils/ci_priority.py +++ b/utils/ci_priority.py @@ -149,7 +149,6 @@ def calculate_priority( or node_count < 1 ): raise ValueError(f"node-count must be a positive integer, got {node_count!r}") - score += _decimal(adjustments.get("additional-node", 0)) * (node_count - 1) if entry.get("prefill") is not None: score += _decimal(adjustments.get("multi-node", 0)) diff --git a/utils/runner_setup/RUNNER_SETUP.md b/utils/runner_setup/RUNNER_SETUP.md index 202ace0522..f4e69268e7 100644 --- a/utils/runner_setup/RUNNER_SETUP.md +++ b/utils/runner_setup/RUNNER_SETUP.md @@ -209,9 +209,10 @@ hardware label bypasses admission accounting. Set `NODE_SLOT_SCHEDULER_ENABLED=true` only after the deployed priority controller supports `nodes:N` and `ci-lease-*`. `PRIORITY_SCHEDULER_ENABLED` must also remain enabled. If either variable is disabled, workflows omit -`nodes:N` and retain the existing unweighted behavior. The priority score also -subtracts `0.001` per additional node so otherwise equal work prefers smaller -allocations without overriding the existing business-priority signals. +`nodes:N` and retain the existing unweighted behavior. Node count is capacity +demand, not a business-priority signal. The dashboard controller packs jobs +within each business-priority band, maximizing admitted jobs and then occupied +nodes without allowing lower-priority work to displace a higher-priority band. Aggregated multi-node search-space entries must declare one aggregate `worker` role and `num-nodes`; that value becomes the generated `node-count` directly. diff --git a/utils/test_ci_priority.py b/utils/test_ci_priority.py index 1bef5fcdaa..4d6dc9380d 100644 --- a/utils/test_ci_priority.py +++ b/utils/test_ci_priority.py @@ -54,22 +54,30 @@ def test_main_branch_jobs_receive_an_automatic_boost(): ) == Decimal("3.000") -def test_smaller_node_allocations_win_otherwise_equal_priority_ties(): +def test_kimi_k3_and_dsv4_receive_the_same_model_priority(): + entry = {"runner": "h100", "framework": "trt"} + + assert calculate_priority( + {**entry, "model-prefix": "kimik3"}, POLICY + ) == calculate_priority({**entry, "model-prefix": "dsv4"}, POLICY) + + +def test_node_count_does_not_change_business_priority(): entry = {"runner": "h100", "framework": "trt"} assert calculate_priority({**entry, "node-count": 1}, POLICY) == Decimal("1.000") - assert calculate_priority({**entry, "node-count": 2}, POLICY) == Decimal("0.999") - assert calculate_priority({**entry, "node-count": 3}, POLICY) == Decimal("0.998") + assert calculate_priority({**entry, "node-count": 2}, POLICY) == Decimal("1.000") + assert calculate_priority({**entry, "node-count": 3}, POLICY) == Decimal("1.000") -def test_node_count_tiebreaker_survives_classifier_projection(): +def test_node_count_validation_survives_classifier_projection(): entry = {"runner": "h100", "framework": "trt", "node-count": 3} assert calculate_priority( entry, POLICY, PriorityContext(criteria=frozenset()), - ) == Decimal("0.998") + ) == Decimal("1.000") @pytest.mark.parametrize("node_count", [0, -1, 1.5, True])