juiceb0xc0de commited on
Commit
4f4e0d4
·
1 Parent(s): 00cabba

Enrich graph: 35 nodes, 36 tiered edges (full curated set)

Browse files
Files changed (2) hide show
  1. forge/harness.py +10 -6
  2. forge/seed.py +136 -73
forge/harness.py CHANGED
@@ -46,12 +46,16 @@ def main():
46
  assert res["fft"]["status"] == "blocked", "QLoRA and FFT are mutually exclusive"
47
  assert res["bnb_4bit"]["status"] in ("conditional", "available")
48
 
49
- # Scenario 3: conditional flips on context. vLLM + gradient_checkpointing.
50
- r_off = engine.resolve(conn, ["vllm"], {"gradient_checkpointing": "disabled"})
51
- r_on = engine.resolve(conn, ["vllm"], {"gradient_checkpointing": "enabled"})
52
- assert r_off["gradient_checkpointing"]["status"] == "conditional"
53
- assert r_on["gradient_checkpointing"]["status"] == "available"
54
- show(conn, ["vllm"], {"gradient_checkpointing": "disabled"})
 
 
 
 
55
 
56
  # Scenario 4: benchmark-backed recommendation (performance, not compatibility).
57
  print(f"\n{C_DIM}── recipe: best schedulers by val_loss (your benchmark) ──{C_RST}")
 
46
  assert res["fft"]["status"] == "blocked", "QLoRA and FFT are mutually exclusive"
47
  assert res["bnb_4bit"]["status"] in ("conditional", "available")
48
 
49
+ # Scenario 3a: hard break vLLM × Grad Checkpoint.
50
+ res = show(conn, ["vllm"])
51
+ assert res["grad_ckpt"]["status"] == "blocked", "grad_ckpt should break with vLLM"
52
+
53
+ # Scenario 3b: a real conditional flips on context — FSDP × bnb 4-bit needs the plugin.
54
+ r_off = engine.resolve(conn, ["fsdp"], {})
55
+ r_on = engine.resolve(conn, ["fsdp"], {"plugin": "bnb-fsdp"})
56
+ assert r_off["bnb_4bit"]["status"] == "conditional", "FSDP+4bit needs the bnb-fsdp plugin"
57
+ assert r_on["bnb_4bit"]["status"] == "available"
58
+ show(conn, ["fsdp"], {})
59
 
60
  # Scenario 4: benchmark-backed recommendation (performance, not compatibility).
61
  print(f"\n{C_DIM}── recipe: best schedulers by val_loss (your benchmark) ──{C_RST}")
