204 lines
11 KiB
Markdown
204 lines
11 KiB
Markdown
---
|
|
license: mit
|
|
base_model: Qwen/Qwen2.5-Coder-7B-Instruct
|
|
tags:
|
|
- text-to-cad
|
|
- cad
|
|
- 3d-modeling
|
|
- parametric
|
|
- lora
|
|
- qwen2
|
|
language:
|
|
- en
|
|
library_name: transformers
|
|
pipeline_tag: text-generation
|
|
---
|
|
|
|
# cad0
|
|
|
|
**cad0** is a fine-tuned language model for text-to-CAD generation. Given a natural
|
|
language description of a mechanical part, it generates [Compact
|
|
IR](https://github.com/ecto/vcad) — a token-efficient domain-specific
|
|
language for parametric 3D geometry.
|
|
|
|
## Demo
|
|
|
|
Try it: [**cad0-demo on HuggingFace
|
|
Spaces**](https://huggingface.co/spaces/campedersen/cad0-demo)
|
|
|
|
For browser/offline use:
|
|
[**cad0-mini**](https://huggingface.co/campedersen/cad0-mini) (0.5B, ONNX quantized)
|
|
|
|
## What It Does
|
|
|
|
```
|
|
Input: "50x30mm mounting plate with 4 corner holes"
|
|
Output: C 50 30 5
|
|
Y 2.5 10
|
|
T 1 5 5 0
|
|
D 0 2
|
|
...
|
|
```
|
|
|
|
The Compact IR output can be parsed and evaluated by the [vcad
|
|
kernel](https://github.com/ecto/vcad) to produce editable parametric
|
|
geometry.
|
|
|
|
## Supported Part Types
|
|
|
|
| Family | Examples |
|
|
|--------|----------|
|
|
| Bracket | L-brackets, Z-brackets, mounting plates |
|
|
| Standoff | Cylindrical spacers, threaded standoffs |
|
|
| Enclosure | Boxes, vented enclosures, rounded shells |
|
|
| Gear | Spur gears, hubs |
|
|
| Flange | Bolt circles, blind flanges |
|
|
| Clip | Snap clips, spring clips |
|
|
|
|
## Usage
|
|
|
|
### With Transformers + PEFT
|
|
|
|
```python
|
|
from transformers import AutoModelForCausalLM, AutoTokenizer
|
|
from peft import PeftModel
|
|
|
|
base_model = AutoModelForCausalLM.from_pretrained(
|
|
"Qwen/Qwen2.5-Coder-7B-Instruct",
|
|
torch_dtype="auto",
|
|
device_map="auto"
|
|
)
|
|
model = PeftModel.from_pretrained(base_model, "campedersen/cad0")
|
|
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-Coder-7B-Instruct")
|
|
|
|
prompt = "50x30mm mounting plate with 4 corner holes"
|
|
messages = [{"role": "user", "content": prompt}]
|
|
text = tokenizer.apply_chat_template(messages, tokenize=False,
|
|
add_generation_prompt=True)
|
|
|
|
inputs = tokenizer(text, return_tensors="pt").to(model.device)
|
|
outputs = model.generate(**inputs, max_new_tokens=256, temperature=0.1,
|
|
do_sample=True)
|
|
ir = tokenizer.decode(outputs[0][inputs.input_ids.shape[1]:],
|
|
skip_special_tokens=True)
|
|
print(ir)
|
|
```
|
|
|
|
### API Endpoint
|
|
|
|
```
|
|
curl -X POST https://ecto--cad0-training-inference-infer.modal.run \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"prompt": "L-bracket with mounting holes", "temperature": 0.1}'
|
|
```
|
|
|
|
## Compact IR Reference
|
|
|
|
```
|
|
┌──────────────┬──────────────┬──────────────────────────────────┐
|
|
│ Op │ Syntax │ Description │
|
|
├──────────────┼──────────────┼──────────────────────────────────┤
|
|
│ Cube │ C x y z │ Box with dimensions x, y, z (mm) │
|
|
├──────────────┼──────────────┼──────────────────────────────────┤
|
|
│ Cylinder │ Y r h │ Cylinder with radius r, height h │
|
|
├──────────────┼──────────────┼──────────────────────────────────┤
|
|
│ Sphere │ S r │ Sphere with radius r │
|
|
├──────────────┼──────────────┼──────────────────────────────────┤
|
|
│ Cone │ K r1 r2 h │ Cone/frustum │
|
|
├──────────────┼──────────────┼──────────────────────────────────┤
|
|
│ Translate │ T n x y z │ Move node n by offset │
|
|
├──────────────┼──────────────┼──────────────────────────────────┤
|
|
│ Rotate │ R n rx ry rz │ Rotate node n (degrees) │
|
|
├──────────────┼──────────────┼──────────────────────────────────┤
|
|
│ Scale │ X n sx sy sz │ Scale node n │
|
|
├──────────────┼──────────────┼──────────────────────────────────┤
|
|
│ Union │ U a b │ Boolean union │
|
|
├──────────────┼──────────────┼──────────────────────────────────┤
|
|
│ Difference │ D a b │ Boolean subtraction │
|
|
├──────────────┼──────────────┼──────────────────────────────────┤
|
|
│ Intersection │ I a b │ Boolean intersection │
|
|
├──────────────┼──────────────┼──────────────────────────────────┤
|
|
│ Shell │ SH n t │ Hollow out with wall thickness t │
|
|
├──────────────┼──────────────┼──────────────────────────────────┤
|
|
│ Fillet │ F n r │ Round edges with radius r │
|
|
├──────────────┼──────────────┼──────────────────────────────────┤
|
|
│ Chamfer │ CH n d │ Bevel edges with distance d │
|
|
└──────────────┴──────────────┴──────────────────────────────────┘
|
|
```
|
|
|
|
Nodes are 0-indexed; each line creates a new node.
|
|
|
|
## Training
|
|
|
|
```
|
|
┌───────────────────┬───────────────────────────┐
|
|
│ Parameter │ Value │
|
|
├───────────────────┼───────────────────────────┤
|
|
│ Base model │ Qwen2.5-Coder-7B-Instruct │
|
|
├───────────────────┼───────────────────────────┤
|
|
│ Method │ QLoRA (4-bit NF4) │
|
|
├───────────────────┼───────────────────────────┤
|
|
│ LoRA rank │ 64 │
|
|
├───────────────────┼───────────────────────────┤
|
|
│ LoRA alpha │ 128 │
|
|
├───────────────────┼───────────────────────────┤
|
|
│ Training examples │ 530,531 │
|
|
├───────────────────┼───────────────────────────┤
|
|
│ Epochs │ 1 │
|
|
├───────────────────┼───────────────────────────┤
|
|
│ Batch size │ 64 (effective) │
|
|
├───────────────────┼───────────────────────────┤
|
|
│ Learning rate │ 2e-4 (cosine) │
|
|
├───────────────────┼───────────────────────────┤
|
|
│ Hardware │ 1x NVIDIA H100 80GB │
|
|
├───────────────────┼───────────────────────────┤
|
|
│ Training time │ 9h 15m │
|
|
└───────────────────┴───────────────────────────┘
|
|
```
|
|
|
|
## Evaluation
|
|
|
|
```
|
|
┌──────────────────────────┬───────────────────────────┐
|
|
│ Metric │ Value │
|
|
├──────────────────────────┼───────────────────────────┤
|
|
│ Final eval loss │ 0.324 │
|
|
├──────────────────────────┼───────────────────────────┤
|
|
│ In-distribution accuracy │ 75% │
|
|
├──────────────────────────┼───────────────────────────┤
|
|
│ Out-of-distribution │ Limited (see Limitations) │
|
|
└──────────────────────────┴───────────────────────────┘
|
|
```
|
|
|
|
## Limitations
|
|
|
|
- Training bias: May add features (holes, fillets) to simple primitives — training
|
|
data weighted toward complex manufactured parts
|
|
- Dimension ambiguity: Occasionally confuses radius vs diameter for cylinders
|
|
- Limited primitives: No native hexagon support; hex shapes require boolean
|
|
workarounds
|
|
- OOD generalization: Struggles with part types not in training distribution
|
|
|
|
## Related
|
|
|
|
- https://github.com/ecto/vcad — Open-source parametric CAD with custom BRep
|
|
kernel
|
|
- https://vcad.io — Web app with cad0 integration
|
|
- https://huggingface.co/campedersen/cad0-mini — 0.5B distilled model for browser
|
|
inference
|
|
|
|
## Citation
|
|
|
|
@misc{cad0,
|
|
author = {Cam Pedersen},
|
|
title = {cad0: Text-to-CAD Language Model},
|
|
year = {2026},
|
|
publisher = {HuggingFace},
|
|
url = {https://huggingface.co/campedersen/cad0}
|
|
}
|
|
|
|
## License
|
|
|
|
MIT
|
|
|