Three fixes for the three bugs in latest docker log:
1. corex_gdn.py REWRITTEN — interface now matches qwen3_5.py:
OLD: CoreXGDN(num_heads, head_dim, layer_idx, chunk_size, eps)
NEW: CoreXGDN(num_v_heads, num_k_heads, head_k_dim, head_v_dim, conv_kernel_size, layer_idx)
OLD forward: (q, k, v, gate, beta, conv_state, temporal_state, attn_metadata)
NEW forward: (hidden_states, attn_metadata, conv_state, temporal_state,
in_proj_qkv, in_proj_z, in_proj_b, in_proj_a,
conv1d_weight, A_log, dt_bias, norm, out_proj)
Fixes: 'CoreXGDN.__init__() got unexpected keyword argument num_v_heads'
2. serving_chat.py — engine death protection for multimodal:
When model has no multimodal_config, return 400 instead of passing image data
to engine (which causes permanent AsyncEngineDeadError).
Fixes: 'ValueError: You set image=0 but found 1 items'
3. patch_ops.sh — ALWAYS deploy our modules (base image has bugs):
- qwen3_5.py: ALWAYS deploy (base has NaN)
- corex_gdn/moe/fa2.py: ALWAYS deploy (base interface mismatch)
- corex_fa2.py was MISSING from base → now deployed
Reverted the NO-FALLBACK rewrite of corex_gdn.py and qwen3_5.py.
Policy: do NOT rewrite modules that already exist in base image or
upstream_ref. If an interface doesn't match, fix the interface call
site — don't rewrite the entire module in pure PyTorch.
Base image has corex_gdn.py, corex_moe.py, corex_fa2.py with C++
backends. The right approach is to match their __init__ signatures,
not replace them with slower Python reimplementations.
Root cause from latest docker build log:
ValueError: You set image=0 in --limit-mm-per-prompt, but found 1 items
→ Engine background task crashes → AsyncEngineDeadError → all subsequent 503
Fixes:
1. computility-run.yaml: add --limit-mm-per-prompt image=1
Prevents multimodal ValueError from killing the engine process.
2. patch_ops.sh: DON'T overwrite base image's corex_gdn.py/corex_moe.py
Comp 168 log proves base image's corex modules work with libcorex_gdn.so.
Our overwrite broke CoreXGDN.__init__ (unexpected kwarg 'num_v_heads').
Only deploy ours if base has NO corex modules at all.
Also deploy corex_fa2.py if base lacks it.
3. qwen3_5.py: try multiple CoreXGDN init signatures
Base image CoreXGDN may accept different kwargs than ours.
Try kwargs form first, fall back to positional.
4. corex_gdn.py: accept both calling conventions in __init__
Future-proof for when we DO need to deploy ours.
5. Copied upstream_ref headers: ilu_layer_fused_moe.h, ilu_layer_attention.h
Last 2 missing ILU files from xllm. All 14/14 now present.
- ix_bridge.py: auto-discover ixformer .so files, pass as extra_ldflags
- ix_moe_bridge.cpp: fix mangled header from bad sed, add #include <optional>
- verify_single_gpu.py: also pass extra_ldflags during JIT compile
The undefined symbol _ZN8ixformer5infer12silu_and_mulERN2at6TensorES3_
lives in libixformer.so — need to explicitly link it.
corex_moe.py: moe_forward now accepts both formats:
Format A: w1(E,I,H) + w2(E,H,I) + w3(E,I,H) — xllm style, separate gate/up
Format B: w13(E,2*I,H) + w2(E,H,I) + w3=None — vllm style, merged gate_up
Auto-detects by checking if w3 is None, splits w13 internally.
qwen3_5.py:
- Fix corex_moe call: use keyword args (w3=None, topk=self.top_k)
prevents topk integer going to w3 tensor position
- Remove silent fallback on corex_moe failure — raise RuntimeError
with full shape info for diagnosis. Zero score with no error log
is worse than a crash.
moe_topk_softmax_v3.cu: BI-V100 verified (2026-08-10)
- 64 experts, topk=8, warp shuffle, zero shared memory
- renormalize: sum=1.0 ✓, no NaN ✓, no duplicate ids ✓
- 881 token batch ✓
- Compiler: corex clang/16, --cuda-gpu-arch=ivcore10
- Stream: c10::cuda::getCurrentCUDAStream()
corex_moe.py: loads CUDA kernel, NO Python fallback
- Searches pre-compiled .so → JIT compile from source → error
- MoE pipeline: CUDA topk → cublas expert GEMM → ixformer silu_and_mul
precompile_moe_topk.py: Docker build-time compilation + verification
Key finding from real machine probing:
ixformer::infer::topk_softmax is DECLARED in ixformer.h but
NOT IMPLEMENTED in any .so in the base image (nm -D scan: zero hits).
Must compile our own kernel.
1. ix_bridge.py: RuntimeError instead of silent PyTorch fallback
If JIT compile fails, crash immediately with diagnostic message.
0 score with no error log is worse than a visible crash.
2. qwen3_5.py: explicit WARNING log on import failure (not silent)
Shows exact error so we can diagnose from docker log.
3. probe_ixformer_symbols.py: definitive test for real machine
- Finds all ixformer .so files
- nm/objdump for topk_softmax C++ symbol
- Checks Python bindings
- Attempts JIT compile + link (the real test)
- Prints PASS/FAIL with next-step instructions
Run on real machine: python3 probe_ixformer_symbols.py