2026/10/27 20:33:20

从一句话到三维模型:Text-to-CAD技术路线与复现实践

从一句话到三维模型:Text-to-CAD技术路线与复现实践 CAD这个圈子最近被text-to-cad这个话题搅得有些热闹。GitHub、论文预印本站点上隔三差五冒出来一个新项目演示起来都很唬人你输入一个带四个安装孔的底板模型就咔咔生成一个三维实体模型。听起来很科幻但真正自己上手复现过的人其实不多。我花了大概两周时间把这条技术路线从论文看到开源代码又一步步跑通、调参、可视化中间踩了不少坑也搞明白了哪些演示是demo很丰满落地很骨感。这篇就把我理解的text-to-cad是什么、主流实现路线怎么选、复现过程的细节和翻车点一次性讲清楚。适合正在观望AI辅助设计、打算做非标自动化或参数化建模的工程师以及想入坑这个方向的研究者参考。1. 一句话变成三维模型难点在参数不在语义1.1 自然语言天生模糊CAD要求精确人类设计师之间说在板的四角打孔能顺利协作是因为双方脑内补全了大量背景信息板多厚、孔多大、孔心离边多远、是通孔还是盲孔。但模型没有这些常识。它面临的任务是把一句充满省略和假设的中文或英文翻译成一组精确到小数点后几位、坐标系统严格、特征顺序不能乱的建模操作。这个语义鸿沟比想象中难跨越。很多text-to-cad demo看起来效果不错本质上是模型在训练数据里记住了相似形状。换一个说法、换一个尺寸表述生成结果可能完全崩掉。我后面会详细说这个现象但这里可以先有一个结论自然语言理解不是这个方向的核心瓶颈从模糊描述里推断精确参数才是。1.2 相比text-to-3Dtext-to-CAD还要保留特征树做过3D生成的同学都知道text-to-3D这两年很猛用Stable Diffusion那套思路配合各种栅格化渲染损失能生成相当惊艳的mesh模型。但text-to-CAD和它是完全不同的东西。CAD模型在工程上真正有价值的地方不只是表面形状而是它有特征树一个法兰盘可能是拉伸一个圆盘 - 在盘上画四个孔草图 - 拉伸切除 - 倒角。每一步都可以回到CAD软件里双击编辑参数。工程师拿到一个只有mesh没有特征树的三维文件基本没法改更没法出工程图、连BOM、做公差标注。所以text-to-CAD的正确输出必须是操作序列而不是几何面片。这就要求模型生成的每个草图、每条直线圆弧、每个拉伸深度都是可解析、可回退的。这个要求让任务难度比单纯生成形状高了一个量级。1.3 行业标准不统一格式与API割裂另一个让text-to-CAD进展慢的客观原因是CAD行业本身没有统一标准。DWG、STEP、IGES、B-rep……不同软件的数据交换历来都是老大难问题。就算模型生成对了想在SolidWorks、Fusion 360、AutoCAD里面自动化重建每个软件的历史和API都不一样。现在大部分开源项目选择的是两条路径要么绑定Fusion 360的Python API要么输出一种中间JSON格式再由脚本转成STEP或mesh。这个最后一公里非常痛苦因为不同的CAD软件对同一段历史操作的解释往往有细微差异生成结果在这个软件里是对的换个软件可能直接报错。2. 三条技术路线各有硬伤哪条最接近CAD原生2.1 代码生成路线LLM写脚本胜在零训练死在API幻觉最早被大家尝试的思路是让LLM直接写CAD脚本。现在的大语言模型对AutoCAD的AutoLISP、FreeCAD的Python宏、OpenSCAD代码都有一定理解能让它直接输出一段可执行代码。这条路最大的优点是上手快、不需要训练数据。你把API文档塞进prompt让GPT生成一段在坐标(0,0)画一个半径20的圆之类的脚本大概率能跑通。但它有两个致命问题一是API幻觉。LLM经常编出看起来合理但实际不存在的函数名、参数顺序或者把不同CAD软件的接口混着用。二是尺寸精度不可控。你说一个长宽高100x60x40的盒子它可能给你生成99.8x60.3x40的因为自然语言到数值的映射在注意力机制里并不稳定。这导致代码生成路线更适合用来做演示和出初步草图离工程可用还差得远。2.2 扩散生成路线mesh好看但参数化还得另起炉灶第二条路线是借鉴text-to-image的扩散模型思路在三维体素或点云上做条件生成再想办法把结果转成CAD参数化模型。这条路线的优势是生成质量高、几何表现力强能得到非常复杂自由曲面。缺点前面说过输出是mesh要转成可编辑特征树极其困难。目前学术界有一些从mesh反推B-rep的工作但速度慢、稳定性差处理复杂工业件基本没戏。所以扩散路线目前还停留在概念设计阶段不适合当CAD的底层引擎。2.3 序列生成路线把建模历史当成语言来学习第三条路线是我个人最看好的把CAD建模历史token化当成一种几何语言来学习。DeepCAD和Text2CAD走的就是这个路子。其核心思想是把一个零件的建模历史拆解成草图实体直线、圆弧、圆、挤出示、旋转等操作每个操作带参数参数离散成token这些token按顺序拼成一个序列本质上就是一段自然语言用Transformer去做序列生成输入文本描述输出一整段CAD操作token序列。这样生成的模型天然带特征树能在支持该格式的CAD软件里直接打开、继续编辑。Text2CAD就是在这个框架上加了文本条件让模型可以根据文字描述生成对应的CAD操作序列。2.4 一张表看透三条路线的本质区别对比维度代码生成路线扩散生成路线序列生成路线代表实现LLM AutoLISP/Python宏3D扩散模型SDF/体素DeepCAD、Text2CAD输出形态可执行脚本mesh/点云/体素CAD操作token序列保留特征树部分保留取决于脚本不保留完整保留尺寸精度无法保证无法保证结构可用尺寸需后处理是否需要训练数据不需要需要大量3D数据需要CAD模型数据集部署成本最低高GPGPU训练中高工程可用度低极低中正在快速迭代一句话总结代码生成适合快速原型扩散生成适合视觉概念序列生成才是面向制造的正路。3. 最快跑通的方式LLM生成AutoCAD脚本的完整实践在去啃复杂的自回归模型之前我建议你先花半天时间把代码生成路线跑通。这一步能帮你建立直觉文本到CAD到底难在哪、API执行链路上容易哪里翻车。3.1 环境准备与COM自动化让Python接管CAD我用的是AutoCAD 2024 Python 3.10。AutoCAD本身支持ActiveX/COM自动化相当于提供了一个远程控制接口Python通过pywin32库就能连上。import win32com.client # 启动或连接已在运行的AutoCAD acad win32com.client.Dispatch(AutoCAD.Application) acad.Visible True # 获取当前文档和模型空间 doc acad.ActiveDocument ms doc.ModelSpace连接成功之后就可以通过COM对象往模型空间里添加直线、圆、多段线等实体# 添加一个圆圆心(50,50,0)半径20 center_point (50, 50, 0) radius 20 circle ms.AddCircle(center_point, radius) # 添加一条直线 start_point (0, 0, 0) end_point (100, 0, 0) line ms.AddLine(start_point, end_point)这里有个小坑COM接口的坐标参数有些版本要求是元组(tuple)有些接受数组直接传列表可能报类型不匹配。统一转成tuple再传比较稳。3.2 提示词设计思路让LLM输出指令JSON而不是CAD代码直接让LLM输出AutoLISP我试下来的成功率大概只有五成左右而且报错信息不直观排查很痛苦。更好的做法是让LLM输出一个结构化的指令列表然后在Python端解析并调用CAD API。我给LLM的prompt一般是这样的你是AutoCAD自动化助手。请根据用户描述输出一组有序的CAD绘制指令格式为JSON数组。每个指令必须包含type字段可选值line/circle/rectangle/array/hole。请给出精确的坐标和尺寸数值不要省略单位。比如用户说画一块200x100的矩形板中心在原点在中心偏右下位置开一个直径20的孔LLM应当输出类似下面的JSON[ {type: rectangle, center: [0, 0, 0], width: 200, height: 100}, {type: circle, center: [50, -20, 0], radius: 10} ]这个设计的好处很明显LLM不用去记复杂的API语法只需要输出类型和参数Python端做参数校验和安全兜底即使一个指令不对也能单独跳过不中断整个流程。这是工程化上很关键的习惯——永远让模型去做填空题而不是让模型去写一整篇作文。3.3 执行与校验从命令到实体的细节处理拿到JSON之后Python端逐条解析执行。执行完还要做校验检查实体是否真正生成、坐标是否在合理范围、是否有重复对象。import json def execute_command_list(ms, command_list): for cmd in command_list: ctype cmd[type] if ctype line: ms.AddLine((cmd[start_x], cmd[start_y], 0), (cmd[end_x], cmd[end_y], 0)) elif ctype circle: ms.AddCircle((cmd[center_x], cmd[center_y], 0), cmd[radius]) elif ctype rectangle: # 矩形用多段线闭合绘制 cx, cy cmd[center][0], cmd[center][1] w, h cmd[width], cmd[height] pts [(cx-w/2, cy-h/2, 0), (cxw/2, cy-h/2, 0), (cxw/2, cyh/2, 0), (cx-w/2, cyh/2, 0)] ms.AddPolyline(pts) else: print(f未知指令类型: {ctype}) continue实际执行时还会遇到一个问题AutoCAD的默认坐标系是世界坐标系如果你在某个局部坐标系中建模坐标要对齐。初学者可以先把所有坐标都固定在世界坐标系下让LLM输出前先明确我处理的是全局坐标不希望有相对偏移。3.4 这条路的真实边界在这套方案里跑通了画板打孔倒角之后我很快意识到这条路线的天花板它只适合非常简单的、规整的零件。换个稍微复杂一点的例子——一个带加强筋的L型支架四条筋的厚度是5毫米筋的位置按均布排列——LLM的JSON输出就开始乱套要么筋的位置算错要么数量不对要么干脆少一个特征。原因也很好理解代码生成路线没有几何约束求解的兜底纯粹靠模型对空间的想象力。它能把每个基础元素画对但没法保证多个元素之间的相对关系、干涉检查、制造可行性。所以这条路线我最推荐的使用方式是做设计前期概念草图和教学演示不要让它在无人确认的情况下直接出工程图。4. 复现Text2CAD自回归模型从token序列到可编辑特征如果你想把text-to-cad往真正实用的方向推那必然要走进序列生成路线。下面是我复现Text2CAD类模型的核心记录。4.1 把CAD建模历史token化本质是学一门几何语言Text2CAD的核心不是从零提出新架构而是把DeepCAD的CAD序列生成框架从无条件生成升级成文本条件生成。具体来说一个零件的建模历史会被解析成这样的token序列start Sketch_1 origin x y SketchCircle(center_x..., center_y..., radius...) SketchLine(p1_x..., p1_y..., p2_x..., p2_y...) ... Extrude(profile_1, height..., taper..., operationnew) Sketch_2 origin x y ... end每个几何元素、每个操作、每个参数都被离散成固定的token ID组成一个长序列。Transformer只要学会了在Sketch之后通常跟若干SketchCircle/SketchLine然后跟Extrude再然后可能有个孔特征这种模式就能生成全新的、符合建模逻辑的零件。Text2CAD做的事情是在这个序列生成模型前面再加一个文本编码器让整个序列的生成以自然语言指令为条件。理解这个设计之后你就明白为什么它生成的零件有CAD味儿不是因为它懂工程而是因为它严格遵守了人类建模语言里的句法规则。4.2 数据集准备Fusion 360 Gallery与文本指令的来源要做这个实验第一步是拿到CAD模型数据集。最常用的两个公开数据集Fusion 360 Gallery dataset包含几千到上万个Fusion 360格式的设计特点是每个模型都带完整的特征树和时间线非常适合序列化。ABC dataset更大规模的B-rep模型库但特征树信息相对弱一些更多用于几何分析。Text2CAD在Fusion 360 Gallery的基础上用LLM辅助生成了对应的文本指令覆盖从初学者指令到高级指令的多个层次。比如同一零件低级别描述是画一个圆再拉伸10毫米高级别描述可能是创建一个直径30的圆台用于安装轴承。预处理阶段我做的事情主要是下载原始数据 - 解析成中间JSON - 过滤掉无效模型特征树不完整、单位异常、草图无法闭合- 做参数归一化 - token化。这个过程非常耗时经常一跑就是好几个小时而且过滤后的有效样本量会缩水百分之二三十。不要跳过过滤这一步脏数据会让模型学会一堆奇怪的坏习惯。4.3 训练成本与参数调试这个模型并不是那种一张普通游戏显卡就能跑的小玩具。我的实验环境是单张RTX 4090 24G用的小规模子集batch size设到16已经接近显存上限了。几个关键参数和经验学习率Transformer类模型一般用1e-4附近配合warmup。我用过3e-4损失很快发散降回来就好了。序列长度一个中等复杂度的零件token序列可能长几百训练时要截断或分批。太长的序列会显著拖慢训练。文本增强同一个零件如果只有一条文本描述模型对换个说法会很脆弱。要做同义改写增强我甚至把四个孔和4个孔这种数字形式差异都当作数据缺陷来看待。时间成本在几千个模型的小子集上一天大概能跑几百个epoch的尝试但真正要得到一个能稳定生成像样零件的模型至少需要几天到一周的连续训练。想省时间就去找作者放出的预训练权重直接在自己的小数据集上微调。4.4 推理后处理token还原成几何的最后一公里训练完模型生成出来的是一串token不是可视的零件。要做后处理把它还原成几何。这一步有几个容易被忽略的坑坐标缩放训练时为了让网络好收敛通常会把坐标归一化到某个区间。推理完必须按相同的缩放因子还原否则零件尺寸完全不对。草图闭合模型生成的草图轮廓可能首尾不闭合导致拉伸失败。需要在后处理脚本里加一个闭合修正判断首尾点距离小于阈值时强制连接。实体顺序检查CAD操作对顺序敏感比如先切除后倒角和先倒角后切除结果完全不同。模型生成的序列多数时候顺序合理但偶发会出现倒角一个并不存在的边这种错误。还原以后可以通过配套的脚本把结果导出成OBJ或STEP或者直接导入到Fusion 360里查看特征树。我建议至少抽检五六个生成结果用可视化软件确认这个零件是不是真的长这样别只盯着数值指标看。5. 实测中的翻车现场五个高频问题与排查链路复现和测试的过程里我几乎每天都会撞上一个新问题。这里挑五个最有代表性的把现象、原因、排查思路完整写出来给你当避坑参考。5.1 文字一换结果全变语言脆弱性怎么定位现象同一个零件用plate with four holes生成得挺正常改成plate with 4 holes后模型生成的孔数量变成六个位置也乱了。我把这两个输入喂给模型发现编码器输出的隐藏层表征差异非常大说明模型对单词与数字之间的语义等价关系没有学扎实。排查链路先确认分词器是否把four和4当作完全不同的token。如果是大概率不是因为模型笨而是数据里就没出现过足够的数字形态变体。检查训练数据中的文本增强策略。我后来在同一句描述里混合4/four/四个再用随机替换的方式做增强情况立刻改善。如果增强后依然脆弱可以考虑冻结CAD序列解码器只微调文本编码器与跨模态投影层让文本与几何的对齐更充分。5.2 序列合法但几何漂浮问题出在归一化现象有一次模型生成的token序列在语法上完全合法草图闭合、拉伸高度也正常但可视化后发现圆孔的中心位置偏到了零件边界外面。我沿着序列逐个token检查发现圆心的坐标值在训练归一化范围之内但换算回真实坐标时圆心距离零件中心的偏移量明显超出了常理。根因我用的数据集里有些零件的草图坐标系远偏离全局原点而训练时我按全局包围盒做了归一化。模型学到的是在这个归一化空间里圆心的分布规律自然就认为远离中心的圆孔也是合理的。后来我在归一化时改为按每个特征局部坐标系计算并把特征的原点偏移也作为一个token输入模型问题才缓解。这个坑提醒我CAD序列生成里的坐标系是一个极其微妙的东西。局部坐标系编码不好模型输出的几何就会飘。5.3 显存不足与训练加速的取舍训练途中频繁遇到CUDA out of memory几乎是家常便饭。处理顺序一般是这样第一选择减小batch size但注意要同步调小学习率。第二选择开混合精度训练能省不少显存还能提升速度。代价是偶发精度损失需要监控loss。第三选择缩短序列长度比如把超过512 token的样本直接丢弃。对大多数简单零件来说信息足够但复杂零件会被腰斩。终极手段换更大显存的卡或者用DeepSpeed/ZeRO那样的显存优化框架。我不建议一上来就无脑上多卡单卡能跑通再考虑规模。5.4 eval指标在骗你CD低不代表模型好复现完后我想评估模型用的指标是Chamfer Distance和IoU。刚跑出来数值在可接受范围我还挺高兴。但把生成结果逐个可视化之后发现有些CD值很低的样本几何上其实张冠李戴孔数量对了位置全错或者整体形状对了但尺寸比例明显失调。原因在于距离指标对全局形状相似性敏感但对局部特征的位置、大小、个数并不敏感。两个零件在体素空间的重叠率可能因为整体轮廓差不多就很高但工程师看一眼就知道完全不能用。我的经验是评估text-to-cad模型必须把距离指标和人眼抽查结合。具体做法是每次生成一批样本随机抽十个把CAD序列渲染成截图人工打标签可用/部分可用/不可用再和指标对比。你会发现指标分数和人工判断的相关性比想象中低。5.5 复现时别忽略代码库版本依赖这个项目的代码依赖链不长但版本敏感度极高。我在复现时踩了两个经典问题一个是PyTorch版本和CUDA版本对不上训练时算子报错另一个是数据处理脚本依赖的某个JSON解析库在Python 3.10以上有行为变化导致数据预处理结果和论文对不上。排查建议很简单创建一个全新的conda环境严格按照仓库给的requirements装不要用全局Python环境。如果作者指定了Python版本哪怕你觉得3.11肯定兼容3.9的语法也先按指定版本装。这类项目经常有一些隐式依赖换版本就悄悄出bug。6. 落地判断先解决语义到模板的翻译再谈通用生成测试到这里你应该能感受到text-to-cad的直接输出还达不到输入一句话就拿到可加工零件的程度。但这并不意味着这个方向没有工程价值。只是落地顺序可能要反过来思考。6.1 工程化组合LLM做槽位填充模板做约束保证如果让我在一家非标自动化公司里落地我不会直接让text-to-cad模型画一个完整零件而是做一套语义槽位填充系统把常用零件固化成模板比如底板、法兰盘、支架、外壳每个模板定义好参数槽长度、宽度、孔数、孔径、倒角半径用LLM从自然语言描述里抽取这些参数并校验数值合理性数值进入模板后由CAD内部的约束求解器保证几何正确性。这套方案比起端到端的text-to-cad模型胜在稳定、可解释、可追溯。LLM的幻觉被限制在抽参数这个低风险环节真正的几何计算交给确定性工具。我在实践中做了一个粗糙的原型用户说四孔的底板孔距八十系统能自动把孔距八十转换成四个孔的坐标生成效率比手动建模高很多。6.2 三个比较现实的落地场景根据我目前的观察端到端文本生成CAD直接落地最可能在以下三个场景里先跑起来维修手册/技术规格书的参数抽取大量老设备只有纸质图纸和文字描述用LLM抽取关键尺寸再套模板生成三维模型用于备件采购价值很高。设计教育与演示课堂上让学生用自然语言描述零件系统实时生成建模过程比传统一步步教命令直观得多。概念设计阶段的灵感生成工程师在方案阶段描述需求text-to-cad给一个能看但不能直接加工的初稿帮助内部沟通和报价而不是直接进制造链。6.3 给想入坑的人的建议如果你是第一次接触这个方向我建议按这个顺序来先跑LLM生成脚本的简单方案理解文本到CAD参数的基础链路再去读DeepCAD和Text2CAD的论文重点看它们的CAD序列表示方法和数据预处理不要一上来就训大模型先下载预训练权重在几个样本上体验推理和可视化想办法弄一批自己领域的CAD模型数据做小规模微调体会数据清洗占比远大于模型调参这个现实。这个领域其实还处在从0到1的阶段大量问题集中在数据表示、坐标系处理、评估标准上谁先把这些基础问题解决谁就能在下一波AI辅助设计工具里占住坑位。我自己复现完这一圈最大的体会是没有银弹模型只有把自然语言、几何约束、行业模板三者咬合起来的工程系统才真正谈得上落地。