Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
cc5a3b8
[Quality] Integrate 8 quality benchmarks into CI
Noridom1 Sep 3, 2026
23a3758
[Quality] Smoke run GPQA-Diamond 10 samples via GreenNode
Noridom1 Sep 3, 2026
be31a3a
[Quality] Fix runner: bench-client_01 -> bench-client_00
Noridom1 Sep 3, 2026
c7d94c6
fix(quality-eval): dispatch quality scenarios directly, bypass runner…
Noridom1 Sep 3, 2026
79fd53a
fix(quality-eval): install lm-eval[api] extra for tenacity dependency
Noridom1 Sep 3, 2026
bcda255
feat(quality-eval): add smoke configs for 7 remaining benchmarks
Noridom1 Sep 3, 2026
972df81
fix(quality-eval): repair 6 broken benchmark smoke setups
Noridom1 Sep 3, 2026
9d1ad25
fix(quality-eval): venv --clear on rebuild, deepswe LIMIT map, scicod…
Noridom1 Sep 3, 2026
32de4e3
fix(quality-eval): 5 smoke fixes + job naming + skip passed benchmarks
Noridom1 Sep 4, 2026
7655d70
fix(quality-eval): swebench_pro imports + scicode pyarrow + hle max_g…
Noridom1 Sep 4, 2026
3e20597
fix(bfcl): honor LIMIT/EVAL_LIMIT via auto-generated run-ids subset
Noridom1 Sep 4, 2026
5a5ec34
fix(quality-eval): swebench_pro submodules + lcb anthropic + bfcl res…
Noridom1 Sep 4, 2026
e81faa4
fix(quality-eval): lcb anthropic patch + scicode numpy<2 + swebench r…
Noridom1 Sep 4, 2026
6b2e013
fix(quality-eval): lcb --limit, scicode datasets>=2.16, swebench dir …
Noridom1 Sep 4, 2026
8c2dd5f
fix(livecodebench): patch lm_styles.py with z-ai/glm-5.2 model
Noridom1 Sep 4, 2026
37fbc2f
ci: skip hle+bfcl (already passed), focus on lcb+scicode+swebench_pro
Noridom1 Sep 4, 2026
0f3e97d
fix: lcb dataset config name, scicode datasets==5.0.1, results.json f…
Noridom1 Sep 4, 2026
8da87f4
fix: lcb LCB_LIMIT env var for smoke subset, scicode inspect log coll…
Noridom1 Sep 4, 2026
4b8d505
feat: enable streaming for all 8 quality benchmarks
Noridom1 Sep 4, 2026
cf4b08b
fix: LCB output path + SciCode validate_scores non-dict metrics
Noridom1 Sep 6, 2026
c6e7522
fix: convert LCB list output to dict format for validate_scores
Noridom1 Sep 6, 2026
220747b
fix: cap SciCode smoke generations at 8k
Noridom1 Sep 6, 2026
be616cb
ci: retry SciCode smoke only
Noridom1 Sep 6, 2026
340da3a
fix: repair SciCode streamed response assembly
Noridom1 Sep 6, 2026
d8cc1e0
fix: reject invalid quality smoke outputs
Noridom1 Sep 7, 2026
ae574e7
test: include quality eval scenarios
Noridom1 Sep 7, 2026
a34138e
ci: rerun HLE and SWE-bench Pro smoke
Noridom1 Sep 7, 2026
898766b
fix: preserve HLE streamed reasoning responses
Noridom1 Sep 7, 2026
ad39155
ci: dispatch HLE smoke only
Noridom1 Sep 7, 2026
bb370c6
fix: repair lm-eval quality smoke
Noridom1 Sep 7, 2026
f4af9c4
fix: extend HLE request timeout
Noridom1 Sep 7, 2026
78bfa5d
ci: run balanced coding benchmarks at ccu4
Noridom1 Sep 7, 2026
48c5ce2
ci: balanced coding + agentic coding | GLM-5.2 | CCU4
Noridom1 Sep 7, 2026
499636c
fix: validate native quality benchmark metrics
Noridom1 Sep 7, 2026
62a47bd
fix: provision cached SciCode test data
Noridom1 Sep 7, 2026
a57d20c
fix: validate all quality benchmark formats
Noridom1 Sep 7, 2026
4c4a132
ci: smoke GLM-5.2 on VNG Cloud MaaS endpoint
Noridom1 Sep 8, 2026
6d2e134
fix: harden coding benchmark smoke harnesses
Noridom1 Sep 8, 2026
b35c252
[Quality] Balanced Coding + Agentic Coding | GLM-5.2 | VNG Cloud MaaS…
Noridom1 Sep 8, 2026
7a18d97
[Quality] Balanced Coding + Agentic Coding | GLM-5.2 | VNG Cloud MaaS…
Noridom1 Sep 8, 2026
1d48932
fix: harden quality benchmark retries
Noridom1 Sep 9, 2026
02741c2
ci: target failed quality benchmarks
Noridom1 Sep 9, 2026
6ee2480
fix: scope quality benchmark rerun
Noridom1 Sep 9, 2026
4955147
ci: dispatch filtered quality evaluations [skip-sweep]
Noridom1 Sep 9, 2026
b6e1793
fix: apply 64k quality generation defaults [skip-sweep]
Noridom1 Sep 9, 2026
aab35a5
fix: read nested BFCL subset results [skip-sweep]
Noridom1 Sep 9, 2026
1bce6ff
fix: extend SWE-bench Pro container startup timeout
Noridom1 Sep 9, 2026
1b92448
Merge vng-benchmark into feat/quality-benchmark
DinhKhangHoang Oct 22, 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
57 changes: 44 additions & 13 deletions .github/workflows/benchmark-tmpl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
# recipe ignores it, and the SPEED-Bench path falls back to HF_TOKEN.
SPEEDBENCH_HF_TOKEN:
required: false
# Bearer token for the GreenNode MaaS endpoint (quality evals, remote bench).
GREENNODE_API_KEY:
required: false
inputs:
config:
description: "Benchmark configuration as JSON"
Expand Down Expand Up @@ -173,28 +176,28 @@
RECIPE_FINGERPRINT: ${{ fromJSON(inputs.config).recipe-fingerprint || '' }}
MODEL: ${{ fromJSON(inputs.config).model }}
MODEL_PREFIX: ${{ fromJSON(inputs.config).model-prefix }}
ISL: ${{ inputs.scenario-type == 'agentic-coding' && '0' || fromJSON(inputs.config).isl }}
OSL: ${{ inputs.scenario-type == 'agentic-coding' && '0' || fromJSON(inputs.config).osl }}
MAX_MODEL_LEN: ${{ inputs.scenario-type == 'agentic-coding' && '0' || fromJSON(inputs.config).max-model-len }}
ISL: ${{ (inputs.scenario-type == 'agentic-coding' || startsWith(inputs.scenario-type, 'quality-')) && '0' || fromJSON(inputs.config).isl }}
OSL: ${{ (inputs.scenario-type == 'agentic-coding' || startsWith(inputs.scenario-type, 'quality-')) && '0' || fromJSON(inputs.config).osl }}
MAX_MODEL_LEN: ${{ (inputs.scenario-type == 'agentic-coding' || startsWith(inputs.scenario-type, 'quality-')) && '0' || fromJSON(inputs.config).max-model-len }}
IMAGE: ${{ fromJSON(inputs.config).image }}
FRAMEWORK: ${{ fromJSON(inputs.config).framework }}
PRECISION: ${{ fromJSON(inputs.config).precision }}
TP: ${{ fromJSON(inputs.config).tp }}
PP_SIZE: ${{ fromJSON(inputs.config).pp }}
DCP_SIZE: ${{ fromJSON(inputs.config).dcp-size }}
PCP_SIZE: ${{ fromJSON(inputs.config).pcp-size }}
EP_SIZE: ${{ fromJSON(inputs.config).ep }}
TP: ${{ startsWith(inputs.scenario-type, 'quality-') && '1' || fromJSON(inputs.config).tp }}
PP_SIZE: ${{ startsWith(inputs.scenario-type, 'quality-') && '1' || fromJSON(inputs.config).pp }}
DCP_SIZE: ${{ startsWith(inputs.scenario-type, 'quality-') && '1' || fromJSON(inputs.config).dcp-size }}
PCP_SIZE: ${{ startsWith(inputs.scenario-type, 'quality-') && '1' || fromJSON(inputs.config).pcp-size }}
EP_SIZE: ${{ startsWith(inputs.scenario-type, 'quality-') && '1' || fromJSON(inputs.config).ep }}
DP_ATTENTION: ${{ inputs.dp-attn }}
CONC: ${{ fromJSON(inputs.config).conc }}
SPEC_DECODING: ${{ fromJSON(inputs.config).spec-decoding }}
DISAGG: ${{ inputs.scenario-type == 'agentic-coding' && 'false' || fromJSON(inputs.config).disagg }}
CONC: ${{ startsWith(inputs.scenario-type, 'quality-') && '1' || fromJSON(inputs.config).conc }}
SPEC_DECODING: ${{ startsWith(inputs.scenario-type, 'quality-') && 'none' || fromJSON(inputs.config).spec-decoding }}
DISAGG: ${{ (inputs.scenario-type == 'agentic-coding' || startsWith(inputs.scenario-type, 'quality-')) && 'false' || fromJSON(inputs.config).disagg }}
RUN_EVAL: ${{ inputs.run-eval }}
EVAL_ONLY: ${{ inputs.eval-only }}
EVAL_FRAMEWORK: ${{ inputs.eval-framework }}
EVAL_SUITE: ${{ inputs.eval-suite }}
# Agentic-coding env. Fixed-seq-len jobs leave these empty.
SCENARIO_TYPE: ${{ inputs.scenario-type }}
SCENARIO_SUBDIR: ${{ inputs.scenario-type == 'agentic-coding' && 'agentic/' || 'fixed_seq_len/' }}
SCENARIO_SUBDIR: ${{ (inputs.scenario-type == 'agentic-coding' && 'agentic/') || (startsWith(inputs.scenario-type, 'quality-') && 'quality/') || 'fixed_seq_len/' }}
IS_AGENTIC: ${{ inputs.scenario-type == 'agentic-coding' && '1' || '0' }}
KV_OFFLOADING: ${{ inputs.scenario-type == 'agentic-coding' && format('{0}', fromJSON(inputs.config).kv-offloading) || '' }}
KV_OFFLOAD_BACKEND: ${{ inputs.scenario-type == 'agentic-coding' && format('{0}', fromJSON(inputs.config).kv-offload-backend.name) || '' }}
Expand Down Expand Up @@ -227,11 +230,11 @@
# scenario in one run). scenario-map is keyed by the row's exp-name; the flat
# serving.scenario is the single-scenario fallback, empty for scenario lists
# so a missing map entry fails loudly in serve_generic.sh (check_env_vars).
SERVING_SCENARIO: ${{ inputs.serving != '' && (fromJSON(inputs.serving).scenario-map[fromJSON(inputs.config).exp-name].scenario || fromJSON(inputs.serving).scenario) || '' }}

