環(huán)境的鴻溝與應(yīng)對(duì))
1. 從一堆跑得通的Demo說起AICAD落地到底卡在哪過去一年多我陸陸續(xù)續(xù)接觸過十幾個(gè)號(hào)稱AICAD的項(xiàng)目有做圖紙智能識(shí)別的有做參數(shù)自動(dòng)生成的也有做自然語言驅(qū)動(dòng)建模的。幾乎每一個(gè)在演示階段都讓人眼前一亮上傳一張DWG幾秒鐘后模型結(jié)構(gòu)就出來了輸入一句給我畫個(gè)法蘭盤屏幕上真的長出了一個(gè)帶螺栓孔的零件。但真正把這些東西往工程環(huán)境里搬的時(shí)候問題就來了——原本在Demo里跑得飛快的流程到了實(shí)際項(xiàng)目里要么精度不夠要么速度慢到?jīng)]法用要么干脆在某個(gè)環(huán)節(jié)直接崩掉。這個(gè)現(xiàn)象不是個(gè)例。我后來跟不少同行聊發(fā)現(xiàn)大家遇到的困境高度相似Demo滿天飛工程走不通。這不是AI不行也不是CAD不行而是兩者結(jié)合的那條鏈路里藏著太多在演示階段被刻意忽略的細(xì)節(jié)。這篇文章我想把這條鏈路拆開從數(shù)據(jù)格式、幾何內(nèi)核、AI能力邊界、工程約束幾個(gè)角度聊聊為什么能跑通和能用之間隔著一道鴻溝以及我實(shí)際踩過的一些坑和總結(jié)出來的應(yīng)對(duì)思路。如果你正在做AICAD相關(guān)的產(chǎn)品、研究或者內(nèi)部工具或者你只是好奇為什么這個(gè)方向喊了這么久卻遲遲沒有大規(guī)模落地那這篇內(nèi)容應(yīng)該能給你一些參考。我會(huì)盡量少講概念多講實(shí)際遇到的情況和背后的原因。2. 數(shù)據(jù)格式這道坎DXF和DWG遠(yuǎn)沒有看起來那么標(biāo)準(zhǔn)2.1 DXF的標(biāo)準(zhǔn)是個(gè)美好的誤會(huì)很多人做AICAD的第一步就是解析DXF因?yàn)樗俏谋靖袷娇雌饋斫Y(jié)構(gòu)清晰用Python的ezdxf庫幾行代碼就能讀出來。我一開始也是這么想的直到我拿了幾十張來自不同設(shè)計(jì)院、不同軟件版本導(dǎo)出的DXF文件做測(cè)試才發(fā)現(xiàn)事情沒那么簡單。DXF確實(shí)有官方規(guī)范但實(shí)際文件里充斥著各種方言。同樣是直線有的用LINE實(shí)體有的用LWPOLYLINE有的用POLYLINE加VERTEX組合同樣是文字MTEXT和TEXT的混用幾乎是常態(tài)而且MTEXT里的格式控制碼能把人逼瘋。更麻煩的是圖層命名有的設(shè)計(jì)院用墻-承重-240有的用WALL_240_LOAD還有的干脆用拼音首字母。你寫一套規(guī)則去解析換一個(gè)來源就失效。我做過一個(gè)統(tǒng)計(jì)拿100張來自不同渠道的DXF文件用同一套解析邏輯去提取墻體信息準(zhǔn)確率大概在60%到70%之間。剩下的30%到40%要么是圖層命名對(duì)不上要么是實(shí)體類型超出預(yù)期要么是坐標(biāo)系統(tǒng)不一致。這個(gè)準(zhǔn)確率在Demo里演示沒問題因?yàn)槟憧梢蕴粢粡埜蓛舻膱D但到了工程環(huán)境沒人會(huì)給你挑圖的機(jī)會(huì)。2.2 DWG的封閉性讓AI無從下手DWG比DXF更麻煩。它是二進(jìn)制格式而且Autodesk一直沒有完全公開其內(nèi)部結(jié)構(gòu)。雖然有一些開源庫能讀DWG但支持程度參差不齊遇到復(fù)雜實(shí)體或者高版本文件就容易出問題。我試過用開源方案讀一個(gè)2018版本的DWG里面包含動(dòng)態(tài)塊和自定義對(duì)象結(jié)果直接報(bào)錯(cuò)退出。這就導(dǎo)致一個(gè)很尷尬的局面AI模型需要結(jié)構(gòu)化數(shù)據(jù)才能發(fā)揮威力但CAD世界里的數(shù)據(jù)恰恰是最不結(jié)構(gòu)化的。你拿到的圖紙本質(zhì)上是一堆幾何圖元的集合沒有語義沒有層級(jí)沒有這是一面墻或者這是一個(gè)螺栓孔的標(biāo)注。AI要做的第一件事就是把這些幾何圖元重新組織成有意義的工程對(duì)象而這個(gè)重新組織的過程恰恰是最難自動(dòng)化的。2.3 從幾何到語義中間缺了一層翻譯我后來想明白一件事AICAD的核心難點(diǎn)不在于AI模型本身有多強(qiáng)而在于從幾何圖元到工程語義之間的那層翻譯。這層翻譯在人類工程師腦子里是自然而然發(fā)生的——看到兩條平行線加一段圓弧就知道那是一個(gè)倒角看到一組同心圓加中心線就知道那是一個(gè)孔。但要讓機(jī)器理解這些需要大量的領(lǐng)域知識(shí)和規(guī)則。我試過用純視覺方案把DWG渲染成圖片然后用目標(biāo)檢測(cè)模型去識(shí)別墻體、門窗、標(biāo)注。效果怎么說呢在簡單圖紙上還行一旦圖紙密度上去或者有大量重疊圖元識(shí)別率就斷崖式下跌。而且視覺方案有個(gè)致命問題它只能給出大概位置沒法給出精確的幾何參數(shù)。工程上要的是精確到毫米的尺寸不是這里大概有個(gè)門。后來我轉(zhuǎn)向了基于圖元關(guān)系的方案先解析出所有幾何實(shí)體然后根據(jù)它們之間的空間關(guān)系平行、垂直、共線、同心等來推斷語義。這個(gè)思路更靠譜但實(shí)現(xiàn)起來工作量巨大而且規(guī)則很難窮舉。一個(gè)墻體的判定可能涉及圖層、線型、顏色、線寬、相鄰關(guān)系、閉合性等十幾個(gè)特征每個(gè)特征都要調(diào)閾值調(diào)完閾值還要處理例外情況。3. 幾何內(nèi)核為什么FreeCAD和OpenCascade不是萬能藥3.1 OpenCascade很強(qiáng)但學(xué)習(xí)曲線陡得嚇人說到CAD幾何內(nèi)核OpenCascade簡稱OCC是繞不開的。它是開源的功能強(qiáng)大支持BRep建模、布爾運(yùn)算、倒角圓角、曲面操作等等。FreeCAD就是基于OCC構(gòu)建的。我一開始覺得有了OCC幾何處理這塊應(yīng)該不用愁了。實(shí)際用起來才發(fā)現(xiàn)OCC的API設(shè)計(jì)對(duì)新手極不友好。它的文檔零散示例代碼少很多功能要靠讀源碼或者翻論壇才能搞明白。而且OCC的報(bào)錯(cuò)信息經(jīng)常讓人摸不著頭腦一個(gè)布爾運(yùn)算失敗可能返回一個(gè)錯(cuò)誤碼但具體為什么失敗、哪一步出了問題得自己一步步排查。我印象最深的一次是想把一個(gè)從DWG讀進(jìn)來的二維輪廓拉伸成三維實(shí)體。輪廓本身是閉合的看起來沒問題但OCC就是報(bào)錯(cuò)說無法構(gòu)建面。后來查了很久才發(fā)現(xiàn)輪廓里有一段圓弧的端點(diǎn)跟相鄰直線的端點(diǎn)差了0.001毫米肉眼完全看不出來但OCC的容差判定就是過不去。這種問題在Demo里不會(huì)遇到因?yàn)镈emo用的都是精心準(zhǔn)備的干凈數(shù)據(jù)但工程數(shù)據(jù)里這種微小誤差遍地都是。3.2 FreeCAD的生態(tài)能用但別指望它開箱即用FreeCAD作為開源CAD平臺(tái)生態(tài)確實(shí)在慢慢變好。它有Python接口可以腳本化操作這對(duì)AICAD來說是個(gè)很大的優(yōu)勢(shì)——你可以用Python寫AI邏輯然后直接調(diào)用FreeCAD的API來建模。但FreeCAD本身有不少坑比如它的齒輪工具經(jīng)常被吐槽不好用參數(shù)化建模的穩(wěn)定性也一般復(fù)雜模型容易崩。我用FreeCAD做過一個(gè)批量生成標(biāo)準(zhǔn)件的工具輸入規(guī)格參數(shù)自動(dòng)生成對(duì)應(yīng)的三維模型。簡單零件沒問題但一旦涉及復(fù)雜特征比如變位齒輪或者非標(biāo)螺紋FreeCAD就力不從心了。而且FreeCAD的版本兼容性也是個(gè)問題不同版本之間的API有差異升級(jí)一次可能就要改一堆代碼。3.3 自研內(nèi)核大多數(shù)團(tuán)隊(duì)想都不要想有些團(tuán)隊(duì)會(huì)想既然開源內(nèi)核有這么多限制那干脆自研一個(gè)。我的建議是除非你有十年以上的幾何算法積累和一個(gè)穩(wěn)定的數(shù)學(xué)團(tuán)隊(duì)否則不要碰這個(gè)方向。幾何內(nèi)核的復(fù)雜度遠(yuǎn)超大多數(shù)人的想象光是布爾運(yùn)算的魯棒性就夠研究好幾年。而且自研內(nèi)核意味著你要自己處理所有邊界情況而CAD里的邊界情況是無窮無盡的。我見過一個(gè)團(tuán)隊(duì)花了兩年時(shí)間自研了一個(gè)簡易內(nèi)核結(jié)果在處理復(fù)雜曲面的時(shí)候頻繁崩潰最后還是切回了OCC。這個(gè)教訓(xùn)很深刻在幾何內(nèi)核這件事上不要重復(fù)造輪子除非你確定自己能造得更好。4. AI模型在CAD場(chǎng)景下的真實(shí)能力邊界4.1 視覺識(shí)別看起來很美用起來很痛用深度學(xué)習(xí)做圖紙識(shí)別是很多AICAD項(xiàng)目的切入點(diǎn)。思路很直接把DWG渲染成圖片然后用目標(biāo)檢測(cè)或者語義分割模型去識(shí)別圖元。我試過幾種主流方案包括基于YOLO的檢測(cè)和基于U-Net的分割效果總結(jié)下來就是在受控條件下表現(xiàn)不錯(cuò)在真實(shí)場(chǎng)景下勉強(qiáng)能用在工程精度要求下不夠看。問題主要出在幾個(gè)方面。第一是分辨率工程圖紙的細(xì)節(jié)非常密集一張A1圖紙渲染成2000x2000的圖片很多小尺寸圖元就糊成一團(tuán)了。要提高分辨率顯存和計(jì)算量就上去了推理速度直線下降。第二是重疊圖元CAD圖紙里圖元重疊是常態(tài)視覺模型很難區(qū)分哪些是主要圖元哪些是輔助線。第三是精度視覺模型給出的是像素坐標(biāo)要轉(zhuǎn)換成工程坐標(biāo)需要標(biāo)定而標(biāo)定本身就會(huì)引入誤差。我后來把視覺方案定位為輔助而不是主力用視覺模型做初步篩選和區(qū)域定位然后用幾何方法做精確提取。這樣結(jié)合下來效果比純視覺好不少但流程也復(fù)雜了不少。4.2 大模型直接生成CAD代碼方向?qū)Φ愤€長最近一年用大模型直接生成CAD腳本或者建模代碼的思路很火。比如你輸入畫一個(gè)長寬高分別為100、50、30的盒子頂部中心有一個(gè)直徑20的孔模型輸出一段Python代碼調(diào)用FreeCAD或者OCC的API來建模。這個(gè)方向我覺得是對(duì)的因?yàn)榇竽P蜕瞄L處理自然語言和結(jié)構(gòu)化輸出而CAD建模本質(zhì)上就是一系列結(jié)構(gòu)化操作。但實(shí)際用下來問題也很明顯。首先是空間推理能力不足大模型對(duì)三維空間的理解還很淺你讓它生成一個(gè)孔在盒子頂部中心它可能把孔放到側(cè)面或者偏離中心。其次是API幻覺大模型經(jīng)常會(huì)編造不存在的函數(shù)或者參數(shù)生成的代碼跑不起來。第三是精度控制工程上對(duì)尺寸公差有嚴(yán)格要求大模型生成的代碼往往忽略這些細(xì)節(jié)。我目前的用法是讓大模型生成骨架代碼然后我自己補(bǔ)全細(xì)節(jié)和校驗(yàn)邏輯。這樣效率確實(shí)有提升但離一句話生成完整模型還有很長的路。4.3 參數(shù)化與約束求解AI暫時(shí)插不上手CAD里有一個(gè)很重要的部分叫參數(shù)化約束求解就是給幾何元素之間定義約束關(guān)系平行、垂直、相切、等長等然后求解器自動(dòng)調(diào)整幾何形狀以滿足約束。這部分目前AI基本插不上手因?yàn)榧s束求解是一個(gè)數(shù)值優(yōu)化問題需要精確的數(shù)學(xué)計(jì)算而不是概率預(yù)測(cè)。我試過用強(qiáng)化學(xué)習(xí)來做約束求解效果很不理想。求解空間太大獎(jiǎng)勵(lì)信號(hào)稀疏訓(xùn)練出來的模型要么收斂慢要么解的質(zhì)量差。后來還是老老實(shí)實(shí)用傳統(tǒng)的數(shù)值求解器AI只在前面做約束識(shí)別和推薦。5. 工程環(huán)境的真實(shí)約束為什么能用比能跑難十倍5.1 精度要求Demo可以模糊工程必須精確Demo里最常聽到的一句話是差不多就行但工程里沒有差不多。一個(gè)螺栓孔的位置偏了0.5毫米可能就導(dǎo)致裝配不上一條墻線的長度差了1毫米可能就導(dǎo)致面積計(jì)算錯(cuò)誤。AI模型天生帶有概率性輸出結(jié)果有不確定性這在工程場(chǎng)景里是致命的。我做過一個(gè)實(shí)驗(yàn)用同一個(gè)AI模型對(duì)同一張圖紙做十次識(shí)別結(jié)果每次的墻體位置都有細(xì)微差異最大偏差到了2毫米。這個(gè)偏差在Demo里看不出來但在工程里是不可接受的。后來我的做法是AI只負(fù)責(zé)識(shí)別不負(fù)責(zé)定位定位交給幾何算法來做確保每次結(jié)果一致。5.2 速度要求批量處理時(shí)慢一秒都是災(zāi)難Demo通常只處理一張圖而且可以等。但工程環(huán)境里一個(gè)項(xiàng)目可能有幾百張圖紙而且用戶希望幾分鐘內(nèi)出結(jié)果。我算過一筆賬如果單張圖紙的處理時(shí)間是30秒100張就是50分鐘這個(gè)時(shí)間成本大多數(shù)用戶接受不了。AI模型的推理速度是瓶頸之一。一個(gè)中等規(guī)模的視覺模型在GPU上跑一張圖可能要幾百毫秒加上前后處理單張圖紙輕松超過10秒。要提速要么換更小的模型精度下降要么加硬件成本上升要么優(yōu)化流程工程量巨大。我目前的做法是把AI推理和幾何處理并行化能壓到單張5秒左右但離秒級(jí)還有距離。5.3 可解釋性出了問題得知道為什么工程環(huán)境里用戶不僅要知道結(jié)果還要知道結(jié)果是怎么來的。如果AI說這里有一面墻用戶會(huì)問為什么你認(rèn)為這是墻依據(jù)是什么如果AI給不出合理的解釋用戶就不敢用。這一點(diǎn)上純AI方案很吃虧。深度學(xué)習(xí)模型是個(gè)黑盒你很難解釋它為什么做出某個(gè)判斷。我后來在流程里加了一層規(guī)則校驗(yàn)AI給出初步判斷然后用幾何規(guī)則去驗(yàn)證驗(yàn)證通過的才輸出不通過的標(biāo)記出來讓人工復(fù)核。這樣雖然增加了工作量但用戶接受度高了很多。5.4 數(shù)據(jù)安全與私有化部署工程圖紙往往涉及商業(yè)機(jī)密很多用戶要求私有化部署不能把圖紙上傳到云端。這就意味著你不能用那些需要聯(lián)網(wǎng)的大模型API只能用本地部署的模型。而本地部署的模型能力通常比云端模型差一截這是個(gè)硬約束。我試過在本地部署一個(gè)中等規(guī)模的開源大模型來做CAD相關(guān)的自然語言處理效果比云端模型差不少尤其是在復(fù)雜指令的理解上。后來只能把任務(wù)拆細(xì)讓本地模型做簡單分類和提取復(fù)雜邏輯用規(guī)則引擎來補(bǔ)。6. 我實(shí)際踩過的幾個(gè)坑和應(yīng)對(duì)思路6.1 坑一以為解析了DXF就萬事大吉前面提過DXF的方言問題讓我吃了不少虧。我最初的解析邏輯只考慮了標(biāo)準(zhǔn)實(shí)體結(jié)果遇到用自定義實(shí)體的圖紙就直接跳過導(dǎo)致信息丟失。后來我加了一層未知實(shí)體收集把所有不認(rèn)識(shí)的實(shí)體單獨(dú)存起來分析它們的共同特征再逐步擴(kuò)展解析規(guī)則。這個(gè)過程很枯燥但效果是實(shí)打?qū)嵉摹?.2 坑二低估了幾何容差的重要性O(shè)CC的容差問題讓我debug了整整一周。后來我養(yǎng)成了一個(gè)習(xí)慣所有從外部讀入的幾何數(shù)據(jù)先做一輪清洗包括合并重合點(diǎn)、修復(fù)微小間隙、統(tǒng)一坐標(biāo)精度。這一步看起來簡單但能避免后面大量的莫名其妙報(bào)錯(cuò)。6.3 坑三AI模型選型只看精度不看速度我一開始選了一個(gè)精度很高的視覺模型單張推理要2秒加上前后處理一張圖紙要15秒。后來換了一個(gè)輕量模型精度降了3個(gè)百分點(diǎn)但速度提升了5倍。在實(shí)際使用中用戶對(duì)速度的敏感度遠(yuǎn)高于對(duì)那3個(gè)百分點(diǎn)精度的敏感度。6.4 坑四忽略了用戶的實(shí)際工作流我最初做的工具是上傳圖紙-等待處理-下載結(jié)果后來發(fā)現(xiàn)用戶根本不這么用。他們希望工具能集成到現(xiàn)有的CAD軟件里直接在繪圖界面里調(diào)用。這個(gè)需求變更導(dǎo)致我重構(gòu)了整個(gè)交互層。教訓(xùn)是做工具之前先搞清楚用戶實(shí)際是怎么工作的。7. 如果現(xiàn)在讓我重新做我會(huì)怎么設(shè)計(jì)這條鏈路7.1 分層架構(gòu)AI只做它擅長的事我現(xiàn)在傾向于把整個(gè)鏈路分成三層感知層、語義層、幾何層。感知層用AI做初步識(shí)別和分類語義層用規(guī)則和知識(shí)圖譜做對(duì)象關(guān)系推斷幾何層用OCC做精確建模和校驗(yàn)。AI只在感知層發(fā)揮作用不參與后面的精確計(jì)算。這樣既利用了AI的泛化能力又保證了工程精度。7.2 數(shù)據(jù)預(yù)處理花多少時(shí)間都值得數(shù)據(jù)預(yù)處理的重要性怎么強(qiáng)調(diào)都不為過。我現(xiàn)在會(huì)把30%到40%的開發(fā)時(shí)間花在數(shù)據(jù)清洗和標(biāo)準(zhǔn)化上包括格式統(tǒng)一、坐標(biāo)歸一、圖層映射、實(shí)體修復(fù)等。這一步做扎實(shí)了后面的AI和幾何處理都會(huì)順暢很多。7.3 人機(jī)協(xié)同不要追求全自動(dòng)全自動(dòng)是很多AICAD項(xiàng)目的執(zhí)念但實(shí)際工程里全自動(dòng)往往意味著高風(fēng)險(xiǎn)。我現(xiàn)在更傾向于人機(jī)協(xié)同AI做初步處理人工做復(fù)核和修正系統(tǒng)記錄人工修正的結(jié)果用來迭代優(yōu)化AI模型。這樣雖然單次處理時(shí)間長了但整體可靠性和用戶信任度高了很多。7.4 從小場(chǎng)景切入別一上來就做通用平臺(tái)我見過太多團(tuán)隊(duì)一上來就想做通用AICAD平臺(tái)結(jié)果做了兩年還在Demo階段。我的建議是先找一個(gè)足夠窄的場(chǎng)景比如批量提取圖紙中的門窗表或者自動(dòng)生成標(biāo)準(zhǔn)件三維模型把這個(gè)場(chǎng)景做到極致再逐步擴(kuò)展。窄場(chǎng)景的好處是邊界清晰容易驗(yàn)證也容易找到愿意付費(fèi)的用戶。8. 一些具體的工具選型和技術(shù)細(xì)節(jié)8.1 DXF解析ezdxf夠用但要自己補(bǔ)很多邏輯Python生態(tài)里ezdxf是解析DXF最成熟的庫。它支持大多數(shù)標(biāo)準(zhǔn)實(shí)體文檔也比較全。但如前所述實(shí)際DXF文件里的方言需要你自己處理。我的做法是在ezdxf之上封裝一層把不同來源的實(shí)體統(tǒng)一成內(nèi)部表示這樣上層邏輯就不用關(guān)心底層差異了。8.2 DWG處理能用ODA就用ODA如果預(yù)算允許ODAOpen Design Alliance的SDK是處理DWG最靠譜的方案。它支持各種版本的DWG實(shí)體覆蓋全穩(wěn)定性好。缺點(diǎn)是收費(fèi)而且集成起來有一定工作量。如果預(yù)算有限可以考慮用FreeCAD的DWG導(dǎo)入功能但支持程度有限復(fù)雜圖紙容易出問題。8.3 幾何處理OCC為主FreeCAD為輔OCC負(fù)責(zé)底層的幾何運(yùn)算FreeCAD負(fù)責(zé)上層的建模和參數(shù)化。兩者通過Python接口銜接。需要注意的是FreeCAD的Python API在不同版本間有變化建議鎖定一個(gè)穩(wěn)定版本不要頻繁升級(jí)。8.4 AI模型本地部署優(yōu)先云端為輔考慮到數(shù)據(jù)安全我傾向于本地部署開源模型。視覺任務(wù)可以用YOLO或者Detectron2自然語言任務(wù)可以用ChatGLM或者Qwen的中小規(guī)模版本。如果確實(shí)需要更強(qiáng)的能力可以在用戶授權(quán)的前提下調(diào)用云端API但要做好數(shù)據(jù)脫敏。9. 關(guān)于這個(gè)方向的一些個(gè)人判斷AICAD這個(gè)方向我覺得長期來看是有價(jià)值的但短期內(nèi)不要期待顛覆。CAD是一個(gè)積累了幾十年的領(lǐng)域里面的工程知識(shí)和經(jīng)驗(yàn)不是AI幾年就能學(xué)會(huì)的。AI能做的是把那些重復(fù)性高、規(guī)則明確的工作自動(dòng)化比如圖紙信息提取、標(biāo)準(zhǔn)件生成、批量修改等。這些場(chǎng)景雖然不性感但實(shí)實(shí)在在能省時(shí)間。另一個(gè)判斷是這個(gè)方向的贏家大概率不是純AI公司也不是純CAD公司而是能把兩者結(jié)合好的團(tuán)隊(duì)。純AI公司不懂CAD的工程約束純CAD公司不懂AI的能力邊界只有兩者都懂才能做出真正能用的產(chǎn)品。最后說一句如果你正在做這個(gè)方向不要被Demo的漂亮效果迷惑多去實(shí)際工程環(huán)境里跑一跑多跟一線工程師聊一聊你會(huì)發(fā)現(xiàn)很多在辦公室里想不到的問題。這些問題才是真正的機(jī)會(huì)所在。