很多人一听 text-to-cad,第一反应是“这不就是给大模型打一句话,让它给我画个三维模型吗?”。实际干过的人都知道,这个领域要拆开的坑比表面看起来多得多:文本怎么编码、模型用什么三维表示、生成的形状能不能直接进 CAD 软件改、数据从哪里来、指标怎么定,每一步都能让人折腾掉不少时间。这篇文章我打算从自己踩过的坑和看过的方案出发,把 text-to-cad 的一条主流落地链路掰开揉碎讲一遍,包括数据集处理、模型选型、训练现场最容易翻车的地方,以及另一条非常实用的“文本生成程序化建模脚本”路线。不管你是刚入门的研究生,还是想把这类能力集成到设计工具里的工程师,应该都能从这里找到可以直接抄作业的部分。
1. Text-to-CAD 到底要解决什么问题
1.1 传统建模流程里的效率瓶颈
先看一个很常见的场景:结构工程师手上有张草图,或者脑子里有一个装配件的描述,比如“一个带四个腰形孔的法兰盘,外径 80,厚度 12,孔绕中心均匀分布”。在没有 text-to-cad 工具之前,他得打开 SolidWorks 或者 FreeCAD,一步步画草图、拉伸、开孔、倒角。整个过程十分钟算快的,反复修改尺寸又是十分钟。如果这个零件只是用来给算法做仿真测试,或者只是概念的初步验证,那这二十分钟就属于“纯重复劳动”。
text-to-cad 想做的,就是把这二十分钟压缩成一分钟:使用者用自然语言描述意图,模型直接输出一个可编辑的 CAD 模型,至少也是能导入 CAD 软件的网格或参数化脚本。注意“可编辑”三个字很关键:工业上真正有价值的是参数化特征模型,比如拉伸、旋转、圆角这些历史记录,而不是一张渲染好看但改不了尺寸的三角网格。传统生成模型输出网格,这在很多场景够用,但离“CAD”这个词还有距离。
1.2 它和 text-to-image、text-to-3D 有什么不一样
很多人会把 text-to-cad 和 text-to-3D 混在一起。确实,早期的 text-to-3D 技术,比如基于 CLIP 的优化方法、基于扩散模型的生成方法,都可以拿来生成一个三维形状。但它们的目标受众和约束条件差别很大。
text-to-3D 更关心的是视觉合理性:生成一个“看起来像椅子”的东西,哪怕底面不平面、壁厚为零、曲面自交叉,只要渲染漂亮就行。text-to-cad 更关心结构合理性:面要封闭、厚度要真实、装配关系要成立、模型能导入 CAM 做路径规划。如果生成的形状只能看不能加工,那对工业场景来说就是废品。这也是为什么现在很多团队会把 text-to-cad 分成两个方向:一个方向仍然用生成模型直接输出体素、网格或隐式场,再后处理成 CAD 实体;另一个方向干脆绕开“形状生成”,让大模型生成 OpenSCAD 或者 CadQuery 这类程序化建模代码,因为代码天然就是参数化、可编辑、可执行的。
1.3 谁最需要这项技术
我实际接触到的需求方主要三类:第一类是做结构优化的工程师,他们需要快速批量生成不同尺寸的零件变体做仿真对比,手动画模型根本忙不过来;第二类是做三维资产生产的团队,游戏和影视项目里要建大量道具、零部件,有个文本生成环节能省下不少建模外包费用;第三类是做 CAD 二次开发和智能化改造的软件厂商,他们想把自然语言交互塞进现有设计软件,让用户用打字代替点菜单。
这三类需求对应的技术选型不一样。结构工程师更偏爱参数化脚本;游戏资产团队更接受网格输出;软件厂商则希望模型能输出带特征树的实体格式。所以做这个方向的项目,第一件事不是选网络结构,而是确定目标格式和下游流程。
2. 数据是第一步:文本描述和三维模型的配对
2.1 现成数据集怎么挑
想训一个 text-to-cad 模型,最核心的燃料是成对的“文本描述 + 三维模型”数据。公开数据集里,Text2Shape 是最常被提到的起点,它基于 ShapeNet 的子集,给每个模型配了人工写的文本描述,内容比较短,一般就是一类物体的视觉特征,比如“一张四条腿的木头桌子”。这个数据集适合做预训练和算法验证,但离 CAD 工程件还有相当距离,因为 ShapeNet 大多是从扫描或者游戏模型整理出来的网格,没有设计历史,没有精确尺寸语义。
做工业场景的话,需要自己攒数据。一个常见做法是拿参数化模型库自动生成样本:你用脚本定义一些带可变参数的模型,比如“一个带 n 个圆孔的圆形法兰盘”,然后把每个参数组合渲染成网格,同时把参数值拼成一段描述文本。这样得到的数据是绝对干净、成对、可追溯的。代价是描述文本会很模板化,模型容易过拟合到模板句式上,后面要加一些描述扰动。
2.2 文本描述的清洗与增强
真实世界的 CAD 描述和公开数据集的短句不一样。用户会说得很口语化,比如“我要一个能装 6 颗 M6 螺丝的支架底座,孔距要能对上标准件”。这种描述里有单位、有标准件名称、有装配语义。直接拿去做分词和编码,模型经常抓不住重点。
我在实践中总结了一套清洗流程:
- 先做术语归一化。把“螺孔”“螺丝孔”“螺纹孔”统一成“螺纹孔”;把“板子”“底座”“基座”这种近义词尽量映射到标准词表。
- 再做单位规范化。凡是涉及尺寸的数字,尽量统一成毫米,并在文本里保留数值。
- 最后做句式增强。一个模型描述可以扩展成“这是一个……”“我们需要……”“包含……特征的……”多个句子,在训练时随机抽一句,相当于免费的数据增广。
如果数据量实在不够,还可以用 LLM 生成同义改写,但注意别让模型学到错误的几何关系,比如“直径”和“半径”被混用,这种错误一旦进入训练集,会让模型在尺寸语义上彻底混乱。
2.3 预处理细节里容易忽略的坑
三维模型进入网络之前要做的预处理,比想象中更琐碎。首先是坐标对齐。很多 CAD 导出模型的坐标轴方向不统一,有的模型 Z 轴向上,有的 Y 轴向上,如果直接混在一起训,模型会学到一团糊的“平均姿态”。我做数据流水线时,会先对每个模型做 PCA 对齐或者手动设置规范坐标系,把模型的朝向固定下来。
接下来是尺寸归一化。CAD 模型自带真实尺寸,但网络通常希望输入在一个单位球或单位立方体里。对工业件来说,一个零件如果长宽比极其夸张,比如横梁,直接归一化会丢失厚度上的比例感。我的做法是保留一个“真实尺寸向量”和模型一起输入网络,让模型知道这个归一化后的形状对应的实际大小是多少。别看这个技巧小,在后续生成带真实尺寸的 CAD 模型时非常有用。
最后是数据划分。同一类零件只做简单的随机划分会导致泄漏,因为同一个参数化模型生成的不同样本高度相似。正确的做法是把参数化模板作为划分单位:训练集只能出现一部分模板,测试集用完全没见过的模板。这样才能测出模型真正的泛化能力,而不是背题能力。
3. 从文本编码到三维生成:一条主流的实现路线
3.1 文本编码器怎么选
文本编码是整个链路里最成熟的部分。当前主流做法是直接用预训练语言模型,在小规模专用数据上再做微调。早期项目喜欢用 BERT 的 [CLS] 向量当作整句表示,后来大家发现 CLIP 的文本编码器在视觉概念上更对齐,生成结果往往更符合人类对物体外观的想象,所以 text-to-cad 项目里 CLIP 文本塔用得很多。工业场景则更推荐微调过的 BERT 或 ELECTRA,因为术语多、格式严,CLIP 在“ISO 法兰”“沉孔”这类专业词上表现不一定好。
我自己的经验是:不要把所有文本都压成一个向量。在输出阶段让文本特征和形状特征做 cross-attention,比单纯把文本向量 concat 进瓶颈层效果更好。原因也好理解:一句话里“外径 80”“四个孔”“倒角 C1”这些信息作用在不同部位,全局向量只能表达“大概有什么”,表达不了“具体在哪”。交叉注意力能让模型在生成不同结构时分别聚焦文本里的对应词语。
3.2 三维表示:体素、点云、网格还是隐式场
这是 text-to-cad 最核心的分岔路。各种表示各有各的优缺点,我列个对比表:
| 表示方式 | 优点 | 缺点 | 适合场景 |
|---|---|---|---|
| 体素 | 结构简单,适合 CNN | 分辨率低,细节丢失严重,内存爆炸 | 快速原型 |
| 点云 | 存储高效,容易用 PointNet 编码 | 没有拓扑,不能直接进 CAD | 散装零件识别 |
| 三角网格 | 适合渲染和后处理 | 生成拓扑难,容易自交 | 视觉资产 |
| 隐式场/SDF | 能表达任意拓扑,细节好 | 提取网格麻烦,可编辑性差 | 高精度表面生成 |
| 程序化代码 | 天然参数化,可编辑性强 | 需要强约束,适用范围取决于代码模板 | 工业参数化建模 |
如果目标是“生成后修修改改就能用”,我特别推荐关注隐式场加一个后续的 CAD 化步骤。具体来说,网络预测一个带符号距离场(SDF),然后跑 Marching Cubes 提取等值面,得到一张流形网格,再交给逆向建模工具转成 CAD 实体。这条链路虽然绕,但每一步都有成熟工具兜底,不容易让模型直接生成非流形垃圾。
3.3 生成模型怎么搭
三维生成模型的主流架构现在基本被扩散模型统治,但 text-to-cad 这个场景里,GAN 和变分自编码器依然有生存空间,原因是 CAD 模型的结构通常更规整、低熵,不像自然图像那样需要极强的多样性。如果你处理的是“给定文本生成某个零件系列”,用条件 VAE 反而更稳,训练快,不容易崩。
我给一个可以跑通的最小方案:文本经过编码器得到语义向量,和随机噪声一起注入一个基于 U-Net 的三维扩散模型。扩散模型的输入是体素或隐式场的带噪版本,条件通过 cross-attention 引入。损失就是噪声重建误差,和图像扩散模型几乎没有区别。区别在数据:你需要把三维模型量化成离散的隐式场网格,训练时随机采样空间点,算它们到模型表面的带符号距离,然后监督网络预测这个距离。这其实就是 Occupancy Network 那套思路,放到扩散框架里依然成立。
如果不追求最新的扩散模型,早期 CLIP-Forge 那种做法也可以参考:用自编码器把三维模型压成隐向量,再训练一个以文本向量为条件的自回归生成器。结构简单,部署容易,效果在规整零件上意外地好。
3.4 损失函数和训练目标
损失设计决定了模型“觉得什么是对的”。单一的重建损失不够,因为 CAD 模型有大量平坦区域和锐利边界,L2 距离会倾向于模糊掉边界,把模型生成成一坨圆润的泡泡。我的做法是多损失混合:
- 几何损失:预测 SDF 值和真值的 L1 误差。L1 比 L2 对边界更友好。
- 法向一致性:随机采样表面附近的点,让预测表面法向和真实法向尽量一致,能明显改善锐边。
- 对比学习项:拉近“文本描述和对应模型”的表征距离,推开不匹配组合,防止模型对文本信息置之不理,只生成平均形状。
训练目标里还有一个被很多人忽略的点:对 CAD 模型来说,“能抽壳”“能倒角”这些可制造性约束很难写进损失函数。我看到有的团队会在生成之后接一个轻量几何检查器,检测非流形边、零厚度区域,把这些样本挑出来重新进训练集当负样本。这个操作虽然土,但非常有效。
4. 训练现场最容易翻车的几个点
4.1 文本歧义比想象中严重
一句话描述在人类眼里意思明确,在模型眼里可能完全不一样。比如“带孔的板”:“孔”是通孔还是沉头孔?“板”是长方形还是圆形?“带”是穿透还是盲孔?没有上下文时这些全是自由变量。训练时如果文本描述不完整,模型只能靠猜,于是出现“同一个提示词每次生成的形状完全不一样”的现象。
我建议在数据集的文本标注阶段就要求描述覆盖几何要素的类别、数量、相对位置、尺寸范围,至少要有“是什么、有几个、在哪、多大”四个要素。推理阶段也要引导用户输入规范描述,可以在交互界面里做一个模板提示,而不是让用户自由发挥。
4.2 模式坍塌和重复输出
早期的 VAE 和 GAN 方案特别容易输出一两个“万金油形状”,对任何文本都返回差不多结果。这本质上是模型发现“糊弄一个平均形状也能把损失降到很低”,而文本条件被丢弃了。解决办法除了前面说的对比损失,还可以在数据里强制加入“负样本对”:故意把描述和模型错配,让模型学会区分差别。比如同样是“法兰”,四孔和八孔的描述必须明确,模型输出也要拉开差距。
在扩散模型里,模式坍塌相对少见,但会出现另一面:生成结果过于依赖初始噪声,明明文本条件完全一致,只是换个随机种子,输出的结构细节就天差地别。如果希望推理阶段可复现,建议固定噪声种子,或者用 DDIM 采样减少随机性。
4.3 验证损失漂亮,实际用不成的“重建陷阱”
这是 text-to-cad 特有的坑。训练时如果文本描述和三维模型来自参数化模板,模型很容易记住模板的隐藏规则,在验证集上 IoU 很高,但一旦给一句没见过的新描述,生成结果立刻崩溃。原因就是模板数据本质上“描述和形状是一一对应的”,模型背下了映射表。
破解方法有三个:加大文本改写的多样性,让同一个形状对应多种说法;加入跨类别的模板;以及在评估时使用真正没见过的描述方式,比如让设计师写一批句子,把测试集换成人工描述。这里我特别推荐第三种,虽然成本高,但最能反映真实效果。
5. 另一条很容易上手的路线:让模型写代码
5.1 从生成网格改成生成 CAD 脚本
如果觉得从头训扩散模型成本太高,我可以明确告诉你:直接让大语言模型生成 OpenSCAD 或 CadQuery 代码,是目前工业落地最容易看到效果的一条路。原因很简单:CAD 建模的本质就是一连串带参数的布尔运算和特征操作,这些操作本身逻辑明确,很适合代码表达。大语言模型在代码生成上的能力已经相当强,缺的只是一个好用的约束框架。
比如用户输入“生成一个直径 50、高度 20 的圆柱,顶面挖一个直径 10 的同心圆孔”,OpenSCAD 的写法就是一段十几行的代码。大模型只要把数字、几何操作、参数映射到正确 API 上,输出几乎可以直接执行。这条路线对数据的需求也小,你不需要海量成对模型,可以用 CAD 脚本库加上文档描述来微调模型,数据构造难度降低了一个数量级。
5.2 用 CadQuery 弥补 OpenSCAD 的工程短板
OpenSCAD 的优点是语法简单、很容易验证;缺点是建模方式偏“魔改”,生成的模型没有特征树,后端很多软件不认。CadQuery 更接近现代 CAD 范式,它用构建脚本描述二维草图、拉伸、开孔、倒角等特征,输出可以带参数历史,更容易转成 STEP 文件。我一般推荐团队用 CadQuery 作为后端。
实际系统可以这么搭:用户输入一句描述,系统先调用大模型生成 CadQuery 脚本;然后本地执行脚本,如果执行失败或生成模型为空,就把错误信息反馈给大模型,让它重试一次;重试成功后渲染一个预览图,再让用户确认。这一套流程用“代码执行 + 错误反馈”代替了纯端到端的生成模型,每一步都可解释,修理起来也方便。以我的经验,这类系统的成功率在小范围内已经能到七成以上,剩下的主要靠提示工程和 API 选型不断调优。
5.3 代码生成路线的边界在哪
说句实在话,代码生成路线也不是万能的。它对“结构清晰、特征明确”的描述很擅长,比如法兰、支架、轴套;但面对完全自由的概念,比如“一个看起来很有科技感的异形外壳”,代码生成就无能为力了,因为根本没有对应的特征操作可以组合。这个场景还是得靠生成模型出形状,再逆向建模。所以文本转 CAD 的完整方案,大概率是“生成模型出自由形状 + 代码生成做参数化规整件”的组合,而不是二选一。
6. 怎么评估一个 text-to-cad 系统到底行不行
6.1 自动指标只能信一半
学术论文里常用 IoU、倒角距离、FID 来评估生成质量。IoU 衡量体素占位重合度,倒角距离衡量点云表面接近程度,FID 衡量生成分布和真实分布的相似程度。这些指标有一个共同问题:它们和“这个零件能不能用”没有直接关系。一个模型可能 IoU 很高,但局部有个零厚度薄片,一抽壳就碎;另一个模型 IoU 低一点,但结构合理,改两个孔位就能装配。后者在工程上反而是更好的结果。
所以我在项目里会把自动指标当作筛选器而不是裁判。先跑一批生成结果,用自动指标把明显不靠谱的淘汰掉,然后进入人工评估环节。
6.2 人工评估最有效的三个维度
给设计师看渲染图然后问“好不好看”,这个做法太主观而且不稳定。我用的评估表只有三个问题:
- 结构完整性:模型是不是一个封闭、连续、无自交的实体?能不能被 CAD 软件正常导入?
- 文本一致性:描述里的每个关键要素是否都体现在模型里?数量、位置、尺寸有没有张冠李戴?
- 可编辑性:生成结果能不能很容易地在 CAD 里改一个参数,比如孔的数量或直径?
这三个维度分别对应生成模型最容易犯的三类错误:拓扑崩坏、语义丢失、不可参数化。用它们做人工评估,不同评估者之间的打分一致性会高很多。
6.3 可制造性检查必须前置
工业场景在评估环节还有一个杀招:直接跑一遍可制造性检查。比如用软件检查模型的最小壁厚、拔模角、干涉区域。这些检查对生成网络是“看不见的惩罚项”,如果不在评估流程里设置,模型永远不会主动朝这些方向优化。我们团队的做法是把这些检查软件打包成自动化脚本,每训练一个 checkpoint 就随机抽 200 个生成结果跑一遍,把失败率当作一个额外指标记录。这个指标在训练曲线上的变化,往往比 FID 更有说服力。
7. 一个实用的工程建议和我的个人体会
做这个领域两年多,我最深的体会是:text-to-cad 不要追求一步到位。不要指望一个端到端模型吃遍天下,更值得投入的是把模型、脚本引擎、规则检查器、人工反馈串成一条自动化管线。每一层做好自己的事,整体效果才稳。
在实际项目里,我的建议是先做一个小闭环。选一个零件品类,比如法兰类或支架类,收集足够数据,跑通“文本到脚本到网格到导入 CAD”的完整流程,哪怕生成质量粗糙也没关系。闭环跑通后,再逐步换更好的模型、更丰富的描述数据、更严格的质量检查。前期把精力花在数据清洗和评估体系上,收益会比死磕模型结构高得多。
最后分享一个小技巧:把交互界面里的提示词设计好,实际上能解决一半模型错误。比如让用户必须输入“类别、主体尺寸、孔/槽的数量与位置、额外特征”四个字段,系统再用模板拼成完整描述。这样做,模型不需要理解天马行空的散文,只需要做有限的填词和组合,稳定性会立刻上一个台阶。这个技巧听着简单,但效果好得惊人,我建议每个刚开始做 text-to-cad 的人都先把它加上,再谈更复杂的模型改进。