Ascend-SACT/Transolver_plus
模型介绍文件和版本Pull Requests讨论分析
下载使用量0

模型介绍

Transolver_plus(Transolver++)是面向百万级非结构化工业几何的 AI4S 神经 PDE 正向求解器,在初代 Transolver 基础上通过自适应物理分片注意力、分层稀疏窗口、低通信并行框架实现显存大幅下降、训练推理显著提速、复杂物理场精度提升,可用于钢材多孔结构、汽车气动、航空构件大规模仿真加速。

一、环境信息

  • 模型:transolver++

  • AI加速卡:910C

  • CPU架构:ARM

  • CANN:9.0.0

二、准备工作

1、启动容器

docker run -it -u root -d --net=host \
--privileged \
--ipc=host \
--device=/dev/davinci_manager \
--device=/dev/devmm_svm \
--device=/dev/hisi_hdc \
-v /usr/local/Ascend/driver:/usr/local/Ascend/driver \
-v /usr/local/dcmi:/usr/local/dcmi \
-v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \
-v /usr/local/sbin:/usr/local/sbin \
-v /usr/local/Ascend/driver/tools/hccn_tool:/usr/local/Ascend/driver/tools/hccn_tool \
--name transolver \
quay.io/ascend/cann:9.0.0-a3-ubuntu22.04-py3.11 \
/bin/bash

注:后续操作均是容器内进行

2、下载代码

cd  /root/
git clone https://github.com/thuml/Transolver_plus.git

3、安装依赖

apt update
apt install libxcb1 libx11-xcb1
apt install -y libgl1-mesa-glx
apt install -y libglib2.0-0 libsm6 libxext6 libxrender-dev libgomp1
apt-get install -y zlib1g-dev build-essential

pip install torch==2.10.0  torch_npu==2.10.0
pip install h5py numpy scipy pandas tqdm  einops

4、代码修改

将代码patch拷贝到目录/root/Transolver_plus/下,应用patch

cd /root/Transolver_plus
git apply transolver_plus_ascend_npu.patch

主要代码修改说明如下:

1、设备适配,cuda → npu,nccl → hccl,所有 17 处 .cuda() 替换
2、DDP 修复:原始代码多卡时模型未用 DistributedDataParallel 包装,导致各 rank 独立训练、checkpoint 竞态覆盖。
已修复为正确 DDP 模式
3、推理优化:model.eval()、FP16 混合精度推理、自动混合精度上下文
4、其他工程化改进

三、模型训练

1、数据集下载

这里使用AirCraft 数据集,将数据集下载到/root/aircraft_data/(30 种飞机设计 × 5 种工况共 150 个 h5 样本(~332K 点/样本)),数据集下载好按照论文比例划分, 140/10 划分训练/测试集,与论文一致。

(注意:论文是没有说明具体划分结果的,所以不同划分下结果会有些许差异)

2、训练脚本

训练脚本内容参考 main_airplane.py

3、单卡训练

通过如下命令启动训练:

python main_airplane.py \
    --data_dir /root/aircraft_data \
    --save_dir /root/aircraft_output \
    --nb_epochs 200 \
    --lr 0.001 \
    --batch_size 1 \
    --device 4

4、训练结果

训练结果如下:

5、多卡训练

官方代码中没有完整的多卡训练示例,这里通过进一步针对DDP的适配修改,可以执行多卡训练,命令参考如下:

torchrun --nproc_per_node=4 main_airplane.py \
    --data_dir /root/aircraft_data \
    --save_dir /root/aircraft_output_lr004 \
    --lr 0.004 --batch_size 8 --nb_epochs 200

说明:这里可以采用线性缩放学习率 lr=0.004或者适当调整策略,补偿 DDP 梯度平均

四、模型推理

1、推理脚本

推理脚本内容参考:

import sys, torch, os, warnings, numpy as np, h5py
warnings.filterwarnings("ignore")
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from dataset.dataset import AirplaneDataLoader, AirplaneDataset
from models.Transolver_plus import Model

