Skip to content

Commit ea0278b

Browse files
committed
Merge branch 'develop' of https://github.com/PaddlePaddle/GraphNet into correctness
2 parents f0b51a6 + 04f3c15 commit ea0278b

File tree

1,163 files changed

+1496675
-66158
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,163 files changed

+1496675
-66158
lines changed

.github/actions/check-bypass/action.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: "Check bypass"
2-
description: "A custom action to encapsulate PFCCLab/ci-bypass"
2+
description: "A custom action to encapsulate GraphNet"
33
inputs:
44
github-token:
55
description: "GitHub token"
@@ -18,7 +18,7 @@ runs:
1818
- id: check-bypass
1919
name: Check Bypass
2020
env:
21-
CI_TEAM_MEMBERS: '["SigureMo", "risemeup1", "tianshuo78520a", "0x3878f", "swgu98", "luotao1", "XieYunshen"]'
21+
CI_TEAM_MEMBERS: '["lixinqi", "Xreki"]'
2222
uses: PFCCLab/ci-bypass@v1
2323
with:
2424
github-token: ${{ inputs.github-token }}

.github/workflows/Validate-GPU.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ jobs:
6161
-v "/home/data/cfs/.ccache:/root/.ccache" \
6262
-v "/dev/shm:/dev/shm" \
6363
-v ${{ github.workspace }}/../../..:${{ github.workspace }}/../../.. \
64-
-v ${{ github.workspace }}:/graphnet \
64+
-v ${{ github.workspace }}:${{ github.workspace }} \
6565
-e python \
6666
-e core_index \
6767
-e BRANCH \
@@ -73,7 +73,7 @@ jobs:
7373
-e CACHE_DIR \
7474
-e GITHUB_API_TOKEN \
7575
-e CFS_DIR \
76-
-w /graphnet --network host ${docker_image}
76+
-w ${{ github.workspace }} --network host ${docker_image}
7777
7878
- name: Run check
7979
env:

README.md

Lines changed: 97 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,143 @@
11
# GraphNet ![](https://img.shields.io/badge/version-v0.1-brightgreen) ![](https://img.shields.io/github/issues/PaddlePaddle/GraphNet?label=open%20issues) [![](https://img.shields.io/badge/Contribute%20to%20GraphNet-blue)](https://github.com/PaddlePaddle/GraphNet/issues/98)
22

3+
**GraphNet** is a large-scale dataset of deep learning **computation graphs**, built as a standard benchmark for **tensor compiler** optimization. It provides 2.7K computation graphs extracted from state-of-the-art deep learning models spanning diverse tasks and ML frameworks. With standardized formats and rich metadata, GraphNet enables fair comparison and reproducible evaluation of the general optimization capabilities of tensor compilers, thereby supporting advanced research such as AI for System on compilers (AI for Compiler).
34

4-
**GraphNet** is a large-scale dataset of deep learning **computation graphs**, designed to serve as a standard benchmark and training corpus for **AI-driven tensor compiler optimization**. It contains diverse graphs extracted from state-of-the-art models, enabling effective evaluation of compiler pass optimizations across frameworks and hardware platforms.
5-
5+
<br>
6+
<div align="center">
7+
<img src="/pics/Eval_result.png" alt="Violin plots of speedup distributions" width="65%">
8+
</div>
69

7-
With GraphNet, users can:
8-
1. Quickly benchmark the optimization performance of various compiler strategies.
9-
2. Easily conduct regression tests on existing compilers.
10-
3. Train AI‑for‑Systems models to automatically generate compiler optimization passes.
10+
Compiler developers can use GraphNet samples to evaluate tensor compilers (e.g., CINN, TorchInductor, TVM) on target tasks. The figure above shows the speedup of two compilers (CINN and TorchInductor) across two tasks (CV and NLP).
1111

12-
**Vision**: We aim to achieve cross-hardware portability of compiler optimizations by allowing models to learn and transfer optimization strategies. It will significantly reduce the manual effort required to develop efficient operator implementations.
12+
## 🧱 Dataset Construction
1313

14+
To guarantee the dataset’s overall quality, reproducibility, and cross-compiler compatibility, we define the following construction **constraints**:
1415

15-
### Dataset Construction Constraints:
16-
1. Dynamic graphs must execute correctly.
17-
2. Graphs and their corresponding Python code must support serialization and deserialization.
16+
1. Computation graphs must be executable in imperative (eager) mode.
17+
2. Computation graphs and their corresponding Python code must support serialization and deserialization.
1818
3. The full graph can be decomposed into two disjoint subgraphs.
1919
4. Operator names within each computation graph must be statically parseable.
2020
5. If custom operators are used, their implementation code must be fully accessible.
2121

