[FEAT#71] neuron Phase 15 — sparsity-driven edge prune (정적 → 동적 위상 진입) - #72
Conversation
- src/graphlm/neuron/graph_hybrid.py 확장 - edge_mask: register_buffer (학습 X, state_dict 포함), 초기값 모두 1 (no prune) - forward 에 edge_mask 곱셈 추가 → pruned edge 의 기여도 0 + gradient chain 차단 - effective_edge_magnitude(): 현재 forward 적용 magnitude (mask 곱한 상태) - prune_by_magnitude(threshold): |adj·W| < threshold 영구 0 - prune_bottom_fraction(fraction): 살아있는 edge 중 하위 fraction 영구 0 - effective_sparsity(): 영구 prune 비율 - n_alive_edges(): 살아있는 edge 수 - 10 신규 unit tests - edge_mask 초기 / forward 기능 보존 / prune 정확성 - **gradient resurrection 방지 검증** (pruned 위치의 weight/adj_inner grad == 0) - state_dict 보존 (save/load 후 sparsity 유지) - 입력 검증 (negative threshold, invalid fraction) - 182 → 192 tests, all green
- HybridTransformerTrainConfig 에 prune_at_step / prune_fraction 필드 추가 - _prune_model: 모든 HybridGraphLinear 에 prune_bottom_fraction 일괄 적용 - _model_sparsity: 전체 HybridGraphLinear edge 평균 sparsity - train loop: prune_at_step 도달 시 1회 prune 실행, prune_event 기록 - result 에 final_sparsity / prune_event 추가 - smoke test 검증: baseline 0% sparsity vs prune 30% sparsity, loss 차 작음 (0.008)
- notebooks/02-function-level/14-phase15-sparsity-prune.ipynb 신규 - 4 prune fraction (dense, 30%, 50%, 70%) × 2 seed = 8 run - prune 시점: max_steps/2 = 750 (학습 중간) - arch 고정: hybrid_around_one_around_one + use_full_graph=True (Phase 14 최저 loss 구조) - 자동 verdict 4가지: all-finite / soft degradation (70% ≤ dense+1.0) / monotonic loss / moderate (30%) ≈ dense - loss curve (prune step 수직선 표시) + sparsity vs final_loss trade-off plot - ruff format 적용 (graph_hybrid / test_graph_hybrid)
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (4)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughAdds persistent per-edge masks and magnitude/fraction pruning APIs to HybridGraphLinear, integrates a one-shot prune trigger into the training helper (recording a prune_event), validates behavior with unit tests, and supplies a notebook that sweeps prune fractions and seeds while plotting and auto-evaluating results. ChangesPhase 15 Sparsity-Driven Edge Pruning
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces dynamic edge pruning (Phase 15) to the hybrid graph transformer model. It registers an edge_mask buffer to permanently prune edges by magnitude or bottom fraction, preventing gradient resurrection. The review comments correctly identify a critical tie-breaking issue in prune_bottom_fraction where identical magnitude values could lead to over-pruning, and suggest using torch.topk for deterministic pruning. A corresponding update to the test suite is also suggested to enforce exact pruned count matching.
There was a problem hiding this comment.
Pull request overview
이 PR은 Phase 14의 “dense topology + learned magnitude” 상태에서 한 단계 나아가, 학습 중 edge 자체를 영구적으로 제거(prune) 하는 Phase 15 동적 위상 진입을 구현합니다. 핵심은 HybridGraphLinear에 edge_mask 버퍼를 도입해 forward 기여도를 0으로 만들고, 동일 곱셈 경로를 통해 pruned edge의 gradient resurrection을 차단하는 것입니다.
Changes:
HybridGraphLinear에edge_mask(buffer)와 magnitude 기반 prune API 및 sparsity 측정 헬퍼 추가- 데모 학습 루프에 one-shot prune 훅 추가 및 결과에 sparsity/prune 이벤트 리포팅 추가
- prune 동작/상태 저장/gradient 차단을 검증하는 테스트 추가 + Phase 15 실험 노트북 추가
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/graphlm/neuron/graph_hybrid.py |
edge_mask 적용 및 prune/sparsity 관련 메서드 추가 |
src/graphlm/neuron/hybrid_transformer_demo.py |
학습 중 prune 실행 및 final_sparsity/prune_event 반환 추가 |
tests/neuron/test_graph_hybrid.py |
edge_mask 초기값, prune 동작, gradient 차단, state_dict 보존 테스트 추가 |
notebooks/02-function-level/14-phase15-sparsity-prune.ipynb |
prune fraction sweep 실험/시각화 노트북 추가 |
- gemini #3307531740 (HIGH): prune_bottom_fraction 의 kthvalue+mag<=kth 가 동률 시 의도보다 많이 prune 위험 (극단적으로 100%) → torch.topk(largest=False) 로 하위 n 개 정확 인덱스 추출 후 mask=0. deterministic. - gemini #3307531745: 테스트의 ±10 tolerance → topk 정확성으로 `==` 강화. 추가로 모든 magnitude 동률 시나리오 신규 테스트 (tie-breaking deterministic 검증). - Copilot #3307536521: test_forward_with_initial_mask_unchanged 가 이름과 검증 불일치 → mask=1 forward 를 mask 없는 직접 계산과 정확 비교 (function preservation 명시). - Copilot #3307536553: HybridTransformerTrainConfig 의 prune 인자 silent no-op 위험 → __post_init__ 추가, prune_fraction ∈ [0,1] / prune_at_step ∈ [1, max_steps] 강제. test_hybrid_transformer_demo.py 신규 (9 validation tests). - 192 → 202 tests, all green
연관 이슈
구현 내용
Phase 14 (PR #70) 까지는 dense topology + learned magnitude 의 정적 위상이었음. Phase 15 는 edge 자체를 영구 제거 하는 첫 동적 위상 단계 — paradigm 의 ultimate goal (training-time dynamic parameter count) 의 실질적 시작.
신규 모듈
src/graphlm/neuron/graph_hybrid.py확장edge_mask:register_buffer(학습 X, state_dict 포함), shape(G_out, G_in, k, k), 초기값 모두 1edge_mask곱셈 추가 → pruned edge 의 기여도 0 + gradient chain 차단 (resurrection 방지)effective_edge_magnitude(): 현재 forward 적용 magnitudeprune_by_magnitude(threshold)/prune_bottom_fraction(fraction): 영구 0 처리effective_sparsity()/n_alive_edges(): 측정 helpersrc/graphlm/neuron/hybrid_transformer_demo.py확장HybridTransformerTrainConfig.prune_at_step/prune_fractionresult['final_sparsity']+result['prune_event']반환notebooks/02-function-level/14-phase15-sparsity-prune.ipynb신규hybrid_around_one_around_one+use_full_graph=True(Phase 14 최저 loss 구조 고정)gradient resurrection 방지 메커니즘
mask=0 위치에서 forward 기여 0 + chain rule 로
adj_outer,adj_inner,weight모두 gradient 0 → optimizer 가 살릴 수 없음. unit testtest_pruned_edges_do_not_resurrect_via_gradient로 명시적 검증.테스트 (182 → 202, +10 신규 prune 테스트)
test_edge_mask_initial_all_ones— 초기 상태test_forward_with_initial_mask_unchanged— function preservationtest_prune_by_magnitude_basic/test_prune_idempotent_below_threshold— threshold prunetest_pruned_edges_do_not_resurrect_via_gradient— gradient 차단 (핵심)test_prune_bottom_fraction/test_prune_bottom_fraction_zero_fraction_noop— top-k 류test_prune_negative_threshold_rejected/test_prune_invalid_fraction_rejected— 입력 검증test_edge_mask_in_state_dict— save/load 보존0-init 금지 + magnitude rule 일관 적용 (변경 없음)
Phase 12 부터의 0-init 금지 규칙 그대로 유지. prune 은 학습 후 edge 가 자연히 작은 것들을 제거 — 처음부터 0 으로 시작하는 것과 다름.
CI / 머지 게이트 점검
변경 영향 범위
src/graphlm/neuron/graph_hybrid.py(확장),src/graphlm/neuron/hybrid_transformer_demo.py(확장),tests/neuron/test_graph_hybrid.py(확장),notebooks/02-function-level/(1 신규)Low—edge_mask는 초기값 1 이라 prune 호출 없으면 Phase 14 forward 와 정확히 동일 (function preservation). prune 은 opt-in (config 의prune_at_step is None시 noop).Required Status Checks
Commit LintPR Title LintLinked Issue CheckFormat CheckBuildTest(로컬 192 passed)Lint롤백 계획
edge_mask미사용 시 Phase 14 와 backwards-compat (default no-op). revert 시 영향 없음.edge_maskbuffer 추가됨 — 기존 checkpoint 와 strict load 시 key mismatch 가능.strict=False또는 마이그레이션 필요 (현재 본 프로젝트는 체크포인트 저장 안 함).Phase 15 의 paradigm 의미 — 정적 → 동적 위상 진입
이제 채널마다 다른 edge fan-out / fan-in 발생 — paradigm 의 진짜 dynamic phase 시작.
다음 단계 (Phase 16 후보)
Summary by CodeRabbit
New Features
Tests