GenCAD 詳細教學

本教學對應 repo commit f5484cf (2025-07-14),最後驗證日 2026-05-20。 涵蓋專案定位、安裝、核心架構、CLI 詳細用法、應用情境、資安掃描、FAQ、進階技巧、整合建議共 11 個章節。


1. 專案定位

1.1 是什麼

GenCAD 是 University of Maryland (Ferdous Alam 等人) 發表於 TMLR 2025 的「影像條件 CAD 生成 (Image-conditioned CAD Generation)」系統。給定一張 2D sketch、影像或渲染圖,系統會生成對應的參數化 CAD command sequence,再透過 OpenCascade (OCC) 還原成 .stl / .step 等 3D 檔案。

1.2 為什麼重要

  • CAD 表示是可編輯的:不像 NeRF / Gaussian Splatting / Mesh 生成,CAD command sequence 保留了「extrudesketchcirclearc」等可解釋語意,工程師可手動微調
  • 比 DeepCAD 進一步:DeepCAD 解決 CAD-only autoencoder;GenCAD 加上 CLIP-style image conditioning + Diffusion Prior,能從 image 直接驅動生成
  • 可作為通用框架:核心三段式 (sequence autoencoder + contrastive align + latent diffusion) 可移植到「分子序列、protein domain、生醫信號」等領域

1.3 與相關工作的關係

工作關係
DeepCAD (ChrisWu1997, 2021)GenCAD 直接借用 cadlib/utils/cad_dataset.py,CAD 序列定義完全相容
DALL·E / Stable Diffusion借鑑 CLIP-style alignment + diffusion prior 概念,但 latent space 是 CAD 命令而非 pixel
DreamFusion / Magic3D都是 image→3D,但 DreamFusion 輸出 NeRF/mesh,GenCAD 輸出可編輯參數
pythonocc-coreOpenCascade 的 Python binding,負責 CAD 命令 → STL 轉檔

1.4 一句話總結

把「sketch / 影像」翻成「可編輯的 CAD 命令序列」的三段式生成系統 — Transformer autoencoder 編碼 CAD 命令,CLIP 對齊影像與 CAD latent,Diffusion Prior 從影像分布抽樣 latent。


2. 安裝指南

2.1 系統需求

項目最低要求建議
OSLinux x86_64Ubuntu 22.04
Python3.103.10
GPUCUDA 11.x 相容 NVIDIAA100 / RTX 4090
RAM16 GB32 GB
Disk5 GB (含 checkpoint)20 GB
pythonocc-core7.9.0conda 安裝(pip 沒得裝)

2.2 方案 A — Docker(推薦)

 1# 1. clone repo
 2git clone https://github.com/ferdous-alam/GenCAD
 3cd GenCAD
 4
 5# 2. 預先下載資料集 + checkpoint(必須先做)
 6#    Dataset: https://drive.google.com/drive/folders/1M0dPr5kILGY9HTRCHox1vLLDhhxJWl_C
 7#    放到 data/
 8#    Checkpoints: https://drive.google.com/drive/folders/1Ej7wdtlqT5P-SoUf3gsZXD8b78XqhiI5
 9#    放到 data/ckpt/
10
11# 3. build image(會解 conda env,需 10–15 min)
12docker build -t gencad:latest .
13
14# 4. 訓練 CSR
15docker run --gpus all -it gencad:latest \
16  conda run -n gencad_env python train_gencad.py csr -name test -gpu 0
17
18# 5. 推論(含 xvfb headless 渲染)
19docker run --gpus all \
20  -v $(pwd)/data/images:/app/data/images \
21  -v $(pwd)/assets:/app/assets \
22  -v $(pwd)/results:/app/results \
23  -it gencad:latest /bin/bash
24
25# 容器內:
26xvfb-run --server-args="-screen 0 2048x2048x24" \
27  python inference_gencad.py -image_path data/images -export_img -export_stl

2.3 方案 B — conda + pip(手動)

 1# 1. 建立 env
 2conda create -n gencad_env python=3.10 -y
 3conda activate gencad_env
 4
 5# 2. pythonocc-core 只能用 conda 裝(pip 沒有)
 6conda install -c conda-forge pythonocc-core=7.9.0
 7
 8# 3. 其他依賴用 pip
 9pip install -r requirements.txt
