campedersen commited on
Commit
bbc5fa5
Β·
verified Β·
1 Parent(s): 42d9e97

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +186 -185
README.md CHANGED
@@ -1,185 +1,186 @@
1
- ---
2
- license: mit
3
- base_model: Qwen/Qwen2.5-Coder-7B-Instruct
4
- tags:
5
- - text-to-cad
6
- - cad
7
- - 3d-modeling
8
- - parametric
9
- - lora
10
- - qwen2
11
- language:
12
- - en
13
- library_name: transformers
14
- pipeline_tag: text-generation
15
- ---
16
-
17
- # cad0
18
-
19
- **cad0** is a fine-tuned language model for text-to-CAD generation. Given a natural
20
- language description of a mechanical part, it generates [Compact
21
- IR](https://github.com/campedersen/vcad) β€” a token-efficient domain-specific
22
- language for parametric 3D geometry.
23
-
24
- ## Demo
25
-
26
- Try it: [**cad0-demo on HuggingFace
27
- Spaces**](https://huggingface.co/spaces/campedersen/cad0-demo)
28
-
29
- For browser/offline use:
30
- [**cad0-mini**](https://huggingface.co/campedersen/cad0-mini) (0.5B, ONNX quantized)
31
-
32
- ## What It Does
33
-
34
- Input: "50x30mm mounting plate with 4 corner holes"
35
- Output: C 50 30 5
36
- Y 2.5 10
37
- T 1 5 5 0
38
- D 0 2
39
- ...
40
-
41
- The Compact IR output can be parsed and evaluated by the [vcad
42
- kernel](https://github.com/campedersen/vcad) to produce editable parametric
43
- geometry.
44
-
45
- ## Supported Part Types
46
-
47
- | Family | Examples |
48
- |--------|----------|
49
- | Bracket | L-brackets, Z-brackets, mounting plates |
50
- | Standoff | Cylindrical spacers, threaded standoffs |
51
- | Enclosure | Boxes, vented enclosures, rounded shells |
52
- | Gear | Spur gears, hubs |
53
- | Flange | Bolt circles, blind flanges |
54
- | Clip | Snap clips, spring clips |
55
-
56
- ## Usage
57
-
58
- ### With Transformers + PEFT
59
-
60
- ```python
61
- from transformers import AutoModelForCausalLM, AutoTokenizer
62
- from peft import PeftModel
63
-
64
- base_model = AutoModelForCausalLM.from_pretrained(
65
- "Qwen/Qwen2.5-Coder-7B-Instruct",
66
- torch_dtype="auto",
67
- device_map="auto"
68
- )
69
- model = PeftModel.from_pretrained(base_model, "campedersen/cad0")
70
- tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-Coder-7B-Instruct")
71
-
72
- prompt = "50x30mm mounting plate with 4 corner holes"
73
- messages = [{"role": "user", "content": prompt}]
74
- text = tokenizer.apply_chat_template(messages, tokenize=False,
75
- add_generation_prompt=True)
76
-
77
- inputs = tokenizer(text, return_tensors="pt").to(model.device)
78
- outputs = model.generate(**inputs, max_new_tokens=256, temperature=0.1,
79
- do_sample=True)
80
- ir = tokenizer.decode(outputs[0][inputs.input_ids.shape[1]:],
81
- skip_special_tokens=True)
82
- print(ir)
83
-
84
- API Endpoint
85
-
86
- curl -X POST https://ecto--cad0-training-inference-infer.modal.run \
87
- -H "Content-Type: application/json" \
88
- -d '{"prompt": "L-bracket with mounting holes", "temperature": 0.1}'
89
-
90
- Compact IR Reference
91
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
92
- β”‚ Op β”‚ Syntax β”‚ Description β”‚
93
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
94
- β”‚ Cube β”‚ C x y z β”‚ Box with dimensions x, y, z (mm) β”‚
95
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
96
- β”‚ Cylinder β”‚ Y r h β”‚ Cylinder with radius r, height h β”‚
97
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
98
- β”‚ Sphere β”‚ S r β”‚ Sphere with radius r β”‚
99
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
100
- β”‚ Cone β”‚ K r1 r2 h β”‚ Cone/frustum β”‚
101
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
102
- β”‚ Translate β”‚ T n x y z β”‚ Move node n by offset β”‚
103
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
104
- β”‚ Rotate β”‚ R n rx ry rz β”‚ Rotate node n (degrees) β”‚
105
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
106
- β”‚ Scale β”‚ X n sx sy sz β”‚ Scale node n β”‚
107
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
108
- β”‚ Union β”‚ U a b β”‚ Boolean union β”‚
109
- ���──────────────┼──────────────┼───────────────────────────────────
110
- β”‚ Difference β”‚ D a b β”‚ Boolean subtraction β”‚
111
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
112
- β”‚ Intersection β”‚ I a b β”‚ Boolean intersection β”‚
113
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
114
- β”‚ Shell β”‚ SH n t β”‚ Hollow out with wall thickness t β”‚
115
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
116
- β”‚ Fillet β”‚ F n r β”‚ Round edges with radius r β”‚
117
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
118
- β”‚ Chamfer β”‚ CH n d β”‚ Bevel edges with distance d β”‚
119
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
120
- Nodes are 0-indexed; each line creates a new node.
121
-
122
- Training
123
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
124
- β”‚ Parameter β”‚ Value β”‚
125
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
126
- β”‚ Base model β”‚ Qwen2.5-Coder-7B-Instruct β”‚
127
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
128
- β”‚ Method β”‚ QLoRA (4-bit NF4) β”‚
129
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
130
- β”‚ LoRA rank β”‚ 64 β”‚
131
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
132
- β”‚ LoRA alpha β”‚ 128 β”‚
133
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
134
- β”‚ Training examples β”‚ 530,531 β”‚
135
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
136
- β”‚ Epochs β”‚ 1 β”‚
137
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
138
- β”‚ Batch size β”‚ 64 (effective) β”‚
139
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
140
- β”‚ Learning rate β”‚ 2e-4 (cosine) β”‚
141
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
142
- β”‚ Hardware β”‚ 1x NVIDIA H100 80GB β”‚
143
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
144
- β”‚ Training time β”‚ 9h 15m β”‚
145
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
146
- Evaluation
147
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
148
- β”‚ Metric β”‚ Value β”‚
149
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
150
- β”‚ Final eval loss β”‚ 0.324 β”‚
151
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
152
- β”‚ In-distribution accuracy β”‚ 75% β”‚
153
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
154
- β”‚ Out-of-distribution β”‚ Limited (see Limitations) β”‚
155
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
156
- Limitations
157
-
158
- - Training bias: May add features (holes, fillets) to simple primitives β€” training
159
- data weighted toward complex manufactured parts
160
- - Dimension ambiguity: Occasionally confuses radius vs diameter for cylinders
161
- - Limited primitives: No native hexagon support; hex shapes require boolean
162
- workarounds
163
- - OOD generalization: Struggles with part types not in training distribution
164
-
165
- Related
166
-
167
- - https://github.com/campedersen/vcad β€” Open-source parametric CAD with custom BRep
168
- kernel
169
- - https://vcad.io β€” Web app with cad0 integration
170
- - https://huggingface.co/campedersen/cad0-mini β€” 0.5B distilled model for browser
171
- inference
172
-
173
- Citation
174
-
175
- @misc{cad0,
176
- author = {Cam Pedersen},
177
- title = {cad0: Text-to-CAD Language Model},
178
- year = {2026},
179
- publisher = {HuggingFace},
180
- url = {https://huggingface.co/campedersen/cad0}
181
- }
182
-
183
- License
184
-
185
- MIT
 
 
1
+ ---
2
+ license: mit
3
+ base_model: Qwen/Qwen2.5-Coder-7B-Instruct
4
+ tags:
5
+ - text-to-cad
6
+ - cad
7
+ - 3d-modeling
8
+ - parametric
9
+ - lora
10
+ - qwen2
11
+ language:
12
+ - en
13
+ library_name: transformers
14
+ pipeline_tag: text-generation
15
+ ---
16
+
17
+ # cad0
18
+
19
+ **cad0** is a fine-tuned language model for text-to-CAD generation. Given a natural
20
+ language description of a mechanical part, it generates [Compact
21
+ IR](https://github.com/campedersen/vcad) β€” a token-efficient domain-specific
22
+ language for parametric 3D geometry.
23
+
24
+ ## Demo
25
+
26
+ Try it: [**cad0-demo on HuggingFace
27
+ Spaces**](https://huggingface.co/spaces/campedersen/cad0-demo)
28
+
29
+ For browser/offline use:
30
+ [**cad0-mini**](https://huggingface.co/campedersen/cad0-mini) (0.5B, ONNX quantized)
31
+
32
+ ## What It Does
33
+
34
+ Input: "50x30mm mounting plate with 4 corner holes"
35
+ Output: C 50 30 5
36
+ Y 2.5 10
37
+ T 1 5 5 0
38
+ D 0 2
39
+ ...
40
+
41
+ The Compact IR output can be parsed and evaluated by the [vcad
42
+ kernel](https://github.com/campedersen/vcad) to produce editable parametric
43
+ geometry.
44
+
45
+ ## Supported Part Types
46
+
47
+ | Family | Examples |
48
+ |--------|----------|
49
+ | Bracket | L-brackets, Z-brackets, mounting plates |
50
+ | Standoff | Cylindrical spacers, threaded standoffs |
51
+ | Enclosure | Boxes, vented enclosures, rounded shells |
52
+ | Gear | Spur gears, hubs |
53
+ | Flange | Bolt circles, blind flanges |
54
+ | Clip | Snap clips, spring clips |
55
+
56
+ ## Usage
57
+
58
+ ### With Transformers + PEFT
59
+
60
+ ```python
61
+ from transformers import AutoModelForCausalLM, AutoTokenizer
62
+ from peft import PeftModel
63
+
64
+ base_model = AutoModelForCausalLM.from_pretrained(
65
+ "Qwen/Qwen2.5-Coder-7B-Instruct",
66
+ torch_dtype="auto",
67
+ device_map="auto"
68
+ )
69
+ model = PeftModel.from_pretrained(base_model, "campedersen/cad0")
70
+ tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-Coder-7B-Instruct")
71
+
72
+ prompt = "50x30mm mounting plate with 4 corner holes"
73
+ messages = [{"role": "user", "content": prompt}]
74
+ text = tokenizer.apply_chat_template(messages, tokenize=False,
75
+ add_generation_prompt=True)
76
+
77
+ inputs = tokenizer(text, return_tensors="pt").to(model.device)
78
+ outputs = model.generate(**inputs, max_new_tokens=256, temperature=0.1,
79
+ do_sample=True)
80
+ ir = tokenizer.decode(outputs[0][inputs.input_ids.shape[1]:],
81
+ skip_special_tokens=True)
82
+ print(ir)
83
+
84
+ API Endpoint
85
+
86
+ curl -X POST https://ecto--cad0-training-inference-infer.modal.run \
87
+ -H "Content-Type: application/json" \
88
+ -d '{"prompt": "L-bracket with mounting holes", "temperature": 0.1}'
89
+
90
+ Compact IR Reference
91
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
92
+ β”‚ Op β”‚ Syntax β”‚ Description β”‚
93
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
94
+ β”‚ Cube β”‚ C x y z β”‚ Box with dimensions x, y, z (mm) β”‚
95
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
96
+ β”‚ Cylinder β”‚ Y r h β”‚ Cylinder with radius r, height h β”‚
97
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
98
+ β”‚ Sphere β”‚ S r β”‚ Sphere with radius r β”‚
99
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
100
+ β”‚ Cone β”‚ K r1 r2 h β”‚ Cone/frustum β”‚
101
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
102
+ β”‚ Translate β”‚ T n x y z β”‚ Move node n by offset β”‚
103
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
104
+ β”‚ Rotate β”‚ R n rx ry rz β”‚ Rotate node n (degrees) β”‚
105
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
106
+ β”‚ Scale β”‚ X n sx sy sz β”‚ Scale node n β”‚
107
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
108
+ β”‚ Union β”‚ U a b β”‚ Boolean union β”‚
109
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
110
+ β”‚ Difference β”‚ D a b β”‚ Boolean subtraction β”‚
111
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
112
+ β”‚ Intersection β”‚ I a b β”‚ Boolean intersection β”‚
113
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
114
+ β”‚ Shell β”‚ SH n t β”‚ Hollow out with wall thickness t β”‚
115
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
116
+ β”‚ Fillet β”‚ F n r β”‚ Round edges with radius r β”‚
117
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
118
+ β”‚ Chamfer β”‚ CH n d β”‚ Bevel edges with distance d β”‚
119
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
120
+ Nodes are 0-indexed; each line creates a new node.
121
+
122
+ Training
123
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
124
+ β”‚ Parameter β”‚ Value β”‚
125
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
126
+ β”‚ Base model β”‚ Qwen2.5-Coder-7B-Instruct β”‚
127
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
128
+ β”‚ Method β”‚ QLoRA (4-bit NF4) β”‚
129
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
130
+ β”‚ LoRA rank β”‚ 64 β”‚
131
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
132
+ β”‚ LoRA alpha β”‚ 128 β”‚
133
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
134
+ β”‚ Training examples β”‚ 530,531 β”‚
135
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
136
+ β”‚ Epochs β”‚ 1 β”‚
137
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
138
+ β”‚ Batch size β”‚ 64 (effective) β”‚
139
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
140
+ β”‚ Learning rate β”‚ 2e-4 (cosine) β”‚
141
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
142
+ β”‚ Hardware β”‚ 1x NVIDIA H100 80GB β”‚
143
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
144
+ β”‚ Training time β”‚ 9h 15m β”‚
145
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
146
+ Evaluation
147
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€οΏ½οΏ½β”€β”
148
+ β”‚ Metric β”‚ Value β”‚
149
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
150
+ β”‚ Final eval loss β”‚ 0.324 β”‚
151
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
152
+ β”‚ In-distribution accuracy β”‚ 75% β”‚
153
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
154
+ β”‚ Out-of-distribution β”‚ Limited (see Limitations) β”‚
155
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
156
+ Limitations
157
+
158
+ - Training bias: May add features (holes, fillets) to simple primitives β€” training
159
+ data weighted toward complex manufactured parts
160
+ - Dimension ambiguity: Occasionally confuses radius vs diameter for cylinders
161
+ - Limited primitives: No native hexagon support; hex shapes require boolean
162
+ workarounds
163
+ - OOD generalization: Struggles with part types not in training distribution
164
+
165
+ Related
166
+
167
+ - https://github.com/campedersen/vcad β€” Open-source parametric CAD with custom BRep
168
+ kernel
169
+ - https://vcad.io β€” Web app with cad0 integration
170
+ - https://huggingface.co/campedersen/cad0-mini β€” 0.5B distilled model for browser
171
+ inference
172
+
173
+ Citation
174
+
175
+ @misc{cad0,
176
+ author = {Cam Pedersen},
177
+ title = {cad0: Text-to-CAD Language Model},
178
+ year = {2026},
179
+ publisher = {HuggingFace},
180
+ url = {https://huggingface.co/campedersen/cad0}
181
+ }
182
+
183
+ License
184
+
185
+ MIT
186
+