☰
文本转CAD技术实践:从自然语言到可编辑参数化模型
2026/10/10 7:29:34 网站建设 项目流程

文本转CAD(text-to-cad)是我近半年一直在折腾的方向。说句实话,两句话就能生成3D模型的AI工具现在遍地都是,但绝大多数生成的是“看起来像”的三角网格,离真正能加工、能装配的机械零件差着十万八千里。text-to-cad最大的不同,是它不输出模型本身,而是输出一段参数化建模代码——你在对话框里描述一个零件,它给你返回能直接跑的建模脚本,跑完就是带完整几何特征的实体模型,能改尺寸、能导STEP、能进CAM走加工流程。这篇文章不聊PPT,就从技术路线、数据语料、完整实操、评估避坑这些维度,把我一路踩过来的经验摊开讲清楚。适合正在做CAD二次开发、想用LLM提效的机械工程师,也适合对程序化建模感兴趣的技术玩家。

1. 技术主线:为什么“生成代码”才是文本转CAD的正确姿势

1.1 三条技术路线的取舍

早期做文本转3D,大家第一反应都是“让AI直接吐出模型几何”。按输出形态可以分三类:第一类是生成三角网格(Mesh),典型做法是从文本特征直接回归顶点坐标和面片索引;第二类是生成体素(Voxel),把三维空间切成立方体格子让模型去填充;第三类是生成点云再拟合成曲面。这三条路线的通病是一样的:输出是一堆离散几何,没有特征树、没有参数约束,后续想改一个孔的直径就得重新生成一遍,更不用说拿去出工程图。

输出形态可编辑性几何精度工业可用度
三角网格差,只能整体变形低,曲面光顺差基本不可用
体素差,分辨率受限低基本不可用
点云+曲面拟合差,参数难挂接中极少用于实际
程序化建模代码好,参数全保留高,特征精确高

所以真正能落地的解法,是把问题从“几何生成”转换成“程序合成”:让LLM直接写CadQuery、OpenSCAD这类程序化建模脚本。比如描述一个“六边形法兰盘,中心孔直径8mm,六个螺栓孔直径4mm,法兰外径40mm”,模型输出的是一段几十行的Python代码,里面有变量定义、有特征调用、有布尔运算。执行这段代码,得到的CAD实体自带特征树,想改外径就改变量,想加孔就加一行feature。这条路线的本质是“让模型写施工图,而不是让模型当泥瓦匠”。

1.2 代码生成路线的四大优势

第一是可编辑性。设计工作从来不是一次到位的,甲方说改就改是常态。生成网格模型改一个圆角半径,可能要重新训练或者手动拖拽顶点;生成代码则只需要改一个数字,重新执行脚本即可。第二是可验证性。代码可以被静态检查、被沙箱执行、被几何校验,三个环节每个都能自动化把关。而网格模型只能靠人肉眼去看,基本做不到自动化质量门禁。第三是参数化继承。机械设计讲究的是特征复用,一个带孔阵列的标准底板改改尺寸就能适应新场景,程序化代码天然就是参数化模型。第四是和现有工具链无缝衔接。CAD软件、CAM软件、PLM系统都认STEP/IGES这类标准格式,代码生成后一导就进去,不需要中间转换的折腾。

1.3 为什么LLM能写CAD代码

这里要解释一下底层原理,很多人以为这是个“奇迹”,其实是个工程问题。LLM本质上是一个极度擅长模式复用的序列预测器,它见过海量编程代码,学到了变量命名、函数调用、结构控制这些语言规律。程序化建模脚本本身就是结构化极强的代码,语法固定、API清晰、逻辑线性。当你把任务限定到“用CadQuery画一个带孔的方板”这个范围时,模型不需要理解真正的物理空间,它只需要学会在正确的语法位置填入正确的参数即可。可以把这理解为“给一个通用翻译官装上机械设计辞典”的过程。语言模型像翻译官,知道怎么组织句子;CadQuery的文档和示例代码就是辞典,教会它“切孔”“圆角”“拉伸”这些设计意图对应的代码模式。两者一结合,文本就变成了可执行的几何约束。

有一个关键点需要说透:LLM对“精确数字”的感知能力其实很弱。tokenizer会把数字拆成不规则的token,63这个数可能被切分成“6”和“3”,模型很难学到“63mm”意味着六十多毫米的连续长度语义。所以纯靠生成代码去卡尺寸,往往是八九不离十但精确不到可加工级别。这就需要引入后续的“执行-校验-修正”闭环。这个话题后面实操部分会专门展开。

2. 数据与语料:文本到CAD模型最容易被低估的环节

2.1 程序化CAD模型从哪里来