forge/seed.py CHANGED
@@ -1,4 +1,4 @@
1
- """Seed the Forge graph.
2
 
3
  Three kinds of truth, kept honestly separate:
4
  - NODES: the components.
@@ -13,95 +13,158 @@ from . import db
13
 
14
  BENCH_URL = "https://huggingface.co/spaces/juiceb0xc0de/lr-scheduler-benchmark"
15
  MEMPALACE = "mempalace://chaos-injection-trainer-notes"
 
 
 
16
 
17
- # (canonical, type, display_name, aliases, description)
18
  NODES = [
19
  # optimizers
20
- ("adamw", "optimizer", "AdamW", ["adam", "adamw_torch"], "Decoupled weight-decay Adam. The benchmark's fixed optimizer."),
21
- ("adamw_8bit", "optimizer", "AdamW 8-bit", ["adamw8bit", "bnb_adamw_8bit"], "bitsandbytes 8-bit AdamW. Default decay/no-decay param groups."),
22
- ("paged_adamw_8bit", "optimizer", "Paged AdamW 8-bit", ["paged_adamw"], "Paged 8-bit AdamW; pairs with QLoRA in the QLoRA paper."),
23
- ("muon", "optimizer", "Muon", [], "Orthogonalizing momentum optimizer for 2D weight matrices."),
24
- # schedulers (subset; benchmark covers 25)
25
- ("cosine", "scheduler", "Cosine", ["cosine_schedule"], "Cosine decay LR schedule."),
26
- ("wsd", "scheduler", "WSD", ["warmup_stable_decay"], "Warmup-Stable-Decay schedule."),
27
- ("constant", "scheduler", "Constant", ["constant_lr"], "Flat LR. Topped accuracy in the benchmark."),
28
- ("linear", "scheduler", "Linear", ["linear_decay"], "Linear decay schedule."),
29
- ("onecycle", "scheduler", "OneCycle", ["one_cycle"], "One-cycle policy. Clear underperformer on short classification finetune."),
30
- ("deep_chaos_scheduler", "scheduler", "DeepChaosScheduler", ["lucky_pick", "lucky-pick-scheduler"], "Rick's scheduler. Top-tier accuracy in the benchmark."),
31
- ("aecs", "scheduler", "AECS", [], "Rick's AECS scheduler. #3 on val_loss in the benchmark."),
32
  ("dlrs", "scheduler", "DLRS", [], "Rick's dynamic LR scheduler. #1 on val_loss in the benchmark."),
33
- ("greedy_lr", "scheduler", "GreedyLR", [], "Rick's greedy LR scheduler. #2 on val_loss in the benchmark."),
 
 
34
  # techniques
35
- ("lora", "technique", "LoRA", [], "Low-rank adaptation."),
36
- ("qlora", "technique", "QLoRA", [], "LoRA on a 4-bit quantized base."),
37
- ("fft", "technique", "Full Fine-Tune", ["full_finetune", "full_finetuning"], "Update all weights."),
38
- ("gradient_checkpointing", "technique", "Gradient Checkpointing", ["grad_ckpt", "checkpointing"], "Trade compute for memory by recomputing activations."),
39
- ("response_only", "technique", "Response-Only Training", ["completion_only", "response_only_training"], "Loss only on completion tokens."),
40
- ("packed_sequences", "technique", "Packed Sequences", ["packing"], "Pack multiple samples per sequence."),
41
- ("per_layer_lr_rotation", "technique", "Per-Layer LR Rotation", ["wavelength_rotation"], "Rotate LR across layer bands during training."),
 
 
 
 
 
42
  # quantization
43
- ("bnb_4bit", "quantization", "bnb 4-bit", ["nf4", "4bit"], "bitsandbytes 4-bit (NF4) base quantization."),
44
- ("bnb_8bit", "quantization", "bnb 8-bit", ["8bit"], "bitsandbytes 8-bit quantization."),
45
- # inference
46
- ("vllm", "inference", "vLLM", [], "High-throughput inference/generation engine."),
47
  # architectures
48
- ("qwen2_5", "architecture", "Qwen2.5", ["qwen2.5", "qwen"], "Qwen2.5 family."),
49
- ("llama3", "architecture", "Llama 3", ["llama-3"], "Llama 3 family."),
50
- ("gemma2", "architecture", "Gemma 2", ["gemma"], "Gemma 2 family."),
51
- ("distilbert", "architecture", "DistilBERT", ["distilbert-base-uncased"], "Benchmark model: DistilBERT on SST-2."),
 
 
 
52
  ]
53
 
54
- # Real relational edges. tier 1 = Rick-verified; tier 2 = documented/definitional.
 
 
 
 
55
  EDGES = [
56
- # --- tier 1: verified in Rick's mempalace / codebase ---
57
  dict(from_canon="per_layer_lr_rotation", to_canon="adamw_8bit", relation="BREAKS", tier=1,
58
- fix="Pass custom optimizer_grouped_parameters split by layer band, OR apply the LR as a per-param multiplier instead of relying on default groups.",
59
- evidence=[dict(url=MEMPALACE, source_type="practitioner_run",
60
- quote="adamw_8bit produces decay/no-decay param groups by default, not layer-band groups; WavelengthRotationCallback maps params to layers but the plumbing doesn't reach the right target.")]),
61
- dict(from_canon="deep_chaos_scheduler", to_canon="adamw", relation="COMPATIBLE", tier=1,
62
- evidence=[dict(url=MEMPALACE, source_type="practitioner_run",
63
- quote="DeepChaosScheduler runs on top of AdamW; confirmed in Rick's codebase and the LR-scheduler benchmark.")]),
64
-
65
- # --- tier 2: documented / definitional ---
66
- dict(from_canon="qlora", to_canon="bnb_4bit", relation="REQUIRES", tier=2,
67
- fix="QLoRA fine-tunes LoRA adapters over a 4-bit (NF4) frozen base by definition.",
68
- evidence=[dict(url="https://arxiv.org/abs/2305.14314", source_type="paper",
69
- quote="QLoRA backpropagates gradients through a frozen, 4-bit quantized base model into LoRA adapters.")]),
70
- dict(from_canon="qlora", to_canon="paged_adamw_8bit", relation="COMPATIBLE", tier=2,
71
- evidence=[dict(url="https://arxiv.org/abs/2305.14314", source_type="paper",
72
- quote="QLoRA uses paged optimizers to manage memory spikes.")]),
73
- dict(from_canon="qlora", to_canon="fft", relation="BREAKS", tier=2,
74
- fix="QLoRA and full fine-tuning are mutually exclusive training modes for one run; pick one.",
75
- evidence=[dict(url="https://arxiv.org/abs/2305.14314", source_type="paper",
76
- quote="QLoRA freezes the base model and trains only adapters; full fine-tuning updates all weights.")]),
77
- dict(from_canon="response_only", to_canon="packed_sequences", relation="CONDITIONAL", tier=2,
78
- conditions={"loss_mask": "packing_aware"},
79
- fix="Use a completion-only loss mask that is packing-aware so loss isn't computed across packed sample boundaries.",
80
- evidence=[dict(url="https://huggingface.co/docs/trl", source_type="docs",
81
- quote="Completion-only loss with packed sequences requires correct masking at sample boundaries.")]),
82
- dict(from_canon="vllm", to_canon="gradient_checkpointing", relation="CONDITIONAL", tier=2,
83
- conditions={"gradient_checkpointing": "enabled"},
84
- fix="Keep gradient_checkpointing ENABLED — disabling it is not compatible with vLLM generation (TRL).",
85
- evidence=[dict(url="https://huggingface.co/docs/trl", source_type="docs",
86
- quote="Disabling this option is not compatible with vLLM generation.")]),
87
- dict(from_canon="gradient_checkpointing", to_canon="lora", relation="COMPATIBLE", tier=2,
88
- evidence=[dict(url="https://huggingface.co/docs/peft", source_type="docs",
89
- quote="Gradient checkpointing is commonly combined with LoRA to cut activation memory.")]),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  ]
91
 
92
- # Unverified ecosystem claims — proposed, NOT asserted. Sit in review_queue until
93
- # corroborated by 2+ sources or Rick approves.
94
  REVIEW = [
95
- dict(raw_a="muon", raw_b="bnb_4bit", relation="CONDITIONAL",
96
- conditions={"note": "Muon orthogonalizes 2D weight matrices; whether it composes cleanly with a 4-bit frozen base is unverified."},
97
- evidence_url=""),
98
- dict(raw_a="muon", raw_b="mup_scaling", relation="COMPATIBLE",
99
- conditions={"note": "Claimed in 'Practical Efficiency of Muon' — needs a real source before promotion."},
100
- evidence_url=""),
101
  ]
102
 
103
  # Rick's LR-scheduler benchmark leaderboard. DistilBERT / SST-2, 3 seeds each.
104
- # tuple: (scheduler, val_loss_mean, val_loss_std, val_acc_mean, val_acc_std, steps_to_target)
105
  BENCH_MODEL, BENCH_TASK = "distilbert-base-uncased", "glue/sst2"
106
  BENCH_CONDITIONS = {"batch_size": 32, "num_epochs": 3, "lr": 2e-5, "weight_decay": 0.01,
107
  "warmup_fraction": 0.06, "target_loss": 0.35}
 
1
+ """Seed the Forge graph — the curated demo graph.
2
 
