Skip to content

op_builder: make JIT compile robust to non-curated conda envs - #143

Draft
Andrewxu313 wants to merge 1 commit into
tairan/deepseek-v4-flashfrom
tairan/jit-env-robustness
Draft

op_builder: make JIT compile robust to non-curated conda envs#143
Andrewxu313 wants to merge 1 commit into
tairan/deepseek-v4-flashfrom
tairan/jit-env-robustness

Conversation

@Andrewxu313

Copy link
Copy Markdown
Contributor

Summary

The default torch.utils.cpp_extension.load() invocation in OpBuilder.jit_load() fails out-of-the-box on any conda env that wasn't pre-blessed for BatchGen. We hit six distinct failure modes installing v1.0.9.post5 on a Gemini-cluster H20 node (Tencent IDC):

# Error Root cause
1 libc10.so: cannot open shared object file conda activate doesn't add <torch>/lib to LD_LIBRARY_PATH
2 __nvJitLinkCreate_12_8 undefined symbol torch's cusparse.so links against newer nvJitLink than the system one
3 cuda.h: No such file or directory conda compiler's sysroot has no CUDA headers
4 numa.h: No such file or directory conda compiler's sysroot has no libnuma headers (numa.h is in $CONDA_PREFIX/include, just not on path)
5 unsupported GNU version! gcc later than 12 are not supported conda env defaults to gcc-14, CUDA 12.x nvcc caps at gcc-12
6 cannot find -lnuma hardcoded -L<env>/lib/stubs doesn't include targets/x86_64-linux/lib where the libnuma symlink lives in conda CUDA bundles

This patch makes jit_load() resilient to all six without changing behaviour on the curated H20 envs (every change is a prepend, idempotent, and skipped if the dir doesn't exist — so it's a no-op when the right paths are already wired up).

What changed

op_builder/builder.py — new OpBuilder._augment_jit_env(), called from jit_load() just before torch.utils.cpp_extension.load:

  • Prepends <torch>/lib + every <site-packages>/nvidia/*/lib to LD_LIBRARY_PATH (fixes 1, 2)
  • Prepends $CUDA_HOME/include and $CONDA_PREFIX/include to CPATH (fixes 3, 4)
  • Prepends $CONDA_PREFIX/{targets/x86_64-linux/lib,lib} to LIBRARY_PATH (helps 6)
  • If host gcc major > nvcc's supported max, searches peer conda envs for a compatible compiler and uses it via -ccbin + -allow-unsupported-compiler in NVCC_PREPEND_FLAGS (fixes 5)

op_builder/core_engine.pyextra_ldflags() now adds $CONDA_PREFIX/targets/x86_64-linux/lib and $CONDA_PREFIX/lib in addition to lib/stubs (fixes 6 — the linker invocation itself).

Validated on Gemini node-1 (8× H20, conda env batchgen with gcc-14, peer ray env with gcc-11)

Before this patch: from batchgen import launch_http_server fails through six rounds of env patching, each surfacing a new failure mode.

After this patch: same import succeeds in ~84 s of JIT compile, core_engine.so is cached, subsequent invocations are instant.

Test plan

  • Confirm H20-Node1 (curated env) launch is unaffected — re-run bash scripts/run_test.sh glm5 L1 and verify same outcome
  • Confirm Gemini node-1 launch now works without an env-wrapper script — python -m batchgen.launch_http_server ... should succeed after just pip install of the v1.0.9.post5 wheels
  • Confirm on a CPU-only / non-Hopper conda env that _augment_jit_env is still safe (no AttributeError on missing CUDA paths)
  • Run tests/test_deepseek_v4_flash_reference.py after JIT compile to confirm we haven't regressed parity

Notes

  • All path additions check os.path.isdir before adding, so this is safe to run on machines with partial / non-conda envs.
  • The _find_peer_compatible_cc lookup walks $CONDA_PREFIX/../*/bin/x86_64-conda-linux-gnu-cc — this is the standard conda envs layout, so should hit on most setups. If no peer is found, we still set -allow-unsupported-compiler as a fallback.
  • This is draft because (a) we still want to confirm the H20 path is unaffected and (b) the peer-env compiler search is a heuristic that could be tightened.

🤖 Generated with Claude Code

The default torch.utils.cpp_extension.load() invocation in jit_load()
fails out-of-the-box on any conda env that wasn't pre-blessed for
BatchGen, because torch's bundled CUDA libs, the system numa.h, and
nvcc's host-compiler version checks are all left up to the user to wire
up. We hit six distinct failure modes installing on a fresh Gemini-class
H20 node (different conda env, gcc-14, no LD_LIBRARY_PATH for nvidia/*,
hardcoded -L<env>/lib/stubs without `targets/x86_64-linux/lib` for the
libnuma symlink).

This patch makes JIT mode resilient to those quirks without changing
behaviour on the curated H20 envs:

builder.py: new OpBuilder._augment_jit_env(), called from jit_load()
just before torch.utils.cpp_extension.load:

  - Prepend <torch>/lib + every <site-packages>/nvidia/*/lib to
    LD_LIBRARY_PATH, so downstream `import deep_gemm` etc. don't fail
    with `libc10.so: cannot open shared object file` or
    `__nvJitLinkCreate_12_8 undefined`.
  - Prepend $CUDA_HOME/include and $CONDA_PREFIX/include to CPATH, so
    .cpp files including <cuda.h> or <numa.h> compile against the conda
    headers (the conda compiler's sysroot has neither).
  - Prepend $CONDA_PREFIX/{targets/x86_64-linux/lib,lib} to LIBRARY_PATH
    so ld can find conda-managed libs at link time.
  - If the active host compiler's gcc major > the running nvcc's
    supported max (CUDA 12.x caps at gcc 12), search for a peer conda
    env with a compatible gcc and pass it via -ccbin, plus prepend
    -allow-unsupported-compiler to NVCC_PREPEND_FLAGS.

core_engine.py: extra_ldflags() now adds $CONDA_PREFIX/targets/x86_64-linux/lib
and $CONDA_PREFIX/lib in addition to lib/stubs, fixing
`/usr/bin/ld: cannot find -lnuma` on Gemini conda envs (libnuma is a
symlink at targets/x86_64-linux/lib/libnuma.so but not at lib/stubs).

All path additions are prepends, idempotent, and skipped if the dir
doesn't exist - so this is a no-op on H20-Node1's curated env where the
right paths are already wired up by the existing scripts/install_deps.sh.

Validated end-to-end on Gemini node-1 (Tencent IDC, 8x H20):
- pip install --force-reinstall of v1.0.9.post5 wheels (batchgen-1.0.9.post5,
  batchgen_kernels-0.3.1.post3, deep_gemm, flash_mla, flash_attn_3)
- conda env: gcc-14, peer ray env has gcc-11
- Without this patch: 6 rounds of env patching to fight libc10.so /
  numa.h / cuda.h / unsupported GNU / _Float32 / -lnuma failures.
- With this patch: `from batchgen import launch_http_server` succeeds
  in ~84 s of JIT compile and the resulting core_engine.so is cached.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

1 participant