Check warning on line 233 in .github/workflows/benchmark-tmpl.yml

View workflow job for this annotation

GitHub Actions / Zizmor

obfuscation

benchmark-tmpl.yml:233: obfuscated usage of GitHub Actions features: index expression is computed
SERVING_LOADER: ${{ inputs.serving != '' && (fromJSON(inputs.serving).scenario-map[fromJSON(inputs.config).exp-name].loader || fromJSON(inputs.serving).loader) || '' }}

Check warning on line 234 in .github/workflows/benchmark-tmpl.yml

View workflow job for this annotation

GitHub Actions / Zizmor

obfuscation

benchmark-tmpl.yml:234: obfuscated usage of GitHub Actions features: index expression is computed
# '1' for sweep scenarios (adaptive_search), '0' otherwise — never '': check_env_vars
# rejects empty values, so '' would abort every non-sweep serving run in serve_generic.sh.
SERVING_SEARCH: ${{ inputs.serving != '' && ((fromJSON(inputs.serving).scenario-map[fromJSON(inputs.config).exp-name].search || fromJSON(inputs.serving).search) && '1' || '0') }}

Check warning on line 237 in .github/workflows/benchmark-tmpl.yml

View workflow job for this annotation

GitHub Actions / Zizmor

obfuscation

benchmark-tmpl.yml:237: obfuscated usage of GitHub Actions features: index expression is computed
SERVING_YAML: ${{ inputs.serving != '' && fromJSON(inputs.serving).yaml || '' }}
# Router sidecar (any router, spec 2026-10-14); only runners/launch_hardware-hcm.sh reads these.
ROUTER_IMAGE: ${{ inputs.serving != '' && fromJSON(inputs.serving).router-image || '' }}
Expand All @@ -247,6 +250,14 @@
# Bearer token for authenticated remote targets. Empty for every other
# recipe, which leaves build_replay_cmd's --api-key branch inert.
REMOTE_API_KEY: ${{ secrets.GREENNODE_API_KEY }}
# Quality-eval env, from the quality row (scenario-type quality-*); empty for every other recipe.
QUALITY_BENCHMARK_NAME: ${{ startsWith(inputs.scenario-type, 'quality-') && fromJSON(inputs.config).benchmark-name || '' }}
QUALITY_ENDPOINT: ${{ startsWith(inputs.scenario-type, 'quality-') && fromJSON(inputs.config).quality-endpoint || '' }}
QUALITY_API_KEY: ${{ secrets.GREENNODE_API_KEY }}
QUALITY_MODEL_NAME: ${{ startsWith(inputs.scenario-type, 'quality-') && fromJSON(inputs.config).quality-model-name || '' }}
SMOKE: ${{ startsWith(inputs.scenario-type, 'quality-') && fromJSON(inputs.config).smoke && 'true' || 'false' }}
NUM_CONCURRENT: ${{ startsWith(inputs.scenario-type, 'quality-') && format('{0}', fromJSON(inputs.config).num-concurrent) || '' }}
MAX_GEN_TOKENS: ${{ startsWith(inputs.scenario-type, 'quality-') && format('{0}', fromJSON(inputs.config).max-gen-tokens) || '' }}
AIPERF_FAILED_REQUEST_THRESHOLD: '0.10'
RESULT_DIR: /workspace/results
PYTHONDONTWRITEBYTECODE: '1'
Expand All @@ -261,7 +272,7 @@