10# 內容:torch torchvision transformers opencv-python scikit-learn x_clip
11#       ema_pytorch tensorboardX tensorboard einops h5py plyfile trimesh
12
13# 4. headless 視覺化需額外裝 xvfb
14sudo apt-get install -y xvfb libgl1 libxrender1 libsm6 libxext6 mesa-utils

2.4 安裝流程圖


flowchart TD
    A[Clone repo] --> B{選擇方案}
    B -->|Docker| C[build gencad:latest
~10–15 min] B -->|conda + pip| D[conda env + pythonocc-core] D --> E[pip install -r requirements.txt] E --> F[apt install xvfb 等 OpenGL libs] C --> G[Download dataset + checkpoint
從 Google Drive] F --> G G --> H{用途} H -->|訓練| I[python train_gencad.py csr/ccip/dp] H -->|推論| J[xvfb-run python inference_gencad.py]

2.5 常見安裝問題

問題解法
ModuleNotFoundError: No module named 'OCC'沒裝 pythonocc-core。pip 裝不了,必須 conda install -c conda-forge pythonocc-core=7.9.0
libtiff.so.6: undefined symbol jpeg12_write_raw_dataconda env 內 libjpeg / libtiff 版本衝突。重建 env 或 conda update --all
RuntimeError: Found no NVIDIA driver容器內沒掛 GPU。Docker 需 --gpus all 旗標
torch.OutOfMemoryError: CUDA out of memory改小 ConfigAEbatch_size,預設 = 2 已經很小

3. 核心架構解析

3.1 三段式 pipeline 總覽


flowchart LR
    subgraph Stage1["Stage 1: CSR Autoencoder (CAD-only)"]
        A1[CAD command sequence
例如 sketch→extrude] --> A2[Transformer Encoder] A2 --> A3[Latent z_cad
256-d] A3 --> A4[Transformer Decoder] A4 --> A5[Reconstructed CAD seq] end subgraph Stage2["Stage 2: CCIP (Image–CAD alignment)"] B1[Sketch / Image] --> B2[ResNet/ViT Image Encoder] A3 -.-> B3[Pretrained CSR Encoder
frozen] B2 --> B4[InfoNCE / CLIP loss] B3 --> B4 B4 --> B5[Aligned image embedding] end subgraph Stage3["Stage 3: Diffusion Prior (DP)"] C1[Image embed] --> C2[ResNet1D Denoiser] C2 --> C3[GaussianDiffusion1D
EMA + auto_normalize] C3 --> C4[Sampled z_cad] end subgraph Inference["Inference"] D1[Test image] --> D2[CCIP image encoder] --> D3[DP sampler] D3 --> D4[CSR decoder] D4 --> D5[CAD vec → vec2CADsolid → STL] end

3.2 各模型檔詳細解析

檔案大小角色關鍵類別
model/autoencoder.py8.3KBCSR Transformer autoencoderVanillaCADTransformer
model/ccip_model.py18KBCLIP-style 對比學習,含 CLOOB / DCL 損失CLIP, GenCADClipAdapter
model/image_encoder.py11.5KBResNet 影像編碼器ResNetImageEncoder
model/image_encoder_vit.py4.2KB備用 ViT 影像編碼器ViT
model/cond_ldm.py20.7KB1D 條件 Latent DiffusionGaussianDiffusion1D
model/denoising_net.py14.8KBResNet1D 去噪網路 (借用 Yura52/rtdl)ResNetDiffusion
model/mlp_prior.py14.1KBMLP-based prior(備選方案)(相關類別)

3.3 三個 Config 對應三段訓練

Config對應主要參數
ConfigAE (configAE.py 5.8KB)CSR autoencoderbatch_size=2, lr=1e-3, num_epochs=10, warmup_step=2000, num_workers=12
ConfigCCIP (configCCIP.py 3.5KB)image–CAD 對齊(見檔內 batch / lr 等)
ConfigDP (configDP.py 3.2KB)Diffusion Priortimesteps, objective, ema_decay, auto_normalize

每個 config 都有 __init__ 自動建 exp_dir 並提示「Overwrite? (y/n)」— 訓練時若想自動化,需手動改 overwrite=True

3.4 CAD command DSL (cadlib/)

