|
| 1 | +# Transolver |
| 2 | + |
| 3 | +!!! note |
| 4 | + |
| 5 | + 第一次运行时,会对 mlcfd_data 进行预处理,大约需要一小时,请耐心等待 |
| 6 | + |
| 7 | +=== "模型训练命令" |
| 8 | + |
| 9 | + ``` sh |
| 10 | + # linux |
| 11 | + wget -nc https://paddle-org.bj.bcebos.com/paddlecfd/datasets/pptransformer/mlcfd_data.zip |
| 12 | + # windows |
| 13 | + # curl https://paddle-org.bj.bcebos.com/paddlecfd/datasets/pptransformer/mlcfd_data.zip -o mlcfd_data.tar |
| 14 | + tar -xvf mlcfd_data.tar |
| 15 | + python main.py |
| 16 | + ``` |
| 17 | + |
| 18 | +=== "模型评估命令" |
| 19 | + |
| 20 | + ``` sh |
| 21 | + # linux |
| 22 | + wget -nc https://paddle-org.bj.bcebos.com/paddlecfd/datasets/pptransformer/mlcfd_data.zip |
| 23 | + # windows |
| 24 | + # curl https://paddle-org.bj.bcebos.com/paddlecfd/datasets/pptransformer/mlcfd_data.zip -o mlcfd_data.tar |
| 25 | + tar -xvf mlcfd_data.tar |
| 26 | + python main.py mode=eval EVAL.pretrained_model_path=https://paddle-org.bj.bcebos.com/paddlescience/models/transolver/transolver_pretrained.pdparams |
| 27 | + ``` |
| 28 | + |
| 29 | +=== "模型导出命令" |
| 30 | + |
| 31 | + ``` sh |
| 32 | + python main.py mode=export |
| 33 | + ``` |
| 34 | + |
| 35 | +=== "模型推理命令" |
| 36 | + |
| 37 | + ``` sh |
| 38 | + python main.py mode=infer |
| 39 | + ``` |
| 40 | + |
| 41 | +| 预训练模型 | 指标 | |
| 42 | +|:--| :--| |
| 43 | +| [transolver_pretrained.pdparams](https://paddle-org.bj.bcebos.com/paddlescience/models/transolver/transolver_pretrained.pdparams) | rho_d:, 0.99044<br>c_d: 0.01216<br>relative l2 error of press: 0.07827<br>relative l2 error of velocity: 0.02397<br>press: 4.97525<br>velocity: [0.12751131 0.15966374 0.4417494 ] 0.28101 | |
| 44 | + |
| 45 | +## 1. 背景简介 |
| 46 | + |
| 47 | +Transolver 是一个基于 Transformer 架构的神经算子模型,用于学习偏微分方程(PDE)的解算子。该模型的核心创新在于其物理注意力机制(Physics Attention),能够高效地处理不规则网格上的物理场预测问题。 |
| 48 | + |
| 49 | +相比传统的 Transformer 模型,Transolver 具有以下特点: |
| 50 | + |
| 51 | +- **物理感知的注意力机制**: 通过切片(slice)技术将不规则网格点聚合成规则的表示,既保留了空间物理信息,又大幅降低了计算复杂度 |
| 52 | +- **灵活的几何适应性**: 能够处理任意形状的几何体和非结构化网格 |
| 53 | +- **高效的计算性能**: 通过切片注意力机制,将计算复杂度从 $O(N^2)$ 降低到 $O(NG)$,其中 $N$ 是网格点数,$G$ 是切片数 |
| 54 | + |
| 55 | +本案例使用 Transolver 模型在 ShapeNet Car 数据集上学习汽车外流场的速度场和压力场分布,这是一个典型的计算流体动力学(CFD)代理建模问题。通过学习大量的汽车形状与对应的流场数据,模型可以快速预测新汽车形状的流场分布,从而大幅降低 CFD 仿真的计算成本。 |
| 56 | + |
| 57 | +## 2. 问题定义 |
| 58 | + |
| 59 | +本案例的目标是建立汽车几何形状到其周围流场(速度场和压力场)的映射关系。具体而言: |
| 60 | + |
| 61 | +- **输入**: 汽车表面及周围空间的网格点坐标 $\mathbf{x} \in \mathbb{R}^{N \times 7}$,其中 $N$ 为网格点数量,7 个维度包括空间坐标、法向量等几何信息 |
| 62 | +- **输出**: 每个网格点处的速度矢量 $\mathbf{v} \in \mathbb{R}^{N \times 3}$ 和压力标量 $p \in \mathbb{R}^{N \times 1}$ |
| 63 | + |
| 64 | +训练目标是最小化预测流场与真实 CFD 仿真结果之间的均方误差,同时确保模型能够准确预测汽车的阻力系数等关键空气动力学参数。 |
| 65 | + |
| 66 | +## 3. 问题求解 |
| 67 | + |
| 68 | +接下来开始讲解如何将问题一步一步地转化为 PaddleScience 代码,用深度学习的方法求解该问题。 |
| 69 | +为了快速理解 PaddleScience,接下来仅对模型构建、约束构建、优化器构建等关键步骤进行阐述,而其余细节请参考 [API文档](../api/arch.md)。 |
| 70 | + |
| 71 | +### 3.1 模型构建 |
| 72 | + |
| 73 | +在本问题中,需要建立从网格点坐标 $\mathbf{x}$ 到流场变量 $(\mathbf{v}, p)$ 的映射函数 $f: \mathbb{R}^{N \times 7} \to \mathbb{R}^{N \times 4}$,即: |
| 74 | + |
| 75 | +$$ |
| 76 | +(\mathbf{v}, p) = f(\mathbf{x}) |
| 77 | +$$ |
| 78 | + |
| 79 | +这里使用 Transolver 模型来表示这个映射函数,用 PaddleScience 代码表示如下: |
| 80 | + |
| 81 | +``` py linenums="25" |
| 82 | +--8<-- |
| 83 | +examples/transolver/main.py:25:27 |
| 84 | +--8<-- |
| 85 | +``` |
| 86 | + |
| 87 | +为了在计算时准确快速地访问具体变量的值,这里指定网络模型的输入变量名是 `["x"]`,输出变量名是 `["velo_vec", "press"]`,这些命名与后续代码保持一致。 |
| 88 | + |
| 89 | +模型的详细配置如下: |
| 90 | + |
| 91 | +``` yaml linenums="43" |
| 92 | +--8<-- |
| 93 | +examples/transolver/conf/shapenet_car.yaml:43:57 |
| 94 | +--8<-- |
| 95 | +``` |
| 96 | + |
| 97 | +其中: |
| 98 | + |
| 99 | +- `space_dim`: 输入空间维度,设为 7(包括空间坐标、法向量等几何信息) |
| 100 | +- `n_layers`: Transformer 层数,设为 8 |
| 101 | +- `n_hidden`: 隐藏层维度,设为 256 |
| 102 | +- `n_head`: 多头注意力的头数,设为 8 |
| 103 | +- `dropout`: Dropout 比率,设为 0 |
| 104 | +- `act`: 激活函数,使用 `gelu` |
| 105 | +- `mlp_ratio`: MLP 层的隐藏层扩展比例,设为 2 |
| 106 | +- `out_dim`: 输出维度列表,`[3, 1]` 分别对应速度场(3维)和压力场(1维) |
| 107 | +- `slice_num`: 切片注意力机制中的切片数量,设为 32,用于降低计算复杂度 |
| 108 | +- `ref`: 参考网格的分辨率,设为 8 |
| 109 | +- `unified_pos`: 是否使用统一的位置编码,设为 False |
| 110 | + |
| 111 | +### 3.2 模型架构详解 |
| 112 | + |
| 113 | +Transolver 的核心架构包括以下几个关键组件: |
| 114 | + |
| 115 | +#### 3.2.1 预处理层 (Preprocessing) |
| 116 | + |
| 117 | +将输入的几何特征映射到隐藏空间: |
| 118 | + |
| 119 | +$$ |
| 120 | +h = \text{MLP}(\text{concat}(f, x)) |
| 121 | +$$ |
| 122 | + |
| 123 | +其中 $f$ 是函数特征(如初始场),$x$ 是空间坐标。 |
| 124 | + |
| 125 | +#### 3.2.2 物理注意力机制 (Physics Attention) |
| 126 | + |
| 127 | +这是 Transolver 的核心创新,通过以下步骤实现高效的全局信息交互: |
| 128 | + |
| 129 | +1. **切片聚合**: 将 $N$ 个不规则网格点聚合成 $G$ 个切片表示 |
| 130 | + |
| 131 | +$$ |
| 132 | +S = \text{softmax}\left(\frac{W_s(h)}{\tau}\right)^T h |
| 133 | +$$ |
| 134 | + |
| 135 | +其中 $S \in \mathbb{R}^{G \times D}$ 是切片表示,$\tau$ 是可学习的温度参数。 |
| 136 | + |
| 137 | +2. **切片上的自注意力**: 在切片表示上进行标准的 Transformer 注意力计算 |
| 138 | + |
| 139 | +$$ |
| 140 | +\text{Attn}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d}}\right)V |
| 141 | +$$ |
| 142 | + |
| 143 | +其中 $Q = W_q S, K = W_k S, V = W_v S$。 |
| 144 | + |
| 145 | +3. **反聚合**: 将切片表示映射回原始网格点 |
| 146 | + |
| 147 | +$$ |
| 148 | +h' = S \cdot \text{Attn}(Q, K, V) \cdot W |
| 149 | +$$ |
| 150 | + |
| 151 | +通过这种机制,计算复杂度从 $O(N^2)$ 降低到 $O(NG + G^2)$,当 $G \ll N$ 时可显著提升效率。 |
| 152 | + |
| 153 | +#### 3.2.3 前馈网络 (MLP) |
| 154 | + |
| 155 | +每个 Transformer 块后接一个前馈网络: |
| 156 | + |
| 157 | +$$ |
| 158 | +\text{FFN}(h) = W_2 \cdot \text{GELU}(W_1 h + b_1) + b_2 |
| 159 | +$$ |
| 160 | + |
| 161 | +#### 3.2.4 层归一化与残差连接 |
| 162 | + |
| 163 | +每个子层都使用层归一化(LayerNorm)和残差连接: |
| 164 | + |
| 165 | +$$ |
| 166 | +\begin{aligned} |
| 167 | +h^{(l+1)} &= \text{Attn}(\text{LN}(h^{(l)})) + h^{(l)} \\ |
| 168 | +h^{(l+1)} &= \text{FFN}(\text{LN}(h^{(l+1)})) + h^{(l+1)} |
| 169 | +\end{aligned} |
| 170 | +$$ |
| 171 | + |
| 172 | +### 3.3 数据加载 |
| 173 | + |
| 174 | +本案例使用 ShapeNet Car 数据集,包含不同汽车形状的 CFD 仿真结果。数据加载代码如下: |
| 175 | + |
| 176 | +``` py linenums="29" |
| 177 | +--8<-- |
| 178 | +examples/transolver/main.py:29:43 |
| 179 | +--8<-- |
| 180 | +``` |
| 181 | + |
| 182 | +数据集配置: |
| 183 | + |
| 184 | +``` yaml linenums="31" |
| 185 | +--8<-- |
| 186 | +examples/transolver/conf/shapenet_car.yaml:31:40 |
| 187 | +--8<-- |
| 188 | +``` |
| 189 | + |
| 190 | +其中: |
| 191 | + |
| 192 | +- `data_dir`: 原始数据目录 |
| 193 | +- `save_dir`: 预处理后数据保存目录 |
| 194 | +- `val_fold_id`: 用于交叉验证的折数 ID |
| 195 | +- `preprocessed`: 是否使用预处理数据 |
| 196 | +- `r`: 数据下采样比例 |
| 197 | + |
| 198 | +### 3.4 约束构建 |
| 199 | + |
| 200 | +本案例使用监督学习约束,通过最小化预测流场与真实流场的误差来训练模型: |
| 201 | + |
| 202 | +``` py linenums="45" |
| 203 | +--8<-- |
| 204 | +examples/transolver/main.py:45:76 |
| 205 | +--8<-- |
| 206 | +``` |
| 207 | + |
| 208 | +损失函数包含两部分: |
| 209 | + |
| 210 | +1. 速度场的均方误差: $\mathcal{L}_{velo} = \text{MSE}(\mathbf{v}_{pred}, \mathbf{v}_{true})$ |
| 211 | +2. 表面压力场的均方误差: $\mathcal{L}_{press} = \text{MSE}(p_{pred}|_{surf}, p_{true}|_{surf})$ |
| 212 | + |
| 213 | +总损失为: $\mathcal{L} = \mathcal{L}_{velo} + w_{press} \cdot \mathcal{L}_{press}$,其中 $w_{press}$ 为压力损失权重。 |
| 214 | + |
| 215 | +### 3.5 优化器构建 |
| 216 | + |
| 217 | +使用 Adam 优化器配合指数衰减学习率策略: |
| 218 | + |
| 219 | +``` py linenums="78" |
| 220 | +--8<-- |
| 221 | +examples/transolver/main.py:78:89 |
| 222 | +--8<-- |
| 223 | +``` |
| 224 | + |
| 225 | +学习率配置: |
| 226 | + |
| 227 | +``` yaml linenums="63" |
| 228 | +--8<-- |
| 229 | +examples/transolver/conf/shapenet_car.yaml:63:67 |
| 230 | +--8<-- |
| 231 | +``` |
| 232 | + |
| 233 | +其中包含: |
| 234 | + |
| 235 | +- 预热阶段(`warmup_epoch`): 前 60 个 epoch 学习率从 $\frac{lr_{max}}{25}$ 逐渐增加到 $lr_{max}$ |
| 236 | +- 衰减阶段: 之后每个 step 学习率按 $lr = lr_{max} \times \gamma^{step}$ 衰减 |
| 237 | + |
| 238 | +### 3.6 评估器构建 |
| 239 | + |
| 240 | +在训练过程中使用验证集评估模型性能: |
| 241 | + |
| 242 | +``` py linenums="91" |
| 243 | +--8<-- |
| 244 | +examples/transolver/main.py:91:129 |
| 245 | +--8<-- |
| 246 | +``` |
| 247 | + |
| 248 | +评估指标包括: |
| 249 | + |
| 250 | +- 速度场的均方误差 |
| 251 | +- 表面压力场的均方误差 |
| 252 | + |
| 253 | +### 3.7 模型训练与评估 |
| 254 | + |
| 255 | +完成上述设置后,将实例化的对象传递给 `ppsci.solver.Solver`,然后启动训练和评估: |
| 256 | + |
| 257 | +``` py linenums="140" |
| 258 | +--8<-- |
| 259 | +examples/transolver/main.py:140:142 |
| 260 | +--8<-- |
| 261 | +``` |
| 262 | + |
| 263 | +### 3.8 模型评估 |
| 264 | + |
| 265 | +评估阶段除了计算常规的误差指标外,还会计算阻力系数的预测误差和斯皮尔曼相关系数: |
| 266 | + |
| 267 | +``` py linenums="145" |
| 268 | +--8<-- |
| 269 | +examples/transolver/main.py:145:241 |
| 270 | +--8<-- |
| 271 | +``` |
| 272 | + |
| 273 | +评估指标包括: |
| 274 | + |
| 275 | +- **相对 L2 误差**: 衡量预测场与真实场的整体偏差 |
| 276 | +- **均方根误差 (RMSE)**: 评估逐点预测精度 |
| 277 | +- **阻力系数误差**: 评估关键空气动力学参数的预测精度 |
| 278 | +- **斯皮尔曼相关系数 ($\rho_d$)**: 评估阻力系数排序的相关性 |
| 279 | + |
| 280 | +## 4. 完整代码 |
| 281 | + |
| 282 | +``` py linenums="1" title="main.py" |
| 283 | +--8<-- |
| 284 | +examples/transolver/main.py |
| 285 | +--8<-- |
| 286 | +``` |
| 287 | + |
| 288 | +## 5. 结果展示 |
| 289 | + |
| 290 | +模型训练完成后,可以在验证集上评估预测性能。主要评估指标包括: |
| 291 | + |
| 292 | +- **速度场相对 L2 误差**: 衡量速度场预测的整体精度 |
| 293 | +- **压力场相对 L2 误差**: 衡量压力场预测的整体精度 |
| 294 | +- **阻力系数相对误差**: 评估关键气动参数的预测准确性 |
| 295 | +- **斯皮尔曼相关系数**: 评估不同汽车形状阻力系数排序的准确性 |
| 296 | + |
| 297 | +通过训练,Transolver 模型能够以较高精度预测汽车周围的流场分布,相比传统 CFD 仿真可以大幅降低计算时间,为汽车气动外形优化提供快速的代理模型。 |
| 298 | + |
| 299 | +## 6. 参考资料 |
| 300 | + |
| 301 | +- [Transolver: A Fast Transformer Solver for PDEs on General Geometries](https://arxiv.org/abs/2402.02366) |
| 302 | +- [Transolver GitHub Repository](https://github.com/thuml/Transolver) |
0 commit comments