ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Text-to-CAD全解析:从自然语言到参数化模型的技术路径与实践

Text-to-CAD全解析:从自然语言到参数化模型的技术路径与实践

text-to-cad,这个方向是我最近一年多最看好的AI工程化落地方向之一。它做的事情其实一句话就能说清:用自然语言直接驱动CAD模型的生成。比如输入“一个直径50mm、厚度8mm的带中心孔法兰盘”,系统就能吐出一个可编辑、带参数约束的CAD实体,而不是一张渲染图,也不是一堆没有特征树的三维网格。这种能力一旦稳定,影响的不只是设计环节,而是整个“需求到模型”的流程重建。

这篇内容我会从一个实践者的角度,把text-to-cad从头到尾拆开讲一遍:它到底是怎么运作的,为什么近几年才出现爆发点,实际跑通一个项目需要准备什么,以及最容易踩的坑都在哪里。适合三类人看:一类是刚接触这个方向、想快速建立全局认识的开发者;一类是在公司做CAD智能化改造、需要评估技术可行性的人;还有一类是已经在跑实验、但被数据质量和评估指标折磨得够呛的算法工程师。

1. Text-to-CAD在解决什么,以及为什么现在才爆发

1.1 一个自然语言到三维模型的直接映射

先理清楚text-to-cad在技术栈里的位置。它处在“语言模型”和“CAD内核”的交叉地带,但又不是简单的“让大模型调用一下API接口”。核心挑战在于:自然语言描述是模糊的、口语化的、丢失精确量纲的,而CAD模型是绝对的、参数化的、必须可制造可修改的。这两者之间的隐含鸿沟,才是这项技术真正要解决的问题。

举个例子,你说“一个支架”,语言模型完全能理解这是承重结构,但它不知道是L形、U形、还是带加强筋的异形件。你说“直径20的孔”,模型需要判断这个20是指通孔直径、螺纹底孔直径、还是沉头孔的小径。传统CAD的应对方式是让人去点菜单、填参数,把所有歧义消灭在设计意图明确之前;text-to-cad的野心是让机器来消化歧义,把语义理解直接映射到参数化操作序列上。

所以我的判断是:text-to-cad本质上不是“增强版的文生图”,而是“反向的CAD参数提取器”。它把一个人脑里的设计意图,经过语言编码,再由模型解码成CAD内核能执行的一串命令。这串命令不只是画一个形状,而是完整的设计流程:选基准面、画草图、加约束、拉伸切除、开孔、倒角、最后生成特征树。这个特征树的存在,决定了生成结果能不能被后续编辑,这也是text-to-cad区别于普通三维生成模型的最关键一点。

1.2 从DeepCAD到Zoo的技术演进关键

任何技术方向突然变热,一定是有几个关键卡点被依次打通了。text-to-cad也一样。我梳理了一下,至少有三代里程碑式的进展值得说。

第一代是DeepCAD,它证明了“CAD指令序列可以被自回归模型生成”。DeepCAD的核心思路是把CAD操作编译成程序化的指令,然后用一个类似机器翻译的encoder-decoder模型去生成。它的局限在于只能输出固定的矩形拉伸、圆孔阵列这类比较基础的CSG结构,复杂倒角、放样、扫掠全都不支持,而且泛化性能很有限。

第二代是Zoo,它做了一个我认为非常关键的工作:构建了一个包含大规模真实参数化CAD模型的数据集,并为每个模型配属了高层次的CAD操作序列。Zoo把问题从中等规模推到了大规模,让模型有机会学习更多种类的特征和拓扑。它的数据是来自真实用户的建模会话,比合成数据更能反映实际设计习惯。

第三代是最近两年陆续出现的、以T5和CodeT5为骨干的Text2CAD系列,以及一些把LLM和CAD指令集结合的项目。这一阶段的突破是统一了数据格式——大家不再各玩各的私有DSL,而是开始向OpenSCAD、CadQuery这种公开的脚本化建模语言靠拢。为什么这一步很关键?因为公开脚本语言具备“文本可解析、指令可编译、渲染可验证”三个特点,这等于把text-to-cad变成了一种可控的代码生成任务,而不是黑盒的形状生成任务。

