AbijahKaj/qwen3.5-4b-kicad-netlist
Qwen3.5-4B KiCad Netlist Generator
Fine-tuned Qwen/Qwen3.5-4B to generate valid KiCad s-expression netlists from natural language circuit descriptions — with optional tool-calling to look up real component data at inference time.
Continuation of [AbijahKaj/qwen3-4b-kicad-netlist](https://huggingface.co/AbijahKaj/qwen3-4b-kicad-netlist) on the newer Qwen3.5 architecture (hybrid GatedDeltaNet + FullAttention).
⚠️ Pending retraining on v2 dataset. The current adapter was trained on v1 dataset (137 examples, many without proper nets). The v2 dataset has 28,702 examples with proper(netssections + 285 tool-augmented examples with bothsearch_componentandget_datasheet_infotools. Seetrain.pyfor the ready-to-run training script.
What It Does
Given a description like "Design an RP2040 flight controller with IMU, barometer, USB-C, and SWD debug", this model:
- Identifies all required components (MCU, sensors, regulators, connectors, passives)
- (Optional) Calls tools to look up component pinouts, footprints, and reference circuits from real databases
- Generates a complete KiCad netlist with all electrical connections, power nets, decoupling caps, and proper pin assignments
Two Modes of Operation
Quick Start
Direct Generation (no tools)
import torch
from transformers import Qwen3_5ForConditionalGeneration, AutoTokenizer, BitsAndBytesConfig
from peft import PeftModel
BASE_MODEL = "Qwen/Qwen3.5-4B"
ADAPTER = "AbijahKaj/qwen3.5-4b-kicad-netlist"
bnb_config = BitsAndBytesConfig(
load_in_4bit=True, bnb_4bit_quant_type="nf4", bnb_4bit_compute_dtype=torch.bfloat16,
)
base_model = Qwen3_5ForConditionalGeneration.from_pretrained(BASE_MODEL, quantization_config=bnb_config, device_map="auto")
model = PeftModel.from_pretrained(base_model, ADAPTER)
model.eval()
tokenizer = AutoTokenizer.from_pretrained(ADAPTER)
messages = [
{"role": "system", "content": "You are an expert electronics engineer and KiCad schematic designer. When given a description of an electronic circuit or system, you generate a complete, valid KiCad netlist in s-expression format."},
{"role": "user", "content": "Design an RP2040-based flight controller with ICM-42688-P IMU on SPI, BMP388 barometer on I2C, 4 PWM motor outputs, USB-C, QSPI flash, and SWD debug header."}
]
text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True, enable_thinking=False)
inputs = tokenizer(text, return_tensors="pt").to(model.device)
with torch.no_grad():
outputs = model.generate(**inputs, max_new_tokens=8192, temperature=0.3, top_p=0.9, do_sample=True)
netlist = tokenizer.decode(outputs[0][inputs["input_ids"].shape[-1]:], skip_special_tokens=True)
print(netlist)Agentic Mode (with tool calling)
See `inference_agent.py` for a full agent implementation that:
- Runs a multi-turn generate → tool call → tool result → generate loop
- Connects to real APIs (Nexar/Octopart, LCSC) for component lookup
- Falls back to a local KiCad library index for offline use
python inference_agent.py "Design an ESP32-S3 IoT gateway with W5500 Ethernet and CAN bus"Important: UseQwen3_5ForConditionalGeneration— notAutoModelForCausalLM. Qwen3.5 is a multimodal model class; using the wrong loader will produce incorrect weight mappings.
Supported Circuit Types
Architecture: Why Qwen3.5 Is Different
Qwen3.5-4B is a hybrid model — not a standard transformer:
Layer Pattern: [GatedDeltaNet, GatedDeltaNet, GatedDeltaNet, FullAttention] × 8
\_______________ 24 layers ________________/ \__ 8 layers __/LoRA Target Modules
target_modules = [
# FullAttention layers (8 layers: 3, 7, 11, 15, 19, 23, 27, 31)
"q_proj", "k_proj", "v_proj", "o_proj",
# GatedDeltaNet layers (24 layers)
"in_proj_a", "in_proj_b", "in_proj_qkv", "in_proj_z", "out_proj",
# MLP (all 32 layers)
"gate_proj", "up_proj", "down_proj",
]
exclude_modules = r".*\b(visual|mtp)\b.*"⚠️ GatedDeltaNet modules arein_proj_a,in_proj_b, etc. — NOTin_proj. PEFT usesendswithmatching, so"in_proj"would match nothing.
Dataset
The v2 dataset contains:
- 28,702 direct-generation examples with proper
(netssections — converted from real.kicad_schschematics from ~6,000 GitHub repos plus synthetic circuits (CM4/CM5 carriers, flight controllers, IoT nodes, CAN bus, etc.) - 285 tool-augmented examples with both
search_component(1,741 calls) andget_datasheet_info(285 calls) tools - 100% have nets, 93% have GND, ~86% have power nets, avg 80 nets per example
Dataset generation scripts are in the dataset repo.
Tool Calling
Two tools available via Qwen-format tool calling:
Connecting Real Backends
See `inference_agent.py` for implementation with all three backends.
ERC Validation
The included erc_validator.py (v2) validates generated netlists:
python erc_validator.py output_netlist.kicad_netTraining
Current Adapter (V1 — pre-v2 dataset)
Trained on v1 dataset (137 examples). Small dataset, nets generation limited.
Next: V2 (v2 dataset — ready to train)
train.py is updated for the v2 dataset (28.7K + 285 tool-augmented):
- Inline ERC v2 with stricter net quality scoring
- 3 epochs (dataset is 200× larger now)
- Both
search_componentandget_datasheet_infotools in chat template - Loads both
train.jsonlandtrain_tool_augmented.jsonl
Training Recipe Sources
Repository Contents
Compared to Qwen3-4B Version
Limitations
- Current adapter: Trained on small v1 dataset. Retraining on v2 will significantly improve quality.
- Component coverage: Limited to components seen during training. Use tool-calling mode for unseen ICs.
- Pin accuracy: Direct generation may hallucinate pin numbers. Tool-augmented mode is more reliable.
- Complexity ceiling: Best results on circuits with <100 components.
- No PCB layout: Generates netlists only, not physical PCB layouts.
Tips
- Be specific: Include IC part numbers, bus types (SPI/I2C/UART), and pin assignments
- Use tool-calling mode for uncommon components
- Temperature 0.3: Low temperature produces more consistent, valid netlists
- Validate output: Always run
erc_validator.pyon generated netlists - Disable thinking: Use
enable_thinking=Falsefor direct output - Use the right model class:
Qwen3_5ForConditionalGeneration, NOTAutoModelForCausalLM
License
Apache 2.0 (same as base model Qwen/Qwen3.5-4B)
