fix(container): prevent mixed UCX linkage in SGLang arm64 runtime - #12558
Conversation
Signed-off-by: Zhuangcheng(Jesse) Gu <zcgu@connect.hku.hk>
WalkthroughThe change adds NIXL and NVSHMEM UCX layout discovery, installs validated UCX compatibility aliases, checks dependency resolution, and enables the setup in non-XPU SGLang runtime images. ChangesNIXL UCX compatibility
Estimated code review effort: 3 (Moderate) | ~25 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Comment |
|
🎯 Code Coverage (details) 🔗 Commit SHA: 003d4b6 | Docs | Datadog PR Page | Give us feedback! |
Signed-off-by: Zhuangcheng(Jesse) Gu <zcgu@connect.hku.hk>
dmitry-tokarev-nv
left a comment
There was a problem hiding this comment.
Reviewed the current head (b9f10fa) alongside DYN-3695 and the existing bot threads. The Devin findings on the not found scope and the dev/local-dev gate are already resolved, so the inline comments below are only the points not raised elsewhere.
The mechanism looks right to me: resolving the generic SONAME to the file NIXL already mapped lets glibc dedupe by (st_dev, st_ino) and reuse the existing mapping instead of creating a second UCX, and keeping the alias in the same directory to preserve $ORIGIN is the correct call — the comment explaining that is the comment a future reader needs.
Three PR-level asks beyond the inline notes:
1. Validation against the ticket's own acceptance criterion. DYN-3695 names test_sglang_serve_deployment[multimodal_epd_video_embedding_cache] (dynamo-qa) as "the only failing case in the 1.4.0-rc.0 sanity run without an owning bug." This PR verifies the linkage (NVSHMEM resolving to Ubuntu UCX 1.16 while NIXL loads its bundled 1.21), but doesn't state that the repro now returns 200 or that the QA case passes. Could you add a Validation section (also required by AGENTS.md) with that result?
2. Flag-specificity isn't explained by the stated mechanism. Mixed linkage is a static property of the image — present on every launch. DYN-3695 documents the identical launch without --multimodal-embedding-cache-capacity-gb passing on the same GB200 node. There is a plausible reconciliation — the cache path registers the domain that becomes md[1], and only that domain needs the CUDA support the mis-linked UCX lacks — but the ticket explicitly leaves root cause unestablished and prescribes the diagnostic: rerun both launches with UCX_LOG_LEVEL=debug / NIXL_LOG_LEVEL=DEBUG and diff the registered memory domains. That should settle it in one run.
Relatedly, the ucx_utils.cpp:444] UCX version is less than 1.19, CUDA support is limited line from the ticket is the strongest single piece of evidence for this fix — it is exactly what you would see if NIXL's runtime UCX were the distro 1.16 rather than its bundled 1.21. It currently lives only in Linear; it belongs in the PR body.
3. Nothing in CI will exercise this. The repro is already in-repo as tests/serve/test_sglang.py::video_e_pd_qwen (multimodal_epd.sh + --multimodal-embedding-cache-capacity-gb 0.1, pre_merge), and it runs against the runtime image this PR fixes (shared-test.yml:142 uses target_tag_plain). But pr.yaml:702,741,780 pin the GPU lanes to ["amd64"] — "No ARM GPUs available" — and the arm64 lanes are CPU-only with single-GPU tests skipped. So the failing configuration has no lane, and the build-time ldd check is the only standing regression guard. That is why the fail-open path flagged inline matters more than it first looks.
Also: DYN-3695 is tagged [release/1.4] against 1.4.0-rc.0 and this targets main — is a release/1.4.0 cherry-pick tracked anywhere?
Signed-off-by: Zhuangcheng(Jesse) Gu <zcgu@connect.hku.hk>
…elease14sglangmultimodal-embedding-cache-breaks Signed-off-by: Zhuangcheng(Jesse) Gu <zcgu@connect.hku.hk>
|
Follow-up after That single line confirms three things at once: the new I also had two things wrong, corrected in the threads above: the compat link targets On the new code itself, nothing blocking. Two things I checked that are easy to get wrong and that you got right: Three things still open, none of them code:
Process note: |
dmitry-tokarev-nv
left a comment
There was a problem hiding this comment.
posted follow ups which IMO are non-blocking. approved
|
Thanks @dmitry-tokarev-nv, added verification in PR description and opened a CP to release 1.4.0 at #12558 |
Resolves one conflict in sglang_runtime.Dockerfile. Main added a UCX alias block (#12558) in the same region where this branch scopes the media purge and the in-tree ffmpeg copy to CUDA, and both sides ended at the same `{% endif %}` -- mine closing `device == "cuda"`, main's closing `device != "xpu" and target not in (dev, local-dev)`. Kept both, each with its own conditional, rather than picking a side: the two guard unrelated things and their conditions are not equivalent. Verified by rendering sglang for cuda/runtime, xpu/runtime and cuda/dev -- the purge and codec guard appear only for CUDA, the UCX block for everything except XPU, exactly as each side intended. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Overview:
Fixes a UCX library conflict in recent SGLang runtime (
nvcr.io/nvstaging/ai-dynamo/sglang-runtime:1.4.0-rc.0, upstreamlmsysorg/sglang:v0.5.16-cu130-runtime) that causes multimodal encode-to-PD NIXL reads to fail withNIXL_ERR_BACKENDon GB200.Verified on GB200: the upstream SGLang container resolves NVSHMEM’s generic UCX dependencies to Ubuntu UCX 1.16 while NIXL loads its bundled UCX 1.21, creating an in-process UCX conflict.
Details:
nixl-cu*wheel and its auditwheel-renamed UCX libraries.libucp.so.*andlibucs.so.*aliases beside NIXL’s private libraries.$ORIGINdependency and module lookup.Validation
Validated on GB200 (aarch64) with
Qwen/Qwen3-VL-2B-Instruct, multimodal E/P/D in--single-gpumode, the defaultnixl-readembedding-transfer path, and the video from DYN-3695.With this PR's compatibility layout:
Embedding cache hit for VIDEO URL index 0, covering both the initial population and cache-hit paths.nvshmem_transport_ucx.so.3, but mapped only NIXL's UCX 1.21 core libraries and CUDA modules.NIXL_ERR_BACKENDerrors were observed.Where should the reviewer start?
container/deps/sglang/install_nixl_ucx_compat.sh— installs the aliases and validates the resulting dependency graph.container/deps/sglang/discover_nixl_ucx_layout.py— discovers the NIXL and NVSHMEM wheel layout without hard-coding CUDA versions or library paths.container/templates/sglang_runtime.Dockerfile— wires the compatibility layout into non-XPU SGLang images.Related Issues
Summary by CodeRabbit
New Features
Bug Fixes