rogermt commited on
Commit
fa9c71d
·
verified ·
1 Parent(s): f6876d5

Update TODO.md: corrected scoring, new roadmap based on V3 results

Browse files
Files changed (1) hide show
  1. own-solver/TODO.md +82 -81
own-solver/TODO.md CHANGED
@@ -1,108 +1,109 @@
1
  # NeuroGolf Solver — Roadmap
2
 
3
- > Current: V90 · 400/400 tasks · LB 5322.64 · Target: >6043
4
- > Philosophy: **Score optimization is now the primary lever.**
5
  > Rule: **NEVER claim a feature works without Kaggle submission confirmation.**
6
- > Updated: 2026-05-21 — V90 confirmed. 400 tasks submitted, 385 solved + 15 fallback.
7
 
8
  ---
9
 
10
- ## The Gap: 5322 → 6043 = +721 pts needed
11
 
12
- Score = log2(1,509,949 / file_size). To gain 721 pts across 400 tasks = avg +1.8 pts/task.
13
- Each 1 pt gain = halving the file size. So we need to halve file sizes on average.
 
14
 
15
- Current avg: ~13.3 pts/task. Target avg: ~15.1 pts/task.
 
16
 
17
  ---
18
 
19
- ## Score Optimization Plan (Priority Order)
20
-
21
- ### Phase 1: fp16 weight conversion (est. +50-100 pts)
22
- - Convert all float32 initializers to float16
23
- - Add Cast(input, to=FLOAT16) at model entry
24
- - Halves weight storage for tasks with large float32 weights
25
- - `fp16_optimizer.py` already exists — run at submission level
26
- - **Target**: All 23 tasks with >1KB fp32 weights
27
-
28
- ### Phase 2: Rebuild conv_var with smaller kernels (est. +100-200 pts)
29
- - conv_var tasks score 8.1-11.2 pts (files 4-90 KB)
30
- - 17 tasks use conv_var → if each gains 3 pts avg = +51 pts
31
- - Strategies:
32
- - Try kernel_size=5 instead of full-grid kernels
33
- - Factored convolutions (depthwise separable)
34
- - Iterative small-kernel approach
35
- - Prune near-zero weights before saving
36
-
37
- ### Phase 3: Weight quantization for MatMul tasks (est. +50-100 pts)
38
- - Tasks with large MatMul weights (182: 462KB, 158: 158KB, 277: 147KB)
39
- - Low-rank factorization: W = U @ V where U is Mx16, V is 16xN
40
- - int8 quantization with DequantizeLinear op
41
- - Could save 75% on largest tasks
42
-
43
- ### Phase 4: Architecture pruning (est. +30-50 pts)
44
- - Remove redundant Cast/Pad/Slice chains in generated models
45
- - Merge consecutive same-type ops
46
- - Eliminate dead branches (outputs not connected to final output)
47
- - Strip unnecessary metadata from ONNX protobuf
48
-
49
- ### Phase 5: Rebuild analytical solvers more compactly (est. +50-100 pts)
50
- - Many wave1-16 solvers use verbose ONNX graphs
51
- - Could merge into fewer ops with same semantics
52
- - Constants sharing across similar operations
53
- - Use fp16 for all intermediate computations
54
 
55
  ---
56
 
57
- ## Task Score Distribution (V90)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
 
59
- | Score Range | Tasks | Example | Action |
60
- |-------------|-------|---------|--------|
61
- | 15-16+ pts | ~80 | transpose (127B), rotate (588B) | Already optimal |
62
- | 13-15 pts | ~150 | Most analytical solvers | Minor gains possible |
63
- | 11-13 pts | ~100 | conv_fixed, medium wave22 | fp16 + pruning |
64
- | 8-11 pts | ~50 | conv_var, large wave22 | Major rebuild needed |
65
- | 1-8 pts | ~20 | Huge MatMul, conv_var large | Quantize/factorize |
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
  ---
68
 
69
- ## Quick Wins (implement first)
70
 
