Commit Graph

12 Commits

Author SHA1 Message Date
project6
17720b5386 arch(core): translate CCCL cc_dispatch.cuh entire design into _HardwarePolicy
cc_dispatch.cuh is CCCL's runtime-hardware → compile-time-policy bridge:
  1. Detect device compute_capability at runtime
  2. policy_selector(cc) returns full kernel config
  3. lowest_cc_resolver merges identical policies across CCs
  4. dispatch_compute_cap bridges runtime → compile-time specialization

Translated as _HardwarePolicy class in qwen3_5.py:
  1. detect() probes BI-V100 capabilities once (SMEM, cuSOLVER, MoE ops)
  2. Returns deltanet_chunk_size, solve_triangular_available, moe_native_*
  3. All kernel code reads from _hw_policy instead of hardcoded constants
  4. MoE forward skips native attempt if hasattr() shows ops missing

Concrete changes:
  - DeltaNet chunk_size: hw_policy-selected (64 if solve_tri, 32 if not)
  - _forward_sub_lower: no per-call try/except, uses pre-detected flag
  - _DNN_CHUNK: reads from hw_policy
  - MoE native: hasattr() pre-check avoids exception on every layer init

CCCL source: cub/cub/detail/cc_dispatch.cuh (full file translation)
Maps to: qwen3_6_scripts/qwen3_5.py
2026-08-07 09:08:22 +00:00
project6
32fdae237a perf(moe): CCCL basic_vector pattern — batch GPU→CPU sync in segment detection
thrust basic_vector.cu: device→host copy is batched (D = H, one memcpy).
Our MoE segment loop did int() per iteration — N separate GPU→CPU syncs.
Fix: .tolist() does ONE sync for all segment boundaries.

Maps to: qwen3_6_scripts/qwen3_5.py (_pure_pytorch_experts prefill path)
2026-08-07 09:03:12 +00:00
project6
86ca125b47 perf(deltanet): CCCL block_scan_raking pattern — replace Python loop with solve_triangular
CCCL block_scan_raking.cuh: parallel prefix scan over C elements using
GPU-native raking threads, not sequential host-driven loops.

Our _forward_sub_lower was a Python for-loop over chunk_size=64 rows,
each launching a separate matmul kernel. This is 64 sequential kernel
launches per DeltaNet layer per chunk.

Fix: Use torch.linalg.solve_triangular (cuBLAS trsm) which solves
the entire (I-A)@X=RHS system in ONE kernel launch. Falls back to
the Python loop if cuSOLVER is unavailable on BI-V100.

CCCL source: cub/cub/block/specializations/block_scan_raking.cuh
Maps to: qwen3_6_scripts/qwen3_5.py (_forward_sub_lower)
2026-08-07 08:57:51 +00:00
project6
a1558b6e50 fix(critical): CCCL policy_selector degradation for MoE — PyTorch fallback for topk_softmax
CCCL tuning_radix_sort.cuh teaches: when one kernel in a chain is unavailable,
replace ONLY that kernel while keeping downstream native ops alive.

Our MoE chain: topk_softmax → moe_align_block_size → invoke_fused_moe_kernel
BI-V100 ixformer lacks vllm_moe_topk_softmax, which killed the ENTIRE chain
and forced 100% PyTorch fallback (_pure_pytorch_experts: 256x F.linear loop).

Fix: Add try/except in topk_softmax with PyTorch fallback (softmax+topk).
Now the chain can proceed to native align+invoke kernels if they exist.
Also: dont permanently disable native path after first failure — retry once.

CCCL source: catch2_test_device_radix_sort_pairs.cu + tuning_radix_sort.cuh
Maps to: _custom_ops.py (topk_softmax) + qwen3_5.py (MoE forward)
2026-08-07 08:56:50 +00:00
project6
5a3bcbc247 fix(engine): CCCL overflow_cast + checked_allocator patterns for NaN/OOM
CCCL overflow_cast.h pattern applied to qwen3_5.py:
- Prefill gate: A_log.float().clamp(-20,20).exp() prevents NaN cascade
- Decode gate: same clamp before exp (was unprotected, unlike prefill path)
- Decode g_t: clamp_(-20,20) before in-place exp_() (was raw exp_())
  Docker logs show 99.98% NaN in GatedDeltaNet layers — these unprotected
  exp() calls are the root cause.