借用自 DeepCAD,定義了 CAD 命令的低階表示:

檔案用途
cadlib/macro.py常數定義:EXT_IDX, LINE_IDX, ARC_IDX, CIRCLE_IDX, EOS_IDX, MAX_TOTAL_LEN=60, N_ARGS=17
cadlib/sketch.pySketch 級結構(line / arc / circle 組成 loop)
cadlib/extrude.pyExtrude 操作(sketch → 3D solid)
cadlib/curves.py曲線基元(419 行)
cadlib/visualize.pyvec2CADsolid — CAD vec → OCC TopoDS_Shape

每筆 CAD command vector 是 (60, 17) 的 int 矩陣:60 步序列、17 維 (1 維 command type + 16 維 args,部分用 -1 padding)。

3.5 推論流程 (inference_gencad.py:280 行)


sequenceDiagram
    participant U as User
    participant I as inference_gencad.py
    participant CLIP as GenCADClipAdapter
    participant DP as GaussianDiffusion1D
    participant DEC as CSR Decoder
    participant OCC as OpenCascade

    U->>I: -image_path data/images -export_stl
    loop 每張圖
        I->>CLIP: embed_image(img)
        CLIP-->>I: image_embed
        I->>DP: sample(cond=image_embed)
        DP-->>I: latent (1,1,256)
        I->>DEC: decoder(z=latent)
        DEC-->>I: batch_out_vec (B,60,17)
        I->>I: 找 EOS_IDX → 截斷
        I->>OCC: vec2CADsolid(cad_vec)
        OCC-->>I: TopoDS_Shape
        I->>OCC: write_stl_file → .stl
    end


4. CLI 詳細用法

4.1 訓練 CSR (Stage 1)

1# 基本
2python train_gencad.py csr -name <exp_name> -gpu 0
3
4# 從 checkpoint 繼續
5python train_gencad.py csr -name <exp_name> -gpu 0 \
6  -ckpt "model/ckpt/ae_ckpt_epoch1000.pth"
旗標必填說明
csr子命令,固定
-name, --exp_name實驗名稱,會建立 proj_log/<name>/CSR/
-gpu, --gpu(預設 0)GPU index,不支援多卡
-ckpt, --ckpt_pathoptionalresume 用的 checkpoint 路徑

4.2 訓練 CCIP (Stage 2)

1python train_gencad.py ccip -name <exp_name> -gpu 0 \
2  -cad_ckpt "model/ckpt/ae_ckpt_epoch1000.pth"

-cad_ckpt 必填:CCIP 需要凍結 CSR encoder。

4.3 訓練 DP (Stage 3)

1python train_gencad.py dp -name <exp_name> -gpu 0 \
2  -cad_emb 'data/embeddings/cad_embeddings.h5' \
3  -img_emb 'data/embeddings/sketch_embeddings.h5'

兩個 h5 檔都必填。需先用訓練好的 CSR / CCIP encoder 把全部 CAD seq 和 image 都 forward 過一次、存到 h5。

4.4 推論

1# headless server
2xvfb-run --server-args="-screen 0 2048x2048x24" \
3  python inference_gencad.py \
4    -image_path data/images \
5    -export_img \
6    -export_stl
旗標預設說明
-image_path(必填)輸入影像資料夾,會掃 *.png
-export_imgFalse輸出生成的 STL 用 OCC 渲染的 PNG
-export_stlFalse輸出 .stl

推論過程:load 3 checkpoints (diffusion / clip / cad decoder) → 逐張影像 → save_view → write_stl_file

4.5 STL 視覺化

1python stl2img.py -src path/to/stl -dst path/to/save/images

5. 應用場景

場景是否適用備註
從手繪 sketch 生成可編輯 CAD✅ 原生用途TMLR 2025 paper 主軸
從產品照片重建 CAD⚠️ 部分training data 偏簡單形狀,複雜照片效果未知
自動化機械零件設計⚠️ 評估中視 dataset 涵蓋範圍
結構生成 (非 CAD)❌ 需大改cadlib/ 是 CAD 專用 DSL
作為 sequence-conditional diffusion 框架借鑑✅ 推薦DP + CSR 設計可移植到其他結構化序列領域
教學 / 論文復現✅ 推薦Docker 完整、checkpoint 齊全