jobs:
benchmark:
runs-on: >-

Check warning on line 275 in .github/workflows/benchmark-tmpl.yml

View workflow job for this annotation

GitHub Actions / Zizmor

self-hosted-runner

benchmark-tmpl.yml:275: runs on a self-hosted runner: expression may expand into a self-hosted runner
${{ fromJSON(
vars.PRIORITY_SCHEDULER_ENABLED == 'true' &&
(
Expand Down Expand Up @@ -306,6 +317,7 @@
timeout-minutes: 500
name: >-
${{ inputs.klaud-run && 'klaud | ' || '' }}p${{ inputs.priority }} | ${{ fromJSON(inputs.config).model-prefix }} ${{ fromJSON(inputs.config).precision }} ${{ inputs.runner }} ${{ fromJSON(inputs.config).framework == 'sglang' && 'sgl' || fromJSON(inputs.config).framework == 'dynamo-sglang' && 'dyn-sgl' || fromJSON(inputs.config).framework == 'sglang-disagg' && 'sgl-disagg' || fromJSON(inputs.config).framework }}
${{ startsWith(inputs.scenario-type, 'quality-') && fromJSON(inputs.config).benchmark-name || '' }}
TP${{ fromJSON(inputs.config).tp }}${{ format('{0}', fromJSON(inputs.config).pp) != '' && format('{0}', fromJSON(inputs.config).pp) != '1' && format('/PP{0}', fromJSON(inputs.config).pp) || '' }}${{ format('{0}', fromJSON(inputs.config).dcp-size) != '' && format('{0}', fromJSON(inputs.config).dcp-size) != '1' && format('/DCP{0}', fromJSON(inputs.config).dcp-size) || '' }}${{ format('{0}', fromJSON(inputs.config).pcp-size) != '' && format('{0}', fromJSON(inputs.config).pcp-size) != '1' && format('/PCP{0}', fromJSON(inputs.config).pcp-size) || '' }}${{ format('{0}', fromJSON(inputs.config).ep) != '' && format('{0}', fromJSON(inputs.config).ep) != '1' && format('/EP{0}', fromJSON(inputs.config).ep) || '' }}${{ inputs.dp-attn && '/DPA' || '' }}
${{ fromJSON(inputs.config).spec-decoding != 'none' && fromJSON(inputs.config).spec-decoding || '' }}
${{ inputs.scenario-type == 'agentic-coding' && format('{0}', fromJSON(inputs.config).kv-offloading) != '' && fromJSON(inputs.config).kv-offloading != 'none' && format('{0} KV offload', fromJSON(inputs.config).kv-offloading) || '' }}
Expand Down Expand Up @@ -440,6 +452,11 @@
hardware-hcm-*) LAUNCH_SCRIPT="runners/launch_hardware-hcm.sh" ;;
*) LAUNCH_SCRIPT="runners/launch_${RUNNER_NAME%%_*}.sh" ;;
esac
# Quality evals drive a remote endpoint from any runner labelled
# cluster:quality-eval, so they skip the per-runner launchers.
if [[ "$SCENARIO_SUBDIR" == "quality/" ]]; then
LAUNCH_SCRIPT="runners/launch_quality-eval.sh"
fi
bash "$LAUNCH_SCRIPT"

if [ "${EVAL_ONLY}" = "true" ]; then
Expand Down Expand Up @@ -590,12 +607,24 @@
agent_preds.json
predictions.jsonl
swebench_report_*.json
eval_results*.json
*.traj*
*.csv
lcb_results*.json
*.jsonl
bfcl_inference_audit.json
bfcl_result_*.json
scicode_debug.tar.gz
if-no-files-found: ${{ inputs.eval-only && 'error' || 'ignore' }}

- name: Verify eval scores
if: ${{ (success() || failure()) && inputs.eval-only }}
run: python3 utils/evals/validate_scores.py
run: |
SMOKE_FLAG=""
if [ "$SMOKE" = "true" ]; then
SMOKE_FLAG="--smoke"
fi
python3 utils/evals/validate_scores.py $SMOKE_FLAG

- name: Cleanup eval outputs (post-upload)
if: ${{ always() && (env.RUN_EVAL == 'true' || inputs.eval-only) }}
Expand All @@ -608,6 +637,8 @@
rm -f sample*.jsonl || true
rm -f -- ./*_artifacts.tar.gz || true
rm -f agent_preds.json predictions.jsonl swebench_report_*.json *.traj* || true
rm -f eval_results*.json *.csv lcb_results*.json || true
rm -f bfcl_inference_audit.json bfcl_result_*.json scicode_debug.tar.gz || true

- name: Repair root-owned artifacts (post-run)
if: ${{ always() && inputs.runner == 'cluster:mi355x-amds' }}
Expand Down
39 changes: 34 additions & 5 deletions .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ jobs:
agentic-eval-config: ${{ steps.get-jobs.outputs.agentic-eval-config }}
multi-node-agentic-config: ${{ steps.get-jobs.outputs.multi-node-agentic-config }}
multi-node-agentic-eval-config: ${{ steps.get-jobs.outputs.multi-node-agentic-eval-config }}
quality-eval-config: ${{ steps.get-jobs.outputs.quality-eval-config }}
serving: ${{ steps.get-jobs.outputs.serving }}
steps:
- name: Checkout code (ref)
Expand Down Expand Up @@ -349,22 +350,50 @@ jobs:
AGENTIC_EVAL=$(echo "$CONFIG_JSON" | python3 -c "import sys,json; d=json.load(sys.stdin); print(json.dumps([x for x in d if x.get('scenario-type') == 'agentic-coding' and 'prefill' not in x and x.get('run-eval', False)]))" | score_matrix agentic-eval)
MULTI_AGENTIC=$(echo "$CONFIG_JSON" | python3 -c "import sys,json; d=json.load(sys.stdin); print(json.dumps([x for x in d if x.get('scenario-type') == 'agentic-coding' and 'prefill' in x and not x.get('eval-only', False)]))" | score_matrix multi-agentic)
MULTI_AGENTIC_EVAL=$(echo "$CONFIG_JSON" | python3 -c "import sys,json; d=json.load(sys.stdin); print(json.dumps([x for x in d if x.get('scenario-type') == 'agentic-coding' and 'prefill' in x and x.get('run-eval', False)]))" | score_matrix multi-agentic-eval)
SINGLE=$(echo "$CONFIG_JSON" | python3 -c "import sys,json; d=json.load(sys.stdin); print(json.dumps([x for x in d if 'prefill' not in x and x.get('scenario-type') != 'agentic-coding' and not x.get('eval-only', False)]))" | score_matrix single)
MULTI=$(echo "$CONFIG_JSON" | python3 -c "import sys,json; d=json.load(sys.stdin); print(json.dumps([x for x in d if 'prefill' in x and x.get('scenario-type') != 'agentic-coding' and not x.get('eval-only', False)]))" | score_matrix multi)
EVALS=$(echo "$CONFIG_JSON" | python3 -c "import sys,json; d=json.load(sys.stdin); print(json.dumps([x for x in d if 'prefill' not in x and x.get('scenario-type') != 'agentic-coding' and x.get('run-eval', False)]))" | score_matrix eval)
QUALITY=$(echo "$CONFIG_JSON" | python3 -c "import sys,json; d=json.load(sys.stdin); print(json.dumps([x for x in d if x.get('scenario-type', '').startswith('quality-')]))" | score_matrix quality-eval)
SINGLE=$(echo "$CONFIG_JSON" | python3 -c "import sys,json; d=json.load(sys.stdin); print(json.dumps([x for x in d if 'prefill' not in x and x.get('scenario-type') != 'agentic-coding' and not x.get('scenario-type', '').startswith('quality-') and not x.get('eval-only', False)]))" | score_matrix single)
MULTI=$(echo "$CONFIG_JSON" | python3 -c "import sys,json; d=json.load(sys.stdin); print(json.dumps([x for x in d if 'prefill' in x and x.get('scenario-type') != 'agentic-coding' and not x.get('scenario-type', '').startswith('quality-') and not x.get('eval-only', False)]))" | score_matrix multi)
EVALS=$(echo "$CONFIG_JSON" | python3 -c "import sys,json; d=json.load(sys.stdin); print(json.dumps([x for x in d if 'prefill' not in x and x.get('scenario-type') != 'agentic-coding' and not x.get('scenario-type', '').startswith('quality-') and x.get('run-eval', False)]))" | score_matrix eval)
MULTI_EVAL=$(echo "$CONFIG_JSON" | python3 -c "import sys,json; d=json.load(sys.stdin); print(json.dumps([x for x in d if 'prefill' in x and x.get('scenario-type') != 'agentic-coding' and x.get('run-eval', False)]))" | score_matrix multi-eval)
{
echo "agentic-config=$AGENTIC"
echo "agentic-eval-config=$AGENTIC_EVAL"
echo "multi-node-agentic-config=$MULTI_AGENTIC"
echo "multi-node-agentic-eval-config=$MULTI_AGENTIC_EVAL"
echo "quality-eval-config=$QUALITY"
echo "single-node-config=$SINGLE"
echo "multi-node-config=$MULTI"
echo "eval-config=$EVALS"
echo "multi-node-eval-config=$MULTI_EVAL"
echo "serving=${SERVING_JSON:-}"
} >> "$GITHUB_OUTPUT"

test-sweep-quality-evals:
needs: get-jobs
if: ${{ needs.get-jobs.outputs.quality-eval-config != '' && needs.get-jobs.outputs.quality-eval-config != '[]' }}
uses: $/.github/workflows/benchmark-tmpl.yml
name: quality eval /
strategy:
fail-fast: ${{ inputs.fail-fast }}
matrix:
config: ${{ fromJson(needs.get-jobs.outputs.quality-eval-config) }}
secrets:
REPO_PAT: ${{ secrets.REPO_PAT }}
INFERENCEX_OFFICIAL_RO_HF_TOKEN: ${{ secrets.INFERENCEX_OFFICIAL_RO_HF_TOKEN }}
GREENNODE_API_KEY: ${{ secrets.GREENNODE_API_KEY }}
with:
config: ${{ toJSON(matrix.config) }}
klaud-run: ${{ inputs.klaud-run }}
runner: ${{ matrix.config.runner }}
priority: ${{ matrix.config.priority }}
queue-token: ${{ matrix.config['queue-token'] }}
skip-queue-pr: ${{ matrix.config['skip-queue-pr'] || '' }}
run-eval: true
eval-only: true
eval-limit: ${{ matrix.config.eval-limit || inputs.eval-limit }}
scenario-type: ${{ matrix.config.scenario-type }}
ref: ${{ inputs.ref }}

test-sweep-multi-node:
needs: get-jobs
if: ${{ needs.get-jobs.outputs.multi-node-config != '' && needs.get-jobs.outputs.multi-node-config != '[]' }}
Expand Down Expand Up @@ -617,8 +646,8 @@ jobs:

collect-evals:
name: collect-evals
needs: [test-sweep-evals, test-sweep-multi-node-evals, test-sweep-agentic-evals, test-sweep-multi-node-agentic-evals]
if: ${{ always() && (needs.test-sweep-evals.result != 'skipped' || needs.test-sweep-multi-node-evals.result != 'skipped' || needs.test-sweep-agentic-evals.result != 'skipped' || needs.test-sweep-multi-node-agentic-evals.result != 'skipped') }}
needs: [test-sweep-evals, test-sweep-multi-node-evals, test-sweep-agentic-evals, test-sweep-multi-node-agentic-evals, test-sweep-quality-evals]
if: ${{ always() && (needs.test-sweep-evals.result != 'skipped' || needs.test-sweep-multi-node-evals.result != 'skipped' || needs.test-sweep-agentic-evals.result != 'skipped' || needs.test-sweep-multi-node-agentic-evals.result != 'skipped' || needs.test-sweep-quality-evals.result != 'skipped') }}
uses: $/.github/workflows/collect-evals.yml

calc-success-rate:
Expand Down
40 changes: 38 additions & 2 deletions .github/workflows/run-sweep.yml
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,42 @@ jobs:
eval-conc: ${{ matrix.config['eval-conc'] }}
scenario-type: agentic-coding

# Quality-eval rows carry the quality-eval input shape (benchmark-name,
# quality-endpoint, quality-model-name, smoke), so they are dispatched
# with their own job rather than sweep-evals' fixed-seq-len inputs.
sweep-quality-evals:
needs: [setup, canary-select, canary-sweep]
if: >-
${{
!cancelled() &&
needs.setup.result == 'success' &&
needs.setup.outputs.reuse-enabled != 'true' &&
(needs.canary-sweep.result == 'success' || needs.canary-sweep.result == 'skipped') &&
toJson(fromJson(needs.setup.outputs.search-space-config).quality_evals) != '[]' &&
toJson(fromJson(needs.setup.outputs.search-space-config).quality_evals) != 'null'
}}
uses: $/.github/workflows/benchmark-tmpl.yml
name: quality eval /
strategy:
fail-fast: ${{ contains(github.event.pull_request.labels.*.name, 'full-sweep-fail-fast') || contains(github.event.pull_request.labels.*.name, 'full-sweep-fail-fast-no-canary') }}
matrix:
config: ${{ fromJson(needs.setup.outputs.search-space-config).quality_evals }}
secrets:
REPO_PAT: ${{ secrets.REPO_PAT }}
INFERENCEX_OFFICIAL_RO_HF_TOKEN: ${{ secrets.INFERENCEX_OFFICIAL_RO_HF_TOKEN }}
GREENNODE_API_KEY: ${{ secrets.GREENNODE_API_KEY }}
with:
config: ${{ toJSON(matrix.config) }}
klaud-run: *klaud-run
runner: ${{ matrix.config.runner }}
priority: ${{ matrix.config.priority }}
queue-token: ${{ matrix.config['queue-token'] }}
skip-queue-pr: ${{ matrix.config['skip-queue-pr'] || '' }}
run-eval: true
eval-only: true
eval-limit: ${{ matrix.config.eval-limit || (contains(github.event.pull_request.labels.*.name, 'sweep-enabled') && '10' || '') }}
scenario-type: ${{ matrix.config.scenario-type }}

collect-results:
name: collect-results
needs:
Expand Down Expand Up @@ -825,8 +861,8 @@ jobs:

collect-evals:
name: collect-evals
needs: [sweep-evals, sweep-agentic-evals, sweep-multi-node-evals, sweep-multi-node-agentic-evals, setup]
if: ${{ always() && needs.setup.result != 'skipped' && (needs.sweep-evals.result != 'skipped' || needs.sweep-agentic-evals.result != 'skipped' || needs.sweep-multi-node-evals.result != 'skipped' || needs.sweep-multi-node-agentic-evals.result != 'skipped') }}
needs: [sweep-evals, sweep-agentic-evals, sweep-multi-node-evals, sweep-multi-node-agentic-evals, sweep-quality-evals, setup]
if: ${{ always() && needs.setup.result != 'skipped' && (needs.sweep-evals.result != 'skipped' || needs.sweep-agentic-evals.result != 'skipped' || needs.sweep-multi-node-evals.result != 'skipped' || needs.sweep-multi-node-agentic-evals.result != 'skipped' || needs.sweep-quality-evals.result != 'skipped') }}
uses: $/.github/workflows/collect-evals.yml

upload-changelog-metadata:
Expand Down
23 changes: 23 additions & 0 deletions BENCHMARK_TIMES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Quality Benchmark Time Estimates

Estimates are for GLM-5.2 at concurrency 4. API latency, reasoning length,
rate limits, image setup, and sandbox execution can change wall time.

| Benchmark | Full size | Full estimate | 20-sample estimate | Default max generation |
|---|---:|---:|---:|---:|
| GPQA-Diamond | 198 | ~20 min | ~2 min | 8K |
| MMLU-Pro | 12,032 | ~22 h | ~2 min* | 8K |
| HLE | 2,158 | ~4.5 h | ~5 min* | 16K |
| LiveCodeBench | 1,055 | ~8 h | ~15 min | 16K |
| BFCL v4 | ~2,000 | ~1.5 h | <1 min | 8K |
| SciCode | 288 subproblems | ~5.5 h | ~23 min | 16K |
| SWE-bench Pro | 731 | ~45 h | ~30 min | 32K per agent turn |
| DeepSWE | 113 | ~29 h | ~5 h | 32K per agent turn |

\* `LIMIT` applies per subtask for MMLU-Pro and HLE, so `LIMIT=20` evaluates
more than 20 total questions.

These are output ceilings, not target lengths. Natural stop conditions still
end generation early. Override any default with `MAX_GEN_TOKENS`; CI matrix
rows may use `max-gen-tokens`. Streaming avoids idle connection timeouts but
does not remove total request deadlines or the cost of long generations.
Loading
Loading