很多做这个方向的团队,前期最大的瓶颈不是模型选型,而是数据。要让LLM学会从文本映射到建模代码,前提是得有大量“文本-代码”配对样本。工业里现成的配对数据几乎没有,但程序化CAD模型库是有的,某开源CAD数据集合里就包含几百万个机械实体模型,而且每个模型的构建脚本刚好是参数化代码。这个“刚好”很关键:既给了你代码样本,又给了你几何结果,两样都是训练要用的。

但原始数据不能直接用,我踩过的坑是从数据清洗开始的。我当时的做法分四步走。第一步是过滤无效脚本,跑一遍完整执行,执行失败的直接扔掉。这一步能去掉大概三分之一的脏数据。第二步是剔除形状异常的模型,比如编译通过但产出体积极度离谱的——box参数里出现负数、拉伸高度为零之类的。第三步是做语义筛选,用规则把建模逻辑特别简单的样本剔除,例如只有一条box命令、没有任何特征操作的模型。第四步是去重,很多模型库里的零件只是尺寸不同、逻辑相似,全量训练会让模型过拟合到少数几个结构上,去重后数据多样性反而更好。最终留下来的有效数据,大概只有原始库的两到三成,但质量高一个数量级。

2.2 文本描述怎么造

有了程序化模型和对应代码,下一个问题是文本描述从哪来。自己写几千条标注不现实,我的做法是“反向生成+模型增强”两条腿走路。反向生成的核心思路很简单:模型不擅长文本生成CAD代码,但很擅长给一段代码写自然语言注释。你把代码脚本丢给LLM,让它用自然语言描述这个零件的外观特征、关键尺寸、功能猜测,就得到了一条初始文本。这一步可以用大模型批量跑,成本低速度快。

但反向生成有个明显问题:描述质量飘忽,有时候像说明书,有时候像废话。所以接下来要做增强。我把初始描述喂给一个更强的大模型,让它把描述重写成三种风格:一是参数化风格,明确写出“底板长60宽40厚3,四个圆角半径2”;二是功能化风格,写成“用于连接两个管路的法兰底座”;三是要素化风格,写成“具有四个均布孔的矩形板,孔间距30mm”。三种风格混在一起训练,模型在推理时对不同措辞的鲁棒性会提高很多。最后还要做一次质检抽样,每批生成数据里抽50条人工过一遍,重点看尺寸描述是否与真实几何一致、有没有“左”和“右”这种方向性错误。不抽样检查的话,LLM自己编出来的错误描述会被当成标准答案,模型越训越歪。

2.3 微调与数据混合技巧

数据准备好后,微调这一步我推荐用指令微调+LoRA(低秩适配)的方案。所谓LoRA,就是把原始大模型的参数全部冻结,只在旁边加一小撮可训练的低秩参数矩阵。好处是显存占用低、训练快、不容易灾难性遗忘。我更愿意用“给通用翻译官装行业词典”这个类比来解释:翻译官本身的语法能力不动,只训练机械术语这块的适应层。用下来的体感是,只用一个中等规模的LoRA适配器,生成的代码质量就能超过直接调通用大模型加长篇提示词的效果。

数据混合比例也要留意。纯CAD代码数据会让模型变成一个“只会写建模脚本的专才”,但对用户各种口吻的泛化能力差。我的经验是训练语料里70%是CAD配对数据,25%是通用代码任务数据,再留5%的对话数据保持模型的自然语言交互能力。温度参数在训练时设低一点,推理时反而可以适度提高到0.7左右,增加生成多样性,便于同一个描述产出多个候选供筛选。

3. 实操全流程:从一段自然语言到可编辑的STEP文件

3.1 环境与工具链

先把我一直在用的工具链列出来,都是开箱即用的东西。CadQuery是程序化建模库,Python API,可以直接生成STEP格式,是做这条路线的主力。OpenSCAD可以作为备选方案,它对建模过程的表达更接近CSG,但特征化程度不如CadQuery。沙箱执行用容器隔离加资源限制,这一步不能省,因为LLM生成的代码不可信,指不定给你来个死循环或者制造一个巨大实体把磁盘塞满。推理服务用vLLM部署开源模型,吞吐量比原生推理高几倍,批量生成时感受明显。

环境安装不算复杂,但有几个版本坑值得提醒。CadQuery建议装带条件依赖的完整版,因为部分高级特征需要依赖OCC内核库;OpenSCAD如果用命令行模式,注意环境变量要指向自带的可执行文件。容器沙箱我用了轻量方案,CPU限制1核、内存限制1GB、超时5秒,正常建模脚本几毫秒就能跑完,所以5秒超时已经非常宽松了。

3.2 端到端推理流程与校验循环