71
- 1. **Run fp16_optimizer.py on full submission** — instant gains, already coded
72
- 2. **Strip unused initializers** from all generated ONNX models
73
- 3. **Reduce conv_var time budget** to prefer smaller kernels
74
- 4. **Rebuild task 239** without TopK to avoid profiler warning
75
 
76
  ---
77
 
78
- ## Remaining 15 "Fallback" Tasks
79
-
80
- These use reference models directly (not our solvers). They score based on file size only.
81
- Improving them requires either:
82
- - Building custom solvers from scratch (hard, unique puzzles)
83
- - Making the reference models smaller (fp16 conversion)
84
-
85
- | Task | Current Size | Potential fp16 Size | Score Gain |
86
- |------|-------------|--------------------:|-----------|
87
- | 133 | 287,675 B | ~144 KB | +1.0 |
88
- | 21 | 29,463 B | ~15 KB | +1.0 |
89
- | 80 | 15,132 B | ~8 KB | +0.9 |
90
- | 208 | 14,111 B | ~7 KB | +1.0 |
91
- | 323 | 11,147 B | ~6 KB | +0.9 |
92
- | 379 | 9,267 B | ~5 KB | +0.9 |
93
- | 5 | 8,024 B | ~4 KB | +0.9 |
94
- | 234 | 7,484 B | ~4 KB | +0.9 |
95
- | 397 | 6,194 B | ~3 KB | +0.9 |
96
- | Others | <5 KB | ~2.5 KB | +0.8 each |
97
 
98
  ---
99
 
100
  ## Research Queue
101
 
102
- 1. [x] Wave 22: 143 tasks (complete)
103
- 2. [x] Fallback zip for 15 unsolved (complete)
104
- 3. [ ] fp16 weight optimization pass
105
- 4. [ ] conv_var kernel size reduction
106
- 5. [ ] MatMul weight factorization
107
- 6. [ ] Architecture pruning pass
108
- 7. [ ] Custom solvers for near-miss tasks (21, 80, 184, 202)
 
1
  # NeuroGolf Solver — Roadmap
2
 
3
+ > Current: V3 optimizer · 400/400 tasks · LB 5560.70 · Target: >6043
4
+ > Philosophy: **Reduce intermediate tensor count + weight memory. That's it.**
5
  > Rule: **NEVER claim a feature works without Kaggle submission confirmation.**
6
+ > Updated: 2026-05-22 — V3 confirmed. Merge + stage1 = +238 pts over V90.
7
 
8
  ---
9
 
10
+ ## The Gap: 5560.70 → 6043 = +483 pts needed
11
 
12
+ Score = max(1.0, 25.0 - ln(memory + params)).
13
+ memory = sum of all intermediate tensor bytes (ORT profiler).
14
+ params = sum of all weight element counts.
15
 
16
+ +483 pts across 400 tasks = avg +1.2 pts/task.
17
+ Each +1 pt ≈ reducing cost by factor of e (2.718×).
18
 
19
  ---
20
 
21
+ ## What Worked (V3 vs V90: +238 pts)
22
+
23
+ 1. **Merge best-of-both** (80 tasks from 5743): +200 pts
24
+ - 5743 has compact 15-70 node models for tasks where V90 had 100+ nodes
25
+ - Fewer nodes = fewer intermediate tensors = less memory
26
+
27
+ 2. **Stage 1 trivial optimization** (6 tasks): +38 pts
28
+ - transpose → 25 pts (was 14.5)
29
+ - color_perm → 21 pts (was 14.5)
30
+ - color_map → 18.8 pts (was 13.3)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
  ---
33
 
