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