22+
### Graph Extraction & Validation
2223

23-
## ⚡ Quick Start
24-
For full implementation details, please refer to the [Co-Creation Tutorial](https://github.com/PaddlePaddle/GraphNet/blob/develop/CONTRIBUTE_TUTORIAL.md#co-creation-tutorial).
25-
### Benchmark your compiler on the model:
24+
We provide automated extraction and validation tools for constructing this dataset.
2625

27-
**graph_net.torch.test_compiler**
28-
```
29-
python3 -m graph_net.torch.test_compiler \
30-
--model-path $GRAPH_NET_EXTRACT_WORKSPACE/model_name/ \
31-
--compiler /path/to/custom/compiler
32-
# Note: if --compiler is omitted, PyTorch’s built-in compiler is used by default
33-
```
26+
<div align="center">
27+
<img src="/pics/graphnet_overview.jpg" alt="GraphNet Architecture Overview" width="65%">
28+
</div>
3429

35-
### Contribute computation graphs to GraphNet:
3630
**Demo: Extract & Validate ResNet‑18**
37-
```
31+
```bash
3832
git clone https://github.com/PaddlePaddle/GraphNet.git
3933
cd GraphNet
4034

4135
# Set your workspace directory
42-
export GRAPH_NET_EXTRACT_WORKSPACE=/home/yourname/graphnet_workspace
36+
export GRAPH_NET_EXTRACT_WORKSPACE=/home/yourname/graphnet_workspace/
4337

4438
# Extract the ResNet‑18 computation graph
4539
python graph_net/test/vision_model_test.py
4640

47-
# Validate the extracted graph (e.g. /home/yourname/graphnet_workspace/resnet18)
41+
# Validate the extracted graph (e.g. /home/yourname/graphnet_workspace/resnet18/)
4842
python -m graph_net.torch.validate \
49-
--model-path $GRAPH_NET_EXTRACT_WORKSPACE/resnet18
43+
--model-path $GRAPH_NET_EXTRACT_WORKSPACE/resnet18/
5044
```
5145

52-
**graph_net.torch.extract**
46+
**Illustration: How does GraphNet extract and construct a computation graph sample on PyTorch?**
5347

54-
```python
48+
<div align="center">
49+
<img src="/pics/graphnet_sample.png" alt="GraphNet Extract Sample" width="65%">
50+
</div>
51+
52+
* Source code of custom_op is required **only when** corresponding operator is used in the module, and **no specific format** is required.
53+
54+
**Step 1: graph_net.torch.extract**
55+
56+
Import and wrap the model with `graph_net.torch.extract(name=model_name, dynamic=dynamic_mode)()` is all you need:
57+
58+
```bash
5559
import graph_net
5660

5761
# Instantiate the model (e.g. a torchvision model)
5862
model = ...
5963

6064
# Extract your own model
61-
model = graph_net.torch.extract(name="model_name")(model)
62-
63-
# After running, the extracted graph will be saved to:
64-
# $GRAPH_NET_EXTRACT_WORKSPACE/model_name
65+
model = graph_net.torch.extract(name="model_name", dynamic="True")(model)
6566
```
6667

67-
**graph_net.torch.validate**
68-
```
69-
# Verify that the extracted model meets requirements
68+
After running, the extracted graph will be saved to: `$GRAPH_NET_EXTRACT_WORKSPACE/model_name/`.
69+
70+
For more details, see docstring of `graph_net.torch.extract` defined in `graph_net/torch/extractor.py`.
71+
72+
**Step 2: graph_net.torch.validate**
73+
74+
To verify that the extracted model meets requirements, we use `graph_net.torch.validate` in CI tool and also ask contributors to self-check in advance:
75+
76+
```bash
7077
python -m graph_net.torch.validate \
7178
--model-path $GRAPH_NET_EXTRACT_WORKSPACE/model_name
7279
```
7380

74-
**graph_net.pack**
75-
```
76-
# Create a ZIP archive of $GRAPH_NET_EXTRACT_WORKSPACE.
77-
# The --clear-after-pack flag (True|False) determines whether to delete the workspace after packing.
78-
python -m graph_net.pack \
79-
--output /path/to/output.zip \
80-
--clear-after-pack True
81+
All the **construction constraints** will be examined automatically. After passing validation, a unique `graph_hash.txt` will be generated and later checked in CI procedure to avoid redundant.
82+
83+
## ⚖️ Compiler Evaluation
84+
85+
**Step 1: Benchmark**
86+
87+
We use `graph_net/benchmark_demo.sh` to benchmark GraphNet computation graph samples:
88+
89+
```bash
90+
bash graph_net/benchmark_demo.sh &
8191
```
8292

83-
Note: To configure your user details (username and email) for GraphNet, run:
93+
The script runs `graph_net.torch.test_compiler` with specific batch and log configurations.
94+
95+
Or you can customize and use `graph_net.torch.test_compiler` yourself:
96+
97+
```bash
98+
python -m graph_net.torch.test_compiler \
99+
--model-path $GRAPH_NET_EXTRACT_WORKSPACE/model_name/ \
100+
--compiler /custom/or/builtin/compiler/ \
101+
--warmup /times/to/warmup/ \
102+
--trials /times/to/test/ \
103+
--device /device/to/execute/ \
104+
--output-dir /path/to/save/JSON/result/file/
105+
106+
# Note: if --compiler is omitted, PyTorch’s built-in compiler is used by default
84107
```
85-
python -m graph_net.config --global \
86-
--username "your-name" \
87-
--email "your-email"
108+
109+
After executing, `graph_net.torch.test_compiler` will:
110+
1. Running the original model in eager mode to record a baseline.
111+
2. Compiling the model with the specified backend (e.g., CINN, TVM, Inductor, TensorRT, XLA, BladeDISC).
112+
3. Executing the compiled model and collecting its runtime and outputs.
113+
4. Conduct speedup by comparing the compiled results against the baseline.
114+
115+
**Step 2: Analysis**
116+
117+
After processing, we provide `graph_net/analysis.py` to generate [violin plot](https://en.m.wikipedia.org/wiki/Violin_plot) based on the JSON results.
118+
119+
```bash
120+
python -m graph_net.analysis \
121+
--benchmark-path /path/to/read/JSON/result/file/ \
122+
--output-dir /path/to/save/output/figures/
88123
```
89-
Once you have packaged these extracted computation graphs, submit them to the GraphNet community via the following group chats.
90124

125+
After executing, one summary plot of results on all compilers, as well as multiple sub-plots of results in categories (model tasks, Library...) on a single compiler will be exported.
126+
127+
The script is designed to process a file structure as `/benchmark_path/compiler_name/category_name/` (for example `/benchmark_logs/paddle/nlp/`), and items on x-axis are identified by name of the folders. So you can modify `read_all_speedups` function to fit the benchmark settings on your demand.
128+
129+
## 📌 Roadmap
130+
131+
1. Scale GraphNet to 10K+ graphs.
132+
2. Further annotate GraphNet samples into more granular sub-categories
133+
3. Extract samples from multi-GPU scenarios to support benchmarking and optimization for large-scale, distributed computing.
134+
4. Enable splitting full graphs into independently optimized subgraphs and operator sequences.
135+
136+
**Vision**: GraphNet aims to lay the foundation for AI for Compiler by enabling **large-scale, systematic evaluation** of tensor compiler optimizations, and providing a **dataset for models to learn** and transfer optimization strategies.
137+
138+
## 💬 GraphNet Community
139+
140+
You can join our community via following group chats. Welcome to ask any questions about using and building GraphNet.
91141

92142
<div align="center">
93143
<table>
@@ -103,8 +153,5 @@ Once you have packaged these extracted computation graphs, submit them to the Gr
103153
</table>
104154
</div>
105155

106-
107-
108-
## License
156+
## 🪪 License
109157
This project is released under the [MIT License](LICENSE).
110-

graph_net/benchmark_demo.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ for package_path in "${samples_dir}"/*/; do
3131

3232
echo "[$(date)] FINISHED: ${package_name}/${model_name}"
3333
fi
34-
} >> "$global_log" 2>&1 &
34+
} >> "$global_log" 2>&1
3535
done
3636
done
3737

graph_net/paddle/check_redundant_incrementally.py

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -43,42 +43,72 @@ def is_single_model_dir(model_dir):
4343

4444

4545
def main(args):
46-
assert os.path.isdir(args.model_path)
47-
assert os.path.isdir(args.graph_net_samples_path)
48-
current_model_graph_hash_pathes = set(
49-
graph_hash_path
50-
for model_path in get_recursively_model_pathes(args.model_path)
51-
for graph_hash_path in [f"{model_path}/graph_hash.txt"]
46+
assert os.path.isdir(
47+
args.graph_net_samples_path
48+
), f"args.graph_net_samples_path ({args.graph_net_samples_path}) is not a directory!"
49+
50+
current_model_graph_hash_pathes = set()
51+
if args.model_path:
52+
assert os.path.isdir(
53+
args.model_path
54+
), f"args.model_path {args.model_path} is not a directory!"
55+
current_model_graph_hash_pathes = set(
56+
graph_hash_path
57+
for model_path in get_recursively_model_pathes(args.model_path)
58+
for graph_hash_path in [f"{model_path}/graph_hash.txt"]
59+
)
60+
61+
find_redundant = False
62+
graph_hash2graph_net_model_path = {}
63+
for model_path in get_recursively_model_pathes(args.graph_net_samples_path):
64+
graph_hash_path = f"{model_path}/graph_hash.txt"
65+
if (
66+
os.path.isfile(graph_hash_path)
67+
and graph_hash_path not in current_model_graph_hash_pathes
68+
):
69+
graph_hash = open(graph_hash_path).read()
70+
if graph_hash not in graph_hash2graph_net_model_path.keys():
71+
graph_hash2graph_net_model_path[graph_hash] = [graph_hash_path]
72+
else:
73+
find_redundant = True
74+
graph_hash2graph_net_model_path[graph_hash].append(graph_hash_path)
75+
print(
76+
f"Totally {len(graph_hash2graph_net_model_path)} unique samples under {args.graph_net_samples_path}."
5277
)
53-
graph_hash2graph_net_model_path = {
54-
graph_hash: graph_hash_path
55-
for model_path in get_recursively_model_pathes(args.graph_net_samples_path)
56-
for graph_hash_path in [f"{model_path}/graph_hash.txt"]
57-
if os.path.isfile(graph_hash_path)
58-
if graph_hash_path not in current_model_graph_hash_pathes
59-
for graph_hash in [open(graph_hash_path).read()]
60-
}
61-
for current_model_graph_hash_path in current_model_graph_hash_pathes:
62-
graph_hash = open(current_model_graph_hash_path).read()
78+
79+
if args.model_path:
80+
# Check whether the specified model is redundant.
81+
for current_model_graph_hash_path in current_model_graph_hash_pathes:
82+
graph_hash = open(current_model_graph_hash_path).read()
83+
assert (
84+
graph_hash not in graph_hash2graph_net_model_path
85+
), f"Redundant models detected.\n\tgraph_hash:{graph_hash}, newly-added-model-path:{current_model_graph_hash_path}, existing-model-path:{graph_hash2graph_net_model_path[graph_hash]}."
86+
else:
87+
# Check whether there are redundant samples under samples directory.
88+
for graph_hash, graph_paths in graph_hash2graph_net_model_path.items():
89+
if len(graph_paths) > 1:
90+
print(f"Redundant models detected for grap_hash {graph_hash}:")
91+
for model_path in graph_paths:
92+
print(f" {model_path}")
6393
assert (
64-
graph_hash not in graph_hash2graph_net_model_path
65-
), f"Redundant models detected. old-model-path:{current_model_graph_hash_path}, new-model-path:{graph_hash2graph_net_model_path[graph_hash]}."
94+
not find_redundant
95+
), f"Redundant models detected under {args.graph_net_samples_path}."
6696

6797

6898
if __name__ == "__main__":
6999
parser = argparse.ArgumentParser(description="Test compiler performance.")
70100
parser.add_argument(
71101
"--model-path",
72102
type=str,
73-
required=True,
103+
required=False,
74104
help="Path to model file(s), each subdirectory containing graph_net.json will be regarded as a model",
75105
)
76106
parser.add_argument(
77107
"--graph-net-samples-path",
78108
type=str,
79-
required=False,
80-
default="default",
109+
required=True,
81110
help="Path to GraphNet samples",
82111
)
83112
args = parser.parse_args()
113+
print(args)
84114
main(args=args)

graph_net/paddle/samples_util.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33

44

55
def get_default_samples_directory():
6-
return f"{os.path.dirname(graph_net.__file__)}/../paddle_samples"
6+
graph_net_root = os.path.dirname(os.path.dirname(graph_net.__file__))
7+
return f"{graph_net_root}/paddle_samples"

0 commit comments

Comments
 (0)