3
  Three kinds of truth, kept honestly separate:
4
  - NODES: the components.
 
13
 
14
  BENCH_URL = "https://huggingface.co/spaces/juiceb0xc0de/lr-scheduler-benchmark"
15
  MEMPALACE = "mempalace://chaos-injection-trainer-notes"
16
+ TRL = "https://huggingface.co/docs/trl"
17
+ PEFT = "https://huggingface.co/docs/peft"
18
+ QLORA_PAPER = "https://arxiv.org/abs/2305.14314"
19
 
20
+ # (canonical, type, name, aliases, description)
21
  NODES = [
22
  # optimizers
23
+ ("adamw", "optimizer", "AdamW", ["adam", "adamw_torch"], "Workhorse decoupled-weight-decay optimizer. Safe default."),
24
+ ("adamw_8bit", "optimizer", "AdamW 8-bit", ["adamw8bit", "bnb_adamw_8bit"], "bitsandbytes 8-bit AdamW. Saves VRAM. Default param groups can fight per-layer LR tricks."),
25
+ ("paged_adamw", "optimizer", "Paged AdamW", ["paged_adamw_8bit", "paged_adamw_32bit"], "CPU-paged optimizer states. For when you really can't fit."),
26
+ ("lion", "optimizer", "Lion", [], "Sign-momentum optimizer. Lower memory than AdamW; needs lower LR."),
27
+ ("muon", "optimizer", "Muon", [], "Newton–Schulz orthogonalized momentum. Faster convergence on hidden weights."),
28
+ ("sophia", "optimizer", "Sophia-G", [], "Hessian-informed second-order. Promising for LLMs."),
29
+ ("adafactor", "optimizer", "Adafactor", [], "Memory-light. Tricky LR schedule."),
30
+ # schedulers
31
+ ("cosine", "scheduler", "Cosine", ["cosine_with_warmup"], "Cosine decay with warmup. Boring; works."),
32
+ ("onecycle", "scheduler", "OneCycle", ["one_cycle"], "Aggressive warm-then-anneal. Faster but can overshoot on long runs."),
 
 
33
  ("dlrs", "scheduler", "DLRS", [], "Rick's dynamic LR scheduler. #1 on val_loss in the benchmark."),
34
+ ("linear", "scheduler", "Linear", [], "Linear warmup linear decay."),
35
+ ("wsd", "scheduler", "WSD", ["warmup_stable_decay"], "Warmup–Stable–Decay. Continual-pretrain friendly."),
36
+ ("constant", "scheduler", "Constant", [], "Flat. Combine with manual restarts."),
37
  # techniques
38
+ ("qlora", "technique", "QLoRA", [], "4-bit base + LoRA adapters. Lets a 70B fit on one card."),
39
+ ("lora", "technique", "LoRA", [], "Low-rank adapters. Cheap, composable, the default PEFT."),
40
+ ("fft", "technique", "Full Fine-Tune", ["full_finetune", "full_finetuning"], "Update every parameter. Hungry. Mutually exclusive with adapter methods."),
41
+ ("grad_ckpt", "technique", "Grad Checkpoint", ["gradient_checkpointing", "checkpointing"], "Trade FLOPs for VRAM. Must be off for vLLM gen during training."),
42
+ ("per_layer_lr_rotation", "technique", "Per-Layer LR Rotation", ["wavelength_rotation"], "Rick's trick: rotate LR across layer bands per step. Needs custom param groups."),
43
+ ("chaos_inject", "technique", "Chaos Injectors", ["chaos_injectors", "entropy_injectors"], "Activation perturbation at hidden layers. NaN-prone without staged melt-in."),
44
+ ("jacobian_reg", "technique", "Jacobian Reg", ["jacobian_regularization"], "Smoothness penalty via Jacobian. Forward pass corrupts the injector cache."),
45
+ ("fsdp", "technique", "FSDP", ["fully_sharded_data_parallel"], "Fully-Sharded Data Parallel. Sharding for big models."),
46
+ ("ddp", "technique", "DDP", ["distributed_data_parallel"], "Vanilla data-parallel. Cheap when the model fits."),
47
+ ("deepspeed_z3", "technique", "DeepSpeed ZeRO-3", ["zero3", "zero_stage_3", "deepspeed_zero3"], "ZeRO stage 3 partitioning. Battle-tested."),
48
+ ("unsloth", "technique", "Unsloth", [], "Fused kernels for LoRA/QLoRA. PyTorch-only; tight coupling to bnb."),
49
+ ("staged_meltin", "technique", "Staged Melt-In", ["melt_in"], "Linear ramp-in of chaos injectors over N steps. Prevents NaN at layer ~6."),
50
  # quantization
51
+ ("bnb_4bit", "quantization", "bnb 4-bit", ["nf4", "4bit"], "bitsandbytes NF4. The QLoRA base."),
52
+ ("bnb_8bit", "quantization", "bnb 8-bit", ["8bit", "int8"], "LLM.int8(). Inference-leaning; training works."),
53
+ ("gptq", "quantization", "GPTQ", [], "Post-training quant. Inference-only for our purposes."),
54
+ ("awq", "quantization", "AWQ", [], "Activation-aware weight quant. Inference-time."),
55
  # architectures
56
+ ("llama3", "architecture", "Llama-3", ["llama-3"], "Llama-3 8B / 70B family."),
57
+ ("mistral", "architecture", "Mistral", ["mixtral"], "Mistral / Mixtral."),
58
+ ("qwen2", "architecture", "Qwen-2.5", ["qwen2.5", "qwen"], "Strong open multilingual base."),
59
+ ("distilbert", "architecture", "DistilBERT", ["distilbert-base-uncased"], "The bench model. SST-2 sandbox."),
60
+ # inference
61
+ ("vllm", "inference", "vLLM", [], "PagedAttention server. Needs grad-ckpt off during in-train generation."),
62
+ ("sglang", "inference", "SGLang", [], "Structured-gen server."),
63
  ]
