Skip to content

fix(autotune): coli tune swept GLM-only CUDA and NUMA knobs on every engine - #1584

Merged
JustVugg merged 2 commits into
JustVugg:devfrom
kevin9327:fix/tune-cuda-knobs-glm-only
Sep 17, 2026
Merged

JustVugg merged 2 commits into
JustVugg:devfrom
kevin9327:fix/tune-cuda-knobs-glm-only

Conversation

@kevin9327

@kevin9327 kevin9327 commented Sep 17, 2026

Copy link
Copy Markdown

Symptom

coli tune offers four knobs to every engine that only GLM-5.2 reads:

  • cuda-pipe-1, cuda-pipe-2 and cuda-sync, whenever the plan lists a GPU;
  • numa-on, on a multi-socket host.

On any other engine each of those candidates runs the baseline again. It costs a full engine start and a full request rotation, and timing noise can be accepted as a gain and written into the saved profile.

coli tune on the tiny Qwen3.6 fixture (Windows, RTX 5080 visible to the planner, CPU-only qwen36.exe), unfixed dev:

  · baseline cap=8 (1/1, prompt 1/2)
  · omp-8 cap=8 (1/1, prompt 1/2)
  · cuda-pipe-2 cap=8 (1/1, prompt 1/2)
  · cuda-sync cap=8 (1/1, prompt 1/2)
  · confirm-winner cap=8 (1/1, prompt 1/2)
  · confirm-baseline cap=8 (1/1, prompt 1/2)

  ✓ accepted cuda-pipe-2: 491.44 → 838.89 tok/s (+70.7%)
  env: OMP_NUM_THREADS=8 COLI_CUDA_PIPE=2

qwen36 never reads COLI_CUDA_PIPE. The reported +70.7% is omp-8 plus noise, and the profile now carries a knob that does nothing.

Root cause

candidate_steps checks arch for PIPE and DIRECT (#898), but not for these four:

knob where it is read
COLI_CUDA_PIPE colibri.c only (g_cuda_pipe, line 11098)
COLI_CUDA_ASYNC expert_group_impl in backend_cuda.cu. That function is reached through coli_cuda_expert_group / _pinned, and colibri.c is their only caller. qwen36 and qwen38 use the _issue/_take pair, which does not read it. olmoe, glm53, deepseek_v41 and inkling do not link backend_cuda.o.
COLI_NUMA colibri.c only (numa_init, which mbinds colibri's own expert slabs)

The docstring said COLI_NUMA was read by every engine. git grep finds no other reader.

Fix

  • Sweep numa-on and the CUDA candidates only when arch == "glm", the same gate PIPE and DIRECT already have.
  • Correct the docstring. OMP_NUM_THREADS stays universal.
  • GLM's candidate list is unchanged.

Two commits: the CUDA pair, then COLI_NUMA.

Tests

In c/tests/test_autotune.py:

  • test_cuda_and_numa_knobs_are_not_swept_on_other_engines uses a plan with a GPU and two sockets.
  • test_sibling_tune_with_a_gpu_and_two_sockets_launches_only_omp runs run_tune for qwen36 through the existing FakeServeEngine, with the same plan. The candidates are baseline and omp-4, no launch sees any of the three variables, and there are 4 engine launches.

Fail-before on unfixed dev:

AssertionError: True is not false : {'omp-4': {'OMP_NUM_THREADS': '4'}, 'numa-on': {'COLI_NUMA': '1'}, 'cuda-pipe-1': {'COLI_CUDA_PIPE': '1'}, 'cuda-pipe-2': {'COLI_CUDA_PIPE': '2'}, 'cuda-sync': {'COLI_CUDA_ASYNC': '0'}}
...
AssertionError: Lists differ: ['baseline', 'omp-4', 'numa-on', 'cuda-pipe-1', 'cuda-pipe-2', 'cuda-sync'] != ['baseline', 'omp-4']
FAILED (failures=9)

That is 8 subtests plus the run_tune test.

Verification

  • tests.test_autotune, tests.test_autotune_engine_output_locale, tests.test_v4_cli (every test module that imports autotune): 47 tests OK, in the cp949 locale and with PYTHONUTF8=1.
  • End to end, Windows, real engines on tiny fixtures, coli tune --tokens 4 --repeats 1 (fixtures from tools/make_qwen36_tiny.py + convert_qwen36.py, tools/make_olmoe_tiny.py + convert_olmoe_merged.py, tools/make_glm_oracle.py):
    • qwen36_tiny_c: baseline, omp-8, then the gate; no CUDA candidate.
    • olmoe_tiny_c: baseline, omp-8, confirm-winner, confirm-baseline.
    • glm_tiny: baseline, omp-8, cuda-pipe-2, cuda-sync, confirm-winner, confirm-baseline, as before.
    • The host has one socket, so numa-on is covered by the unit tests only.
  • Full Python suite (Windows, gcc 16.2, PYTHONUTF8=1, first commit): 1085 tests, 1 failure and 6 errors, none from this change.
    • The 6 errors are test_cuda_test_makefile, which needs make on PATH.
    • The failure is test_kimi_usage_cli.test_no_arguments_points_at_the_launcher_and_fails. On Windows the engine prints coli.cmd chat and the test looks for coli chat; it has nothing to do with autotune.

🤖 Generated with Claude Code

kevin9327 and others added 2 commits September 17, 2026 20:04
candidate_steps offered cuda-pipe-1, cuda-pipe-2 and cuda-sync whenever
the plan listed a GPU, whatever the engine. COLI_CUDA_PIPE is read in
colibri.c only, and COLI_CUDA_ASYNC only inside expert_group_impl, which
is reached from colibri.c alone. On any other engine those candidates
were identical runs: each cost a full engine start, and a timing wobble
could be accepted as a gain and written into the saved profile.

Gate the CUDA sweep on arch == "glm", the same rule JustVugg#898 applied to
PIPE and DIRECT.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
numa-on was offered to every engine on a multi-socket host, and the
docstring called COLI_NUMA engine-agnostic. The only reader is
colibri.c's numa_init, which mbinds colibri's own expert slabs; no other
engine reads the variable. Gate it on arch == "glm" with the CUDA pair
and correct the docstring.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@kevin9327 kevin9327 changed the title fix(autotune): coli tune swept GLM-only CUDA knobs on every engine fix(autotune): coli tune swept GLM-only CUDA and NUMA knobs on every engine Sep 17, 2026
@JustVugg
JustVugg merged commit 0f36f6a into JustVugg:dev Sep 17, 2026
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants