Each config drove an identical LangGraph ReAct agent (tools: list_dir, read_file, search_code over the Atlas-Inf/atlas Rust codebase β 1,770 .rs files β plus a Flash-Next architecture reference) to produce a gap analysis: what Atlas must adopt to support Qwen3.8-Flash-Next (qwen4exp). No token budget; wrap-up nudge after ~100 messages; no-think; temp 0.3. Same hardware/configs as the tower-defense shootout. 2026-08-30.
| Config | Wall | LLM steps | Tool calls | Input tok | Output tok | Prefill tok/s | Decode tok/s | Agent tok/sβ | Report | Grade* |
|---|---|---|---|---|---|---|---|---|---|---|
| P (prod 27B) | 17.7 min | 57 (hit cap) | 79 | 2.10M | 16.6K | 720.6 | ~49 | 15.7 | truncated β table cut mid-row; plan/risks lost | 6/10 |
| E2 (FN Q3) | 13.4 min | 41 (self-stopped) | 65 | 1.42M | 5.3K | 475.0 | ~20 | 6.6 | truncated β overview only | 4/10 |
| A (FN Q4) | 13.4 min | 36 (self-stopped) | 66 | 1.23M | 6.8K | 465.7 | ~19 | 8.4 | complete β 14.2 KB, all 4 sections | 8.5/10 |
β Agent tok/s = output tokens Γ· total wall time β the effective end-to-end agent speed, dragged down by re-prefilling the growing history every step (this is why it is far below decode speed, and why prefill throughput matters most for agentic work). Prefill is the server-side measured rate on long file-embedded prompts; decode from the tower-defense long-generation rounds on the same servers.
*Graded against the ground-truth qwen4exp feature list (llama.cpp PR #27742): coverage of the 9 required features,
evidence quality, plan actionability, report completeness. A wins: complete, deep (found the in-tree kernels/gb10/qwen3.8-27b
precedent, identified the sparse-attention indexer as the one real kernel gap, named concrete risk classes) β though it entirely missed
the 51B n-gram PLE table, conflating "n-gram" with n-gram speculative drafting. P had the best raw research coverage β
the only one to verify PLE is missing (grep: 0 hits) and to flag the shared-expert gating question β but never self-terminated
(researched to the step cap) and its report was cut. E2 stopped earliest and delivered the least.
1) Prefill dominates agentic work: each ReAct step re-feeds the growing history β 1.2β2.4M input tokens per run.
Prod's 720 tok/s prefill gave it a 3.4Γ wall-clock edge at equal steps in run 1.
2) No model self-terminates without pressure: with no budget, all three researched until the 170-step cap in run 1.
A wrap-up nudge fixed it β and the 125B configs heeded it better (36β41 steps) than the 27B (cap again).
3) Template-token collision: P's and E2's reports quoted literal <think> / </tool_call>
while describing Atlas's chat templates β llama.cpp's template parser intercepted them and swallowed the rest of the message.
A real hazard for agents that write about chat templates on llama.cpp-served models.
Atlas is a single-GPU-first, Rust inference engine organized around a registry-driven model factory and a model-agnostic runtime:
crates/atlas-core/src/config.rs + config/{dispatch,factory,parsers,gguf}): a single ModelConfig struct is the source of truth, parsed from HF config.json (per-family parser modules under config/parsers/) or GGUF (config/gguf.rs). It already encodes hybrid layer layouts (LayerType, layer_types, full_attention_interval), GDN/SSM dims (linear_num_key_heads, linear_conv_kernel_dim, β¦), MoE fields (experts, top-k, shared expert, norm_topk_prob, decoder_sparse_step, per-layer heterogeneous sizes), MLA/low-rank fields, YaRN/MRoPE (mrope_section, mrope_interleaved), MTP/DSpark fields, and quantization metadata (quantization_config β QuantFormat dispatcher).crates/spark-model/src/factory.rs): loader_for_config() is the only place model_type strings are matched; adding a model = implementing ModelWeightLoader + one match arm. Supported families include qwen3_next, qwen3_5/3_6_moe, qwen3_vl_moe, nemotron_h, minimax_m2, step3p7, deepseek_v4, gemma4, mistral, laguna, m2m_100.crates/spark-model/src/layers/): a mature Gated Delta Net implementation (qwen3_ssm/, incl. FLA-style chunked prefill, WY kernels, multi-seq batched decode, FP16 h-state), full attention with gated Q (attn_gated), MLA + DeepSeek-V4 CSA/HCA compressed attention (qwen3_attention/prefill/cache_skip_v4.rs, decode/attention_forward_v4.rs), mHC hyper-connections (layers/ops/hyper_connection.rs), Mamba-2 (nemotron_mamba2/), MoE with softmax / sigmoid+bias / sqrtsoftplus routing (layers/moe/, layers/ops/moe_gate.rs), MTP heads (single/multi, mtp_head/, mtp_multi.rs, deepseek_v4_mtp.rs), DFlash block-diffusion drafter (dflash_head/), and a vision encoder (vision_encoder/).crates/spark-runtime/): paged KV cache with FP8/NVFP4/turbo KV dtypes, prefix caching + radix tree, buffer arena sized from ModelConfig, CUDA graphs, cuBLASLt/CUTLASS/FlashInfer backends, sampler, EP/TP sharding (spark-model/src/tp_shard.rs, layers/ep_dispatch.rs), expert-tier RDMA paging (spark-storage/src/expert_peer.rs, expert_tier_rdma.rs).crates/spark-server/): OpenAI/Anthropic APIs, thinking/enable_thinking/reasoning_effort handling, tool-call parsing, grammar-constrained decoding, speculative decoding modes (--speculative MTP, --self-speculative, --ngram-speculative, --dflash), per-model tuning via kernels/<target>/<model>/MODEL.toml (sampling presets, match_names, kernel_source reuse).Notably, the repo already carries a kernels/gb10/qwen3.8-27b/ target whose MODEL.toml documents a dense sibling of the same architecture family (GDN + full attention + MRoPE-interleaved + gated attention, mrope_section=[11,11,10], partial_rotary_factor=0.25), reusing kernel_source = "qwen3.6-27b" β strong evidence that much of the Flash-Next feature surface is already exercised in-tree.
| Flash-Next feature | Atlas status | Evidence file(s) |
|---|---|---|
model_type = qwen4exp registration | Not present β factory bails on unknown types; closest arms are qwen3_next, qwen3_5/3_6_moe, holo3_1_moe | crates/spark-model/src/factory.rs (loader_for_config), crates/atlas-core/src/config/dispatch.rs |
| Hybrid GDN + full-attention layer layout | Present, mature β LayerType/layer_types, full GDN decode/prefill (FLA chunked, WY, reg-resident), conv1d+L2-norm, gated RMSNorm, per-layer state (SsmLayerState) | crates/atlas-core/src/config.rs, crates/spark-model/src/layers/qwen3_ssm/mod.rs, kernels/gb10/common/gated_delta_rule*.cu, crates/spark-model/src/layer.rs |
Gated Q output (attn_output_gate) | Present β attn_gated flag drives 2Γ q_proj sizing, TP sharding, LoRA shapes | crates/atlas-core/src/config.rs:333, crates/spark-runtime/src/buffers/sizes.rs, crates/spark-model/src/tp_shard.rs |
| Partial RoPE (factor 0.25) + YaRN variants | Present β partial_rotary_factor, full YaRN parameter set, rope_yarn kernels | crates/atlas-core/src/config.rs:52,285-309, kernels/gb10/common/rope.cu |
MRoPE-interleaved [11,11,10] | Present β mrope_section, mrope_interleaved, dedicated kernel; documented on qwen3.6/3.8 targets | crates/atlas-core/src/config.rs:338-347, kernels/gb10/common/rope_mrope_interleaved.cu, kernels/gb10/qwen3.8-27b/MODEL.toml |
| MoE: sigmoid routing + correction bias (noaux_tc), shared expert with sigmoid gate, routed scaling | Present β moe_topk_sigmoid (β€512 experts, β€top-32), moe_topk_sqrtsoftplus (V4), shared-expert gate, routed_scaling_factor; K2/K3/grouped/token-major/EP kernels | kernels/gb10/common/moe_topk_sigmoid.cu, crates/spark-model/src/layers/ops/moe_gate.rs, crates/spark-model/src/layers/moe/{mod,forward,init}.rs |
| Per-layer heterogeneous MoE (intermediate size / top-k) | Present β moe_intermediate_sizes, num_experts_per_toks (Puzzle) | crates/atlas-core/src/config.rs:200-208 |
| MTP speculative decoding (multi-module) | Present β mtp_num_hidden_layers, single/multi MTP heads, verify pipeline, --speculative/--num-drafts | crates/spark-model/src/layers/mtp_{head,multi}.rs, crates/spark-server/src/cli/serve_args.rs:504-527 |
| N-gram / self-speculative drafting | Present β --ngram-speculative, --self-speculative, DFlash drafter | crates/spark-server/src/ngram.rs, crates/spark-server/src/cli/serve_args.rs, crates/spark-model/src/layers/dflash_head.rs |
| Paged KV + FP8/NVFP4 KV, prefix cache, sliding window | Present β paged decode kernels across KV dtypes, radix prefix cache, sliding-window attention | crates/spark-runtime/src/kv_cache.rs, prefix_cache.rs, radix_tree.rs, kernels/gb10/common/paged_decode_attn*.cu |
| GDN recurrent-state management for prefix cache / branching | Present β SSM snapshot/restore, async checkpoint, pool-slot remap on prefix reuse | crates/spark-model/src/model/ssm_snapshot.rs, model/trait_impl/async_chkpt.rs, sequence.rs |
| Quantization: NVFP4, FP8 block/per-row, MXFP4-E8M0, GGUF Q2/Q4, mixed-precision exemption lists | Present β QuantFormat dispatcher, ignore-lists, per-row FP8 prefill arm (the exact case flagged for Qwen3.8-27B-NVFP4's mixed FP8/NVFP4 config) | crates/spark-model/src/quant_format/, config/parsers/quantization.rs, layers/qwen3_ssm/mod.rs (qkvz_fp8w_rowwise), kernels/gb10/qwen3.8-27b/MODEL.toml:9-30 |
Vision tower / multimodal (if Flash-Next ships vision_config) | Present β Qwen3-VL loader + vision/video preprocess; MRoPE interleaved already wired | crates/spark-model/src/weight_loader/qwen3_vl.rs, vision_preprocess.rs, video_preprocess.rs |
| Thinking mode / chat template | Present β enable_thinking, thinking budgets, jinja templates per family (qwen3_5_moe.jinja); a Flash-Next template file likely needed | crates/spark-server/src/openai/chat_request.rs, jinja-templates/, kernels/gb10/qwen3.8-27b/MODEL.toml sampling presets |
Semantic-indexer top-k sparse attention (index_n_heads/index_head_dim/index_topk) | Config fields exist; kernel/forward path NOT found β V4's CSA/HCA path implements windowed softmax-gated compression (csa_compress) but no learned indexer selecting top-k compressed blocks; comments explicitly call the indexer "a no-op" | crates/atlas-core/src/config.rs:272-280, crates/spark-model/src/layers/qwen3_attention/prefill/cache_skip_v4.rs:414-417 (repo-wide grep for indexer finds only config + comments) |
| **N-gram drafting combined with MTP** (Flash-Next's recommended hybrid drafting, if that is the reference recipe) | Partially β both mechanisms exist but appear mutually exclusive per CLI validation grouping; needs verification of combinability | crates/spark-server/src/cli/serve_args.rs:504-527, validate.rs:217-230 |
| CPU/RAM weight streaming for oversized MoE (single-box) | Partial β RDMA expert-tier peer paging exists (expert_peer.rs), but no local mmap-backed on-demand expert streaming found in spark-runtime/src/weights/ | crates/spark-storage/src/expert_tier_rdma.rs, spark-runtime/src/weights/loader.rs |
qwen4exp-specific config parser (new fields, e.g. updated GDN gate form, new rope scheme) | Not present β no parsers/qwen4exp.rs; unknown fields silently default, which risks wrong numerics | crates/atlas-core/src/config/parsers/ |
qwen4exp (Complexity: LowβMedium). Add config/parsers/qwen4exp.rs (clone the qwen3.5/3.6 dispatch path in config/dispatch.rs), set attn_gated, mrope_section/interleaved, partial_rotary_factor, layer-type layout, MoE routing kind; add the "qwen4exp" arm in factory.rs::loader_for_config. Reuse Qwen35WeightLoader/Qwen35DenseWeightLoader if tensor names match (the qwen3.8-27b precedent shows name-level identity across 3.6/3.8).
Verify checkpoint tensor names against the qwen35 loader arms (weight_loader/qwen35/load_layers/attention_arms.rs, qwen35_dense.rs); route mixed FP8-channel + NVFP4 configs through the existing QuantFormat dispatcher and the per-row-FP8 prefill arm; document any double-quantization (per-row FP8 β BF16 β NVFP4) exactly as done for qwen3.8-27b.
index_topk > 0) (Complexity: High). Atlas has the compressed-KV pool infrastructure (V4 csa_compress, FP8 compressed-block persistence) but no indexer: needs indexer projections (q/index weights), a top-k selection kernel over compressed blocks, gather-based attention over selected blocks in both prefill and decode, and pool bookkeeping in kv_cache/prefix cache. This is the single largest genuine kernel gap.
Wire the checkpoint's routing (sigmoid+correction-bias vs softmax vs sqrtsoftplus) through the existing selection logic in layers/moe/init.rs/forward.rs; check num_experts β€ 512, top_k β€ 32 kernel bounds; add a MODEL.toml kernel target with match_names if config alone cannot disambiguate from qwen3.5/3.6 (the documented tie-breaking requirement in atlas-kernels/src/resolve.rs).
Map Flash-Next's MTP module count to mtp_num_hidden_layers and existing MTP heads; if the reference recipe combines n-gram + MTP drafting, extend cli/validate.rs and the scheduler proposer chain to allow composition (Complexity: Medium, scheduler work).
Add jinja-templates/qwen4exp.jinja (or rely on the checkpoint-embedded template), MODEL.toml with card-derived sampling presets (thinking/non-thinking/tools, penalty-free tools per family rule), thinking_default, loop-watchdog settings β mirroring kernels/gb10/qwen3.8-27b/MODEL.toml.
Re-derive effective_context and sliding-window interaction for Flash-Next's context length; validate FP8-KV calibration path (fp8_calibration.rs, --fp8-kv-headroom) and GDN state memory (48/64 linear layers β per-seq state cost) against the buffer arena sizing in spark-runtime/src/buffers/sizes.rs.
If a Flash-Next MoE variant exceeds single-GPU weight budget, build on spark-storage expert-tier machinery to add a local mmap/pinned-RAM expert tier (pinned_hosts.rs exists) with async H2D prefetch on routed expert ids.
debug_assert in cache_skip_v4.rs:564) which may not hold.qwen4exp may be numerically indistinguishable from qwen3_5/qwen3_6 configs (the qwen3.8-27b MODEL.toml documents an exact-tie that required match_names); a wrong loader silently changes numerics rather than failing.w8a16's [N/128,K/128] block-grid indexing; the dequantβNVFP4 fallback is deliberate but costs accuracy β the same trap is documented and must be re-checked tensor-by-tensor on the Flash-Next checkpoint.exp(-AΒ·softplus(Ξ±+dt_bias)) variant, L2-norm placement, beta form), Atlas's heavily-optimized kernel zoo (WY/FLA/reg-resident, FP16 h-state) must be re-derived bit-exactly; the cos-gate test harness exists but each variant multiplies maintenance.V4_WINDOW=128 const, not config-driven); porting that pattern to Flash-Next risks OOD behavior ("prompt-length salad" noted in code) if window/compression split differs.auto speculative arbiter behavior under a new model is untested.v4_comp_pool_filled comment) and would need targeted tests for Flash-Next.gb10; other targets degrade or fail to resolve.Atlas is an AGPL-3.0 inference stack for NVIDIA GB10 / DGX Spark (unified memory). Relevant pieces I inspected:
crates/spark-model/ β model assembly. factory.rs::loader_for_config is the only place model_type strings are matched; each family gets a ModelWeightLoader impl under weight_loader/ (qwen3, qwen35, qwen35_dense, qwen3_vl, minimax, nemotron, gemma4, deepseek_v4, step3p7, laguna, mistral, nllb). Layers live in layers/: qwen3_ssm/ (Gated Delta Net), qwen3_attention/ (shared GQA/MLA/sparse-attention stack), moe/ (routed + shared expert, BF16/FP8/NVFP4), mtp_head/ + mtp_multi.rs (speculative drafter), vision_encoder/.crates/spark-runtime/ β GPU backend, kv_cache/, prefix_cache/, radix_tree/, buffers/, sampler/, weights/.crates/atlas-core/src/config/ β ModelConfig (SSOT for dims), dispatch.rs (per-model JSON parser), parsers/ (deepseek_v4, gemma4, minimax, step3p7, mistral, laguna, vision, quantization).crates/spark-server/ β OpenAI/Anthropic HTTP, tokenizer (tokenizers crate, byte-level BPE), Jinja chat templates in jinja-templates/.kernels/<hw>/<model>/<quant>/MODEL.toml β per-model kernel target + sampling/behavior presets.crates/atlas-kernels/ β Rust glue over compiled PTX; one artefact per (hw, model, quant).Existing model support matrix (from factory.rs): qwen3_next, qwen3_5_moe, qwen3_5, qwen3_6_moe, holo3_1_moe, qwen3_vl_moe, nemotron_h, nemotron_h_puzzle, gemma4, mistral, minimax_m2, step3p7, laguna, deepseek_v4, m2m_100.
| Flash-Next feature | Atlas status | Evidence |
|---|---|---|
model_type = "qwen4_exp" dispatch | Missing β no arm in loader_for_config; no parser in dispatch.rs | crates/spark-model/src/factory.rs; crates/atlas-core/src/config/dispatch.rs:51-273 |
| Gated DeltaNet (3 of 4 layers, recurrent state) | Present β full GDN stack: decode, batched, prefill (WY32, FLA, TMA, reg-resident), per-sequence state pool, FP16/FP32 h-state | crates/spark-model/src/layers/qwen3_ssm/mod.rs (498 lines of kernel handles) |
| GDN sigmoid output gate | Present β gated_rms_norm_k / gated_rms_norm_f32_k (Z-gate on GDN output) | crates/spark-model/src/layers/qwen3_ssm/mod.rs:87-88 |
| Per-seq recurrent state, checkpointed for batching, reset per seq | Present β SsmLayerState, h_is_f16, per-seq pool slots, batched dispatch | crates/spark-model/src/layers/qwen3_ssm/mod.rs:122-130 |
| Full-attention layers (GQA) | Present β shared Qwen3AttentionLayer | crates/spark-model/src/layers/qwen3_attention/ |
| Hybrid layer schedule (GDN + full attn, 3:1) | Present β LayerType::{FullAttention, SlidingAttention, LinearAttention, Moe} + layer_types / full_attention_interval | crates/atlas-core/src/config.rs:12-20,92-101 |
| Sparse MoE, 512 experts, top-10 | Present β routed + shared expert, BF16/FP8/NVFP4, EP/TP; per-layer top-K (num_experts_per_toks) | crates/spark-model/src/layers/moe/forward.rs; crates/atlas-core/src/config.rs:70-90,208 |
| Gated shared expert (gating differs from Qwen3-MoE) | Partial β shared-expert FFN exists (fused gate/up+silu/down, BF16/FP8/NVFP4), but the output is a plain additive sum; no learned gate on the shared-expert output found | crates/spark-model/src/layers/moe/forward.rs (shared expert computed, added); no shared_gate/shared_expert_gate symbol |
norm_topk_prob | Present | crates/atlas-core/src/config.rs:85 |
| Qwen Sparse Attention (QSA) β budget-based, indexer selects KV under a token budget | Partial β DeepSeek-V4 CSA/HCA path exists (compress_ratios, index_n_heads, index_head_dim, index_topk) but is ratio-based, not budget-based; no token_budget/attn_budget symbols | crates/atlas-core/src/config.rs:267-283; crates/spark-model/src/layers/qwen3_attention/init_arch_gates.rs:37-53; crates/spark-model/src/weight_loader/deepseek_v4/assemble.rs:366-369 |
| QSA + quantized KV "attn-rot disable" interaction | Partial β FP8 KV cache + online calibration exist; no explicit RoPE-disable flag for sparse layers found | crates/atlas-core/src/config.rs:380-390; no attn_rot_disable symbol |
| Per-layer n-gram embeddings (PLE), ~51B table, hashed lookups, host-side placement | Missing β no ngram, n_gram, ple_, per_layer_emb symbols anywhere | grep across crates/ returns 0 hits |
Low-rank hyper-connections (hc_count=4, learned low-rank projections) | Present β DeepSeek-V4 mHC path: hc_mult, hc_sinkhorn_iters, hc_eps, buffers, ops | crates/atlas-core/src/config.rs:255-266; crates/spark-model/src/layers/ops/hyper_connection.rs; crates/spark-runtime/src/buffers/sizes.rs:449-465 |
| MTP head (speculative) | Present β MtpHead, BF16/FP8/NVFP4, drafter prefill, catch-up, refeed; multi-module mtp_multi.rs | crates/spark-model/src/layers/mtp_head/; crates/spark-model/src/layers/mtp_multi.rs; crates/spark-model/src/speculative.rs |
| Multimodal (image+video, CLIP-style ViT + mmproj) | Present β vision_encoder/enc_impl/ (patch_embed, pos_embed, vit_block, merger); vision_config parsing | crates/spark-model/src/layers/vision_encoder/enc_impl/; crates/atlas-core/src/config/parsers/vision.rs |
| 262,144-token context | Present β max_position_embeddings + YaRN fields; radix/prefix cache | crates/atlas-core/src/config.rs:112,285-312; crates/spark-runtime/src/radix_tree/ |
Thinking/non-thinking chat modes (enable_thinking) | Present β qwen3_5_moe.jinja emits ` |
Research caveat: this report is based on direct inspection of the Atlas tree (atlas-coreconfig layer,spark-modelfactory/loaders/layers,spark-runtimeKV/buffers/backends,spark-servertokenizer/tool-parsing,kernels/gb10/*target manifests) plus the Flash-Next architecture reference. A few late verification searches were truncated (notably: generic CPU/mmap weight-residency per tensor group, and the exactspark-quantcrate layout). Items resting on those are marked unverified rather than asserted as gaps.
Atlas is a single-binary, single-hardware (NVIDIA GB10 / SM121) inference engine organized around seven trait/convention plug points, all confirmed in code:
crates/atlas-core/src/config.rs defines one ModelConfig as the "single source of truth" for dimensions and feature flags. config/dispatch.rs::parse_config probes model_type and routes to family parsers (config/parsers/{deepseek_v4,gemma4,minimax,mistral,step3p7,laguna}.rs, plus inline Qwen3.5/3.6/Nemotron arms). Parsers normalize HF field names into canonical Atlas fields and set architecture flags (attn_gated, mrope_interleaved, scoring_func, hc_mult, hc_sinkhorn_iters, hc_eps, compress_ratios, index_n_heads/index_head_dim/index_topk, num_hash_layers, kv_lora_rank, moe_latent_size, β¦).crates/spark-model/src/factory.rs::loader_for_config is documented as "the ONLY place model_type strings are matched"; ~14 loaders under spark-model/src/weight_loader/ implement ModelWeightLoader. factory::build_model assembles a model-agnostic TransformerModel (embed β [layers] β norm β lm_head).spark-model/src/layers/ holds composable TransformerLayer impls: qwen3_attention/ (GQA + paged KV), qwen3_ssm/ (Gated DeltaNet: QKVZ proj, causal conv1d, delta-rule recurrence, gated RMS-norm β decode / batched decode / FLA-chunked prefill / WY32 / reg-resident kernel families), nemotron_mamba2/, moe/ + nemotron_moe/ (routed + shared experts, LatentMoE, sigmoid/sqrtsoftplus scoring, routing bias), dense_ffn.rs, mtp_head/ + mtp_multi.rs, deepseek_v4_mtp.rs, dflash_head/, vision_encoder/, and layers/ops/hyper_connection.rs (mHC expand/collapse/Sinkhorn ops).spark-runtime: kv_cache.rs (KvCacheDtype, 16 variants incl. turbo*/asymmetric), prefix_cache/ + radix_tree/, kv_spill.rs (NVMe offload via StorageBackend), buffers/ (arena sizing incl. hc_streams/hc_post/hc_comb, moe_latent buffers), gpu/ (GpuBackend trait; CUDA + Metal backends), sampler/, weights/ (WeightStore, O_DIRECT fast loader with mmap fallback).kernels/<hw>/<model>/<quant>/ auto-discovered by build.rs; kernels/gb10/deepseek-v4-flash/MODEL.toml carries per-model geometry (hc_mult = 4).spark-server: OpenAI/Anthropic APIs, scheduler (fifo/slai), MTP + DFlash speculative decoding (spark-model/src/speculative.rs, preflight.rs MTP_SUPPORTED_MODEL_TYPES), tokenizer/ (jinja rendering, effort/thinking directives β openai/tests/thinking.rs shows a full enable_thinking/budget/effort pipeline with reasoning_content streaming), tool_parser.rs (ToolCallParser trait; hermes JSON and qwen3_coder XML inner formats under shared `Released 2026-08-26 by the Qwen team; the first public preview of the Qwen4 architecture.
HF: Qwen/Qwen3.8-Flash-Next (BF16, ~355 GB) and Qwen/Qwen3.8-Flash-Next-FP8.
Config model_type: qwen4_exp. Not supported by released Transformers/vLLM as of 2026-08-28;
llama.cpp support exists only in unmerged PR ggml-org/llama.cpp#27742.
Key architectural features an inference engine must implement:
plus a gated shared expert. Standard grouped expert FFN kernels apply, but the router
and shared-expert gating differ from Qwen3-MoE.
state) DeltaNet blocks with a sigmoid output gate. No KV cache for these layers; instead a
per-sequence recurrent state that must be tracked, checkpointed for batching, and reset per sequence.
an indexer selects which cached KV entries each query attends to under a token budget.
Quantized KV cache interacts poorly with rotation tricks (llama.cpp needed an attn-rot disable).
hashed lookups per layer. Can be executed host-side (CPU/mmap) to keep it out of GPU memory;
engines should support placing this tensor group on a separate backend/device.
projections (replaces the single residual stream; affects the whole block dataflow).
decoding (analogous to Qwen3.5's MTP-2).
(enable_thinking flag); recommended sampling: instruct temp 0.7 top_p 0.8, thinking temp 1.0 top_p 0.95.
with tool-call JSON blocks.
Quantization notes: community GGUFs exist (Unsloth UD-Q3_K_XL 84 GB, UD-Q4_K_XL 111 GB).
On 128 GB unified-memory hosts the PLE table is typically offloaded to CPU/mmap.
The research target grew: vLLM checked out at PR #53896 (the actual Flash-Next implementation β which revealed vLLM's "day-0 support" is also an unmerged PR, same as llama.cpp's). Agents research BOTH codebases and write a comparative adoption plan. Budget: 400-step cap, ~10K tok/step, wrap-up nudge at ~260 messages, special-token escaping rule (fixes round 1's truncation bug). 2026-08-30/31.
| Config | Wall | LLM steps | Tool calls | Input tok | Output tok | Report | Grade* |
|---|---|---|---|---|---|---|---|
| A (FN Q4) | 125 min | 113 (self-stopped) | 148 | 5.01M | 14.0K | complete, 20.6 KB | 9.5/10 |
| E2 (FN Q3) | 60 min | 126 (self-stopped) | 136 | 6.10M | 11.7K | complete, 12.8 KB | 6.5/10 |
| P (prod 27B) | 72 minβ | 130 (hit cap) | 133 | 6.43M | 11.2K | forced (toolless finale), 9.6 KB | 5.5/10 |
*Graded by verifying every cited vLLM file against the actual PR tree and cross-checking mechanism descriptions against the code.
A: 9.5/10 β every citation real, package layout exactly right, and the code check confirmed its QSA account
(Qwen4ExpQSAAttention merged owner + QSAKeyStateCache/QSACompressedKeyCache + the
qwen4_exp_qsa_with_output custom op); staff-engineer-grade 6-phase plan with a GB10-specific divergence (host-resident PLE via UVA/mmap).
E2: 6.5/10 β excellent Atlas-side table, but fabricated two vLLM files (common/gdn.py, common/ngram_embedding.py) and confabulated
an MLA-aliasing QSA mechanism β dangerous precisely because of its confident line-number citations.
P: 5.5/10 β honest method (read one kernel fully, inferred the rest β citations real), but shallow vLLM coverage, and its Atlas
status table contradicts round 1's verified findings (claims GDN/MTP/HC missing when they exist) β its pruned context had evicted the early Atlas research.
β P failed round 1 of this task outright (researched to the cap, ignored all stop instructions incl. "no more tools"); the number is its re-run with a
force-final that binds no tools. The 27B never voluntarily stops digging; both 125B configs self-terminated.
Scope note: this report is based on a deep read of the vLLM PR #53896 tree (vllm/models/qwen4_exp/, config plumbing, cache specs) and on targeted searches of the Atlas tree. A few Atlas-side confirmations (exact kernel inventories per feature) were still in flight when research was cut off; where Atlas status is stated with lower confidence it is flagged as such. All findings below are from files actually read; inferences are labeled.
---
vllm/models/qwen4_exp/ with config.py (root), common/ (platform-neutral: HC math, PLE helpers, QSA cache specs/metadata), nvidia/ (model, QSA owner, indexer, PLE layer, MTP, fused Triton ops under nvidia/ops/), amd/.vllm/transformers_utils/configs/qwen4_exp.py re-exports from vllm/models/qwen4_exp/config.py.vllm/models/qwen4_exp/config.pyQwen4ExpTextConfig subclasses Qwen3NextConfig and adds: hc_count (4), hc_lowrank (320), ple_layer_ids (1-based), ple_embed_dim, ple_conv_kernel_size (4), ngram_size (3), heads_per_ngram (8), ngram_vocab_size_base (20M), make_ngram_vocab_size_divisible_by (128), output_gate_type, rope_parameters, layer_types.indexer_n_heads, indexer_kv_heads (must be 1 β MQA), indexer_head_dim (must cover rotary dim), indexer_budget, indexer_compress_ratio; budget / compress_ratio must be 512 or 2048 (block-topk granularity).short_conv_layer_ids (0-based PLE layers), short_conv_state_shape = (hidden*hc_count, (ple_conv_kernel-1)*ngram_size), ngram_context_len = ngram_size-1.Qwen4ExpConfig is a VL wrapper (vision_config = Qwen3-VL vision, text_config = above).nvidia/model.pyQwen4ExpDecoderLayer: per layer, optional Qwen4ExpPLELayer (when layer_idx+1 β ple_layer_ids), then either linear_attention β QwenGatedDeltaNetAttention (shared qwen3_next GDN, gqa_interleaved_layout=False) or full_attention β Qwen4ExpQSAAttention (if indexer config present) else plain Qwen3NextAttention; MLP is Qwen4ExpSparseMoeBlock (subclass of Qwen3NextSparseMoeBlock, rejects sequence-parallel MoE) or dense Qwen3NextMLP per mlp_only_layers / decoder_sparse_step.repeat(1, hc_count) β [T, HC*H] flows through every layer; blocks see a mixed single stream.(hidden_states, block_output, injection); the *next* HC module fuses the pending combine into its own mix via combine_and_mix(). PLE additions and deepstack insertions force an eager combine() first (they add to the materialized multi-stream state). PP boundaries and the final hyper_connection_mixer also materialize via combine.combine_and_mix returns both the sampled single stream and the pre-mixer multi-stream state, copied into _mtp_hidden_buffer for the MTP drafter (zero extra compute).AutoWeightsLoader + WeightsMappers β HC input_mix_weight_down and block_inject_weight are packed into one merged column-parallel GEMM (_HC_WEIGHTS_MAPPER, padded to 16 rows); QSA cache-scale names remapped onto the merged QSA owner (_remap_qsa_cache_scale_name); non-persistent runtime buffers (hashstats_*, token_lookup, mixer inject) skipped; shared expert optionally fused into routed experts (maybe_fuse_shared_experts); modelopt_fp4 excluded for QKV (without_modelopt_fp4).requires_raw_input_tokens = True; the runner supplies query_start_loc and ngram_context forward kwargs (_maybe_add_ngram_kwargs), declared dynamic in @support_torch_compile.[HC,H] and added after terminating the delayed combine.common/hyperconnection.py + nvidia/hyperconnection.py + nvidia/ops/hc.pycommon/): per-stream GroupedGemmaRMSNorm (each H-sized stream normalized independently, affine over the full HC*H layout); mix = sigmoid(up(silu(down(xn)/hc_count))) β xn, mean over streams; combine = residual + block_out * (2Β·sigmoid(inject(xn)/hc_count)).Linears (so quant/low-latency GEMM dispatch works); down+inject fused into MergedColumnParallelLinear with [lora_rank, hc_count, pad] output shards, disable_tp=True (HC is replicated); glue is Triton: grouped_gemma_rmsnorm, hc_silu, hc_gate_mix, hc_combine, and the key fusion hc_combine_norm (fuses pending combine + next RMSNorm).mix() returns (hyper_input, block_input, injection_logits); combine_and_mix() consumes the previous block's output+injection.vllm/model_executor/layers/mamba/gdn/qwen_gdn_linear_attn.QwenGatedDeltaNetAttention with in_proj_qkvz/in_proj_ba packing; state via MambaStateShapeCalculator.gated_delta_net_state_shape (conv state + SSM state, num_spec-aware for spec decode); dtypes via gated_delta_net_state_dtype (bf16 conv, optional fp32 SSM via mamba_cache_dtype/mamba_ssm_cache_dtype).IsHybrid + HasInnerState; mamba_cache_mode="all" is rejected (needs align).nvidia/ple_layer.py (+ common/ple.py)Qwen4ExpPLELayer per selected layer: n-gram hashing of token IDs (ngram_size, heads_per_ngram, hashed n-gram vocab ~20M rounded by 128) β per-head embedding lookups β concat to ple_embed_dim; a short dilated causal conv (ple_conv_kernel_size, dilation = ngram_size) whose state is cached as a SHORT_CONV mamba state of shape [(ple_conv_kernel-1)*ngram_size, hidden*hc_count] β i.e., the conv runs directly on the multi-stream HC state (channels = HCΒ·H), and PLE output is added to the multi-stream state.ngram_context (ngram_context_len = ngram_size-1 previous tokens) plus query_start_loc so conv/hash never crosses request boundaries.MambaSpec (tp_replicated=True) via get_ple_mamba_state_shape_from_config (conv kernel +1 for spec tokens); copy func short_conv_state_copy_func.hashstats_*, token_lookup) are non-persistent and skipped at weight load. Note: PRs #53899/#54129/#54371 (UVA/mmap PLE offload) are *not* in this tree; here the ~20M-entry n-gram table lives on-device β a key memory item for Atlas/GB10.nvidia/qsa.py, nvidia/indexer_qsa.py, common/qsa_cache.py, nvidia/ops/qsa*.pyQwen4ExpQSAAttention owns the main paged KV cache (FullAttentionSpec, BF16 only, no KV quant, no ALiBi/sinks/sliding-window/CP) *and* the indexer side branch, and registers one custom op qwen4_exp_qsa_with_output so the whole index β KV-update β sparse-attend transaction is opaque to torch.compile._run_qsa): indexer produces topk_indices_buffer[T, budget + compress_ratio - 1] (request-relative token indices, -1 padded) β do_kv_cache_update (normal paged write) β Triton qsa_sparse_paged_attention reads manager pages directly with logical_indices + block_table + token_to_req. Attention itself: GQA with sigmoid output gate (always on), GemmaRMSNorm q/k heads, fused QK-norm+RoPE+gate Triton path when possible.QSAIndexer): replicated index_qk_proj (n Q heads + 1 KV head, head_dim 128, rotary 64), GemmaRMSNorm q/k, same RoPE as main attention (incl. interleaved MRoPE). Two side caches:QSAKeyStateCache β raw keys in a per-request circular ring (CircularBufferSpec, capacity = compress_ratio + num_spec rounded to whole groups, must divide block size; optional int64 MRoPE positions packed into the same BF16 rows).QSACompressedKeyCache β one compressed key per complete group of compress_ratio tokens (mean-pool β GemmaRMSNorm β RoPE at group's first position), stored as MLAAttentionSpec with tokens_per_state=compress_ratio so its block table follows the main KV lifecycle.qsa_select_paged_tokens): score q vs compressed keys (weight-free β no learned score MLP), pick block top-k (budget/compress_ratio β {512,2048} groups), expand selected groups back to token indices (hence budget + compress_ratio - 1 width). Fused qsa_pre_indexer Triton kernel does norm+RoPE+raw-store+group-compress+compressed-store in one pass (conditions: head_dim=128, rotary=64, kv_heads=1, power-of-2 ratio).skip_topk reuses step-0 selections on later draft steps while still updating the side cache.QSAMetadataBuilder + Triton _build_qsa_metadata_kernel computes token_to_req, logical_positions, circular/compressed slot mappings and compressor work-list (k_work_metadata) on-device (CUDA-graph-safe, PDL-annotated); torch fallback provided.Qwen3NextSparseMoeBlock (renormalized top-k routing, shared expert via shared_expert_intermediate_size, fused-shared-expert packing, EPLB via Qwen4ExpMixtureOfExperts protocol). Only additions: SP-MoE rejected under HC; n_shared_experts derived from config.nvidia/mtp.pyget_mtp_target_hidden_states() β the multi-stream pre-final-mixer hidden [T, HCΒ·H] ("scheme A"), so the drafter's first step feeds a real HC backbone state; QSA side caches keep updating with skip_topk semantics; GDN/short-conv state shapes account for num_speculative_tokens.low_latency_gemm.py: swaps in a skinny-GEMM path for HC's tiny projections (MΓ320-ish) at model init.model_state.py: Qwen4ExpModelState (per-forward state object for the runner, incl. ngram kwargs preparation).---
(Inferred from searches of the Atlas tree; confidence noted.)
| Area | Atlas status | Evidence / notes |
|---|---|---|
| Gated DeltaNet | Likely present or close β Atlas already runs Qwen3-Next-class hybrids; search for gated delta/gdn/ssm hits in the mamba/linear-attention paths (medium confidence β exact kernel parity with vLLM's QwenGatedDeltaNetAttention not fully verified). | If present, main gap is gqa_interleaved_layout=False handling and num_spec-extended conv state. |
| Hybrid (GDN+full) scheduling / mamba-style state cache | Partially exists β Atlas has per-request recurrent state for its existing hybrid models, but no notion of *two different* state kinds (GDN + short-conv) with different page sizes / TP-replication. | vLLM's get_mamba_specs_from_config returning a tuple of specs and taking max page size is the pattern to mirror. |
| QSA sparse attention | Missing. No indexer, no block-topk sparse paged attention kernel. Atlas has dense paged attention only. | |
| Indexer + side caches | Missing. No CircularBufferSpec analogue (per-request fixed ring block), no MLAAttentionSpec-with-tokens_per_state analogue (compressed cache tied to main block table). | |
| PLE / n-gram embeddings | Missing. No per-layer embedding branch, no hashed n-gram lookup, no short dilated conv state, no ngram_context plumbing through the scheduler/runner. | |
| Hyper-connections | Missing. No multi-stream [T, HCΒ·H] hidden state, no gated mix/combine, no fused combine+norm kernel. Atlas residual flow is single-stream fused-add+rmsnorm. | |
| MoE | Exists (routing, shared expert, expert-parallel). Gaps: fused-shared-expert packing semantics matching qwen3_next, EPLB-style metadata hooks, and the SP-MoE-rejection interaction with HC. | |
| MTP | Partially exists (Atlas has spec decode / MTP for existing models). Gap: feeding multi-stream hidden to the drafter, skip_topk reuse, spec-aware state shapes. | |
| Config plumbing | Missing qwen4exp config: hc/ple/ngram/qsa fields + validation (indexer_kv_heads=1, budget/ratio β {512,2048}, ring divides block size, etc.). | |
| Raw input tokens to model | Needs check β Atlas must pass input_ids, query_start_loc, ngram_context into the model forward (vLLM: requires_raw_input_tokens). |
---
| Feature | vLLM mechanism (files) | Atlas status | Port difficulty |
|---|---|---|---|
| Config + validation | models/qwen4_exp/config.py subclass of Qwen3NextConfig; strict QSA/PLE validators | Missing | Low |
| Multi-stream HC state | hidden.repeat(1,4) through stack; delayed combine (nvidia/hyperconnection.py, model.py) | Missing | High (touches every layer's tensor shapes) |
| HC mix/combine kernels | Triton hc_combine_norm, hc_gate_mix, hc_silu, grouped GemmaRMSNorm; merged down+inject GEMM padded to 16 | Missing | Medium (custom CUDA/Metal/C++ kernels in Atlas; fusions matter for perf) |
| Gated DeltaNet | Reuses qwen3_next QwenGatedDeltaNetAttention + mamba state calculators | Likely exists (verify) | LowβMedium |
| Dual state kinds (GDN + short-conv) | Two MambaSpecs, max page size, tp_replicated short-conv, mamba_cache_mode=align | Partial (single state kind) | Medium |
| PLE n-gram branch | nvidia/ple_layer.py: hashed n-gram lookup (~20M rows) + dilated short conv on HCΒ·H channels, ngram_context across requests | Missing | High (new cache kind + runner plumbing + big table memory) |
| QSA sparse attention | Merged owner + opaque custom op; Triton qsa_sparse_paged_attention over manager pages + topk indices | Missing | High |
| Indexer + side caches | indexer_qsa.py, qsa_cache.py: raw-key ring (CircularBufferSpec) + compressed keys (MLAAttentionSpec.tokens_per_state), fused pre-indexer, on-device metadata kernel | Missing | High |
| MoE | qwen3_next MoE reuse + EPLB + fused shared expert | Exists | Low |
| MTP | Multi-stream target hidden buffer; skip_topk; spec-aware state sizes | Partial | Medium |
| Weight loading quirks | HC merged GEMM mapper, QSA scale remap, non-persistent skips | Needs equivalents in Atlas loader | LowβMedium |
| Low-latency skinny GEMM | low_latency_gemm.py for HC projections | Missing | Low (GB10 cublasLt likely fine; measure) |
---
Phase 1 β config & skeleton (1β2 wks).
Qwen4ExpConfig/TextConfig with all hc/ple/qsa fields and port vLLM's validators verbatim (they encode kernel constraints: indexer_kv_heads==1, budget/ratio β {512,2048}, rotary_dim β€ indexer_head_dim, ring capacity divides block size, ple_embed_dim % ((ngram_size-1)*heads_per_ngram) == 0).decoder_sparse_step/mlp_only_layers.Phase 2 β hyper-connections (highest structural impact, do early).
[T, HCΒ·H]; implement mix/combine/combine_and_mix with vLLM's delayed-combine dataflow β it is what keeps the extra HCΒ·H bandwidth to ~1 extra read+write per block instead of per mix+combine. Write fused combine+RMSNorm and gate-mix kernels; merge down+inject into one GEMM padded to 16 rows; keep HC projections un-quantized and un-TP'd (vLLM: disable_tp=True, without_modelopt_fp4 on QKV).Phase 3 β GDN + dual state cache.
QwenGatedDeltaNetAttention semantics (non-interleaved layout, a/b gating, conv+SSM states, spec-token extension).get_mamba_specs_from_config. Adopt "align"-style prefix-cache semantics only; vLLM rejects all.Phase 4 β PLE.
ngram_context (ngram_size-1 tokens) threaded through the scheduler/runner alongside query_start_loc. In Rust, the hash/lookup kernel is straightforward; the runner plumbing (raw input tokens to forward, per-request boundary masking) is the real work.Phase 5 β QSA.
FullAttentionSpec BF16 cache + indexer side branch, wrapped as one opaque transaction (Atlas's graph capture must treat indexβKV-writeβsparse-attend as one node, like qwen4_exp_qsa_with_output).compress_ratio + num_spec rounded to groups, must divide block size) and compressed-key cache whose block table shares the main KV block table lifecycle (vLLM's tokens_per_state trick β in Atlas, alias the compressed cache's page mapping to the main block table at 1/ratio density).budget + ratio - 1, -1 padded), and a sparse paged GQA kernel consuming logical indices. Port vLLM's on-device metadata kernel semantics (token_to_req, logical_positions, slot mappings, compressor work-list) into Atlas's CUDA-graph-safe metadata builder.Phase 6 β MTP + polish.
skip_topk reuse on draft steps, spec-aware state shapes; then EPLB/fused-shared-expert parity and low-latency skinny GEMM tuning (measure on GB10 before porting vLLM's custom path).Suggested ordering rationale: HC changes the tensor contract of the whole stack (do first, once); PLE and QSA both depend on HC state shapes and on the generalized state manager; MTP last.
---
ple_dense_layer_id tables β confirm sizing.)skip_topk reuse, +1 conv-kernel slack for short-conv/GDN states β subtle; vLLM's comments encode hard-won edge cases worth mirroring in tests.model.py; text-only first would de-risk.Research was done against the PR #53896 tree in vllm (model package vllm/models/qwen4_exp/{common,nvidia,amd}, config in vllm/transformers_utils/configs/qwen4_exp.py, registry entries at vllm/model_executor/models/registry.py:114-117 and :670) and the Atlas tree (crates/atlas-core, crates/spark-runtime, crates/spark-model). Where I could not fully trace a vLLM function to its leaf (notably the exact stream-collapse op feeding Qwen4ExpModel.norm), I say so explicitly rather than guess.
---
vllm/transformers_utils/configs/qwen4_exp.py defines Qwen4ExpConfig with every knob from the reference: ngram_size/ngram_vocab_size_base/emb_size/hidden_size, layer_types + num_mtp_layers, linear_* (GDN), full_attention_interval, topk/index_topk/index_n_heads/index_kv_heads/index_hidden_size/indexer_filter_size/indexer_rope_interleave, hc* (count/method/params/final/norm/infer_skip), norm_topk_prob, scoring_func, routed_scaling_factor, n_group/topk_group, use_qsa, ple_layer_ids, start_compress_layer, use_mtp, num_nextn_predict_weights.Qwen4ExpModelArchConfigConvertor (model_arch_config_convertor.py:645) maps HF β vLLM ModelConfig; Qwen4ExpConfig.update_config derives mamba_ba/num_heads/head_dim from the linear_* fields, builds layer_types (defaulting full_attention_interval=4), and forces hc_method="gated_residual", hc_final_method="gated_residual".vllm/config/model.py:1100-1106 sets hf_config.use_qsa = use_qsa and num_experts > 1 β QSA is gated on MoE presence.vllm/model_executor/models/config.py (Qwen4ExpForConditionalGenerationConfig, Qwen4ExpMTPConfig at :900) computes mamba_page_size_padded (conv + recurrent state bytes), aligns it to the attention page size, and sets skip_select_block, num_speculative_tokens = num_mtp_layers, disable_cascade_attn = True.registry.py:114 (Qwen4ExpForCausalLM β vllm.models.qwen4_exp) and :670 (Qwen4ExpMTP).common/gdn.py::Qwen4ExpGatedDeltaNet builds in_proj_qkvz (β key|value|z) and in_proj_ba (β b, a) as separate MergedColumnParallelLinear (the reference's "must stay separate" rule, enforced structurally), plus out_proj as RowParallelLinear.MambaMixer2Spec (_Qwen4ExpGDNMamba2Spec, gdn.py:42-54): the recurrent_state (FP32 per mamba_ssm_cache_dtype) and the short-conv state (_CONV_STATES_DTYPES = BF16), with get_mamba2_state_indices_layer_offset for multi-GDN-layer-per-request indexing.causal_conv1d_fn prefill / ..._update decode) β gated delta rule (chunked kernel prefill, gdn_attention decode) β RMSNorm-gated output (use_qk_l2norm) β out_proj.nvidia/model.py:729-735 (get_linear_attention_spec) and :737-756 (get_attention_spec) pick Qwen4ExpGatedDeltaNet vs Qwen4ExpMLA per layer_types[i].nvidia/attention.py::Qwen4ExpMLA = QwenMultiTokenRoutingMLA (one shared QProjRouter + per-topk-slot QProjMain/KVProj) with use_ngram_attn=True, so it calls nvidia/ops/qsa.py::qsa_indexer_forward instead of the DeepSeek rope/index path.qsa_indexer_forward (qsa.py:665):use_indexer_from_kv=True, qsa.py:727-732): kv_state = kv_buffer[:, :config.kv_lora_rank], rope half at offset kv_lora_rank. No separate indexer KV allocation.indexer_filter_size hidden states (index_q_from_hidden_proj, qsa.py:700-725), not a projection of the current token.q_rope = index_q_from_nope.view(B,S,nh,128).permute(...).flatten(2) then indexer_rope(q_rope, ngram_roped_ids) (qsa.py:734-742), with indexer_rope_interleave selecting the interleave flag.qwen_sparse_attention_qk_bf16_m930_fp32 (or fp8_m1600 when indexer_kv_dtype=="mxfp8", with MXFP8 quant of q and of the KV cache slices).top_k_per_row / persistent_topk / cooperative_topk (SM90+ cluster kernel, csrc/libtorch_stable/cooperative_topk.cu, kβ{512,1024,2048}, β€32 rows) chosen by row count and alignment (qsa.py:788-800); topk_buffer = full(-1) then topk_indices += cu_seqlen makes them global token offsets.qwen_sparse_attention_block_pool_bf16/fp8 reduces each indexer_block_size group, then a second top-k picks topk//indexer_block_size blocks, which are re-expanded to token indices (qsa.py:812-840).per = arange(topk); per[::2]=idx[:topk//2]; per[1::2]=idx[topk//2:] (qsa.py:843-845) β the reference's "even slots = first half, odd = second half".mla.forward_cuda(..., topk=indices) (FlashMLA/triton_attention with top-k gather; topk_buffer is zero-padded to topk_pad_len for CUDA graphs).model.py:115-116) because top-k selection is per-request.common/ngram_embedding.py::Qwen4ExpNGramEmbedding (referenced from nvidia/model.py:34, :421-441): builds the n-gram token ids from the token stream, hashes them into the shared embed_tokens table with per-layer offsets (ngram_embedding_offsets, emb_size vs hidden_size), and produces the per-layer embedding tensor [T, hc_count, emb_size].Qwen4ExpModel.embed_input_ids (nvidia/model.py:758-782) returns a 3-D tensor [T, hc_count, emb_size] (HC streams already expanded) and stashes self._ple_input_trusted = True for the MTP path.Qwen4ExpModel.compute_ple_input (:784-799) is the re-embedding hook for MTP: it re-embeds the shifted token ids (input_ids[1:] + vocab, last = 0) so the drafter's PLE input matches its shifted embedding input.:801-832): the embedding is VocabParallelEmbedding; tp_rank == 0 broadcasts the full PLE tensor to all ranks (tp_group.broadcast), other ranks receive into a buffer. PLE is therefore replicated after broadcast, not sharded.:834-867): _mtp_share_and_slice_input does an all_gather of [input_ids, inputs_embeds, hc] on the first MTP stage and slices per stage β i.e. the target's hidden + PLE are handed to the drafter across PP/TP.[ngram_vocab, emb_size] table resident.vllm/model_executor/layers/hpc/hpc_ihc.py implements the gated_residual method: per-block hc_fn/hc_scale/hc_base parameters, a sigmoid gate per stream (no Sinkhorn), hc_head_fn/scale/base for the final collapse, and hc_infer_skip to skip the broadcast copies during inference.Qwen4ExpDecoderLayer (nvidia/model.py:188-336) applies self.attn(hs, ...) / self.mlp(hs, ...) where hs is the 3-D [T, hc_count, hidden] tensor β the HC mixing is inside the attention and MoE modules, so the residual highway is threaded through every sublayer.Qwen4ExpModel.forward (:886-948) keeps hc 3-D through all layers; self.norm(hc) collapses to [T, hidden] for logits. Open point: I could not locate the concrete hc_head/stream-collapse call used by qwen4exp in this tree β hc_head ops exist in vllm/model_executor/kernels/mhc/* and layers/mhc.py but those are wired to DeepSeek-V4's mHC, not to Qwen4ExpModel. Atlas must implement the collapse itself (see risks).Qwen4ExpSparseMoeBlock (nvidia/model.py:104-185): fused_experts with is_internal_routing=True, renormalize=norm_topk_prob, apply_router_weight_on_input=False, shared_experts=shared_expert_intermediate_size//moe_intermediate_size, routed_scaling_factor.FusedMoE is constructed with scoring_func, top_k_group, num_expert_group, n_shared_experts, expert_map β i.e. the grouped (noaux_tc-style) routing path, matching scoring_func β {sigmoid, sqrt_pre_softmax} + topk_group/n_group.gate/gate.e_score_correction_bias with a router.* β gate.* weight mapper (:293-297).nvidia/mtp.py::Qwen4ExpMTP (:368) is a full standalone model (own Qwen4ExpModel body + Qwen4ExpSparseMoeBlock + lm_head), registered as Qwen4ExpMTP.Qwen4ExpMTPProposer(EagleProposer) (vllm/v1/spec_decode/qwen4_exp.py:21) drives it; num_speculative_tokens = num_mtp_layers is set by the config class.set_inputs_embeds_for_qwen4exp_mtp (nvidia/mtp.py:354) + compute_ple_input + _mtp_share_and_slice_input, i.e. shifted token ids re-embedded, target hidden concatenated/projected, and the PLE re-computed for the shifted ids.load_weights drops mtp.* from the target (orig_to_new_substr={"mtp.": None}, nvidia/model.py:1007) and drops model.visual.* in text-only mode (:466-471).Qwen4ExpForConditionalGeneration (:652) wraps the text model with a Qwen3-VL-style QwenVisionTransformer, get_input_embeddings re-embeds mm_placeholders after the PLE injection, and deepstack embeddings are injected per layer. Qwen4ExpForCausalLM is a subclass with language_model_only=True.---
| Feature | Atlas evidence | Status |
|---|---|---|
| Config plumbing | crates/atlas-core/src/config.rs has hc_mult, num_experts, num_experts_per_tok, num_experts_per_toks (per-layer K, :206-208), mamba_num_heads/mamba_head_dim, conv_dim; parsers live in crates/atlas-core/src/config/parsers/*.rs; factory dispatch at crates/spark-model/src/factory.rs:109-113 (supported list: qwen3_next, qwen3_5_moe, β¦, deepseek_v4 β no qwen4exp) | Missing for qwen4exp; infra exists |
| GDN (Gated DeltaNet) | crates/spark-model/src/layers/qwen3_ssm/ β full GDN: init.rs (gated_delta_rule_decode, _f32_*, wy2/wy3 variants), trait_prefill_gdn.rs + trait_prefill_gdn/batched.rs (FLA recompute_wu β chunk_delta_h_ksplit β chunk_fwd_o, plus FlashInfer tensor-core path behind ATLAS_GDN_FLASHINFER=1), trait_decode_batched_conv_gdn*.rs (fused conv+GDN decode, K=2..8 for spec verify), ssm_forward.rs | Exists and is mature (Qwen3-Next lineage) |
| SSM state paging | crates/spark-model/src/ssm_reserve.rs, model/ssm_tier/fingerprint.rs, weight_loader/qwen35_dense.rs | Exists |
| MLA | crates/spark-model/src/layers/qwen3_attention/ (paged decode, FP8/2-bit KV, RoPE) | Exists |
| QSA / top-k sparse attention | No indexer anywhere (indexer, index_topk, topk_attention β no matches). Nearest thing is DeepSeek-V4 CSA/HCA compressed-KV (layers/qwen3_attention/types_weights.rs:80, init_arch_gates.rs:37, prefill/cache_skip_v4.rs:415) β a fixed-ratio compressor, not learned top-k selection | Missing |
| Per-row top-k kernel | Only moe_topk_softmax* (layers/moe/init.rs:93-101) β softmax top-k for routing, not FP32 logit top-k over a KV row | Missing |
| PLE / n-gram | Zero matches for ngram, per_layer_embed, ple across crates/ | Missing entirely |
| Hyper-connections | crates/spark-model/src/layers/ops/hyper_connection.rs implements mHC (Sinkhorn comb, hc_pre/hc_post/hc_head) for DeepSeek-V4; buffers [M, hc_mult, hidden] in crates/spark-runtime/src/buffers/{sizes.rs:449-465,accessors.rs:149-157}; config hc_mult/hc_sinkhorn_iters/hc_eps | Partially exists β wrong variant. No sigmoid gated_residual mode |
| MoE grouped routing | layers/moe/{mod.rs,init.rs,forward*.rs} β W4A16/FP8/W8A8 grouped GEMM, shared-expert fusion, sort-by-expert, EP dispatch (layers/ep_dispatch.rs), num_experts_per_toks per-layer K, correction_bias preflight (preflight.rs:299-305) | Exists; needs scoring_func/topk_group/n_group verification |
| MTP | layers/mtp_head.rs (single-layer drafter, NVFP4/FP8/BF16, drafter-context prefill), layers/mtp_multi.rs, layers/deepseek_v4_mtp.rs, speculative.rs (DraftProposer), weight_loader/deepseek_v4/mtp.rs | Exists; no PLE-aware input construction |
| CUDA graphs / shape stability | layers/qwen3_attention/decode/run_paged_decode.rs, model/trait_impl/* | Exists; top-k buffer padding is new |
---
| Feature | vLLM mechanism (file) | Atlas status | Port difficulty |
|---|---|---|---|
| Config + registration | configs/qwen4_exp.py, `Q |
The tree is the PR #53896 branch. The model lives under vllm/models/qwen4_exp/ (with an nvidia/ sub-tree of Triton/CUDA ops). I read the QSA pre-indexer kernel in depth; the other features are described from their file locations and the architecture reference.
Model definition & config. vllm/models/qwen4_exp/model.py defines the decoder stack and registers the qwen4exp architecture. Config conversion in vllm/config/model.py maps the HF config (hidden size, layer types, MoE dims, SSM dims, QSA dims, PLE dims, MTP depth) into vLLM's ModelConfig/CacheConfig. Layer types are per-layer: a mix of Gated DeltaNet (linear-attention/SSM) layers, QSA sparse-attention layers, and MoE FFN layers, plus per-layer n-gram (PLE) embedding layers.
Gated DeltaNet (linear attention / SSM). Implemented via the shared vllm/model_executor/layers/mamba/ + gated_delta_net kernels (chunked scan with a per-head recurrent state). Caching: a per-request fixed-size recurrent state (the "conv state" + "ssm state"), not a KV cache. Prefill runs the chunked parallel scan; decode runs the single-step recurrence. This is the same mechanism vLLM uses for Qwen3-Next / Falcon-Mamba, so the plumbing (state layout, slot allocation, prefix-cache semantics for the recurrent state) already exists.
QSA sparse attention + indexer. This is the novel piece. vllm/models/qwen4_exp/nvidia/ops/qsa_pre_indexer.py (508 lines, read in full) is a fused Triton kernel that, in one launch:
weight + 1.0, fp32 accumulate) and applies NeoX RoPE, with optional mrope (interleaved temporal/height/width rotary pairs selected by pairs % 3 masks, MROPE_H/MROPE_W constexprs) β see _norm_rope, lines 10β80;COMPRESS_RATIO (one work item per completed compression group, k_work_metadata), and commits the request's current raw-K suffix into a circular raw state cache (state_cache, state_slots, state_block_table) β the pid < num_k_work branch, lines 196β400.So QSA keeps two caches: a small circular raw-K window (for the indexer's local attention) and a compressed-K cache (for the sparse long-range attention). The indexer scores queries against the compressed cache to select which raw/compressed K blocks the full attention reads. The kernel is tiled over (token, head) for Q and over compression groups for K, with TILE_T_Q/TILE_H_Q chosen by token count (β€4096 β 2Γ2, else 2Γ4), num_warps=1.
Per-layer n-gram (PLE) embeddings. PLE layers inject n-gram-derived embeddings per layer. In this tree they are computed inline (the baseline); the offload variants (UVA/mmap) are in the separate PRs #53899/#54129/#54371 and are not in this tree. The baseline keeps PLE tables in HBM and gathers per-layer.
Hyper-connections. Residual "hyper-connection" mixing across the per-layer branches is implemented as extra learned mixing weights applied in the decoder block forward (see the block forward in model.py); it is a small per-token linear combine, not a new cache.
MoE routing. Standard grouped-expert MoE with the existing vLLM fused-MoE kernels (top-k gating, expert parallelism optional). Nothing qwen4exp-specific beyond dims.
MTP. Multi-token-prediction head(s) per the config depth, using the existing MTP scaffolding (draft head + shared trunk), with the recurrent/SSM state carried across the MTP steps.
Atlas (Rust, GB10) has no qwen4exp in the tree. Searching for the feature keywords:
gated_delta, no deltanet, no ssm state manager found. Atlas's attention path is KV-cache-centric (paged KV). β Missing.qsa, no indexer, no compressed-K cache, no circular raw-state cache. Atlas has generic paged attention but no sparse-selection indexer and no dual (raw + compressed) K cache. β Missing.ngram, no ple, no per_layer embedding gather. β Missing.hyper_connection. β Missing.moe/expert hits in the FFN layer code), so grouped-expert routing exists and can be reused. β Partially exists (reusable).mtp scaffolding found. β Missing (or minimal; needs the draft-head + shared-trunk path).pairs % 3) is not present. β Partially exists.| Feature | vLLM mechanism | Atlas status | Port difficulty |
|---|---|---|---|
| Gated DeltaNet (SSM) | Chunked parallel scan (prefill) + single-step recurrence (decode); per-request recurrent state, not KV | Missing (KV-centric) | High β new state type, new kernels, new cache manager |
| QSA sparse attention | Fused pre-indexer (norm+RoPE+K-compress+circular raw state) + indexer selection + sparse attention over compressed/raw K | Missing | High β dual K cache + indexer + sparse attention |
| Indexer / compressed-K cache | COMPRESS_RATIO compressed cache + circular raw-K window, slot/block tables | Missing | High |
| mrope (interleaved t/h/w) | pairs % 3 axis masks in fused kernel | Partial (plain RoPE) | Medium |
| PLE per-layer n-gram | Inline per-layer gather (baseline); offload in separate PRs | Missing | Medium |
| Hyper-connections | Per-block learned residual mixing | Missing | LowβMedium |
| MoE routing | Fused grouped-expert MoE | Exists (reusable) | Low |
| MTP | Draft head + shared trunk, state carried | Missing | Medium |
| Config plumbing | qwen4exp arch + per-layer type mapping | Missing | Low |
qwen4exp arch, per-layer type table (DeltaNet / QSA / MoE / PLE), and the decoder-block forward with hyper-connection mixing. Reuse the existing MoE path. This unblocks everything else and is mostly plumbing.qsa_pre_indexer as a fused kernel (norm + mrope + K-compress + circular raw-state commit). Add the two caches (compressed-K at COMPRESS_RATIO, circular raw-K window) with slot/block tables. Then the indexer (score Q vs compressed cache β select blocks) and the sparse attention over the selected raw/compressed K. Keep the single-launch K-work/Q-work split; it's the design decision worth borrowing.pairs % 3 masks). Fold into the QSA pre-indexer kernel as vLLM does rather than a separate op.Where to diverge for Rust/GB10: (i) implement the fused pre-indexer as a CUDA kernel in Atlas's kernel harness rather than Triton; (ii) if GB10's memory hierarchy favors it, consider fusing the indexer scoring into the same kernel as the K-compress (vLLM keeps them separate for register-shape independence β keep that separation first, fuse later only if profiling demands); (iii) keep the recurrent-state cache as a first-class cache type in Atlas's cache manager rather than shoehorning it into paged KV.
COMPRESS_RATIO + circular raw-window interaction is subtle (the raw-suffix commit in work-item-zero, lines 196β400). This is the highest-risk kernel to port; needs a golden-output test against vLLM.pairs % 3 selection with MROPE_H/MROPE_W bounds is easy to get off-by-one; test with 2D/3D position inputs.Special tokens (if quoting the chat template): [think], [/tool_call], [IM_START].
Same comparative format as round 2, new blueprint: the llama.cpp tree that actually serves Flash-Next in these very benches (PR #27742). 2026-08-31.
| Config | Wall | LLM steps | Tool calls | Input tok | Output tok | Report | Grade* |
|---|---|---|---|---|---|---|---|
| E2 (FN Q3) | 84 min | 113 (self-stopped) | 149 | 5.83M | 15.3K | complete, 24.0 KB | 9.5/10 |
| A (FN Q4) | 43 min | 116 (self-stopped) | 145 | 5.94M | 14.7K | complete, 21.1 KB | 9/10 |
| P (prod 27B) | 115 min | 133 (hit cap) | 134 | 6.61M | 10.9K | forced finale, 10.9 KB | 4.5/10 |
*Every cited llama.cpp path was checked against the tree; the boldest mechanism claims were verified line-by-line.
E2: 9.5/10 β zero fabrications this round, and every spot-check landed exactly (the ple_history struct with its
seq_rm/cp/keep/add/div mirrors, the signed-sqrt PLE gate, the converter's np.memmap trick, ggml_solve_tri
in the delta-rule, the FWHT matmul hint). Deepest implementation analysis of the whole series β a total reversal of its round-2 confabulation,
suggesting that failure was variance, not a Q3 trait. A: 9/10 β equally sound, with unique correctness insights (the indexer cache
reusing the attention cache's slot layout so the two "cannot drift"; the mirrored-not-split multi-GPU indexer; precomputed Hadamard matrices);
one garbled filename (wht_bf16.cu for the real fwht.cu). P: 4.5/10 β decent llama.cpp half, but its Atlas half is confidently wrong
(declares GDN/MTP/hyper-connections "missing" β all verified present in rounds 1β2): context pruning evicts its early research and it
back-fills with guesses. Third run out of three where it researched to the hard cap and needed the toolless forced finale.
Bonus robustness note: a leftover contradictory heading instruction in the prompt ("vLLM vs Atlas" vs the llama.cpp marker) was noticed,
resolved correctly, and documented by both 125B configs.
*(Note on title: the task brief asked for a "vLLM vs Atlas" heading; the actual comparison performed is llama.cpp PR #27742 vs Atlas, so the report uses the accurate title as instructed by the final directive.)*
---
qwen4exp)llama.cpp adds a new arch LLM_ARCH_QWEN4EXP (src/llama-arch.cpp:43) with a dedicated model-builder src/models/qwen4exp.cpp (~1,148 lines), a new memory class llama_memory_hybrid_idx (src/llama-memory-hybrid-idx.{h,cpp}), hparams extensions (src/llama-hparams.h:253β291), a converter (conversion/qwen4exp.py), and two new GGML primitives (GGML_OP_GATED_DELTA_NET, GGML_HINT_SRC0_IS_HADAMARD). The model is composed of five architectural features, most of which are shared with an existing DeepSeek-V4 (deepseek4.cpp) and Qwen3.5 (qwen35*.cpp) code base β this reuse is llama.cpp's single most important design property, and it maps well onto Atlas, which already ships DeepSeek-V4 and Qwen3.5/Qwen3.6.
dsv4_hc_mult, dsv4_hc_sinkhorn_iters, hc_low_rank, dsv4_hc_eps (src/llama-hparams.h:265β276). The converter writes hc_count / hc_lowrank (conversion/qwen4exp.py:62β63).hc_mult-stream hidden state; n_embd_out_impl = dsv4_hc_mult * n_embd (qwen4exp.cpp:27, same trick as deepseek4.cpp:55) so the LM head consumes the collapsed/expanded stream correctly.GGML_HINT_SRC0_IS_HADAMARD on a MUL_MAT and skip the materialized Hadamard matrix entirely (ggml-cuda.cu:1820, ggml-cpu.c:1262, ggml-metal-ops.cpp:2338, ggml-blas.cpp:422, SYCL fwht.hpp). Sinkhorn normalization of the HC weight matrices is done with ggml_sinkhorn using the shared DSV4 path.llama_memory_hybrid (attn cache + recurrent cache) is extended by llama_memory_hybrid_idx (src/llama-memory-hybrid-idx.h:18β117), which adds a third cache β one indexer key per token β that is *cell-aligned* with the attention cache: "same size, padding, stream count and slots, so cell j is the same token in both" (header comment, lines 13β16). It has its own hparams_idx because a llama_kv_cache instance keeps a hparams reference (lines 99β103).llama_memory_hybrid_idx_context carries a parallel ctx_idx whose next()/apply() are stepped in lockstep with the attn/rs contexts (.cpp:540β558), plus get_n_stream() for the batched/streamed layout.struct ple_history { next_pos; toks } per sequence, tagged [TAG_PLE_HISTORY] (llama-memory-hybrid-idx.h:81β106). Crucially, it is kept consistent through *all* cache mutation ops β seq_rm/cp/keep/add/div each have a ple_hist_* mirror (lines 109β113) β and it is serialized into the session state blob (ple_hist_state_write/read, lines 115β116). This is the correct home for it in any engine: it is per-sequence state that must follow rollback, branch (seq_cp), prompt-caching prune (seq_keep) and position rewrites (seq_add/div).indexer_n_head/head_size/top_k, MSA-style indexer_block_size, indexer_local_blocks, and a per-layer is_indexer_full_impl array β indexers are either "full" (1) or "shared" (0), where shared layers reuse the top-k of the previous full layer (src/llama-hparams.h:253β263, is_indexer_full()).indexer.index_qk_proj.weight into separate q/k tensors (conversion/qwen4exp.py:130β137), and zero-centers Gemma-style gammas (indexer.q_layernorm/k_layernorm, ple.norm_{key,query,conv}) by +1 (lines 140β142).set_input_qsa(cell_blk, blk_cells, blk_pos, bias, ubatch, ratio) (llama-memory-hybrid-idx.h:164β171, impl .cpp:576β676). Key design decisions visible in that code:.cpp:616β652).F32 [n_kv, n_tokens/ns, ns]: -inf invisible, 0 selected-block, +1e9 "always visible" for the incomplete tail block (matching the reference), with an explicit note that +1e9 is finite so it can never meet -inf and produce NaN (lines 662β674).blk_of = -1) but clamped to block 0 to keep the gather in range (lines 624β651).qwen4exp.cpp:793 calls build_recurrent_attn(...), the shared helper in src/models/delta-net-base.cpp:527 used by qwen3next/qwen35/qwen35moe/bailingmoe3.delta-net-base.cpp:442β447):g, decay_mask = exp(tril(g_cs_j - g_cs_i)), and a ggml_solve_tri call to solve the (I + tril(k k^T Ξ²)) system (line 166), i.e. the delta-rule UT transform expressed as a triangular solve. Supports both scalar-g GDN and KDA (kda when g is per-channel, chunk size 16 vs 64, lines 61β145).ggml_gated_delta_net(q,k,v,g,b,s,K) β a real GGML op (ggml.h:572, 2590) with CUDA/CPU/Vulkan/SYCL/Metal/OpenCL/Hexagon implementations, which additionally emits K state snapshots into its output so rollback groups can be written with one ggml_cpy (delta-net-base.cpp:567β603).build_conv_state, lines 449β525) concatenates the rolling conv history with the new tokens and writes back the tail; with n_rs_seq > 0 it writes K snapshot slots, relying on split_equal(n_keep_tail) to keep the tail tokens in one ubatch ([TAG_RECURRENT_ROLLBACK_SPLITS], lines 498β521).src/llama-hparams.h:278β291): ple_ngram_size, ple_heads_per_ngram, ple_conv_kernel, derived ple_n_heads = (ngram_size-1)*heads_per_ngram, ple_head_dim, ple_eos_token_id, ple_image_token_id, per-layer is_ple_impl, and the hash constants ple_layer_multipliers[], ple_head_offsets[], ple_head_vocab_sizes[] (int64, 45-bit multipliers).ple.layers, ple.ngram_size, β¦ (llama-arch.cpp:299β300); read at load in qwen4exp.cpp:40β59 with ple_ngram_size β [2, LLAMA_MAX_PLE_NGRAM].ngram_size-1 tokens, which a decode ubatch does not carry. That history is the ple_history struct in the memory layer (Β§2). EOS resets the window; image positions substitute ple_image_token_id because an image is fed as an embeddings-only batch with no placeholder ids to hash (conversion/qwen4exp.py:85β89).build_ple, qwen4exp.cpp:1040β1147):rows tensor of size n_heads * n_tokens β the hashed row indices β gathered out of the single giant table: ggml_get_rows(model.per_layer_tok_embd, rows) then reshaped to [head_dim*n_heads, n_tokens] (lines 1054β1062). This is the *only* place the ~100 GB-scale table is touched, and it is a pure gather β an ideal CPU/mmap-offload candidate.ple_key/ple_value projections, then a grouped RMS norm over hc streams with a weight spanning hc*n_embd (lines 1068β1077).1/sqrt(n_embd), then a signed square root sign(s)Β·sqrt(|s|) before sigmoid (lines 1080β1084) β an unusual op spelled out as sqrt(clamp(abs(s))) Γ sgn.hc streams (ggml_repeat_4d) and gated (lines 1088β1091).ple_ngram_size: implemented as a sum of shifted copies, explicitly because ggml_conv_1d_dw is documented as unreliable (lines 1099β1141). The conv weight is stored in file type and cast to F32 before multiplying F32 activations (lines 1133β1137).(kernel-1)*dilation rows of hc_dim, stored inside the recurrent-state row (n_embd_r() - ple_conv_state(), line 1115) via the same build_conv_state_at machinery used by the GDN conv (lines 996β1038), so chunked prefill matches single-shot exactly.hidden + gated + silu(conv_out) (line 1147).ple_conv_state() = (ple_conv_kernel-1) * ple_ngram_size * dsv4_hc_mult * n_embd (llama-hparams.cpp:249) β PLE reuses the *recurrent* cache dimensioning, so a PLE-only layer still occupies an rs slot.conversion/qwen4exp.py): inherits the Qwen3.5 GDN + interleaved-MRoPE mixins; drops the MTP block (supports_mtp_export = False, line 30). Reads int64 hash constants straight from the checkpoint, bypassing prepare_tensors()'s float32 cast, because 45-bit multipliers would silently round (lines 43β56, 116β124). The 128-shard n-gram table would peak ~300 GB RSS, so each shard is written directly into an np.memmap at its final row offset and dropped, then the file is re-mapped and emitted as one per_layer_token_embd.weight (lines 149β227).src/llama-quant.cpp): per_layer_token_embd.weight is treated as a token-embedding category (line 101β104) so it follows --token-embedding-type, but an explicit --tensor-type regex can name it separately because it's a huge standalone table (lines 696β712). per_layer_model_proj is never quantized (line 324); ssm_conv1d and indexer q_proj/k_proj are excluded as tiny (lines 332, 336β337).per_layer_token_embd is declared LLM_TENSOR_LAYER_INPUT with GGML_OP_GET_ROWS (llama-arch.cpp:887), which is what makes --override-tensor CPU/mmap offload work for it β the gather is the only consumer, so the table never needs to be resident.---
| Feature | Atlas status | Evidence | ||
|---|---|---|---|---|
| Hyper-connections (mHC) | Exists (DeepSeek-V4). FP32 [M, hc_mult, hidden] highway in the buffer arena, fused hc_pre/hc_post/hc_head kernels incl. Sinkhorn, wired into the Qwen3-attention layer trait for prefill, decode and multi-seq. | kernels/gb10/deepseek-v4-flash/nvfp4/hyper_connection.cu; crates/spark-model/src/layers/ops/hyper_connection.rs; crates/spark-runtime/src/buffers.rs:84, buffers/sizes.rs:51,451, buffers/accessors.rs:149; layers/qwen3_attention/{types.rs:101, init.rs:153, types_weights.rs:142, trait_impl/prefill_inner.rs:39, trait_impl/decode_inner.rs:30, trait_impl/multi_seq/mod.rs:52}; crates/atlas-core/src/config/parsers/deepseek_v4.rs:210 | ||
| Gated delta net / linear attention | Exists (Qwen3.5/3.6 + qwen3_next). Full GDN prefill (chunked) + decode (single & multi-seq), conv+GDN fused decode variants, exact and multi variants, plus a dedicated SSM state pool with snapshot/spill/tier management. | crates/spark-model/src/layers/qwen3_ssm/{mod.rs, ssm_forward.rs, trait_prefill_gdn.rs, trait_decode_batched_conv_gdn*.rs, gdn_flags.rs}; crates/spark-model/src/forward/qwen3_5/linear_attention.rs; crates/spark-model/src/model/{ssm_pool.rs, ssm_snapshot*.rs, ssm_batched_copy.rs, ssm_reserve.rs} | ||
| Hybrid attn+recurrent memory | Exists. Paged KV + a separately managed recurrent-state pool with snapshots, spill to lower tiers, fault-in, and batched copy. | crates/spark-model/src/model/ssm_pool.rs, ssm_snapshot*.rs, ssm_tier/; crates/spark-model/src/ssm_reserve.rs | ||
| MoE / experts | Exists, incl. grouped decode, EP dispatch, NVFP4/MXFP4 routed experts. | layers/moe/, layers/ep_dispatch.rs, layers/moe_grouped_decode_tests.rs, weight_loader/deepseek_v4/* | ||
| Sparse attention / indexer | Partially exists, but a different mechanism. Atlas has DeepSeek-V4 CSA/HCA window compression (a compressor kernel + attention over `[raw causal | compressed] KV + sink) and config fields for a *semantic indexer* (indexer_n_head/head_dim/top_k), but the indexer fields appear to be config-only; there is no top-k-over-blocks selection path, no indexer key cache, and no cell_blk/blk_cells/bias` plumbing. | kernels/gb10/deepseek-v4-flash/nvfp4/{csa_compress.cu, prefill_attn_compressed.cu}; crates/atlas-core/src/config.rs:267β278; layers/qwen3_attention/prefill/cache_skip_v4.rs:414β490; layers/qwen3_attention/prefill/paged_v4.rs:187; weight_loader/deepseek_v4/assemble.rs:366β420 | |
| PLE / n-gram hash embeddings | Missing. No per_layer_*, no hashed embedding table, no n-gram history. (ngram in Atlas refers exclusively to the unrelated n-gram *speculative decoding* proposer.) | grep for `per_layer | ple_ | ngram in crates/ β only spark-server/src/ngram.rs (spec-decode) and unrelated IndexError` hits |
| MTP | Exists, incl. a DeepSeek-V4-specific MTP that reuses the V4 layer body (MLA + mHC + MoE) β the right precedent for a Flash-Next MTP if one is ever wanted. | layers/deepseek_v4_mtp.rs, weight_loader/deepseek_v4/mtp.rs, docs/deepseek_v4_mtp_support.md | ||
| MRoPE interleaved | Exists (Qwen3.5/3.6 VL path): T/H/W position streams staged per prefill chunk, mrope_interleaved config flag. | model/trait_impl/prefill_b/{mrope_pos.rs, stage_batched.rs, upload_meta.rs}, layer.rs:116β183, factory.rs:89 | ||
| Model registration for qwen4exp | Missing. factory.rs::loader_for_config matches qwen3_next, qwen3_5*, qwen3_6_moe, deepseek_v4, β¦ β no qwen4exp/Qwen4ExpForConditionalGeneration. | crates/spark-model/src/factory.rs:65β118 | ||
| Hadamard fast path for HC matmuls | Not found (no hadamard/fwht in Atlas); Atlas uses fused HC kernels instead. | grep hadamard in atlas β no matches |
---
| Feature | llama.cpp mechanism (PR #27742) | Atlas status | Port difficulty |
|---|---|---|---|
| Arch registration / hparams | LLM_ARCH_QWEN4EXP + LLM_KV_*/LLM_TENSOR_* tables; per-layer is_ple_impl, is_indexer_full_impl arrays | factory.rs string dispatch + atlas-core::config parsers (deepseek_v4.rs precedent) | Easy β mechanical |
| Hyper-connections | Shared DSV4 mHC; Hadamard hinted MUL_MAT + ggml_sinkhorn; n_embd_out_impl = hc_mult*n_embd | Full mHC already (fused CUDA kernels, FP32 highway, prefill/decode/multi-seq) | Easy β reuse V4 layer body; only the *low-rank* HC variant (hc_lowrank) may need a new branch |
| GDN linear attention | Shared llm_build_delta_net_base; GGML_OP_GATED_DELTA_NET fused op w/ K snapshots, or ggml_solve_tri chunked reference | Native Rust/CUDA GDN prefill+decode, conv+GDN fused, multi-seq, exact variants | EasyβMedium β already there; must confirm *scalar-g* GDN (not KDA) config and conv kernel=4 semantics match Qwen3.5's |
| Hybrid memory (KV + recurrent) | llama_memory_hybrid with rs rows packing conv + PLE conv history into n_embd_r() | Paged KV + ssm_pool + snapshot/spill/tier | Medium β Atlas's rs pool is *not* row-packed the llama.cpp way; PLE conv state needs a new per-seq state slot |
| QSA block-sparse attention | Third cell-aligned indexer cache + host-built cell_blk/blk_cells/blk_pos/bias; blocks cut the *position* line; additive Β±inf/1e9 bias; full/shared indexer alternation | CSA/HCA compressor exists; no top-k block selection, no indexer key cache | Hard β biggest new subsystem: new cache buffer, new selection kernel, paged-block gather, bias/mask integration into both prefill and decode attention |
| PLE n-gram hash embeddings | Host-side hash of token window (history in memory layer), get_rows gather from a giant table, grouped RMS norms, signed-sqrt sigmoid gate, dilated depthwise conv as sum-of-shifts, conv state in rs cache | Missing entirely | MediumβHard β math is simple; the work is (i) a new per-seq hash-history object wired into rollback/branch/prefix-cache, (ii) hosting a ~100 GB table, (iii) 3 new small kernels |
| PLE table hosting / offload | LAYER_INPUT + GET_ROWS β --override-tensor CPU/mmap; quantized as token-embedding type, name-overridable | Atlas has pinned-pack / tier / overlay machinery (model/pinned_pack.rs, token_overlay.rs, atlas-tier) but no embedding-table offload policy | Medium β needs a gather-from-host or tiered-table path; GB10 unified memory makes host-resident + cudaHost gather viable |
| MTP | Deliberately dropped at conversion (no_mtp = True) | V4-style MTP already implemented | N/A now β skip, matching llama.cpp |
| MRoPE interleaved | Inherited _Qwen35MRopeMixin | Already implemented for Qwen3.5/3.6 | Easy |
| Converter | conversion/qwen4exp.py: memmap-stitched 128-shard table, int64 constants read raw, qk-proj split, gamma +1 | Atlas weight loaders (weight_loader/deepseek_v4/assemble.rs, csa_ape.rs for exact-F32-constant handling) | Medium β the shard-stitching and int64-exactness traps apply verbatim to a Rust loader |
| Session/state persistence | ple_history serialized into the state blob alongside the caches | Atlas snapshots/spill cover KV+SSM; PLE history would need adding | Medium β easy to forget, catastrophic when wrong |
---
P0 β Registration + config (1β2 days).
Add qwen4exp to factory.rs::loader_for_config and a config/parsers/qwen4exp.rs modeled on deepseek_v4.rs. Reuse the existing hc_mult/compress_ratios/indexer_* fields (atlas-core/src/config.rs:233β278) β they already exist because of V4. Add new fields for PLE (ple_layers, ngram_size, heads_per_ngram, conv_kernel, head_dim, eos_token_id, image_token_id, and the three int64 constant arrays). Borrow llama.cpp's decision to keep these as per-layer arrays (is_ple_impl, is_indexer_full_impl) rather than predicates β Flash-Next's layer pattern is irregular.
P1 β Layer body: mHC + GDN + MoE + MRoPE (days, mostly wiring).
Assemble the layer from parts Atlas already has, exactly as weight_loader/deepseek_v4/assemble.rs assembles a V4 layer. This mirrors llama.cpp's own structure (qwen4exp.cpp inherits delta-net from qwen35 and HC from deepseek4). Two checks: (i) confirm the GDN is scalar-g (chunk 64), not KDA β llama.cpp distinguishes them by g->ne[0] == S_k (delta-net-base.cpp:31); (ii) confirm hc_lowrank handling, since llama.cpp exposes hc_low_rank separately from the V4 default. Divergence: do *not* port llama.cpp's Hadamard-hint trick β Atlas's fused hyper_connection.cu already fuses residual+norm+mix and is the better design for a GPU-first engine.
P2 β PLE (the differentiator; ~2β3 weeks).
PleHistory { next_pos: i64, toks: Vec<u32> } per sequence, owned by the scheduler/conversation state, not the layer. llama.cpp's lesson is the hard part: it must be mirrored on every cache mutation β rollback, seq_cp (branch/fork), seq_keep (prefix-cache prune), seq_add (position shift), and serialized with snapshots. In Atlas that means hooking model/ssm_snapshot*.rs, the prefix cache, and the spec-decode rollback paths (scheduler/spec_step.rs). Add an explicit untrusted sentinel (next_pos = -1) and pad the window front with EOS, as llama.cpp does.prefill_b/stage_batched.rs), producing an I32 [n_heads * n_tokens] row-index tensor. Keep llama.cpp's two properties: hash on the host (it is scalar, branchy, and needs history), and make the table access a pure gather so it can be offloaded.per_layer_token_embd resident in host/pinned memory and gather over PCIe/NVLink, or use atlas-tier to page it. GB10's unified memory makes this genuinely cheap; llama.cpp reaches the same conclusion via --override-tensor. Quantize it as an embedding (Q-type by embedding policy, name-overridable) β copy llama.cpp's rule (llama-quant.cpp:696β712).hc streams with a full-width weight; the signed-sqrt sigmoid gate (sigmoid(sign(s)Β·sqrt(clamp(|s|,1e-6)))); and the dilated depthwise conv as a sum of kern shifted slices. Take llama.cpp's sum-of-shifts formulation (it explicitly rejects conv_1d_dw as unreliable) β it also makes the chunked-prefill/history semantics obvious.(kernel-1)*ngram_size*hc*n_embd per sequence in the SSM pool alongside the GDN state (ssm_pool.rs), following llama.cpp's ple_conv_state() (llama-hparams.cpp:249) so chunked prefill is bit-consistent with single-shot.P3 β QSA sparse attention (~3β5 weeks, hardest).
llama-memory-hybrid-idx.h:165). Atlas's paged layout makes this *more* necessary, not less. Build cell_blk / blk_cells / bias on device (Atlas can do this in a kernel; llama.cpp does it on host because it must stay backend-agnostic) β this is the main deliberate divergence.+1e9 trick for the always-visible incomplete tail block (llama-memory-hybrid-idx.cpp:659β674), so it plugs into Atlas's existing paged attention (qwen3_attention/prefill/paged_v4.rs) without a new masking path, and never produces NaN.is_indexer_full_impl): shared layers reuse the previous full layer's top-k. This halves indexer cost and is a pure scheduling/graph-level decision β cheap to adopt, easy to get wrong if ignored.assemble.rs:399β420), not for selection β QSA's top-k gather is a different dataflow.P4 β Loader + conversion parity.
Port conversion/qwen4exp.py semantics into a Rust loader. Two traps llama.cpp documents explicitly: (i) int64 hash constants must not pass through a float cast β 45-bit multipliers silently round (qwen4exp.py:43β56); Atlas's csa_ape.rs already has the "keep exact F32/int constants" discipline to extend. (ii) The 128-shard n-gram table must be streamed to a scratch file at final row offsets, never concatenated in RAM (peak ~300 GB otherwise). Also: split fused index_qk_proj into q/k, and apply the Gemma zero-centered gamma +1 to ple.norm_{key,query,conv} and indexer.{q,k}_layernorm.
P5 β Skip MTP at export, matching llama.cpp (no_mtp = True, qwen4exp.py:30). Revisit only if a Flash-Next MTP is validated; layers/deepseek_v4_mtp.rs shows the pattern (reuse the real layer body).
P6 β Verification. Per-feature parity vs. the HF reference and vs. llama.cpp itself (which is a working reference implementation on the same weights): greedy logprob diff for (a) PLE on/off, (b) chunked vs single-shot prefill (exercises both conv-state paths), (c) branch
*(Scope note: the requested heading was "vLLM vs Atlas", but the task β and all research performed β compares llama.cpp PR #27742 against Atlas. The title below reflects what was actually analyzed.)*
---
qwen4exp)LLM_ARCH_QWEN4EXP with its own model class llama_model_qwen4exp, dispatched in src/llama-model.cpp:323-324.src/llama-arch.cpp (e.g. per_layer_token_embd at llama-arch.cpp:542, registered as an input-layer GET_ROWS tensor at :887; enum in src/llama-arch.h:483, shared with Gemma3n/Gemma4).src/llama-hparams.*) add per-layer predicate tables computed at load time:is_recr(il) / is_swa(il) / is_ple(il) / is_indexer_full(il) / has_rope(il) / has_kv(il) (llama-hparams.cpp:235-320). has_rope() also exempts a router_layer from RoPE shifting.ple_conv_state() = (ple_conv_kernel-1) * ple_ngram_size * dsv4_hc_mult * n_embd (llama-hparams.cpp:243-250) β a *second, dilated* short-conv state (dilation = n-gram size) stored inside the recurrent row. Because recurrent rows must be uniform, every recurrent layer reserves the PLE conv slot even where unused (n_embd_r(), llama-hparams.cpp:183-209).n_embd_s = head_dimΒ² Γ n_head (llama-hparams.cpp:211-233).src/models/qwen4exp.cpp)is_recr(il).GGML_OP_GATED_DELTA_NET (ggml/include/ggml.h:572) plus SSM_CONV-style conv state; the recurrent state (h + conv, plus the PLE dilated conv) lives in the recurrent memory rows.q/k are passed through a Hadamard rotation before the lightning indexer (qwen4exp.cpp:527-528), and the attention itself gathers only the top-k selected KV cells. The indexer's own MQA key cache (cache_idx_k/v_l*, one head of indexer_head_size) is written through the dedicated indexer cache (Β§4). Hadamard rotation is implemented as llama_mul_mat_hadamard() with GGML_HINT_SRC0_IS_HADAMARD (src/llama-impl.h:57-71), which the CUDA backend fast-paths to a Fast Walsh-Hadamard Transform instead of a dense matmul (ggml/src/ggml-cuda/ggml-cuda.cu:1820, fwht.cuh), with a CPU FWHT too (ggml/src/ggml-cpu/ggml-cpu.c:1262). Hadamard matrices are precomputed per rotation size in the KV-cache object (src/llama-kv-cache.cpp:22, 326-360, 1795-1806).GGML_OP_DSV4_HC_COMB/PRE/POST, ggml.h:574-576) gated by dsv4_hc_mult; the PLE n-gram conv operates over dsv4_hc_mult Γ n_embd rows, i.e. PLE is applied on the HC-expanded stream.per_layer_token_embd.weight is loaded as one [n_embd_altup Γ n_layer, n_vocab]-style tensor (qwen4exp.cpp:103-107); at each PLE layer a per-layer row-slice is GET_ROWS-ed, n-gram/dilated-convolved (state in the recurrent row, [TAG_PLE_HISTORY]), gated, and added to the trunk β the Gemma3n altup pattern generalized (src/models/gemma3n.cpp:41, gemma4.cpp:53).n_layer_nextn (n_layer() = n_layer_all - n_layer_nextn, llama-hparams.cpp:322-324) and the shared nextn/dflash paths (LLM_ARCH_DFLASH with dsv4_hc_mult > 0 recognized in src/llama-context.cpp:2304-2306).max(n_tokens*40, 32*n_tensors) nodes (llama-context.cpp:2299-2310) β a hint of how many small ops the HC + indexer + PLE stack generates.src/llama-memory-hybrid*.cpp)llama_memory_hybrid composes a llama_kv_cache (attention layers) + llama_memory_recurrent (GDN layers) with per-layer filters (llama-memory-hybrid.h:16-91).llama_memory_hybrid_idx (new for this model family, llama-memory-hybrid-idx.{h,cpp}) adds a third memory: the indexer KV cache:llama_kv_cache shaped by indexer_head_size, with its own idx_ tensor-name prefix (llama-memory-hybrid-idx.cpp:48-59).:114-119). This is the key correctness decision: indexer keys are addressed *by attention-cache cell index*, so top-k gather indices transfer directly.seq_rm/cp/keep/add/div) are fanned out to all three caches plus the PLE history window (ple_hist_*), which tracks per-sequence recent-token state for the n-gram conv, including rollback on failed drafts (:136-206).1 + n_rs_seq tokens in one ubatch so recurrent rollback snapshots stay valid ([TAG_RECURRENT_ROLLBACK_SPLITS], :80-85).--override-tensor buffer-type overrides in the model loader (src/llama-model-loader.cpp:1182-1208); the operational pattern for Flash-Next is to keep the huge per_layer_token_embd.weight (n_vocab Γ n_layer Γ n_embd β the single biggest tensor) in CPU/mmap memory and stream rows to GPU per layer, with a warning when mmap + CPU override interact (:1191-1196).per_layer_token_embd.weight follows --token-embedding-type by default but is treated specially as a large tensor (src/llama-quant.cpp:103, 697-700); imatrix quantization exploits that its rows are independent (:1283).pattern_idx_cache β GGML_BACKEND_SPLIT_AXIS_MIRRORED (src/llama-model.cpp:382, 495-498).conversion/qwen4exp.py maps HF checkpoints β GGUF: HC tensors under the DSV4 names, per_layer_token_embd.weight as one fused tensor, indexer projections, full_attention_idx-style layer pattern β is_swa/is_recr/is_ple/is_indexer_full metadata, plus the PLE hparams (ple_n_heads, ple_conv_kernel, ple_ngram_size).---
| Feature | Status | Evidence |
|---|---|---|
Config dispatch / new model_type | Exists, extensible β JSON model_type β parser routing | crates/atlas-core/src/config/dispatch.rs:41-164; per-family parsers in crates/atlas-core/src/config/parsers/ (deepseek_v4, minimax, mistral, β¦). No qwen4exp entry. |
| Capability flags | Exists β ModelCapabilities SSOT (SsmArchitecture::Gdn, has_moe_layers, has_mtp, AttentionType::Mla) | crates/atlas-core/src/capabilities.rs:9-106. No PLE/hyper-connection/sparse-attention flags. |
| Gated delta net (decode) | Mature β decode kernels incl. FP32/FP16 h-state, strided multi-seq batched, half/SRAM retention variants | crates/spark-model/src/layers/qwen3_ssm/mod.rs:107-131 (gdn_f32_strided_norm_*, gdn_f16_*), trait_decode_batched_conv_gdn*.rs |
| GDN prefill | Mature β WY4/WY32, FLA chunked multi-kernel (recompute_wu β chunk_delta_h β chunk_fwd_o), TMA variant, register-resident replay | qwen3_ssm/mod.rs:150-198 |
| Conv1d + L2-norm inside GDN | Exists | conv1d_l2norm_f32_strided_k (mod.rs:100-106) |
| Recurrent state pool (paged/batched, snapshots, spill/tiering) | Exists, strong β SSM pool, snapshots, spill, tiering, batched copy | crates/spark-model/src/model/ssm_pool.rs, ssm_snapshot*.rs, ssm_tier/, ssm_batched_copy.rs, ssm_reserve.rs |
| Hybrid layer scheduling (attn vs SSM per layer) | Exists β LayerType::{LinearAttention, FullAttention, Moe} + hybrid pattern mapping | config/dispatch.rs:194-200 (Nemotron pattern), capabilities.rs:67-75 |
| MoE (grouped GEMM, EP/TP, routing bias) | Exists | layers/moe/, ep_dispatch.rs, tp_shard.rs, config scoring_func/use_routing_bias (atlas-core/src/config.rs:402-415) |
| MTP speculative decoding | Exists β Qwen3.5 single-module, MiniMax multi-module, DFlash, DeepSeek-V4 MTP heads | layers/mtp_head/, mtp_multi.rs, deepseek_v4_mtp.rs, dflash_head.rs, config num_mtp_modules (config.rs:422-430) |
| Hyper-connections (mHC, Sinkhorn) | Exists but DSv4-hardwired β hc_mult/hc_sinkhorn_iters/hc_eps config fields, HC buffers, fused CUDA kernels | config.rs:255-266; spark-runtime/src/buffers/sizes.rs:449-465; kernels/gb10/deepseek-v4-flash/nvfp4/hyper_connection.cu; loader weight_loader/deepseek_v4/*. Flash-Next needs hc_mult=2 + learned per-site alpha scales, which the DSv4 path (hc=4, no alpha) does not cover. |
| Sparse attention / lightning indexer | Config fields exist; no runtime path for this shape β index_n_heads/index_head_dim/index_topk parsed only by the DeepSeek-V4 parser (config/parsers/deepseek_v4.rs:200-201); DSv4 uses a *compressed-KV* LID path (layers/qwen3_attention/prefill/cache_skip_v4.rs, weight_loader/deepseek_v4/assemble.rs:367). No generic "gather top-k from paged KV by indexer score" kernel found. | |
| Hadamard rotation as fused op | Missing as attention op β WHT exists only inside TurboQuant KV quantization (kernels/gb10/common/wht_bf16.cu, qwen3_attention/decode/write_kv_cache.rs:67), not as a Q/K/V transform in the attention path. | |
| PLE / per-layer token embedding | Missing entirely β no per_layer*/n-gram/altup code anywhere in spark-model. Embedding is a single embed_tokens table + batched_embed (model/trait_impl/prefill_c.rs:121, decode_b.rs:144). | |
| PLE dilated n-gram conv state | Missing β SSM row layout has conv+state only; no second dilated-conv slot (layer.rs SsmLayerState, ssm_reserve.rs). | |
| Indexer key cache as third memory | Missing β memory is paged KV (spark-runtime/src/kv_cache.rs) + SSM pool; no per-layer MQA "index cache" sharing slot layout with the main KV. | |
| Large-embedding CPU/mmap offload | Partially exists β weight loader has precision/tier machinery (precision_schedule.rs, w4a16_gemv_tiers.rs, pinned_pack.rs, token_overlay.rs), but no regex tensorβCPU-buffer override equivalent to --override-tensor. | |
| MRoPE (T,H,W streams) | Exists β interleaved MRoPE with 3 position streams through prefill/verify | model/trait_impl/prefill_b/mrope_pos.rs, stage_batched.rs:78-187, layer.rs:116-183. Flash-Next's imrope variant (llama.cpp n_pos_per_embd returns 4 for MROPE/IMROPE, llama-hparams.cpp:260-262) needs verification. |
swiglu_oai FFN activation | Likely missing β no SWIGLU_OAI analog found in Atlas kernels; standard SwiGLU exists in dense_ffn.rs/moe/. |
---
| Feature | llama.cpp mechanism (PR #27742) | Atlas status | Port difficulty |
|---|---|---|---|
| Arch/config registration | LLM_ARCH_QWEN4EXP + hparams predicate tables (is_recr/is_ple/is_indexer_full) | dispatch.rs + ModelCapabilities SSOT | Low β add parser + capability flags |
| Gated delta net | GGML_OP_GATED_DELTA_NET, per-seq recurrent rows | Mature GDN kernels (decode+chunked prefill, batched, FP16 state) | Low β reuse; validate head dims (32Γ128) & gate formula vs reference |
| Recurrent state mgmt | llama_memory_recurrent, uniform rows incl. PLE slot | ssm_pool + snapshots + tiering (better than llama.cpp) | Low-Med β extend row layout with PLE conv slot |
| Hybrid memory composition | llama_memory_hybrid = KV + recurrent, layer filters | LayerType-driven layer scheduling | Low |
| Sparse attention (top-k gather) | attention gathers top-k cells from KV by indexer score; indexer cache shares attention slot layout | No generic top-k-gather attention; DSv4 path is compressed-KV specific | High β new kernel (gather-from-paged + flash over β€512 selected blocks) |
| Lightning indexer | GGML_OP_LIGHTNING_INDEXER + GGML_OP_TOP_K + ARGMAX chain; own MQA cache (idx_ prefix), mirrored across GPUs | config fields only (index_topk etc.) | High β new op + index-cache memory + top-k kernel |
| Hadamard Q/K/V rotation | mul_mat + SRC0_IS_HADAMARD hint β FWHT fast path; precomputed matrices in cache object | WHT kernels exist but only in KV-quant path | Med β expose wht_bf16 as a standalone transform in the attention path |
| mHC hyper-connections | reuse DSV4_HC_{PRE,POST,COMB} ops, dsv4_hc_mult | DSv4 kernels + buffers, hc=4 hard-tuned, no learned alpha | Med β generalize to hc=2 + per-site alpha scales; buffers already parameterized by hc_mult |
| PLE (per-layer embed + n-gram dilated conv) | fused per_layer_token_embd tensor, GET_ROWS per layer, dilated conv state in recurrent row, ple_hist window in memory layer | Nothing | High β new layer component + state slot + memory bookkeeping |
| PLE weight offload (CPU/mmap) | regex --override-tensor β CPU buft, mmap warning (llama-model-loader.cpp:1182-1208) | no equivalent; has pinned/pack/tier machinery | Med β add per-tensor placement policy to loader |
| MTP nextn | n_layer_nextn, DFLASH nextn recognized for dsv4-hc models | MTP heads incl. multi-module & DFlash | Low-Med β wire nextn layer through existing MTP infra |
| Quant/conversion | qwen4exp.py; PLE tensor follows token-embedding type, row-independent imatrix | quant_format/ dispatcher, NVFP4/FP8/Q2 paths | Med β new weight_map + loader; PLE tensor quant policy |
| MRoPE | imrope rope type, 4 pos/embd | interleaved MRoPE T/H/W streams | Low β verify imrope semantics against Atlas's rule (mrope_pos.rs) |
swiglu_oai | GGML_GLU_OP_SWIGLU_OAI (ggml.h:627) | not found | Low β pointwise kernel |
| Multi-GPU split | indexer cache mirrored (llama-model.cpp:495-498) | TP/EP sharding exists | Low priority (GB10 single device) |
---
Phase 1 β config + skeleton (no kernels).
qwen4exp to config/dispatch.rs (nested-config handling like qwen3_5_moe), new fields for PLE (ple_n_heads, ple_conv_kernel, ple_ngram_size), hc_mult reuse, index_* reuse, full_attention_interval, n_layer_nextn. Extend ModelCapabilities with has_ple, has_hyper_connections, has_sparse_attention β following the SSOT philosophy of capabilities.rs.layers/qwen4exp/ reusing qwen3_ssm (GDN), qwen3_attention, moe components; layer-kind selection via layer_types (already the Atlas pattern).Phase 2 β reuse what Atlas already does better than llama.cpp.
qwen3_ssm decode/prefill kernels verbatim if dims match (32 heads Γ 128, conv kernel 4); the Atlas FLA chunked prefill and batched multi-seq decode will substantially beat llama.cpp's per-token recurrent path at batch >1. Add the PLE dilated-conv slot to the SSM row layout (ssm_reserve.rs, layer.rs::SsmLayerState) β copy llama.cpp's uniform-row decision (llama-hparams.cpp:206-208): reserve the slot on every recurrent layer so pool slices stay uniform and batched copies (ssm_batched_copy.rs) remain trivial.hyper_connection.cu + buffers/sizes.rs from DSv4 (hc=4) to Flash-Next (hc=2) and add the learned per-site alpha scales. Atlas's fixed [M, hc_mult, hidden] BF16 stream buffers map 1:1 to llama.cpp's HC ops; this is a parameterization task, not a new design.Phase 3 β new ops (the genuinely hard part).
index_score_topk(q_idx, k_idx_cache, paged_slots) β topk_indices[n, 512]. Adopt llama.cpp's two decisive design choices: (i) indexer cache is a 1-head MQA cache of indexer_head_size rows, allocated with the same slot layout as the main paged KV (llama-memory-hybrid-idx.cpp:114-119) β in Atlas this means a second block table per sequence sharing the main block allocation, so a top-k slot index is directly usable by the attention gather; (ii) Hadamard-rotate q/k before scoring β reuse wht_bf16.cu as a standalone transform (fused into the indexer prologue ideally), rather than llama.cpp's matmul-with-hint indirection.per_layer_token_embd (batched embed kernel already exists), n-gram combine with dilated conv (dilation = n-gram size) over the hc_mult Γ n_embd stream, sigmoid gate, residual add. Bookkeeping: mirror llama.cpp's ple_hist β the n-gram window must follow seq_rm/cp/keep semantics; in Atlas this belongs in the sequence-state manager next to the SSM pool slots, and must be snapshot/rollback-aware for spec decode (Atlas's ssm_snapshot* machinery is the right hook; llama.cpp needed [TAG_RECURRENT_ROLLBACK_SPLITS] for exactly this).swiglu_oai pointwise kernel; verify imrope against mrope_pos.rs.Phase 4 β weights + serving.
per_layer_token_embd into one tensor (llama.cpp convention) but place it CPU-resident by default with pinned staging β add a tensor-placement policy to weight_loader/ (Atlas lacks --override-tensor; pinned_pack.rs/token_overlay.rs are the natural extension point). On GB10's unified memory this is a bandwidth decision: measure row-gather-over-UVM vs pinned double-buffer; llama.cpp's mmap warning (llama-model-loader.cpp:1191-1196) shows the mmap+CPU-override trap to avoid.mtp_head/ with HC-aware input (mtp_carry.rs), reusing the DFlash/DSv4-MTP precedent.numeric.rs, preflight preflight/deepseek_v4.rs); add a preflight/qwen4exp.rs mirroring the DSv4 tensor-shape checks.Where to diverge from llama.cpp: (1) do *not* copy the matmul-hint Hadamard indirection β fuse WHT directly; (2) llama.cpp's recurrent memory is per-sequence rows with CPU offload β Atlas's paged SSM pool + snapshots should absorb PLE state rather than adopting the row model; (3) llama.cpp's ubatch splitting keeps rollback tokens together β Atlas's CUDA-graph verify paths need the PLE window carried in the existing speculative carry buffers instead; (4) indexer-cache mirroring is irrelevant on single-device GB10 β skip.
---
n_tokens*40, llama-context.cpp:2310) β Atlas's CUDA-graph capture must handle the same op-count explosion (HC + indexer + PLE per layer Γ 48 layers).verify_e.rs) synthesize steps β the PLE n-gram window and dilated conv state must be rolled back identically or acceptance/resample diverges. Highest correctness risk in the port.[n_layer Γ n_vocab Γ n_embd] at 256K vocab is tens of GB in BF16; even row-gathered it's ~48 embedding reads/token. Needs a quantization policy (llama.cpp keeps it at token-embedding type; Atlas could NVFP4 it β rows are independent, as llama.cpp's imatrix note observes, llama-quant.cpp:1283).hyper_connection.cu:18).imrope semantics: llama.cpp distinguishes it from mrope (llama-hparams.cpp:260-262); the exact position-stream rule must be diffed against Atlas's mrope_pos.rs before trusting vision/long-context paths.self_v_rot): applied to V *before cache write and after read* β the cache stores rotated V. This interacts with Atlas's TurboQuant KV (which also applies WHT before quantization): composing two rotations (or double-rotating) must be checked; likely the model's V-rotation should be fused into the existing WHT bookend rather than stacked.conversion/qwen4exp.py is the ground truth for tensor fusion (BA packing, interleaved QKVZ vs sequential β Atlas already supports both modes, qwen3_ssm/mod.rs:75-78); pin the exact variant rather than auto-detecting.Architecture identity. LLM_ARCH_QWEN4EXP is registered as a *hybrid* architecture (llm_arch_is_hybrid true, llm_arch_is_recurrent false). It is grouped with QWEN3NEXT / QWEN35 / QWEN35MOE throughout the code, meaning it reuses the same "gated delta net (SSM/linear-attention) + sparse attention" block family, with two qwen4exp-specific additions: a per-token indexer cache (sparse attention over an indexer) and per-layer token embeddings (per_layer_token_embd).
Memory / cache strategy β the core design decision. In llama_model::create_memory (src/llama-model.cpp:2441-2536), qwen4exp is routed to a dedicated memory type:
needs_mem_idx = (arch == LLM_ARCH_QWEN4EXP) (:2449).indexer_head_size > 0, it instantiates llama_memory_hybrid_idx (:2496-2516) β a hybrid cache that carries *three* independent state streams: (1) a standard attention KV cache for the dense-attention layers, (2) a recurrent/SSM state (r/s) for the gated-delta-net layers, and (3) a per-token indexer cache for the sparse-attention layers.:2460-2473): filter_attn = layers that are *not* recurrent; filter_recr = layers that *are* recurrent; filter_idx = the same non-recurrent set, gated on indexer_head_size > 0. So the indexer cache lives only on the dense-attention (sparse) layers, while the SSM state lives only on the recurrent layers.llama_memory_hybrid_iswa (:2476-2495); qwen4exp's production config is the non-SWA hybrid_idx path.Tensor placement / offload. The generic split logic in llama-model.cpp treats qwen4exp identically to Qwen3Next/3.5 for the SSM/delta-net tensors:
get_split_segments (:588-636): for the recurrent layers it computes head_k_dim = ssm_d_state, n_k_heads = ssm_n_group, n_v_heads = ssm_dt_rank, and splits qkv_weight / ssm_conv1d / r_cache / s_cache along the head axis (Qwen3Next pattern [k0_v0, k0_v1, k1_v2, k1_v3]).get_split_granularity (:661-684): aligns splits to lcm(blck_size,128) and to ssm_d_state so quant blocks don't straddle heads; the s_cache (the recurrent state) is split by n_k_heads * head_v_dim * head_v_dim.pattern_idx_cache β GGML_BACKEND_SPLIT_AXIS_MIRRORED, :496-498) because the QSA indexer has a single key head whose projections are mirrored β it cannot be sharded..scale / .input_scale sidecars (NVFP4-style) are loaded generically for ssm_in/out/alpha/beta and the MoE expert weights (:1563-1646), so the delta-net and MoE paths both support quantized weights.Graph / ops. The recurrent block is the standard gated-delta-net / SSM op set (ssm_in, ssm_conv1d, ssm_dt, ssm_a, ssm_alpha, ssm_beta, ssm_out, plus r_cache/s_cache state). The sparse-attention path uses the pattern_idx_cache indexer plus the normal Q/K/V attention ops. MoE experts use the ffn_gate_up_exps / ffn_down_exps fused-expert tensors (create_tensor_gate_up_exps, :3122-3128). per_layer_token_embd is handled via the generic per-layer embedding path and can be offloaded to CPU/mmap with --override-tensor.
Conversion. conversion/qwen4exp.py maps HF weights to the GGUF tensor names above (ssm_*, ssm_conv1d, ssm_dt/a/alpha/beta, ssm_out, r_cache/s_cache, idx cache, ffn_*_exps, per_layer_token_embd) and emits the GGUF keys that drive is_recr(il), indexer_head_size, ssm_d_state, ssm_n_group, ssm_dt_rank, ssm_d_conv.
Key point for Atlas: llama.cpp's whole approach is *state-centric* β the recurrent layers keep a fixed-size SSM state per sequence (no KV growth), the sparse layers keep a full KV + a per-token indexer, and everything is expressed as a single fused graph with per-tensor device placement. It is not paged and not batched in the vLLM/Atlas sense; batching is via the graph's seq dimension and the hybrid memory's n_seq_max/n_rs_seq bookkeeping.
Atlas (Rust, GB10, paged/batched/GPU-first) does not yet support qwen4exp. Per feature:
ssm_in/ssm_conv1d/ssm_dt/ssm_a/ssm_alpha/ssm_beta/ssm_out ops, no r_cache/s_cache recurrent state, no ssm_d_state/ssm_n_group/ssm_dt_rank hparams. Atlas's attention path is KV-cache based; it has no recurrent-state slot.pattern_idx_cache equivalent, no per-token indexer cache, no top-k selection over an indexer. Atlas has standard paged KV attention only.ffn_gate_up_exps/ffn_down_exps expert layout and per-expert scale sidecars used by qwen4exp are not wired for this arch.| Feature | llama.cpp mechanism | Atlas status | Port difficulty |
|---|---|---|---|
| Recurrent gated-delta-net (SSM) block | ssm_* ops + r_cache/s_cache fixed per-seq state; head-axis split (ssm_d_state,ssm_n_group,ssm_dt_rank) | Missing (KV-only) | High β new op family + new state type |
| Recurrent state memory | llama_memory_hybrid/_idx recurrent stream, n_rs_seq | Missing | High β new cache dimension |
| Sparse attention + per-token indexer | pattern_idx_cache (mirrored) + top-k over indexer on dense layers | Missing | High β new cache + selection kernel |
| Hybrid KV+recurrent(+idx) memory | llama_memory_hybrid_idx with 3 filters | Missing (paged KV only) | High β unify 3 state streams |
| MoE experts (fused gate_up/down_exps) | create_tensor_gate_up_exps, per-expert scales | Partial | Medium |
| per_layer_token_embd | per-layer embedding + --override-tensor offload | Missing | Medium |
| Quant sidecars (ssm/expert) | generic .scale/.input_scale load | Partial | LowβMedium |
| Conversion HFβGGUF | conversion/qwen4exp.py | n/a (Atlas loads its own format) | Medium β mapping table |
| Tensor placement/offload | per-tensor split axis + granularity | Atlas uses paged placement | Medium β adapt to paged model |
ssm_in β ssm_conv1d β (ssm_dt,ssm_a,ssm_alpha,ssm_beta) β ssm_out graph and the r_cache/s_cache per-sequence fixed-size state. This is the single biggest gap. Borrow llama.cpp's head layout (ssm_d_state, ssm_n_group, ssm_dt_rank) and the lcm(blck_size,128,ssm_d_state) alignment so quant blocks don't straddle heads. *Diverge:* store the recurrent state in a contiguous per-sequence slab (not paged), since it is fixed-size β this is cheaper than paging and matches llama.cpp's n_rs_seq model.filter_attn = non-recurrent, filter_recr = recurrent, filter_idx = non-recurrent with indexer_head_size>0) as the source of truth for which layers use which stream. *Diverge:* Atlas can keep KV paged (its strength) while the recurrent + indexer streams are dense per-sequence buffers β do not force paging onto the fixed-size state.ffn_gate_up_exps/ffn_down_exps layout and the generic .scale/.input_scale sidecar loading.--override-tensor), so the per-layer embedding table can live in host/mmap memory.conversion/qwen4exp.py (ssm_*, ssm_conv1d, ssm_dt/a/alpha/beta, ssm_out, r/s cache, idx cache, ffn_*_exps, per_layer_token_embd, and the GGUF keys is_recr, indexer_head_size, ssm_d_state, ssm_n_group, ssm_dt_rank, ssm_d_conv).n_seq_max/n_rs_seq; Atlas batches via paged blocks. The recurrent op must be batched over sequences with per-sequence state pointers β verify the GPU kernel supports gather/scatter over a state slab.ssm_* and per-expert scales, especially NVFP4.src/models/qwen4exp.cpp graph builder or llama-memory-hybrid-idx.* internals in this pass (the model file is large and I focused on the memory/placement/conversion wiring in llama-model.cpp). The op-level graph order (exact placement of ssm_conv1d vs the delta update, and the exact top-k indexer kernel) should be confirmed against src/models/qwen4exp.cpp before finalizing the Atlas op list. The feature set, memory topology, and placement decisions above are taken directly from the cited llama-model.cpp code and are reliable.Cross-referencing all nine agent reports (rounds 1β3), keeping only claims verified against the actual trees, and choosing per feature whichever engine's design fits Atlas's paged/batched/GPU-first architecture.
Mature Gated DeltaNet (layers/qwen3_ssm/) + recurrent-state pool (snapshots/spill/tiering); DSV4 mHC infra;
512-expert-capable MoE; MTP (DSV4 "reuse the layer body" precedent); MRoPE-interleaved; vision tower; quant dispatcher.
Qwen4ExpConfig validators verbatim (they encode kernel invariants:
MQA indexer, budget/ratio β {512,2048}, ringΓ·block-size, PLE divisibility). Reuse qwen3.5 loader arms; match_names tie-break.
Trap from llama.cpp: 45-bit n-gram hash multipliers are int64 β never fp32-cast.gated_residual mode to the existing mHC path;
adopt vLLM's delayed-combine (β1 extra read+write per block instead of per mix+combine) + fused combine+RMSNorm + merged
down/inject GEMM (un-TP'd, un-quantized). Changes the whole stack's tensor contract. Verify sigmoid-vs-Sinkhorn gate against the checkpoint.ple_history in the memory layer with mirrors for every seq mutation + session serialize; dilated short-conv state
stored inside the recurrent row β reuses Atlas's SSM pool as a second state-kind. Table stays host-resident (mmap/UVA) β
one GET_ROWS consumer makes it clean; GB10 coherent C2C makes it fast; production --override-tensor offload already validates it.skip_topk on draft steps, and the whole
indexβwriteβattend transaction as one opaque graph node. v1 constraints: BF16 KV, MQA indexer, no KV quant.| Phase | What | Effort | Expected outcome |
|---|---|---|---|
| 0 | Config + validators + factory + loader verify | Low | Checkpoint parses and loads with the correct loader; all invariants enforced (bad configs fail loudly, not numerically); tensor names mapped end-to-end. No forward yet. |
| 1 | HC gated_residual + delayed combine (tensor contract) | High | Decoder stack carries the 4-stream state; HC mix/combine unit-tests match reference numerics bit-for-bit; existing models untouched; measured HC overhead β€ ~15% decode latency (fusions proven). |
| 2 | GDN parity check + multi-state-kind pool | LowβMed | Hybrid GDN+attention layers run on the HC stream; GDN output matches llama.cpp goldens; state pool hosts two state kinds (GDN + short-conv) with per-spec sizing, snapshot/rollback intact. |
| 3 | PLE (llama.cpp bookkeeping + host-resident table) | Med-High | Full forward through GDN/dense layers is token-parity with llama.cpp on fixed prompts incl. n-gram effects across chunk boundaries and after seq_rm/cp; PLE table off-GPU with <~2 GB device overhead; branch/rollback tests green. |
| 4 | QSA (cell-aligned indexer + compressed cache) | High β long pole | End-to-end generation works. Quality parity with llama.cpp PR (~4.01 wikitext-2 ppl, β₯98% top-1 agreement); first Atlas tok/s numbers β target β₯ llama.cpp single-stream (~25 t/s) with batched upside. |
| 5 | MTP scheme-A (pre-mixer multi-stream β drafter) + polish | Med | Speculative decode live (target β₯1.3Γ decode speedup); EPLB/shared-expert parity; batched serving stable β production-candidate build that beats llama.cpp on concurrent throughput. |
Atlas PR #16 actually implements qwen4exp serving (372 files, +45.6K lines, RadixArk NVFP4 on one GB10, "six silent defects" fixed). Two independent reviews of the same PR, written blind to each other: config A (Flash-Next Q4, 124 steps / 96 min / 6.17M input tokens) and Claude (~30 min of targeted reading). 2026-08-31.
| A (Flash-Next Q4) | Claude | |
|---|---|---|
| Depth | Code-level, exhaustive β 21.9 KB, all four forward shapes traced | Architecture + narrative verification, targeted reads |
| Unique catches | D1 padding-row inference from ple: None (diverged call sites); D2 aux blobs excluded from the NVMe spill tier, unversioned; D3 conv-carry rewind unproven across six verify paths; D5 exact-leaf prefix hit disabled by default over a 23%-vs-60% quality regression (verified verbatim in code); dual PLE kernels with one oracle; 7 targeted pre-merge tests |
ATLAS_PLE_MAX_TOKENS default footgun (2048 fails a 2,191-token prompt); cross-engine grounding (vLLM/llama.cpp PLE + QSA design comparison); perf context vs llama.cpp; NVMe latency-probe suggestion |
| Verified accuracy | Spot-checks landed verbatim (23%/60% comment, GDN-deferral note, aux HashMap) | All claims code-verified before writing |
| Verdict reached | Merge after targeted hardening (fix D1, version+tier aux blobs, land D3 test) | Merge gated on CLA + PLE default fix + long-context quality gate |
Honest scoring: A 9.5/10, Claude 8/10 on this task. A's review is materially deeper where it counts β D1/D2/D3/D5 are real pre-merge findings Claude's pass missed, and every spot-checked citation was verbatim-accurate. Claude's added value was contextual (engine comparisons, ops posture, the env-var footgun A overlooked). The reviews are complementary: union them and you have a genuinely complete PR review.
Scope note: this review is based on direct reading of the PR tree (atlaspr) against atlas main across the areas that carry the correctness burden: config/buffer sizing, hyper-connections (mHC highway), PLE / n-gram embedding and its history bookkeeping, QSA sparse attention + indexer, the batched/multi-sequence and speculative (verify) dispatch paths, aux-state snapshotting (Marconi/prefix cache), and the new kernels/gb10/qwen3.8-flash-next + kernels/gb10/common kernel families. I did not execute the test suite (no GPU here); everything below is static review plus the PR's own documented measurements.
---
1. Config parsing / model registration.
The qwen4_exp model type is parsed into ModelConfig with both spellings of the stream count retained: hc_count (the checkpoint's own field name, read by the manifest and the reference crate) is *mapped onto* hc_mult (the field the engine dispatches on). Both are kept so the reference/manifest readers keep working β see the sizing tests in crates/spark-runtime/src/buffers/sizes.rs:611-676 (both_spellings_size_the_same_highway). Layer typing reuses the existing LinearAttention (GDN) / FullAttention (QSA) alternation, with index_topk / index_compress_ratio / index_n_heads / index_head_dim fields driving the sparse-attention path.
2. Hyper-connections (mHC, multi-stream highway).
An FP32 [n, hc_mult*H] stream highway (buffers.hc_streams()) with hc_expand / hc_pre_site / hc_post_site / hc_head_site ops, per-site weight groups (hc.attn, hc.ffn, hc.head), low-rank mixing scratch (hc_lowrank_scratch), and a HcVariant abstraction that encodes the Qwen-vs-DeepSeek-V4 divergence: on Qwen, hc_pre's grouped hc_norm *is* the block input norm, so no second RMS is applied and there is no per-layer input_layernorm (qwen3_attention/trait_impl/prefill_inner.rs:640-659, multi_seq/mod.rs:207-223). Highway sites are wired in all four forward shapes: single decode (decode_a), batched multi-seq decode (qwen3_ssm/trait_decode_multi_seq/hc.rs, qwen3_attention/trait_impl/multi_seq/mod.rs:131+), batched verify (qwen3_ssm/trait_decode_batched_hc.rs), and prefill (prefill_inner.rs).
3. Gated DeltaNet (GDN) changes.
The SSM layer (qwen3_ssm) gained an hc and a ple optional member, a per-seq SsmLayerState { β¦, ple: Option<PleSeqState> }, a batched-GEMM decode core (try_decode_multi_seq_ssm_batched) and a per-seq recurrence fallback, and the highway-aware multi-seq driver described above. The batched core is deliberately *not* engaged under the highway yet because its epilogues fold the residual in (trait_decode_multi_seq/hc.rs:26-29) β an honest, documented deferral.
4. PLE / n-gram embedding.
crates/spark-model/src/layers/ple/layer.rs + kernels/gb10/qwen3.8-flash-next/nvfp4/ple.cu (+ the kernels/gb10/common/qwen4exp_ple.cu twin): key/value projections of hashed n-gram embeddings, a highway-conditioned gate (ple_gate), a dilated depthwise causal conv with in-place rolled carry (ple_conv, state [(k_size-1)*dilation, C], FP32 chain end-to-end β see the PRECISION NOTE referenced in ops/ple.rs:10-16), and ple_add_highway, which injects into the FP32 highway *before* the layer's attention hyper-connection, matching the reference ordering.
History bookkeeping is the interesting part:
Layer::decode_prestage (decode_a.rs:153-164) and Layer::verify_prestage for the whole draft window (verify_c.rs:199-212, verify_e.rs:421-437), so a replayed graph only reads refreshed fixed-address buffers. The per-sequence windowing in verify_e.rs:427-437 (tokens[off[i]..off[i+1]]) is correct and explicitly guards against injecting one sequence's lexical history into another.trait_decode_multi_seq/hc.rs:81-121): each row reads *its own* token from ctx.host_token_ids and *its own* PleSeqState.verify_snaps (ple/layer.rs:413-456), so a rejected draft can rewind the conv state; prefill widths keep the batched launch and set verify_snap_rows = 0.verify_c.rs:199 comment: "n-gram hash + NVMe fault-in + slot upload").5. QSA sparse attention + indexer.
layers/qsa.rs + layers/qsa_select.rs: per-seq QsaSeqState lazily created via helpers::qsa_seq_state (helpers.rs:256-269); prefill *ingests* raw indexer keys per chunk (prefill_inner.rs:661-668), decode steps decode_select against them; selection is inert below index_topk + index_compress_ratio - 1 visible tokens (the "budget" bound, decode_a2.rs:127-134). Selection scratch is a fixed-address arena sized in buffers/sizes.rs:539-550 (ROWS=2048, q/k-weight + key + score-block + topk regions), with the ROWS constant duplicated in qsa_select.rs:136 β a coupling that should be a shared const.
6. MoE routing.
Reuses the existing event-dispatch / hash-MoE machinery (token_ids stable buffer for tid2eid), plus route-aware LoRA handling on the new paths (moe_lora_route, reject_decode_lora on multi-seq/speculative). The batched FFN ladder explicitly *refuses* shortcut-MoE models rather than silently computing an incomplete block (multi_seq/ffn.rs:41-49) β good fail-loud discipline.
7. MTP / speculative.
layers/qwen4exp_mtp_forward.rs, layers/deepseek_v4_mtp.rs, and the verify family (verify_a/b/c/c2/d/e/fused), with PLE/QSA hooks threaded through: per-seq prestaging, row_owner maps so the indexer advances once per row against its owner (verify_e.rs:474-481, multi_seq/mod.rs:247-289), and mapped-argmax to kill a measured 137 ms copy-engine tail stall (verify_e.rs:566-581).
8. Sequence-op bookkeeping (prefix cache / snapshots / HSS).
A new generic aux-state mechanism: Layer::{has_aux_state, snapshot_aux, restore_aux} driven by collect_aux_states / apply_aux_states / requires_aux_state (model/trait_impl/mod.rs:893-935), blobs attached to SSM snapshot slots (model/ssm_snapshot.rs:452-470), and a restore gate that declines aux-less snapshots for aux-carrying models (prefill_a.rs:155, prefill_c.rs:194, prefill_b/prefix_lookup.rs:208-211). Aux is captured at every snapshot site: chunk-boundary (prefill_b/finalize_last.rs:393-400), intermediate checkpoint (prefill_b/save_checkpoint.rs:137-146), decode Marconi checkpoint and retire-leaf (decode_checkpoint.rs:131-142, 254-263). This is the right shape for PLE history + QSA indexer keys, which a GDN-only snapshot would otherwise silently drop.
9. Kernels.
kernels/gb10/qwen3.8-flash-next/ (nvfp4 PLE chain, hc ops, GDN) and kernels/gb10/common/qwen4exp_ple.cu, with oracle/parity harnesses (layers/ops/qwen4exp_oracle_ple_tests.rs runs the *production* ple_gate β ple_conv β ple_add_highway chain against a reference; ple_tests.rs, qsa_tests*.rs, microtest examples under spark-model/examples/qwen4exp_microtest/).
---
Where the PR is right, and right in a non-obvious way:
sizes.rs:627-629) shows the authors understand silent-corruption failure modes, not just loud ones.hc_pre's grouped norm *is* the input norm on Qwen.** Reusing it rather than applying a second RMS with a ones-placeholder is the correct reading of a checkpoint that has no input_layernorm; the code explicitly notes the placeholder "would NOT make a second RMS an identity" (prefill_inner.rs:652-658). This is the kind of divergence between V4 and Flash-Next that ports usually get wrong silently.decode_select returns Some where the gate promised inert, the layer bails rather than serving dense-past-budget attention, which "is NOT the reference model" (multi_seq/mod.rs:247-288). Same pattern for shortcut-MoE and HSS in batched prefill.Notable divergences / debatable choices:
decode_a.rs:247-250, decode_a2.rs:260-265). Sound correctness-wise β a dense-captured graph replaying after selection activates would be catastrophic β but it means once any sequence crosses the budget bound, *all* decode goes eager and/or per-seq. That is a large, permanent perf cliff for long-context Flash-Next serving, and it is architectural, not incidental.decode_a2.rs:114-136), with logits staged through the host per sequence. Correct, but the "real concurrent batches, not queued interleaving" claim is only true below the QSA inert bound or with the batched GEMM core engaged β and the core is explicitly *not* engaged under the highway (trait_decode_multi_seq/hc.rs:26-29). The headline capability is therefore narrower than the PR text implies.index_topk interpreted as a token budget with selection inert below topk + ratio - 1 β is a serving shortcut: past the budget, selection activates and everything gets slow. It matches a 2048-token scratch design, but it hard-couples max effective context behavior to a buffer constant duplicated in two files.hc_streams is FP32 sized by max(mult, count) β good β but the dual-spelling (hc_mult and hc_count both live on the config) is a standing foot-gun; it is defended only by tests, not by construction.---
I could positively identify several of the class of fixes the PR claims, and they are genuine silent-corruption fixes, not cosmetic:
hc_count vs hc_mult buffer sizing (sizes.rs:611-631): a model spelling the field hc_count would have received a 256-byte placeholder highway and written over neighboring buffers. Fixed with a max-of-both allocation and four tests. Sound.host_token_ids (trait_decode_multi_seq/hc.rs:85-112, documented in decode_a2.rs:381-394): the per-seq PLE loop bounded by padded_n indexing an active-length slice β previously rejected every non-boundary batch ("3 host ids for 4 seqs"). The fix (skip padding rows, which carry ple: None by construction; stay loud for a live state with no token) is correct. However β see D1 below.decode_a2.rs:147-154): staging logits copies on the scheduler's stream 0 while decode() runs on the backend default stream produced a measured two-way row swap at every C=2 step. Fixed by staging on gpu.default_stream() with copy_d2h_on_stream. Sound, and a textbook silent cross-sequence contamination bug.verify_c.rs:186-197): the indexer's ingested counter froze at the capture step while the sequence advanced, surfacing only at the MTP gate's batch-width switch ("decode at pos 34 but 26 tokens ingested"). Fixed by extending the decode_graph_unsupported veto to the verify paths. Sound.verify_c.rs:199-212, verify_e.rs:421-437): without hoisting, the forward fell back to a D2H readback that invalidated the recording graph (error 901). Fixed; and the multi-seq variant in verify_e correctly windows per sequence.ple/layer.rs:413-456): per-row conv launches + parked carries at verify widths. The mechanism is sound; the *rollback application* is the risk (see D3).D1 β Padding-row PLE skip is a correctness landmine in the graph-borrow path (medium-high).
trait_decode_multi_seq/hc.rs:98-105 treats "no ple state" as "padding row, skip". That invariant holds for the all_layer_states construction in decode_a2.rs:434-468 (ple: None for pads) and for the drain-tail graph borrow. But the same take(n) loop is used with states vectors built elsewhere (e.g. decode_batched_hc.rs:164 uses the stricter host.len() >= n check β the two call sites have *diverged* on the same question). If any future caller hands a live sequence whose ple field is None because its state was constructed through a different path (checkpoint restore, h_prefill_stage variants, LoRA paths), the row silently receives no PLE injection β degraded output with no error. The safe form is to pass the active count separately (or a per-row is_pad flag) rather than inferring padding from state contents.
D2 β Aux blobs live only in a host HashMap keyed by snapshot slot (high).
ssm_snapshot.rs:65, 452-470: aux (PLE n-gram history, conv carry, QSA indexer keys) is a Mutex<HashMap<usize, Vec<u8>>> in RAM. But the SSM snapshot pool has an explicit spill/fault-in tier (ssm_snapshot_spill.rs, ssm_snapshot_faultin.rs, ssm_tier/) and free() drops aux with the slot. Consequences: (i) a snapshot spilled to the NVMe tier and faulted back β or a process restart with tier replay β restores SSM state but is aux-less, so the restore gate declines it: correct, but every warm multi-turn hit that spilled silently loses its Marconi benefit; (ii) there is no versioning/serialization format, so any blob-layout change is an in-place corruption across a rolling deploy if the tier store survives; (iii) aux is cloned on every aux() read. This is the weakest data-lifecycle decision in the PR.
D3 β Verify conv-carry rollback: snapshot mechanism visible, rewind application not proven.
ple/layer.rs parks per-row carries into st.verify_snaps and records verify_snap_rows, and ple/verify.rs exists, but I did not find (nor a test demonstrating) the rewind being invoked on *partial* acceptance in every verify variant (verify_a/b/c/c2/d/e/fused β six paths; verify_e additionally has ghost/borrowed rows). If any one accept path forgets the rewind, the conv carry is over-advanced by the rejected suffix β a silent, slowly-accumulating quality regression that only shows up with drafts rejected mid-window, i.e. exactly the regime benchmarks don't stress. This needs a targeted test, not inspection.
D4 β QSA row_owner ordering is an asserted invariant, not an enforced one.
multi_seq/mod.rs:253-288: "decode_select asserts pos == ingested, so the ordering here is the invariant, not an optimization." Several rows share one sequence's state and must advance in row order. The assert exists, but the batched path also *relies on the dispatch gate agreeing* (sel.is_none() bail). Two independent mechanisms (gate + assert) guarding one property is fine, but the gate computes activity from seqs.iter().any(|s| s.seq_len >= bound) while the assert fires per-row mid-forward β a mismatch aborts a request in flight rather than never occurring.
D5 β Exact-leaf snapshot shortcut is disabled by default.
prefix_lookup.rs:299-310: the exact full-prompt hit path is force-recomputed ("ATLAS_MARCONI_EXACT=1 re-enables") because cache-on workspace quality was ~23% vs ~60% cache-off. That is an admission that the exact-hit path (including the stashed-hidden first-token trick) is still suspect on this model family. Defensible as a default, but it means the PR's prefix-cache story is materially weaker than its code volume suggests, and the disabled path still ships.
D6 β hc_streams FP32 at max_batch Γ 4 Γ H Γ 4 bytes is a large fixed arena (e.g. 128Γ4Γ2560Γ4 β 5 MB β fine on GB10, but it scales with batch and is allocated whenever either hc spelling is nonzero, including for speculative row widths r_total that exceed decode batch). Verify the arena is sized against r_total (VERIFY_ROW_CAP) and not just decode padded_n; I saw hc buffers indexed by n on the verify path with n = Ξ£ ks[i].
D7 β Smaller items.
qsa_select_scratch ROWS=2048 duplicated in qsa_select.rs:136 and sizes.rs:540 β must be one const.hc_pre_k is used for *both* the attn and ffn sites (trait_decode_multi_seq/hc.rs:127,187) β correct only if the checkpoint shares the low-rank projection across sites per layer; worth a parity assertion.prefill_inner_hc bails on batched mode with seq_len_start == 0 and on HSS-engaged layers β correct refusals, but they mean batched prefill + highway + HSS is simply unsupported (gap, below).ple_gate kernel exists twice (nvfp4/ple.cu and common/qwen4exp_ple.cu as q4e_ple_gate); the oracle test exercises the nvfp4 one (qwen4exp_oracle_ple_tests.rs:33) while production PleLayer loads "ple"/"ple_gate" and the microtest loads "qwen4exp_ple"/"q4e_ple_gate". Two implementations of the same math, only one oracle-covered β classic drift risk.---
trait_decode_multi_seq/hc.rs:26-29); concurrent-batch bandwidth scaling is therefore not yet delivered.comm.is_some().---
Merge-ready with conditions β I would not merge as-is; I would merge after a short, targeted hardening pass. The architecture reading is excellent (FP32 highway, norm reuse, PLE ordering, aux-gated restore, fail-loud gates), and the silent-defect fixes I could identify are real, well-diagnosed, and soundly repaired. The residual risk is concentrated in (1) padding-row inference by state contents (D1), (2) the un-tiered, unversioned aux blob lifecycle (D2), and (3) unproven conv-carry rewind across the six verify paths (D3).
Tests I would require before merge:
ingested equal the no-draft reference state (bitwise for conv, since it's the rewindable one).ATLAS_HC_PERSEQ_DECODE on/off, asserting batched decode == per-seq decode logits within tolerance β this is the regression class that produced "3 host ids for 4 seqs".index_topk + ratio - 1 in one batch; assert the gate routes per-seq, no sel.is_none() bail fires, and outputs match a dense-reference for below-budget and the reference sparse selection above it.ple_gate vs q4e_ple_gate (and the conv/add twins) on identical inputs in CI, or delete one.qwen4exp_reference crate on the checkpoint: greedy prompts at lengths spanning {below budget, across budget, across a chunk boundary, across a snapshot restore}, with the quickstart recipe run as a smoke test.hc_streams/hc_post/hc_comb sizing covers r_total on the widest verify configuration.Fix D1 (explicit pad flag), file D2 as a blocking follow-up with the blob format versioned *now* (before any tier store exists to migrate), land the D3 test, and this is a strong merge.
parsers/qwen4_exp.rs + Qwen4ExpWeightLoader (also maps the qwen3_8_flash_next naming); both-or-neither validation of hc_mult/hc_lowrank; an MTP loader module exists.NgramTable does row-granular pread off NVMe (~2.5 KB/token) with a host row cache β further than either reference engine (vLLM: resident; llama.cpp: mmap CPU tensor). The pread-not-mmap rationale (no invisible page-fault stalls near CUDA threads; io::Error instead of SIGBUS) is sound and GB10-appropriate.Better than both reference engines on PLE memory strategy for this hardware; simpler than both on QSA (no cell-aligned third cache, no compressed-key cache) β defensible for v1 single-GB10; stage 2 will need one of those designs. The eight-defect narrative checks out where visible: shard-mapped rows (#1), dtype-aware strides (#2), pin-lifetime fix (#5) each carry an honest post-mortem in comments.
Merge-worthy engineering, gated on: CLA, the PLE scratch default fix, a long-context (>2051) quality gate, and tap-diff in CI on a slice checkpoint. The evidence culture (bitwise-determinism control, independent reproduction, honest known-not-done) is the best seen in this evaluation. Perf context: 14.5β16.5 tok/s single NVFP4 trails llama.cpp's ~25 (Q3 GGUF), but 28.4 aggregate @4 streams is the batching llama.cpp can't do β Atlas's reason to exist.
The capstone: Claude as orchestrator/reviewer, spark's models as executors, turning the round-4 review findings into real patches against Atlas PR #16 β culminating in PR #17. 2026-08-31 β 09-01.
| # | Item | Executor | Outcome |
|---|---|---|---|
| 1 | RadixArk NVFP4 checkpoint (126 GB, 206 shards) verify | orchestrator + agent | β SERVE-READY (all config fields match parser) |
| 2 | Build PR #16 tree on GB10 | agent diagnose + orchestrator verify | β (found CUDARC_CUDA_VERSION convention; NCCL link dep harvested from container) |
| 3 | π§ͺ Gate 1: quickstart | orchestrator | β 7/7 coherence Β· 6/6 tools Β· 17.0 / 36.5 tok/s β above the author's 14.5 / 28.4 (3rd independent GB10) |
| 4 | PLE docs staleness fix | 27B | β 12 steps, 88 s β after discovering the intended code fix already existed in the PR |
| 5 | QSA scratch-rows shared const | 27B | β textbook diff, lint-aware |
| 6 | π§ͺ Gate 2: regression | orchestrator | β on rerun (first run lost a temp-1.0 sampling dice roll β probes are stochastic by design) |
| 7 | Explicit padding-row accounting (review finding D1) | 27B plan Γ2 β A executes | β 8-file behavioral fix + negative test; 654 tests green |
| 8 | PLE rewind partial-acceptance test (D3) | A Γ4 | β not landed β fully specced (seam proven CPU-observable), attached as suggested test |
| 9 | π§ͺ Gate 3: cuda suite + quickstart | orchestrator | β after fixing a pre-existing doctest failure the gate itself exposed |
QSA_SELECT_SCRATCH_ROWS β one authoritative constant (was duplicated with a "must agree" comment)active_seqs threading β a live row with no PLE carry now fails loudly instead of silently losing its n-gram injection; includes a MockGpuBackend negative testfault_threads timing table fenced as text (was compiled as a Rust doctest and failing --doc)Status at time of writing: CLA signed β ; five CI workflows awaiting first-time-contributor approval from the maintainer.
args β v__args), context pruning evicting the brief (fixed by pinning it into the system prompt), env-var-capable cargo needed to run the repo's own documented commands.Everything above was produced by two small Python programs driving llama.cpp's OpenAI-compatible
endpoint through LangGraph, plus bash drivers (server lifecycle: stop prod β serve config β run β trap-restore prod). The research agent below is
the round-2 version; rounds 3β4 are the same program with the repo pair, marker and system prompt swapped. Full archive on spark:
~/agentbench/ (agents, briefs, per-item traces) and ~/driver_*.sh.
#!/usr/bin/env python3
# Agentic shootout round 2: compare vLLM's Flash-Next implementation (PR #53896 branch)
# with Atlas, produce an adoption plan. usage: agent2.py <base_url_v1> <label>
import json, os, subprocess, sys, time
from langchain_core.tools import tool
from langchain_core.messages import HumanMessage, AIMessage, ToolMessage
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
BASE = sys.argv[1]
LABEL = sys.argv[2]
REPOS = {"atlas": os.path.expanduser("~/agentbench/atlas"),
"vllm": os.path.expanduser("~/agentbench/vllm")}
OUT = os.path.expanduser(f"~/agentbench/out2/{LABEL}")
os.makedirs(OUT, exist_ok=True)
trace = open(f"{OUT}/trace.jsonl", "a")
T0 = time.time()
MARKER = "# Flash-Next support: vLLM vs Atlas"
def _safe(repo: str, path: str) -> str:
root = REPOS.get(repo)
if not root:
raise ValueError("repo must be 'atlas' or 'vllm'")
p = os.path.normpath(os.path.join(root, path.lstrip("/")))
if not p.startswith(root):
raise ValueError("path escapes repo")
return p
@tool
def list_dir(repo: str, path: str = ".") -> str:
"""List files/directories at a path inside a repository. repo is 'atlas' (Rust inference
engine) or 'vllm' (Python, checked out at the Flash-Next support PR #53896 branch).
Directories end with '/'."""
p = _safe(repo, path)
if not os.path.isdir(p):
return f"not a directory: {repo}:{path}"
out = []
for e in sorted(os.listdir(p)):
if e in (".git", "target", "__pycache__"):
continue
full = os.path.join(p, e)
out.append(e + "/" if os.path.isdir(full) else f"{e} ({os.path.getsize(full)}b)")
return "\n".join(out[:200]) or "(empty)"
@tool
def read_file(repo: str, path: str, start_line: int = 1) -> str:
"""Read up to 200 lines of a file in repo 'atlas' or 'vllm', starting at start_line (1-based).
Call again with a higher start_line to continue."""
p = _safe(repo, path)
if not os.path.isfile(p):
return f"not a file: {repo}:{path}"
try:
lines = open(p, errors="replace").read().splitlines()
except Exception as e:
return f"error: {e}"
s = max(1, int(start_line)) - 1
chunk = lines[s:s + 200]
body = "\n".join(f"{s+i+1}: {l[:400]}" for i, l in enumerate(chunk))
more = f"\n... file has {len(lines)} lines total" if len(lines) > s + 200 else "\n(end of file)"
return (body or "(empty)") + more
@tool
def search_code(repo: str, pattern: str, subdir: str = ".") -> str:
"""Search a repository ('atlas' or 'vllm') for a regex pattern (grep -rn, case-insensitive).
Returns up to 60 matching lines as path:line:text."""
p = _safe(repo, subdir)
try:
r = subprocess.run(
["grep", "-rniI", "--include=*.rs", "--include=*.py", "--include=*.cu",
"--include=*.cuh", "--include=*.toml", "--include=*.md",
"--exclude-dir=.git", "--exclude-dir=target", "--exclude-dir=__pycache__",
"-e", pattern, p],
capture_output=True, text=True, timeout=60)
except subprocess.TimeoutExpired:
return "search timed out; use a narrower pattern or subdir"
total = len(r.stdout.splitlines())
lines = [l.replace(REPOS[repo] + "/", f"{repo}:")[:300] for l in r.stdout.splitlines()[:60]]
tail = f"\n... {total} total matches (showing 60)" if total > 60 else ""
return ("\n".join(lines) or "no matches") + tail
@tool
def read_flashnext_reference() -> str:
"""Read the Qwen3.8-Flash-Next (qwen4exp) architecture reference: every feature an
inference engine must implement to run this model."""
return open(os.path.expanduser("~/agentbench/flashnext_reference.md")).read()
SYSTEM = """You are a senior systems engineer. Two codebases are available through your tools:
- repo 'vllm' (Python): vLLM checked out at the branch of PR #53896, which ADDS Qwen3.8-Flash-Next (qwen4exp) support. This is a real, working implementation. Key areas to find: model definition, config conversion, Gated DeltaNet integration, QSA sparse attention + indexer, per-layer n-gram (PLE) embedding handling, hyper-connections, MoE routing, MTP. (Separate open PRs #53899/#54129/#54371 add PLE offload via UVA/mmap; they are NOT in this tree, but PLE handling in this tree shows the baseline.)
- repo 'atlas' (Rust): the Atlas inference engine for NVIDIA GB10, which does NOT yet support qwen4exp.
Your goal: a comparative implementation analysis that tells the Atlas team exactly how to add Flash-Next support, using vLLM's implementation as the blueprint.
Method:
1. Read the Flash-Next architecture reference.
2. In 'vllm': locate and READ the qwen4_exp implementation (search for qwen4_exp, flash_next, deltanet, qsa, indexer, ngram, ple, hyper). Understand HOW each architectural feature is implemented: dataflow, caching strategy, kernels/ops used, config plumbing.
3. In 'atlas': determine per feature what exists, partially exists, or is missing (search for: gated delta, ssm, moe, expert, sparse, indexer, hyper_connection, mtp, ngram, per_layer).
4. Compare: for each feature, how vLLM does it vs what Atlas would need.
IMPORTANT OUTPUT RULE: when quoting chat-template or special tokens, ALWAYS write them with square brackets (e.g. [think], [/tool_call], [IM_START]) β NEVER with literal angle brackets, which corrupt the transport.
When (and only when) research is complete, output the final report in markdown, starting exactly with:
# Flash-Next support: vLLM vs Atlas
Report sections: (a) how vLLM implements qwen4exp β feature by feature, with file citations; (b) Atlas current status per feature, with file citations; (c) side-by-side comparison table (feature | vLLM mechanism | Atlas status | port difficulty); (d) a concrete, prioritized adoption plan for Atlas that borrows vLLM's design decisions where sensible (and diverges where Rust/GB10 constraints demand); (e) risks and open questions."""
TASK = ("Compare vLLM's Qwen3.8-Flash-Next implementation (PR #53896 tree) with Atlas and produce "
"the comparative gap analysis and Atlas adoption plan.")
llm = ChatOpenAI(
base_url=BASE, api_key="x", model="qwen",
temperature=0.3, max_tokens=10240, timeout=3600,
extra_body={"chat_template_kwargs": {"enable_thinking": False}},
)
tools = [read_flashnext_reference, list_dir, read_file, search_code]
def prune(state):
msgs = state["messages"]
head, tail = msgs[:1], msgs[1:]
budget = 150_000
kept, size = [], 0
for m in reversed(tail):
c = m.content if isinstance(m.content, str) else json.dumps(m.content)
size += len(c)
kept.append(m)
if size > budget:
break
kept = list(reversed(kept))
while kept and isinstance(kept[0], ToolMessage):
kept.pop(0)
out = head + kept
if len(msgs) > 260:
out = out + [HumanMessage(
"You have used a very large number of research steps. Finish up: stop calling tools and "
f"write the complete final report NOW, starting with '{MARKER}'.")]
return {"llm_input_messages": out}
agent = create_react_agent(llm, tools, prompt=SYSTEM, pre_model_hook=prune)
steps = tool_calls = 0
in_tok = out_tok = 0
report = None
messages = [HumanMessage(TASK)]
last_msgs = messages
try:
for chunk in agent.stream({"messages": messages},
config={"recursion_limit": 400}, stream_mode="values"):
last_msgs = chunk["messages"]
m = last_msgs[-1]
if isinstance(m, AIMessage):
steps += 1
u = getattr(m, "usage_metadata", None) or {}
in_tok += u.get("input_tokens", 0)
out_tok += u.get("output_tokens", 0)
calls = [tc["name"] for tc in (m.tool_calls or [])]
tool_calls += len(calls)
content = m.content if isinstance(m.content, str) else ""
trace.write(json.dumps({"t": round(time.time() - T0, 1), "step": steps,
"tools": calls, "in": u.get("input_tokens", 0),
"out": u.get("output_tokens", 0),
"content_head": content[:150]}) + "\n")
trace.flush()
print(f"[{LABEL} step {steps}] t={time.time()-T0:.0f}s tools={calls} "
f"in={u.get('input_tokens',0)} out={u.get('output_tokens',0)}", flush=True)
if MARKER in content:
report = content
except Exception as e:
print(f"[{LABEL}] agent loop ended: {type(e).__name__}: {str(e)[:200]}", flush=True)
if report is None:
print(f"[{LABEL}] forcing final report", flush=True)
try:
from langchain_core.messages import SystemMessage
pruned = prune({"messages": list(last_msgs)})["llm_input_messages"]
# call the RAW llm with no tools bound: it physically cannot call tools
final_msg = llm.invoke(
[SystemMessage(SYSTEM)] + pruned + [HumanMessage(
"Research is over. Using everything gathered above, write the complete final report "
f"immediately. Start with '{MARKER}'.")])
if isinstance(final_msg.content, str) and len(final_msg.content) > 1000:
report = final_msg.content
u = getattr(final_msg, "usage_metadata", None) or {}
in_tok += u.get("input_tokens", 0); out_tok += u.get("output_tokens", 0)
except Exception as e:
print(f"[{LABEL}] force-final failed: {e}", flush=True)
wall = time.time() - T0
if report:
open(f"{OUT}/report.md", "w").write(report)
summary = {"label": LABEL, "wall_s": round(wall, 1), "llm_steps": steps, "tool_calls": tool_calls,
"input_tokens": in_tok, "output_tokens": out_tok,
"gen_tps_overall": round(out_tok / wall, 2) if wall else 0,
"report": bool(report), "report_chars": len(report or "")}
open(f"{OUT}/summary.json", "w").write(json.dumps(summary, indent=1))
print(f"=== AGENT_SUMMARY {json.dumps(summary)}", flush=True)
print(f"=== AGENTBENCH2_DONE {LABEL} ===", flush=True)
#!/usr/bin/env python3
# Executor agent: carries out ONE work item on the Atlas PR-16 work tree.
# usage: agent5.py <base_url_v1> <item_id> <brief_path>
# Budget: 50 agent turns. Orchestrator reviews the diff afterwards.
import json, os, subprocess, sys, time
from langchain_core.tools import tool
from langchain_core.messages import HumanMessage, AIMessage, ToolMessage, SystemMessage
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
BASE = sys.argv[1]
ITEM = sys.argv[2]
BRIEF_PATH = sys.argv[3]
WORK = os.path.expanduser("~/agentbench/atlas-work")
OUT = os.path.expanduser(f"~/agentbench/items/{ITEM}")
os.makedirs(OUT, exist_ok=True)
trace = open(f"{OUT}/trace.jsonl", "a")
T0 = time.time()
MARKER = "# ITEM COMPLETE"
def _safe(path: str) -> str:
p = os.path.normpath(os.path.join(WORK, path.lstrip("/")))
if not p.startswith(WORK):
raise ValueError("path escapes the work tree")
return p
@tool
def read_brief() -> str:
"""Read this work item's brief: the goal, constraints, and acceptance criteria."""
return open(BRIEF_PATH).read()
@tool
def list_dir(path: str = ".") -> str:
"""List files/directories at a path in the work tree."""
p = _safe(path)
if not os.path.isdir(p):
return f"not a directory: {path}"
out = []
for e in sorted(os.listdir(p)):
if e in (".git", "target", "__pycache__"):
continue
full = os.path.join(p, e)
out.append(e + "/" if os.path.isdir(full) else f"{e} ({os.path.getsize(full)}b)")
return "\n".join(out[:200]) or "(empty)"
@tool
def read_file(path: str, start_line: int = 1) -> str:
"""Read up to 200 lines of a file in the work tree, starting at start_line (1-based)."""
p = _safe(path)
if not os.path.isfile(p):
return f"not a file: {path}"
lines = open(p, errors="replace").read().splitlines()
s = max(1, int(start_line)) - 1
chunk = lines[s:s + 200]
body = "\n".join(f"{s+i+1}: {l[:400]}" for i, l in enumerate(chunk))
more = f"\n... file has {len(lines)} lines total" if len(lines) > s + 200 else "\n(end of file)"
return (body or "(empty)") + more
@tool
def search_code(pattern: str, subdir: str = ".") -> str:
"""Search the work tree for a regex pattern (grep -rn, case-insensitive), up to 60 hits."""
p = _safe(subdir)
r = subprocess.run(
["grep", "-rniI", "--include=*.rs", "--include=*.toml", "--include=*.cu",
"--include=*.py", "--include=*.sh", "--include=*.yaml", "--include=*.md",
"--exclude-dir=.git", "--exclude-dir=target", "-e", pattern, p],
capture_output=True, text=True, timeout=60)
total = len(r.stdout.splitlines())
lines = [l.replace(WORK + "/", "")[:300] for l in r.stdout.splitlines()[:60]]
tail = f"\n... {total} total matches (showing 60)" if total > 60 else ""
return ("\n".join(lines) or "no matches") + tail
@tool
def edit_file(path: str, old: str, new: str) -> str:
"""Edit a file by exact string replacement. `old` must appear EXACTLY ONCE in the file
(include enough surrounding lines to make it unique). Returns ok or a precise error."""
p = _safe(path)
if not os.path.isfile(p):
return f"not a file: {path}"
src = open(p, errors="replace").read()
n = src.count(old)
if n == 0:
return "ERROR: `old` not found β re-read the file and copy the text exactly"
if n > 1:
return f"ERROR: `old` appears {n} times β include more context to make it unique"
open(p, "w").write(src.replace(old, new, 1))
return f"ok: replaced 1 occurrence in {path}"
@tool
def write_file(path: str, content: str) -> str:
"""Create or overwrite a file in the work tree (use for NEW files, e.g. tests)."""
p = _safe(path)
os.makedirs(os.path.dirname(p), exist_ok=True)
open(p, "w").write(content)
return f"ok: wrote {len(content)} bytes to {path}"
@tool
def cargo(command_line: str) -> str:
"""Run cargo in the work tree. Pass the full cargo arguments as one string in `command_line`.
Allowed subcommands: check, build, test, fmt, metadata. You may prefix whitelisted
env assignments (CUDARC_CUDA_VERSION, ATLAS_SKIP_BUILD, ATLAS_TARGET_HW/MODEL/QUANT, RUST_BACKTRACE).
Example: command_line='CUDARC_CUDA_VERSION=13000 check --workspace'."""
parts = command_line.split()
env = dict(os.environ)
env["PATH"] = os.path.expanduser("~/.cargo/bin") + ":" + env.get("PATH", "")
ALLOWED_ENV = ("CUDARC_CUDA_VERSION", "ATLAS_SKIP_BUILD", "ATLAS_TARGET_HW",
"ATLAS_TARGET_MODEL", "ATLAS_TARGET_QUANT", "RUST_BACKTRACE")
while parts and "=" in parts[0] and not parts[0].startswith("-"):
k, _, v = parts[0].partition("=")
if k not in ALLOWED_ENV:
return f"ERROR: env var {k} not in whitelist {ALLOWED_ENV}"
env[k] = v
parts = parts[1:]
if not parts or parts[0] not in ("check", "build", "test", "fmt", "metadata"):
return "ERROR: only check/build/test/fmt/metadata are allowed"
try:
r = subprocess.run(["cargo"] + parts, cwd=WORK, capture_output=True, text=True,
timeout=3600, env=env)
except subprocess.TimeoutExpired:
return "ERROR: cargo timed out after 3600s"
out = (r.stdout + "\n" + r.stderr).strip()
lines = out.splitlines()
if len(lines) > 120:
out = "\n".join(lines[:20]) + f"\n... [{len(lines)-80} lines elided] ...\n" + "\n".join(lines[-60:])
return f"exit={r.returncode}\n{out}"
@tool
def git_diff() -> str:
"""Show the current uncommitted diff of the work tree (your changes so far)."""
r = subprocess.run(["git", "diff", "--stat"], cwd=WORK, capture_output=True, text=True)
r2 = subprocess.run(["git", "diff"], cwd=WORK, capture_output=True, text=True)
d = r2.stdout
if len(d) > 12000:
d = d[:12000] + "\n... [diff truncated]"
return r.stdout + "\n" + d
SYSTEM = """You are a senior Rust engineer executing ONE scoped work item on the Atlas inference
engine (work tree = the PR #16 qwen4exp branch). Read the brief FIRST (read_brief), then do exactly
what it asks β no scope creep, no drive-by refactors. The diff you leave will be reviewed by a human
orchestrator and become a standalone PR, so keep it minimal, correct, and in the codebase's own style
(match the surrounding comment density and naming).
Rules:
- Verify claims by reading code, not by assumption.
- After editing, run the brief's acceptance commands (cargo check/test as specified) and fix what breaks.
- You have a budget of ~50 turns. Leave time to verify.
- When (and only when) the item is done and verified, output a summary starting exactly with:
# ITEM COMPLETE
containing: what changed (files), why, how it was verified (commands + results), and anything the
reviewer must double-check."""
llm = ChatOpenAI(
base_url=BASE, api_key="x", model="qwen",
temperature=0.2, max_tokens=8192, timeout=3600,
extra_body={"chat_template_kwargs": {"enable_thinking": False}},
)
tools = [read_brief, list_dir, read_file, search_code, edit_file, write_file, cargo, git_diff]
def prune(state):
msgs = state["messages"]
head, tail = msgs[:1], msgs[1:]
budget = 140_000
kept, size = [], 0
for m in reversed(tail):
c = m.content if isinstance(m.content, str) else json.dumps(m.content)
size += len(c)
kept.append(m)
if size > budget:
break
kept = list(reversed(kept))
while kept and isinstance(kept[0], ToolMessage):
kept.pop(0)
out = head + kept
if len(msgs) > int(os.environ.get("ITEM_NUDGE_MSGS", "80")):
out = out + [HumanMessage(
f"Budget nearly exhausted. Finish verification and output the summary NOW, starting with '{MARKER}'.")]
return {"llm_input_messages": out}
# pin the brief into the system prompt so context pruning can never evict it
SYSTEM = SYSTEM + "\n\n===== THE WORK ITEM BRIEF (authoritative, do exactly this) =====\n" + open(BRIEF_PATH).read()
agent = create_react_agent(llm, tools, prompt=SYSTEM, pre_model_hook=prune)
steps = 0
in_tok = out_tok = 0
report = None
messages = [HumanMessage("Execute the work item described by read_brief().")]
last_msgs = messages
try:
for chunk in agent.stream({"messages": messages},
config={"recursion_limit": int(os.environ.get("ITEM_RECURSION", "100"))}, stream_mode="values"):
last_msgs = chunk["messages"]
m = last_msgs[-1]
if isinstance(m, AIMessage):
steps += 1
u = getattr(m, "usage_metadata", None) or {}
in_tok += u.get("input_tokens", 0)
out_tok += u.get("output_tokens", 0)
calls = [tc["name"] for tc in (m.tool_calls or [])]
content = m.content if isinstance(m.content, str) else ""
trace.write(json.dumps({"t": round(time.time()-T0, 1), "step": steps, "tools": calls,
"in": u.get("input_tokens", 0), "out": u.get("output_tokens", 0),
"head": content[:120]}) + "\n")
trace.flush()
print(f"[{ITEM} step {steps}] t={time.time()-T0:.0f}s {calls}", flush=True)
if MARKER in content:
report = content
except Exception as e:
print(f"[{ITEM}] loop ended: {type(e).__name__}: {str(e)[:200]}", flush=True)
if report is None:
print(f"[{ITEM}] forcing summary", flush=True)
try:
pruned = prune({"messages": list(last_msgs)})["llm_input_messages"]
fm = llm.invoke([SystemMessage(SYSTEM)] + pruned + [HumanMessage(
f"Time is up. Output the item summary NOW, starting with '{MARKER}'. State honestly what is done and what is not.")])
if isinstance(fm.content, str):
report = fm.content
except Exception as e:
print(f"[{ITEM}] force-final failed: {e}", flush=True)
if report:
open(f"{OUT}/summary.md", "w").write(report)
print(f"=== ITEM_STATS {json.dumps({'item': ITEM, 'wall_s': round(time.time()-T0,1), 'steps': steps, 'in': in_tok, 'out': out_tok, 'summary': bool(report)})}", flush=True)
print(f"=== ITEM_DONE {ITEM} ===", flush=True)
None of the stages above were isolated experiments β they were a selection funnel, each stage cutting candidates and feeding what survived into a harder test, until the survivor was put to work on a real deliverable:
| Stage | Field | Cut / decision | What it taught the next stage |
|---|---|---|---|
| 1. Feasibility screen | 6 configs (P, A, B, C, D, E) Γ 3 engines | D out (vLLM can't load qwen4_exp), C out (12.5 tok/s), B dominated by A | the working recipes + the stop-prod rule (unified memory) |
| 2. Capability benches | P, E2, A | none cut β profiles built: prod fastest, Flash-Next best craft; no-think mandatory | prompts, budgets and sampling for agentic work |
| 3. Agentic research Γ3 | P, E2, A on real codebases | P out for long-horizon work (never terminates, pruning amnesia); E2 β A, A most consistent | verification-first grading; wrap-up pressure; token-escape rule |
| 4. External calibration | A vs Claude on a 45K-line PR | A confirmed at/above strong-reviewer level (9.5 vs 8) | the exact defect list that became the work items |
| 5. Selection | A (Q4) chosen as sole executor β by measured behavior, not benchmark folklore; 27B kept briefly as investigator, then retired | ||
| 6. Harness & delivery | A + orchestrator/reviewer | 9 items, 3 hardware gates, task-shaped budgets | shipped: Atlas PR #17, 4 verified fixes on a real engine |
The point of the funnel: benchmarks were never the product β they were selection pressure. Every number earned its keep by deciding something (a config cut, a budget set, a role assigned), and by stage 6 the choice of executor, its turn budget, its sampling mode, and even its prompt hygiene were all decisions the earlier stages had already paid for. That is the reusable method: screen wide on your own hardware β profile on tasks shaped like your real work β select on verified behavior β spend the harness engineering on the survivor.
self-maintenance, as demonstrated by the field's true pioneer Β· via Tenor