A06_9 — DETR-Style Sparse 3D Transformer CSI Path Predictor (New Branch)
Goal Description
Build, in the sibling directory A06_9_detr_style_voxel_sparse_3d_transformer_net/, a CSI-only network that predicts, for each (scene, TX, RX) triple, a variable number of propagation paths (each path = existence, delay in ns, peak attenuation in dB) using a DETR-style set-prediction head over a sparse 3D voxel backbone. The architecture borrows TRELLIS-2's sparse transformer blocks, sparse 3D downsampling, and AdaLN-zero modulation, and abandons the A06_7 rigid ordered-slot CSI head whose power-undershoot failure mode is considered unfixable.
This branch is explicitly CSI-only. The A06_7 radiomap head is out of scope here and will be re-attached as a frozen-backbone adapter in a later branch.
Plan Version 12 (2026-04-19) — user-directed scope change. The user has instructed the team to drop the cross-model A06_7 throughput baseline comparison ("跳过对比算法 base line a06-7") and focus on the DETR branch's own convergence on single-scene and tiny10 at 200 epochs. Concretely:
- AC-5's "≥ 0.67 × A06_7 baseline" clause is removed; AC-5 is now a self-contained caching + throughput contract (see the AC-5 plan-note).
- Two new acceptance criteria land: AC-11 (training-speed optimization — BF16 default, larger batch, efficient DataLoader, GPU utilization ≥ 70%) and AC-12 (200-epoch convergence sweep on single-scene + tiny10 with per-epoch loss CSV + every-10-epoch full metric JSON + analysis recommending a default training-epoch budget).
- Two new milestones: M6 (training-speed optimization) and M7 (200-epoch sweep). M8 absorbs the optional 30/50/100-scene scale-up and is explicitly conditional on M7's convergence analysis.
- task16–task19 are narrowed to the bring-up path (short single-scene + short tiny10 smoke); the real convergence and AC-8 check live in task22 (200-epoch single-scene) and task23 (200-epoch tiny10 +
convergence_analysis.md).- task20 (profile), task21 (speed optimization implementation), task22 (200-epoch single-scene), task23 (200-epoch tiny10 + analysis) are added.
Acceptance Criteria
Following TDD philosophy, each criterion includes positive and negative tests for deterministic verification.
AC-1: Repository scaffold exists, isolated from A06_7, with reproducible
reference/clones of the external borrowed codebases.- Positive Tests (expected to PASS):
A06_9_detr_style_voxel_sparse_3d_transformer_net/code_snapshot/contains a fresh package (e.g.radiomapvggt_v20_voxel_cir_detr/) whose__init__.py,config.py,models/,data/,engine/,utils/directories are importable without reaching into../A06_7_*/.reference/subdirectory contains read-only clones ofroboflow/rf-detr,happinesslz/SEED,JIA-Lab-research/VoxelNeXt, each pinned to a specific commit hash recorded inreference/MANIFEST.md.pytest code_snapshot/tests/test_import_smoke.pyimports the model, dataset, and trainer classes with zeroImportErrorfrom the new package.
- Negative Tests (expected to FAIL):
- Any
importpath in the new package resolves to a file inside../A06_7_*/(the branch must be self-contained; a grep forA06_7incode_snapshot/returns zero hits outside comments). - Running training with
radiomap_*weights or radiomap manifests loaded raises a configured guard error rather than silently training a radiomap head.
- Any
- Positive Tests (expected to PASS):
AC-2: Target contract is frozen and shared by data, loss, and metrics.
- Positive Tests:
- A single module (e.g.
data/csi_path_targets.py) defines one function that converts a raw Sionna CIR into the set of supervised paths. Whether that set is "raw physical paths" or "merged unique delay-bin paths" is decided in DEC-1; the code matches exactly one option. - The loss module imports the target spec from that module without redefining "what counts as a path".
- The metric module (PDP cosine, peak dB MAE, delay MAE, count accuracy, false-positive rate on zero-path samples) imports the same spec.
- A single module (e.g.
- Negative Tests:
- Two of {data, loss, metric} disagree on whether two co-bin paths are one path or two (the cross-module contract would be broken).
- A sample with zero paths is dropped silently by the collate function (zero-path samples MUST survive to validation).
- Positive Tests:
AC-3: A DETR-style set-prediction CSI head is implemented with Hungarian matching between K learnable path queries and the ground-truth path set, emitting
(exists_logit, delay_pred, peak_db_pred)per query, under the frozen batch tensor contract defined below.Batch Tensor Contract (frozen; referenced by AC-3, AC-5, AC-6, AC-7, AC-9, task5, task10, task11, task12). After collation, a batch holds
Qtriples, whereQis the number of(scene_id, tx_id, rx_id)triples in that batch. The dataset/collator emits:scene_idx [Q]— integer index into the batch's unique scene list;U = number of unique scene_ids in batch.tx_scene_idx [Q]— integer index into the batch's unique(scene_id, tx_id)pair list;P = number of unique (scene, TX) pairs in batch.rx_xyz_norm [Q, 3],tx_xyz_norm [Q, 3],scene_extent [Q, ...], plus the voxel structures indexed by scene.- Ground-truth paths per triple:
gt_num_paths [Q],gt_delay_ns [Q, M_max],gt_peak_db [Q, M_max],gt_path_mask [Q, M_max], whereM_max = max GT paths in the batch.
The head's forward returns exactly:
csi_exists_logits [Q, K],csi_delay_ns [Q, K],csi_peak_db [Q, K], withK = configured query budget(defaultK = 8, subject to DEC-5).- Positive Tests:
- Given a synthetic
Q-triple batch with known GT paths, the Hungarian-matching unit test recovers the correct 1:1 assignment when predictions are close and the correct "no-object" assignment when they are far. - The head's forward returns exactly the three keys above with the exact shapes above; extra keys or missing keys both fail the test.
- Finite-output assert: for random input, all three outputs are finite;
csi_peak_dbis inside[db_low − ε, db_high + ε]under the configured bounded parameterization.
- Given a synthetic
- Negative Tests:
- The head mixes Hungarian matching with an ordered-slot loss applied to unmatched queries (e.g. also penalizing delay_rank of a query marked no-object). This is the exact failure mode Codex flagged and is disallowed.
- The head predicts
peak_dbvia anyfloor_db + softplus(raw)parameterization (with any value offloor_db). Power MUST be produced by a saturating map to[db_low, db_high]configured from dataset statistics (e.g.,db_low + (db_high − db_low) · σ(raw)), so a randomly-initialized head cannot output a value outside the configured dB range.
AC-4: Backbone uses TRELLIS-2-style sparse 3D transformer blocks with at least one sparse 3D downsample stage, and TX is injected as AdaLN-zero global modulation rather than as a separate token.
- Positive Tests:
- The backbone class imports
SparseTransformerBlock(and/orModulatedSparseTransformerBlock) plusSparseDownsamplefrom whichever TRELLIS-2 source DEC-8 resolves to (vendored pinned subset undercode_snapshot/vendor/trellis2_sparse/by default, or live dependency on a pinned commit of/data/conda_envs/trellis2if the user overrides DEC-8), and a forward pass runs on a tiny voxel batch without CUDA OOM on a single 80 GB GPU. - A config switch toggles the number of downsample stages
S ∈ {1, 2, 3}; all three configurations pass a shape-and-finite smoke test on synthetic voxels. - TX injection is implemented via modulation; a unit test confirms that passing two distinct TXs through the backbone yields modulated scene features that differ in at least one AdaLN
scale/shiftvector, and that the underlying SparseTensor coordinates stay the same (only features/modulation differ).
- The backbone class imports
- Negative Tests:
- The model prepends TX and RX as two extra sparse voxel tokens (the exact pattern the draft rules out).
- RX is injected into the backbone before the final downsample stage (RX-conditioned backbone features cannot be reused; late injection is the architectural requirement — see DEC-3).
- Positive Tests:
AC-5: Per-
(scene, TX, RX)inference reuses backbone work across all RXs sharing a(scene, TX)within the batch; throughput is measured in normalized work units so the metric remains comparable as batch shape changes. (Plan Version 12 / 2026-04-19: the cross-model A06_7 throughput ratio is REMOVED per user directive "跳过对比算法 base line a06-7". The A06_7 baseline reruns referenced in prior Round 0–11 summaries are retained on disk for future lookup but are no longer a gate. AC-5 is now a self-contained caching + throughput contract.)- Positive Tests:
- The trainer logs, per gradient step, (a) the voxel-encoder forward-call count
C_encand (b) the TX-modulation forward-call countC_txmod. WithU= uniquescene_ids in the batch andP= unique(scene_id, tx_id)pairs in the batch (as defined in AC-3's tensor contract), every logged step satisfiesC_enc ≤ UandC_txmod ≤ P. A unit test injects a batch with knownU, P, Qand asserts these counters. - A benchmark script reports throughput in triples per second on a fixed tiny10
(scene, TX, RX)manifest (manifest path pinned inbenchmarks/tiny10_triples_manifest.json), recorded as median over ≥ 100 warmed-up gradient steps on a single 80 GB GPU. The benchmark also reports peak CUDA memory per step. - The benchmark script reports
mean_triples_per_stepalongside triples/sec so any future shape adapter cannot silently over-count throughput.
- The trainer logs, per gradient step, (a) the voxel-encoder forward-call count
- Negative Tests:
C_encscales withQ(the encoder runs once per triple), indicating scene-token caching is absent.C_txmodscales withQrather thanP, indicating(scene, TX)memory caching is absent and DEC-4 has been silently violated.- Wall-clock per triple grows with
R(RXs per(scene, TX)) instead of staying flat, proving the decoder is wasting work on reusable backbone state. - Throughput is reported as raw steps/sec or samples/sec without the triples-per-step normalization.
- Positive Tests:
AC-6: Loss is unambiguously defined over the matched set only (plus no-object BCE on unmatched queries), in dB space for power and ns-space for delay, operating on the
[Q, K]outputs from AC-3's tensor contract.- Positive Tests:
- For every training step, a logged
loss_dictlists these four keys always present:loss_match_exists,loss_match_delay_ns,loss_match_peak_db,loss_no_object_exists. Two optional auxiliary keysloss_pair_gap_delayandloss_pair_gap_dbare computed ONLY over matched pairs sorted by predicted delay, and default to OFF (enable_pair_gap_losses = False) for the first end-to-end run; enabling them requires an explicit config override. - Unit test: a triple with zero GT paths (
gt_num_paths[q] == 0) contributes onlyloss_no_object_exists; all other per-triple loss components are exactly zero for that triple. - Unit test: the delay loss numerically equals Huber or L1 in nanoseconds applied to
csi_delay_nsselected by the Hungarian matching indices; the dB loss numerically equals Huber or L1 in dB applied tocsi_peak_dbat those same indices.
- For every training step, a logged
- Negative Tests:
- The loss linearizes power (converts dB to mW) before the regression term — this is forbidden per the draft's explicit dB-domain requirement.
- An ordered-slot delay-rank loss is applied to unmatched queries (Codex flagged this as the predecessor's failure trap).
- Pair-gap losses are silently enabled by default, or are computed over unmatched queries.
- Positive Tests:
AC-7: Checkpoint selection uses a composite CSI criterion that jointly guards against power collapse, false positives on zero-path samples, count-prediction failure, delay-regression failure, and single-metric local optima.
- Positive Tests:
- The validation loop reports at least:
pdp_cosine_nonzero,peak_db_mae_matched,peak_db_bias_matched,delay_mae_matched_ns,count_acc,zero_path_fpr, andgt_paths_truncated_rate(fraction of val samples wheregt_num_paths > K). - The checkpoint selector is a deterministic function of the validation metric table implementing this composite rule (all thresholds configured in
config.py, default values shown in brackets):- Feasibility guards (hard gates): an epoch is a candidate only if
peak_db_bias_matched ∈ [−3, +3] dBANDzero_path_fpr ≤ 10%ANDcount_acc ≥ 0.5ANDdelay_mae_matched_ns ≤ 1.0. - Primary objective over feasible candidates: maximize
pdp_cosine_nonzero. - Lexicographic tie-break within 0.001 of the primary optimum: minimize
peak_db_mae_matched; then minimizedelay_mae_matched_ns; then maximizecount_acc. - Fallback: if no epoch is feasible, the selector refuses to pick one, emits a loud warning, and returns
Noneso the run fails loudly rather than silently saving a pathological checkpoint.
- Feasibility guards (hard gates): an epoch is a candidate only if
- Unit test on a synthetic epoch table: exactly one canonical "best" row is returned, matches the rule above row-by-row, and the pathological row (high cosine but
peak_db_bias_matched = −150 dB) is rejected.
- The validation loop reports at least:
- Negative Tests:
- The selector picks
argmax(pdp_cosine_nonzero)even when any hard gate fails. peak_db_bias_matched,count_acc,delay_mae_matched_ns, orzero_path_fpris missing from the validation log.- The selector uses only two guards (bias + FPR) without count / delay gates, reproducing the Codex-flagged under-specified variant.
- The selector picks
- Positive Tests:
AC-8: One-scene success gate is enforced before multi-scene sweeps.
- Positive Tests:
- A dedicated single-scene manifest exists (e.g.
manifests/task_a069_single_scene.json) selecting exactly one scene from the tiny10 set. - A "scale-up gate" check in the training orchestrator refuses to launch the 10/30/50/100-scene runs unless the single-scene run's final checkpoint satisfies a configurable success rule (default:
count_acc ≥ 0.9,delay_mae_matched_ns ≤ 0.3 ns,peak_db_bias_matched ∈ [-3 dB, +3 dB]— all tunable inconfig.py).
- A dedicated single-scene manifest exists (e.g.
- Negative Tests:
- The 100-scene run launches even though the single-scene model has not met the gate (the orchestrator MUST block).
- The gate uses only a single metric (e.g. cosine alone), reproducing the predecessor's selection pathology.
- Positive Tests:
AC-9: Zero-path samples are first-class citizens in data, loss, and metrics.
- Positive Tests:
- The dataset reports the zero-path sample rate per manifest; validation metrics include
zero_path_fpr,nonzero_path_count_mae, andmatch_rate_over_all_samples(matched paths divided by GT paths across the full val set including zero-path samples). - A direct unit test with a zero-path batch asserts that
loss_no_object_existsis the only non-zero training loss term and that gradients do not contain NaNs/Infs.
- The dataset reports the zero-path sample rate per manifest; validation metrics include
- Negative Tests:
zero_path_fpris missing from the validation log.- Zero-path samples are discarded in the collate step.
- Positive Tests:
AC-10: DETR-style query budget
Kis justified by dataset statistics, supervised truncation is measured at runtime, and truncation never happens silently.- Positive Tests:
- A small utility script emits the histogram of GT path counts per sample over the tiny10 training set and writes it to
reports/path_count_histogram.md, with per-bucket counts and the cumulative percentile at every integernum_pathsvalue. - The config default for
Kis chosen such that at least 99% of tiny10 samples havenum_paths ≤ K, or a documentedDEC-5user override exists. gt_paths_truncated_rate(fraction of val samples where GT path count exceededKand was truncated to the top-Kearliest paths) is computed in every validation epoch and included in the AC-7 metric bundle; a run withgt_paths_truncated_rate > 0.01for the chosen manifest emits a loud warning at val end.
- A small utility script emits the histogram of GT path counts per sample over the tiny10 training set and writes it to
- Negative Tests:
K = 8is committed to config with zero evidence that the tiny10 distribution truncation rate is acceptable.- Samples with more than
KGT paths are truncated without being counted;gt_paths_truncated_rateis missing from the metric dict.
- Positive Tests:
AC-11: Training-speed optimization lands before the 200-epoch sweeps so wall-clock is not the bottleneck. (Plan Version 12 / 2026-04-19: user directive — "我们训练轮数这么高,所以说在进行这个200轮训练之前,一定要优化一下我们的数据集读写以及我们的模型训练速度".)
- Positive Tests:
- The trainer uses bf16 autocast on CUDA for trellis2 backbone forward + head (already in place; AC-11 requires it to be the DEFAULT enabled path, not an opt-in flag).
- A benchmark-optimization report
reports/training_speed_optimization.mddocuments the before/after numbers for: (a) median triples/sec on the pinned tiny10 manifest at batch_triples=8, (b) peak CUDA memory MB, (c) GPU utilization % (vianvidia-smi dmon -s u -c 30), (d) DataLoader time / total step time ratio. The file must show a post-optimization GPU utilization ≥ 70% for at least 80% of sampleddmonrows, and data-loader time fraction ≤ 15% of median step time. DataLoader(num_workers≥4, pin_memory=True, persistent_workers=True, prefetch_factor=4)(or the equivalent optimization) is enabled by default when a manifest is provided toscripts/train_and_eval.py; a test or a runtime assertion verifies these flags are on.- The batch size
--batch-triplescan be raised at least to the largest power-of-two value that fits in 80 GB without triggering OOM during the 200-epoch sweeps (AC-12); the optimization report records the chosen max value and the observed peak memory at that value.
- Negative Tests:
- Training runs in fp32 when CUDA + trellis2 is available (should be bf16 autocast).
- DataLoader runs
num_workers=0by default, forcing synchronous data materialization. - The training launcher refuses to print GPU utilization in the report.
- Raising batch size causes silent truncation, dropping samples from an epoch.
- Positive Tests:
AC-12: Empirical convergence sweep answers "how many epochs does DETR need to fit". (Plan Version 12 / 2026-04-19: user directive — "200 轮收敛验证,单场景 + tiny10,每 epoch 记 loss,每 10 epoch 详细指标,挑出最优训练轮数".)
- Positive Tests:
- Two training runs land in
reports/: (a)reports/single_scene_200ep.{md,csv,json}onmanifests/task_a069_single_scene.json, and (b)reports/tiny10_200ep.{md,csv,json}onbenchmarks/tiny10_triples_manifest.json. Both runs are 200 epochs, backbone=trellis2, AC-11 optimized config. The CSV logs one row per epoch with columns:epoch, lr, train_loss_total, loss_match_exists, loss_match_delay_ns, loss_match_peak_db, loss_no_object_exists, grad_norm. The JSON logs, every 10 epochs AND at the final epoch, the full AC-7 metric bundle (pdp_cosine_nonzero, count_acc, delay_mae_matched_ns, peak_db_mae_matched, peak_db_bias_matched, zero_path_fpr, nonzero_path_count_mae, match_rate_over_all_samples, gt_paths_truncated_rate). - Learning-rate schedule: initial
lr=1e-4, with at least one documented decay (e.g. cosine to1e-6, or step-decay ×0.1 at{100, 150}). The exact schedule is picked during task20 and recorded in the config section of each report. - An analysis report
reports/convergence_analysis.mdcompares the two 200-epoch logs, plots loss trajectories and per-metric trajectories, identifies the earliest epoch at which the AC-7 feasibility gates are satisfied, and the peak-metric epoch on the primary objectivepdp_cosine_nonzero. Based on that evidence the report recommends a default training epoch budget for future runs. - AC-8 single-scene gate (
count_acc ≥ 0.9,delay_mae_matched_ns ≤ 0.3,peak_db_bias_matched ∈ [−3, +3]) is either PASSED at some epoch in the 200-epoch window (and that epoch is reported), OR explicitly RECORDED AS NOT YET REACHED with the best-epoch numbers. The plan does not require AC-8 to pass at 200 epochs for AC-12 to be met; AC-12 is satisfied by the honest empirical answer.
- Two training runs land in
- Negative Tests:
- The 200-epoch run exits early without emitting the per-epoch CSV row for each completed epoch.
- The every-10-epoch metric JSON is written only at the final epoch (loss-only logging is not enough).
convergence_analysis.mdrecommends an epoch budget without citing the CSV + JSON evidence it is derived from.
- Positive Tests:
Path Boundaries
Path boundaries define the acceptable range of implementation quality and choices.
Upper Bound (Maximum Acceptable Scope)
The A06_9 branch delivers:
- A standalone
code_snapshot/radiomapvggt_v20_voxel_cir_detr/package with its ownconfig.py, dataset, model, trainer, losses, and metrics; no imports fromA06_7_*. - A sparse 3D backbone built from TRELLIS-2's
SparseTransformerBlock,ModulatedSparseTransformerBlock, andSparseDownsample, with 2–3 downsample stages kept sparse throughout (no forced dense grid). - A DETR-style head with
Klearnable path queries (defaultK = 8), Hungarian set matching, bounded-dB power regression, optional AdaLN modulation by TX embedding at the backbone stage and cross-attention to TX/RX features at the decoder stage. - A scene-token cache and a
(scene, TX)memory cache so that per-RX compute is decoder-only in a batch. - A composite-rule checkpoint selector, a single-scene success gate, a scale-up manifest sweep (1 → 10 → 30 → 50 → 100 scenes), and a benchmark script reproducing tiny10 throughput.
- Unit tests for the head's Hungarian matching, power bound, zero-path handling, and TX-injection invariance; a smoke import test; one end-to-end 10-step training test on a synthetic batch.
reference/with pinned clones of rf-detr, SEED, VoxelNeXt, each with a shortNOTES.mdlisting which subsystem informed which design decision.
Lower Bound (Minimum Acceptable Scope)
A06_9 passes AC-1 through AC-10 with:
- One backbone variant (one downsample stage is acceptable if justified by throughput).
- Hungarian matching WITHOUT auxiliary pair-gap losses.
- TX injection via AdaLN-zero modulation; RX strictly via learnable query + cross-attention only.
- AC-5 caching invariants (
C_enc ≤ UandC_txmod ≤ P) are mandatory; the minimum permitted implementation may satisfyC_txmod ≤ Pvia an in-step bucketized(scene, TX)grouping (no persistent cross-step cache object required), but per-step TX-modulation reruns per triple are NOT acceptable. - Single-scene gate + tiny10 run; the 30/50/100-scene runs are not a hard requirement for lower-bound acceptance.
reference/cloning is mandatory (AC-1); design notes per reference may be terse.
Allowed Choices
- Can use: TRELLIS-2 sparse ops (AdaLN-zero modulated blocks, SparseDownsample, SparseUpsample), FlexGEMM / torchsparse / spconv backends as configured upstream, FlashAttention for dense attention paths, scipy's
linear_sum_assignmentfor Hungarian matching on CPU per-sample (standard DETR pattern), Huber or L1 for delay / dB regression, BCE or focal for existence. - Can use: bounded-range power parameterization (
db_low + (db_high − db_low) · σ(raw)), additive dB offsets, learnable per-slot dB biases. - Cannot use: TX or RX as extra sparse voxel tokens prepended into the backbone; RX conditioning placed before the final downsample stage; ANY
floor_db + softplus(raw)power parameterization regardless offloor_dbvalue (this is a hard ban — the A06_9 head must use a bounded saturating map such asdb_low + (db_high − db_low) · σ(raw)for every path-power output); rigid delay-ordered slot supervision anywhere in the live training loss (permitted only inside an explicitly labeled offline ablation script, not inconfig.pydefaults); a single-metric checkpoint selector; silent truncation of zero-path samples; silent truncation ofnum_paths > Ksamples without metric recording; linearization of power before the regression loss. - Cannot use: the existing A06_7
CSIPathSetHead,_collapse_paths_by_delay_slot, or A06_7 trainer modules as live dependencies. They may be referenced as read-only for migration, but not imported.
Note on Deterministic Designs: The draft fixes several semantic choices (dB domain, query-based set prediction, TX/RX-as-modulation rather than tokens, 8-slot query budget as a starting guess, CSI-only scope, new branch path). The path boundaries above reflect these constraints. Items still under genuine choice (matching policy, target merging rule, RX injection placement, compute caching strategy, query budget
K) are surfaced asDEC-*entries in## Pending User Decisions.
Feasibility Hints and Suggestions
Note: This section is for reference and understanding only. These are conceptual suggestions, not prescriptive requirements.
Conceptual Approach
Pipeline for one forward step on a batch of P (scene, TX) pairs with R_p RXs each:
- Scene encoding (once per unique scene in the batch):
- Build sparse voxel input from scene occupancy (reuse A06_7 voxel cache format if still valid, else rebuild).
- Run
Sstages ofModulatedSparseTransformerBlock, interleaved withSparseDownsample(e.g. 40 cm → 80 cm → 1.6 m base voxel size, capped at ~16³ effective resolution for the deepest stage; remains sparse throughout). Each block is modulated by a zero vector (no condition) or, optionally, a static scene-level embedding. Output:scene_tokens_cache[scene_id].
- TX conditioning (once per unique
(scene, TX)in the batch):- Encode TX coordinate with a continuous Fourier embedding + small MLP →
tx_emb [D]. - Run a shallow
ModulatedSparseTransformerBlockstack overscene_tokens_cache[scene_id], modulated bytx_emb. This is the TX-conditioned scene memory. Output:tx_mem_cache[(scene_id, tx_id)].
- Encode TX coordinate with a continuous Fourier embedding + small MLP →
- Query decoding (once per
(scene, TX, RX)triple):- Encode RX with a continuous Fourier embedding + small MLP →
rx_emb [D]. - Instantiate
Klearnable path queries; addrx_embas a modulation or as an added positional bias on the queries (RX goes LATE, never into the backbone). - Run
Ldecoder layers of self-attention over queries + cross-attention totx_mem_cache[(scene_id, tx_id)]. - Project to
(exists_logit, delay_pred_ns, peak_db_pred)per query. Power is bounded viadb_low + (db_high − db_low) · σ(raw_peak)withdb_low, db_highset from dataset statistics (e.g.,-120 dB, -10 dB).
- Encode RX with a continuous Fourier embedding + small MLP →
- Matching and loss:
- For each
(scene, TX, RX)sample in the batch, compute the DETR cost matrix betweenKpredictions andMGT paths (cost =α · |Δdelay_ns| + β · |Δpeak_db| + γ · BCE(exists)). - Hungarian match via
scipy.optimize.linear_sum_assignmenton the CPU per sample (standard DETR pattern); matched pairs contribute delay / dB / exists losses, unmatched queries contribute no-object exists loss only. - Optional auxiliary: sort matched pairs by predicted delay, compute pair-gap losses over adjacent matched pairs only.
- For each
Relevant References
/data/conda_envs/trellis2/trellis2/modules/sparse/transformer/blocks.py—SparseTransformerBlockclass and signature./data/conda_envs/trellis2/trellis2/modules/sparse/transformer/modulated.py—ModulatedSparseTransformerBlock(AdaLN-zero),ModulatedSparseTransformerCrossBlock(self + cross + modulation)./data/conda_envs/trellis2/trellis2/modules/sparse/spatial/basic.py—SparseDownsample,SparseUpsample(stride-2 sparse pool/gather)./data/jing_code/wl/radiomapvggt/v20_voxel_radiomap_cir/ablationstudy/A06_7_merged_tap_set_prediction/code_snapshot/radiomapvggt_v20_voxel_cir/models/csi_path_head.py— legacy ordered-slot head; read-only reference for migration, not importable./data/jing_code/wl/radiomapvggt/v20_voxel_radiomap_cir/ablationstudy/A06_7_merged_tap_set_prediction/reports/T08_A06_7_LASTPT_POWER_UNDERSHOOT_ANALYSIS_CN.md— the documented failure mode this branch must avoid reproducing./data/jing_code/wl/radiomapvggt/v20_voxel_radiomap_cir/ablationstudy/A06_7_merged_tap_set_prediction/code_snapshot/radiomapvggt_v20_voxel_cir/utils/metrics.py— PDP cosine, peak dB MAE, tap match-rate utilities (pattern to match, not import).reference/rf-detr/— DETR decoder, Hungarian matcher, no-object class handling.reference/SEED/— DETR-style sparse 3D detection (closest analogue to the voxel-based set head).reference/VoxelNeXt/— sparse voxel backbone with 3D downsampling.
Dependencies and Sequence
Milestones
Milestone M1 — Repo scaffold and target contract (AC-1, AC-2, AC-10).
- Phase M1.A: Create the
code_snapshot/tree,reference/with pinned clones, manifest for tiny10 single-scene, smoke import test. - Phase M1.B: Define the target contract (raw vs. merged, per DEC-1) in
data/csi_path_targets.py. Emit the path-count histogram report used to justifyK. - Phase M1.C: Verify zero-path samples survive collate.
- Phase M1.A: Create the
Milestone M2 — Backbone and caching (AC-4, AC-5).
- Phase M2.A: Port / vendor the minimum TRELLIS-2 sparse blocks required; confirm CUDA extensions build in the project's existing environment.
- Phase M2.B: Implement the sparse 3D backbone with configurable downsample count; TX injection via AdaLN-zero.
- Phase M2.C: Implement
scene_tokens_cacheand(scene, TX)memory cache in the trainer's batch loop; verify forward-call invariants from AC-5 via logged counters.
Milestone M3 — DETR head, loss, matching (AC-3, AC-6, AC-9).
- Phase M3.A: Implement the head with
Klearnable queries, bounded-dB output, unit tests for shape/bound/finite. - Phase M3.B: Implement Hungarian matcher using
scipy.optimize.linear_sum_assignment; unit test on synthetic batches. - Phase M3.C: Implement loss module strictly over matched-plus-no-object; unit test zero-path and all-matched cases.
- Phase M3.A: Implement the head with
Milestone M4 — Metrics, checkpoint selection, gate (AC-7, AC-8, AC-9, AC-10).
- Phase M4.A: Implement the full validation metric bundle required by AC-7, AC-9, and AC-10:
pdp_cosine_nonzero,peak_db_mae_matched,peak_db_bias_matched,delay_mae_matched_ns,count_acc,nonzero_path_count_mae,zero_path_fpr,match_rate_over_all_samples, andgt_paths_truncated_rate. - Phase M4.B: Implement composite checkpoint selector with the AC-7 guard rules (four hard feasibility guards + cosine primary + lexicographic tie-break + loud-fail
Nonefallback). - Phase M4.C: Implement the single-scene → multi-scene gate; make scale-up a manifest sweep rather than a monolithic run.
- Phase M4.A: Implement the full validation metric bundle required by AC-7, AC-9, and AC-10:
Milestone M5 — Single-scene and tiny10 validation runs (bring-up).
- Phase M5.A: Single-scene overfit bring-up (short run) — smoke test the pipeline.
- Phase M5.B: Tiny10 bring-up on the pinned
benchmarks/tiny10_triples_manifest.json; verify AC-5 caching invariants + triples/sec envelope and peak CUDA memory; verify AC-7 composite checkpoint selection infrastructure on short-run data. - Phase M5.C: Scale-up decision is DEFERRED to M7; M5 stops at bring-up.
Milestone M6 — Training-speed optimization (AC-11). Prerequisite for M7.
- Phase M6.A: Profile the current tiny10 forward; classify time spent between (DataLoader, scene encode, TX modulation, decoder, head, backward).
- Phase M6.B: Raise
--batch-triplesto the largest power-of-two that fits in 80 GB without OOM. EnableDataLoader(num_workers≥4, pin_memory=True, persistent_workers=True, prefetch_factor=4)as the training default. Confirm bf16 autocast on CUDA is the default for trellis2 forward. Reportreports/training_speed_optimization.mdwith before/after numbers andnvidia-smi dmonGPU utilization. - Phase M6.C: Produce the optimized-config snapshot (batch, num_workers, autocast, lr baseline) that M7 consumes. No AC-8 attempt in M6.
Milestone M7 — 200-epoch convergence sweep (AC-12). Prerequisite: M6 landed.
- Phase M7.A: Single-scene 200-epoch run under M6 config; write per-epoch CSV + every-10-epoch JSON metric bundle. Log
reports/single_scene_200ep.{md,csv,json}. - Phase M7.B: Tiny10 200-epoch run under M6 config (same schedule); write
reports/tiny10_200ep.{md,csv,json}. - Phase M7.C: Analyze both 200-epoch logs;
reports/convergence_analysis.mdrecommends a default training-epoch budget and reports the best-metric epoch + earliest-feasibility-gate epoch per run. Records honestly whether AC-8 was reached in the 200-epoch window.
- Phase M7.A: Single-scene 200-epoch run under M6 config; write per-epoch CSV + every-10-epoch JSON metric bundle. Log
Milestone M8 — Optional scale-up (conditional). Conditional on M7's convergence-analysis verdict being favourable.
- Phase M8.A: 30-scene run under the M7-recommended epoch budget.
- Phase M8.B: 50-scene run.
- Phase M8.C: 100-scene run. M8 as a whole is optional and does not block plan completion.
Dependencies: M1 must complete before any model code is written. M2 blocks M3's end-to-end integration test. M3 blocks M4. M4 blocks M5. M5 blocks M6 (the speed optimization needs a working bring-up to profile against). M6 blocks M7. M7 blocks M8. Within M3, M3.A / M3.B / M3.C can be written in parallel but all three must pass unit tests before an end-to-end forward on real data is attempted.
Task Breakdown
Each task must include exactly one routing tag:
coding: implemented by Claudeanalyze: executed via Codex (/humanize:ask-codex)
| Task ID | Description | Target AC | Tag (coding/analyze) |
Depends On |
|---|---|---|---|---|
| task1 | Build the empty code_snapshot/ package skeleton, reference/ clones with pinned commits, smoke-import test. |
AC-1 | coding | - |
| task2 | Analyze A06_7's Sionna CIR → supervised-path pipeline end-to-end and recommend a frozen target contract (raw vs merged, same-bin multipath behavior, truncation rule). | AC-2, DEC-1 | analyze | task1 |
| task3 | Implement data/csi_path_targets.py under the chosen contract; add the path-count histogram utility; verify zero-path samples survive collate. |
AC-2, AC-9, AC-10 | coding | task2 |
| task4 | Analyze whether current A06_7 voxel caches and manifests are reusable for (scene, TX, RX) sampling or need a new collator. |
AC-5 | analyze | task1 |
| task5 | Implement the new collator and dataset for (scene, TX, RX) triples, reusing A06_7 voxel caches where valid. The collator MUST emit the frozen AC-3 batch tensor contract: scene_idx [Q], tx_scene_idx [Q], rx_xyz_norm [Q, 3], tx_xyz_norm [Q, 3], and the GT set tensors gt_num_paths [Q], gt_delay_ns [Q, M_max], gt_peak_db [Q, M_max], gt_path_mask [Q, M_max]. |
AC-5, AC-9 | coding | task4 |
| task6 | Vendor the minimal TRELLIS-2 sparse module set needed (blocks, modulated blocks, sparse downsample, sparse backend adapter). Confirm the CUDA extensions build in the project environment. | AC-4 | coding | task1 |
| task7 | Implement the sparse 3D backbone with configurable downsample count and AdaLN-zero TX modulation. | AC-4 | coding | task6 |
| task8 | Implement the scene_tokens_cache and (scene, TX) memory cache in the trainer's batch iterator; add unit tests that assert BOTH C_enc ≤ U and C_txmod ≤ P on an injected batch with known U, P, Q. |
AC-5 | coding | task7 |
| task9 | Analyze and recommend bounded-dB power parameterization constants (db_low, db_high) from A06_7 tiny10 statistics. |
AC-3, AC-6 | analyze | task3 |
| task10 | Implement the DETR-style head: K queries, bounded-dB output, Hungarian matcher, unit tests. |
AC-3 | coding | task9 |
| task11 | Implement the loss module (matched-set regression + no-object BCE + optional matched-pair gap losses). | AC-6 | coding | task10 |
| task12 | Implement the full validation metric bundle: pdp_cosine_nonzero, peak_db_mae_matched, peak_db_bias_matched, delay_mae_matched_ns, count_acc, nonzero_path_count_mae, zero_path_fpr, match_rate_over_all_samples, gt_paths_truncated_rate. |
AC-7, AC-9, AC-10 | coding | task11 |
| task13 | Implement the composite checkpoint selector with guard rules and regression tests. | AC-7 | coding | task12 |
| task14 | Implement the single-scene success gate and the scale-up manifest orchestrator. | AC-8 | coding | task13 |
| task15 | Implement the self-contained throughput benchmark script and verify the AC-5 caching invariants + triples/sec envelope on tiny10. (Plan Version 12: cross-model A06_7 comparison removed.) | AC-5 | coding | task8, task10 |
| task16 | Run the single-scene bring-up experiment to smoke-test the pipeline; record honest gate status. AC-8 is NOT expected to pass at bring-up; the real AC-8 check happens inside task22's 200-epoch run. | AC-8 | coding | task14 |
| task17 | Run the tiny10 bring-up experiment on benchmarks/tiny10_triples_manifest.json, collect the full AC-7/AC-9/AC-10 metric bundle on a short run, confirm AC-5 triples/sec envelope and peak memory, confirm composite checkpoint selection infrastructure. |
AC-5, AC-7 | coding | task15, task16 |
| task18 | Analyze the tiny10 bring-up report; recommend whether the pipeline is ready for 200-epoch sweeps. No cross-model A06_7 comparison required. | - | analyze | task17 |
| task19 | Conditional: placeholder for any 30 / 50 / 100-scene manifest sweep. Now gated by task23, not task18. | - | coding | task23 |
| task20 | Profile current tiny10 forward+backward at bring-up config; classify time spent between DataLoader, scene encode, TX modulation, decoder, head, backward. Report baseline GPU utilization via nvidia-smi dmon -s u -c 30. |
AC-11 | analyze | task17 |
| task21 | Implement training-speed optimization: raise --batch-triples to the largest OOM-safe power-of-two; enable DataLoader(num_workers≥4, pin_memory=True, persistent_workers=True, prefetch_factor=4) as default; confirm bf16 autocast on CUDA for trellis2 is the default. Produce reports/training_speed_optimization.md with before/after triples/sec, peak memory, GPU utilization, and data-loader time fraction. |
AC-11 | coding | task20 |
| task22 | Run the single-scene 200-epoch sweep with AC-12's schedule (lr=1e-4, at least one documented decay). Per-epoch CSV logging of loss + optimizer state; every-10-epoch JSON dump of the full AC-7 metric bundle. Write reports/single_scene_200ep.{md,csv,json}. Honestly record whether AC-8 gate is reached and at which epoch. |
AC-12, AC-8 | coding | task21 |
| task23 | Run the tiny10 200-epoch sweep with the same schedule as task22. Write reports/tiny10_200ep.{md,csv,json}. Then produce reports/convergence_analysis.md comparing the two 200-epoch logs: earliest-feasibility-gate epoch, peak-metric epoch, and a recommended default training-epoch budget for future runs. |
AC-12, AC-7 | coding | task22 |
Claude-Codex Deliberation
Agreements
- A06_7's CSI head is structurally trapped by
floor_db + softplus(raw)power parameterization plus rigid ordered-slot supervision; a new branch is the correct response. - Power regression MUST stay in the dB domain and MUST be bounded to a realistic dB range; the predecessor's extreme
floor_dbis disallowed. - Zero-path samples,
zero_path_fpr, andpeak_db_bias_matchedMUST be first-class citizens in data, loss, and validation. - Checkpoint selection via a single metric (
pdp_cosine_nonzero) is pathological and MUST be replaced by a composite guarded rule. - The sample unit changes to
(scene, TX, RX); without scene-token caching, this inflates backbone compute per batch rather than reducing it. - TX modulation via AdaLN-zero over sparse transformer blocks (TRELLIS-2 pattern) is a sound replacement for treating TX as a token.
- TRELLIS-2's
ModulatedSparseTransformerBlock,ModulatedSparseTransformerCrossBlock, andSparseDownsampleare the correct primitives to borrow; the sparse path does NOT need to be densified to a16³dense grid. K = 8query budget is a draft starting value and MUST be validated against the tiny10 path-count histogram.- The single-scene success gate must precede multi-scene scale-up; CSI-only isolation from radiomap is a hard constraint for this branch.
Resolved Disagreements
- Mixing Hungarian matching with rigid delay-ordered slot supervision. Claude's v1 position: keep both as co-equal losses. Codex position: doing so reproduces the predecessor's failure trap because rigid ordering conflicts with set-prediction gradients. Resolution: Hungarian matching is the primary supervision; rigid ordered loss is forbidden in the primary loss and is moved entirely out of acceptance criteria into an optional offline ablation script. This is codified in AC-3, AC-6, the "Ablation and experiment notes" section, and the allowed-choice list.
- Dense
16³latent compression. Draft hint: "compress to 16×16×16 grid, TRELLIS-2-style 3D VAE." Codex position: forced dense compression likely destroys fine-scale cues critical for weak reflection paths. Resolution: keep sparse throughout; the deepest stage may operate at a coarse voxel size (e.g. 1.6 m base with reduced active voxels), but no forced dense grid. - TX and RX injected symmetrically. Draft position: both TX and RX as modulation into the backbone. Codex position: RX-conditioned backbone features cannot be reused across the RXs in a batch, killing throughput. Resolution: TX as AdaLN-zero modulation in the backbone (shared across all RXs for a given
(scene, TX)); RX only in the decoder (late cross-attention or query-level bias). Codified in AC-4 / AC-5; surfaced as DEC-3 in ratify-or-reopen form. - AC-5 throughput contract ambiguity (Round 1). R1 Codex position:
steps/sec at matched batch sizeis not stable when the sample unit changes. Resolution: AC-5 is rewritten to use normalized triples/sec on a pinned tiny10 triples manifest, plusC_enc ≤ UandC_txmod ≤ Pinvariants, plus peak CUDA memory accounting. - Ambiguous batch tensor shape
[B, N, K](Round 1). R1 Codex position: after the sample unit change,BandNare under-defined. Resolution: AC-3 introduces a single frozen batch tensor contract based onQ= number of(scene, TX, RX)triples,U= unique scenes,P= unique(scene, TX)pairs. All downstream sections (AC-5, AC-6, AC-7, AC-9, AC-10, hard invariants) reference this contract. - Power parameterization loophole (Round 1). R1 Codex position: AC-3 mandates bounded dB output but "Allowed Choices" leaves a
floor_db + softplus(raw)loophole with moderate floor values. Resolution:floor_db + softplus(raw)is now banned regardless of floor; the only permitted parameterization is a bounded saturating map to[db_low, db_high]. - Checkpoint selector under-specification (Round 1). R1 Codex position: guards on bias + FPR alone still allow single-metric local optima on count / delay. Resolution: AC-7 now requires four hard feasibility guards (bias, zero-path FPR, count accuracy, delay MAE), a primary objective (cosine), a lexicographic tie-break, and a "no feasible epoch → return None" fallback.
- DEC-2 / DEC-3 / DEC-4 framing (Round 1). R1 Codex position: these were marked pending but the plan text already hard-committed one side. Resolution: reframe each as "ratify-or-reopen" with explicit disclosure of the plan's currently-encoded default, so the user can either ratify the default (zero-cost) or request a rewrite (non-trivial replan).
- Ordered-slot ablation as acceptance criterion (Round 1). R1 Codex position: useful but not a convergence gate. Resolution: moved from AC-3 positive test into "Ablation and experiment notes".
- Query-budget truncation measurement (Round 1). R1 Codex position: histogram-and-documentation alone is not enough. Resolution: AC-10 now requires
gt_paths_truncated_ratecomputed every validation epoch and surfaced in the AC-7 metric bundle. - Pair-gap losses defaulting on (Round 1). R1 Codex position: default them off for the first end-to-end run. Resolution: AC-6 now specifies
enable_pair_gap_losses = Falseas the default; enabling requires an explicit config override. - TRELLIS-2 dependency ambiguity (Round 1). R1 Codex position: plan allows both vendored and live-env, weakening reproducibility. Resolution: new DEC-8 forces an explicit choice; vendored pinned subset is the recommended default.
- Lower-Bound contradiction (Round 2). R2 Codex position: Lower Bound said "scene-token caching ONLY" while AC-5 and DEC-4 encoded both caches as mandatory, and it skipped AC-10. Resolution: Lower Bound now requires AC-1 through AC-10, explicitly restates that
C_enc ≤ UANDC_txmod ≤ Pare mandatory at minimum scope, and clarifies that a persistent cross-step cache object is optional so long as the per-step invariants hold. - Stale metric-count wording (Round 2). R2 Codex position: M4.A and task12 still said "six validation metrics" while the full bundle had grown. Resolution: M4.A and task12 now enumerate the complete nine-metric bundle (
pdp_cosine_nonzero,peak_db_mae_matched,peak_db_bias_matched,delay_mae_matched_ns,count_acc,nonzero_path_count_mae,zero_path_fpr,match_rate_over_all_samples,gt_paths_truncated_rate), and task12 now targets AC-7, AC-9, and AC-10. - task8 invariant coverage (Round 2). R2 Codex position: task8 only mentioned encoder-call counts, leaving
C_txmod ≤ Puncovered. Resolution: task8 now explicitly requires unit tests for BOTHC_enc ≤ UandC_txmod ≤ P. - Secondary wording alignment (Round 2, optional). R2 Codex noted M5.B / task17 / DEC-6 still used weaker "matched batch size" / "≤ 1.5× wall-clock" language. Resolution: all three now reference the pinned
benchmarks/tiny10_triples_manifest.jsonand thetriples/sec ≥ 0.67 × A06_7 baselinerule; AC-4 now ties its TRELLIS-2 source reference to DEC-8; task5 now explicitly emits the frozen AC-3 batch tensor contract.
Convergence Status
- Final Status:
converged— all Round 1, Round 2, and Round 3 Codex items are incorporated in plan v3, and all eight user decisions (DEC-1 through DEC-8) areRESOLVEDby user choice (recorded in each DEC entry above). No PENDING items remain. The plan is ready for/humanize:start-rlcr-loopexecution.
Pending User Decisions
DEC-1: Target contract — raw physical paths or merged unique delay-bin paths?
- Claude Position: Merged unique delay-bin paths, to retain metric comparability with A06_7 and to avoid same-bin multipath ambiguity during Hungarian matching. Document the merge rule (e.g., two paths within < 0.1 ns collapse to one, power summed in dB via
10 · log10(10^(p1/10) + 10^(p2/10))). - Codex Position: N/A — open question (Codex flagged this as under-specified; either choice is defensible if fixed once).
- Tradeoff Summary: Raw paths preserve physical fidelity and are closer to Sionna's native output but make Hungarian matching ambiguous when two GT paths share a delay bin. Merged paths are easier to match and keep parity with A06_7's label pipeline but lose information about multipath that happens to be co-bin.
- Decision Status:
RESOLVED — Merged delay-bin paths.data/csi_path_targets.pyimplements the merge rule (co-bin dB-sum via10·log10(Σ 10^(p_i/10))); task3 is now unambiguous.
- Claude Position: Merged unique delay-bin paths, to retain metric comparability with A06_7 and to avoid same-bin multipath ambiguity during Hungarian matching. Document the merge rule (e.g., two paths within < 0.1 ns collapse to one, power summed in dB via
DEC-2: Matching policy — ratify pure Hungarian (currently encoded) or reopen for staged coarse-to-fine?
- Plan's Currently-Encoded Default: Pure Hungarian matching. AC-3, AC-6, M3, and task10 are written under this assumption and enforce it.
- Claude Position: Ratify pure Hungarian. Pair-gap auxiliary losses default OFF per AC-6. Staging deferred unless tiny10 fails.
- Codex Position: Pure Hungarian is defensible once named and locked; acceptable as the plan default. Coarse-to-fine would require reopening AC-3 / AC-6 / task10.
- Tradeoff Summary: Pure Hungarian is simpler, standard DETR, fewer moving parts. Staged coarse-to-fine (predict delay-bin occupancy first, regress top-k paths second) reduces search space but adds a second head and staging complexity.
- Decision Status:
RESOLVED — Ratified pure Hungarian. No rewrite of AC-3 / AC-6 / M3 / task10 required; pair-gap auxiliaries remain OFF by default.
DEC-3: RX conditioning placement — ratify late-only (currently encoded) or reopen for full backbone modulation?
- Plan's Currently-Encoded Default: Late-only RX injection. AC-4 negative tests forbid RX into the backbone; AC-5 caching invariants assume scene/
(scene,TX)features are RX-independent; lower-bound scope also assumes late-only. - Claude Position: Ratify late-only. This enables the AC-5 caching invariants; full backbone RX modulation would re-multiply backbone compute by the RX count per
(scene,TX). - Codex Position: Late-only is strongly preferred; full modulation forfeits cache reuse at the most expensive stage.
- Tradeoff Summary: Late-only is a throughput multiplier; full modulation is more expressive but costs per-RX backbone reruns. Draft text implies symmetric TX/RX modulation.
- Decision Status:
RESOLVED — Ratified late-only RX. RX stays at the decoder; AC-4 / AC-5 stand as written.
- Plan's Currently-Encoded Default: Late-only RX injection. AC-4 negative tests forbid RX into the backbone; AC-5 caching invariants assume scene/
DEC-4: Compute caching scope — ratify "both caches mandatory" (currently encoded) or relax to scene-token-only?
- Plan's Currently-Encoded Default: Both caches mandatory for convergence. AC-5 positive tests require
C_txmod ≤ P, which presumes(scene, TX)memory caching; task8 builds both caches; upper-bound scope requires both. - Claude Position: Ratify "both mandatory." Both caches easily fit in host/device memory for tiny10-scale runs.
- Codex Position: Both caches are recommended; scene-only is acceptable as a relaxed minimum if memory pressure is real.
- Tradeoff Summary: Both caches = less redundant compute, more memory pressure. Scene-only relaxes memory at the cost of a per-
(scene,TX)TX-modulation rerun; this would weaken the AC-5 invariantC_txmod ≤ PtoC_txmod ≤ total (scene,TX) pair occurrences in batch. - Decision Status:
RESOLVED — Ratified both caches mandatory. AC-5's invariantC_txmod ≤ Pstays mandatory; task8 implements both caches.
- Plan's Currently-Encoded Default: Both caches mandatory for convergence. AC-5 positive tests require
DEC-5: Query budget
K— fixed 8 or dataset-driven?- Claude Position: Start at
K = 8per draft, but only after confirming via the path-count histogram that tiny10 samples with more than 8 GT paths are ≤ 1%; otherwise raiseKto cover ≥ 99% of samples. - Codex Position: Evidence-driven only.
K = 8without histogram evidence is a silent truncation risk. - Tradeoff Summary: Larger
K= more no-object queries and slightly more compute, but no truncation risk. SmallerKsaves compute but may silently drop multipath-rich samples. The dataset statistic settles it. - Decision Status:
RESOLVED — Dataset-driven after histogram. task3 emits the histogram first;Kis then set so ≥ 99% of tiny10 samples satisfynum_paths ≤ K. Start fromK = 8only if the evidence supports it.
- Claude Position: Start at
DEC-6: First hard success gate — single-scene overfit, tiny10 win over A06_7, or throughput gate?
- Claude Position: Single-scene overfit first (AC-8), then tiny10 triples/sec on the pinned manifest at ≥ 0.67 × A06_7 baseline on the same manifest (AC-5), then scale-up.
- Codex Position: Option D (all three in sequence) is safest.
- Tradeoff Summary: Single-scene gate first is fastest to fail-fast on fundamental architecture bugs. Tiny10 direct is more ambitious and exposes scaling / regularization issues earlier. Throughput gate first avoids spending GPU-hours on an inefficient forward pass.
- Decision Status:
RESOLVED — Single-scene → tiny10 triples/sec → scale-up. M5.A is the first mandatory gate; M5.B is the second; M5.C (30/50/100-scene sweep) is gated by M5.B success.
DEC-7: Metric continuity with A06_7 — strict backward-comparable or CSI-only new metrics?
- Claude Position: Dual report — keep A06_7 metrics that are semantically valid under the new target contract (PDP cosine, count accuracy, peak dB MAE computed over matched pairs) AND add new set-prediction metrics (
zero_path_fpr,peak_db_bias_matched,match_rate_over_all_samples,gt_paths_truncated_rate). - Codex Position: Dual report is the safer path during the branch's first validation; strict backward-compat may be impossible if DEC-1 chooses "raw paths."
- Tradeoff Summary: Dual reporting slightly increases validation cost but makes cross-branch comparison with A06_7 reports feasible. Pure new metrics are cleaner but sever that comparability.
- Decision Status:
RESOLVED — Dual report. The AC-7 metric bundle includes both A06_7-comparable and new set-prediction metrics; M4.A and task12 remain as enumerated.
- Claude Position: Dual report — keep A06_7 metrics that are semantically valid under the new target contract (PDP cosine, count accuracy, peak dB MAE computed over matched pairs) AND add new set-prediction metrics (
DEC-8: TRELLIS-2 dependency handling — vendored pinned subset in-branch or live dependency on
/data/conda_envs/trellis2?- Claude Position: Vendored pinned subset. Copy only the minimal set of TRELLIS-2 sparse modules (blocks, modulated blocks, sparse down/upsample, sparse backend adapter, their CUDA extensions' build scripts) into
code_snapshot/vendor/trellis2_sparse/with a pinned commit hash recorded. This makes the branch self-contained and reproducible. - Codex Position: Exactly one of vendored-pinned or live-env MUST be chosen. Allowing both (as v1 implied) weakens reproducibility and branch isolation.
- Tradeoff Summary: Vendored = reproducible, robust to upstream TRELLIS-2 changes, heavier in-branch footprint, rebuild of CUDA extensions required once. Live dependency = lighter footprint, simpler initial bringup, BUT fragile: any upstream change silently alters A06_9 behavior, and the branch is not truly self-contained per AC-1's intent.
- Decision Status:
RESOLVED — Vendored pinned subset in-branch. task6 vendors the minimal TRELLIS-2 sparse module set intocode_snapshot/vendor/trellis2_sparse/with a pinned commit hash recorded inreference/MANIFEST.md. AC-1 branch isolation stands; AC-4's import path resolves to the vendored subset.
- Claude Position: Vendored pinned subset. Copy only the minimal set of TRELLIS-2 sparse modules (blocks, modulated blocks, sparse down/upsample, sparse backend adapter, their CUDA extensions' build scripts) into
Implementation Notes
Code Style Requirements
- Implementation code and comments must NOT contain plan-specific terminology such as "AC-", "Milestone", "Step", "Phase", or similar workflow markers
- These terms are for plan documentation only, not for the resulting codebase
- Use descriptive, domain-appropriate naming in code instead
Hard engineering invariants (derived from AC-3, AC-4, AC-5, AC-6, AC-7)
- Sparse voxel encoder forward must be called at most
Utimes per gradient step, whereU= uniquescene_ids in the batch (AC-5 invariant logged via a counter). - TX-modulation block forward must be called at most
Ptimes per gradient step, whereP= unique(scene_id, tx_id)pairs in the batch (AC-5 invariant logged via a counter). - Power head output range must be clamped to
[db_low − ε, db_high + ε]via a bounded parameterization; a runtime assert guards against drift.floor_db + softplus(raw)is banned regardless of floor value. - Loss modules must be pure functions of
(predictions, gt, matching); matching is computed once and passed through, never silently recomputed. - Pair-gap auxiliary losses default OFF; enabling them requires an explicit config flag; even when on, they compute only over matched pairs sorted by predicted delay.
- Checkpoint selector must be implemented as a deterministic function of the validation metric table; unit tests cover both the canonical "best feasible" case and the "all epochs fail the guard → return None" regression case.
- The batch tensor contract in AC-3 is the single source of truth for tensor shapes; any module that reshapes to ambiguous
[B, N, K]notation must first normalize into the[Q, K]contract.
Ablation and experiment notes (non-blocking)
- An optional offline ablation script may swap Hungarian matching for rigid delay-ordered assignment to reproduce A06_7-like behavior for diagnostic comparison. This ablation is explicitly NOT a convergence gate and lives under
scripts/ablations/rather than in the main training loop. - Memory accounting: the benchmark report from AC-5 includes peak CUDA memory alongside triples/sec so cache-strategy tradeoffs (DEC-4) remain visible.
Device and environment assumptions
- CUDA-only training; single-GPU tiny10 and single-scene runs; multi-GPU is optional for 30/50/100-scene runs.
- TRELLIS-2 dependency handling is governed by DEC-8. Under the default (vendored pinned subset), the branch env rebuilds the CUDA extensions locally; under the live-env override,
/data/conda_envs/trellis2is pinned to a specific commit and the branch is no longer fully self-contained. - Dataset artifacts (voxel caches, manifests, Sionna CIR labels) reuse the A06_7 paths; no new dataset generation is in scope.
Output File Convention
This template is used to produce the main output file (e.g., plan.md).
Translated Language Variant
When alternative_plan_language resolves to a supported language name through merged config loading, a translated variant of the output file is also written after the main file. Humanize loads config from merged layers in this order: default config, optional user config, then optional project config; alternative_plan_language may be set at any of those layers. The variant filename is constructed by inserting _<code> (the ISO 639-1 code from the built-in mapping table) immediately before the file extension:
plan.mdbecomesplan_<code>.md(e.g.plan_zh.mdfor Chinese,plan_ko.mdfor Korean)docs/my-plan.mdbecomesdocs/my-plan_<code>.mdoutput(no extension) becomesoutput_<code>
The translated variant file contains a full translation of the main plan file's current content in the configured language. All identifiers (AC-*, task IDs, file paths, API names, command flags) remain unchanged, as they are language-neutral.
When alternative_plan_language is empty, absent, set to "English", or set to an unsupported language, no translated variant is written. Humanize does not auto-create .humanize/config.json when no project config file is present.
--- Original Design Draft Start ---
我们这里设计一个DETR风格的3D的稀疏Transformer+3D下采样,融合的一个预测CSI的网络
就是说我们把每一个给定的场景下的一个TX和一个RX pair它的路径数。把它看成不定的,对吧,它本身就是不定,然后它每个路径数就是通过这样的query方式把它猜出来,这不就是一种DTR的风格嘛,只不过,我们这里要用到我们的场景是提速输入,然后我们TX和RX是坐标,我觉得它可以作为一种调制方式,作为输入进去,然后我们来学习和编码。至于其他的部分,可能你们自行参考和修改,选择一个合适的方式。大概至于这个数据的范围呀,约束呀,还有一些激活呀,这些小细节,我可能就需要你们自己来,嗯,还有网络结构啊,都要都都你们自己来决定
原先的这个版本,它就是说我觉得它其实还是有一些问题的,而且它已经积重难返了,那就开一个新的分支对吧 /data/jing_code/wl/radiomapvggt/v20_voxel_radiomap_cir/ablationstudy/A06_7_merged_tap_set_prediction
新分支我们放在这里 /data/jing_code/wl/radiomapvggt/v20_voxel_radiomap_cir/ablationstudy/A06_9_detr_style_voxel_sparse_3d_transformer_net
这里要设计指标
比如预测给定了一个TX,一个RX,还有它的场景,他们之间可能没有路径,也可能有3~4条不同路径四条不同的路径,它有它的时间的延时和它的一个信号的一个衰减,相当于是一个CIR 但是这些不同路径之间,他们的信号衰减可能是按DB来算的,可能iOS的路径它是-20多DB,那一次反射路径可能就直接降到了-50 DB. 所以说我们预测还有做这个处理,还是做损失,还是做一些其他的计算,最好都是在DB领域来做。因为如果你进行转换成线性领域的话,他可能就直接学习不了任何东西了
设计三个指标,首先对于每一条路径,我们看看预测的准不准,依次匹配。它的定义,比如一次性,我们最多预测8条路径,就相当于有8个slot,根据D,e, TR的风格,对吧?然后我们暂时规定:从第一个slot到第8个slot,它的延时上就是第一个slot预测延时到达最到达最快的那个,相当于我们按延时分布。第二个lo就是第二条到达路径。第三个就是第3条到达路径路径 然后我们计算这个是这个预测上的时间延时的损失,它就是一个时间延时的一个散度对吧, 我们还要预测每一个到达路径,它有一个线代表这条路径的信道衰减,预测的损失代表直接按DB来算,相当于代表了一个散度。我们这里自己定义一个可能物理意义上没那么好的散度。比如第一条路径真实值是-25 DB,预测是-20 DB,相当于有5 DB的差距。第二条路径是-50 DB,预测是-55 DB,相当于又是一个5 DB的差距,然后我们要算它的这样的一个,每次损失的它的一个均值和一个方差,相当于作为我们一个评判的指标
我现在是这么想的,我们这个CSI header它可能扩展成一个新的架构吧,就可能就是说,我们直接重新设计整个网络的结构。我现在是这么想的 嗯,主线任务1就是说我们的backbone部分,就是说我们是voxel的输入对吧 人的网络结构,还有它使用的一些基于稀疏的提速的处理,都来源于这个模型的借鉴,对吧 /data/TRELLIS.2 嗯,原始的A06-7,它还是前期的一些操作是可以保留下来的,就比如说他会对输入voxel做多层attention相互关注。 然后我们可以新增两个部分 第一个部分就是3D下采样,你可能有多种设计方案,你可以挑一个比较好的设计方案给我,然后参数量也不要太小,否则的话,他可能学不了什么东西 但是这里后面的话,我们可以,嗯,把它进行压缩,我觉得就是说我们把它进行3D的当sample,然后然后再做稀疏的3D的attention,然后再当sample,把它压缩成类似于16×16×16这样的一个grid,这里的借鉴就是借鉴于TRELLIS.2一种3D的Vae思想,对吧,然后 然后第二个部分 嗯,这里我只有一个大概的思路,所以我具体设计还要你们来搞里的话,可能它的block和层数可能不能太少,太少的话,可能他也学不到什么东西 就是多层的attention网络,加上我们的TX和RX的注入,所以我们把TX和RX token看成是一种条件的信息,是一种约束的条件信息,它是注入进来的。而我们的query token就是说我们预测给定的TX和RX token的它八条路径,这就是我们的query token 这里相当于说,OK, 我暂时没想好怎么注入比较好,但是我觉得它不应该是作为单独的token输入进来。我觉得它是可以作为注入的手段,让他理解OK,我们的TX是这样,RX这样注入到我们这样的一个attention网络里,就像那些,DiffuSiOn model或者是flow matching model, 他们是把这些条件信息注入进去的 TX token和RX token, 它可能会作为一种调制手段注入到我们的这些体素里,这里的话可以参考一下我们的这个TRELLIS.2
然后后面一个部分就是query,就是说我们固定好8个路径,最多8个路径来做query Query, 如何和我们最后的得到的attention再做融合?这个网络可能还要再设计一下,确保它的GPU利用率、显存占用率都得到合理的使用 可能也要用多层的attention m LP, 还有一些其他的东西.
嗯,主线任务2就是说我们要基于DETR的思想设计一个更好的输出头部分 这个首先它的输出头部分是DETR的思想,但我目前想法很朴素,可能后面你需要自己把它变得更加的完善和具体。相当于我们可能就是说我们固定了18个预测路径的slot,然后它相当于有8个query在这里,每个query它要输出它自己的一个它存不存在,然后它的时间延时和它预测的这样的路径的一个信号衰减。这是一个大概的思路,具体设计可能还要再参考很多别的设计和思路,最后最后让它的使用率和显存使用率能够有效的提高
主线主线任务3就是我们的损失函数,还有我们的这样的一个优化器,还有我们的学习力。这些东西可能还要重新设计一下,他们可能需要有效的能够训练他们: 然后每一个预测好的路径,他们之间也可以做处理。就比如说,我们预测了总共就3个路径,然后每个路径我们还要之间,就比如说,比如说它有三个路径,那第一条和第二条路径之间的延时和它们之间的功率项差距,也是可以拿来做损失和训练的。 第二条和第三条路径之间的延时,和他们的损失差距也是可以拿来做训练的。
然后,我们的网络可以先在一个场景上看看能不能学会,然后在10个场景看看看能不能学会。然后30个场景、50个场景、100个场景分别试一试,他的训练轮数可能要高一点,嗯,主要是第一TR他可能训练起来没那么容易,我觉得所以说。然后它的一个sample 可能已经变成了给定一个TX,给定一个RX,给定一个场景这样的一个sample了 这个sample相较于我们原先的sample,是一个TX加上一个Z轴平面的RX,相当于是一个TX和1296个RX,其实已经缩短了非常多了。所以说,我们可以把batch size之类东西开的高一点,嗯,可能还要优化一下,这样的话,保证我们的训练速度不要太慢
当然也许有其他的方法可以优化一下他的学习速度,或者是优化一下他的这样的一个批量输入和批量输出的速度和效率率,可以使它的GPU利用率高一点
一些可以借鉴的算法,你可以下载下来放到我们这个文件夹里,放到这个reference的文件夹,我们可能有多个不同的代码,可以作为借鉴和参考注意,我们主任务用的代码其实是基于 trellis 2 他的仓库和文件继续开发的 /data/conda_envs/trellis2 https://github.com/roboflow/rf-detr
https://github.com/happinesslz/SEED
https://github.com/JIA-Lab-research/VoxelNeXt
对于那个radio map header, 它的输出头,它的输入要一个TS和一个Z轴平面来实现。我觉得这个可以暂时先切割开来,暂时不不把它加入我们这里了。毕竟我们radioma它的预测已经效果已经很好了,它相当于那他的那一套处理方法已经感觉可以定型,不用管了,哪怕后面我们写论文的时候,也就相当于把它看成两条分支,完全单独处理也是可以的 甚至我觉得他们后续我们就把,如果我们的CSI这条重新设计的整个网络结构比较好的话,我们再把radio、map他们那些东西给重新加进来,就是作为额外分支加到我们已经训练好的这个网络里,再重新训练就行了。所以说就是先别管他们,总而言之就是先别管radiomap了,就先看看我们这样的一个新的模型架构能不能用
数据集就参考以前的数据集,就是我们基于之前的那个分支接着用就行 --- Original Design Draft End ---