|
|
--- |
|
|
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 |
|
|
|
|
|
|