第一次看到 text-to-cad 这个方向时,我第一反应是:如果自然语言真能直接变成可编辑的三维模型,那设计师是不是终于可以把重复的建模工作丢给机器了。实际研究了一圈之后发现,这个领域比想象中复杂得多,但也比想象中有价值得多。它解决的并不是“生成一张好看的渲染图”,而是把人的工程意图转成下游真正能用的参数化模型,也就是带特征树、带尺寸、能改参数、能出工程图的那种模型。
这篇文章我会从底层表达、方案选型、完整实操、效果评估到常见坑位,把 text-to-cad 这个方向彻底拆开讲清楚。适合正在做 AI+CAD 交叉方向的研究者、想给团队引入智能建模能力的工程师,以及只是好奇“一句话生成模型到底靠不靠谱”的读者。内容会保持技术向,但尽量说人话,能直接抄作业的步骤我不会省略。
1. 先别急着跑模型:text-to-cad 到底在生成什么东西
很多人第一次接触这个方向,会把 text-to-cad 和 text-to-3D(比如生成 NeRF、网格模型)混为一谈。两者最大的区别不在“输入”,而在“输出”。
1.1 产出的不是形状,而是一棵可编辑的特征树
text-to-3D 类任务输出的是网格、点云或者神经隐式场,本质上是“形状的近似表达”。你拿到一个 STL 文件,能看、能渲染、能 3D 打印,但没法改尺寸、没法拖拽特征、没法把它送进 CAM 做刀路规划。工程师一看就知道这东西在实际生产线里基本不可用。
text-to-cad 的目标完全不同。它想产出的是一个“参数化实体模型”,底层基于 B-Rep(边界表示)或特征历史,打开之后能看到这个模型是由哪些草图、拉伸、切除、倒角、阵列构成的。你改一个孔的直径,后面的圆角、阵列位置会自动联动。这在 CAD 术语里叫“参数化驱动”,是工程软件的基本功,也是 text-to-cad 和普通三维生成最大的分水岭。
可以这样类比:文生图是给画家一句描述,让他画一幅画;text-to-cad 是给木匠一张带尺寸标注的图纸,木匠照图施工,做完还能反过来调整图纸。画可以有一点艺术发挥,图纸不行。
1.2 从自然语言到 CAD 模型,中间隔着三层转换
一句“做一个长 60、宽 40、高 10 的平板,上面均匀分布四个直径 8 的圆孔”,听起来很直观,但模型要处理三层信息:
- 第一层是语义理解:识别“平板”是一个长方体拉伸件,“圆孔”是通孔,“均匀分布”暗示阵列或对称约束。
- 第二层是几何推断:四个孔的位置怎么排?是四角布置、单排布置还是 2x2 阵列?如果没有更多描述,需要按工程常识补默认值。
- 第三层是参数化表达:把上面的理解翻译成具体的建模操作序列,比如“新建草图 > 画矩形 60x40 > 拉伸 10 > 在四个角点画圆 > 切除贯穿”。
这三层转换恰恰是问题的核心。自然语言是高度歧义的,“均匀分布”在不同人脑子里可能是完全不同的排布方式,但 CAD 模型必须给出确定的坐标和参数。所以 text-to-cad 并不只是“语言生成模型”的问题,它同时是几何推理问题和参数化表达问题。
2. 方案选型:为什么大家都用“特征序列”而不是直接输出网格
早期也有工作尝试让模型直接回归网格顶点坐标,或者生成体素场再转换。这类方案放到 CAD 场景里几乎是灾难,原因很简单:网格模型没有特征信息,转成 B-Rep 极其困难,而且拓扑稍微复杂一点就会出现破面、缝隙、非流形边。对于生产环境,这种结果没法用。
2.1 特征序列表示法与 DeepCAD 的启发
目前 text-to-cad 的主流表示方法,很大程度上受到了 DeepCAD 这类工作的启发。核心思路是:把 CAD 模型的构造过程表示成一个有序的操作序列,每一步是一个带参数的建模原语,比如:
- Extrude(拉伸):需要一个草图轮廓和拉伸高度;
- Revolve(旋转):需要一个截面轮廓、旋转轴和角度;
- Fillet / Chamfer(倒圆角 / 倒角):需要指定边和半径;
- Cut(切除):本质上是布尔减运算;
- 布尔合并:把多个体素组合成一个实体。
这样一个法兰盘可以表示成:画草图圆 → 拉伸成圆柱 → 画底部矩形 → 拉伸 → 合并 → 选择边倒圆角。整个过程很像一个简化版的“建模操作日志”。
为了让神经网络能处理,这些操作和参数需要被离散化成 token。拉伸高度 5.0 可能对应某个 token,4.8 对应另一个 token。整个模型的构造历史就变成了一长串离散符号序列,类似于自然语言里的句子。于是问题被转换成一个条件序列生成任务:输入文本,输出一段 token 序列,解码后再交给 CAD 内核重建出实体模型。
2.2 为什么选择“序列”而不是“直接回归参数”
有人可能会问:既然最终要的是参数,为什么不直接让模型回归参数数值,非要绕一圈转成 token 序列?
一个原因是 CAD 模型的结构是变长的。两个模型的操作数量、草图复杂度完全不一样,直接回归固定维度向量根本行不通。另一个原因是“多解性”。同一个零件可以用拉伸加切除实现,也可以用旋转加倒角实现,两种特征序列都合法。序列生成天然适合这种多模态输出,而回归模型通常只能给出一个平均值,这在几何上是灾难级的错误。
token 化的另一个隐藏好处是:可以直接借用大语言模型里成熟的序列建模工具。Transformer 解码器、beam search、token masking 这些技术全都能迁移过来,省去了大量自创方法的工作量。
2.3 文本编码与条件注入
有了特征序列,剩下的问题就是怎么把文本“灌”进模型。最常见的做法是双编码器结构:
- 文本侧用预训练语言模型(比如基于 Transformer 的编码器)把自然语言描述编码成向量或 token 序列,保留语义信息;
- 序列侧用自回归解码器,在每一步生成下一个特征 token 时,通过 cross-attention 机制去参考文本上下文。
训练时用大量“文本描述 + CAD 特征序列”配对数据做监督。文本描述越贴近真实工程师的表述,模型学到的对齐关系越可靠。实际使用中我也建议对输入文本做一些预处理,比如固定单位描述、统一“孔”“圆孔”“通孔”这类叫法,能显著减少模型的理解偏差。
这里要泼一盆冷水:现阶段不要指望通用大模型直接端到端生成高精度 CAD 几何。语言模型擅长语义理解和逻辑推理,但“精确到 0.01mm”这件事它做不好,而且大模型输出的是文本,不保证合法拓扑。更务实的做法是把大模型当作调度器,让它在理解需求后调用我们上面说的专用 text-to-cad 网络或参数化模板库,最终几何交给 CAD 内核完成。
3. 完整实操路径:从一句自然语言到能打开的三维模型
下面讲一条我自己实践过多轮的端到端流程。整体思路是:数据准备 → 模型训练 → 推理重建 → 校验导出四步走。
3.1 端到端流水线长什么样
一个可落地的 text-to-cad 系统一般长这样:
- 输入文本,先做清洗和标准化,比如统一单位、补全默认厚度等缺失信息;
- 专用生成网络把文本编码成特征 token 序列;
- 序列经过合法性过滤(比如剪掉非法布尔、检查参数范围),交给 CAD 内核重建;
- 在 CAD 内核里做几何验证,确认体积非零、无自交、无零厚度面;
- 导出 STEP、FCStd 等下游可用格式。
听起来简单,但每一步都能卡住你半天到一周,后面我专门讲坑。
3.2 数据准备和训练样本构造
text-to-cad 最大的瓶颈不是模型结构,而是数据。
公开可用的高质量数据首先是 DeepCAD 这类数据集,里面包含大量从真实 CAD 软件导出的建模历史记录,格式就是前文说的特征序列。这些数据非常宝贵,因为它们是“构造过程”,不是最终形状。有了构造过程,模型学到的才是“怎么建模”,而不是“形状长什么样”。
困难在于文本描述。原始 DeepCAD 数据没有文字说明,需要自己造配对语料。常见做法有三种:
- 模板生成:定义一些固定句式,把参数填进去,比如“一个长{length}宽{width}高{height}的{shape_type},带{num}个直径{diameter}的圆孔”。
- 程序合成:根据特征序列自动反推可能的自然语言描述,再用同义词替换扩充表达多样性;
- 人工改写:把模板句改成口语化表达,让模型适应真实世界的输入,而不是只认死格式。
我强烈建议不要跳过数据清洗。训练之前必须做几何合法性检查,比如用 Open CASCADE 内核加载每个序列、执行特征操作、检查结果是否有效。模型生成出来的垃圾序列多半来自训练集里混入了失败的建模历史,源头脏了,后面怎么调结构都白搭。
3.3 模型推理与后处理
推理阶段的伪代码大致是下面这个流程,不是某个特定框架的代码,但结构可以复用:
# 伪代码示例:text-to-cad 推理主流程 text = normalize_input("long 60 wide 40 thick 10 plate with four 8mm holes") text_vec = text_encoder.encode(text) # 自回归解码,生成特征 token 序列 for step in range(max_len): token = decoder.generate_next_token(text_vec, previous_tokens) if not is_valid_partial(token_sequence): # 参数越界或非法操作,触发过滤/回退 token = fallback_token() sequence.append(token) # 交给 CAD 内核重建实体 cad_doc = cad_kernel.new_document() for op_token in sequence: cad_doc.execute(op_token.to_cad_command()) # 几何校验 if not cad_doc.validate(): cad_doc.repair(min_fillet=0.1, tolerance=1e-3) cad_doc.export("output.step")解码阶段建议用 beam search,不要用贪心解码。贪心解码每一步只取概率最大的 token,但 CAD 序列是强结构化的,某个位置选错一个参数,后面整个几何就会崩掉。beam search 保留多个候选序列,最后在候选里按“合法性 + 文本相关度 + 长度惩罚”排序,成功率会高很多。
后处理阶段,模型输出的 token 序列还不等于实体模型。你需要把每个特征操作映射到 CAD 内核的命令,这一步通常基于 Open CASCADE 或者 CadQuery。CadQuery 的好处是代码就是建模指令,模型生成的序列可以直接翻译成 CadQuery 语句,非常顺。重建完成后再用内核做一次布尔运算检查和体量检测,凡是体积接近零或者面数异常的输出,一律打回重生成。
3.4 我的建议最小验证集
训练完第一个模型,别急着上复杂样例。建议先人工准备 8 个标准描述,覆盖最基本的特征组合:
- “长 60 宽 40 高 10 的平板,四个直径 8 的圆孔均匀分布”
- “直径 30 高 50 的圆柱,底部有半径 3 的倒角”
- “边长 20 的立方体,顶部切一个 10x10x5 的矩形槽”
- “直径 40 的圆盘,中心有一个直径 10 的贯穿孔”
- “长 100 宽 60 高 8 的底座,四角有直径 6 深 5 的沉孔”
- “六角形柱体,对边距离 24,高 30,中心贯穿孔直径 12”
- “两块垂直相交的板,厚度均为 5,相交处有半径 2 的圆角”
- “直径 25 高 30 的轴,一端有半径 4 的倒角,另一端有 20mm 长的 M16 螺纹段”
这组提示词覆盖了拉伸、切除、阵列、倒角、旋转、布尔合并这些基本特征类型。如果这几个都不能稳定生成,说明底子还没打好,不需要急着上复杂装配体。
4. 效果怎么评:光看渲染图是远远不够的
很多生成模型的评估方法到了 CAD 场景都要重写一遍。渲染好看不代表模型能用,真正的考核标准是“能不能进下游流程”。
4.1 几何精度类指标
最常用的几何指标还是体素 IoU 和 Chamfer Distance。IoU 衡量两个实体在三维空间中的重合程度,公式就是交集体积除以并集体积,数值越接近 1 越好。Chamfer Distance 则比较两个形状表面点云之间的平均最近距离,用来刻画“局部是否贴合”,单位是毫米,越小越好。
这两个指标需要把重建出的 B-Rep 模型离散化后才能计算,实际操作中一般通过网格化或者点云采样完成。注意两个指标口径差异很大,IoU 对整体形状贴合敏感,Chamfer 对细部偏差敏感,建议两个都报,不要只挑好看的那个。除此之外还有边缘 F1,专门衡量面与面之间的棱边是否对齐,适合判断圆角、倒角这类细节是否到位。
4.2 语义和合法性指标
几何贴合只能说明“形状像”,不能说明“建模过程对不对”。一个更关键也更容易被忽略的指标是特征树合法性,也就是模型生成的序列交回 CAD 内核重建时,有多大比例能成功构建出有效实体。这个比例直接决定了系统的自动化上限。实测中很多模型看起来 IoU 不错,但重建率只有 20%,因为输出序列里有非法草图、非法布尔操作,内核直接报错。
文本语义对齐也需要单独评估。可以把生成的 CAD 模型渲染成多视角图,再用 CLIP 类模型计算与输入文本的语义相似度;也可以设计一个简单的 CADScore:按输入文本里提到的关键约束逐项打分,比如是否包含“四个孔”、“倒角半径是否为 3mm”、“底座尺寸是否 100mm”。这个规则化评分比纯粹的 CLIP 分数更能暴露问题,建议两个结合。
4.3 失败模式分类
我自己习惯把生成结果分成四类:
| 分类 | 表现 | 常见原因 |
|---|---|---|
| 完全无效 | 内核无法重建,序列执行直接报错 | 非法布尔、草图自交、参数越界 |
| 拓扑错误 | 能重建但出现零厚度面、破面、非流形边 | 训练数据不干净,或后处理容差设置不当 |
| 语义偏离 | 形状完整但和文本描述对不上 | 文本编码弱、语料模板过少 |
| 参数漂移 | 结构对了但尺寸偏差大 | 尺寸 token 量化粒度太粗、损失函数未加权 |
四个类别的占比比单一分数更有指导意义。如果“参数漂移”占大头,说明模型结构没问题,是数值精度不够,可以调 token 量化或损失权重;如果“完全无效”占大头,那问题大概率出在数据清洗和后处理校验上。对症下药才高效。
5. 踩坑实录:我这几个月被卡住的地方
这个方向上能踩的坑实在太多,我挑几个最典型的展开讲,每个都是我实际体验过或看过别人反复摔倒的地方。
5.1 数据清洗不干净,训练出来的模型只会生成废料
最让我崩溃的一次经历:模型训练了几天,测试时发现大量输出在重建阶段报错,打开错误日志一看,全是“自交面”、“非法实体”、“布尔运算失败”。排查到最后,根子在训练数据。公开数据集里有一部分建模历史在原始 CAD 软件里就是失败的,或者步骤之间的参数是不自洽的,比如先拉伸出一个长方体,再尝试切除一个完全不在体内的圆柱。
解决办法只有一条:训练前做全量几何合法性清洗。用 Open CASCADE 或 CadQuery 把每个训练序列完整执行一遍,捕捉异常并把失败样本剔除。这个步骤很耗时,但绝对不能省。顺便说一句,光靠“能不能执行成功”还不够,还要做参数统计分析。比如如果数据集里拉伸高度的分布是 0.5mm 到 500mm,而你的文本样本里大量出现“厚度 3mm”,那就需要做对数空间重采样,避免模型对高频尺寸过度拟合。
5.2 尺寸漂移:模型总是往“平均尺寸”靠
我一开始训练出来的模型有个很烦人的毛病:你让它生成长 200mm 的板子,它给你输出 120mm;你让它生成长 20mm 的板子,还是 120mm 左右。原因不复杂,序列生成模型在尺寸 token 上的分布很不均匀,训练集中间尺寸样本多,小尺寸和大尺寸样本少,模型自然学会了“均值偏移”。
解决思路有几个,可以叠加使用。首先是对尺寸值做 log 变换后再分桶,避免大尺寸主导损失;其次是按尺寸区间做训练集重采样,保证每个区间样本量接近;最后是在损失函数里给尺寸误差更高的权重,让模型意识到“尺寸错了比形状错了更严重”。这三个组合拳打下来,我这边尺寸漂移问题降了大概一半。
5.3 布尔运算退化:共面、切边与零厚度
CAD 建模里布尔运算本来就是最容易出事的环节,在生成模型里这个问题被放得更大。模型生成的切除圆柱可能与主体表面刚好共面,或者与已有特征相切,内核执行布尔运算时会出现数值不稳定甚至崩溃。
我的经验是两条路并行:训练阶段在数据里增加“最小偏移”约束,比如孔的中心不能距离边界小于某个阈值,厚度不能低于 1mm;推理阶段加上拓扑安全规则,凡是被判断为共面、相切、零厚度的操作直接拒绝并触发重新采样。另外,模型输出的坐标值不要直接拿去做布尔,先做四舍五入对齐到网格(比如 0.01mm 精度),能避免大量浮点噪声导致的拓扑退化。
5.4 长序列生成崩溃
CAD 操作序列可以很长,一个中等复杂零件可能有上百个 token。自回归模型在长序列上很容易出现“跑偏”,前面的某一步选错了操作,后面全盘皆输,而且越到后面错误越不可挽回。
应对方案我实验下来最有效的是课程学习:先训练短序列(比如少于 20 个 token)的样本,模型稳定后再逐步加入长序列。推理阶段用 beam search 同时限制起始 token,比如强制第一个 token 必须是某个拉伸操作而不是倒角,等于给模型装了一个“建模规范”的前置条件。还有一个技巧是在解码序列末尾增加特殊的“结束特征” token,让模型自己判断什么时候该停,否则模型会把简单零件先生成到一个荒谬长度。
5.5 问题速查表
| 现象 | 可能原因 | 排查顺序 |
|---|---|---|
| 重建成功率极低 | 训练数据含有非法序列 | 先跑一遍全量几何合法性清洗 |
| 尺寸普遍偏中间 | 尺寸 token 分布不均、损失未加权 | 检查尺寸直方图,做 log 分桶 |
| 孔没了或位置偏移 | 布尔切除被后处理过滤 | 检查布尔安全规则和后处理容差 |
| 复杂模型生成到一半崩溃 | 解码步长过长、早期错误累积 | 改用 beam search + 课程学习 |
| 文本描述稍变就失效 | 训练语料模板太单一 | 扩充同义表达、加入人工改写数据 |
6. 工程落地:离“AI CAD 工程师”还有多远
实验室里跑通一个 demo 是一回事,真正放到产品里是另一回事。以现在的技术状态,text-to-cad 还做不到“输入一句话,直接交付生产图纸”,但它已经能在某些约束明确的场景里发挥价值。
6.1 当前最务实的落地形态
我目前比较看好的落地方式不是全自动生成,而是“模板库 + 文本检索 + 参数化调整”的半自动辅助。企业把常用的标准件、典型结构件做成参数化模板,用户输入自然语言需求,系统负责匹配模板并填入参数,再由 CAD 内核驱动生成最终模型。这种形态把问题从“从零生成一个任意几何体”降级为“从有限集合里做一个匹配和参数填写”,可靠性大幅提升,也更容易通过企业的质量评审。
对于生成式 text-to-cad,现阶段更适合放在设计早期的概念探索阶段。设计师用文本快速生成几个候选方案,从中获取灵感,再基于生成结果做修改。与其追求一次成型,不如把它当成“能听懂话的草图工具”。这个定位下即使生成的尺寸不精确,只要结构大致符合预期,就已经能节省大量从空白开始建模的时间。
6.2 扩展方向:多模态、约束优化与双向编辑
接下来值得关注的方向,一个是多模态输入。纯文本描述在很多场景下维度不够,比如“类似这个图,但把孔距改成 50mm”,这种需求必须结合草图或参考图。文本负责描述意图,图像负责提供参考形状,两者融合后生成 CAD 序列,比单一模态强很多。
另一个方向是和传统约束求解器结合。当前神经网络生成的尺寸只是“看起来合理”,并不一定满足强度、重量、装配空间等工程约束。一个可行的做法是让网络先生成一个基础的参数化结构,再接入优化器,在满足约束的前提下微调尺寸参数。这是生成模型和传统 CAE 工具链融合的关键路径,也是工程价值最大的方向。
6.3 现实约束与我的个人体会
最后说点现实的。text-to-cad 目前的推理速度还不够快,一个中等复杂模型的序列生成加内核重建可能要几十秒,比工程师自己建模慢不少,谈不上“提效”,只能说“省手”。硬件上,训练一个像样的模型需要一张 24GB 以上显存的卡,推理阶段稍微好一点,但也不是单 CPU 能扛的。数据集版权也需要留意,很多公开数据集来自商业软件用户贡献,商用前必须确认许可条款。
我自己实际跑下来的最大体会是:这个方向真正难的不是模型结构,而是“工程约束如何进入生成过程”。神经网络擅长从数据里学分布,但不擅长理解“这个孔不能跟那个孔干涉”、“这个壁厚不能小于加工极限”。这些问题短期内要靠后处理规则来兜底,长期则需要让约束信息参与训练。如果你准备入坑,建议先把手上的水管接好,也就是数据清洗、合法校验、CAD 内核重建这条链路,再回头调模型。这条链路通了,后面换什么模型架构都会顺手很多。