text-to-cad 这两年算是AI辅助设计圈最出圈的方向之一。简单说,就是输入一句自然语言——"一个带四个圆孔的矩形法兰盘,孔距80mm,板厚10mm"——系统直接吐出一个可编辑、可制造的三维CAD模型,而不是一张渲染图片。这跟 text-to-image 有本质区别,图像生成给的是像素,text-to-cad 给的是带拓扑结构、带参数约束、能进CAM流程的几何实体。
这篇文章我想从技术路线、数据集、实操微调、效果评估、踩坑记录这几个维度,把 text-to-cad 这个方向从标题到落地完整拆一遍。不管你是做机械设计的、搞AI算法研究的,还是3D打印爱好者,只要能看懂Python代码,都能从这篇文章里找到可以直接上手的内容。我会把关键原理讲透,把能跑通的方案给你列出来,也会把我实际测试中踩过的坑原原本本写清楚。
1. 项目概述:text-to-cad 到底在做一件什么事
1.1 一句话需求背后的真实痛点
传统CAD建模的学习曲线非常陡。一个熟练的机械工程师,用SolidWorks或者Fusion 360从零画一个中等复杂度的零件,怎么也得二三十分钟;如果是曲面造型或者装配体,花费的时间更是按小时计。更麻烦的是,很多时候设计师拿到的是一个模糊的需求——"客户说要一个能卡在桌面边缘的支架,承重5公斤",这种描述离可编辑的CAD模型隔着十万八千里。
text-to-cad 试图把这段距离直接抹平。它让非专业人士也能用自然语言描述需求,让系统完成从语义到几何的映射。对专业设计师来说,这个概念设计的阶段价值最大——你不需要亲自动手画草图和拉伸,只需要不断用语言描述你的想法,系统快速给出版本,你在它基础上修改,效率能翻好几倍。
这个领域的核心难点在于:自然语言是离散的、模糊的,而CAD模型是连续的、精确的、带严格约束的几何体。一句话里"四个圆孔"这种信息,必须被转化成精确的空间坐标、直径、深度和布尔运算关系,任何一个细节错了,零件就废了。
1.2 这不是换皮版的文生图
text-to-image 的扩散模型生成的是体素或者隐式表达,最终渲染成2D像素。text-to-cad 要输出的是参数化建模的操作序列——比如"画一个矩形草图→拉伸10mm→在指定位置打孔"。这种操作序列就是CAD软件的建模历史树,是真实可编辑的。
这里面的关键差异是:CAD模型必须是B-rep(边界表示)或者CSG(构造实体几何)层面的精确几何,而不是网格近似。你3D打印一个齿轮,用扩散模型生成的网格可能有空洞、破面、非流形边,根本没法切片;但text-to-cad生成的参数化模型天然具备水密性和可制造性。这也是为什么这个方向选择了语言模型而不是扩散模型作为主力架构——生成离散token序列这件事,就是LLM的主场。
1.3 谁应该关注这个方向
我觉得三类人最应该关注。第一是机械和工业设计领域的从业者,text-to-cad能帮你做方案探索,快速试错;第二是AI算法工程师,这个方向在序列生成、多模态对齐、几何推理上都有很多未解决的问题,是个很有潜力的研究方向;第三是教育工作者和创客,学生用自然语言描述形状,系统来建模,能把学习门槛降得很低。
2. 技术路线梳理:文本走到底层几何的三种主流解法
2.1 序列化指令生成式方案——目前绝对的主力
这条路线的核心思路是:把CAD建模过程抽象成一系列带参数的命令序列,然后用语言模型做序列到序列的生成。输入是自然语言描述,输出是CAD操作序列。目前学术圈提到text-to-cad,默认指的就是这个方向。
具体来说,一个CAD模型被表达成一串结构化的token。比如"S0L0"代表第0个草图上的第0条线段,后面跟着线段的起点终点坐标;"EXT0"代表一个拉伸操作,后面跟着拉伸方向和距离。整个模型就是这样一个层次化的token序列,既能保证信息完整,又能用标准transformer架构做自回归生成。
以开源项目Text2CAD为代表的具体做法是:收集Fusion 360 Gallery里的大量真实模型,把这些模型的历史树解析成操作序列,然后用GPT-4给每个序列生成对应的自然语言描述,形成一个"文本-CAD对"的大规模数据集。模型端直接沿用Llama系列架构,在CAD序列上加指令微调。实测下来,对于常见的拉伸、旋转、打孔、倒角这类基础特征,生成成功率相当可观。
这套方案的优点很突出:数据好造(CAD历史树现成的)、模型架构不需要创新(吃LLM红利)、输出天然可编辑。缺点是自由曲面和复杂扫掠这类特征还做不好,而且长序列生成时会累积误差,最后一步的尺寸可能会偏离原始描述不少。
2.2 多模态大模型方案——把草图纳入输入
纯粹的text-to-cad有一个天然短板:自然语言的描述精度终究有限。你说"一个类似手机壳形状的零件",不同人理解的手机壳轮廓完全不一样。所以2024年下半年开始,业界出现了像CAD-MLLM这样的多模态方案——输入同时支持文本和图像,可以是手绘草图或者参考图。
这类方案的架构通常是:视觉编码器(比如CLIP的ViT)+ 语言模型底座。图像经过视觉编码器变成视觉token,和文本token拼在一起,输入LLM生成CAD操作序列。测试下来,当你给一张粗糙的手绘草图再加上一句"补全这里的圆角",效果比纯文本描述好非常多,因为图像信息提前锚定了轮廓的大致形状,语言只需要做增量修改。
这个方向我认为是text-to-cad走向实用的必经之路。尤其是逆向工程场景——拿到一张实物照片或者扫描图,加上自己的设计意图描述,系统直接生成可编辑模型,这个工作流价值太大了。
2.3 检索增强与程序合成路线——工程界的补充方案
学术圈还有一种思路:不做端到端生成,而是先通过语言描述在已有的零件库中检索相似模型,再用程序合成的方式对检索结果做参数调整。这种方案本质上更保守,但它解决了一个关键问题——生成结果的可靠性。
理由很简单:检索出来的模型是所有结构都是真实存在的,不会出现"理论可行实际破面"的情况。程序合成负责把参数按描述修改,比如检索到一个法兰盘,根据"孔径加大到12mm"这句话,找到对应的直径参数改成12。这个路线对参数化标准件特别有效,但对检索库以外的复杂零件完全无能为力,所以只能当一个补充方案。
2.4 三种方案的对比与选型建议
我整理了一张表,方便你快速选型:
| 方案 | 代表项目 | 核心优势 | 核心短板 | 适合场景 |
|---|---|---|---|---|
| 序列化生成 | Text2CAD、DeepCAD | 数据易得、模型成熟、输出可编辑 | 复杂曲面弱、长序列误差累积 | 通用零件设计、概念探索 |
| 多模态生成 | CAD-MLLM | 支持图像输入、几何锚定好 | 视觉编码器与CAD域gap大 | 逆向工程、草图规范化 |
| 检索+程序合成 | 垂直行业自研为主 | 可靠性极高、参数可控 | 泛化性差、依赖零件库 | 标准件、系列件衍生设计 |
我的建议是:入门玩序列化生成,因为代码和数据集都是现成的;要做实际产品,优先看多模态方案;如果你们公司有成熟的零件库体系,第三条路反而最容易落地。
3. 数据集与表示格式:几何模型如何变成模型能读懂的"话"
3.1 CADText 数据集的结构与规模
不看数据集直接谈模型就是耍流氓。当前text-to-cad最有价值的开源数据集是CADText,它从Fusion 360 Gallery中提取了超过17万条文本-CAD对。每条数据包含三块信息:自然语言描述、对应的CAD操作序列、以及最终导出的几何模型文件。
这里要强调一下:Fusion 360 Gallery里的模型都是用户创建的、经过实际设计流程验证的参数化模型,建模历史是完整的,而不是单纯的网格扫描结果。这意味着解析出来的操作序列质量很高,不会出现"模型能看但历史树乱七八糟"的情况。数据集的构建流程是:先解析原始建模历史为命令序列,再用GPT-4对每个序列生成多角度的文本描述,然后做人工+规则的二次过滤,筛掉那些生成质量差或者描述不准确的样本。
3.2 序列化表示法解析
我直接给一段简化版的序列示例,帮你直观感受一下:
S0L0(0,0 -> 100,0) S0L1(100,0 -> 100,60) S0L2(100,60 -> 0,60) S0L3(0,60 -> 0,0) EXT0(profile=S0, depth=10, dir=+Z) S1C0(center=50,30, radius=5) S1OP0(profile=S1, hole=True, depth=10)这段序列描述的就是:画一个100×60的矩形草图S0,然后沿Z方向拉伸10mm成实体,再在底板上(几何中心50,30处)打一个直径10的通孔。语言模型的任务就是把"一个100乘60、厚10、中心有个直径10通孔的矩形板"变成上面这串token。
实际框架中的表示法比这个复杂得多,涉及曲线类型(直线、圆弧、样条)、约束关系(平行、垂直、相切)、特征操作(拉伸、旋转、扫掠、放样、倒角、圆角)等。这些都被映射到一个受限的token词表里。token词表设计得好不好,直接影响模型的学习难度。Text2CAD的做法是参考DeepCAD的表示法,做了精简,舍掉了一部分低频特征操作,保证训练数据的命令组合分布相对集中。
3.3 数据清洗的实操要点
这块我实际操作时踩过不少坑,给你几个关键经验:
第一,必须过滤掉未经布尔运算校验的序列。有些用户上传的模型历史树里存在自相交或者不闭合的情况,解析出来的序列虽然语法正确,但几何上非法。建议对每个训练样本用OCCT(OpenCASCADE)做一次实体校验,跑不通的直接丢掉。
第二,文本描述需要统一风格。GPT-4生成的描述容易出现长度分布不均,有的只有一句话,有的写了一长段。训练时建议把描述截断到固定长度(比如256 token),过长会影响模型对关键信息的注意力分配。
第三,去重不能只看文本,要看序列。两句话描述同一个零件,生成的操作序列完全一样,这种数据在训练集里会造成偏差,需要用序列哈希做去重。
4. 实操实录:从零微调一个text-to-cad模型
4.1 环境配置与依赖清单
如果你用的是Text2CAD的官方代码库,环境要求大致如下:
# Ubuntu 20.04+ / CUDA 11.8 # Python 3.9/3.10 # PyTorch 2.x conda create -n text2cad python=3.10 conda activate text2cad pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 pip install transformers datasets accelerate peft deepspeed cadquery重点说下cadquery,这个库负责把生成的序列转为实际几何体。它在序列评估阶段是不可或缺的——生成序列后你需要解析成CADQuery脚本,跑一遍得到STEP文件,才能算几何层面的指标。注意安装的时候要确认版本兼容性,我之前用旧版cadquery碰到过线程安全问题,生成大量文件时偶发崩溃。
显存方面,如果你用LoRA微调7B模型,单卡A100 40G是起步线;想更省的话用QLoRA,把基座模型量化到4bit,大约12G就能跑,只是训练时间会长一些。我个人建议至少准备一张48G显存的卡,体验会从容很多。
4.2 数据准备与预处理流程
数据准备是整个流程里最枯燥但最关键的环节。下载CADText数据集后,你需要做以下几件事:
# 1. 解压数据,转换成统一的JSON格式 python scripts/parse_cadtext.py --input_dir ./data/cadtext --output_file ./data/cadtext_all.json # 2. 过滤非法几何 python scripts/filter_invalid.py --input ./data/cadtext_all.json --output ./data/cadtext_valid.json # 3. 划分训练/验证/测试集(推荐 90%/5%/5%) python scripts/split_dataset.py --input ./data/cadtext_valid.json \ --output ./data/train.json --output ./data/valid.json --output ./data/test.json经过我的测试,原始数据集做完几何校验后,大约会损失10%-15%的样本,这属于正常现象,不要心疼。如果损失的样本比例超过20%,大概率是解析脚本版本和数据集版本不匹配,优先检查特征的token映射表。
预处理阶段有一个特别容易忽略的细节:坐标归一化。CAD数据的绝对坐标范围波动很大,有的模型整体尺寸是毫米级,有的是米级,如果不做标准化,模型很容易被极值带偏。实际操作中,我会把整个模型的包围盒缩放到单位立方体内,同时在序列里额外保留一个缩放因子token,方便推理时还原真实尺寸。
4.3 模型微调的关键超参与训练策略
模型基座选什么?Text2CAD官方用了Llama-2-7B和Llama-3-8B,我的复现经验是Llama-3-8B在指令跟随和生成质量上都明显更好。如果你算力有限,也可以试试更小的模型比如Qwen-1.5-7B,效果差距不大,但中文描述的支持会好很多。
训练用的关键超参数,我直接给一组能复现效果的配置:
| 超参数 | 推荐值 | 备注 |
|---|---|---|
| LoRA rank | 16 | 太低学不住几何规律,太高显存压力大 |
| LoRA alpha | 32 | 保持2倍rank,微调效果更稳 |
| 学习率 | 2e-4(AdamW) | warmup比例建议5% |
| 批大小 | 32(梯度累积8×4) | 总batch对效果影响大于单卡batch |
| 最大序列长度 | 2048 | 长序列截断,短序列要padding对齐 |
| 训练轮数 | 2 | 第一轮拟合,第二轮精修 |
| 采样温度 | 0.7 | 推理时偏低有助于生成稳定结构 |
训练时我强烈建议用DeepSpeed ZeRO Stage 2配合LoRA,能大幅节省显存。还有一个小经验:不要在一开始就用完整数据集,先用1%的数据跑通整个训练和评估流程,确认各环节都正常,再全量训练。全量训练2000条数据在A100上大概需要6-8小时,这个量级的成本是可以接受的。
4.4 推理生成与CAD模型导出
模型训练好之后,推理生成CAD模型的流程如下:
from transformers import AutoModelForCausalLM, AutoTokenizer from src.dataloader import CADTokenizer # 加载微调后的模型 model = AutoModelForCausalLM.from_pretrained("./text2cad-llama3-lora-merged") tokenizer = CADTokenizer.from_pretrained("./text2cad-llama3-lora-merged") # 输入自然语言描述 prompt = "A rectangular flange with four circular holes, hole diameter 10mm, distance between holes 80mm, plate thickness 8mm" # 生成CAD序列 inputs = tokenizer(prompt, return_tensors="pt").to("cuda") outputs = model.generate( inputs.input_ids, max_new_tokens=1024, do_sample=True, temperature=0.7, top_p=0.9, num_return_sequences=1 ) cad_sequence = tokenizer.decode(outputs[0], skip_special_tokens=True) # 解析并导出STEP from src.export_utils import sequence_to_cadquery result = sequence_to_cadquery(cad_sequence, output_format="step") result.export("output_model.step")这段代码里最关键的是生成参数。温度设太高(超过1.0)几何结构容易发散,生成一堆自相交的边;设太低(低于0.3)模型会倾向于输出训练集中的"典型零件",灵活性很差。0.7左右是个比较均衡的点。
另外一个经验是:对于复杂零件,建议先在文本描述里把结构拆成多个简单句子,比如香醍"先是一个底座……底座上有两个凸台……每个凸台中心有一个孔"。让模型分步生成的效果,远好于让模型一步到位想象所有细节。
5. 效果评估:怎么判断生成的质量不是"能看不能用"
5.1 几何质量指标——从CD距离到实体校验
文本生成CAD模型的评估比文本生成图像更复杂。图像只要"看起来像",CAD模型要"确实能用"。最常用的几何指标是Chamfer距离(CD):把生成模型和真实模型分别采样成点云,然后计算两个点云之间的平均最近距离。CD越小,几何形状越接近。我自己实际测试中,CD值在0.5mm以下(基于单位归一化后的尺度)生成结果基本可用;超过2mm的,基本已经偏离原意了。
但CD只能衡量形状近似,不能衡量实体合法性。一个模型CD很小,但可能存在非流形边、零厚度面这些问题,制造时直接报废。所以除了CD,必须跑一遍实体的布尔运算自检:用OCCT对生成模型做切片、布尔交、体积计算,任何一步报错,这个样本直接判负。
5.2 文本-模型语义对齐评估
几何对了不代表"语义对齐"了。你说"四个圆孔",模型生成了四个方孔,CD可能也小(因为大体形状像),但完全没满足需求。常规做法是引入多模态对齐模型,比如用CLIP把文本和渲染图投影到同一语义空间计算相似度。操作上是把生成模型渲染成多视角图片,和原始文本一起丢给CLIP打分。
实测下来CLIP分数在0.25以上算语义基本对齐,低于0.2大概率是跑偏了。这个方法虽然粗糙,但作为自动筛选手段效率很高,能一次性过滤掉一半以上的低质量生成结果,然后再进入人工评估阶段,能省下大量检查时间。
5.3 可编辑性与参数化评估
这个维度是我自己加的,但我觉得特别重要。生成一个CAD模型,如果建模历史树乱七八糟,里面的关键尺寸参数调整不了,那它的实用价值就大打折扣。我评估可编辑性的方法是:拿到生成的模型后,尝试修改一个关键尺寸(比如孔径改大20%),看能不能在不破坏整体拓扑的前提下完成。能改,说明参数化质量过关;一改就报错,说明模型是"死"的。
要提升参数化质量,核心要看生成序列里的约束信息是否完整。训练数据里一定要包含真实的约束关系,不能只有纯粹的无约束坐标命令。你在预处理阶段检查训练数据时,如果发现约束信息的占比偏低,建议优先清洗掉这部分数据——否则模型学到的是"画图形"而不是"设计参数化模型"。
6. 常见问题与实测避坑实录
6.1 生成序列语法正确但几何非法的终极排查法
这是我在测试中遇到频率最高的问题:模型生成的token序列语法完全正确,tokenizer解码也能过,但cadquery解析时报错说"profile is not closed"或者"wire is not planar"。
原因多半是模型在生成闭合轮廓时,最后一条边的终点和第一条边的起点没有精确重合。数值上差了0.0001mm,人眼看不出,但CAD内核直接暴毙。解决思路有两个:一是在解析阶段加容差处理,把距离小于某个阈值(比如0.01mm)的断点强制焊接;二是从训练阶段下手,在序列化表示里增加一个闭合标记token,让模型学会显式表达"轮廓闭合"。实测下来,加闭合标记token的效果更好,能把几何非法率从30%压到8%左右。
6.2 训练数据不平衡导致的"特征坍缩"
如果你发现模型生成的结果越到后面越单一,翻来覆去就是那些矩形板、圆盘、简单轴类零件,那十有八九是训练数据分布出了问题。CADText这个数据集里,拉伸类特征占绝对主导,旋转、扫掠、放样这类高级特征占比很小。模型在训练时天然倾向学习高频模式,你让它生成"旋转体轴套"它可能直接给拉伸体。
应对策略有两个:第一,对低频特征做过采样,让旋转、扫掠这类样本在训练集中占的比例提升到10%-15%;第二,在指令中强制指定特征类型,比如prompt里明写"Please use revolve feature",这招结合过采样效果最明显。
6.3 上下文长度与长模型生成的不稳定
CAD序列的token数通常比自然语言文本长得多。一个中等复杂度的零件,操作序列可能轻松超过1500 token。自回归生成在长序列上有个通病:靠后的token受前面错误累积影响,容易出现主尺寸偏移。
我的实测经验是,生成过程中不要把温度调太固定。可以在前几百个token用略低的温度(0.5)保证结构稳定,后半段切换到0.8补充多样性,实现方式是在generate函数的重复惩罚或者logits processor里做分段调整。另外,如果模型输出的主尺寸和你描述的参数对不上,优先检查是不是上下文长度被截断了——把max_new_tokens往上调一些,情况往往会好很多。
6.4 全流程排错速查表
| 现象 | 大概率原因 | 排查与处理方法 |
|---|---|---|
| 数据预处理时样本损失比例过高 | 解析脚本版本和数据集版本不匹配 | 检查token映射表,更新脚本 |
| 训练loss下降但生成全乱码 | 分词器不匹配,用了基座模型的tokenizer | 确认使用CADTokenizer,序列化格式和训练时编码一致 |
| 生成结果CD很小但语义偏了 | 几何形状对了,特征数量/位置不对 | 加CLIP对齐指标做过滤,人工复查低分样本 |
| cadquery解析时常崩溃 | 生成序列存在非法几何 | 在解析模块加容差焊接,或用闭合标记token重训 |
| 输出STEP文件无法导入CAD | 版本兼容性问题 | 导出时选STEP AP214格式,通用性最好 |
写在最后:这个方向还缺什么
我在实际跑完整个流程后,最大的感受是:text-to-cad 目前的瓶颈既不在模型,也不在算法,而在数据质量和评估标准。CADText 这类数据集覆盖的特征类型还是太少,真实工业场景里大量的钣金特征、焊接符号、公差标注都没有覆盖。评估标准上,业内也还没有一个公认的、像BLEU和CLIP那样直接可比的统一指标,导致不同论文的结果很难横向对比。
所以如果你对这个方向感兴趣,除了自己复现跑通之外,更值得投入的地方其实是数据基础设施——构建更高质量、更多特征覆盖、带完整约束信息的CAD文本对齐数据集。这个事的价值会被越来越多团队看见。
最后再分享一个小技巧:实际用text-to-cad做概念设计时,生成的第一个版本通常不能直接用,但它会给你提供一个很重要的东西——出发的锚点。在它基础上修改,比对着空白画布从零开始,效率高太多了。工具的意义不是一步到位替你做完,而是帮你把"从0到1"的时间压缩到原来的十分之一,剩下的"从1到N"依然是你作为设计师的核心价值。