text-to-cad的推理不能是“生成一次就完事”,必须做成“生成-执行-校验-修正”的闭环。我的完整流程是这样的:用户输入自然语言描述,系统先把它组装进一个固定模板,模板里明确要求LLM用CadQuery语法、必须给出参数化变量、不得省略特征列表。生成的代码进沙箱执行,执行输出与报错信息一起返回。如果没有报错,继续做几何校验,比如实体体积是否大于零、包围盒尺寸是否符合描述。校验不通过就把错误信息反馈给模型,让它重新生成。这个循环最多跑三到四次,超过就放弃并返回失败原因。

用伪代码把核心逻辑写出来,方便你照着搭:

def generate_cad(prompt, retries=3): code = llm.generate(CAD_PROMPT_TEMPLATE.format(prompt)) for attempt in range(retries): report = sandbox.run(code, timeout=5) if report.success and geometry_check(report.bbox, prompt): return code, report code = llm.generate( FIX_PROMPT_TEMPLATE.format( original_prompt=prompt, last_code=code, error_msg=report.error ) ) return None, report

这个循环的价值在于把“模型犯错”转化为“可管理的重试成本”。LLM生成代码的首次成功率实测大概在60%到70%,但经过一次修正后能到85%以上,两次修正后基本稳定在90%以上。也就是说,真正卡住系统的不是模型能力,而是你愿不愿意多写这一层校验逻辑。

3.3 真实案例拆解:带四个圆角孔的矩形底板

用一个实际例子把整个流程串起来。假设用户输入:“设计一个矩形底板,长60mm宽40mm厚3mm,四角有R2圆角,四个安装孔直径6mm,孔中心距边缘5mm。”

模型生成的CadQuery代码大致长这样:

import cadquery as cq L, W, H = 60.0, 40.0, 3.0 corner_r = 2.0 hole_d = 6.0 margin = 5.0 half_l = L / 2 - margin half_w = W / 2 - margin plate = ( cq.Workplane("XY") .rect(L, W) .vertices() .fillet(corner_r) .extrude(H) ) plate = ( plate.faces(">Z") .workplane() .pushPoints([ (half_l, half_w), (half_l, -half_w), (-half_l, half_w), (-half_l, -half_w), ]) .hole(hole_d) ) cq.exporters.export(plate, "plate.step")

这段代码执行后,得到的是圆心位于四角圆角范围内的四个孔,孔中心到边缘的距离是5mm,圆角半径2mm,整体形状正确。但如果我没有校验循环,模型第一次生成时很可能会把pushPoints里的坐标写成(L - margin, W - margin)这种绝对坐标,那样所有孔都会挤到右上角一个象限里去。这种错误静态检查看不出问题,代码能跑、几何能生成,但语义完全错误。只有几何校验环节去检查四个孔中心两两之间的距离是否符合矩形分布,才能抓出来。

3.4 参数化自校正与导出

讲到参数化,还有一个实用技巧:在生成的代码末尾加一段自检代码,让CadQuery自己把实体的体积、包围盒尺寸、面数打印出来。这样校验逻辑就不需要依赖外部几何分析工具了,直接解析输出字符串即可。我的习惯是让模型遵循约定在代码末尾打印一段JSON格式的实体报告,用正则提取出关键字段,失败就自动进入修正流程。

导出格式方面,国内机械加工和设计评审链条上,STEP是最稳的中间格式,几乎所有CAD与CAM工具都认。CadQuery导出STEP是在cq.exporters.export(plate, "plate.step")这行代码里完成的。注意导出的坐标单位默认是毫米,这是机械设计里的标准惯用单位,不需要额外转换。如果需要做渲染预览,CadQuery也可以直接导出SVG三视图,方便快速核查形状。

4. 评估与避坑:怎么判断一个text-to-cad系统“真的能用”

4.1 三层评估体系

模型训完了,怎么量化判断“它到底行不行”?单纯看代码能不能跑,完全不够,因为能跑的代码可能语义完全错误。我搭了一套三层评估体系,每一层解决一个问题。

评估层方法解决的问题
执行成功率代码在沙箱中能否成功产出几何实体是否具备基本语法与建模能力
几何对齐度生成实体与描述中关键尺寸的误差(体积、包围盒、孔数)是否准确理解了尺寸与特征
语义匹配度多视角渲染图与文本做多模态相似度计算是否真正符合用户的形状意图

第一层的执行成功率:用一个固定测试集,每条文本生成3次,只要有1次能成功执行就算通过。这个指标决定系统有没有“下限”。我实测的项目里,从0到能跑到稳定90%以上,主要靠数据清洗和控制生成时的温度参数。第二层的几何对齐度:让模型生成同一描述下的多次输出,检查孔的个数、位置分布、包围盒尺寸是否符合描述。这个指标对尺寸漂移类问题很敏感。第三层的语义匹配度:把生成的STEP渲染成六视图,与输入文本计算相似度分数,虽然对CAD这种抽象形状来说不够精确,但作为快速筛选信号足够用。