34
+ ## Optimization Plan (Priority Order)
35
+
36
+ ### Phase 1: Reduce intermediate count for ALL tasks [est. +150-250 pts]
37
+
38
+ **The single biggest lever.** Each intermediate tensor (1,10,30,30) float32 = 36KB memory.
39
+ Removing 3 unnecessary intermediates from 200 tasks = +0.8 pts × 200 = +160 pts.
40
+
41
+ Techniques:
42
+ - **OneHot replacement**: Replace 10×(Equal+Cast)+Concat with single OneHot op
43
+ - Saves 9-19 intermediate tensors per conv/analytical task
44
+ - Applies to: conv_var (18), conv_fixed (16), many wave22 tasks
45
+ - **Direct output pattern**: Ensure last node outputs directly to graph 'output'
46
+ - **Fuse Slice+Pad chains**: Consecutive Slice or Pad operations → merge into one
47
+ - **Remove dead value_info entries**: Some models have unused intermediate declarations
48
+
49
+ ### Phase 2: fp16 weights WITHOUT Cast node [est. +50-100 pts]
50
+
51
+ Convert float32 initializers to float16 but do NOT add Cast(input→fp16).
52
+ The Cast creates a new intermediate (1,10,30,30) fp16 = 18KB — often MORE than the savings.
53
+
54
+ Better approach: Store weights as fp16, let ORT handle mixed-precision inference.
55
+ OR: Only add Cast when weight savings > 18KB (i.e., weights > 36KB float32).
56
 
57
+ Target: 60+ tasks with >10KB weights.
58
+
59
+ ### Phase 3: SVD factorization for large weights [est. +20-50 pts]
60
+
61
+ Tasks with 50-462 KB weight matrices:
62
+ - 182 (462KB), 158 (158KB), 277 (147KB), 387 (101KB), 285 (99KB), 324 (93KB)
63
+ - Factor W(M×N) → U(M×R) @ V(R×N), validate at each R
64
+
65
+ ### Phase 4: Sign-corrected Conv for conv_var [est. +8 pts]
66
+
67
+ Already working for 6 tasks (127, 171, 220, 230, 258, 261).
68
+ Replaces 15-node architecture with 3 nodes.
69
+ Upload `sign_corrected_conv.py` to solver pipeline.
70
+
71
+ ### Phase 5: Solve more tasks with compact models [est. +50-100 pts]
72
+
73
+ 15 unsolved tasks currently use fallback reference models.
74
+ Some could potentially be solved with custom compact solvers.
75
+ Also: tasks currently using bloated approaches might have simpler solutions.
76
 
77
  ---
78
 
79
+ ## Quick Wins (implement next)
80
 
81
+ 1. ☐ **OneHot op replacement** in conv.py — replace `add_onehot_block()` with single OneHot node
82
+ 2. ☐ **fp16 weights without Cast** — modify fp16_optimizer to skip the Cast node
83
+ 3. ☐ **Integrate sign_corrected_conv** into solve_conv_variable as first attempt
84
+ 4. ☐ **Run optimizer on V91** (once V91 has above fixes integrated)
85
 
86
  ---
87
 
88
+ ## Task Score Distribution (V3, estimated)
89
+
90
+ | Score Range | Tasks | Optimization Target |
91
+ |-------------|-------|-------------------|
92
+ | 18-25 pts | ~6 | Already optimal (trivial tasks) |
93
+ | 14-16 pts | ~50 | Minor gains from fp16/node reduction |
94
+ | 13-14 pts | ~200 | Phase 1 target: reduce intermediates |
95
+ | 12-13 pts | ~100 | Phase 1+2: intermediates + fp16 |
96
+ | 10-12 pts | ~30 | Phase 2+3: fp16 + SVD for large weights |
97
+ | <10 pts | ~14 | Fallback tasks, hard to improve |
 
 
 
 
 
 
 
 
 
98
 
99
  ---
100
 
101
  ## Research Queue
102
 
103
+ 1. [x] Merge best-of-both (V3: +238 pts)
104
+ 2. [x] Stage 1 trivial optimization (6 tasks)
105
+ 3. [x] Sign-corrected Conv (6 conv_var tasks)
106
+ 4. [ ] OneHot op replacement (conv + analytical tasks)
107
+ 5. [ ] fp16 weights without Cast overhead
108
+ 6. [ ] SVD factorization for large weights
109
+ 7. [ ] Solve/improve fallback tasks