Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,6 @@ python -c "import paddle; paddle.utils.run_check()"

cd PaddleScience

# windows 用户安装前请执行如下命令,否则可能因为gbk编码问题导致安装失败
set PYTHONUTF8=1

# install paddlesci with editable mode
pip install -e . -i https://pypi.tuna.tsinghua.edu.cn/simple
```
Expand Down
2 changes: 1 addition & 1 deletion docker/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ if [ -x "$(command -v nvidia-docker)" ]; then
elif [ -x "$(command -v docker)" ]; then
docker run --gpus all --network=host -it paddlescience
else
echo "Please install docker or nvidia-docker first."
echo "Docker start failed, please install nvidia-docker or docker(>=19.03) first"
fi
4 changes: 4 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@
./README.md:description
--8<--

--8<--
./docs/zh/overview.md:panorama
--8<--

## 📝案例列表

<style>
Expand Down
2 changes: 1 addition & 1 deletion docs/stylesheets/extra.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

.md-grid {
/* readable page width */
max-width: 1440px;
max-width: 1550px;
}

.md-header__topic > .md-ellipsis {
Expand Down
182 changes: 175 additions & 7 deletions docs/zh/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ PaddleScience 相关的论文复现、API 开发任务开始之前需提交 RFC

## 1. 准备工作

1. PaddleScience fork 到**自己的仓库**
1. 在网页上将 PaddleScience fork 到**自己的仓库**
2. 克隆**自己仓库**里的 PaddleScience 到本地,并进入该目录

``` sh
git clone -b develop https://github.com/USER_NAME/PaddleScience.git
cd PaddleScience
```

上方 `clone` 命令中的 `USER_NAME` 字段请填入的自己的用户名
上方 `clone` 命令中的 `USER_NAME` 字段请填入自己的 github 用户名

3. 安装必要的依赖包

Expand Down Expand Up @@ -602,23 +602,191 @@ solver = ppsci.solver.Solver(
)
```

### 2.12 训练
### 2.12 编写配置文件[重要]

??? info "内容较长,点击展开"

经过上述步骤的开发,案例代码的主要部分已经完成。
当我们想基于这份代码运行一些调优实验,从而得到更好的结果,或更好地对运行参数设置进行管理,
则可以利用 PaddleScience 提供的配置管理系统,将实验运行参数从代码中分离出来,写到 `yaml` 格式的配置文件中,从而更好的管理、记录、调优实验。

以 `viv` 案例代码为例,在运行时我们需要在适当的位置设置方程参数、STL 文件路径、训练轮数、`batch_size`、随机种子、学习率等超参数,如下所示。

``` py
...
# set dataloader config
train_dataloader_cfg = {
"dataset": {
"name": "MatDataset",
"file_path": cfg.VIV_DATA_PATH,
"input_keys": ("t_f",),
"label_keys": ("eta", "f"),
"weight_dict": {"eta": 100},
},
"batch_size": cfg.TRAIN.batch_size,
"sampler": {
"name": "BatchSampler",
"drop_last": False,
"shuffle": True,
},
}
...
...
# set optimizer
lr_scheduler = ppsci.optimizer.lr_scheduler.Step(**cfg.TRAIN.lr_scheduler)()
...
```

这些参数在实验过程中随时可能作为变量而被手动调整,在调整过程中如何避免频繁修改源代码导致试验记录混乱、保障记录完整可追溯便是一大问题,因此 PaddleScience 提供了基于 hydra + omegaconf 的
配置文件管理系统来解决这一问题。

将已有的代码修改成配置文件控制的方式非常简单,只需要将必要的参数写到 `yaml` 文件中,然后通过 hydra 在程序运行时读取、解析该文件,通过其内容控制实验运行即可,以 `viv` 案例为例,具体包含以下几个步骤。

1. 则需在代码文件 `viv.py` 所在目录下新建 `conf` 文件夹,并在 `conf` 下新建与 `viv.py` 同名的 `viv.yaml` 文件,如下所示。

``` sh hl_lines="3-4"
PaddleScience/examples/fsi/
├── viv.py
└── conf
└── viv.yaml
```

