Skip to content

Generate kernel-aware NAS candidates#110

Merged
peaktwilight merged 1 commit into
mainfrom
feat/nas-candidate-generation
May 24, 2026
Merged

Generate kernel-aware NAS candidates#110
peaktwilight merged 1 commit into
mainfrom
feat/nas-candidate-generation

Conversation

@Darkroom4364

@Darkroom4364 Darkroom4364 commented May 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • add generate_nas_candidates for hidden width, head_dim, GQA ratio, FFN ratio, window size, and QK-norm placement
  • skip invalid head/KV combinations and align generated FFN dimensions to matmul tile boundaries
  • rank the generated 2B-class candidate space in scripts/nas_experiment.py
  • document the generated candidate-search path for Kernel-aware architecture search: use kernel perf data to design models #81

Refs #81

Tests

  • python3 -m unittest tests.test_arch_cost_model
  • python3 -m unittest tests.test_arch_cost_model tests.test_cli tests.test_ci_local_script
  • python3 scripts/nas_experiment.py --hardware a100
  • python3 scripts/nas_experiment.py --hardware t4
  • python3 scripts/nas_experiment.py --hardware h100
  • python3 -m py_compile src/research_engine/arch_cost_model.py scripts/nas_experiment.py tests/test_arch_cost_model.py
  • git diff --cached --check

Note: ruff is not installed locally.

Summary by CodeRabbit

  • New Features

    • Added neural architecture search capability to automatically generate and rank transformer architecture candidates based on performance metrics, including latency and efficiency measurements.
  • Documentation

    • Updated research documentation to describe the candidate generation process and ranking methodology.
  • Tests

    • Added comprehensive tests for NAS candidate generation and ranking functionality.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 23, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@Darkroom4364, we couldn't start this review because you've used your available PR reviews for now.

Your plan currently allows 1 review/hour. Refill in 56 minutes and 30 seconds.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more review capacity refills, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than trial, open-source, and free plans. In all cases, review capacity refills continuously over time.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 67be4b11-be4b-41a8-b3da-ff4065aa011a

📥 Commits

Reviewing files that changed from the base of the PR and between fb4c1fb and d783032.

📒 Files selected for processing (4)
  • docs/research/kernel-aware-nas.md
  • scripts/nas_experiment.py
  • src/research_engine/arch_cost_model.py
  • tests/test_arch_cost_model.py
📝 Walkthrough

Walkthrough

This PR introduces kernel-aware NAS candidate generation, adding a generate_nas_candidates() function that sweeps over architectural hyperparameters (hidden size, head size, FFN ratio, KV heads, window size, QK-norm placement) to explore a compact search space. The experiment script integrates the generator, ranks candidates by latency and efficiency, and prints a top-N summary. Tests validate generation correctness and rankability; documentation clarifies the approach and next steps.

Changes

Kernel-aware NAS candidate generation and ranking

Layer / File(s) Summary
NAS candidate generator implementation
src/research_engine/arch_cost_model.py
Adds _round_up_to_multiple() and _format_ratio() helpers, plus generate_nas_candidates() which sweeps over hidden dims, head dims, FFN ratios, KV head counts, sliding window sizes, and QK-norm options; de-duplicates candidates by name and shape; enforces tile alignment on FFN; skips invalid head/KV combinations.
NAS experiment script integration
scripts/nas_experiment.py
Imports generate_nas_candidates, adds generated_candidate_configs() to build a base 2B config and expand it via hyperparameter sweep, adds run_generated_search() to rank generated candidates and format top-N output with latency, efficiency metric, and bottleneck label, wires search into main() after comparison run.
Tests and documentation
tests/test_arch_cost_model.py, docs/research/kernel-aware-nas.md
Test suite adds import, two methods to verify candidate generation produces unique architecturally valid configs with expected knob combinations and that they rank via ArchitectureCostModel.rank_configs(), and one test asserting run_generated_search prints formatted top-N output. Documentation expands "Current implementation" section, adds "What this answers" question about fastest-ranking candidates, and updates "Next steps" to require JSON artifact emission.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • 0sec-labs/noeris#105: Adds or modifies ArchitectureCostModel.rank_configs() and tile-penalty outputs in the cost model, which this PR directly calls to rank generated NAS candidates.
  • 0sec-labs/noeris#108: Extends scripts/nas_experiment.py and main() to emit JSON reports and CLI output, building on top of the generated-candidate ranking added in this PR.

Poem