def main():
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument('--data_dir', default='/root/aircraft_data')
    parser.add_argument('--save_dir', default='/root/trans/aircraft_output_lr004_easy')
    parser.add_argument('--ckpt', default='model_200.pth')
    parser.add_argument('--device', default=0, type=int)
    parser.add_argument('--save_npy', action='store_true', help='save predictions as .npy files')
    args = parser.parse_args()

    device = torch.device("npu", args.device)
    torch.npu.set_device(device)
    data_dir = args.data_dir

    train_ds = AirplaneDataset(data_dir, train=True)
    val_ds = AirplaneDataset(data_dir, train=False)
    val_loader = AirplaneDataLoader(val_ds, batch_size=1)

    all_pos, all_vals = [], []
    for f in train_ds.f_list:
        with h5py.File(f, "r") as h:
            all_pos.append(h["pos"][:])
            all_vals.append(h["values"][:])
    pos = torch.from_numpy(np.concatenate(all_pos, axis=0)).float()
    val = torch.from_numpy(np.concatenate(all_vals, axis=0)).float()
    pm, ps = pos.mean(dim=0).view(1,1,3).npu(), pos.std(dim=0).view(1,1,3).npu()
    om, os_ = val.mean(dim=0).view(1,1,-1).npu(), val.std(dim=0).view(1,1,-1).npu()

    model = Model(n_hidden=256, n_layers=4, space_dim=7, fun_dim=0, n_head=8,
                  mlp_ratio=2, out_dim=6, slice_num=32, unified_pos=0, dropout=0.1).npu()
    sd = torch.load(os.path.join(args.save_dir, args.ckpt), map_location="npu", weights_only=True)
    # handle DDP wrapped checkpoint
    if any(k.startswith("module.") for k in sd):
        sd = {k.removeprefix("module."): v for k, v in sd.items()}
    model.load_state_dict(sd)
    model.eval()

    ch_names = ["Cp", "rho", "u(CL)", "v", "w", "ch5(SURF)"]
    l2res = {c: [] for c in range(6)}
    fnames = []
    with torch.no_grad():
        for i, (x, y, pos, geom, _) in enumerate(val_loader):
            fname = os.path.basename(val_ds.f_list[i])
            fnames.append(fname)
            x, pos, y, geom = x.npu(), pos.npu(), y.npu(), geom.npu()
            pos_n = (pos - pm) / ps
            x[:,:,:3] = pos_n
            out = model((x, pos_n, geom)) * os_ + om
            for c in range(6):
                l2r = torch.norm(out[0,:,c] - y[0,:,c]).item() / torch.norm(y[0,:,c]).item()
                l2res[c].append(l2r)
            if args.save_npy:
                stem = os.path.splitext(fname)[0]
                np.save(os.path.join(args.save_dir, f"{stem}.npy"), out.cpu().numpy())

    print(f"\nPer-sample L2RE (ch5):")
    for i, fn in enumerate(fnames):
        print(f"  {fn}: {l2res[5][i]:.4f}")

    print(f"\nPer-channel L2RE:")
    for c in range(6):
        print(f"  ch{c} ({ch_names[c]:>10s}): {np.mean(l2res[c]):.4f}")

    print(f"\n  SURF(ch5) = {np.mean(l2res[5]):.4f}")
    print(f"  CL(ch2)   = {np.mean(l2res[2]):.4f}")

if __name__ == '__main__':
    main()

也可以参考官方的推理脚本(依赖 result.csv)

2、推理验证

命令参考:

python eval.py \
    --data_dir /root/aircraft_data \
    --save_dir /path/to/checkpoint_dir \
    --device 0

执行结果:

其他

1、精度对齐

使用论文中同样的数据集,最终验证的精度结果:

SURFch5ch5ch5 = 0.064

CLch2ch2ch2 = 0.012

与论文中的精度效果一致。

2、单卡容量验证

Transolver++ 通过消除冗余 f 投影),单卡可处理 1.2M 点(A100 40GB)。在 Ascend NPU 910C 上通过合成数据验证此声称。

验证方案:

使用 capacity_test.py 生成椭球面合成网格数据(pos + normals + values),匹配 AirCraft 的 h5 格式

在不同点数规模下加载模型(4 层, hidden=256, 8 head, slice_num=32,与 AirCraft 配置一致),分别测量推理(forward only)和训练(forward + backward + optim.step)的峰值显存。峰值显存通过 torch.npu.reset_peak_memory_stats\) + torch.npu.max\_memory\_allocated\( 采集。

验证结果: NPU 910C单卡( 65.8GB)训练模式下可处理约 1.9M 点,按照显存比计算与官方宣称效果基本一致。