2. 将 `viv.py` 中必要的超参数按照其语义填写到 `viv.yaml` 的各个层级的配置中,如通用参数 `mode`、`output_dir`、`seed`、方程参数、文件路径等,直接填写在一级层级;而只与模型、训练相关的模型结构参数、训练轮数等,只需分别填写在 `MODEL`、`TRAIN` 层级下即可(`EVAL` 层级同理)。
3. 将已有的 `train` 和 `evaluate` 函数修改为接受一个参数 `cfg`(`cfg` 即为读取进来的 `yaml` 文件里的内容,并以字典的形式存储),并将其内部的超参数统一改为通过 `cfg.xxx` 获取而非原先的直接设置为数字或字符串,如下所示。

``` py
from omegaconf import DictConfig

def train(cfg: DictConfig):
# 训练代码...

def evaluate(cfg: DictConfig):
# 评估代码...
```

4. 新建一个 `main` 函数(同样接受且只接受一个 `cfg` 参数),它负责根据 `cfg.mode` 来调用 `train` 或 `evaluate` 函数,并 `main` 函数加上装饰器 `@hydra.main(version_base=None, config_path="./conf", config_name="viv.yaml")`,如下所示。

``` py
@hydra.main(version_base=None, config_path="./conf", config_name="viv.yaml")
def main(cfg: DictConfig):
if cfg.mode == "train":
train(cfg)
elif cfg.mode == "eval":
evaluate(cfg)
else:
raise ValueError(f"cfg.mode should in ['train', 'eval'], but got '{cfg.mode}'")

```

5. 在主程序的启动入口 `if __name__ == "__main__":` 中启动 `main()` 即可,如下所示。

``` py
if __name__ == "__main__":
main()
```

全部改造完毕后,`viv.py` 和 `viv.yaml` 如下所示。

=== "examples/fsi/viv.py"

``` py linenums="1"
--8<--
examples/fsi/viv.py
--8<--
```

=== "examples/fsi/conf/viv.yaml"

``` yaml linenums="1" hl_lines="1 4 19 25 31 34 42 59"
hydra: # (1)
run:
# dynamic output directory according to running time and override name
dir: outputs_VIV/${now:%Y-%m-%d}/${now:%H-%M-%S}/${hydra.job.override_dirname}
job:
name: ${mode} # name of logfile
chdir: false # keep current working direcotry unchaned
config:
override_dirname:
exclude_keys:
- TRAIN.checkpoint_path
- TRAIN.pretrained_model_path
- EVAL.pretrained_model_path
- mode
- output_dir
- log_freq
callbacks:
init_callback:
_target_: ppsci.utils.callbacks.InitCallback # (2)
sweep:
# output directory for multirun
dir: ${hydra.run.dir}
subdir: ./

# general settings (3)
mode: train # running mode: train/eval
seed: 42
output_dir: ${hydra:run.dir}
log_freq: 20

# set data file path (4)
VIV_DATA_PATH: "./VIV_Training_Neta100.mat"

# model settings (5)
MODEL:
input_keys: ["t_f"]
output_keys: ["eta"]
num_layers: 5
hidden_size: 50
activation: "tanh"

# training settings (6)
TRAIN:
epochs: 100000
iters_per_epoch: 1
save_freq: 10000
eval_during_train: true
eval_freq: 1000
batch_size: 100
lr_scheduler:
epochs: ${TRAIN.epochs}
iters_per_epoch: ${TRAIN.iters_per_epoch}
learning_rate: 0.001
step_size: 20000
gamma: 0.9
pretrained_model_path: null
checkpoint_path: null

# evaluation settings (7)
EVAL:
pretrained_model_path: null
batch_size: 32
```

1. `hydra:` 下的配置段用于控制 hydra 运行时的一些行为,如输出目录、回调函数等,用户只需要修改 `dir:` 后的内容,即可控制输出目录,其余的字段一般不需关注。
2. `callbacks:` 下的配置段用于控制回调函数,如此处添加了负责程序运行前自动固定随机种子、初始化 logger 并创建输出目录的回调函数 `InitCallback`,一般不需要修改这里。
3. `general settings` 下的四个通用设置,包括运行模式 `mode`、随机数种子 `seed`、输出目录 `output_dir` 和日志记录频率 `log_freq`。
4. `set XXX file path` 下的字段,用于控制数据集的路径,如 `VIV_DATA_PATH` 等。
5. `MODEL` 下的字段,用于控制模型结构,如 `disp_net`、`stress_net` 等。
6. `TRAIN:` 下的字段,用于控制训练过程,如 `epochs`、`iters_per_epoch` 等
7. `EVAL:` 下的字段,用于控制评估过程,如 `pretrained_model_path`、`eval_with_no_grad` 等

