feat: support Ktransformers, CPU-GPU MoE offload via FusedMoE layer - #548
feat: support Ktransformers, CPU-GPU MoE offload via FusedMoE layer#548whjthu wants to merge 1 commit into
Conversation
42acd99 to
e73c49d
Compare
Codex review结论:Request changes。当前 KT 路径能在部分模型上完成初始化和生成,但存在跨模型污染、未校验的并行配置、dtype 静默错误,以及已实测的模型兼容性/正确性失败,暂不建议合入。 Blocking findings
Validation matrix环境:
三组多模态均通过 Current usage constraints当前没有 CLI 开关。使用者需要在构造 建议合入前至少补充:callback ownership/lifecycle、TP/EP/device/dtype 强校验、DeepSeek/Qwen3-Next 正确性修复,以及覆盖双模型同进程、非 KT 回归和各支持架构的自动化测试。 — Codex |
Summary
Q4_K_MGGUF) while attention / router / shared-experts stay on GPU, enabling models larger than VRAM (e.g. 80B on a 48GB L20).csrc/layers/moe/kt_moe_callback.hpp(new): per-layer callback registry; lock-free invocation (callback copied out under mutex, executed GIL-safe), TOCTOU-freeget().csrc/layers/moe/fused_moe.{hpp,cpp}: KT dispatch atforward()entry; dispatcher/runner construction skipped underuse_kt_moe; explicit error when the flag is set but no callback is registered for the layer.csrc/layers/moe/experts/fused_moe_experts.cpp: skipw13/w2GPU weight allocation underuse_kt_moe.csrc/models/deepseek_v2/deepseek_v2_moe.{hpp,cpp}(+ both deepseek decoder layers): model-level KT branch for the dedicateddeepseek_moekernel path (not built onFusedMoE), with atensor_parallel_size > 1guard.csrc/pybind11/bindings.cc:_infinilm.set_kt_moe_callback/clear_kt_moe_callbacks, Python exception translation at the GIL boundary, capsule cleanup at interpreter shutdown.python/infinilm/kt_integration.py(new): performance-tuned callback setup — persistent staging buffers,cudaMemcpyAsyncvia ctypes on the default stream, double-buffered output snapshot (KT reuses its internal output buffer across calls), prefill capacity guard, rollback on partial registration,enable_graphcompatibility check.python/infinilm/modeling_utils.py: skip routed-expert weight keys and scopecheck_parametersto non-expert keys underuse_kt_moe(safetensors and.binpaths).MoE models built on
FusedMoE(qwen3_moe,qwen3_next) require zero model-level changes for KT support.Motivation
MoE models whose routed-expert weights exceed GPU VRAM cannot be served at all today (e.g. Qwen3-Next-80B-A3B ≈ 45GB in INT4 vs 46GB L20, plus attention/KV overhead). KT-style CPU offload is the established deployment pattern for such models (KTransformers, sglang-kt). This PR brings that capability to InfiniLM with a minimal, non-invasive hook at the common
FusedMoElayer, keeping parity with SGLang+KT throughput on the same hardware (see Benchmark section).Type of Change
feat— new feature / new modelfix— bug fixperf— performance improvement (no behavioral change)refactor— code restructuring without behavior changetest— adding or fixing tests onlydocs— documentation onlybuild/ci— build system or CI configurationchore— tooling, formatting, or other non-code changesuse_kt_moedefaults tofalse; all pre-existing paths are unchanged when the flag is unset.Test Results of Involved Models on Supported Platforms (Please attach screenshots)
KT offload requires an external
kt-kernelinstall plus an INT4 GGUF, which the four standard tests do not exercise (they run the native GPU path). Verified instead with dedicated end-to-end scripts on L20:mainbaselineBenchmark / Performance Impact
Stress matrix vs SGLang+KT (sglang-kt 0.6.4 server, same machine, same INT4 GGUF, same 8 CPU threads, experts all on CPU), Qwen3-Next-80B-A3B:
Soak (B=32, N=512, ×3): SGLang 196.1 ± 0.3 vs InfiniLM 177.3 ± 0.3 (both stability 1.003). Remaining gap concentrates at low concurrency (SGLang CUDA-graph + overlap-scheduler advantage); at production-level concurrency (B≥32) the two engines are within 2–9%.
Methodology: 1 warmup request, then wall-clock over concurrent batch; aggregate tokens/s counted from actual
completion_tokens.Notes for Reviewers
fix/qwen3-next-layer-idx(decoder layer dropslayer_idx, all 48 layers construct as layer 0). Please merge that first;qwen3_moeanddeepseek_v2are unaffected by that bug.kt-kernel==0.6.4from PyPI; integration is via its publicKTMoEWrapperAPI only (same API surface SGLang uses).enable_graph=Trueis rejected bysetup_kt_moe(CUDA-graph capture executes the Python callback); single GPU /tensor_parallel_size=1only (DSV2 path throws otherwise); staging buffers bound InfiniLM-side max prefill batch (guarded with a clearRuntimeError, not silent corruption).MoeQuantMethod), GPU/CPU expert parallel execution inside one layer (SGLang-style cpu_stream overlap),ernie4_5_vladaptation.CI / ChatOps
CI will be triggered manually from the Actions tab on this branch after the PR is opened.
Checklist
Title, Branch, and Commits
feat(nvidia): …,fix(cuda/gemm): …).<type>/xxx-yyyy-zzzzwhere<type>matches the PR title's Conventional Commits type and words are joined with hyphens (seeCONTRIBUTING.md§Branches).CONTRIBUTING.md§Pull Requests).main— the branch is rebased cleanly on top of the currentmain.fixup!/squash!/wipcommits remain.Scope and Design
CONTRIBUTING.md§Code/General).printf/std::cout/print(...)left behind, orTODOwithout an owner and issue link.General Code Hygiene (applies to all languages)
CONTRIBUTING.md§Code/General).CONTRIBUTING.md§Code/General).the `seqlens_k` tensor) (CONTRIBUTING.md§Code/General).CONTRIBUTING.md§Code/General).CONTRIBUTING.md§Code/General; §Python).C++ Specific (if C++ files changed)
CONTRIBUTING.md§C++).CONTRIBUTING.md§C++).new/delete; RAII / smart pointers / existing allocators are used.scripts/format.py(clang-format-16, same version as CI; re-verified build + 30B E2E regression after formatting).csrc/models/llama_legacy/.Python Specific (if Python files changed)
CONTRIBUTING.md§Python).CONTRIBUTING.md§Python).scripts/format.py(black; re-verified syntax + E2E regression after formatting).python/infinilm/auto_config.py.Testing
examples/test_infer.py), or specify the reason for skipping.examples/bench.py), or specify the reason for skipping.test/bench/test_benchmark.py), or specify the reason for skipping.python/infinilm/server/inference_server.py+scripts/test_perf.py), or specify the reason for skipping.Build, CI, and Tooling
/retestwas requested.Documentation
README.md,CONTRIBUTING.md, or inline docs updated when behavior, build flags, or developer workflow changed.!orBREAKING CHANGE:footer.Security and Safety