Repository navigation
train: a node the device cannot run refuses the JOB, not the server; supports_op tells the truth - #35
Conversation
…supports_op tells the truth Measured on the 5090 2026-10-06: /train on a qwen35 model aborted the SERVING process from inside a CUDA kernel (unary.cu, SQR on a viewed k_conv). CUDA supports_op returned true unconditionally for SQR/SQRT/SIN/COS/LOG while those kernels assert a contiguous src0, so the scheduler trusted it. - CUDA supports_op: SQR/SQRT/SIN/COS/LOG report the contiguity their kernel asserts (split out of the NONE/VIEW/PERMUTE... group, which stays true). - ggml_opt_alloc: before anything is allocated, every compute node of a training graph must be supported by the device backend; a "no" refuses the job with the op, node and source named (ggml_opt_refusal). Inference keeps its fallback; only a training graph turns supports_op's "no" into a refused job (Cormac's shape: supports_op stays the ONE place that knows). - llama_opt_failure carries the reason; server-train reports it instead of "did not fit in device memory". - ggml_acc_or_set: a viewed gradient (a slice of a fused QKV) is accumulated from a contiguous copy, so the VIEW backward stays on the device. The new check found this: it had been running through the CPU fallback. 0.8B qwen35 (unsloth/Qwen3.5-0.8B-GGUF): - without the L2/ACC rule fixes, the job refuses with "the training graph has a node CUDA0 cannot run: ACC 'grad for Qcur-23' ..." and then "SQR ... on 'k_conv-22' (a non-contiguous view)"; /health stays ok throughout - with them, it trains on the GPU, no refusal (loss 0.5924) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q4NU4VNiELPQfBpCacDZGc
|
APPROVED at 9652942. This is the shape we agreed on: supports_op stays the one place that knows (SQR/SQRT/SIN/COS/LOG now report the contiguity their kernel asserts, and CLAMP keeps its unconditional yes), and ggml_opt_alloc turns a device 'no' into a refused JOB before allocating, naming the op, node and source, carried through llama_opt_failure to /train's error. ggml_acc_or_set copies a viewed gradient, and skips the copy where grad_accs requires in-place accumulation. Correct. The supports_op change is also a strict win for inference: those ops on a view now fall back instead of asserting. One check before it reaches every node: the refusal is broader than the old behaviour. A training graph with ANY op the GPU doesn't implement used to run with that op on the CPU; now the whole job is refused. Please run the configs that trained before (the 1.5B parity set, and the 0.8B at both depths, which you have) and confirm none is now refused. A previously-working graph turned into a refusal would be a regression that reads as safety. |
…s the job, not the server (#4819) CambrianTech/llama.cpp#35 (approved by Cormac): CUDA supports_op reports the contiguity SQR/SQRT/SIN/COS/LOG kernels assert, and ggml_opt_alloc refuses a training graph with any node the device backend cannot run, before allocating, with the op and node named in the /train error. On the 5090 such a node aborted Kimi's serving process. The VIEW backward also accumulates a viewed gradient from a contiguous copy, so it stays on the GPU. Measured: the 0.8B qwen35 job refuses with the node named while /health stays ok, and trains on the GPU once the rules are fixed. The 1.5B parity sets still train unchanged (eval 0.511 -> 0.241 -> 0.217; 0.496 -> 0.285 -> 0.174). Claude-Session: https://claude.ai/code/session_01Q4NU4VNiELPQfBpCacDZGc Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…end-can-run train: refuse only a node NO scheduler backend can run (fix the Metal regression from #35)
Why:
/trainon a qwen35 model aborted the serving process from inside a CUDA kernel (unary.cu, SQR on a viewedk_conv, 5090 2026-10-06). CUDAsupports_opreturned true unconditionally for SQR/SQRT/SIN/COS/LOG while those kernels assert a contiguous src0, and the scheduler trusted it.Changes:
supports_op: SQR/SQRT/SIN/COS/LOG report the contiguity their kernel asserts. They're split out of the NONE/VIEW/PERMUTE/… case group, which stays true.ggml_opt_allocrefuses the job: before anything is allocated, every compute node of a training graph must be supported by the device backend. A "no" refuses the job with the op, node and source named (ggml_opt_refusal).supports_opstays the one place that knows (Cormac's shape).llama_opt_failurecarries the reason, andserver-trainreports it instead of "did not fit in device memory".ggml_acc_or_set: a viewed gradient (a slice of a fused QKV) is accumulated from a contiguous copy, so the VIEW backward stays on the device. The new check found this: it had been running through the CPU fallback.Measured, 0.8B qwen35 (
unsloth/Qwen3.5-0.8B-GGUF):the training graph has a node CUDA0 cannot run: ACC 'grad for Qcur-23' …, thenSQR … on 'k_conv-22' (a non-contiguous view)Remaining sweep (Fable): other backward rules that apply a unary op straight to a view (sin/cos, abs, relu, exp, swiglu's silu). This check now names each one as a refused job instead of a crash.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Q4NU4VNiELPQfBpCacDZGc