我现在回头看,这个方向爆发的逻辑非常清晰:CAD数据规模上来了,语言模型能力上来了,公开的脚本化建模工具也在持续迭代,三者撞到一起,才有了今天这个局面。

阶段代表工作核心能力主要瓶颈
第一阶段DeepCAD基础CSG指令序列生成能生成的模型种类少,泛化差
第二阶段Zoo大规模真实CAD数据与操作序列数据标注成本高,语义对齐不够
第三阶段Text2CAD、LLM+脚本化CAD自然语言直接到参数化脚本精确尺寸控制、评估体系仍需完善

2. 核心细节解析:数据、模型架构与输出约束

2.1 数据闭环:自然语言、代码、树结构与渲染

很多刚接触text-to-cad的人,第一反应是找模型、调参数,但真正决定上限的是数据。这个方向的训练数据,不是简单的“一句话配一个模型文件”,而是一个完整的闭环,至少包含四层:

第一层是自然语言描述。这部分来源很杂,有从CAD建模教程里爬的,有从模型库标签里筛的,也有通过合成方式生成的。质量差异极大。有些描述是“一个简单的L形支架”,有些是“dimensions: 40x30x5, hole diameter 4.5, fillet radius 2”,后者根本不算自然语言,但对训练非常有用。

第二层是CAD代码。这是模型要生成的目标。首选CadQuery和OpenSCAD的脚本,因为它们把参数和特征关系暴露得很清楚。CadQuery的优势在于它和真实CAD更接近,操作语义是“以某个面为基准生成拉伸体”,而OpenSCAD更偏向CSG布尔运算,两者在模型的输出行为和后续编辑能力上差距明显。

第三层是树结构。把代码解析成抽象语法树,是为了给模型一个更结构化的监督信号。你问“带加强筋的L形支架”和“没有加强筋的U形槽”,虽然最终三维形状差别很大,但在代码层面可能只差一两行;而有了树结构,模型可以更容易学到“什么特征服务于什么功能”。

第四层是渲染结果。渲染不是给用户看的,是给模型做跨模态对齐用的。通过多视角渲染图,可以计算生成模型与描述文本之间的CLIP匹配度,或者用渲染对比约束生成过程。实测下来,渲染图像在数据规模足够大的时候,对提升模型的空间感知能力有明显帮助,尤其是判断“开孔方向”和“倒角位置”这类强几何属性时。

2.2 模型选型:为什么Decoder-only不是万能钥匙

text-to-cad的模型选型,我建议直接放弃“什么都用LLM”的思路。现在很多项目喜欢把自然语言描述和CAD代码都塞给一个大的decoder-only模型,让它自己学着生成。效果确实有,但问题也很明显:CAD代码的语法是强约束的,尺寸是绝对精度敏感的,小模型的幻觉在代码场景里会被放大到完全不可用。

更稳妥的方案是经典encoder-decoder架构,或者把大语言模型当作“语义理解器”,把具体的CAD生成交给专门的生成模型。我实测下来,T5系列的性价比非常高。T5的encoder可以把自然语言描述编码成语义向量,decoder可以一步步预测代码token序列。它不像GPT那样需要海量参数去积累世界知识,因为CAD生成本质上不是“知识密集型”任务,而是“结构密集型”任务。

当然,Decoder-only并非不可用。如果你的应用场景是“给一句非常详细的描述,生成固定模板的零件”,比如螺栓、螺母、垫圈这类标准化件,大模型反而更好使,因为模板知识在参数里压缩得非常密集。但一旦涉及自由形态的结构件设计,Decoder-only的输出长度不收敛、尺寸漂移、特征顺序混乱这些毛病就会频繁冒出来。

在实际模型选型时,我更多会看两点:第一,模型是否接受过“代码tokenizer”的预训练,而不是纯自然语言tokenizer;第二,模型是否有位置编码的稳定性——CAD代码动辄几百上千个token,序列长度对transformer位置编码的考验比普通文本大得多。CodeT5在这方面天然占优,这也是我内部实验默认选择它的原因。

2.3 输出验证:CSG合法性只是第一道关卡