64
 
65
+
66
+ def _ev(url, quote, source_type, tier):
67
+ return [{"url": url, "quote": quote, "source_type": source_type, "source_tier": tier}]
68
+
69
+
70
  EDGES = [
71
+ # --- tier 1: Rick-verified (mempalace) + documented definitional ---
72
  dict(from_canon="per_layer_lr_rotation", to_canon="adamw_8bit", relation="BREAKS", tier=1,
73
+ fix="Pass custom optimizer_grouped_parameters adamw_8bit's default decay/no-decay split overrides your per-layer LR bands.",
74
+ evidence=_ev(MEMPALACE, "adamw_8bit produces decay/no-decay param groups by default; per-layer LR rotation silently no-ops unless you pass optimizer_grouped_parameters yourself.", "practitioner_run", 1)),
75
+ dict(from_canon="jacobian_reg", to_canon="chaos_inject", relation="BREAKS", tier=1,
76
+ fix="Jacobian-reg's extra forward pass corrupts the injector activation cache → ortho_loss is poisoned. Disable one.",
77
+ evidence=_ev(MEMPALACE, "the jacobian reg forward overwrites the activation cache that chaos_inject samples from; ortho_loss explodes.", "practitioner_run", 1)),
78
+ dict(from_canon="chaos_inject", to_canon="staged_meltin", relation="REQUIRES", tier=1,
79
+ fix="Stage injectors in over ~100 steps; NaN at layer ~6 if injected from step 0.",
80
+ evidence=_ev(MEMPALACE, "NaN at injector layer ~6 if run from step 0; staged melt-in over 100 steps fixed it.", "practitioner_run", 1)),
81
+ dict(from_canon="grad_ckpt", to_canon="vllm", relation="BREAKS", tier=1,
82
+ fix="Disable gradient_checkpointing for the in-train vLLM gen pass. TRL-documented.",
83
+ evidence=_ev(TRL, "gradient_checkpointing must be disabled when generating with vLLM during training.", "official_docs", 1)),
84
+ dict(from_canon="qlora", to_canon="fft", relation="BREAKS", tier=1,
85
+ fix="QLoRA freezes the base model; Full Fine-Tune updates it. Pick one.",
86
+ evidence=_ev(QLORA_PAPER, "QLoRA backprops gradients through a frozen 4-bit quantized model into low-rank adapters.", "paper", 1)),
87
+ dict(from_canon="qlora", to_canon="bnb_4bit", relation="REQUIRES", tier=1,
88
+ fix="QLoRA is defined as 4-bit NF4 base + LoRA adapters — load the base in bnb 4-bit.",
89
+ evidence=_ev(PEFT, "QLoRA fine-tunes a 4-bit quantized base model loaded via bitsandbytes NF4.", "official_docs", 1)),
90
+ dict(from_canon="qlora", to_canon="lora", relation="REQUIRES", tier=1,
91
+ fix="QLoRA = 4-bit base + LoRA adapters. The adapter rank is your hyperparameter.",
92
+ evidence=_ev(QLORA_PAPER, "QLoRA augments the frozen quantized model with Low-Rank Adapters.", "paper", 1)),
93
+ dict(from_canon="unsloth", to_canon="bnb_4bit", relation="REQUIRES", tier=1,
94
+ fix="Unsloth's fused kernels assume a bnb 4-bit base.",
95
+ evidence=_ev("https://github.com/unslothai/unsloth", "Unsloth supports 4-bit quantized models via bitsandbytes for QLoRA fine-tuning.", "official_docs", 1)),
96
+ dict(from_canon="unsloth", to_canon="lora", relation="REQUIRES", tier=1,
97
+ fix="Unsloth's fast path is the LoRA / QLoRA path.",
98
+ evidence=_ev("https://github.com/unslothai/unsloth", "Unsloth accelerates LoRA and QLoRA fine-tuning with custom Triton kernels.", "official_docs", 1)),
99
+
100
+ # --- tier 2: documented / 2+ sources ---
101
+ dict(from_canon="lora", to_canon="fft", relation="BREAKS", tier=2,
102
+ fix="Adapter-method and full fine-tune are mutually exclusive within one run.",
103
+ evidence=_ev(PEFT, "PEFT methods freeze the base; choose either full fine-tuning or a PEFT method per run.", "official_docs", 2)),
104
+ dict(from_canon="muon", to_canon="adamw_8bit", relation="BREAKS", tier=2,
105
+ fix="Muon owns the optimizer step for hidden weights; 8-bit AdamW state is incompatible with the Newton–Schulz update.",
106
+ evidence=_ev("https://kellerjordan.github.io/posts/muon/", "Muon replaces the optimizer update for 2D weights; use AdamW for the rest, not its 8-bit variant.", "blog", 2)),
107
+ dict(from_canon="muon", to_canon="adamw", relation="REQUIRES", tier=2,
108
+ fix="Muon only updates 2D hidden weights — embeddings + biases still need AdamW.",
109
+ evidence=_ev("https://kellerjordan.github.io/posts/muon/", "non-hidden parameters (embeddings, scalars) are handled by a standard AdamW.", "blog", 2)),
110
+ dict(from_canon="unsloth", to_canon="fsdp", relation="BREAKS", tier=2,
111
+ fix="Unsloth's custom kernels don't compose with FSDP sharding hooks today.",
112
+ evidence=_ev("https://github.com/unslothai/unsloth/issues", "FSDP is not currently supported alongside Unsloth's fused kernels.", "issue", 2)),
113
+ dict(from_canon="awq", to_canon="fft", relation="BREAKS", tier=2,
114
+ fix="AWQ is an inference-time weight quant. You can't fine-tune through it.",
115
+ evidence=_ev("https://github.com/casper-hansen/AutoAWQ", "AWQ is intended for post-training quantization for inference.", "official_docs", 2)),
116
+ dict(from_canon="gptq", to_canon="fft", relation="BREAKS", tier=2,
117
+ fix="GPTQ is post-training quant — frozen base only.",
118
+ evidence=_ev("https://arxiv.org/abs/2210.17323", "GPTQ is a one-shot post-training quantization method.", "paper", 2)),
119
+ dict(from_canon="fsdp", to_canon="bnb_4bit", relation="CONDITIONAL", tier=2, conditions={"plugin": "bnb-fsdp"},
120
+ fix="Works only with the bnb-FSDP plugin; vanilla FSDP shards over uninitialized 4-bit weights.",
121
+ evidence=_ev("https://huggingface.co/docs/accelerate", "FSDP + bitsandbytes 4-bit requires the bnb-fsdp wrap policy.", "official_docs", 2)),
122
+
123
+ # --- tier 3: single source (low confidence, shown as such) ---
124
+ dict(from_canon="lion", to_canon="bnb_8bit", relation="DEGRADES", tier=3,
125
+ fix="Lion sign-update interacts poorly with 8-bit state quant — drop to 16-bit moments.",
126
+ evidence=_ev("https://github.com/bitsandbytes-foundation/bitsandbytes", "single user report: Lion+8-bit moments diverged at step 4k on a 7B base.", "issue", 3)),
127
+ dict(from_canon="deepspeed_z3", to_canon="bnb_8bit", relation="DEGRADES", tier=3,
128
+ fix="Reports of slowdown / hangs on multi-node Z3 + 8-bit. Use bf16 weights, 8-bit optimizer states only.",
129
+ evidence=_ev("https://github.com/microsoft/DeepSpeed/issues", "Z3 + 8-bit weights hang on the param-gather step in some configs.", "issue", 3)),
130
+
131
+ # --- benchmark-backed performance edges (tier 1, Rick's real bench) ---
132
+ dict(from_canon="dlrs", to_canon="distilbert", relation="COMPATIBLE", tier=1,
133
+ fix="DLRS #1 on the SST-2 bench: val_loss 0.2653, val_acc 0.890, steps_to_target 266.7 (n=3 seeds).",
134
+ evidence=_ev(BENCH_URL, "DLRS leads on val_loss across 3 seeds on distilbert/sst2.", "benchmark", 1)),
135
+ dict(from_canon="onecycle", to_canon="distilbert", relation="DEGRADES", tier=1,
136
+ fix="OneCycle underperforms on the SST-2 bench: val_loss 0.4284 vs cohort cutoff 0.4022.",
137
+ evidence=_ev(BENCH_URL, "OneCycle val_loss 0.4284 is above the cohort cutoff 0.4022.", "benchmark", 1)),
138
+
139
+ # --- positive/compatible edges (so the graph isn't all conflict) ---
140
+ dict(from_canon="lora", to_canon="bnb_8bit", relation="COMPATIBLE", tier=2),
141
+ dict(from_canon="lora", to_canon="bnb_4bit", relation="COMPATIBLE", tier=1),
142
+ dict(from_canon="grad_ckpt", to_canon="fsdp", relation="COMPATIBLE", tier=1),
143
+ dict(from_canon="grad_ckpt", to_canon="qlora", relation="COMPATIBLE", tier=1),
144
+ dict(from_canon="cosine", to_canon="adamw", relation="COMPATIBLE", tier=1),
145
+ dict(from_canon="dlrs", to_canon="adamw", relation="COMPATIBLE", tier=1),
146
+ dict(from_canon="fsdp", to_canon="llama3", relation="COMPATIBLE", tier=1),
147
+ dict(from_canon="qlora", to_canon="llama3", relation="COMPATIBLE", tier=1),
148
+ dict(from_canon="qlora", to_canon="mistral", relation="COMPATIBLE", tier=1),
149
+ dict(from_canon="qlora", to_canon="qwen2", relation="COMPATIBLE", tier=1),
150
+ dict(from_canon="lora", to_canon="distilbert", relation="COMPATIBLE", tier=1),
151
+ dict(from_canon="vllm", to_canon="llama3", relation="COMPATIBLE", tier=1),
152
+ dict(from_canon="vllm", to_canon="mistral", relation="COMPATIBLE", tier=1),
153
+ dict(from_canon="deepspeed_z3", to_canon="fft", relation="COMPATIBLE", tier=1),
154
+ dict(from_canon="fsdp", to_canon="fft", relation="COMPATIBLE", tier=1),
155
+ dict(from_canon="muon", to_canon="llama3", relation="COMPATIBLE", tier=2),
156
  ]
157
 
158
+ # Unverified ecosystem claims — proposed, NOT asserted. Sit in review_queue.
 
159
  REVIEW = [
160
+ dict(raw_a="sophia", raw_b="bnb_8bit", relation="DEGRADES",
161
+ conditions={"note": "Sophia-G + 8-bit state single forum mention, unverified."}, evidence_url=""),
162
+ dict(raw_a="adafactor", raw_b="lora", relation="COMPATIBLE",
163
+ conditions={"note": "Commonly paired but no canonical source captured yet."}, evidence_url=""),
 
 
164
  ]
165
 
166
  # Rick's LR-scheduler benchmark leaderboard. DistilBERT / SST-2, 3 seeds each.
167
+ # (scheduler, val_loss_mean, val_loss_std, val_acc_mean, val_acc_std, steps_to_target)
168
  BENCH_MODEL, BENCH_TASK = "distilbert-base-uncased", "glue/sst2"
169
  BENCH_CONDITIONS = {"batch_size": 32, "num_epochs": 3, "lr": 2e-5, "weight_decay": 0.01,
170
  "warmup_fraction": 0.06, "target_loss": 0.35}