4.2 高频故障与排查实录

我把自己遇到的故障按频率排了个序,前几个具有很高的复现率。

故障现象根因排查思路
生成代码语法错误LLM生成的括号不匹配、变量名不一致静态检查+报错回传修复,重试3次
执行超时/死循环模型写出了while真循环或异常递归沙箱强制超时5秒,内存限制1GB
尺寸严重漂移数字token切分导致精确数值感知弱在prompt里列出参数表,生成后做数值校验
特征方向错误孔开在反方向、拉伸方向反了检查生成实体的面法向与开孔方向
代码能跑但特征丢失模型“忘记”了描述中的部分特征用结构化prompt把特征清单逐条列出

尺寸漂移这个坑要多说几句。LLM对数字的“感知”是离散的,不像几何内核那样连续。我见过最典型的一个案例:要求“孔间距18mm”,模型生成了“hole(18)”——它把“间距18mm”理解成“孔直径18mm”了。这个错误的级别非常隐蔽,因为代码能执行、模型也正确生成了一个孔,只是语义被偷换了。我的应对办法是强制prompt使用结构化参数声明,把尺寸变量单独拎出来声明,而不要在特征函数里裸写数字:

# 正确写法 hole_diameter = 6.0 hole_spacing = 18.0 # 使用变量进行特征操作

这种做法本质上是在“给数字做语义锚点”,变相降低模型对数值的误用概率。另一个通行的办法是生成后用正则提取所有数字,与预期尺寸表做交叉验证,一旦发现越界数值就触发修正或直接丢弃。

4.3 工程化心得:沙箱、批处理与速度优化

工程化落地时还有几个非技术问题的经验。沙箱的安全约束不能只靠超时,我见过一次模型生成的代码在循环里反复拉伸实体,一瞬间给磁盘写入了几个G的临时数据。所以我现在的沙箱会在网络、磁盘写入、CPU时间三个维度同时加限制:禁网、禁大文件写入、限定CPU配额。这个组合目前没有再出现过安全事故。

批处理场景下,vLLM的吞吐量优势非常明显。单条推理延迟可能不比原生推理快,但并发请求上来之后,单位时间生成条数能提升三到五倍。我在做批量评估时会先用vLLM一次性生成100条候选代码,流水线并行执行校验,效率很可观。推理时的prompt模板也值得反复打磨:不要用“请生成一个……”这种开放式指令,要明确约束“只输出Python代码,使用CadQuery库,变量定义放在代码开头”。实测下来,明确约束能让执行成功率提高近20个百分点。

5. 落地场景与下一步扩展

5.1 真正有需求的场景

text-to-cad的价值要落在具体场景里才看得出来。第一类是3D打印创客场景,很多人脑子里有想法但不会建三维模型,口语化描述配合生成可编辑参数模型,能大幅降低创作门槛。第二类是非标自动化设备设计,比如夹具、防错工装这类零件结构相对标准化但尺寸频繁变动的场景,把“生成-校验-修改”做成闭环后,每次变动省下的建模时间以小时计。第三类是标准件选型和零件复用,用自然语言描述特征去检索既有CAD库里的相似模型,比按文件名翻找高效得多。

第四类容易被忽略但我觉得潜力很大:设计规则的自动化校验。结合LLM生成的参数化特征与几何校验逻辑,可以在设计早期就判断出“壁厚过薄不适合注塑”“孔距过近容易导致应力集中”这类规则类问题。这本质上是把文本到CAD从“生成器”扩展成了“设计审查助手”。

5.2 从单轮调用到多智能体协作

目前我的实践还是单轮“文本进-代码出”为主,但下一步毫无疑问是往Agent化走。具体说,就是让LLM不再一次性生成完整模型,而是先规划建模步骤,再分步调用建模工具,每做完一步就做一次几何检查,发现偏差自动回退再试。这更符合真实设计流程里“先定轮廓、再加特征、最后做修饰”的节奏,也能显著降低单次生成的压力。

另外一个值得探索的方向是与仿真分析工具打通。参数化模型天然能挂接材料属性,生成后直接进有限元分析,然后把仿真结果反馈给LLM,形成一个“设计-验证-迭代”的自动化循环。这个方向一旦跑通,机械设计里的很多重复性工作会被真正替代。

最后分享一个我个人的体会:不要被“大模型能理解三维空间”这种说法迷惑。它并不能,它只是在按统计规律拼接代码,一切几何正确性都依赖你搭的那层执行校验闭环。所以做这个方向,与其追逐更聪明的模型,不如把精力投在“数据质量”和“校验闭环”上。把执行成功率和几何校验做到90%以上,哪怕基座模型不那么大,这套系统也能在真实生产环境里稳稳立住。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询