模型生成完代码,不能直接当作结果交付。一个被很多人忽略的环节是输出验证。验证分几个层次,最基础的是CSG合法性检查:生成的几何体必须封闭、没有自交、没有零厚度的悬面。这一层至少能拦截掉百分之三四十的明显失败案例。

第二层是约束一致性检查。比如用户说孔距50mm,模型生成了49.8mm,视觉上几乎看不出差别,但装配时会出问题。所以需要把提取到的尺寸参数与描述中的期望值做比对,超过容差就判定失败。这层检查在纯生成模型里很难加入,但如果在代码层面做,其实很直接——就是解析生成脚本里的数值参数,再和文本中用正则或语义解析出的数值做匹配。

第三层是物理可行性检查。对结构件来说,至少要做简单的静态校核,比如过大的悬臂梁、过薄的筋板、不合理的开孔位置,都应该被拦截。大部分text-to-cad项目不会做到这一层,但一旦你的目标是“生成的可直接用”,物理校验就是绕不开的。这也是我一直强调的:text-to-cad不是AI论文里的玩具,它是一个“生成-验证-反馈”的工程闭环。

3. 实操过程:完整跑通一个Text-to-CAD示例

3.1 环境与工具链准备

纸上谈兵没意思,我直接用一个开源项目作为示例,带大家跑通一个最小闭环。这里我选的是Zoo这个项目配套的指令生成工具链,加上CadQuery作为后端建模引擎,再配合一个小规模微调脚本。这套组合的好处是全部开源、无商业依赖,适合作为研究方向的第一块试验田。

环境准备其实不复杂,核心依赖就四样:

  • Python 3.10以上(我用的3.10,稳定且包兼容性好)
  • 一个支持CUDA的PyTorch环境
  • CadQuery(用来编译生成的代码)
  • transformers库(用来加载和微调CodeT5模型)
conda create -n text2cad python=3.10 -y conda activate text2cad pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install cadquery transformers datasets

有一点要提醒:CadQuery和OpenCascade的版本兼容性非常折磨人。建议直接通过conda安装CadQuery,而不是用pip,否则经常会遇到动态库找不到或符号冲突的问题。我踩过一次大坑,pip装的cadquery在编译复杂模型时直接崩掉,换了conda版之后稳得一批。

3.2 数据准备与提示词设计

Zoo项目提供了原始CAD数据和对应的操作序列,但要用于text-to-cad,还需要把数据改造成“自然语言描述-CAD代码”对。Zoo自带的描述字段偏向结构化注释,比如“Bracket with four holes”,这种描述可以直接用,但信息量不足,模型很难学到丰富的语义关联。

我的做法是做一个半自动的描述增强管道。先用规则生成基础描述,包括类型词、主要特征、尺寸信息,再用一个本地小模型把这些要素串成通顺的自然语言句子。效果还不错,但要注意:不要引入过多的同义改写,否则模型会学到“描述越长代码越复杂”这种没有意义的关联。

提示词设计方面,不需要像ChatGPT那样写复杂的prompt模板,但有一点很关键——把尺寸信息显式地放在前面。我习惯用这个格式:

Create a [part_type] with [num_features] features. Key dimensions: length=..., width=..., height=..., hole_diameter=... Feature details: [feature list]

为什么尺寸要前置?因为在encoder-decoder结构里,序列开头的token会获得更高的注意力权重,把关键数值放在前面,等于给模型一个强提示,让它在生成过程中更早意识到尺寸约束。实测下来,这个简单的调整能让尺寸准确率提升好几个百分点。

3.3 训练与推理的完整流程

数据准备完成后,进入模型微调阶段。我用的是CodeT5-small,参数规模不大,训练速度快,适合先验证数据质量和管线正确性。

from transformers import AutoTokenizer, AutoModelForSeq2SeqLM tokenizer = AutoTokenizer.from_pretrained("Salesforce/codet5-small") model = AutoModelForSeq2SeqLM.from_pretrained("Salesforce/codet5-small") inputs = tokenizer( "Create a bracket with four holes. length=40 width=25 height=5 hole_diameter=4", return_tensors="pt", max_length=128, truncation=True ) outputs = model.generate( **inputs, max_length=256, num_beams=4, early_stopping=True ) code = tokenizer.decode(outputs[0], skip_special_tokens=True) print(code)

