CI(consolidated): skip false-positive patches in runtime ledger; drop job-level continue-on-error

Two cleanups derived from review of the matrix output:

1. Skip false-positive zero-arg patches in the runtime ledger.
   Three patches have all-defaulted signatures but require either
   runtime args or real CUDA, so calling them in isolation produces
   a meaningless failure:
     - patch_linear_scaling: defaults are None placeholders;
       body starts with `assert rope_module is not None` etc.
     - patch_llama_rope_scaling: same shape.
     - patch_unsloth_smart_gradient_checkpointing: legitimately
       allocates CUDA tensors via aten::empty.memory_format inside
       initialize_unsloth_gradient_checkpointing(); the torch.cuda.*
       Python spoof can't intercept that at the dispatcher level.
   Add NEEDS_PRECONDITION = {...} to the shim and skip those by name.
   Symbol presence is still verified via REQUIRED.

2. Drop the job-level `continue-on-error: true`.
   Previously the cell reported SUCCESS even when steps failed, which
   made the PR check UI lie. Real failures now turn the cell red.
   Per-step `continue-on-error: true` stays so a single failed step
   does not cascade and skip the rest of the ledger.

Three other failures the matrix surfaced are addressed by separate PRs
to source:
  - unslothai/unsloth#5319 (patch_fast_lora missing import,
    patch_sft_trainer_tokenizer Union NameError, openenv OSError)
  - unslothai/unsloth-zoo#628 (skip MoE coverage on older transformers)
This commit is contained in:
Daniel Han 2026-05-07 06:19:36 +00:00
commit 433cfa93d7

View file

@ -82,9 +82,14 @@ jobs:
name: "Consolidated CPU (${{ matrix.combo.label }})"
runs-on: ubuntu-latest
timeout-minutes: 35
# First-pass posture: surface results in the PR check UI without blocking
# merge. Flip to false (or delete this line) once every cell is green.
continue-on-error: true
# NOTE: previously had a job-level `continue-on-error: true` so cells
# reported SUCCESS even when individual steps failed. That made the
# PR check UI lie. The job-level flag is removed; per-step
# `continue-on-error: true` remains so a single failed step does not
# cascade and skip the rest of the ledger. Real failures now show up
# as a red cell on the PR. Patches with known preconditions are now
# explicitly skipped via NEEDS_PRECONDITION in the runtime check
# shim, not silenced via blanket continue-on-error.
env:
UNSLOTH_ZOO_REF: ${{ inputs.unsloth_zoo_ref || 'main' }}
MATRIX_TRANSFORMERS_SPEC: ${{ matrix.combo.transformers_spec }}
@ -434,9 +439,26 @@ jobs:
"patch_unsloth_smart_gradient_checkpointing",
"patch_gradient_accumulation_fix",
}
# Patches whose signature looks zero-arg (`()` or all-defaulted)
# but which actually require either runtime args or real CUDA.
# Calling these in isolation is meaningless, so skip the
# invocation. Symbol presence (REQUIRED above) is still verified.
# patch_linear_scaling / patch_llama_rope_scaling: defaults are
# None placeholders; the bodies start with
# `assert <param> is not None`.
# patch_unsloth_smart_gradient_checkpointing: legitimately
# allocates CUDA tensors via aten::empty.memory_format inside
# initialize_unsloth_gradient_checkpointing(); the
# torch.cuda.* spoof can't intercept that at the dispatcher
# level.
NEEDS_PRECONDITION = {
"patch_linear_scaling",
"patch_llama_rope_scaling",
"patch_unsloth_smart_gradient_checkpointing",
}
def test_zero_arg_patch_invocations():
ok, fail, args, miss_imports = 0, [], [], {}
ok, fail, args, skipped, miss_imports = 0, [], [], [], {}
seen_required = set()
for mod_name in MODULES:
try:
@ -459,6 +481,10 @@ jobs:
need = []
if need:
args.append((mod_name, name, need)); continue
if name in NEEDS_PRECONDITION:
skipped.append(f"{mod_name}.{name}")
print(f" SKIP {mod_name}.{name} (needs precondition / CUDA)")
continue
try:
fn()
ok += 1
@ -466,10 +492,12 @@ jobs:
except Exception as e:
fail.append((mod_name, name, type(e).__name__, str(e)[:200]))
print(f" FAIL {mod_name}.{name} -> {type(e).__name__}: {str(e)[:200]}")
print(f"\nzero-arg patch_*: ok={ok} fail={len(fail)}")
print(f"\nzero-arg patch_*: ok={ok} fail={len(fail)} skipped={len(skipped)}")
print(f"arg-required patch_* (skipped, listed for review): {len(args)}")
for m, n, r in args:
print(f" needs={r}: {m}.{n}")
if skipped:
print(f"explicitly skipped (needs precondition / CUDA): {skipped}")
if miss_imports:
print("\nmodules failed to import (skipped):")
for k, v in miss_imports.items():