Skip to content

Commit 18c4bab

Browse files
committed
observatory: update document and cli options to feat new module structure
1 parent 1094ea2 commit 18c4bab

7 files changed

Lines changed: 73 additions & 164 deletions

File tree

backends/qualcomm/debugger/observatory/cli.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ def main():
7272
AccuracyLens.register_dataset_patches(install_qnn_dataset_patches)
7373
Observatory.register_lens(AccuracyLens)
7474

75+
from .lenses.per_layer_accuracy import PerLayerAccuracyLens
76+
cls.register_lens(PerLayerAccuracyLens)
77+
78+
79+
7580
run_observatory(obs_flags, script_path, script_argv, Observatory)
7681

7782

backends/xnnpack/debugger/observatory/cli.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ def main():
6969

7070
Observatory.register_lens(AccuracyLens)
7171

72+
from .lenses.per_layer_accuracy import PerLayerAccuracyLens
73+
cls.register_lens(PerLayerAccuracyLens)
74+
75+
76+
7277
run_observatory(obs_flags, script_path, script_argv, Observatory)
7378

7479

devtools/observatory/README.md

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,30 @@ A standalone HTML report containing:
3636
### CLI (zero-config)
3737

3838
Point the CLI at any ExecuTorch export script:
39+
The simplest invocation: point the CLI at your script and pass its arguments through.
40+
Use `--report-html` to set output paths explicitly:
41+
```bash
42+
python -m devtools.observatory.cli \
43+
--report-html /path/to/output_report.html \
44+
{your original script and arguments}
45+
```
46+
For example:
3947

4048
```bash
41-
python -m backends.qualcomm.debugger.observatory.cli \
49+
python -m devtools.observatory.cli \
50+
--report-html /tmp/obs/report.html \
51+
--report-json /tmp/obs/report.json \
52+
--report-title "Swin V2-T Qualcomm" \
53+
examples/qualcomm/oss_scripts/swin_v2_t.py \
54+
--model SM8650 -b ./build-android -d imagenet-mini/val -a ./swin_v2_t
55+
```
56+
57+
Use backend-specific observatory cli for additional customized lenses and hooks (for example, xnnpack backend with per-layer accuracy analysis)
58+
59+
```bash
60+
python -m backends.xnnpack.debugger.observatory.cli \
61+
--report-html /tmp/obs/report.html \
62+
--accuracy \
4263
examples/xnnpack/aot_compiler.py \
4364
--model_name=mv2 --delegate --quantize --output_dir /tmp/mv2
4465
```
@@ -50,10 +71,12 @@ This produces:
5071
### Python API
5172

5273
```python
53-
from executorch.backends.qualcomm.debugger.observatory import Observatory
74+
from executorch.devtools.observatory import Observatory
5475

5576
Observatory.clear()
5677
with Observatory.enable_context():
78+
# Auto: Lenses can auto-insert collection points by monkey patching when entering context
79+
# Manual: Insert the collection point anywhere
5780
Observatory.collect("step_0", graph_module)
5881

5982
Observatory.export_html_report("/tmp/report.html")
@@ -90,16 +113,16 @@ This means you can collect data in CI and generate reports locally, or regenerat
90113

91114
```bash
92115
# Step 1: collect (e.g., in CI)
93-
python -m backends.qualcomm.debugger.observatory.cli --json-only script.py ...
116+
python -m devtools.observatory.cli --json-only script.py ...
94117

