Mingqian-233 commited on
Commit
8ad8408
·
verified ·
1 Parent(s): 4a6cd09

Update final docs/config_parity.md

Browse files
Files changed (1) hide show
  1. docs/config_parity.md +60 -102
docs/config_parity.md CHANGED
@@ -1,106 +1,64 @@
1
- # Config Parity:官方 mmrotate config ↔ Jittor config 逐项对照
2
 
3
- > 真相来源:`/root/ref/Point2RBox-v3/configs/point2rbox_v2/*.py`(解析展平后的 golden
4
- > `tests/parity/golden/config_*.json`,由 `tools/dump_config.py` 生成)。
5
- > 可执行版对照:`tests/parity/test_L0_config.py::TestJittorConfigParity`(10 tests)。
6
- > 本文只记录**映射规则**与**疑似异常清单**,数值一律以 golden 为准。
7
 
8
- ## 类名 / 写法映射表(铁律一允许变的三类)
9
 
10
- | 官方(mmrotate/mmdet/mmengine) | JittorJDet | 说明 |
11
  |---|---|---|
12
- | `mmdet.ResNet, out_indices=(1,2,3)` | `Resnet50, return_stages=['layer2','layer3','layer4']` | 数值语义相同 |
13
- | `init_cfg=Pretrained(torchvision://resnet50)` | `pretrained=True` | 同一份 torchvision 权重 |
14
- | `mmdet.FPN` | `FPN` | 参数逐值相同 |
15
- | `mmdet.FocalLoss` | `FocalLoss` | |
16
- | `GWDLoss`(v3 注册名)/`GDLoss(gwd)` | `GDLoss(loss_type='gwd')` | |
17
- | `optim_wrapper.optimizer=AdamW(...)` + `clip_grad` | `optimizer=AdamW(..., grad_clip=...)` | clip 数值不变 |
18
- | `param_scheduler=[LinearLR, MultiStepLR]` | `scheduler=LinearWarmupMultiStepLR` | LR 序列逐点相等(L1 测试 1440 点 rtol 1e-9) |
19
- | `custom_hooks=[mmdet.SetEpochInfoHook]` | Runner 内建 `model.set_epoch(epoch)` | C3 |
20
- | `train_cfg=EpochBasedTrainLoop(max_epochs=12, val_interval=12)` | `max_epoch=12, eval_interval=12` | |
21
- | `default_hooks.logger interval=50 / checkpoint interval=1` | `log_interval=50 / checkpoint_interval=1` | |
22
- | pipeline `LoadImageFromFile→LoadAnnotations(qbox)→ConvertBoxType→ConvertWeakSupervision` | `P2RV2DOTADataset`(内建,直读 split txt) | qbox→rbox 用 cv2.minAreaRect 原样;point_dummy=1 官方默认 |
23
- | pipeline `Resize((1024,1024), keep_ratio=True)` | `MMRotateResize(min_size=1024, max_size=1024)` | 不复用底座 RotatedResize(会重规范角度) |
24
- | pipeline `RandomFlip(0.75, [h,v,diag])` | `MMRotateRandomFlip(同参数)` | 不复用底座 RotatedRandomFlip(-1 偏移+角度公式不同) |
25
- | `data_preprocessor(mean/std/bgr_to_rgb/pad_size_divisor)` | transforms `Normalize`+`Pad(32)`;mean/std 同时传 model TED 反归一化 | |
26
-
27
- ## 疑似异常但已确认照抄(铁律二,勿"修正")
28
-
29
- | # | | 已照抄的值 | 状态 |
30
- |---|---|---|---|
31
- | 1 | `_delete_=True` clip_grad 仍生效 | `grad_clip(max_norm=35, norm_type=2)` | ✅ C1 + L0 锚定测试 |
32
- | 2 | param_scheduler 未被覆盖 | LinearLR(1/3, iter 0→500) × MultiStepLR([8,11], 0.1) | ✅ C2,LR 逐点相等 |
33
- | 3 | SetEpochInfoHook 是功能性依赖 | runner epoch 注入 | ✅ C3 |
34
- | 4 | val 指向 trainval/ | 照抄 | ✅ config + L0 测试断言 |
35
- | 5 | stage-2 wd=0.005(≠端到端 0.05) | 照抄 | ✅ golden 锚定(stage-2 config M7 时写) |
36
- | 6 | head strides=[8] 单层 | 照抄 | |
37
- | 7 | backbone out_indices v2=(1,2,3) / stage-2=(0,1,2,3) | 各是各的 | ✅ |
38
- | 8 | square_cls/edge_loss_cls/post_process/voronoi_thres 逐类魔数 | 一个数不动 | ✅ L0 锚定 |
39
- | 9 | ss_prob=[0.68,0.07,0.25] | 照抄 | ✅ |
40
- | 10 | RandomFlip prob=0.75 | 照抄 | ✅ |
41
- | 11 | boxtype2tensor=False / relu_before_extra_convs=True / add_extra_convs='on_output' / filter_empty_gt=True | 全部显式 | ✅ |
42
- | 12 | `label_assign_pseudo_label_switch_eopch` 拼写 | v3 用,v2 未涉及;若移植中遇到保持原拼写 | 备案 |
43
-
44
- ## 已知实现层差异(非 config 数值,均有记录与理由)
45
-
46
- | | 差异 | 影响 |
47
- |---|---|---|
48
- | torchvision `resized_crop` antialias | jt.nn.interpolate antialias | sca 增广路径图像内容,训练随机性范围内 |
49
- | mmcv RoIAlignRotated aligned=True 不做 1x1 钳制 | JDet kernel 始终钳制 | 仅亚像素 roi |
50
- | jdet nms keep 顺序 | head 内先按分数排序再 NMS,语义对齐 mmcv | 已适配 |
51
- | reduce_mean(分布式均值) | 单卡训练恒等 | 官方总 batch=2 单卡,无差异 |
52
- | eigh 简并子梯度基底 | w==h 时与 torch 的 a/c 分配不同(trace 一致) | 数学等价的子梯度选择 |
53
-
54
- ---
55
-
56
- # v3 专项附录(Agent B:SAM 配置与 utils 怪癖)
57
-
58
- # Config Parity — 官方 config ↔ Jittor config 对照
59
-
60
- > 状态:开档(2026-07-26)。M5' 写 v3 config 时逐项补全对照表与类名映射表。
61
- > L0 测试:A `tools/dump_config.py` golden + `tests/parity/`,v3 侧比对在 M5' 接入。
62
-
63
- ## 疑似异常但已确认照抄(只记录,禁止"修正")
64
-
65
- ### 来自计划铁律二(写 config 时逐条勾选,见 PLAN §6)
66
-
67
- 12 条清单在 M5' 写 config 时逐条核对后搬进本表。先行确认的:
68
-
69
- | # | 项 | 实测情况 | 处置 |
70
- |---|---|---|---|
71
- | 铁律二 #7 | class 1/0/14 weights ��� color_consistency 但 required_metrics 未列 | **实测只有 class 1 不对称**(0/14 两边都列了);计划描述有偏差,行为照抄不受影响 | `_base_sam-dotav1-0.py` 已逐字节 cp(md5=772f1e23…) |
72
- | 铁律二 #8 | class 3/8/10 的 circularity 权重 = -3 + penalty_circularity=100 | 已数值验证:圆形 mask 在这三类被压掉、斜矩形胜出(tests/test_filter_masks.py) | 照抄 ✓ |
73
-
74
- ### 代码层怪癖(losses/utils.py 移植时发现,均已 1e-6 parity 验证照抄)
75
-
76
- 1. **`filter_masks` 内置 fallback config 与 `_base_sam-dotav1-0.py` 数值不同**:
77
- fallback 的 default color_consistency 权重 6(配置文件是 2);fallback 的 class 11 多
78
- `rectangularity: -2`、class 0/14 多 `rectangularity: -1`;aspect_ratio_range 普遍不同
79
- (class 7:fallback (1.3,3) vs 配置 (1,5))。训练时 config 恒传入,fallback 仅
80
- config=None 时生效。**两套都照抄,不合并、不统一。**
81
- 2. `circularity` 的 `radius=int(radius)` 截断 + `countNonZero` 栅格化圆面积(非解析
82
- πr²)——量化行为,照抄。
83
- 3. fallback 里 class 2 的 required_metrics 列了 aspect_ratio_reasonableness 但没配
84
- aspect_ratio_range → 该 metric 实际永不计算(weights 也没它,无实际影响)。照抄。
85
- 4. `center_alignment` 在 prompt 点落在 mask 外时返回硬惩罚 -100.0(×权重 10 = -1000),
86
- 刻意设计,照抄。
87
-
88
- ## 偏离项记录(config 语法层,非数值)
89
-
90
- - (待 M5' 填写:registry 类名映射、JDet config 语法差异等允许项)
91
-
92
- ## 追加豁免(2026-07-26 14:35)
93
-
94
- | 项 | 官方值 | Jittor 侧 | 理由 |
95
- |---|---|---|---|
96
- | `train/val/test_dataloader.num_workers` | 2 | 0 | jittor 1.3.8.5 多进程 dataset 环形缓冲死锁(A commit 3d87c60 实测)。纯 infra 参数,不影响样本组成/顺序/任何训练数学。jittor 修复后可恢复 |
97
-
98
- ## 上游可复现性发现(2026-07-26,loss_by_feat parity 期间)
99
-
100
- **上游 v3 训练的 MobileSAM 实际使用了未播种的随机 attention bias。**
101
- `mobile_sam` 包 `build_sam` 先 `eval()` 后 `load_state_dict`:TinyViT Attention 在 eval()
102
- 时缓存非持久的 `ab`(attention bias 索引结果),随后 load_state_dict 不刷新它——
103
- 上游每次训练运行的 SAM attention bias 都是随机初始化残留,逐次不同、不可复现。
104
- 本仓库 Jittor 移植是「加载后自然刷新」的正确语义(golden 采用修正语义后 SAM E2E 逐位一致)。
105
- **含义**:我们的 SAM 是正确权重版;与上游 61.38 的 mAP 对比中该差异方向未知(推测中性或
106
- 偏正面),若最终精度有出入这是候选解释之一。详见 tools/dump_v3_head_loss_reference.py 注释。
 
1
+ # Configuration parity
2
 
3
+ The files in `configs/point2rbox_v3/` reproduce the official mmrotate
4
+ Point2RBox-v3 configuration. `tests/parity/test_L0_v3_config.py` compares the
5
+ flattened values with stored reference goldens.
 
6
 
7
+ ## Framework mappings
8
 
9
+ | PyTorch/mmrotate | Jittor/JDet | Equivalent behavior |
10
  |---|---|---|
11
+ | `mmdet.ResNet(out_indices=...)` | `Resnet50(return_stages=...)` | same feature stages |
12
+ | torchvision ResNet-50 initialization | `pretrained=True` | same pretrained source |
13
+ | `mmdet.FPN` | `FPN` | matching channels and levels |
14
+ | `mmdet.FocalLoss` | `MMDetFocalLoss` | mmdetection reduction semantics |
15
+ | `GWDLoss` | `GDLoss(loss_type='gwd')` | matching Gaussian distance |
16
+ | AdamW + `clip_grad` | JDet AdamW with `grad_clip` | global L2 clip at 35 |
17
+ | LinearLR + MultiStepLR | `LinearWarmupMultiStepLR` | pointwise-equal LR sequence |
18
+ | `SetEpochInfoHook` | runner `model.set_epoch(epoch)` | epoch switches preserved |
19
+ | mmrotate qbox transforms | `P2RV2DOTADataset` | qbox/rbox and point labels |
20
+ | mmrotate resize/flip | `MMRotateResize` / `MMRotateRandomFlip` | coordinate and angle parity |
21
+
22
+ ## Locked training values
23
+
24
+ - 12 epochs, evaluation at epoch 12, checkpoint every epoch.
25
+ - AdamW learning rate `5e-5`, gradient clip `35`.
26
+ - Linear warmup from factor `1/3` for 500 iterations; learning-rate milestones
27
+ at epochs 8 and 11 with factor 0.1.
28
+ - End-to-end batch size 2 and second-stage batch size 4 on one GPU.
29
+ - End-to-end weight decay 0.05; second-stage weight decay 0.005.
30
+ - Five FPN strides `[8, 16, 32, 64, 128]` for v3.
31
+ - Self-supervision probabilities `[0.68, 0.07, 0.25]`.
32
+ - Epoch 6 switches for edge supervision, pseudo-label assignment and copy-paste
33
+ routing. The upstream key spelling
34
+ `label_assign_pseudo_label_switch_eopch` is intentionally preserved.
35
+ - Validation points to the reference trainval split, matching the official
36
+ diagnostic protocol.
37
+
38
+ ## SAM filtering configuration
39
+
40
+ `configs/point2rbox_v3/_base_sam-dotav1-0.py` preserves the complete
41
+ class-specific filtering table from the reference. The L0 test compares every
42
+ key, value and tuple/list type. Notable intentional values include:
43
+
44
+ - classes 3, 8 and 10 use circularity weight `-3` with circularity penalty 100;
45
+ - prompt points outside a mask receive the reference hard center-alignment
46
+ penalty;
47
+ - the internal fallback filter table is kept separate from the config table,
48
+ because the reference values differ and the configured training path always
49
+ passes the explicit table.
50
+
51
+ ## Infrastructure-only adaptation
52
+
53
+ The validated Jittor setup uses `num_workers=0`. Jittor 1.3.8.5 can deadlock in
54
+ the multiprocessing dataset ring buffer for this variable-instance workload.
55
+ This changes loading concurrency only; sample definitions, transforms and
56
+ training math remain unchanged.
57
+
58
+ ## Upstream MobileSAM cache behavior
59
+
60
+ The upstream builder enters evaluation mode before loading the TinyViT state
61
+ dict, which can leave a cached attention-bias tensor derived from initialization
62
+ values. The Jittor builder loads weights first and then refreshes the evaluation
63
+ cache. This is the deterministic checkpoint-loading behavior documented in
64
+ [porting_notes.md](porting_notes.md).