这是一个简化的推理示例。真正训练的时候,需要把数据集切成train/val/test,用标准的seq2seq训练方式,学习率设置在5e-5到1e-4之间,batch size根据显存调整。有一个细节值得注意:不要使用fp16半精度训练。CAD代码生成中数值精度非常敏感,半精度的浮点误差可能会让生成的尺寸参数出现系统性偏差,导致一个倒角从2.0mm变成了1.98mm。虽然看起来只差0.02mm,但到了装配阶段就可能是废件。

训练完成后,推理端不要用纯贪心解码,至少要加beam search,beam size设成4。这样会牺牲一点速度,但代码的语法有效性会显著提升。如果你对推理延迟有硬性要求,比如要做实时交互,那可以考虑用constrained generation,把输出限制在合法的token集合内。CadQuery的语法相对固定,我们可以预定义一个合法的关键字集合,在解码时强制屏蔽不在集合内的token。

3.4 关键参数的选择逻辑

实操中你会发现,调参不是最费时间的,最费时间的是理解每个参数为什么重要。我重点说三个:

第一个是max_length的设置。CAD代码往往比文本描述长得多,但也不能无限制拉长。如果设置的输出长度超过实际需要,模型会在生成结束后输出一堆无意义的填充token;如果设置太短,代码会在中间被截断,整个模型直接废掉。我的经验是,先对训练集里的代码长度做分位数统计,选择p95值作为max_length。

第二个是beam search的惩罚参数。设了length_penalty,默认值是1.0,但在CAD生成任务里,我建议调到1.2左右。原因是CAD代码有效信息密度高,多输出几个填充token的代价远不如保住一个完整特征。惩罚参数太小,模型倾向于提前结束;参数太大,模型会拖出冗长的无效代码。1.2是一个经过多次实验的平衡值。

第三个是数据清洗时的过滤阈值。训练数据里有很多无效样本,比如渲染失败的、打开就报错的、体积为0的。建议用CadQuery批量编译所有代码样本,能通过编译的才进训练集。不要只过滤“代码报错”的,还要过滤“编译成功但体积异常”的。比如一个零件所有尺寸都正确,但孔位置全挤在一个点上,这种样本对模型是纯毒药。

参数建议值作用常见错误
max_length训练集代码长度的p95避免截断或填充过多盲目给定值导致生成失效
num_beams4提升代码语法正确率beam太大导致显存爆炸
length_penalty1.2控制输出简洁度默认1.0导致提前终止
learning_rate5e-5微调稳定过大会导致Loss发散

4. 评估指标的陷阱与常见问题排查

4.1 四类评估指标的解读与误导

text-to-cad项目的评估,目前没有统一标准,但主流的做法大致四类。第一类是Match率,把生成的CAD模型和真实模型做相似度比对,用IoU或者距离度量。这个指标很直观,但也很容易被骗:两个模型看起来很像,但一个是实心件一个是带内腔的薄壁件,在密度图上可能很接近,实际功能却完全不同。

第二类是代码正确率,看生成代码能不能成功编译,能编译就算成功。这个指标太粗糙了,能编译不代表能制造,更不代表符合需求。

第三类是尺寸误差。这套指标最接近真实使用感受。用户说孔距50mm,生成48mm就是失败。计算方式也比较直接:从生成代码里提取所有带单位的数值,与描述中出现的数字逐一匹配,计算相对误差。这个指标做起来费劲,但它反映的能力是最贴近生产力的。

第四类是特征匹配度。把模型的特征树和用户描述的语义特征逐一比对,比如“有没有开孔”“有没有倒角”“是不是拉伸特征”。这个指标更能反映模型是否真正理解了自然语言,但目前实现成本高,需要训练一个特征分类器,或者依赖前文提到的树结构解析。

这里必须泼一盆冷水:如果只看Match率,很多模型看起来已经很强了,但拿到工业场景里一用就露馅。原因在于Match率是用几何形状相似度算的,它天然偏向大尺度的形状一致性,对“小但关键”的特征不敏感。一个缺失的M3螺纹孔,在IoU计算里可能只占千分之几的面积,但对制造来说就是废件。