95118
# Step 2: visualize (e.g., locally)
96-
python -m backends.qualcomm.debugger.observatory.cli visualize \
119+
python -m devtools.observatory.cli visualize \
97120
--input report.json --output report.html
98121
```
99122

100123
### Fx-Viewer
101124

102-
Fx-Viewer (`backends/qualcomm/utils/fx_viewer`) is the graph visualization component used inside Observatory's Graph View. Observatory owns the workflow; Fx-Viewer provides the interactive graph rendering, node inspection, and highlighting within that workflow.
125+
Fx-Viewer (`devtools/utils/fx_viewer`) is the graph visualization component used inside Observatory's Graph View. Observatory owns the workflow; Fx-Viewer provides the interactive graph rendering, node inspection, and highlighting within that workflow.
103126

104127
## How to use it
105128

@@ -117,7 +140,7 @@ See [USAGE.md](USAGE.md) for the full CLI usage guide, including:
117140
A lens implements the `observe -> digest -> analyze -> frontend` lifecycle:
118141

119142
```python
120-
from executorch.backends.qualcomm.debugger.observatory.interfaces import (
143+
from executorch.devtools.observatory.interfaces import (
121144
AnalysisResult, Frontend, TableBlock, TableRecordSpec, ViewList,
122145
)
123146

@@ -164,7 +187,7 @@ Lenses can contribute colored graph overlays during the `analyze()` phase:
164187
from executorch.backends.qualcomm.debugger.observatory.interfaces import (
165188
AnalysisResult, RecordAnalysis,
166189
)
167-
from executorch.backends.qualcomm.utils.fx_viewer import (
190+
from executorch.devtools.fx_viewer import (
168191
GraphExtensionPayload, GraphExtensionNodePayload,
169192
)
170193

@@ -208,5 +231,5 @@ return AnalysisResult(per_record_data={"step_1": record_analysis})
208231
## Tests
209232

210233
```bash
211-
pytest -q backends/qualcomm/debugger/observatory/tests
234+
pytest -q backends/devtools/observatory/tests
212235
```

devtools/observatory/USAGE.md

Lines changed: 25 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,33 @@ automatically collecting graph snapshots and accuracy metrics at each compilatio
66
## 1. Zero-Config E2E Workflow
77

88
The simplest invocation: point the CLI at your script and pass its arguments through.
9-
The CLI infers the output directory from the script's `-a`/`--artifact` or `-o`/`--output_dir` flag.
10-
9+
Use `--report-html` to set output paths explicitly:
1110
```bash
12-
python -m backends.qualcomm.debugger.observatory.cli \
13-
examples/qualcomm/oss_scripts/swin_v2_t.py \
14-
--model SM8650 -b ./build-android -d imagenet-mini/val -a ./swin_v2_t
11+
python -m devtools.observatory.cli \
12+
{your original script and arguments}
1513
```
16-
17-
Output (inferred from `-a ./swin_v2_t`):
18-
- `./swin_v2_t/observatory_report.html` — interactive report
19-
- `./swin_v2_t/observatory_report.json` — raw data for later re-analysis
20-
21-
To set paths explicitly:
14+
For example:
2215

2316
```bash
24-
python -m backends.qualcomm.debugger.observatory.cli \
17+
python -m devtools.observatory.cli \
2518
--report-html /tmp/obs/report.html \
2619
--report-json /tmp/obs/report.json \
2720
--report-title "Swin V2-T Qualcomm" \
2821
examples/qualcomm/oss_scripts/swin_v2_t.py \
2922
--model SM8650 -b ./build-android -d imagenet-mini/val -a ./swin_v2_t
3023
```
3124

25+
Use backend-specific observatory cli for additional customized lenses and hooks (qualcomm for example)
26+
27+
```bash
28+
python -m backends.xnnpack.debugger.observatory.cli \
29+
--report-html /tmp/obs/report.html \
30+
--accuracy \
31+
examples/xnnpack/aot_compiler.py \
32+
--model_name=mv2 --delegate --quantize --output_dir /tmp/mv2
33+
```
34+
35+
3236
## 2. JSON-Only Export (CI / Storage)
3337

3438
Use `--json-only` to collect data and export only the raw JSON, skipping HTML generation.
@@ -82,8 +86,8 @@ python -m backends.qualcomm.debugger.observatory.cli visualize \
8286
--title "My Model Report"
8387
```
8488

85-
This separates the expensive on-device execution (Step 1) from the interactive
86-
visualization (Step 2), which can be re-run any number of times.
89+
This separates the history archive results of on-device execution (Step 1) from the interactive
90+
visualization (Step 2), which can be re-run on demand (e.g. comparing models between 2 history commits).
8791

8892
## 5. Disabling Lenses
8993

@@ -109,7 +113,8 @@ When using the Observatory Python API directly, pass a config dict to
109113
`enable_context()` or `export_html_report()`:
110114

111115
```python
112-
from executorch.backends.qualcomm.debugger.observatory import Observatory
116+
from executorch.devtools.observatory import Observatory
117+
113118

114119
config = {
115120
"accuracy": {"enabled": False},
@@ -135,7 +140,7 @@ custom lowering steps.
135140

136141
```python
137142
import torch
138-
from executorch.backends.qualcomm.debugger.observatory import Observatory
143+
from executorch.devtools.observatory import Observatory
139144

140145
model = MyModel().eval()
141146
graph = torch.fx.symbolic_trace(model)
@@ -157,6 +162,8 @@ Observatory.export_json("pass_debug.json")
157162
To compare graphs before and after a specific pass:
158163

159164
```python
165+
166+
from executorch.devtools.observatory import Observatory
160167
with Observatory.enable_context():
161168
for name, module in model.named_modules():
162169
before = torch.fx.symbolic_trace(module)
@@ -173,55 +180,13 @@ You can add collection points to your script without any setup:
173180

174181
```python
175182
# In your export script (e.g., my_model.py):
176-
from executorch.backends.qualcomm.debugger.observatory import Observatory
183+
from executorch.devtools.observatory import Observatory
177184

178185
# This fires only when Observatory context is active (i.e., when run via CLI).
179186
# It is a no-op otherwise.
180187
Observatory.collect("pre_quantize", exported_program)
181188
```
182-
183-
## 7. Demo Script Modes
184-
185-
The batch demo script (`scripts/generate_observatory_demo.py`) supports three modes:
186-
187-
### Default: run all jobs
188-
189-
```bash
190-
python scripts/generate_observatory_demo.py \
191-
--xnn-models mv2 \
192-
--qualcomm-models mobilenet_v2 \
193-
--qnn-sdk-root /path/to/qairt/2.37.0
194-
```
195-
196-
Runs each job, writes HTML + JSON reports, and refreshes `index.html`.
197-
198-
### `--plan-only`: register without running
199-
200-
```bash
201-
python scripts/generate_observatory_demo.py \
202-
--plan-only \
203-
--xnn-models mv2,resnet18 \
204-
--qualcomm-models mobilenet_v2,roberta
205-
```
206-
207-
Creates output directories and writes `manifest.json` + `index.html` with all
208-
jobs listed as `"planned"` status. No scripts are executed. Useful for previewing
209-
the job plan or pre-creating the index before a long run.
210-
211-
### `--visualize-only`: re-render HTML from existing JSON
212-
213-
```bash
214-
python scripts/generate_observatory_demo.py --visualize-only
215-
```
216-
217-
Reads `manifest.json`, calls `cli visualize` for each job that has an existing
218-
JSON file, and refreshes `index.html`. Jobs without a JSON file are skipped with
219-
a warning. Requires a prior successful run (or manually placed JSON files).
220-
221-
Use this after updating lens code to regenerate all HTML reports without
222-
re-running the expensive export scripts.
223-
224-
## 8. Quick Reference
189+
## 7. Quick Reference
225190

226191
| Scenario | Command |
227192
|----------|---------|
@@ -231,7 +196,3 @@ re-running the expensive export scripts.
231196
| JSON → HTML | `cli visualize --input X.json --output X.html` |
232197
| No accuracy metrics | `cli --no-accuracy script.py ...` |
233198
| No output files | `cli --no-report script.py ...` |
234-
| Batch plan (no run) | `generate_observatory_demo.py --plan-only` |
235-
| Batch run | `generate_observatory_demo.py` |
236-
| Batch re-render HTML | `generate_observatory_demo.py --visualize-only` |
237-
| Single model batch | `generate_observatory_demo.py --xnn-models mv2 --qualcomm-models mobilenet_v2` |

devtools/observatory/cli.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,9 @@ def main():
284284

285285
if obs_flags["--accuracy"]:
286286
from .lenses.accuracy import AccuracyLens
287-
288287
Observatory.register_lens(AccuracyLens)
288+
from .lenses.per_layer_accuracy import PerLayerAccuracyLens
289+
cls.register_lens(PerLayerAccuracyLens)
289290

290291
run_observatory(obs_flags, script_path, script_argv, Observatory)
291292

0 commit comments

Comments
 (0)