CCCL checked_allocator.cuh pattern applied to model_runner.py:
- Wrap model forward in try/except torch.cuda.OutOfMemoryError
- On OOM: empty_cache + gc.collect + retry once
- Competitor Sub168 died permanently at layernorm x.float() OOM
  during replay (docker log evidence). This recovery keeps server alive.

Source: cccl_upstream/libcudacxx/include/cuda/__numeric/overflow_cast.h
Source: cccl_upstream/c2h/include/c2h/checked_allocator.cuh
2026-08-07 08:56:36 +00:00
Claude
840fe923cc fix(critical): DeltaNet NaN 99.98% — clamp gate logits before exp to prevent overflow
Docker log reveals: 'NaN in prefill GatedDeltaNet layer 0 (frac=0.9998)'
Every DeltaNet (linear attention) layer produces 99.98% NaN values.
nan_to_num replaces them with zeros, destroying model output quality.
This is the root cause of d10_thinking_disable_ctk gibberish output.

Root cause: g.cumsum(dim=-1) accumulates unbounded gate logits.
When fed to exp(), large values overflow to Inf, which propagates
as NaN through subsequent matmul and forward_sub operations.

Fix: Clamp cumulative gate logits to [-20, 20] before any exp().
Range keeps exp in [~2e-9, ~5e8] — safe for float32 accumulation.
Inspired by CCCL dispatch_reduce_deterministic.cuh: numerical
stability requires bounded intermediate values (RFA pattern).

Also in this log:
- FusedMoE: 'vllm_moe_topk_softmax' not in ixformer → PyTorch fallback
  (expected, cannot fix without BI-V100 kernel rebuild)
- OOM at end of sub168: 31.72 GiB GPU with 30.86 GiB allocated

CCCL input: dispatch_reduce_deterministic.cuh RFA pattern,
tuning_batch_memcpy.cuh (small=128t×4buf, large=256t×32B)
2026-08-07 08:37:48 +00:00
muh-bot
bf5d19991c [FIX] qwen3_5.py: replace solve_triangular with manual forward substitution
BI-V100 base image does not have libcusolver.so at:
  /opt/sw_home/local/cuda/lib64/libcusolver.so

torch.linalg.solve_triangular requires cuSOLVER which is missing.
Replace with row-by-row forward substitution using only basic
matmul and indexing ops (torch.zeros_like, matmul, indexing).

The linear_attention gated_delta_rule solves (I-A)@X=RHS where A
is strictly lower-triangular. Forward sub: x[0]=rhs[0],
x[i]=rhs[i]+A[i,:i]@x[:i]. Mathematically equivalent.
2026-08-06 03:02:29 +00:00
Claude
6d0965195c [CCCL-PORT] Try native FusedMoE kernel before PyTorch fallback
CCCL source read: cub/device/dispatch/dispatch_reduce_by_key.cuh
  - DeviceReduceByKey sorts input by key, pads to tile boundary, then
    one fused kernel processes all key-value segments in parallel.
  - This is architecturally identical to base engine's fused_moe.py:
    moe_align_block_size (sort+pad) → invoke_fused_moe_kernel (one launch).

Discovery: _custom_ops.py (line 776-806) confirms ixformer HAS native MoE:
  - ixf_F.vllm_moe_topk_softmax
  - ixf_F.vllm_moe_align_block_size
  - ixf_F.vllm_invoke_fused_moe_kernel (takes only BLOCK_SIZE_M config)

Previous code assumed 'ixformer lacks MoE kernels' and used _pure_pytorch_experts
(Python for-loop over 256 experts). This may have been wrong or outdated.

Change: MoeSparseBlock.forward now tries self.experts (FusedMoE native) first.
If the native kernel fails on BI-V100, it catches the exception, logs a warning,
and permanently falls back to _pure_pytorch_experts for that instance.

