先聊聊现在做3D生成的人都在盯的一个方向:text-to-cad。这个方向的目标很直接,就是你输入一句话,比如“一个带四个圆孔的矩形法兰盘”,模型直接给你吐出一个可编辑、可制造、带完整特征树的CAD模型,而不是一张图片,也不是一个网格。
这个难度比text-to-image高了一个数量级。图像生成只需要在像素空间里做映射,模型自由发挥的空间很大;CAD模型是严格参数化的,面与面之间有拓扑关系、有约束、有特征历史。差一个毫米就是废件。所以text-to-cad本质上不是“画图”问题,而是“程序合成”问题——模型要从自然语言里理解设计意图,再把它翻译成一段可以被CAD内核执行的建模指令序列。这也是它最近两年在学术圈和工业圈同时火起来的原因。
这篇文章我把这个方向的来龙去脉、主流技术路线、实操训练流程和踩过的坑一次性讲清楚。不管你是有CAD二次开发背景的工程师,还是做深度学习想切3D方向的研究者,或者纯粹想评估这个技术能不能落到自己产品里的技术负责人,都能在这篇里找到对应的参考。内容会偏工程视角,尽量避免当成论文解读来写。
1. text-to-cad的核心难点与整体解决思路
1.1 为什么text-to-cad比想象中难
先拆解一下问题本身。CAD模型和普通3D网格最大的区别在于,CAD模型是“有历史”的。一个机械零件在建模软件里通常是由一系列操作叠加出来的:先画一个草图,然后拉伸,布尔运算切掉一块,再加圆角,最后打孔。每一步操作都依赖上一步的几何基准,这种依赖关系构成了特征树。特征是CAD的灵魂,下游的尺寸标注、工程图生成、CAM编程全部依赖这些特征信息。
如果模型直接输出一个STL网格,那它在机械制造流程里几乎是废的——没法改参数、没法出工程图、没法做CAM仿真。所以text-to-cad的核心目标不是“生成一个形状像的东西”,而是“生成一个符合建模逻辑、特征可解析、参数可修改的B-Rep实体”。
这就带来了第一个难点:输出空间不是连续空间,而是一个离散的建模指令序列。你要让模型学会的是怎么在CAD内核里“操作”,而不是怎么“画”。比如要让模型生成一个圆柱体,它不能直接输出三角形网格,而要输出“圆心坐标、半径、高度”加上一个“拉伸”操作。这种序列化CAD操作的方式,在行业内有个专门说法叫“程序化建模”。模型本质上是在做代码生成,只不过这门“语言”是CAD内核的定义语法。
第二个难点是自然语言到三维空间的语义对齐。自然语言描述是高度抽象的,“一个L型支架”这句话在人的头脑里能补全出无数细节——厚度多少、孔位在哪、圆角半径多大,这些信息在文本里根本不存在。模型必须在缺失信息的情况下做出合理猜测,而且这个猜测必须落在合法的参数区间里。同样一句描述,在草图上对应哪个平面、拉伸方向朝哪边,都要模型自己推断。
第三个难点是评估指标难以定义。图像生成可以用FID、IS这些指标量化。CAD生成怎么看?IoU只能衡量几何形状的相似度,但两个几何形状完全一样、特征树顺序不同的模型,在工程上的价值天差地别。业内目前还在摸索一套既能衡量几何正确性又能衡量特征合理性的评价体系,这也是这个领域进展看起来“慢”的原因之一。
1.2 当前三条主流技术路线
围绕上面的难点,目前主流做法可以分成三大流派,各有利弊。
第一条路线是基于草图-拉伸序列的监督式生成。这是学术界研究最多的一条路。思路是把已有CAD模型全部解析成“草图+拉伸+布尔+圆角”的命令序列,然后用Transformer或类似序列模型来做文本到命令序列的翻译。比较有代表性的工作是把CAD模型数据解析成边界表征(B-Rep),再把边界表征转成程序化建模的指令流,然后训练一个自回归模型来生成指令。它的优点是生成结果天然是B-Rep实体,可以直接导入CAD软件进行编辑。缺点是严重依赖解析器的质量,模型只能生成数据集中出现过的建模模式,泛化性受限于训练集的覆盖范围。
第二条路线是基于大语言模型的程序化生成。这条路线在2023年之后突然火起来,核心思路是绕开“从CAD模型提取命令序列”这一步,直接把文本输入送给大模型,让大模型生成一段程序化建模代码。这些代码运行在CAD内核上,由内核完成真正的几何建模。现在一些开源项目就是把代码生成能力与参数化建模内核组合起来,效果相当惊艳。这条路的优点是对数据的需求大幅降低——大模型已经预训练过海量代码,只需要微调少量CAD建模代码示例就能泛化。缺点是生成质量不稳定,代码偶尔会算错坐标,经常需要多次采样和容错机制。
第三条路线是基于三维隐式场的文本引导生成。这条路线是用文本嵌入作为条件,用扩散模型或自回归模型直接在体素空间、占用场或符号距离函数(SDF)场里生成几何,再把隐式场通过后处理转成网格。这条路线生成速度快、几何形态灵活,适合自由曲面和概念设计场景。但它有个致命弱点——生成结果是网格,不是可编辑的CAD实体。下游要用的话还得再做B-Rep反向重建,这个重建过程目前精度损失很难控制。
1.3 从事的角度怎么选路线
如果你是企业里准备落地的工程师,我的建议很明确:优先看第二条路线。理由很现实,监督式生成那条路线对数据的要求太高。要把几万个CAD模型都转成高质量命令序列,数据清洗工作量足以让团队崩溃。而大模型路线不需要操心解析器的准确率,只要建好代码模板库和验证机制,工程化难度小一个量级。
从技术成熟度上看,目前业界最好的结果也主要集中在“简单机械零件+标准特征”这个范围内。带自由曲面的消费电子产品、复杂型腔的模具件,还远远做不到端到端生成。所以评估方案预期要务实:先把范围限定在“标准件/通用件快速建模”这个场景里,才可能真正跑通。
2. 核心模块拆解:命令序列、模型架构与数据构建
2.1 命令序列:如何把一个CAD模型变成一段“程序”
前面提到,text-to-cad的一个核心任务是让模型学会输出“可以执行的CAD建模指令”。这里的关键是定义好指令集的粒度。
指令集设计有粗有细。粗粒度的设计是直接定义高阶特征,比如“绘制矩形”“拉伸”“打孔”“倒角”。每一条指令对应CAD软件里的一个特征操作。这种设计优点是生成结果特征语义清晰、后处理方便,缺点是需要海量标注数据来学会特征与特征之间的组合规律。
细粒度的设计则是把建模过程拆到更底层,比如直接在指令里指定草图的每一条边、每个圆弧的半径和圆心坐标。这种设计更灵活,能表达复杂的草图轮廓,但模型学起来难度大,输出长度长。用Transformer这类模型在这种超长序列上训练,容易出现累积误差——一个坐标错,后面的几何全错。
我个人的实践体会是:指令集不要完全自己拍脑袋定,建议直接采用业界成熟方案。目前做得比较好的开源CAD解析器可以反编译B-Rep模型,输出结构化的操作步骤。它会把一个拉伸体分解为“平面选择、草图轮廓、拉伸深度、布尔类型”这样的完整信息。在它基础上做一层文本映射,工作量会小很多。
配合指令集设计,还有一个Token化的问题。几何数值要离散成Token才能输入语言模型。这里的技巧是不要用绝对坐标直接编码,而是用相对坐标、归一化参数,并且把数值范围压缩到合理区间。我当时训练时踩过一个坑:直接用原始毫米做编码,模型生成的坐标值频繁越界。后来把整个模型做单位化,再对数值做分桶,问题才解决。
2.2 模型架构选择:Encoder-Decoder还是纯Decoder
确定了输出是指令序列,模型架构的选择就清晰了。目前主流做法是基于Transformer的Encoder-Decoder架构,或者纯Decoder的架构。
Encoder-Decoder的好处是输入侧和输出侧可以不对称。输入侧用预训练的文本编码器把自然语言编码成语义向量,输出侧再用自回归解码器逐步生成指令Token。文本编码器可以加载现成的预训练模型,训练时冻结或者低学习率微调,能有效降低训练成本。
纯Decoder的架构则更符合当前大模型的主流做法,把文本和指令拼接成同一个序列做自回归建模。好处是架构统一、代码实现简单,坏处是需要更大规模的语料才能学到文本到指令的对齐关系。在数据量不过万级的情况下,纯Decoder的训练难度明显偏高。
我的操作建议是:如果你是第一次在自有数据集上做实验,先拿Encoder-Decoder跑通Baseline。数据量不足两万条的情况下,它的收敛速度和稳定性都更好。等数据积累到一定规模再切换纯Decoder做扩展,收益会更大。
2.3 数据管道:从模型库到文本-指令对
整个项目里最耗精力的部分一定不是调模型,而是造数据。
第一步是拿到CAD模型文件,从中解析出B-Rep信息和操作历史。第二步是把操作历史转成指令序列。第三步是给指令序列配文本描述。前两步可以通过解析工具半自动完成,第三步则需要大量自动化脚本加人工校验。
文本描述的生成是一个容易被低估的环节。比较好的做法是采用“模板+属性抽取”的方式自动生成描述,保证每一条指令都有对应的中文或英文文本。比如解析出一个零件有4个孔、厚度8毫米,就自动拼成“厚度8mm的板上分布4个通孔”。这种自动生成的文本虽然不够“自然”,但胜在覆盖率高、成本低,对模型训练来说完全够用。条件允许的话,再雇人把一部分文本改写成人话,用做数据增强。
整个管道跑完后,一定要做指令合法性校验。校验方法是把生成的指令序列重新喂给CAD内核执行,能成功构建出实体、并且与原始模型的形状误差在阈值内,才算一条有效数据。这个环节不能省,模型大量正样本以合法指令为主。
3. 实操细节:训练一个text-to-cad项目的完整流程
3.1 环境准备与工具链选型
开始动手前,先把工具链搭好。
文本编码器建议直接使用开源的预训练语言模型,某个轻量级的中文或英文编码模型都可以。这一类模型的优点是在文本语义理解上已经有了不错的基础,微调成本低。对于CAD指令解码器,可以选用标准的Transformer解码器,6到8层就足够起步,再深对当前数据规模反而容易过拟合。
几何处理部分需要一个能读取CAD模型的库,建议直接用工业级的CAD内核封装,而不是自己写几何解析器。市面上常见的几个CAD内核社区版、开源解析库都可以用,选型的核心标准是两点:能不能可靠读取STEP/IGES格式,能不能执行布尔运算和生成B-Rep。这两点直接决定数据管道的成败。
我个人建议初学者直接从公开的CAD模型数据集起步。某开源数据集合集了大量从社区抓取的机械零件CAD模型,数量级在十几万个,足够支撑一个最小可行的实验。不要一上来就用自己的私有模型库,先把全流程跑通再说。
3.2 数据预处理的关键细节
清洗原始模型数据这一步,比想象中要脏。CAD模型文件里混入了大量曲面模型、钣金件、装配体,这些在第一步就要通过脚本全部过滤掉。过滤规则可以很简单:只保留能够被解析器完整解析成B-Rep实体的零件文件。解析失败或产生奇异几何的直接丢。
数值Token化这一步做得好不好,直接影响下游训练。推荐的做法是把所有几何参数标准化。长度值除以包围盒的对角线长度,把数值范围压缩到0到1之间。角度值做归一化到0到2π。标准化后再做分桶编码,比如每个连续数值离散成200到500个桶位。桶位太密模型学不进去,太疏几何精度又不够,要根据数据分布调几次才能找到合适的点。
数据补齐之后做一个训练/验证/测试集划分,注意按“模型来源”划分而不是按“样本数”划分。同一批机械设计文件会有大量相似零件,混在一起划分容易导致评估失真。这个坑我是在项目中期才发现的,前期测试集表现虚高,换成按来源划分之后指标立马回落,后面所有实验结果都以这种方式重新评估。
3.3 模型训练:参数与策略心得
训练配置参考以下经验值。Batch size不要开太大,CAD指令序列普遍较长,显存占用明显,一般够用就行。学习率建议用带预热和衰减的调度器,峰值学习率设置在较小量级,对Transformer类模型比较安全。
文本编码器训练时的处理方式要区分阶段。第一阶段冻结文本编码器,只训练解码器,等解码器学会基本的指令语法之后,再解冻文本编码器做联合微调。这样做的好处是前期训练稳定,不容易出现文本侧灾难性遗忘。实际跑下来这个两段式策略比一上来就全量微调的效果稳定得多。
训练结束之后做生成测试时,采样策略采用“束搜索+长度惩罚”组合效果比较好。纯贪心解码经常生成残缺的指令序列,问题主要出在几何坐标的累进错误上。束搜索宽度可以设大一点,配合适当的长度惩罚,生成完整性和几何正确性都有提升。我自己试下来的组合是束宽加一定的长度惩罚系数,用验证集上的重建成功率来定参数。
3.4 推理与后处理:从Token序列到可编辑CAD
模型输出Token序列之后,还差最后一步——转成完整体现到CAD软件里。
步骤很简单:把指令序列交给CAD内核按顺序执行,每一条指令对应一个建模操作。执行完成后再做过闭合检测,确保生成的模型是水密实体,不出现开放面片。测试脚本里可以用几何内核的检查函数自动判断。如果是开放实体,最简单的处理是丢弃整个生成结果重新采样,不要尝试做自动修补——修补这一步的复杂度不一定比重新生成低。
后处理阶段还要做参数校准。模型生成的数值经过桶编码离散化,精度有限,在工程应用场景不够用。做法是执行完基本建模操作后,再用优化算法把关键尺寸微调到目标值。比如“孔间距30毫米”这个语义,模型生成的可能是29.8毫米,这时在原始指令上做一个局部参数优化即可,不需要重训模型。
4. 文本-指令数据集的构建与扩展策略
4.1 自动生成描述与人工润色的结合
文本描述质量直接影响模型的上限。自动生成描述的正样本有“机器味”重的特点,模型可能学会固化句式而不是理解语义,导致换个说法就生成失败。
我采用的模式是“机器为主,人工为辅”。先把所有样本用脚本自动生成描述文本,再从中抽取固定比例的样本做人工改写,把“厚度为8毫米的矩形板上有4个直径10毫米的通孔”这样的描述改写成“一块长方形的板,四个角上各打一个螺丝孔”。这样模型的语义空间不至于过于狭窄,在真实用户输入上也能表现出更好的抗变体能力。
中文技术社区里做这个方向的团队还很少,大部分开源数据都是英文。如果你做的是中文产品,建议在数据管道里单独加一个“中文化”步骤。简单做法是准备好专业术语映射表,把“extrude→拉伸”“fillet→圆角”“chamfer→倒角”,再配合模板生成中文描述。中文化的成本不高,但对产品的终端体验影响明显。
4.2 数据增强与长尾问题处理
CAD数据集的长尾问题非常严重。大量零件集中在少数几种形状类型,比如法兰盘、轴类件、轴承座,而复杂型面零件极少。模型很容易在这类头部数据上过拟合,长尾数据则完全学不到。
有效缓解办法有两个。第一个是对头部类别做欠采样,限制每个类别的最大样本数。第二个是对长尾类别做复制增强,用参数随机化对已有模型做微小改动——改孔径、改圆角半径、改板的长度,生成一批“同结构、不同尺寸”的变体。这样做既丰富了数据量,又不破坏特征结构的合法性。
更进阶的做法是主动构造“组合式描述”。把一个零件拆成多个局部特征,各自配上独立的描述文本,再自动合并成“描述A,并且描述B”的复合文本。这种数据能诱导模型学会分步生成和局部组合,对后续生成复杂零件有很大帮助。这也是我目前用来提升模型复杂件生成能力最有效的手段。
4.3 数据质量评测清单
给数据集做质检时,直接沿用设计阶段的验收标准。指令序列转模型后要跑几个基本测试:实体检查、面数量比对、体积与原始模型误差、特征数量一致性。只有全部通过的样本才被认为是高质量数据。实际执行过程中,自动化检查通过率一般在七成左右就算不错,剩下的需要人工排查是解析问题还是原始模型本身有缺陷。
注意:不要只看“解析成功率”,要看“重建精度”。很多模型文件虽然能解析出指令序列,但重建出来的实体和原始模型已经差之千里。这类样本放进训练集等于给模型灌输错误知识。
5. 常见问题排查与经验记录
5.1 生成结果不收敛或Loss震荡
常见原因有三个:数据里混入了大量非法指令序列,模型为了拟合噪声导致梯度不稳定;数值Token化分桶太密,模型很难在这么多类别里学到规律;学习率过大,Transformer类模型对这种离散序列输出特别敏感。
排查顺序建议先清洗数据再做参数调整。把训练集里所有样本跑一遍重建测试,删除重建失败的数据,光这一步就能解决大半问题。如果清洗后仍然震荡,检查分桶数量,适当降低桶位数,模型更容易收敛。
5.2 生成结果可看但不可用
所谓“可看”,指的是渲染出来像一个零件;“不可用”,指的是导入CAD软件后特征树乱成一团或者根本无法编辑。
根因在于训练数据里指令序列顺序不统一。同样的零件,有人先打孔后倒角,有人先倒角后打孔。模型学到的是“统计平均”,但特征顺序是敏感信息。我的解决办法是做指令顺序标准化,统一成“先草图、再拉伸、再特征操作(打孔/倒角/阵列)”这个固定顺序。标准化之后生成的模型特征树干净很多,编辑友好度大幅提升。
5.3 长文本描述输入时生成完全失败
用户输入的描述往往比训练数据长得多,且包含大量与几何无关的修饰词,比如“这是一块安装在设备底部的支撑板”。模型对这类输入泛化性差,输出指令序列经常半途断掉。
一种有效对策是输入侧做“语义裁剪”。用语言模型把用户输入先压缩成训练数据里的描述风格,再去生成CAD指令。相当于在前面加一层“转述器”,把口语翻译成设计语言。我实测下来,这种做法比直接拿着原始长文本生成的成功率高不少。
实操总结与经验沉淀
这个方向在现阶段依然很早期,没有现成的、拿来即用的产品级解决方案。但整个流程跑下来我个人最大的体会是:做text-to-cad的核心瓶颈从来不在模型结构,而在数据管道和评估基建。数据管道干净、评估标准合理,模型哪怕用很常规的Transformer都能得到不错的结果;反过来,数据脏、评估靠肉眼,再花哨的模型架构也只是在错误的方向上加速。
如果你正准备动手,我的建议是先把数据管道跑扎实,能用脚本自动完成从模型文件到文本-指令对的转换,再开始碰模型训练。另外,在设定预期时不要贪多求全,优先锁定一类零件(板类件、轴类件、法兰类都是不错的切入点),把这一类做到可用,再考虑扩展。
后续这个方向可以延伸的东西也很多,比如反方向做CAD-to-text(模型描述自动生成)、用户的实时交互修改、与CAM/CAE流程的打通。每一步都有工程价值。希望这篇经验能帮你少踩几个坑,省下几个月摸索的时间。