### 2.13 训练

PaddleScience 模型的训练只需调用一行代码。

``` py title="examples/demo/demo.py"
solver.train()
```

### 2.13 评估
### 2.14 评估

PaddleScience 模型的评估只需调用一行代码。

``` py title="examples/demo/demo.py"
solver.eval()
```

### 2.14 可视化[可选]
### 2.15 可视化[可选]

若 `Solver` 实例化时传入了 `visualizer` 参数,则 PaddleScience 模型的可视化只需调用一行代码。

Expand All @@ -632,7 +800,7 @@ solver.visualize()

## 3. 编写文档

除了案例代码,PaddleScience 同时存放了对应案例的详细文档,使用 Markdown + [Mkdocs-Material](https://squidfunk.github.io/mkdocs-material/) 进行编写和渲染,撰写文档步骤如下。
除了案例代码,PaddleScience 同时存放了对应案例的详细文档,使用 Markdown + [Mkdocs](https://www.mkdocs.org/) + [Mkdocs-Material](https://squidfunk.github.io/mkdocs-material/) 进行编写和渲染,撰写文档步骤如下。

### 3.1 安装必要依赖包

Expand Down Expand Up @@ -686,7 +854,7 @@ PaddleScience 是一个开源的代码库,由多人共同参与开发,因此
PaddleScience 使用了包括 [isort](https://github.com/PyCQA/isort#installing-isort)、[black](https://github.com/psf/black) 等自动化代码检查、格式化插件,
让 commit 的代码遵循 python [PEP8](https://pep8.org/) 代码风格规范。

因此在 commit 您的代码之前,请务必先执行以下命令安装 `pre-commit`。
因此在 commit 您的代码之前,请务必先执行以下命令安装 `pre-commit`,否则提交的 PR 会被 code-style 检测到代码未格式化而无法合入

``` sh
pip install pre-commit
Expand Down
11 changes: 7 additions & 4 deletions docs/zh/install_setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@

### 1.1 从 docker 镜像启动[可选]

如果你对 docker 有一定了解,则可以通过我们提供的 docker 文件,直接构建出能运行 PaddleScience 的环境。按照下列步骤构建 docker 并自动进入该环境,以运行 PaddleScience。
如果你对 docker 有一定了解,则可以通过我们提供的 Dockerfile 文件,直接构建出能运行 PaddleScience 的环境。按照下列步骤构建镜像,创建容器并进入容器,以运行 PaddleScience。

1. 下载 PyMesh 预编译文件压缩包 [pymesh.tar.xz](https://paddle-org.bj.bcebos.com/paddlescience/docker/pymesh.tar.xz),并放置在 `PaddleScience/docker/` 目录下
2. 执行 `bash run.sh`,等待 docker build 完毕后自动进入环境。如果出现因网络问题导致的 apt 下载报错,则重复执行 `bash run.sh` 直至 build 完成即可。
3. 在 docker 环境中,执行 `ldconfig`
1. 克隆 PaddleScience 源码:`git clone https://github.com/PaddlePaddle/PaddleScience.git`
2. 下载 PyMesh 预编译文件压缩包 [pymesh.tar.xz](https://paddle-org.bj.bcebos.com/paddlescience/docker/pymesh.tar.xz),并放置在 `PaddleScience/docker/` 目录下
3. 在 `PaddleScience/docker/` 目录下,执行 `bash run.sh`,等待 docker build 完毕后自动进入环境。如果出现因网络问题导致的 apt 下载报错,则重复执行 `bash run.sh` 直至 build 完成即可
4. 在 docker 环境中,执行 `ldconfig`

更多关于 Paddle Docker 的安装和使用,请参考 [Docker 安装](https://www.paddlepaddle.org.cn/documentation/docs/zh/install/docker/fromdocker.html)

### 1.2 python 环境安装[可选]

Expand Down
4 changes: 3 additions & 1 deletion docs/zh/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

PaddleScience 在代码结构上划分为 12 个模块。从一般深度学习工作流的角度来看,这 12 个模块分别负责构建输入数据、构建神经网络模型、构建损失函数、构建优化器,训练、评估、可视化等功能。从科学计算角度来看,部分模块承担了不同于 CV、NLP 任务的功能,比如用于物理机理驱动的 Equation 模块,定义方程公式和辅助高阶微分计算;用于涉及几何场景采样的 Geometry 模块,定义简单、复杂几何形状并在其内部、边界采样构造数据;Constraint 模块将不同的优化目标视为一种“约束”,使得套件能用一套训练代码统一物理机理驱动、数据驱动、数理融合三种不同的求解流程。

![panorama](https://paddle-org.bj.bcebos.com/paddlescience/docs/overview/panorama.png)
<!-- --8<-- [start:panorama] -->
<img src="https://paddle-org.bj.bcebos.com/paddlescience/docs/overview/panorama.png" alt="panorama" width="100%" height="auto">
<!-- --8<-- [end:panorama] -->

## 1. 整体工作流

Expand Down
8 changes: 4 additions & 4 deletions docs/zh/user_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ TRAIN:

``` sh title="$ tree PaddleScience/examples/bracket/outputs_bracket/"
PaddleScience/examples/bracket/outputs_bracket/
└──2023-10-14 # (1)
└── 2023-10-14 # (1)
└── 04-01-52 # (2)
├── TRAIN.epochs=10,20,seed=42,1024 # multirun 总配置保存目录
│ └── multirun.yaml # multirun 配置文件 (3)
Expand Down Expand Up @@ -202,9 +202,9 @@ PaddleScience/examples/bracket/outputs_bracket/

``` py hl_lines="12 13 14 15 16"
N = 100 # 假设要预测100个样本的结果
x = np.random.randn(N, 1) # 准备 字段
y = np.random.randn(N, 1)
z = np.random.randn(N, 1)
x = np.random.randn(N, 1) # 输入数据x
y = np.random.randn(N, 1) # 输入数据y
z = np.random.randn(N, 1) # 输入数据z

input_dict = {
"x": x,
Expand Down
2 changes: 1 addition & 1 deletion examples/fsi/viv.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def train(cfg: DictConfig):
"drop_last": False,
"shuffle": True,
},
"num_workers": 0, # NOTE: Keep this 0 or else it will slow down the speed of dataloader 10x.
# "num_workers": 0,
}

# set constraint
Expand Down
11 changes: 5 additions & 6 deletions examples/ldc/conf/ldc2d_steady_Re10.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,11 @@ RHO: 1.0

# model settings
MODEL:
model:
input_keys: ["x", "y"]
output_keys: ["u", "v", "p"]
num_layers: 9
hidden_size: 50
activation: "tanh"
input_keys: ["x", "y"]
output_keys: ["u", "v", "p"]
num_layers: 9
hidden_size: 50
activation: "tanh"

# training settings
TRAIN:
Expand Down
11 changes: 5 additions & 6 deletions examples/ldc/conf/ldc2d_unsteady_Re10.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,11 @@ NTIME_ALL: 16

# model settings
MODEL:
model:
input_keys: ["t", "x", "y"]
output_keys: ["u", "v", "p"]
num_layers: 9
hidden_size: 50
activation: "tanh"
input_keys: ["t", "x", "y"]
output_keys: ["u", "v", "p"]
num_layers: 9
hidden_size: 50
activation: "tanh"

# training settings
TRAIN:
Expand Down
6 changes: 3 additions & 3 deletions examples/ldc/ldc2d_steady_Re10.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def train(cfg: DictConfig):
logger.init_logger("ppsci", osp.join(cfg.output_dir, "train.log"), "info")

# set model
model = ppsci.arch.MLP(**cfg.MODEL.model)
model = ppsci.arch.MLP(**cfg.MODEL)

# set equation
equation = {"NavierStokes": ppsci.equation.NavierStokes(cfg.NU, cfg.RHO, 2, False)}
Expand Down Expand Up @@ -151,7 +151,7 @@ def train(cfg: DictConfig):
lr_scheduler,
cfg.TRAIN.epochs,
cfg.TRAIN.iters_per_epoch,
eval_during_train=cfg.EVAL.pretrained_model_path,
eval_during_train=cfg.TRAIN.eval_during_train,
eval_freq=cfg.TRAIN.eval_freq,
equation=equation,
geom=geom,
Expand All @@ -174,7 +174,7 @@ def evaluate(cfg: DictConfig):
logger.init_logger("ppsci", osp.join(cfg.output_dir, "eval.log"), "info")

# set model
model = ppsci.arch.MLP(**cfg.MODEL.model)
model = ppsci.arch.MLP(**cfg.MODEL)

# set equation
equation = {"NavierStokes": ppsci.equation.NavierStokes(cfg.NU, cfg.RHO, 2, False)}
Expand Down
Loading