Warn if Linux automatic NUMA balancing is enabled at buffer init#644
Warn if Linux automatic NUMA balancing is enabled at buffer init#644toffee-desuwa wants to merge 3 commits into
Conversation
I tested on my node with: funclatency-bpfcc -d 60 -m -p 347328 task_numa_work Result: 0 -> 1 ms : 4 So on this run I did not reproduce the high task_numa_work overhead from #624. The overhead was negligible for this PID/workload. |
|
Thanks for actually running the numbers, @alpha-baby. A real measurement beats hand-waving, so this is a useful data point. One thing to clear up: the 16+ms figure isn't mine — it's from the trace in #624 (different kernel and workload from yours). The warning says "can add up to" on purpose; it's not claiming NUMA balancing is always slow. task_numa_work only costs anything when a process actually triggers NUMA page scanning, so it's very workload- and topology-dependent. The warning is based on that report rather than my own GPU runs. Your 4 hits in 60s vs #624's 139 is about a 35x gap, which usually means the process just wasn't doing much cross-NUMA scanning during the trace. Two questions so we're comparing the same thing: Was your run-pipe process actually doing DeepEP internode/intranode dispatch while you traced it? #624's overhead is specific to that comm hot path — if it wasn't, few task_numa_work hits is exactly what you'd expect. What's the NUMA topology (sockets, does the model span NUMA nodes, cores pinned)? When memory doesn't cross NUMA boundaries, task_numa_work has nothing to do. If overhead stays negligible even under a real internode-dispatch workload, that's genuinely worth knowing — it'd mean the warning should be narrowed (e.g. gated to specific kernels) rather than shown broadly. Happy to adjust based on what you find. |
|
During the monitoring period of funclatency-bpfcc, DeepEP internode was being called frequently. We did not pin the LLM training processes to specific NUMA nodes. |
|
That answers both questions clearly — thanks. So: real internode dispatch, no NUMA pinning, and still negligible overhead. That's a strong counter-example. The remaining variable is kernel version: you're on 5.10, while #624 was on 5.15 (NUMA balancing behavior changed meaningfully around 5.12+). But regardless of root cause, a warning that fires on setups where the overhead is near-zero isn't useful. I'll narrow the check — likely gate it on kernel version or downgrade to a one-time info log instead of a warning. Will push an update. |
A contributor tested with frequent DeepEP internode dispatch on a 5.10 kernel (no NUMA pinning, numa_balancing=1) and observed negligible overhead (4 hits/60s vs 139 in issue deepseek-ai#624 on 5.15). - Replace "can add up to 16+ ms" with "can add milliseconds of tail latency on some kernel versions and workloads" - Change "Disable with" to "If you observe unexpected latency spikes, consider:" - Add the counter-example to README for context Trigger condition (numa_balancing != 0) and warning level (RuntimeWarning) unchanged. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
@alpha-baby Pushed an update based on your findings — thanks again for the data. Dropped the "16+ ms" claim, now says "milliseconds of tail latency on some kernel versions and workloads", and changed "Disable" to "If you observe unexpected latency spikes, consider:". Also kept the README consistent. Trigger logic and warning level unchanged. |
|
This issue is not a low hanging fruit for Claude Opus. |
|
@wenjianhn Fair point. The check is just reading a sysctl flag — pretty surface-level. You wrote the original trace in #624, so you probably know what actually causes the overhead. |
Sorry, I don't know why I can't reproduce this problem in my environment. |
|
See #624 (comment) |
|
Thanks, that explains it. So the real variables are memory size and thread busyness, not kernel version — the kernel hands the scan work to whichever thread is busy, and bigger memory means longer page-table walks. That's also probably why @alpha-baby didn't hit it. My kernel-version guess was wrong. I'll update the warning text and README to say this, instead of the vague "some kernel versions and workloads". |
Per wenjianhn's root-cause explanation in deepseek-ai#624: the kernel hands task_numa_work to busy threads, and the per-scan cost grows with process resident memory. A dispatch thread at 100% CPU inside a process holding hundreds of GB is the worst case. Replace the earlier kernel-version framing (a red herring) with this mechanism in both the warning text and the README. Co-Authored-By: Claude <noreply@anthropic.com>
|
Pushed d389e22 — the warning and README now describe the busy-thread + memory-size mechanism instead of the kernel-version guess. Thanks @wenjianhn. |
Summary
Adds a startup-time warning when
/proc/sys/kernel/numa_balancing != 0, plus a new## Performance gotchassection in the README documenting the mitigation. Fixes #624.Background
@wenjianhnreported in #624 that Linux automatic NUMA balancing (kernel.numa_balancing != 0, default on most 5.x kernels) periodically rewrites PTEs at the user/kernel boundary viatask_numa_work, which is directly visible on thedeep_ep::Buffer::internode_dispatchhot path.funclatency -d 60 -m -p <pid> task_numa_workover 60 s on an SGLang workload:139 invocations in 60 s, with 2 samples reaching the 16-31 ms bucket — added directly to the EP critical path.
Change
deep_ep/__init__.py: newcheck_numa_balancing()helper, called betweencheck_nccl_so()andinit_jit()in the existing init block. Mirrors thecheck_nccl_sopattern (env-var suppress, silent skip on non-Linux, single warning emit).kernel.numa_balancingis a bitmask, so the check isvalue != '0'(covers modes 1, 2, and OR-ed combinations, all of which runtask_numa_work).README.md: new## Performance gotchassection documenting the issue and thesysctl kernel.numa_balancing=0mitigation, plus anEP_SUPPRESS_NUMA_CHECKentry in the env var listing.The check is opt-out via
EP_SUPPRESS_NUMA_CHECK=1for CI / containerized environments where the user cannot toggle the sysctl.Validation
kernel.numa_balancingis non-zero:kernel.numa_balancing=0:EP_SUPPRESS_NUMA_CHECK=1:/proc/sys/kernel/numa_balancing):OSErrorcaught silently.python -m py_compile deep_ep/__init__.pypasses;git diff --checkclean; file is excluded from the repository ruff target so no lint conflicts.