资讯动态

text-to-cad实战:从自然语言到参数化CAD模型的技术路线与踩坑记录

发布时间:2026/10/8 20:12:44 来源:尧图企业网站定制
1. 认识text-to-cad一句话生成三维模型到底是怎么回事先说结论text-to-cad 这个赛道就是把“帮我做一个带圆形阵列的法兰盘中心孔直径40毫米外圈有8个M6螺纹孔”这样的自然语言描述直接变成可编辑、可加工、参数化的CAD模型文件。它不是渲染一张图片也不是生成一个3D网格而是生成真正的工程模型——带完整的建模历史树、可回退参数、可继续修改的特征结构。我最初听到这个概念的时候第一反应是“这不就是自动化的三维建模嘛”。真正上手才发现这玩意和文生图完全是两码事。文生图生成的是像素矩阵错了可以糊过去、可以风格化CAD模型面对的是公差、装配、干涉检查、工艺流程差一个毫米都有可能让零件报废。所以text-to-cad的难点不在于“把字变成立体形状”而在于把模糊的自然语言精确化为确定性的几何操作序列。这篇文章适合三类人看第一类是搞AI应用开发、想找个垂直场景落地的算法工程师第二类是机械设计/产品设计领域想尝鲜的传统设计师第三类是纯粹好奇AI怎么跟工程软件结合的爱好者。我不会只讲概念会把技术路线、数据集、模型细节、我实际跑通的最小管线和踩坑记录全部摊开尽量让你看完之后能自己搭一个雏形出来。2. 方案选型文本转CAD的三条主流技术路线text-to-cad目前没有标准答案不同团队走的路线差异很大。我把它拆成三条主线来对比这条思路也适用于你自己做技术选型。2.1 路线一让大模型生成CAD脚本代码这个思路最简单粗暴本质上是利用大模型的代码生成能力。你把需求用自然语言描述模型输出OpenSCAD、CadQuery、或者Fusion 360的Python API代码然后由几何内核去执行代码生成实体模型。这条路最大的优势是可解释性极强。生成的每一步都能追溯错了可以改参数重跑跟传统建模逻辑天然兼容。而且吃的是语言模型的存量能力不需要重新设计网络结构开发周期短。短板也明显模型容易“一本正经地胡说八道”。我实测过很多次描述一个常见的支架零件LLM会生成看起来很合理但其实自相交的扫掠路径或者布尔运算对象不共面导致内核直接报错。代码生成成功率看着还行实际能跑通并生成合法实体的比例会掉一大截。另外生成质量非常依赖提示词模板换个说法结果可能天差地别。2.2 路线二端到端生成B-rep边界表示这是学术界更热衷的方向代表作就是DeepCAD那套思路衍生出来的一批工作。B-rep是CAD内核真正使用的几何表示通过面、边、顶点的拓扑关系描述实体。端到端方法把B-rep序列化成一串token用Transformer去直接预测这个token序列然后再重建成实体。这条路最大的优势是上限高不依赖代码中间层理论上模型学到的就是几何本身的规律。而且因为输出的是显式的B-rep结构后续做特征识别、参数化重建都有基础。但它对工程实践非常不友好。B-rep序列很长一个中等复杂度的零件动辄几百上千个token训练收敛慢而且一旦序列中某个顶点坐标出现微小偏差整个模型就废了——拓扑结构对数值误差极其敏感。我见过很多论文里的效果图很惊艳但开源代码跑起来之后能生成的零件复杂度其实非常有限基本停留在轴套、简单壳体这个级别。2.3 路线三草图加拉伸的类人建模路径还有一条折中路线模拟人类设计师的思路先生成二维草图直线、圆弧、约束关系再通过拉伸、旋转、放样这些特征操作生成三维实体。这条路线在Fusion 360、SolidWorks这类参数化软件里很常见也符合传统CAD的数据结构。好处是符合现有设计习惯生成的特征树跟人工建模高度一致后编辑空间大。难点则是草图阶段的几何约束求解非常麻烦——二维几何的约束关系相切、共线、对称等用token表示起来维度很高模型很容易生成互相矛盾的约束组导致求解器找不到满足条件的解。2.4 我的取舍建议我自己实际用的方案是混合式主体走路线一用大模型生成CadQuery脚本再用一个小的规则引擎做几何合法性校验校验不通过就自动反馈给模型重新生成。原因很现实路线二和路线三的模型研发成本太高对算力和数据的要求不是个人开发者能轻易承受的。路线一结合现成的LLM API能在几天内跑出一个能看的效果。这条思路也代表着当前行业里落地方案的主流选择——重交互、重校验、重迭代而不是追求一步到位。3. 数据与模型细节想让模型懂几何得先学会怎么“说话”确定了技术路线下一步就是数据和模型。这部分我拆成几个小点讲都是实操中最容易忽略的地方。3.1 训练数据到底从哪来做text-to-cad绕不开的数据集主要是两个支线一是CAD模型数据集比如DeepCAD、ABC Dataset、Fusion 360 Gallery这些。DeepCAD包含约17万个由SolidWorks用户创建的机械零件带有完整的建模命令序列ABC Dataset则包含超过100万个CAD模型覆盖面更广但很多模型只有最终B-rep没有操作序列训练时只能硬编码拓扑信息难度更大。二是文本-模型配对数据集。这个才是最稀缺的。早期工作靠人工标注成本极高后来的Text2CAD数据集采用“模型描述生成器LLM清洗”的半自动流程为每个CAD模型自动生成多种自然语言描述再经过过滤保证质量。我补充一句如果你只是做路线一的工程应用其实不需要去训练模型这些数据集的意义在于帮你理解“文本-代码-几何”之间的映射关系以及设计你的提示词模板。真正想训练专属模型建议先租GPU跑一遍DeepCAD的数据预处理流程把建模序列token化体会一下数据规模对训练时长的影响再决定要不要all in。3.2 Token化把几何变成模型能读的“语言”模型不认识几何体只认识token序列。把CAD建模过程拆成token序列常见的做法是把每一步操作编码成一个结构化片段包含操作类型比如新建草图、拉伸、打孔、关键参数拉伸深度、孔直径、阵列数量以及位置坐标。举个具体例子一条“拉伸”操作的token序列大致长这样[START_DRAW] sketch_planeXY point(10.0, 20.0) line_to(30.0, 20.0) ... [EXTRUDE] height25.0 directionpositive [END_DRAW]坐标值一定要做离散化。你不可能让模型直接回归连续数值坐标那样误差累积起来几何就完全变形。常见的做法是把坐标量化为若干个bin比如把[0, 100)毫米的范围分成1000个bin每个bin代表0.1毫米。bin的数量决定精度上限我试下来512到1024之间的bin数比较平衡太少则圆孔会变成多边形太多则序列过长训练不动。还有个很多人踩的坑单位一致性。同一个数据集里有的模型用毫米有的用英寸有的用厘米。如果不做单位归一化模型会学到一套混乱的尺度意识生成出来的零件尺寸完全不可控。归一化到单位立方体再配合原始尺度的缩放信息输出是必备操作。3.3 模型架构与训练策略路线二的经典架构是Transformer的encoder-decoder结构。encoder吃文本描述decoder输出B-rep token序列。在自回归生成时每一步生成一个token并以上一步生成的token为条件继续预测下一步跟语言模型生成文本的机制完全相同。训练上有两个很实用的技巧loss加权要偏向拓扑关键位置。B-rep序列里大多数token是坐标数值少数token是操作类型和拓扑关系。如果统一做交叉熵模型会花大量精力去把坐标bin预测准反而忽略了面边拓扑的正确性。我在实践中把操作类token的loss权重调到坐标token的2到3倍拓扑结构的正确率会有肉眼可见的提升。课程学习真的有用。先拿简单零件比如只有拉伸和孔操作的轴套类训练模型loss降到稳定之后再加入复杂零件数据。这能避免模型一开始就被长序列和复杂拓扑吓住训练速度也快很多。3.4 后处理模型输出只是半成品不管你走哪条路线模型输出都不能直接拿去用。必须经过几何内核的“体检”——常见的操作包括拓扑修复裂缝、重面、悬边这些在B-rep序列里是数值误差的必然产物尺寸合法性检查壁厚是否小于零、孔是否穿透、是否存在退化面实体校验调用CAD内核求体积如果体积为零或明显异常直接判定失败路线一相对好办CadQuery执行的本身就是合法操作但也会出现特征冲突、布尔失败等问题。关键是要把“校验-反馈-重生成”做成闭环而不是让用户拿到一个坏模型干瞪眼。4. 从零搭一个最小可用管线文本到可编辑模型的完整实操下面这一段我手把手带你跑通一个最小可行的text-to-cad管线。这个方案不需要训练模型基于现成的LLM API加CadQuery就能跑起来整体架构是一个“文本→结构话参数抽取→CadQuery脚本生成→几何校验→模型文件输出”的链路。4.1 环境准备依赖很简单Python 3.9以上安装cadquery和openai或者你习惯的任何LLM SDKpip install cadquery openaiCadQuery用的是OCCT几何内核安装后建议先跑一个最小用例验证环境import cadquery as cq result cq.Workplane(XY).box(10, 10, 10) cq.exporters.export(result, test.step)能正常输出test.step就说明环境没问题。4.2 核心代码实现我的做法不是让LLM直接从零写完整CAD代码那太飘了。核心思路是先让LLM输出结构化参数再由固定的代码模板生成建模脚本。这样生成失败的概率大大降低而且参数可控性强。下面是一个简化但有代表性的实现import json import cadquery as cq from openai import OpenAI client OpenAI() SYSTEM_PROMPT 你是一个CAD参数抽取器。根据用户的自然语言描述输出JSON格式的建模参数。 参数包括 - width, depth, height 基本体尺寸 - holes: [{diameter, depth, position:[x,y]}] - fillet_radius: 圆角半径可选 只输出JSON不要输出任何其他解释。 def extract_params(text: str) - dict: resp client.chat.completions.create( modelgpt-4o, # 或你的实际模型 messages[ {role: system, content: SYSTEM_PROMPT}, {role: user, content: text}, ], response_format{type: json_object}, ) return json.loads(resp.choices[0].message.content) def build_model(params: dict): work cq.Workplane(XY) base work.box(params[width], params[depth], params[height]) # 打孔 for hole in params.get(holes, []): base ( base.faces(Z) .workplane() .center(hole[position][0], hole[position][1]) .hole(hole[diameter], hole[depth]) ) # 圆角 if params.get(fillet_radius): base base.edges(|Z).fillet(params[fillet_radius]) return base def text_to_cad(text: str, output_path: str result.step): params extract_params(text) print(抽取参数:, params) model build_model(params) cq.exporters.export(model, output_path) print(输出完成:, output_path) if __name__ __main__: text_to_cad(做一个长80宽50高10的底座上面有两个直径10深度5的孔位置分别在(20, 0)和(-20, 0))这个管线的关键设计点是把参数的数值计算交给LLM把几何操作交给确定性代码。LLM擅长语言理解和模糊匹配但不擅长严谨的数字推理CAD内核擅长精确建模但不理解自然语言。两者各干各擅长的部分是我踩了无数坑之后总结出来最稳的组合。4.3 效果评估别只看模型长什么样跑通之后还得知道模型生成得好不好。评估text-to-cad有三个核心指标我在实际中也都实现了几何相似度把生成模型和参考模型都转成体素网格或点云计算IoU交并比。大于0.7基本上肉眼已经比较像了低于0.4基本可以说是另一个东西。拓扑正确率是否能通过CAD内核的实体校验体积大于零、无开放面、无边自交。这个指标很低的话说明模型生成的实体是“虚”的加工厂根本没法用。参数准确率针对孔距、孔径、壁厚这类可量化参数比较生成值和目标值的偏差。这个指标最贴近工程实际——长得很像但孔位偏了0.5毫米在装配场景里就是废品。我自己建了一个50条测试样本的评估集涵盖了板类、支架类、法兰类三种常见机械零件。在这里也建议你把常见零件类型固定下来做回归测试不要今天测螺丝明天测箱体否则模型哪里进步哪里退步根本看不出。5. 常见问题与排查实录我实际踩过的那些坑这部分是真正的经验干货。以下每个问题我都实际遇到过不是从文档里抄的。5.1 文本太抽象抽参数瞎猜用户说“做一个差不多大小的L形支架”这里“差不多”就是个模糊量。LLM往往会凭概率给一个值而不会反问用户。我一开始的解决办法是让模型多轮追问但实测对话轮次一多用户就烦了。更实用的办法是规则兜底在提示词中约定默认值体系比如“若用户未指定尺寸宽度默认50、深度默认50、厚度默认8”全程保持一致性。同时在输出参数里加一个“confidence”字段当模型的置信度低于阈值时宁可返回二次确认对话框也不要硬生成一个用户没要的尺寸。5.2 几何校验通过但零件看着很怪这是最隐蔽的问题模型从CAD内核角度是合法实体体积正常、面封闭但拓扑根本不符合直觉。典型例子是应该贯穿的孔只打了半边或者本应该对称的凸台偏到一边去了。排查这类问题我发现一个很好用的方法——把生成过程和原理解释给用户看。我在界面上不只展示结果模型还把抽取出的参数表格一并展示。一旦发现参数不对当场就能看出来问题出在哪一步。这对定位是LLM的问题还是模板的问题很有帮助。5.3 模型总是生成超薄壁或者细长条这个现象在训练路线二时特别明显。模型学到的几何分布偏向某些高频出现的形状而实际机械零件中常见的厚重块体反而不容易被生成。两个解决办法一个是在数据层面做形状均衡采样把B-rep序列按长度分桶每个桶内采样数量上限做限制避免长序列少、短序列多造成的分布倾斜另一个是在loss层面惩罚薄壁结构比如对两个相邻面的距离过小时增加额外loss但这需要你额外写一个几何特征提取器工作量大一些。5.4 常见问题速查表现象可能原因排查/解决办法生成的模型文件打不开几何内核版本不一致统一用同一OCCT版本导出STEP格式比BREP兼容性好孔的位置偏差大坐标离散化bin太粗把bin数提到1024以上或改为局部坐标回归同一个描述每次生成结果完全不同LLM采样温度过高推理时把temperature降到0.2以下必要时固定seed提示词换一种说法效果骤降系统提示词过拟合扩充提示词变体做基于上下文的动态提示抽取参数里出现负数尺寸缺少参数合法性约束在系统提示词里逐条声明“所有尺寸必须为正数”并在代码里再次校验布尔运算莫名其妙失败两个特征完全共面或重叠把依赖的基准面改为偏移0.001毫米的平行面避免面重合这个表我建议你贴在工位旁边基本覆盖了我在项目里遇到过的80%的运行时问题。最后分享一个能救命的习惯如果你真的准备在这个方向投入时间我自己的体会是一定要为每一次生成保留完整的日志链路。记录原始输入文本、中间抽取参数、生成代码、校验结果、最终文件路径。这不仅是为了排查问题更重要的是你能通过日志积累出“什么类型的描述做得好、什么类型做不好”的边界清单。我一开始没有这个习惯导致某类零件的失败原因反复排查了三轮才定位到是提示词模板的措辞歧义。另外还有一个日常小技巧生成失败的案例不要删掉定期收集起来人工修正后专门用来做提示词补充或者作为后续微调模型的负样本。这些失败样本比任何公开数据集都更有价值因为它们正是你的真实用户会提出、而你当前系统搞不定的需求。text-to-cad这个方向最近发展很快但离真正替代工程师做设计还有很长的路要走。现阶段比较务实的定位是当一个“设计加速器”把重复性高、规则明确的基础零件建模自动化让人力聚焦在真正需要创造力的部分。这也是我整个项目里一直在坚持的取舍标准。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