`DEEPINFER_ENABLE_FLAGGEMS=1` turns it on. Verified on all 8 DP ranks: exit=0, 8/8 ranks agreeing, no kernel fallbacks, `hard failures: none`, correct answers. 19 ops actually dispatched, 152 call sites, 43 registrations from 37 requested names. The default is `flag_gems.only_enable(include=[...])`, not `enable()`, and that is the whole design: * allow-list -- every intermediate state is safe (unproven ops stay on PyTorch, which is correct by construction); an incomplete list costs throughput, not correctness. * deny-list -- I tried it first. Five full engine runs, one new defect each: `cat` (e8m0 dtype), `mul` (broadcast shape), `topk` (compile blowup), `rms_norm` (signature), `mm` (compile assert). The method requires being bitten before it can exclude, and every state along the way is unsafe. That matches the instruction this was built to: use what works, leave the rest. Where it is called is not incidental. `import flag_gems` initialises a CUDA context -- measured, `torch.cuda.is_initialized()` flips on the import alone, before `enable()`. A `sitecustomize` injector therefore put all 8 ranks on device 0 and NCCL refused with "Multiple Ranks are using the same GPU". It now runs inside `create_llm`, after `setup_cuda_visible_devices`, which is the same hazard already documented there for the profiler. Defects found and documented rather than worked around, because each one is worth knowing: * `mul` returns the *first operand's shape* when broadcasting expands it: (1,64,8)*(4,1,8) gives (1,64,8), and (64,1)*(1,128) gives (64,1). Silent, no error, fewer elements computed. It made `engram_hash_ref` disagree with PyTorch during a real run. add/sub/div/maximum/minimum all broadcast correctly, so it is mul's own bug. * `cumsum` drifts by up to 1.0 over a 512-element bf16 row (tolerance ~0.17) -- bf16 accumulation. * `topk`'s compile time explodes with k: 4.8 s at k=8, 19 s at k=64, >180 s at k=512, and the sampler asks for 4096. py-spy put all 8 ranks at 100% CPU inside `make_llir` with every GPU idle. * `cat` raises `KeyError: 'float8_e8m0fnu'` on the model's UE8M0 scale tensors during weight load. * `mm` passes every isolated probe yet fails inside the engine at `general_mm`; trigger unknown, so GEMMs stay on cuBLAS, which is faster anyway. Two methodological errors in my own measurements, both fixed and both recorded: 1. After `enable()`, `torch.mul` *is* `flag_gems.mul`, so the first version of the mul A/B compared FlagGems with itself and reported a perfect score. All references are now computed before enable. 2. "ok" did not mean FlagGems ran. `torch.bitwise_xor` has no FlagGems registration at all, so that "match" was PyTorch against PyTorch. `screen_ops.py` now checks registration first and reports such cases as `skip` rather than pass. Name mismatch is its own trap: FlagGems registers `add` bare but `eq.Scalar`, `where.self`, `repeat_interleave.self_int`, `_softmax` (not `softmax`), `div.true_divide`. Asking for `softmax` silently registers nothing. The bootstrap now expands names against `flag_gems._FULL_CONFIG` and warns on anything unresolved -- which is how `softmax` was found to need `_softmax`. Output is not token-identical to the no-FlagGems build (diverges at the first token), but two runs of the same FlagGems config are bit-identical, so the difference is Triton-versus-eager accumulation order, not nondeterminism. Answers stay correct and coherent. |
||
|---|---|---|
| csrc | ||
| deep_cluster | ||
| deepinfer | ||
| doc | ||
| eval | ||
| examples | ||
| scripts | ||
| tests | ||
| vendor | ||
| .clang-format | ||
| .gitignore | ||
| .gitmodules | ||
| build.sh | ||
| CONTRIBUTING.md | ||
| H20-BRANCHES.md | ||
| H20-DEBUG-PLAN.md | ||
| H20-DRIFT-ANALYSIS.md | ||
| H20-FLAGGEMS-PLAN.md | ||
| H20-PORTING-JOURNAL.md | ||
| H20-SM90-FINDINGS.md | ||
| H20-TRITON-PLAN.md | ||
| LICENSE | ||
| Makefile | ||
| pyproject.toml | ||
| README.md | ||
| requirements-ascend.txt | ||
| requirements-dev.txt | ||
| requirements-nvidia.txt | ||
| requirements.txt | ||
| setup.py | ||
| TODO.md | ||
DeepInfer
DeepInfer is the high-performance inference framework that powers DeepSeek's large-scale production services. This open-source release provides offline inference with the core features needed for serving at scale.
Supported models:
- DeepSeek-V4.1-Flash
Supported features:
- Optimized kernels, model and sampler runtime
- Parallelism: Attention DP / balanced CP, MoE EP + EPLB
- DSpark and confidence-scheduled verification
- SWA bounded replay
- Asynchronous scheduling (zero-overhead batch scheduler)
- Batch-invariant inference
- Deterministic sampling
- Structured outputs
Feature details and configuration
- Optimized kernels: FlashMLA, DeepGEMM, DeepEP, TileKernels, DeepSelect, and custom TileLang kernels.
- DSpark and confidence-scheduled verification: accelerate decoding with draft tokens and use confidence estimates to schedule verification. Set
DEEPINFER_ENABLE_MTP_VARLEN=1;DEEPINFER_USE_NEXTN_DECODEcontrols the maximum draft length (default: 5). - Decoder SWA bounded replay: reduce decoder prefill work by replaying only a bounded suffix. Set
DEEPINFER_YOCO_PREFILL_TRUNCATION_MODE=compactandDEEPINFER_YOCO_PREFILL_KEEP_TOKENS=140for the default V4.1 settings; the retained suffix must cover the SWA window plus the maximum backtracking length. - Asynchronous scheduling: overlap CPU batch scheduling with device execution. Enabled by default.
- Batch-invariant inference: keep model results identical across different batch compositions. Enable with
DEEPINFER_BATCH_INVARIANT=1(NVIDIA only). - Deterministic sampling: produce identical outputs for identical input tokens and sampling parameters. Set
DEEPINFER_BATCH_INVARIANT=1 DEEPINFER_ENABLE_MTP_VARLEN=0and pass a fixedseq_seedtoSamplingParams(NVIDIA only). - Structured outputs: constrain generation to a regex, JSON schema, or EBNF grammar. Pass
so_args={"schema_type": ..., "schema": ...}toSamplingParams; see examples.
Supported hardware:
- NVIDIA SM100 GPUs
- Huawei Ascend 950 NPUs
Required for a complete inference service (not included in this release):
- A KV cache system
- VE/Prefill/Decode disaggregation (most required engine functionality is already implemented)
- Load balancing across data-parallel replicas for both prefill and decode
Getting started
Prerequisites
- Linux
- GCC >= 13.0
- Python 3.12
- CUDA 13 (NVIDIA only)
- CANN 9.2 (Ascend only)
Build from source
Before building DeepInfer, please create and activate an empty Python 3.12 environment.
# Use `ascend` instead for the Ascend platform
# Keep it exported in the environment where you run DeepInfer
export DEEPINFER_ACCELERATOR=nvidia
./build.sh
Offline inference
The default checkpoint, deepseek-ai/DeepSeek-V4.1-Flash-1017, is
downloaded into the Hugging Face cache on the first run; set DEEPINFER_HF_MODEL_DIR=/path/to/DeepSeek-V4.1-Flash-1017 to
run from a local copy instead.
python examples/offline_inference.py
See examples for details.
Performance benchmarks
| Prefill | Decode |
|---|---|
![]() |
![]() |
Measured on 4 SM100 GPUs for prefill and 64 for decode — each within one scale-up domain. To reproduce the benchmarks, see run_sweep.sh.
Evaluation benchmarks
See eval/README.md.
License
DeepInfer is released under the Apache License 2.0. See LICENSE for details.
Acknowledgments
DeepInfer was originally built primarily on vLLM, with additional inspiration from SGLang and TensorRT-LLM. We thank their developers.
Citation
@misc{deepinfer2026,
title = {DeepInfer: High-performance, large-scale inference framework for DeepSeek models},
author = {DeepSeek-AI},
year = {2026},
publisher = {GitHub},
howpublished = {\url{https://github.com/deepseek-ai/DeepInfer}},
}