Impact if native works: one fused CUDA kernel vs 256× F.linear calls = massive
decode speedup. Impact if native fails: same behavior as before (fallback).
2026-08-05 08:31:34 +00:00
Claude
10af71357b [CCCL-PORT] Two architecture-level optimizations from CCCL system design
Source CCCL files read as input:
  - cub/block/block_scan.cuh (RAKING algorithm concept)
  - cub/device/dispatch/dispatch_reduce.cuh (GridEvenShare, two-pass)
  - cub/agent/agent_reduce.cuh (vectorized vs scalar load paths)
  - thrust/examples/histogram.cu (sort + reduce_by_key pattern)
  - thrust/examples/scan_by_key.cu (keyed scan for state propagation)

Optimization 1: DeltaNet chunk kernel — solve_triangular replaces for-loop
  63 Python iterations → 1 CUDA kernel (lower-triangular system solve)

Optimization 2: MoE prefill — sort tokens by expert_id for contiguous gather
  CCCL histogram pattern: sort → segment → batched process
2026-08-05 08:20:01 +00:00
Claude
c5a0d61851 sync: align with enginex-vllm-bi100-qwen36 baseline (1902c81f)
Synced files from EngineX baseline zip (2026-06-30):
- ADD paged_attn.py (root): production paged attention with PyTorch fallback
- ADD launch_service: BI-V100 server startup script with env configuration
- SYNC computility-run.yaml: gpu_memory=0.9, batched_tokens=8192, seq_capture=32768
- SYNC qwen3_6_scripts/paged_attn.py: +311 lines, Triton bypass docs, _forward_decode_pytorch shape docs
- SYNC qwen3_6_scripts/qwen3_5.py: -72 lines, revert optimized MoE prefill to baseline (untested on BI-V100)
- KEEP Dockerfile: repo version has V2/Triton/head256 optimization patches not in baseline

Baseline commit: 1902c81fdd373943f17f5983eb8750758c7f4a69
Source: enginex-vllm-bi100-qwen36-main.zip (dev.modelhub.org.cn)
2026-07-31 09:43:58 +00:00
dylanyunlon
7ad59e781f [OPT] MoE prefill: sorted-token grouped GEMM (contiguous per-expert access)
Qwen3.6-35B-A3B has 256 experts × top_k=8. The baseline prefill MoE:
  for eid in unique_eids:  # up to 256 iterations
      tokens = hidden_states[tok_ids]  # SCATTERED gather
      F.linear(tokens, w13[eid])

Problem: hidden_states[tok_ids] creates a non-contiguous gather for each expert.
With 16384 tokens × 256 experts, this is 256 scattered gathers per layer.

Optimization (CCCL segmented-sort pattern):
  1. Flatten all token-expert pairs: (T×K,) assignments
  2. Sort by expert ID: tokens for same expert become CONTIGUOUS
  3. Each F.linear gets contiguous input → much better memory access
  4. Activation (silu × up) computed in ONE fused op across all pairs
  5. index_add_ scatter-back is one kernel call

Memory access improvement:
  Before: 256 × hidden_states[random_indices] → scattered HBM reads
  After:  sorted_tokens[start:end] → sequential HBM reads per expert

The expert loop still exists (can't batch variable-size GEMMs with F.linear),
but each iteration reads contiguous memory instead of scattered indices.
2026-07-30 16:12:42 +00:00
dylanyunlon
ef6abf3dc7 [DEPLOY] Complete submission: baseline + all optimizations
Adds ALL files needed for Dockerfile build:
  - qwen3_6_scripts/ (baseline patches + our optimizations)
  - vllm/ (full vllm package)
  - paged_attention_v2_pytorch.py (V2 with single-bmm optimization)
  - Dockerfile + computility-run.yaml

Our optimizations vs baseline:
  1. paged_attn.py: pre-gathered context KV (eliminates 194 gather calls),
     Triton try/fallback, V2 heuristic, threshold 32K→64K
  2. paged_attention_v2_pytorch.py: fills NotImplementedError,
     single-bmm Phase 1 (195 launches → 3)
  3. patch_enable_triton.py: HAS_TRITON=True with safety fallback
  4. patch_triton_tuning.py: BLOCK=64, NUM_WARPS=4 for BI-V100
  5. computility-run.yaml: gpu-memory-utilization 0.9→0.95,
     max-num-batched-tokens 8192→16384

This repo can now be submitted to dev.modelhub.org.cn as-is.
2026-07-30 16:06:20 +00:00