4.2 实操中最高频的六个问题

根据我自己和身边朋友做类似项目跑出来的经验,下面六个问题是出现频率最高的,我把现象、原因和解决方案一起列出来。

第一个问题是模型生成的代码编译失败。现象是CadQuery抛异常,原因是tokenizer输出了一些无效代码片段。解决方案是推理时使用更大的beam size,以及把“编译失败”的样本在训练时保留一小部分,并用对比学习的方式让模型学会避开这些错误路径。

第二个问题是尺寸偏小或偏大统一漂移。现象是模型生成的参数和真实值有稳定的比例偏差,比如所有直径都乘以了0.98。原因往往是数据预处理时归一化方式不一致。建议在全流程保持统一的毫米单位,只做固定尺度的缩放,并在代码里加入尺度校验层,生成后直接把所有长度数值与描述值做比率检查。

第三个问题是孔特征生成不稳定。零件外形生成得很好,但孔经常被漏掉或者数量不对。原因在于孔在CAD模型中是负空间特征,放在代码层面看,它往往是最后一个特征,而decoder在长序列后半段注意力衰减严重。解决思路:把训练时的样本做特征排序,强制性把所有孔特征前移到代码前面;如果不想改数据,也可以在推理时分别预测“主体外形”和“孔特征”。

第四个问题是模型对口语化描述的理解差。比如“大概五厘米”这种描述,模型不知道它是50mm,也没有容差范围的概念。我建议在处理语义时,对模糊量词做规范化转换,比如“大约”“左右”这类词,直接映射为±1%的容差标记,而不是让模型自行理解。

第五个问题是多面构型的歧义。同一个自然语言描述,可能对应无数个合法CAD模型。这个不是模型的问题,是问题本身没有唯一解。解决方案是引入用户反馈闭环,第一次生成后如果尺寸不符,就用对话方式迭代修正,把“单轮生成”变成“多轮人机协作”。实测下来,两轮迭代内,成功率和用户满意度都能大幅提升。

第六个问题是训练数据里相似样本过多。Zoo数据集里有很多同一零件的微小变异,比如孔距从40mm变41mm,如果不去重,模型会严重过拟合到高频的模式上,泛化能力反而变差。建议在训练前做基于代码相似度的去重,去除编辑距离过小的样本对。

问题根因实操建议
代码编译失败无效token输出beam size调大,保留少量负样本
尺寸统一漂移归一化不一致统一毫米单位,加尺度校验层
孔特征缺失注意力在长序列后端衰减特征前移,或分开预测外型与孔
口语描述理解差模糊量词与机构缺映射做模糊量词到容差的规范化
多面构型歧义问题本身没有唯一解做多轮迭代交互
训练过拟合重复样本太多按代码相似度去重

5. 实操总结与个人经验

text-to-cad从原理到落地,中间隔着的不是一堵墙,而是一连串细节问题。我做了这么多实验之后,最深的体会是,这个项目最难的永远不是模型结构,而是数据质量、输出验证和评估体系这三者的循环建设。模型结构再先进,数据里充满尺寸漂移和无效样本,训练出来也只是一个漂亮的废物。

我个人的习惯是,每跑完一轮实验,不要急着看指标涨了多少,先随机抽一百个生成结果,用CadQuery全部编译,再手动打开看五十个。这一步虽然费时间,但能最直观地暴露问题。等模型能稳定生成可编译、尺寸准确的模型之后,再开始用自动指标做迭代优化。否则你在一个评估指标虚高的模型上反复调参,浪费的只会是宝贵的迭代周期。

另外一个经验是,text-to-cad项目的成功,很大程度上取决于它跟实际设计流程的整合程度。如果只是做一个“模型输出结果给人看”的Demo,那永远停留在“AI生成示意图”的层面。真正有价值的方向,是让生成的参数化模型直接嵌入到下游的设计链路里,比如进CAE仿真、进CAM加工、进BOM表。这个方向上目前还没出现绝对的最佳实践,但值得所有人投入精力去摸索。

返回列表