6. 資安掃描報告

掃描日期:2026-05-20 / 範圍:*.py + model/ + trainer/ + utils/ + config/ + cadlib/

6.1 紅黃綠燈總結

等級數量摘要
🔴 高風險0無外部 API 呼叫、無 secrets 洩漏、無真 eval/exec
🟡 中風險2 類(1) torch.load 大量使用 (11 處) — pickle 反序列化潛在 RCE;(2) cadlib/visualize.py:136os.system + .format 模板
🟢 低風險其餘為 model.eval() 模式切換、URL 註解、相對路徑 makedirs

6.2 詳細發現

🟡 風險 1:torch.load 大量未指定 weights_only

1# inference_gencad.py:177, 194, 214
2ckpt = torch.load(diffusion_ckpt_path, map_location="cpu")
3clip_checkpoint = torch.load(clip_ckpt_path, map_location='cpu')
4cad_ckpt = torch.load(cad_ckpt_path)
5# trainer/*.py 還有 7 處類似
  • 影響:PyTorch < 2.6 預設 weights_only=False,會用 pickle 反序列化,載入不明來源的 checkpoint 可能執行任意程式碼
  • 緩解:(1) 只用官方 Google Drive checkpoint;(2) PyTorch 2.6+ 改用 torch.load(path, weights_only=True)

🟡 風險 2:os.system.format 模板

1# cadlib/visualize.py:136
2os.system("rm tmp_out_{}.stl".format(name))
  • 影響:若 name 來自不可信輸入並含 shell metacharacter (例如 ; rm -rf /),會 command injection
  • 實務評估:本專案 name 通常是內部 ID / 序號,直接外部利用機會低,但仍建議改為 os.remove(f"tmp_out_{name}.stl")shlex.quote

6.3 觀察到的好習慣

  • 全部 os.makedirs 路徑都是相對路徑或 config-derived,無任意路徑寫入
  • 註解中的 URL 皆為學術引用 (arxiv.org, github.com/...),無實際下載行為
  • 無 hardcoded 密鑰 / API key / database URI
  • subprocess(shell=True)、無 pickle.load、無 __import__ 動態載入

6.4 結論

整體風險:🟡 中等(學術研究使用無問題)。 主要風險集中在「載入第三方 checkpoint」場景。建議:(1) 升 PyTorch ≥ 2.6 並加 weights_only=True;(2) 修 visualize.py:136;(3) 不要從不明來源下載 .pt 檔案。


7. FAQ

Q1: cannot find EOS 是什麼意思? A: Inference 時 CSR decoder 沒在 MAX_TOTAL_LEN=60 步內生成 EOS_IDX,code 用 try/except 跳過。原因通常是:(1) checkpoint 未訓練到收斂;(2) 輸入影像超出 training distribution;(3) Diffusion sample 不穩定。多跑幾次 inference 或調整 DP 的 sampling steps 通常會緩解。

Q2: 為什麼 GPU 沒被用? A: train_gencad.py 只支援單 GPU。確認 -gpu 0 有傳、確認 torch.cuda.is_available()、Docker 確認 --gpus all。Issue #16 詳細討論。

Q3: pythonocc-core 為何不能 pip? A: pythonocc-core 是 OpenCascade 的 SWIG-generated binding,依賴 C++ build 與 OCCT 動態庫,conda-forge 預編譯,pip 沒得裝(除非自己 build)。

Q4: 可以換 ViT 嗎? A: 可以。model/image_encoder_vit.py 已備 ViT 類別,把 train_gencad.pyimage_encoder = ResNetImageEncoder(...) 換成 image_encoder = ViT(...) 即可,但要確認 output dim 與 CCIP 對齊。

Q5: 訓練要多久? A: 論文未明示具體 GPU 時數。從 ConfigAE 預設 num_epochs=10 + batch_size=2 推測,CSR 在單 A100 上應在幾天內。完整 3 stage 預估 1–2 週。

Q6: 沒 GPU 可以跑嗎? A: 推論勉強可(CPU 慢數倍);訓練實務上不行。


8. 進階技巧

8.1 替換影像編碼器

  1. model/ 加新 encoder class,輸出 dim 與 CCIP latent 對齊(預設 256)
  2. train_gencad.pyimage_encoder = ... 換新類別
  3. 重新訓練 CCIP 與 DP(CSR 不需重訓)