🐰 A rabbit hops through hidden states,
Sweeping heads and ratios wide—
Which config runs the fastest race?
Generated candidates ranked with pride!
From base to search, the NAS takes flight. 🏃‍♂️✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 29.41% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Generate kernel-aware NAS candidates' directly matches the main objective of the pull request: adding a new function to generate kernel-aware NAS candidates across multiple architectural dimensions.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/nas-candidate-generation

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Darkroom4364 Darkroom4364 force-pushed the feat/nas-candidate-generation branch from fb4c1fb to d783032 Compare May 23, 2026 08:49

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/research_engine/arch_cost_model.py`:
- Around line 131-145: The current use of truthy fallbacks (e.g., hidden_dims =
hidden_dims or [base_config["hidden_dim"]]) hides explicit empty-sweep lists and
the tile_multiple parameter can cause a ZeroDivisionError when <= 0; change each
fallback to use "is None" checks so empty lists are preserved (e.g., if
hidden_dims is None: hidden_dims = [...]) for hidden_dims, head_dims,
ffn_ratios, kv_head_counts, window_sizes, and qk_norm_options, and add
validation for tile_multiple at the start (raise a ValueError if tile_multiple
is <= 0) so downstream code that divides by tile_multiple cannot error
unpredictably.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 06052804-503c-45b3-8161-aa7b46400b62

📥 Commits

Reviewing files that changed from the base of the PR and between ceb6499 and fb4c1fb.

📒 Files selected for processing (4)
  • docs/research/kernel-aware-nas.md
  • scripts/nas_experiment.py
  • src/research_engine/arch_cost_model.py
  • tests/test_arch_cost_model.py

Comment on lines +131 to +145
tile_multiple: int = MATMUL_TILE_SIZE,
max_candidates: int | None = None,
) -> list[dict[str, Any]]:
"""Generate tile-aligned transformer architecture candidates.

The search varies dimensions that are natural handles for kernel-aware NAS:
hidden width, attention head width, GQA ratio, FFN expansion, sliding-window
attention, and QK-norm placement. Invalid combinations are skipped.
"""
hidden_dims = hidden_dims or [base_config["hidden_dim"]]
head_dims = head_dims or [64, 128, 256]
ffn_ratios = ffn_ratios or [3.0, 4.0, 5.333]
kv_head_counts = kv_head_counts or [1, 2, 4, 8]
window_sizes = window_sizes or [base_config.get("window_size"), None]
qk_norm_options = qk_norm_options or [base_config.get("use_qk_norm", True), False]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Handle explicit empty sweeps and invalid tile_multiple deterministically.

Line 140-145 currently uses truthy fallback (or), so explicit empty lists are ignored and silently replaced by defaults. Also, Line 160 can raise ZeroDivisionError when tile_multiple <= 0. Please validate the argument and switch to is None defaults.

Suggested patch
 def generate_nas_candidates(
@@
 ) -> list[dict[str, Any]]:
@@
-    hidden_dims = hidden_dims or [base_config["hidden_dim"]]
-    head_dims = head_dims or [64, 128, 256]
-    ffn_ratios = ffn_ratios or [3.0, 4.0, 5.333]
-    kv_head_counts = kv_head_counts or [1, 2, 4, 8]
-    window_sizes = window_sizes or [base_config.get("window_size"), None]
-    qk_norm_options = qk_norm_options or [base_config.get("use_qk_norm", True), False]
+    if tile_multiple <= 0:
+        raise ValueError("tile_multiple must be > 0")
+
+    hidden_dims = [base_config["hidden_dim"]] if hidden_dims is None else hidden_dims
+    head_dims = [64, 128, 256] if head_dims is None else head_dims
+    ffn_ratios = [3.0, 4.0, 5.333] if ffn_ratios is None else ffn_ratios
+    kv_head_counts = [1, 2, 4, 8] if kv_head_counts is None else kv_head_counts
+    window_sizes = [base_config.get("window_size"), None] if window_sizes is None else window_sizes
+    qk_norm_options = [base_config.get("use_qk_norm", True), False] if qk_norm_options is None else qk_norm_options

Also applies to: 160-160

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/research_engine/arch_cost_model.py` around lines 131 - 145, The current
use of truthy fallbacks (e.g., hidden_dims = hidden_dims or
[base_config["hidden_dim"]]) hides explicit empty-sweep lists and the
tile_multiple parameter can cause a ZeroDivisionError when <= 0; change each
fallback to use "is None" checks so empty lists are preserved (e.g., if
hidden_dims is None: hidden_dims = [...]) for hidden_dims, head_dims,
ffn_ratios, kv_head_counts, window_sizes, and qk_norm_options, and add
validation for tile_multiple at the start (raise a ValueError if tile_multiple
is <= 0) so downstream code that divides by tile_multiple cannot error
unpredictably.

@peaktwilight peaktwilight merged commit d28b4e6 into main May 24, 2026
2 checks passed
@peaktwilight peaktwilight deleted the feat/nas-candidate-generation branch May 24, 2026 19:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants