Qwen3 4b Skidl
A fine-tune of Qwen/Qwen3-4B for generating executable SKiDL Python netlists from natural-language circuit descriptions. Given a description like "ESP32 board with BME280 on I2C and USB-C", the model outputs valid...
Fonte do modelo
- Tipo
- LoRA
- Tamanho do arquivo
- 504 MB–7,49 GB
- Modelo base
- Qwen/Qwen3-4B
- Versão
- vRevision 69f2dbf
- Atualizado
- 2 de out. de 2026
- Publicador
- @AbijahKaj
- Downloads
- 241
- Parâmetros
- 4B
- Tarefas
- Geração de texto
- Fonte
- Hugging Face
Descrição da fonte
qwen3-4b-skidl
A fine-tune of Qwen/Qwen3-4B for generating executable SKiDL Python netlists from natural-language circuit descriptions. Given a description like "ESP32 board with BME280 on I2C and USB-C", the model outputs valid Python using Part(), Net(), and generate_netlist() — producing a .net file KiCad can open directly.
Blog post: Teaching a Small LLM to Design Electronic Circuits: Fine-Tuning Qwen3-4B on 100K KiCad Netlists
This repo has two branches:
| Branch | Contents | Size | Use |
|---|---|---|---|
main (this) | Merged weights — LoRA baked into base | 7.5 GB | Load directly, no base model needed |
lora | Adapter only | 504 MB | Lightweight; load on top of Qwen3-4B |
Quick start
Merged (main branch — recommended)
from transformers import AutoModelForCausalLM, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained(
"AbijahKaj/qwen3-4b-skidl",
dtype="auto",
device_map="auto",
)
tokenizer = AutoTokenizer.from_pretrained("AbijahKaj/qwen3-4b-skidl")
LoRA adapter (lora branch)
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel
base = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-4B", dtype="auto", device_map="auto")
tokenizer = AutoTokenizer.from_pretrained("AbijahKaj/qwen3-4b-skidl", revision="lora")
model = PeftModel.from_pretrained(base, "AbijahKaj/qwen3-4b-skidl", revision="lora")
Generating a circuit
SYSTEM = (
"You are an expert electronics engineer and KiCad schematic designer. "
"When given a description of an electronic circuit, generate executable "
"SKiDL Python code that defines the circuit using the SKiDL library."
)
messages = [
{"role": "system", "content": SYSTEM},
{"role": "user", "content": "Design a CAN bus interface using MCP2515 controller and TJA1050 transceiver on SPI, with 120 ohm termination resistor."},
]
text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
inputs = tokenizer(text, return_tensors="pt").to(model.device)
out = model.generate(**inputs, max_new_tokens=1024, do_sample=False)
print(tokenizer.decode(out[0][inputs.input_ids.shape[1]:], skip_special_tokens=True))
Training
| Base model | Qwen/Qwen3-4B |
| Method | SFT + LoRA |
| Dataset | AbijahKaj/kicad-netlist-sft-dataset — 100,179 SKiDL Python circuit examples |
| LoRA rank / alpha | r=64, α=32, dropout=0.05 |
| Target modules | q/k/v/o_proj, gate/up/down_proj |
| Epochs | 2 |
| Peak LR | 2e-4 (cosine decay) |
| Effective batch | 8 |
| Max length | 8192 tokens |
| Trainable params | ~132M (5.65% of 4B) |
Loss curve
| Phase | Train loss | Token accuracy |
|---|---|---|
| Start | 0.86 | 75% |
| Epoch 1 end | 0.17 | 95% |
| Epoch 2 end | 0.15 | 95–96% |
| Eval loss (final) | 0.1581 | 95.3% |
SKiDL validation (final checkpoint)
Functional scoring across 5 held-out circuits: Python syntax + SKiDL import + net count + part count + connectivity + GND checks.
| Circuit | Score |
|---|---|
| LED blink — ATtiny85 | 0.85 |
| USB power meter — ATmega328P + INA219 | 0.85 |
| CAN bus — MCP2515 + TJA1050 | 0.95 |
| Average | 0.883 |
Why SKiDL?
KiCad's native s-expression netlist is deeply nested and pathological for LLMs. PCBSchemaGen (arXiv:2602.00510) shows SKiDL Python achieves 87% Pass@1 with GPT-4o on circuit generation — because Python-based HDLs align with LLM pretraining data and are 3× more compact than s-expressions.
Dataset
AbijahKaj/kicad-netlist-sft-dataset — 100,179 ChatML examples:
| Source | Count |
|---|---|
| Si7li/ltspice-spice-circuits (LTspice → SKiDL) | ~54,000 |
bshada/open-schematics (GitHub .kicad_sch files) | ~45,000 |
| Ashed00/SPICE-Circuits | ~800 |
| Synthetic + tool-augmented | ~308 |
References
Fontes
1 fonte
Fontes
1 fonteVerificado 2 de out.
Artefatos de modelo
2 artefatos
Artefatos de modelo
2 artefatosTrechos de fonte
3 trechos
Trechos de fonte
3 trechos--- base_model: Qwen/Qwen3-4B datasets: - AbijahKaj/kicad-netlist-sft-dataset language: - en license: apache-2.0 library_name: transformers tags: - electronics - kicad - netlist - schematic - eda - circuit-design - skidl - pcb - trl - sft - peft - lora --- # qwen3-4b-skidl A fine-tune of [Qwen/Qwen3-4B](https://huggingface.co/Qwen/Qwen3-4B) for generating **executable SKiDL Python netlists** from natural-language circuit descriptions. Given a description like *"ESP32 board with BME280 on I2C and USB-C"*, the model outputs valid Python using `Part()`, `Net()`, and `generate_netlist()` — producing a `.net` file KiCad can open directly. **Blog post:** [Teaching a Small LLM to Design Electronic Circuits: Fine-Tuning Qwen3-4B on 100K KiCad Netlists](https://blog.abijah.me/teaching-a-small-llm-to-design-electronic-circuits-fine-tuning-qwen3-4b-on-100k-kicad-netlists) This repo has two branches: | Branch | Contents | Size | Use | |---|---|---|---| | **`main`** (this) | Merged weights — LoRA baked into base | 7.5 GB | Load directly, no base model needed | | [`lora`](https://huggingface.co/AbijahKaj/qwen3-4b-skidl/tree/lora) | Adapter only | 504 MB | Lightweight; load on top of Qwen3-4B | ## Quick start ### Merged (main branch — recommended) ```python from transformers import AutoModelForCausalLM, AutoTokenizer model = AutoModelForCausalLM.from_pretrained( "AbijahKaj/qwen3-4b-skidl", dtype="auto", device_map="auto", ) tokenizer = AutoTokenizer.from_pretrained("AbijahKaj/qwen3-4b-skidl") ``` ### LoRA adapter (lora branch) ```python from transformers import AutoModelForCausalLM, AutoTokenizer from peft import PeftModel base = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-4B", dtype="auto", device_map="auto") tokenizer = AutoTokenizer.from_pretrained("AbijahKaj/qwen3-4b-skidl", revision="lora") model = PeftModel.from_pretrained(base, "AbijahKaj/qwen3-4b-skidl", revision="lora") ``` ### Generating a circuit ```python SYSTEM = ( "You are an expert electronics engineer and KiCad schematic designer. " "When given a description of an electronic circuit, generate executable " "SKiDL Python code that defines the circuit using the SKiDL library." ) messages = [ {"role": "system", "content": SYSTEM}, {"role": "user", "content": "Design a CAN bus interface using MCP2515 controller and TJA1050 transceiver on SPI, with 120 ohm termination resistor."}, ]...
--- base_model: Qwen/Qwen3-4B datasets: - AbijahKaj/kicad-netlist-sft-dataset language: - en license: apache-2.0 library_name: transformers tags: - electronics - kicad - netlist - schematic - eda - circuit-design - skidl - pcb - trl - sft - peft - lora --- # qwen3-4b-skidl A fine-tune of [Qwen/Qwen3-4B](https://huggingface.co/Qwen/Qwen3-4B) for generating **executable SKiDL Python netlists** from natural-language circuit descriptions. Given a description like *"ESP32 board with BME280 on I2C and USB-C"*, the model outputs valid Python using `Part()`, `Net()`, and `generate_netlist()` — producing a `.net` file KiCad can open directly. This repo has two branches: | Branch | Contents | Size | Use | |---|---|---|---| | **`main`** (this) | Merged weights — LoRA baked into base | 7.5 GB | Load directly, no base model needed | | [`lora`](https://huggingface.co/AbijahKaj/qwen3-4b-skidl/tree/lora) | Adapter only | 504 MB | Lightweight; load on top of Qwen3-4B | ## Quick start ### Merged (main branch — recommended) ```python from transformers import AutoModelForCausalLM, AutoTokenizer model = AutoModelForCausalLM.from_pretrained( "AbijahKaj/qwen3-4b-skidl", dtype="auto", device_map="auto", ) tokenizer = AutoTokenizer.from_pretrained("AbijahKaj/qwen3-4b-skidl") ``` ### LoRA adapter (lora branch) ```python from transformers import AutoModelForCausalLM, AutoTokenizer from peft import PeftModel base = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-4B", dtype="auto", device_map="auto") tokenizer = AutoTokenizer.from_pretrained("AbijahKaj/qwen3-4b-skidl", revision="lora") model = PeftModel.from_pretrained(base, "AbijahKaj/qwen3-4b-skidl", revision="lora") ``` ### Generating a circuit ```python SYSTEM = ( "You are an expert electronics engineer and KiCad schematic designer. " "When given a description of an electronic circuit, generate executable " "SKiDL Python code that defines the circuit using the SKiDL library." ) messages = [ {"role": "system", "content": SYSTEM}, {"role": "user", "content": "Design a CAN bus interface using MCP2515 controller and TJA1050 transceiver on SPI, with 120 ohm termination resistor."}, ] text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True) inputs = tokenizer(text, return_tensors="pt").to(model.device) out = model.generate(**inputs, max_new_tokens=1024, do_sample=False) print(tok...
Source context: 241 downloads · 1 likes · Pipeline text-generation · Library transformers · Repo AbijahKaj/qwen3-4b-skidl
