APPENDIX B
Repository and execution map
The chapters organise DeepInfer by mechanisms. This appendix organises the same implementation by processes, call boundaries and directories. Use it to choose a starting symbol, then return to the chapter that explains its behaviour. Line anchors refer to the pinned edition in Appendix C.
The question
On four devices, how can one configuration have four engine drivers and another have two drivers, while both have four device workers? Does adding expert parallelism create another pool of processes?
python3 labs/28_ranks.py
DP, CP and EP mean data, context and expert parallelism. The lab translates rank arithmetic; it starts no workers. DP4/CP1 gives four drivers, each using one device. DP2/CP2 gives two drivers, each with one spawned CP follower. EP4 groups those same four device workers in both configurations. For DP2/CP2 the computed memberships are:
DP groups: [[0, 2], [1, 3]]
CP groups: [[0, 1], [2, 3]]
EP groups: [[0, 1, 2, 3]]
The grouping arithmetic in the lab is small enough to inspect directly:
def layout(dp, cp, ep):
world = dp * cp
assert world % ep == 0
workers = [(e * cp + c, e, c, "driver" if c == 0 else "child")
for e in range(dp) for c in range(cp)]
dp_groups = [[e * cp + c for e in range(dp)] for c in range(cp)]
cp_groups = [[e * cp + c for c in range(cp)] for e in range(dp)]
ep_groups = [list(range(start, start + ep)) for start in range(0, world, ep)]
Thus DP, CP and EP describe different groupings of the same workers. They are not three process pools to add together. The following map assumes one node, zero device offset and no extra Engram replicas. Production choices in the Q&A are a separate configuration, discussed in chapter 11.
B.1 Processes, devices and communication groups
The example launcher examples/_launch.py:26, run_dp, starts one process
per engine rank assigned to the node (or uses the current process for one engine).
Its RANK/WORLD_SIZE select the node’s share of those ranks. Within each engine,
deepinfer/engine/llm_engine.py:368, _init_workers, spawns CP ranks 1 through
. CP
rank zero is a Worker in the engine process itself. The engine’s Python controller is therefore not
an additional device worker [94].
WorkerBase in deepinfer/worker/base.py:79 assigns
where is
engine rank,
is CP size and
is CP rank. The example factory’s setup_cuda_visible_devices assigns each engine its
contiguous slice of devices; within that slice a worker uses its local index. Figure B.1 shows the
two example layouts with four local devices and no offset.
ParallelProcessGroup.create_process_groups builds DP groups across engines at a fixed
CP position, CP groups within an engine, and contiguous EP groups:
# DP group
dp_ranks = rearrange(ranks, "(replica dp cp) -> (replica cp) dp", dp=dp_size, cp=cp_size)
self.dp = _split_group(dp_ranks.tolist(), backend=backend, pg_options=options)
self.cpu_dp_group = _split_group(dp_ranks.tolist(), backend="gloo")
# CP group
cp_ranks = rearrange(ranks, "(dp cp) -> dp cp", cp=cp_size)
self.cp = _split_group(cp_ranks.tolist(), backend=backend, pg_options=options)
self.cpu_cp_group = _split_group(cp_ranks.tolist(), backend="gloo")
# EP groups: contiguous groups of ep_size ranks.
if ep_size == ranks.numel():
self.ep = self.world
else:
ep_ranks = rearrange(ranks, "(edp ep) -> edp ep", ep=ep_size)
self.ep = _split_group(ep_ranks.tolist(), backend=backend, pg_options=options)
For DP2/CP2, this produces DP groups and , CP groups and , and the EP group . The membership formula is distinct from a workload split: CP workers cooperate on the same engine’s requests, whereas DP engines admit different requests. EP determines where experts run.
Within a CP group, the query rows of each sequence are divided by a mirrored, or zigzag, rule. The
reference expansion in model_executor/layers/tilelang_ops/prepare_cp_mirror.py, lines 135–146, cuts
a sequence of
rows into
pieces of
rows; rank
takes pieces
and . With
and eight rows,
rank 0 holds rows 0–1 and 6–7, while rank 1 holds rows 2–5. This is why the scheduler rounds prefill workloads
to cp_align
(csrc/engine/scheduler.hpp:90; chapter 5). Under causal attention, later rows read more
context, so pairing an early piece with a late one plausibly evens out the work. That is our
reading of the README’s “balanced CP”, not a measured balance [94].
The general configuration is broader. deepinfer/config.py:150, ParallelConfig, allows
Engram parallelism to enlarge the world; the world size is the maximum of that size and DP
times CP. The lab deliberately excludes those replicas. CPU control groups and shared-memory
queues also exist. Their transport implementation and all distributed failure paths are not
covered here [94].
B.2 Follow one step into computation
Figure B.2 is a call-boundary map, not an elapsed-time chart. The scheduler returns work to the engine. It does not call the model runner. The worker separately launches main-model execution and sampling.
The following anchors locate each hop. Paths in this table are relative to deepinfer/, except
those starting with csrc/.
File and anchor | Symbol, boundary and reading |
|
|
|
|
| Binding
of
|
|
|
|
|
|
|
The model runner first prepares input metadata. The eager path calls the model; the graph path replays captured work:
if run_cuda_graph:
model_output = self.cuda_graph_runner.replay(cuda_graph_used)
else:
model_output = self.model(kv_caches=kv_caches, input_metadata=input_metadata)
The registered architecture name is DeepseekV41ForCausalLM. It selects the
DeepseekVLForCausalLM wrapper, whose forward prepares prompt embeddings when needed. It
then delegates to the base wrapper’s DeepseekForCausalLM.forward, which calls the core model
[95].
File
and
anchor
within
| Symbol and reading |
|
|
| VL
|
| Causal-LM
|
|
|
|
|
|
|
B.3 Follow results back to their owner
The reverse path is not simply Sampler returning a Python answer. Sampling completion permits
post-processing; C++ updates sequence state and builds pooled output records; the Python
entrypoint clones records it retains (Figure B.3).
The engine installs its callbacks when constructing the driver:
driver_kwargs = {
"engine_callbacks": EngineCallbacks(post_process_fn=self.post_process, pre_sampler_sync_fn=self.pre_sampler_sync),
}
Start at worker/worker.py:248, _post_process_step. It waits for the sampling event,
runs the model runner’s post-functions and invokes the engine callback on the driver.
engine/llm_engine.py:984, post_process, enters _process_model_outputs at line 687. That
method calls scheduler.process_outputs at line 727, then build_request_outputs at line
743. The binding is in csrc/engine/pybind_output.cpp:41; the builder and pool are in
csrc/engine/outputs.hpp:94 and 45. The returned array holds integer addresses.
entrypoints/llm.py:181 clones each retained record [5, 96].
These names identify a dependency path, not a guarantee that one
step() returns the tokens it just launched. The worker may process step
while
step
runs. To investigate missing final tokens, follow flush_inflight_reqs; to investigate stale
addresses, follow the output pool’s release, not Python reference counts.
B.4 Start from a README feature
The pinned README lists eight features. These tables connect each name to its controls and a source entry point. Batch invariance and deterministic sampling have separate rows because their conditions differ. Settings are not a complete launch recipe; follow the indicated chapter for defaults and limits [1, 97].
Paths are relative to deepinfer/, except csrc/, vendor/ and requirements.txt.
The example entry points’ ep and cp arguments choose group sizes; seq_seed and
so_args are SamplingParams fields. Names beginning with DEEPINFER_ are environment
variables.
README feature | Setting | Entry file and symbol | Read |
Attention DP / balanced CP; EP + EPLB |
|
| 7, B |
DSpark |
|
| 8 |
SWA bounded replay |
|
| 9 |
Asynchronous scheduling |
|
| 6 |
README feature | Setting | Entry file and symbol | Read |
Batch-invariant inference |
|
| 10 |
Deterministic sampling |
|
| 10 |
Structured outputs |
|
| 10 |
Optimized kernels, model and sampler runtime | No single switch |
| 3, A, B |
B.5 Choose a directory before choosing a file
Coverage labels below describe the book, not the maturity of the software. Deep means a mechanism is traced in detail; partial means selected paths are analysed; locate gives responsibility and an entry point only; outside marks implementation details not analysed. A deep directory entry still does not mean every file in it was reviewed.
Runtime area | Responsibility and coverage |
| Public LLM interface,
request lifecycle and scheduling orchestration. Deep:
chapters 1, 5, 6. The second path here and below is
relative to |
| Native scheduler, sequence/block state, metadata and output bindings; Python extension interface. Deep: chapters 1, 4–6, 8; appendix A. |
| Worker lifetime, model runner, cache engine and graphs. Deep for execution/state; partial for initialisation. Chapters 3, 4, 6, 9. |
| Python metadata views, ZOS preparation, YOCO and draft layouts. Partial: chapters 3, 6, 8, 9. |
| Statistics, replica/placement policy and weight movement. Deep: chapter 7. |
| Grammar compilation, matching and rollback. Partial: chapters 5, 10. |
Model and kernel area within | Responsibility and coverage |
| Attention, compression, indexer, MoE, sharing and model adapters. Partial overall; deep paths in chapters 3, 7, 9 and appendix A. |
| DFlash proposals and confidence. Partial: chapter 8. |
| Vision computation and multimodal processing workers. Locate; architecture and preprocessing outside. |
| Sampling, linear/norm/rotary layers and attention backend interfaces. Partial: chapters 3, 8, 10; appendix A. |
| Interfaces, references and device kernels. Selected formulas are analysed; general kernel tuning is outside. |
| Relative to the preceding layers directory: GPU and Ascend implementations. CUDA has selected deep dives; Ascend internals are outside. |
For the model modules not expanded in appendix A, start with v4_modules/hc.py:
HCLayerMixin mixes the multiple residual streams around attention and feed-forward sublayers,
while HCHead folds them back before the output head. hc_blocks.py, hc_lazy.py and mhc_*
provide related mixing and deferred work. In v4_modules/engram.py, EngramRuntime fetches
sharded n-gram embeddings; related metadata and parameter files describe their representation.
These are navigation descriptions, not derivations or evaluations of either model mechanism
[95].
Support area | Responsibility and coverage |
| Configuration translation, checkpoint parameters,
loading and tokenisation. Configuration is partial;
loading internals outside. Start with |
| Registry lookup and model construction/loading.
Locate; model structure also starts in |
| Groups, collectives, buffers and shared-memory transport. Partial: chapters 6, 7 and this appendix; complete initialisation/recovery outside. |
| Platform selection, NPU adapters, device discovery and affinity. Locate; platform-specific algorithms outside. |
| Launch and benchmark entry points, evaluation and tests. Partial: chapters 2, 8–11; inspect test assertions rather than treating file names as guarantees. |
| Independent library pins, build scripts and native timing. Dependency boundaries and timing are partial; library/kernel implementation surveys and build-system internals outside. |
| Deployment account, usage and installation requirements. Chapter 11 separates described service logic from released code. |
Platform dispatch has a useful search boundary: model_executor/layers/tilelang_ops/ops.py
imports the backend selected by PLATFORM.tilelang_ops_backend and exports its *_tl
factories. An interface module can therefore look platform-neutral while selecting CUDA or
Ascend implementations. This is a route into those files, not evidence that their numerics or
performance are identical. The independent DeepSeek libraries in vendor/ include DeepGEMM,
DeepEP, DeepSelect and FlashMLA; use their pinned submodule revisions when crossing that
repository boundary. TileKernels is another independent DeepSeek library, installed
through tile-kernels==2.1.0 in requirements.txt, not a vendor/ submodule
[97].
B.6 Find the corresponding code in another edition
Begin with a symbol and responsibility, then use line anchors as a convenience. For example, from a DeepInfer checkout:
rg -n 'def execute_model_step|def _post_process_step' deepinfer/worker
rg -n 'class Compressor|class MQA' deepinfer/model_executor/models
rg -n '"schedule"|"process_outputs"' csrc/engine/pybind_scheduler.cpp
rg --files deepinfer/model_executor/parallel_utils
Follow callers as well as definitions: a helper’s existence does not establish that the released
engine drives it, as chapter 11’s state-transfer example showed. Recheck defaults and the chosen
model/platform branch. To compare a checkout with this book’s evidence, run make
check from the book with DEEPINFER_SOURCE=/path/to/DeepInfer. A mismatch
detects a changed source edition; it does not identify which behavioural claims remain
valid.
As a reading exercise, choose one object: an input position, a compressed row, a grammar matcher or a pooled output address. Locate its creator, its next reader and its release or reuse condition. The directory map supplies entry points; the ownership and evidence methods from the chapters supply the check.