8.2 自製 CAD 資料集

  1. 收集 .step / .brep
  2. 用 DeepCAD 提供的 JSON schema 轉成 command sequence (utils/json2vec.py)
  3. utils/cad_dataset.pyCADDataset 介面包裝
  4. CSR 從新資料集 from scratch 或 fine-tune

8.3 加 weights_only=True 補丁

在所有 torch.load(...) 後面加 weights_only=True(PyTorch ≥ 2.6),消除 RCE 風險:

1# repo 內統一改寫
2grep -rln "torch.load(" --include="*.py" \
3  | xargs sed -i 's/torch\.load(\(.*\))/torch.load(\1, weights_only=True)/g'
4# 注意:sed 不會處理已有 weights_only 的;手動驗證

8.4 用 TensorBoard 監控

1tensorboard --logdir proj_log/<exp_name>/CSR/log --port 6006

8.5 多 GPU(需自行改)

原碼用 model.to(device) 而非 DataParallel/DDP。要改:

  1. model = nn.DataParallel(model) (簡單但慢)
  2. 改用 accelerate / torch.distributed 完整 DDP

9. 整合進其他工作流

  • 可借鑑設計:三段式 (sequence autoencoder + contrastive align + diffusion prior) 可移植到「分子結構 / protein domain / 生化路徑」等結構化序列領域
  • 建議讀法:先讀 model/autoencoder.pymodel/cond_ldm.py,跳過 cadlib/ 與 OCC 相關

9.2 與本知識庫其他 Layer 配合

Layer用途
gh-tutorial-qd (本流程)取得本份教學 + qd HTML
docling若要把 paper PDF 轉成 markdown 深度閱讀
paper-searchpaper read: arxiv:2409.16294 拉本論文與被引清單
paper-qa-lite用 paper-search 拉的 paper 集做 RAG 問答
gitnexus把 GenCAD codebase 建符號圖,深入追 VanillaCADTransformer 等類別

9.3 衍生 / 後續題目

  • Image-to-Molecule:把 CAD command sequence 換成 SMILES / SELFIES,CSR 改成 SMILES Transformer,pipeline 可直接套
  • Image-to-Circuit:把 CAD 換成 SPICE netlist 或 Verilog token
  • Conditional CAD editing:image + 文字描述 → 微調 CAD,多模態條件擴展

10. 重點摘要 Checklist

  • 三段式:CSR (CAD autoencoder) → CCIP (image-CAD CLIP) → DP (diffusion prior)
  • 主 entry:train_gencad.py {csr,ccip,dp} + inference_gencad.py
  • 依賴最大坑:pythonocc-core 只能 conda 裝
  • 推論需 xvfb-run (OCC viewer 需 X server)
  • CAD 表示是 (60, 17) int 矩陣(60 步序列 × 17 維 command+args)
  • 資安:🟡 中(torch.load 反序列化 + 1 處 os.system)
  • 訓練不支援多 GPU
  • Checkpoint / dataset 從 Google Drive 下載(信任邊界
  • 借用大量 DeepCAD 程式碼(cadlib/utils/cad_dataset.py

11. 進一步閱讀

資源連結
GenCAD Paper (TMLR 2025)https://openreview.net/pdf?id=e817c1wEZ6
GenCAD arXivhttps://arxiv.org/abs/2409.16294
GenCAD Project Pagehttps://gencad.github.io/
DeepCAD (上游)https://github.com/ChrisWu1997/DeepCAD
pythonocc-corehttps://github.com/tpaviot/pythonocc-core
x_clip (CLIP impl 借用)https://github.com/lucidrains/x-clip
ema_pytorch (EMA 工具)https://github.com/lucidrains/ema-pytorch
rtdl (denoising net 借用)https://github.com/Yura52/rtdl
GaussianDiffusion1D (架構靈感)https://github.com/lucidrains/denoising-diffusion-pytorch
Issue trackerhttps://github.com/ferdous-alam/GenCAD/issues

本教學由 gh-tutorial-qd skill 自動生成 / 2026-05-20 / commit f5484cf 若有錯誤或更新,請更新 inbox/2026-05-20-tutorial-GenCAD.md 並重編 qd / HTML。