Views
No views yet
| System | Overall | Easy (41) | Medium (37) |
|---|---|---|---|
| Base Qwen2.5-Coder-32B-Instruct | 14.10% (11/78) | 21.95% | 5.41% |
| + SFT fine-tuning | 19.23% (15/78) | 24.39% | 13.51% |
| + RL GRPO v2 (this adapter) | 29.49% (23/78) | 36.59% | 21.62% |
| + Agentic loop v10 (Qwen+Sonnet reflector) | 53.85% (42/78) | 70.73% | 35.14% |
| Final system (agentic v10+v11 cherry-pick) | 58.97% (46/78) | 75.61% | 40.54% |
| Claude Sonnet 4.6 standalone (baseline) | 55.13% (43/78) | — | — |
shailja/Verilog_GitHub (~7,500 validated Verilog modules)1import torch
2from transformers import AutoTokenizer, AutoModelForCausalLM
3from peft import PeftModel
4
5base_model_id = "Qwen/Qwen2.5-Coder-32B-Instruct"
6adapter_id = "Noahsabb/spec2rtl-qwen32b-lora-rl-v2"
7
8# Load base model in bf16 (requires ~65GB VRAM — fits a single H100 or A100 80GB)
9tokenizer = AutoTokenizer.from_pretrained(adapter_id) # tokenizer is included in adapter repo
10model = AutoModelForCausalLM.from_pretrained(
11 base_model_id,
12 torch_dtype=torch.bfloat16,
13 low_cpu_mem_usage=True,
14)
15model = PeftModel.from_pretrained(model, adapter_id)
16model = model.merge_and_unload() # merge LoRA into base for faster inference
17model = model.to("cuda:0")
18model.eval()1spec = """
2## Specification
3
4Design a synchronous 4-bit up-counter with active-high reset.
5- Inputs: clk (clock), rst (synchronous reset, active high), en (count enable)
6- Outputs: count [3:0] (counter value)
7- Behavior: On rising clock edge, if rst is high, count resets to 0.
8 If en is high and rst is low, count increments by 1, wrapping from 15 to 0.
9"""
10
11prompt = f"Generate synthesizable Verilog RTL for the following specification.\n\n{spec}"
12messages = [{"role": "user", "content": prompt}]
13
14text = tokenizer.apply_chat_template(
15 messages,
16 tokenize=False,
17 add_generation_prompt=True,
18)
19inputs = tokenizer(text, return_tensors="pt").to("cuda:0")
20
21with torch.no_grad():
22 outputs = model.generate(
23 **inputs,
24 max_new_tokens=2048,
25 temperature=0.2,
26 do_sample=True,
27 pad_token_id=tokenizer.eos_token_id,
28 )
29
30generated = tokenizer.decode(
31 outputs[0][inputs["input_ids"].shape[1]:],
32 skip_special_tokens=True,
33)
34print(generated)merge_and_unload() and use the adapter directly without merging. The model will use slightly more memory during inference but avoids the merge overhead.1@misc{spec2rtl2026,
2 author = {Sabbavarapu, Noah},
3 title = {Spec2RTL: Fine-tuned Qwen2.5-Coder-32B + Agentic Self-Correction for Verilog RTL Generation},
4 year = {2026},
5 url = {https://github.com/Noahsabb/spec2RTL}
6}